五子棋 Python實現


設計思路

​ 使用Python中的turtle庫實現棋盤棋子的控制。

​ 程序功能:游戲雙方輪流使用鼠標進行落子,並自動判定勝負

畫布的初始化

1.棋盤尺寸

​ 查閱資料可知,標准五子棋棋盤大小為15格*15格

​ 考慮電腦屏幕大小,取棋盤大小為420*420

2.區分棋盤與非棋盤區域

​ 用灰色填充棋盤區域

color('grey')
begin_fill()
penup()
goto(-210,-210)
pendown()
goto(-210,210)
goto(210,210)
goto(210,-210)
goto(-210,-210)
end_fill()

3.畫線

color('black')
for i in range(-210,211,30):
    penup()
    goto(i,-550)
    pendown()
    goto(i,550)
for i in range(-210,211,30):
    penup()
    goto(-550,i)
    pendown()
    goto(550,i)

吸附功能

此處使用了奇怪的實現方式,不建議學習。代碼如下:

for i in range(1,16):
    for j in range(1,16):
        for x in range(-240+30*i-15,-240+30*i+15):
            for y in range(240-30*j-15,240-30*j+15):
                P[(x,y)]=(i,j)

P是從屏幕上點的坐標到棋盤上的行、列數的映射

雙方輪流落子功能

用一個 bool變量表示 [當前是白方回合]

def play(x,y):
    global t
    t=not t

每次調用play函數都交換落子權

    if t:
        color('white')
        draw(p[0],p[1])
        m[p]=-1
    else:
        color('black')
        draw(p[0],p[1])
        m[p]=1

不合法落子的處理

情況一 在棋盤外落子

if (x,y) not in P:
    t=not t
    return

情況二 在已落子處落子

p=P[(x,y)]
if m[p]!=0:
	t=not t
	return

其中m的含義在交換落子權處可以看出。
m[p]=1表示p點有黑棋,m[p]=-1表示有白棋,m[p]=0表示沒有棋子

判斷勝負

def game_end(x,y):
    global Gmov
    for i in tw:
        tot[i]=0
        xn=x+i[0]
        yn=y+i[1]
        while (xn in range(1,16)) and (yn in range(1,16)) and m[(xn,yn)]==m[(x,y)]:
            tot[i]=tot[i]+1
            xn=xn+i[0]
            yn=yn+i[1]
    for i in range(4):
        if tot[tw[i]]+tot[tw[7-i]]+1 >= 5:
            begin_fill()
            penup()
            goto(-210,-210)
            pendown()
            goto(-210,210)
            goto(210,210)
            goto(210,-210)
            goto(-210,-210)
            end_fill()
            print("game over")
            Gmov=True
            return

如上,在每次落子后向周圍8個方向搜索連續的相同顏色的棋子的個數。

總代碼

from turtle import *
ht()
speed(0)
rt(90)
Gmov=False
# 15*15
def drawnet():
    # too slow?
    # use:
    # tracer(False)
    color('grey')
    begin_fill()
    penup()
    goto(-210,-210)
    pendown()
    goto(-210,210)
    goto(210,210)
    goto(210,-210)
    goto(-210,-210)
    end_fill()
    color('black')
    for i in range(-210,211,30):
        penup()
        goto(i,-550)
        pendown()
        goto(i,550)
    for i in range(-210,211,30):
        penup()
        goto(-550,i)
        pendown()
        goto(550,i)
        
t=True
m={}
P={}
for i in range(1,16):
    for j in range(1,16):
        for x in range(-240+30*i-15,-240+30*i+15):
            for y in range(240-30*j-15,240-30*j+15):
                P[(x,y)]=(i,j)
        m[(i,j)]=0

tw=[(-1,-1),(-1,0),(-1,1),(0,-1),(0,1),(1,-1),(1,0),(1,1)]
tot={}

def game_end(x,y):
    global Gmov
    for i in tw:
        tot[i]=0
        xn=x+i[0]
        yn=y+i[1]
        while (xn in range(1,16)) and (yn in range(1,16)) and m[(xn,yn)]==m[(x,y)]:
            tot[i]=tot[i]+1
            xn=xn+i[0]
            yn=yn+i[1]
    for i in range(4):
        if tot[tw[i]]+tot[tw[7-i]]+1 >= 5:
            begin_fill()
            penup()
            goto(-210,-210)
            pendown()
            goto(-210,210)
            goto(210,210)
            goto(210,-210)
            goto(-210,-210)
            end_fill()
            print("game over")
            Gmov=True
            return

def draw(i,j):
    x=-240+30*i
    y=240-30*j
    penup()
    goto(x-5,y)
    pendown()
    begin_fill()
    circle(5)
    end_fill()

def play(x,y):
    if(Gmov):
        return
    global t
    t=not t
    if (x,y) not in P:
        t=not t
        return
    p=P[(x,y)]
    if m[p]!=0:
        t=not t
        return
    if t:
        color('white')
        draw(p[0],p[1])
        m[p]=-1
    else:
        color('black')
        draw(p[0],p[1])
        m[p]=1
    game_end(p[0],p[1])
        
def undo(x,y):
    print("Sorry,not supported yet.")

setup(550,550)
drawnet()
onscreenclick(play,1,None)
onscreenclick(undo,3,None)
done()


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM