import numpy as np BOARD_SIZE = 15 EMPTY = 0 PLAYER = 1 AI = 2 class GobangGame: def __init__(self): self.board = np.zeros((BOARD_SIZE, BOARD_SIZE), dtype=int) def is_win(self, x, y, chess_type): directions = [[1, 0], [0, 1], [1, 1], [1, -1]] for dx, dy in directions: count = 1 cx, cy = x + dx, y + dy while 0 <= cx < BOARD_SIZE and 0 <= cy < BOARD_SIZE and self.board[cx][cy] == chess_type: count += 1 cx += dx cy += dy cx, cy = x - dx, y - dy while 0 <= cx < BOARD_SIZE and 0 <= cy < BOARD_SIZE and self.board[cx][cy] == chess_type: count += 1 cx -= dx cy -= dy if count >= 5: return True return False def get_continuous(self, start_x, start_y, dx, dy, chess_type): """获取连续棋子数量,并且判断两端是否有空位,返回(连子数量,左边空位,右边空位)""" cnt = 1 left_empty, right_empty = False, False # 往反方向查找 x1, y1 = start_x - dx, start_y - dy if 0 <= x1 < BOARD_SIZE and 0 <= y1 < BOARD_SIZE and self.board[x1][y1] == EMPTY: left_empty = True while 0 <= x1 < BOARD_SIZE and 0 <= y1 < BOARD_SIZE and self.board[x1][y1] == chess_type: cnt += 1 x1 -= dx y1 -= dy # 正方向查找 x2, y2 = start_x + dx, start_y + dy if 0 <= x2 < BOARD_SIZE and 0 <= y2 < BOARD_SIZE and self.board[x2][y2] == EMPTY: right_empty = True while 0 <= x2 < BOARD_SIZE and 0 <= y2 < BOARD_SIZE and self.board[x2][y2] == chess_type: cnt += 1 x2 += dx y2 += dy return cnt, left_empty, right_empty def get_score(self, x, y): """修正后的打分函数,只判断连续棋子""" if self.board[x][y] != EMPTY: return -1 score = 0 directions = [[1, 0], [0, 1], [1, 1], [1, -1]] # 模拟落子 self.board[x][y] = AI for dx, dy in directions: ai_num, ai_left, ai_right = self.get_continuous(x, y, dx, dy, AI) if ai_num == 4: if ai_left and ai_right: score += 100000 # AI活四优先级最高 else: score += 10000 # AI冲四 elif ai_num == 3: if ai_left and ai_right: score += 5000 else: score += 800 elif ai_num == 2: if ai_left and ai_right: score += 300 else: score += 50 self.board[x][y] = EMPTY # 评估玩家威胁,AI防守 self.board[x][y] = PLAYER for dx, dy in directions: p_num, p_left, p_right = self.get_continuous(x, y, dx, dy, PLAYER) if p_num == 4: if p_left and p_right: score += 80000 # 玩家活四必须堵 else: score += 9000 elif p_num == 3: if p_left and p_right: score += 4000 else: score += 700 elif p_num == 2: if p_left and p_right: score += 200 self.board[x][y] = EMPTY # 棋盘中心位置加分 distance = abs(x - 7) + abs(y - 7) score += (14 - distance) * 6 return score def ai_choose(self): max_score = -1 best_x, best_y = 7, 7 for i in range(BOARD_SIZE): for j in range(BOARD_SIZE): if self.board[i][j] == EMPTY: current_score = self.get_score(i, j) if current_score > max_score: max_score = current_score best_x, best_y = i, j return best_x, best_y def is_board_full(self): """判断棋盘已满,平局""" for i in range(BOARD_SIZE): for j in range(BOARD_SIZE): if self.board[i][j] == EMPTY: return False return True def print_board(self): print(" ", end="") for idx in range(BOARD_SIZE): print(f"{idx:2d}", end=" ") print() for i in range(BOARD_SIZE): print(f"{i:2d}", end=" ") line = [] for j in range(BOARD_SIZE): val = self.board[i][j] if val == PLAYER: line.append("●") elif val == AI: line.append("○") else: line.append(".") print(" ".join(line)) def start_game(self): print("====五子棋人机对战====") print("你执黑棋●先行,输入坐标 x y 例如:7 7") while True: self.print_board() # 玩家落子 while True: try: x, y = map(int, input("请输入落子坐标(x y):").split()) if 0 <= x < BOARD_SIZE and 0 <= y < BOARD_SIZE and self.board[x][y] == EMPTY: break else: print("坐标越界或者该位置已有棋子,请重新输入!") except Exception: print("输入格式错误,示例:7 7") self.board[x][y] = PLAYER if self.is_win(x, y, PLAYER): self.print_board() print("恭喜你战胜AI!游戏结束") break if self.is_board_full(): self.print_board() print("棋盘已满,本局平局!") break # AI落子 ai_x, ai_y = self.ai_choose() self.board[ai_x][ai_y] = AI print(f"\nAI落子位置:{ai_x} {ai_y}") if self.is_win(ai_x, ai_y, AI): self.print_board() print("AI获胜,游戏结束!") break if self.is_board_full(): self.print_board() print("棋盘已满,本局平局!") break if __name__ == "__main__": game = GobangGame() game.start_game()
html2.link
举报