Compare commits

...

2 Commits

Author SHA1 Message Date
Cory 70c8ff1308 (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]
2024-04-08 10:12:37 -04:00
Cory 0a3d7e31f5 Completed checkpoint 3
What I changed
(I gave the computer player the look ahead strategy. This also required importing LookaheadStrategy in player.py.
I also answered the questions in notes.md.)

Why I changed it
(I was working on completing checkpoint 3. I realized I had to do the importing since otherwise it wouldn't let me play.)

Estimate for remaining time to finish assignment: [I am REALLY bad at these estimates. I mean in terms of actual work time, I'm probably not too far off. Fingers crossed, maybe another hour of actual work time?]
2024-03-20 20:13:39 -04:00
8 changed files with 63 additions and 12 deletions

BIN
.DS_Store vendored Normal file

Binary file not shown.

49
nim/game.py Normal file
View 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

View File

@ -1,16 +1,16 @@
from nim.game_stub import NimGameStub from nim.game import NimGame
from strategy.lookahead_strategy import LookaheadStrategy from strategy.lookahead_strategy import LookaheadStrategy
class HumanNimPlayer: class HumanNimPlayer:
def __init__(self, name): def __init__(self, name):
self.name = name self.name = name
self.game = NimGameStub() self.game = NimGame()
def choose_action(self, state): def choose_action(self, state):
actions = self.game.get_actions(state) actions = self.game.get_actions(state)
for i, action in enumerate(actions): for i, action in enumerate(actions):
row, lines_to_remove = action 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)) choice = self.get_int(len(actions))
return actions[choice] return actions[choice]
@ -26,10 +26,10 @@ class HumanNimPlayer:
class ComputerNimPlayer: class ComputerNimPlayer:
def __init__(self, name): def __init__(self, name):
self.name = 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): def choose_action(self, state):
action = self.strategy.choose_action(state) action = self.strategy.choose_action(state)
row, lines_to_remove = action 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 return action

View File

@ -1,9 +1,9 @@
from nim.game_stub import NimGameStub from nim.game import NimGame
class NimView: class NimView:
def __init__(self, player0, player1): def __init__(self, player0, player1):
self.players = [player0, player1] self.players = [player0, player1]
self.game = NimGameStub() self.game = NimGame()
def greet(self): def greet(self):
print(f"{self.players[0].name} and {self.players[1].name}, welcome to Nim.") print(f"{self.players[0].name} and {self.players[1].name}, welcome to Nim.")

View File

@ -37,4 +37,5 @@ For the first one, I would put an X on the rightmost cell in the middle row. Thi
You can get the inital game state using game.get_initial_state(). You can get the inital game state using game.get_initial_state().
What is the current and future reward for this state? What does this mean? What is the current and future reward for this state? What does this mean?
The current and future reward for this state is 1. This means the state favors player X assuming both players continue using the same look ahead strategy.

View File

@ -1,11 +1,11 @@
from nim.game_stub import NimGameStub from nim.game import NimGame
from nim.view import NimView from nim.view import NimView
from nim.player import HumanNimPlayer, ComputerNimPlayer from nim.player import HumanNimPlayer, ComputerNimPlayer
player0 = HumanNimPlayer(input("What's your name? ")) player0 = HumanNimPlayer(input("What's your name? "))
player1 = ComputerNimPlayer("Robot") player1 = ComputerNimPlayer("Robot")
view = NimView(player0, player1) view = NimView(player0, player1)
game = NimGameStub() game = NimGame()
view.greet() view.greet()
state = game.get_initial_state() state = game.get_initial_state()

View File

@ -2,8 +2,8 @@ from ttt.game import TTTGame
from ttt.view import TTTView from ttt.view import TTTView
from ttt.player import TTTHumanPlayer, TTTComputerPlayer from ttt.player import TTTHumanPlayer, TTTComputerPlayer
player0 = TTTHumanPlayer("Player 1") player0 = TTTHumanPlayer("Pleayer 1")
player1 = TTTHumanPlayer("Player 2") player1 = TTTComputerPlayer("Robot 1")
game = TTTGame() game = TTTGame()
view = TTTView(player0, player1) view = TTTView(player0, player1)

View File

@ -1,4 +1,5 @@
from click import Choice, prompt from click import Choice, prompt
from strategy.lookahead_strategy import LookaheadStrategy
from strategy.random_strategy import RandomStrategy from strategy.random_strategy import RandomStrategy
from ttt.game import TTTGame from ttt.game import TTTGame
import random import random
@ -24,7 +25,7 @@ class TTTComputerPlayer:
def __init__(self, name): def __init__(self, name):
"Sets up the player." "Sets up the player."
self.name = name self.name = name
self.strategy = RandomStrategy(TTTGame()) self.strategy = LookaheadStrategy(TTTGame(),deterministic=False)
def choose_action(self, state): def choose_action(self, state):
"Chooses a random move from the moves available." "Chooses a random move from the moves available."