python实现单机五子棋


Posted in Python onAugust 28, 2020

简介

这是实验室2018年底招新时的考核题目,使用Python编写一个能够完成基本对战的五子棋游戏。面向新手。

程序主要包括两个部分,图形创建与逻辑编写两部分。

程序的运行结果:

python实现单机五子棋

样式创建

老规矩,先把用到的包导入进来。

'''
@Auther : gaoxin
@Date : 2019.01.01
@Version : 1.0
'''

from tkinter import *
import math

然后建立一个样式的类,类名称chessBoard。这里加了很多注释,避免新手看不懂函数的作用,说实话我觉得挺别扭的。

#定义棋盘类
class chessBoard() :
 def __init__(self) :
  #创建一个tk对象,即窗口
  self.window = Tk()
  #窗口命名
  self.window.title("五子棋游戏")
  #定义窗口大小
  self.window.geometry("660x470")
  #定义窗口不可放缩
  self.window.resizable(0,0)
  #定义窗口里的画布
  self.canvas=Canvas(self.window , bg="#EEE8AC" , width=470, height=470)
  #画出画布内容
  self.paint_board()
  #定义画布所在的网格
  self.canvas.grid(row = 0 , column = 0)

 def paint_board(self) :
  #画横线
  for row in range(0,15) :
   if row == 0 or row == 14 :
    self.canvas.create_line(25 , 25+row*30 , 25+14*30 , 25+row*30 , width = 2)
   else :
    self.canvas.create_line(25 , 25+row*30 , 25+14*30 , 25+row*30 , width = 1)
  
  #画竖线
  for column in range(0,15) :
   if column == 0 or column == 14 :
    self.canvas.create_line(25+column*30 ,25, 25+column*30 , 25+14*30 ,width = 2)
   else :
    self.canvas.create_line(25+column*30 ,25, 25+column*30 , 25+14*30 , width = 1)
  
  #画圆
  self.canvas.create_oval(112, 112, 118, 118, fill="black")
  self.canvas.create_oval(352, 112, 358, 118, fill="black")
  self.canvas.create_oval(112, 352, 118, 358, fill="black")
  self.canvas.create_oval(232, 232, 238, 238, fill="black")
  self.canvas.create_oval(352, 352, 358, 358, fill="black")

逻辑编写

这里的主要看每个函数的功能就好了。

#定义五子棋游戏类
#0为黑子 , 1为白子 , 2为空位
class Gobang() :
 #初始化
 def __init__(self) :
  self.board = chessBoard()
  self.game_print = StringVar()
  self.game_print.set("")
  #16*16的二维列表,保证不会out of index
  self.db = [([2] * 16) for i in range(16)]
  #悔棋用的顺序列表
  self.order = []
  #棋子颜色
  self.color_count = 0 
  self.color = 'black'
  #清空与赢的初始化,已赢为1,已清空为1
  self.flag_win = 1
  self.flag_empty = 1
  self.options()
  
  
 #黑白互换
 def change_color(self) :
  self.color_count = (self.color_count + 1 ) % 2
  if self.color_count == 0 :
   self.color = "black"
  elif self.color_count ==1 :
   self.color = "white"
 
 
 #落子
 def chess_moving(self ,event) :
  #不点击“开始”与“清空”无法再次开始落子
  if self.flag_win ==1 or self.flag_empty ==0 :
   return
  #坐标转化为下标
  x,y = event.x-25 , event.y-25
  x = round(x/30)
  y = round(y/30)
  #点击位置没用落子,且没有在棋盘线外,可以落子
  while self.db[y][x] == 2 and self.limit_boarder(y,x):
   self.db[y][x] = self.color_count
   self.order.append(x+15*y) 
   self.board.canvas.create_oval(25+30*x-12 , 25+30*y-12 , 25+30*x+12 , 25+30*y+12 , fill = self.color,tags = "chessman")
   if self.game_win(y,x,self.color_count) :
    print(self.color,"获胜")
    self.game_print.set(self.color+"获胜")
   else :
    self.change_color()
    self.game_print.set("请"+self.color+"落子")
 

 #保证棋子落在棋盘上
 def limit_boarder(self , y , x) :
  if x<0 or x>14 or y<0 or y>14 :
   return False
  else :
   return True


 #计算连子的数目,并返回最大连子数目
 def chessman_count(self , y , x , color_count ) :
  count1,count2,count3,count4 = 1,1,1,1
  #横计算
  for i in range(-1 , -5 , -1) :
   if self.db[y][x+i] == color_count :
    count1 += 1
   else:
    break 
  for i in range(1 , 5 ,1 ) :
   if self.db[y][x+i] == color_count :
    count1 += 1
   else:
    break 
  #竖计算
  for i in range(-1 , -5 , -1) :
   if self.db[y+i][x] == color_count :
    count2 += 1
   else:
    break 
  for i in range(1 , 5 ,1 ) :
   if self.db[y+i][x] == color_count :
    count2 += 1
   else:
    break 
  #/计算
  for i in range(-1 , -5 , -1) :
   if self.db[y+i][x+i] == color_count :
    count3 += 1
   else:
    break 
  for i in range(1 , 5 ,1 ) :
   if self.db[y+i][x+i] == color_count :
    count3 += 1
   else:
    break 
  #\计算
  for i in range(-1 , -5 , -1) :
   if self.db[y+i][x-i] == color_count :
    count4 += 1
   else:
    break 
  for i in range(1 , 5 ,1 ) :
   if self.db[y+i][x-i] == color_count :
    count4 += 1
   else:
    break 
   
  return max(count1 , count2 , count3 , count4)


 #判断输赢
 def game_win(self , y , x , color_count ) :
  if self.chessman_count(y,x,color_count) >= 5 :
   self.flag_win = 1
   self.flag_empty = 0
   return True
  else :
   return False
  

 #悔棋,清空棋盘,再画剩下的n-1个棋子
 def withdraw(self ) :
  if len(self.order)==0 or self.flag_win == 1:
   return
  self.board.canvas.delete("chessman")
  z = self.order.pop()
  x = z%15
  y = z//15
  self.db[y][x] = 2
  self.color_count = 1
  for i in self.order :
   ix = i%15
   iy = i//15
   self.change_color()
   self.board.canvas.create_oval(25+30*ix-12 , 25+30*iy-12 , 25+30*ix+12 , 25+30*iy+12 , fill = self.color,tags = "chessman")
  self.change_color()
  self.game_print.set("请"+self.color+"落子")
 

 #清空
 def empty_all(self) :
  self.board.canvas.delete("chessman")
  #还原初始化
  self.db = [([2] * 16) for i in range(16)]
  self.order = []
  self.color_count = 0 
  self.color = 'black'
  self.flag_win = 1
  self.flag_empty = 1
  self.game_print.set("")


 #将self.flag_win置0才能在棋盘上落子
 def game_start(self) :
  #没有清空棋子不能置0开始
  if self.flag_empty == 0:
   return
  self.flag_win = 0
  self.game_print.set("请"+self.color+"落子")


 def options(self) :
  self.board.canvas.bind("<Button-1>",self.chess_moving)
  Label(self.board.window , textvariable = self.game_print , font = ("Arial", 20) ).place(relx = 0, rely = 0 ,x = 495 , y = 200)
  Button(self.board.window , text= "开始游戏" ,command = self.game_start,width = 13, font = ("Verdana", 12)).place(relx=0, rely=0, x=495, y=15)
  Button(self.board.window , text= "我要悔棋" ,command = self.withdraw,width = 13, font = ("Verdana", 12)).place(relx=0, rely=0, x=495, y=60)
  Button(self.board.window , text= "清空棋局" ,command = self.empty_all,width = 13, font = ("Verdana", 12)).place(relx=0, rely=0, x=495, y=105)
  Button(self.board.window , text= "结束游戏" ,command = self.board.window.destroy,width = 13, font = ("Verdana", 12)).place(relx=0, rely=0, x=495, y=420)
  self.board.window.mainloop()

最后,main函数

if __name__ == "__main__":
 game = Gobang()

将以上的所有程序复制粘贴,即为完整的程序了,可以运行。

最后来一个完整程序,一个一个复制粘贴简直不要太麻烦。

'''
@Auther : gaoxin
@Date : 2019.01.01
@Version : 1.0

'''

from tkinter import *
import math

#定义棋盘类
class chessBoard() :
 def __init__(self) :
  self.window = Tk()
  self.window.title("五子棋游戏")
  self.window.geometry("660x470")
  self.window.resizable(0,0)
  self.canvas=Canvas(self.window , bg="#EEE8AC" , width=470, height=470)
  self.paint_board()
  self.canvas.grid(row = 0 , column = 0)

 def paint_board(self) :
  for row in range(0,15) :
   if row == 0 or row == 14 :
    self.canvas.create_line(25 , 25+row*30 , 25+14*30 , 25+row*30 , width = 2)
   else :
    self.canvas.create_line(25 , 25+row*30 , 25+14*30 , 25+row*30 , width = 1)
  for column in range(0,15) :
   if column == 0 or column == 14 :
    self.canvas.create_line(25+column*30 ,25, 25+column*30 , 25+14*30 ,width = 2)
   else :
    self.canvas.create_line(25+column*30 ,25, 25+column*30 , 25+14*30 , width = 1)
   
  self.canvas.create_oval(112, 112, 118, 118, fill="black")
  self.canvas.create_oval(352, 112, 358, 118, fill="black")
  self.canvas.create_oval(112, 352, 118, 358, fill="black")
  self.canvas.create_oval(232, 232, 238, 238, fill="black")
  self.canvas.create_oval(352, 352, 358, 358, fill="black")


#定义五子棋游戏类
#0为黑子 , 1为白子 , 2为空位
class Gobang() :
 #初始化
 def __init__(self) :
  self.board = chessBoard()
  self.game_print = StringVar()
  self.game_print.set("")
  #16*16的二维列表,保证不会out of index
  self.db = [([2] * 16) for i in range(16)]
  #悔棋用的顺序列表
  self.order = []
  #棋子颜色
  self.color_count = 0 
  self.color = 'black'
  #清空与赢的初始化,已赢为1,已清空为1
  self.flag_win = 1
  self.flag_empty = 1
  self.options()
  
  
 #黑白互换
 def change_color(self) :
  self.color_count = (self.color_count + 1 ) % 2
  if self.color_count == 0 :
   self.color = "black"
  elif self.color_count ==1 :
   self.color = "white"
 
 
 #落子
 def chess_moving(self ,event) :
  #不点击“开始”与“清空”无法再次开始落子
  if self.flag_win ==1 or self.flag_empty ==0 :
   return
  #坐标转化为下标
  x,y = event.x-25 , event.y-25
  x = round(x/30)
  y = round(y/30)
  #点击位置没用落子,且没有在棋盘线外,可以落子
  while self.db[y][x] == 2 and self.limit_boarder(y,x):
   self.db[y][x] = self.color_count
   self.order.append(x+15*y) 
   self.board.canvas.create_oval(25+30*x-12 , 25+30*y-12 , 25+30*x+12 , 25+30*y+12 , fill = self.color,tags = "chessman")
   if self.game_win(y,x,self.color_count) :
    print(self.color,"获胜")
    self.game_print.set(self.color+"获胜")
   else :
    self.change_color()
    self.game_print.set("请"+self.color+"落子")
 

 #保证棋子落在棋盘上
 def limit_boarder(self , y , x) :
  if x<0 or x>14 or y<0 or y>14 :
   return False
  else :
   return True


 #计算连子的数目,并返回最大连子数目
 def chessman_count(self , y , x , color_count ) :
  count1,count2,count3,count4 = 1,1,1,1
  #横计算
  for i in range(-1 , -5 , -1) :
   if self.db[y][x+i] == color_count :
    count1 += 1
   else:
    break 
  for i in range(1 , 5 ,1 ) :
   if self.db[y][x+i] == color_count :
    count1 += 1
   else:
    break 
  #竖计算
  for i in range(-1 , -5 , -1) :
   if self.db[y+i][x] == color_count :
    count2 += 1
   else:
    break 
  for i in range(1 , 5 ,1 ) :
   if self.db[y+i][x] == color_count :
    count2 += 1
   else:
    break 
  #/计算
  for i in range(-1 , -5 , -1) :
   if self.db[y+i][x+i] == color_count :
    count3 += 1
   else:
    break 
  for i in range(1 , 5 ,1 ) :
   if self.db[y+i][x+i] == color_count :
    count3 += 1
   else:
    break 
  #\计算
  for i in range(-1 , -5 , -1) :
   if self.db[y+i][x-i] == color_count :
    count4 += 1
   else:
    break 
  for i in range(1 , 5 ,1 ) :
   if self.db[y+i][x-i] == color_count :
    count4 += 1
   else:
    break 
   
  return max(count1 , count2 , count3 , count4)


 #判断输赢
 def game_win(self , y , x , color_count ) :
  if self.chessman_count(y,x,color_count) >= 5 :
   self.flag_win = 1
   self.flag_empty = 0
   return True
  else :
   return False
  

 #悔棋,清空棋盘,再画剩下的n-1个棋子
 def withdraw(self ) :
  if len(self.order)==0 or self.flag_win == 1:
   return
  self.board.canvas.delete("chessman")
  z = self.order.pop()
  x = z%15
  y = z//15
  self.db[y][x] = 2
  self.color_count = 1
  for i in self.order :
   ix = i%15
   iy = i//15
   self.change_color()
   self.board.canvas.create_oval(25+30*ix-12 , 25+30*iy-12 , 25+30*ix+12 , 25+30*iy+12 , fill = self.color,tags = "chessman")
  self.change_color()
  self.game_print.set("请"+self.color+"落子")
 

 #清空
 def empty_all(self) :
  self.board.canvas.delete("chessman")
  #还原初始化
  self.db = [([2] * 16) for i in range(16)]
  self.order = []
  self.color_count = 0 
  self.color = 'black'
  self.flag_win = 1
  self.flag_empty = 1
  self.game_print.set("")


 #将self.flag_win置0才能在棋盘上落子
 def game_start(self) :
  #没有清空棋子不能置0开始
  if self.flag_empty == 0:
   return
  self.flag_win = 0
  self.game_print.set("请"+self.color+"落子")


 def options(self) :
  self.board.canvas.bind("<Button-1>",self.chess_moving)
  Label(self.board.window , textvariable = self.game_print , font = ("Arial", 20) ).place(relx = 0, rely = 0 ,x = 495 , y = 200)
  Button(self.board.window , text= "开始游戏" ,command = self.game_start,width = 13, font = ("Verdana", 12)).place(relx=0, rely=0, x=495, y=15)
  Button(self.board.window , text= "我要悔棋" ,command = self.withdraw,width = 13, font = ("Verdana", 12)).place(relx=0, rely=0, x=495, y=60)
  Button(self.board.window , text= "清空棋局" ,command = self.empty_all,width = 13, font = ("Verdana", 12)).place(relx=0, rely=0, x=495, y=105)
  Button(self.board.window , text= "结束游戏" ,command = self.board.window.destroy,width = 13, font = ("Verdana", 12)).place(relx=0, rely=0, x=495, y=420)
  self.board.window.mainloop()

 
if __name__ == "__main__":
 game = Gobang()

更多有趣的经典小游戏实现专题,分享给大家:

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Python 相关文章推荐
python实现html转ubb代码(html2ubb)
Jul 03 Python
12步入门Python中的decorator装饰器使用方法
Jun 20 Python
详解python之简单主机批量管理工具
Jan 27 Python
Python入门_浅谈逻辑判断与运算符
May 16 Python
Python图形绘制操作之正弦曲线实现方法分析
Dec 25 Python
Python全局变量与局部变量区别及用法分析
Sep 03 Python
Python多进程写入同一文件的方法
Jan 14 Python
对Python生成器、装饰器、递归的使用详解
Jul 19 Python
在PyCharm的 Terminal(终端)切换Python版本的方法
Aug 02 Python
在python3中实现查找数组中最接近与某值的元素操作
Feb 29 Python
PyQt5结合matplotlib绘图的实现示例
Sep 15 Python
python线程池 ThreadPoolExecutor 的用法示例
Oct 10 Python
Python3+selenium配置常见报错解决方案
Aug 28 #Python
Python 中如何写注释
Aug 28 #Python
Python操作Word批量生成合同的实现示例
Aug 28 #Python
Python接口自动化测试的实现
Aug 28 #Python
解决python和pycharm安装gmpy2 出现ERROR的问题
Aug 28 #Python
Python自动登录QQ的实现示例
Aug 28 #Python
python opencv pytesseract 验证码识别的实现
Aug 28 #Python
You might like
php表单请求获得数据求和示例
2014/05/15 PHP
自己写的兼容低于PHP 5.5版本的array_column()函数
2014/10/24 PHP
PHP处理CSV表格文件的常用操作方法总结
2016/07/01 PHP
PHP实现根据数组的值进行分组的方法
2017/04/20 PHP
浅谈使用 Yii2 AssetBundle 中 $publishOptions 的正确姿势
2017/11/08 PHP
用 javascript 实现的点击复制代码
2007/03/24 Javascript
js用图作提交按钮或超连接
2008/03/26 Javascript
js对列表中第一个值处理与jsp页面对列表中第一个值处理的区别详解
2013/11/05 Javascript
Javascript封装DOMContentLoaded事件实例
2014/06/12 Javascript
小结Node.js中非阻塞IO和事件循环
2014/09/18 Javascript
纯JavaScript代码实现文本比较工具
2016/02/17 Javascript
AngularJS 模块化详解及实例代码
2016/09/14 Javascript
JQuery手速测试小游戏实现思路详解
2016/09/20 Javascript
jQuery图片拖动组件Dropzone用法示例
2017/01/17 Javascript
AngularJS表格样式简单设置方法示例
2017/03/03 Javascript
微信小程序中使用javascript 回调函数
2017/05/11 Javascript
详解利用Angular实现多团队模块化SPA开发框架
2017/11/27 Javascript
cropper js基于vue的图片裁剪上传功能的实现代码
2018/03/01 Javascript
如何以Angular的姿势打开Font-Awesome详解
2018/04/22 Javascript
vue-form表单验证是否为空值的实例详解
2019/10/29 Javascript
JQuery样式与属性设置方法分析
2019/12/07 jQuery
python基于BeautifulSoup实现抓取网页指定内容的方法
2015/07/09 Python
Python标准库inspect的具体使用方法
2017/12/06 Python
TensorFlow的权值更新方法
2018/06/14 Python
在python中获取div的文本内容并和想定结果进行对比详解
2019/01/02 Python
python使用wxpy实现微信消息防撤回脚本
2019/04/29 Python
Python 监测文件是否更新的方法
2019/06/10 Python
Python求离散序列导数的示例
2019/07/10 Python
Python内置加密模块用法解析
2019/11/25 Python
使用PyTorch将文件夹下的图片分为训练集和验证集实例
2020/01/08 Python
Python编程快速上手——strip()函数的正则表达式实现方法分析
2020/02/29 Python
工程专业求职自荐书范文
2014/02/18 职场文书
教师病假条范文
2015/08/17 职场文书
纯CSS实现酷炫的霓虹灯效果
2021/04/13 HTML / CSS
Python 解决空列表.append() 输出为None的问题
2021/05/23 Python
解决vue $http的get和post请求跨域问题
2021/06/07 Vue.js