generated from mwc/lab_tic_tac_toe
	(Completed Nim as part of the tic tac toe lab.)
What I changed (I made a copy of game_stub.py called game.py and corrected the methods so that the game would work.) Why I changed it (To complete the lab.) Estimate for remaining time to finish assignment: [Done]
This commit is contained in:
		
							
								
								
									
										49
									
								
								nim/game.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										49
									
								
								nim/game.py
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,49 @@
 | 
			
		||||
class NimGame:
 | 
			
		||||
    """A Nim game class based off NimGameStub.
 | 
			
		||||
    """
 | 
			
		||||
    def get_initial_state(self):
 | 
			
		||||
        ''' Constructs the game board and has player 1 start the game. '''
 | 
			
		||||
        return {
 | 
			
		||||
            "board": [1, 3, 5, 7],
 | 
			
		||||
            "first_player": True
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
    def get_next_state(self, state, action):
 | 
			
		||||
        ''' Creates a copy of the current board and then makes adjustments
 | 
			
		||||
        based on the chosen action from a player's turn. '''
 | 
			
		||||
        new_board = state["board"].copy()
 | 
			
		||||
        new_board[action[0]] = new_board[action[0]] - action[1]
 | 
			
		||||
        return {
 | 
			
		||||
            "board": new_board,
 | 
			
		||||
            "first_player": not state["first_player"],
 | 
			
		||||
        }
 | 
			
		||||
    
 | 
			
		||||
    def get_actions(self, state):
 | 
			
		||||
        ''' Construct the list of actions that can be taken by a player.
 | 
			
		||||
        Is there a more efficient way of doign this? '''
 | 
			
		||||
        actions = []
 | 
			
		||||
        new_board = state["board"].copy()
 | 
			
		||||
        for i in range(4):                      # check the four rows of the board
 | 
			
		||||
            if new_board[i] > 0:                # if a row is not empty
 | 
			
		||||
                for j in range(1,4):            # check if you can remove 1, 2, or 3 ticks in the row
 | 
			
		||||
                    if j <= new_board[i]:       # if so
 | 
			
		||||
                        actions.append((i,j))   # include that as an option
 | 
			
		||||
        return actions   
 | 
			
		||||
 | 
			
		||||
    def get_reward(self, state):
 | 
			
		||||
        ''' Reports who wins. '''
 | 
			
		||||
        if state["first_player"]:
 | 
			
		||||
            return 1    # If it is the player's turn and there is nothing on the board, then it was the robot who crossed off the last line.
 | 
			
		||||
        return 0        # Otherwise, the first player made the last move and lost.
 | 
			
		||||
 | 
			
		||||
    def is_over(self, state):
 | 
			
		||||
        ''' Reports true if there are no more lines to cross. '''
 | 
			
		||||
        if all(ticks == 0 for ticks in state["board"]):
 | 
			
		||||
            return True
 | 
			
		||||
        return False
 | 
			
		||||
 | 
			
		||||
    def get_objective(self, state):
 | 
			
		||||
        ''' Reports the desired obejctive to help choose the move that 
 | 
			
		||||
        yields the optimal reward under the lookahead_strategy for
 | 
			
		||||
        computer players. '''
 | 
			
		||||
        return max if state["first_player"] else min
 | 
			
		||||
@@ -1,16 +1,16 @@
 | 
			
		||||
from nim.game_stub import NimGameStub
 | 
			
		||||
from nim.game import NimGame
 | 
			
		||||
from strategy.lookahead_strategy import LookaheadStrategy
 | 
			
		||||
 | 
			
		||||
class HumanNimPlayer:
 | 
			
		||||
    def __init__(self, name):
 | 
			
		||||
        self.name = name
 | 
			
		||||
        self.game = NimGameStub()
 | 
			
		||||
        self.game = NimGame()
 | 
			
		||||
 | 
			
		||||
    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}.")
 | 
			
		||||
            print(f"{i}. Remove {lines_to_remove} from row {row+1}.")
 | 
			
		||||
        choice = self.get_int(len(actions))
 | 
			
		||||
        return actions[choice]
 | 
			
		||||
 | 
			
		||||
@@ -26,10 +26,10 @@ class HumanNimPlayer:
 | 
			
		||||
class ComputerNimPlayer:
 | 
			
		||||
    def __init__(self, name):
 | 
			
		||||
        self.name = name
 | 
			
		||||
        self.strategy = LookaheadStrategy(NimGameStub(), max_depth=3, deterministic=False)
 | 
			
		||||
        self.strategy = LookaheadStrategy(NimGame(), max_depth=5, 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}")
 | 
			
		||||
        print(f"{self.name} removes {lines_to_remove} from row {row+1}")
 | 
			
		||||
        return action
 | 
			
		||||
 
 | 
			
		||||
@@ -1,9 +1,9 @@
 | 
			
		||||
from nim.game_stub import NimGameStub
 | 
			
		||||
from nim.game import NimGame
 | 
			
		||||
 | 
			
		||||
class NimView:
 | 
			
		||||
    def __init__(self, player0, player1):
 | 
			
		||||
        self.players = [player0, player1]
 | 
			
		||||
        self.game = NimGameStub()
 | 
			
		||||
        self.game = NimGame()
 | 
			
		||||
 | 
			
		||||
    def greet(self):
 | 
			
		||||
        print(f"{self.players[0].name} and {self.players[1].name}, welcome to Nim.")
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user