def solve(self, board, to_play): state = board.copy() # to_play = state.current_player # Initialize proof tree and run negamax search starts with current player proof_tree = [] # Set timer signal.signal(signal.SIGALRM, handler) signal.alarm(self.timelimit) try: result = self.negamaxBoolean(state, self.depth_limit, proof_tree) except Exception as e: # print(e) result = None signal.alarm(0) proof_tree.reverse() # Convert result to current player if result == None: return 'unknown', None elif result: if proof_tree[0] == None: proof_tree[0] = 'pass' return GoBoardUtil.int_to_color(to_play), proof_tree[0] else: return GoBoardUtil.int_to_color( GoBoardUtil.opponent(to_play)), None
def solve(self, args): # Create a copy of our current environment as the root of the tree. root = node(self.board) negamaxResult = self.negamax( root, GoBoardUtil.int_to_color(self.board.current_player), time.time(), self.timelimit) #print(negamaxResult) self.respond("{0} {1}".format( GoBoardUtil.int_to_color(negamaxResult[0]), ""))
def solve_cmd(self, args): color, position = self.board.solve() # didn't finish if color == None: self.respond('\nunknown') # winner elif position != None: self.respond('\n' + str( GoBoardUtil.int_to_color(color) + ' ' + str( GoBoardUtil.format_point( self.board._point_to_coord(position))))) # loser else: self.respond('\n' + str(GoBoardUtil.int_to_color(color)))
def solve(self, board, connection): self.startTime = time.process_time() self.timedOut = False winnable, best = self.negamax(board, board.current_player, 0, connection) if not winnable: return GoBoardUtil.int_to_color( GoBoardUtil.opponent(board.current_player)) if not best: best = GoBoardUtil.format_point(best) else: best = GoBoardUtil.format_point(board._point_to_coord(best)) # Unsure of how to deal with this if self.timedOut: return 'Unknown' return GoBoardUtil.int_to_color(board.current_player) + ' ' + best
def solve_cmd(self, args=None): colour = self.board.current_player can_win, move = self.solve(args) if self.timed_out: self.respond("unknown") else: if can_win: if move: formatted_move = GoBoardUtil.format_point( self.board._point_to_coord(move)) else: formatted_move = GoBoardUtil.format_point(move) self.respond( GoBoardUtil.int_to_color(colour) + ' ' + formatted_move) else: self.respond( GoBoardUtil.int_to_color(GoBoardUtil.opponent(colour)))
def solve_cmd(self, args): self.board.hit = 0 score = self.board.call_search() # print('hit=', self.board.hit) if score == 0: # Timeout self.respond('unknown') elif score == 1: # The player can win _, move = self.board.tree_cache[self.board] self.respond('{} {}'.format( GoBoardUtil.int_to_color(self.board.to_play), move)) else: # The opponent can win self.respond( GoBoardUtil.int_to_color( GoBoardUtil.opponent(self.board.to_play)))
def solve_cmd(self, args): self.move = [] self.start = time.process_time() self.time = False win = self.negamaxBoolean(0) if self.time: self.respond("unknown") return False elif win: self.respond( GoBoardUtil.int_to_color(self.board.current_player) + ' ' + GoBoardUtil.format_point( self.board._point_to_coord(self.move[0]))) return True else: self.respond( GoBoardUtil.int_to_color( GoBoardUtil.opponent(self.board.current_player)))
def solve_cmd(self, args): """ Solves the current game state and returns the winner and the winning move. """ signal.signal(signal.SIGALRM, self.handler) signal.alarm(self.timelimit) try: winner, last_move, first_move = GoBoardUtil.solve(self.board) if self.board.to_play is winner: self.respond("{} {}".format(GoBoardUtil.int_to_color(winner), GoBoardUtil.format_point(self.board._point_to_coord(last_move)))) else: self.respond("{}".format(GoBoardUtil.int_to_color(winner))) except RuntimeError: self.respond("unknown") warnings.warn("Times Up") signal.alarm(0)
def solve(self): board = self.board.copy() depth = self.board.depth try: signal.alarm(self.timelimit) #start = time.process_time() result = self.negamaxBoolean(board, depth) #self.respond("Time: {}".format(str(time.process_time() - start))) signal.alarm(0) except Exception as e: if str(e) == "Timeout": winner, move = "unknown", "" else: raise e else: if result[0]: winner, move = GoBoardUtil.int_to_color( self.board.to_play), result[1] else: winner, move = GoBoardUtil.int_to_color( GoBoardUtil.opponent(self.board.to_play)), "" return winner, move
def _points_color(self, point): """ Return the state of the specified point. Arguments --------- point Returns ------- color: string color representing the specified point . """ p_int_color = self.board[point] return GoBoardUtil.int_to_color(p_int_color)
def print_stat(self, board, root, color): s_color = GoBoardUtil.int_to_color(color) print("Numebr of children {}".format(len(root._children))) print("Number of roots visits: {}".format(root._n_visits)) stats = [] for move, node in root._children.items(): if color == self.init_color: wins = node._black_wins else: wins = node._n_visits - node._black_wins visits = node._n_visits if visits: win_rate = float(wins) / visits else: win_rate = 0 if move == PASS: move = None pointString = board.point_to_string(move) stats.append((pointString, win_rate, wins, visits)) print("Statistics: {}".format( sorted(stats, key=lambda i: i[3], reverse=True)))
def _play_move(self, point, color): """ This function is for playing the move Arguments --------- point, color Return --------- State of move and appropriate message for that move """ if self.board[point] != EMPTY: c = self._point_to_coord(point) msg = "Row and Column: %d %d is already filled with a %s stone" % ( c[0], c[1], GoBoardUtil.int_to_color(color)) return False, msg if point == self.ko_constraint: msg = "KO move is not permitted!" return False, msg self.board[point] = color self._is_empty = False self.caps = [] single_captures = [] cap_inds = None neighbors = self._neighbors(point) for n in neighbors: if self.board[n] == BORDER: continue if self.board[n] != color: if self.board[n] != EMPTY: fboard = self._flood_fill(n) if not self._liberty_flood(fboard): print("no es bueno") #msg = "no es bueno" #return False , msg # if there are no more liberties for a certain stone, come here print('Hey we are here at liberty flood') cap_inds = fboard == FLOODFILL #self.caps = np.where(fboard==FLOODFILL) self.caps += list(*np.where(fboard == FLOODFILL)) num_captures = np.sum(cap_inds) if num_captures == self.size * self.size: self._is_empty = True if num_captures == 1: single_captures.append(n) if self._liberty_flood(fboard) and color == WHITE: #testin the self._liberty_flood # TODO: error message, undo move, return to player to make a new move # MAYBE in here, just make an error message saying cant do that move # allow player to makw a different move # HERE #self.white_captures += num_captures print("error: no liberites for white capturing") # self.white_captures += num_captures #so despit not actually having any code here, white still somehow takes out black else: #break #TODO error message, undo move, return to player to make a new move # error messages are in gtp_connection.py # self.black_captures += num_captures print("error: no liberties for black capturing") self.board[cap_inds] = EMPTY #### THIS IS WHERE WE REMOVE CAPTURED STONE #TODO: NEED TO keep track so we know when game ends # eg if there is no where left you are allowed to play, game is ove in_enemy_eye = self._is_eyeish(point) != color fboard = self._flood_fill(point) self.ko_constraint = single_captures[0] if in_enemy_eye and len( single_captures) == 1 else None if self._liberty_flood(fboard) and self.suicide: #non suicidal move #if there are liberties if cap_inds != None: print("Hi sorry, no captures allowed...") msg = "remember, no russian" return False, msg c = self._point_to_coord(point) msg = "Playing a move with %s color in the row and column %d %d is permited" % ( color, c[0], c[1]) return True, msg else: # undoing the move because of being suicidal self.board[point] = EMPTY if cap_inds != None: self.board[cap_inds] = GoBoardUtil.opponent(color) c = self._point_to_coord(point) msg = "Suicide move with color %s in the row and column: %d %d " % ( color, c[0], c[1]) return False, msg
def _play_move(self, point, color): """ This function is for playing the move Arguments --------- point, color Return --------- State of move and appropriate message for that move """ if point == None: #play a pass move msg = "Playing a pass move with %s color is permitted" % (color) return True, msg if self.board[point] != EMPTY: c = self._point_to_coord(point) msg = "Row and Column: %d %d is already filled with a %s stone" % ( c[0], c[1], GoBoardUtil.int_to_color(color)) return False, msg if point == self.ko_constraint: msg = "KO move is not permitted!" return False, msg in_enemy_eye = self._is_eyeish(point) == GoBoardUtil.opponent(color) self.board[point] = color self._is_empty = False self.captured_stones = [] single_captures = [] cap_inds = None neighbors = self._neighbors(point) for n in neighbors: if self.board[n] == BORDER: continue if self.board[n] != color: if self.board[n] != EMPTY: fboard = self._flood_fill(n) if not self._liberty_flood(fboard): cap_inds = fboard == FLOODFILL self.captured_stones += list(*np.where( fboard == FLOODFILL)) num_captures = np.sum(cap_inds) if num_captures == self.size * self.size: self._is_empty = True if num_captures == 1: single_captures.append(n) if color == WHITE: self.white_captures += num_captures else: self.black_captures += num_captures self.board[cap_inds] = EMPTY fboard = self._flood_fill(point) self.ko_constraint = single_captures[0] if in_enemy_eye and len( single_captures) == 1 else None if not self.check_suicide: msg = "NO SUICIDE CHECKING. Playing a move with %s color in the row and column %d %d is permitted" % ( color, c[0], c[1]) return True, msg if self._liberty_flood(fboard): #non suicidal move c = self._point_to_coord(point) msg = "Playing a move with %s color in the row and column %d %d is permitted" % ( color, c[0], c[1]) return True, msg else: # undoing the move because of being suicidal self.board[point] = EMPTY if cap_inds != None: self.board[cap_inds] = GoBoardUtil.opponent(color) c = self._point_to_coord(point) msg = "Suicide move with color %s in the row and column: %d %d " % ( color, c[0], c[1]) return False, msg
def _play_move(self, point, color): """ This function is for playing the move Arguments --------- point, color Return --------- State of move and appropriate message for that move """ if point == None: #play a pass move msg = "Playing a pass move with %s color is permitted" % (color) self.num_pass += 1 game_ended = self.end_of_game() if game_ended: return True, "Game has ended!", None return True, msg, None self.num_pass = 0 if self.board[point] != EMPTY: c = self._point_to_coord(point) msg = "Row and Column: %d %d is already filled with a %s stone" % ( c[0], c[1], GoBoardUtil.int_to_color(color)) return False, msg, None if point == self.ko_constraint: msg = "KO move is not permitted!" return False, msg, None in_enemy_eye = self._is_eyeish(point) == GoBoardUtil.opponent(color) self.board[point] = color self._is_empty = False caps = [] single_captures = [] neighbors = self._neighbors(point) cap_inds = None for n in neighbors: assert self.board[n] != BORDER if self.board[n] != color: if self.board[n] != EMPTY: hasLiberty, fboard = self._liberty_flood(n) if not hasLiberty: cap_inds = fboard == FLOODFILL caps.extend(list(*np.where(fboard == FLOODFILL))) num_captures = np.sum(cap_inds) if num_captures == self.size * self.size: self._is_empty = True if num_captures == 1: single_captures.append(n) if color == WHITE: self.white_captures += num_captures else: self.black_captures += num_captures self.liberty_dp[cap_inds] = -1 self.board[cap_inds] = EMPTY self.ko_constraint = single_captures[0] if in_enemy_eye and len( single_captures) == 1 else None if (not self.check_suicide): #not check suicidal move c = self._point_to_coord(point) msg = "Playing a move with %s color in the row and column %d %d is permitted" % ( color, c[0], c[1]) return True, msg, caps else: res, lp = self._liberty_flood(point) if res == True: #non suicidal move self.liberty_dp[point] = lp c = self._point_to_coord(point) msg = "Playing a move with %s color in the row and column %d %d is permitted" % ( color, c[0], c[1]) return True, msg, caps else: # undoing the move because of being suicidal # think cap_inds must be None? self.board[point] = EMPTY if cap_inds != None: self.board[cap_inds] = GoBoardUtil.opponent(color) c = self._point_to_coord(point) msg = "Suicide move with color %s in the row and column: %d %d " % ( color, c[0], c[1]) return False, msg, None
def _play_move2(self,point, color): import board_util """ This function is for playing the move Arguments --------- point, color Return --------- State of move and appropriate message for that move """ if self.board[point] != EMPTY: c=self._point_to_coord(point) #board_util.raise_occupied_error() msg = "Row and Column: %d %d is already filled with a %s stone"%(c[0],c[1],GoBoardUtil.int_to_color(color)) return False,msg if(color == 'b') or (color == 'w'): board_util.raise_color_error() return False, "" if point == self.ko_constraint: msg ="KO move is not permitted!" return False , msg self.board[point] = color self._is_empty = False self.caps = [] single_captures = [] reset_cap = [] cap_inds = None num_captures = 0 # neighbors around point neighbors = self._neighbors(point) for n in neighbors: # its neighbor is a side if self.board[n]==BORDER: continue # its neighbor isn't itself if self.board[n]!=color: if self.board[n]!=EMPTY: # add the previous positions fboard = self._flood_fill(n) reset_cap.append(n) if not self._liberty_flood(fboard): cap_inds = fboard==FLOODFILL #self.caps = np.where(fboard==FLOODFILL) self.caps += list(*np.where(fboard==FLOODFILL)) num_captures = np.sum(cap_inds) ###################### self.board[point] = EMPTY if cap_inds is None: self.board[cap_inds]=GoBoardUtil.opponent(color) c=self._point_to_coord(point) #board_util.raise_capture_error() msg = "Capture" return False, msg ###################### in_enemy_eye = self._is_eyeish(point) != color # plays the point on the board fboard = self._flood_fill(point) self.ko_constraint = single_captures[0] if in_enemy_eye and len(single_captures) == 1 else None if(num_captures > 0): self.board[point] = EMPTY if cap_inds is None: self.board[cap_inds]=GoBoardUtil.opponent(color) for x in reset_cap: fboard = self._flood_fill(x) c=self._point_to_coord(point) msg = "Capture check" return False, msg elif self._liberty_flood(fboard) and self.suicide: #non suicidal move c=self._point_to_coord(point) msg = "" return True, msg elif (self.suicide): # undoing the move because of being suicidal self.board[point] = EMPTY if cap_inds!= None: self.board[cap_inds]=GoBoardUtil.opponent(color) c=self._point_to_coord(point) msg = "Suicide" #board_util.raise_suicide_error() return False, msg
def policy_moves_cmd(self, args): """ Return list of policy moves for the current_player of the board """ #ATARI CAPTURE if self.board.last_move != None: moves = self.last_moves_empty() diagonal = self.board._diag_neighbors(self.board.last_move) capture_moves = list(set(moves) - set(diagonal)) capture_moves = GoBoardUtil.filter_moves( self.board, capture_moves, self.go_engine.check_selfatari) if (len(capture_moves) == 1): if (self.board._liberty( capture_moves[0], self.board._points_color(capture_moves[0])) == 1): policy_moves, type_of_move = capture_moves, 'AtariCapture' response = type_of_move + " " + GoBoardUtil.sorted_point_string( policy_moves, self.board.NS) self.respond(response) # self.respond("akjhfjkasdhfkjahsd") return # # ATARI DEFENCE # else: # defence_moves=[] # moves = self.board._neighbors(self.board.last_move) # # moves.extend(board._diag_neighbors2(board.last_move)) # for move in moves: # if(self.board._single_liberty(move,self.board.current_player)!=None): # # print(self.board._single_liberty(move,self.board.current_player)) # # print(self.board._point_to_coord(move)) # defence_moves.append(self.board._single_liberty(move,self.board.current_player)) # if(defence_moves != []): # defence_moves = GoBoardUtil.filter_moves(self.board, defence_moves, self.go_engine.check_selfatari) # policy_moves, type_of_move = defence_moves, 'AtariDefense' # response = type_of_move + " " + GoBoardUtil.sorted_point_string(policy_moves, self.board.NS) # self.respond(response) # return defence_moves = [] lm = self.board.last_move if lm != None: current_play = self.board.current_player opponent = GoBoardUtil.opponent(self.board.current_player) for elem in self.board._neighbors(lm): val = GoBoardUtil.color_to_int(self.board._points_color(elem)) if current_play == val: # print(self.board._neighbors(elem)) # if self.board._neighbors(val) != None: if (self.board._single_liberty( elem, GoBoardUtil.int_to_color(val)) != None): # val3 = GoBoardUtil.color_to_int(self.board._points_color(elem)) if self.board._liberty( self.board._single_liberty( elem, GoBoardUtil.int_to_color(val)), current_play) > 1: defence_moves.append( self.board._single_liberty( elem, GoBoardUtil.int_to_color(val))) ng = self.board._neighbors(lm) dg = self.board._diag_neighbors(self.board.last_move) all_ng = ng + dg # print(all_ng) count = 0 for elem in all_ng: val = GoBoardUtil.color_to_int(self.board._points_color(elem)) if opponent == val: # print(self.board._single_liberty(elem, GoBoardUtil.int_to_color(val))) if (self.board._single_liberty( elem, GoBoardUtil.int_to_color(val)) != None): # print(elem) for i in self.board._neighbors(elem): # print(i) val2 = GoBoardUtil.color_to_int( self.board._points_color(i)) if (val2 == opponent): # print(self.board._liberty(i, GoBoardUtil.int_to_color(val2))) if (self.board._liberty( i, GoBoardUtil.int_to_color(val2)) != None): count += 1 # print(count) if (count == 0): defence_moves.append( self.board._single_liberty( elem, GoBoardUtil.int_to_color(val))) count = 0 # print(self.board.co defence_moves) # for v in defence_moves: # print(v) defence_moves = GoBoardUtil.filter_moves( self.board, defence_moves, self.go_engine.check_selfatari) defence_moves = GoBoardUtil.sorted_point_string( defence_moves, self.board.NS) if len(defence_moves) > 0: # defence_moves = GoBoardUtil.filter_moves(self.board,defence_moves, self.go_engine.check_selfatari) self.respond("AtariDefense " + defence_moves) return policy_moves, type_of_move = GoBoardUtil.generate_all_policy_moves( self.board, self.go_engine.use_pattern, self.go_engine.check_selfatari) if len(policy_moves) == 0: self.respond("Pass") else: response = type_of_move + " " + GoBoardUtil.sorted_point_string( policy_moves, self.board.NS) self.respond(response) return