当前位置: 首页 > news >正文

初阶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'')

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


 

相关文章:

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

前言 大家已经和博主学习有一段时间了&#xff0c;今天讲一个有趣的实战项目——三子棋 目录 前言 制作菜单 构建游戏选择框架 实现游戏功能 模块化编程 初始化棋盘 打印棋盘 玩家下棋 电脑下棋 时间戳&#xff1a;推荐一篇 C语言生成随机数的方法_c语言随机数_杯浅…...

计网第三章(数据链路层)(三)

一、点对点协议PPP 在第一篇里有提到数据链路层的信道分为两种&#xff1a;点对点信道和广播信道。 PPP协议就属于点对点信道上的协议。 如果对前面数据链路层的三个基本问题了解的比较透彻&#xff0c;那么这一块很多东西都很好理解。 从考试的角度来讲&#xff0c;PPP协议…...

蓝桥杯每日N题 (砝码称重)

大家好 我是寸铁 希望这篇题解对你有用&#xff0c;麻烦动动手指点个赞或关注&#xff0c;感谢您的关注 不清楚蓝桥杯考什么的点点下方&#x1f447; 考点秘籍 想背纯享模版的伙伴们点点下方&#x1f447; 蓝桥杯省一你一定不能错过的模板大全(第一期) 蓝桥杯省一你一定不…...

Opencv 视频的读取与写入

目录 前言 通过路径获取视频内容 获取视频内容 检查是否正确打开 循环播放 完整代码 从摄像头读取视频数据 获取视频设备 其他与直接读取视频一致 完整实例 录制视频 用于创建视频编解码器的四字符码&#xff08;FourCC&#xff09; cv2.VideoWriter() 将视频帧…...

LeetCode 833. Find And Replace in String【字符串,哈希表,模拟】1460

本文属于「征服LeetCode」系列文章之一&#xff0c;这一系列正式开始于2021/08/12。由于LeetCode上部分题目有锁&#xff0c;本系列将至少持续到刷完所有无锁题之日为止&#xff1b;由于LeetCode还在不断地创建新题&#xff0c;本系列的终止日期可能是永远。在这一系列刷题文章…...

Cesium轨迹漫游及视角切换

飞行漫游&#xff0c;就是让Camera飞行。Camera有一些方法可以实现位置、视角的调整&#xff0c;比如flyTo&#xff0c;setView方法。但这些方法并不能沿着我们想要的路径调整&#xff0c;在通过插值的方法不停的调用setView&#xff0c;但这样会造成视图卡顿&#xff0c;而且计…...

构建去中心化微服务集群,满足高可用性和高并发需求的实践指南!

随着互联网技术的不断发展&#xff0c;微服务架构已经成为了开发和部署应用程序的一种主流方式。然而&#xff0c;当应用程序需要满足高可用性和高并发需求时&#xff0c;单一中心化的微服务架构可能无法满足性能和可靠性的要求。因此&#xff0c;构建一个去中心化的微服务集群…...

开集输出和开漏输出

​​​​​​ 首先指明一下以下8中GPIO输入输出模式&#xff1a; GPIO_Mode_AIN 模拟输入&#xff1b; GPIO_Mode_IN_FLOATING 浮空输入&#xff1b; GPIO_Mode_IPD 下拉输入&#xff1b; GPIO_Mode…...

解决内网GitLab 社区版 15.11.13项目拉取失败

问题描述 GitLab 社区版 发布不久&#xff0c;搭建在内网拉取项目报错&#xff0c;可能提示 unable to access https://github.comxxxxxxxxxxx: Failed to connect to xxxxxxxxxxxxxGit clone error - Invalid argument error:14077438:SSL routines:SSL23_GET_S 15.11.13ht…...

【MySQL--->表的约束】

文章目录 [TOC](文章目录) 一、表的约束概念二、空属性约束三、default约束四、zerofill约束五、主键约束六、auto_increment(自增长)约束七、唯一键约束八、外键约束 一、表的约束概念 表通过约束可以保证插入数据的合法性,本质是通过技术手段,保证插入数据收约束,保证数据的…...

github中Keyless Google Maps API在网页中显示地图和标记 无需api key

使用Google Maps API在网页中显示地图和标记的示例博客。以下是一个简单的示例&#xff1a; C:\pythoncode\blog\google-map-markers-gh-pages\google-map-markers-gh-pages\index.html 介绍&#xff1a; 在本篇博客中&#xff0c;我们将学习如何使用Google Maps API在网页中…...

ComPDFKit PDF SDK for Windows Crack

ComPDFKit PDF SDK for Windows Crack 添加了在创建文本框时调整默认属性的支持。 增加了对调整PDF大小时调整宽度的支持。 添加了对编辑文本时更多快捷方式的支持。 优化了文本输入&#xff0c;并将字体样式与原始文本相匹配。 在内容编辑器模式下复制和粘贴时优化了UI交互。 …...

React+Typescript 状态管理

好 本文 我们来说说状态管理 也就是我们的 state 我们直接顺便写一个组件 参考代码如下 import * as React from "react";interface IProps {title: string,age: number }interface IState {count:number }export default class hello extends React.Component<I…...

stable diffusion 运行时报错: returned non-zero exit status 1.

运行sh run.sh安装stable diffusion时报错&#xff1a;ImportError: cannot import name builder from google.protobuf.internal (stable-diffusion-webui/venv/lib/python3.8/site-packages/google/protobuf/internal/__init__.py) 原因&#xff1a;python版本过低&#xff0…...

el-popover弹窗修改三角样式或者位置

el-popover中设置类名 popper-class"filepopver"&#xff0c;我这位置是placement"top-start" <el-popover placement"top-start" popper-class"filepopver" class"filename" width"300" trigger"hover&q…...

Linux驱动开发之点亮三盏小灯

头文件 #ifndef __HEAD_H__ #define __HEAD_H__//LED1和LED3的硬件地址 #define PHY_LED1_MODER 0x50006000 #define PHY_LED1_ODR 0x50006014 #define PHY_LED1_RCC 0x50000A28 //LED2的硬件地址 #define PHY_LED2_MODER 0x50007000 #define PHY_LED2_ODR 0x50007014 #define…...

【SA8295P 源码分析】71 - QAM8295P 原理图参考设计 之 MIPI DSI 接口硬件原理分析

【SA8295P 源码分析】71 - QAM8295P 原理图参考设计 之 MIPI DSI 接口硬件原理分析 一、MIPI-DSI 接口介绍二、高通参考硬件原理图分析:ANX7625 桥接芯片方案2.1 高通参考设计:两路 4-Lane DSI 接口2.2 高通参考设计:DSI0 硬件原理图,将 4 Lane DSI数据通过 ANX7625 桥接芯…...

macOS(m1/m2)破解Sublime Text和Navicat16

破解Sublime Text 说明&#xff1a;全程使用的是终端操作 1. 下载Sublime Text&#xff0c;建议使用brew下载 2. 进入到下载的app的文件夹 cd "/Applications/Sublime Text.app/Contents/MacOS/"3. 执行以下操作以确认版本是否匹配 md5 -q sublime_text | grep -i…...

【排排站:探索数据结构中的队列奇象】

本章重点 队列的概念及结构 队列的实现方式 链表方式实现栈接口 队列面试题 一、队列的概念及结构 队列&#xff1a;只允许在一端进行插入数据操作&#xff0c;在另一端进行删除数据操作的特殊线性表&#xff0c;队列具有先进先出 FIFO(First In First Out) 入队列&#x…...

Mac OS 中JDK 环境(jdk 1.8.0_831)安装配置、环境变量配置及卸载操作

前言&#xff1a; 摊牌了&#xff0c;本来就有点喜新厌旧的我&#xff0c;特意把系统和开发环境都拉到比较高&#xff0c;想试验一下兼容性和某些新特性&#xff0c;探索了一下新大陆&#xff0c;也见识了各种光怪陆离的妖魔鬼怪。 因为要着手云平台项目的重构改版和新系统的架…...

XML Group端口详解

在XML数据映射过程中&#xff0c;经常需要对数据进行分组聚合操作。例如&#xff0c;当处理包含多个物料明细的XML文件时&#xff0c;可能需要将相同物料号的明细归为一组&#xff0c;或对相同物料号的数量进行求和计算。传统实现方式通常需要编写脚本代码&#xff0c;增加了开…...

【网络】每天掌握一个Linux命令 - iftop

在Linux系统中&#xff0c;iftop是网络管理的得力助手&#xff0c;能实时监控网络流量、连接情况等&#xff0c;帮助排查网络异常。接下来从多方面详细介绍它。 目录 【网络】每天掌握一个Linux命令 - iftop工具概述安装方式核心功能基础用法进阶操作实战案例面试题场景生产场景…...

MySQL 隔离级别:脏读、幻读及不可重复读的原理与示例

一、MySQL 隔离级别 MySQL 提供了四种隔离级别,用于控制事务之间的并发访问以及数据的可见性,不同隔离级别对脏读、幻读、不可重复读这几种并发数据问题有着不同的处理方式,具体如下: 隔离级别脏读不可重复读幻读性能特点及锁机制读未提交(READ UNCOMMITTED)允许出现允许…...

AI Agent与Agentic AI:原理、应用、挑战与未来展望

文章目录 一、引言二、AI Agent与Agentic AI的兴起2.1 技术契机与生态成熟2.2 Agent的定义与特征2.3 Agent的发展历程 三、AI Agent的核心技术栈解密3.1 感知模块代码示例&#xff1a;使用Python和OpenCV进行图像识别 3.2 认知与决策模块代码示例&#xff1a;使用OpenAI GPT-3进…...

在rocky linux 9.5上在线安装 docker

前面是指南&#xff0c;后面是日志 sudo dnf config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo sudo dnf install docker-ce docker-ce-cli containerd.io -y docker version sudo systemctl start docker sudo systemctl status docker …...

Neo4j 集群管理:原理、技术与最佳实践深度解析

Neo4j 的集群技术是其企业级高可用性、可扩展性和容错能力的核心。通过深入分析官方文档,本文将系统阐述其集群管理的核心原理、关键技术、实用技巧和行业最佳实践。 Neo4j 的 Causal Clustering 架构提供了一个强大而灵活的基石,用于构建高可用、可扩展且一致的图数据库服务…...

汇编常见指令

汇编常见指令 一、数据传送指令 指令功能示例说明MOV数据传送MOV EAX, 10将立即数 10 送入 EAXMOV [EBX], EAX将 EAX 值存入 EBX 指向的内存LEA加载有效地址LEA EAX, [EBX4]将 EBX4 的地址存入 EAX&#xff08;不访问内存&#xff09;XCHG交换数据XCHG EAX, EBX交换 EAX 和 EB…...

是否存在路径(FIFOBB算法)

题目描述 一个具有 n 个顶点e条边的无向图&#xff0c;该图顶点的编号依次为0到n-1且不存在顶点与自身相连的边。请使用FIFOBB算法编写程序&#xff0c;确定是否存在从顶点 source到顶点 destination的路径。 输入 第一行两个整数&#xff0c;分别表示n 和 e 的值&#xff08;1…...

Fabric V2.5 通用溯源系统——增加图片上传与下载功能

fabric-trace项目在发布一年后,部署量已突破1000次,为支持更多场景,现新增支持图片信息上链,本文对图片上传、下载功能代码进行梳理,包含智能合约、后端、前端部分。 一、智能合约修改 为了增加图片信息上链溯源,需要对底层数据结构进行修改,在此对智能合约中的农产品数…...

android RelativeLayout布局

<?xml version"1.0" encoding"utf-8"?> <RelativeLayout xmlns:android"http://schemas.android.com/apk/res/android"android:layout_width"match_parent"android:layout_height"match_parent"android:gravity&…...