1.设置棋盘

五子棋标准棋盘是15x15的,如果我们每个格子的大小是40x40的话,棋盘应该是40x(15-1)=560的宽度,我们在四面各保留60的边距,那么窗口的长宽各是40x(15-1)+60x2

# -*- coding=utf-8 -*-
import random
import pygame
pygame.init()space = 60 # 四周留下的边距
cell_size = 40 # 每个格子大小
cell_num = 15
grid_size = cell_size * (cell_num - 1) + space * 2 # 棋盘的大小
screencaption = pygame.display.set_caption('FIR')
screen = pygame.display.set_mode((grid_size,grid_size)) #设置窗口长宽while True:for event in pygame.event.get():if event.type == pygame.QUIT:pygame.quit()exit()screen.fill((0,0,150)) # 将界面设置为蓝色for x in range(0,cell_size*cell_num,cell_size):pygame.draw.line(screen,(200,200,200),(x+space,0+space),(x+space,cell_size*(cell_num-1)+space),1)for y in range(0,cell_size*cell_num,cell_size):pygame.draw.line(screen,(200,200,200),(0+space,y+space),(cell_size*(cell_num-1)+space,y+space),1)pygame.display.update() # 必须调用update才能看到绘图显示

2.落子

首先我们定义一个chess_arr数组用于存储落到棋盘上的棋子

chess_arr = []

然后在游戏主循环监听下鼠标弹起事件,然后在捕捉到鼠标弹起事件时获取鼠标位置并把位置添加进chess_arr

for event in pygame.event.get():……if event.type == pygame.MOUSEBUTTONUP: # 鼠标弹起x, y = pygame.mouse.get_pos() # 获取鼠标位置chess_arr.append((x,y))

最后我们在pygame.display.update()前将棋子绘制出来看看效果

可以看到,现在已经能点出棋子了,但是棋子的位置不是纵横线的交叉点,所以我们必须对鼠标位置进行取整,不能把x,y这个位置加的这么随意,处理下x,y位置的代码如下

for event in pygame.event.get():……if event.type == pygame.MOUSEBUTTONUP: # 鼠标弹起x, y = pygame.mouse.get_pos() # 获取鼠标位置xi = int(round((x - space)*1.0/cell_size)) # 获取到x方向上取整的序号yi = int(round((y - space)*1.0/cell_size)) # 获取到y方向上取整的序号if xi>=0 and xi<cell_num and yi>=0 and yi<cell_num:chess_arr.append((xi*cell_size+space,yi*cell_size+space))

现在发现落子位置靠谱多了

为了代码的可读性更好点,以后一些棋盘计算更方便,我们把放入chess_arr数组的绝对坐标改成放入的是格子的序号,也就是把

 chess_arr.append((xi*cell_size+space,yi*cell_size+space))

改成

chess_arr.append((xi,yi))

然后在画棋子的地方也稍作修改,把

pygame.draw.circle(screen,(205,205,205), [x, y], 16,16)

改成

pygame.draw.circle(screen,(205,205,205), [x*cell_size+space, y*cell_size+space], 16,16)

接下来还有个问题,因为进到chess_arr数组前并没有判断某一位置是否已经有棋子,存在重复落子的情况,所以这边还要多加个判断,因为python语言够强大,可以直接判断是否包含tuple或者数组,所以只要多加一个(xi,yi) not in chess_arr的判断就好了,开不开森~

    for event in pygame.event.get():……if event.type == pygame.MOUSEBUTTONUP: # 鼠标弹起……if xi>=0 and xi<cell_num and yi>=0 and yi<cell_num and (xi,yi) not in chess_arr:chess_arr.append((xi,yi))

为免代码偏差,先更新下目前的完整代码

# -*- coding=utf-8 -*-
import random
import pygame
from pygame.locals import MOUSEBUTTONUP
pygame.init()space = 60 # 四周留下的边距
cell_size = 40 # 每个格子大小
cell_num = 15
grid_size = cell_size * (cell_num - 1) + space * 2 # 棋盘的大小
screencaption = pygame.display.set_caption('FIR')
screen = pygame.display.set_mode((grid_size,grid_size)) #设置窗口长宽chess_arr = []while True:for event in pygame.event.get():if event.type == pygame.QUIT:pygame.quit()exit()if event.type == pygame.MOUSEBUTTONUP: # 鼠标弹起x, y = pygame.mouse.get_pos() # 获取鼠标位置xi = int(round((x - space)*1.0/cell_size)) # 获取到x方向上取整的序号yi = int(round((y - space)*1.0/cell_size)) # 获取到y方向上取整的序号if xi>=0 and xi<cell_num and yi>=0 and yi<cell_num and (xi,yi) not in chess_arr:chess_arr.append((xi,yi))screen.fill((0,0,150)) # 将界面设置为蓝色for x in range(0,cell_size*cell_num,cell_size):pygame.draw.line(screen,(200,200,200),(x+space,0+space),(x+space,cell_size*(cell_num-1)+space),1)for y in range(0,cell_size*cell_num,cell_size):pygame.draw.line(screen,(200,200,200),(0+space,y+space),(cell_size*(cell_num-1)+space,y+space),1)for x, y in chess_arr:pygame.draw.circle(screen,(205,205,205), [x*cell_size+space, y*cell_size+space], 16,16)pygame.display.update() # 必须调用update才能看到绘图显示

3.区分黑白子

这里常规的想法可能有这么两种:1.chess_arr理论应该是黑白相间的,一个隔一个不同颜色画就好了(这种在不考虑正规比赛五手两打或者让子的情况下是没问题的) 2.往chess_arr里填(x,y)时多填一个黑白标记改成(x,y,flag) ,这里我们选择第二种方案
首先,我们全局定义个flag变量

flag = 1 # 1黑 2白

我们把

if xi>=0 and xi<cell_num and yi>=0 and yi<cell_num and (xi,yi) not in chess_arr:chess_arr.append((xi,yi))

这里改成

if xi>=0 and xi<cell_num and yi>=0 and yi<cell_num and (xi,yi,1) not in chess_arr and (xi,yi,2) not in chess_arr:chess_arr.append((xi,yi,flag))flag = 2 if flag == 1 else 2

再把画棋的

for x, y in chess_arr:pygame.draw.circle(screen,(205,205,205), [x*cell_size+space, y*cell_size+space], 16,16)

改成

for x, y, c in chess_arr:chess_color = (30,30,30) if c == 1 else (225,225,225)pygame.draw.circle(screen, chess_color, [x*cell_size+space, y*cell_size+space], 16,16)


现在看起来有点像那么回事了

4.判断输赢

判断输赢的关键当然还是使用chess_arr这个数组,这个数组用来判断胜利并不太方便,我们把它转一个15*15的二维数组来计算,转换代码如下

m = [[0]*15 for i in range(15)] # 先定义一个15*15的全0数组
for x, y, c in chess_arr:m[y][x] = 1 # 上面有棋则标1

我们把这代码一起放到一个check_win(chess_arr, flag)函数里,用于判断某一方是否胜利,基本流程是分别判断最后一颗落下的子的横线、竖线、斜线上是不是有5个以上子,有则返回True,函数代码如下:

def get_one_dire_num(lx, ly, dx, dy, m):tx = lxty = lys = 0while True:tx += dxty += dyif tx < 0 or tx >= cell_num or ty < 0 or ty >= cell_num or m[ty][tx] == 0: return ss+=1def check_win(chess_arr, flag):m = [[0]*cell_num for i in range(cell_num)] # 先定义一个15*15的全0的数组,不能用[[0]*cell_num]*cell_num的方式去定义因为一位数组会被重复引用for x, y, c in chess_arr:if c == flag:m[y][x] = 1 # 上面有棋则标1lx = chess_arr[-1][0] # 最后一个子的xly = chess_arr[-1][1] # 最后一个子的ydire_arr = [[(-1,0),(1,0)],[(0,-1),(0,1)],[(-1,-1),(1,1)],[(-1,1),(1,-1)]] # 4个方向数组,往左+往右、往上+往下、往左上+往右下、往左下+往右上,4组判断方向for dire1,dire2 in dire_arr:dx, dy = dire1num1 = get_one_dire_num(lx, ly, dx, dy, m)dx, dy = dire2num2 = get_one_dire_num(lx, ly, dx, dy, m)if num1 + num2 + 1 >= 5: return Truereturn False

判断函数完成了,我们再定一个全局变量用于保存游戏状态

game_state = 1 # 游戏状态1.表示正常进行 2.表示黑胜 3.表示白胜

我们在鼠标添加棋子的代码后面做下修改,调用判断胜利的函数

                 if check_win(chess_arr, flag):game_state = 2 if flag == 1 else 3else:flag = 2 if flag == 1 else 1

最后在pygame.display.update()前加个游戏状态判断,用于显示获胜文字

    if game_state != 1:myfont = pygame.font.Font(None,60)white = 210,210,0win_text = "%s win"%('black' if game_state == 2 else 'white')textImage = myfont.render(win_text, True, white)screen.blit(textImage, (260,320))

另外,鼠标事件判断处也要做下修改,判断下游戏状态是不是游戏中

if game_state == 1 and event.type == pygame.MOUSEBUTTONUP: # 鼠标弹起

至此主要的代码都完整了,下面是效果图

最后贴下完整程序,这边没有做禁手的判断和判输,后面有时间再处理

# -*- coding=utf-8 -*-
import random
import pygame
from pygame.locals import MOUSEBUTTONUP
pygame.init()space = 60 # 四周留下的边距
cell_size = 40 # 每个格子大小
cell_num = 15
grid_size = cell_size * (cell_num - 1) + space * 2 # 棋盘的大小
screencaption = pygame.display.set_caption('FIR')
screen = pygame.display.set_mode((grid_size,grid_size)) #设置窗口长宽chess_arr = []
flag = 1 # 1黑 2白
game_state = 1 # 游戏状态1.表示正常进行 2.表示黑胜 3.表示白胜def get_one_dire_num(lx, ly, dx, dy, m):tx = lxty = lys = 0while True:tx += dxty += dyif tx < 0 or tx >= cell_num or ty < 0 or ty >= cell_num or m[ty][tx] == 0: return ss+=1def check_win(chess_arr, flag):m = [[0]*cell_num for i in range(cell_num)] # 先定义一个15*15的全0的数组,不能用[[0]*cell_num]*cell_num的方式去定义因为一位数组会被重复引用for x, y, c in chess_arr:if c == flag:m[y][x] = 1 # 上面有棋则标1lx = chess_arr[-1][0] # 最后一个子的xly = chess_arr[-1][1] # 最后一个子的ydire_arr = [[(-1,0),(1,0)],[(0,-1),(0,1)],[(-1,-1),(1,1)],[(-1,1),(1,-1)]] # 4个方向数组,往左+往右、往上+往下、往左上+往右下、往左下+往右上,4组判断方向for dire1,dire2 in dire_arr:dx, dy = dire1num1 = get_one_dire_num(lx, ly, dx, dy, m)dx, dy = dire2num2 = get_one_dire_num(lx, ly, dx, dy, m)if num1 + num2 + 1 >= 5: return Truereturn Falsewhile True:for event in pygame.event.get():if event.type == pygame.QUIT:pygame.quit()exit()if game_state == 1 and event.type == pygame.MOUSEBUTTONUP: # 鼠标弹起x, y = pygame.mouse.get_pos() # 获取鼠标位置xi = int(round((x - space)*1.0/cell_size)) # 获取到x方向上取整的序号yi = int(round((y - space)*1.0/cell_size)) # 获取到y方向上取整的序号if xi>=0 and xi<cell_num and yi>=0 and yi<cell_num and (xi,yi,1) not in chess_arr and (xi,yi,2) not in chess_arr:chess_arr.append((xi,yi,flag))if check_win(chess_arr, flag):game_state = 2 if flag == 1 else 3else:flag = 2 if flag == 1 else 1screen.fill((0,0,150)) # 将界面设置为蓝色for x in range(0,cell_size*cell_num,cell_size):pygame.draw.line(screen,(200,200,200),(x+space,0+space),(x+space,cell_size*(cell_num-1)+space),1)for y in range(0,cell_size*cell_num,cell_size):pygame.draw.line(screen,(200,200,200),(0+space,y+space),(cell_size*(cell_num-1)+space,y+space),1)for x, y, c in chess_arr:chess_color = (30,30,30) if c == 1 else (225,225,225)pygame.draw.circle(screen, chess_color, [x*cell_size+space, y*cell_size+space], 16,16)if game_state != 1:myfont = pygame.font.Font(None,60)white = 210,210,0win_text = "%s win"%('black' if game_state == 2 else 'white')textImage = myfont.render(win_text, True, white)screen.blit(textImage, (260,320))pygame.display.update() # 必须调用update才能看到绘图显示

五、pygame做一个简单的五子棋游戏相关推荐

  1. pygame做一个简单的打字游戏

    pygame做一个简单的打字游戏 1.基本代码 下面的代码完成了每一秒在界面的顶部随机生成一个新的字母 # -*- coding=utf-8 -*- import pygame from pygame ...

  2. 用74l138实现一个一位全减器_用pygame实现一个简单的五子棋游戏

    准备 python基础相关准备: pygame的基础知识,参考目光博客的"用Python和Pygame写游戏-从入门到精通" 安装python 3.8.0 在python官网下载, ...

  3. 用pygame做一个简单的python小游戏---贪吃蛇

    用pygame做一个简单的python小游戏-贪吃蛇 贪吃蛇游戏博客链接:(方法一样,语言不一样) c++贪吃蛇:https://blog.csdn.net/weixin_46791942/artic ...

  4. 用pygame做一个简单的python小游戏---七彩同心圆

    用pygame做一个简单的python小游戏-七彩同心圆 这个小游戏原是我同学python课的课后作业,并不是很难,就简单实现了一下,顺便加强一下pygame库的学习. 玩法:每次点击鼠标时,会以鼠标 ...

  5. 用pygame做一个简单的python小游戏---生命游戏

    用pygame做一个简单的python小游戏-生命游戏 生命游戏(Game of Life) 生命游戏(Game of Life)是剑桥大学约翰·何顿·康威(John Horton Conway)教授 ...

  6. python七彩同心圆_用pygame做一个简单的python小游戏---七彩同心圆

    用pygame做一个简单的python小游戏---七彩同心圆 用pygame做一个简单的python小游戏-七彩同心圆 这个小游戏原是我同学python课的课后作业,并不是很难,就简单实现了一下,顺便 ...

  7. 用java做一个简单的打字游戏

    Java也是可以做桌面程序的.只不过需要运行在装有JDK的电脑环境上,所以应用不是很广泛,但是用来提高自身的代码逻辑还是可以的!偶有一天看到金山的打字通,就想起何不做个简单的打字游戏用来练练手.于是就 ...

  8. 如何使用cocos2d-x 3.0来做一个简单的iphone游戏教程(第一部分)

    游戏截图: cocos2d-x 是一个支持多平台的开源框架,用于构建游戏.应用程序和其他图形界面交互应用.Cocos2d-x项目可以很容易地建立和运行在iOS,Android的三星Bada,黑莓Bla ...

  9. 用python做一个简单的猜拳游戏

    提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 文章目录 前言 一.简介 二.代码 总结一 总结二 注意 前言 用python编写一个简单的猜拳游戏 一.简介 这是我用python编 ...

  10. 用Python代码做一个简单数字小游戏

    #作者是一个十三岁的小男孩. 编辑工具 电脑Python 需要模块 random #今日用代码做一个猜数小游戏 #话不多说,上代码!!! import random number = random.r ...

最新文章

  1. java强引用弱引用_Java 的强引用、弱引用、软引用、虚引用
  2. 向HtmlAgilityPack道歉:解析HTML还是你好用
  3. 《卓有成效的管理者》——读书笔记
  4. 生成和验证注册码的基本思路
  5. mysql查询不同老师所教不同课程_mysql学习训练记录及笔记(二)
  6. 计算机应用技术的创新
  7. 【算法分析与设计】浅析二分查找
  8. python logger 服务器_python——logger模块
  9. Leecode刷题热题HOT100(13)——罗马数字转整数
  10. linuxpython源文件_如何在Linux中运行Python源文件
  11. mysql8 :客户端连接caching-sha2-password问题
  12. 南阳oj a+b问题
  13. mx250显卡天梯图_MX250相当于什么显卡?来看显卡天梯图
  14. 免费下载卫星地图 高清卫星地图软件
  15. 第三十一篇 -- 学习第六十八天打卡20190911
  16. 报错:Web server failed to start. Port 8080 was already in use
  17. 【CSS】537- 认真介绍 CSS 原理
  18. java搜索拉钩_java实现拉钩网上的FizzBuzzWhizz问题示例
  19. crontab -r删除后恢复
  20. Android——在线计算器完整代码

热门文章

  1. java移位运算符详解_java移位运算符详解
  2. UDP之socket编程实例
  3. 调用栈(call stack)
  4. 马云透露:未来10大行业即将消失!
  5. 邮件服务器怎么填写,邮箱可以绑定哪些客户端?
  6. 西威变频器 服务器显示,西威变频器故障查询及操作方法;
  7. IT 技能发展:10 大基本 IT 技能(精通一半你就是人才)
  8. MATLAB函数拟合使用
  9. SPSS多元统计分析【009期】
  10. 手机上最好用的五笔输入法_手机输入法哪家最好用?我推荐百度,不好用你打我...