五⼦棋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=Truem={}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 returndef 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()