Skip to content

Instantly share code, notes, and snippets.

@sjatkins
Last active November 15, 2016 07:51
Show Gist options
  • Save sjatkins/1cee945612e01e344089e1bb4f17abb5 to your computer and use it in GitHub Desktop.
Save sjatkins/1cee945612e01e344089e1bb4f17abb5 to your computer and use it in GitHub Desktop.
from itertools import permutations, product
def pairs(it):
return [(a,b) for a in it[:-1] for b in it[a+1:]]
class Board(object):
offset_pairs = ((1, -2), (1, 2), (2, -1), (2, 1), (-1, -2), (-1, 2), (-2, 1), (-2, -1))
unrestricted = (-2, -1, 1, -2)
dim_specials = {
0: (1,2), 1:(-1, 1, 2), -1: (-1, -2), -2: (1, -1, -2)
}
def __init__(self, *dimension_sizes):
self._dims = dimension_sizes
self._dim_pairs = pairs(range(len(self._dims)))
self._dim_legal = self._compute_dim_legals()
def _compute_dim_legals(self):
def dim_legal(dim):
return lambda val: self.dim_specials.get(val) or self.dim_specials.get(val - dim) or self.unrestricted
return [dim_legal(d) for d in self._dims]
def offset_by(self, coord, offset):
return tuple([(coord[i] + offset[i]) for i in range(len(coord))])
def legal_offsets(self, coord):
legals = [f(c) for f,c in zip(self._dim_legal, coord)]
for d1, d2 in self._dim_pairs:
for a,b in product(legals[d1], legals[d2]):
if abs(a) != abs(b):
res = [0] * len(self._dims)
res[d1] = a
res[d2] = b
yield res
def knight_moves(self, coord):
return [self.offset_by(coord, o) for o in self.legal_offsets(coord)]
def coords(self):
return product(*[range(d) for d in self._dims])
def knights_graph(self):
"""
returns adjacency map of coordinate -> legal knight move end coordinates
from coordinate
"""
return {coord: self.knight_moves(coord) for coord in self.coords()}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment