这是一个可以调参的井字棋AI,思路参考了清华附中徐岩老师的想法,在此表示感谢
#这是一个人对人的井字棋
#导入模块
import tkinter as tk
from tkinter import messagebox
import random
#创建tk对象
window = tk.Tk()
window.title("井字棋")
result_text = tk.StringVar()
#井字棋布局
label1=tk.Label(window,text="现在该Player",textvariable=result_text, font=("Arial", 20), height=2, width=6)
label1.grid(row=0, column=1,sticky="nsew")
button=[None] * 9
button[0] = tk.Button(window, text="", font=("Arial", 50), height=2, width=6, bg="lightblue",command=lambda:handle_click(0))
button[0].grid(row=1, column=0,sticky="nsew")
button[1] = tk.Button(window, text="", font=("Arial", 50), height=2, width=6, bg="lightblue",command=lambda:handle_click(1))
button[1].grid(row=1, column=1,sticky="nsew")
button[2] = tk.Button(window, text="", font=("Arial", 50), height=2, width=6, bg="lightblue",command=lambda:handle_click(2))
button[2].grid(row=1, column=2,sticky="nsew")
button[3] = tk.Button(window, text="", font=("Arial", 50), height=2, width=6, bg="lightblue",command=lambda:handle_click(3))
button[3].grid(row=2, column=0,sticky="nsew")
button[4] = tk.Button(window, text="", font=("Arial", 50), height=2, width=6, bg="lightblue",command=lambda:handle_click(4))
button[4].grid(row=2, column=1,sticky="nsew")
button[5] = tk.Button(window, text="", font=("Arial", 50), height=2, width=6, bg="lightblue",command=lambda:handle_click(5))
button[5].grid(row=2, column=2,sticky="nsew")
button[6] = tk.Button(window, text="", font=("Arial", 50), height=2, width=6, bg="lightblue",command=lambda:handle_click(6))
button[6].grid(row=3, column=0,sticky="nsew")
button[7] = tk.Button(window, text="", font=("Arial", 50), height=2, width=6, bg="lightblue",command=lambda:handle_click(7))
button[7].grid(row=3, column=1,sticky="nsew")
button[8] = tk.Button(window, text="", font=("Arial", 50), height=2, width=6, bg="lightblue",command=lambda:handle_click(8))
button[8].grid(row=3, column=2,sticky="nsew")
#定义一个提示走棋框
def start():
text="请player"+str(current_player)+"下棋"
result_text.set(text)
#给井字棋赋初值
q=[0,0,0,0,0,0,0,0,0]
current_player = 1
start()
#定义单击按钮函数
def handle_click(i):
global current_player
#q[i]标记1或-1,button[i]标记为X或O
if q[i]==0 :#q[i]==0,说明q[i]这个地方还没有放棋子
if current_player == 1:
q[i] = 1
button[i].config(text="X")
#调用判胜函数
Iswin,W1,W2,W3=is_win(q)
#如果胜利,弹出胜利框
if Iswin==True:
messagebox.showwarning(title="消息警告", message=f"玩家{current_player} 获胜!")
window.destroy()
#如果是平局,弹出平局消息框
elif Iswin=='Tie':
messagebox.showwarning(title="消息警告", message="平局")
window.destroy()
else:
current_player = 2#交换玩家
#提示player走棋
start()
if current_player == 2:
#让电脑自己下棋
j=next(q)
q[j] = -1
button[j].config(text="O")
Iswin,W1,W2,W3=is_win(q)
if Iswin==True :
messagebox.showwarning(title="消息警告", message=f"玩家{current_player} 获胜!")
window.destroy()
#如果是平局,弹出平局消息框
elif Iswin=='Tie':
messagebox.showwarning(title="消息警告", message="平局")
window.destroy()
else:
current_player = 1#交换玩家
#提示player走棋
start()
#判断是否平局
def is_full(q):
if q[0]==0:
return False
elif q[1]==0:
return False
elif q[2]==0:
return False
elif q[3]==0:
return False
elif q[4]==0:
return False
elif q[5]==0:
return False
elif q[6]==0:
return False
elif q[7]==0:
return False
elif q[8]==0:
return False
else:
return True
#判断是否是胜利局面
def is_win(q):
if q[0]==q[1]==q[2]!=0:#如果 q[0]===q[1]==q[2],且不等于0,说明三子连珠
iswin,w1,w2,w3=True,0,1,2#iswin==True 说明三子连珠
elif q[3]==q[4]==q[5]!=0:
iswin,w1,w2,w3=True,3,4,5
elif q[6]==q[7]==q[8]!=0:
iswin,w1,w2,w3=True,6,7,8
elif q[0]==q[3]==q[6]!=0:
iswin,w1,w2,w3=True,0,3,6
elif q[1]==q[4]==q[7]!=0:
iswin,w1,w2,w3=True,1,4,7
elif q[2]==q[5]==q[8]!=0:
iswin,w1,w2,w3=True,2,5,8
elif q[0]==q[4]==q[8]!=0:
iswin,w1,w2,w3=True,0,4,8
elif q[2]==q[4]==q[6]!=0:
iswin,w1,w2,w3=True,2,4,6
elif is_full(q):#平局
iswin,w1,w2,w3="Tie",-1,-1,-1
else:
iswin,w1,w2,w3=False,-1,-1,-1#还没出现三子连珠
return iswin,w1,w2,w3
def next(q):
v=0
Gj=[10,10,10,10,10,10,10,10,10]
while v<9:
t=q[v]
if t==0:
q[v]=-1
g=sorce(q)
Gj[v]=g
q[v]=t
v=v+1
j=find_min_index(Gj)
return j
#返回最大值的位置函数
def find_min_index(lst):
return lst.index(min(lst))
def s(i,j,k,q,x,o):
#统计X棋手的局面
if q[i]+q[j]+q[k]==3:#说明三个位置都是1,即X
x[3]=x[3]+1
if q[i]+q[j]+q[k]==2:#说明三个位置有两个位置是1,另一个为空
x[2]=x[2]+1
if q[i]+q[j]+q[k]==1 and q[i]*q[j]*q[k]==0:#说明说明三个位置有一个位置是1,另外两个是空
x[1]=x[1]+1
#统计O棋手的局面
if q[i]+q[j]+q[k]==-3:#说明三个位置都是-1,即O
o[3]=o[3]+1
if q[i]+q[j]+q[k]==-2:#说明三个位置有两个位置是-1,另一个为空
o[2]=o[2]+1
if q[i]+q[j]+q[k]==-1 and q[i]*q[j]*q[k]==0:#说明说明三个位置有一个位置是-1,另外两个是空
o[1]=o[1]+1
return x,o
def sorce(q):
x=[0,0,0,0]
o=[0,0,0,0]
s(0,1,2,q,x,o)# 统计第一行
s(3,4,5,q,x,o)#统计第二行
s(6,7,8,q,x,o) #统计第三行
s(0,3,6,q,x,o)#统计第1列
s(1,4,7,q,x,o)#统计第2列
s(2,5,8,q,x,o)#统计第3列
s(0,4,8,q,x,o)#统计交叉1
s(2,4,6,q,x,o)#统计交叉2
g=x[3]*0.1+x[2]*3+x[1]*1-(o[3]*1+o[2]*1+o[1]*1)
return g
window.mainloop()