Ejemplo n.º 1
0
def main():
    """
    The main driver for our code.
    This will handle user input and updating the graphics.
    """
    p.init()
    screen = p.display.set_mode(
        (BOARD_WIDTH + MOVE_LOG_PANEL_WIDTH, BOARD_HEIGHT))
    clock = p.time.Clock()
    screen.fill(p.Color("white"))
    game_state = ChessEngine.GameState()
    valid_moves = game_state.getValidMoves()
    move_made = False  # flag variable for when a move is made
    animate = False  # flag variable for when we should animate a move
    loadImages()  # do this only once before while loop
    running = True
    square_selected = (
    )  # no square is selected initially, this will keep track of the last click of the user (tuple(row,col))
    player_clicks = []  # this will keep track of player clicks (two tuples)
    game_over = False
    ai_thinking = False
    move_undone = False
    move_finder_process = None
    move_log_font = p.font.SysFont("Arial", 14, False, False)
    player_one = True  # if a human is playing white, then this will be True, else False
    player_two = False  # if a hyman is playing white, then this will be True, else False

    while running:
        human_turn = (game_state.white_to_move
                      and player_one) or (not game_state.white_to_move
                                          and player_two)
        for e in p.event.get():
            if e.type == p.QUIT:
                p.quit()
                sys.exit()
            # mouse handler
            elif e.type == p.MOUSEBUTTONDOWN:
                if not game_over:
                    location = p.mouse.get_pos(
                    )  # (x, y) location of the mouse
                    col = location[0] // SQUARE_SIZE
                    row = location[1] // SQUARE_SIZE
                    if square_selected == (
                            row, col
                    ) or col >= 8:  # user clicked the same square twice
                        square_selected = ()  # deselect
                        player_clicks = []  # clear clicks
                    else:
                        square_selected = (row, col)
                        player_clicks.append(
                            square_selected
                        )  # append for both 1st and 2nd click
                    if len(player_clicks
                           ) == 2 and human_turn:  # after 2nd click
                        move = ChessEngine.Move(player_clicks[0],
                                                player_clicks[1],
                                                game_state.board)
                        for i in range(len(valid_moves)):
                            if move == valid_moves[i]:
                                game_state.makeMove(valid_moves[i])
                                move_made = True
                                animate = True
                                square_selected = ()  # reset user clicks
                                player_clicks = []
                        if not move_made:
                            player_clicks = [square_selected]

            # key handler
            elif e.type == p.KEYDOWN:
                if e.key == p.K_z:  # undo when 'z' is pressed
                    game_state.undoMove()
                    move_made = True
                    animate = False
                    game_over = False
                    if ai_thinking:
                        move_finder_process.terminate()
                        ai_thinking = False
                    move_undone = True
                if e.key == p.K_r:  # reset the game when 'r' is pressed
                    game_state = ChessEngine.GameState()
                    valid_moves = game_state.getValidMoves()
                    square_selected = ()
                    player_clicks = []
                    move_made = False
                    animate = False
                    game_over = False
                    if ai_thinking:
                        move_finder_process.terminate()
                        ai_thinking = False
                    move_undone = True

        # AI move finder
        if not game_over and not human_turn and not move_undone:
            if not ai_thinking:
                ai_thinking = True
                return_queue = Queue()  # used to pass data between threads
                move_finder_process = Process(target=ChessAI.findBestMove,
                                              args=(game_state, valid_moves,
                                                    return_queue))
                move_finder_process.start()

            if not move_finder_process.is_alive():
                ai_move = return_queue.get()
                if ai_move is None:
                    ai_move = ChessAI.findRandomMove(valid_moves)
                game_state.makeMove(ai_move)
                move_made = True
                animate = True
                ai_thinking = False

        if move_made:
            if animate:
                animateMove(game_state.move_log[-1], screen, game_state.board,
                            clock)
            valid_moves = game_state.getValidMoves()
            move_made = False
            animate = False
            move_undone = False

        drawGameState(screen, game_state, valid_moves, square_selected)

        if not game_over:
            drawMoveLog(screen, game_state, move_log_font)

        if game_state.checkmate:
            game_over = True
            if game_state.white_to_move:
                drawEndGameText(screen, "Black wins by checkmate")
            else:
                drawEndGameText(screen, "White wins by checkmate")

        elif game_state.stalemate:
            game_over = True
            drawEndGameText(screen, "Stalemate")

        clock.tick(MAX_FPS)
        p.display.flip()
Ejemplo n.º 2
0
def main():
    p.init()
    screen = p.display.set_mode((WIDTH, HEIGHT))
    clock = p.time.Clock()
    screen.fill(p.Color("white"))
    gs = ChessEngine.GameState()
    validMoves = gs.getValidMoves()
    moveMade = False
    animate = False
    gameOver = False
    load_images()
    sqSelected = ()  # last click of the user
    playerClicks = []  # keeps track of player clicks  - two tuples
    running = True
    playerOne = True  # if a human is white this is True
    playerTwo = True  # if a human is black  this is True
    while running:
        humanTurn = (gs.whiteToMove and playerOne) or (not gs.whiteToMove
                                                       and playerTwo)
        for e in p.event.get():
            if e.type == p.QUIT:
                running = False
                # mouse handler
            elif e.type == p.MOUSEBUTTONDOWN:
                if not gameOver and humanTurn:
                    location = p.mouse.get_pos()
                    col = location[0] // SQ_SIZE
                    row = location[1] // SQ_SIZE
                    if sqSelected == (
                            row, col
                    ):  # clicking twice the same sq deselects everything
                        sqSelected = ()
                        playerClicks = []
                    else:
                        sqSelected = (row, col)
                        playerClicks.append(sqSelected)
                    if len(playerClicks) == 2:  # after 2nd click
                        move = ChessEngine.Move(playerClicks[0],
                                                playerClicks[1], gs.board)
                        for i in range(len(validMoves)):
                            if move == validMoves[i]:
                                gs.makeMove(validMoves[i])
                                moveMade = True
                                animate = True
                                gameOver = False
                                sqSelected = ()
                                playerClicks = []
                        if not moveMade:
                            playerClicks = [sqSelected]

            # key handler
            elif e.type == p.KEYDOWN:
                if e.key == p.K_z:  # undo a move when z is pressed
                    gs.undoMove()
                    moveMade = True
                    animate = False  # don't animate after a undo
                    gameOver = False
                if e.key == p.K_r:
                    gs = ChessEngine.GameState()
                    validMoves = gs.getValidMoves()
                    sqSelected = ()
                    playerClicks = []
                    gameOver = False
                    animate = False
                    moveMade = False
        # AI move finder
        if not gameOver and not humanTurn:
            AIMove = ChessAI.findBestMoveMinMax(gs, validMoves)
            if AIMove is None:
                ChessAI.findRandomMove(validMoves)
            # AIMove = ChessAI.findRandomMove(validMoves)
            gs.makeMove(AIMove)
            moveMade = True
            animate = True

        if moveMade:
            if animate:
                animateMove(gs.moveLog[-1], screen, gs.board, clock)
            validMoves = gs.getValidMoves()
            moveMade = False
            animate = False

        drawGameState(screen, gs, validMoves, sqSelected)

        if gs.checkmate:
            gameOver = True
            if gs.whiteToMove:
                drawText(screen, 'Black won by checkmate')
            else:
                drawText(screen, 'White won by checkmate')
        elif gs.stalemate:
            gameOver = True
            drawText(screen, 'Draw by stalemate')

        clock.tick(MAX_FPS)
        p.display.flip()
Ejemplo n.º 3
0
def main():
    """ Main function that handles user input and graphics """

    # PyGame initialization
    pg.init()
    clock = pg.time.Clock()
    screen = pg.display.set_icon(IMAGES['logo'])  # add icon to the pg window
    screen = pg.display.set_caption(' Chess')  # add title to the pg window
    screen = pg.display.set_mode((BOARD_WIDTH + MOVE_LOG_PANEL_WIDTH,
                                  BOARD_HEIGHT))  # set size of the pg window
    screen.fill(pg.Color("black"))  # add background color to the pg window

    move_log_font = pg.font.SysFont("Arial", 13, True, False)

    # GameEngine initialization
    game_state = ChessEngine.GameState()
    running = True
    sq_selected = ()  # store last click of the user
    player_click = []  # store clicks up to two clicks
    move_finder_process = None  # allow multi processing

    valid_moves = game_state.get_all_valid_moves()
    move_made = False  # flag variable for when a move is made
    animate = False  # flag variable for when a move needs to be animated
    game_over = False  # flag variable for when game is over
    ai_thinking = False  # flag variable for when the AI is finding best move
    move_undone = False  # flag variable for when the move is undone

    # if a human is playing white, then this will be True, else False
    player_one = False

    # if a human is playing black, then this will be True, else False
    player_two = False

    # infinite loop
    while running:

        human_turn = (game_state.white_to_move and player_one) or (
            not game_state.white_to_move and player_two
        )  # check if the human is controlling the turn

        for e in pg.event.get():  # for each event in event queue

            if e.type == pg.QUIT:  # trigger for ending infinite loop
                pg.quit()
                sys.exit()

            elif not game_over and e.type == pg.MOUSEBUTTONDOWN:
                if not game_over and human_turn:
                    location = pg.mouse.get_pos(
                    )  # (x, y) location fot the mouse
                    col = location[0] // SQ_SIZE
                    row = location[1] // SQ_SIZE

                    # storing player clicks
                    if sq_selected == (
                            row, col
                    ) or col >= 8:  # in case the click is same as previous click, reset player clicks
                        sq_selected = ()
                        player_click.clear()

                    else:  # else update the new click position
                        sq_selected = (row, col)
                        player_click.append(sq_selected)

                    if len(player_click
                           ) == 2:  # when 2 unique clicks have been identified
                        move = ChessEngine.Move(player_click[0],
                                                player_click[1],
                                                game_state.board)

                        for i in range(len(valid_moves)):
                            if move == valid_moves[i]:
                                game_state.make_move(valid_moves[i])

                                move_made = True
                                animate = True

                                # reset input
                                sq_selected = ()
                                player_click.clear()
                                break

                        else:
                            player_click = [sq_selected]

            elif e.type == pg.KEYDOWN and e.key == pg.K_z:  # trigger for undoing a move
                game_state.undo_move()
                move_made = True
                animate = False
                game_over = False

                if ai_thinking:
                    move_finder_process.terminate()
                    ai_thinking = False

                move_undone = True

            elif e.type == pg.KEYDOWN and e.key == pg.K_r:  # trigger for resetting the board
                game_state = ChessEngine.GameState()
                valid_moves = game_state.get_all_valid_moves()
                sq_selected = ()
                player_click.clear()
                move_made = False
                animate = False
                game_over = False

                if ai_thinking:
                    move_finder_process.terminate()
                    ai_thinking = False

                move_undone = True

        # AI move finder
        if not game_over and not human_turn and not move_undone:

            if not ai_thinking:
                ai_thinking = True
                return_queue = Queue()  # store and pass data between threads
                move_finder_process = Process(target=ChessAI.find_best_move,
                                              args=(game_state, valid_moves,
                                                    return_queue))
                move_finder_process.start()

            if not move_finder_process.is_alive():
                ai_move = return_queue.get()

                if ai_move is None:
                    ai_move = ChessAI.findRandomMove(valid_moves)

                game_state.make_move(ai_move)
                move_made = True
                animate = True
                ai_thinking = False

        if move_made:
            if animate:
                animate_move(game_state.move_log[-1], screen, game_state.board,
                             clock)  # animate the move made by the user
            valid_moves = game_state.get_all_valid_moves()
            move_made = False
            animate = False
            move_undone = False

        if not game_over:
            draw_GameState(screen, game_state, valid_moves, sq_selected,
                           move_log_font)

        if game_state.check_mate or game_state.stale_mate:
            game_over = True
            win_txt = 'Stalemate' if game_state.stale_mate else 'Black wins by checkmate.' if game_state.white_to_move else 'White  wins by checkmate.'
            draw_end_game_text(screen, win_txt)

        clock.tick(MAX_FPS)
        pg.display.flip()
Ejemplo n.º 4
0
def main():
    '''
    The main driver for our code.
    This will handle user input and updating the graphics.
    '''
    p.init()
    screen = p.display.set_mode((WIDTH, HEIGHT))
    clock = p.time.Clock()
    screen.fill(p.Color("white"))
    game_state = ChessEngine.GameState()
    valid_moves = game_state.getValidMoves()
    move_made = False #flag variable for when a move is made
    animate = False #flag variable for when we should animate a move
    loadImages() #do this only once before while loop
    
    running = True
    square_selected = () #no square is selected initially, this will keep track of the last click of the user (tuple(row,col))
    player_clicks = [] #this will keep track of player clicks (two tuples)
    game_over = False
    
    white_did_check = ""
    black_did_check = ""
    last_move_printed = False
    moves_list = []
    
    turn = 1
    
    player_one = True #if a human is playing white, then this will be True, else False
    player_two = False #if a human is playing white, then thiss will be True, else False

    while running:
        human_turn = (game_state.white_to_move and player_one) or (not game_state.white_to_move and player_two)
        for e in p.event.get():  
            if e.type == p.QUIT:
                running = False
                p.quit()
                sys.exit()
            #mouse handler            
            elif e.type == p.MOUSEBUTTONDOWN:
                if not game_over and human_turn:
                    location = p.mouse.get_pos() #(x, y) location of the mouse
                    col = location[0] // SQUARE_SIZE
                    row = location[1] // SQUARE_SIZE
                    if square_selected == (row, col): #user clicked the same square twice
                        square_selected = () #deselect
                        player_clicks = [] #clear clicks
                    else:
                        square_selected = (row, col)
                        player_clicks.append(square_selected) #append for both 1st and 2nd click
                    if len(player_clicks) == 2: #after 2nd click                                                                    
                        move = ChessEngine.Move(player_clicks[0], player_clicks[1], game_state.board)  
                        for i in range(len(valid_moves)):
                            if move == valid_moves[i]:
                                game_state.makeMove(valid_moves[i])
                                move_made = True
                                animate = True
                                square_selected = () #reset user clicks
                                player_clicks = []   
                        if not move_made:
                            player_clicks = [square_selected]

            #key handler
            elif e.type == p.KEYDOWN:
                if e.key == p.K_z: #undo when 'z' is pressed
                    if game_state.white_to_move:
                        if turn > 1:
                            turn -= 1
                    game_state.undoMove()
                    move_made = True
                    animate = False
                    game_over = False
                    last_move_printed = False

                if e.key == p.K_r: #reset the game when 'r' is pressed
                    game_state = ChessEngine.GameState()
                    valid_moves = game_state.getValidMoves()
                    square_selected = ()
                    player_clicks = []
                    move_made = False
                    animate = False
                    game_over = False
                    turn = 1    
                    last_move_printed = False
                    moves_list = []
                    
        #AI move finder
        if not game_over and not human_turn:
            AI_move = ChessAI.findBestMoveNegaMaxAlphaBeta(game_state, valid_moves)
            if AI_move is None:
                AI_move = ChessAI.findRandomMove(valid_moves)
            game_state.makeMove(AI_move)
            move_made = True
            animate = True
        
        if move_made:
            if game_state.checkForPinsAndChecks()[0]:
                if not game_state.white_to_move:
                    white_did_check = "+"
                else:
                    black_did_check = "+"
            if game_state.white_to_move:
                moves_list.append(f"\n{turn}. {game_state.move_log[-2].getChessNotation()}{white_did_check} {game_state.move_log[-1].getChessNotation()}{black_did_check}")
                print(f"\n{turn}. {game_state.move_log[-2].getChessNotation()}{white_did_check} {game_state.move_log[-1].getChessNotation()}{black_did_check}", end= "")
                turn+=1
                white_did_check = ""
                black_did_check = ""
            
            
            
            if animate:
                animateMove(game_state.move_log[-1], screen, game_state.board, clock)
            valid_moves = game_state.getValidMoves()
            move_made = False
            animate = False
                    
                            
        drawGameState(screen, game_state, valid_moves, square_selected) 
        
        if game_state.checkmate:
            game_over = True
            if game_state.white_to_move:
                drawText(screen, "Black wins by checkmate")
                if not last_move_printed:
                    moves_list[-1] += "+"
                    moves_list.append("result: 0-1")
                    print("+")
                    print("result: 0-1")
                    last_move_printed = True
                    saveGame(moves_list)
                    
            else:
                drawText(screen, "White wins by checkmate")
                if not last_move_printed:
                    moves_list.append(f"\n{turn}. {game_state.move_log[-1].getChessNotation()}++")
                    moves_list.append("result: 1-0")
                    print(f"\n{turn}. {game_state.move_log[-1].getChessNotation()}++")
                    print("result: 1-0")
                    last_move_printed = True
                    saveGame(moves_list)

        elif game_state.stalemate:
            game_over = True
            drawText(screen, "Stalemate")
            if not last_move_printed:
                if not game_state.white_to_move:
                    moves_list.append(f"\n{turn}. {game_state.move_log[-1].getChessNotation()}")
                    moves_list.append("result: 1/2-1/2")
                    print(f"\n{turn}. {game_state.move_log[-1].getChessNotation()}")
                    print("result: 1/2-1/2")
                    last_move_printed = True      
                    saveGame(moves_list)
        
        clock.tick(MAX_FPS)
        p.display.flip()