def policy_moves_cmd(self, args): # if the game is already end if (self.board.check_game_end_gomoku()[0]): self.respond() return # check if still have the empty points if len(GoBoardUtil.generate_legal_moves_gomoku(self.board)) == 0: self.respond() return # use copy board cboard = self.board.copy() # check policy if self.policy_type == "random": moves = GoBoardUtil.generate_legal_moves_gomoku(self.board) moves_string = [] for move in moves: move_coord = point_to_coord(move, self.board.size) move_as_string = format_point(move_coord) moves_string.append(move_as_string) sorted_moves = ' '.join(sorted(moves_string)) self.respond("Random {}".format(sorted_moves)) else: policy, moves = PatternUtil.generate_policy_moves(cboard) moves_string = [] for move in moves: move_coord = point_to_coord(move, self.board.size) move_as_string = format_point(move_coord) moves_string.append(move_as_string) sorted_moves = ' '.join(sorted(moves_string)) self.respond(policy + " " + sorted_moves)
def solve(board): result = game_end(board) if (result != None): return result, "First" alpha, beta = -1, 1 haveDraw = False solvePoint = board.list_solve_point() if solvePoint: #print(solvePoint[0]) board.play_move_gomoku(solvePoint[0], board.current_player) result = -alphabeta(board, -beta, -alpha) undo(board, solvePoint[0]) if (result == 1): return True, solvePoint[0] elif (result == 0): haveDraw = True else: for m in GoBoardUtil.generate_legal_moves_gomoku(board): board.play_move_gomoku(m, board.current_player) result = -alphabeta(board, -beta, -alpha) #print(GoBoardUtil.get_twoD_board(board)) #print(result) undo(board, m) if (result == 1): return True, m elif (result == 0): haveDraw = True return haveDraw, "NoMove" """
def simulate(self, board, color, legal_moves, mode): winList = [] if not legal_moves: legal_moves = GoBoardUtil.generate_legal_moves_gomoku(board) check = board.check_game_end_gomoku() if check[0] == True: return elif legal_moves == []: return if mode == 'random': mode_sim = 'random' else: mode_sim = 'rule' for move in legal_moves: s = 0 for i in range(self.N): temp_b = board.copy() temp_b.play_move_gomoku(move, color) s = s + self.simulate_iter(temp_b, color, mode_sim) s = s / 10 winList.append(s) index = winList.index(max(winList)) if winList: index = winList.index(max(winList)) best = legal_moves[index] return best
def get_move(self, board, color_to_play): """ The genmove function called by gtp_connection """ moves = GoBoardUtil.generate_legal_moves_gomoku(board) toplay = board.current_player best_result, best_move = -1.1, None best_move = moves[0] wins = np.zeros(len(moves)) visits = np.zeros(len(moves)) while True: for i, move in enumerate(moves): play_move(board, move, toplay) res = game_result(board) if res == toplay: undo(board, move) #This move is a immediate win self.best_move = move return move ret = self._do_playout(board, toplay) wins[i] += ret visits[i] += 1 win_rate = wins[i] / visits[i] if win_rate > best_result: best_result = win_rate best_move = move self.best_move = best_move undo(board, move) assert (best_move is not None) return best_move
def BlockWin(self): legal_moves = GoBoardUtil.generate_legal_moves_gomoku(self.board) opp = GoBoardUtil.opponent(self.board.current_player) result = self.Win(opp) if result: return result return False
def alphabetaDL(self, alpha, beta, depth): moves = self.board.get_empty_points() board_full = (len(moves) == 0) #board full check win_step = [] if self.board.check_game_end_gomoku( )[0] or depth == 0 or board_full: #checking end game, no depth, draw return self.staticallyEvaluateForToPlay() for move in GoBoardUtil.generate_legal_moves_gomoku( self.board): #moves inlegal move self.board.play_move_gomoku( move, self.board.current_player) #play a stone value = -self.alphabetaDL(-beta, -alpha, depth - 1)[0] #alphabeta search if value > alpha: alpha = value win_step.clear() win_step.append(move) ''' if value == alpha: win_step.append(move)''' self.board.undo(move) if value >= beta: return beta, win_step # or value in failsoft (later) return alpha, win_step
def my_policy_moves(self,board,color): points = GoBoardUtil.generate_legal_moves_gomoku(board) moves = self.legalMoves(board) self.move_to_point=dict(zip(moves,points)) self.point_to_move=dict(zip(points,moves)) empty_moves = self.legalMoves(board) win_moves = [] block_win_moves = [] open_four_moves = [] block_open_four_moves = [] open_three_moves = [] steps = [1,board.NS,board.NS-1,board.NS+1] for move in empty_moves: for step in steps: point = self.move_to_point[move] if board.five_in_row(point,board.current_player,step): win_moves.append(move) elif board.five_in_row(point,GoBoardUtil.opponent(board.current_player),step): block_win_moves.append(move) elif board.OpenFour(point,board.current_player,step): open_four_moves.append(move) elif board.BlockOpenFour(point,GoBoardUtil.opponent(board.current_player),step): block_open_four_moves.append(move) move_types=["Win ","BlockWin ","OpenFour ","BlockOpenFour ","Random "] moves=[win_moves,block_win_moves,open_four_moves,block_open_four_moves,empty_moves] for i in range(len(move_types)): if moves[i]: return move_types,moves[i]
def alphabeta(board, alpha, beta): #print(GoBoardUtil.get_twoD_board(board),alpha,beta) result = game_end(board) if (result != None): return result solvePoint = board.list_solve_point() if solvePoint: #print(solvePoint[0]) board.play_move_gomoku(solvePoint[0], board.current_player) result = -alphabeta(board, -beta, -alpha) if (result > alpha): alpha = result undo(board, solvePoint[0]) if (result >= beta): return beta else: for m in GoBoardUtil.generate_legal_moves_gomoku(board): board.play_move_gomoku(m, board.current_player) result = -alphabeta(board, -beta, -alpha) if (result > alpha): alpha = result undo(board, m) if (result >= beta): return beta return alpha
def get_pattern_move_by_signal(self, board, color_to_play): ## RAY's before Apr.6, 2019 ###### # ret = board.get_pattern_moves() # if ret is None: # return GoBoardUtil.generate_random_move_gomoku(board) # movetype_id, moves = ret # move = random.choice(moves) # return move ################################## ## RAY's after Apr.6 2019 ######## ret = board.get_pattern_moves() if ret is None: moves = GoBoardUtil.generate_legal_moves_gomoku(board) else: movetype_id, moves = ret best_move = moves[0] best_score = -math.inf # print(moves) for move in moves: board.play_move_gomoku(move, color_to_play) score = board.board_searcher.evaluator.evaluate( board.twoDBoard, color_to_play) if score > best_score: best_score = score best_move = move board.undo_move_gomoku() return best_move
def policy_moves_cmd(self, args): checkpoint = "Random" moves = GoBoardUtil.generate_legal_moves_gomoku(self.board) color = self.board.current_player if self.policytype == "rule_based": if self.Win(color): checkpoint = "Win" moves = self.Win(color) elif self.BlockWin(): checkpoint = "BlockWin" moves = self.BlockWin() elif self.OpenFour(color): checkpoint = "OpenFour" moves = self.OpenFour(color) elif self.BlockOpenFour(color): checkpoint = "BlockOpenFour" moves = self.BlockOpenFour(color) move = [] for i in moves: move_coord = point_to_coord(i, self.board.size) move_as_string = format_point(move_coord) move.append(move_as_string) move.sort() for i in move: checkpoint += " " + i if checkpoint == "Random": checkpoint = "" self.respond(checkpoint)
def __init__(self, go_engine, board, debug_mode=False): """ Manage a GTP connection for a Go-playing engine Parameters ---------- go_engine: a program that can reply to a set of GTP commandsbelow board: Represents the current board state. """ self._debug_mode = debug_mode self.go_engine = go_engine self.board = board self.policy_type = "rule_based" #signal.signal(signal.SIGALRM, self.handler) self.commands = { "protocol_version": self.protocol_version_cmd, "quit": self.quit_cmd, "name": self.name_cmd, "boardsize": self.boardsize_cmd, "showboard": self.showboard_cmd, "clear_board": self.clear_board_cmd, "komi": self.komi_cmd, "version": self.version_cmd, "known_command": self.known_command_cmd, "genmove": self.genmove_cmd, "list_commands": self.list_commands_cmd, "play": self.play_cmd, "legal_moves": self.legal_moves_cmd, "gogui-rules_game_id": self.gogui_rules_game_id_cmd, "gogui-rules_board_size": self.gogui_rules_board_size_cmd, "gogui-rules_legal_moves": self.gogui_rules_legal_moves_cmd, "gogui-rules_side_to_move": self.gogui_rules_side_to_move_cmd, "gogui-rules_board": self.gogui_rules_board_cmd, "gogui-rules_final_result": self.gogui_rules_final_result_cmd, "gogui-analyze_commands": self.gogui_analyze_cmd, "timelimit": self.timelimit_cmd, "policy_moves": self.policy_moves_cmd, "policy": self.policy_cmd, "count": self.count_color_cmd } self.timelimit = 60 self.open = False # used for argument checking # values: (required number of arguments, # error message on argnum failure) self.argmap = { "boardsize": (1, 'Usage: boardsize INT'), "komi": (1, 'Usage: komi FLOAT'), "known_command": (1, 'Usage: known_command CMD_NAME'), "genmove": (1, 'Usage: genmove {w,b}'), "play": (2, 'Usage: play {b,w} MOVE'), "legal_moves": (1, 'Usage: legal_moves {w,b}') } self.all_points = GoBoardUtil.generate_legal_moves_gomoku(self.board) moves = self.legalMoves() self.move_to_point = dict(zip(moves, self.all_points)) self.point_to_move = dict(zip(self.all_points, moves))
def MinimaxBooleanAND(board, depth, color, alpha, beta, start_time): moves = GoBoardUtil.generate_legal_moves_gomoku(board) worst_points = 10000 time_elapsed = time.time() - start_time #DEBUG - remove later print(time_elapsed) #check to see if out of time if time_elapsed >= TIME_LIMIT: return False, EMPTY, 0 #check to see if terminal state check_win, check_color = board.check_game_end_gomoku() if check_win == True: if check_color == color: return False, check_color, 0 else: return True, check_color, 10000 #base case if (depth == 0 or len(moves) == 0): if len(moves) == 0: return board.StatisticallyEvaluate(False) return board.StatisticallyEvaluate() for move in moves: save_board(board) board.play_move_gomoku(move, color) win, col, points = MinimaxBooleanOR(board, depth - 1, opposite_color(color), alpha, beta, start_time) if win == False and col == EMPTY: return False, EMPTY, 0 if col != opposite_color(color): win = False points = -points if not win: board = undo() return False, col, 0 if points < worst_points: worst_points = points board = undo() # deal with alpha-beta values #if worst_points <= alpha: #alert("alpha cutoff: " + str(alpha)) #return False, opposite_color(color), worst_points if worst_points <= beta: beta = points #DEBUG #print("Worst points: " + str(worst_points)) #print("MinimaxAND: ") #print(str(GoBoardUtil.get_twoD_board(board))) return True, opposite_color(color), 10000
def BlockOpenFour(self, color): legal_moves = GoBoardUtil.generate_legal_moves_gomoku(self.board) opp = GoBoardUtil.opponent(color) result = self.OpenFour_my(opp) if result: return result return False
def legalMoves(self): moves = GoBoardUtil.generate_legal_moves_gomoku(self.board) gtp_moves = [] for move in moves: coords = point_to_coord(move, self.board.size) gtp_moves.append(format_point(coords)) return gtp_moves
def genmove_cmd(self, args): """ Generate a move for the color args[0] in {'b', 'w'}, for the game of gomoku. """ board_color = args[0].lower() color = color_to_int(board_color) game_end, winner = self.board.check_game_end_gomoku() if game_end: if winner == color: self.respond("pass") else: self.respond("resign") return move = GoBoardUtil.generate_legal_moves_gomoku(self.board) if (self.policytype == "random"): best = None cur_max = 0 for i in move: if best == None: best = i gmax = 0 for _ in range(10): result = self.random(self.board, color, color) gmax += result if (gmax / 10) > cur_max: best = i cur_max = (gmax / 10) elif (self.policytype == "rule_based"): best = None cur_max = 0 for i in move: if best == None: best = i gmax = 0 self.board.play_move_gomoku(i, color) for _ in range(10): result = self.rules(self.board, color, GoBoardUtil.opponent(color)) gmax += result #print(wins) if (gmax / 10) > cur_max: best = i #print(best_move) cur_max = (gmax / 10) self.board.reset_point_gomoku(i, color) if best == PASS: self.respond("pass") return move_coord = point_to_coord(best, self.board.size) move_as_string = format_point(move_coord) if self.board.is_legal_gomoku(best, color): self.board.play_move_gomoku(best, color) self.respond(move_as_string) else: self.respond("illegal move: {}".format(move_as_string))
def Minimax(board, depth, color): start_time = time.time() moves = GoBoardUtil.generate_legal_moves_gomoku(board) best_points = 0 best_move = None is_win = 0 alpha = NINFINITY beta = INFINITY #special case: check to see if current board already has a winner win, col = board.check_game_end_gomoku() if win == True: #if the opposite color already won, then return win=0 if col == opposite_color(color): return 0, None #if our current winner already won, return for move in moves: time_elapsed = time.time() - start_time if time_elapsed >= TIME_LIMIT: return 4, None #DEBUG - remove later print(time_elapsed) save_board(board) board.play_move_gomoku(move, color) win, col, points = MinimaxBooleanAND(board, depth - 1, opposite_color(color), alpha, beta, start_time) if col == EMPTY: return 4, None #DEBUG move_coord = point_to_coord(move, board.size) move_as_string = format_point(move_coord) print("move: " + move_as_string + ", points: " + str(points)) if win and col == color: is_win = 2 best_move = move best_points = points alpha = best_points return is_win, best_move if not win and col == opposite_color(color): is_win = 0 best_move = None #process a draw, best condition if win not an option #if ((is_win != 2 and is_win != 0) and points == 0): if not win and col == None: is_win = 1 best_move = move board = undo() return is_win, best_move
def reset(self, size): """ Reset the board to empty board of given size """ self.board.reset(size) points = GoBoardUtil.generate_legal_moves_gomoku(self.board) moves = self.legalMoves() self.move_to_point = dict(zip(moves, points)) self.point_to_move = dict(zip(points, moves))
def expand(self, board, color): """ Expands tree by creating new children. """ moves = GoBoardUtil.generate_legal_moves_gomoku(board) for move in moves: if move not in self._children: self._children[move] = TreeNode(self) self._children[move]._move = move self._expanded = True
def Win(self, color): legal_moves = GoBoardUtil.generate_legal_moves_gomoku(self.board) shuai = [] for point in legal_moves: rt_moves = self.detect_immediate_win_for_a_point(point, color) if len(rt_moves) != 0: shuai.append(rt_moves[0]) if len(shuai) > 0: # print("shuai:", shuai) return shuai return False
def get_policy_moves(self, board, useRules=True): if (useRules): MoveType, moves = GoBoardUtil.generate_rule_based_moves(board) if (MoveType != "Random"): return MoveType, moves # if we're not using rules # or generate_rule_based_moves(..) returned nothing moves = GoBoardUtil.generate_legal_moves_gomoku(board) if (len(moves) > 0): return "Random", moves return "", []
def BlockOpenFour(self, color): legal_moves = GoBoardUtil.generate_legal_moves_gomoku(self.board) opp = GoBoardUtil.opponent(color) result = self.OpenFour_my(opp) if result: if len(result) == 1: for node in legal_moves: check_3_connect(point) else: return result return False
def gogui_rules_legal_moves_cmd(self, args): game_end, _ = self.board.check_game_end_gomoku() if game_end: self.respond() return moves = GoBoardUtil.generate_legal_moves_gomoku(self.board) gtp_moves = [] for move in moves: coords = point_to_coord(move, self.board.size) gtp_moves.append(format_point(coords)) sorted_moves = ' '.join(sorted(gtp_moves)) self.respond(sorted_moves)
def policy_moves(board, color_to_play): # if(self.playout_policy=='random'): # return "Random", self._random_moves(board, color_to_play) #else: # assert(self.playout_policy=='rule_based') # assert(isinstance(board, SimpleGoBoard)) pattern_list = ['Win', 'BlockWin', 'OpenFour', 'BlockOpenFour', 'Random'] ret = board.get_pattern_moves() if ret is None: return "Random", GoBoardUtil.generate_legal_moves_gomoku(board) movetype_id, moves = ret return pattern_list[movetype_id], moves
def gogui_rules_legal_moves_cmd(self, args): game_end,_ = self.board.check_game_end_gomoku() if game_end: self.respond() return moves = GoBoardUtil.generate_legal_moves_gomoku(self.board) gtp_moves = [] for move in moves: coords = point_to_coord(move, self.board.size) gtp_moves.append(format_point(coords)) # adding sort key sorts by letter first then the numeric value A1, A2, > A10 sorted_moves = ' '.join(sorted(gtp_moves, key=lambda m: (m[0:1], int(m[1:])))) self.respond(sorted_moves)
def solve(board): result=game_end(board) if (result!=None): return result,"First" alpha,beta=-1,1 haveDraw=False solvePoint=board.list_solve_point() if solvePoint: #print(solvePoint[0]) board.play_move_gomoku(solvePoint[0],board.current_player) result=-int(alphabeta(board,-beta,-alpha)) undo(board,solvePoint[0]) if(result==1): return True,solvePoint[0] elif(result==0): haveDraw=True else: for m in GoBoardUtil.generate_legal_moves_gomoku(board): board.play_move_gomoku(m,board.current_player) result=-int(alphabeta(board,-beta,-alpha)) #print(GoBoardUtil.get_twoD_board(board)) #print(result) undo(board,m) if(result==1): return True,m elif(result==0): haveDraw=True return haveDraw,"NoMove" # for m in board.legal_moves(): # history_set.add(str(board.get_twoD_board())+str(board.current_player)) # board.move(m, board.current_player) # result,move=None, None # if board.end_of_game(): # result,move = isSuccess(board, komi), "NoMove" # elif str(board.get_twoD_board())+str(board.current_player) in history_set: # board.undo_move() # continue # if result==None and move==None: # result, move = negamaxBoolean(board, komi, history_set) # success = not result # board.undo_move() # history_set.remove(str(board.get_twoD_board())+str(board.current_player)) # if success: # return True, m # return False, "NoMove"
def get_move(self, board, color_to_play): """ The genmove function called by gtp_connection """ sensible_moves = GoBoardUtil.generate_legal_moves_gomoku(board) if len(sensible_moves) > 0: start = timer() move = self.mcts.get_move(board) end = timer() self.mcts.update_with_move(-1) print("time = ", end - start) return move else: print("WARNING: the board is full")
def detect_immediate_win_for_a_point(self, current, color): # BLACK or WHITE, aka 1 or 2 occu = GoBoardUtil.generate_current_color(self.board, color) # # legal = GoBoardUtil.generate_legal_moves_gomoku(self.board) i_win_list = [] # print(current, color) check = self.four_in_5(current, occu) #print(check) upper = (self.board.size + 1)**2 if check in [int(i) for i in legal]: # print("pass") if check not in i_win_list: i_win_list.append(check) # print(i_win_list) return i_win_list #the list with points that fits
def firstsixteen(self, board, color): game_end, win = self.board.check_game_end_gomoku() checkpoint = "killer mode" if self.Win(color): checkpoint = "Win" moves = self.Win(color) elif self.BlockWin(): checkpoint = "BlockWin" moves = self.BlockWin() elif self.OpenFour(color): checkpoint = "OpenFour" moves = self.OpenFour(color) elif self.BlockOpenFour(color): checkpoint = "BlockOpenFour" moves = self.BlockOpenFour(color) else: moves = GoBoardUtil.generate_legal_moves_gomoku(board) cur = GoBoardUtil.generate_current_color(board, color) if len(cur) == 0: #first step to go move = 35 #print(type(move)) print(1) return int(move) seikiro = [] #a list for ranking of best points xianfengsi = [] for i in moves: length, point = self.findlongestsequence(i, cur) if length != False: seikiro.append([length, point]) print(seikiro) for i in seikiro: if i[1] in moves: xianfengsi.append(i) print(moves) geili = sorted(xianfengsi, key=lambda x: x[0], reverse=True) print(geili) return geili[0][1] #return the best point return moves[0] #return
def get_move(self, board, color): """ Run one-player MC simulations to get a move to play """ color = board.current_player cboard = board.copy() if self.random_simulation: moves = GoBoardUtil.generate_legal_moves_gomoku(board) else: _, moves = PatternUtil.generate_policy_moves(board) move_wins = [] for move in moves: wins = self.simulate_move(cboard, move, color) move_wins.append(wins) return select_best_move(board, moves, move_wins)
def check_game_end_gomoku(self): """ Check if the game ends for the game of Gomoku. """ white_points = where1d(self.board == WHITE) black_points = where1d(self.board == BLACK) if len(GoBoardUtil.generate_legal_moves_gomoku(self)) == 0: return True, TIE for point in white_points: if self.point_check_game_end_gomoku(point): return True, WHITE for point in black_points: if self.point_check_game_end_gomoku(point): return True, BLACK return False, None