猫史档案馆


【Python作品分享】五子棋

用户:空bF6B空bF6B查看:0 回复:2 评论:0 创建时间:2021-07-21T14:42:39


【作品展示】

center_image

 

【作品介绍】

和AI下棋

 

【作品源代码】

from graphics import *
import time
num = [[0 for a in range(16)] for a in range(16)]
dx = [1,1,0,-1,-1,-1,0,1]
dy = [0,1,1,1,0,-1,-1,-1]
is_end = False
go_first = 1
start = 1
ai = 1
L1_max=-100000
L2_min=100000
list=[]
RESTART_FLAG = False
QUIT_FLAG = False
win = GraphWin("五子棋",550,451)
aiFirst = Text(Point(500,100),"")
manFirst = Text(Point(500,140),"")
notice = Text(Point(500,290),"")
notice.setFill('red')
last_ai = Text(Point(500,330),"")
last_man = Text(Point(500,370),"")
QUIT = Text(Point(500,20),"退出")
QUIT.setFill('red')
RESTART = Text(Point(500,60),"重玩")
RESTART.setFill('red')
def init():
    global is_end,start,go_first,RESTART_FLAG
    is_end=False
    start=1
    go_first=1
    RESTART_FLAG=False
    QUIT_FLAG=False
    for i in range(16):
        for j in range(16):
            if(num[i][j]!=0):
                num[i][j]=0
    for i in range(len(list)):
        list[-1].undraw()
        list.pop(-1)
    aiFirst.setText("AI 先")
    manFirst.setText("我先")
    notice.setText("")
    last_ai.setText("")
    last_man.setText("")
def drawWin():
    win.setBackground('yellow')
    for i in range(0,451,30):
        line=Line(Point(i,0),Point(i,450))
        line.draw(win)
    for j in range(0,451,30):
        line=Line(Point(0,j),Point(450,j))
        line.draw(win)
    Rectangle(Point(460,5),Point(540,35)).draw(win)
    Rectangle(Point(460,45),Point(540,75)).draw(win)
    Rectangle(Point(460,85),Point(540,115)).draw(win)
    Rectangle(Point(460,125),Point(540,155)).draw(win)
    Rectangle(Point(452,275),Point(548,305)).draw(win)
    Rectangle(Point(452,307),Point(548,395)).draw(win)
    aiFirst.draw(win)
    manFirst.draw(win)
    notice.draw(win)
    last_ai.draw(win)
    last_man.draw(win)
    QUIT.draw(win)
    RESTART.draw(win)
def inBoard(x,y):
    if(x>=0 and x<=15 and y>=0 and y<=15): return True
    else: return False
def downOk(x,y):
    if(inBoard(x,y) and num[x][y]==0): return True
    else: return False
def sameColor(x,y,i):
    if(inBoard(x,y) and num[x][y]==i): return True
    else: return False
def numInline(x,y,v):
    i=x+dx[v]; j=y+dy[v]
    s=0; ref=num[x][y]
    if(ref==0): return 0
    while(sameColor(i,j,ref)):
        s=s+1; i=i+dx[v]; j=j+dy[v]
    return s
def liveFour(x,y):
    key=num[x][y]; s=0
    for u in range(4):
        samekey=1
        samekey,i=numofSamekey(x,y,u,1,key,samekey)
        if(not downOk(x+dx[u]*i,y+dy[u]*i)):
            continue
        samekey,i=numofSamekey(x,y,u,-1,key,samekey)
        if(not downOk(x+dx[u]*i,y+dy[u]*i)):
            continue
        if(samekey==4):
            s=s+1
    return s
def chongFour(x,y):
    key=num[x][y]; s=0
    for u in range(8):
        samekey=0; flag=True; i=1
        while(sameColor(x+dx[u]*i,y+dy[u]*i,key) or flag):
            if(not sameColor(x+dx[u]*i,y+dy[u]*i,key)):
                if(flag and inBoard(x+dx[u]*i,y+dy[u]*i) and num[x+dx[u]*i][y+dy[u]*i]!=0):
                    samekey-=10
                flag=False
            samekey+=1
            i+=1
        i-=1
        if(not inBoard(x+dx[u]*i,y+dy[u]*i)):
            continue
        samekey,i=numofSamekey(x,y,u,-1,key,samekey)
        if(samekey==4):
            s+=1
    return s-liveFour(x,y)*2
def liveThree(x,y):
    key=num[x][y]; s=0
    for u in range(4):
        samekey=1
        samekey,i=numofSamekey(x,y,u,1,key,samekey)
        if(not downOk(x+dx[u]*i,y+dy[u]*i)):
            continue
        if(not downOk(x+dx[u]*(i+1),y+dy[u]*(i+1))):
            continue
        samekey,i=numofSamekey(x,y,u,-1,key,samekey)
        if(not downOk(x+dx[u]*i,y+dy[u]*i)):
            continue
        if(not downOk(x+dx[u]*(i-1),y+dy[u]*(i-1))):
            continue
        if(samekey==3):
            s+=1
    for u in range(8):
        samekey=0; flag=True; i=1
        while(sameColor(x+dx[u]*i,y+dy[u]*i,key) or flag):
            if(not sameColor(x+dx[u]*i,y+dy[u]*i,key)):
                if(flag and inBoard(x+dx[u]*i,y+dy[u]*i) and num[x+dx[u]*i][y+dy[u]*i]!=0):
                    samekey-=10
                flag=False
            samekey+=1
            i+=1
        if(not downOk(x+dx[u]*i,y+dy[u]*i)):
            continue
        if(inBoard(x+dx[u]*(i-1),y+dy[u]*(i-1)) and num[x+dx[u]*(i-1)][y+dy[u]*(i-1)]==0):
            continue
        samekey,i=numofSamekey(x,y,u,-1,key,samekey)
        if(not downOk(x+dx[u]*i,y+dy[u]*i)):
            continue
        if(samekey==3):
            s+=1
    return s
def overLine(x,y):
    flag=False
    for u in range(4):
        if((numInline(x,y,u)+numInline(x,y,u+4))>4):
            flag=True
    return flag
def ban(x,y):
    if(sameColor(x,y,3-go_first)):
        return False
    flag=((liveThree(x,y)>1) or (overLine(x,y)) or ((liveFour(x,y)+chongFour(x,y))>1))
    return flag
def numofSamekey(x,y,u,i,key,sk):
    if(i==1):
        while(sameColor(x+dx[u]*i,y+dy[u]*i,key)):
            sk+=1
            i+=1
    elif(i==-1):
        while(sameColor(x+dx[u]*i,y+dy[u]*i,key)):
            sk+=1
            i-=1
    return sk,i
def gameOver(x,y):
    global is_end
    for u in range(4):
        if((numInline(x,y,u)+numInline(x,y,u+4))>=4):
            is_end=True
            return True
    return False
def getScore(x,y):
    global is_end
    if(ban(x,y)):
        return 0
    if(gameOver(x,y)):
        is_end=False
        return 10000
    score=liveFour(x,y)*1000+(chongFour(x,y)+liveThree(x,y))*100
    for u in range(8):
        if(inBoard(x+dx[u],y+dy[u]) and num[x+dx[u]][y+dy[u]]!=0):
            score=score+1
    return score
def AI1():
    global L1_max
    L1_max=-100000
    if(num[8][8]==0 and go_first==ai):
        return go(8,8)
    keyi=-1; keyj=-1
    for x in [8,7,9,6,10,5,11,4,12,3,13,2,14,1,15,0]:
        for y in [8,7,9,6,10,5,11,4,12,3,13,2,14,1,15,0]:
            if(not downOk(x,y)):
                continue
            num[x][y]=ai
            tempp=getScore(x,y)
            if(tempp==0):
                num[x][y]=0; continue
            if(tempp==10000):
                return go(x,y)
            tempp=AI2()
            num[x][y]=0
            if(tempp>L1_max):
                L1_max=tempp; keyi=x; keyj=y
    go(keyi,keyj)
def AI2():
    global L2_min
    L2_min=100000
    for x in [8,7,9,6,10,5,11,4,12,3,13,2,14,1,15,0]:
        for y in [8,7,9,6,10,5,11,4,12,3,13,2,14,1,15,0]:
            if(not downOk(x,y)):
                continue
            num[x][y]=3-ai
            tempp=getScore(x,y)
            if(tempp==0):
                num[x][y]=0; continue
            if(tempp==10000):
                num[x][y]=0; return -10000
            tempp=AI3(tempp)
            if(temppL2_min):
                num[x][y]=0; return 10000
            num[x][y]=0
            if(tempp-p2*2>keyp):
                keyp=tempp-p2*2
    return keyp
def manPlay():
    p=win.getMouse()
    if(Restart(p) or Quit(p)): return
    x=round(p.getX()/30)
    y=round(p.getY()/30)
    if(downOk(x,y)): go(x,y)
    else: manPlay()
def go(x,y):
    global is_end
    c=Circle(Point(x*30,y*30),13)
    if(start==ai):
        num[x][y]=ai
        last_ai.setText("AI 落子:\n(x:y)=("+str(x)+":"+str(y)+")")
        if(go_first==ai): c.setFill('black')
        else: c.setFill('white')
    else:
        num[x][y]=3-ai
        last_man.setText("玩家落子:\n(x:y)=("+str(x)+":"+str(y)+")")
        if(go_first==ai): c.setFill('white')
        else: c.setFill('black')
    c.draw(win)
    list.append(c)
    if(ban(x,y)):
        if(start==ai):
            notice.setText("AI 禁手,玩家赢!\n点击重玩")
        else:
            notice.setText("玩家禁手,AI 赢!\n点击重玩")
        is_end=True
    elif(gameOver(x,y)):
        if(start==ai):
            notice.setText("AI 赢!\n点击重玩")
        else:
            notice.setText("玩家赢!\n点击重玩")
def Restart(p):
    global RESTART_FLAG
    x=p.getX(); y=p.getY()
    if((abs(500-x)<40) and (abs(60-y)<15)):
        init()
        RESTART_FLAG=True
        notice.setText("重新开始")
        time.sleep(1)
        return True
    else:
        return False
def Quit(p):
    global QUIT_FLAG, is_end
    x=p.getX(); y=p.getY()
    if((abs(500-x)<40) and (abs(20-y)<15)):
        init()
        QUIT_FLAG=True
        is_end=True
        notice.setText("退出")
        time.sleep(1)
        return True
    else:
        return False
def whoStart(p):
    global start, go_first
    x=p.getX(); y=p.getY()
    if((abs(500-x)<40) and (abs(100-y)<15)):
        start=1
        go_first=1
        aiFirst.setText("AI 执黑")
        manFirst.setText("玩家执白")
        return True
    elif((abs(500-x)<40) and (abs(140-y)<15)):
        start=2
        go_first=2
        aiFirst.setText("AI 执白")
        manFirst.setText("玩家执黑")
        return True
    else:
        return False
if __name__ == '__main__':
    init()
    drawWin()
    notice.setText("请选择先后")
    p=win.getMouse()
    while(not whoStart(p) and not Quit(p)):
        p=win.getMouse()
    while(not is_end):
        RESTART_FLAG=False
        if(start==ai):
            notice.setText("AI 正在下棋...")
            AI1()
        else:
            notice.setText("请你下棋...")
            manPlay()
        start=3-start
        if(RESTART_FLAG):
            notice.setText("请选择先后")
            p=win.getMouse()
            while(not whoStart(p) and not Quit(p)):
                p=win.getMouse()
        elif(not QUIT_FLAG and is_end):
            p=win.getMouse()
            while(not Restart(p) and not Quit(p)):
                p=win.getMouse()
            if(RESTART_FLAG):
                notice.setText("请选择先后")
                p=win.getMouse()
                while(not whoStart(p) and not Quit(p)):
                    p=win.getMouse()

 

【提示】

部分含有Python第三方库相关内容的作品,在海龟编辑器网页端无法运行哦!如遇到这种情况,可以打开下面的链接,下载海龟编辑器客户端:

https://python.codemao.cn


回复

上一页1 页 / 共 1下一页
KIHIOKIHIO

没法运行

点赞0


评论


Python-happyyyyPython-happyyyy

请问AI3是什么?你好像没有定义AI3

点赞0


评论