def test_check_history_states(self): move_ref = MoveReferee() board1 = self._get_empty_board() board2 = self._get_empty_board() board3 = self._get_empty_board() self.assertTrue( move_ref._check_history_states([board3, board2, board1]))
def game_over(self, end_tag): # Reset default player for next game if end_tag == [GAME_OVER]: self.stone_type = None self.move_referee = MoveReferee() return True else: return False
def test_check_will_suicide(self): board = self._get_empty_board() move_ref = MoveReferee() board.place_stone(StoneEnum.BLACK, Point(0, 1)) board.place_stone(StoneEnum.BLACK, Point(1, 0)) board.place_stone(StoneEnum.BLACK, Point(1, 2)) board.place_stone(StoneEnum.BLACK, Point(2, 1)) self.assertTrue( move_ref._check_will_suicide(board, StoneEnum.BLACK, Point(0, 0)))
def __init__(self, name=None): """ This class implements a Go Player who chooses moves using a dumb strategy of the first valid minimum column, minimum row position on the board. """ self.name = name self.default_name = "default_player" #"no name" self.stone_type = None self.move_referee = MoveReferee()
def test_valid_move(self): board = self._get_empty_board() move_ref = MoveReferee() self.assertTrue( move_ref.valid_move(StoneEnum.BLACK, Point(0, 0), [board], board)) board_prev = board board_prev.place_stone(StoneEnum.BLACK, Point(0, 0)) self.assertFalse( move_ref.valid_move(StoneEnum.WHITE, Point(0, 0), [board_prev, board], board_prev))
def __init__(self, name=None): self.name = name self.default_name = "Player 1" self.stone_type = None self.color = "" self.move_referee = MoveReferee() self.click = None # Creates self.root window self.root = Tk() self.root.title("Go Game GUI") self.root.resizable(0, 0) self.root.geometry('1000x1000') self.e = Entry(self.root, text="ENTER YOUR NAME HERE", width=20, borderwidth=5, bg="yellow", fg="black") self.e.grid(row=0, column=0, columnspan=7) self.e1 = Entry(self.root, width=20, borderwidth=5, bg="yellow", fg="black") self.e1.grid(row=10, column=0, columnspan=7) self.button_register = Button(self.root, text="Register", command=self.myClick) self.button_move = Button(self.root, text="Make Move", command=self.myMove) self.pass_move = Button(self.root, text="Pass", command=self.Pass) self.button_register.grid(row=0, column=10, columnspan=1) self.button_move.grid(row=10, column=10, columnspan=1) self.pass_move.grid(row=9, column=10, columnspan=1) self.buttons = dict() for x in range(1, BOARD_DIM + 1): for y in range(1, BOARD_DIM + 1): button_num = "{}-{}".format(y, x) self.buttons["{}-{}".format(y, x)] = Button( self.root, text=" ", bg="goldenrod", padx=0.0, pady=20, command=lambda butt=button_num: self.button_click(butt)) self.buttons["{}-{}".format(y, x)].grid(row=x, column=y, columnspan=1)
def test_valid_play(self): board = self._get_empty_board() move_ref = MoveReferee() self.assertTrue(move_ref.valid_play(StoneEnum.BLACK, PASS)) self.assertTrue( move_ref.valid_play(StoneEnum.BLACK, [Point(1, 1), [board]])) board_prev = board board_prev.place_stone(StoneEnum.BLACK, Point(0, 0)) self.assertFalse( move_ref.valid_play(StoneEnum.BLACK, [Point(0, 0), [board_prev, board]]))
def test_check_history_prog(self): board1 = self._get_empty_board() move_ref = MoveReferee() board1.place_stone(StoneEnum.BLACK, Point(0, 0)) board2 = self._get_empty_board() board2.place_stone(StoneEnum.BLACK, Point(0, 0)) board2.place_stone(StoneEnum.BLACK, Point(5, 5)) board3 = self._get_empty_board() board3.place_stone(StoneEnum.BLACK, Point(0, 0)) board3.place_stone(StoneEnum.BLACK, Point(0, 1)) board3.place_stone(StoneEnum.BLACK, Point(0, 2)) self.assertFalse( move_ref._check_history_prog([board3, board2, board1], StoneEnum.WHITE))
def test_valid_step(self): move_ref = MoveReferee() curr_board = self._get_empty_board() curr_board.place_stone(StoneEnum.BLACK, Point(0, 0)) next_board = self._get_empty_board() next_board.place_stone(StoneEnum.BLACK, Point(0, 0)) next_board.place_stone(StoneEnum.WHITE, Point(0, 2)) self.assertTrue( move_ref._valid_step(curr_board, StoneEnum.WHITE, next_board)) ahead_board = self._get_empty_board() ahead_board.place_stone(StoneEnum.BLACK, Point(0, 0)) ahead_board.place_stone(StoneEnum.WHITE, Point(0, 2)) ahead_board.place_stone(StoneEnum.BLACK, Point(1, 1)) ahead_board.place_stone(StoneEnum.BLACK, Point(1, 2)) self.assertFalse( move_ref._valid_step(next_board, StoneEnum.WHITE, ahead_board))
def execute_input(arr): if is_board(arr): referee = ScoreReferee() result = referee.get_score(parse_board(arr)) return format_score(result) elif is_move(arr): referee = MoveReferee() stone_type, move = parse_move(arr) return referee.valid_play(stone_type, move) else: raise Exception("invalid input")
def __init__(self, board_size=BOARD_DIM, board=None, player1=None, player2=None): """ This class implements a referee component for the go game. Internally it holds a Go board, board history, a rule checker, a score keeper, and then information on the two players and state of the game. """ self.board_size = board_size self.board_history = [get_board([[" "] * self.board_size for row in range(self.board_size)])] self.players = {StoneEnum.BLACK: player1, StoneEnum.WHITE: player2} self.current_player = StoneEnum.BLACK self.move_ref = MoveReferee() self.score_ref = ScoreReferee() self.game_over = False self.winner_declared = False self.winner = None self.broke_rules = None
def test_get_history_mover(self): move_ref = MoveReferee() self.assertEqual(StoneEnum.WHITE, move_ref._get_history_mover(1, StoneEnum.BLACK)) self.assertEqual(StoneEnum.BLACK, move_ref._get_history_mover(2, StoneEnum.BLACK)) self.assertEqual(StoneEnum.BLACK, move_ref._get_history_mover(1, StoneEnum.WHITE)) self.assertEqual(StoneEnum.WHITE, move_ref._get_history_mover(2, StoneEnum.WHITE))
def test_valid_history(self): board = self._get_empty_board() move_ref = MoveReferee() board_history = [board] # Beginning Game self.assertTrue(move_ref.valid_history(StoneEnum.BLACK, board_history)) self.assertFalse(move_ref.valid_history(StoneEnum.WHITE, board_history)) board_history1 = [board, board] self.assertFalse( move_ref.valid_history(StoneEnum.BLACK, board_history1)) self.assertTrue(move_ref.valid_history(StoneEnum.WHITE, board_history1)) board_history2 = [board, board, board] # End Game self.assertFalse( move_ref.valid_history(StoneEnum.BLACK, board_history2)) self.assertFalse( move_ref.valid_history(StoneEnum.WHITE, board_history2))
class GoPlayerRandom(GoPlayer): def __init__(self): super().__init__() self.move_ref = MoveReferee() def register(self): return "random-player-{}".format(random.randint(0, 100000)) def choose_move(self, boards): if random.random() < 0.3: return PASS empty_spaces = list(boards[0].get_points(None)) random.shuffle(empty_spaces) for x, y in empty_spaces: if self.move_ref.valid_move(self.stone_type, Point(x, y), boards, boards[0]): return Point(x, y) return PASS
def __init__(self): super().__init__() self.move_ref = MoveReferee()
def test_check_valid_point(self): board = self._get_empty_board() move_ref = MoveReferee() self.assertTrue(move_ref._check_valid_point(board, Point(0, 0))) board.place_stone(StoneEnum.BLACK, Point(0, 0)) self.assertFalse(move_ref._check_valid_point(board, Point(0, 0)))
class GoPlayerBase: ## Decorators def valid_stone(func): def wrapper(*args, **kwargs): if not args[1] or not isinstance(args[1], StoneEnum): raise Exception("GPB: Invalid parameter, bad stone passed.") return func(*args, **kwargs) return wrapper def protocol_registered(func): def wrapper(*args, **kwargs): if not args[0].name: raise Exception( "GPB: Invalid protocol, player must be registered first.") return func(*args, **kwargs) return wrapper def protocol_stone_set(func): def wrapper(*args, **kwargs): if not args[0].stone_type: raise Exception( "GPB: Invalid protocol, stone must be received first.") return func(*args, **kwargs) return wrapper ## Constructor def __init__(self, name=None): """ This class implements a Go Player who chooses moves using a dumb strategy of the first valid minimum column, minimum row position on the board. """ self.name = name self.default_name = "default_player" #"no name" self.stone_type = None self.move_referee = MoveReferee() ## Public Methods def register(self): if not self.name: self.name = self.default_name return self.name @valid_stone @protocol_registered def receive_stone(self, stone_type): self.stone_type = stone_type @protocol_registered @protocol_stone_set def choose_move(self, boards): """ if not self.move_referee.valid_history(self.stone_type, boards): return "This history makes no sense!" for x, y in sorted(list(boards[0].get_points(None))): if self.move_referee.valid_move(self.stone_type, Point(x, y), boards, boards[0]): return (x, y) else: return PASS """ epsilon = 0.3 roll = random.random() if roll > epsilon: if not self.move_referee.valid_history(self.stone_type, boards): return "This history makes no sense!" for x, y in sorted(list(boards[0].get_points(None))): if self.move_referee.valid_move(self.stone_type, Point(x, y), boards, boards[0]): return (x, y) else: return PASS else: return PASS def game_over(self, end_tag): # Reset default player for next game if end_tag == [GAME_OVER]: self.stone_type = None self.move_referee = MoveReferee() return True else: return False
class GoGUIPlayer(): ## Decorators def valid_stone(func): def wrapper(*args, **kwargs): if not args[1] or not isinstance(args[1], StoneEnum): raise Exception("GPB: Invalid parameter, bad stone passed.") return func(*args, **kwargs) return wrapper def protocol_registered(func): def wrapper(*args, **kwargs): if not args[0].name: raise Exception( "GPB: Invalid protocol, player must be registered first.") return func(*args, **kwargs) return wrapper def protocol_stone_set(func): def wrapper(*args, **kwargs): if not args[0].stone_type: raise Exception( "GPB: Invalid protocol, stone must be received first.") return func(*args, **kwargs) return wrapper # Constructor def __init__(self, name=None): self.name = name self.default_name = "Player 1" self.stone_type = None self.color = "" self.move_referee = MoveReferee() self.click = None # Creates self.root window self.root = Tk() self.root.title("Go Game GUI") self.root.resizable(0, 0) self.root.geometry('1000x1000') self.e = Entry(self.root, text="ENTER YOUR NAME HERE", width=20, borderwidth=5, bg="yellow", fg="black") self.e.grid(row=0, column=0, columnspan=7) self.e1 = Entry(self.root, width=20, borderwidth=5, bg="yellow", fg="black") self.e1.grid(row=10, column=0, columnspan=7) self.button_register = Button(self.root, text="Register", command=self.myClick) self.button_move = Button(self.root, text="Make Move", command=self.myMove) self.pass_move = Button(self.root, text="Pass", command=self.Pass) self.button_register.grid(row=0, column=10, columnspan=1) self.button_move.grid(row=10, column=10, columnspan=1) self.pass_move.grid(row=9, column=10, columnspan=1) self.buttons = dict() for x in range(1, BOARD_DIM + 1): for y in range(1, BOARD_DIM + 1): button_num = "{}-{}".format(y, x) self.buttons["{}-{}".format(y, x)] = Button( self.root, text=" ", bg="goldenrod", padx=0.0, pady=20, command=lambda butt=button_num: self.button_click(butt)) self.buttons["{}-{}".format(y, x)].grid(row=x, column=y, columnspan=1) def myClick(self): self.name = self.e.get() hello = "Welcome to Go, " + self.name myLabel = Label(self.root, text=hello) myLabel.grid(row=0, column=0, columnspan=3) self.button_register.configure(state=DISABLED) def button_click(self, button_idx): if self.name: self.click = button_idx self.buttons[self.click].configure(bg=self.color) def myMove(self): if self.name: self.click = self.e1.get() def Pass(self): if self.name: self.click = "pass" def register(self): while not self.name: self.root.update() self.root.update_idletasks() return self.name def receive_stone(self, stone_type): self.stone_type = stone_type if stone_type == StoneEnum.BLACK: self.color = "black" else: self.color = "white" def choose_move(self, boards): if not self.move_referee.valid_history(self.stone_type, boards): return "This history makes no sense!" else: board = boards[0] for x in range(len(board)): for y in range(len(board[0])): if board[x][y].get_raw() == WHITE_STONE: self.buttons["{}-{}".format(x + 1, y + 1)].configure(bg="white") elif board[x][y].get_raw() == BLACK_STONE: self.buttons["{}-{}".format(x + 1, y + 1)].configure(bg="black") else: self.buttons["{}-{}".format( x + 1, y + 1)].configure(bg="goldenrod") while not self.click: self.root.update() self.root.update_idletasks() if self.click == "pass": self.click = None return PASS ret = str_to_point(self.click) #if not self.move_referee.valid_move(stone_type=self.stone_type, point=ret, boards=boards, current_board=board): # raise Exception("Invalid point.") self.click = None return (ret.x, ret.y)
def test_valid_start(self): board = self._get_empty_board() move_ref = MoveReferee() self.assertFalse(move_ref._valid_start([board], StoneEnum.WHITE)) self.assertFalse(move_ref._valid_start([board, board], StoneEnum.BLACK))
def __init__(self): self.name = None self.stone_type = None self.move_referee = MoveReferee()
class GoReferee: ## Validators def valid_stone(func): def wrapper(*args, **kwargs): if not args[1] or not isinstance(args[1], StoneEnum): raise Exception("GO REF: Invalid parameter, bad stone passed.") return func(*args, **kwargs) return wrapper ## Constructors def __init__(self, board_size=BOARD_DIM, board=None, player1=None, player2=None): """ This class implements a referee component for the go game. Internally it holds a Go board, board history, a rule checker, a score keeper, and then information on the two players and state of the game. """ self.board_size = board_size self.board_history = [get_board([[" "] * self.board_size for row in range(self.board_size)])] self.players = {StoneEnum.BLACK: player1, StoneEnum.WHITE: player2} self.current_player = StoneEnum.BLACK self.move_ref = MoveReferee() self.score_ref = ScoreReferee() self.game_over = False self.winner_declared = False self.winner = None self.broke_rules = None ## Public Methods def referee_game(self): # Play game after registration complete while not self.game_over: print(self.players[self.current_player].name + "'s turn:") p = self.players[self.current_player].choose_move(self.board_history) if p == PASS: print("{} ({}) makes move {}".format(self.players[self.current_player].name, make_stone(self.current_player).get_raw(), p)) self.execute_move(PASS) else: print("{} ({}) makes move {}".format(self.players[self.current_player].name, make_stone(self.current_player).get_raw(), get_raw(p))) self.execute_move(Point(p[0], p[1])) print(format_pretty_json(format_one_board(self.board_history[0]))) def execute_move(self, move): if (not self.game_over): old_history = deepcopy(self.board_history) if (move == PASS): add_board = old_history[0] self.update_history(add_board) # Check for both players consecutive passes if len(self.board_history) == 3: if self.board_history[0].equal(self.board_history[1]) and self.board_history[1].equal(self.board_history[2]): self.game_over = True elif isinstance(move, Point): if (self.move_ref.valid_move(self.current_player, move, self.board_history, self.board_history[0])): add_board = self.make_move(self.current_player, move) self.update_history(add_board) else: self.game_over = True self.broke_rules = self.current_player self.winner = get_other_type(self.current_player) else: raise Exception("GO REF: Not a valid move.") self.current_player = get_other_type(self.current_player) return old_history def make_move(self, stone, point): last_board = deepcopy(self.board_history)[0] new_board = last_board.place_and_update(stone, point) return new_board def update_history(self, board): old_history = deepcopy(self.board_history) if (len(old_history) == 1): new_history = [board, old_history[0]] self.board_history = new_history if ((len(old_history) == 2) or (len(old_history) == 3)): new_history = [board, old_history[0], old_history[1]] self.board_history = new_history def get_winners(self): if (self.winner != None): return [self.players[self.winner].name] else: final_score = self.score_ref.get_score(self.board_history[0]) black_score = final_score[StoneEnum.BLACK] white_score = final_score[StoneEnum.WHITE] if black_score > white_score: return [self.players[StoneEnum.BLACK].name] elif white_score > black_score: return [self.players[StoneEnum.WHITE].name] else: tied_game = [self.players[StoneEnum.BLACK].name, self.players[StoneEnum.WHITE].name] tied_game = sorted(tied_game) return tied_game
def __init__(self): super().__init__() self.move_ref = MoveReferee() self.randomness = 0.5
class GoReferee: ## Class Variables move_ref = MoveReferee() score_ref = ScoreReferee() ## Constructors def __init__(self, players): self.history = [empty_board()] self.players = players self.invalid_mover = None ## Public Methods def play_game(self): pass_count, turn = 0, 0 while pass_count < 2: curr = self.players[turn] try: move = curr.choose_move(self.history) except CloseConnectionException: self.invalid_mover = turn break if move == PASS: pass_count += 1 elif isinstance(move, Point): pass_count = 0 move_valid = self.move_ref.valid_move(curr.stone_type, move, self.history, self.history[0]) if not move_valid: self.invalid_mover = turn break else: self.invalid_mover = turn break self.play_move(move, turn) turn = self.next_turn(turn) self.try_end_game() return sorted(self.determine_winner()), self.invalid_mover def play_move(self, move, turn): new_board = deepcopy(self.history[0]) if move != PASS: new_board.place_and_update(self.players[turn].stone_type, move) self.history.insert(0, new_board) if len(self.history) == 4: self.history.pop() def determine_winner(self): if self.invalid_mover is not None: winner = self.next_turn(self.invalid_mover) return [self.players[winner].name] score_dict = self.score_ref.get_score(self.history[0]) player1_score = score_dict[self.players[0].stone_type] player2_score = score_dict[self.players[1].stone_type] if player1_score == player2_score: return [self.players[0].name, self.players[1].name] elif player1_score > player2_score: return [self.players[0].name] else: return [self.players[1].name] def next_turn(self, turn): return (turn + 1) % 2 def try_end_game(self): for p in self.players: try: p.end_game() except CloseConnectionException: pass