You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Hello. I'm trying to make a chess engine using the chess library, however during testing this error occurred:
Traceback (most recent call last):
File "c:\Users\Admin\Desktop\MyFish 1.0\search.py", line 163, in <module>
raise e
File "c:\Users\Admin\Desktop\MyFish 1.0\search.py", line 159, in <module>
move = search.minimax(board, 20, -1, -1, True, chess.BLACK)[1]
~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "c:\Users\Admin\Desktop\MyFish 1.0\search.py", line 124, in minimax
raise e
File "c:\Users\Admin\Desktop\MyFish 1.0\search.py", line 92, in minimax
evaluation = self.minimax(new_board, depth-1, alpha, beta, False, side)
File "c:\Users\Admin\Desktop\MyFish 1.0\search.py", line 124, in minimax
raise e
File "c:\Users\Admin\Desktop\MyFish 1.0\search.py", line 111, in minimax
evaluation = self.minimax(new_board, depth-1, alpha, beta, True, side)
File "c:\Users\Admin\Desktop\MyFish 1.0\search.py", line 124, in minimax
raise e
File "c:\Users\Admin\Desktop\MyFish 1.0\search.py", line 92, in minimax
evaluation = self.minimax(new_board, depth-1, alpha, beta, False, side)
File "c:\Users\Admin\Desktop\MyFish 1.0\search.py", line 124, in minimax
raise e
File "c:\Users\Admin\Desktop\MyFish 1.0\search.py", line 111, in minimax
evaluation = self.minimax(new_board, depth-1, alpha, beta, True, side)
File "c:\Users\Admin\Desktop\MyFish 1.0\search.py", line 124, in minimax
raise e
File "c:\Users\Admin\Desktop\MyFish 1.0\search.py", line 92, in minimax
evaluation = self.minimax(new_board, depth-1, alpha, beta, False, side)
File "c:\Users\Admin\Desktop\MyFish 1.0\search.py", line 124, in minimax
raise e
File "c:\Users\Admin\Desktop\MyFish 1.0\search.py", line 111, in minimax
evaluation = self.minimax(new_board, depth-1, alpha, beta, True, side)
File "c:\Users\Admin\Desktop\MyFish 1.0\search.py", line 124, in minimax
raise e
File "c:\Users\Admin\Desktop\MyFish 1.0\search.py", line 92, in minimax
evaluation = self.minimax(new_board, depth-1, alpha, beta, False, side)
File "c:\Users\Admin\Desktop\MyFish 1.0\search.py", line 124, in minimax
raise e
File "c:\Users\Admin\Desktop\MyFish 1.0\search.py", line 111, in minimax
evaluation = self.minimax(new_board, depth-1, alpha, beta, True, side)
File "c:\Users\Admin\Desktop\MyFish 1.0\search.py", line 124, in minimax
raise e
File "c:\Users\Admin\Desktop\MyFish 1.0\search.py", line 92, in minimax
evaluation = self.minimax(new_board, depth-1, alpha, beta, False, side)
File "c:\Users\Admin\Desktop\MyFish 1.0\search.py", line 124, in minimax
raise e
File "c:\Users\Admin\Desktop\MyFish 1.0\search.py", line 111, in minimax
evaluation = self.minimax(new_board, depth-1, alpha, beta, True, side)
File "c:\Users\Admin\Desktop\MyFish 1.0\search.py", line 124, in minimax
raise e
File "c:\Users\Admin\Desktop\MyFish 1.0\search.py", line 92, in minimax
evaluation = self.minimax(new_board, depth-1, alpha, beta, False, side)
File "c:\Users\Admin\Desktop\MyFish 1.0\search.py", line 124, in minimax
raise e
File "c:\Users\Admin\Desktop\MyFish 1.0\search.py", line 111, in minimax
evaluation = self.minimax(new_board, depth-1, alpha, beta, True, side)
File "c:\Users\Admin\Desktop\MyFish 1.0\search.py", line 124, in minimax
raise e
File "c:\Users\Admin\Desktop\MyFish 1.0\search.py", line 92, in minimax
evaluation = self.minimax(new_board, depth-1, alpha, beta, False, side)
File "c:\Users\Admin\Desktop\MyFish 1.0\search.py", line 124, in minimax
raise e
File "c:\Users\Admin\Desktop\MyFish 1.0\search.py", line 111, in minimax
evaluation = self.minimax(new_board, depth-1, alpha, beta, True, side)
File "c:\Users\Admin\Desktop\MyFish 1.0\search.py", line 124, in minimax
raise e
File "c:\Users\Admin\Desktop\MyFish 1.0\search.py", line 92, in minimax
evaluation = self.minimax(new_board, depth-1, alpha, beta, False, side)
File "c:\Users\Admin\Desktop\MyFish 1.0\search.py", line 124, in minimax
raise e
File "c:\Users\Admin\Desktop\MyFish 1.0\search.py", line 111, in minimax
evaluation = self.minimax(new_board, depth-1, alpha, beta, True, side)
File "c:\Users\Admin\Desktop\MyFish 1.0\search.py", line 124, in minimax
raise e
File "c:\Users\Admin\Desktop\MyFish 1.0\search.py", line 92, in minimax
evaluation = self.minimax(new_board, depth-1, alpha, beta, False, side)
File "c:\Users\Admin\Desktop\MyFish 1.0\search.py", line 124, in minimax
raise e
File "c:\Users\Admin\Desktop\MyFish 1.0\search.py", line 111, in minimax
evaluation = self.minimax(new_board, depth-1, alpha, beta, True, side)
File "c:\Users\Admin\Desktop\MyFish 1.0\search.py", line 124, in minimax
raise e
File "c:\Users\Admin\Desktop\MyFish 1.0\search.py", line 92, in minimax
evaluation = self.minimax(new_board, depth-1, alpha, beta, False, side)
File "c:\Users\Admin\Desktop\MyFish 1.0\search.py", line 124, in minimax
raise e
File "c:\Users\Admin\Desktop\MyFish 1.0\search.py", line 111, in minimax
evaluation = self.minimax(new_board, depth-1, alpha, beta, True, side)
File "c:\Users\Admin\Desktop\MyFish 1.0\search.py", line 79, in minimax
return self.Quiescence(board, side, 4, -1, 1)
~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^
File "c:\Users\Admin\Desktop\MyFish 1.0\search.py", line 47, in Quiescence
raise e
File "c:\Users\Admin\Desktop\MyFish 1.0\search.py", line 37, in Quiescence
current = self.Quiescence(new_board, side, depth-1, alpha, beta)
File "c:\Users\Admin\Desktop\MyFish 1.0\search.py", line 47, in Quiescence
raise e
File "c:\Users\Admin\Desktop\MyFish 1.0\search.py", line 37, in Quiescence
current = self.Quiescence(new_board, side, depth-1, alpha, beta)
File "c:\Users\Admin\Desktop\MyFish 1.0\search.py", line 47, in Quiescence
raise e
File "c:\Users\Admin\Desktop\MyFish 1.0\search.py", line 32, in Quiescence
attack_outcome = {list(board.legal_moves)[0]: Evaluate(board, side)}
~~~~~~~~^^^^^^^^^^^^^
File "c:\Users\Admin\Desktop\MyFish 1.0\search.py", line 6, in Evaluate
friendly = EvaluateSide(board, side)
File "c:\Users\Admin\Desktop\MyFish 1.0\eval.py", line 93, in EvaluateSide
king_location = list(board.pieces(chess.KING, side))[0]
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^^^
IndexError: list index out of range
so then i used a try and except statement to findout what color the "side" argument is, and it is black like it should be.
Here's the search.py file:
from eval import EvaluateSide
import random
import chess
def Evaluate(board: chess.Board, side: chess.WHITE | chess.BLACK):
friendly = EvaluateSide(board, side)
enemy = EvaluateSide(board, not side)
return ((friendly/(friendly+enemy))*2)-1
class Search:
def __init__(self):
self.pv_table = {}
self.nodes = 0
def Quiescence(self, board: chess.Board, side, depth, alpha = -1, beta = 1):
if depth == 0:
return Evaluate(board, side)
try:
attacks = [list(board.legal_moves)[0]]
for move in list(board.legal_moves):
if move.to_square in list(board.attacks(move.from_square)):
attacks.append(move)
if len(attacks) == 0:
return Evaluate(board, side)
attack_outcome = {list(board.legal_moves)[0]: Evaluate(board, side)}
for attack in attacks:
self.nodes += 1
new_board = board.copy()
new_board.push(attack)
current = self.Quiescence(new_board, side, depth-1, alpha, beta)
attack_outcome[attack] = current
if (board.turn == side):
alpha = max(current, alpha)
else:
beta = min(current, beta)
attacks.sort(key=lambda move: attack_outcome[move], reverse=(board.turn == side))
return attack_outcome[attacks[0]]
except Exception as e:
if not board.is_game_over():
raise e
return Evaluate(board, side)
def MoveOrdering(self, board: chess.Board):
move_ranking = {}
moves = list(board.legal_moves)
key = (int(board.occupied)*2)+int(not board.turn)
hit = None
if key in self.pv_table and self.pv_table[key] in moves:
try:
hit = self.pv_table[key]
moves.remove(moves.index(hit))
except:
hit = None
current_board = board.copy()
for move in moves:
board = current_board.copy()
board.push(move)
score = Evaluate(board, board.turn)
move_ranking[move] = score
moves.sort(key=lambda move: move_ranking[move], reverse=False)
if hit:
moves.insert(0, hit)
return moves
def minimax(self, board: chess.Board, depth, alpha = -1, beta = 1, maximizingPlayer = False, side = chess.WHITE):
if depth == 0:
return self.Quiescence(board, side, 4, -1, 1)
moves = self.MoveOrdering(board)
try:
if maximizingPlayer:
key = (int(board.occupied)*2)+int(not board.turn)
maxMove = moves[0]
maxEval = -1
for move in moves:
self.nodes += 1
new_board = board.copy()
new_board.push(move)
evaluation = self.minimax(new_board, depth-1, alpha, beta, False, side)
if type(evaluation) != float:
evaluation = evaluation[0]
if evaluation > maxEval:
maxEval = evaluation
maxMove = move
alpha = max(alpha, evaluation)
if beta <= alpha:
break
self.pv_table[key] = maxMove
return [maxEval, maxMove]
else:
key = (int(board.occupied)*2)+int(not board.turn)
minMove = moves[0]
minEval = 1
for move in moves:
self.nodes += 1
new_board = board.copy()
new_board.push(move)
evaluation = self.minimax(new_board, depth-1, alpha, beta, True, side)
if type(evaluation) != float:
evaluation = evaluation[0]
if evaluation < minEval:
minEval = evaluation
minMove = move
beta = min(beta, evaluation)
if beta <= alpha:
break
self.pv_table[key] = minMove
return [minEval, minMove]
except Exception as e:
if not board.is_game_over():
raise e
return self.Quiescence(board, side, 4, -1, 1)
def Visualize(board: chess.Board):
black = ["KQRBNP", "♔♕♖♗♘♙"]
white = ["KQRBNP", "♚♛♜♝♞♟"]
lines = []
for i in range(8):
lines.append([".", ".", ".", ".", ".", ".", ".", "."])#([".", ".", ".", ".", ".", ".", ".", "."])
pieces = []
for piece in [chess.PAWN, chess.KNIGHT, chess.BISHOP, chess.ROOK, chess.QUEEN, chess.KING]:
pieces = pieces + list(board.pieces(piece, chess.BLACK))
pieces = pieces + list(board.pieces(piece, chess.WHITE))
for piece in pieces:
if board.color_at(piece) == chess.BLACK:
lines[int(chess.square_name(piece)[1])-1]["abcdefgh".index(chess.square_name(piece)[0])] = black[1][black[0].index(board.piece_at(piece).symbol().upper())]
if board.color_at(piece) == chess.WHITE:
lines[int(chess.square_name(piece)[1])-1]["abcdefgh".index(chess.square_name(piece)[0])] = white[1][white[0].index(board.piece_at(piece).symbol().upper())]
string = ""
for i in range(8):
string = string+str(9-(i+1))+". "+(" ".join(lines[7-i]))+"\n"
string = string + " " + (" ".join(list("ABCDEFGH")))
return string
board = chess.Board()
search = Search()
while True:
try:
print(Visualize(board))
board.push_uci(input())
print(Visualize(board))
move = search.minimax(board, 20, -1, -1, True, chess.BLACK)[1]
board.push(move)
except Exception as e:
print(board.fen())
raise e
and here's the eval.py file (with one unprofessional comment removed):
import chess
import math
MG_PIECE_VALUES = {
chess.PAWN: 82,
chess.KNIGHT: 337,
chess.BISHOP: 365,
chess.ROOK: 477,
chess.QUEEN: 1025,
chess.KING: 24000,
}
EG_PIECE_VALUES = {
chess.PAWN: 94,
chess.KNIGHT: 281,
chess.BISHOP: 297,
chess.ROOK: 512,
chess.QUEEN: 936,
chess.KING: 24000,
}
Attack_Table = {
1: 0,
2: 50,
3: 75,
4: 88,
5: 94,
6: 97,
7: 99,
}
def PieceEvaluation(board: chess.Board, position: int, type: any, side: chess.WHITE | chess.BLACK):
if type == chess.PAWN:
if side == chess.WHITE:
if position == 0:
position = 1
position = math.ceil(position/8)
else:
position = 63-position
if position == 0:
position = 1
position = math.ceil(position/8)
return 1+(position/32)
return 1
def EvaluateSide(board: chess.Board, side: chess.WHITE | chess.BLACK):
# Mate-at-a-Glance detection
board.turn = not side
for move in list(board.legal_moves):
board.push(move)
if board.is_checkmate():
return 0
board.pop()
# Compute Safe-Entropy / Mobility
attacked = {}
for attacker in chess.SquareSet(board.occupied_co[not side]):
for attack in board.attacks(attacker):
attacked[attack] = 0
board.turn = side
moves = 0
Safe = {}
for move in list(board.legal_moves):
if move.from_square in Safe or board.attackers(not side, move.from_square) == chess.SquareSet():
Safe[move.from_square] = 1
moves += 1
controlled = {}
for attacker in chess.SquareSet(board.occupied_co[side]):
if attacker in Safe:
for attack in board.attacks(attacker):
if not attack in attacked:
controlled[attack] = 1
entropy = 140*math.log((len(list(controlled.keys()))*moves)+1)
# Compute Material (+ entropy consideration)
stage = (len(list(chess.SquareSet(board.occupied_co[side])))+len(list(chess.SquareSet(board.occupied_co[not side]))))/32
material = 0
for piece in chess.SquareSet(board.occupied_co[side]):
piece_type = board.piece_type_at(piece)
MG_value = MG_PIECE_VALUES[piece_type]
EG_value = EG_PIECE_VALUES[piece_type]
material += ((MG_value * stage) + (EG_value * (1 - stage)))*PieceEvaluation(board, piece, board.piece_type_at(piece), board.color_at(piece))
# Compute king-safety
attackers = 0
king_location = list(board.pieces(chess.KING, side))[0]
for offset in [-9, -8, -7, -1, 1, 7, 8, 9]:
try:
square = king_location - offset
if chess.square_distance(king_location, square) == 1:
attackers += len(list(board.attackers(not side, square)))
except:
pass
attackers = max(1, attackers)
attackers = min(7, attackers)
king_safety = 1-(Attack_Table[attackers]/100)
# Compute Final Score
score = (material+entropy)*king_safety
return score
this error occured on python 3.13.3 with the latest "chess" library update.
The text was updated successfully, but these errors were encountered:
Hello. I'm trying to make a chess engine using the chess library, however during testing this error occurred:
so then i used a try and except statement to findout what color the "side" argument is, and it is black like it should be.
Here's the search.py file:
and here's the eval.py file (with one unprofessional comment removed):
this error occured on python 3.13.3 with the latest "chess" library update.
The text was updated successfully, but these errors were encountered: