【C语言】三子棋游戏实现代码

目录

1.三子棋代码功能介绍

2.三子棋游戏实现步骤

①打印菜单栏

②判断是否进入三子棋游戏 

③三子棋游戏基本函数实现

(1)清空(初始化)棋盘函数实现

(2)打印棋盘函数实现

(3)玩家下棋函数实现 

(4)电脑下棋函数实现

(5)判断输赢函数

(6)判断平局函数

④整个游戏算法实现(实现逻辑)

3.三子棋游戏完整代码实现

①game.h头文件

②progress.c源文件

③game.c源文件

 4.结语



1.三子棋代码功能介绍

①用坐标代替点位来下棋

②与电脑进行对局

输赢的判断

2.三子棋游戏实现步骤

①打印菜单栏

void menu()//打印三子棋菜单栏
{printf("*************************\n");printf("*******THREECHESS********\n");printf("#####1.PLAY   0.EXIT#####\n");printf("*************************\n");}

②判断是否进入三子棋游戏 

通过scanf函数来获取用户输入;

再使用switch语句来判断是否进入或退出三子棋游戏;

void progress()//判断是否进入游戏
{int input = 0;do{menu();printf("请输入>:");scanf_s("%d", &input);switch (input){case 1://如果用户输入1就进入游戏printf("进入游戏\n");game();//三子棋游戏实现函数printf("\n\n\n");//打印空行使得排版更好看break;case 0:printf("退出游戏\n");break;default://输入不为1或0的情况处理printf("输入错误\n");break;}}while (input);//如果input不为0则一直进入循环判断是否进入三子棋
}

如图所示:

③三子棋游戏基本函数实现

注:首先要知道我们用二维字符数组(char board[ROW][COL])来抽象实现三子棋;

        ROW,COL宏定义为3;

        col,rol传给函数的内容也是3;

(1)清空(初始化)棋盘函数实现

初始化棋盘实际就是将二维数组的各个元素全都初始化为空格,用嵌套for循环来实现

void InitBoard(char board[ROW][COL], int row, int col)//初始化棋盘,这里ROW,COL是宏定义值是3
{int i = 0;int j = 0;for (i = 0; i < row; i++)//用for循环来逐一初始化{for (j = 0; j < col; j++){board[i][j] = ' ';//初始化为空格}}
}

(2)打印棋盘函数实现

类似于初始化棋盘函数打印棋盘函数也使用嵌套的for循环语句

并借用键盘上的字符‘|’‘-’分割棋盘形状

void DisPlayBoard(char board[ROW][COL], int row, int col)//打印棋盘,ROW,COL宏定义为3,col,
//rol传的内容也是3
{int i = 0;int j = 0;for (i = 0; i < row; i++){for (j = 0; j < col; j++)//for循环来逐一打印{printf(" %c ",board[i][j]);if (j < col - 1){printf("|");//打印‘|’来分割每个格子}	}if(i < row - 1)printf("\n---|---|---\n");//一行打印完用横线分割下一行,进行下一行的打印}
}

运行结果如下:

(3)玩家下棋函数实现 

:玩家下棋用‘*’, 电脑下棋用‘#’

        要用if语句判断玩家输入的坐标是否在3*3棋盘内;

        还要用if语句判断玩家输入的坐标是否被占用(是否已经下过)

void PlayerMove(char board[ROW][COL], int row, int col)//玩家下棋
{int x = 0;int y = 0;printf("\n玩家下棋>>");//提示玩家下棋while (1)//如果输入坐标不正确就多次输入{printf("\n请输入坐标:\n");scanf("%d%d", &x, &y);if (x > 0 && x <= row && y > 0 && y <= col)//判断坐标是否在3*3棋盘内{if (board[x - 1][y - 1] == ' ')//判断该格子是否被占用{board[x - 1][y - 1] = '*';//没有占用就放字符‘*’作为玩家下过的标志break;//玩家已经下过一次后跳出循环进行下一轮}elseprintf("该坐标已被占用,请重新输入.\n");//如果坐标被占用进行提示重新输入}elseprintf("坐标输入非法,请重新输入.\n");//如果坐标非法提示重新输入}
}

运行结果如下:

(4)电脑下棋函数实现

:使用随机数生成函数(rand)来获得电脑要下的坐标;

        获得的随机数除以3取余数就可以获得大于等于0小于3的整数以此来作为电脑下棋的坐标;

        同时也要判断随机生成的坐标是否合法

        如果坐标合法且未被占用就标记‘#’;

void ComputerMove(char board[ROW][COL], int row, int col)//电脑下棋
{printf("\n电脑下棋>>\n");//提示电脑下棋int x = 0;int y = 0;while (1)//如果坐标非法就重新输入{x = rand() % row;//使用随机数生成函数生成随机数,并除以3得余数获得0~2的数y = rand() % col;{if (board[x][y] == ' ')//判断该坐标在棋盘上是否被占用{board[x][y] = '#';//没被占用就标记‘#’break;}			}}
}

(5)判断输赢函数

:判断输赢函数多增加了一个参数tmp来传入玩家和电脑代表的字符,一旦一列或一行或从左往右或从右往左的直线有三个相同的字符并且等于tmp的就返回字符tmp,通过tmp就可以判断出玩家赢了还是电脑赢了

char IsWin(char board[ROW][COL], int row, int col, char tmp)//判断输赢,返回字符
{int i = 0;int j = 0;int count = 0;for (i = 0; i < ROW; i++)//判断一是否有三个字符相同{int count = 0;for (j = 0; j < COL; j++){if (board[i][j] != tmp)//有一个不同就break跳出本次循环break;elsecount++;//有一个相同count就+1if (count == 3)//当count等于3时就代表一行中有三个相同return tmp;//当一行中有三个相同的字符时就代表该字符所对应的赢了返回该字符}}for (j = 0; j < COL; j++)//同理判断一列中是否有三个字符相同{int count = 0;for (i = 0; i < ROW; i++){if (board[i][j] != tmp)break;elsecount++;if (count == 3)return tmp;}}for (count = 0,i = 0; i < ROW; i++)//判断从左往右的直线三个字符是否相同{if (board[i][i] != tmp)break;elsecount++;if (count == 3)return tmp;	}for (count = 0,j = COL - 1,i =0; j >= 0,i <ROW; j--,i++)//判断从左往右的直线{if (board[i][j] != tmp)break;elsecount++;if (count == 3)return tmp;}return 0;
}

(6)判断平局函数

:除了判断输赢还要记得判断是否有平局的情况;

        用嵌套for循环来逐一判断二位数组是否有空格;

        没有空格代表平局,返回字符‘Q’

char IsFull(char board[ROW][COL], int row, int col)//判断平局
{int i = 0;int j = 0;for (i = 0; i < row; i++){for (j = 0; j < col; j++)//使用for循环逐一判断棋盘是否有空格{if (board[i][j] == ' ')return 0;//有空格也就是还没下完返回0}}return 'Q';//没有空格平局了返回字符‘Q’
}

④整个游戏算法实现(实现逻辑)

void game()//游戏的整个算法实现
{char ret = 0;char bian = 0;char board[ROW][COL] = { 0 };InitBoard(board, ROW, COL);//清空棋盘DisPlayBoard(board, ROW, COL);//打印棋盘while (1){PlayerMove(board, ROW, COL);//玩家下棋DisPlayBoard(board, ROW, COL);//打印棋盘ret = IsWin(board, ROW, COL, '*');//判断输赢bian = IsFull(board, ROW, COL);//判断是否平局if (ret == '*'){printf("\n玩家赢啦~");break;}if (bian == 'Q'){printf("\n平局");break;}ComputerMove(board, ROW, COL);//电脑下棋DisPlayBoard(board, ROW, COL);//打印棋盘ret = IsWin(board, ROW, COL, '#');//判断输赢bian = IsFull(board, ROW, COL);//判断是否平局if (ret == '#'){printf("\n太可惜了,电脑赢了");break;}if (bian == 'Q'){printf("\n平局");break;}}
}

运行结果如下:

3.三子棋游戏完整代码实现

:有些注释上文标注但在完整代码中未标注

①game.h头文件

#pragma once
#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<time.h>
constexpr auto ROW = 3;
constexpr auto COL = 3;
void InitBoard(char board[ROW][COL], int row, int col);//初始化棋盘函数
void DisPlayBoard(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, char tmp);//判断输赢函数
char IsFull(char board[ROW][COL], int row, int col);//判断平局函数

②progress.c源文件

#include"game.h"
void menu()//打印菜单栏
{printf("*************************\n");printf("*******THREECHESS********\n");printf("#####1.PLAY   0.EXIT#####\n");printf("*************************\n");}
void game()//游戏的整个算法实现
{char ret = 0;char bian = 0;char board[ROW][COL] = { 0 };InitBoard(board, ROW, COL);//清空棋盘DisPlayBoard(board, ROW, COL);//打印棋盘while (1){PlayerMove(board, ROW, COL);//玩家下棋DisPlayBoard(board, ROW, COL);//打印棋盘ret = IsWin(board, ROW, COL, '*');//判断输赢bian = IsFull(board, ROW, COL);//判断是否平局if (ret == '*'){printf("\n玩家赢啦~");break;}if (bian == 'Q'){printf("\n平局");break;}ComputerMove(board, ROW, COL);//电脑下棋DisPlayBoard(board, ROW, COL);//打印棋盘ret = IsWin(board, ROW, COL, '#');//判断输赢bian = IsFull(board, ROW, COL);//判断是否平局if (ret == '#'){printf("\n太可惜了,电脑赢了");break;}if (bian == 'Q'){printf("\n平局");break;}}
}void progress()//判断是否进入游戏
{int input = 0;do{menu();printf("请输入>:");scanf_s("%d", &input);switch (input){case 1:printf("进入游戏\n");game();printf("\n\n\n");break;case 0:printf("退出游戏\n");break;default:printf("输入错误\n");break;}}while (input);}int main()	
{int row = ROW;int col = COL;srand((unsigned int)time(NULL));//设置随机数的生成起点progress();return 0;}

③game.c源文件

#include"game.h"
void InitBoard(char board[ROW][COL], int row, int col)//初始化棋盘
{int i = 0;int j = 0;for (i = 0; i < row; i++){for (j = 0; j < col; j++){board[i][j] = ' ';}}
}
void DisPlayBoard(char board[ROW][COL], int row, int col)//打印棋盘
{int i = 0;int j = 0;for (i = 0; i < row; i++){for (j = 0; j < col; j++){printf(" %c ",board[i][j]);if (j < col - 1){printf("|");}	}if(i < row - 1)printf("\n---|---|---\n");}
}void PlayerMove(char board[ROW][COL], int row, int col)//玩家下棋
{int x = 0;int y = 0;printf("\n玩家下棋>>");while (1){printf("\n请输入坐标:\n");scanf("%d%d", &x, &y);if (x > 0 && x <= row && y > 0 && y <= col){if (board[x - 1][y - 1] == ' '){board[x - 1][y - 1] = '*';break;}elseprintf("该坐标已被占用,请重新输入.\n");}elseprintf("坐标输入非法,请重新输入.\n");}
}
void ComputerMove(char board[ROW][COL], int row, int col)//电脑下棋
{printf("\n电脑下棋>>\n");int x = 0;int y = 0;while (1){x = rand() % row;y = rand() % col;{if (board[x][y] == ' '){board[x][y] = '#';break;}			}}
}char IsWin(char board[ROW][COL], int row, int col, char tmp)//判断输赢
{int i = 0;int j = 0;int count = 0;for (i = 0; i < ROW; i++){int count = 0;for (j = 0; j < COL; j++){if (board[i][j] != tmp)break;elsecount++;if (count == 3)return tmp;}}for (j = 0; j < COL; j++){int count = 0;for (i = 0; i < ROW; i++){if (board[i][j] != tmp)break;elsecount++;if (count == 3)return tmp;}}for (count = 0,i = 0; i < ROW; i++){if (board[i][i] != tmp)break;elsecount++;if (count == 3)return tmp;	}for (count = 0,j = COL - 1,i =0; j >= 0,i <ROW; j--,i++){if (board[i][j] != tmp)break;elsecount++;if (count == 3)return tmp;}return 0;
}char IsFull(char board[ROW][COL], int row, int col)//判断平局
{int i = 0;int j = 0;for (i = 0; i < row; i++){for (j = 0; j < col; j++){if (board[i][j] == ' ')return 0;}}return 'Q';
}

 4.结语

以上就是C语言实现简单三子棋游戏完整代码以及过程实现啦,我们也可以通过三子棋的代码思考五子棋游戏的实现,以及对于随机数生成来作为电脑下棋的坐标似乎有点愚笨,我们或许可以试着写一些让电脑选择坐标更聪明一点的函数,让玩家拥有更好的游戏体验哦,希望能和大家一起学习进步。

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

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

相关文章

【如何学习CAN总线测试】——Vector VH6501干扰仪测试BusOff

系列文章目录 【如何学习CAN总线测试】系列文章目录汇总 文章目录 系列文章目录前言一、环境搭建1.硬件环境2.软件环境3.原理 二、测试方法1.打开Disturbance(CAN)工程2.使能 VH65013.MainConfigPanel面板4.TriggerConfiguration配置5.Sequence Configuration配置6.干扰结果 前…

leetcode9. 回文数|详细深入讲解算法

前往题目有 反转一半数字 思路 映入脑海的第一个想法是将数字转换为字符串&#xff0c;并检查字符串是否为回文。但是&#xff0c;这需要额外的非常量空间来创建问题描述中所不允许的字符串。 第二个想法是将数字本身反转&#xff0c;然后将反转后的数字与原始数字进行比较&…

通信图(Communication Diagram)

UML2.0之前叫协作图(Collaboration Diagram) 一、定义 显示在某种情形下对象之间发送的消息。 协作图显示了一系列的对象和在这些对象之间的联系以及对象间发送和接收的消息 二、元素 通信图的组成元素: 对象、链、消息 1、对象 通信图中的对象与顺序图中对象的概念相同&…

js中的事件模型详解

文章目录 一、事件与事件流二、事件模型原始事件模型标准事件模型IE事件模型 一、事件与事件流 javascript中的事件&#xff0c;可以理解就是在HTML文档或者浏览器中发生的一种交互操作&#xff0c;使得网页具备互动性&#xff0c; 常见的有加载事件、鼠标事件、自定义事件等 …

工业以太网交换机引领现代工厂自动化新潮流

随着科技的飞速发展&#xff0c;现代工厂正迎来一场前所未有的自动化变革&#xff0c;而工业以太网交换机的崭新角色正是这场变革的关键组成部分。本文将深入探讨工业以太网交换机与现代工厂自动化的紧密集成&#xff0c;探讨这一集成如何推动工业生产的智能化、效率提升以及未…

金融信贷风控系统设计

前言 近一年多以来在金融行业负责风控系统&#xff0c;根据自己工作中的经验&#xff0c;写下这篇文章。既是对自己在风控领域工作的总结&#xff0c;也是给刚入行和准备入行的朋友打个样&#xff0c;希望能有所帮助。 为什么要有风控系统 记得 2016 年信贷行业的发展形势还…

Tauri 的基本使用笔记

文章目录 前言如何将 Tauri 集成到前端项目?进程间通信&#xff08;命令&#xff09;const invoke window.__TAURI__.invoke; 进程间通信&#xff08;事件&#xff09;前端 ⇒ RustRust ⇒ 前端我的疑问 开发时的一些技巧用代码打开前端的开发者工具让 Tauri 不要监听文件Rus…

cocos creator 3.x 预制体无法显示

双击预制体&#xff0c;进入详情页&#xff0c;没有显示资源 Bomb 是个预制体&#xff0c;但是当我双击进来什么都没有了&#xff0c;无法对预制体进行可视化编辑 目前我只试出来一个解决方法&#xff1a; 把预制体拖进Canvas文件中&#xff0c;这样就能展示到屏幕上&#xff…

Wireshark中的ARP协议包分析

Wireshark可以跟踪网络协议的通讯过程&#xff0c;本节通过ARP协议&#xff0c;在了解Wireshark使用的基础上&#xff0c;重温ARP协议的通讯过程。 ARP&#xff08;Address Resolution Protocol&#xff09;地址解析协议&#xff0c;是根据IP地址获取物理地址的一个TCP/IP协议。…

Vue-53、Vue技术vuex使用

vuex 是什么 1、概念 专门在Vue 中实现集中式状态&#xff08;数据&#xff09;管理的一个Vue 插件&#xff0c;对vue 应用中多个组件的共享状态进行集中式的 管理&#xff08;读/写&#xff09;&#xff0c;也是一种组件间通信的方式&#xff0c;且适用于任意组件间通信。2、…

无心剑小诗《醉爱平凡人生》

醉爱平凡人生 平凡人生&#xff0c;别样卓越 做调色板上最亮的颜料 没有豪华光环与繁杂束缚 只有一份简单的快乐 不追求虚名&#xff0c;不被物欲左右 安静地享受生活&#xff0c;品味每滴雨露 平凡人生&#xff0c;宛如流淌的小溪 没有壮烈激流&#xff0c;却有恒久细流 不…

pwn旅行之[WUSTCTF 2020]getshell2(一些小知识)

题目分析1 首先打开这个题目的链接的时候&#xff0c;看到了ret2syscall&#xff0c;以为是一个纯正的syscall的题&#xff0c;结果&#xff0c;做的时候发现这个题的危险函数限制的字符串个数不足以写入syscall需要的所有地址&#xff0c;所以&#xff0c;这里参考dalao们的方…

Go 中如何检查文件是否存在?可能产生竞态条件?

嗨&#xff0c;大家好&#xff01;本文是系列文章 Go 技巧第十三篇&#xff0c;系列文章查看&#xff1a;Go 语言技巧。 Go 中如何检查文件是否存在呢&#xff1f; 如果你用的是 Python&#xff0c;可通过标准库中 os.path.exists 函数实现。遗憾的是&#xff0c;Go 标准库没有…

MySQL查询优化技巧和10个案例展示

优化MySQL查询的实战技巧&#xff1a; **避免使用SELECT ***&#xff1a;只获取需要的列&#xff0c;这样可以减少数据传输量&#xff0c;提高查询效率。使用索引&#xff1a;为查询频繁的列创建索引&#xff0c;可以显著提高查询速度。但请注意&#xff0c;索引并非万能&…

大华 DSS 数字监控系统 attachment_getAttList.action SQL 注入漏洞复现

0x01 产品简介 大华 DSS 数字监控系统是大华开发的一款安防视频监控系统,拥有实时监视、云台操作、录像回放、报警处理、设备管理等功能。 0x02 漏洞概述 大华 DSS存在SQL注入漏洞,攻击者 /portal/attachment_getAttList.action 路由发送特殊构造的数据包,利用报错注入获…

林浩然与杨凌芸的Java奇缘:抽象类、接口与多态的编程三部曲

林浩然与杨凌芸的Java奇缘&#xff1a;抽象类、接口与多态的编程三部曲 The Java Odyssey of Lin Haoran and Yang Lingyun: A Trio of Programming Wisdom with Abstract Classes, Interfaces, and Polymorphism 在代码王国里&#xff0c;住着两位程序员明星——林浩然和杨凌芸…

如何理解S参数的三大特性

提到S参数的时候经常会涉及一些概念&#xff0c;如无源性、因果性、互易性等&#xff0c;本文将逐一介绍这些特性。 无源性&#xff08;Passivity&#xff09; 对于S参数所表征的网络&#xff0c;设计者需要它是一个无源的系统&#xff0c;即满足能量守恒&#xff0c;以二端口网…

should be also和should also be

will also be 是正确的 但老师和新概念的两个说法都没有错. will also be 是固定搭配.就好像will not be一样, 限定词加在be前.老师说的是陈述之类的句型 Nbe动词alson/adj/动词短语.例&#xff1a;He is also good at physic. should be also还是should also be also应该插在…

生存类游戏《幻兽帕鲁》从部署服务器到开始体验全过程

SteamDB数据显示&#xff0c;《幻兽帕鲁》上线24小时内&#xff0c;在线人数峰值便突破200万&#xff0c;跻身Steam历史排行榜第二位。随着热度进一步发酵&#xff0c;《幻兽帕鲁》官方发布推文称&#xff0c;游戏发售不到6天&#xff0c;销量已经突破了 800万份。欢迎大家在阿…

冻雨 冰雨。冻雨与冰雹的区别?

冻雨&#xff0c;也被称为冰雨 是一种降水形式&#xff0c;它发生在冷空气层覆盖在地面上方较薄的暖空气层之下。在这种情况下&#xff0c;雨水通过暖空气层下降时变成液态&#xff0c;但当它接触到冰点以下的地面或其他物体时&#xff0c;立即冻结形成冰层。这可以导致道路、…