class ScorebookGame(object):
    def __init__(self, white='', black='', event='', date='', moves='', round='1', id=None):
        # things that is stored
        self.id = int(id) if id else None
        self.white = white
        self.black = black
        self.event = event
        self.date = date
        self.round = round
        self.moves = moves # string

        # the rest
        self.moves_list = ScorebookGame.convert_moves(moves)
        self.game = Game()

        self.update()

    @property
    def move_count(self):
        return len(self.moves_list)

    @property
    def json_dict(self):
        all = self.__dict__
        to_store = ['white', 'black', 'event', 'date', 'moves', 'round', 'id']
        jd = {}
        for what in to_store:
            jd[what] = all[what]
        return jd

    @staticmethod
    def convert_moves(moves_string):
        return moves_string.split(' ') if moves_string else []

    @staticmethod
    def get_unique_id():
        store = JsonStore('games.json')
        ids = []
        for key in store:
            ids.append(int(key))
        if ids:
            return max(ids)+1
        else:
            return 1

    def update(self):
        print self.moves_list
        for move in self.moves_list:
            if move:
                self.game.apply_move(move)

    def save(self):
        # TODO: Would be a good idea to store in .pgn format. Hmm, maybe later. Plus, it requires Algebraic Notation converter.
        if not self.id:
            self.id = ScorebookGame.get_unique_id()
        store = JsonStore('games.json')
        store[str(self.id)] = self.json_dict
Example #2
0
    def __init__(self, **kwargs):
        super(MenuLayout, self).__init__(**kwargs)
        self.orientation = 'vertical' if self.height > self.width else 'horizontal'

        size = self.width if self.orientation == 'vertical' else self.height
        options = ['p', 'r', 'n', 'b', 'q', 'P', 'R', 'N', 'B', 'Q']
        action_chessman = choice(options)
        self.menu = ChessMenu(game=Game(),
                              action_chessman=action_chessman,
                              size_hint=(None, None),
                              width=size,
                              height=size)

        menu_title = BoxLayout(orientation="vertical", padding=dp(10))
        t = AppTitleLabel()
        f = ActionFigureLabel(action_chessman=action_chessman)
        i = AppMenuInst()
        menu_title.add_widget(t)
        menu_title.add_widget(f)
        menu_title.add_widget(i)

        self.add_widget(menu_title)
        self.add_widget(self.menu)

        self.bind(on_size=self.on_size)
Example #3
0
    def __init__(self, **kwargs):
        super(GameRecorder, self).__init__(**kwargs)
        self.orientation = 'vertical' if self.height > self.width else 'horizontal'
        self.bind(size=self.on_size, orientation=self.on_orientation)

        self.game = Game()
        side_box = BoxLayout(orientation='vertical')
        b = BoxLayout(size_hint_y=None, height=dp(50))
        back_button = CustomButton(text='<< Games')
        undo_button = CustomButton(text='Reset')
        undo_button.bind(on_release=self.reset)
        back_button.bind(on_release=self.go_back)
        b.add_widget(back_button)
        b.add_widget(undo_button)

        save_button = CustomButton(text='Save game', size_hint_y=None, height=dp(50))
        save_button.bind(on_release=self.save_popup)
        side_box.add_widget(b)
        side_box.add_widget(save_button)


        moves_scroll = ScrollView()
        self.moves_table=MovesGrid(padding=dp(10), spacing=dp(10))
        for move in self.game.move_history:
            self.moves_table.add_widget(MoveButton(text=move))

        side = self.height if self.orientation == 'horizontal' else self.width
        self.board = ChessboardUI(game=self.game, size_hint=(None,None), height=side, width=side)
        self.board.bind(move_made=self.change_moves)

        self.add_widget(self.board)
        moves_scroll.add_widget(self.moves_table)
        side_box.add_widget(moves_scroll)
        self.add_widget(side_box)
Example #4
0
    def test_status(self):

        # NORMAL
        game = Game()
        self.assertEqual(game.status, Game.NORMAL)

        # CHECK
        game = Game(fen='r3rk2/8/8/8/8/8/8/R3K2R w KQ - 0 1')
        self.assertEqual(game.status, game.CHECK)

        # CHECKMATE
        game = Game(fen='8/p5kp/1p6/2p5/P5P1/2n4P/r2p4/1K6 w - - 2 37')
        self.assertEqual(game.status, Game.CHECKMATE)

        # STALEMATE
        game = Game(fen='8/8/8/8/8/7k/5q2/7K w - - 0 37')
        self.assertEqual(game.status, Game.STALEMATE)
    def change_game(self, all_moves):
        # reset game
        # if self.game:
        #     self.game.reset()
        # else:
        self.game = Game()

        # apply move history
        for move in all_moves:
            self.game.apply_move(move)
        # print self.game.move_history
        # print self.game.board
        # populate new position
        board = self.game.board._position
        for n, cell in enumerate(self.children):
            cell.clear_widgets()
            i = 63 - n
            if board[i] != ' ':
                man = Chessman(symbol=board[i])
                cell.add_widget(man)
Example #6
0
    def test_san_to_long(self):
        self.game.reset()  # reset board to starting position
        game = [
            'e4', 'e5', 'Nf3', 'd6', 'd4', 'Bg4', 'dxe5', 'Bxf3', 'Qxf3',
            'dxe5', 'Bc4', 'Nf6', 'Qb3', 'Qe7', 'Nc3', 'c6', 'Bg5', 'b5',
            'Nxb5', 'cxb5', 'Bxb5', 'Nbd7', '0-0-0', 'Rd8', 'Rxd7', 'Rxd7',
            'Rd1', 'Qe6', 'Bxd7', 'Nxd7', 'Qb8+', 'Nxb8', 'Rd8++'
        ]
        for move in game:
            self.game.apply_san_move(move)
        self.assertEqual(
            self.game.get_fen(),
            '1n1Rkb1r/p4ppp/4q3/4p1B1/4P3/8/PPP2PPP/2K5 b k - 1 17')

        self.game = Game(fen='8/P7/1K6/8/k7/8/8/8 w - - 0 40')
        self.game.apply_san_move('a8=Q')
        self.assertEqual(self.game.get_fen(), 'Q7/8/1K6/8/k7/8/8/8 b - - 0 40')

        self.game = Game(fen='8/8/1K6/8/k7/8/p7/8 b - - 0 40')
        self.game.apply_san_move('a1=Q')
        self.assertEqual(self.game.get_fen(), '8/8/1K6/8/k7/8/8/q7 w - - 0 41')
    def test_get_moves(self):
        # legal openings
        self.game.reset()
        self.assertEqual(sorted(self.game.get_moves()), LEGAL_OPENINGS)

        # en passant
        fen = 'rnbqkbnr/ppp2ppp/4p3/3pP3/8/8/PPPP1PPP/RNBQKBNR w KQkq d6 0 1'
        self.game = Game(fen=fen)
        self.assertEqual(self.game.get_moves(idx_list=[28]), ['e5d6'])

        # checkmate
        fen = '8/p5kp/1p6/2p5/P5P1/2n4P/r2p4/1K6 w - - 2 37'
        self.game = Game(fen=fen)
        self.assertEqual(self.game.get_moves(), [])

        # castling into occupied space & king moving into check
        fen = '8/2p5/5p2/7r/7P/3R1P2/P3R1P1/2k1K3 b - - 13 46'
        self.game = Game(fen=fen)
        self.assertIn('c7c6', self.game.get_moves())
        fen = '8/8/2p2p2/7r/7P/3R1P2/P3R1P1/2k1K3 w - - 0 47'
        self.game = Game(fen=fen, validate=False)
        self.assertNotIn('e1c1', self.game.get_moves())

        # castling through check
        fen = 'r3k2r/8/8/8/8/8/8/3RKR2 b kq - 0 1'
        self.game = Game(fen=fen)
        self.assertNotIn('e8c8', self.game.get_moves(idx_list=[4]))
        self.assertNotIn('e8g8', self.game.get_moves(idx_list=[4]))

        # castling out of check
        fen = 'r3rk2/8/8/8/8/8/8/R3K2R w KQ - 0 1'
        self.game = Game(fen=fen)
        self.assertNotIn('e1c8', self.game.get_moves(idx_list=[60]))
    def __init__(self, white='', black='', event='', date='', moves='', round='1', id=None):
        # things that is stored
        self.id = int(id) if id else None
        self.white = white
        self.black = black
        self.event = event
        self.date = date
        self.round = round
        self.moves = moves # string

        # the rest
        self.moves_list = ScorebookGame.convert_moves(moves)
        self.game = Game()

        self.update()
    def change_game(self, all_moves):
        # reset game
        # if self.game:
        #     self.game.reset()
        # else:
        self.game = Game()

        # apply move history
        for move in all_moves:
            self.game.apply_move(move)
        # print self.game.move_history
        # print self.game.board
        # populate new position
        board = self.game.board._position
        for n, cell in enumerate(self.children):
            cell.clear_widgets()
            i = 63 - n
            if board[i] != ' ':
                man = Chessman(symbol=board[i])
                cell.add_widget(man)
class GameTest(unittest.TestCase):

    def setUp(self):
        self.game = Game()

    def test_i2xy(self):
        for idx in xrange(64):
            self.assertIn(Game.i2xy(idx), ALG_POS)

    def test_xy2i(self):
        for pos in ALG_POS:
            self.assertIn(Game.xy2i(pos), IDX_POS)

    def test_str(self):
        self.game.reset()  # reset board to starting position
        self.assertEqual(str(self.game), START_POS)

    def test_fen_history(self):
        self.game.reset()
        self.assertEqual(self.game.fen_history, [START_POS])
        self.game.apply_move('e2e4')
        hist = [START_POS,
                'rnbqkbnr/pppppppp/8/8/4P3/8/PPPP1PPP/RNBQKBNR b KQkq e3 0 1']
        self.assertEqual(self.game.fen_history, hist)

    def test_move_history(self):
        self.game = None
        self.game = Game()
        self.assertEqual(self.game.move_history, [])
        self.game.apply_move('e2e4')
        self.assertEqual(self.game.move_history, ['e2e4'])

    def test_get_moves(self):
        # legal openings
        self.game.reset()
        self.assertEqual(sorted(self.game.get_moves()), LEGAL_OPENINGS)

        # en passant
        fen = 'rnbqkbnr/ppp2ppp/4p3/3pP3/8/8/PPPP1PPP/RNBQKBNR w KQkq d6 0 1'
        self.game = Game(fen=fen)
        self.assertEqual(self.game.get_moves(idx_list=[28]), ['e5d6'])

        # checkmate
        fen = '8/p5kp/1p6/2p5/P5P1/2n4P/r2p4/1K6 w - - 2 37'
        self.game = Game(fen=fen)
        self.assertEqual(self.game.get_moves(), [])

        # castling into occupied space & king moving into check
        fen = '8/2p5/5p2/7r/7P/3R1P2/P3R1P1/2k1K3 b - - 13 46'
        self.game = Game(fen=fen)
        self.assertIn('c7c6', self.game.get_moves())
        fen = '8/8/2p2p2/7r/7P/3R1P2/P3R1P1/2k1K3 w - - 0 47'
        self.game = Game(fen=fen, validate=False)
        self.assertNotIn('e1c1', self.game.get_moves())

        # castling through check
        fen = 'r3k2r/8/8/8/8/8/8/3RKR2 b kq - 0 1'
        self.game = Game(fen=fen)
        self.assertNotIn('e8c8', self.game.get_moves(idx_list=[4]))
        self.assertNotIn('e8g8', self.game.get_moves(idx_list=[4]))

        # castling out of check
        fen = 'r3rk2/8/8/8/8/8/8/R3K2R w KQ - 0 1'
        self.game = Game(fen=fen)
        self.assertNotIn('e1c8', self.game.get_moves(idx_list=[60]))

    def test_apply_move(self):
        # pawn promotion
        fen = '3qk1b1/P7/8/8/8/8/7P/4K3 w - - 0 1'
        self.game = Game(fen=fen)
        self.game.apply_move('a7a8q')
        self.assertEqual(str(self.game), 'Q2qk1b1/8/8/8/8/8/7P/4K3 b - - 0 1')

        # apply moves
        self.game.apply_move('g8h7')
        self.assertEqual(str(self.game), 'Q2qk3/7b/8/8/8/8/7P/4K3 w - - 1 2')
        self.game.apply_move('h2h4')
        self.assertEqual(str(self.game), 'Q2qk3/7b/8/8/7P/8/8/4K3 b - h3 0 2')

        # block vector tail with capture
        moves = ['d8c8', 'd8b8', 'd8a8', 'e8f8', 'e8d7', 'e8e7', 'e8f7',
                 'g8f7', 'g8e6', 'g8d5', 'g8c4', 'g8b3', 'g8a2', 'g8h7']
        self.game.reset(fen='Q2qk1b1/8/8/8/8/8/7P/4K3 b - - 0 1')
        self.assertEqual(self.game.get_moves(), moves)
        self.game.apply_move('d8b8')
        moves = set(self.game.get_moves())
        self.assertIn('a8b8', moves)
        self.assertNotIn('a8c8', moves)

        # white castling
        fen = 'r3k2r/pppqbppp/3pb3/8/8/3PB3/PPPQBPPP/R3K2R w KQkq - 0 7'
        new_fen = 'r3k2r/pppqbppp/3pb3/8/8/3PB3/PPPQBPPP/R4RK1 b kq - 1 7'
        self.game = Game(fen=fen)
        self.game.apply_move('e1g1')
        self.assertEqual(str(self.game), new_fen)
        new_fen = 'r3k2r/pppqbppp/3pb3/8/8/3PB3/PPPQBPPP/2KR3R b kq - 1 7'
        self.game = Game(fen=fen)
        self.game.apply_move('e1c1')
        self.assertEqual(str(self.game), new_fen)

        # black castling
        fen = 'r3k2r/pppqbppp/3pb3/8/8/3PB3/PPPQBPPP/R3K2R b KQkq - 0 7'
        new_fen = 'r4rk1/pppqbppp/3pb3/8/8/3PB3/PPPQBPPP/R3K2R w KQ - 1 8'
        self.game = Game(fen=fen)
        self.game.apply_move('e8g8')
        self.assertEqual(str(self.game), new_fen)
        new_fen = '2kr3r/pppqbppp/3pb3/8/8/3PB3/PPPQBPPP/R3K2R w KQ - 1 8'
        self.game = Game(fen=fen)
        self.game.apply_move('e8c8')
        self.assertEqual(str(self.game), new_fen)

        # Disable castling on capture
        fen = '1r2k2r/3nb1Qp/p1pp4/3p4/3P4/P1N2P2/1PP3PP/R1B3K1 w k - 0 22'
        new_fen = '1r2k2Q/3nb2p/p1pp4/3p4/3P4/P1N2P2/1PP3PP/R1B3K1 b - - 0 22'
        self.game = Game(fen=fen)
        self.game.apply_move('g7h8')
        self.assertEqual(str(self.game), new_fen)

        # white en passant
        fen = 'rnbqkbnr/ppp2ppp/4p3/3pP3/8/8/PPPP1PPP/RNBQKBNR w KQkq d6 0 1'
        self.game = Game(fen=fen)
        self.game.apply_move('e5d6')
        new_fen = 'rnbqkbnr/ppp2ppp/3Pp3/8/8/8/PPPP1PPP/RNBQKBNR b KQkq - 0 1'
        self.assertEqual(str(self.game), new_fen)

        # black en passant
        fen = 'rnbqkbnr/ppp1pppp/8/8/3pP3/8/PPPP1PPP/RNBQKBNR b KQkq e3 0 1'
        self.game = Game(fen=fen)
        self.game.apply_move('d4e3')
        new_fen = 'rnbqkbnr/ppp1pppp/8/8/8/4p3/PPPP1PPP/RNBQKBNR w KQkq - 0 2'
        self.assertEqual(str(self.game), new_fen)

        # capture
        fen = 'r2q1rk1/pppbbppp/2n5/3p4/3PN3/4PN2/1PPBBPPP/R2Q1RK1 b - - 0 9'
        self.game = Game(fen=fen)
        self.game.apply_move('d5e4')
        n_fen = 'r2q1rk1/pppbbppp/2n5/8/3Pp3/4PN2/1PPBBPPP/R2Q1RK1 w - - 0 10'
        self.assertEqual(str(self.game), n_fen)

        # invalid move
        self.game.reset()
        with self.assertRaises(InvalidMove):
            self.game.apply_move('e2e2')
class Chessboard(GridLayout):
    '''
    Actual chessboard with moving pieces
    '''
    # all_moves = ListProperty()
    game = ObjectProperty()
    move_made = BooleanProperty(False)
    # for menu!
    go_to = StringProperty('')

    def __init__(self, **kwargs):
        super(Chessboard, self).__init__(**kwargs)
        self.game = kwargs.get('game', None)
        if self.game:
            board = self.game.board._position
            for row in ('8', '7', '6', '5', '4', '3', '2', '1'):
                for col in ('a', 'b', 'c', 'd', 'e', 'f', 'g', 'h'):
                    cell = BoardCell(name=col + row)
                    self.add_widget(cell)
            for n, cell in enumerate(self.children):
                i = 63 - n
                if board[i] != ' ':
                    man = Chessman(symbol=board[i])
                    cell.add_widget(man)

        self.grabbed = None

        # when move history changes
        # self.bind(all_moves=self.change_game)

    def change_game(self, all_moves):
        # reset game
        # if self.game:
        #     self.game.reset()
        # else:
        self.game = Game()

        # apply move history
        for move in all_moves:
            self.game.apply_move(move)
        # print self.game.move_history
        # print self.game.board
        # populate new position
        board = self.game.board._position
        for n, cell in enumerate(self.children):
            cell.clear_widgets()
            i = 63 - n
            if board[i] != ' ':
                man = Chessman(symbol=board[i])
                cell.add_widget(man)

    def update(self):
        board = self.game.board._position
        for n, cell in enumerate(self.children):
            cell.clear_widgets()
            i = 63 - n
            if board[i] != ' ':
                man = Chessman(symbol=board[i])
                cell.add_widget(man)

    def on_touch_down(self, touch):
        for cell in self.children:
            if cell.collide_point(*touch.pos):
                if cell.children:
                    self.move_start = cell.name
                    # print self.move_start
                    self.grabbed = cell.children[0]
                    # print self.grabbed.parent
                    touch.grab(self.grabbed)

    def on_touch_move(self, touch):
        if self.grabbed:
            self.grabbed.pos = [
                touch.x - self.grabbed.size[0] / 2,
                touch.y - self.grabbed.size[1] / 2
            ]

    def on_touch_up(self, touch):
        for cell in self.children:
            if cell.collide_point(*touch.pos) and self.grabbed:
                self.destination = cell.name
                try:
                    self.game.apply_move(self.move_start + self.destination)
                    print "Is Legal"
                    self.grabbed.parent.clear_widgets()
                    cell.clear_widgets()
                    cell.add_widget(self.grabbed)
                    # self.grabbed.pos = cell.pos
                    self.move_made = False if self.move_made else True
                    self.update()
                except InvalidMove:
                    print 'Not Legal Move'
                    self.grabbed.pos = self.grabbed.parent.pos

        if self.grabbed:
            touch.ungrab(self.grabbed)
            self.grabbed = None
    def test_apply_move(self):
        # pawn promotion
        fen = '3qk1b1/P7/8/8/8/8/7P/4K3 w - - 0 1'
        self.game = Game(fen=fen)
        self.game.apply_move('a7a8q')
        self.assertEqual(str(self.game), 'Q2qk1b1/8/8/8/8/8/7P/4K3 b - - 0 1')

        # apply moves
        self.game.apply_move('g8h7')
        self.assertEqual(str(self.game), 'Q2qk3/7b/8/8/8/8/7P/4K3 w - - 1 2')
        self.game.apply_move('h2h4')
        self.assertEqual(str(self.game), 'Q2qk3/7b/8/8/7P/8/8/4K3 b - h3 0 2')

        # block vector tail with capture
        moves = ['d8c8', 'd8b8', 'd8a8', 'e8f8', 'e8d7', 'e8e7', 'e8f7',
                 'g8f7', 'g8e6', 'g8d5', 'g8c4', 'g8b3', 'g8a2', 'g8h7']
        self.game.reset(fen='Q2qk1b1/8/8/8/8/8/7P/4K3 b - - 0 1')
        self.assertEqual(self.game.get_moves(), moves)
        self.game.apply_move('d8b8')
        moves = set(self.game.get_moves())
        self.assertIn('a8b8', moves)
        self.assertNotIn('a8c8', moves)

        # white castling
        fen = 'r3k2r/pppqbppp/3pb3/8/8/3PB3/PPPQBPPP/R3K2R w KQkq - 0 7'
        new_fen = 'r3k2r/pppqbppp/3pb3/8/8/3PB3/PPPQBPPP/R4RK1 b kq - 1 7'
        self.game = Game(fen=fen)
        self.game.apply_move('e1g1')
        self.assertEqual(str(self.game), new_fen)
        new_fen = 'r3k2r/pppqbppp/3pb3/8/8/3PB3/PPPQBPPP/2KR3R b kq - 1 7'
        self.game = Game(fen=fen)
        self.game.apply_move('e1c1')
        self.assertEqual(str(self.game), new_fen)

        # black castling
        fen = 'r3k2r/pppqbppp/3pb3/8/8/3PB3/PPPQBPPP/R3K2R b KQkq - 0 7'
        new_fen = 'r4rk1/pppqbppp/3pb3/8/8/3PB3/PPPQBPPP/R3K2R w KQ - 1 8'
        self.game = Game(fen=fen)
        self.game.apply_move('e8g8')
        self.assertEqual(str(self.game), new_fen)
        new_fen = '2kr3r/pppqbppp/3pb3/8/8/3PB3/PPPQBPPP/R3K2R w KQ - 1 8'
        self.game = Game(fen=fen)
        self.game.apply_move('e8c8')
        self.assertEqual(str(self.game), new_fen)

        # Disable castling on capture
        fen = '1r2k2r/3nb1Qp/p1pp4/3p4/3P4/P1N2P2/1PP3PP/R1B3K1 w k - 0 22'
        new_fen = '1r2k2Q/3nb2p/p1pp4/3p4/3P4/P1N2P2/1PP3PP/R1B3K1 b - - 0 22'
        self.game = Game(fen=fen)
        self.game.apply_move('g7h8')
        self.assertEqual(str(self.game), new_fen)

        # white en passant
        fen = 'rnbqkbnr/ppp2ppp/4p3/3pP3/8/8/PPPP1PPP/RNBQKBNR w KQkq d6 0 1'
        self.game = Game(fen=fen)
        self.game.apply_move('e5d6')
        new_fen = 'rnbqkbnr/ppp2ppp/3Pp3/8/8/8/PPPP1PPP/RNBQKBNR b KQkq - 0 1'
        self.assertEqual(str(self.game), new_fen)

        # black en passant
        fen = 'rnbqkbnr/ppp1pppp/8/8/3pP3/8/PPPP1PPP/RNBQKBNR b KQkq e3 0 1'
        self.game = Game(fen=fen)
        self.game.apply_move('d4e3')
        new_fen = 'rnbqkbnr/ppp1pppp/8/8/8/4p3/PPPP1PPP/RNBQKBNR w KQkq - 0 2'
        self.assertEqual(str(self.game), new_fen)

        # capture
        fen = 'r2q1rk1/pppbbppp/2n5/3p4/3PN3/4PN2/1PPBBPPP/R2Q1RK1 b - - 0 9'
        self.game = Game(fen=fen)
        self.game.apply_move('d5e4')
        n_fen = 'r2q1rk1/pppbbppp/2n5/8/3Pp3/4PN2/1PPBBPPP/R2Q1RK1 w - - 0 10'
        self.assertEqual(str(self.game), n_fen)

        # invalid move
        self.game.reset()
        with self.assertRaises(InvalidMove):
            self.game.apply_move('e2e2')
Example #13
0
    def test_apply_move(self):
        # pawn promotion
        fen = '3qk1b1/P7/8/8/8/8/7P/4K3 w - - 0 1'
        self.game = Game(fen=fen)
        self.game.apply_move('a7a8q')
        self.assertEqual(str(self.game), 'Q2qk1b1/8/8/8/8/8/7P/4K3 b - - 0 1')

        # apply moves
        self.game.apply_move('g8h7')
        self.assertEqual(str(self.game), 'Q2qk3/7b/8/8/8/8/7P/4K3 w - - 1 2')
        self.game.apply_move('h2h4')
        self.assertEqual(str(self.game), 'Q2qk3/7b/8/8/7P/8/8/4K3 b - h3 0 2')

        # block vector tail with capture
        moves = [
            'd8c8', 'd8b8', 'd8a8', 'e8f8', 'e8d7', 'e8e7', 'e8f7', 'g8f7',
            'g8e6', 'g8d5', 'g8c4', 'g8b3', 'g8a2', 'g8h7'
        ]
        self.game.reset(fen='Q2qk1b1/8/8/8/8/8/7P/4K3 b - - 0 1')
        self.assertEqual(self.game.get_moves(), moves)
        self.game.apply_move('d8b8')
        moves = set(self.game.get_moves())
        self.assertIn('a8b8', moves)
        self.assertNotIn('a8c8', moves)

        # white castling
        fen = 'r3k2r/pppqbppp/3pb3/8/8/3PB3/PPPQBPPP/R3K2R w KQkq - 0 7'
        new_fen = 'r3k2r/pppqbppp/3pb3/8/8/3PB3/PPPQBPPP/R4RK1 b kq - 1 7'
        self.game = Game(fen=fen)
        self.game.apply_move('e1g1')
        self.assertEqual(str(self.game), new_fen)
        new_fen = 'r3k2r/pppqbppp/3pb3/8/8/3PB3/PPPQBPPP/2KR3R b kq - 1 7'
        self.game = Game(fen=fen)
        self.game.apply_move('e1c1')
        self.assertEqual(str(self.game), new_fen)

        # black castling
        fen = 'r3k2r/pppqbppp/3pb3/8/8/3PB3/PPPQBPPP/R3K2R b KQkq - 0 7'
        new_fen = 'r4rk1/pppqbppp/3pb3/8/8/3PB3/PPPQBPPP/R3K2R w KQ - 1 8'
        self.game = Game(fen=fen)
        self.game.apply_move('e8g8')
        self.assertEqual(str(self.game), new_fen)
        new_fen = '2kr3r/pppqbppp/3pb3/8/8/3PB3/PPPQBPPP/R3K2R w KQ - 1 8'
        self.game = Game(fen=fen)
        self.game.apply_move('e8c8')
        self.assertEqual(str(self.game), new_fen)

        # Disable castling on capture
        fen = '1r2k2r/3nb1Qp/p1pp4/3p4/3P4/P1N2P2/1PP3PP/R1B3K1 w k - 0 22'
        new_fen = '1r2k2Q/3nb2p/p1pp4/3p4/3P4/P1N2P2/1PP3PP/R1B3K1 b - - 0 22'
        self.game = Game(fen=fen)
        self.game.apply_move('g7h8')
        self.assertEqual(str(self.game), new_fen)

        # white en passant
        fen = 'rnbqkbnr/ppp2ppp/4p3/3pP3/8/8/PPPP1PPP/RNBQKBNR w KQkq d6 0 1'
        self.game = Game(fen=fen)
        self.game.apply_move('e5d6')
        new_fen = 'rnbqkbnr/ppp2ppp/3Pp3/8/8/8/PPPP1PPP/RNBQKBNR b KQkq - 0 1'
        self.assertEqual(str(self.game), new_fen)

        # black en passant
        fen = 'rnbqkbnr/ppp1pppp/8/8/3pP3/8/PPPP1PPP/RNBQKBNR b KQkq e3 0 1'
        self.game = Game(fen=fen)
        self.game.apply_move('d4e3')
        new_fen = 'rnbqkbnr/ppp1pppp/8/8/8/4p3/PPPP1PPP/RNBQKBNR w KQkq - 0 2'
        self.assertEqual(str(self.game), new_fen)

        # capture
        fen = 'r2q1rk1/pppbbppp/2n5/3p4/3PN3/4PN2/1PPBBPPP/R2Q1RK1 b - - 0 9'
        self.game = Game(fen=fen)
        self.game.apply_move('d5e4')
        n_fen = 'r2q1rk1/pppbbppp/2n5/8/3Pp3/4PN2/1PPBBPPP/R2Q1RK1 w - - 0 10'
        self.assertEqual(str(self.game), n_fen)

        # invalid move
        self.game.reset()
        with self.assertRaises(InvalidMove):
            self.game.apply_move('e2e2')
Example #14
0
 def test_move_history(self):
     self.game = None
     self.game = Game()
     self.assertEqual(self.game.move_history, [])
     self.game.apply_move('e2e4')
     self.assertEqual(self.game.move_history, ['e2e4'])
Example #15
0
 def test_i2xy(self):
     for idx in range(64):
         self.assertIn(Game.i2xy(idx), ALG_POS)
Example #16
0
class GameTest(unittest.TestCase):
    def setUp(self):
        self.game = Game()

    def test_i2xy(self):
        for idx in range(64):
            self.assertIn(Game.i2xy(idx), ALG_POS)

    def test_xy2i(self):
        for pos in ALG_POS:
            self.assertIn(Game.xy2i(pos), IDX_POS)

    def test_str(self):
        self.game.reset()  # reset board to starting position
        self.assertEqual(str(self.game), START_POS)

    def test_fen_history(self):
        self.game.reset()
        self.assertEqual(self.game.fen_history, [START_POS])
        self.game.apply_move('e2e4')
        hist = [
            START_POS,
            'rnbqkbnr/pppppppp/8/8/4P3/8/PPPP1PPP/RNBQKBNR b KQkq e3 0 1'
        ]
        self.assertEqual(self.game.fen_history, hist)

    def test_move_history(self):
        self.game = None
        self.game = Game()
        self.assertEqual(self.game.move_history, [])
        self.game.apply_move('e2e4')
        self.assertEqual(self.game.move_history, ['e2e4'])

    def test_get_moves(self):
        # legal openings
        self.game.reset()
        self.assertEqual(sorted(self.game.get_moves()), LEGAL_OPENINGS)

        # en passant
        fen = 'rnbqkbnr/ppp2ppp/4p3/3pP3/8/8/PPPP1PPP/RNBQKBNR w KQkq d6 0 1'
        self.game = Game(fen=fen)
        self.assertEqual(self.game.get_moves(idx_list=[28]), ['e5d6'])

        # checkmate
        fen = '8/p5kp/1p6/2p5/P5P1/2n4P/r2p4/1K6 w - - 2 37'
        self.game = Game(fen=fen)
        self.assertEqual(self.game.get_moves(), [])

        # castling into occupied space & king moving into check
        fen = '8/2p5/5p2/7r/7P/3R1P2/P3R1P1/2k1K3 b - - 13 46'
        self.game = Game(fen=fen)
        self.assertIn('c7c6', self.game.get_moves())
        fen = '8/8/2p2p2/7r/7P/3R1P2/P3R1P1/2k1K3 w - - 0 47'
        self.game = Game(fen=fen, validate=False)
        self.assertNotIn('e1c1', self.game.get_moves())

        # castling through check
        fen = 'r3k2r/8/8/8/8/8/8/3RKR2 b kq - 0 1'
        self.game = Game(fen=fen)
        self.assertNotIn('e8c8', self.game.get_moves(idx_list=[4]))
        self.assertNotIn('e8g8', self.game.get_moves(idx_list=[4]))

        # castling out of check
        fen = 'r3rk2/8/8/8/8/8/8/R3K2R w KQ - 0 1'
        self.game = Game(fen=fen)
        self.assertNotIn('e1c8', self.game.get_moves(idx_list=[60]))

        # Github Issue 9
        fen = 'r3kb1r/p1p2pp1/2p4p/3Pp3/6b1/2P5/PP1NN2P/R2QK1q1 w Qkq - 0 16'
        self.game = Game(fen=fen)
        self.assertEqual(['d2f1', 'e2g1'], self.game.get_moves())

    def test_apply_move(self):
        # pawn promotion
        fen = '3qk1b1/P7/8/8/8/8/7P/4K3 w - - 0 1'
        self.game = Game(fen=fen)
        self.game.apply_move('a7a8q')
        self.assertEqual(str(self.game), 'Q2qk1b1/8/8/8/8/8/7P/4K3 b - - 0 1')

        # apply moves
        self.game.apply_move('g8h7')
        self.assertEqual(str(self.game), 'Q2qk3/7b/8/8/8/8/7P/4K3 w - - 1 2')
        self.game.apply_move('h2h4')
        self.assertEqual(str(self.game), 'Q2qk3/7b/8/8/7P/8/8/4K3 b - h3 0 2')

        # block vector tail with capture
        moves = [
            'd8c8', 'd8b8', 'd8a8', 'e8f8', 'e8d7', 'e8e7', 'e8f7', 'g8f7',
            'g8e6', 'g8d5', 'g8c4', 'g8b3', 'g8a2', 'g8h7'
        ]
        self.game.reset(fen='Q2qk1b1/8/8/8/8/8/7P/4K3 b - - 0 1')
        self.assertEqual(self.game.get_moves(), moves)
        self.game.apply_move('d8b8')
        moves = set(self.game.get_moves())
        self.assertIn('a8b8', moves)
        self.assertNotIn('a8c8', moves)

        # white castling
        fen = 'r3k2r/pppqbppp/3pb3/8/8/3PB3/PPPQBPPP/R3K2R w KQkq - 0 7'
        new_fen = 'r3k2r/pppqbppp/3pb3/8/8/3PB3/PPPQBPPP/R4RK1 b kq - 1 7'
        self.game = Game(fen=fen)
        self.game.apply_move('e1g1')
        self.assertEqual(str(self.game), new_fen)
        new_fen = 'r3k2r/pppqbppp/3pb3/8/8/3PB3/PPPQBPPP/2KR3R b kq - 1 7'
        self.game = Game(fen=fen)
        self.game.apply_move('e1c1')
        self.assertEqual(str(self.game), new_fen)

        # black castling
        fen = 'r3k2r/pppqbppp/3pb3/8/8/3PB3/PPPQBPPP/R3K2R b KQkq - 0 7'
        new_fen = 'r4rk1/pppqbppp/3pb3/8/8/3PB3/PPPQBPPP/R3K2R w KQ - 1 8'
        self.game = Game(fen=fen)
        self.game.apply_move('e8g8')
        self.assertEqual(str(self.game), new_fen)
        new_fen = '2kr3r/pppqbppp/3pb3/8/8/3PB3/PPPQBPPP/R3K2R w KQ - 1 8'
        self.game = Game(fen=fen)
        self.game.apply_move('e8c8')
        self.assertEqual(str(self.game), new_fen)

        # Disable castling on capture
        fen = '1r2k2r/3nb1Qp/p1pp4/3p4/3P4/P1N2P2/1PP3PP/R1B3K1 w k - 0 22'
        new_fen = '1r2k2Q/3nb2p/p1pp4/3p4/3P4/P1N2P2/1PP3PP/R1B3K1 b - - 0 22'
        self.game = Game(fen=fen)
        self.game.apply_move('g7h8')
        self.assertEqual(str(self.game), new_fen)

        # white en passant
        fen = 'rnbqkbnr/ppp2ppp/4p3/3pP3/8/8/PPPP1PPP/RNBQKBNR w KQkq d6 0 1'
        self.game = Game(fen=fen)
        self.game.apply_move('e5d6')
        new_fen = 'rnbqkbnr/ppp2ppp/3Pp3/8/8/8/PPPP1PPP/RNBQKBNR b KQkq - 0 1'
        self.assertEqual(str(self.game), new_fen)

        # black en passant
        fen = 'rnbqkbnr/ppp1pppp/8/8/3pP3/8/PPPP1PPP/RNBQKBNR b KQkq e3 0 1'
        self.game = Game(fen=fen)
        self.game.apply_move('d4e3')
        new_fen = 'rnbqkbnr/ppp1pppp/8/8/8/4p3/PPPP1PPP/RNBQKBNR w KQkq - 0 2'
        self.assertEqual(str(self.game), new_fen)

        # capture
        fen = 'r2q1rk1/pppbbppp/2n5/3p4/3PN3/4PN2/1PPBBPPP/R2Q1RK1 b - - 0 9'
        self.game = Game(fen=fen)
        self.game.apply_move('d5e4')
        n_fen = 'r2q1rk1/pppbbppp/2n5/8/3Pp3/4PN2/1PPBBPPP/R2Q1RK1 w - - 0 10'
        self.assertEqual(str(self.game), n_fen)

        # invalid move
        self.game.reset()
        with self.assertRaises(InvalidMove):
            self.game.apply_move('e2e2')

    def test_status(self):

        # NORMAL
        game = Game()
        self.assertEqual(game.status, Game.NORMAL)

        # CHECK
        game = Game(fen='r3rk2/8/8/8/8/8/8/R3K2R w KQ - 0 1')
        self.assertEqual(game.status, game.CHECK)

        # CHECKMATE
        game = Game(fen='8/p5kp/1p6/2p5/P5P1/2n4P/r2p4/1K6 w - - 2 37')
        self.assertEqual(game.status, Game.CHECKMATE)

        # STALEMATE
        game = Game(fen='8/8/8/8/8/7k/5q2/7K w - - 0 37')
        self.assertEqual(game.status, Game.STALEMATE)
class Chessboard(GridLayout):
    '''
    Actual chessboard with moving pieces
    '''
    # all_moves = ListProperty()
    game = ObjectProperty()
    move_made = BooleanProperty(False)
    # for menu!
    go_to = StringProperty('')
    def __init__(self, **kwargs):
        super(Chessboard, self).__init__(**kwargs)
        self.game = kwargs.get('game', None)
        if self.game:
            board = self.game.board._position
            for row in ('8','7','6','5','4','3','2','1'):
                for col in ('a','b','c','d','e','f','g','h'):
                    cell = BoardCell(name=col+row)
                    self.add_widget(cell)
            for n, cell in enumerate(self.children):
                i = 63 - n
                if board[i] != ' ':
                    man = Chessman(symbol=board[i])
                    cell.add_widget(man)

        self.grabbed = None

        # when move history changes
        # self.bind(all_moves=self.change_game)

    def change_game(self, all_moves):
        # reset game
        # if self.game:
        #     self.game.reset()
        # else:
        self.game = Game()

        # apply move history
        for move in all_moves:
            self.game.apply_move(move)
        # print self.game.move_history
        # print self.game.board
        # populate new position
        board = self.game.board._position
        for n, cell in enumerate(self.children):
            cell.clear_widgets()
            i = 63 - n
            if board[i] != ' ':
                man = Chessman(symbol=board[i])
                cell.add_widget(man)

    def update(self):
        board = self.game.board._position
        for n, cell in enumerate(self.children):
            cell.clear_widgets()
            i = 63 - n
            if board[i] != ' ':
                man = Chessman(symbol=board[i])
                cell.add_widget(man)

    def on_touch_down(self, touch):
        for cell in self.children:
            if cell.collide_point(*touch.pos):
                if cell.children:
                    self.move_start = cell.name
                    # print self.move_start
                    self.grabbed = cell.children[0]
                    # print self.grabbed.parent
                    touch.grab(self.grabbed)

    def on_touch_move(self, touch):
        if self.grabbed:
            self.grabbed.pos = [touch.x-self.grabbed.size[0]/2, touch.y-self.grabbed.size[1]/2]

    def on_touch_up(self, touch):
        for cell in self.children:
            if cell.collide_point(*touch.pos) and self.grabbed:
                self.destination = cell.name
                try:
                    self.game.apply_move(self.move_start+self.destination)
                    print "Is Legal"
                    self.grabbed.parent.clear_widgets()
                    cell.clear_widgets()
                    cell.add_widget(self.grabbed)
                    # self.grabbed.pos = cell.pos
                    self.move_made = False if self.move_made else True
                    self.update()
                except InvalidMove:
                    print 'Not Legal Move'
                    self.grabbed.pos = self.grabbed.parent.pos

        if self.grabbed:
            touch.ungrab(self.grabbed)
            self.grabbed = None
Example #18
0
 def __init__(self, **kwargs):
     super(NavMenu, self).__init__(**kwargs)
     # self.add_widget(ModeScreen(name='ModeScreen'))
     screen = Screen()
     screen.add_widget(ChessMenu(game=Game()))
     self.add_widget(screen)
Example #19
0
 def test_last_line_pawn_check(self):
     # If a pawn is able to expose a king on its last line
     game = Game(fen='8/5b2/8/6P1/8/p7/1pk5/K7 w - - 0 51')
     self.assertEqual(game.status, Game.CHECKMATE)
Example #20
0
 def setUp(self):
     self.game = Game()
 def setUp(self):
     self.game = Game()
Example #22
0
 def test_xy2i(self):
     for pos in ALG_POS:
         self.assertIn(Game.xy2i(pos), IDX_POS)
 def test_i2xy(self):
     for idx in xrange(64):
         self.assertIn(Game.i2xy(idx), ALG_POS)
Example #24
0
    def test_get_moves(self):
        # legal openings
        self.game.reset()
        self.assertEqual(sorted(self.game.get_moves()), LEGAL_OPENINGS)

        # en passant
        fen = 'rnbqkbnr/ppp2ppp/4p3/3pP3/8/8/PPPP1PPP/RNBQKBNR w KQkq d6 0 1'
        self.game = Game(fen=fen)
        self.assertEqual(self.game.get_moves(idx_list=[28]), ['e5d6'])

        # checkmate
        fen = '8/p5kp/1p6/2p5/P5P1/2n4P/r2p4/1K6 w - - 2 37'
        self.game = Game(fen=fen)
        self.assertEqual(self.game.get_moves(), [])

        # castling into occupied space & king moving into check
        fen = '8/2p5/5p2/7r/7P/3R1P2/P3R1P1/2k1K3 b - - 13 46'
        self.game = Game(fen=fen)
        self.assertIn('c7c6', self.game.get_moves())
        fen = '8/8/2p2p2/7r/7P/3R1P2/P3R1P1/2k1K3 w - - 0 47'
        self.game = Game(fen=fen, validate=False)
        self.assertNotIn('e1c1', self.game.get_moves())

        # castling through check
        fen = 'r3k2r/8/8/8/8/8/8/3RKR2 b kq - 0 1'
        self.game = Game(fen=fen)
        self.assertNotIn('e8c8', self.game.get_moves(idx_list=[4]))
        self.assertNotIn('e8g8', self.game.get_moves(idx_list=[4]))

        # castling out of check
        fen = 'r3rk2/8/8/8/8/8/8/R3K2R w KQ - 0 1'
        self.game = Game(fen=fen)
        self.assertNotIn('e1c8', self.game.get_moves(idx_list=[60]))

        # Github Issue 9
        fen = 'r3kb1r/p1p2pp1/2p4p/3Pp3/6b1/2P5/PP1NN2P/R2QK1q1 w Qkq - 0 16'
        self.game = Game(fen=fen)
        self.assertEqual(['d2f1', 'e2g1'], self.game.get_moves())
 def test_xy2i(self):
     for pos in ALG_POS:
         self.assertIn(Game.xy2i(pos), IDX_POS)
 def test_move_history(self):
     self.game = None
     self.game = Game()
     self.assertEqual(self.game.move_history, [])
     self.game.apply_move('e2e4')
     self.assertEqual(self.game.move_history, ['e2e4'])
Example #27
0
    def test_apply_san_move(self):
        # pawn promotion
        fen = '3qk1b1/P7/8/8/8/8/7P/4K3 w - - 0 1'
        self.game = Game(fen=fen)
        self.game.apply_san_move('a8=Q')
        self.assertEqual(str(self.game), 'Q2qk1b1/8/8/8/8/8/7P/4K3 b - - 0 1')

        # apply moves
        self.game.apply_san_move('Bh7')
        self.assertEqual(str(self.game), 'Q2qk3/7b/8/8/8/8/7P/4K3 w - - 1 2')
        self.game.apply_san_move('h4')
        self.assertEqual(str(self.game), 'Q2qk3/7b/8/8/7P/8/8/4K3 b - h3 0 2')

        # white castling
        fen = 'r3k2r/pppqbppp/3pb3/8/8/3PB3/PPPQBPPP/R3K2R w KQkq - 0 7'
        new_fen = 'r3k2r/pppqbppp/3pb3/8/8/3PB3/PPPQBPPP/R4RK1 b kq - 1 7'
        self.game = Game(fen=fen)
        self.game.apply_san_move('0-0')
        self.assertEqual(str(self.game), new_fen)
        new_fen = 'r3k2r/pppqbppp/3pb3/8/8/3PB3/PPPQBPPP/2KR3R b kq - 1 7'
        self.game = Game(fen=fen)
        self.game.apply_san_move('0-0-0')
        self.assertEqual(str(self.game), new_fen)

        # black castling
        fen = 'r3k2r/pppqbppp/3pb3/8/8/3PB3/PPPQBPPP/R3K2R b KQkq - 0 7'
        new_fen = 'r4rk1/pppqbppp/3pb3/8/8/3PB3/PPPQBPPP/R3K2R w KQ - 1 8'
        self.game = Game(fen=fen)
        self.game.apply_san_move('0-0')
        self.assertEqual(str(self.game), new_fen)
        new_fen = '2kr3r/pppqbppp/3pb3/8/8/3PB3/PPPQBPPP/R3K2R w KQ - 1 8'
        self.game = Game(fen=fen)
        self.game.apply_san_move('0-0-0')
        self.assertEqual(str(self.game), new_fen)

        # Disable castling on capture
        fen = '1r2k2r/3nb1Qp/p1pp4/3p4/3P4/P1N2P2/1PP3PP/R1B3K1 w k - 0 22'
        new_fen = '1r2k2Q/3nb2p/p1pp4/3p4/3P4/P1N2P2/1PP3PP/R1B3K1 b - - 0 22'
        self.game = Game(fen=fen)
        self.game.apply_san_move('Qxh8')
        self.assertEqual(str(self.game), new_fen)

        # white en passant
        fen = 'rnbqkbnr/ppp2ppp/4p3/3pP3/8/8/PPPP1PPP/RNBQKBNR w KQkq d6 0 1'
        self.game = Game(fen=fen)
        self.game.apply_san_move('exd6')
        new_fen = 'rnbqkbnr/ppp2ppp/3Pp3/8/8/8/PPPP1PPP/RNBQKBNR b KQkq - 0 1'
        self.assertEqual(str(self.game), new_fen)

        # black en passant
        fen = 'rnbqkbnr/ppp1pppp/8/8/3pP3/8/PPPP1PPP/RNBQKBNR b KQkq e3 0 1'
        self.game = Game(fen=fen)
        self.game.apply_san_move('dxe3')
        new_fen = 'rnbqkbnr/ppp1pppp/8/8/8/4p3/PPPP1PPP/RNBQKBNR w KQkq - 0 2'
        self.assertEqual(str(self.game), new_fen)

        # capture
        fen = 'r2q1rk1/pppbbppp/2n5/3p4/3PN3/4PN2/1PPBBPPP/R2Q1RK1 b - - 0 9'
        self.game = Game(fen=fen)
        self.game.apply_san_move('dxe4')
        n_fen = 'r2q1rk1/pppbbppp/2n5/8/3Pp3/4PN2/1PPBBPPP/R2Q1RK1 w - - 0 10'
        self.assertEqual(str(self.game), n_fen)