Add nim stub to main repo
This commit is contained in:
parent
cc50795d43
commit
af79c47691
|
@ -0,0 +1,34 @@
|
|||
class NimGameStub:
|
||||
"""A stub is a minimal version of a class which stands in for the
|
||||
real class, which hasn't yet been written. The stub has all the correct
|
||||
methods, and their inputs and outputs are the right kind of thing,
|
||||
but it doesn't really do anything.
|
||||
"""
|
||||
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"],
|
||||
}
|
||||
return next_state
|
||||
|
||||
def get_actions(self, state):
|
||||
return [
|
||||
(0, 0),
|
||||
(1, 0), (1, 1),
|
||||
(2, 0), (2, 1), (2, 2), (3, 0), (3, 1), (3, 2), (3, 3),
|
||||
]
|
||||
|
||||
def get_reward(self, state):
|
||||
return 0
|
||||
|
||||
def is_over(self, state):
|
||||
return False
|
||||
|
||||
def get_objective(self, state):
|
||||
return max if state["first_player"] else min
|
|
@ -0,0 +1,35 @@
|
|||
from nim.game_stub import NimGameStub
|
||||
from strategy.lookahead_strategy import LookaheadStrategy
|
||||
|
||||
class HumanNimPlayer:
|
||||
def __init__(self, name):
|
||||
self.name = name
|
||||
self.game = NimGameStub()
|
||||
|
||||
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(NimGameStub(), 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
|
|
@ -0,0 +1,32 @@
|
|||
from nim.game_stub import NimGameStub
|
||||
|
||||
class NimView:
|
||||
def __init__(self, player0, player1):
|
||||
self.players = [player0, player1]
|
||||
self.game = NimGameStub()
|
||||
|
||||
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}!")
|
|
@ -0,0 +1,15 @@
|
|||
from nim.game_stub import NimGameStub
|
||||
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()
|
||||
|
||||
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)
|
Loading…
Reference in New Issue