generated from mwc/lab_tic_tac_toe
Submission for tic tac toe lab.
What I changed I completed checkpoints 1-3. I would have submitted all three separately, but a bug prohibited my initial submissions. I also started working on the nim section of the lab. Why I changed it I made these changes in order to make a functions tic tac toe and nim game. Estimate for remaining time to finish assignment: 15 minutes
This commit is contained in:
parent
8f32985ecb
commit
736cba0006
|
@ -0,0 +1,50 @@
|
|||
class NimGame:
|
||||
|
||||
def get_initial_state(self):
|
||||
return {
|
||||
"board": [1, 3, 5, 7],
|
||||
"first_player": True
|
||||
}
|
||||
|
||||
def get_next_state(self, state, action):
|
||||
board = state["board"].copy()
|
||||
row = action[0]
|
||||
number_to_remove = action[1]
|
||||
board[row] = board[row] - number_to_remove
|
||||
next_state = {
|
||||
"board": board,
|
||||
"first_player": not state["first_player"],
|
||||
}
|
||||
return next_state
|
||||
|
||||
def get_actions(self, state):
|
||||
options = []
|
||||
for num in range(4):
|
||||
row = state["board"][num]
|
||||
if row >=3:
|
||||
options.append((num, 1))
|
||||
options.append((num, 2))
|
||||
options.append((num, 3))
|
||||
elif row == 2:
|
||||
options.append((num, 1))
|
||||
options.append((num, 2))
|
||||
elif row == 1:
|
||||
options.append((num, 1))
|
||||
return options
|
||||
|
||||
def get_reward(self, state):
|
||||
if state["first_player"]:
|
||||
return 1
|
||||
elif not state["first_player"]:
|
||||
return -1
|
||||
else:
|
||||
return 0
|
||||
|
||||
def is_over(self, state):
|
||||
for row in state["board"]:
|
||||
if row != 0:
|
||||
return False
|
||||
return True
|
||||
|
||||
def get_objective(self, state):
|
||||
return max if state["first_player"] else min
|
|
@ -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)
|
||||
|
|
|
@ -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.")
|
||||
|
|
19
notes.md
19
notes.md
|
@ -6,16 +6,21 @@ Which class is responsible for each of the following behaviors?
|
|||
For each, explain how the behavior is accomplished.
|
||||
|
||||
### Checking to see whether the game is over
|
||||
|
||||
The game class is responsible for checking to see if the game is over. The method is_over checks the current
|
||||
state of the game to see if the board is full or if either X or O has won. If any of these three things are true,
|
||||
the game is over.
|
||||
### Determining which actions are available at a particular state
|
||||
|
||||
The game class is responsible for determining which actions are available at a particular state. The get_actions
|
||||
method returns a list of the indices of open spaces. These are the actions that are available at that state.
|
||||
### Showing the board
|
||||
|
||||
The view class is responsible for showing the board. The format_row and format_value methods are responsible for formatting, and the print_board method displays the board to the user. The board is actually shown when the get_action method is called.
|
||||
### Choosing which action to play on a turn
|
||||
|
||||
The player class is responsible for choosing which action to play on a turn. The choose_action method prompts the player to choose the action.
|
||||
|
||||
## Checkpoint 2 Notes
|
||||
|
||||
For Checkpoint 2, I just programmed the method to check every possible winning combination in the game.
|
||||
|
||||
### TTT Strategy
|
||||
|
||||
For each of the following board states, if you are playing as X
|
||||
|
@ -27,9 +32,15 @@ and it's your turn, which action would you take? Why?
|
|||
---+---+--- ---+---+--- ---+---+--- ---+---+---
|
||||
| | | | O | | | |
|
||||
|
||||
For the first board I would choose the middle row right column because that would result in a win.
|
||||
For the second board, I would choose the middle row right column to prevent the other player from winning next turn.
|
||||
For the third board, I would choose the top row left column because it would guarantee a win on my next turn.
|
||||
For the last board, I would choose the middle space. That would force my opponent to take the bottom right. Then I could take the bottom left and win on my next turn.
|
||||
|
||||
### Initial game 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?
|
||||
|
||||
The current and future reward for this state is 0. That means that if both players play optimally, the game will result in a tie.
|
||||
|
||||
|
|
|
@ -1,11 +1,11 @@
|
|||
from nim.game_stub import NimGameStub
|
||||
from nim.game import NimGame
|
||||
from nim.view import NimView
|
||||
from nim.player import HumanNimPlayer, ComputerNimPlayer
|
||||
|
||||
player0 = HumanNimPlayer(input("What's your name? "))
|
||||
player1 = ComputerNimPlayer("Robot")
|
||||
view = NimView(player0, player1)
|
||||
game = NimGameStub()
|
||||
game = NimGame()
|
||||
|
||||
view.greet()
|
||||
state = game.get_initial_state()
|
||||
|
|
|
@ -3,7 +3,7 @@ from ttt.view import TTTView
|
|||
from ttt.player import TTTHumanPlayer, TTTComputerPlayer
|
||||
|
||||
player0 = TTTHumanPlayer("Player 1")
|
||||
player1 = TTTHumanPlayer("Player 2")
|
||||
player1 = TTTComputerPlayer("Robot")
|
||||
game = TTTGame()
|
||||
view = TTTView(player0, player1)
|
||||
|
||||
|
|
20
ttt/game.py
20
ttt/game.py
|
@ -58,4 +58,22 @@ class TTTGame:
|
|||
|
||||
def check_winner(self, state, symbol):
|
||||
"Checks whether the player with `symbol` has won the game."
|
||||
return False
|
||||
board = state["board"]
|
||||
if board[0] == symbol and board[1] == symbol and board[2] == symbol:
|
||||
return True
|
||||
elif board[3] == symbol and board[4] == symbol and board[5] == symbol:
|
||||
return True
|
||||
elif board[6] == symbol and board[7] == symbol and board[8] == symbol:
|
||||
return True
|
||||
elif board[0] == symbol and board[3] == symbol and board[6] == symbol:
|
||||
return True
|
||||
elif board[1] == symbol and board[4] == symbol and board[7] == symbol:
|
||||
return True
|
||||
elif board[2] == symbol and board[5] == symbol and board[8] == symbol:
|
||||
return True
|
||||
elif board[0] == symbol and board[4] == symbol and board[8] == symbol:
|
||||
return True
|
||||
elif board[2] == symbol and board[4] == symbol and board[6] == symbol:
|
||||
return True
|
||||
else:
|
||||
return False
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
from click import Choice, prompt
|
||||
from strategy.random_strategy import RandomStrategy
|
||||
from strategy.lookahead_strategy import LookaheadStrategy
|
||||
from ttt.game import TTTGame
|
||||
import random
|
||||
|
||||
|
@ -24,7 +25,7 @@ class TTTComputerPlayer:
|
|||
def __init__(self, name):
|
||||
"Sets up the player."
|
||||
self.name = name
|
||||
self.strategy = RandomStrategy(TTTGame())
|
||||
self.strategy = LookaheadStrategy(TTTGame(), deterministic=False)
|
||||
|
||||
def choose_action(self, state):
|
||||
"Chooses a random move from the moves available."
|
||||
|
|
Loading…
Reference in New Issue