def try_to_block_oppoent_immediate_win(self, color): # xoooo. # ooo.o # oo.oo result = [] EMPTY_POINT = where1d(self.board == EMPTY) opponent = GoBoardUtil.opponent(color) for point in EMPTY_POINT: if self.check_in_line_with_empty( point, 1, opponent, 5, False, False) or self.check_in_line_with_empty( point, self.NS, opponent, 5, False, False) or self.check_in_line_with_empty( point, self.NS + 1, opponent, 5, False, False) or self.check_in_line_with_empty( point, self.NS - 1, opponent, 5, False, False): # print(str(color) + " block with " + str(point)) result.append(point) return result
def try_to_play_immediate_win(self, color): # xxxx. # xxx.x # xx.xx # xxx.xxx result = [] EMPTY_POINT = where1d(self.board == EMPTY) for point in EMPTY_POINT: if self.check_in_line_with_empty( point, 1, color, 5, False, False) or self.check_in_line_with_empty( point, self.NS, color, 5, False, False) or self.check_in_line_with_empty( point, self.NS + 1, color, 5, False, False) or self.check_in_line_with_empty( point, self.NS - 1, color, 5, False, False): # print(str(color) + " immediate win " + str(point)) result.append(point) return result
def open_four(self, color): # if you have a move that creates an open four position of type .XXXX., then play it. # Examples of this scenario are: .X.XX. and .XXX.. found_points = [] empty_pts = where1d(self.board == 0) for point in empty_pts: if self.straight_check(point, 1, color, 4, False, True): #f (1) found_points.append(point) elif self.straight_check(point, self.NS, color, 4, False, True): found_points.append(point) elif self.straight_check(point, self.NS + 1, color, 4, False, True): found_points.append(point) elif self.straight_check(point, self.NS - 1, color, 4, False, True): found_points.append(point) return found_points
def _detect_and_process_capture(self, nb_point): """ Check whether opponent block on nb_point is captured. If yes, remove the stones. Returns the stone if only a single stone was captured, and returns None otherwise. This result is used in play_move to check for possible ko """ if self._fast_liberty_check(nb_point): return None opp_block = self._block_of(nb_point) if self._has_liberty(opp_block): return None captures = list(where1d(opp_block)) self.board[captures] = EMPTY self.liberty_of[captures] = NULLPOINT single_capture = None if len(captures) == 1: single_capture = nb_point return single_capture
def block_open_four(self, color): EMPTY_POINT = where1d(self.board == EMPTY) patterns = { '.x.xx.': 0, '.xx.x.': 0, '?.xxx..': 1, '..xxx.?': 0, '-.xxx.-': 1 } for point in EMPTY_POINT: for pattern in patterns.keys(): for shift in [ 1, -1, self.NS, -self.NS, self.NS + 1, -self.NS - 1, self.NS - 1, -self.NS + 1 ]: isFound, result = self.check_pattern( pattern, point, color, shift, patterns[pattern]) if isFound: return result return []
def try_play_intersection(self, color): # . # .oo.. # o # o # . EMPTY_POINT = where1d(self.board == EMPTY) for point in EMPTY_POINT: count = 0 if self.check_in_line_with_empty(point, 1, color, 3, False, True): count += 1 if self.check_in_line_with_empty(point, self.NS, color, 3, False, True): count += 1 if self.check_in_line_with_empty(point, self.NS + 1, color, 3, False, True): count += 1 if self.check_in_line_with_empty(point, self.NS - 1, color, 3, False, True): count += 1 if count >= 2: # print(str(color) + " win intersection " + str(point)) return point return False
def get_empty_points(self): """ Return: The empty points on the board """ return where1d(self.board == EMPTY)
def get_color_points(self, color): """ Return: All points of color on the board """ return where1d(self.board == color)
def get_color_points(self, color): return where1d(self.board == color)
def winDetection(self): myWins = [] theirWins = [] my2mWins = [] their2mWins = [] size = self.size startPoint = size + 2 points = where1d(self.board == self.current_player) #print("Horizontal") # horizontal checks for rowStart in range(startPoint, startPoint + size * size + 1, size + 1): winStr = "" for point in range(rowStart, rowStart + size): winStr += self.getPointRep(self.current_player, point) # check 2-move wins if len(winStr) == 6: self.checkThreat(threatDict, winStr, my2mWins, their2mWins, point, 1) # reduce the string to a 5-long string winStr = winStr[1:] # check for 1-move wins if len(winStr) == 5: if self.checkWin(winDict, winStr, myWins, theirWins, point, 1): # return early if we found a win, because we can just play that return myWins, [], [], [] #print("Vertical") # vertical checks for colStart in range(startPoint, startPoint + size): winStr = "" for point in range(colStart, colStart + (size + 1) * (size - 1) + 1, size + 1): winStr += self.getPointRep(self.current_player, point) if len(winStr) == 6: self.checkThreat(threatDict, winStr, my2mWins, their2mWins, point, size + 1) winStr = winStr[1:] if len(winStr) == 5: if self.checkWin(winDict, winStr, myWins, theirWins, point, size + 1): # return early if we found a win, because we can just play that return myWins, [], [], [] # diagonal I #print("Diag I") exists = size - 5 checkRight = startPoint + 1 checkDown = startPoint + size + 1 dIStarts = [startPoint] for i in range(0, exists): dIStarts.append(checkDown) dIStarts.append(checkRight) checkRight += 1 checkDown += size + 1 dSize = size reduceDSize = True for start in dIStarts: point = start winStr = "" for i in range(0, dSize): winStr += self.getPointRep(self.current_player, point) if len(winStr) == 6: self.checkThreat(threatDict, winStr, my2mWins, their2mWins, point, size + 2) winStr = winStr[1:] if len(winStr) == 5: #print(winStr) if self.checkWin(winDict, winStr, myWins, theirWins, point, size + 2): # return early if we found a win, because we can just play that return myWins, [], [], [] point += size + 2 if reduceDSize: dSize -= 1 reduceDSize = not reduceDSize # diagonal II #print("diag II") checkLeft = startPoint + (size - 1) - 1 checkDown = startPoint + (size - 1) + (size + 1) dIIStarts = [startPoint + size - 1] exists = size - 5 for i in range(0, exists): dIIStarts.append(checkLeft) dIIStarts.append(checkDown) checkLeft -= 1 checkDown += size + 1 dSize = size reduceDSize = True for start in dIIStarts: point = start winStr = "" for i in range(0, dSize): winStr += self.getPointRep(self.current_player, point) if len(winStr) == 6: self.checkThreat(threatDict, winStr, my2mWins, their2mWins, point, size) winStr = winStr[1:] if len(winStr) == 5: #print(winStr) if self.checkWin(winDict, winStr, myWins, theirWins, point, size): # return early if we found a win, because we can just play that return myWins, [], [], [] point += size if reduceDSize: dSize -= 1 reduceDSize = not reduceDSize return myWins, theirWins, my2mWins, their2mWins
def BlockOpenFour(self): color = WHITE + BLACK - self.current_player moves = where1d(self.board == EMPTY) move_list = [] for i in moves: rowc, rows, rd, rs1, rs2 = self.checkrow2(i, color) colc, cols, cd, cs1, cs2 = self.checkcol2(i, color) d1c, d1s, d1, ds1, ds2 = self.checkd12(i, color) d2c, d2s, d2, d21, d22 = self.checkd22(i, color) if rowc == 4 and rows == 1: if rd == 1 and self.board[i + 5] == 0: move_list.append(i + 5) move_list.append(i) elif rd == -1 and self.board[i - 5] == 0: move_list.append(i + 5) move_list.append(i) if colc == 4 and cols == 1: if cd == 1: if self.board[i + 5 * self.NS] == 0: move_list.append(i + 5 * self.NS) move_list.append(i) elif cd == -1: if self.board[i - 5 * self.NS] == 0: move_list.append(i - 5 * self.NS) move_list.append(i) if d1c == 4 and d1s == 1: if d1 == 1: if self.board[i + 5 * (self.NS + 1)] == 0: move_list.append(i + 5 * (self.NS + 1)) move_list.append(i) elif d1 == -1: if self.board[i - 5 * (self.NS + 1)] == 0: move_list.append(i - 5 * (self.NS + 1)) move_list.append(i) if d2c == 4 and d2s == 1: if d2 == 1: if self.board[i + 5 * (self.NS - 1)] == 0: move_list.append(i + 5 * (self.NS - 1)) move_list.append(i) elif d2 == -1: if self.board[i - 5 * (self.NS - 1)] == 0: move_list.append(i - 5 * (self.NS - 1)) move_list.append(i) if rowc == 4 and rows == 2: move_list.append(i) if colc == 4 and cols == 2: move_list.append(i) if d1c == 4 and d1s == 2: move_list.append(i) if d2c == 4 and d2s == 2: move_list.append(i) if rowc == 4 and rows == 2 and rd == 0: move_list.append(rs1) move_list.append(rs2) if colc == 4 and cols == 2 and cd == 0: move_list.append(cs1) move_list.append(cs2) if d1c == 4 and d1s == 2 and d1 == 0: move_list.append(ds1) move_list.append(ds2) if d2c == 4 and d2s == 2 and d2 == 0: move_list.append(d21) move_list.append(d22) move_list = list(set(move_list)) return move_list
def count_colors(goboard): count = [] for color in range(BORDER + 1): points_in_color = where1d(goboard.board == color) count.append(len(points_in_color)) return count
def gogui_rules_final_result_cmd( self, args): #----------Done---------------------- """ Implement this function for Assignment 1 This command checks if the game is over and outputs one of the following game results: """ result = "unknown" colour = self.board.current_player if colour == 1: colour = 'b' else: colour = 'w' #print("#############:", colour) board_color = colour.lower() color = color_to_int(board_color) moves = GoBoardUtil.generate_legal_moves(self.board, self.board.current_player) gtp_moves = [] for move in moves: # check if a PASS if move == "PASS": continue coords = point_to_coord(move, self.board.size) if self.board.board[move] != 0: continue board_copy = self.board.copy() opp_color = GoBoardUtil.opponent(color) board_copy.board[move] = color capture = False single_captures = [] neighbors = board_copy._neighbors(move) No = False for nb in neighbors: if board_copy.board[nb] == opp_color: single_capture = None opp_block = board_copy._block_of(nb) if not board_copy._has_liberty(opp_block): captures = list(where1d(opp_block)) board_copy.board[captures] = 0 if len(captures) == 1: single_capture = nb if len(captures) >= 1: No = True break if single_capture != None: # use single captures to detect suicide single_captures.append(single_capture) if not No: if single_captures != []: continue block = board_copy._block_of(move) if not board_copy._has_liberty(block): # undo suicide move continue gtp_moves.append(format_point(coords)) if not gtp_moves: result = GoBoardUtil.opponent(color) if result == 1: result = 'black' elif result == 2: result = 'white' self.respond(result)
def play_cmd(self, args): #-----------Done-------------------- """ Modify this function for Assignment 1 play a move args[1] for given color args[0] in {'b','w'} Check in following order: wrong color wrong coordinate occupied capture suicide """ try: board_color = args[0].lower() board_move = args[1] color = color_to_int(board_color) #wrong color self.board.current_player if self.board.current_player != color: #figure out a way to implement this elegantly self.respond("illegal move: \"{}\" wrong color".format( " ".join(args))) return #Check if move is "PASS" if board_move.lower() == "pass": #Pass is not allowd so generate Illegal move message self.respond("illegal move: \"{}\" wrong coordinate".format( " ".join(args))) return else: coord = move_to_coord(board_move, self.board.size) if coord: move = coord_to_point(coord[0], coord[1], self.board.size) # check for spot occupation, ex. empty if self.board.board[move] != 0: self.respond("illegal move: \"{}\" occupied".format( " ".join(args))) return board_copy = self.board.copy() #test for captures, then suicide # General case: deal with captures, suicide, and next ko point opp_color = GoBoardUtil.opponent(color) board_copy.board[move] = color capture = False single_captures = [] neighbors = board_copy._neighbors(move) for nb in neighbors: if board_copy.board[nb] == opp_color: single_capture = None opp_block = board_copy._block_of(nb) if not board_copy._has_liberty(opp_block): captures = list(where1d(opp_block)) board_copy.board[captures] = 0 if len(captures) == 1: single_capture = nb if len(captures) >= 1: self.respond("illegal move: \"{}\" capture".format( " ".join(args))) return if single_capture != None: # use single captures to detect suicide single_captures.append(single_capture) if single_captures != []: self.respond("illegal move: \"{}\" capture".format( " ".join(args))) return block = board_copy._block_of(move) if not board_copy._has_liberty(block): # undo suicide move self.respond("illegal move: \"{}\" suicide".format( " ".join(args))) return # try to playe the move if not self.board.play_move(move, color): #false, probably the wrong move self.respond("Illegal move: {}".format(board_move)) return self.respond() except Exception as e: # return an error message self.respond('Error: {}'.format(str(e))) self.respond("illegal Move: \"{}\" wrong coordinate ex".format( " ".join(args)))
def valid_point(self): a = where1d(self.board == BLACK) b = where1d(self.board == WHITE) c = where1d(self.board == EMPTY) return np.concatenate([a, b, c])
def order_the_point(self, color): white_points = where1d(self.board == WHITE) black_points = where1d(self.board == BLACK) final_final_list = [] final_4 = [] final_3 = [] final_2 = [] final_1 = [] if color == 2: for point in white_points: # check 4 block first: # here we need 2 lists to track the duplicate elements if self.check_n(point, 4) != False: list_temp = self.check_n(point, 4) list_4 = [x for x in list_temp if x not in final_4] # for all points final_4 = final_4 + list_4 for point in white_points: if self.check_n(point, 3) != False: list_temp = self.check_n(point, 3) # remove the duplication list_3 = [x for x in list_temp if x not in final_3] # combine these 2 final_3 = final_3 + list_3 final_3 = [x for x in final_3 if x not in final_4] final_final_list = final_4 + final_3 for point in white_points: if self.check_n(point, 2) != False: list_temp = self.check_n(point, 2) # remove the duplication list_2 = [x for x in list_temp if x not in final_2] final_2 = final_2 + list_2 final_2 = [x for x in final_2 if x not in final_final_list] final_final_list = final_final_list + final_2 for point in white_points: if self.check_n(point, 1) != False: list_temp = self.check_n(point, 1) # remove the duplication list_1 = [x for x in list_temp if x not in final_1] final_1 = final_1 + list_1 final_1 = [x for x in final_1 if x not in final_final_list] final_final_list = final_final_list + final_1 list_temp = self.generate_legal_moves(color) total_list = [x for x in list_temp if x not in final_final_list] final_final_list = final_final_list + total_list else: for point in black_points: # check 4 block first: # here we need 2 lists to track the duplicate elements if self.check_n(point, 4) != False: list_temp = self.check_n(point, 4) list_4 = [x for x in list_temp if x not in final_4] # for all points final_4 = final_4 + list_4 for point in black_points: if self.check_n(point, 3) != False: list_temp = self.check_n(point, 3) # remove the duplication list_3 = [x for x in list_temp if x not in final_3] # combine these 2 final_3 = final_3 + list_3 final_3 = [x for x in final_3 if x not in final_4] final_final_list = final_4 + final_3 for point in black_points: if self.check_n(point, 2) != False: list_temp = self.check_n(point, 2) # remove the duplication list_2 = [x for x in list_temp if x not in final_2] final_2 = final_2 + list_2 final_2 = [x for x in final_2 if x not in final_final_list] final_final_list = final_final_list + final_2 for point in black_points: if self.check_n(point, 1) != False: list_temp = self.check_n(point, 1) # remove the duplication list_1 = [x for x in list_temp if x not in final_1] final_1 = final_1 + list_1 final_1 = [x for x in final_1 if x not in final_final_list] final_final_list = final_final_list + final_1 list_temp = self.generate_legal_moves(color) total_list = [x for x in list_temp if x not in final_final_list] final_final_list = final_final_list + total_list return final_final_list
def scan_board(self): myWins = [] theirWins = [] my2mWins = [] their2mWins = [] size = self.size startPoint = size + 2 points = where1d(self.board == self.current_player) # Horizontal Checks for rowStart in range(startPoint, startPoint + size * size + 1, size + 1): winStr = "#" # start with border to get track specials for point in range(rowStart, rowStart + size): winStr += self.getPointRep(self.current_player, point) if len(winStr) >= 7: #print(winStr[-7:]) if winStr[-7:] in specialBlockFourDict: adj = specialBlockFourDict[winStr[-7:]] their2mWins.append(point - adj) # check 2-move wins if len(winStr) >= 6: self.checkThreat(threatDict, winStr[-6:], my2mWins, their2mWins, point, 1) # check for 1-move wins if len(winStr) >= 5: self.checkWin(winDict, winStr[-5:], myWins, theirWins, point, 1) # account for final border winStr += "#" if len(winStr) >= 7: if winStr[-7:] in specialBlockFourDict: adj = specialBlockFourDict[winStr[-7:]] - 1 their2mWins.append(point - adj) # Vertical Checks for colStart in range(startPoint, startPoint + size): winStr = "#" for point in range(colStart, colStart + (size + 1) * (size - 1) + (size + 2), size + 1): winStr += self.getPointRep(self.current_player, point) if len(winStr) >= 7: #print(winStr[-7:]) if winStr[-7:] in specialBlockFourDict: i = specialBlockFourDict[winStr[-7:]] adj = i * (size + 1) their2mWins.append(point - adj) # check 2-move wins if len(winStr) >= 6: self.checkThreat(threatDict, winStr[-6:], my2mWins, their2mWins, point, size + 1) # check for 1-move wins if len(winStr) >= 5: self.checkWin(winDict, winStr[-5:], myWins, theirWins, point, size + 1) # diagonal I exists = size - 5 checkRight = startPoint + 1 checkDown = startPoint + size + 1 dIStarts = [startPoint] for i in range(0, exists): dIStarts.append(checkDown) dIStarts.append(checkRight) checkRight += 1 checkDown += size + 1 dSize = size reduceDSize = True for start in dIStarts: point = start winStr = "#" for i in range(0, dSize): winStr += self.getPointRep(self.current_player, point) # check 2-move wins if len(winStr) >= 7: if winStr[-7:] in specialBlockFourDict: i = specialBlockFourDict[winStr[-7:]] adj = i * (size + 2) their2mWins.append(point - adj) if len(winStr) >= 6: self.checkThreat(threatDict, winStr[-6:], my2mWins, their2mWins, point, size + 2) # check for 1-move wins if len(winStr) >= 5: self.checkWin(winDict, winStr[-5:], myWins, theirWins, point, size + 2) point += size + 2 winStr += "#" if len(winStr) >= 7: if winStr[-7:] in specialBlockFourDict: i = specialBlockFourDict[winStr[-7:]] adj = i * (size + 2) their2mWins.append(point - adj) if reduceDSize: dSize -= 1 reduceDSize = not reduceDSize # diagonal II checkLeft = startPoint + (size - 1) - 1 checkDown = startPoint + (size - 1) + (size + 1) dIIStarts = [startPoint + size - 1] exists = size - 5 for i in range(0, exists): dIIStarts.append(checkLeft) dIIStarts.append(checkDown) checkLeft -= 1 checkDown += size + 1 dSize = size reduceDSize = True for start in dIIStarts: point = start winStr = "#" for i in range(0, dSize): winStr += self.getPointRep(self.current_player, point) # check 2-move wins if len(winStr) >= 7: if winStr[-7:] in specialBlockFourDict: i = specialBlockFourDict[winStr[-7:]] adj = i * (size + 2) their2mWins.append(point - adj) # check 2-move wins if len(winStr) >= 6: self.checkThreat(threatDict, winStr[-6:], my2mWins, their2mWins, point, size) # check for 1-move wins if len(winStr) >= 5: self.checkWin(winDict, winStr[-5:], myWins, theirWins, point, size) point += size winStr += "#" if len(winStr) >= 7: if winStr[-7:] in specialBlockFourDict: i = specialBlockFourDict[winStr[-7:]] adj = i * (size) their2mWins.append(point - adj) if reduceDSize: dSize -= 1 reduceDSize = not reduceDSize myWins = list(set(myWins)) theirWins = list(set(theirWins)) my2mWins = list(set(my2mWins)) their2mWins = list(set(their2mWins)) return myWins, theirWins, my2mWins, their2mWins
def genmove_cmd(self, args): #------------Done--------------------- """ Modify this function for Assignment 1 """ """ generate a move for color args[0] in {'b','w'} """ board_color = args[0].lower() color = color_to_int(board_color) move = self.go_engine.get_move(self.board, color) move_coord = point_to_coord(move, self.board.size) move_as_string = format_point(move_coord) # our code colour = 1 if board_color == 'w': colour == 2 elif board_color == 'b': colour == 1 moves = GoBoardUtil.generate_legal_moves(self.board, colour) gtp_moves = [] for Move in moves: # check if a PASS if Move == "PASS": continue coords = point_to_coord(Move, self.board.size) if self.board.board[Move] != 0: continue board_copy = self.board.copy() opp_color = GoBoardUtil.opponent(color) board_copy.board[Move] = color capture = False single_captures = [] neighbors = board_copy._neighbors(move) No = False for nb in neighbors: if board_copy.board[nb] == opp_color: single_capture = None opp_block = board_copy._block_of(nb) if not board_copy._has_liberty(opp_block): captures = list(where1d(opp_block)) board_copy.board[captures] = 0 if len(captures) == 1: single_capture = nb if len(captures) >= 1: No = True break if single_capture != None: # use single captures to detect suicide single_captures.append(single_capture) if not No: if single_captures != []: continue block = board_copy._block_of(Move) if not board_copy._has_liberty(block): # undo suicide move continue gtp_moves.append(format_point(coords)) print(*gtp_moves) if not gtp_moves: self.respond("resign") else: if format_point(move_coord) in gtp_moves: self.board.play_move(move, color) self.respond(move_as_string) else: self.respond("Illegal move: {}".format(move_as_string))