初阶c语言:实战项目三子棋

前言

大家已经和博主学习有一段时间了,今天讲一个有趣的实战项目——三子棋

目录

前言

制作菜单

构建游戏选择框架

实现游戏功能

模块化编程

初始化棋盘

打印棋盘

 玩家下棋

电脑下棋

时间戳:推荐一篇

C语言生成随机数的方法_c语言随机数_杯浅的博客-CSDN博客

判断输赢

游戏逻辑实现


制作菜单

   在玩游戏时,我们在进入游戏都会有菜单选项,选择开始游戏,推出游戏等这些指令,说到选择,那么我们可以依据我们所学的循环和分支语句来先完成基本框架的设计。

首先我们进入游戏都是先显示选项,做出选择,并且在玩游戏时玩一局,还想玩怎么办(想一想我们前边的知识哪种结构符合先进入游戏出现菜单再循环这一需求)那肯定是do…while的循环结构更符合,那么我们就先使用函数来打印输出一个菜单选项

void menu()
{printf("*****************************\n");printf("*****************************\n");printf("**********1.play^************\n");printf("**********0.exit^************\n");//菜单printf("*****************************\n");printf("*****************************\n");
}int main()
{int a = 0;do{menu();printf("请选择:");scanf("%d",&a);}while();  
return 0;
}

构建游戏选择框架

游戏菜单已在屏幕上显示完成,现在需要完成选择,并且在玩游戏时玩一局,还想玩怎么办。

这时候需要应用博主之前阐述的switch语句来实现:

int main()
{int input = 0;do{menu();printf("PLEASE SELECT:");scanf("%d", &input);switch(input){case 1:game();    //以上为界面的选择break;case 0:printf("Exit\n");break;default:printf("ERRO,PLEASE CHOOSE AGAIN\n");break;}} while (input);//while循环可以利用0为假,其余为来实现用户可反复选择
//直到选到合适为止return 0;
}                     

实现游戏功能

模块化编程

这里博主引入一个概念:模块化编程。方便引用,不会显得头重脚轻,而且转为静态库不易被盗用。这里需要创建三个文件:test.c   game.c   game.h   

test.c:是用来实现游戏逻辑    game.c:用来实现游戏功能的函数   game.h:用来申明游戏功能函数(可引用)

传统方式编程:所有的函数均放在main.c里,若使用的模块比较多,则一个文件内会有很多的代码,不利于代码的组织和管理,而且很影响编程者的思路。

模块化编程:把各个模块的代码放在不同的.c文件里,在.h文件里提供外部可调用函数的声明,其它.c文件想使用其中的代码时,只需要#include "XXX.h"文件即可。使用模块化编程可极大的提高代码的可阅读性、可维护性、可移植性等。

传统方式编程:所有的函数均放在main.c里,若使用的模块比较多,则一个文件内会有很多的代码,不利于代码的组织和管理,而且很影响编程者的思路。

模块化编程:把各个模块的代码放在不同的.c文件里,在.h文件里提供外部可调用函数的声明,其它.c文件想使用其中的代码时,只需要#include "XXX.h"文件即可。使用模块化编程可极大的提高代码的可阅读性、可维护性、可移植性等!

总的来说就是:当你代码比较多的时候,就可以采用模块化编程来完成这个程序。 

三子棋,我们需要在棋盘中输入要下的位置,相当于是一个三乘三的数组(这里我们就用到了二维数组的知识),那么游戏开始前需要我们先对棋盘初始化(使数组中的元素都为空格),那么就是数组初始化赋值(只用循环遍历每一个元素并赋予空格就ok了)。

注意:这里设置函数的时候因为用到二维数组,所以函数的形参为数组名,行 ,列

void initboard(char board[row][col], int hang, int lie)
{int i = 0;int j = 0;for (i = 0; i < hang; i++){for (j = 0; j <lie; j++){board[i][j] =' ';}	printf("\n");}
}

打印棋盘

将置空的二维数组用线隔开

void displayboard(char board[row][col], int hang, int lie) //可以随意控制棋盘大小
{int i = 0;for (i = 0; i <hang; i++){int j = 0;for (j = 0; j <lie; j++){printf(" %c ",board[i][j]);if (j < lie - 1)//为了不让最后一行打印‘|’printf("|");}printf("\n");if (i < hang - 1){int j = 0;for (j = 0; j < lie; j++){printf("---");if (j < lie - 1)printf("|");}printf("\n");}}
}

效果图

 玩家下棋

玩家下棋的话使用*标志,利用坐标来将“空格”替换

void player(board[row][col],int hang,int lie)
{int x = 0;int y = 0;
printf("玩家开始下棋");
scanf("%d %d",&a,&b);
if(x>=1&&x<=3&&y>=1&&y<=3)   
{  if(board[x-1][y-1]==' '){board[x-1][y-1]='*';}else
{printf("坐标已经被占用,请重新选择");}else
{printf("坐标非法请重新输入");}}   
}

玩家下完棋需要有对立面,也就是我们的电脑

电脑下棋

时间戳:推荐一篇

C语言生成随机数的方法_c语言随机数_杯浅的博客-CSDN博客

void computer(char board[row][col], int hang, int lie)
{printf("电脑下棋\n");int x = 0;int y = 0;while(1){ x = rand() % hang;//0-2//模取余数不会超过这个数y = rand() % lie;if (board[x][y] ==' '){board[x][y] = '#';break;}}
}

判断输赢

输赢情况分析:行三连,列三连,对角线俩条。

char panduan(char board[row][col], int hang, int lie)
{int i = 0;for (i = 0; i < hang; i++)//行{if(board[i][0]==board[i][1]&&board[i][1]==board[i][2] && board[i][1] != ' '){return board[i][1];//电脑和玩家都可以用这一个判断}}int j = 0;for (j = 0; j< lie; j++)//列
{if (board[0][j] == board[1][j] && board[1][j] == board[2][j] && board[1][j] != ' '){return board[1][j];}}if (board[0][0] == board[1][1] && board[1][1] == board[2][2] && board[1][1] != ' '){return board[1][1];}if (board[0][2] == board[1][1] && board[1][1] == board[2][0] && board[1][1] != ' '){return board[1][1];}//平局if (isfull(board, hang, lie)){return 'q';//平局 else}	return 'c';
}

游戏逻辑实现

创建菜单函数选择 进入游戏 以及 退出游戏。
首先,初始化 棋盘。
然后,再打印棋盘。注意:一定是要先进行 初始化 然后再 打印棋盘。
玩家下棋,并打印出棋盘(玩家输入行、列坐标方式进行落子,'x' = 玩家落子)
判断玩家是否 赢,判断是否 继续游戏。(字符'c'代表 继续游戏、字符'q'代表 游戏平局)
电脑进行落子下棋(随机位置进行落子,'o' = 电脑落子)
判断③种胜负方式!分别是:玩家赢、电脑赢、以及 平局。
然后,再回到步骤①,是否选择 进入游戏 以及 退出游戏。
 

void game()
{int key = 0;char board[row][col] = { 0 };   //不直接写成数字,利于改变棋盘大小//初始化棋盘的函数initboard(board,row,col);displayboard(board,row,col);while(1){player(board, row, col);key=panduan(board, row, col);if(key!='c'){break;}displayboard(board, row, col); computer(board, row, col);key = panduan(board, row, col);if (key != 'c'){break;}displayboard(board, row, col);}	if (key == '*'){printf("玩家胜利\n");}else if(key=='#'){printf("电脑胜利\n");}else if(key=='p'){printf("平局\n");}
}

另外我们还需要将game.c以声明的形式放入game.h中:

#pragma once
#define _CRT_SECURE_NO_WARNINGS 
#include <stdio.h>
#include<windows.h>
#include<stdlib.h>
#include<time.h>//这个全可以调用
#define row 3
#define col 3
//初始化棋盘
void initboard(char board[row][col], int hang, int lie);
//打印棋盘 难点
void displayboard(char board[row][col], int hang, int lie);
//玩家下棋
void player(char board[row][col], int hang, int lie);
//电脑下棋
void computer(char board[row][col], int hang, int lie);
//判断输赢  玩家赢  电脑赢  平  继续/
char panduan(char board[row][col], int hang, int lie);
int isfull(char board[row][col], int hang, int lie);

之后利用test.c来实现游戏逻辑(在编辑的开始需要加上#include''game.h'')

好了今天的文章到这里,希望对大家有帮助!


 

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

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

相关文章

Delegates.observable追踪观察可变数据更新,Kotlin

Delegates.observable追踪观察可变数据更新&#xff0c;Kotlin import kotlin.properties.Delegates import kotlin.reflect.KPropertyclass Person {var name: String by Delegates.observable("fly") { prop: KProperty<*>, old: String, new: String ->p…

虚幻官方项目《CropOut》技术解析 之 程序化岛屿生成器(IslandGenerator)

开个新坑详细分析一下虚幻官方发布的《CropOut》&#xff0c;文章会同步发布到我在知乎|CSDN的专栏里 文章目录 概要Create Island几何体生成部分随机种子Step 1Step 2Step 3Step 4Step 5Step 6 岛屿材质部分动态为草地设置颜色 程序设计的小技巧其它Platform Switch函数 概要 …

Android OpenCV(七十四): Android OpenCV SDK 升级至 4.8.0

前言 如昨日文章所述,OpenCV 4.8.0 已经发布,虽然系列文章已经停更很久,但是版本升级工作笔者是很乐意快速完成的。 OpenCV 4.8.0 Android SDK:https://github.com/opencv/opencv/releases/download/4.8.0/opencv-4.8.0-android-sdk.zip 更新日志:https://github.com/o…

安防视频汇聚平台EasyCVR视频监控综合管理平台H.265转码功能更新,新增分辨率配置的具体步骤

安防视频集中存储EasyCVR视频监控综合管理平台可以根据不同的场景需求&#xff0c;让平台在内网、专网、VPN、广域网、互联网等各种环境下进行音视频的采集、接入与多端分发。在视频能力上&#xff0c;视频云存储平台EasyCVR可实现视频实时直播、云端录像、视频云存储、视频存储…

Open3D 进阶(5)变分贝叶斯高斯混合点云聚类

目录 一、算法原理二、代码实现三、结果展示四、测试数据本文由CSDN点云侠原创,原文链接。如果你不是在点云侠的博客中看到该文章,那么此处便是不要脸的爬虫。 系列文章(连载中。。。爬虫,你倒是爬个完整的呀?): Open3D 进阶(1) MeanShift点云聚类Open3D 进阶(2)DB…

shell脚本之循环语句

循环语句 循环含义 将某代码段重复运行多次&#xff0c;通常有进入循环的条件和退出循环的条件 for循环语句 一般知道循环次数使用for循环 第一类 格式1&#xff1a; for名称 in 取值次数;do;done; 格式2&#xff1a; for 名称 in {取值列表} do done# 打印20次 for i i…

[MySQL]02关于事务的解析

目录 原子性 一致性 持久性 隔离性 事务隔离级别 并发执行可能存在问题 脏读问题 不可重复读 幻读 难点解析 原子性 事务最核心的就是原子性 以前人们认为原子不可再分&#xff0c;用原子性来表示一个事务不可分割 update account set balancebalance-500 where nam…

浅析Java设计模式之四策略模式

title: 浅析Java设计模式之四策略模式 date: 2018-12-29 17:26:17 categories: 设计模式 description: 浅析Java设计模式之四策略模式 1. 目录 1. 目录2. 概念 2.1. 应用场景2.2. 优缺点 2.2.1. 优点2.2.2. 缺点 3. 模式结构4. 样例 4.1. 定义策略4.2. 定义具体策略4.3. 定义…

Android内存泄漏总结和性能优化技巧

我们在开发安卓应用时&#xff0c;性能优化是非常重要的方面。一方面&#xff0c;优化可以提高应用的响应速度、降低卡顿率和提升应用流畅度&#xff0c;从而提升用户体验&#xff1b;另一方面&#xff0c;优化也可以减少应用的资源占用&#xff0c;提高应用的稳定性和安全性&a…

vue3、react组件数据传值对比分析——父组件传递子组件,子组件传递父组件

文章目录 ⭐前言⭐react 组件传值实例&#x1f496;父组件传值给子组件&#xff08;props&#xff09;&#x1f496;子组件传递事件给父组件props绑定事件&#x1f496;父组件触发子组件的事件Ref ⭐vue3 组件传值实例&#x1f496; 父组件传递数据给子组件props&#x1f496; …

【论文阅读】SHADEWATCHER:使用系统审计记录的推荐引导网络威胁分析(SP-2022)

SHADEWATCHER: Recommendation-guided CyberThreat Analysis using System Audit Records S&P-2022 新加坡国立大学、中国科学技术大学 Zengy J, Wang X, Liu J, et al. Shadewatcher: Recommendation-guided cyber threat analysis using system audit records[C]//2022 I…

学C的第三十四天【程序环境和预处理】

相关代码gitee自取&#xff1a; C语言学习日记: 加油努力 (gitee.com) 接上期&#xff1a; 学C的第三十三天【C语言文件操作】_高高的胖子的博客-CSDN博客 1 . 程序的翻译环境和执行环境 在ANSI C(C语言标准)的任何一种实现中&#xff0c;存在两个不同的环境。 &#xff0…

容器虚拟化基础之cgroups/LXC

"你真的&#xff0c;自由了~" 容器虚拟化基础之Cgroups: (1) 什么是cgroups cgroups是 linux 内核提供的一种机制&#xff0c; 这种机制可以根据需求把一系列系统任务及其子任务整合(或分隔)到按资源划分等级的不同组内&#xff0c;从而为系统资源管理提供一个统一…

3D与沉浸式技术,如何助力企业数字化转型?

说起3D&#xff0c;估计许多读者朋友会在第一时间想起《阿凡达》系列和《侏罗纪公园》系列电影大作。每一帧细节纤毫毕现的逼真画面&#xff0c;让观众几乎分不清虚拟与现实&#xff0c;完全沉浸在导演打造的视觉盛宴中。 事实上&#xff0c;除了大家所熟知的3D影视动画之外&am…

快速学习GO语言总结

备注&#xff1a;本博客将自己初步学习GO的总结进行分享&#xff0c;希望大家通过本博客可以在短时间内快速掌握GO的基本程序编码能力&#xff0c;如有错误请留言指正&#xff0c;谢谢&#xff01; 一、初步了解Go语言 &#xff08;一&#xff09;Go语言诞生的主要问题和目标…

iOS17 widget Content margin

iOS17小组件有4个新的地方可以放置分别是&#xff1a;Mac桌面、iPad锁屏界面、 iPhone Standby模式、watch的smart stack Transition to content margins iOS17中苹果为widget新增了Content margin, 使widget的内容能够距离边缘有一定的间隙&#xff0c;确保内容显示完整。这…

学习设计模式之适配器模式,但是宝可梦

前言 作者在准备秋招中&#xff0c;学习设计模式&#xff0c;做点小笔记&#xff0c;用宝可梦为场景举例&#xff0c;有错误欢迎指出。 适配器模式 意图&#xff1a;将一个类的接口转换成客户希望的另一个接口 主要解决&#xff1a;把现有对象放到新环境里&#xff0c;而新…

IDEA 如何制作代码补丁?IDEA 生成 patch 和使用 patch

什么是升级补丁&#xff1f; 比如你本地修复的 bug&#xff0c;需要把增量文件发给客户&#xff0c;很多场景下大家都需要手工整理修改的文件&#xff0c;并整理好目录&#xff0c;这个很麻烦。那有没有简单的技巧呢&#xff1f;看看 IDEA 生成 patch 和使用 patch 的使用。 介…

一、Kafka概述

目录 1.3 Kafka的基础架构 1.3 Kafka的基础架构 Producer&#xff1a;消息生产者&#xff0c;就是向 Kafka broker 发消息的客户端Consumer&#xff1a;消息消费者&#xff0c;向 Kafka broker 取消息的客户端。Consumer Group&#xff08;CG&#xff09;&#xff1a;消费者组&…

PyTorch学习笔记(十六)——利用GPU训练

一、方式一 网络模型、损失函数、数据&#xff08;包括输入、标注&#xff09; 找到以上三种变量&#xff0c;调用它们的.cuda()&#xff0c;再返回即可 if torch.cuda.is_available():mynn mynn.cuda() if torch.cuda.is_available():loss_function loss_function.cuda(…