12. 利用“文件组织”实现石头剪刀布小游戏

文章目录

    • 概要
    • 整体架构流程
    • 技术名词解释
    • 小结

1. 概要

 ~  Jack Qiao对米粒说:“前面咱们了解过“文件组织”,让我们利用“文件组织”来制作一个有趣的“石头、剪刀、布”小游戏。”举个栗子

>  程序随机生成一个选择(石头、剪刀、布)。

>  用户输入自己的选择。

>  程序比较用户的选择和计算机的选择,决定胜负。

>  输出比赛结果。

~  米粒思考后,将这个游戏分为3个部分:

>  头文件 rps.h:声明游戏相关的函数。

>  源文件 rps.c:实现游戏相关的函数。

>  主程序 main.c:调用游戏函数并运行游戏。

2. 整体架构流程

2.1. 头文件

#ifndef RPS_GAME_H
#define RPS_GAME_H

void play_rps();

#endif // RPS_GAME_H

 声明了 play_rps 函数,以便在其他文件中调用。

2.2. 源文件 

#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include "rps_game.h"

// 定义游戏选项
enum Choice { ROCK, PAPER, SCISSORS };

// 获取用户输入
int get_user_choice() {
    int choice;
    printf("请选择:1. 石头  2. 剪刀  3. 布\n");
    int result = scanf("%d", &choice);

    // 检查 scanf 是否成功读取一个整数
    if (result != 1) {
        printf("输入错误,请重新输入。\n");
        // 清除输入缓冲区
        while (getchar() != '\n');
        return get_user_choice(); // 递归调用,重新获取输入
    }

    while (choice < 1 || choice > 3) {
        printf("无效输入,请重新选择:1. 石头  2. 剪刀  3. 布\n");
        result = scanf("%d", &choice);
        if (result != 1) {
            printf("输入错误,请重新输入。\n");
            // 清除输入缓冲区
            while (getchar() != '\n');
            return get_user_choice(); // 递归调用,重新获取输入
        }
    }
    return choice - 1; // 转换为0, 1, 2
}

// 获取计算机选择
int get_computer_choice() {
    return rand() % 3;
}

// 判断胜负
char* determine_winner(int user_choice, int computer_choice) {
    if (user_choice == computer_choice) {
        return "平局";
    }
    else if ((user_choice == ROCK && computer_choice == SCISSORS) ||
        (user_choice == PAPER && computer_choice == ROCK) ||
        (user_choice == SCISSORS && computer_choice == PAPER)) {
        return "你赢了";
    }
    else {
        return "你输了";
    }
}

// 打印选择
void print_choice(int choice) {
    switch (choice) {
    case ROCK:
        printf("石头");
        break;
    case PAPER:
        printf("布");
        break;
    case SCISSORS:
        printf("剪刀");
        break;
    }
}

void play_rps() {
    // 初始化随机数生成器
    srand(time(NULL));

    int user_choice = get_user_choice();
    int computer_choice = get_computer_choice();

    printf("你的选择:");
    print_choice(user_choice);
    printf("\n计算机的选择:");
    print_choice(computer_choice);
    printf("\n");

    char* result = determine_winner(user_choice, computer_choice);
    printf("%s\n", result);
}

 实现了 play_rps 函数,包含了游戏的主要逻辑,包括获取用户和计算机的选择、判断胜负和打印结果。

2.2.1.  定义游戏选项
enum Choice { ROCK, PAPER, SCISSORS };

  这里枚举类型 (enum)

  • 知识点:枚举类型 (enum) 是一种用户自定义的数据类型,用于定义一组命名的整数常量。在本程序中,ROCKPAPER  SCISSORS 分别对应整数值 01  2
  • 作用:使用枚举类型可以使代码更具可读性和可维护性,避免使用魔法数字(如 012),使代码更清晰
 2.2.2. 输入验证和错误处理
int get_user_choice() {
    int choice;
    printf("请选择:1. 石头  2. 剪刀  3. 布\n");
    int result = scanf("%d", &choice);

    if (result != 1) {
        printf("输入错误,请重新输入。\n");
        while (getchar() != '\n');
        return get_user_choice();
    }

    while (choice < 1 || choice > 3) {
        printf("无效输入,请重新选择:1. 石头  2. 剪刀  3. 布\n");
        result = scanf("%d", &choice);
        if (result != 1) {
            printf("输入错误,请重新输入。\n");
            while (getchar() != '\n');
            return get_user_choice();
        }
    }
    return choice - 1;
}

  输入验证和错误处理

  • 知识点:输入验证和错误处理是确保程序健壮性的关键。scanf 函数的返回值用于检查是否成功读取了预期的数据类型。
  • 作用:通过检查 scanf 的返回值和清除输入缓冲区,确保用户输入有效,并在输入无效时提示用户重新输入
 2.2.3.  随机数生成
int get_computer_choice() {
    return rand() % 3;
}

void play_rps() {
    srand(time(NULL));
    // ...
}

   随机数生成器

  • 知识点rand() 函数生成一个伪随机数,srand() 函数用于初始化随机数生成器。
  • 作用rand() % 3 生成一个范围在 [0, 2] 之间的随机数,模拟计算机的选择。 
  • 其中srand(time(NULL)) 使用当前时间作为种子,确保每次运行程序时生成的随机数序列不同。

2.3.  主程序

#include <stdio.h>
#include "rps_game.h"

int main() {
    play_rps();
    return 0;
}

 >  主程序 main.c:调用了 play_rps 函数,启动游戏。

2.4. 运行结果 

3. 技术名词解释

这里枚举类型 (enum)

  • 知识点:枚举类型 (enum) 是一种用户自定义的数据类型,用于定义一组命名的整数常量。在本程序中,ROCKPAPER  SCISSORS 分别对应整数值 01  2
  • 作用:使用枚举类型可以使代码更具可读性和可维护性,避免使用魔法数字(如 012),使代码更清晰
  • 举个栗子
#include <stdio.h>

enum Color { RED, GREEN, BLUE };

int main() {
    enum Color myColor = GREEN;

    if (myColor == GREEN) {
        printf("颜色是绿色。\n");
    }

    return 0;
}

 4. 小结

~  通过这个小游戏,米粒深刻认识到: 

文件组织”通过将功能相关的代码分组,枚举类型定义了游戏选项提高了代码的可读性和可维护性

>  函数封装条件判断实现了游戏逻辑的清晰和模块化,使得代码结构更加简洁。

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

VRT: 关于视频修复的模型

VRT: 关于视频修复的模型 1. 视频修复的背景与重要性背景介绍&#xff1a;重要性&#xff1a; 2. VRT的重要性和研究背景VRT的背景&#xff1a;VRT的重要性&#xff1a; 3. 视频修复概述3.1 定义与目标3.2 与单图像修复的区别3.3 对时间信息利用的需求 4. VRT模型详解4.1 整体框…

Stable Diffusion经典应用场景

&#x1f33a;系列文章推荐&#x1f33a; 扩散模型系列文章正在持续的更新&#xff0c;更新节奏如下&#xff0c;先更新SD模型讲解&#xff0c;再更新相关的微调方法文章&#xff0c;敬请期待&#xff01;&#xff01;&#xff01;&#xff08;本文及其之前的文章均已更新&…

04 —— Webpack打包CSS代码

加载器css-loader &#xff1a;解析css代码 webpack 中文文档 | webpack中文文档 | webpack中文网 加载器style-loader&#xff1a;把解析后的css代码插入到DOM style-loader | webpack 中文文档 | webpack中文文档 | webpack中文网 准备css代码&#xff0c;放到src/login目…

springboot高校网上缴费综合务系统

摘 要 相比于以前的传统手工管理方式&#xff0c;智能化的管理方式可以大幅降低运营人员成本&#xff0c;实现了高校网上缴费综合务系统的标准化、制度化、程序化的管理&#xff0c;有效地防止了高校网上缴费综合务的随意管理&#xff0c;提高了信息的处理速度和精确度&#x…

IDEA怎么定位java类所用maven依赖版本及引用位置

在实际开发中&#xff0c;我们可能会遇到需要搞清楚代码所用依赖版本号及引用位置的场景&#xff0c;便于排查问题&#xff0c;怎么通过IDEA实现呢&#xff1f; 可以在IDEA中打开项目&#xff0c;右键点击maven的pom.xml文件&#xff0c;或者在maven窗口下选中项目&#xff0c;…

springMVC重点知识

一、springMVC请求流程 二、springMVC环境搭建 Idea 下创建 springmvc01 ⼯程 1、pom.xml 坐标添加 <properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <maven.compiler.source>12</maven.compiler.source> …

django基于python 语言的酒店推荐系统

摘 要 酒店推荐系统旨在提供一个全面酒店推荐在线平台&#xff0c;该系统允许用户浏览不同的客房类型&#xff0c;并根据个人偏好和需求推荐合适的酒店客房。用户可以便捷地进行客房预订&#xff0c;并在抵达后简化入住登记流程。为了确保连续的住宿体验&#xff0c;系统还提供…

机器学习笔记——30种常见机器学习算法简要汇总

本笔记介绍机器学习中常见的30种机器学习算法。 文章目录 监督学习算法&#xff08;Supervised Learning&#xff09;回归算法&#xff08;Regression Algorithms&#xff09;分类算法&#xff08;Classification Algorithms&#xff09; 无监督学习算法&#xff08;Unsupervis…

Vue3、Vite5、Primevue、Oxlint、Husky9 简单快速搭建最新的Web项目模板

Vue3、Vite5、Oxlint、Husky9 简单搭建最新的Web项目模板 特色进入正题创建基础模板配置API自动化导入配置组件自动化导入配置UnoCss接入Primevue接入VueRouter4配置项目全局环境变量 封装Axios接入Pinia状态管理接入Prerttier OXLint ESLint接入 husky lint-staged&#xf…

利用RAGflow和LM Studio建立食品法规问答系统

前言 食品企业在管理标准、法规&#xff0c;特别是食品原料、特殊食品法规时&#xff0c;难以通过速查法规得到准确的结果。随着AI技术的发展&#xff0c;互联网上出现很多AI知识库的解决方案。 经过一轮测试&#xff0c;找到问题抓手、打通业务底层逻辑、对齐行业颗粒度、沉…

百度智能云千帆大模型平台引领企业创新增长

本文整理自百度世界大会 2024——「智能跃迁 产业加速」论坛的同名演讲。 更多大会演讲内容&#xff0c;请访问&#xff1a; https://baiduworld.baidu.com 首先&#xff0c;跟大家分享一张图&#xff0c;这个是我们目前大模型应用落地的场景分布。可以看到&#xff0c;大模型…

人形机器人开发、XR仿真训练、影视动画制作,一副手套支持多种应用

近日&#xff0c;动作捕捉数据手套供应商Manus 推出了其最新产品Metagloves Pro。其最大特点是佩戴更加方便简洁且精度更高。Metagloves Pro功能强大且适用于多种应用场景&#xff0c;包括&#xff1a;人形机器人研究、XR仿真训练以及影视动画制作等。 一、人形机器人研究 Man…

sql server怎样用sql profiler捕获带变量值的慢sql

一 新建跟踪 点击工具-SQL Server Profiler&#xff1a; 点击文件-新建跟踪的按钮&#xff1a; 在‘事件选择’选项卡只选择如下两项内容&#xff08;RPC:Completed,SQL:BatchCompleted&#xff09;&#xff0c;把多余的取消勾选&#xff1a; 然后勾选上面截图中右下方的‘显示…

Linux中虚拟内存详解

一、虚拟内存的概念 虚拟内存是现代操作系统为了有效管理内存资源、提高内存利用率以及实现多任务处理等目的而引入的一种重要的内存管理机制。它为每个程序&#xff08;通常对应一个进程&#xff09;提供了一个看似连续且容量较大的地址空间&#xff0c;而这个地址空间并不一…

Qt、C++实现五子棋人机对战与本地双人对战(高难度AI,极少代码)

介绍 本项目基于 Qt C 实现了一个完整的五子棋游戏&#xff0c;支持 人机对战 和 人人对战 模式&#xff0c;并提供了三种难度选择&#xff08;简单、中等、困难&#xff09;。界面美观&#xff0c;逻辑清晰&#xff0c;是一个综合性很强的 Qt 小项目 标题项目核心功能 棋盘…

Vue非单文件组件

目录 Vue非单文件组件 几个注意点 组件的嵌套 关于VueComponent 重要的内置关系 Vue非单文件组件 Vue中使用组件的三大步骤&#xff1a; 一、定义组件(创建组件) 二、注册组件 三、使用组件(写组件标签) 一、…

关于C++地址交换的实现

关于地址的交换实现&#xff0c;我们要使用指针引用的方式进行&#xff0c;例如&#xff1a; #include <iostream>// 定义函数交换两个整型指针的地址 void swapIntPtrAddresses(int* &ptr1, int* &ptr2) {int *temp ptr1;ptr1 ptr2;ptr2 temp; }int main() …

Windows 软件之 FFmpeg

文章目录 前言1 FFmpeg 视频处理1.1 编解码1.2 其它视频编辑命令1.3 视频抽帧 2 FFmpeg 音频处理3 FFmpeg 图片处理3.1 编解码3.2 拼接图片3.3 图片合成视频 附录1&#xff1a;mediainfo.ps1 前言 FFmpeg 是一套可以用来记录、转换数字音频、视频&#xff0c;并能将其转化为流的…

Android okhttp 网络链接各阶段监控

步骤 1: 添加依赖 在项目的 build.gradle 文件中&#xff0c;添加 OkHttp 依赖&#xff1a; implementation com.squareup.okhttp3:okhttp:4.11.0 步骤 2: 创建自定义的 EventListener 创建一个自定义的 EventListener 类&#xff1a; import android.util.Log import okht…

【Java】字节码文件

字节码文件组成部分 1、基本信息 1.1 Magic 魔数 文件是无法通过文件扩展名来确定文件类型的&#xff0c;文件扩展名可以随意修改&#xff0c;不影响文件的内容。软件使用文件的头几个字节&#xff08;文件头&#xff09;去校验文件的类型&#xff0c;如果软件不支持该种类型就…