Created
February 22, 2021 17:23
-
-
Save Ankirama/887c72225b84cef964c07423d9b41a4d to your computer and use it in GitHub Desktop.
Tenable CTF Is King Check / Checkmate?
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
PIECES = { | |
'q': { | |
'name': 'Queen', | |
'moves': [ | |
(0, 1), | |
(1, 1), | |
(1, 0) | |
], | |
'isdir': True, | |
'ismul': True | |
}, | |
'k': { | |
'name': 'King', | |
'moves': [ | |
(0, 1), | |
(1, 1), | |
(1, 0) | |
], | |
'isdir': True, | |
'ismul': False | |
}, | |
'b': { | |
'name': 'Bishop', | |
'moves': [ | |
(1, 1) | |
], | |
'isdir': True, | |
'ismul': True | |
}, | |
'r': { | |
'name': 'Rook', | |
'moves': [ | |
(0, 1), | |
(1, 0) | |
], | |
'isdir': True, | |
'ismul': True | |
}, | |
'n': { | |
'name': 'Knight', | |
'moves': [ | |
(1, 2), | |
(2, 1) | |
], | |
'isdir': True, | |
'ismul': False | |
}, | |
'p': { | |
'name': 'Pawn', | |
'moves': [ | |
(1, -1), | |
(1, 1) | |
], | |
'isdir': False, | |
'ismul': False | |
} | |
} | |
class Piece(): | |
def __init__(self, c, t, p): | |
self.x = ord(p[0]) - ord('a') + 1 | |
self.y = int(p[1]) | |
self.t = t | |
self.c = c | |
self.moves = PIECES[t]['moves'] | |
self.isdir = PIECES[t]['isdir'] | |
self.ismul = PIECES[t]['ismul'] | |
def check_position(self, addx, addy, x, y): | |
return self.x + addx == x and self.y + addy == y | |
def check_positions(self, x, y, mulx=1, muly=1): | |
for move in self.moves: | |
if self.check_position(move[0] * mulx, move[1] * muly, x, y): | |
return True | |
return False | |
def can_i_go_there_please(self, x, y): | |
if not self.ismul: | |
if not self.isdir: | |
return self.check_positions(x, y, -1 if self.c == 'w' else 1) | |
else: | |
for mx in [-1, 1]: | |
for my in [-1, 1]: | |
if self.check_positions(x, y, mx, my): | |
return True | |
else: | |
kx = abs(x - self.x) | |
ky = abs(y - self.y) | |
for move in self.moves: | |
if kx == 0: | |
if move[0] == 0: | |
return True | |
if ky == 0: | |
if move[1] == 0: | |
return True | |
if kx - ky == 0: | |
return True | |
return False | |
def ParseMatches(chess_matches): | |
return [c.split('+') for c in chess_matches.split(' ')] | |
def IsKingInCheck(chess_match): | |
pieces = {'w': [], 'b': []} | |
kings = {'w': None, 'b': None} | |
for raw_piece in chess_match: | |
piece = Piece(*raw_piece.split(',')) | |
if piece.t != 'k': | |
pieces[piece.c].append(piece) | |
else: | |
kings[piece.c] = piece | |
if kings['w'] is None and kings['b'] is None: | |
return False | |
for color, pieces_c in pieces.items(): | |
c = 'b' if color == 'w' else 'w' | |
for piece in pieces_c: | |
if piece.can_i_go_there_please(kings[c].x, kings[c].y): | |
return True | |
return False | |
result = [] | |
chess_matches = ParseMatches(raw_input()) | |
for chess_match in chess_matches: | |
result.append(IsKingInCheck(chess_match)) | |
print(result) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment