Kathryn Odell-Hamilton

4.6.24
Corrected bugs with Nim game.

Had issues trying to update TTTGame:
To find the value of the first state, enter the
Python shell (python) and run the following:
-This was the typed and error message
   from ttt.game import TTTGame
    zsh: command not found: from

How do I accomplish the last task with TTTGame?
Thank you in advance.
This commit is contained in:
kathrynoh23 2024-04-06 19:33:41 -04:00
parent 0929ab7173
commit 9019a2efa5
10 changed files with 255 additions and 4 deletions

BIN
.DS_Store vendored

Binary file not shown.

BIN
nim/.DS_Store vendored Normal file

Binary file not shown.

51
nim/game_rev.py Normal file
View File

@ -0,0 +1,51 @@
class NimGameRev:
"""This is the NimGameRev. game_stub.py was used as the beginning
shell code in reference to correct methods, inputs, and outputs.
I entered the code for the game to be functional.
"""
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"],
}
row,num_lines=action
next_state["board"][row]-=num_lines
return next_state
"""def get_actions(self, state):
"initalize with actions"
actions = [
(0, 0),
(1, 0), (1, 1),
(2, 0), (2, 1), (2, 2),
(3, 0), (3, 1), (3, 2), (3, 3),
]
return actions"""
def get_actions(self, state):
actions = []
for row_index, lines_in_row in enumerate(state["board"]):
for num_lines_to_remove in range(1, lines_in_row + 1):
actions.append((row_index, num_lines_to_remove))
return actions
def get_reward(self, state):
if self.is_over(state):
return -1 if state["first_player"] else 1
return 0
def is_over(self, state):
"""Determines if the game is over.
Checks a condition, whether all rows are empty.
If all rows are empty game is over.
"""
return all(lines == 0 for lines in state["board"])
def get_objective(self, state):
return max if state["first_player"] else min

View File

@ -1,10 +1,10 @@
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)
@ -26,7 +26,7 @@ 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=3, deterministic=False)
def choose_action(self, state):
action = self.strategy.choose_action(state)

35
nim/player_rev.py Normal file
View File

@ -0,0 +1,35 @@
from nim.game_rev import NimGameRev
from strategy.lookahead_strategy import LookaheadStrategy
class HumanNimPlayer:
def __init__(self, name):
self.name = name
self.game = NimGameRev()
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(NimGameRev(), 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_rev.py Normal file
View File

@ -0,0 +1,32 @@
from nim.game_rev import NimGameRev
class NimViewRev:
def __init__(self, player0, player1):
self.players = [player0, player1]
self.game = NimGameRev()
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}!")

118
notes.md
View File

@ -109,4 +109,122 @@ game.py. “def get_initial_state(self):”
Is returning the game's initial state with the Tic Tac Toe board ready for the 1st player to play the initial round.
Within “next state” there is a Boolean of True to see if its “Xs” turn and if not its “0s” turn to play. The future reward for the state is that the game proceeds and updates until the all spots have been used by both player with an outcome of a winner or not.
*****Getting errors entering code in python
I did all the preliminary with the poetry shell
from ttt.game import TTTGame "zsh: command not found: from"
Can't get beyond this. What am I doing incorrectly?
from ttt.game import TTTGame
from strategy.lookahead_strategy import LookaheadStrategy
game = TTTGame()
strategy = LookaheadStrategy(game, explain=True)
state = {"board": ['-','O','O','X','X','-','-','-','-'], "player_x": True} >>> strategy.get_current_and_future_reward(state, explain=True)
Nim Game
Wrote the NimGameRev class and replaced NimGameStub
The Nim Game was stuck with 1 line left and wouldn't end.
Honestly, I used AI to help me better understand the reasoning for the code.
I was stuck with def get_actions(self, state):
And used from AI
def get_actions(self, state):
actions = []
for row_index, lines_in_row in enumerate(state["board"]):
for num_lines_to_remove in range(1, lines_in_row + 1):
actions.append((row_index, num_lines_to_remove))
return actions
I have AI be more definitive because the use of 'i' and 'j' was too abstract.
The Nim Game worked with the Robot winning.
The Nim Game
What's your name? Kathryn
Kathryn and Robot, welcome to Nim.
|
| | |
| | | | |
| | | | | | |
0. Remove 1 from row 0.
1. Remove 1 from row 1.
2. Remove 2 from row 1.
3. Remove 3 from row 1.
4. Remove 1 from row 2.
5. Remove 2 from row 2.
6. Remove 3 from row 2.
7. Remove 4 from row 2.
8. Remove 5 from row 2.
9. Remove 1 from row 3.
10. Remove 2 from row 3.
11. Remove 3 from row 3.
12. Remove 4 from row 3.
13. Remove 5 from row 3.
14. Remove 6 from row 3.
15. Remove 7 from row 3.
> 1
|
| |
| | | | |
| | | | | | |
Robot removes 1 from row 3
|
| |
| | | | |
| | | | | |
0. Remove 1 from row 0.
1. Remove 1 from row 1.
2. Remove 2 from row 1.
3. Remove 1 from row 2.
4. Remove 2 from row 2.
5. Remove 3 from row 2.
6. Remove 4 from row 2.
7. Remove 5 from row 2.
8. Remove 1 from row 3.
9. Remove 2 from row 3.
10. Remove 3 from row 3.
11. Remove 4 from row 3.
12. Remove 5 from row 3.
13. Remove 6 from row 3.
> 2
|
| | | | |
| | | | | |
Robot removes 3 from row 2
|
| |
| | | | | |
0. Remove 1 from row 0.
1. Remove 1 from row 2.
2. Remove 2 from row 2.
3. Remove 1 from row 3.
4. Remove 2 from row 3.
5. Remove 3 from row 3.
6. Remove 4 from row 3.
7. Remove 5 from row 3.
8. Remove 6 from row 3.
> 8
|
| |
Robot removes 1 from row 2
|
|
0. Remove 1 from row 0.
1. Remove 1 from row 2.
> 1
|
Robot removes 1 from row 0
Congratulations, Robot!

View File

@ -1,4 +1,4 @@
from nim.game_stub import NimGameStub
from nim.game_stub import NimGameStub # type: ignore
from nim.view import NimView
from nim.player import HumanNimPlayer, ComputerNimPlayer

15
play_nim_rev.py Normal file
View File

@ -0,0 +1,15 @@
from nim.game_rev import NimGameRev
from nim.view_rev import NimViewRev
from nim.player_rev import HumanNimPlayer, ComputerNimPlayer
player0 = HumanNimPlayer(input("What's your name? "))
player1 = ComputerNimPlayer("Robot")
view = NimViewRev(player0, player1)
game = NimGameRev()
view.greet()
state = game.get_initial_state()
while not game.is_over(state):
action = view.get_action(state)
state = game.get_next_state(state, action)
view.conclude(state)

BIN
strategy/.DS_Store vendored

Binary file not shown.