I am undertaking the (somewhat ambitious) project of writing a chess game to be played in a Mac Terminal, using algebraic notation inputs to effect the moves.
I have written my board as a list of lists, with each nested list serving as a rank (horizontal line) on the board:
board = [['bR', 'bN', 'bB', 'bQ', 'bK', 'bB', 'bN', 'bR'],
['bP', 'bP', 'bP', 'bP', 'bP', 'bP', 'bP', 'bP'],
['e ', 'e ', 'e ', 'e ', 'e ', 'e ', 'e ', 'e '],
['e ', 'e ', 'e ', 'e ', 'e ', 'e ', 'e ', 'e '],
['e ', 'e ', 'e ', 'e ', 'e ', 'e ', 'e ', 'e '],
['e ', 'e ', 'e ', 'e ', 'e ', 'e ', 'e ', 'e '],
['wP', 'wP', 'wP', 'wP', 'wP', 'wP', 'wP', 'wP'],
['wR', 'wN', 'wB', 'wQ', 'wK', 'wB', 'wN', 'wR']
]
I have then written a (rather long) procedure to check what legal moves are available for a piece, based exclusively on the input given by the user of the desired move s/he would like to make.
I am trying to make my code less repetitive, but I am having trouble generating the list of possible moves for bishops, rooks, and the queen. For example, for a bishop, I first use the given input to locate the bishop that could move to that particular square and store its position. Then, I generate a list of possible squares to which the bishop can move, using a while loop to go in the direction of each diagonal. It ends up looking like:
elif piece == 'B':
s,d = square[0] + square[1], square[0] - square[1]
squares = [(r,f) for r in range(-8,0) for f in range(len(board)) if r-f == d or r+f==s]
pos_bishop=[]
for i in squares:
pos = board[i[0]][i[1]]
if pos == mover:
pos_bishop.append(i[0])
pos_bishop.append(i[1])
break
if len(pos_bishop) == 0:
return False
squares2 = []
j,k = pos_bishop[0], pos_bishop[1]
while j>-8 and k>0 and board[j-1][k-1] == 'e ':
squares2.append((j-1,k-1))
j-=1
k-=1
j,k = pos_bishop[0], pos_bishop[1]
while j>-8 and k<8 and board[j-1][k+1] == 'e ':
squares2.append((j-1,k+1))
j-=1
k+=1
j,k = pos_bishop[0], pos_bishop[1]
while j<-1 and k>0 and board[j+1][k-1] == 'e ':
squares2.append((j+1,k-1))
j+=1
k-=1
j,k = pos_bishop[0], pos_bishop[1]
while j<-1 and k<8 and board[j+1][k+1] == 'e ':
squares2.append((j+1,k+1))
j+=1
k+=1
if square in squares2:
return True
As you can see, there are four 'while' loops, and at the start of each I have to redefine the position variables. This seems unwieldy, but I am having trouble thinking of a different way to generate the moves in a more efficient manner. (I am not yet working on if the move is a capture, btw, just seeing if the square is empty.)
I would appreciate a push in the right direction rather than just an explicit solution; but any advice would be welcome. Thanks !