From 9019a2efa57c6f9559c892ead0ed5ce5b37b6491 Mon Sep 17 00:00:00 2001 From: kathrynoh23 <126970932+kathrynoh23@users.noreply.github.com> Date: Sat, 6 Apr 2024 19:33:41 -0400 Subject: [PATCH] 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. --- .DS_Store | Bin 6148 -> 6148 bytes nim/.DS_Store | Bin 0 -> 6148 bytes nim/game_rev.py | 51 ++++++++++++++++++++ nim/player.py | 6 +-- nim/player_rev.py | 35 ++++++++++++++ nim/view_rev.py | 32 ++++++++++++ notes.md | 118 +++++++++++++++++++++++++++++++++++++++++++++ play_nim.py | 2 +- play_nim_rev.py | 15 ++++++ strategy/.DS_Store | Bin 6148 -> 6148 bytes 10 files changed, 255 insertions(+), 4 deletions(-) create mode 100644 nim/.DS_Store create mode 100644 nim/game_rev.py create mode 100644 nim/player_rev.py create mode 100644 nim/view_rev.py create mode 100644 play_nim_rev.py diff --git a/.DS_Store b/.DS_Store index bda659fda86d541d712336b452df7d340b643894..42073a0b7ef185fa636ad85e953bb78e6aa6fe12 100644 GIT binary patch delta 87 zcmZoMXfc=|&e%S&P;8=}q5v}k0|O%ig8)NvPEvk;4&y|9iHR3PL_osK40#Nh47n-A kP^pbQ8SI=h6bQ#VPI7>M$h&m2>c}_IdtuEgkdX>d0V;4;z`hR!Zden?K>u_g_y_=8 zBJGB?&l13531Cee1CfDgP=P_!95FQL$d|0EiDO{UMRWMjJXv!>Q9m8;FJ3NM0~x6R z6__fpi0#_?{~P?t{68geM+KA!1r*gxx&q`b_#;GW1zQV hY^)t`yeR65t?|4jj)6``-swR8445u7D)83|+yF)|6_)@2 literal 0 HcmV?d00001 diff --git a/nim/game_rev.py b/nim/game_rev.py new file mode 100644 index 0000000..6018a2a --- /dev/null +++ b/nim/game_rev.py @@ -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 diff --git a/nim/player.py b/nim/player.py index 32fd9fc..67faf3c 100644 --- a/nim/player.py +++ b/nim/player.py @@ -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) diff --git a/nim/player_rev.py b/nim/player_rev.py new file mode 100644 index 0000000..74fac04 --- /dev/null +++ b/nim/player_rev.py @@ -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 diff --git a/nim/view_rev.py b/nim/view_rev.py new file mode 100644 index 0000000..1cd5820 --- /dev/null +++ b/nim/view_rev.py @@ -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}!") diff --git a/notes.md b/notes.md index 1768ed9..716103f 100644 --- a/notes.md +++ b/notes.md @@ -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 it’s “X’s” turn and if not it’s “0’s” 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! \ No newline at end of file diff --git a/play_nim.py b/play_nim.py index 61f5cf2..45d5bb1 100644 --- a/play_nim.py +++ b/play_nim.py @@ -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 diff --git a/play_nim_rev.py b/play_nim_rev.py new file mode 100644 index 0000000..21ac3ce --- /dev/null +++ b/play_nim_rev.py @@ -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) diff --git a/strategy/.DS_Store b/strategy/.DS_Store index a292f56e49e07b1b584c4550f1aadb55b0d12f63..38734ca2de71d90578b12a191d5ff30a57f26d5c 100644 GIT binary patch delta 14 VcmZoMXfc?uZsW!<_Qfn50st)X1tkCg delta 17 YcmZoMXfc?uj*)TW#xVBHtQ`OO0Xe${HUIzs