Hello, I was wondering if there should be an effort to re-write the Game class.
I think having separated functions to deal with moving and priting the board ( like in #7 ) would make it easier later on if we want to change how the board is displayed, or if you want a way to change between UCI and Algebric.
Here are some changes I propose and some code to get us started:
(I'm no pyhon expert, so please let me know if there is a better way to do this)
I don't think we need Game to inherent Thread (since we are most likely playing just one game each time).
Game only needs to take three arguments:
Lichess board instance, which is how we connect to Lichess
The game_id, to get the stream of events and send moves
player_id, so we can check if the player is playing white or black
Each Game() instance should create its own chess.Board() instance, instead of a global chess.Board().
Instead of making the move on the chess.Board() and sending it to Lichess at the same time, I think we need to first send the command to Lichess, and then we wait for Lichess to send our own move.
I think it would then be better to check the legality of the move locally before sending it to Lichess.
I think there is a lot of python-chess features we can use like chess.WHITE and chess.BLACK.
We should also use chess.Board.turn() everytime we get a move update, instead of trying to keep track locally.
We store lichess_board, game_id and player_id
We call next(self.stream) for the first time, which will always send us the game information, and the moves so far (we save those to a list).
We create an instance of chess.Board().
def set_player_color(self):
if "id" in self.initial_status["white"]:
if self.initial_status["white"]["id"] == self.player_id:
print("Player is white")
self.player_color = chess.WHITE
else:
print("Player is black")
self.player_color = chess.BLACK
else:
print("Player is black")
self.player_color = chess.BLACK
This function just checks if the player is white or black.
We need to check if "id" is a valid key, because when playing the AI it has no "id".
def print_board(self):
if self.player_color is chess.WHITE:
print(self.chess_board)
else:
vertical_flip = self.chess_board.transform(chess.flip_vertical)
final_flip = vertical_flip.transform(chess.flip_horizontal)
print(final_flip)
This function flips the board, we can also use ( #7 ).
def start_game(self):
self.set_player_color()
for move_uci in self.list_move:
move = self.chess_board.parse_uci(move_uci)
self.chess_board.push(move)
self.print_board()
We start the game by setting the player color, pushing the stored moves to our local board (this means you can connect to a game midway). And we print the board.
What is missing right now is the event loop for the game. I suggest we go the following way:
chess.Board.turn() checks if it is the player turn:
Ask the player for input, if it is valid, send it to lichess, then call next(self.stream)
Otherwise, call next(self.stream)
When we receive a new change of state from lichess, we make the move in our local board (this can be either player move), we go back to 1. again.
I think this changes to the class would lead to the following:
Easier to test
Easier to change function for printing the board and making moves later on
Being able to join a game in the middle of it
Being able to play multiple games at the same time
I think we can even spectate and watch replays this way (not sure if this is a wanted feature, but it wouldn't be hard to implement it).
Please let me know what you guys think.
We can create a separated branch and test it out.
Hello, I was wondering if there should be an effort to re-write the Game class. I think having separated functions to deal with moving and priting the board ( like in #7 ) would make it easier later on if we want to change how the board is displayed, or if you want a way to change between UCI and Algebric. Here are some changes I propose and some code to get us started: (I'm no pyhon expert, so please let me know if there is a better way to do this)
I don't think we need Game to inherent Thread (since we are most likely playing just one game each time).
Game only needs to take three arguments:
board
instance, which is how we connect to Lichessgame_id
, to get the stream of events and send movesplayer_id
, so we can check if the player is playing white or blackEach
Game()
instance should create its ownchess.Board()
instance, instead of a globalchess.Board()
.Instead of making the move on the
chess.Board()
and sending it to Lichess at the same time, I think we need to first send the command to Lichess, and then we wait for Lichess to send our own move. I think it would then be better to check the legality of the move locally before sending it to Lichess.I think there is a lot of
python-chess
features we can use like chess.WHITE and chess.BLACK.We should also use
chess.Board.turn()
everytime we get a move update, instead of trying to keep track locally.We store
lichess_board
,game_id
andplayer_id
We callnext(self.stream)
for the first time, which will always send us the game information, and the moves so far (we save those to a list). We create an instance of chess.Board().This function just checks if the player is white or black. We need to check if
"id"
is a valid key, because when playing the AI it has no"id"
.This function flips the board, we can also use ( #7 ).
We start the game by setting the player color, pushing the stored moves to our local board (this means you can connect to a game midway). And we print the board.
What is missing right now is the event loop for the game. I suggest we go the following way:
chess.Board.turn()
checks if it is the player turn:next(self.stream)
next(self.stream)
When we receive a new change of state from lichess, we make the move in our local board (this can be either player move), we go back to 1. again.
I think this changes to the class would lead to the following:
Please let me know what you guys think. We can create a separated branch and test it out.