目录:

一、说明

二、多文件创建

三、设计思路

四、代码实现

五、总体代码

六、总结


一、说明

随着我们对C语言学习的逐渐深入,我们可以实现一些简单的小游戏,本文将会介绍C语言实现三子棋小游戏,通过本文可以了解C语言中数组的用法以及循环、选择结构的使用方法

二、多文件创建

当我们在写一些比较大的程序时,直接写在一个文件中会十分混乱,可读性差。这时我们通常可以把一个大的程序分为几个小部分,比如头文件,函数文件和主函数文件,随着需要的增加也可以增加文件。本文中我们包含三个文件,分别为主函数test.c文件,其中包含了菜单和主函数;游戏game.c文件,其中包含了游戏部分函数;game.h头文件,其中包含了游戏引用的头文件。接下来将会详细解读各个部分文件,如果需要复制代码可以直接翻到最后看总体代码。

三、设计思路

首先,我介绍一下三子棋游戏玩法及规则,这里我们引用以下百度百科对三子棋的介绍。

设计思路:

首先,当我们要进行三子棋游戏时,首先打印出菜单,让玩家选择是否游戏,如果玩家选择1那么玩家进入游戏,如果玩家选择零则玩家退出游戏,当玩家输入错误时我们提示玩家输入错误,重新输入,在这里我们使用do-while循环使玩家如果没有玩过瘾可以继续玩。当玩家选择进入游戏后,我们初始化棋盘后将棋盘打印出来,随后玩家选择坐标,然后下棋,接下来电脑选择坐标,随后电脑下棋。为了实现玩家下棋之后电脑下棋的效果我们使用while循环。每次下棋结束都进行一次判断输赢,当有一方胜利或者平局时游戏结束。以上就是三子棋游戏的设计思路。

当我们要进行三子棋游戏时,首先打印出菜单,让玩家选择是否游戏,如果玩家选择1那么玩家进入游戏,如果玩家选择零则玩家退出游戏,当玩家输入错误时我们提示玩家输入错误,重新输入,在这里我们使用do-while循环使玩家如果没有玩过瘾可以继续玩。当玩家选择进入游戏后,我们初始化棋盘后将棋盘打印出来,随后玩家选择坐标,然后下棋,接下来电脑选择坐标,随后电脑下棋。为了实现玩家下棋之后电脑下棋的效果我们使用while循环。每次下棋结束都进行一次判断输赢,当有一方胜利或者平局时游戏结束。以上就是三子棋游戏的设计思路。

四、代码实现

1.test.c

代码如下:

#include"game.h"
void menu()
{printf("**********************************************\n");printf("****************  1.play  ********************\n");printf("****************  0.exit  ********************\n");printf("**********************************************\n");
}
void game()
{char ret = 0;//存放下棋的数据char board[ROW][COL] = { 0 };//初始化棋盘为全空格init_board(board, ROW, COL);//打印棋盘display_board(board, ROW, COL);while (1){//玩家下棋player_move(board, ROW, COL);display_board(board, ROW, COL);//判断输赢ret = is_win(board, ROW, COL);if (ret != 'C'){break;}//电脑下棋computer_move(board, ROW, COL);display_board(board, ROW, COL);//判断输赢ret = is_win(board, ROW, COL);if (ret != 'C'){break;}}if (ret == '*'){printf("玩家赢了\n");}else if (ret == '#'){printf("电脑赢了\n");}else if (ret == 'Q'){printf("平局\n");}}
//玩家赢--'*'
//电脑赢--'#'
//平局--'Q'
//继续--'C'
int main()
{int input = 0;srand((unsigned int)time(NULL));//生成随机值do{menu();printf("请输入:");scanf("%d", &input);switch (input){case 1:game();break;case 0:printf("退出游戏\n");break;default:printf("输入错误,请重新输入\n");break;}} while (input);return 0;
}

首先,我们要让玩家选择是否游戏,所以我们使用scanf来让玩家进行输入选择。为了让玩家玩游戏多次,所以使用do-while循环。我们先打印出菜单,在menu函数中写出一个简易的菜单并且在主函数中使用。随后运用switch语句,当选择1时进入游戏,当选择0时退出游戏,输入其他字符时让玩家重新选择。

2.game.h

在头文件中我们可以我们可以需要引用的库函数放在里面,这样在主函数中不必重复引用,而且在头文件中我们可以声明自定义函数,在主函数中就不必声明。而且我们可以用宏定义,将棋盘的长和宽用ROW和COL代替,这样便于使用。我们在头文件中放入init_board(初始化棋盘),display_board(打印棋盘),player_move(玩家移动),computer_move(电脑移动),is_win(判断胜负)。

#include<stdio.h>
#include<stdlib.h>
#include<time.h>
#include<Windows.h>#define ROW 3
#define COL 3void menu();
void game();//初始化棋盘
void init_board(char board[ROW][COL], int row, int col);//打印棋盘
void display_board(char board[ROW][COL], int row, int col);//玩家下棋
void player_move(char board[ROW][COL], int row, int col);//电脑下棋
void computer_move(char board[ROW][COL], int row,int col);//判断输赢
char is_win(char board[ROW][COL], int row,int col);

3.game.c

(1)init_board()

初始化棋盘

{int i = 0;for (i = 0; i < row; i++){for (int j = 0; j < col; j++){board[i][j] = ' '; }}
}

利用两个for循环嵌套将board数组每个元素初始化为空格

(2)display_board()

打印棋盘

{for (int i = 0; i < row; i++){int j = 0;for (j = 0; j < col; j++){//打印数据printf(" %c ", board[i][j]);if(j<col-1)printf("|");}printf("\n");//打印分割行if (i < row - 1){for (j = 0; j < col; j++){printf("---", board[i][j]);if (j < col - 1)printf("|");}printf("\n");}}
}

在打印棋盘中我们想要的效果如下图所示。按照理想图来写代码,花费一点时间琢磨便可。

(3)player_move()

玩家移动

{int x = 0;int y = 0;printf("玩家下棋\n");while (1){printf("请输入坐标:\n");scanf("%d %d", &x, &y);if (x >= 1 && x <= row && y >= 1 && y <= col){//下棋if (board[x - 1][y - 1] == ' '){board[x - 1][y - 1] = '*';break;}else{printf("该坐标被占用请重新输入\n");}}elseprintf("坐标非法,请重新输入\n");}}

首先,我们用scanf让玩家输入坐标,当坐标合法、也就是x大于1小于棋盘宽度、y大于1小于棋盘长度时,如果这个坐标上为空格,那么玩家在这个坐标下棋,也就是将(x,y)处的字符替换成*,如果被占用或者输入错误则提示玩家重新输入。

(4)computer_move()

电脑移动

{int x = 0;int y = 0;printf("电脑下棋\n");while (1){x = rand() % row;y = rand() % col;if (board[x][x] == ' '){board[x][y] = '#';break;}}}

电脑下棋困难的问题是生成随机坐标,这里我们用的方法是利用时间戳来生成随机值,这部分内容在之前写的猜数字游戏中有详细介绍。下棋部分同玩家下棋相同。

(5)if_full()

判断平局

{int i = 0;for (i = 0; i < row; i++){int j = 0;for (j = 0; j < col; j++){if (board[i][j] == ' '){return 0;}}}return 1;
}

当棋盘所有位置都被占用时返回1,当有位置未被占用时返回零

(6)is_win()

判断胜负

{int i = 0;for (i = 0; i < row; i++){if (board[i][0] == board[i][1] && board[i][1] == board[i][2] && board[i][1] != ' '){return board[i][1];}}for (i = 0; i < col; i++){if (board[0][i] == board[1][i] && board[1][i] == board[2][i] && board[1][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 (if_full(board, row, col) == 1){return 'Q';}return 'C';
}

判断函数胜负的方法首先要知道胜利的条件。

条件:横排三个都相同||竖排三个都相同||斜排三个都相同。知道胜负条件便有思路了。我们利用for循环先遍历没排字符,当一排中的字符相同时我们返回这一排的字符,当平局是返回值为Q,除了这些情况返回C,也就是continue——继续。

然后我们俩看game函数中判断谁胜谁负的方法

void game()
{char ret = 0;//存放下棋的数据char board[ROW][COL] = { 0 };//初始化棋盘为全空格init_board(board, ROW, COL);//打印棋盘display_board(board, ROW, COL);while (1){//玩家下棋player_move(board, ROW, COL);display_board(board, ROW, COL);//判断输赢ret = is_win(board, ROW, COL);if (ret != 'C'){break;}//电脑下棋computer_move(board, ROW, COL);display_board(board, ROW, COL);//判断输赢ret = is_win(board, ROW, COL);if (ret != 'C'){break;}}if (ret == '*'){printf("玩家赢了\n");}else if (ret == '#'){printf("电脑赢了\n");}else if (ret == 'Q'){printf("平局\n");}}
//玩家赢--'*'
//电脑赢--'#'
//平局--'Q'
//继续--'C'

这里我们写了一个字符变量ret来接收is_win函数的返回值,并且在代码中进行判断,具体部分见函数。

五、总体代码

//game.h
#include<stdio.h>
#include<stdlib.h>
#include<time.h>
#include<Windows.h>#define ROW 3
#define COL 3void menu();
void game();//初始化棋盘
void init_board(char board[ROW][COL], int row, int col);//打印棋盘
void display_board(char board[ROW][COL], int row, int col);//玩家下棋
void player_move(char board[ROW][COL], int row, int col);//电脑下棋
void computer_move(char board[ROW][COL], int row,int col);//判断输赢
char is_win(char board[ROW][COL], int row,int col);
//test.c
#include"game.h"
void menu()
{printf("**********************************************\n");printf("****************  1.play  ********************\n");printf("****************  0.exit  ********************\n");printf("**********************************************\n");
}
void game()
{char ret = 0;//存放下棋的数据char board[ROW][COL] = { 0 };//初始化棋盘为全空格init_board(board, ROW, COL);//打印棋盘display_board(board, ROW, COL);while (1){//玩家下棋player_move(board, ROW, COL);display_board(board, ROW, COL);//判断输赢ret = is_win(board, ROW, COL);if (ret != 'C'){break;}//电脑下棋computer_move(board, ROW, COL);display_board(board, ROW, COL);//判断输赢ret = is_win(board, ROW, COL);if (ret != 'C'){break;}}if (ret == '*'){printf("玩家赢了\n");}else if (ret == '#'){printf("电脑赢了\n");}else if (ret == 'Q'){printf("平局\n");}}
//玩家赢--'*'
//电脑赢--'#'
//平局--'Q'
//继续--'C'
int main()
{int input = 0;srand((unsigned int)time(NULL));do{menu();printf("请输入:");scanf("%d", &input);switch (input){case 1:game();break;case 0:printf("退出游戏\n");break;default:printf("输入错误,请重新输入\n");break;}} while (input);return 0;
}
//game.c
#include"game.h"
void init_board(char board[ROW][COL], int row, int col)
{int i = 0;for (i = 0; i < row; i++){for (int j = 0; j < col; j++){board[i][j] = ' '; }}
}
void display_board(char board[ROW][COL], int row, int col)
{for (int i = 0; i < row; i++){int j = 0;for (j = 0; j < col; j++){//打印数据printf(" %c ", board[i][j]);if(j<col-1)printf("|");}printf("\n");//打印分割行if (i < row - 1){for (j = 0; j < col; j++){printf("---", board[i][j]);if (j < col - 1)printf("|");}printf("\n");}}
}
void player_move(char board[ROW][COL], int row, int col)
{int x = 0;int y = 0;printf("玩家下棋\n");while (1){printf("请输入坐标:\n");scanf("%d %d", &x, &y);if (x >= 1 && x <= row && y >= 1 && y <= col){//下棋if (board[x - 1][y - 1] == ' '){board[x - 1][y - 1] = '*';break;}else{printf("该坐标被占用请重新输入\n");}}elseprintf("坐标非法,请重新输入\n");}}
void computer_move(char board[ROW][COL], int row, int col)
{int x = 0;int y = 0;printf("电脑下棋\n");while (1){x = rand() % row;y = rand() % col;if (board[x][x] == ' '){board[x][y] = '#';break;}}}
static int if_full(char board[ROW][COL], int row, int col)
{int i = 0;for (i = 0; i < row; i++){int j = 0;for (j = 0; j < col; j++){if (board[i][j] == ' '){return 0;}}}return 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][1] != ' '){return board[i][1];}}for (i = 0; i < col; i++){if (board[0][i] == board[1][i] && board[1][i] == board[2][i] && board[1][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 (if_full(board, row, col) == 1){return 'Q';}return 'C';
}

六、总结

这篇文章主要介绍三子棋游戏的实现,其中介绍了循环、选择语句使用以及如何结构化的完成一个项目,并且在设计过程中的调试过程会提升我们的技术,我认为是值得花费时间在这上面的,以上便是这篇文章的全部内容,感谢观看。

期待关注.

详细解读:C语言实现三子棋相关推荐

  1. 趣讲用c语言实现三子棋小游戏

    目录 直接先看看最后运行效果吧 三子棋如何设计的,及其步骤 1,源文件已经头文件的创建 2.创建主函数 3.test函数的创建 4.game函数的创建和运行 5.五个函数的实现 a.init_boar ...

  2. c语言程序下三子棋,C语言实现三子棋游戏(初级版)

    本文实例为大家分享了C语言实现三子棋游戏的具体代码,供大家参考,具体内容如下 game.h #include #include #include #define ROW 3 #define COL 3 ...

  3. 使用C语言编写三子棋小游戏

    使用C语言编写三子棋小游戏: 首先进行分析: 1.需要将游戏实现分为三个部分:头文件,函数功能实现,游戏组合测试. 2.游戏可以循环进行,不必多次打开,可采用 do...while循环结构. 3.游戏 ...

  4. C语言实现三子棋游戏 代码+思路+电脑下棋算法

    C语言实现三子棋游戏 代码+思路+电脑下棋算法 重点: 当检测到电脑已经两子连续时,将会尝试获得胜利. 在检测到玩家即将胜利(连城两子)时,进行拦截 尝试胜利的优先级高于拦截,意味着如果玩家不能再下一 ...

  5. 用C语言实现三子棋小游戏(C语言菜单创建--设置光标,隐藏光标)

    文章目录 前言 一.菜单设置 二.三子棋游戏 1.各部分代码 2.运行结果 总结 前言 本文主要用C语言实现三子棋(简易版)小游戏,同时介绍C语言中的菜单设置. 一.菜单设置 我们在C语言中设置菜单一 ...

  6. C语言实现三子棋小游戏(源码+教程)

    我猜中了开头,却猜不到这结局.--<大话西游> 目录 1.设计框架 2.设计流程 2.1菜单 2.2初始化棋子 2.3初始化棋盘 2.4玩家输入落子的坐标 2.5电脑随机生成棋子 2.6判 ...

  7. C语言实现三子棋游戏—可扩展到任意N子棋

    C语言实现三子棋 游戏介绍 游戏编程思路 游戏代码详解 主函数 游戏菜单函数 游戏逻辑函数 初始化棋盘 打印棋盘 玩家下棋 电脑下棋 判断输赢 完整代码 test.c game_chess.c gam ...

  8. 简单c语言实现三子棋/多子棋

    简单c语言实现三子棋/多子棋主要是想实现以下几个功能 (先做再循环)do while 一.目录: 1.play 0.exit 二.选择:(Switch)选择 三.进行游戏: 1.储存数据 - 二维数组 ...

  9. 【C语言】三子棋游戏的实现(玩家VS玩家 or 玩家VS电脑)

    目    录 一.三子棋游戏介绍 二.游戏功能函数分析 1 菜单显示函数 2 菜单选择函数 3 选择确认函数 4 显示当前棋盘状态函数 5 棋盘初始化函数 6 玩家下棋函数 7 电脑下棋函数 8 棋局 ...

最新文章

  1. 牛客网 PAT 算法历年真题 1003: 数素数 (20)
  2. 《JavaScript面向对象编程指南》——1.7 训练环境设置
  3. 如何用PPT编制方案 (2)PPT内容的逻辑表达
  4. 【离散数学】图的基本概念和结论
  5. SLF4J 与Log4J
  6. 【Visual C++】游戏开发笔记三十四 浅墨DirectX提高班之三 起承转合的艺术:Direct3D渲染五步曲...
  7. oracle-- 文字与格式字符串不匹配
  8. win10跳过计算机密码,win10开机密码忘了怎么办
  9. unity导出fbx模型_三维制作内容,maya模型贴图文件导入untiy,烘焙灯光贴图
  10. Centos7 快捷键调节屏幕亮度
  11. L2UWE: A Framework for the Efficient Enhancement of Low-Light Underwater Images阅读札记
  12. 企业从无到有,云账户CEO大谈创业时代的创业者思维
  13. 28 诊断偏差和方差:学习曲线 (28 Diagnosing bias and variance_ Learning curves)
  14. 数据技术嘉年华专列10月28日抵达广州,请做好接站准备
  15. 八爪鱼软件爬取数据的操作流程
  16. Access FileDialog 用户定义类型未定义(User-defined type not defined)的解决方法
  17. R语言科学计数法详解:digits和scipen设置
  18. 阳光男孩陈颢天 受邀担任第六季完美童模全球总决赛代言人
  19. 设计模式(二)The Observer Pattern(观察者模式)
  20. Dev-Control-gridview的属性说明

热门文章

  1. mysql注入之limit 注入
  2. 连接池中的maxIdle,MaxActive,maxWait等参数详解
  3. @JSONField
  4. python 的调试
  5. SQL(左连接,右连接,内连接)
  6. C语言-一元二次方程(求根公式)
  7. 安全测试之xss漏洞的检测与防御
  8. 《小白WEB安全入门》01. 扫盲篇
  9. 【bzoj2149】拆迁队
  10. 关于BufferedReader.readLine()