def test_castle(self): bot = AxolotlBot() bot.handle_game_start(chess.WHITE, chess.Board("8/8/8/b7/3Pp3/8/8/4K2R b K d3 0 1"), "") bot.handle_opponent_move_result(False, None) self.assertEqual(8, len(bot.hypotheses)) bot.handle_game_end(None, None, GameHistory()) bot.handle_game_start(chess.WHITE, chess.Board("8/8/8/b7/3Pp3/8/8/4K2R b K d3 0 1"), "") bot.handle_opponent_move_result(True, chess.D3) self.assertEqual(1, len(bot.hypotheses)) bot.handle_game_end(None, None, GameHistory()) bot.handle_game_start(chess.WHITE, chess.Board("8/8/8/b7/3Pp3/8/8/4K2R b K d3 0 1"), "") bot.handle_opponent_move_result(True, chess.E1) self.assertEqual(1, len(bot.hypotheses)) bot.handle_game_end(None, None, GameHistory()) bot.handle_game_start(chess.BLACK, chess.Board("8/8/8/b7/3Pp3/8/8/4K2R w K - 0 1"), "") bot.handle_opponent_move_result(False, None) self.assertEqual(17, len(bot.hypotheses)) bot.handle_game_end(None, None, GameHistory())
def test_blocked(self): bot = AxolotlBot() bot.handle_game_start(chess.WHITE, chess.Board("8/b7/8/8/3P4/8/5K2/R7 w - - 0 1"), "") bot.move = chess.Move.from_uci("a1a8") bot.handle_move_result(chess.Move.from_uci("a1a8"), chess.Move.from_uci("a1a7"), True, chess.A7) self.assertEqual(1, len(bot.hypotheses)) bot.handle_game_end(None, None, GameHistory()) bot.handle_game_start(chess.BLACK, chess.Board(), "") bot.hypotheses = { "8/b7/8/8/3P4/8/5K2/R7 b - - 0 1": 0.5, "8/b7/8/8/8/8/5K2/R7 b - - 0 1": 0.5 } bot.move = chess.Move.from_uci("a7f2") bot.handle_move_result(chess.Move.from_uci("a7f2"), chess.Move.from_uci("a7f2"), True, chess.F2) self.assertEqual(1, len(bot.hypotheses)) bot.handle_game_end(None, None, GameHistory()) bot.handle_game_start(chess.BLACK, chess.Board(), "") bot.hypotheses = { "8/b7/8/8/3P4/8/5K2/R7 b - - 0 1": 0.5, "8/b7/8/8/8/8/5K2/R7 b - - 0 1": 0.5 } bot.move = chess.Move.from_uci("a7f2") bot.handle_move_result(chess.Move.from_uci("a7f2"), chess.Move.from_uci("a7d4"), True, chess.D4) self.assertEqual(1, len(bot.hypotheses)) bot.handle_game_end(None, None, GameHistory())
def from_history(cls, history: GameHistory) -> "Replay": actions = [] for turn in history.turns(): sense = history.sense(turn) actions.append( "00" if sense is None else chess.SQUARE_NAMES[sense]) actions.append((history.requested_move(turn) or chess.Move.null()).uci()) actions = " ".join(actions) return Replay(actions)
def playback(game_history: GameHistory, player: Player, color: Color): game = LocalGame() player.handle_game_start(color, game.board.copy()) game.start() turn = game_history.first_turn() while not game.is_over() and turn < game_history.last_turn(): opt_capture_square = game.opponent_move_results() if game.turn == color: player.handle_opponent_move_result(opt_capture_square is not None, opt_capture_square) sense_actions = game.sense_actions() move_actions = game.move_actions() sense = game_history.sense(turn) player_sense = player.choose_sense(sense_actions, move_actions, game.get_seconds_left()) if game.turn == color and sense != player_sense: print( 'Warning: Sense action did not match history on turn {}. Using the sense action from history.' .format(turn)) sense_result = game.sense(sense) if game.turn == color: player.handle_sense_result(sense_result) move = game_history.requested_move(turn) player_move = player.choose_move(move_actions, game.get_seconds_left()) if game.turn == color and move != player_move: print( 'Warning: Move action did not match history on turn {}. Using the move action from history.' .format(turn)) requested_move, taken_move, opt_enemy_capture_square = game.move(move) if game.turn == color: player.handle_move_result(requested_move, taken_move, opt_enemy_capture_square is not None, opt_enemy_capture_square) game.end_turn() turn = turn.next game.end() winner_color = game.get_winner_color() win_reason = game.get_win_reason() game_history = game.get_game_history() player.handle_game_end(winner_color, win_reason, game_history)
def test_promotion(self): bot = AxolotlBot() bot.handle_game_start(chess.BLACK, chess.Board("8/3P4/8/8/8/8/1p4p1/8 w - - 0 1"), "") bot.handle_opponent_move_result(False, None) self.assertEqual(5, len(bot.hypotheses)) bot.handle_game_end(None, None, GameHistory()) bot.handle_game_start(chess.WHITE, chess.Board("8/3P4/8/8/8/8/1p4p1/8 b - - 0 1"), "") bot.handle_opponent_move_result(False, None) self.assertEqual(9, len(bot.hypotheses)) bot.handle_game_end(None, None, GameHistory())
def test_basic(self): bot = AxolotlBot() bot.handle_game_start(chess.WHITE, chess.Board(), "") bot.hypotheses = { chess.STARTING_BOARD_FEN: 0.5, "rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/1NBQKBNR w Kkq - 0 1": 0.5 } self.assertEqual(chess.B2, bot.choose_sense([], [], 10)) bot.handle_game_end(None, None, GameHistory())
def test_false(self): bot = AxolotlBot() bot.handle_game_start(chess.WHITE, chess.Board("8/b7/8/8/3P4/8/5K2/R7 w - - 0 1"), "") bot.move = chess.Move.from_uci("a1a7") bot.handle_move_result(chess.Move.from_uci("a1a7"), chess.Move.from_uci("a1a7"), False, None) self.assertEqual(0, len(bot.hypotheses)) bot.handle_game_end(None, None, GameHistory()) bot.handle_game_start(chess.WHITE, chess.Board("8/b7/8/8/3P4/8/5K2/R7 w - - 0 1"), "") bot.move = chess.Move.from_uci("a1a7") bot.handle_move_result(chess.Move.from_uci("a1a7"), chess.Move.from_uci("a1a6"), False, None) self.assertEqual(0, len(bot.hypotheses)) bot.handle_game_end(None, None, GameHistory())
def main(): parser = argparse.ArgumentParser( description='Allows you to watch a saved match.') parser.add_argument('history_path', help='Path to saved Game History file.') args = parser.parse_args() window = ReplayWindow(GameHistory.from_file(args.history_path)) while True: window.update() window.draw()
def test_one_turn(self): board = chess.Board() bot = AxolotlBot() bot.handle_game_start(chess.BLACK, chess.Board(), "") board.push(chess.Move.from_uci("e2e4")) self.assertEqual(1, len(bot.hypotheses)) bot.handle_opponent_move_result(False, None) self.assertEqual(21, len(bot.hypotheses)) moves = list(board.pseudo_legal_moves) for i in range(7): moves.append( chess.Move.from_uci("abcdefgh"[i] + "7" + "abcdefgh"[i + 1] + "6")) for i in range(1, 8): moves.append( chess.Move.from_uci("abcdefgh"[i] + "7" + "abcdefgh"[i - 1] + "6")) sense = bot.choose_sense(chess.BB_SQUARES, moves, 10) # code for sense from reconchess.LocalGame rank, file = chess.square_rank(sense), chess.square_file(sense) sense_result = [] for delta_rank in [1, 0, -1]: for delta_file in [-1, 0, 1]: if 0 <= rank + delta_rank <= 7 and 0 <= file + delta_file <= 7: sense_square = chess.square(file + delta_file, rank + delta_rank) sense_result.append( (sense_square, board.piece_at(sense_square))) bot.handle_sense_result(sense_result) self.assertLess(1, len(bot.hypotheses)) move = bot.choose_move(moves, 10) if move in board.pseudo_legal_moves: bot.handle_move_result(move, move, False, None) else: bot.handle_move_result(move, None, False, None) self.assertLess(1, len(bot.hypotheses)) bot.handle_game_end(None, None, GameHistory())
def test_basic(self): bot = AxolotlBot() bot.handle_game_start(chess.WHITE, chess.Board(), "") moves = list(chess.Board().pseudo_legal_moves) for i in range(7): moves.append( chess.Move.from_uci("abcdefgh"[i] + "2" + "abcdefgh"[i + 1] + "3")) for i in range(1, 8): moves.append( chess.Move.from_uci("abcdefgh"[i] + "2" + "abcdefgh"[i - 1] + "3")) self.assertNotEqual(chess.Move.null(), bot.choose_move(moves, 1.0)) bot.handle_game_end(None, None, GameHistory())
def test_basic_2(self): bot = AxolotlBot() bot.handle_game_start(chess.WHITE, chess.Board("7k/b7/8/8/3P4/8/5K2/R7 w - - 0 1"), "") moves = list( chess.Board("7k/b7/8/8/3P4/8/5K2/R7 w - - 0 1").pseudo_legal_moves) moves.append(chess.Move.from_uci("d4c5")) moves.append(chess.Move.from_uci("d4e5")) self.assertIn( bot.choose_move(moves, 1.0), [chess.Move.from_uci("a1a7"), chess.Move.from_uci("a1h1")]) bot.handle_game_end(None, None, GameHistory())
def test_nonstandard(self): bot = AxolotlBot() bot.handle_game_start( chess.WHITE, chess.Board( "r1bqkb1r/ppp1pp1p/8/8/8/8/PPPPPPPP/RNBQKBNR b KQkq - 0 1"), "") bot.handle_opponent_move_result(False, None) self.assertEqual(28, len(bot.hypotheses)) bot.handle_game_end(None, None, GameHistory()) bot.handle_game_start( chess.WHITE, chess.Board( "r1bqkb1r/ppp1pp1p/8/8/8/8/PPPPPPPP/RNBQKBNR b KQkq - 0 1"), "") bot.handle_opponent_move_result(True, chess.D2) self.assertEqual(1, len(bot.hypotheses)) bot.handle_game_end(None, None, GameHistory()) bot.handle_game_start( chess.BLACK, chess.Board( "rnbqkbnr/pppppppp/8/8/8/8/P1P1PPPP/R1BQKB1R w KQkq - 0 1"), "") bot.handle_opponent_move_result(False, None) self.assertEqual(28, len(bot.hypotheses)) bot.handle_game_end(None, None, GameHistory()) bot.handle_game_start( chess.BLACK, chess.Board( "rnbqkbnr/pppppppp/8/8/8/8/P1P1PPPP/R1BQKB1R w KQkq - 0 1"), "") bot.handle_opponent_move_result(True, chess.D7) self.assertEqual(1, len(bot.hypotheses)) bot.handle_game_end(None, None, GameHistory())
def main(): parser = argparse.ArgumentParser( formatter_class=argparse.ArgumentDefaultsHelpFormatter) parser.add_argument('game_history_path', help='Path to game history JSON file.') parser.add_argument('bot_path', help='The path to bot source file or module.') parser.add_argument('color', default='random', choices=['white', 'black'], help='The color of the player to playback.') args = parser.parse_args() game_history = GameHistory.from_file(args.game_history_path) white_bot_name, white_player_cls = load_player(args.bot_path) color = chess.WHITE if args.color == 'white' else chess.BLACK playback(game_history, white_player_cls(), color)
def test_false(self): bot = AxolotlBot() bot.handle_game_start(chess.WHITE, chess.Board(), "") bot.hypotheses = { chess.STARTING_BOARD_FEN: 0.5, "rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/1NBQKBNR w Kkq - 0 1": 0.5 } bot.sense = chess.B2 bot.handle_sense_result([ (chess.A1, chess.Piece(chess.ROOK, chess.WHITE)), (chess.B1, chess.Piece(chess.KNIGHT, chess.WHITE)), (chess.C1, chess.Piece(chess.BISHOP, chess.WHITE)), (chess.A2, chess.Piece(chess.PAWN, chess.WHITE)), (chess.B2, chess.Piece(chess.PAWN, chess.WHITE)), (chess.C2, chess.Piece(chess.PAWN, chess.WHITE)), (chess.A3, None), (chess.B3, None), (chess.C3, chess.Piece(chess.PAWN, chess.WHITE)) ]) self.assertEqual(0, len(bot.hypotheses)) bot.handle_game_end(None, None, GameHistory())
def __init__(self, history: GameHistory): self.actions = [] for turn in history.turns(): if history.has_sense(turn): self.actions.append({ 'phase': 'sense', 'turn_number': turn.turn_number, 'turn_color': turn.color, 'sense': history.sense(turn), 'sense_result': history.sense_result(turn), 'fen': history.truth_fen_before_move(turn), }) if history.has_move(turn): self.actions.append({ 'phase': 'move', 'turn_number': turn.turn_number, 'turn_color': turn.color, 'requested_move': history.requested_move(turn), 'taken_move': history.taken_move(turn), 'capture_square': history.capture_square(turn), 'fen': history.truth_fen_after_move(turn), }) self.board = chess.Board() self.action_index = None self.fps = 30 self.square_size = 80 self.width = self.square_size * 8 self.height = self.square_size * 9 self.image_by_piece = {} for color in chess.COLORS: for piece_type in chess.PIECE_TYPES: piece = chess.Piece(piece_type, color) img_path = 'res/{}/{}.png'.format(chess.COLOR_NAMES[color], piece.symbol()) full_path = pkg_resources.resource_filename('reconchess', img_path) img = pygame.image.load(full_path) img = pygame.transform.scale(img, (self.square_size, self.square_size)) self.image_by_piece[piece] = img pygame.init() pygame.display.set_caption('Recon Chess') pygame.display.set_icon( pygame.transform.scale(self.image_by_piece[chess.Piece(chess.KING, chess.WHITE)], (32, 32))) self.clock = pygame.time.Clock() self.screen = pygame.display.set_mode((self.width, self.height)) self.background = pygame.Surface((self.screen.get_size())) self.perspective = chess.WHITE self.font = pygame.font.SysFont(pygame.font.get_default_font(), 30) self.buttons = [] x, y = self.text_coords_below(chess.C1) self.buttons.append(Button(x, y, self.square_size / 2, self.square_size / 4, self.font, '<<', onclick=self.go_to_beginning)) x, y = self.text_coords_below(chess.D1) self.buttons.append(Button(x, y, self.square_size / 2, self.square_size / 4, self.font, '<', onclick=self.go_backwards)) x, y = self.text_coords_below(chess.E1) self.buttons.append(Button(x, y, self.square_size / 2, self.square_size / 4, self.font, '>', onclick=self.go_forwards)) x, y = self.text_coords_below(chess.F1) self.buttons.append(Button(x, y, self.square_size / 2, self.square_size / 4, self.font, '>>', onclick=self.go_to_end)) self.go_to_beginning()
text = 'Turn: {} / {}'.format(turn, self.actions[-1]['turn_number'] + 1) text_width, text_height = self.font.size(text) x, y = self.text_coords_below(chess.A1, vertical_offset=0.33) x, y = (x, y - text_height / 2 + .33) self.background.blit(self.font.render(text, True, (0, 0, 0)), (x, y)) text = 'Player: {}'.format(player) text_width, text_height = self.font.size(text) x, y = self.text_coords_below(chess.A1, vertical_offset=0.66) x, y = (x, y - text_height / 2 + .33) self.background.blit(self.font.render(text, True, (0, 0, 0)), (x, y)) def turn_color(self): return (255, 255, 255) if self.actions[self.action_index]['turn_color'] else (0, 0, 0) def draw_highlight(self, square, color=(255, 255, 0)): pygame.draw.rect(self.background, color, self.square_rect(square), 3) if __name__ == '__main__': parser = argparse.ArgumentParser(description='Allows you to watch a saved match.') parser.add_argument('history_path', help='Path to saved Game History file.') args = parser.parse_args() window = ReplayWindow(GameHistory.from_file(args.history_path)) while True: window.update() window.draw()
def test_standard_board(self): bot = AxolotlBot() bot.handle_game_start(chess.WHITE, chess.Board(), "") self.assertEqual(1, len(bot.hypotheses)) bot.handle_game_end(None, None, GameHistory())
def test_false(self): bot = AxolotlBot() bot.handle_game_start(chess.BLACK, chess.Board(), "") bot.handle_opponent_move_result(True, chess.A7) self.assertEqual(0, len(bot.hypotheses)) bot.handle_game_end(None, None, GameHistory())