1
\$\begingroup\$

I am pretty sure my code does not follow PEP 8 and would definitely want someone to point out my errors specifically. I am open any form of criticism or suggestions.

import chess
import chess.engine
import time
import stockfish

engine = chess.engine.SimpleEngine.popen_uci("stockfish")
board = chess.Board()

def pact():  # Player's Action
    print('----------------\n' + 'The legal moves are: \n' +
          str(board.legal_moves) + '\n' + str(board))
    Action = input('Declare your moves: ')
    try:
        board.push_san(Action)
    except ValueError:
        # output: "integer division or modulo by zero"
        print('Invalid move, try again')

def cact():  # Computer's Action
    result = engine.play(board, chess.engine.Limit(time=2.0))
    board.push(result.move)

    print(board)

print(board)

for index in range(3, 0, -1):
    print('The game starts in ' + str(index) + 'seconds')
    time.sleep(1)
while(board.is_checkmate() == False):
    pact()
    cact()
    # print(engine.play.move(board, limit)

Ideally I would like to incorporate sound recognition and making it a hands-free chess playing with Stockfish or other player. For now, I just want to get the basics right to avoid any future bugs and improve overall tidiness so I can have a good habit in my future coding progress.

\$\endgroup\$
3
\$\begingroup\$
  • The game logic is broken in many respects.

    First, the game may reach an "insufficient material" condition, in which checkmate is impossible. Infinite loop right away.

    Second, the game may get into a stalemate. There is no legal moves in a stalemate, so pact would reject anything the user tries to enter. Yet another infinite loop.

    Finally, the end of game condition shall be tested after each half-move. BTW, chess module conveniently offers a board.is_game_over() method, which encompasses everything above, plus three-fold repetition, plus 50 moves rule.

  • Board is printed only after a computer move. This is strange.

  • Listing the legal moves unconditionally is annoying. It should only be printed when the player enters an illegal one.

  • When you feel compelled to put a comment like

      def pact():  # Player's Action
    

    it means that you fail to express yourself clearly in the code. Giving the function a meaningful name, like

      def player_action():
    

    eliminates the need to comment it.

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.