井字棋ai对弈版0.1

这是一个ai对弈的程序,可以进行调参后的两组学生比赛

#这是一个ai对弈的井字棋
#导入模块

import tkinter as tk
from tkinter import messagebox
import random
#创建tk对象 
window = tk.Tk()
window.title("井字棋")


#井字棋布局

label1=tk.Label(window,text="井字棋AI世界杯", font=("Arial", 20), height=2, width=6)
label1.grid(row=0, column=1,sticky="nsew")

button=[None] * 10
button[0] = tk.Button(window, text="", font=("Arial", 40), height=2, width=6, bg="lightblue")
button[0].grid(row=1, column=0,sticky="nsew")
button[1] = tk.Button(window, text="", font=("Arial", 40), height=2, width=6, bg="lightblue")
button[1].grid(row=1, column=1,sticky="nsew")
button[2] = tk.Button(window, text="", font=("Arial", 40), height=2, width=6, bg="lightblue")
button[2].grid(row=1, column=2,sticky="nsew")
button[3] = tk.Button(window, text="", font=("Arial", 40), height=2, width=6, bg="lightblue")
button[3].grid(row=2, column=0,sticky="nsew")
button[4] = tk.Button(window, text="", font=("Arial", 40), height=2, width=6, bg="lightblue")
button[4].grid(row=2, column=1,sticky="nsew")
button[5] = tk.Button(window, text="", font=("Arial", 40), height=2, width=6, bg="lightblue")
button[5].grid(row=2, column=2,sticky="nsew")
button[6] = tk.Button(window, text="", font=("Arial", 40), height=2, width=6, bg="lightblue")
button[6].grid(row=3, column=0,sticky="nsew")
button[7] = tk.Button(window, text="", font=("Arial", 40), height=2, width=6, bg="lightblue")
button[7].grid(row=3, column=1,sticky="nsew")
button[8] = tk.Button(window, text="", font=("Arial", 40), height=2, width=6, bg="lightblue")
button[8].grid(row=3, column=2,sticky="nsew")
button[8] = tk.Button(window, text="比赛开始", font=("Arial", 30), height=2, width=6, bg="lightblue",command=lambda:handle_click())
button[8].grid(row=4, column=1,sticky="nsew")

#给井字棋赋初值
q=[0,0,0,0,0,0,0,0,0]
current_player = 1



#定义单击按钮函数
def handle_click():
    global current_player
    i=first(q)
    #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#交换玩家
          
            
        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#交换玩家
               
  #判断是否平局
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_n(q)
            Gj[v]=g
            q[v]=t
        
        v=v+1
 
    j=find_min_index(Gj)
    return j
def first(q):
    
    v=0
    Gjh=[-10,-10,-10,-10,-10,-10,-10,-10,-10]
    
    while v<9:
        t=q[v]
        if t==0:
            q[v]=1
            h=sorce_h(q)
            Gjh[v]=h
            q[v]=t
        
        v=v+1
 
    i=find_max_index(Gjh)
    return i    
#返回最大值的位置函数
def find_min_index(lst):
    return lst.index(min(lst))

def find_max_index(lst):
    return lst.index(max(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_n(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]*1+x[2]*1+x[1]*1-(o[3]*1+o[2]*1+o[1]*1)
    return g
def sorce_h(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
   
    h=x[3]*3+x[2]*3+x[1]*3-(o[3]*1+o[2]*1+o[1]*1)
    return h
window.mainloop() 

  • 3
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值