Skip to content

Instantly share code, notes, and snippets.

@JoaoFelipe
Created September 24, 2018 18:36
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save JoaoFelipe/1349e3094001cb9e95d3b6983891de28 to your computer and use it in GitHub Desktop.
Save JoaoFelipe/1349e3094001cb9e95d3b6983891de28 to your computer and use it in GitHub Desktop.
Chess
from collections import deque
def chess_to_tuple(chess_position):
"Converts chess position (eg., 'a1') to tuple (eg., (1, 1))"
first = ord(chess_position[0]) - ord('a') + 1
second = int(chess_position[1])
return (first , second)
def tuple_to_chess(column, line):
"Converts position to chess notation (eg., 'a1')"
if 1 <= column <= 8 and 1 <= line <= 8:
first = chr(column + ord('a') - 1)
second = str(line)
return first + second
return None
def knight_moves(chess_position):
"Generates possible movement positions for the knight"
position_tuple = chess_to_tuple(chess_position)
delta_moves = [
(1, -2), (-1, 2), (-2, -1), (1, 2),
(2, -1), (-2, 1), (-1, -2), (2, 1)
]
for delta in delta_moves:
new_position = tuple_to_chess(
position_tuple[0] + delta[0],
position_tuple[1] + delta[1]
)
if new_position is not None:
yield new_position
def knight(source, target):
"Calculates the minimum number of steps for the chess knight go from source to target"
visited = {source: 0}
fifo = deque([source])
if source == target:
return 0
while fifo:
element = fifo.popleft()
for pos in knight_moves(element):
if not pos in visited:
visited[pos] = visited[element] + 1
fifo.append(pos)
if pos == target:
return visited[pos]
print(knight("h8", "a1"))
chess_to_tuple = lambda pos: (ord(pos[0]) - ord('a') + 1, int(pos[1]))
tuple_to_chess = lambda col, lin: (
chr(col + ord('a') - 1) + str(lin)
if 1 <= col <= 8 and 1 <= lin <= 8
else None
)
knight_moves = lambda pos: (lambda tup: filter(
lambda y: y is not None,
map(
lambda x: tuple_to_chess(x[0] + tup[0], x[1] + tup[1]),
[(1, -2), (-1, 2), (-2, -1), (1, 2),
(2, -1), (-2, 1), (-1, -2), (2, 1)]
)
))(chess_to_tuple(pos))
knight = lambda source, target: (
lambda itself: lambda target, visited, fifo: itself(target, visited, fifo, itself))(
lambda target, visited, fifo, itself: (
itself(target, *(lambda element, *rest: (lambda filtered: (
{**visited, **{pos: visited[element] + 1
for pos in filtered}},
list(rest) + filtered if target not in filtered else [target]
))(
[x for x in knight_moves(element) if x not in visited]
))(*fifo), itself) if fifo else visited[target]
)
)(target, {source: 0}, [source])
print(knight("h8", "a1"))
knight = (lambda source, target: (
lambda itself: lambda target, visited, fifo: itself(target, visited, fifo, itself))(
lambda target, visited, fifo, itself: (
(lambda chess_to_tuple, tuple_to_chess: (
(lambda knight_moves: (
itself(target, *(lambda element, *rest: (lambda filtered: (
{**visited, **{pos: visited[element] + 1
for pos in filtered}},
list(rest) + filtered if target not in filtered else [target]
))(
[x for x in knight_moves(element) if x not in visited]
))(*fifo), itself) if fifo else visited[target]
))(
lambda pos: (lambda tup: filter(
lambda y: y is not None,
map(
lambda x: tuple_to_chess(x[0] + tup[0], x[1] + tup[1]),
[(1, -2), (-1, 2), (-2, -1), (1, 2),
(2, -1), (-2, 1), (-1, -2), (2, 1)]
)
))(chess_to_tuple(pos))
)
))(
lambda pos: (ord(pos[0]) - ord('a') + 1, int(pos[1])),
lambda col, lin: chr(col + ord('a') - 1) + str(lin) if 1 <= col <= 8 and 1 <= lin <= 8 else None
)
)
)(target, {source: 0}, [source]))
print(knight("h8", "a1"))
knight = (lambda source, target: (lambda itself: lambda target, visited, fifo: itself(target, visited, fifo, itself))(lambda target, visited, fifo, itself: ((lambda chess_to_tuple, tuple_to_chess: ((lambda knight_moves: (itself(target, *(lambda element, *rest: (lambda filtered: ({**visited, **{pos: visited[element] + 1 for pos in filtered}},list(rest) + filtered if target not in filtered else [target]))([x for x in knight_moves(element) if x not in visited]))(*fifo), itself) if fifo else visited[target]))(lambda pos: (lambda tup: filter(lambda y: y is not None,map(lambda x: tuple_to_chess(x[0] + tup[0], x[1] + tup[1]),[(1, -2), (-1, 2), (-2, -1), (1, 2),(2, -1), (-2, 1), (-1, -2), (2, 1)])))(chess_to_tuple(pos)))))(lambda pos: (ord(pos[0]) - ord('a') + 1, int(pos[1])),lambda col, lin: chr(col + ord('a') - 1) + str(lin) if 1 <= col <= 8 and 1 <= lin <= 8 else None)))(target, {source: 0}, [source]))
print(knight("h8", "a1"))
knight = (
lambda
source, target: (
lambda itself:
lambda target,
visited, fifo:
itself (target,
visited, fifo, itself))(
lambda target ,visited, fifo, itself: (
(lambda chess_to_tuple, tuple_to_chess: (
(lambda knight_moves: (
itself( target,
*(lambda element,
*rest: (lambda filtered: (
{** visited, **{pos:
visited [element]
+ 1 for pos in filtered
}}, list (rest) +
filtered if target
not in filtered else [
target]))([x for x in
knight_moves(element) if x not in visited]
))(*fifo), itself) if fifo
else visited
[target]))( lambda
pos: (lambda
tup: filter
(lambda y: y
is not None,
map( lambda x:
tuple_to_chess (x[0] + tup[0], x[1] + tup[1]), [(1, -2), (-1, 2), (-2, -1),
(1, 2), (2, -1),
(-2, 1), (-1, -2),
(2, 1)]))) (chess_to_tuple
(pos))) ))(lambda pos:
(ord (pos[0])
- ord('a') + 1, int
(pos[1])), lambda col,
lin: chr(col +
ord('a') - 1) + str
(lin) if 1 <= col <= 8 and 1 <= lin <= 8 else None)))(target, {source: 0}, [source]))
print(knight("h8", "a1"))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment