pygame—炸弹牌(可做课设)

news2024/11/14 14:29:01

游戏介绍

  1. 在5X5的数字宫格里翻牌,翻出所有的2和3即可获胜
  2. 每一格只能是0、1、2、3,
  3. 第六列和最第六行为 X | Y,X代表该列或该行的数字总和,Y代表该列或该行的0的个数
  4. 控制难度,每行每列的数字总和不超过9
  5. 该游戏需要一定运气及技巧

核心代码

生成二维数字列表

def createNumList() -> list:
    arr = []
    for i in range(6):
        row = []
        row_sum = 0
        col_sum = 0
        row_zeros = 0
        col_zeros = 0
        for j in range(5):
            # 从第二行开始计算每列当前和
            col_sum = sum([arr[s - 1][j] for s in range(i)]) if i > 0 else None
            if i < 5:
                num = random.randint(0, 3)
                if col_sum:
                    while row_sum + num > 9 or col_sum + num > 9: # 控制总和
                        num = random.randint(0, 3)
                else:
                    while row_sum + num > 9: # 控制总和
                        num = random.randint(0, 3)
                row.append(num)
                row_sum += num
                row_zeros = row_zeros + 1 if num == 0 else row_zeros
            else:
                # 第六行开始计算每列0的数量
                col_zeros = [arr[s][j] for s in range(5)].count(0)
                row.append((col_sum, col_zeros))
        row.append((row_sum, row_zeros))
        arr.append(row)
    return arr

绘制宫格

def makePalace(numList, window, screen, click_list=[]):
    """
    绘制宫格,根据是否被点击来更改样式
    :param click_list: 被点击的格子,默认没有
    :param numList: 数字列表
    :param window:  surface
    :param screen: screen
    :return: 宫格列表(一维)
    """
    palace_list = []
    for i in range(6):
        for j in range(6):
            # 特殊格子的内容
            if i == 5 or j == 5:
                text = f'{numList[i][j][0]} | {numList[i][j][1]}'
                if i == 5 and j == 5:
                    text = ' '
            else:
                text = numList[i][j]

            # 每一个的样式
            border = 2
            palace_color = color_dict['black']

            if (i, j) in click_list:
                if text == '0':
                    border = 0
                    palace_color = color_dict['red']
                    text_color = color_dict['white']
                else:
                    border = 1
                    text_color = color_dict['black']
            else:
                text_color = color_dict['white']

            if i == 5 or j == 5:
                text_color = color_dict['black']

            palace = makeAndDrawRect(surface=window,
                                     x=(screen.width - screen.height) / 2 + j * screen.height / 6,
                                     y=i * screen.height / 6,
                                     width=screen.height / 6,
                                     height=screen.height / 6,
                                     border=border,
                                     color=palace_color,
                                     text=text,
                                     text_color=text_color,
                                     font_size=70)
            palace_list.append({
                'rect': palace,
                'click': False,
                'index': (i, j),
                'data': text if len(text) == 1 else None
            })
    return palace_list

完整代码

import pygame
import screeninfo
import gameNum

from color import color_dict

pygame.init()


def makeText(surface, txt, x, y, text_color=color_dict['white'], size=40):
    """
    绘制以(x, y)为中心的文本
    :param size:
    :param surface:
    :param txt:
    :param x:
    :param y:
    :param text_color:
    :return:
    """
    font_name = pygame.font.match_font('Microsoft YaHei')
    font = pygame.font.Font(font_name, size)
    text = font.render(txt, True, text_color)
    text_rect = text.get_rect(center=(x, y))
    surface.blit(text, text_rect)


def makeAndDrawRect(surface, x, y, width, height, text=None, border=0, color=color_dict['white'],
                    text_color=color_dict['white'], font_size=40, border_radius=0):
    """
    生成按钮,生成以(x, y)为顶点,文本在中间的按钮
    :param border_radius:
    :param font_size:
    :param text_color:
    :param color:
    :param border:
    :param surface:
    :param x:
    :param y:
    :param width:
    :param height:
    :param text:
    :return: button
    """
    button = pygame.Rect(x, y, width, height)
    pygame.draw.rect(surface, color, rect=button, width=border, border_radius=border_radius)
    if text:
        makeText(surface, text, x + width / 2, y + height / 2, text_color, font_size)
    return button


def makePalace(numList, window, screen, click_list=[]):
    """
    绘制宫格,根据是否被点击来更改样式
    :param click_list: 被点击的格子,默认没有
    :param numList: 数字列表
    :param window:  surface
    :param screen: screen
    :return: 宫格列表(一维)
    """
    palace_list = []
    for i in range(6):
        for j in range(6):
            # 特殊格子的内容
            if i == 5 or j == 5:
                text = f'{numList[i][j][0]} | {numList[i][j][1]}'
                if i == 5 and j == 5:
                    text = ' '
            else:
                text = numList[i][j]

            # 每一个的样式
            border = 2
            palace_color = color_dict['black']

            if (i, j) in click_list:
                if text == '0':
                    border = 0
                    palace_color = color_dict['red']
                    text_color = color_dict['white']
                else:
                    border = 1
                    text_color = color_dict['black']
            else:
                text_color = color_dict['white']

            if i == 5 or j == 5:
                text_color = color_dict['black']

            palace = makeAndDrawRect(surface=window,
                                     x=(screen.width - screen.height) / 2 + j * screen.height / 6,
                                     y=i * screen.height / 6,
                                     width=screen.height / 6,
                                     height=screen.height / 6,
                                     border=border,
                                     color=palace_color,
                                     text=text,
                                     text_color=text_color,
                                     font_size=70)
            palace_list.append({
                'rect': palace,
                'click': False,
                'index': (i, j),
                'data': text if len(text) == 1 else None
            })
    return palace_list


def main():
    screen = screeninfo.get_monitors()[0]
    window = pygame.display.set_mode((screen.width, screen.height))
    pygame.display.set_caption('炸弹牌')

    Gameplay = "每一个格子的数字只能是1、2、3, \n" \
               "'X | Y' 代表了该行或该列的数字之和为X,炸弹数量为Y\n" \
               "找出所有的2和3即为胜利"
    numList = []  # 每一局的数字列表
    clickPalace_indexList = []  # 被点击的格子
    now_2_3_Count = 0
    bt_again = None

    sound_click = pygame.mixer.Sound('turn.wav')
    sound_over = pygame.mixer.Sound('dedede.wav')
    sound_win = pygame.mixer.Sound('win.mp3')

    running = True
    playing = False
    result = None  # True则赢,False则输
    while running:
        window.fill(color_dict['black'])
        # 开始界面
        if playing is False:
            bt_start = makeAndDrawRect(surface=window,
                                       x=(screen.width - 200) / 2,
                                       y=screen.height * 0.7,
                                       width=200,
                                       height=80,
                                       text='开始游戏',
                                       border=5,
                                       border_radius=5)
            bt_exit = makeAndDrawRect(surface=window,
                                      x=(screen.width - 200) / 2,
                                      y=screen.height * 0.7 + 120,
                                      width=200,
                                      height=80,
                                      text='退出游戏',
                                      border=5,
                                      border_radius=5)
            lines = Gameplay.split('\n')
            offset = -60
            for line in lines:
                makeText(window, line, screen.width / 2, screen.height / 2 + offset)
                offset += 60
        else:
            # 生成当局数字
            if numList:
                pass
            else:
                numList = gameNum.elementToStr()

            bt_exit = makeAndDrawRect(surface=window,
                                      x=50,
                                      y=screen.height * 0.7 + 120,
                                      width=200,
                                      height=80,
                                      text='退出游戏',
                                      border=5,
                                      border_radius=5)
            # 正方形白色背景
            makeAndDrawRect(surface=window,
                            x=(screen.width - screen.height) / 2,
                            y=0,
                            width=screen.height,
                            height=screen.height)
            # 根据是否被点击显示内容
            palace_list = makePalace(numList, window, screen, clickPalace_indexList if clickPalace_indexList else [])

            # 游戏结束所显示的内容
            if result is not None:
                bt_again = bt_start = makeAndDrawRect(surface=window,
                                                      x=50,
                                                      y=screen.height * 0.7,
                                                      width=200,
                                                      height=80,
                                                      text='再玩一局',
                                                      border=5,
                                                      border_radius=5)
                if result is True:
                    makeText(window, '你赢了!', screen.width * 0.1, screen.height * 0.5)
                else:
                    makeText(window, '翻到炸弹了!', screen.width * 0.1, screen.height * 0.5)

        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                running = False
            if event.type == pygame.MOUSEBUTTONDOWN:
                if bt_exit.collidepoint(event.pos):
                    sound_click.play()
                    running = False
                if playing is False:
                    if bt_start.collidepoint(event.pos):
                        sound_click.play()
                        playing = True
                        del bt_start
                else:
                    # 点击宫格
                    count_2_3 = len([x for x in palace_list if x['data'] in ['2', '3']])
                    for palace in palace_list:
                        if palace['rect'].collidepoint(event.pos) and result is None:  # 被点击且游戏还没有结束
                            if palace['index'] not in clickPalace_indexList and palace['data']:  # 去重插入数字区数据
                                if palace['data'] == '0':
                                    sound_over.play()
                                    result = False
                                else:
                                    sound_click.play()
                                if palace['data'] != '1':
                                    now_2_3_Count += 1
                                clickPalace_indexList.append(palace['index'])
                    # 所有2和3被找出
                    if count_2_3 == now_2_3_Count and result is not True:
                        sound_win.play()
                        result = True

                # 游戏结束
                if result is not None and bt_again:
                    if bt_again.collidepoint(event.pos):
                        sound_click.play()
                        result = None
                        now_2_3_Count = 0
                        numList = []
                        clickPalace_indexList = []
                        bt_again = None

        pygame.display.flip()
    pygame.quit()


if __name__ == '__main__':
    main()

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

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

相关文章

Vue3学习笔记之数据绑定篇(0823)

学习完Vue2 的C友们&#xff0c;今天继续追赶Vue3的大潮流吧&#xff01; 废话不多说&#xff0c;直接上代码 <!DOCTYPE html> <html lang"zh-CN"> <head><meta charset"UTF-8"><meta name"viewport" content"…

MobaXterm接触session会话保存14个的限制

问题描述 在我们使用MobeXterm的过程中&#xff0c;发现session保存了14个之后&#xff0c;再无法继续保存了&#xff1b; 原因是免费版本的MobeXterm的最大个数被限制了&#xff0c;需要进行破解&#xff1b; MobaXterm-keygen解除session保存限制的python脚本 可以使用上面…

计算机的错误计算(七十一)

摘要 计算机的错误计算&#xff08;七十&#xff09;探讨了大数的正割函数的错误计算。本节讨论另外一类数值&#xff1a; 附近数 的正割函数的计算精度问题。 例1. 已知 计算 若用 在 Python下编程计算&#xff0c;则有 若在 Excel 中计算&#xff0c;则有&#xff1a…

Xmind 在线导图上线!多设备实时同步,节约本地空间

在现代职场上&#xff0c;高效的工作方法对于提升个人和团队的生产力至关重要。 Xmind 作为一款领先的思维导图软件&#xff0c;最近推出了其在线版本&#xff0c;旨在帮助我们解决在工作中常见的 「掉线状态」 问题&#xff0c;并提升工作效率。 在日常工作中&#xff0c;我们…

抖音如何去水印导出,3种高效工具让你轻松掌握

在抖音上&#xff0c;我们经常会遇到一些精彩视频想要保存下来&#xff0c;但视频上往往带有水印&#xff0c;影响了观看和分享的体验。下面&#xff0c;我将介绍三种去除抖音视频水印的方法&#xff0c;让你轻松保存无水印视频。 技巧一&#xff1a;奈斯水印助手(小程序) 这是…

基于大语言模型的物联网(artificial intelligence of thing)

与当下热门的AI类似&#xff0c;曾几何时&#xff0c;物联网&#xff08;Internet of thing&#xff09;实现“万物互联"给人类带来了无限的遐想。但是往往事与愿违&#xff0c;美好的愿景并没有如约而至。十几年来&#xff0c;物联网远没有实现”万物互联“的美好愿景。 …

Kafka·Producer

Producer发送原理 拦截器进行拦截 对key和value进行序列化 org.apache.kafka.clients.producer.KafkaProducer#doSend 分区选择 计算消息要发送到topic的哪个分区上 若指定了分区&#xff0c;则使用指定的值没有指定的话则使用分区器计算得到或者使用hash取余的方式 暂存…

Stm32通过SPI读写W25QXX

Printf的重定向 因为printf是c中的库函数&#xff0c;要使用printf输出到串口&#xff0c;需要重定向&#xff0c;将printf定向到HAL_UART_Transmit。 新建一个retarget.c文件。 #include "stdio.h" #include "stm32f1xx_hal.h" #include "usart.h&…

创意无限,尽在掌握:热门视频剪辑软件一览

我们记录生活、分享故事、传播信息用视频的频率越来越高了。而这些视频往往都是通过剪辑之后才能展示出当前的效果。那这次我们就来探索剪辑视频的时候都会用到什么工具吧。 1.福昕视频剪辑 连接直达>>https://www.pdf365.cn/foxit-clip/ 这是一款专为追求高效与创意…

Pytorch 张量运算函数(补充)

mean() mean()函数是进行张量均值计算的函数,常用参数可以设置参数dim来进行对应维度的均值计算 以下是使用一个二维张量进行演示的例子 import numpy as np import torch device torch.device(mps if torch.backends.mps.is_available() else cpu) print(device ) data1 …

【数据管理】数据治理

目录 1、相关概念 2、数据治理和管理职责语境关系图 3、业务驱动因素 4、目标和原则 5、 数据治理和数据管理的关系 6、数据治理组织 7、数据管理职能 8、数据制度 9、数据资产估值 1、相关概念 1&#xff09;战略(Stategy)&#xff1a;定义、交流和驱动数据战略和数…

[数据集][目标检测]电力场景输电线异物检测数据集VOC+YOLO格式2060张1类别

数据集格式&#xff1a;Pascal VOC格式YOLO格式(不包含分割路径的txt文件&#xff0c;仅仅包含jpg图片以及对应的VOC格式xml文件和yolo格式txt文件) 图片数量(jpg文件个数)&#xff1a;2060 标注数量(xml文件个数)&#xff1a;2060 标注数量(txt文件个数)&#xff1a;2060 标注…

电脑丢失dll文件一键修复之dll确实损坏影响电脑运行

在使用电脑过程中&#xff0c;DLL文件丢失或损坏是一个常见的问题&#xff0c;它可能导致程序无法正常运行&#xff0c;甚至影响整个系统的稳定性。本文将详细介绍如何一键修复丢失的DLL文件&#xff0c;探讨常见的DLL丢失报错原因&#xff0c;并提供详细的修复步骤和预防措施。…

sklearn回归树

说明&#xff1a;内容来自菜菜的sklearn机器学习和ai生成 回归树 调用对象的参数 class sklearn.tree.DecisionTreeRegressor (criterion’mse’, splitter’best’, max_depthNone, min_samples_split2, min_samples_leaf1, min_weight_fraction_leaf0.0, max_featuresNone…

大数据基础:数仓架构演变

文章目录 数仓架构演变 一、传统离线大数据架构 二、​​​​​​Lambda架构 三、Kappa架构 四、​​​​​​​​​​​​​​混合架构 五、湖仓一体架构 六、流批一体架构 数仓架构演变 20世纪70年代&#xff0c;MIT(麻省理工)的研究员致力于研究一种优化的技术架构&…

Linux shell编程学习笔记75:sed命令——沧海横流任我行(下)

0 前言 在 Linux shell编程学习笔记73&#xff1a;sed命令——沧海横流任我行&#xff08;上&#xff09;-CSDN博客文章浏览阅读684次&#xff0c;点赞32次&#xff0c;收藏24次。在大数据时代&#xff0c;我们要面对大量数据&#xff0c;有时需要对数据进行替换、删除、新增、…

OpenCV几何图像变换(9)仿射变换函数warpAffine()的使用

操作系统&#xff1a;ubuntu22.04 OpenCV版本&#xff1a;OpenCV4.9 IDE:Visual Studio Code 编程语言&#xff1a;C11 算法描述 函数是应用一个仿射变换到图像上。 warpAffine 函数使用指定的矩阵对源图像进行仿射变换&#xff1a; dst ( x , y ) src ( M 11 x M 12 y M…

Elasticsearch:使用 ELSER 进行语义搜索 - sparse_vector

Elastic Learned Sparse EncodeR&#xff08;或 ELSER&#xff09;是由 Elastic 训练的 NLP 模型&#xff0c;可让你使用稀疏向量表示执行语义搜索。语义搜索不是根据搜索词进行文字匹配&#xff0c;而是根据搜索查询的意图和上下文含义检索结果。 本教程中的说明向你展示了如…

[医疗 AI ] 3D TransUNet:通过 Vision Transformer 推进医学图像分割

[医疗 AI ] 3D TransUNet&#xff1a;通过 Vision Transformer 推进医学图像分割’ 论文地址 - https://arxiv.org/pdf/2310.07781 0. 摘要 医学图像分割在推进医疗保健系统的疾病诊断和治疗计划中起着至关重要的作用。U 形架构&#xff0c;俗称 U-Net&#xff0c;已被证明在…

提高实时多媒体传输效率的三大方法

实时多媒体数据传输面临的挑战 实时多媒体数据的传输具有数据量巨大、对时延和时延抖动高度敏感及能容忍丢分组的特点。然而&#xff0c;当今互联网的网络层协议提供的仅是一种“尽最大努力服务”&#xff0c;对分组的端到端时延、时延抖动和分组丢失率等指标不做任何承诺。这…