Beispiel #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_Player
		self.opponent = self.Black_Player

		#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

		#for eval board
		self.aggressive = 11
		self.minimax = False

		#For Arduino logic
		self.piece_taken = False
		self.garbage_location = (0,8) #For White
		self.attacker_position = (100, 100)
Beispiel #2
0
	def init_white(self, playerType):
		if playerType == PlayerType.Human:
			self.White_Player = Human(Color.White)
		elif playerType == PlayerType.AI:
			self.White_Player = AI(Color.White)
		elif playerType == PlayerType.Arduino:
			self.White_Player = ArduinoPlayer(Color.White)
		elif playerType == PlayerType.Voice:
			self.White_Player = Voice(Color.White)
Beispiel #3
0
	def init_black(self, playerType):
		if playerType == PlayerType.Human:
			self.Black_Player = Human(Color.Black)
		elif playerType == PlayerType.AI:
			self.Black_Player = AI(Color.Black)
		elif playerType == PlayerType.Arduino:
			self.Black_Player = ArduinoPlayer(Color.Black)
		elif playerType == PlayerType.Voice:
			self.Black_Player = Voice(Color.Black)
Beispiel #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_Player
		self.opponent = self.Black_Player

		#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

		#for eval board
		self.aggressive = 11
		self.minimax = False

		#For Arduino logic
		self.piece_taken = False
		self.garbage_location = (0,8) #For White
		self.attacker_position = (100, 100)

	#Similar set up in initialize 
	def reset(self):
		self.gameBoard.reset()

		self.White_Player.reset()
		self.Black_Player.reset()
		self.current_player = self.White_Player
		self.opponent = self.Black_Player	

		#Logic for updating/resetting the board
		self.piece_moved = ""
		self.original_location = ""
		self.new_location = ""
		self.piece_removed = ""

		self.pieces_in_game = []

		#for eval board
		self.aggressive = 11
		self.minimax = False

		#For Arduino logic
		self.piece_taken = False
		self.garbage_location = (0,8) #For White
		self.attacker_position = (100, 100)

	#Initialize white player
	def init_white(self, playerType):
		if playerType == PlayerType.Human:
			self.White_Player = Human(Color.White)
		elif playerType == PlayerType.AI:
			self.White_Player = AI(Color.White)
		elif playerType == PlayerType.Arduino:
			self.White_Player = ArduinoPlayer(Color.White)
		elif playerType == PlayerType.Voice:
			self.White_Player = Voice(Color.White)

	#Initialize black player
	def init_black(self, playerType):
		if playerType == PlayerType.Human:
			self.Black_Player = Human(Color.Black)
		elif playerType == PlayerType.AI:
			self.Black_Player = AI(Color.Black)
		elif playerType == PlayerType.Arduino:
			self.Black_Player = ArduinoPlayer(Color.Black)
		elif playerType == PlayerType.Voice:
			self.Black_Player = Voice(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)
		Black_Player.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)
		White_Player.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
			self.opponent = self.Black_Player
		else:
			self.current_player = self.Black_Player
			self.opponent = self.White_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

	#Alters the board but step may easily be reversed. Necessary for checkmate logic.
	def speculate_move(self, color, piece, position):

		#print "White Pieces:", names(self.White_Player.pieces)
		#print "Black Pieces:", names(self.Black_Player.pieces)

		self.piece_moved = piece

		#Get rid of piece at old location
		original_location = piece.position
		self.gameBoard.set_value(original_location, 0)

		#Place piece at new
		new_location = mapper_2D[position]
		piece_removed = self.gameBoard.get_board_value(new_location)

		#print piece_removed, self.opponent.name
		#Check to see if self.opponent piece is being taken over at new location
		if piece_removed and piece_removed.color == self.opponent.color: #corner case for king castling legal moves
			#print self.opponent, names(self.opponent.pieces)
			self.opponent.remove_piece(piece_removed)
			self.pieces_in_game.remove(piece_removed)

		self.gameBoard.set_value(new_location, piece)
		piece.position = new_location
		
		#New move means new legal positions for both parties
		self.legal_positions()
		self.check_kings()
		return piece, original_location, piece_removed, new_location, color, 0
	
	#Needed to reverse the step done by speculate move 
	#Ex: (shouldn't have done a move if it leads my king being checked)
	def reverse_step(self, piece_moved, old_location, piece_removed, new_location, color, castle):

		#Reverse the castle moving
		if castle:
			if castle == 1:
				c1 = mapper_2D["C1"]
				d1 = mapper_2D["D1"]
				self.gameBoard.set_value(c1, 0)
				self.gameBoard.set_value(d1, 0)

			elif castle == 2:
				g1 = mapper_2D["G1"]
				f1 = mapper_2D["F1"]
				self.gameBoard.set_value(g1, 0)
				self.gameBoard.set_value(f1, 0)

			elif castle == 3:
				c8 = mapper_2D["C8"]
				d8 = mapper_2D["D8"]
				self.gameBoard.set_value(c8, 0)
				self.gameBoard.set_value(d8, 0)
			else:
				g8 = mapper_2D["G8"]
				f8 = mapper_2D["F8"]
				self.gameBoard.set_value(g8, 0)
				self.gameBoard.set_value(f8, 0)

		#Put piece moved back at original position
		self.gameBoard.set_value(old_location, piece_moved)
		piece_moved.position = old_location

		if piece_removed and piece_removed.color == self.opponent.color:
			#print "Reverse Step:", self.opponent.name, piece_removed.name
			self.opponent.add_piece(piece_removed)
			self.pieces_in_game.append(piece_removed)
		if piece_removed:
			piece_removed.position = new_location
		#print get_rankfile(new_location), new_location
		self.gameBoard.set_value(new_location, piece_removed)
		self.legal_positions()
		self.check_kings()
		#piece_moved.moved = False

		
	#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

			self.piece_taken = False

			#if get_2D(position) in legalMoves of Piece

			#Is move legal?
			p, old_loc, p_removed, new_loc, c, castle = self.check_legal(piece, position)
			

			#Create all the legal moves of opponent 			
			self.opponent_next_legal_moves()
			
			#Check if player won
			if not(self.minimax) and 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 not(self.minimax) and self.check_draw():
				self.change_turns()
				self.game_state = State.Draw
				raise GameOver("DRAW! Game is over.")

			#Commit to speculated move if no error messages raised
			piece.moved = True
			#print "Moved:", piece.name, position
			#print "White Player Pieces: ", self.White_Player.pieces_left()
			#print "Black Player Pieces: ", self.Black_Player.pieces_left()
			self.change_turns()
			if p_removed:
				self.piece_taken = True
				self.attacker_position = old_loc
				if (p_removed.color == Color.White):
					self.garbage_location = (0, 8)
				else:
					self.garbage_location = (16, 8)
			return p, old_loc, p_removed, new_loc, c, castle

		else:
			raise GameOver("Game is over.")

	def check_legal(self, piece, position):
			#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, True):
				string = "(Error: Not a valid move for -- " + piece.name + " " + position + ")"
				raise InvalidMove(string)

			#Need legal positions for castling
			self.legal_positions()

			#check castle logic
			if isinstance(piece, King) and (position == "A1" or position == "A8" or position == "H1" or position == "H8") and not(piece.moved):
				p, old_loc, p_removed, new_loc, c, castle = self.castle_logic(piece, position)
			else:
				p, old_loc, p_removed, new_loc, c, castle = self.speculate_move(self.current_player.color, piece, position)


			if self.is_my_king_checked():		
				self.reverse_step(p, old_loc, p_removed, new_loc, c, castle)
				raise Check("(Error: Cannot move there. Your king will/still be checked.)")

			#if no errors raised => move is legal! 
			return p, old_loc, p_removed, new_loc, c, castle

	#Check logic for castling
	def castle_logic(self, piece, move):

		#print "Castle Logic:", piece.name, move
		#self.display_board()
		castle = 0
		castle_fail = True
		old_loc = piece.position
		rook = self.gameBoard.get_board_value(get_2D(move))
		if rook and self.current_player.color == Color.White:
			if move == "A1":
				if rook.name == "R1" and not(rook.moved):
					translated = translate(self.opponent.legal_positions)
					if not("C1" in translated) and not("D1" in translated):
						self.speculate_move(Color.White, piece, "C1")
						self.speculate_move(Color.White, rook, "D1")
						castle = 1
						castle_fail = False
			else: #H1
				if rook.name == "R2" and not(rook.moved):
					translated = translate(self.opponent.legal_positions)
					if not("F1" in translated) and not("G1" in translated):
						self.speculate_move(Color.White, piece, "G1")
						self.speculate_move(Color.White, rook, "F1")
						castle = 2
						castle_fail = False		

		elif rook and self.current_player.color == Color.Black: #player black
			if move == "A8":
				if rook.name == "r1" and not(rook.moved):
					translated = translate(self.opponent.legal_positions)
					if not("C8" in translated) and not("D8" in translated):
						self.speculate_move(Color.Black, piece, "C8")
						self.speculate_move(Color.Black, rook, "D8")
						castle = 3
						castle_fail = False
			else: #H8
				if rook.name == "r2" and not(rook.moved):
					translated = translate(self.opponent.legal_positions)
					if not("F8" in translated) and not("G8" in translated):
						self.speculate_move(Color.Black, piece, "G8")
						self.speculate_move(Color.Black, rook, "F8")
						castle = 4
						castle_fail = False			
		if castle_fail:
			raise Castle("(Castle failed! Rook may have moved/king in check/spaces challenged.)")
		else: #Castling successful. Return old and new locations in case castle needs to be reversed
			return piece, old_loc, rook, get_2D(move), self.current_player.color, castle

	#Update legal positions for both yourself and opponent
	def legal_positions(self):

		next_legal = []
		for piece in self.current_player.pieces:
			legalMoves = piece.legalMoves(self, True)
			for move in legalMoves:
				next_legal.append(move)
		self.current_player.legal_positions = next_legal	

		next_legal = []
		for piece in self.opponent.pieces:
			legalMoves = piece.legalMoves(self, True)
			for move in legalMoves:
				next_legal.append(move)
		self.opponent.legal_positions = next_legal	


	#Update to see if the opponent's king is checked
	def check_kings(self):
		#print "CHECK KING:", translate(self.current_player.legal_positions)
		if self.opponent.king.position in self.current_player.legal_positions:
			self.opponent.king.checked = True
		else:
			self.opponent.king.checked = False
		
		if self.current_player.king.position in self.opponent.legal_positions:
			self.current_player.king.checked = True
		else:
			self.current_player.king.checked = False

	#See if current player's king is checked
	#This is if king's location is in self.opponent's legal attack moves
	def is_my_king_checked(self):
		return self.current_player.king.checked

	#Create a list of your own legal moves
	def next_legal_moves(self):
 		next_legal = []
		for piece in self.current_player.pieces:
			legalMoves = piece.legalMoves(self, False)
			for move in legalMoves:
				next_legal.append((piece,move))	
		self.current_player.legal_moves = next_legal
		#print "Next Legal:", next_legal

	#Returns a list of the next legal moves of opponent.
	#Necessary for checkmate and draw logic
	def opponent_next_legal_moves(self):

		#Pretend to be opponent
		self.change_turns()
		next_legal = []
		for piece in self.current_player.pieces:
			legalMoves = piece.legalMoves(self, False)
			for move in legalMoves:
				next_legal.append((piece,move))

		self.current_player.legal_moves = next_legal
		self.change_turns()
	
	def is_checkmate(self):
		#print self.opponent.legal_moves, self.opponent.name
		if self.opponent.king.checked and not(self.opponent.legal_moves):
			self.opponent.king.checkmated = True
			#print "GOT HERE"
			return True
		else:
			self.opponent.king.checkmated = False
			return False

	#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 not(self.opponent.king.checked) and not(self.opponent.legal_moves):
			#print "DRAW GOT HERE"
			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

	def evalBoard(self, color):
		score = 0
		turn = self.current_player.color

		if color == Color.White:
			#More move options in the beginning = better (open aggressively)
			score += self.aggressive*(len(self.White_Player.legal_moves) - self.prev_white_legal_len)
			#print self.aggressive*(len(self.black_legal) - self.prev_black_legal_len)
			# #Restrict other player's movement, also good
			score += self.aggressive*(self.prev_black_legal_len - len(self.Black_Player.legal_moves) ) 
			#print self.aggressive*(self.prev_black_legal_len - len(self.black_legal))

			#Don't want yourself to be checked but you do want to check the other king
			if self.Black_Player.king.checked:
				score += 20
				#print "WHITE!"
				# if self.is_checkmate():
				# 	score += 1000

			if self.White_Player.king.checked:
				score -= 20
				#print "BLACK!"
				# if self.is_checkmate():
				# 	score -= 1000

			#Iterate through white pieces. Determine:
			#1. How many remaining pieces you have. +points
			#2. How much you threatened black piece. Each threatened + points
			#3. How protected each black piece is. Each protection + points
			for piece in self.White_Player.pieces:

				if isinstance(piece, Queen):
					score += 35

				elif isinstance(piece, Rook):
					score += 20

				elif isinstance(piece, Knight) or isinstance(piece, Bishop):
					score += 15
				else: #Pawn and #King
					score += 10

				legalMoves = piece.legalMoves(self, False)

				#Points for threatening
				for move in legalMoves:
					for position in self.Black_Player.pieces_locations():
						if move == position:
							threatened_piece = self.gameBoard.get_board_value(move)
							threatened_piece.threatened_by.append(piece)
							threatened_piece.threatened += threatened_piece.weight*piece.threat
							#print threatened_piece.name


				#Count how many other pieces are protecting this one
				for protecting in piece.protecting:
					protecting.protected += protecting.weight

			#Iterate through black pieces. Determine:
			#1. How many remaining pieces self.opponent has. -points
			#2. How much white threatens your pieces. Each threatened - points
			#3. How protected each white piece is. Each protection - points
			white_piece_locations = self.White_Player.pieces_locations()
			for piece in self.Black_Player.pieces:
				#Want to reduce amount of black pieces
				#Weight necessary in order to make AI realize pawn = HIGH THREAT 
				if isinstance(piece, Queen):
					score -= 30
				elif isinstance(piece, Rook):
					score -= 20
				elif isinstance(piece, Knight) or isinstance(piece, Bishop):
					score -= 15
				else: #Pawn
					score -= 10

				legalMoves = piece.legalMoves(self, False)
				for move in legalMoves:
					for position in  white_piece_locations:
						if move == position:
							#print "Piece:", piece.name, get_rankfile(move)
							#print "Black piece locations:",  translate(black_piece_locations)
							#self.display_board()

							#Want to offset this cost if threatend_piece is protected
							threatened_piece = self.gameBoard.get_board_value(move)
							threatened_piece.threatened_by.append(piece)
							threatened_piece.threatened += threatened_piece.weight * piece.threat
							#print threatened_piece.name

			
			for protecting in piece.protecting:
				protecting.protected += protecting.weight

			#If own piece threatened, +protection - threaten
			#If other piece threatened, -protection + threaten
			for piece in self.White_Player.pieces:
				#Piece is threatened
				if piece.threatened != 0:
					pawn_threat = False
					for attacker in piece.threatened_by:
						if isinstance(attacker, Pawn):
							pawn_threat = True
						#Nullifies his attack if your turn is next and he's unprotected and himself threatened
						elif piece.protected != 0 and attacker.protected == 0 and attacker.threatened != 0:
							piece.threatened -= piece.weight*attacker.threat
							piece.threatened_by.remove(attacker)
							#print "Got here", piece.threatened
							#self.display_board()

					#print "Next Move would have been:", self.current_player.name
					# print "Threatened Black:", piece.name, piece.protected - piece.threatened
					# print "Threatened by:", names(piece.threatened_by)
					# self.display_board()

					#If threatened by a pawn, doesn't matter if you're protected. Gtfo!
					if pawn_threat and not (isinstance(piece, Pawn)):
						# print "Threatened Black by Pawn:", piece.name, piece.protected - piece.threatened
						# print "Threatened by:", names(piece.threatened_by)
						# self.display_board()				
						score = score - piece.threatened
					else:
						if (piece.protected > piece.threatened):
							score += piece.weight / 2
						else:
							score -= piece.weight / 2

					piece.threatened = 0
					piece.protected = 0
					piece.threatened_by = []
	
			for piece in self.Black_Player.pieces:
				#Piece is threatened
				if piece.threatened != 0:
					nullify_threat = False
					for attacker in piece.threatened_by:
						#Nullifies your attack if your turn is not next and you're undefended and threatened
						if piece.protected != 0 and attacker.protected == 0 and attacker.threatened != 0:
							score -= attacker.weight / 2
							piece.threatened -= piece.weight*attacker.threat
							piece.threatened_by.remove(attacker)
							#print "Got here", piece.threatened

					#Value for threatening said piece is half its weight (therefore taking that piece = GOOD)
					if piece.threatened != 0 and piece.protected == 0:
						score += piece.weight / 2

					#self.display_board()

					piece.threatened = 0
					piece.protected = 0
					piece.threatened_by = []

		else:
			#More move options in the beginning = better (open aggressively)
			score += self.aggressive*(len(self.Black_Player.legal_moves) - self.prev_black_legal_len)
			#print self.aggressive*(len(self.black_legal) - self.prev_black_legal_len)
			# #Restrict other player's movement, also good
			score += self.aggressive*(self.prev_white_legal_len - len(self.White_Player.legal_moves) ) 
			#print self.aggressive*(self.prev_white_legal_len - len(self.white_legal))

			#Don't want yourself to be checked but you do want to check the other king
			if self.White_Player.king.checked:
				score += 20
				#print "WHITE!"
				# if self.is_checkmate():
				# 	score += 1000

			if self.Black_Player.king.checked:
				score -= 20
				#print "BLACK!"
				# if self.is_checkmate():
				# 	score -= 1000

			#Iterate through black pieces. Determine:
			#1. How many remaining pieces you have. +points
			#2. How much you threatened white piece. Each threatened + points
			#3. How protected each black piece is. Each protection + points
			for piece in self.Black_Player.pieces:

				if isinstance(piece, Queen):
					score += 35

				elif isinstance(piece, Rook):
					score += 20

				elif isinstance(piece, Knight) or isinstance(piece, Bishop):
					score += 15
				else: #Pawn and #King
					score += 10

				legalMoves = piece.legalMoves(self, False)

				#Points for threatening
				for move in legalMoves:
					for position in self.White_Player.pieces_locations():
						if move == position:
							threatened_piece = self.gameBoard.get_board_value(move)
							threatened_piece.threatened_by.append(piece)
							threatened_piece.threatened += threatened_piece.weight*piece.threat
							#print threatened_piece.name


				#Count how many other pieces are protecting this one
				for protecting in piece.protecting:
					protecting.protected += protecting.weight

			#Iterate through white pieces. Determine:
			#1. How many remaining pieces self.opponent has. -points
			#2. How much white threatens your pieces. Each threatened - points
			#3. How protected each white piece is. Each protection - points
			black_piece_locations = self.Black_Player.pieces_locations()
			for piece in self.White_Player.pieces:
				#Want to reduce amount of white pieces
				#Weight necessary in order to make AI realize pawn = HIGH THREAT 
				if isinstance(piece, Queen):
					score -= 30
				elif isinstance(piece, Rook):
					score -= 20
				elif isinstance(piece, Knight) or isinstance(piece, Bishop):
					score -= 15
				else: #Pawn
					score -= 10

				legalMoves = piece.legalMoves(self, False)
				for move in legalMoves:
					for position in black_piece_locations:
						if move == position:
							#print "Piece:", piece.name, get_rankfile(move)
							#print "Black piece locations:",  translate(black_piece_locations)
							#self.display_board()

							#Want to offset this cost if threatend_piece is protected
							threatened_piece = self.gameBoard.get_board_value(move)
							threatened_piece.threatened_by.append(piece)
							threatened_piece.threatened += threatened_piece.weight * piece.threat
							#print threatened_piece.name

				
				for protecting in piece.protecting:
					protecting.protected += protecting.weight

			#If own piece threatened, +protection - threaten
			#If other piece threatened, -protection + threaten
			for piece in self.Black_Player.pieces:
				#Piece is threatened
				if piece.threatened != 0:
					pawn_threat = False
					for attacker in piece.threatened_by:
						if isinstance(attacker, Pawn):
							pawn_threat = True
						#Nullifies his attack if your turn is next and he's unprotected and himself threatened
						elif piece.protected != 0 and attacker.protected == 0 and attacker.threatened != 0:
							piece.threatened -= piece.weight*attacker.threat
							piece.threatened_by.remove(attacker)
							#print "Got here", piece.threatened
							#self.display_board()

					#print "Next Move would have been:", self.current_player.name
					# print "Threatened Black:", piece.name, piece.protected - piece.threatened
					# print "Threatened by:", names(piece.threatened_by)
					# self.display_board()

					#If threatened by a pawn, doesn't matter if you're protected. Gtfo!
					if pawn_threat and not (isinstance(piece, Pawn)):
						# print "Threatened Black by Pawn:", piece.name, piece.protected - piece.threatened
						# print "Threatened by:", names(piece.threatened_by)
						# self.display_board()				
						score = score - piece.threatened
					else:
						if (piece.protected > piece.threatened):
							score += piece.weight / 2
						else:
							score -= piece.weight / 2

				piece.threatened = 0
				piece.protected = 0
				piece.threatened_by = []
	
			for piece in self.White_Player.pieces:
				#Piece is threatened
				if piece.threatened != 0:
					for attacker in piece.threatened_by:
						#Nullifies your attack if your turn is not next and you're undefended and threatened
						if piece.protected != 0 and attacker.protected == 0 and attacker.threatened != 0:
							score -= attacker.weight / 2
							piece.threatened -= piece.weight*attacker.threat
							piece.threatened_by.remove(attacker)
							#print "Got here", piece.threatened

					#Value for threatening said piece is half its weight (therefore taking that piece = GOOD)
					if piece.threatened != 0 and piece.protected == 0:
						score += piece.weight / 2

					#self.display_board()

					piece.threatened = 0
					piece.protected = 0
					piece.threatened_by = []

		#if self.Black_Player.pieces[1].position == get_2D("H3"):
		# print "SCORE OF BOARD", score
		# self.display_board()
		return score


	def setup(self):
		self.initialize_game()
		self.current_player = self.White_Player
		self.opponent = self.Black_Player
		self.next_legal_moves()
		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.current_player.king.checked:
					print "-------Checked!--------"
				
			else:
				print("--Black Player's Turn--")
				if self.current_player.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

	def is_valid_move(self, piece, location, attackingDirection):
		valid_thus_far = False
		if is_valid(location):
			piece_at_location = self.gameBoard.get_board_value(location)
			if piece_at_location == 0:
				valid_thus_far = True	
			elif piece_at_location != piece.color and attackingDirection:
				valid_thus_far = True
			else:
				if attackingDirection:
					piece.protecting.append(piece_at_location)
					# if isinstance(piece, Queen):
					# 	attacking_piece.protecting += 6
					# elif isinstance(piece, Rook):
					# 	attacking_piece.protecting += 3
					# elif isinstance(piece, Knight) or isinstance(piece, Bishop):
					# 	attacking_piece.protecting += 2	
					# else: #Pawn
					# 	attacking_piece.protecting += 1

		if (valid_thus_far):
			try:
				p, old_loc, p_removed, new_loc, c, castle = self.check_legal(piece, get_rankfile(location))
				self.reverse_step(p, old_loc, p_removed, new_loc, c, castle)
				return True
			except ChessError as error:
				#if isinstance(error, Check):
				#	self.reverse_step(p, old_loc, p_removed, new_loc, c, castle)
				return False

		return False

#B = Board()
#G = Game(B)
#G.run()