-2

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 !

petezurich
  • 9,280
  • 9
  • 43
  • 57

1 Answers1

0

Question: thinking of a different way to generate the moves in a more efficient manner.

If you generalize it, using a function, you can use it for other pices as well.
Adding the four other directions, and the knowledge of "which moves are valid for the given pice", this function can be use for all pices

For example:

def compute_moves(pb0, pb1):
    m = []

    def get_moves(j, k, direction):
        if direction == 'sw':
            while j > -8 and k > 0 and board[j - 1][k - 1] == 'e ':
                m.append((j - 1, k - 1))
                j -= 1
                k -= 1
        elif direction == 'nw':
            while j > -8 and k < 8 and board[j - 1][k + 1] == 'e ':
                m.append((j - 1, k + 1))
                j -= 1
                k += 1
        elif direction == 'se':
            while j < -1 and k > 0 and board[j + 1][k - 1] == 'e ':
                m.append((j + 1, k - 1))
                j += 1
                k -= 1
        elif direction == 'ne':
            while j < -1 and k < 8 and board[j + 1][k + 1] == 'e ':
                m.append((j + 1, k + 1))
                j += 1
                k += 1

    for direction in ['sw', 'nw', 'se', 'ne']:
        get_moves(pb0, pb1, direction)

    return m       


if __name__ in "__main__":
    moves = compute_moves(pos_bishop[0], pos_bishop[1])
stovfl
  • 14,998
  • 7
  • 24
  • 51