Example #1
0
def main():
    board = ChessBoard()
    change_settings = 0
    while True:
        if change_settings == 0:
            num_player = get_user_response("How many players do you want (1-2)?: ", "012")
            if num_player == 0:
                p1 = CPUPlayer(Color.WHITE)
                p2 = CPUPlayer(Color.BLACK)
            elif num_player == 1:
                who_first = get_user_response("Do you want to be White(W) or Black(B)?: ", "WB")
                difficulty = get_user_response("How good do you want the computer to play (1-9): ", "123456789")
                if who_first == 0:
                    p1 = HumanPlayer(Color.WHITE)
                    p2 = CPUPlayer(Color.BLACK)
                else:
                    p1 = CPUPlayer(Color.WHITE)
                    p2 = HumanPlayer(Color.BLACK)
            else:
                p1 = HumanPlayer(Color.WHITE)
                p2 = HumanPlayer(Color.BLACK)
        board.init_board()
        play_game(p1, p2, board)
        pa_resp = get_user_response("Do you want to play again Y/N: ", "YN")
        if pa_resp == 1:  # break if user wanted to quit
            break
        change_settings = get_user_response("Do you want to change the settings Y/N: ", "YN")
    del board
    del p1
    del p2
Example #2
0
    def PlaySingleMatch(self):
        self.Board = ChessBoard(0)  #reset board
        currentPlayerIndex = 0
        turnCount = 0

        while not self.Rules.IsCheckmate(
                self.Board.GetState(), self.player[currentPlayerIndex].color):
            board = self.Board.GetState()
            currentColor = self.player[currentPlayerIndex].GetColor()
            #hardcoded so that player 1 is always white
            if currentColor == 'white':
                turnCount = turnCount + 1
                if turnCount % 10 == 0:
                    print " %d" % turnCount,
                if turnCount > 200:
                    return (
                        turnCount, -1
                    )  #Call it a draw... otherwise some games can go on forever.
            moveTuple = self.player[currentPlayerIndex].GetMove(
                self.Board.GetState(), currentColor)
            moveReport = self.Board.MovePiece(
                moveTuple
            )  #moveReport = string like "White Bishop moves from A1 to C3" (+) "and captures ___!"
            #print moveReport
            currentPlayerIndex = (
                currentPlayerIndex + 1
            ) % 2  #this will cause the currentPlayerIndex to toggle between 1 and 0

        winnerIndex = (currentPlayerIndex + 1) % 2

        return (turnCount, winnerIndex)
Example #3
0
 def playRandom():
     cb = ChessBoard()
     return_value = playRandomGame(cb)
     printBoard(cb)
     print ("\n%s win one board. last move is %s %s, return value is %d" % (
         transferSymbol(cb.get_winner()), numToAlp(cb.get_lastmove()[0]), numToAlp(cb.get_lastmove()[1]),
         return_value))
Example #4
0
def rnd_game():
    SCREEN_SIZE = (base_size * 3, base_size * 3)
    pygame.init()
    screen = pygame.display.set_mode(SCREEN_SIZE, RESIZABLE, 32)

    cb = ChessBoard()
    sa = StatisticAgent(cb, cb.player1_flag, cb.player2_flag)

    draw_background(screen, (100,200,100), SCREEN_SIZE[0], SCREEN_SIZE[1])

    finished = False
    game_step = 0

    while True:
        event = pygame.event.wait()
        if event.type == QUIT:
            exit()
        pressed_mouse = pygame.mouse.get_pressed()
        if pressed_mouse[0] and game_step % 2 + 1 == sa.enemy_flag and finished == False:
            x, y =  pygame.mouse.get_pos()
            r, c = xy2rc(x, y)
            if cb.is_empty(r, c):
                winner = cb.make_a_move(r, c, sa.enemy_flag, True)
                game_step += 1
                draw_chessboard(screen, cb)
                if winner != None:
                    finished = True
        if (game_step % 2) + 1 == sa.my_flag and finished == False:
            winner = cb.make_rnd_move(sa.my_flag)
            game_step += 1
            draw_chessboard(screen, cb)
            if winner != None:
                finished = True

        pygame.display.update()
Example #5
0
def statistic_test():
    cb = ChessBoard()
    sa = StatisticAgent(cb, cb.player1_flag, cb.player2_flag)
    cb.print_board()

    for i in range(9):
        winner = sa.make_statistic_move(cb, sa.my_flag)
        cb.print_board()
        if winner != None and winner != -1:
            print winner, "wins!"
            break
        elif winner == -1:
            print "The game is already over."
            break
        r, c = 0, 0
        while True:
            move = [int(i) for i in raw_input("your move:").split()]
            r, c = move[0], move[1]
            if cb.is_empty(r, c):
                break
            else:
                print "[%d, %d] is occupied! Try again."%(r, c)
        winner = cb.make_a_move(r, c, sa.enemy_flag, True)
        cb.print_board()
        if winner == cb.player1_flag or winner == cb.player2_flag:
            print winner, "wins!"
            break
        elif winner == cb.draw_flag:
            print "There is a draw."
            break
    def test_Checkmate(self, mockGetListOfValidMoves):
        "Unit test for ChessRules method: IsCheckmate"
        # NOTE 1: We only check that there are valid moves for a given color
        # NOTE 2: We are NOT checking the setting color logic in this unit test. You need to write another unit test for this logic.

        # Creating objects of Chessboard and ChessRules class and calling IsCheckmate function with each piece for initial position and "black" color
        cb = ChessBoard(
            0)  #Create a chess board object with the initial position
        chess_rules_obj = ChessRules.ChessRules()
        chess_rules_obj.IsCheckmate(cb.GetState(), "black")

        # Create expected_arg_calls list which is supposed to be called with GetListOfValidMoves for initial position
        # IsCheckmate calls GetListOfValidMoves with arguments: board, color (who is to play?) and co-ordinates of a square with a piece on it
        expected_arg_calls = []
        for row in range(0, 2):
            for col in range(0, 8):
                expected_arg_calls.append(
                    mock.call(cb.GetState(), 'black', (row, col)))

        # Assert that the mockGetListOfValidMoves.call_args_list matches expected_arg_calls
        self.assertEqual(mockGetListOfValidMoves.call_args_list,
                         expected_arg_calls)

        # DID YOU KNOW?
        # assert_any_call can be used to assert a method that was called at least once with some arguments
        #mockGetListOfValidMoves.assert_any_call(cb.GetState(),"black",(1,6))

        # DID YOU KNOW?
        # call_count can be used to check the number of times your mocked method was called
        self.assertEqual(mockGetListOfValidMoves.call_count, 16)
Example #7
0
    def move(self, board: ChessBoard) -> bool:
        while True:
            resp_string = self.ask_for_player_move()
            if resp_string == "q":
                return True
            # turn response into list of 4 ascii values
            resp = [ord(c) for c in resp_string]
            ord_string = "a1a1"
            origin = [ord(c) for c in ord_string
                      ]  # create list for origin ascii values
            diff = []

            # subtract inputted coordinates from origin to get coordinates as 0 based index in 2d list
            zip_object = zip(resp, origin)
            for resp_i, origin_i in zip_object:
                diff.append(resp_i - origin_i)

            if board.is_valid_move(diff[1], diff[0], diff[3], diff[2],
                                   self.player_color):
                # Have the board make the move and return True if checkmate was a achieved and false if it wasn't
                # if move failed then loop is continued and nothing is returned
                move_type = board.move_piece(diff[1], diff[0],
                                             diff[3], diff[2],
                                             self.color_to_string(True))
                if move_type == MoveType.CHECKMATE:
                    return True
                elif move_type == MoveType.MOVE_PASSED:
                    return False
            else:
                print("Error invalid move. Please try again!")
Example #8
0
    def test_putpiece1(self):
        cb = ChessBoard()

        self.assertEqual(0, cb.put_piece(0, 0, 1))
        self.assertEqual(-2, cb.put_piece(0, 0, 1))
        self.assertEqual(-1, cb.put_piece(-1, 0, 1))
        self.assertEqual(-1, cb.put_piece(0, 16, 1))
class PythonChessMain:
    def __init__(self, options):
        if options.debug:
            self.Board = ChessBoard(2)
            self.debugMode = True
        else:
            self.Board = ChessBoard(
                0
            )  # 0 for normal board setup; see ChessBoard class for other options (for testing purposes)
            self.debugMode = False

    def SetUp(self, options):
        # gameSetupParams: Player 1 and 2 Name, Color, Human/AI level

        self.guitype = "pygame"
        if options.old:
            self.Gui = ChessGUI_pygame(0)
        else:
            self.Gui = ChessGUI_pygame(1)

    def MainLoop(self):
        for x in range(10):
            self.Board.generate()
            self.Board.GetState()
            self.Gui.Draw(board)
            time.sleep(2)
        self.Gui.EndGame(board)
Example #10
0
 def test_putpiece2(self):
     cb = ChessBoard()
     muser = 1
     for i in xrange(4):
         for j in xrange(15):
             return_value = cb.put_piece(i, j, muser)
             self.assertEqual(0, return_value)
             muser = 2 if muser == 1 else 1
	def __init__(self,options):
		if options.debug:
			self.Board = ChessBoard(2)
			self.debugMode = True
		else:
			self.Board = ChessBoard(0)#0 for normal board setup; see ChessBoard class for other options (for testing purposes)
			self.debugMode = False

		self.Rules = ChessRules()
 def __init__(self, options):
     if options.debug:
         self.Board = ChessBoard(2)
         self.debugMode = True
     else:
         self.Board = ChessBoard(
             0
         )  # 0 for normal board setup; see ChessBoard class for other options (for testing purposes)
         self.debugMode = False
Example #13
0
    def __init__(self, options):
        if options.debug:
            self.Board = ChessBoard(2)
            self.debugMode = True
        else:
            self.Board = ChessBoard(
                6
            )  #6 for Checkmate with knights setup; see ChessBoard class for other options (for testing purposes)
            self.debugMode = False

        self.Rules = ChessRules()
Example #14
0
    def __init__(self, options):
        if options.debug:
            self.Board = ChessBoard(2)
            self.debugMode = True
        else:
            self.Board = ChessBoard(
                7
            )  #7 for Bishops Checkmate setup; see ChessBoard class for other options (for testing purposes)
            self.debugMode = False

        self.Rules = ChessRules()
Example #15
0
 def __init__(self, room_id_):
     self.play_users = []
     self.position2users = {}  # 1 black role   2 white role
     self.room_id = room_id_
     self.users = []
     self.max_player_num = 2
     self.max_user_num = 10000
     self.board = ChessBoard()
     self.status_signature = None
     self.set_changed()
     self.chess_folder = 'chess_output'
     # self.game_status = GameRoom.GAME_STATUS_NOTBEGIN
     self.ask_take_back = 0
Example #16
0
    def IsInCheck(self,chessboard):
        # Now we're checking for any black moves that take the king. We want to consider the opponent of "color"'s moves.
        chessboard.Rotate(skipsq=True)

        check=False
        for move in self.GetAllValidMoveNumbers(chessboard,skipCheckTest=True):
            newboard = ChessBoard([chessboard.board,[],0])
            newboard.MovePiece(move,skipsq=True)
            if 'k' not in newboard.board:
                check=True
                break

        chessboard.Rotate(skipsq=True)
        return check
Example #17
0
def play_game(p1: Player, p2: Player, board: ChessBoard):
    p1.reset_game()
    p2.reset_game()
    cur_player = 0
    quit_game = False
    while True:
        board.display_board()
        if quit_game:
            break
        if cur_player == 0:
            quit_game = p1.move(board)
        else:
            quit_game = p2.move(board)
        cur_player = 1 - cur_player  # switch whose turn it is
        print("")
Example #18
0
    def syncBoard(self, m):
        if not isinstance(m, ChessMoveMessage):
            return

        chess = ChessBoard()
        if isinstance(m, ChessMoveMessage):
            for move in m.history:
                chess.addTextMove(move)

        board = chess.getBoard()
        cboard = self.strategy.board()

        for row, rank in enumerate(board):
            for col, square in enumerate(rank):
                cboard.setPiece(row, col, square)
    def syncBoard(self, m):
        if not isinstance(m, ChessMoveMessage):
            return

        chess = ChessBoard()
        if isinstance(m, ChessMoveMessage):
            for move in m.history:
                chess.addTextMove(move)

        board = chess.getBoard()
        cboard = self.strategy.board()

        for row, rank in enumerate(board):
            for col, square in enumerate(rank):
                cboard.setPiece(row, col, square)
Example #20
0
 def __init__(self,aSkillLevel,aMoveTime):
     """
     Create an object to hold the game state
     Use Chessboard library for logic
     """
     print "Game State Initilized"
     self.chessGame = ChessBoard()
     self.chessGame.resetBoard()
     self.chessGame.printBoard()
     self.moveTime = aMoveTime #Used to store movetime
     self.skillLevel = aSkillLevel #Used to store skill level
     self.gameMoves = [] #Used to store all moves in game
     self.saveFileExt = ".txt"
     self.saveFilePath = ""
     self.startPos = "startpos" #Used to store the start position or fen string
Example #21
0
    def __init__(self, player_white, player_black):
        self.board = ChessBoard()
        self.board.set_start_position()
        self.player_white = player_white
        self.player_black = player_black
        self.move_number = 1
        self.previous_board = copy.deepcopy(self.board)
        self.result_notation_text = ''

        self.is_white_check = False
        self.is_black_check = False

        self.possible_white_long_castling = True
        self.possible_white_short_castling = True
        self.possible_black_long_castling = True
        self.possible_black_short_castling = True
Example #22
0
 def createGame(self, game_id, p1, p2):
     game = {
         'player 1' : p1,
         'player -1' : p2,
         'board' : ChessBoard()
     }
     self.__editGames(game_id, game)
Example #23
0
    def add_coord_to_path(self,path, r1,c1, r2,c2):
        # cheking if the piece captures the bait
        if(ChessBoard.piece_val(self.board[r1,c1])==6 and self.board[r2,c2]==self.enm_bait):
            en_pass_take = True
            # temporary removing enemy pawn that used en_passant and get captured
            self.board.put_at(r1,c2,0)
        else:
            en_pass_take = False
            
        temp_piece = self.board[r2,c2]
        self.board.transact(r1,c1, r2,c2)
        
        attk_zone = self.get_weakness()
        k_val = np.argwhere(ChessBoard.PIECES == ('WK' if self.color == 'WHITE' else 'BK'))[0,0]
#        print(k_val)
        k_pos = np.argwhere(self.board.board == k_val)[0]
#        print(k_pos)
        # if move is not getting king under attack then add path
        if attk_zone[k_pos[0],k_pos[1]] == 0:
#            print("True")
            path.append((r2,c2))
        
        self.board.transact(r2,c2, r1,c1)
        self.board.put_at(r2,c2, temp_piece)
        if en_pass_take:
            # putting the enemy pawn back
            self.board.put_at(r1,c2,12 if self.color == 'WHITE' else 6)
Example #24
0
 def playMuch(num):
     oi = 0
     for i in xrange(num):
         cb = ChessBoard()
         playRandomGame(cb)
         oi += cb.move_num
     print(oi / num)
Example #25
0
    def onChessMessage(self, m):
        log.info(str(m))
        chess = ChessBoard()
        if not isinstance(m, ChessMoveMessage):
            self.clear()
            return

        algebraicNotationMoves = []
        for move in m.history:
            chess.addTextMove(move)
            algebraicNotationMoves.append(chess.getLastTextMove(ChessBoard.AN))

        stockfishFEN, legalMoves, scores, pctM, pctE1, pctE2, total = self.stockfish.eval(
            algebraicNotationMoves)

        ## Call:
        ## lm(formula = whiteWins ~ s, data = a, na.action = na.exclude)
        ##
        ## Residuals:
        ##     Min      1Q  Median      3Q     Max
        ## -0.7457 -0.4437 -0.1217  0.4577  0.8783
        ##
        ## Coefficients:
        ##              Estimate Std. Error t value Pr(>|t|)
        ## (Intercept) 0.4337105  0.0012811   338.5   <2e-16 ***
        ## s           0.1247885  0.0008928   139.8   <2e-16 ***
        ## ---
        ## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
        ##
        ## Residual standard error: 0.4669 on 137618 degrees of freedom
        ##   (70 observations deleted due to missingness)
        ## Multiple R-squared:  0.1243,	Adjusted R-squared:  0.1243
        ## F-statistic: 1.953e+04 on 1 and 137618 DF,  p-value: < 2.2e-16

        ##log.info(scores)
        s = total
        s = min(s, 2.5)
        s = max(s, -2.5)

        self.feat['total'] = total
        self.feat['s'] = s
        self.feat['pctM'] = pctM

        self.fp = (0.4337105 + 0.1247885 * s) * 100
        self.fp = min(self.fp, 100)
        self.fp = max(self.fp, 0)
Example #26
0
 def simulation(self, r, c):
     sim_board = copy.deepcopy(self.chess_board.board)
     sim_chess_board = ChessBoard(sim_board)
     winner = sim_chess_board.make_a_move(r, c, self.my_flag)
     if winner == self.chess_board.draw_flag:
         return 0.0
     elif winner == self.my_flag:
         return 1.1
     win_times = 0
     lost_times = 0
     for i in range(self.sim_times):
         sim_board2 = copy.deepcopy(sim_board)
         sim_chess_board2 = ChessBoard(sim_board2)
         while True:
             winner = sim_chess_board2.make_rnd_move(self.enemy_flag)
             if winner == self.enemy_flag:
                 lost_times += 1
                 break
             elif winner == self.chess_board.draw_flag:
                 break
             winner = sim_chess_board2.make_rnd_move(self.my_flag)
             if winner == self.my_flag:
                 win_times += 1
                 break
             elif winner == self.chess_board.draw_flag:
                 break
     return 1.0 * (self.sim_times - lost_times) / self.sim_times
    def onChessMessage(self,m):
        log.info(str(m))
        chess = ChessBoard()
        if not isinstance(m, ChessMoveMessage):
            self.clear()
            return

        algebraicNotationMoves = []
        for move in m.history:
            chess.addTextMove(move)
            algebraicNotationMoves.append(chess.getLastTextMove(ChessBoard.AN))

        stockfishFEN, legalMoves, scores, pctM, pctE1, pctE2, total = self.stockfish.eval(algebraicNotationMoves)

        ## Call:
        ## lm(formula = whiteWins ~ s, data = a, na.action = na.exclude)
        ##
        ## Residuals:
        ##     Min      1Q  Median      3Q     Max
        ## -0.7457 -0.4437 -0.1217  0.4577  0.8783
        ##
        ## Coefficients:
        ##              Estimate Std. Error t value Pr(>|t|)
        ## (Intercept) 0.4337105  0.0012811   338.5   <2e-16 ***
        ## s           0.1247885  0.0008928   139.8   <2e-16 ***
        ## ---
        ## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
        ##
        ## Residual standard error: 0.4669 on 137618 degrees of freedom
        ##   (70 observations deleted due to missingness)
        ## Multiple R-squared:  0.1243,	Adjusted R-squared:  0.1243
        ## F-statistic: 1.953e+04 on 1 and 137618 DF,  p-value: < 2.2e-16

        ##log.info(scores)
        s = total
        s = min(s,  2.5)
        s = max(s, -2.5)

        self.feat['total'] = total
        self.feat['s'] = s
        self.feat['pctM'] = pctM

        self.fp = (0.4337105 + 0.1247885 * s)*100
        self.fp = min(self.fp, 100)
        self.fp = max(self.fp,   0)
Example #28
0
        def parse_score(line):
            analysis_board = ChessBoard()
            analysis_board.setFEN(self.chessboard.getFEN())
            tokens = line.split()
            try:
                score_index = tokens.index('score')
            except ValueError:
                score_index = -1
            score = None
            move_list = []
            if score_index != -1 and tokens[score_index + 1] == "cp":
                score = float(tokens[score_index + 2]) / 100 * 1.0
            try:
                line_index = tokens.index('pv')
                for mv in tokens[line_index + 1:]:
                    analysis_board.addTextMove(mv)
                    move_list.append(analysis_board.getLastTextMove())

            except ValueError:
                line_index = -1
            variation = self.generate_move_list(
                move_list, start_move_num=self.chessboard.getCurrentMove() +
                1) if line_index != -1 else None

            del analysis_board
            if variation and score:
                return move_list, "[b]%s[/b][color=0d4cd6][ref=engine_toggle]         Stop[/ref][/color]\n[color=77b5fe]%s[/color]" % (
                    score, "".join(variation))
Example #29
0
	def __init__(self, dad=None, fromPiece=(0,0), toPiece=(0,0), board=ChessBoard().squares, lvl=0):
		self.dad = dad
		self.fromPiece = fromPiece
		self.toPiece = toPiece
		self.board = board
		self.color = self.setColor(fromPiece)
		self.score = self.cScore()
		self.lvl = lvl
		self.children = []
		del self.board
Example #30
0
    def __init__(self):
        pygame.init()
        self.game_display = pygame.display.set_mode((900, 650))
        pygame.display.set_caption('Chess')

        self.settings = {'board_image': 'images/orange_board.png'}
        self.board_image = pygame.image.load(self.settings['board_image'])

        self.clock = pygame.time.Clock()
        self.chess_board = ChessBoard()

        self.curr_selected_piece = None
        self.curr_poss_moves = []
        self.all_poss_moves = self.get_all_poss_moves()

        self.white_pieces_taken_images = []
        self.black_pieces_taken_images = []

        self.play_game()
Example #31
0
    def test_called_with_args(self, mockGetListOfValidMoves):
        "Unit test for ChessRules method: IsCheckmate"

        # Creating objects of Chessboard and ChessRules class and calling IsCheckmate function with each piece for initial position and "black" color
        cb = ChessBoard(
            0)  # Create a chess board object with the initial position
        chess_rules_obj = ChessRules.ChessRules()
        chess_rules_obj.IsCheckmate(cb.GetState(), "black")

        # Create expected_arg_calls list which is supposed to be called with GetListOfValidMoves for initial position
        # IsCheckmate calls GetListOfValidMoves with arguments: board, color (who is to play?) and co-ordinates of a square with a piece on it
        expected_arg_calls = []
        for row in range(0, 2):
            for col in range(0, 8):
                expected_arg_calls.append(
                    mock.call(cb.GetState(), 'black', (row, col)))

        # assert that method was called at least once with some argument
        mockGetListOfValidMoves.assert_any_call(cb.GetState(), "black", (1, 6))
Example #32
0
        def parse_score(line):
            analysis_board = ChessBoard()
            analysis_board.setFEN(self.chessboard.getFEN())
            tokens = line.split()
            try:
                score_index = tokens.index('score')
            except ValueError:
                score_index = -1
            score = None
            move_list = []
            if score_index!=-1 and tokens[score_index+1]=="cp":
                score = float(tokens[score_index+2])/100*1.0
            try:
                line_index = tokens.index('pv')
                for mv in tokens[line_index+1:]:
                    analysis_board.addTextMove(mv)
                    move_list.append(analysis_board.getLastTextMove())

            except ValueError:
                line_index = -1
            variation = self.generate_move_list(move_list,start_move_num=self.chessboard.getCurrentMove()+1) if line_index!=-1 else None

            del analysis_board
            if variation and score:
                return move_list, "[b]%s[/b][color=0d4cd6][ref=engine_toggle]         Stop[/ref][/color]\n[color=77b5fe]%s[/color]" %(score,"".join(variation))
Example #33
0
 def __init__(self, server_url):
     self.session = requests.Session()
     self.session.cookies = cookielib.CookieJar()
     agent = 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Maxthon/5.1.2.3000 Chrome/55.0.2883.75 Safari/537.36'
     self.headers = {
         "Host": server_url,
         "Origin": server_url,
         "Referer": server_url,
         'User-Agent': agent
     }
     self.server_url = server_url
     self.board = ChessBoard()
     self.last_status_signature = ""
Example #34
0
    def onChessMessage(self, m):
        log.info(str(m))
        chess = ChessBoard()
        if not isinstance(m, ChessMoveMessage):
            self.materialScore = 0
            return

        for move in m.history:
            chess.addTextMove(move)

        values = {"P": 1, "N": 3, "B": 3, "R": 5, "Q": 9, "K": 1}
        board = chess.getBoard()
        W, B = 0, 0
        for rank in board:
            for square in rank:
                if square != ".":
                    if square.isupper():
                        W += values[square]
                    else:
                        B += values[square.upper()]
        self.materialScore = W - B
        log.info("materialScore = %d" % self.materialScore)
    def syncStockfish(self, m):
        if not isinstance(m, ChessMoveMessage) or not self.stockfish:
            return

        chess = ChessBoard()
        algebraicNotationMoves = []
        for move in m.history:
            chess.addTextMove(move)
            algebraicNotationMoves.append(chess.getLastTextMove(ChessBoard.AN))

        fen, legalMoves, scores, pctM, pctE1, pctE2, total = self.stockfish.eval(algebraicNotationMoves)

        sf = self.strategy.stockfish()
        sf.reset()
        sf.setFEN(fen)
        sf.setLegalMoves(legalMoves)
        sf.setTotal(pctM, pctE1, pctE2, total)

        for scoreType, scoreList in scores.iteritems():
            for scoreSubtype, score in scoreList.iteritems():
                if not math.isnan(score):
                    sf.setScore(scoreType, scoreSubtype, score)
    def onChessMessage(self,m):
        log.info(str(m))
        chess = ChessBoard()
        if not isinstance(m, ChessMoveMessage):
            self.materialScore = 0
            return

        for move in m.history:
            chess.addTextMove(move)

        values = {"P": 1, "N": 3, "B": 3, "R": 5, "Q": 9, "K": 1}
        board = chess.getBoard()
        W,B = 0,0
        for rank in board:
            for square in rank:
                if square != ".":
                    if square.isupper():
                        W += values[square]
                    else:
                        B += values[square.upper()]
        self.materialScore = W-B
        log.info("materialScore = %d" % self.materialScore)
def main():
	board = ChessBoard()
	loadStandardGame(board)
	board.printBoard()
	print("Enter moves as coordinates pair (eg: 7a to 6a")
	print("Type 'quit' to exit!")
	print("White starts!")

	while True:
		start = input("start: ")
		end = input("end: ")
		if start.lower() == 'quit' or end.lower() == 'quit':
			break
		board.moveOnBoard(start, end)
		board.printBoard()
		print("Next player turn!")
Example #38
0
    def __init__(self, player_white, player_black):
        self.board = ChessBoard()
        self.board.set_start_position()
        self.player_white = player_white
        self.player_black = player_black
        self.move_number = 1
        self.previous_board = copy.deepcopy(self.board)
        self.result_notation_text = ''

        self.is_white_check = False
        self.is_black_check = False

        self.possible_white_long_castling = True
        self.possible_white_short_castling = True
        self.possible_black_long_castling = True
        self.possible_black_short_castling = True
Example #39
0
    def __init__(self):
        pygame.init()
        self.game_display = pygame.display.set_mode((900, 650))
        pygame.display.set_caption('Chess')

        self.settings = {'board_image': 'images/orange_board.png'}
        self.board_image = pygame.image.load(self.settings['board_image'])

        self.clock = pygame.time.Clock()
        self.chess_board = ChessBoard()

        self.curr_selected_piece = None
        self.curr_poss_moves = []
        self.all_poss_moves = self.get_all_poss_moves()

        self.white_pieces_taken_images = []
        self.black_pieces_taken_images = []

        self.play_game()
Example #40
0
 def __init__(self, x_size, y_size, log=None, initial_position=INITIAL_POSITION, max_pending_moves=MAX_PENDING_MOVES):
     """
     max_pending_moves :
         * Maximum number of last moves awaiting for mandatory changes before calling for help
         * Maximum number of moves a non-matched change waits before calling for help
     """
     # FIXME x_size and y_size are not verified against initial_position
     self.log_function = log or self.defaultLogFunction
     self.initial_position = initial_position
     self.max_pending_moves = max_pending_moves
     self.chessboard = ChessBoard(x_size, y_size)
     self.chessboard.initializeFEN(initial_position)
     self.move_history = []
     self.change_buffer = []
     self.pending_changes = []
     self.recording = False
     self.name = None
     self.last_ambiguous_change = None
     initial_repr = initial_position.split("/")
     initial_repr.reverse()
     self.change_history = [PhysicalBoardChange(0, None, None, None, initial_repr)]
     self.change_history_index = 0
Example #41
0
    def mainLooptemp(self):     
        chess = ChessBoard()
        clock = pygame.time.Clock()
        screen = pygame.display.set_mode((480, 480),1)
        pygame.display.set_caption('ChessBoard Client')
        view = PyGameWindowView(chess,screen)
        controller = Controller(chess)        
        running = True
              
#        paired_piece_weights_1 = run_genetic_algorithms.build_random_pair_piece_dict()    
#        paired_piece_weights_2 = run_genetic_algorithms.build_random_pair_piece_dict()    
        
        player_1 = Human(ChessBoard.WHITE)
#        player_2 = Human(ChessBoard.BLACK)
#        AI1ply = 2
#        player_1 = ChessAI(ChessBoard.WHITE,chess,evaluation_functions.terminal_eval_simple,
#                           prune_functions.never_prune,QFunctions.simple_end_game,paired_piece_weights_1,AI1ply)
        AI2ply = 2
        player_2 = ChessAI(ChessBoard.BLACK,chess,evaluation_functions.terminal_eval,
                           prune_functions.never_prune,QFunctions.no_extension,None,AI2ply)
##        AI_color = ChessBoard.BLACK
#        player_color = ChessBoard.WHITE
#        human_player = Player(player_color)
##        AI = (AI_color)    
#        player_2_color = ChessBoard.BLACK
#        human_player_2 = Player(player_2_color)
        
        while running:
            clock.tick(30)        
            if chess.getTurn() == player_1.color and not chess.isGameOver():
                if type(player_1) == Human:
                    for event in pygame.event.get():
                        if event.type == QUIT:
                            running = False
                            pygame.quit()
                            return
                        else:
                            controller.handle_event(event)   
                else:
                    print "AI 1 (WHITE) making turn"
                    player_1.make_next_move()
                    chess.moveNumber += 1
            elif chess.getTurn() == player_2.color and not chess.isGameOver():
                if type(player_2) == Human:
                    for event in pygame.event.get():
                        if event.type == QUIT:
                            running = False
                            pygame.quit()
                            return
                        else:
                            controller.handle_event(event)   
                else:
                    print "AI 2 (BLACK) making turn"
                    player_2.make_next_move()
                    chess.moveNumber += 1
                    
            #multithread in python to be able to make calculations and quit during player's turn
            
#            if chess.getTurn() == AI.color:
#                    turn = machine.get_turn()
#                    board.updatewithMachine'sturn
                    
            if chess.isGameOver():
                view.title_game_display(chess)
                chess.validMoves = []
                chess.markPos[0] = -1
                chess.markPos[1] = -1
                for event in pygame.event.get():
                    if event.type == QUIT:
                        running = False
                        pygame.quit()
                        return
            else:
                pygame.display.set_caption('ChessBoard Client') 
                                            
            view.draw(chess)
            pygame.display.flip()  
            
        pygame.quit()
    def mainLoop(self):    
        pygame.init()    
        
        pieces = {}    
        chess = ChessBoard()
        board = chess.getBoard()
        turn = chess.getTurn()

        screen = pygame.display.set_mode((480, 480),1)
        pygame.display.set_caption('ChessBoard Client')

        # load all images
        pieces = [{},{}]
        pieces[0]["r"] = pygame.image.load("./img/brw.png")                
        pieces[0]["n"] = pygame.image.load("./img/bnw.png")                
        pieces[0]["b"] = pygame.image.load("./img/bbw.png")                
        pieces[0]["k"] = pygame.image.load("./img/bkw.png")                
        pieces[0]["q"] = pygame.image.load("./img/bqw.png")                
        pieces[0]["p"] = pygame.image.load("./img/bpw.png")                
        pieces[0]["R"] = pygame.image.load("./img/wrw.png")                
        pieces[0]["N"] = pygame.image.load("./img/wnw.png")                
        pieces[0]["B"] = pygame.image.load("./img/wbw.png")                
        pieces[0]["K"] = pygame.image.load("./img/wkw.png")                
        pieces[0]["Q"] = pygame.image.load("./img/wqw.png")                
        pieces[0]["P"] = pygame.image.load("./img/wpw.png")                
        pieces[0]["."] = pygame.image.load("./img/w.png")                
        pieces[1]["r"] = pygame.image.load("./img/brb.png")                
        pieces[1]["n"] = pygame.image.load("./img/bnb.png")                
        pieces[1]["b"] = pygame.image.load("./img/bbb.png")                
        pieces[1]["k"] = pygame.image.load("./img/bkb.png")                
        pieces[1]["q"] = pygame.image.load("./img/bqb.png")                
        pieces[1]["p"] = pygame.image.load("./img/bpb.png")                
        pieces[1]["R"] = pygame.image.load("./img/wrb.png")                
        pieces[1]["N"] = pygame.image.load("./img/wnb.png")                
        pieces[1]["B"] = pygame.image.load("./img/wbb.png")                
        pieces[1]["K"] = pygame.image.load("./img/wkb.png")                
        pieces[1]["Q"] = pygame.image.load("./img/wqb.png")                
        pieces[1]["P"] = pygame.image.load("./img/wpb.png")                
        pieces[1]["."] = pygame.image.load("./img/b.png")                

        clock = pygame.time.Clock()

        posRect = pygame.Rect(0,0,60,60)

        mousePos = [-1,-1]
        markPos = [-1,-1]
        validMoves = []
        
        gameResults = ["","WHITE WINS!","BLACK WINS!","STALEMATE","DRAW BY THE FIFTHY MOVES RULE","DRAW BY THE THREE REPETITION RULE"]
        
        while 1:
            clock.tick(30)        
    
            for event in pygame.event.get():
                if event.type == QUIT:
                    return
                elif event.type == KEYDOWN:
                    if event.key == K_ESCAPE:
                        return
                    elif event.key == K_LEFT:
                        chess.undo()
                    elif event.key == K_RIGHT:
                        chess.redo()
                    elif event.unicode in ("f","F"):
                        print chess.getFEN()
                    elif event.unicode in ("a","A"):
                        an = chess.getAllTextMoves(chess.AN)
                        if an:
                            print "AN: " + ", ".join(an)
                    elif event.unicode in ("s","S"):
                        san = chess.getAllTextMoves(chess.SAN)
                        if san:
                            print "SAN: " + ", ".join(san)
                    elif event.unicode in ("l","L"):
                        lan = chess.getAllTextMoves(chess.LAN)
                        if lan:
                            print "LAN: " + ", ".join(lan)
                    board = chess.getBoard()
                    turn = chess.getTurn()
                    markPos[0] = -1
                    validMoves = [] 
                        
                if not chess.isGameOver():
                    if event.type == MOUSEMOTION:
                        mx = event.pos[0]
                        my = event.pos[1]
                        mousePos[0] = mx/60
                        mousePos[1] = my/60
                    elif event.type == MOUSEBUTTONDOWN:
                        if mousePos[0] != -1:
                            if markPos[0] == mousePos[0] and markPos[1] == mousePos[1]:
                                markPos[0] = -1
                                validMoves = []
                            else: 
                                if (turn==ChessBoard.WHITE and board[mousePos[1]][mousePos[0]].isupper()) or \
                                   (turn==ChessBoard.BLACK and board[mousePos[1]][mousePos[0]].islower()):    
                                    markPos[0] = mousePos[0]
                                    markPos[1] = mousePos[1]
                                    validMoves = chess.getValidMoves(tuple(markPos))
                                    
                                else:
                                    if markPos[0] != -1:
                                        res = chess.addMove(markPos,mousePos)
                                        if not res and chess.getReason() == chess.MUST_SET_PROMOTION:
                                            chess.setPromotion(chess.QUEEN)                                                
                                            res = chess.addMove(markPos,mousePos)                                            
                                        if res:
                                            #print chess.getLastMove()
                                            print chess.getLastTextMove(chess.SAN)
                                            board = chess.getBoard()
                                            turn = chess.getTurn()
                                            markPos[0] = -1
                                            validMoves = [] 

            if chess.isGameOver():
                pygame.display.set_caption("Game Over! (Reason:%s)" % gameResults[chess.getGameResult()])
                validMove = []
                markPos[0] = -1
                markPos[1] = -1
            else:
                pygame.display.set_caption('ChessBoard Client') 
                                            
            y = 0
            for rank in board:
                x = 0
                for p in rank:
                    screen.blit(pieces[(x+y)%2][p],(x*60,y*60))
                    x+=1
                y+=1             

            if markPos[0] != -1:
                posRect.left = markPos[0]*60
                posRect.top = markPos[1]*60
                pygame.draw.rect(screen, (255,255,0),posRect, 4)

            for v in validMoves:
                posRect.left = v[0]*60
                posRect.top = v[1]*60
                pygame.draw.rect(screen, (255,255,0),posRect, 4)
                                       
            pygame.display.flip()        
class GameState:
    def __init__(self,aSkillLevel,aMoveTime):
        """
        Create an object to hold the game state
        Use Chessboard library for logic
        """
        print "Game State Initilized"
        self.chessGame = ChessBoard()
        self.chessGame.resetBoard()
        self.chessGame.printBoard()
        self.moveTime = aMoveTime #Used to store movetime
        self.skillLevel = aSkillLevel #Used to store skill level
        self.gameMoves = [] #Used to store all moves in game
        self.saveFileExt = ".txt"
        self.saveFilePath = ""
        self.startPos = "startpos" #Used to store the start position or fen string

    def loadGameState(self,aFileName):
        """
        Load from file, game should be reset first
        """
        if len(self.gameMoves) == 0:
            #Game moves must be empty to load game
            try:
                aFile = open(self.saveFilePath + aFileName + self.saveFileExt,'r')
                for aLine in aFile:
                    if aLine[0] != '#':
                        self.gameMoves.append(aLine[0:4])
                        self.chessGame.addTextMove(aLine)
                aFile.close()
                #Show moves
                self.chessGame.printBoard()
            except IOError:
                print "File Error"
        else:
            #Game moves not empty
            print "Can't load game, has it been reset?"

    def loadFen(self,aFileName):
        """
        Load from file, game should be reset first
        """
        if len(self.gameMoves) == 0:
            #Game moves must be empty to load game
            try:
                fenInstruc = ""
                aFile = open(self.saveFilePath + aFileName + self.saveFileExt,'r')
                for aLine in aFile:
                    if aLine[0] == '$':
                        removeChar = aLine.strip('$') #remove the first char
                        removeChar = removeChar.strip('\n')
                        fenInstruc = fenInstruc + removeChar + " " #build any instructions for game
                    if aLine[0] == '!':
                        fenLine = aLine #found line with fen code
                        fenLine = fenLine.strip('!')
                        
                aFile.close()
                #Load fen line on to game board
                self.chessGame.setFEN(fenLine)
                print fenInstruc
                self.chessGame.printBoard()
                self.startPos = "fen " + fenLine #set startpos to fen line
            except IOError:
                print "File Error"
        else:
            #Game moves not empty
            print "Can't load FEN file, has it been reset?"

    def saveGameState(self,aFileName):
        """
        Save game moves to file
        """
        print "Saving game state"
        if len(self.gameMoves) > 0:
            #Have a game to save
            aFile = open(self.saveFilePath + aFileName + self.saveFileExt,'w')
            for aMove in self.gameMoves:
                aFile.write(aMove + "\n")
            aFile.close()
        else:
            #No moves stored, nothing to save
            print "No game to save"

    def getSkillLevel(self):
        """
        Return game state skill level as a string
        """
        return str(self.skillLevel)

    def getMoveTime(self):
        """
        Return movetime as a string
        """
        return str(self.moveTime)
    def getMoveList(self):
        """
        Return moves in list as a string 
        """
        moveString = ""
        for aMove in self.gameMoves:
            moveString = moveString + " " + aMove
        return moveString

    def addMove(self,chessMove):
        """
        Add chess move to game state 
        """
        theMove = chessMove.lower()
        if self.chessGame.addTextMove(theMove) == False:
            #Invalid move
            errorText = "Error in GameState:" + str(self.chessGame.getReason()) + " " + theMove
            print errorText
            self.chessGame.printBoard()
            theMove = "xxxx" #return something to catch if the move had an error
        else:
            #Move OK
            self.chessGame.printBoard()
            #Add the move to the list of moves for this game
            self.gameMoves.append(theMove)
        return theMove    
    def undoMove(self):
        """
        Undo the last move.  Will need to undo last two moves
        as the last move will be the engine's and then the players
        """
        if len(self.gameMoves) > 1:
            self.gameMoves.pop()
            self.gameMoves.pop()
            self.chessGame.undo()
            self.chessGame.undo()
            self.chessGame.printBoard()
            print "Last move undo"
        else:
            print "No moves to undo!"
    def getStartPos(self):
        """
        Return the current start positionof the game
        this will be 'startpos' or fen <some fen string>
        """
        return self.startPos
    def findLocation(self,aPiece):
        """
        Find the location of a Piece orPieces
        """
        pieceList = []
        rowNumber = 8
        theBoard = self.chessGame.getBoard()
        for eachRow in theBoard:
            columnNumber = 1
            for piece in eachRow:
                if piece == aPiece:
                    value = self.colToLetter(columnNumber) + str(rowNumber)
                    pieceList.append(value)
                columnNumber = columnNumber + 1
            rowNumber = rowNumber - 1 #rows inverted to match a chess board
        print pieceList
    def colToLetter(self,aNumber):
        """
        Convert column number to a letter
        """
        letter =""
        if aNumber == 1: letter = 'A'
        elif aNumber == 2: letter = 'B'
        elif aNumber == 3: letter = 'C'
        elif aNumber == 4: letter = 'D'
        elif aNumber == 5: letter = 'E'
        elif aNumber == 6: letter = 'F'
        elif aNumber == 7: letter = 'G'
        elif aNumber == 8: letter = 'H'
        return letter
Example #44
0
    def mainLoop(self):
        print("White Player, choose an army:")
        print("1. Classic   2. Nemesis   3. Empowered")
        print("4. Reaper 5. Two Kings 6. Animals")
        while True:
            print('Type the number, not the name.')
            userInput = getpass.getpass('> ')
            if userInput in string.digits:
                if int(userInput) < 7:
                    if int(userInput) > 0:
                        break
                print('Please enter only one of the above.')
            else:
                print('Please enter only one character')
        wArmy = userInput

        print("Black Player, choose an army:")
        print("1. Classic   2. Nemesis   3. Empowered")
        print("4. Reaper 5. Two Kings 6. Animals")
        while True:
            print('Type the number, not the name.')
            userInput = getpass.getpass('> ')
            if userInput in string.digits:
                if int(userInput) < 7:
                    if int(userInput) > 0:
                        break
                print('Please enter only one of the above.')
            else:
                print('Please enter only one of the above.')
        bArmy = userInput

        turn = 0
        chess = ChessBoard(int(wArmy), int(bArmy))

        prototype = []
        prototype.append('[Event "Sample Games"]')
        prototype.append('[Site "' + 'Fantasy Strike Website' '\"]')
        prototype.append('[Date "' + ".".join((time.strftime("%Y"), time.strftime("%m"), time.strftime("%d"))) + '"]')
        prototype.append('[Round "' + '-' + '"]')
        prototype.append('[White "' + chess.army_name_dict[int(wArmy)] + '"]')
        prototype.append('[Black "' + chess.army_name_dict[int(bArmy)] + '"]')

        while True:
            turn = chess.getTurn()
            board = chess.printBoard()
            for row in board:
                print(row)
            if not chess.isGameOver():
                if chess._turn == chess.BLACK:
                    curArmy = chess._black_army
                else:
                    curArmy = chess._white_army

                if chess._secondTurn:
                    print("{}'s Warrior King turn. Type your move, or type \"decline\" to skip.".format(str(chess.value_to_color_dict[turn])))
                else:
                    print("{}'s turn. Type your move.".format(str(chess.value_to_color_dict[turn])))

                move = input("> ")
                # Fully quit the program, regardless.
                if move == "exit":
                    sys.exit(0)
                # Save the current game as a pgn file.
                elif move == "save":
                    f = open('san.pgn', 'w')
                    acc = ""
                    save = chess.getAllTextMoves(chess.SAN)
                    for moves in save:
                        length, w, b = moves
                        if b is None:
                            b = ""
                        acc = acc + "{}. {} {} ".format(length, w, b)
                    pgn_details = prototype
                    pgn_details.append('[Result "' + chess.pgn_result_list[chess.getGameResult()] + '"]')
                    pgn_details.append('')
                    pgn_details.append(acc.rstrip())
                    for x in pgn_details:
                        f.write(str(x) + '\n')
                    f.close()
                elif any(var in move for var in ("SAN", "san")):
                    san = chess.getAllTextMoves(chess.SAN)
                    if san:
                        for moves in san:
                            length, x, y = moves
                            print("{}. {} {}".format(length, x, y))
                elif any(var in move for var in ("LAN", "lan")):
                    lan = chess.getAllTextMoves(chess.LAN)
                    if lan:
                        for moves in lan:
                            length, x, y = moves
                            print("{}. {} {}".format(length, x, y))
                elif any(var in move for var in ("AN", "an")):
                    an = chess.getAllTextMoves(chess.AN)
                    if an:
                        for moves in an:
                            length, x, y = moves
                            print("{}. {} {}".format(length, x, y))
                elif any(var in move for var in ("FEN", "fen")):
                    print(chess.getFEN())
                elif move == "set":
                    chess.setFEN(input("Paste FEN: "))
                elif move == "get": # Displaying available moves for a given space.
                    getter = input("> ")
                    print(str(getter))
                    try:
                        getter = chess.parseTextMove(getter)[3:5]
                        print(chess.getValidMoves(getter))
                    except: pass
                elif len(move) < 2:
                    print("Type a real move.")
                elif any(var in move for var in ("whirlwind", "ww", "Whirlwind", "WW")):
                    if curArmy == chess.TWOKINGS:
                        print("Which Warrior King performs the whirlwind?")
                        while True:
                            location = input("> ")
                            if location == "exit":
                                sys.exit(0)
                            elif len(location) != 2:
                                print("Please only enter the square.")
                            else:
                                res = chess.addTextMove("K" + location, secondTurn=chess._secondTurn, whirlwind=True)
                                if not res:
                                    print("Can't whirlwind there.")
                                turn = chess.getTurn()
                                break
                    else:
                        print("You're not playing Two Kings!")
                elif any(var in move for var in ("decline", "Decline", "skip", "s", "Skip", "S")):
                    if curArmy == chess.TWOKINGS:
                        if chess._secondTurn:
                            print("Second turn skipped.")
                            chess._secondTurn = False
                            if chess._turn == chess.BLACK:
                                chess._turn = chess.WHITE
                            else:
                                chess._turn = chess.BLACK
                            turn = chess.getTurn()
                    else:
                        print("You're not playing Two Kings!")
                else:
                    res = chess.checkTextMove(move)
                    # True: a correctly entered move
                    if res is True:
                        result = chess.addTextMove(move, secondTurn=chess._secondTurn)
                        if result:
                            turn = chess.getTurn()
                            chess.updateRoyalLocations()
                        elif chess.getReason() == chess.MUST_SET_PROMOTION:
                            print("{}, what do you want to promote to?".format(chess.value_to_color_dict[turn]))
                            print('Please enter the letter of the piece: QRNB.')
                            while True:
                                promo = input("> ")
                                promo = str(promo.upper())
                                if len(promo) == 1:
                                    if any(var in promo for var in ("Q", "R", "N", "B")):
                                        break
                                    print('Please enter the letter of the piece: QRNB.')
                                print('Please enter the letter of the piece: QRNB.')
                            result = chess.addTextMove(move+promo, secondTurn=chess._secondTurn)
                            if result:
                                turn = chess.getTurn()
                                chess.updateRoyalLocations()
                            else:
                                print("{}".format(chess.move_reason_list[chess.getReason()]))
                        else:
                            print("{}".format(chess.move_reason_list[chess.getReason()]))
                    # False: The move couldn't be parsed or is ambiguous or wrong
                    elif res is False:
                        print("{}".format(chess.move_reason_list[chess.getReason()]))
                    # Other: TIME TO DU-DU-DU-DUEL
                    else:
                        print("{}, would you like to initiate a duel? It will cost {}.".format(str(chess.value_to_color_dict[not turn]), res))
                        tmp_white = chess._white_stones
                        tmp_black = chess._black_stones
                        duel_cost = None
                        while True:
                            answer = input("> ")
                            if answer == "exit":
                                sys.exit(0)
                            # Duel initiation
                            elif any(var in answer for var in ('y', 'Y', 'Yes', 'yes')):
                                duel_cost = res
                                if turn == chess.WHITE:
                                    tmp_white = tmp_white + res
                                    tmp_att = tmp_white
                                    tmp_def = tmp_black
                                else:
                                    tmp_black = tmp_black + res
                                    tmp_att = tmp_black
                                    tmp_def = tmp_white
                                print("White stones: {}".format(tmp_white))
                                print("Black stones: {}".format(tmp_black))
                                print("{}, how much would you like to bid?".format(str(chess.value_to_color_dict[not turn])))
                                # Defender Bid
                                while True:
                                    defending_bid = getpass.getpass("> ")
                                    if defending_bid == "exit":
                                        sys.exit(0)
                                    elif defending_bid in string.digits:
                                        if int(defending_bid) <= min(2, tmp_def):
                                            if int(defending_bid) > -1:
                                                defending_bid = int(defending_bid)
                                                break
                                            print("Please only bid a number of stones between 0 and {}.".format(min(2, tmp_def)))
                                        print("Please only bid a number of stones between 0 and {}.".format(min(2, tmp_def)))
                                    else:
                                        print("Please only bid a number of stones between 0 and {}.".format(min(2, tmp_def)))
                                print("{}, how much would you like to bid?".format(str(chess.value_to_color_dict[turn])))
                                # Attacker Bid
                                while True:
                                    attacking_bid = getpass.getpass("> ")
                                    if attacking_bid == "exit":
                                        sys.exit(0)
                                    elif attacking_bid in string.digits:
                                        if int(attacking_bid) <= min(2, tmp_att):
                                            if int(attacking_bid) > -1:
                                                attacking_bid = int(attacking_bid)
                                                break
                                            print("Please only bid a number of stones between 0 and {}.".format(min(2, tmp_att)))
                                        print("Please only bid a number of stones between 0 and {}.".format(min(2, tmp_att)))
                                    else:
                                        print("Please only bid a number of stones between 0 and {}.".format(min(2, tmp_att)))
                                if attacking_bid == 0 and defending_bid == 0:
                                    duel_results = chess.BLUFF
                                elif attacking_bid >= defending_bid:
                                    duel_results = chess.ATT_WIN
                                else:
                                    duel_results = chess.DEF_WIN
                                # duel_results will now be either 0, 1, or 2
                                print("{} bid: {}".format(chess.value_to_color_dict[turn], attacking_bid))
                                print("{} bid: {}".format(chess.value_to_color_dict[not turn], defending_bid))
                                if duel_results == chess.BLUFF:
                                    print("{} called the bluff! Do you want to gain a stone or force {} to lose a stone?".format(
                                        chess.value_to_color_dict[turn], chess.value_to_color_dict[not turn]))
                                    while True:
                                        bluff_choice = input("> ")
                                        if bluff_choice == "exit":
                                            sys.exit(0)
                                        elif any(var in bluff_choice for var in ("g", "gain", "G", "Gain")):
                                            att_result = chess.addTextMove(move, secondTurn=chess._secondTurn, duel=str(duel_cost) + str(attacking_bid) + str(defending_bid) + "g")
                                            if att_result:
                                                turn = chess.getTurn()
                                                chess.updateRoyalLocations()
                                                break
                                            elif chess.getReason() == chess.MUST_SET_PROMOTION:
                                                print("{}, what do you want to promote to?".format(chess.value_to_color_dict[turn]))
                                                print('Please enter the letter of the piece: QRNB.')
                                                while True:
                                                    promo = input("> ")
                                                    promo = str(promo.upper())
                                                    if len(promo) == 1:
                                                        if any(var in promo for var in ("Q", "R", "N", "B")):
                                                            break
                                                        print('Please enter the letter of the piece: QRNB.')
                                                    print('Please enter the letter of the piece: QRNB.')
                                                att_result = chess.addTextMove(move+promo, secondTurn=chess._secondTurn, duel=str(duel_cost) + str(attacking_bid) + str(defending_bid) + "g")
                                                if att_result:
                                                    turn = chess.getTurn()
                                                    chess.updateRoyalLocations()
                                                else:
                                                    print("{}".format(chess.move_reason_list[chess.getReason()]))
                                                    break
                                            else:
                                                print("{}".format(chess.move_reason_list[chess.getReason()]))
                                                break
                                        elif any(var in bluff_choice for var in ("l", "lose", "L", "Lose")):
                                            att_result = chess.addTextMove(move, secondTurn=chess._secondTurn, duel=str(duel_cost) + str(attacking_bid) + str(defending_bid) + "l")
                                            if att_result:
                                                turn = chess.getTurn()
                                                chess.updateRoyalLocations()
                                                break
                                            elif chess.getReason() == chess.MUST_SET_PROMOTION:
                                                print("{}, what do you want to promote to?".format(chess.value_to_color_dict[turn]))
                                                print('Please enter the letter of the piece: QRNB.')
                                                while True:
                                                    promo = input("> ")
                                                    promo = str(promo.upper())
                                                    if len(promo) == 1:
                                                        if any(var in promo for var in ("Q", "R", "N", "B")):
                                                            break
                                                        print('Please enter the letter of the piece: QRNB.')
                                                    print('Please enter the letter of the piece: QRNB.')
                                                att_result = chess.addTextMove(move+promo, secondTurn=chess._secondTurn, duel=str(duel_cost) + str(attacking_bid) + str(defending_bid) + "l")
                                                if att_result:
                                                    turn = chess.getTurn()
                                                    chess.updateRoyalLocations()
                                                else:
                                                    print("{}".format(chess.move_reason_list[chess.getReason()]))
                                                    break
                                            else:
                                                print("{}".format(chess.move_reason_list[chess.getReason()]))
                                                break
                                        else:
                                            print('Please choose between gaining a stone and forcing a lose of a stone.')
                                elif duel_results == chess.ATT_WIN:
                                    print("Attacker wins!")
                                    att_result = chess.addTextMove(move, secondTurn=chess._secondTurn, duel=str(duel_cost) + str(attacking_bid) + str(defending_bid) + "n")
                                    if att_result:
                                        turn = chess.getTurn()
                                        chess.updateRoyalLocations()
                                    elif chess.getReason() == chess.MUST_SET_PROMOTION:
                                        print("{}, what do you want to promote to?".format(chess.value_to_color_dict[turn]))
                                        print('Please enter the letter of the piece: QRNB.')
                                        while True:
                                            promo = input("> ")
                                            promo = str(promo.upper())
                                            if len(promo) == 1:
                                                if any(var in promo for var in ("Q", "R", "N", "B")):
                                                    break
                                                print('Please enter the letter of the piece: QRNB.')
                                            print('Please enter the letter of the piece: QRNB.')
                                        att_result = chess.addTextMove(move+promo, secondTurn=chess._secondTurn, duel=str(duel_cost) + str(attacking_bid) + str(defending_bid) + "n")
                                        if att_result:
                                            turn = chess.getTurn()
                                            chess.updateRoyalLocations()
                                        else:
                                            print("{}".format(chess.move_reason_list[chess.getReason()]))
                                    else:
                                        print("{}".format(chess.move_reason_list[chess.getReason()]))
                                else:
                                    print("Defender wins!")
                                    att_result = chess.addTextMove(move, secondTurn=chess._secondTurn, clearLocation=True, duel=str(duel_cost) + str(attacking_bid) + str(defending_bid) + "n")
                                    if att_result:
                                        turn = chess.getTurn()
                                        chess.updateRoyalLocations()
                                    elif chess.getReason() == chess.MUST_SET_PROMOTION:
                                        print("{}, what do you want to promote to?".format(chess.value_to_color_dict[turn]))
                                        print('Please enter the letter of the piece: QRNB.')
                                        while True:
                                            promo = input("> ")
                                            promo = str(promo.upper())
                                            if len(promo) == 1:
                                                if any(var in promo for var in ("Q", "R", "N", "B")):
                                                    break
                                                print('Please enter the letter of the piece: QRNB.')
                                            print('Please enter the letter of the piece: QRNB.')
                                        att_result = chess.addTextMove(move+promo, secondTurn=chess._secondTurn, duel=str(duel_cost) + str(attacking_bid) + str(defending_bid) + "n")
                                        if att_result:
                                            turn = chess.getTurn()
                                            chess.updateRoyalLocations()
                                        else:
                                            print("{}".format(chess.move_reason_list[chess.getReason()]))
                                    else:
                                        print("{}".format(chess.move_reason_list[chess.getReason()]))
                                turn = chess.getTurn()
                                break
                            # Non-Duel initiation
                            elif any(var in answer for var in ('n', 'N', 'No', 'no')):
                                result = chess.addTextMove(move, secondTurn=chess._secondTurn)
                                if result:
                                    turn = chess.getTurn()
                                    chess.updateRoyalLocations()
                                elif chess.getReason() == chess.MUST_SET_PROMOTION:
                                    print("{}, what do you want to promote to?".format(chess.value_to_color_dict[turn]))
                                    print('Please enter the letter of the piece: QRNB.')
                                    while True:
                                        promo = input("> ")
                                        promo = str(promo.upper())
                                        if len(promo) == 1:
                                            if any(var in promo for var in ("Q", "R", "N", "B")):
                                                break
                                            print('Please enter the letter of the piece: QRNB.')
                                        print('Please enter the letter of the piece: QRNB.')
                                    result = chess.addTextMove(move+promo, secondTurn=chess._secondTurn)
                                    if result:
                                        turn = chess.getTurn()
                                        chess.updateRoyalLocations()
                                    else:
                                        print("{}".format(chess.move_reason_list[chess.getReason()]))
                                else:
                                    print("{}".format(chess.move_reason_list[chess.getReason()]))
                                break
                            else:
                                print('Please enter \'yes\' or \'no\'.')
                            break
            else:
                break
        f = open('san.pgn', 'w')
        acc = ""
        save = chess.getAllTextMoves(chess.SAN)
        for moves in save:
            length, w, b = moves
            if b is None:
                b = ""
            acc = acc + "{}. {} {} ".format(length, w, b)
        acc = acc + chess.pgn_result_list[chess.getGameResult()]
        pgn_details = prototype
        pgn_details.append('[Result "' + chess.pgn_result_list[chess.getGameResult()] + '"]')
        pgn_details.append('')
        pgn_details.append(acc.rstrip())
        for x in pgn_details:
            f.write(str(x) + '\n')
        f.close()
        print("Game over! {}".format(chess.game_result_list[chess.getGameResult()]))
Example #45
0
    def mainLoop(self):
        pygame.init()

        print "White Player, choose an army:"
        print "1. Classic   2. Nemesis   3. Reaper"
        print "4. Empowered 5. Two Kings 6. Animals"
        while True:
            userInput = raw_input('Type the number, not the name:')
            if userInput in string.digits:
                if int(userInput) < 7:
                    if int(userInput) > 0:
                        break
                print 'Please enter only one of the above.'
            else:
                print 'Please enter only one character'
        wArmy = userInput

        print "Black Player, choose an army:"
        print "1. Classic   2. Nemesis   3. Reaper"
        print "4. Empowered 5. Two Kings 6. Animals"
        while True:
            userInput = raw_input('Type the number, not the name:')
            if userInput in string.digits:
                if int(userInput) < 7:
                    if int(userInput) > 0:
                        break
                print 'Please enter only one of the above.'
            else:
                print 'Please enter only one of the above.'
        bArmy = userInput

        pieces = {}
        chess = ChessBoard(int(wArmy), int(bArmy))
        board = chess.getBoard()
        turn = chess.getTurn()

        screen = pygame.display.set_mode((840, 480), 1)
        pygame.display.set_caption('ChessBoard Client')

        # load all images
        # pieces format:
        # pieces[background id: 0 = white, 1 = black]["piece letter"]
        pieces = [{}, {}]
        pieces[0]["."] = pygame.image.load("./img/Generic/w.png")
        pieces[1]["."] = pygame.image.load("./img/Generic/b.png")

        # file names format:
        # (army color)(piece letter)(background color).png
        # white background
        for img in chess.piece_to_army_dict:
            for color in chess.color_dict:
                for back in chess.color_dict:
                    if color == 0:
                        pieces[back][img] = pygame.image.load(
                            "./img/" +
                            chess.piece_to_army_dict[img] + "/" +
                            chess.color_dict[color] + img.lower() +
                            chess.color_dict[back] + ".png")
                    else:
                        img = img.lower()
                        pieces[back][img] = pygame.image.load(
                            "./img/" +
                            chess.piece_to_army_dict[img.upper()] + "/" +
                            chess.color_dict[color] + img +
                            chess.color_dict[back] + ".png")

        clock = pygame.time.Clock()

        posRect = pygame.Rect(0, 0, 60, 60)
        sidebarRect = pygame.Rect(480, 0, 360, 480)

        mousePos = [-1, -1]
        markPos = [-1, -1]
        validMoves = []
        pieceSelected = None

        while 1:
            clock.tick(30)

            for event in pygame.event.get():
                if event.type == QUIT:
                    return
                elif event.type == KEYDOWN:
                    if event.key == K_ESCAPE:
                        return
                    elif event.key == K_LEFT:
                        chess.undo()
                    elif event.key == K_RIGHT:
                        chess.redo()
                    elif event.unicode in ("f", "F"):
                        print chess.getFEN()
                    elif event.unicode in ("a", "A"):
                        an = chess.getAllTextMoves(chess.AN)
                        if an:
                            print "AN: " + ", ".join(an)
                    elif event.unicode in ("s", "S"):
                        san = chess.getAllTextMoves(chess.SAN)
                        if san:
                            print "SAN: " + ", ".join(san)
                    elif event.unicode in ("l", "L"):
                        lan = chess.getAllTextMoves(chess.LAN)
                        if lan:
                            print "LAN: " + ", ".join(lan)
                    board = chess.getBoard()
                    turn = chess.getTurn()
                    markPos[0] = -1
                    validMoves = []

                if not chess.isGameOver():
                    if event.type == MOUSEMOTION:
                        mx = event.pos[0]
                        my = event.pos[1]
                        mousePos[0] = mx / 60
                        mousePos[1] = my / 60
                    elif event.type == MOUSEBUTTONDOWN:
                        if mousePos[0] != -1:
                            if markPos[0] == mousePos[0] and markPos[1] == mousePos[1]:
                                markPos[0] = -1
                                validMoves = []
                                pieceSelected = None
                            else:
                                if pieceSelected is None:
                                    if (turn == ChessBoard.WHITE and board[mousePos[1]][mousePos[0]].isupper()) or \
                                       (turn == ChessBoard.BLACK and board[mousePos[1]][mousePos[0]].islower()):
                                        markPos[0] = mousePos[0]
                                        markPos[1] = mousePos[1]
                                        validMoves = chess.getValidMoves(tuple(markPos))
                                        pieceSelected = board[markPos[1]][markPos[0]].upper
                                elif pieceSelected == ("H" or "E"):
                                    if markPos[0] != -1:
                                        res = chess.addMove(markPos, mousePos)
                                        if not res and chess.getReason() == chess.MUST_SET_PROMOTION:
                                            chess.setPromotion(chess.QUEEN)
                                            res = chess.addMove(markPos, mousePos)
                                        if res:
                                            print chess.getLastTextMove(chess.SAN)
                                            board = chess.getBoard()
                                            turn = chess.getTurn()
                                            chess.updateRoyalLocations()
                                            markPos[0] = -1
                                            validMoves = []
                                            pieceSelected = None
                                else:
                                    if markPos[0] != -1:
                                        res = chess.addMove(markPos, mousePos)
                                        if not res and chess.getReason() == chess.MUST_SET_PROMOTION:
                                            chess.setPromotion(chess.QUEEN)
                                            res = chess.addMove(markPos, mousePos)
                                        if res:
                                            print chess.getLastTextMove(chess.SAN)
                                            board = chess.getBoard()
                                            turn = chess.getTurn()
                                            chess.updateRoyalLocations()
                                            markPos[0] = -1
                                            validMoves = []
                                            pieceSelected = None

                if chess.isGameOver():
                    pygame.display.set_caption("Game Over! %s" % chess.game_result_dict[chess.getGameResult()])
                    validMove = []
                    markPos[0] = -1
                    markPos[1] = -1
                else:
                    pygame.display.set_caption('ChessBoard Client')

                y = 0
                for rank in board:
                    x = 0
                    for p in rank:
                        screen.blit(pieces[(x + y) % 2][p], (x * 60, y * 60))
                        x += 1
                    y += 1

                if markPos[0] != -1:
                    posRect.left = markPos[0] * 60
                    posRect.top = markPos[1] * 60
                    pygame.draw.rect(screen, (255, 255, 0), posRect, 4)

                for v in validMoves:
                    posRect.left = v[0] * 60
                    posRect.top = v[1] * 60
                    pygame.draw.rect(screen, (255, 255, 0), posRect, 4)

                pygame.draw.rect(screen, (0, 0, 0), sidebarRect, 0)
                pygame.display.flip()
Example #46
0
class Game:
    def __init__(self):
        pygame.init()
        self.game_display = pygame.display.set_mode((900, 650))
        pygame.display.set_caption('Chess')

        self.settings = {'board_image': 'images/orange_board.png'}
        self.board_image = pygame.image.load(self.settings['board_image'])

        self.clock = pygame.time.Clock()
        self.chess_board = ChessBoard()

        self.curr_selected_piece = None
        self.curr_poss_moves = []
        self.all_poss_moves = self.get_all_poss_moves()

        self.white_pieces_taken_images = []
        self.black_pieces_taken_images = []

        self.play_game()

    def play_game(self):
        """Loop that executes the game"""
        while True:

            # Draw whole window (and draw board)
            self.draw_window()

            for event in pygame.event.get():
                if event.type == pygame.QUIT:
                    quit()

                if event.type == pygame.MOUSEBUTTONUP:
                    # Get user click
                    self.get_user_click()

            # pygame.display.flip()
            self.clock.tick(60)

    def draw_window(self):
        """Draws everything in the window"""
        self.game_display.fill(white)
        # Draw side menu
        self.draw_side_menu()
        # Draw bottom menu
        # Draw board
        self.draw_board()
        pygame.display.update()

    def draw_side_menu(self):
        """Draws right side menu"""
        pygame.draw.rect(self.game_display, black, Rect((650, 100), (200, 400)), 5)

        # Draw box around current player
        if self.chess_board.curr_player == 'b':
            pygame.draw.rect(self.game_display, blue, Rect((700, 25), (100, 50)), 5)
        else:
            pygame.draw.rect(self.game_display, blue, Rect((700, 525), (100, 50)), 5)

        self.message_display('Black', (750, 50), fontsize=30)
        self.message_display('White', (750, 550), fontsize=30)

        # Display all moves played
        start = 0
        if len(self.get_all_played_moves()) > 10:
            start = len(self.get_all_played_moves()) - 10
        for i, move in enumerate(self.get_all_played_moves()[start:]):
            self.message_display(move, (740, 125 + (i * 30)), fontsize=20)
            start += 1

        # Display all black pieces taken
        for i, image in enumerate(self.black_pieces_taken_images):
            image = pygame.image.load(image)
            image = pygame.transform.scale(image, (30, 30))
            pos = 610 + i * 20, 5
            self.game_display.blit(image, pos)

        # Display all white pieces taken
        for i, image in enumerate(self.white_pieces_taken_images):
            image = pygame.image.load(image)
            image = pygame.transform.scale(image, (30, 30))
            pos = 610 + i * 20, 595
            self.game_display.blit(image, pos)

    def draw_board(self):
        """Draw chess board and all pieces on the board"""
        # Draw chess board
        self.game_display.blit(self.board_image, (0, 0))

        # Draw pieces on board
        for piece in self.chess_board.get_all_pieces():
            image_position = piece.position
            image_position = image_position[0] * 75, (7 - image_position[1]) * 75
            piece_image = pygame.image.load(piece.image)
            self.game_display.blit(piece_image, image_position)

        # Determine if piece is currently selected
        # If yes:
        if self.curr_selected_piece:
            # Highlight that piece
            box_x, box_y = self.convert_space_to_coordinates(self.curr_selected_piece.position)
            pygame.draw.rect(self.game_display, blue, Rect((box_x, box_y), (75, 75)), 5)
            # Display possible moves for that piece
            for move in self.curr_poss_moves:
                box1_x, box1_y = self.convert_space_to_coordinates(move)
                pygame.draw.rect(self.game_display, red, Rect((box1_x, box1_y), (75, 75)), 5)

    def get_user_click(self):
        """Analyze the position clicked by the user."""
        x, y = pygame.mouse.get_pos()
        # Determine if click is:
        # On bottom menu
        if y > 600:
            pass
        # On right side menu
        elif x > 600:
            pass
        # If on board:
        else:
            # Convert coordinates into space
            selected_space = self.convert_coordinates_to_space(x, y)
            # If piece is not already selected:
            if not self.curr_selected_piece:

                # Validate and set curr_selected_piece to this piece
                if self.is_piece_of_curr_player(selected_space):
                    self.new_piece_selected(selected_space)

            # Else if piece already selected:
            else:
                # Determine if selected space is in possible moves

                # If space is current selected space
                if selected_space == self.curr_selected_piece.position:
                    self.deselect_piece()

                # Else if space in possible moves:
                elif selected_space in self.curr_poss_moves:
                    #### Check if piece is a king!!! ###
                    # Check if selected space is king and in poss_castle_move
                    if self.curr_selected_piece.name == 'King' and selected_space in self.chess_board.get_castle_moves_for_curr_player():
                            # Castle that king
                            self.add_move(self.curr_selected_piece.position, selected_space)
                            self.chess_board.castle_king(self.curr_selected_piece, selected_space)

                    else:
                        # Move selected piece to this spot
                        self.add_move(self.curr_selected_piece.position, selected_space)
                        self.move_piece(self.curr_selected_piece, selected_space)

                        if self.curr_selected_piece.name == 'Pawn' and selected_space[1] == 0 or selected_space[1] == 7:
                            self.chess_board.board[selected_space[0]][selected_space[1]] = None
                            self.chess_board.board[selected_space[0]][selected_space[1]] = Queen(self.chess_board.curr_player, selected_space)

                    # Deselect current piece and remove poss moves
                    self.deselect_piece()
                    # Change current player
                    self.change_curr_player()

                    # Check for checkmate and get new list of all possible moves
                    self.all_poss_moves = self.get_all_poss_moves()
                    checkmate = True
                    for piece_pos in self.all_poss_moves:
                        if len(self.all_poss_moves[piece_pos]) != 0:
                            checkmate = False
                    if checkmate:
                        self.draw_window()
                        self.message_display('Checkmate!', (400, 300))
                        winner = 'White' if self.chess_board.curr_player == 'b' else 'Black'
                        self.message_display('%s wins!' % winner, (400, 400))
                        pygame.display.update()
                        time.sleep(2)
                        quit()

                # Else if another piece of curr player:
                elif selected_space in [piece.position for piece in self.chess_board.get_curr_player_pieces()]:
                    # Make that piece current selected piece
                    self.new_piece_selected(selected_space)

                # Else (random non-selectable space):
                else:
                    # Deselect current move
                    self.deselect_piece()

    def convert_coordinates_to_space(self, x, y):
        """Converts (x, y) coordinates to corresponding space on board"""
        # NOTE: Board is drawn upside down, so y axis is flipped
        return x // 75, 7 - y // 75

    def convert_space_to_coordinates(self, position):
        """Returns the top left corner coordinate corresponding to given chess spot"""
        return position[0] * 75, (7 - position[1]) * 75

    def is_piece_of_curr_player(self, space):
        """Returns if space holds a piece of current player"""
        for piece in self.chess_board.get_curr_player_pieces():
            if space == piece.position:
                return True

    def get_all_poss_moves(self):
        """Returns dictionary of all possible moves available. NOTE: will return empty list if checkmate"""
        # Creates dictionary of piece position to possible moves
        moves = {}
        pieces = self.chess_board.get_curr_player_pieces()
        for piece in pieces:
            p_moves = self.chess_board.get_poss_moves_for(piece)
            moves[piece.position] = self.chess_board.is_curr_player_in_check(piece, p_moves)
        return moves

    def get_curr_poss_moves(self):
        """Returns possible moves corresponding to cuurently selected piece"""
        return self.all_poss_moves[self.curr_selected_piece.position]

    def get_all_played_moves(self):
        return self.chess_board.played_moves

    def move_piece(self, piece, new_position):
        """Moves piece to new position and updates pieces taken"""
        # NOTE: This just moves piece, does not check if move is valid
        # Checks if piece is taken
        piece_captured = self.chess_board.move_piece(piece, new_position)
        if piece_captured:
            self.piece_was_captured(piece_captured)

    def change_curr_player(self):
        """Change current player between 'w' and 'b'"""
        self.chess_board.curr_player = 'w' if self.chess_board.curr_player == 'b' else 'b'

    def new_piece_selected(self, new_space):
        """Sets new space to curr_selected_piece and gets new moves for that piece"""
        self.curr_selected_piece = self.chess_board.get_piece_at(new_space)
        self.curr_poss_moves = self.get_curr_poss_moves()

    def deselect_piece(self):
        """Deselects current piece"""
        self.curr_selected_piece = None
        self.curr_poss_moves = None

    def add_move(self, pos_1, pos_2):
        """Add move to list of played moves"""
        name = self.chess_board.curr_player.upper() + ':     '
        move = name + self.convert_coordinate_to_space_name(pos_1) + ' -> ' + self.convert_coordinate_to_space_name(pos_2)
        self.chess_board.played_moves.append(move)

    def convert_coordinate_to_space_name(self, coordinate):
        """Returns converted name of position (ex: (1,3) -> 'B3')"""
        conversions = {0 : 'A', 1: 'B', 2: 'C', 3: 'D', 4: 'E', 5: 'F', 6: 'G', 7: 'H'}
        return str(conversions[coordinate[0]]) + str(coordinate[1] + 1)

    def piece_was_captured(self, piece):
        """Updates list of pieces taken to display on side menu"""
        if piece.color == 'w':
            self.white_pieces_taken_images.append(piece.image)
        else:
            self.black_pieces_taken_images.append(piece.image)

    def message_display(self, text, point, fontsize=90):
        """Displays message in window"""
        large_text = pygame.font.Font('freesansbold.ttf', fontsize)
        text_surface = large_text.render(text, True, black)
        text_rect = text_surface.get_rect()
        text_rect.center = (point)
        self.game_display.blit(text_surface, text_rect)
Example #47
0
    def mainLoop(self):
        pygame.init()

        pieces = {}
        chess = ChessBoard()
        board = chess.getBoard()
        turn = chess.getTurn()

        libro_activo = True
        libro_overwrite = False
        board_white = True

        book=OpeningBook.OpeningBook()

        letra=pygame.font.Font(None, 40)

        screen = pygame.display.set_mode((1024, self.tCasilla*8))
        pygame.display.set_caption('ChessBoard Client')

        # load all images
        pieces = [{},{}]
        pieces[0]["r"] = pygame.image.load("./img/br.png")
        pieces[0]["n"] = pygame.image.load("./img/bn.png")
        pieces[0]["b"] = pygame.image.load("./img/bb.png")
        pieces[0]["k"] = pygame.image.load("./img/bk.png")
        pieces[0]["q"] = pygame.image.load("./img/bq.png")
        pieces[0]["p"] = pygame.image.load("./img/bp.png")
        pieces[0]["R"] = pygame.image.load("./img/wr.png")
        pieces[0]["N"] = pygame.image.load("./img/wn.png")
        pieces[0]["B"] = pygame.image.load("./img/wb.png")
        pieces[0]["K"] = pygame.image.load("./img/wk.png")
        pieces[0]["Q"] = pygame.image.load("./img/wq.png")
        pieces[0]["P"] = pygame.image.load("./img/wp.png")
        pieces[0]["."] = pygame.image.load("./img/w.png")
        pieces[1]["r"] = pygame.image.load("./img/br.png")
        pieces[1]["n"] = pygame.image.load("./img/bn.png")
        pieces[1]["b"] = pygame.image.load("./img/bb.png")
        pieces[1]["k"] = pygame.image.load("./img/bk.png")
        pieces[1]["q"] = pygame.image.load("./img/bq.png")
        pieces[1]["p"] = pygame.image.load("./img/bp.png")
        pieces[1]["R"] = pygame.image.load("./img/wr.png")
        pieces[1]["N"] = pygame.image.load("./img/wn.png")
        pieces[1]["B"] = pygame.image.load("./img/wb.png")
        pieces[1]["K"] = pygame.image.load("./img/wk.png")
        pieces[1]["Q"] = pygame.image.load("./img/wq.png")
        pieces[1]["P"] = pygame.image.load("./img/wp.png")
        pieces[1]["."] = pygame.image.load("./img/b.png")

        clock = pygame.time.Clock()

        posRect = pygame.Rect(0,0,self.tCasilla,self.tCasilla)
        rectangulo = pygame.Rect(self.tCasilla*8+5,0,315,self.tCasilla*8)
        informacion = pygame.Rect(self.tCasilla*8+5,380,315,100)

        mousePos = [-1,-1]
        markPos = [-1,-1]
        validMoves = []

        gameResults = ["","WHITE WINS!","BLACK WINS!","STALEMATE","DRAW BY THE FIFTHY MOVES RULE","DRAW BY THE THREE REPETITION RULE"]

        letra_libro_activo = letra.render("Libro Activo", 1, (255, 255, 255))
        letra_libro_overwrite = letra.render("(Sobreescribir)", 1, (255, 255, 255))

        while 1:
            clock.tick(10)

            # Obtener la pos actual
            tablero=chess.getFEN()

            # Escribir el n de jugada
            num_jugada = str(chess.getCurrentMove()/2 + 1)
            if turn:
                num_jugada = num_jugada + ". ..., "
            else:
                num_jugada = num_jugada + ". "
            letra_num_jugada = letra.render(num_jugada, 1, (255, 255, 255))
            screen.blit(letra_num_jugada, (self.tCasilla*8+20, 30))

            # Obtener las jugadas almacenadas
            jugadas_teoricas = book.getMoves(tablero)

            # Si hay jugadas almacenadas, escrcribirlas
            if jugadas_teoricas != None:
                num_jugadas = len(jugadas_teoricas)
                contador = 0
                for jugada in jugadas_teoricas:
                    posx = self.tCasilla*8+20 +150*(contador%2)
                    posy = 100 + 40*(contador//2)
                    texto_jugada = letra.render(jugada+jugadas_teoricas[jugada], 1, (255, 255, 255))
                    screen.blit(texto_jugada, (posx, posy))
                    contador += 1

            # Si libro activo o activada sobreescritura, escribirlo
            if libro_activo:
                screen.blit(letra_libro_activo, (self.tCasilla*8+20, 400))
                if libro_overwrite:
                    screen.blit(letra_libro_overwrite, (self.tCasilla*8+20, 450))
            else:
                pygame.draw.rect(screen, (0, 0, 0), informacion)

            # Bucle de eventos
            for event in pygame.event.get():
                if event.type == QUIT:
                    return
                elif event.type == KEYDOWN:
                    if event.key == K_ESCAPE:
                        # La tecla ESC sale del programa
                        return
                    elif event.key == K_LEFT or event.key == K_o:
                        # La tecla LEFT retrocede una jugada
                        chess.undo()
                        pygame.draw.rect(screen, (0, 0, 0), rectangulo)
                    elif event.key == K_RIGHT or event.key == K_p:
                        # La tecla RIGHT avanza una jugada
                        chess.redo()
                        pygame.draw.rect(screen, (0, 0, 0), rectangulo)
                    elif event.key == K_UP or event.key == K_a:
                        # La tecla UP conmuta entre libro activado y desactivado
                        libro_activo = not libro_activo
                    elif event.key == K_DOWN or event.key == K_s:
                        # La tecla DOWN conmuta el estado de sobreescritura
                        libro_overwrite = not libro_overwrite
                    elif event.unicode in ("f","F"):
                        # La tecla F inprime la pos actual
                        print chess.getFEN()
                    elif event.unicode in ("t","T"):
                        # ?
                        #mykeys = virtkeyboard.VirtualKeyboard()
                        #print mykeys.run(screen, "Nfxh4+")
                        # Invierte el tablero
                        board_white = not board_white
                    elif event.unicode in ("a","A"):
                        # La tecla A imprime la lista de jugadas (AN)
                        an = chess.getAllTextMoves(chess.AN)
                        if an:
                            print "AN: " + ", ".join(an)
                    elif event.unicode in ("s","S"):
                        # La tecla S imprime la lista de jugadas (SAN)
                        san = chess.getAllTextMoves(chess.SAN)
                        if san:
                            print "SAN: " + ", ".join(san)
                    elif event.unicode in ("l","L"):
                        # La tecla L imprime la lista de jugadas (LAN)
                        lan = chess.getAllTextMoves(chess.LAN)
                        if lan:
                            print "LAN: " + ", ".join(lan)

                    board = chess.getBoard()
                    turn = chess.getTurn()
                    markPos[0] = -1
                    validMoves = []

                if not chess.isGameOver():
                    if event.type == MOUSEMOTION:
                        mx = event.pos[0]
                        my = event.pos[1]
                        mousePos[0] = mx/self.tCasilla
                        mousePos[1] = my/self.tCasilla
                        if not board_white:
                            mousePos[0] = 7 - mousePos[0]
                            mousePos[1] = 7 - mousePos[1]
                    elif event.type == MOUSEBUTTONDOWN:
                        if mousePos[0] >= 0 and mousePos[0] <= 7:
                            if markPos[0] == mousePos[0] and markPos[1] == mousePos[1]:
                                markPos[0] = -1
                                validMoves = []
                            else:
                                if (turn==ChessBoard.WHITE and board[mousePos[1]][mousePos[0]].isupper()) or \
                                   (turn==ChessBoard.BLACK and board[mousePos[1]][mousePos[0]].islower()):
                                    markPos[0] = mousePos[0]
                                    markPos[1] = mousePos[1]
                                    validMoves = chess.getValidMoves(tuple(markPos))

                                else:
                                    if markPos[0] != -1:
                                        res = chess.addMove(markPos,mousePos)
                                        if not res and chess.getReason() == chess.MUST_SET_PROMOTION:
                                            chess.setPromotion(chess.QUEEN)
                                            res = chess.addMove(markPos,mousePos)
                                        if res:
                                            jugada = chess.getLastTextMove(chess.SAN)
                                            # Almacenar la jugada si es nueva o si activado el modo OVERWRITE
                                            if libro_activo:
                                                if libro_overwrite or jugadas_teoricas == None or not jugadas_teoricas.has_key(jugada):
                                                    teclado = virtkeyboard.VirtualKeyboard()
                                                    valoracion = teclado.run(screen, jugada)
                                                    book.addMove(tablero, jugada, valoracion,libro_overwrite)
                                            board = chess.getBoard()
                                            turn = chess.getTurn()
                                            markPos[0] = -1
                                            validMoves = []
                                            pygame.draw.rect(screen, (0, 0, 0), rectangulo)

            if chess.isGameOver():
                pygame.display.set_caption("Game Over! (Reason:%s)" % gameResults[chess.getGameResult()])
                validMove = []
                markPos[0] = -1
                markPos[1] = -1
            else:
                pygame.display.set_caption('ChessBoard Client')

            y = 0
            for rank in board:
                x = 0
                for p in rank:
                    screen.blit(pieces[(x+y)%2]["."],(x*self.tCasilla,y*self.tCasilla))
                    if board_white:
                        screen.blit(pieces[(x+y)%2][p],(x*self.tCasilla,y*self.tCasilla))
                    else:
                        screen.blit(pieces[(x+y)%2][p],((7-x)*self.tCasilla,(7-y)*self.tCasilla))
                    x+=1
                y+=1

            if markPos[0] != -1:
                if board_white:
                    mP0 = markPos[0]
                    mP1 = markPos[1]
                else:
                    mP0 = 7 - markPos[0]
                    mP1 = 7 - markPos[1]
                posRect.left = mP0*self.tCasilla
                posRect.top = mP1*self.tCasilla
                pygame.draw.rect(screen, (255,255,0),posRect, 4)

            for v in validMoves:
                if board_white:
                    v0 = v[0]
                    v1 = v[1]
                else:
                    v0 = 7 - v[0]
                    v1 = 7 - v[1]
                posRect.left = v0*self.tCasilla
                posRect.top = v1*self.tCasilla
                pygame.draw.rect(screen, (255,255,0),posRect, 4)

            pygame.display.flip()
Example #48
0
class ChessGame(object):
    """
    A representation of a chess game tracked by an electronic board
    A ChessGame is able to rebuild a valid game from a sequence of
    events based on physical squares
    ! Not thread-safe
    """
    # XXX A move applied by a human must not be able to be undone by automatism
    # XXX TODO Possibility to associate a change index to a move index by human (all moves before are associated to "human")
    def __init__(self, x_size, y_size, log=None, initial_position=INITIAL_POSITION, max_pending_moves=MAX_PENDING_MOVES):
        """
        max_pending_moves :
            * Maximum number of last moves awaiting for mandatory changes before calling for help
            * Maximum number of moves a non-matched change waits before calling for help
        """
        # FIXME x_size and y_size are not verified against initial_position
        self.log_function = log or self.defaultLogFunction
        self.initial_position = initial_position
        self.max_pending_moves = max_pending_moves
        self.chessboard = ChessBoard(x_size, y_size)
        self.chessboard.initializeFEN(initial_position)
        self.move_history = []
        self.change_buffer = []
        self.pending_changes = []
        self.recording = False
        self.name = None
        self.last_ambiguous_change = None
        initial_repr = initial_position.split("/")
        initial_repr.reverse()
        self.change_history = [PhysicalBoardChange(0, None, None, None, initial_repr)]
        self.change_history_index = 0

    def __str__(self):
        return "Game(%s)" % (self.name or "NoName")

    def log(self, level, message, *args):
        """
        Logs a message
        """
        self.log_function(self, level, message, *args)
    def defaultLogFunction(self, obj, level, message, *args):
        """
        Default log function : it simply prints the message on stdout
        """
        print "[%s] - %s - %s" % (obj, level, message % args)

    def getTurn(self):
        return self.chessboard.turn


    def _getPieceColour(self, piece):
        """
        Internal method return the colour of a piece
        """
        if piece in "kqrbnp":
            return BLACK
        if piece in "KQRBNP":
            return WHITE
        raise Exception("Unknown piece : %s" % piece)


    def getValidatedDotFEN(self):
        """
        Returns the current validated position in FEN notation
        with dots in place of spaces
        """
        return self.chessboard.getFEN(dots=True)

    def getPhysicalDotFEN(self):
        """
        Returns the position on board in FEN notation
        with dots in place of spaces
        """
        board_repr = self.change_history[self.change_history_index].board_after
        return_list = []
        for i in range(len(board_repr)):
            return_list.insert(0,"".join(board_repr[i]))
        return "/".join(return_list)
            

    def getPGN(self):
        """
        Returns a PGN representation of the game (without headers)
        """
        return_string = ""
        for i in range(self.history_index+1):
            turn = i/2+1
            white_turn = i%2 == 0
            if white_turn:
                return_string += " %i." % turn
            return_string += " " + self.move_list[i]["short"] # XXX use history["last_move"]
        # XXX 0-1, 1-0 or 1/2-1/2
        return return_string.lstrip()


    def record(self, order):
        """
        Turns on or off recording. order is a boolean
        """
        self.recording = order


    def update(self, update_type, *args, **kw):
        """
        Updates the current game with given data
        The parameters depend on the update_type
        """
        f = getattr(self, "_update%s" % update_type.capitalize(), None)
        if f is not None and callable(f):
            return f(*args, **kw)
        raise Exception("Unknown update_type : %s" % update_type)


    def _updateSquare(self, x, y, new_piece):
        """
        Updates the current game with the given information :
        The square located on x,y has a new piece
        """
        # change_history[-1] because we append the new change to everything
        current_repr = self.change_history[-1].board_after
        current_piece = current_repr[y][x]
        inserted_change = None
        if current_piece == new_piece:
            self.log(VERBOSE, "Piece on %s,%s is already %s - skipping", x, y, new_piece)
            return
        if current_piece != "." and new_piece != ".":
            # Insert a change to free the square
            inserted_repr = current_repr[:]
            row = list(inserted_repr[y])
            row[x] = "."
            inserted_repr[y] = "".join(row)
            inserted_change = PhysicalBoardChange(len(self.change_history), ".", current_piece, Coordinate(x,y), inserted_repr)
            self.log(VERBOSE, "Receiving from board a change without freeing the square. Inserting a freeing change %s" % inserted_change)
            self.change_history.append(inserted_change)
            current_piece = "."

        new_repr = current_repr[:]
        row = list(new_repr[y])
        row[x] = new_piece
        new_repr[y] = "".join(row)
        current_change = PhysicalBoardChange(len(self.change_history), new_piece, current_piece, Coordinate(x,y), new_repr)
        self.log(VERBOSE, "New change from board : %s", current_change)
        self.change_history.append(current_change)
        if self.recording:
            if inserted_change is not None:
                self.log(VERBOSE, "Recording is on, handling the inserted change first")
                self.change_buffer.append(inserted_change) # XXX Only if pending_changes is empty
                self._handleChange(inserted_change)
            self.log(VERBOSE, "Recording is on, handling the new change")
            self.change_buffer.append(current_change) # XXX Only if pending_changes is empty
            self._handleChange(current_change)

            # Test if change_buffer is getting too big
            if len(self.change_buffer) > MAX_BUFFERED_CHANGES:
                self.log(ERROR, "change_buffer is too big. Undoing last move")
                undo()
                raise NeedHelp("Change buffer is too big. Something was wrong. Undid last move")

        else:
            if inserted_change is not None:
                self.log(VERBOSE, "Recording is off, storing the inserted change in pending_changes")
                self.pending_changes.append(inserted_change)
            self.log(VERBOSE, "Recording is off, storing the new change in pending_changes")
            self.pending_changes.append(current_change)


    def _handleChange(self, current_change):
        """
        Internal method used to treat the content of the change buffer
        and find associated moves
        The buffer is populated for each new arriving change while recording is on
        If recording is off, the buffer is not populated anymore, but another
        buffer is filled. When recording is set on again, the other buffer
        empties into change_buffer and each moved change is analyzed here.
        """
        # XXX Manage King positions to indicate game result
        # Search the change in change_buffer and operate only until it
        change_buffer = None
        for i in range(len(self.change_buffer)):
            if self.change_buffer[i].index == current_change.index:
                change_buffer = self.change_buffer[:i+1]
        if change_buffer is None:
            raise Exception("Change %s is not in change_buffer" % current_change)
        self.log(VERBOSE, "Handling change %s" % current_change)
        new_piece = current_change.piece
        old_piece = current_change.old_piece

        kw = {
            "current_change": current_change,
            "change_buffer" : change_buffer,
            "new_piece" : new_piece,
            "old_piece" : old_piece
        }

        # First search for a pending symmetrical move (i.e. "square empty" <-> "square gets a piece")
        if self._searchSymmetricalChange(**kw):
            return

        # Search for an awaited change from the previous moves
        for last_move in self.move_history[-self.max_pending_moves:]:
            for change in last_move.getAwaitedChanges():
                if change == current_change:
                    self.log(VERBOSE, "Found awaited change '%s' from previous move '%s'", current_change, last_move)
                    last_move.associateChange(current_change)
                    last_move.removeAwaitedChange(current_change)
                    removeExactChange(self.change_buffer, current_change)
                    return
            # Intermediate changes cannot occur after the ending change of a move :
            # - Promotion is done on the ending square
            # - Capture is done on the ending square, excepting for en passant,
            #       but in this case the change related to the removed Pawn is mandatory
            #       and registered as an initial move

        if new_piece == ".":
            # Look for a previous ambiguous change and try to solve it
            # with the current change
            if self._searchUnambiguatingChange(**kw):
                return
            self.log(VERBOSE, "Nothing found for change '%s'. Waiting next changes", current_change)
            return

        # A landing piece can be the "key" change for a move
        if self._getPieceColour(new_piece) == self.chessboard.turn:
            # The previous move was correct and the current player now plays
            if self._findMove(**kw):
                return
            # _findMove always returns True

        # The landed is of the same colour as the last played move
        if len(self.move_history)>0 and self.move_history[-1].index > current_change.index:
            self.log(VERBOSE, "Change %s occurred before Move %s and cannot replace it. Waiting for next changes", current_change, self.move_history[-1])
            return

        if len(self.move_history) == 0:
            self.log(VERBOSE, "The wrong player plays, but there are no move to undo. Waiting for next changes")
            return

        # The opponent player plays again !
        # It means the previous identified move was not ended
        # We need to cancel it and reiterate from the previous validated position
        self._cancelAndReiterate(**kw)


    def _searchSymmetricalChange(self, **kw):
        """
        Internal method
        """
        current_change = kw["current_change"]
        change_buffer = kw["change_buffer"]
        new_piece = kw["new_piece"]
        old_piece = kw["old_piece"]
        symmetrical_change = None
        for change in change_buffer[:-1]:
            if symmetrical_change is None:
                if change.coord == current_change.coord and \
                   ((new_piece == "." and change.piece == old_piece) or \
                    (new_piece == change.old_piece and change.piece == ".")):
                        symmetrical_change = change
        if symmetrical_change is not None:
            self.log(VERBOSE, "Found symmetrical change '%s' for '%s' : cancelling both", symmetrical_change, current_change)
            current_change.cancel(symmetrical_change)
            removeExactChange(self.change_buffer, symmetrical_change)
            removeExactChange(self.change_buffer, current_change)
            return True
        return False


    def _searchUnambiguatingChange(self, **kw):
        """
        Internal method
        """
        current_change = kw["current_change"]
        ambiguous_change = self.last_ambiguous_change
        if ambiguous_change is None:
            return False
        # Try to associate this starting change with previous ambiguous one
        index = findExactChange(self.change_buffer, ambiguous_change)
        if index is not None and index < current_change.index:
            self.log(VERBOSE, "Trying to move the currently handled change %s to index %s of change_buffer to resolve ambiguous change %s", current_change, index, ambiguous_change)
            removeExactChange(self.change_buffer, current_change)
            self.change_buffer.insert(index, current_change)
            self._handleChange(ambiguous_change)
            if findExactChange(self.change_buffer, current_change) is None:
                self.log(VERBOSE, "Change %s resolved previous ambiguous change %s !", current_change, ambiguous_change)
                return True
            else:
                self.log(VERBOSE, "Change %s did not resold ambiguous change. Resorting change_buffer", current_change)
                self.change_buffer.sort(key=lambda c: c.index)
        return False

            
    def _findMove(self, **kw):
        """
        Internal method
        """
        current_change = kw["current_change"]
        change_buffer = kw["change_buffer"]
        candidate_list = CandidateMoves(self.chessboard).getCandidates(current_change)
        if len(candidate_list) == 0:
            self.log(VERBOSE, "No candidate move for change '%s'. Waiting next changes", current_change)
            return True
        if len(candidate_list) > 1:
            # There are more than one possible candidate.
            # We search for corresponding initial changes
            self.log(VERBOSE, "Candidate moves for change '%s' : %s. Searching initial changes",
                     current_change, ";".join([str(m) for m in candidate_list]))
            new_candidate_list = []
            for candidate in candidate_list:
                if len([c for c in change_buffer[:-1] if c in candidate.initial_changes]) > 0:
                    new_candidate_list.append(candidate)
            if len(new_candidate_list) == 0:
                self.log(VERBOSE, "No potential initial change found. Waiting next changes")
                self.last_ambiguous_change = current_change
                return True
            if len(new_candidate_list) > 1:
                self.log(VERBOSE, "Moves found for '%s' : %s. Need human help",
                         current_change, ";".join([str(m) for m in new_candidate_list]))
                raise NeedHelp("Moves found for '%s' : %s" % (current_change, ";".join([str(m) for m in new_candidate_list])))

            # Found a single move, so apply it
            self.log(VERBOSE, "Move selected for '%s' : %s. Applying", current_change, new_candidate_list[0])
            self._applyMove(new_candidate_list[0], current_change.index)
            return True

        # Change not ambiguous
        self.log(VERBOSE, "Only move found for '%s' : %s. Applying", current_change, candidate_list[0])
        self._applyMove(candidate_list[0], current_change.index)
        return True


    def _cancelAndReiterate(self, **kw):
        """
        Internal method
        """
        current_change = kw["current_change"]
        self.log(VERBOSE, "The same player plays again. It means the latest move was wrong. Undoing it")
        self.undo()
        self.record(True)
        self.log(INFO, "Last move was undone because the same player has played again. Restarting _handleBuffer")
        self._handleChange(current_change)
        if current_change in self.change_buffer:
            self.log(VERBOSE, "We did an undo for %s, but could not determine a move. Rehandling all changes in change_buffer", current_change)
        else:
            self.log(VERBOSE, "%s needed an undo to be interpreted, rehandling all changes in change_buffer", current_change)
        for change in self.change_buffer[:]:
            # We work on a copy
            if change in self.change_buffer and change.index < current_change.index:
                self._handleChange(change)
        self.log(VERBOSE, "Rehandled all changes in change_buffer. End of handling for %s", current_change)


    def _applyMove(self, move, index):
        """
        Apply the given move, associate changes with it, and record the move in ChessBoard
        """
        # In this method we do some sanity checks to avoid strange behaviours
        # Do not hesitate to call for human help : players are human, then can do anything !
        self.log(INFO, "Applying move %s...", move)

        # Search the change in change_buffer and operate only until it
        change_buffer = None
        for i in range(len(self.change_buffer)):
            if self.change_buffer[i].index == index:
                change_buffer = self.change_buffer[:i+1]
        if change_buffer is None:
            raise Exception("Change index %s is not in change_buffer" % index)

        # First verify if there are no changes waiting for a while
        try:
            old_move = self.move_history[-self.max_pending_moves]
            awaited_changes = old_move.getAwaitedChanges()
            if len(awaited_changes) > 0:
                self.log(ERROR, "Still waiting changes '%s' for move '%s'. Something is wrong",
                         ";".join([str(c) for c in awaited_changes]), old_move)
                for i in range(self.max_pending_moves):
                    self.undo()
                raise NeedHelp("Still waiting changes '%s' for move '%s'. Undid %s last moves " % (
                               ";".join([str(c) for c in awaited_changes]), old_move, self.max_pending_moves))
        except IndexError:
            # Simply no old moves
            old_move = None

        # Apply the move itself and associate it with changes
        move.setIndex(index)
        self.chessboard.makeMove(move.short_notation)
        awaited_changes = set(move.initial_changes) | set(move.final_changes)
        intermediate_changes = set(move.intermediate_changes)
        for change in change_buffer:
            if change in awaited_changes:
                self.log(VERBOSE, "Consuming mandatory change %s", change)
                awaited_changes.remove(change)
                move.associateChange(change)
                removeExactChange(self.change_buffer, change)
            elif change in intermediate_changes:
                self.log(VERBOSE, "Consuming intermediate change %s", change)
                move.associateChange(change)
                removeExactChange(self.change_buffer, change)
            else:
                self.log(VERBOSE, "Change %s is independent from move %s", change, move)
        self.log(VERBOSE, "Still awaited changes after consuming existing ones : %s", ";".join([str(c) for c in awaited_changes]))
        move.setAwaitedChanges(*awaited_changes)
        self.move_history.append(move)

        # Finally check if some changes in buffer are too old
        for change in self.change_buffer:
            change.age += 1
            if change.age >= self.max_pending_moves:
                self.log(ERROR, "Change '%s' is too old. Something is wrong", change)
                for i in range(self.max_pending_moves):
                    self.undo()
                raise NeedHelp("Change '%s' is too old. Something is wrong. " % (change) +
                               "Undid %s last moves" % self.max_pending_moves)


    def undo(self):
        """
        Undo the last move, replace the associated changes in the buffer,
        and stop the recording to wait a human intervention
        """
        if len(self.move_history) == 0:
            # XXX exception ?
            return
        self.record(False)
        last_move = self.move_history.pop()
        for change in self.change_buffer:
            change.age -= 1
        self.log(INFO, "Undoing move %s", last_move)
        unassociated_changes = last_move.associated_changes
        index = last_move.index
        for change in unassociated_changes:
            self.log(VERBOSE, "Unassociating change %s", change)
            change.unassociate()
            #if change.index > index:
            #    self.log(VERBOSE, "Change %s is placed in pending_changes", change)
            #    self.pending_changes.append(change)
            #else:
            self.log(VERBOSE, "Change %s is placed in change_buffer", change)
            self.change_buffer.append(change)
        #for change in self.change_buffer[:]:
        #    if change.index > index:
        #        self.log(VERBOSE, "Moving change %s from change_buffer to pending_change", change)
        #        self.pending_changes.append(change)
        #        self.change_buffer.remove(change)
        #self.pending_changes.sort(key=lambda c: c.index)
        self.change_buffer.sort(key=lambda c: c.index)
        self.chessboard.undo()
        self.log(INFO, "Move %s is undone", last_move)
Example #49
0
class UserInterface:

	ROTATIONS_RIGHT = 2

	STATE_WAITING_FOR_START_POS = 0
	STATE_WAITING_FOR_BOARD_CHANGE = 1
	STATE_WAITING_FOR_ENGINE = 2
	STATE_GAME_OVER = 3

	def __init__(self):
		self.state = UserInterface.STATE_WAITING_FOR_START_POS
		self.engine = ChessEngine()
		self.startingPos = np.array(
			[[-1,-1,-1,-1,-1,-1,-1,-1],
			[-1,-1,-1,-1,-1,-1,-1,-1],
			[ 0, 0, 0, 0, 0, 0, 0, 0],
			[ 0, 0, 0, 0, 0, 0, 0, 0],
			[ 0, 0, 0, 0, 0, 0, 0, 0],
			[ 0, 0, 0, 0, 0, 0, 0, 0],
			[ 1, 1, 1, 1, 1, 1, 1, 1],
			[ 1, 1, 1, 1, 1, 1, 1, 1]], np.int8)
		if sys.platform == 'darwin':
			self.cv = MockCV()
			UserInterface.ROTATIONS_RIGHT = 0
		else:
			self.cv = ChessCV()
		self.cv.continuous = True
		thread.start_new_thread(self.cvThread, (self,))
		self.boardscan = np.ndarray(shape=(8,8), dtype=np.int8)
		self.boardscan.fill(0)
		self.chess = None
		self.lastFullScreenToggle = 0
		self.boardScale = 2
		self.considering = []
		self.lastConsider = None
		self.requestedMove = None
		self.dirtyUi = True
		pygame.init()
		#self.screen = pygame.display.set_mode((800, 800))
		#self.screen = pygame.display.set_mode((1824, 1016))
		self.screen = pygame.display.set_mode((0,0), pygame.FULLSCREEN)

		self.bgimage = pygame.image.load("./img/background.png")
		self.light_sabers = pygame.image.load("./img/light_sabers2.png")
		self.would_you_like_to_play = pygame.image.load("./img/headings/would_you_like_to_play.png")
		self.checkmate_suckah = pygame.image.load("./img/headings/checkmate_suckah.png")
		self.my_turn = pygame.image.load("./img/headings/my_turn.png")
		self.my_turn_move_piece = pygame.image.load("./img/headings/my_turn_move_piece.png")
		self.one_moment_please = pygame.image.load("./img/headings/one_moment_please.png")
		self.would_you_like_to_play = pygame.image.load("./img/headings/would_you_like_to_play.png")
		self.your_turn = pygame.image.load("./img/headings/your_turn.png")
		self.your_turn_cheater = pygame.image.load("./img/headings/your_turn_cheater.png")

		self.check = pygame.image.load("./img/bottom_headers/check.png")
		self.checkmate_suckah = pygame.image.load("./img/bottom_headers/checkmate_suckah.png")

		self.topHeading = None
		self.bottomHeading = None
		self.boardbg = self.loadImage("board_v2.gif")
		self.pieces = {}
		self.pieces['r'] = self.loadImage("br.png")
		self.pieces['n'] = self.loadImage("bn.png")
		self.pieces['b'] = self.loadImage("bb.png")
		self.pieces['k'] = self.loadImage("bk.png")
		self.pieces['q'] = self.loadImage("bq.png")
		self.pieces['p'] = self.loadImage("bp.png")
		self.pieces['R'] = self.loadImage("wr.png")
		self.pieces['N'] = self.loadImage("wn.png")
		self.pieces['B'] = self.loadImage("wb.png")
		self.pieces['K'] = self.loadImage("wk.png")
		self.pieces['Q'] = self.loadImage("wq.png")
		self.pieces['P'] = self.loadImage("wp.png")
		pygame.display.flip()

	def loadImage(self, file):
		img = pygame.image.load("./img/%s" % file).convert(32, pygame.SRCALPHA)
		rect = img.get_rect()
		return pygame.transform.smoothscale(img, (int(rect.w * self.boardScale), int(rect.h * self.boardScale)))

	def getFont(self, size):
		return pygame.font.SysFont("freesans", size, bold=True)

	def mainLoop(self):    
		clock = pygame.time.Clock()
		self.renderBoard()

		while 1:
			clock.tick(30)

			for event in pygame.event.get():
				if event.type == QUIT:
					return
				elif event.type == KEYDOWN:
					print event.key
					if event.key == K_ESCAPE:
						return
					if event.key == 102: # F
						if time.time() - self.lastFullScreenToggle > 1:
							self.lastFullScreenToggle = time.time() 
							pygame.display.toggle_fullscreen()
					if event.key == 32: # space
						self.cv.snapshot = True
					if event.key == 49:	# 1
						self.cv.set_board(self.startingPos.copy())
					if event.key == 50:	# 2
						self.cv.set_board(np.array(
							[[-1,-1,-1,-1,-1,-1,-1,-1],
							[-1,-1,-1,-1,-1,-1,-1,-1],
							[ 0, 0, 0, 0, 0, 0, 0, 0],
							[ 0, 0, 0, 0, 0, 0, 0, 0],
							[ 0, 0, 0, 0, 1, 0, 0, 0],
							[ 0, 0, 0, 0, 0, 0, 0, 0],
							[ 1, 1, 1, 1, 0, 1, 1, 1],
							[ 1, 1, 1, 1, 1, 1, 1, 1]], np.int8))
					if event.key == 51:	# 3
						self.cv.set_board(np.array(
							[[-1,-1,-1,-1,-1,-1,-1,-1],
							[-1,-1,-1, 0,-1,-1,-1,-1],
							[ 0, 0, 0, 0, 0, 0, 0, 0],
							[ 0, 0, 0,-1, 0, 0, 0, 0],
							[ 0, 0, 0, 0, 1, 0, 0, 0],
							[ 0, 0, 0, 0, 0, 0, 0, 0],
							[ 1, 1, 1, 1, 0, 1, 1, 1],
							[ 1, 1, 1, 1, 1, 1, 1, 1]], np.int8))
					if event.key == 52:	# 4
						self.cv.set_board(np.array(
							[[-1,-1,-1,-1,-1,-1,-1,-1],
							[-1,-1,-1, 0,-1,-1,-1,-1],
							[ 0, 0, 0, 0, 0, 0, 0, 0],
							[ 0, 0, 0, 1, 0, 0, 0, 0],
							[ 0, 0, 0, 0, 0, 0, 0, 0],
							[ 0, 0, 0, 0, 0, 0, 0, 0],
							[ 1, 1, 1, 1, 0, 1, 1, 1],
							[ 1, 1, 1, 1, 1, 1, 1, 1]], np.int8))
			self.gameTick()


	def gameTick(self):
		self.updateConsideringLine()
		if self.state == UserInterface.STATE_WAITING_FOR_START_POS:
			if np.array_equal(self.boardscan, self.startingPos):
				print "NEW GAME: Creating chess board"
				self.chess = ChessBoard()
				self.lastBoardscan = self.boardscan
				self.engine.newGame()
				self.topHeading = self.your_turn
				self.dirtyUi = True
				self.state = UserInterface.STATE_WAITING_FOR_BOARD_CHANGE
		elif self.state == UserInterface.STATE_WAITING_FOR_ENGINE:
			if self.engine.bestmove is not None:
				self.requestedMove = self.engine.bestmove
				self.considering = []
				self.state = UserInterface.STATE_WAITING_FOR_BOARD_CHANGE
				self.topHeading = self.my_turn_move_piece
				self.dirtyUi = True
			self.renderBoard()
		elif self.state == UserInterface.STATE_WAITING_FOR_BOARD_CHANGE:
			changes = self.boardscan - self.lastBoardscan
			numChanges = np.count_nonzero(changes)
			if numChanges == 2 or numChanges == 3 or numChanges == 4:
				self.dirtyUi = True
				print ""
				print "changes:\n" + str(changes)
				moveFrom = ()
				moveTo = ()
				nonzeroChanges = changes.nonzero()
				print "nonzeroChanges: " + str(nonzeroChanges)
				print "len(nonzeroChanges[0]) = %d" % len(nonzeroChanges[0])
				for i in range(len(nonzeroChanges[0])):
					change = (nonzeroChanges[1][i], nonzeroChanges[0][i])
					value = changes[change[1], change[0]]
					colorBefore = self.lastBoardscan[change[1], change[0]]
					print "\tchange: %s\tvalue: %s\tcolorBefore: %s" % (str(change), value, colorBefore)
					if self.chess.getTurn() == ChessBoard.WHITE:
						# WHITE's turn
						if value == -1:
							if numChanges != 4 or (change == (4,7)):
								moveFrom = change
						else:
							if numChanges == 4:
								if change == (6,7) or change == (2,7):
									moveTo = change
							elif numChanges == 3:
								if colorBefore == 0:
									moveTo = change
							else:
								moveTo = change
					else:
						# BLACK's turn
						if value == 1:
							if numChanges != 4 or (change == (4,0)):
								print "setting moveFrom to ", change
								moveFrom = change
						else:
							if numChanges == 4:
								if change == (6,0) or change == (2,0):
									print "setting moveTo to ", change
									moveTo = change
							elif numChanges == 3:
								if colorBefore == 0:
									print "setting moveTo to ", change
									moveTo = change
							else:
								moveTo = change
				print "moveFrom: " + str(moveFrom)
				print "moveTo:   " + str(moveTo)
				if moveFrom and moveTo:
					print "getTurn before:", self.chess.getTurn()
					result = self.chess.addMove(moveFrom, moveTo)
					print "getTurn after:", self.chess.getTurn()
					if result is False:
						print "Could not make move: ", self.chess.getReason()
					else:
						lastMove = string.replace(self.chess.getLastTextMove(ChessBoard.AN), '-', '')
						cheater = False
						if self.requestedMove is not None and self.requestedMove != lastMove:
							cheater = True
						if self.chess.isCheck():
							print "**** CHECK ****"
							self.bottomHeading = self.check
						else:
							self.bottomHeading = None
						self.requestedMove = None
						self.lastBoardscan = self.boardscan
						self.chess.printBoard()
						print "Last move type: " + str(self.chess.getLastMoveType())
						print "New FEN: " + self.chess.getFEN()
						# Check if game is over
						if self.chess.isGameOver():
							result = self.chess.getGameResult()
							if result == ChessBoard.WHITE_WIN:
								print "**** WHITE WINS ****"
							elif result == ChessBoard.BLACK_WIN:
								print "**** BLACK WINS ****"
								self.bottomHeading = self.checkmate_suckah
							else:
								print "**** STALEMATE ****"
							self.state = UserInterface.STATE_GAME_OVER
						elif self.chess.getTurn() == ChessBoard.BLACK:
							# It's black's turn, engage the engine
							self.topHeading = self.one_moment_please
							self.engine.makeMove(self.chess.getFEN())
							self.state = UserInterface.STATE_WAITING_FOR_ENGINE
						else:
							if cheater:
								self.topHeading = self.your_turn_cheater
							else:
								self.topHeading = self.your_turn
						self.renderBoard()

			elif numChanges != 0:
				print "Invalid number of board changes: ", numChanges
				self.cv.reset_board()
			# Set boardscan to the last one just so we don't keep analyzing it until next scan comes in
			self.boardscan = self.lastBoardscan
			self.renderBoard()


	def updateConsideringLine(self):
		now = time.time()
		engine_considering = self.engine.considering
		if self.state == UserInterface.STATE_WAITING_FOR_ENGINE and engine_considering is not None:
			if len(self.engine.considering) > 0:
				latest = engine_considering[0]
				if len(latest) == 0:
					engine_considering.pop()
					self.considering = []
					self.updateConsideringLine()
					return
				self.considering.append(latest.pop())
			self.lastConsider = now
			self.dirtyUi = True
			self.renderBoard()


	def renderBoard(self):

		if not self.dirtyUi:
			return

		self.dirtyUi = False

		self.screen.blit(self.bgimage, (0,0))
		if self.chess is None:
			self.screen.blit(self.would_you_like_to_play, (587, 395))
			pygame.display.flip()
			return
			
		files = 'abcdefgh'
		boardOffsetX = 64
		boardOffsetY = 64
		square_size = self.pieces['r'].get_rect().w

		# First the background
		bgsize = self.boardbg.get_rect().w
		for y in range(4):
			for x in range(4):
				self.screen.blit(self.boardbg, (boardOffsetX+x*bgsize, boardOffsetY+y*bgsize))

		# Render the pieces
		y = 0
		for rank in self.chess.getBoard():
			x = 0
			for p in rank:
				if p != '.':
					self.screen.blit(self.pieces[p],(boardOffsetX+x*square_size, boardOffsetY+y*square_size))
				x += 1
			y += 1

		# Heading
		if self.topHeading is not None:
			self.screen.blit(self.topHeading, (1105, 84))

		# Sabers
		self.screen.blit(self.light_sabers, (1105, 84 + 140))

		# Render considering moves (if any)
		if len(self.considering) > 0:
			for move in self.considering:
				x1 = boardOffsetX+files.find(move[0])*square_size+int(square_size/2)
				y1 = boardOffsetY+((8-int(move[1]))*square_size)+int(square_size/2)
				x2 = boardOffsetX+files.find(move[2])*square_size+int(square_size/2)
				y2 = boardOffsetY+((8-int(move[3]))*square_size)+int(square_size/2)
				pygame.draw.line(self.screen, (164, 119, 131), (x1,y1), (x2,y2), 15)
				pygame.draw.circle(self.screen, (127, 91, 102), (x1,y1), 15)
				pygame.draw.circle(self.screen, (127, 91, 102), (x2,y2), 15)

		# Render requested move (if any)
		if self.requestedMove is not None:
			x1 = boardOffsetX+files.find(self.requestedMove[0])*square_size+int(square_size/2)
			y1 = boardOffsetY+((8-int(self.requestedMove[1]))*square_size)+int(square_size/2)
			x2 = boardOffsetX+files.find(self.requestedMove[2])*square_size+int(square_size/2)
			y2 = boardOffsetY+((8-int(self.requestedMove[3]))*square_size)+int(square_size/2)
			pygame.draw.line(self.screen, (229, 72, 84), (x1,y1), (x2,y2), 15)
			pygame.draw.circle(self.screen, (173, 58, 75), (x2,y2), 15)
			# Redraw piece on "from" square so line comes from underneath it (but covers other pieces, potentially)
			y = 8-int(self.requestedMove[1])
			x = files.find(self.requestedMove[0])
			piece = self.chess.getBoard()[y][x]
			self.screen.blit(self.pieces[piece],(boardOffsetX+x*square_size, boardOffsetY+y*square_size))

		# Bottom heading
		if self.bottomHeading is not None:
			self.screen.blit(self.bottomHeading, (1105, 84 + 140 + 165 + 403))

		# Render chess moves
		color = (255, 255, 255)
		x = 1105
		startY = 84 + 140 + 165
		y = startY
		font = self.getFont(20)
		allMoves = self.chess.getAllTextMoves(ChessBoard.LAN)
		if allMoves is not None:
			whiteMoves = allMoves[0::2]
			blackMoves = allMoves[1::2]
			num = 1
			for move in whiteMoves:
				txt = "%d.  %s" % (num, move)
				if num < 10:
					txt = " " + txt
				fs = font.render(txt, True, color)
				self.screen.blit(fs, (x, y))
				y += 25
				num = num + 1
				if y > startY + 403:
					break
			x += 200
			y = startY
			for move in blackMoves:
				fs = font.render(move, True, color)
				self.screen.blit(fs, (x, y))
				y += 25
				if y > startY + 403:
					break


		pygame.display.flip()

				
	def cvThread(self, cv):
		while True:
			try:
				if self.state == UserInterface.STATE_WAITING_FOR_BOARD_CHANGE or self.state == UserInterface.STATE_WAITING_FOR_START_POS:
					if self.cv.continuous == True or self.cv.snapshot == True:
						self.cv.snapshot = False
						sys.stdout.write('.')
						sys.stdout.flush()
						board = self.cv.current_board()
						if board is not None:
							self.boardscan = np.rot90(board, UserInterface.ROTATIONS_RIGHT)
			except Exception, e:
				print e
			time.sleep(0.25)
Example #50
0
#!/usr/bin/python  
# Hello World from Python
from ChessBoard import ChessBoard

def solveBoard(board):
    if(board.isSolved()):
        return True
    else:
        curr_Pos = board.curr_Pos()
        moves = board.nextMove()
        for move in moves:
            x = move[0]
            y = move[1]
            board.add_Move(x, y)
            if(solveBoard(board)):
                return True
            else:
                board.remove_Last()
                #print "Reversing"
        return False

for i in xrange(8):
    x = ChessBoard()
    x.add_Move(i, 0)
    solveBoard(x)
#next = x.nextMove()
#print next
    x.printGrid()
    print " "
Example #51
0
class ChessGame:
    def __init__(self, player_white, player_black):
        self.board = ChessBoard()
        self.board.set_start_position()
        self.player_white = player_white
        self.player_black = player_black
        self.move_number = 1
        self.previous_board = copy.deepcopy(self.board)
        self.result_notation_text = ''

        self.is_white_check = False
        self.is_black_check = False

        self.possible_white_long_castling = True
        self.possible_white_short_castling = True
        self.possible_black_long_castling = True
        self.possible_black_short_castling = True

        # self.move_correct_checkers = {ChessPieceType.Pawn: self.is_pawn_move_correct,
        #     ChessPieceType.Rook: self.is_rook_move_correct,
        #     ChessPieceType.Bishop: self.is_bishop_move_correct,
        #     ChessPieceType.Queen: self.is_queen_move_is_correct,
        #     ChessPieceType.King: self.is_king_move_correct,
        #     ChessPieceType.Knight: self.is_knight_move_correct}

    def can_this_color_fix_check(self, color):
        if self.whose_turn() != color:
            return False
        for i in range(BOARD_SIZE):
            for j in range(BOARD_SIZE):
                if not self.board.is_empty(i, j):
                    if self.board.get_piece(i, j).get_color() == color:
                        for k in range(BOARD_SIZE):
                            for l in range(BOARD_SIZE):
                                if self.is_move_correct(i, j, k, l):
                                    attacked_piece = None
                                    if not self.board.is_empty(k, l):
                                        attacked_piece = self.board.get_piece(k, l)
                                    self.board.move_piece(i, j, k, l)
                                    if not self.is_check(color):
                                        self.board.move_piece(k, l, i, j)
                                        self.board.set_piece(k, l, attacked_piece)
                                        return True
                                    self.board.move_piece(k, l, i, j)
                                    self.board.set_piece(k, l, attacked_piece)
        return False

    def move(self, source_x, source_y, destination_x, destination_y):
        if self.board.is_empty(source_x, source_y):
            raise ChessException('Empty source square')
        source_color = self.board.get_piece(source_x, source_y).get_color()
        if self.whose_turn() != source_color:
            raise ChessException("It's "+str(source_color.get_another_color())+' turn!')

        if not self.is_move_correct(source_x, source_y, destination_x, destination_y):
            raise ChessException("Incorrect move")

        # Если это рокировка, то ладью тоже нужно передвинуть
        #self.previous_board = copy.deepcopy(self.board)
        if self.check_castling(source_x, source_y, destination_x, destination_y):
            if destination_x < source_x:
                rook_x = 0
            else:
                rook_x = BOARD_SIZE - 1
                # destination_x может быть равна только 3 или 5

            self.add_step_to_notation_if_castling(source_x, source_y, destination_x, destination_y)
            self.board.move_piece(rook_x, source_y, 3 + 2 * sign(rook_x), source_y)
        else:
            self.add_step_to_notation(source_x, source_y, destination_x, destination_y)

        self.board.move_piece(source_x, source_y, destination_x, destination_y)
        self.move_number += 1
        black_mate = self.is_mate(ChessColor.Black)
        white_mate = self.is_mate(ChessColor.White)
        if black_mate or white_mate:
            self.result_notation_text += '#'
        # Если ход был сделан Ладьей или Королем, исключаем дальнейшую возможность соответствующих рокировок
        if (source_x, source_y) == (0, 0) or (source_x, source_y) == (4, 0) or (destination_x, destination_y) == (0, 0):
            self.possible_white_long_castling = False
        if (source_x, source_y) == (7, 0) or (source_x, source_y) == (4, 0) or (destination_x, destination_y) == (7, 0):
            self.possible_white_short_castling = False
        if (source_x, source_y) == (0, 7) or (source_x, source_y) == (4, 7) or (destination_x, destination_y) == (0, 7):
            self.possible_black_long_castling = False
        if (source_x, source_y) == (7, 7) or (source_x, source_y) == (4, 7) or (destination_x, destination_y) == (7, 7):
            self.possible_black_short_castling = False

        if self.is_check(ChessColor.Black):
            self.is_black_check = True
        elif self.is_black_check:
            self.is_black_check = False
        if self.is_check(ChessColor.White):
            self.is_white_check = True
        elif self.is_white_check:
            self.is_white_check = False

        #print(self.squares_changed_last_move())

    def squares_changed_last_move(self):
        result = []
        for i in range(BOARD_SIZE):
            for j in range(BOARD_SIZE):
                if self.board.is_empty(i, j) + self.previous_board.is_empty(i, j) == 1:
                    result.append((i, j))
                    #print(i, j)
                elif self.board.is_empty(i, j) + self.previous_board.is_empty(i, j) == 0:
                    if self.board.get_piece(i, j) != self.previous_board.get_piece(i, j):
                        result.append((i, j))
                        #print(self.previous_board.get_piece(i, j), self.board.get_piece(i, j))
        #print(result)
        return result

    def whose_turn(self):
        if self.move_number % 2 == 0:
            return ChessColor.Black
        return ChessColor.White

    def is_check(self, color):
        # print(type(self.board.find_king(color)))
        # self.board.show()
        (king_x, king_y) = self.board.find_king(color)
        # print('looking for ', str(color), 'King === ', king_x,' ', king_y)
        return self.can_be_attacked(king_x, king_y, color)

    def is_mate(self, color):
        return self.is_check(color) and not self.can_this_color_fix_check(color)

    def make_check_himself(self, source_x, source_y, destination_x, destination_y):
        color = self.board.get_piece(source_x, source_y).get_color()
        self.board.move_piece(source_x, source_y, destination_x, destination_y)
        if self.is_check(color):
            self.board.move_piece(destination_x, destination_y, source_x, source_y)
            return True
        self.board.move_piece(destination_x, destination_y, source_x, source_y)
        return False

    # Проверяет, что
    # в клетке [source] есть фигура
    # если в клетке [destination] есть фигура, то она другого цвета
    # check_is_move_under_check - проверить, есть ли сейчас шах ходящему игроку, и, если есть, корректен ли ход с точки зрения этого шаха
    # (закрывает ли его при необходимости)
    def is_move_correct(self, source_x, source_y, destination_x, destination_y, check_is_move_under_check=True):
        if self.board.is_empty(source_x, source_y):
            return False
        source_color = self.board.get_piece(source_x, source_y).get_color()
        if not self.board.is_empty(destination_x, destination_y):
            destination_color = self.board.get_piece(destination_x, destination_y).get_color()
            if source_color == destination_color:
                return False
        piece_type = self.board.get_piece(source_x, source_y).get_type()
        # Check the castling
        if self.check_castling(source_x, source_y, destination_x, destination_y):
            return True
        # if self.make_check_himself(source_x, source_y, destination_x, destination_y):
        #     return False

        if check_is_move_under_check:
            if self.is_check(source_color):
                piece_under_attack = None
                if not self.board.is_empty(destination_x, destination_y):
                    piece_under_attack = self.board.get_piece(destination_x, destination_y)
                self.board.move_piece(source_x, source_y, destination_x, destination_y)

                is_check_after_move = self.is_check(source_color)

                self.board.move_piece(destination_x, destination_y, source_x, source_y)
                self.board.set_piece(destination_x, destination_y, piece_under_attack)

                if is_check_after_move:
                    return False


        return move_correct_checkers[piece_type](self, source_x, source_y, destination_x, destination_y)

    def can_be_attacked(self, x, y, color):
        result = False
        substitution_done = False
        if self.board.is_empty(x, y):
            self.board.set_piece(x, y, ChessPiece(color, ChessPieceType.Pawn))
            substitution_done = True
        for i in range(BOARD_SIZE):
            for j in range(BOARD_SIZE):
                if self.is_move_correct(i, j, x, y, check_is_move_under_check=False):
                    result = True
        if substitution_done:
            self.board.clear_square(x, y)
        return result

    def check_castling(self, source_x, source_y, destination_x, destination_y):
        if self.board.is_empty(source_x, source_y):
            return False
        if self.board.get_piece(source_x, source_y).get_type() != ChessPieceType.King:
            return False
        difference_x = destination_x - source_x
        difference_y = destination_y - source_y
        if abs(difference_x) != 2 or difference_y != 0:
            return False
        factor_x = sign(difference_x)
        # Проверям, что на пути от короля до ладьи ничего не стоит
        checking_square = [source_x + factor_x, source_y]
        while self.board.is_empty(*checking_square) and 0 <= checking_square[0] < BOARD_SIZE:
            checking_square[0] += factor_x
        if checking_square[0] < 0 or checking_square[0] >= BOARD_SIZE:
            return False
        if self.board.get_piece(*checking_square).get_type() != ChessPieceType.Rook:
            return False
        # Проверка, что король не под шахом и поле, пересекаемое или занимаемое им, не атаковано
        for i in range(3):
            checking_square = [source_x + factor_x * i, source_y]
            if self.can_be_attacked(checking_square[0], checking_square[1], self.board.get_piece(source_x, source_y).get_color()):
                return False
        # Проверяем, что данные ладья и король не делали свой ход
        if (source_x, source_y, destination_x, destination_y) == (4, 0, 2, 0) and self.possible_white_long_castling:
            return True
        if (source_x, source_y, destination_x, destination_y) == (4, 0, 6, 0) and self.possible_white_short_castling:
            return True
        if (source_x, source_y, destination_x, destination_y) == (4, 7, 2, 7) and self.possible_black_long_castling:
            return True
        if (source_x, source_y, destination_x, destination_y) == (4, 7, 6, 7) and self.possible_black_short_castling:
            return True
        return False

    def is_pawn_move_correct(self, source_x, source_y, destination_x, destination_y):
        pawn = self.board.get_piece(source_x, source_y)
        color_pawn = pawn.get_color()
        if source_x == destination_x and self.board.is_empty(destination_x, destination_y):
            if (source_y - destination_y == 1) and (color_pawn == ChessColor.Black):
                return True
            if (destination_y - source_y == 1) and (color_pawn == ChessColor.White):
                return True
            if (source_y - destination_y == 2) and (color_pawn == ChessColor.Black) and (
                        source_y == 6) and self.board.is_empty(source_x, source_y - 1):
                return True
            if (destination_y - source_y == 2) and (color_pawn == ChessColor.White) and (
                        source_y == 1) and self.board.is_empty(source_x, source_y + 1):
                return True
        if abs(source_x - destination_x) == 1:
            if not self.board.is_empty(destination_x, destination_y):
                color_attacked_piece = self.board.get_piece(destination_x, destination_y).get_color()
                if (source_y - destination_y == 1) and (color_pawn == ChessColor.Black) and (
                            color_attacked_piece != color_pawn):
                    return True
                if (destination_y - source_y == 1) and (color_pawn == ChessColor.White) and (
                            color_attacked_piece != color_pawn):
                    return True
        return False

    def is_knight_move_correct(self, source_x, source_y, destination_x, destination_y):
        # Knight should move 1 step along the first axis and two steps for the other. 1*2 = 2
        if abs(destination_x - source_x) * abs(destination_y - source_y) == 2:
            if self.board.is_empty(destination_x, destination_y):
                return True
            # if the delivery square is not empty, the figure of a different color should be there
            color_attacking_piece = self.board.get_piece(destination_x, destination_y).get_color()
            color_attacked_piece = self.board.get_piece(source_x, source_y).get_color()
            return color_attacked_piece != color_attacking_piece
        return False

    def is_rook_move_correct(self, source_x, source_y, destination_x, destination_y):
        # Проверим, что в пункте назначения не стоит фигура того же цвета, что и наша
        if not self.board.is_empty(destination_x, destination_y):
            if self.board.get_piece(source_x, source_y).get_color() == self.board.get_piece(destination_x,
                                                                                            destination_y).get_color():
                return False
        difference_x = destination_x - source_x  # перемещение вдоль оси Х
        difference_y = destination_y - source_y  # перемещение вдоль оси Y
        # Если движение не по одной оси, ладья не может сходить так
        if (difference_x * difference_y != 0) or (difference_x + difference_y == 0):
            return False
        # направление по осям
        factor_x = sign(difference_x)
        factor_y = sign(difference_y)
        for index in range(1, abs(difference_x)):
            if not self.board.is_empty(source_x + factor_x * index, source_y + factor_y * index):
                return False
        for index in range(1, abs(difference_y)):
            if not self.board.is_empty(source_x + factor_x * index, source_y + factor_y * index):
                return False
        return True

    def is_king_move_correct(self, source_x, source_y, destination_x, destination_y):
        # Проверим, что в пункте назначения не стоит фигура того же цвета, что и наша
        if not self.board.is_empty(destination_x, destination_y):
            if self.board.get_piece(source_x, source_y).get_color() == self.board.get_piece(destination_x,
                                                                                            destination_y).get_color():
                return False
        difference_x = destination_x - source_x  # перемещение вдоль оси Х
        difference_y = destination_y - source_y  # перемещение вдоль оси Y
        if abs(difference_x) <= 1 and abs(difference_y) <= 1:
            return True
        return False

    def is_bishop_move_correct(self, source_x, source_y, destination_x, destination_y):
        # Проверим, что в пункте назначения не стоит фигура того же цвета, что и наша
        if not self.board.is_empty(destination_x, destination_y):
            if self.board.get_piece(source_x, source_y).get_color() == self.board.get_piece(destination_x,
                                                                                            destination_y).get_color():
                return False
        difference_x = destination_x - source_x  # перемещение вдоль оси Х
        difference_y = destination_y - source_y  # перемещение вдоль оси Y
        if abs(destination_x - source_x) != abs(destination_y - source_y):
            return False
        # направление по осям
        factor_x = sign(difference_x)
        factor_y = sign(difference_y)
        for index in range(1, abs(difference_x)):
            if not self.board.is_empty(source_x + factor_x * index, source_y + factor_y * index):
                return False
        return True

    def is_queen_move_is_correct(self, source_x, source_y, destination_x, destination_y):
        return self.is_bishop_move_correct(source_x, source_y, destination_x, destination_y) or \
               self.is_rook_move_correct(source_x, source_y, destination_x, destination_y)

    def get_number_of_string_in_notation(self):
        return str((self.move_number+1)//2) + '. '

    def add_step_to_notation(self, source_x, source_y, destination_x, destination_y):
        moving_piece = self.board.get_piece(source_x, source_y)
        if moving_piece.get_color() == ChessColor.White:
            # str_step = '\n'*sign(self.game.move_number-1) + str((self.game.move_number+1)//2) + '. '
            # str_step = ('\n' if self.game.move_number > 1 else '' ) + str((self.game.move_number+1)//2) + '. '
            str_step = ('\n' if self.move_number > 1 else '') + self.get_number_of_string_in_notation()
        else:
            str_step = ' '
        str_step += moving_piece.get_name_for_notation()
        str_step += LETTERS_ON_BOARD[source_x] + str(source_y+1)
        if self.board.is_empty(destination_x, destination_y):
            str_step += '-'
        else:
            str_step += 'x'
        str_step += LETTERS_ON_BOARD[destination_x] + str(destination_y+1)
        self.result_notation_text += str_step

    def add_step_to_notation_if_castling(self, source_x, source_y, destination_x, destination_y):
        print('Da, castling dolzhna bit')
        if (destination_x, destination_y) == (2, 0):
            self.result_notation_text += '\n' + self.get_number_of_string_in_notation() + '0-0-0 '
        if (destination_x, destination_y) == (2, 7):
            self.result_notation_text += '0-0-0'
        if (destination_x, destination_y) == (6, 0):
            self.result_notation_text += '\n' + self.get_number_of_string_in_notation() + '0-0 '
        if (destination_x, destination_y) == (6, 7):
            self.result_notation_text += '0-0 '
Example #52
0
    def build(self):
        self.from_move = None
        self.to_move = None
        self.chessboard = ChessBoard()
        self.analysis_board = ChessBoard()
        self.squares = []
        self.use_engine = False
        self.last_touch_down_move = None
        self.last_touch_up_move = None

        parent = BoxLayout(size_hint=(1,1))
        grid = GridLayout(cols = 8, rows = 8, spacing = 0, size_hint=(1, 1))

        for i, name in enumerate(SQUARES):
            bt = Image(allow_stretch=True)
            bt.sq = i
            bt.name = name
            # bt.border = [0,0,0,0]
            if i in light_squares:
                bt.sq_color = "l"
                bt.background_down = "img/empty-l.png"

            #                bt.background_color=[1,1,1,1]
            else:
                bt.sq_color = "d"
                bt.background_down = "img/empty-d.png"

            #                bt.background_color=[0,0,0,0]
            #                print i
            # bt.bind(on_press=self.callback)
            bt.bind(on_touch_down=self.touch_down_move)
            bt.bind(on_touch_up=self.touch_up_move)
            # bt.bind(on_touch_up=self.touch_move)


            grid.add_widget(bt)
            self.squares.append(bt)


        b = BoxLayout(size_hint=(0.15,0.15))
        ## Spacers
#        b.add_widget(Button(spacing=1))
#        b.add_widget(Button(spacing=1))
#        b.add_widget(Button(spacing=1))

        # Move control buttons
#        back_bt = Button(markup=True)
#       # back_bt.background_normal="img/empty-l.png"
#        back_bt.text="[color=ff3333]Back[/color]"
#        back_bt.bind(on_press=self.back)
#        b.add_widget(back_bt)
#
        save_bt = Button(markup=True)
        #fwd_bt.background_normal="img/empty-d.png"
        save_bt.text="[color=3333ff]Save[/color]"
        # save_bt.text="Save"

        save_bt.bind(on_press=self.save)
        b.add_widget(save_bt)

#        b.add_widget(Button(spacing=10))
#        b.add_widget(Button(spacing=10))
#        b.add_widget(Button(spacing=10))

#        grid.add_widget(b)

#        board_box.add_widget(grid)
#        board_box.add_widget(b)

#        fen_input = TextInput(text="FEN", focus=True, multiline=False)
#        def on_fen_input(instance):
#            self.chessboard.setFEN(instance.text)
#            self.refresh_board()
##            print 'The widget', instance.text
#
#        fen_input.bind(on_text_validate=on_fen_input)
##        self._keyboard.bind(on_key_down=self._on_keyboard_down)
#
#
#        b.add_widget(fen_input)

        settings_bt = Button(markup=True, text='Setup')
        settings_bt.bind(on_press=self.go_to_settings)
        b.add_widget(settings_bt)


#        self.root.current='settings'


        parent.add_widget(grid)

        info_grid = GridLayout(cols = 1, rows = 4, spacing = 1, size_hint=(0.3, 1), orientation='vertical')
        info_grid.add_widget(b)


        self.game_score = ScrollableLabel('New Game', ref_callback=self.go_to_move)

        info_grid.add_widget(self.game_score)

        self.engine_score = ScrollableLabel('[ref=engine_toggle]Analysis[/ref]', ref_callback=self.add_eng_moves)
        info_grid.add_widget(self.engine_score)

        info_grid.add_widget(Button(text="Text"))

        parent.add_widget(info_grid)
        self.refresh_board()

        platform = kivy.utils.platform()
        self.uci_engine = None
        if self.is_desktop():
            self._keyboard = Window.request_keyboard(
                self._keyboard_closed, self)
            self._keyboard.bind(on_key_down=self._on_keyboard_down)

            self.start_engine_thread()
        sm = ScreenManager(transition=SlideTransition())
        board_screen = Screen(name='main')
        board_screen.add_widget(parent)
        sm.add_widget(board_screen)

        settings_screen = SettingsScreen(name='settings')
        settings_screen.add_widget(self.generate_settings())

        sm.add_widget(settings_screen)

        return sm
Example #53
0
class Chess_app(App):
    def generate_settings(self):

        settings_panel = Settings() #create instance of Settings

#        def add_one_panel(from_instance):
#            panel = SettingsPanel(title="I like trains", settings=self)
#            panel.add_widget(AsyncImage(source="http://i3.kym-cdn.com/entries/icons/original/000/004/795/I-LIKE-TRAINS.jpg"))
#            settings_panel.add_widget(panel)
#            print "Hello World from ", from_instance

        panel = SettingsPanel(title="Engine") #create instance of left side panel
        item1 = SettingItem(panel=panel, title="Board") #create instance of one item in left side panel
        item2 = SettingItem(panel=panel, title="Level") #create instance of one item in left side panel

    #        item2 = SettingTitle(title="Level") #another widget in left side panel
#        button = Button(text="Add one more panel")

#        item1.add_widget(button) #add widget to item1 in left side panel
#        button.bind(on_release=add_one_panel) #bind that button to function

        panel.add_widget(item1) # add item1 to left side panel
        panel.add_widget(item2) # add item2 to left side panel
        settings_panel.add_widget(panel) #add left side panel itself to the settings menu
        def go_back():
            self.root.current = 'main'
        settings_panel.on_close=go_back

        return settings_panel # show the settings interface
#
#        parent = BoxLayout(size_hint=(1, 1))
#        bt = Button(text='Settings')
#        parent.add_widget(bt)
#
#        def go_back(instance):
#            self.root.current = 'main'
#
#        back_bt = Button(text='Back to Main')
#        back_bt.bind(on_press=go_back)
#        parent.add_widget(back_bt)
#
#        return parent

    def build(self):
        self.from_move = None
        self.to_move = None
        self.chessboard = ChessBoard()
        self.analysis_board = ChessBoard()
        self.squares = []
        self.use_engine = False
        self.last_touch_down_move = None
        self.last_touch_up_move = None

        parent = BoxLayout(size_hint=(1,1))
        grid = GridLayout(cols = 8, rows = 8, spacing = 0, size_hint=(1, 1))

        for i, name in enumerate(SQUARES):
            bt = Image(allow_stretch=True)
            bt.sq = i
            bt.name = name
            # bt.border = [0,0,0,0]
            if i in light_squares:
                bt.sq_color = "l"
                bt.background_down = "img/empty-l.png"

            #                bt.background_color=[1,1,1,1]
            else:
                bt.sq_color = "d"
                bt.background_down = "img/empty-d.png"

            #                bt.background_color=[0,0,0,0]
            #                print i
            # bt.bind(on_press=self.callback)
            bt.bind(on_touch_down=self.touch_down_move)
            bt.bind(on_touch_up=self.touch_up_move)
            # bt.bind(on_touch_up=self.touch_move)


            grid.add_widget(bt)
            self.squares.append(bt)


        b = BoxLayout(size_hint=(0.15,0.15))
        ## Spacers
#        b.add_widget(Button(spacing=1))
#        b.add_widget(Button(spacing=1))
#        b.add_widget(Button(spacing=1))

        # Move control buttons
#        back_bt = Button(markup=True)
#       # back_bt.background_normal="img/empty-l.png"
#        back_bt.text="[color=ff3333]Back[/color]"
#        back_bt.bind(on_press=self.back)
#        b.add_widget(back_bt)
#
        save_bt = Button(markup=True)
        #fwd_bt.background_normal="img/empty-d.png"
        save_bt.text="[color=3333ff]Save[/color]"
        # save_bt.text="Save"

        save_bt.bind(on_press=self.save)
        b.add_widget(save_bt)

#        b.add_widget(Button(spacing=10))
#        b.add_widget(Button(spacing=10))
#        b.add_widget(Button(spacing=10))

#        grid.add_widget(b)

#        board_box.add_widget(grid)
#        board_box.add_widget(b)

#        fen_input = TextInput(text="FEN", focus=True, multiline=False)
#        def on_fen_input(instance):
#            self.chessboard.setFEN(instance.text)
#            self.refresh_board()
##            print 'The widget', instance.text
#
#        fen_input.bind(on_text_validate=on_fen_input)
##        self._keyboard.bind(on_key_down=self._on_keyboard_down)
#
#
#        b.add_widget(fen_input)

        settings_bt = Button(markup=True, text='Setup')
        settings_bt.bind(on_press=self.go_to_settings)
        b.add_widget(settings_bt)


#        self.root.current='settings'


        parent.add_widget(grid)

        info_grid = GridLayout(cols = 1, rows = 4, spacing = 1, size_hint=(0.3, 1), orientation='vertical')
        info_grid.add_widget(b)


        self.game_score = ScrollableLabel('New Game', ref_callback=self.go_to_move)

        info_grid.add_widget(self.game_score)

        self.engine_score = ScrollableLabel('[ref=engine_toggle]Analysis[/ref]', ref_callback=self.add_eng_moves)
        info_grid.add_widget(self.engine_score)

        info_grid.add_widget(Button(text="Text"))

        parent.add_widget(info_grid)
        self.refresh_board()

        platform = kivy.utils.platform()
        self.uci_engine = None
        if self.is_desktop():
            self._keyboard = Window.request_keyboard(
                self._keyboard_closed, self)
            self._keyboard.bind(on_key_down=self._on_keyboard_down)

            self.start_engine_thread()
        sm = ScreenManager(transition=SlideTransition())
        board_screen = Screen(name='main')
        board_screen.add_widget(parent)
        sm.add_widget(board_screen)

        settings_screen = SettingsScreen(name='settings')
        settings_screen.add_widget(self.generate_settings())

        sm.add_widget(settings_screen)

        return sm

    def go_to_settings(self, instance):
        self.root.current='settings'

    def go_to_move(self, instance, value):
#        print 'Going back to move.. ', value

        move_num, color = value.split(":")

        half_move_num = int(move_num)*2 - 1
#        print "half_move_num:%d"%half_move_num

        if color == 'b':
            half_move_num+=1

        self.chessboard.gotoMove(half_move_num)
        self.refresh_board()

    def add_eng_moves(self, instance, value):
        if value=="engine_toggle":
#            print "Bringing up engine menu"
            if self.use_engine:
                self.use_engine = False
                self.uci_engine.stop()
            else:
                self.use_engine = True

            self.refresh_board()
        else:
            for i, mv in enumerate(self.engine_score.raw):
                if i>=1:
                    break
                self.chessboard.addTextMove(mv)

        self.refresh_board()

    def is_desktop(self):
        platform = kivy.utils.platform()
#        print platform
        return True if platform.startswith('win') or platform.startswith('linux') or platform.startswith('mac') else False


    def back(self, obj):
        self.chessboard.undo()
        self.refresh_board()

    def _keyboard_closed(self):
#        print 'My keyboard have been closed!'
        self._keyboard.unbind(on_key_down=self.back)
        self._keyboard = None


    def start_engine_thread(self):
        t = Thread(target=self.update_engine_output, args=(self.engine_score,))
        t.daemon = True # thread dies with the program
        t.start()

    def start_engine(self):
#        self.use_engine = False

        uci_engine = UCIEngine()
        uci_engine.start()
        uci_engine.configure({'Threads': '1'})
        #uci_engine.configure({'Use Sleeping Threads': 'false'})

        # Wait until the uci connection is setup
        while not uci_engine.ready:
            uci_engine.registerIncomingData()

        uci_engine.startGame()
        # uci_engine.requestMove()
        self.uci_engine=uci_engine


    def update_engine_output(self, output):
        if not self.use_engine:
            self.start_engine()

        def parse_score(line):
            self.analysis_board.setFEN(self.chessboard.getFEN())
            tokens = line.split()
            try:
                score_index = tokens.index('score')
            except ValueError:
                score_index = -1
            score = None
            move_list = []
            if score_index!=-1 and tokens[score_index+1]=="cp":
                score = float(tokens[score_index+2])/100*1.0
            try:
                line_index = tokens.index('pv')
                for mv in tokens[line_index+1:]:
                    self.analysis_board.addTextMove(mv)
                    move_list.append(self.analysis_board.getLastTextMove())

            except ValueError:
                line_index = -1
            variation = self.generate_move_list(move_list,start_move_num=self.chessboard.getCurrentMove()+1) if line_index!=-1 else None

            #del analysis_board
            if variation and score:
                return move_list, "[b]%s[/b][color=0d4cd6][ref=engine_toggle]         Stop[/ref][/color]\n[color=77b5fe]%s[/color]" %(score,"".join(variation))

        while True:
            if self.use_engine:
                line = self.uci_engine.getOutput()
                if line:
                    #out_score = None
                    out_score = parse_score(line)
                    if out_score:
                        raw_line, cleaned_line = out_score
                        if cleaned_line:
                            output.children[0].text = cleaned_line
                        if raw_line:
                            output.raw = raw_line
            elif output.children[0].text != ANALYSIS_HEADER:
                output.children[0].text = ANALYSIS_HEADER


    def _on_keyboard_down(self, keyboard, keycode, text, modifiers):
#        print 'The key', keycode, 'have been pressed'
#        print ' - text is %r' % text
#        print ' - modifiers are %r' % modifiers

        # Keycode is composed of an integer + a string
        # If we hit escape, release the keyboard
        if keycode[1] == 'escape':
            keyboard.release()

        if keycode[1] == 'left':
            self.back(None)
        elif keycode[1] == 'right':
            self.fwd(None)


        # Return True to accept the key. Otherwise, it will be used by
        # the system.
        return True

    def fwd(self, obj):
        self.chessboard.redo()
        self.refresh_board()

    def save(self, obj):
        f = open('game.pgn','w')
        f.write('Game Header - Analysis \n\n')
        f.write(self.generate_move_list(self.chessboard.getAllTextMoves(),raw=True))
        f.close()

    def touch_down_move(self, img, touch):
        if not img.collide_point(touch.x, touch.y):
            return
        # print "touch_move"
        # print touch
        mv = img.name
        squares = [item for sublist in self.chessboard.getBoard() for item in sublist]

        if squares[SQUARES.index(mv)]!='.':
            # self.from_move = move
            self.last_touch_down_move = mv

            # self.process_move(mv)

    def touch_up_move(self, img, touch):
        if not img.collide_point(touch.x, touch.y):
            return
        # print "touch_move"
        # print touch
        mv = img.name
        self.last_touch_up_move = img.name
        if self.last_touch_up_move != self.last_touch_down_move:
            self.process_move()

    def process_move(self):
        if self.chessboard.addTextMove(self.last_touch_down_move+self.last_touch_up_move):
            self.refresh_board()

    def generate_move_list(self, all_moves, start_move_num = 1, raw = False):
        score = ""
        # if raw:
        #     return " ".join(all_moves)
        for i, mv in it.izip(it.count(start_move_num), all_moves):
            move = "b"
            if i % 2 == 1:
                score += "%d. " % ((i + 1) / 2)
                move = "w"

            if mv:
                if raw:
                    score += " % s" % mv
                    if i % 5 == 0:
                        score += "\n"

                else:
                    score += " [ref=%d:%s] %s [/ref]"%((i + 1) / 2, move, mv)
        return score

    def refresh_board(self):
        # flatten lists into one list of 64 squares
        squares = [item for sublist in self.chessboard.getBoard() for item in sublist]

        for i, p in enumerate(squares):
            sq = self.squares[i]
            if p==".":
                sq.source=sq.background_down

            if p!=".":
                p_color = 'w' if p.isupper() else 'b'
                sq.source="img/pieces/Merida/"+sq.sq_color+p_color+p.lower()+".png"

        # Update game notation
        all_moves = self.chessboard.getAllTextMoves()
        if all_moves:
            score = self.generate_move_list(all_moves)
            self.game_score.children[0].text="[color=fcf7da]%s[/color]"%score
#            self.game_score.raw = self.generate_move_list(all_moves, raw=True)

        if self.use_engine:
            #self.analysis_board.setFEN(self.chessboard.getFEN())
            self.uci_engine.stop()
            self.uci_engine.reportMoves(self.chessboard.getAllTextMoves(format=0, till_current_move=True))
#            self.uci_engine.reportMove(self.chessboard.getLastTextMove(format=0))
            self.uci_engine.requestMove()
Example #54
0
	def gameTick(self):
		self.updateConsideringLine()
		if self.state == UserInterface.STATE_WAITING_FOR_START_POS:
			if np.array_equal(self.boardscan, self.startingPos):
				print "NEW GAME: Creating chess board"
				self.chess = ChessBoard()
				self.lastBoardscan = self.boardscan
				self.engine.newGame()
				self.topHeading = self.your_turn
				self.dirtyUi = True
				self.state = UserInterface.STATE_WAITING_FOR_BOARD_CHANGE
		elif self.state == UserInterface.STATE_WAITING_FOR_ENGINE:
			if self.engine.bestmove is not None:
				self.requestedMove = self.engine.bestmove
				self.considering = []
				self.state = UserInterface.STATE_WAITING_FOR_BOARD_CHANGE
				self.topHeading = self.my_turn_move_piece
				self.dirtyUi = True
			self.renderBoard()
		elif self.state == UserInterface.STATE_WAITING_FOR_BOARD_CHANGE:
			changes = self.boardscan - self.lastBoardscan
			numChanges = np.count_nonzero(changes)
			if numChanges == 2 or numChanges == 3 or numChanges == 4:
				self.dirtyUi = True
				print ""
				print "changes:\n" + str(changes)
				moveFrom = ()
				moveTo = ()
				nonzeroChanges = changes.nonzero()
				print "nonzeroChanges: " + str(nonzeroChanges)
				print "len(nonzeroChanges[0]) = %d" % len(nonzeroChanges[0])
				for i in range(len(nonzeroChanges[0])):
					change = (nonzeroChanges[1][i], nonzeroChanges[0][i])
					value = changes[change[1], change[0]]
					colorBefore = self.lastBoardscan[change[1], change[0]]
					print "\tchange: %s\tvalue: %s\tcolorBefore: %s" % (str(change), value, colorBefore)
					if self.chess.getTurn() == ChessBoard.WHITE:
						# WHITE's turn
						if value == -1:
							if numChanges != 4 or (change == (4,7)):
								moveFrom = change
						else:
							if numChanges == 4:
								if change == (6,7) or change == (2,7):
									moveTo = change
							elif numChanges == 3:
								if colorBefore == 0:
									moveTo = change
							else:
								moveTo = change
					else:
						# BLACK's turn
						if value == 1:
							if numChanges != 4 or (change == (4,0)):
								print "setting moveFrom to ", change
								moveFrom = change
						else:
							if numChanges == 4:
								if change == (6,0) or change == (2,0):
									print "setting moveTo to ", change
									moveTo = change
							elif numChanges == 3:
								if colorBefore == 0:
									print "setting moveTo to ", change
									moveTo = change
							else:
								moveTo = change
				print "moveFrom: " + str(moveFrom)
				print "moveTo:   " + str(moveTo)
				if moveFrom and moveTo:
					print "getTurn before:", self.chess.getTurn()
					result = self.chess.addMove(moveFrom, moveTo)
					print "getTurn after:", self.chess.getTurn()
					if result is False:
						print "Could not make move: ", self.chess.getReason()
					else:
						lastMove = string.replace(self.chess.getLastTextMove(ChessBoard.AN), '-', '')
						cheater = False
						if self.requestedMove is not None and self.requestedMove != lastMove:
							cheater = True
						if self.chess.isCheck():
							print "**** CHECK ****"
							self.bottomHeading = self.check
						else:
							self.bottomHeading = None
						self.requestedMove = None
						self.lastBoardscan = self.boardscan
						self.chess.printBoard()
						print "Last move type: " + str(self.chess.getLastMoveType())
						print "New FEN: " + self.chess.getFEN()
						# Check if game is over
						if self.chess.isGameOver():
							result = self.chess.getGameResult()
							if result == ChessBoard.WHITE_WIN:
								print "**** WHITE WINS ****"
							elif result == ChessBoard.BLACK_WIN:
								print "**** BLACK WINS ****"
								self.bottomHeading = self.checkmate_suckah
							else:
								print "**** STALEMATE ****"
							self.state = UserInterface.STATE_GAME_OVER
						elif self.chess.getTurn() == ChessBoard.BLACK:
							# It's black's turn, engage the engine
							self.topHeading = self.one_moment_please
							self.engine.makeMove(self.chess.getFEN())
							self.state = UserInterface.STATE_WAITING_FOR_ENGINE
						else:
							if cheater:
								self.topHeading = self.your_turn_cheater
							else:
								self.topHeading = self.your_turn
						self.renderBoard()

			elif numChanges != 0:
				print "Invalid number of board changes: ", numChanges
				self.cv.reset_board()
			# Set boardscan to the last one just so we don't keep analyzing it until next scan comes in
			self.boardscan = self.lastBoardscan
			self.renderBoard()
Example #55
0
        pieces[1]["P"] = pygame.image.load(chessboardDirectory + "/img/wpb.png")
        pieces[1]["."] = pygame.image.load(chessboardDirectory + "/img/b.png")
    except ImportError:
        prettyBoard = False

def drawPrettyBoard(board):
    for y, rank in enumerate(board):
        for x, p in enumerate(rank):
            pygameScreen.blit(pieces[(x+y)%2][p],(x*60,y*60))
    if os.path.isfile("pnl.png"):
        pnl = pygame.image.load("pnl.png")
        pygameScreen.blit(pnl, (0,480))

    pygame.display.flip()

chess = ChessBoard()

b = book.Book()
prevSeq = None
drops = 0

f = feed.Feed()

##p = pnl.Pnl(sys.argv[1])

stdscr = curses.initscr()

curses.noecho()
curses.cbreak()
curses.curs_set(0)
stdscr.keypad(1)