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
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
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.
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))
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With