Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I generate all of a knight's moves?

Tags:

python

chess

I am writing a Chess program in Python that needs to generate all the moves of a knight. For those not familiar with chess, a knight moves in an L shape.

So, given a position of (2, 4) a knight could move to (0, 3), (0, 5), (1, 2), (3, 2), etc. for a total of (at most) eight different moves.

I want to write a function called knight_moves that generates these tuples in a list. What is the easiest way to do this in Python?

def knight_moves(position):
    ''' Returns a list of new positions given a knight's current position. '''
    pass
like image 298
sdasdadas Avatar asked Oct 15 '13 03:10

sdasdadas


3 Answers

Ok, so thanks to Niall Byrne, I came up with this:

from itertools import product
def knight_moves(position):
    x, y = position
    moves = list(product([x-1, x+1],[y-2, y+2])) + list(product([x-2,x+2],[y-1,y+1]))
    moves = [(x,y) for x,y in moves if x >= 0 and y >= 0 and x < 8 and y < 8]
    return moves
like image 138
sdasdadas Avatar answered Nov 12 '22 18:11

sdasdadas


Why not store the relative pairs it can move in ? So take your starting point, and add a set of possible moves away from it, you then would just need a sanity check to make sure they are still in bounds, or not on another piece.

ie given your (2, 4) starting point, the options are (-2,-1), (-2,+1), (-1,+2), (+2,+1) The relative positions would thus always be the same.

like image 8
Niall Byrne Avatar answered Nov 12 '22 18:11

Niall Byrne


Not familiar with chess...

deltas = [(-2, -1), (-2, +1), (+2, -1), (+2, +1), (-1, -2), (-1, +2), (+1, -2), (+1, +2)]
def knight_moves(position):
    valid_position = lambda (x, y): x >= 0 and y >= 0 and ???
    return filter(valid_position, map(lambda (x, y): (position[0] + x, position[1] + y), deltas))
like image 5
xiaowl Avatar answered Nov 12 '22 18:11

xiaowl