【C语言】通过C语言实现简单的三子棋

文章目录

    • 【C语言】通过C语言实现简单的三子棋
  • 前言
  • 一、本次小小小小项目前提
  • 二、游戏简易菜单
    • 1.菜单打印
    • 2.游戏菜单的逻辑执行
  • 三、三子棋游戏
    • 1.初始化棋盘
    • 2.打印棋盘
    • 3.玩家下棋
    • 4.电脑下棋
    • 5.判断游戏状态

前言

本篇文章是对我半个月来C语言学习的总结,通过一个简单的三子棋程序,来加深对分支-循环-数组相关内容的理解。
欢迎各位大牛来给予意见,有什么不对的地方拜托指出。


一、本次小小小小项目前提

1.模块化编程

    本程序可以初步认识进行模块化编程,体验模块化编程的优点和相关内容。可以先对本程序做几个简单的要求。

(1)程序的逻辑执行放在test.c这个源文件中 。

(2)程序里的函数声明、头文件创建和引用,放在tpoc.h头文件中。

(3)三子棋使用的相关函数放在tpoc.h这个源文件中。

二、游戏简易菜单

1.菜单打印

    这个很简单,直接使用printf来打印出一个简易的菜单就行,菜单是什么样子的可以自由发挥。

比如这样的:

代码如下(示例):

    printf("***************************\n"); printf("*****    1.开始游戏    *****\n");printf("*****    0.退出游戏    *****\n");printf("***************************\n");

或者是这样的:

 printf("====================\n"); printf("|    1.开始游戏     |\n"); printf("|    0.退出游戏     |\n");printf("====================\n");

具体是什么样子可以自由发挥,喜欢什么样子搞什么样子,自己认为好看就行。 这里我就选择第一个。

然后我们把他放在一个函数meun()里

2.游戏菜单的逻辑执行

代码如下(示例):

#include "tpoc.h"int main()
{int input = 0;do{meun();//打印菜单 printf("请选择:"); //提示玩家选择开始/退出 游戏。scanf("%d", & input);//玩家选择1或者0switch(input)//通过一个switch循环函数,来判断玩家输入的值是否合法,是开始游戏还是退出游戏。{case 1:printf("开始游戏\n");tpoc();//三子棋游戏break;case 0:printf("退出游戏\n");break;default :printf("输入错误,请重新输入\n");//提示玩家输入的数字不合法。break;}} while (input);//通过一个do-whlie函数来进行游戏的循环,同时由input进行判断,如果玩家输入0,则为假,退出游戏,不再进行循环。return 0;
}

注意我这里使用的头文件名是tpco.h,这个是我们自己创建的头文件,里面包含了<stdio.h>

在tpoc.h里引用<stdio.h>,包括后续要使用的头文件我们都放在tpco.h里,这样的话我们test.c的文件里面只需要引用tpco.h头文件就可以了。

使用自定义头文件的时候要用 " " 来引用。


当前头文件tpco.h里面的代码 ​

 #include<stdio.h>

到这里,我们的简易游戏菜单内容就完成了。

运行测试一下,输入 1 2 0 没有问题。
​​​​​​
​​​

三、三子棋游戏

1.初始化棋盘

下面就正式开始我们的三子棋游戏了,既然是下棋,那么我们首先要有一个棋盘。我们要先打印一个棋盘出来。
我们知道,三子棋的内容本质上是一个二维数组,所以我们这边要先创建一个二维数组borad,然后把这个数组打印出来,就是我们的一个三子棋了。

void tpoc()
{char board[3][3];
}

这里创建了一个数组,但是可以发现一点问题,假如我们以后不想玩三子棋了,想玩五子棋了。我们还需要在一个个的修改,我们可以通过两个全局变量,来确定这个二维数组的内容,这个变量我们可以放在头文件tpco.h里面,因为后续还有其他的地方需要用到。
当前头文件tpco.h里面的代码

当前头文件tpco.h里面的代码`

#include<stdio.h>#define ROW 3#define COL 3

但打印棋盘之前我们需要进行一个初始化,主要是为了对棋盘进行清空。初始化棋盘很简单,进行一次遍历,把内容全部初始化为‘ ’(空格)即可。这里我们创建一个名为InitBoard的函数,放在tpco.h里进行声明。

当前tpco.h里的代码:

​
#include<stdio.h>#define ROW 3#define COL 3void InitBoard(char board[ROW][COL], int row, int col);​

> 然后我们在tpco.c文件里进行函数的实现
​
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] = ' ';}}
}

这里后面的函数我就不展示tpco.h里面的代码了,逻辑是一样的。

2.打印棋盘

初始化完成之后我们就可以进行棋盘的打印了,直接进行一次遍历打印出数组内容并且进行分割就可以了。这里我们使用DisplayBoard函数来实现打印棋盘的功能。

​
void DisplayBoard(char board[ROW][COL], int row, int col)
{int i = 0;for (i = 0; i < row; i++){for (int j = 0; j < col; j++){printf(" %c ", board[i][j]);if (j < col - 1)//这里if的作用是保证最后一列不打印{printf("|");}}printf("\n");if (i < row - 1){for (int j = 0; j < col; j++){printf("---");if (j < col - 1)这里if的作用是保证最后一行不打印{printf("|");}}printf("\n");}}

我们来看一下

3.玩家下棋

棋盘出来了,下面我们就可以开始下棋了,这里我们先默认是玩家先开始下棋。这里我们用一个PlayerMove函数来进行玩家下棋这一步。

​
void PlayerMove(char board[ROW][COL], int row, int col)
{while (1){int x, y;printf("玩家走:");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;}else{printf("坐标已被占用,请重新输入\n");//如果被占用了,提示被占用了,重新输入}}else{printf("超过棋盘范围,请重新输入\n");}}}

在玩家走这一步我们要注意几个点:

(1)玩家输入的坐标是从1开始,而数组的下标是从0开始。

(2)判断玩家输入坐标的合法性,如果超过范围要提示并重新输入。

(3)判断玩家输入坐标的位置有没有棋,如果有了,提示并重新输入。

(4)当玩家输入正确的坐标后,跳出循环。

测试一下:


4.电脑下棋

电脑下棋相比玩家下棋不用判断输入的合法性,但是有三个需要注意的点
(1)需要用到rand函数来随机。
(2)同样需要判断坐标是否被占用,如果被占用再随机一个坐标进去。
(3)rand函数需要使用srand函数,我们需要在tese.c文件中用srand函数,并且配合时间戳来进行一个数的随机。
(4)srand和time需要引头文件<stdlib.h>和,我们把它们放在tpoc.h里面。

​
void AI_Move(char board[ROW][COL], int row, int col)
{int x, y;printf("电脑走:\n");while (1){x = rand() % row;             //生成在棋盘范围内的随机数y = rand() % col;if (board[x][y] == ' ')  //判断坐标是否被占用{board[x][y] = '#';break;                        //没被占用则跳出循环,被占用继续随机。}}
}
 srand((unsigned int)time(NULL));//放在main函数的前面

5.判断游戏状态

每当玩家或电脑下棋后我们需要进行一次游戏状态的判定,这个时候会有四种情况,我们为这四种情况来进行一个返回值,并且用一个Is_Win函数来判断这四种情况。
(1)玩家赢了 -返回 *

(2)电脑赢了 -返回 #

(3)棋盘满了-平局 -返回 Q

(4)棋盘还有位置-游戏继续 -返回 C

确定了返回值我们开始写这个函数,我们可以通过判断行 判断列 判断对角来返回相应的字符,平局需要通过另外一个函数来进行一次遍历来判断数组内还有没有空格就能判断棋盘是否满了。如果以上几种情况都没有,那可以返回C,游戏继续。

​
char Is_Win(char board[ROW][COL], int row, int col)
{int i = 0;for ( i = 0; i < row; i++)//判断行{if (board[i][0] == board[i][1] && board[i][1] == board[i][2] && board[i][0] != ' '){return board[i][1];}}for (i = 0; i < col; i++)//判断列{if (board[0][i] == board[1][i] && board[0][i] == board[2][i] && board[0][i] != ' '){return board[1][i];}}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 (Is_Full(board, row, col) == 1)//通过一个函数确认棋盘有没有满,来判断是否是平局。{return 'Q';}return 'C';
}

Is_Full代码的实现

​
int Is_Full(char board[ROW][COL], int row, int col)
{for (int i = 0; i < row; i++){for (int j = 0; j < col; j++){if (board[i][j] == ' '){return 0;//棋盘如果未满返回 0}}}return 1;//棋盘满了返回 1
}

下面我们回到test.c,来理清tpco函数的逻辑
大概的逻辑顺序为:

1.初始化棋盘——打印棋盘——循环(玩家下棋并且判断——电脑下棋并且判断)——出结果了跳出循环,并判断结果。

​
void tpoc()
{char board[ROW][COL];//存放棋盘的数组char ret;//用来判断返回内容的字符InitBoard(board, ROW, COL);//初始化棋盘DisplayBoard(board, ROW, COL);//打印棋盘while (1){PlayerMove(board, ROW, COL);//玩家下棋DisplayBoard(board, ROW, COL);//玩家下完棋打印ret = Is_Win(board, ROW, COL);//判断游戏状态if (ret != 'C')//不为C说明出结果了,跳出循环,进行判断。{break;}AI_Move(board, ROW, COL);//电脑下棋DisplayBoard(board, ROW, COL);//电脑下完棋打印ret = Is_Win(board, ROW, COL);//判断游戏状态if (ret != 'C')//不为C说明出结果了,跳出循环,进行判断。{break;}}if (ret == '*')//返回*说明玩家赢了{printf("我恭喜你发财了\n");}else if (ret == '#'){printf("回家养猪去吧\n");//这种弱智电脑都玩不过,可以回去养猪了(bushi)返回 # 电脑赢了}else{printf("平局\n");//仅剩一种情况了,那就是平局。}}​

最后让我们看看全部的代码:

test.c

​
//test.c
#include "tpoc.h"void meun()
{printf("****************************\n");printf("*****    1.开始游戏    *****\n");printf("*****    0.退出游戏    *****\n");printf("****************************\n");
}void tpoc()
{char board[ROW][COL];//存放棋盘的数组char ret;//用来判断返回内容的字符InitBoard(board, ROW, COL);//初始化棋盘DisplayBoard(board, ROW, COL);//打印棋盘while (1){PlayerMove(board, ROW, COL);//玩家下棋DisplayBoard(board, ROW, COL);//玩家下完棋打印ret = Is_Win(board, ROW, COL);//判断游戏状态if (ret != 'C')//不为C说明出结果了,跳出循环,进行判断。{break;}AI_Move(board, ROW, COL);//电脑下棋DisplayBoard(board, ROW, COL);//电脑下完棋打印ret = Is_Win(board, ROW, COL);//判断游戏状态if (ret != 'C')//不为C说明出结果了,跳出循环,进行判断。{break;}}if (ret == '*')//返回*说明玩家赢了{printf("我恭喜你发财了\n");}else if (ret == '#'){printf("回家养猪去吧\n");//这种弱智电脑都玩不过,可以回去养猪了(bushi)返回 # 电脑赢了}else{printf("平局\n");//仅剩一种情况了,那就是平局。}}
int main()
{int input = 0;srand((unsigned int)time(NULL));do{meun();//打印菜单 printf("请选择:"); //提示玩家选择开始/退出 游戏。scanf("%d", & input);//玩家选择1或者0switch(input)//通过一个switch循环函数,来判断玩家输入的值是否合法,是开始游戏还是退出游戏。{case 1:printf("开始游戏\n");tpoc();//三子棋游戏break;case 0:printf("退出游戏\n");break;default :printf("输入错误,请重新输入\n");//提示玩家输入的数字不合法。break;}} while (input);//通过一个do-whlie函数来进行游戏的循环,同时由input进行判断,如果玩家输入0,则为假,退出游戏,不再进行循环。return 0;
}​> tpoc.c ```c
​
#include "tpoc.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 DisplayBoard(char board[ROW][COL], int row, int col)
{int i = 0;for (i = 0; i < row; i++){for (int j = 0; j < col; j++){printf(" %c ", board[i][j]);if (j < col - 1){printf("|");}}printf("\n");if (i < row - 1){for (int j = 0; j < col; j++){printf("---");if (j < col - 1){printf("|");}}printf("\n");}}}void PlayerMove(char board[ROW][COL], int row, int col)
{while (1){int x, y;printf("玩家走:");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;}else{printf("坐标已被占用,请重新输入\n");//如果被占用了,提示被占用了,重新输入}}else{printf("超过棋盘范围,请重新输入\n");}}}void AI_Move(char board[ROW][COL], int row, int col)
{int x, y;printf("电脑走:\n");while (1){x = rand() % row;             //生成在棋盘范围内的随机数y = rand() % col;if (board[x][y] == ' ')  //判断坐标是否被占用{board[x][y] = '#';break;                        //没被占用则跳出循环,被占用继续随机。}}}int Is_Full(char board[ROW][COL], int row, int col)
{for (int i = 0; i < row; i++){for (int j = 0; j < col; j++){if (board[i][j] == ' '){return 0;//棋盘如果未满返回 0}}}return 1;//棋盘满了返回 1
}char Is_Win(char board[ROW][COL], int row, int col)
{int i = 0;for ( i = 0; i < row; i++)//判断行{if (board[i][0] == board[i][1] && board[i][1] == board[i][2] && board[i][0] != ' '){return board[i][1];}}for (i = 0; i < col; i++)//判断列{if (board[0][i] == board[1][i] && board[0][i] == board[2][i] && board[0][i] != ' '){return board[1][i];}}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 (Is_Full(board, row, col) == 1)//通过一个函数确认棋盘有没有满,来判断是否是平局。{return 'Q';}return 'C';
}​

tpoc.h

​
#include <stdio.h>
#include <stdlib.h>
#include <time.h>#define ROW 3#define COL 3void 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 AI_Move(char board[ROW][COL], int row, int col);char Is_Win(char board[ROW][COL], int row, int col);

最后运行我就不贴出来了,毕竟输一把电脑挺难的。我的水平目前只能让电脑是这个智商了。

【C语言】通过C语言实现简单的三子棋相关推荐

  1. C语言的简单运用——三子棋

    前言 学习新知识固然重要,但如何运用所学的知识解决生活中的问题更为重要.只会学而不会用,何异于纸上谈兵.那么就让我们来看看如何用C语言来实现一个简单的三子棋吧! 目录 前言 一点建议 一.游戏菜单 1 ...

  2. C语言(通识)_对三子棋的简单实现

    文章目录 创建文件 准备环节 1.菜单打印 2.初始化棋盘 3.打印棋盘 low版本 better版 落子环节 玩家落子 电脑落子 输赢判断 代码汇总 game.h game.c test.c 战术总 ...

  3. C语言实现简单游戏 三子棋

    对基本C语言的知识有了一定的了解和认识,能够通过C语言编程解决一些简单的问题.使用C语言编程完成一个简单的游戏<三子棋>. 游戏简介:常见的3x3棋盘,有两名游戏玩家,在本版本中实现的效果 ...

  4. 【C语言】简单实现三子棋(井字棋)小游戏

    背景 C语言学习过程中会有很多有趣的实践小程序需要大家编写,这里带给大家一个常见的三子棋小游戏的代码.如果有不足之处,还望指出,感谢浏览. 框架 这里给刚开始学习或接触C语言的小伙伴分享一点我个人的经 ...

  5. c语言小游戏 三子棋,C语言实现简单的三子棋小游戏

    学习完数组就能用C语言写出的简单小游戏: 编译器使用的为VS2013 代码分为三个部分 1.头文件 game.h 2.源文件 game.c 用来存放游戏中所有的函数 3.源文件 test.c 用来存放 ...

  6. 如何实现简单的三子棋小游戏(改两个数就可以变为五子棋)

    首先我们创建一个新项目,新项目中添加两个源文件,一个用来放置该游戏所需的所有函数(game.c),另一个放置主函数来测试(test.c),所有的函数可以包含在新创建的头文件里(game.h),这样在主 ...

  7. C语言 小游戏 电脑大概率获胜,用C语言实现简单的三子棋小游戏

    三子棋问题即在3 * 3的二维数组上下棋,只要有棋子在行.列或对角线连成一线即取得胜利. 可实现玩家与电脑对弈. 说明 : (1)本游戏玩家输入的是棋盘的坐标. (2)"X"代表玩 ...

  8. C语言实现简单的三子棋小游戏(童年游戏)

    ⭐️前面的话⭐️

  9. C语言简单实现三子棋小游戏

    游戏规则: 三子棋是一种民间传统游戏,又叫九宫棋.圈圈叉叉.一条龙等.游戏是在一个3*3的棋盘里面下棋的.只要有三个一样的连成一条线,就表示有一方胜出:如果下完了9个格子还没有玩家胜出,游戏为平局. ...

最新文章

  1. 《自然》深度:中国AI能在2030年制霸世界吗?
  2. SqlSessionFactoryBuilder、SqlSessionFactory、SqlSession作用域(Scope)和生命周期
  3. java 单机版_JAVA单机版管理系统源代码.pdf
  4. 批创建清账凭证,POSTING_INTERFACE_CLEARING
  5. 认识微服务-SpringCloud
  6. 在ASP.NET Core Web API上使用Swagger提供API文档
  7. dynamodb java_使用Java第2部分查询DynamoDB项
  8. 高德车道级导航已上线8城 新增支持小米11 Pro
  9. 计算机网络—路由器(Cisco Packet Tracer)常用的命令总结
  10. Ajax 学习(一)
  11. 每日英语听力 Mac
  12. 面经:中国人民银行金融科技研究院
  13. 必要的系统组件未能正常运行,请修复Adobe Flash Player
  14. Recurrent Feature Reasoning for Image Inpainting解读
  15. 十进制小数化为二进制小数的方法是什么_二进制的转换
  16. 电信中兴光猫ZXHN F650超管密码获取工具
  17. 十一届蓝桥模拟赛 元辅音字母 JAVA
  18. jQuery动画与效果
  19. 完全否定联想需谨慎,加工贸易对中国制造起到了巨大推动作用
  20. 倒霉。。。倒霉。。。。。

热门文章

  1. 具有黑马潜质的电影都有哪些特色?
  2. 华硕b560m-PLUS WIFI主板+i5 10400F平台安装Win7
  3. 计算机二级网上报名中北大学,2018年中北大学英语六级考试报名通知
  4. PAT - 1036 跟奥巴马一起编程
  5. UE4数字孪生项目开发学习大纲
  6. 英语单词----分类记
  7. 光滑粒子流体动力学_(图文+视频)C4D野教程:奇怪的流体包裹球体动画制作方法...
  8. Https证书校验不当引起的安全问题
  9. 【Android取证篇】华为手机助手备份加密的版本
  10. 苹果手机左上角的数字怎么弄_出了新朋友,莫忘老朋友,苹果Macbook这款小键盘能让你键步如飞...