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装饰器
Jul 27 Python
Python代码缩进和测试模块示例详解
May 07 Python
使用sklearn之LabelEncoder将Label标准化的方法
Jul 11 Python
python安装pywin32clipboard的操作方法
Jan 24 Python
Python字典推导式将cookie字符串转化为字典解析
Aug 10 Python
Python基于类路径字符串获取静态属性
Mar 12 Python
解决python DataFrame 打印结果不换行问题
Apr 09 Python
python模拟实现分发扑克牌
Apr 22 Python
Python如何转换字符串大小写
Jun 04 Python
PyCharm+Miniconda3安装配置教程详解
Feb 16 Python
Django中的DateTimeField和DateField实现
Feb 24 Python
Python中递归以及递归遍历目录详解
Oct 24 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/07/30 PHP
PHP7引入的&quot;??&quot;和&quot;?:&quot;的区别讲解
2019/04/08 PHP
php中array_fill函数的实例用法
2021/03/02 PHP
jquery 弹出登录窗口实现代码
2009/12/24 Javascript
js 得到文件后缀(通过正则实现)
2013/07/08 Javascript
可自己添加html的伪弹出框实现代码
2013/09/08 Javascript
jquery fancybox ie6不显示关闭按钮的解决办法
2013/12/25 Javascript
js 设置缓存及获取设置的缓存
2014/05/08 Javascript
实现js保留小数点后N位的代码
2014/11/13 Javascript
js实现动态加载脚本的方法实例汇总
2015/11/02 Javascript
js中less常用的方法小结
2017/08/09 Javascript
vue watch关于对象内的属性监听
2019/04/22 Javascript
element-ui表格合并span-method的实现方法
2019/05/21 Javascript
在layui框架中select下拉框监听更改事件的例子
2019/09/20 Javascript
js实现坦克大战游戏
2020/02/24 Javascript
小程序Scroll-view上拉滚动刷新数据
2020/06/21 Javascript
PyQt5每天必学之事件与信号
2018/04/20 Python
Python3.6.0+opencv3.3.0人脸检测示例
2018/05/25 Python
浅谈Django+Gunicorn+Nginx部署之路
2019/09/11 Python
python实现代码统计器
2019/09/19 Python
opencv3/C++图像像素操作详解
2019/12/10 Python
Tensorflow的常用矩阵生成方式
2020/01/04 Python
phonegap常用事件总结(必看篇)
2017/03/31 HTML / CSS
关于打架的检讨书
2014/01/17 职场文书
保密工作实施方案
2014/02/24 职场文书
幼儿园开学寄语
2014/04/03 职场文书
建筑工程质量通病防治方案
2014/06/08 职场文书
房屋转让协议书
2014/10/18 职场文书
三好学生评语大全
2014/12/29 职场文书
党风廉正建设责任书
2015/01/29 职场文书
专项资金申请报告
2015/05/15 职场文书
党支部综合考察意见
2015/06/01 职场文书
委托收款证明
2015/06/23 职场文书
会议新闻稿
2015/07/17 职场文书
奇妙的 CSS shapes(CSS图形)
2021/04/05 HTML / CSS
python基于机器学习预测股票交易信号
2021/05/25 Python