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
|
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)
|
||||||
|
@ -26,7 +26,7 @@ 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=3, deterministic=False)
|
||||||
|
|
||||||
def choose_action(self, state):
|
def choose_action(self, state):
|
||||||
action = self.strategy.choose_action(state)
|
action = self.strategy.choose_action(state)
|
||||||
|
|
|
@ -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.")
|
||||||
|
|
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.
|
For each, explain how the behavior is accomplished.
|
||||||
|
|
||||||
### Checking to see whether the game is over
|
### 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
|
### 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
|
### 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
|
### 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
|
## Checkpoint 2 Notes
|
||||||
|
|
||||||
|
For Checkpoint 2, I just programmed the method to check every possible winning combination in the game.
|
||||||
|
|
||||||
### TTT Strategy
|
### TTT Strategy
|
||||||
|
|
||||||
For each of the following board states, if you are playing as X
|
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 | | | |
|
| | | | 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
|
### Initial game state
|
||||||
|
|
||||||
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 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.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()
|
||||||
|
|
|
@ -3,7 +3,7 @@ from ttt.view import TTTView
|
||||||
from ttt.player import TTTHumanPlayer, TTTComputerPlayer
|
from ttt.player import TTTHumanPlayer, TTTComputerPlayer
|
||||||
|
|
||||||
player0 = TTTHumanPlayer("Player 1")
|
player0 = TTTHumanPlayer("Player 1")
|
||||||
player1 = TTTHumanPlayer("Player 2")
|
player1 = TTTComputerPlayer("Robot")
|
||||||
game = TTTGame()
|
game = TTTGame()
|
||||||
view = TTTView(player0, player1)
|
view = TTTView(player0, player1)
|
||||||
|
|
||||||
|
|
20
ttt/game.py
20
ttt/game.py
|
@ -58,4 +58,22 @@ class TTTGame:
|
||||||
|
|
||||||
def check_winner(self, state, symbol):
|
def check_winner(self, state, symbol):
|
||||||
"Checks whether the player with `symbol` has won the game."
|
"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 click import Choice, prompt
|
||||||
from strategy.random_strategy import RandomStrategy
|
from strategy.random_strategy import RandomStrategy
|
||||||
|
from strategy.lookahead_strategy import LookaheadStrategy
|
||||||
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."
|
||||||
|
|
Loading…
Reference in New Issue