棋盘即战场,黑白双色如阴阳激荡!此刻,人类智慧与人工智能的史诗对决轰然展开。指尖悬停的刹那,血脉奔涌如江河咆哮——这是跨越千年的谋略传承与算法洪流的正面对撞!每一步落子皆是灵感的惊雷,每一轮攻防都是思维的核爆。AI的算力如银河倾泻,而人类以直觉为刃,以韧性为盾,在精密代码的围剿中劈开血色黎明。纵使败局已定,那永不屈服的瞳孔仍将点燃文明的火种:机器可计算亿万可能,却算不透人类以凡躯比肩神明的孤勇!此战无关胜负,唯见灵魂在钢铁森林中迸射的光芒,永恒闪耀于星辰之间。
文章目录
一、游戏界面预览
二、游戏制作框架
1. 采用Python语言
只引入 tkinter 、messagebox两个库,没有引入pygame,我们自己定义AI的实现方法使他更智能,对弈时更难以取胜。
2. 游戏功能介绍
1. 玩家点击棋盘落黑子
2. AI会自动响应落白子
3. 实时显示当前步数和胜负统计
4. 支持"新游戏"按钮重置对局
5. AI具有基本的攻防判断能力
6. 自动判断五连胜利
运行后会出现一个25x25的五子棋棋盘,玩家可以点击棋盘进行对弈,AI会自动响应。当有一方五连时会出现胜利提示,可以通过"新游戏"按钮随时开始新对局。
3.具体实现步骤
1)创建主窗口和Canvas:设置窗口大小为800x800左右,Canvas用于绘制棋盘和棋子。棋盘线间隔30像素,25条线,总长度24*30=720,所以棋盘区域可能从(40,40)开始,留出边距,或者调整格子大小。或者计算合适的起始位置,使得棋盘居中。
2)棋盘绘制:使用循环绘制横线和竖线,间隔30像素,共25行25列。
3)处理鼠标点击:绑定Canvas的鼠标点击事件。将鼠标的x,y坐标转换为棋盘的行列索引。检查该位置是否为空,如果是,放置黑子,更新数组,绘制黑子。
4)调用AI函数,让AI下白子。AI逻辑:遍历所有空位,计算每个位置的得分。选择得分最高的位置下子。得分计算包括进攻和防守因素。
5)胜负判断:每次落子后,检查该位置是否形成五连。如果有,游戏结束,显示结果。新游戏按钮:创建按钮,点击时重置棋盘数组,清空Canvas上的棋子,重置步数和比分。
6)显示步数和比分:使用Label组件显示当前步数,黑子和白子的胜利次数。
三、AI的策略说明
1. 首先给不同的棋型赋予不同的分数:
连五:100000分(直接胜利)
活四:10000分
冲四:1000分
活三:1000分
眠三:100分
活二:100分
眠二:10分
2. 评估函数evaluate_position 对于AI下白子时,计算该位置的白子连击情况,同时也要计算如果玩家下黑子在该位置的连击情况,防守分是后者的评分。总分为进攻分+防守分*权重
ai_move函数中的评分逻辑:
score_attack = self.evaluate_position(row, col, 2) # AI下白子的得分
score_defend = self.evaluate_position(row, col, 1) # 玩家下黑子的得分,
需要防守 total_score = score_attack + score_defend * 1.2 # 防守权重更高
这样,AI会优先防守玩家的高威胁位置,同时寻找自己的进攻机会。
3. 为了提高AI的智能,选择每一步的下法都有相对应的评分。
在evaluate_position函数中,可以针对给定的颜色,评估在该位置下子后的得分。例如,检查四个方向,计算每个方向的连续棋子数,并根据情况加分。
例如,对于某个方向,如果连续有四个同色棋子,且两端为空,则是活四,得分很高。如果连续四个,但一端被堵,则是冲四,得分次之。
实现逻辑:在评估某个方向时,除了统计连续的同色棋子数,还要检查两端的情况。
例如,在某个方向的正方向和反方向延伸,统计连续的同色棋子数,并检查延伸后的下一个位置是否为空或被对方堵住。
evaluate_position函数:
def evaluate_position(self, row, col, color): score = 0 directions = [(0,1), (1,0), (1,1), (1,-1)] for dx, dy in directions:
# 检查正方向 consecutive = 1 block = 0 x, y = row + dx, col + dy while 0 <= x < self.board_size and 0 <= y < self.board_size: if self.chess_board[x][y] == color: consecutive +=1 else: if self.chess_board[x][y] != 0: block +=1 break x += dx y += dy
# 检查反方向 x, y = row - dx, col - dy while 0 <= x < self.board_size and 0 <= y < self.board_size: if self.chess_board[x][y] == color: consecutive +=1 else: if self.chess_board[x][y] !=0: block +=1 break x -= dx y -= dy
# 根据连续数和block数来评分 if consecutive >=5: score += 100000 else: if consecutive ==4: if block ==0: score += 10000 # 活四 elif block ==1: score += 1000 # 冲四 elif consecutive ==3: if block ==0: score += 1000 # 活三 elif block ==1: score += 200 # 眠三 elif consecutive ==2: if block ==0: score += 100 # 活二 elif block ==1: score += 50 # 眠二 elif consecutive ==1: score +=10 return score
这样,当连续的同色棋子数为4,且没有被堵住(block=0),则视为活四,得分高。如果被堵住一端(block=1),则是冲四,得分次之。
同样,对于其他数量的连续棋子,根据block的情况赋予不同的分数。
这样,AI在评估时会优先形成活四、冲四等高威胁棋型,同时防守对方的类似棋型。
最后需AI会确保不会下在已经有棋子的位置,并且优先选择得分高的位置。
四、完整代码
import tkinter as tk
from tkinter import messagebox
class Gobang:
def __init__(self):
self.root = tk.Tk()
self.root.title("五子棋人机对战")
self.board_size = 25
self.cell_size = 28
self.offset = 30
self.win_size = self.offset * 2 + (self.board_size - 1) * self.cell_size
# 初始化游戏数据
self.chess_board = [[0] * self.board_size for _ in range(self.board_size)]
self.current_player = 1 # 1: 玩家(黑棋), 2: AI(白棋)
self.game_over = False
self.steps = 0
self.black_wins = 0
self.white_wins = 0
# 创建界面
self.create_widgets()
self.draw_board()
self.root.mainloop()
def create_widgets(self):
# 创建画布
self.canvas = tk.Canvas(self.root, width=self.win_size, height=self.win_size, bg="#CDBA96")
self.canvas.pack(padx=10, pady=10)
# 信息面板
info_frame = tk.Frame(self.root)
info_frame.pack(fill=tk.X, padx=10, pady=5)
self.step_label = tk.Label(info_frame, text=f"步数: {self.steps}")
self.step_label.pack(side=tk.LEFT)
self.score_label = tk.Label(info_frame,
text=f"黑方胜: {self.black_wins} 白方胜: {self.white_wins}")
self.score_label.pack(side=tk.RIGHT)
# 控制按钮
ctrl_frame = tk.Frame(self.root)
ctrl_frame.pack(padx=10, pady=5)
tk.Button(ctrl_frame, text="新游戏", command=self.new_game).pack()
# 绑定事件
self.canvas.bind("<Button-1>", self.human_play)
def draw_board(self):
"""绘制棋盘"""
for i in range(self.board_size):
x = self.offset + i * self.cell_size
self.canvas.create_line(x, self.offset,
x, self.win_size - self.offset)
self.canvas.create_line(self.offset, x,
self.win_size - self.offset, x)
def human_play(self, event):
"""玩家下棋"""
if self.game_over or self.current_player != 1:
return
# 计算落子位置(修正坐标计算)
x = (event.x - self.offset + self.cell_size // 2) // self.cell_size
y = (event.y - self.offset + self.cell_size // 2) // self.cell_size
if 0 <= x < self.board_size and 0 <= y < self.board_size:
if self.chess_board[y][x] == 0:
self.place_chess(y, x, 1)
if self.check_win(y, x, 1):
self.game_over = True
self.black_wins += 1
messagebox.showinfo("游戏结束", "黑方获胜!")
else:
self.current_player = 2
self.steps += 1
self.update_info()
self.root.after(200, self.ai_play)
def ai_play(self):
"""AI下棋"""
if self.game_over:
return
# 寻找最佳位置
best_score = -1
best_pos = None
for y in range(self.board_size):
for x in range(self.board_size):
if self.chess_board[y][x] == 0:
attack_score = self.evaluate_position(y, x, 2)
defend_score = self.evaluate_position(y, x, 1)
total_score = attack_score + defend_score * 1.2
if total_score > best_score or (total_score == best_score and best_pos is None):
best_score = total_score
best_pos = (y, x)
if best_pos:
y, x = best_pos
self.place_chess(y, x, 2)
if self.check_win(y, x, 2):
self.game_over = True
self.white_wins += 1
messagebox.showinfo("游戏结束", "白方获胜!")
else:
self.current_player = 1
self.steps += 1
self.update_info()
def evaluate_position(self, y, x, color):
"""评估位置得分"""
directions = [(0, 1), (1, 0), (1, 1), (1, -1)]
total_score = 0
for dy, dx in directions:
score = 0
consecutive = 1
blocks = 0
open_ends = 0
# 正方向检查
ny, nx = y + dy, x + dx
while 0 <= ny < self.board_size and 0 <= nx < self.board_size:
if self.chess_board[ny][nx] == color:
consecutive += 1
else:
if self.chess_board[ny][nx] == 0:
open_ends += 1
else:
blocks += 1
break
ny += dy
nx += dx
# 反方向检查
ny, nx = y - dy, x - dx
while 0 <= ny < self.board_size and 0 <= nx < self.board_size:
if self.chess_board[ny][nx] == color:
consecutive += 1
else:
if self.chess_board[ny][nx] == 0:
open_ends += 1
else:
blocks += 1
break
ny -= dy
nx -= dx
# 评分逻辑
if consecutive >= 5:
score += 100000
else:
if consecutive == 4:
if open_ends > 0:
score += 10000 if blocks == 0 else 1000
elif consecutive == 3:
if open_ends > 0:
score += 1000 if blocks == 0 else 200
elif consecutive == 2:
if open_ends > 0:
score += 200 if blocks == 0 else 50
elif consecutive == 1:
score += 10
if open_ends == 2 and consecutive >= 3:
score *= 2
total_score += score
return total_score
def place_chess(self, y, x, color):
"""在棋盘上放置棋子"""
self.chess_board[y][x] = color
cx = self.offset + x * self.cell_size
cy = self.offset + y * self.cell_size
self.canvas.create_oval(cx - 12, cy - 12, cx + 12, cy + 12,
fill="black" if color == 1 else "white",
outline="black")
def check_win(self, y, x, color):
"""检查是否获胜(完整实现)"""
directions = [(0, 1), (1, 0), (1, 1), (1, -1)]
for dy, dx in directions:
count = 1
# 向正方向检查
ny, nx = y + dy, x + dx
while 0 <= ny < self.board_size and 0 <= nx < self.board_size:
if self.chess_board[ny][nx] == color:
count += 1
ny += dy
nx += dx
else:
break
# 向反方向检查
ny, nx = y - dy, x - dx
while 0 <= ny < self.board_size and 0 <= nx < self.board_size:
if self.chess_board[ny][nx] == color:
count += 1
ny -= dy
nx -= dx
else:
break
if count >= 5:
return True
return False
def update_info(self):
"""更新信息显示"""
self.step_label.config(text=f"步数: {self.steps}")
self.score_label.config(text=f"黑方胜: {self.black_wins} 白方胜: {self.white_wins}")
def new_game(self):
"""开始新游戏"""
self.canvas.delete("all")
self.chess_board = [[0] * self.board_size for _ in range(self.board_size)]
self.current_player = 1
self.game_over = False
self.steps = 0
self.draw_board()
self.update_info()
if __name__ == "__main__":
Gobang()
五、结论——AI很强大
和AI打了几把,发现很难取胜,一不留神就输给他了,不信的话大家可以自己尝试挑战下!