五子棋 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()

作者:_Veritas
欢迎任何形式的转载,但请务必注明出处。
限于本人水平,如果文章和代码有表述不当之处,还请不吝赐教。

posted @   _Veritas  阅读(3247)  评论(4编辑  收藏  举报
编辑推荐:
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
阅读排行:
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 单元测试从入门到精通
· 上周热点回顾(3.3-3.9)
· Vue3状态管理终极指南:Pinia保姆级教程
点击右上角即可分享
微信分享提示