Closed OfekShochat closed 4 years ago
board.legal_moves
should not do that. Please show a concrete code example that behaves incorrectly.
Hi, I think the thing that is behaving incorrectly is only the board.legal_moves
Because it is the only thing that can allow us to capture something that he is not supposed to and make moves that it is not supposed to.
And thank you so much for the prompt reply. I expected it to be at least 20 minutes.
So far I wasn't able to find an example of that. Please give a concrete position where it happens.
r n b q k b n r
p p p p . p p p
. . . . P . . .
. . . . . . . .
. . . . . . . .
. . . . . . . .
P P P P P P P P
R N B Q K B N R
and then:
r n b q k b n r
p p p . . p p p
. . . . P . . .
. . . p . . . .
. . . . . . . .
. . . . . . . .
P P P P P P P P
R N B Q K B N R
and:
r n b q k b n r p p p p . p p p . . . . P . . . . . . . . . . . . . . . . . . . . . . . . . . . P P P P P P P P R N B Q K B N R r n b q k b n r p p p . . p p p . . . . P . . . . . . p . . . . . . . . . . . . . . . . . . . . P P P P P P P P R N B Q K B N R r n b q k b n r p p p . . p p p . . . . P . . . . . . p . . . . . . . . . . . . . . . . . . . . P P P P P P P P R N B Q K B N R r n b q k b n r p p p . . p p p . . . . P . . . . . . . . . . . . . . P . . . . . . . . . . . . P P P P P P P P R N B Q K B N R r n b q k b n r p p p . . p p p . . . . P . . . . . . . . . . . . . . P . . . . . . . . . . . . P P P P P P P P R N B Q K B N R r n b . k b n r p p p . . p p p . . . . P . . . . . . q . . . . . . . P . . . . . . . . . . . . P P P P P P P P R N B Q K B N R r n b . k b n r p p p . . p p p . . . . P . . . . . . q . . . . . . . P . . . . . . . . . . . . P P P P P P P P R N B Q K B N R r n b . k b n r p p p . . p p p . . . . P . . . . . . q . . . . . . . P P . . . . . . . . . . . P P P P . P P P R N B Q K B N R r n b . k b n r p p p . . p p p . . . . P . . . . . . q . . . . . . . P P . . . . . . . . . . . P P P P . P P P R N B Q K B N R
this is one example for the second issue I mentioned
Already the first position
r n b q k b n r
p p p p . p p p
. . . . P . . .
. . . . . . . .
. . . . . . . .
. . . . . . . .
P P P P P P P P
R N B Q K B N R
looks wierd with the white pawn on e6. How was it produced?
this is how it was played. I didn't leave out any position
I am asking for the code that produced this sequence, even just the first position.
with the algorithm?
this is the full code:
from math import inf
import chess
from time import time
import io
import table_analysis
import threading
from time import sleep
import sys
import os
def times_up(st, how_much):
if time() - st >= how_much:
return True
return False
def get_piece_val(piece:str):
temp = 0
if piece == "k":
temp = -100000
if piece == "q":
temp = -900
if piece == "r":
temp = -500
if piece == "b":
temp = -400
if piece == "n":
temp = -300
if piece == "p":
temp = -10
if piece == "K":
temp = 100000
if piece == "Q":
temp = 900
if piece == "R":
temp = 500
if piece == "B":
temp = 400
if piece == "N":
temp = 300
if piece == "P":
temp = 10
return temp
def evaluate(board_fen, color, debugger=False):
thisboard = chess.Board(board_fen)
evaluation = 0
for i in str(thisboard):
evaluation += get_piece_val(i)
#evaluation += table_analysis.tables[get_piece_val(i)]
for i in chess.LegalMoveGenerator(thisboard): evaluation += 1 * table_analysis.weights["mobility"]
if list(chess.LegalMoveGenerator(thisboard)) == []:
if thisboard.is_check:
return 10000
return 0
move = list(thisboard.legal_moves)[0]
move = chess.Move.from_uci(str(move))
thisboard.push(move)
for i in chess.LegalMoveGenerator(thisboard): evaluation -= 1 * table_analysis.weights["mobility"]
return evaluation * color
def iterative_deepening(max_depth, board, color):
firstguess = 0
st = time()
previous_fen = board.fen()
board = chess.Board(previous_fen)
value = -10000
for d in range(max_depth):
for move in board.legal_moves:
board.push(chess.Move.from_uci(str(move)))
firstguess = negamax(board, d, color)
board = chess.Board(previous_fen)
if firstguess > value:
best_move = move
value = firstguess
if times_up(st, 1) or firstguess >= 10000:
break
if times_up(st, 1) or firstguess >= 10000:
break
return str(best_move)
def negamax(board, depth, color: int):
"""
color can be either 1 or -1. 1 for white and -1 for black
"""
if depth == 0:
return evaluate(board.fen(), color)
value = -inf
previous_fen = board.fen()
for move in board.legal_moves:
board.push(chess.Move.from_uci(str(move)))
nega = -negamax(board, depth-1, -color)
value = max(value, nega) # can do class node that stores a board and the possible moves and then I can say if it is a terminal node (a node that determains loss, win and draws) with a parameter purpose.
board = chess.Board(previous_fen)
return value
def quiesce(alpha,beta, board):
stand_pat = evaluate(board.fen(), 1)
if( stand_pat >= beta ): return beta
if( alpha < stand_pat ): alpha = stand_pat
for capture in board.generate_pseudo_legal_captures():
board.push(chess.Move.from_uci(str(capture)))
score = -quiesce( -beta, -alpha, board )
board.pop()
if( score >= beta ): return beta
if( score > alpha ): alpha = score
return alpha
def main1(time_left):
board = chess.Board()
move_num = 0
game = ""
pgn = ""
try:
while not board.is_game_over():
move_num += 1
value = iterative_deepening(10, board, 1)
board.push(chess.Move.from_uci(value))
#os.system("clear")
print(board)
game += "%s. %s" % (str(move_num), str(value))
if board.is_game_over(): break
value = iterative_deepening(10, board, -1)
#os.system("clear")
print(board)
game += " %s " % value
pgn = io.StringIO(game)
except Exception as err:
print(err)
for i in pgn:
print(i)
print(move_num)
for i in pgn:
print(i)
if __name__ == "__main__":
main1(10)
There's at least one bug in your code: In (C) a new position is assigned to board
while still iterating over the legal moves of the old position (A).
def iterative_deepening(max_depth, board, color):
firstguess = 0
st = time()
previous_fen = board.fen()
board = chess.Board(previous_fen)
value = -10000
for d in range(max_depth):
for move in board.legal_moves: # (A)
board.push(chess.Move.from_uci(str(move))) # (B)
firstguess = negamax(board, d, color)
board = chess.Board(previous_fen) # (C)
if firstguess > value:
best_move = move
value = firstguess
if times_up(st, 1) or firstguess >= 10000:
break
if times_up(st, 1) or firstguess >= 10000:
break
return str(best_move)
I recommend putting something like assert board.is_legal(move)
before each board.push()
to find these issues. Remove the blanket except Exception
to get better backtraces.
Unrelated: I noticed a lot of useless string conversions: board.push(chess.Move.from_uci(str(move)))
where move
is a Move
object can be written as board.push(move)
.
tried to do board.push(move)
but got an error somhow.
I don't know why but board.pop()
isn't working as well
and thank you so much
I am making a chess engine for the experience (that is why I am using python). when I write the board.legal_moves it is giving me an option to eat my pieces. So the engine is eating itself. Secondly, you can just play a game with only one side playing. All of the above can be helpful sometimes when you want to get to a specific board. So can you make a settings function or something like that? Is it only a problem I have?
EDIT: can eat king too and the game doesn't stop even if I say
and the king stepping into checks too