Finding all legal bishop moves I am trying to create a two player Chess game. To do this I want to generate a list of legal moves. I am having trouble with the brevity of the code to generate the moves for the rooks and bishops.

The code I have pasted below works (i.e. shows legal bishop moves) but there is a lot of repetition, which is not ideal. To make this work for both black and white bishops I would need to add even more repetitive lines. 

Is there a better way to do this? I do not want to use any 'chess modules' as this is a learning exercise for me; as you can tell, I am a beginner.

import numpy as np

# chess board is a numpy array
# white pieces are capitalised, black pieces are not
board = np.zeros((8,8),dtype=str)

# example piece positions
white_bishop = (4,5)
white_pawn = (6,7)
black_knight = (0,1)
board[white_bishop] = 'B'
board[white_pawn] = 'P'
board[black_knight] = 'n'

def bishop(insquare):
    '''
    Gets all legal moves for bishop on insquare
    output is a list (outsquares) of indices of possible squares
    '''
    out_squares = []
    y,x = insquare

    y1 = y-1 # these are steps in one of the four directions bishops can go
    x1 = x-1
    while (x1 &gt; -1) and (y1 &gt; -1): # edge of the board
        if not board[(y1,x1)].isupper(): # if not a white piece...
            out_squares.append((y1,x1)) # square is legal
            if board[(y1,x1)].islower(): # if black piece...
                y1 = -1 # look no further in this direction
        else: # if white piece...
            y1 = -1 # look no further in this direction
        y1 -= 1 # check next square
        x1 -= 1

    # check all other directions
    y1 = y+1
    x1 = x+1
    while (x1 &lt; 8) and (y1 &lt; 8):
        if not board[(y1,x1)].isupper():
            out_squares.append((y1,x1))
            if board[(y1,x1)].islower():
                y1 = 8
        else:
            y1 = 8
        y1 += 1
        x1 += 1

    y1 = y + 1
    x1 = x - 1
    while (x1 &gt; -1) and (y1 &lt; 8):
        if not board[(y1,x1)].isupper():
            out_squares.append((y1,x1))
            if board[(y1,x1)].islower():
                y1 = 8
        else:
            y1 = 8
        y1 += 1
        x1 -= 1

    y1 = y - 1
    x1 = x + 1
    while (x1 &lt; 8) and (y1 &gt; -1):
        if not board[(y1,x1)].isupper():
            out_squares.append((y1,x1))
            if board[(y1,x1)].islower():
                y1 = -1
        else:
            y1 = -1
        y1 = y1 - 1
        x1 = x1 + 1
    return out_squares

# Get all legal moves for the white bishop
print bishop((4,5))
# &gt;&gt;&gt; [(3, 4), (2, 3), (1, 2), (5, 6), (5, 4), (6, 3), (7, 2), (3, 6), (2, 7)]
When you find yourself having a lot of duplicate code, you should factor out the commonalities. In this case, we have four separate directions we need to consider. So let's write one function that considers one direction:

def append(dx, dy):
    for i in itertools.count(start=1):
        newx = x + dx*i
        newy = y + dy*i
        sq = (newy, newx)

        if 0 &lt;= newx &lt; 8 and 0 &lt;= newy &lt; 8:
            if not board[sq].isupper():
                out_squares.append(sq)
                if board[sq].islower():
                    break
            else:
                break
        else:
            break


And then just call it 4 times:

for dx in (-1, 1):
    for dy in (-1, 1):
        append(dx, dy)


Full solution:

def bishop(insquare):
    ''' 
    Gets all legal moves for bishop on insquare
    output is a list (outsquares) of indices of possible squares
    '''
    out_squares = []
    y,x = insquare

    def append(dx, dy):
        for i in itertools.count(start=1):
            newx = x + dx*i
            newy = y + dy*i

            if 0 &lt;= newx &lt; 8 and 0 &lt;= newy &lt; 8:
                sq = (newy, newx)
                if not board[sq].isupper():
                    out_squares.append(sq)
                    if board[sq].islower():
                        break
                else:
                    break
            else:
                break

    for dx in (-1, 1):
        for dy in (-1, 1):
            append(dx, dy) 

    return out_squares