python实现五子棋游戏(pygame版)(附零基础学习资料)

news2024/11/14 23:50:18

前言

使用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 sys
import 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.font
class 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 sys
import 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 pygame
from settings import Settings
from checkerboard import Checkerboard
from collections import namedtuple
import game_functions as gf
from 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、加上开始游戏按钮,

3、胜负榜单等,

读者福利:知道你对Python感兴趣,便准备了这套python学习资料,

对于0基础小白入门:

如果你是零基础小白,想快速入门Python是可以考虑的。

一方面是学习时间相对较短,学习内容更全面更集中。
二方面是可以找到适合自己的学习方案

包括:Python web开发,Python爬虫,Python数据分析,人工智能、机器学习等教程。带你从零基础系统性的学好Python!

零基础Python学习资源介绍

👉Python学习路线汇总👈

Python所有方向的技术点做的整理,形成各个领域的知识点汇总,它的用处就在于,你可以按照上面的知识点去找对应的学习资源,保证自己学得较为全面。(学习教程文末领取哈)

👉Python必备开发工具👈

温馨提示:篇幅有限,已打包文件夹,获取方式在:文末

👉Python学习视频600合集👈

观看零基础学习视频,看视频学习是最快捷也是最有效果的方式,跟着视频中老师的思路,从基础到深入,还是很容易入门的。

👉实战案例👈

光学理论是没用的,要学会跟着一起敲,要动手实操,才能将自己的所学运用到实际当中去,这时候可以搞点实战案例来学习。

👉100道Python练习题👈

检查学习结果。

👉面试刷题👈



在这里插入图片描述

资料领取

这份完整版的Python全套学习资料已为大家备好,朋友们如果需要可以微信扫描下方二维码添加,输入"领取资料" 可免费领取全套资料【有什么需要协作的还可以随时联系我】朋友圈也会不定时的更新最前言python知识。
在这里插入图片描述

好文推荐

了解python的前景: https://blog.csdn.net/weixin_49892805/article/details/127196159

python有什么用: https://blog.csdn.net/weixin_49892805/article/details/127214402

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/23386.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

APT 攻击溯源方法

概述&#xff1a; 当今世界正值百年未有之大变局&#xff0c;网络空间成为继陆、海、空、天之后的第五大疆域&#xff0c;安全威胁也随之延伸至网络空间。没有网络安全就没有国家安全&#xff0c;在新时代网络空间安全已经上升至国家安全的高度。高级持续性威胁(Advanced Pers…

yolov1模型

目录 一、机器视觉算法 二、yolov1 预测阶段&#xff08;向前推断&#xff09;​ 三、预测阶段的后处理 &#xff08;声明&#xff1a;本文章是在学习他人视频的学习笔记&#xff0c;图片出处均来自该up主&#xff0c;侵权删 视频链接&#xff1a;为什么要学YOLOV1_哔哩哔哩_b…

拿铁DHT-PHEV座舱智能程度体验笔记(超详细)

评测时间&#xff1a; •第一次 2022年10月1日-10月7日 •第二次 2022年10月25日 评测配置&#xff1a; •两驱超大杯 18.98万元好评功能盘点 座舱芯片及内存&#xff1a;高通骁龙 8155&#xff0c;算力8TOPS&#xff0c;存储8GB&#xff0c;内存12G&#xff0c;一流的配置。 四…

领悟《信号与系统》之 连续时间信号的时域分析法

连续时间信号的时域分析法一、LTI 连续系统的响应1. LTI 微分方程的建立与求解2. LTI 连续系统的零输入响应与零状态响应1. 零输入响应2. 零状态响应3. 全响应二、冲激响应和阶跃响应1. 冲激响应2. 阶跃响应三、卷积积分及其性质1. 任意信号的分解2. 任意信号作用下的零状态响应…

一个合格的中级前端工程师需要掌握的 28 个 JavaScript 技巧

1. 判断对象的数据类型 使用 Object.prototype.toString 配合闭包&#xff0c;通过传入不同的判断类型来返回不同的判断函数&#xff0c;一行代码&#xff0c;简洁优雅灵活&#xff08;注意传入 type 参数时首字母大写&#xff09; 不推荐将这个函数用来检测可能会产生包装类型…

【跨境电商】6种实用有效的策略帮助改善客户沟通

关键词&#xff1a;跨境电商卖家、客户沟通 1.什么是客户沟通&#xff1f; 客户沟通是公司与消费者的互动。品牌识别接触点并通过各种渠道&#xff08;例如电话、电子邮件和实时聊天&#xff09;在每个接触点建立关系。公司可以通过始终如一的参与并将消费者置于这种互动的中心…

【Redis】内存回收:内存淘汰策略

【Redis】内存回收&#xff1a;内存淘汰策略 文章目录【Redis】内存回收&#xff1a;内存淘汰策略一、Redis内存回收-过期key处理二、Redis内存回收-内存淘汰策略一、Redis内存回收-过期key处理 如果你发现&#xff0c;平时在操作 Redis 时&#xff0c;并没有延迟很大的情况发生…

Watermelon Book(二)线性模型

文章目录线性回归对数几率回归线性类别分类多分类学习类别不平衡问题基本形式&#xff1a;若给定 d个属性描述的示例x(x1,x2,x3…xd)&#xff0c;则线性模型试图学得一个 通过属性的线性组合来进行预测。f(x)W1*X1W2*X2...Wn*Xnw(T)xbw(w1;w2;w3;wn;)线性模型形式简单、易于建模…

[附源码]java毕业设计校园共享单车系统

项目运行 环境配置&#xff1a; Jdk1.8 Tomcat7.0 Mysql HBuilderX&#xff08;Webstorm也行&#xff09; Eclispe&#xff08;IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持&#xff09;。 项目技术&#xff1a; SSM mybatis Maven Vue 等等组成&#xff0c;B/S模式 M…

排序算法——七种排序算法汇总,详细

文章目录排序排序的概念及应用一、直接插入排序1. 简介2.动图展示3.过程4.代码5.总结二、希尔排序1.简介2.过程3.代码4.总结三、选择排序1.简介2.代码3.总结四、堆排序1.代码2.总结五、冒泡排序1.过程2.代码3.总结六、快速排序1.简介2.过程3.两种优化快速排序的思想4.代码-递归…

【附源码】计算机毕业设计JAVA学生校内兼职管理平台

【附源码】计算机毕业设计JAVA学生校内兼职管理平台 目运行 环境项配置&#xff1a; Jdk1.8 Tomcat8.5 Mysql HBuilderX&#xff08;Webstorm也行&#xff09; Eclispe&#xff08;IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持&#xff09;。 项目技术&#xff1a; JAVA…

什么是 SSH 密钥? 生成、身份验证、密钥对信息等

SSH 密钥不仅可以提高安全性&#xff0c;还可以实现当今企业所需的大规模连接流程、单点登录 (SSO) 以及身份和访问管理的自动化。 什么是 SSH 密钥&#xff1f; SSH 密钥是安全外壳 (SSH) 协议中使用的安全访问凭证。 SSH 密钥使用基于公钥基础设施 (PKI) 技术&#xff08;数…

Android12窗口模糊(二)高斯模糊API源码解析

前言 在 Android 12 中&#xff0c;提供了一些用于实现窗口模糊处理效果&#xff08;例如背景模糊处理和模糊处理后方屏幕&#xff09;的公共 API。窗口模糊处理或跨窗口模糊处理用于模糊处理给定窗口后方的屏幕。 有两种窗口模糊处理方式&#xff0c;可用于实现不同的视觉效果…

不小心清空了回收站怎么恢复,回收站删除的东西可以恢复吗

不小心清空了回收站怎么恢复&#xff1f;回收站是操作系统提供的一个非常实用的功能&#xff0c;专门为用户保存从电脑硬盘删除的各种数据&#xff0c;因而很多时候我们都会用到回收站&#xff0c;它能够保存各种数据&#xff0c;我们也能够在里面恢复自己想要的数据&#xff0…

Flutter组件--AppBar相关属性

AppBar介绍 AppBar是基于Material Design设计风格的应用栏&#xff0c;一般使用在Scaffold内部&#xff0c;作为顶部导航栏。 为什么需要AppBar 1、因为导航栏里面一般由左侧功能键&#xff08;返回键、菜单键&#xff09;、标题、右侧功能键组成&#xff0c;而AppBar里面内置…

django的使用步骤详细

一、安装django pip install django 二、创建django项目 放django文件的的文件路径上输入cmd进入终端输入下面的命令 django-admin startproject 项目名称 三、app的创建 进入创建好的项目里面输入一下的命令 python manage.py startapp app名称 四、注册app 五、编写U…

计算机视觉:基于Numpy的图像处理技术(二):图像主成分分析(PCA)

计算机视觉&#xff1a;基于Numpy的图像处理技术&#xff08;二&#xff09;&#xff1a;图像主成分分析&#x1f3f3;️‍&#x1f308; 文章目录计算机视觉&#xff1a;基于Numpy的图像处理技术&#xff08;二&#xff09;&#xff1a;图像主成分分析:rainbow_flag:图像主成分…

企业数据泄漏事件频发,如何防止企业数据泄漏?

2022年即将接近尾声&#xff0c;这一年受疫情和国际经济形势影响&#xff0c;各行各业都不太好过&#xff0c;同样互联网领域发展不平衡、规则不健全、秩序不合理等问题日益凸显&#xff0c;虽然互联网的快速发展为企业数字化转型提供了支撑&#xff0c;但是互联网发展进程中“…

Android App开发动画特效之利用滚动器实现平滑翻页(附源码和演示 简单易懂)

需要图片集请点赞关注收藏后评论区留言~~~ 一、利用滚动器实现平滑翻页 在日常生活中&#xff0c;平移动画比较常见&#xff0c;有时也被称为位移动画&#xff0c;左右翻页和上下滚动其实都用到了平移动画&#xff0c;譬如平滑翻书的动画效果&#xff0c;就是位移动画的一种应…

BHQ-3 amine,1661064-89-6可在430nm至730nm范围内猝灭所有普通荧光团

英文名称&#xff1a;BHQ-3 amine CAS&#xff1a;1661064-89-6 外观&#xff1a;深紫色粉末 分子式&#xff1a;C32H36N7 分子量&#xff1a;518.69 储存条件&#xff1a;-20C&#xff0c;避光避湿 结构式&#xff1a; 凯新生物产品简介&#xff1a;干燥的寡核苷酸在环境…