Created
February 27, 2021 21:06
Tenable CTF Is King In Check Solution
This file contains 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
import itertools | |
WHITE = "white" | |
BLACK = "black" | |
class Game: | |
def __init__(self,pieces): | |
self.playersturn = BLACK | |
self.message = "NoCheck" | |
self.gameboard = {} | |
self.placePiecesEdited(pieces) | |
def placePiecesEdited(self,pieces): | |
placers={ | |
"q" : Queen, | |
"k" : King, | |
"b" : Bishop, | |
"r" : Rook, | |
"n" : Knight, | |
"p" : Pawn | |
} | |
colors={ | |
"w" : WHITE, | |
"b" : BLACK | |
} | |
for piece in pieces: | |
color,placer_t,coordinat = piece.split(',') | |
coordinat=((ord(coordinat[0])-97), int(coordinat[1])-1) | |
placer = placers[placer_t] | |
color =colors[color] | |
dir = 1 if color=="white" else -1 | |
if placer_t=="p": | |
self.gameboard[(coordinat[0],coordinat[1])] =Pawn(color,uniDict[color][placer] , dir) | |
else: | |
self.gameboard[(coordinat[0],coordinat[1])] =placer(color,uniDict[color][placer]) | |
self.isCheck() | |
def isCheck(self): | |
king = King | |
kingDict = {} | |
pieceDict = {BLACK : [], WHITE : []} | |
for position,piece in self.gameboard.items(): | |
if isinstance(piece,King): | |
kingDict[piece.Color] = position | |
pieceDict[piece.Color].append((piece,position)) | |
if self.canSeeKing(kingDict[WHITE],pieceDict[BLACK]): | |
self.message = "White player is in check" | |
if self.canSeeKing(kingDict[BLACK],pieceDict[WHITE]): | |
self.message = "Black player is in check" | |
def canSeeKing(self,kingpos,piecelist): | |
for piece,position in piecelist: | |
if piece.isValid(position,kingpos,piece.Color,self.gameboard): | |
return True | |
class Piece: | |
def __init__(self,color,name): | |
self.name = name | |
self.position = None | |
self.Color = color | |
def isValid(self,startpos,endpos,Color,gameboard): | |
if endpos in self.availableMoves(startpos[0],startpos[1],gameboard, Color = Color): | |
return True | |
return False | |
def availableMoves(self,x,y,gameboard): | |
print("ERROR: no movement for base class") | |
def AdNauseum(self,x,y,gameboard, Color, intervals): | |
answers = [] | |
for xint,yint in intervals: | |
xtemp,ytemp = x+xint,y+yint | |
while self.isInBounds(xtemp,ytemp): | |
target = gameboard.get((xtemp,ytemp),None) | |
if target is None: answers.append((xtemp,ytemp)) | |
elif target.Color != Color: | |
answers.append((xtemp,ytemp)) | |
break | |
else: | |
break | |
xtemp,ytemp = xtemp + xint,ytemp + yint | |
return answers | |
def isInBounds(self,x,y): | |
if x >= 0 and x < 8 and y >= 0 and y < 8: | |
return True | |
return False | |
def noConflict(self,gameboard,initialColor,x,y): | |
if self.isInBounds(x,y) and (((x,y) not in gameboard) or gameboard[(x,y)].Color != initialColor) : return True | |
return False | |
chessCardinals = [(1,0),(0,1),(-1,0),(0,-1)] | |
chessDiagonals = [(1,1),(-1,1),(1,-1),(-1,-1)] | |
def knightList(x,y,int1,int2): | |
return [(x+int1,y+int2),(x-int1,y+int2),(x+int1,y-int2),(x-int1,y-int2),(x+int2,y+int1),(x-int2,y+int1),(x+int2,y-int1),(x-int2,y-int1)] | |
def kingList(x,y): | |
return [(x+1,y),(x+1,y+1),(x+1,y-1),(x,y+1),(x,y-1),(x-1,y),(x-1,y+1),(x-1,y-1)] | |
class Knight(Piece): | |
def availableMoves(self,x,y,gameboard, Color = None): | |
if Color is None : Color = self.Color | |
return [(xx,yy) for xx,yy in knightList(x,y,2,1) if self.noConflict(gameboard, Color, xx, yy)] | |
class Rook(Piece): | |
def availableMoves(self,x,y,gameboard ,Color = None): | |
if Color is None : Color = self.Color | |
return self.AdNauseum(x, y, gameboard, Color, chessCardinals) | |
class Bishop(Piece): | |
def availableMoves(self,x,y,gameboard, Color = None): | |
if Color is None : Color = self.Color | |
return self.AdNauseum(x, y, gameboard, Color, chessDiagonals) | |
class Queen(Piece): | |
def availableMoves(self,x,y,gameboard, Color = None): | |
if Color is None : Color = self.Color | |
return self.AdNauseum(x, y, gameboard, Color, chessCardinals+chessDiagonals) | |
class King(Piece): | |
def availableMoves(self,x,y,gameboard, Color = None): | |
if Color is None : Color = self.Color | |
return [(xx,yy) for xx,yy in kingList(x,y) if self.noConflict(gameboard, Color, xx, yy)] | |
class Pawn(Piece): | |
def __init__(self,color,name,direction): | |
self.name = name | |
self.Color = color | |
self.direction = direction | |
def availableMoves(self,x,y,gameboard, Color = None): | |
if Color is None : Color = self.Color | |
answers = [] | |
if (x+1,y+self.direction) in gameboard and self.noConflict(gameboard, Color, x+1, y+self.direction) : answers.append((x+1,y+self.direction)) | |
if (x-1,y+self.direction) in gameboard and self.noConflict(gameboard, Color, x-1, y+self.direction) : answers.append((x-1,y+self.direction)) | |
if (x,y+self.direction) not in gameboard and Color == self.Color : answers.append((x,y+self.direction)) | |
return answers | |
uniDict = {WHITE : {Pawn : "wp", Rook : "wr", Knight : "wk", Bishop : "wb", King : "wk", Queen : "wq" }, | |
BLACK : {Pawn : "bp", Rook : "br", Knight : "bk", Bishop : "bb", King : "bk", Queen : "bq" }} | |
def ParseMatches(chess_matches): | |
return [c.split('+') for c in chess_matches.split(' ')] | |
def IsKingInCheck(chess_match): | |
pieces=chess_match | |
game = Game(pieces) | |
if game.message=="NoCheck": | |
return False | |
return True | |
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