def value(board, color): '''Evaluate the board situation based on the number of black and white on the board''' black, white = gamePlay.score(board) if color == "W": # If agent plays white, do white minus black return white - black elif color == "B": # If agent plays black, do black minus white return black - white
def maxVal(node,color,depth,a,b): #if game is over or reached search depth, calculate score. #here, I simply use the score function provided in gameplay. if gameOver(node.state) or depth==0: black,white=score(node.state) if (color == "B"): node.value=black; return black elif (color == "W"): node.value=white; return white #set v value to a very small number v=-999; #populate children node.populateChildren(color); #if no children, just get value at current step if len(node.children)==0: return maxVal(node,color,0,a,b); #for each child in next depth, calculate opponent score for child in node.children: returnValue=minVal(child,opponent(color),depth-1,a,b); v=max(v,returnValue); node.value=v; if v>=b: return v; a=max(a,v); return v;
def minVal(node,color,depth,a,b): #if game is over or reached search depth, calculate score. if gameOver(node.state) or depth==0: black,white=score(node.state) if (color == "B"): node.value=black; return black elif (color == "W"): node.value=white; return white #set v value to a very large number v=999; #populate children node.populateChildren(color); #if no children, just get value at current step if len(node.children)==0: return minVal(node,color,0,a,b); #for each child in next depth, calculate opponent score for child in node.children: returnValue=maxVal(child,opponent(color),depth-1,a,b) v=min(v,returnValue); node.value=v; if v<=a: return v; b=min(b,v); return v
def heuristic(node,color): black,white=score(node.state) if (color == "B"): node.value=black; return black elif (color == "W"): node.value=white; return white
def alpha_beta(board, color, depth, alpha, beta): """Find the utility value of the game and the best_val move in the game.""" if depth == 0: return eval_fn(board, color) if gamePlay.gameOver(board): return gamePlay.score(board) moves = [] for row in range(8): for col in range(8): if gamePlay.valid(board, color, (row, col)): moves.append((row, col)) #shuffle the moves in case it places the same position in every game #shuffle(moves) if len(moves) == 0: return "pass" if moves == "pass": return eval_fn(board, color) opp = gamePlay.opponent(color) # try each move #evaluate max's position and choose the best value if color == "B": for move in moves: newBoard = board[:] gamePlay.doMove(newBoard, color, move) #cut off the branches alpha = max(alpha, alpha_beta(newBoard, opp, depth-1, alpha, beta)) if beta <= alpha: return return alpha #evaluate min's position and choose the best value if color == "W": for move in moves: newBoard = board[:] gamePlay.doMove(newBoard, color, move) #cut off the branches beta = min(beta, alpha_beta(newBoard, opp, depth-1, alpha, beta)) if beta <= alpha: return return beta
def minimax(board, color, depth): #Find the best move in the game #if depth = 0, we calculate the score if depth == 0: return eval_fn(board, color) #if game is over, we calculate the score if gamePlay.gameOver(board): return gamePlay.score(board) best_val = None best_move = None opp = gamePlay.opponent(color) # valid moves moves = [] for row in range(8): for col in range(8): if gamePlay.valid(board, color, (row,col)): moves.append((row,col)) #shuffle the moves in case it places the same position in every game #shuffle(moves) if len(moves) == 0: return "pass" if move == "pass": return eval_fn(board, color) #try each move in valid moves #evaluate max's position and choose the best value if color == "B": for move in moves: newBoard = board[:] gamePlay.doMove(newboard, color, move) val = minimax(newBoard, opp, depth-1) if best_val is None or val > (best_val, best_move)[0]: (best_val, best_move) = (val, move) #evaluate min's position and choose the best value if color == "W": for move in moves: newBoard = board[:] gamePlay.doMove(newboard, color, move) val = minimax(newBoard, opp, depth-1) if best_val is None or val < (best_val, best_move)[0]: (best_val, best_move) = (val, move) return (best_val, best_move)[0]
def alphaBeta(node, depth, currentPlayerTurn, color, alpha, beta): if depth==0 or gameOver(node.state): black,white=score(node.state); if(color=="W"): node.value=white; #print node.value return white; elif (color=="B"): node.value=black; #print node.value return black; if currentPlayerTurn: #expand children: node.populateChildren(); for child in node.children: returnedval=alphaBeta(child,depth-1,False,color,alpha,beta) #print "alpha ret:",returnedval #alpha=max(alpha,alphaBeta(child,depth-1,False,color,alpha,beta)); alpha=max(alpha,returnedval); if beta <= alpha: break; node.value=alpha; #print "alpha, b:",beta, "a:",alpha return alpha; else: #expand children: node.populateChildren(); for child in node.children: returnedval=alphaBeta(child,depth-1,False,color,alpha,beta) #print alphaBeta(child,depth-1,False,color,alpha,beta) #beta=min(beta,alphaBeta(child,depth-1,False,color,alpha,beta)); beta=min(beta,returnedval); #print "beta ret:",returnedval, beta if beta <= alpha: break; node.value=beta; #print "beta, b:",beta, "a:",alpha, "len:",len(node.children) return beta;
def eval_fn(board, color): # if the game is over, give a 100 point bonus to the winning player if gamePlay.gameOver(board): point = gamePlay.score(board) if point > 0: return 100 elif point < 0: return -100 else: return 0 point = 0 #find the color of the opponent opp = gamePlay.opponent(color) for row in range(8): for col in range(8): #calculate the point of current player if board[row][col] == color: point += gradingStrategy[(row+1)*10+1+col] #calculate the point of the opponent elif board[row][col] == opp: point -= gradingStrategy[(row+1)*10+1+col] return point
def evaluation(board, color): '''Use the number of black minus white as evaluation for current situation''' black, white = gamePlay.score(board) return black - white