侯体宗的博客
  • 首页
  • Hyperf版
  • beego仿版
  • 人生(杂谈)
  • 技术
  • 关于我
  • 更多分类
    • 文件下载
    • 文字修仙
    • 中国象棋ai
    • 群聊
    • 九宫格抽奖
    • 拼图
    • 消消乐
    • 相册

python实现五子棋游戏(pygame版)

Python  /  管理员 发布于 7年前   346

本文实例为大家分享了python五子棋游戏的具体代码,供大家参考,具体内容如下

目录

  • 简介
  • 实现过程
  • 结语

简介

使用python实现pygame版的五子棋游戏;

环境:Windows系统+python3.8.0

游戏规则:

1.分两位棋手对战,默认黑棋先下;当在棋盘点击左键,即在该位置绘制黑棋;

2.自动切换到白棋,当在棋盘点击左键,即在该位置绘制白棋;

3.轮流切换棋手下棋,当那方先形成5子连线者获胜(横、竖、斜、反斜四个方向都可以)。

游戏运行效果如下:

实现过程

1.新建文件settings.py,用来定义一些必须的基本属性和初始值;

class Settings(): def __init__(self): """初始化的游戏配置""" # 屏幕宽高 self.width = 700 self.height = 554 # 文字颜色和大小 self.fontsize = 14 self.fonttype = 'simsunnsimsun' # 棋盘格数 self.number = 15 # 棋盘左边距、上边距和间隔 self.bd_left = 30 self.bd_top = 30 self.bd_space = 36 # 判断游戏是否结束(默认开始) self.game_active = True # 判断哪方下棋(默认黑子先写) self.chess_player = 1 self.prompt_info = '当前棋手:黑棋' # 开始校验输赢(两边合计9,因为已经有一边5步) self.win_number = 0 # 设置背景图、黑棋图片、白棋图片路径 self.checkerboard_bg = 'images/checkerboard_bg.png' self.black_chess = 'images/black_chess.png' self.white_chess = 'images/white_chess.png' # 存储落子数据 self.move_chess = []

2.新建文件checkerboard.py,主要用来绘制背景图和棋格线;

import sysimport pygame class Checkerboard(): def __init__(self, ck_settings, screen, position): self.ck_settings = ck_settings self.screen = screen self.position = position  # 颜色和坐标大小 self.text_color = (0, 0, 0) self.font = pygame.font.SysFont(ck_settings.fonttype, ck_settings.fontsize) # 存储棋子坐标 self.checkerboard = [] # 加载背景图、黑棋和白棋(当有图片不存在时,打印错误并退出游戏) try: self.bg_image = pygame.image.load(ck_settings.checkerboard_bg)  self.black_image = pygame.image.load(ck_settings.black_chess).convert_alpha() # convert_alpha背景透明 self.white_image = pygame.image.load(ck_settings.white_chess).convert_alpha() self.chess_rect = self.black_image.get_rect() except Exception as e: print('error:', e) sys.exit()  def draw_board(self):  # 存储棋子坐标  for i in range(self.ck_settings.number): self.checkerboard.append([]) for j in range(self.ck_settings.number): self.checkerboard[i].append(self.position(self.ck_settings.bd_left + i * self.ck_settings.bd_space, self.ck_settings.bd_top + j * self.ck_settings.bd_space)) # 绘制棋盘坐标 for i in range(0, self.ck_settings.number): # ord返回字符的ASCII数值,chr再返回字符 x_text = self.font.render(chr(ord('A') + i), True, self.text_color) # A-O y_text = self.font.render(str(i + 1), True, self.text_color) # 1-15  # 绘制xy轴坐标(在棋盘背景图绘制) self.bg_image.blit(x_text, (self.checkerboard[i][0].x - x_text.get_width() / 2, self.checkerboard[i][0].y - 20)) self.bg_image.blit(y_text, (self.checkerboard[0][i].x - 20, self.checkerboard[0][i].y - y_text.get_height() / 2))   # 绘制横竖线(在棋盘背景图绘制) pygame.draw.line(self.bg_image, self.text_color, self.checkerboard[0][i], self.checkerboard[self.ck_settings.number-1][i]) pygame.draw.line(self.bg_image, self.text_color, self.checkerboard[i][0], self.checkerboard[i][self.ck_settings.number-1]) # 绘制棋盘背景图 self.screen.blit(self.bg_image, (0, 0))

3.新建文件infopanel.py,主要用来绘制棋盘右边提示信息(暂时只有显示下棋方和获胜信息);

import pygame.fontclass Infopanel(): def __init__(self, ck_settings, screen): """初始化属性""" self.settings = ck_settings self.screen = screen self.screen_rect = screen.get_rect() # 设置文字颜色和字体大小 self.info_color = (217, 8, 10) self.font = pygame.font.SysFont(ck_settings.fonttype, 16)  def draw_info(self, info): """将文字渲染为图像,并定位到右边水平居中""" self.info_image = self.font.render(info, True, self.info_color) self.info_image_rect = self.info_image.get_rect() self.info_image_rect.right = self.screen_rect.right - (self.screen_rect.width - 536 - self.info_image_rect.width) / 2 self.info_image_rect.top = 50 # 绘制到屏幕 self.screen.blit(self.info_image, self.info_image_rect)

4.新建文件“game_functions.py”,存放跟游戏有关的所有业务逻辑函数;

import sysimport pygame # 棋def update_board(ck_settings, cb, index_coordinates, position): """更新棋盘信息""" # 判断棋手(黑棋或白棋) if ck_settings.chess_player == 1: ck_settings.prompt_info = '当前棋手:白棋' img = cb.black_image chess_type = 'black' else: ck_settings.prompt_info = '当前棋手:黑棋' img = cb.white_image chess_type = 'white'  """落棋""" dropState = check_at(ck_settings, index_coordinates) if dropState: i, j = index_coordinates chess_x = cb.checkerboard[j][i].x - cb.chess_rect.width / 2 chess_y = cb.checkerboard[j][i].y - cb.chess_rect.height / 2 # 累计步数(两边合计) ck_settings.win_number += 1 # 落子并转换棋手 ck_settings.move_chess.append({'type': chess_type, 'coord': position(i, j)}) cb.bg_image.blit(img, (chess_x, chess_y)) ck_settings.chess_player *= -1 # 合计9步开始校验输赢 if ck_settings.win_number >= 9: check_stats(ck_settings, (i, j))  else: ck_settings.prompt_info = '已经有其他棋子'  # 检查(i,j)位置是否已占用 def check_at(ck_settings, index_coordinates): for item in ck_settings.move_chess: if index_coordinates == item['coord']: return False return True def check_stats(ck_settings, pos): """校验四个方向,是否有了输赢""" pos_i, pos_j = pos directs = [(1, 0), (0, 1), (1, 1), (1, -1)] # 横、竖、斜、反斜 四个方向检查  for direct in directs: line_checkerboard = [] d_x, d_y = direct  last = ck_settings.move_chess[-1] line_ball = [] # 存放在一条线上的棋子 for ball in ck_settings.move_chess: # 跟最后落子判断 if ball['type'] == last['type']: x = ball['coord'].x - last['coord'].x  y = ball['coord'].y - last['coord'].y if d_x == 0:  if x == 0:  line_ball.append(ball['coord']) if d_y == 0:  if y == 0:  line_ball.append(ball['coord']) if x * d_y == y * d_x:  line_ball.append(ball['coord'])  if len(line_ball) >= 5: # 只有5子及以上才继续判断 sorted_line = sorted(line_ball) for i, item in enumerate(sorted_line):  index = i + 4 if index < len(sorted_line):  if d_x == 0:  y1 = item.y  y2 = sorted_line[index].y  # 此点和第5个点比较y值,如相差为4则连成5子  if abs(y1 - y2) == 4:  ck_settings.prompt_info = '黑棋获胜' if last['type'] == 'black' else '白棋获胜'  else:  x1 = item.x  x2 = sorted_line[index].x  # 此点和第5个点比较x值,如相差为4则连成5子  if abs(x1 - x2) == 4:  ck_settings.prompt_info = '黑棋获胜' if last['type'] == 'black' else '白棋获胜' else:  break # 事件def check_events(ck_settings, cb, position): """监听事件""" for event in pygame.event.get(): if event.type == pygame.QUIT: sys.exit() elif event.type == pygame.MOUSEBUTTONDOWN: # 点击左键 if event.button == 1: pos = pygame.mouse.get_pos() # 获取点击实际坐标 # 判断是否溢出 x_first = cb.checkerboard[0][0].x x_last = cb.checkerboard[ck_settings.number - 1][ck_settings.number - 1].x y_first = cb.checkerboard[0][0].y y_last = cb.checkerboard[ck_settings.number - 1][ck_settings.number - 1].y if pos[0] < x_first or pos[0] > x_last or pos[1] < y_first or pos[1] > y_last:  ck_settings.prompt_info = '落子位置不正确!' else:  index_coordinates = to_index(ck_settings, pos)  update_board(ck_settings, cb, index_coordinates, position) def to_index(ck_settings, pos): """实际坐标转换为棋盘下标""" i = round((pos[1] - ck_settings.bd_top) / ck_settings.bd_space) j = round((pos[0] - ck_settings.bd_left) / ck_settings.bd_space) return (i, j)

5.新建文件gobang.py,主函数用来初始化程序,并同步更新程序的信息;

import pygamefrom settings import Settingsfrom checkerboard import Checkerboardfrom collections import namedtupleimport game_functions as gffrom infopanel import Infopanel def run_game(): """运行游戏""" # 初始化游戏屏幕 pygame.init() # 创建时钟对象 (可以控制游戏循环频率) clock = pygame.time.Clock() # 配置实例化 ck_settings = Settings()  screen = pygame.display.set_mode((ck_settings.width, ck_settings.height)) pygame.display.set_caption('五子棋游戏') # namedtuple创建类似于元组的数据类型,除了可以用索引访问,能够迭代,还能用属性名访问数据 position = namedtuple('Position', ['x', 'y']) # 创建实例 cb = Checkerboard(ck_settings, screen, position)  # 实例化面板信息 infopanel = Infopanel(ck_settings, screen)  while ck_settings.game_active: # 绘制棋盘 cb.draw_board() # 绘制面板信息 infopanel.draw_info(ck_settings.prompt_info) # 检查玩家事件并更新棋盘 gf.check_events(ck_settings, cb, position) # 让最近绘制的屏幕可见 pygame.display.flip()  # 通过时钟对象指定循环频率 clock.tick(60) # 每秒循环60次 run_game()

6.在文件gobang.py目录路径下,执行命令“python gobang.py”弹出窗口,即可对其操作游玩。

结语

该游戏只是实现了基础功能,还有很多可优化的功能:

1.根据实际情况加上更详细的面板信息(比如倒计时等);

2.加上开始游戏按钮,可参考前面python实例;

3.胜负榜单等,可参考前面python实例。

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


  • 上一条:
    使用python turtle画高达
    下一条:
    Python turtle画图库&&画姓名实例
  • 昵称:

    邮箱:

    0条评论 (评论内容有缓存机制,请悉知!)
    最新最热
    • 分类目录
    • 人生(杂谈)
    • 技术
    • linux
    • Java
    • php
    • 框架(架构)
    • 前端
    • ThinkPHP
    • 数据库
    • 微信(小程序)
    • Laravel
    • Redis
    • Docker
    • Go
    • swoole
    • Windows
    • Python
    • 苹果(mac/ios)
    • 相关文章
    • 在python语言中Flask框架的学习及简单功能示例(0个评论)
    • 在Python语言中实现GUI全屏倒计时代码示例(0个评论)
    • Python + zipfile库实现zip文件解压自动化脚本示例(0个评论)
    • python爬虫BeautifulSoup快速抓取网站图片(1个评论)
    • vscode 配置 python3开发环境的方法(0个评论)
    • 近期文章
    • 在go+gin中使用"github.com/skip2/go-qrcode"实现url转二维码功能(0个评论)
    • 在go语言中使用api.geonames.org接口实现根据国际邮政编码获取地址信息功能(1个评论)
    • 在go语言中使用github.com/signintech/gopdf实现生成pdf分页文件功能(0个评论)
    • gmail发邮件报错:534 5.7.9 Application-specific password required...解决方案(0个评论)
    • 欧盟关于强迫劳动的规定的官方举报渠道及官方举报网站(0个评论)
    • 在go语言中使用github.com/signintech/gopdf实现生成pdf文件功能(0个评论)
    • Laravel从Accel获得5700万美元A轮融资(0个评论)
    • 在go + gin中gorm实现指定搜索/区间搜索分页列表功能接口实例(0个评论)
    • 在go语言中实现IP/CIDR的ip和netmask互转及IP段形式互转及ip是否存在IP/CIDR(0个评论)
    • PHP 8.4 Alpha 1现已发布!(0个评论)
    • 近期评论
    • 122 在

      学历:一种延缓就业设计,生活需求下的权衡之选中评论 工作几年后,报名考研了,到现在还没认真学习备考,迷茫中。作为一名北漂互联网打工人..
    • 123 在

      Clash for Windows作者删库跑路了,github已404中评论 按理说只要你在国内,所有的流量进出都在监控范围内,不管你怎么隐藏也没用,想搞你分..
    • 原梓番博客 在

      在Laravel框架中使用模型Model分表最简单的方法中评论 好久好久都没看友情链接申请了,今天刚看,已经添加。..
    • 博主 在

      佛跳墙vpn软件不会用?上不了网?佛跳墙vpn常见问题以及解决办法中评论 @1111老铁这个不行了,可以看看近期评论的其他文章..
    • 1111 在

      佛跳墙vpn软件不会用?上不了网?佛跳墙vpn常见问题以及解决办法中评论 网站不能打开,博主百忙中能否发个APP下载链接,佛跳墙或极光..
    • 2016-10
    • 2016-11
    • 2018-04
    • 2020-03
    • 2020-04
    • 2020-05
    • 2020-06
    • 2022-01
    • 2023-07
    • 2023-10
    Top

    Copyright·© 2019 侯体宗版权所有· 粤ICP备20027696号 PHP交流群

    侯体宗的博客