C语言实现简易n子棋小游戏(代码含注解)

利用C语言简单实现一个n子棋小游戏,棋盘大小由自己定义

将源文件分为   执行游戏的测试文件(test.c)和保存游戏运行逻辑的相关函数的文件(game.c)

头文件中声明符号和函数的定义(game.h)

游戏执行主要依靠二维数组实现,电脑走棋采用随机值的方法简易地实现而非采用高级的算法

头文件 game.h

#define _CRT_SECURE_NO_WARNINGS 1
#include <stdio.h>
#include <string.h>
#include <math.h>
#include<stdlib.h>
#include<windows.h>
#include<time.h>
//符号的定义(定义几子棋)
#define ROW 3
#define COL 3//函数的定义
void InitBoard(char board[ROW][COL], int row, int col);//初始化棋盘
void PrintBoard(char board[ROW][COL], int row, int col);//打印棋盘
void PlayerMove(char board[ROW][COL], int row, int col);//玩家下棋
void ComputerMove(char board[ROW][COL], int row, int col);//电脑下棋
char IsWin(char board[ROW][COL], int row, int col);//判断游戏结果

源文件 test.c

#include "game.h"            //引用头文件
void game() {char ret;char board[ROW][COL];  //二维数组存储游戏数据,ROW、COL为行和列,在头文件game.h中定义InitBoard(board,ROW,COL);//初始化棋盘为空格PrintBoard(board, ROW, COL);//打印棋盘while (1) {printf("玩家走\n\n");PlayerMove(board, ROW, COL);  //玩家下棋Sleep(500);PrintBoard(board, ROW, COL);  //判断玩家是否赢得游戏ret=IsWin(board, ROW, COL);		//返回值为*代表玩家获胜、#代表电脑获胜、D代表平局、C代表未出结果,游戏继续if (ret != 'C') {break;}printf("电脑走\n\n");ComputerMove(board, ROW, COL);//玩家下棋Sleep(1300);PrintBoard(board, ROW, COL);//判断电脑是否赢得游戏ret = IsWin(board, ROW, COL);if (ret != 'C') {break;}}if (ret == '*') {printf("玩家获胜\n\n");}else if (ret =='#') {printf("电脑获胜\n\n");}else if (ret == 'D') {printf("平局\n\n");}PrintBoard(board, ROW, COL);//打印游戏结果}
void menu() {printf("***************************\n");printf("*****      1.play     *****\n");printf("*****      0.exit     *****\n");printf("***************************\n");}
int main() {int n;srand((unsigned int)time(NULL));//设置随机数种子do{menu();printf("请选择:\n");scanf("%d", &n);switch (n){case 1:game();break;case 0:printf("退出游戏\n");break;default:printf("选择错误,重新选择\n");break;}} while (n);return 0;
}

源文件 game.c

#include "game.h"                        //引用头文件
void InitBoard(char board[ROW][COL], int row, int col) {for (int i = 0; i < ROW; i++) {for (int j = 0; j < COL; j++) {board[i][j] = ' ';}}
}
void PrintBoard(char board[ROW][COL], int row, int col) {          //打印棋盘for (int j = 0; j < col; j++) {printf(" ___");}printf(" \n");for (int i = 0; i < row; i++) {for (int j = 0; j < col; j++) {printf("| %c ",board[i][j]);}printf("|\n");if (i < row ) {for (int j = 0; j < col; j++) {printf("|___");}printf("|\n");}}printf("\n");
}
void PlayerMove(char board[ROW][COL], int row, int col) {while (1) {                            //若输入错误则一直循环int x, y;printf("请输入坐标:\n");scanf("%d %d", &x, &y);if (x <= row && x >= 1 && y <= col && y >= 1) {         //判断坐标是否合法if (board[x - 1][y - 1] == ' ')                     //玩家输入的坐标需要减1,因为数组从0开始,同时判断坐标是否被占用过{board[x - 1][y - 1] = '*';break;}else{printf("坐标被占用,请重新输入:\n");}}else{printf("坐标不合法,请重新输入:\n");}}
}
void ComputerMove(char board[ROW][COL], int row, int col) {while (1) {int x = rand() % row;  //生成合法的行坐标int y = rand() % col;  //生成合法的列坐标if (board[x][y]==' ') {board[x][y] = '#';break;}}
}char IsWin(char board[ROW][COL], int row, int col) {int x = 0;                   //计数器判断一行或一列是否遍历结束int sum1 = 0;                //判断*的数量int sum2 = 0;                //判断#的数量for (int i = 0; i < col; i++) {for (int j = 0; j < row; j++) {               //判断每行上是否有连续三个相等的符号if (board[i][j] == '*') {sum1 += 1;}if (board[i][j] == '#') {sum2 +=1;}x++;if(x==row){                                 //一行统计完时if (sum1 == row) {                        //一行全是*return '*';}else if (sum2 == row) {return '#';                         //一行全是#}else {                                  //一行中未分胜负则计数器清零统计下一行sum1 = 0;                         sum2 = 0;x = 0;}}}}for (int j = 0; j < row; j++) {for (int i = 0; i < col; i++) {                //行未分出胜负,则开始统计列if (board[i][j] == '*') {sum1 += 1;}if (board[i][j] == '#') {sum2 += 1;}x++;if (x == row) {                             //一列统计完时if (sum1 == row) {                        //一列全是*return '*';}else if (sum2 == row) {return '#';                         //一列连全是#}else {                                  //一列中未分胜负则计数器清零统计下一列sum1 = 0;sum2 = 0;x = 0;}}}}for (int i = 0; i < col; i++) {for (int j = 0; j < row; j++) {                 //行列都为分出胜负统计主对角线元素if (i == j) {if (board[i][j] == '*') {sum1 += 1;}else if (board[i][j] == '#') {sum2 += 1;}}}}if (sum1 == row) {return '*';                                     //主对角线上元素都为*}else if (sum2 == row) {return '#';                                     //主对角线上元素都为#}else {sum1 = 0;sum2 = 0;                                       //计数器清零统计副对角线}//查看副对角线上的元素,可以先复制一个横向翻转的临时棋盘board1,查看主对角线上的元素char board1[ROW][COL];for (int i = 0; i < row; i++) {for (int j = 0; j < col; j++) {board1[i][j] = board[i][col-j-1];}}//判断临时棋盘的主对角线元素for (int i = 0; i < col; i++) {for (int j = 0; j < row; j++) {                 if (i == j) {if (board1[i][j] == '*') {sum1 += 1;}else if (board1[i][j] == '#') {sum2 += 1;}}}}if (sum1 == row) {return '*';                                     //主对角线上元素都为*}else if (sum2 == row) {return '#';                                     //主对角线上元素都为#}else {sum1 = 0;sum2 = 0;                                       //计数器清零}//查看是否为平局,则是以上都判断完后,棋盘是否满了,满了则返回‘D’,不满则继续for (int i = 0; i < row; i++) {for (int j = 0; j < col; j++) {if (board[i][j] == ' ') {return 'C';                     //有地方是空的,游戏还未出结果}}}return 'D';                                 //棋盘满了且没分出胜负,则为平局
}

运行结果(以3子为例):

以上为C语言简易实现n子棋的内容

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

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

相关文章

鸿蒙原生应用再添新丁!万达 入局鸿蒙

鸿蒙原生应用再添新丁&#xff01;万达 入局鸿蒙 来自 HarmonyOS 微博1月11日消息&#xff0c;#万达酒店及度假村启动鸿蒙原生应用及元服务开发# 作为具有中国特色的国牌服务酒店标杆之一&#xff0c;万达酒店及度假村Wanda 将带来全新的服务和交互方式&#xff0c;一步获取“…

Vue3 + TS + Element-Plus —— 项目系统中封装表格+搜索表单 十分钟写五个UI不在是问题

前期回顾 纯前端 —— 200行JS代码、实现导出Excel、支持DIY样式&#xff0c;纵横合并-CSDN博客https://blog.csdn.net/m0_57904695/article/details/135537511?spm1001.2014.3001.5501 目录 一、&#x1f6e0;️ newTable.vue 封装Table 二、&#x1f6a9; newForm.vue …

离散数学3

补变元 解释&#xff1a;它是以反^作为一组一组的&#xff0c;因此&#xff0c;对于P反^Q来说&#xff0c;P是一组&#xff0c;Q是一组&#xff0c;又有以下&#xff1a;对缺少变元的项要补齐&#xff0c;P缺少Q&#xff0c;Q缺少P。因此&#xff0c;补齐。 用分配律展开 解释&…

数据库用户密码修改时间和密码加密值查询(DM8:达梦数据库)

DM8:达梦数据库用户密码加密值查询 环境介绍1 查询达梦数据库密码修改时间与加密值2 查询数据库密码相同的用户3 达梦数据库学习使用列表 环境介绍 要查询用户密码修改时间,用第一个sql;要查询哪些数据库用户密码是一样的,用第二个sql;若忘记达梦数据库用户密码,1 可以试错,2 …

C++使用map插入insert数据(二进制数据和非二进制数据)接口封装+读取文件

1、定义编写代码 //生成insert sql语句std::string GetInsertsql(XDATA kv, std::string table);//插入非二进制数据bool Insert(XDATA kv, std::string table);//插入二进制数据bool InsertBin(XDATA kv, std::string table); std::string LXMysql::GetInsertsql(XDATA kv, s…

x-cmd pkg | dua - 磁盘使用分析器

目录 简介首次用户技术特点竞品和相关作品进一步阅读 简介 dua 是 Disk Usage Analyzer 的简写&#xff0c;该工具可以快速查看给定目录的磁盘空间使用情况。 对于想要深入了解磁盘空间使用情况并有效管理存储的用户来说&#xff0c;Dua 是一个很有价值的工具。通过使用 Dua …

华为“纯血”鸿蒙加速进场 高校、企业瞄准生态开发新风口

近日&#xff0c;华为终端BG CEO、智能汽车解决方案BU董事长余承东在2024年新年信中提出&#xff0c;开启华为终端未来大发展的新十年。 他特别提到&#xff0c;未来要构建强大的鸿蒙生态&#xff0c;2024年是原生鸿蒙的关键一年&#xff0c;将加快推进各类鸿蒙原生应用的开发…

指导AI进行推理:提示工程如何弥补RAG系统中的差距

每日推荐一篇专注于解决实际问题的外文,精准翻译并深入解读其要点,助力读者培养实际问题解决和代码动手的能力。 欢迎关注公众号(NLP Research) 原文标题:Instructing AI to Reason: How Prompt Engineering Bridges the Gap in RAG Systems 原文地址:https://medium.c…

el-select 单选时,选择后输入框的is-focus状态并没有取消

前两天在封装组件的时候&#xff0c;发现el-select 单选时&#xff0c;选择后输入框的is-focus状态并没有取消&#xff0c;需要手动点其它地方才会取消&#xff0c;于是想着找找为什么 一、通过调试源码发现&#xff0c;输入框在点击选项后触发blur&#xff0c;紧接着又触发了…

使用MySQL的过程中,有没有遇到过count()比较慢的情况?

count(*)的实现方式 MyISAM引擎把一个表的总行数存在了磁盘上&#xff0c;执行count(*)的时候直接返回这个数&#xff0c;效率很高&#xff1b; InnoDB引擎执行count(*)的时候&#xff0c;需要把数据一行一行地从引擎里面读出来&#xff0c;然后累积计数。 上述说明是在没有…

AOP切面逻辑实现后,原有正常业务代码失效?

问题代码展示 OverrideAround("annotation(sessionChange)")public void aroundSessionChange(SessionChange sessionChange) {SessionChangeAspect.super.aroundSessionChange(sessionChange);}/*** 模拟登录* return*/GetMapping("/logon")SessionChange…

【AI视野·今日CV 计算机视觉论文速览 第286期】Tue, 9 Jan 2024

AI视野今日CS.CV 计算机视觉论文速览 Tue, 9 Jan 2024 Totally 121 papers &#x1f449;上期速览✈更多精彩请移步主页 Daily Computer Vision Papers Dr$^2$Net: Dynamic Reversible Dual-Residual Networks for Memory-Efficient Finetuning Authors Chen Zhao, Shuming Li…