예제 #1
0
	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
예제 #2
0
	def init_black(self, playerType):
		if playerType == PlayerType.Human:
			self.Black_Player = Human(Color.Black)
		else:
			self.Black_Player = AI(Color.Black)
예제 #3
0
	def init_white(self, playerType):
		if playerType == PlayerType.Human:
			self.White_Player = Human(Color.White)
		else:
			self.White_Player = AI(Color.White)
예제 #4
0
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()