def __init__(self, gameBoard): self.gameBoard = gameBoard self.White_Player = Human(Color.White) self.Black_Player = Human(Color.Black) self.current_player = "" self.white_legal = [] self.black_legal = [] #Create pointers to white/black's king respectively self.white_king = "" self.black_king = "" #Logic for updating/resetting the board self.piece_moved = "" self.original_location = "" self.new_location = "" self.piece_removed = "" self.pieces_in_game = [] self.game_state = State.Not_Started
def init_black(self, playerType): if playerType == PlayerType.Human: self.Black_Player = Human(Color.Black) else: self.Black_Player = AI(Color.Black)
def init_white(self, playerType): if playerType == PlayerType.Human: self.White_Player = Human(Color.White) else: self.White_Player = AI(Color.White)
class Game: def __init__(self, gameBoard): self.gameBoard = gameBoard self.White_Player = Human(Color.White) self.Black_Player = Human(Color.Black) self.current_player = "" self.white_legal = [] self.black_legal = [] #Create pointers to white/black's king respectively self.white_king = "" self.black_king = "" #Logic for updating/resetting the board self.piece_moved = "" self.original_location = "" self.new_location = "" self.piece_removed = "" self.pieces_in_game = [] self.game_state = State.Not_Started def reset(self): self.gameBoard.reset() self.White_Player.reset() self.Black_Player.reset() self.current_player = "" self.white_legal = [] self.black_legal = [] #Create pointers to white/black's king respectively self.white_king = "" self.black_king = "" #Logic for updating/resetting the board self.piece_moved = "" self.original_location = "" self.new_location = "" self.piece_removed = "" self.pieces_in_game = [] #Initialize white player def init_white(self, playerType): if playerType == PlayerType.Human: self.White_Player = Human(Color.White) else: self.White_Player = AI(Color.White) def init_black(self, playerType): if playerType == PlayerType.Human: self.Black_Player = Human(Color.Black) else: self.Black_Player = AI(Color.Black) def initialize_game(self): #Initialize Players White_Player = self.White_Player Black_Player = self.Black_Player #Set up for black pieces r1 = Rook("r1", Color.Black) r2 = Rook("r2", Color.Black) place_piece(self.gameBoard, "a8", r1) place_piece(self.gameBoard, "h8", r2) n1 = Knight("n1", Color.Black) n2 = Knight("n2", Color.Black) place_piece(self.gameBoard, "b8", n1) place_piece(self.gameBoard, "g8", n2) b1 = Bishop("b1", Color.Black) b2 = Bishop("b2", Color.Black) place_piece(self.gameBoard, "c8", b1) place_piece(self.gameBoard, "f8", b2) q = Queen("q", Color.Black) k = King("k", Color.Black) place_piece(self.gameBoard, "d8", q) place_piece(self.gameBoard, "e8", k) self.black_king = k p1 = Pawn("p1", Color.Black) p2 = Pawn("p2", Color.Black) p3 = Pawn("p3", Color.Black) p4 = Pawn("p4", Color.Black) p5 = Pawn("p5", Color.Black) p6 = Pawn("p6", Color.Black) p7 = Pawn("p7", Color.Black) p8 = Pawn("p8", Color.Black) place_piece(self.gameBoard, "a7", p1) place_piece(self.gameBoard, "b7", p2) place_piece(self.gameBoard, "c7", p3) place_piece(self.gameBoard, "d7", p4) place_piece(self.gameBoard, "e7", p5) place_piece(self.gameBoard, "f7", p6) place_piece(self.gameBoard, "g7", p7) place_piece(self.gameBoard, "h7", p8) #Add pieces to black player's current pieces Black_Player.add_piece(r1) Black_Player.add_piece(r2) Black_Player.add_piece(n1) Black_Player.add_piece(n2) Black_Player.add_piece(b1) Black_Player.add_piece(b2) Black_Player.add_piece(q) Black_Player.add_piece(k) Black_Player.add_piece(p1) Black_Player.add_piece(p2) Black_Player.add_piece(p3) Black_Player.add_piece(p4) Black_Player.add_piece(p5) Black_Player.add_piece(p6) Black_Player.add_piece(p7) Black_Player.add_piece(p8) #set up for white pieces R1 = Rook("R1", Color.White) R2 = Rook("R2", Color.White) place_piece(self.gameBoard, "a1", R1) place_piece(self.gameBoard, "h1", R2) N1 = Knight("N1", Color.White) N2 = Knight("N2", Color.White) place_piece(self.gameBoard, "b1", N1) place_piece(self.gameBoard, "g1", N2) B1 = Bishop("B1", Color.White) B2 = Bishop("B2", Color.White) place_piece(self.gameBoard, "c1", B1) place_piece(self.gameBoard, "f1", B2) Q = Queen("Q", Color.White) K = King("K", Color.White) place_piece(self.gameBoard, "d1", Q) place_piece(self.gameBoard, "e1", K) self.white_king = K P1 = Pawn("P1", Color.White) P2 = Pawn("P2", Color.White) P3 = Pawn("P3", Color.White) P4 = Pawn("P4", Color.White) P5 = Pawn("P5", Color.White) P6 = Pawn("P6", Color.White) P7 = Pawn("P7", Color.White) P8 = Pawn("P8", Color.White) place_piece(self.gameBoard, "a2", P1) place_piece(self.gameBoard, "b2", P2) place_piece(self.gameBoard, "c2", P3) place_piece(self.gameBoard, "d2", P4) place_piece(self.gameBoard, "e2", P5) place_piece(self.gameBoard, "f2", P6) place_piece(self.gameBoard, "g2", P7) place_piece(self.gameBoard, "h2", P8) #Add pieces to white player's current pieces White_Player.add_piece(R1) White_Player.add_piece(R2) White_Player.add_piece(N1) White_Player.add_piece(N2) White_Player.add_piece(B1) White_Player.add_piece(B2) White_Player.add_piece(Q) White_Player.add_piece(K) White_Player.add_piece(P1) White_Player.add_piece(P2) White_Player.add_piece(P3) White_Player.add_piece(P4) White_Player.add_piece(P5) White_Player.add_piece(P6) White_Player.add_piece(P7) White_Player.add_piece(P8) self.pieces_in_game.extend(White_Player.pieces) self.pieces_in_game.extend(Black_Player.pieces) def display_board(self): display.print_board(self.gameBoard.board) #Change player turns def change_turns(self): if self.current_player.color == Color.Black: self.current_player = self.White_Player else: self.current_player = self.Black_Player #Define game pieces left def game_pieces_left(self): new_list = [] for piece in self.pieces_in_game: new_list.append(piece.name) return new_list #Keep track of all possible locations that each player can attack (Necessary for check logic) def update_moves(self): white_legal = [] for piece in self.White_Player.pieces: legalMoves = piece.legalMoves(self.gameBoard, False) for move in legalMoves: if not(move in white_legal): white_legal.append(move) self.white_legal = white_legal #print "White Legal Moves:", translate(self.white_legal) black_legal = [] for piece in self.Black_Player.pieces: legalMoves = piece.legalMoves(self.gameBoard, False) for move in legalMoves: if not(move in black_legal): black_legal.append(move) self.black_legal = black_legal #print "Black Legal Moves:", translate(self.black_legal) #See if either players' kings are checked #This is if king's location is in opponent's legal attack moves def is_checked(self): #See if white king is in danger if self.white_king.position in self.black_legal: self.white_king.checked = True else: self.white_king.checked = False #See if black king is in danger if self.black_king.position in self.white_legal: self.black_king.checked = True else: self.black_king.checked = False def is_checkmate(self): #print "Checkmate Check:" if self.white_king.checked: #change turns to pretend to be white player self.change_turns() #Try moving each remaining white piece in all its possible locations in hopes of being able to defend attack #Includes seeing if king can be moved safely or take out the offending piece for piece in self.White_Player.pieces: legalMoves = piece.legalMoves(self.gameBoard, False) for move in legalMoves: self.speculate_move(piece, get_rankfile(move)) self.update_moves() self.is_checked() if not(self.white_king.checked): #print piece.name, get_rankfile(move) self.backstep_board() self.change_turns() self.update_moves() self.is_checked() #print "White Player:", self.White_Player.pieces_left() #print "Black Player:", self.Black_Player.pieces_left() return False self.backstep_board() self.change_turns() return True else: #change turns to pretend to be black player self.change_turns() #Try moving each remaining black piece in all its possible locations in hopes of being able to defend attack #Includes seeing if king can be moved safely or take out the offending piece for piece in self.Black_Player.pieces: legalMoves = piece.legalMoves(self.gameBoard, False) for move in legalMoves: self.speculate_move(piece, get_rankfile(move)) self.update_moves() self.is_checked() if not(self.black_king.checked): #print piece.name, get_rankfile(move) self.backstep_board() self.change_turns() self.update_moves() self.is_checked() return False self.backstep_board() self.change_turns() return True #Alters the board but resets it back to normal afterwards. Necessary for checkmate logic. def speculate_move(self, piece, position): self.piece_moved = piece #Get rid of piece at old location original_location = piece.position self.original_location = original_location old_col, old_row = original_location self.gameBoard.board[old_col][old_row] = 0 #print "original_location:", get_rankfile(original_location) #print "update board:", self.gameBoard.board[old_col][old_row] #Check to see if opponent piece is being taken over at new location if self.current_player.color == Color.Black: opponent = self.White_Player else: opponent = self.Black_Player #Place piece at new new_location = mapper_2D[position] self.new_location = new_location column, row = new_location piece_at_location = self.gameBoard.board[column][row] if piece_at_location and piece_at_location.color == opponent.color: #corner case for king castling legal moves opponent.remove_piece(piece_at_location) self.pieces_in_game.remove(piece_at_location) self.piece_removed = piece_at_location else: self.piece_removed = 0 self.gameBoard.board[column][row] = piece piece.position = new_location return piece, self.original_location, self.piece_removed, self.new_location def castle_logic(self, piece, move): print "got here" castle_fail = True rook = self.gameBoard.get_board_value(get_2D(move)) if self.current_player.color == Color.White: if move == "A1": if rook.name == "R1" and not(rook.moved): translated = translate(self.black_legal) if not("C1" in translated) and not("D1" in translated): self.speculate_move(piece, "C1") self.speculate_move(rook, "D1") castle_fail = False else: #H1 if rook.name == "R2" and not(rook.moved): translated = translate(self.black_legal) if not("F1" in translated) and not("G1" in translated): self.speculate_move(piece, "G1") self.speculate_move(rook, "F1") castle_fail = False else: #player black if move == "A8": if rook.name == "r1" and not(rook.moved): translated = translate(self.white_legal) if not("C8" in translated) and not("D8" in translated): self.speculate_move(piece, "C8") self.speculate_move(rook, "D8") castle_fail = False else: #H8 if rook.name == "r2" and not(rook.moved): translated = translate(self.white_legal) if not("F8" in translated) and not("G8" in translated): self.speculate_move(piece, "G8") self.speculate_move(rook, "F8") castle_fail = False if castle_fail: raise Castle("(Castle failed! Rook may have moved/king in check/spaces challenged.)") #Checks for draw condition #1. STALEMATE - current player has no legal moves but not in check #2. IMPOSSIBLE - remaining pieces makes it impossible to checkmate def check_draw(self): if self.current_player.color == Color.White: if not(self.white_legal) and not(self.white_king.checked): return True elif self.current_player.color == Color.Black: if not(self.black_legal) and not(self.black_king.checked): return True #Just two kings left if len(self.White_Player.pieces) == 1 and len(self.Black_Player.pieces) == 1: return True #One king vs (bishop and king) or (knight and king) if len(self.White_Player.pieces) == 1 and len(self.Black_Player.pieces) == 2: for piece in self.Black_Player.pieces: if isinstance(piece, King): pass elif isinstance(piece, Bishop): return True elif isinstance(piece, Knight): return True else: return False elif len(self.White_Player.pieces) == 2 and len(self.Black_Player.pieces) == 1: for piece in self.White_Player.pieces: if isinstance(piece, King): pass elif isinstance(piece, Bishop): return True elif isinstance(piece, Knight): return True else: False elif len(self.White_Player.pieces) == 2 and len(self.Black_Player.pieces) == 2: for piece in self.White_Player.pieces: if isinstance(piece, King): pass elif isinstance(piece, Bishop): pass else: return False for piece in self.Black_Player.pieces: if isinstance(piece, King): pass elif isinstance(piece, Bishop): return True else: return False return False #Good to use if backstep happens immediately after speculate def backstep_board(self): if self.current_player.color == Color.Black: opponent = self.White_Player else: opponent = self.Black_Player #Put piece moved back at original position old_col, old_row = self.original_location self.gameBoard.board[old_col][old_row] = self.piece_moved self.piece_moved.position = self.original_location col, row = self.new_location if self.piece_removed: opponent.add_piece(self.piece_removed) self.pieces_in_game.append(self.piece_removed) self.gameBoard.board[col][row] = self.piece_removed #Needed for AI minimax search. In this case, backstep might not be called after speculate def reverse_step(self, piece_moved, old_location, piece_removed, new_location): if self.current_player.color == Color.Black: opponent = self.White_Player else: opponent = self.Black_Player #Put piece moved back at original position old_col, old_row = old_location self.gameBoard.board[old_col][old_row] = piece_moved piece_moved.position = old_location col, row = new_location if piece_removed: print "Reverse Step:", opponent.name, piece_removed.name opponent.add_piece(piece_removed) self.pieces_in_game.append(piece_removed) self.gameBoard.board[col][row] = piece_removed #Updates the board given a move. Also shares information so that a reset can happen (necessary for check logic) def update_board(self, piece, position): if self.game_state == State.Running: print "Current Player", self.current_player.name, self.current_player.color #Invalid piece if not(isinstance(piece, Pieces)): raise InvalidPiece("Not a valid piece.") #Wrong piece if piece.color != self.current_player.color: print piece.name, piece.color, position raise NotYourTurn("Wrong piece. It is " + self.current_player.name + "'s Turn.") #Invalid move for piece check_valid = get_2D(position) if check_valid not in piece.legalMoves(self.gameBoard, False): string = "(Error: Not a valid move for -- " + piece.name + ")" raise InvalidMove(string) #check castle logic if isinstance(piece, King) and (position == "A1" or position == "A8" or position == "H1" or position == "H8"): if not(piece.moved): self.castle_logic(piece, position) else: self.speculate_move(piece, position) self.update_moves() self.is_checked() if ((self.current_player.color == Color.White and self.white_king.checked) or (self.current_player.color == Color.Black and self.black_king.checked)): self.backstep_board() self.update_moves() self.is_checked() #self.display_board() print self.current_player.name raise Check("(Error: Cannot move there. Your king will/still be checked.)") #Check if player won elif self.white_king.checked or self.black_king.checked: if self.is_checkmate(): self.game_state = State.Over raise GameOver("CHECKMATE! " + self.current_player.name + " WINS!") #self.display_board() #sys.exit(1) #Check draw condition if self.check_draw(): self.game_state = State.Draw raise GameOver("DRAW! Game is over.") #Commit to speculated move if no error messages raised piece.moved = True #self.display_board() print "Moved:", piece.name, position self.change_turns() else: raise GameOver("Game is over.") def evalBoard(self, color): score = 0 if color == Color.White: #More move options = better score += len(self.white_legal) #Different weights for whatever piece was removed if self.piece_removed: if isinstance(self.piece_removed, Queen): score += 10 elif isinstance(self.piece_removed, Rook): score += 5 elif isinstance(self.piece_removed, Knight) or isinstance(self.piece_removed, Bishop): score += 3 else: #Pawn score += 1 #Points given for more opportunities to take out enemy pieces for piece in self.White_Player.pieces: legalMoves = piece.legalMoves(self.gameBoard, False) #print piece.name, piece.protecting score += piece.protecting*2 for move in legalMoves: for position in self.Black_Player.pieces_locations(): if move == position: score += 3 else: #More move options = better score += len(self.black_legal) #Different weights for whatever piece was removed if self.piece_removed: if isinstance(self.piece_removed, Queen): score += 10 elif isinstance(self.piece_removed, Rook): score += 5 elif isinstance(self.piece_removed, Knight) or isinstance(self.piece_removed, Bishop): score += 3 else: #Pawn score += 1 #Points given for more opportunities to take out enemy pieces for piece in self.Black_Player.pieces: legalMoves = piece.legalMoves(self.gameBoard, False) #print legalMoves #print piece.name, piece.protecting score += piece.protecting*2 for move in legalMoves: for position in self.White_Player.pieces_locations(): if move == position: score += 3 return score #Points awarded for protecting own pieces def setup(self): self.initialize_game() self.update_moves() self.current_player = self.White_Player self.game_state = State.Running #if test is true, then don't initialize game def run(self, test = False): print("Specify what piece you want to use and where. Example: <a2 a3>.") #Have configuration to specify human vs AI #Should player have options? like help and display board? if not(test): self.setup() self.display_board() while(1): if self.current_player.color == Color.White: print("--White Player's Turn--") if self.white_king.checked: print "-------Checked!--------" else: print("--Black Player's Turn--") if self.black_king.checked: print "-------Checked!--------" piece, position = self.current_player.move(self) try: self.update_board(piece, position) self.display_board() except ChessError as error: if isinstance(error, GameOver): print error.msg self.game_state = State.Over self.display_board() sys.exit(1) print error.msg else: pass #B = Board() #G = Game(B) #G.run()