generated from mwc/lab_tic_tac_toe
	Initial commit
This commit is contained in:
		
							
								
								
									
										34
									
								
								nim/game_stub.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										34
									
								
								nim/game_stub.py
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,34 @@
 | 
			
		||||
class NimGameStub:
 | 
			
		||||
    """A stub is a minimal version of a class which stands in for the 
 | 
			
		||||
    real class, which hasn't yet been written. The stub has all the correct 
 | 
			
		||||
    methods, and their inputs and outputs are the right kind of thing, 
 | 
			
		||||
    but it doesn't really do anything. 
 | 
			
		||||
    """
 | 
			
		||||
    def get_initial_state(self):
 | 
			
		||||
        return {
 | 
			
		||||
            "board": [1, 3, 5, 7],
 | 
			
		||||
            "first_player": True
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
    def get_next_state(self, state, action):
 | 
			
		||||
        next_state = {
 | 
			
		||||
            "board": state["board"].copy(),
 | 
			
		||||
            "first_player": not state["first_player"],
 | 
			
		||||
        }
 | 
			
		||||
        return next_state
 | 
			
		||||
 | 
			
		||||
    def get_actions(self, state):
 | 
			
		||||
        return [
 | 
			
		||||
            (0, 0), 
 | 
			
		||||
            (1, 0), (1, 1),
 | 
			
		||||
            (2, 0), (2, 1), (2, 2), (3, 0), (3, 1), (3, 2), (3, 3),
 | 
			
		||||
        ]
 | 
			
		||||
 | 
			
		||||
    def get_reward(self, state):
 | 
			
		||||
        return 0
 | 
			
		||||
 | 
			
		||||
    def is_over(self, state):
 | 
			
		||||
        return False
 | 
			
		||||
 | 
			
		||||
    def get_objective(self, state):
 | 
			
		||||
        return max if state["first_player"] else min
 | 
			
		||||
							
								
								
									
										35
									
								
								nim/player.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										35
									
								
								nim/player.py
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,35 @@
 | 
			
		||||
from nim.game_stub import NimGameStub
 | 
			
		||||
from strategy.lookahead_strategy import LookaheadStrategy
 | 
			
		||||
 | 
			
		||||
class HumanNimPlayer:
 | 
			
		||||
    def __init__(self, name):
 | 
			
		||||
        self.name = name
 | 
			
		||||
        self.game = NimGameStub()
 | 
			
		||||
 | 
			
		||||
    def choose_action(self, state):
 | 
			
		||||
        actions = self.game.get_actions(state)
 | 
			
		||||
        for i, action in enumerate(actions):
 | 
			
		||||
            row, lines_to_remove = action
 | 
			
		||||
            print(f"{i}. Remove {lines_to_remove} from row {row}.")
 | 
			
		||||
        choice = self.get_int(len(actions))
 | 
			
		||||
        return actions[choice]
 | 
			
		||||
 | 
			
		||||
    def get_int(self, maximum):
 | 
			
		||||
        while True:
 | 
			
		||||
            response = input("> ")
 | 
			
		||||
            if response.isdigit():
 | 
			
		||||
                value = int(response)
 | 
			
		||||
                if value < maximum:
 | 
			
		||||
                    return value
 | 
			
		||||
            print("Invalid input.")
 | 
			
		||||
 | 
			
		||||
class ComputerNimPlayer:
 | 
			
		||||
    def __init__(self, name):
 | 
			
		||||
        self.name = name
 | 
			
		||||
        self.strategy = LookaheadStrategy(NimGameStub(), max_depth=3, deterministic=False)
 | 
			
		||||
 | 
			
		||||
    def choose_action(self, state):
 | 
			
		||||
        action = self.strategy.choose_action(state)
 | 
			
		||||
        row, lines_to_remove = action
 | 
			
		||||
        print(f"{self.name} removes {lines_to_remove} from row {row}")
 | 
			
		||||
        return action
 | 
			
		||||
							
								
								
									
										32
									
								
								nim/view.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										32
									
								
								nim/view.py
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,32 @@
 | 
			
		||||
from nim.game_stub import NimGameStub
 | 
			
		||||
 | 
			
		||||
class NimView:
 | 
			
		||||
    def __init__(self, player0, player1):
 | 
			
		||||
        self.players = [player0, player1]
 | 
			
		||||
        self.game = NimGameStub()
 | 
			
		||||
 | 
			
		||||
    def greet(self):
 | 
			
		||||
        print(f"{self.players[0].name} and {self.players[1].name}, welcome to Nim.")
 | 
			
		||||
    
 | 
			
		||||
    def show_board(self, state):
 | 
			
		||||
        for lines_in_row in state["board"]:
 | 
			
		||||
            print("| " * lines_in_row)
 | 
			
		||||
 | 
			
		||||
    def get_action(self, state):
 | 
			
		||||
        self.show_board(state)
 | 
			
		||||
        player = self.get_current_player(state)
 | 
			
		||||
        return player.choose_action(state)
 | 
			
		||||
 | 
			
		||||
    def get_current_player(self, state):
 | 
			
		||||
        if state["first_player"]:
 | 
			
		||||
            return self.players[0]
 | 
			
		||||
        else:
 | 
			
		||||
            return self.players[1]
 | 
			
		||||
 | 
			
		||||
    def conclude(self, state):
 | 
			
		||||
        self.show_board(state)
 | 
			
		||||
        if self.game.get_reward(state) > 0:
 | 
			
		||||
            winner = self.players[0]
 | 
			
		||||
        else:
 | 
			
		||||
            winner = self.players[1]
 | 
			
		||||
        print(f"Congratulations, {winner.name}!")
 | 
			
		||||
		Reference in New Issue
	
	Block a user