python实现五子棋对弈,Python五子棋游戏大作业
本文主要详细介绍了基于Python的五子棋游戏的实现。本文中的示例代码非常详细,具有一定的参考价值。感兴趣的朋友可以参考一下。
本文分享用Python实现五子棋游戏的具体代码,供大家参考。具体如下。
了解游戏规则是我们需要做的第一件事。如果我们不知道规则,那我们哪儿也去不了。
五子棋游戏规则:
1.游戏的每一方都有自己的棋子。
2.从一个空棋盘开始。
3.先黑后白,交替下一个孩子,一次只生一个孩子。
4.棋子在棋盘的空白处。棋子拼成后,不得移动到其他点,也不得从棋盘上取下或捡起丢到别处。
5.黑方的第一个棋子可以放在棋盘的任意交叉点上。
6.轮流是双方的权利,但允许任何一方放弃走下一步的权利(即通过权)。
五子棋游戏,实行黑方指定开局,三手可以互换,五手两打的规则。整个游戏过程中,黑方有禁手,白方没有禁手。黑禁手分三种:三三禁手,四四禁手,长伴禁手。
在这个博客里,我们只执行了比较简单的规则,不考虑规则6和禁手的相关规定(个人能力有限,如果有愿意学习的朋友,可以一起学习/加油)。
设计思路:
1.首先,我们需要使用界面。首先我们需要分析界面上需要实现什么画面,也就是我们玩这个五子棋游戏想看到什么。要看:棋盘,棋子(棋子要分颜色,黑白),这些都是玩游戏必备的。
2.外观做好之后,我们需要思考内部代码的填充,思考:
棋子如何落到指定位置,
(2)如何实现棋子的交替摆放,实现颜色的交替变化,并做好记录,方便棋子排列的计算。
如何计算四个方向相同颜色的棋子的赢数?
首先,调用窗口并实现代码:
从tkinter导入*#导入窗口第三方库
Root=Tk() #创建一个窗口
Root.title(韩寒下的五子棋)#窗口名称
W1=canvas (root,width=600,height=600,background= lightcyan) #在窗口中央创建一个画布。根是宽度600,高度600的窗口,背景颜色是淡青色。
W1.pack() #布局,需要全球统一。
主循环()
五子棋棋盘由15条横线和15条竖线组成。
画一个棋盘:
对于范围(0,15):内的I
w1.create_line(i * 40 20,20,i * 40 20,580)
w1.create_line(20,i * 40 20,580,i * 40 20)
w1.create_oval(135,135,145,145,fill=black )
w1.create_oval(135,455,145,465,fill=black )
w1.create_oval(465,135,455,145,fill=black )
w1.create_oval(455,455,465,465,fill=black )
w1.create_oval(295,295,305,305,fill=black )
窗口左上角的坐标是(0,0)。经过调试,我们得出起始位置为(20,20)。经过多次调试比较,我选择40的行距作为较好的选择。当然,线宽,圆的大小,棋盘线的间距都是可以调整的。可以慢慢测试(h_h)。棋盘上的五个黑点需要我们计算它们的位置。
Create_line:画一条直线。
Create _ oval (x1,y1,x2,y2,fill= color )这是画一个内切圆。矩形的左上角(x1,y1)和右下角(x2,y2)是填充颜色。我们可以在网上找龟色库,顺便帮你找一个,选你喜欢的颜色。
效果图:
棋盘做好了,我们就开始设计棋子。这里我们需要交替改变颜色,所以我们需要通过一个判断方法来改变棋子的颜色。我想到两种:一种是在当前鼠标上用字符标注棋子颜色,换成另一种。另一种是通过计数来改变。另外,我们还要规定不能在已经放了棋子的位置再放棋子,也就是要判断当前位置是否还有棋子,才能移动。
Num=0 #数一数棋盘上有多少颗棋子,判断下一颗棋子的颜色。
A=np.full((15,15),0) # store
位置已有棋子的矩阵
B=np.full((15,15),) #用来记录每个位置棋子的颜色
def callback(event): #输入的是点击事件,event.x和event.y是鼠标点击事件的位置
global num ,A #全局变量可以全局使用
for j in range (0,15): #双重循环定位点击位置最近的网格线交点(i,j),保证棋子落在线的交点处。
for i in range (0,15):
if (event.x - 20 - 40 * i) ** 2 + (event.y - 20 - 40 * j) ** 2 <= 2 * 20 ** 2:
break
if (event.x - 20 - 40 * i) ** 2 + (event.y - 20 - 40 * j) ** 2 <= 2*20 ** 2:
break
if num % 2 == 0 and A[i][j] != 1:#判断现在这颗棋子的颜色。
w1.create_oval(40*i+5, 40*j+5, 40*i+35, 40*j+35,fill=black)
A[i][j] = 1
B[i][j] = b
num += 1
if num % 2 != 0 and A[i][j] != 1 :
w1.create_oval(40*i+5, 40*j+5, 40*i+35, 40*j+35,fill=white)
A[i][j] = 1
B[i][j] = w
num += 1
落子以后需要计算是否五子连珠,每个棋子的计算方向有八个形成四条线,那么就是从落子处算先向一端算,直到遇到另一种颜色的棋子,反向查询遇到另一个颜色棋处出停止,当达到五颗棋子时即代表一方获胜,否则循环下一条线。当四条线结束未达到胜利条件,即可继续落子。
f = [[-1, 0], [-1, 1], [0, 1], [1, 1]] #四条线其中一个方向的坐标变化规律for z in range(0, 4): #循环方向
a, b = f[z][0], f[z][1]
count1, count2 = 0, 0
x, y = i, j
while B[x][y] == B[i][j]:#当颜色相同即可进行计算
count1 += 1
if x + a > 0 and y + b > 0 and x + a < 15 and y + b < 15 and B[x + a][y + b] == B[i][j]:#保证不超出矩阵的边界,否则会报错
[x, y] = np.array([x, y]) + np.array([a, b])
else:
x, y = i, j
break
while B[x][y] == B[i][j]:#从落子处反向计算同色棋子个数。
count2 += 1
if x - a < 15 and y - b < 15 and x - a > 0 and y - b > 0 and B[x - a][y - b] == B[i][j]:
[x, y] = np.array([x, y]) - np.array([a, b])
else:
break
if count1 + count2 == 6: #计算了两次落子处
if B[i][j] == b:
tkinter.messagebox.showinfo(提示, 黑棋获胜)
else:
tkinter.messagebox.showinfo(提示, 白棋获胜)
点击事件,每次点击以后都需要进行一次落子和游戏结束判断。调用函数进行落子,判断是否结束游戏。
w1.bind("<Button -1>",callback)w1.pack()
设置退出按钮:
u=Button(root,text="退出",width=10,height=1,command=quit,font=(楷体,15))u.pack()
完整代码:
from tkinter import *import tkinter.messagebox # 弹窗库
import numpy as np
root = Tk() #创建窗口
root.title("憨憨制作的五子棋") #窗口名字
w1 = Canvas(root, width=600,height=600,background=lightcyan)
w1.pack()
for i in range(0, 15):
w1.create_line(i * 40 + 20, 20, i * 40 + 20, 580)
w1.create_line(20, i * 40 + 20, 580, i * 40 + 20)
w1.create_oval(135, 135, 145, 145,fill=black)
w1.create_oval(135, 455, 145, 465,fill=black)
w1.create_oval(465, 135, 455, 145,fill=black)
w1.create_oval(455, 455, 465, 465,fill=black)
w1.create_oval(295, 295, 305, 305,fill=black)
num=0
A=np.full((15,15),0)
B=np.full((15,15),)
def callback(event):
global num ,A
for j in range (0,15):
for i in range (0,15):
if (event.x - 20 - 40 * i) ** 2 + (event.y - 20 - 40 * j) ** 2 <= 2 * 20 ** 2:
break
if (event.x - 20 - 40 * i) ** 2 + (event.y - 20 - 40 * j) ** 2 <= 2*20 ** 2:
break
if num % 2 == 0 and A[i][j] != 1:
w1.create_oval(40*i+5, 40*j+5, 40*i+35, 40*j+35,fill=black)
A[i][j] = 1
B[i][j] = b
num += 1
if num % 2 != 0 and A[i][j] != 1 :
w1.create_oval(40*i+5, 40*j+5, 40*i+35, 40*j+35,fill=white)
A[i][j] = 1.
B[i][j] = w
num += 1
f = [[-1, 0], [-1, 1], [0, 1], [1, 1]]
for z in range(0, 4):
a, b = f[z][0], f[z][1]
count1, count2 = 0, 0
x, y = i, j
while B[x][y] == B[i][j]:
count1 += 1
if x + a > 0 and y + b > 0 and x + a < 15 and y + b < 15 and B[x + a][y + b] == B[i][j]:
[x, y] = np.array([x, y]) + np.array([a, b])
else:
x, y = i, j
break
while B[x][y] == B[i][j]:
count2 += 1
if x - a < 15 and y - b < 15 and x - a > 0 and y - b > 0 and B[x - a][y - b] == B[i][j]:
[x, y] = np.array([x, y]) - np.array([a, b])
else:
break
if count1 + count2 == 6:
if B[i][j] == b:
tkinter.messagebox.showinfo(提示, 黑棋获胜)
else:
tkinter.messagebox.showinfo(提示, 白棋获胜)
w1.bind("<Button -1>",callback)
w1.pack()
def quit():
root.quit()
u=Button(root,text="退出",width=10,height=1,command=quit,font=(楷体,15))
u.pack()
mainloop()
技术不精,但是喜欢做点小研究,从学习中找到玩耍的快乐,愿意和大家一起学习玩耍。
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持盛行IT软件开发工作室。
郑重声明:本文由网友发布,不代表盛行IT的观点,版权归原作者所有,仅为传播更多信息之目的,如有侵权请联系,我们将第一时间修改或删除,多谢。