C语言三子棋,五子棋,n子棋的代码实现

  • 这里以五子棋为例,来说明开发过程
  • 开发思路
  • 菜单打印
  • 棋盘的打印
  • 棋子的打印
  • 电脑下棋(随机数)
  • 判断输赢
  • 代码整合
  • 注意事项

这里以五子棋为例,来说明开发过程

其中该项目包含3个文件,一个.h文件声明所用的函数,两个.c文件进行主要的代码书写。

项目效果展示:

开发思路

  • 菜单打印
  • 棋盘的打印(二维数组)
  • 棋子打印(下标)
  • 电脑下棋(随机数)
  • 判断输赢(竖,横,左斜,右斜…)

大致的思路就是这些,看过开发思路,脑海里应该就大致有了想法,有了主意。
接着,我们一步一步的进行开发。

菜单打印

菜单我们可以设计简单一些,同时把其放在一个函数中,这样便于调用。
该函数如下所示:

void menu()
{printf("*********************\n");printf("*** 1.play 0.exit ***\n");printf("*********************\n");
}

这里我们要不断的去 接收用户的输入,当为1时,进入游戏,为0时,退出程序
直接就想到了 条件语句判断,这里我们用switch

不断的:用户完成游戏后,可以再次打印菜单供用户选择

这个操作当然是项目的核心部分了,放在 main()函数里

int main()
{srand((unsigned int)time(NULL));// 设置随机数的生成起点(利用时间)  后面会讲随机数的使用int input = 0;do{menu();//打印菜单printf("请选择->\n");scanf("%d", &input);switch (input){case 1:game();break;case 0:printf("退出游戏\n");break;default:printf("输入错误!!!\n");break;}} while (input);return 0;
}

棋盘的打印

我们是利用二维数组打印棋盘,观察效果展示后可以发现,打印棋子的地方上 空格,然后用 “|”和“_” 装饰地图

首先打印出空格,为了便于控制棋盘行列数量,我们直接定义一个变量,之后对其进行赋值操作。
row col

void Initboard(char board[Row][Col], int row, int col)
{int i = 0, j = 0;for (i = 0; i < row; i++){for (j = 0; j < col; j++){board[i][j] = ' ';}}
}

同时在 game.h头文件中声明其函数,并定义变量的值

#pragma once#include <stdio.h>
#define Row 10
#define Col 10// 初始化棋盘
void Initboard(char board[Row][Col], int row, int col);
// 打印棋盘
void displayboard(char board[Row][Col], int row, int col);

最后,对棋盘进行装饰

void displayboard(char board[Row][Col], int row, int col)
{int i = 0;for (i = 0; i < row; i++){// 打印数据//printf(" %c | %c | %c | %c | %c \n", //board[i][0], board[i][1]......board[i][4]);int j = 0;for (j = 0; j < col; j++){printf(" %c ", board[i][j]);if (j < col - 1){printf("|");}}printf("\n");// 打印分割信息//printf("---|---|---|---|---\n");if (i < row - 1){int j = 0;for (j = 0; j < col; j++){printf("---");if (j < col - 1){printf("|");}}printf("\n");}}
}

棋子的打印

棋子的打印分为两部分:
1.玩家输入棋子坐标进行下棋
2.电脑根据随机数进行下棋

首先,进行玩家下棋
思路:
让用户输入二维数组下标进行判断
如果是空格,就可以用一个字符代替棋子进行占用。
若不为空格,则说明该位置上有棋子,则让玩家重新输入坐标

void paly_move(char board[Row][Col], int row, int col)
{// 玩家输入其坐标int x = 0, y = 0;printf("请玩家输入坐标(例如:1 1):\n");while (1){printf("请输入坐标->\n");scanf("%d %d", &x, &y);// 坐标的合法性判断  1.范围  2.是否被占用if (x >= 1 && x <= row && y >= 1 && y <= col){// 玩家输入的1 1 ,在二维数组中对应的为0 0// 二维数组坐标从0开始if (board[x - 1][y - 1] == ' '){board[x - 1][y - 1] = '*';break;}else{printf("坐标已被占用,不能下棋,请选择其他位置\n");}}else{printf("坐标非法,请重新输入->\n");}}
}

电脑下棋(随机数)

思路:
电脑下棋就是产生随机数–>随机坐标下棋
然后,判断该位置是否有棋子,若无则打印,若有则再次随机产生

随机数:
利用srand()time()函数
用法如下:

 #include <time.h>srand((unsigned int)time(NULL));

unsigned int 可以理解为自然数

这里是利用变化的时间作为种子,来进行产生随机数(:如果调用的间隙过短,则是产生相同的值)
对应rand()的随机数范围是0~32767

void computer_move(char board[Row][Col], int row, int col)
{printf("电脑下棋->\n");int x = 0, y = 0;// 判断并下棋while (1){// 利用随机数       返回test.c设置随机数的起点x = rand() % row;// rand()的随机数范围是0~32767 模上row(5) 就是0~5y = rand() % col;if (board[x][y] == ' '){board[x][y] = '#';break;}}
}

判断输赢

在循环下棋中,每次都去进行判断,所以有四种情况
我们可以 让其返回的值不同,然后就可以直接对返回值进行判断,进而判断输赢

  • 玩家赢 (返回值):*

  • 电脑赢 #

  • 平局 Q

  • 继续下棋 C

定义一个函数,判断棋盘是否满子
满子返回 1
未满返回 0

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

判断:

char who_win(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] == board[i][j+1] && board[i][j+1] == board[i][j+2] && board[i][j+2] == board[i][j+3] && board[i][j+3] == board[i][j+4] && board[i][j+3] != ' '){return board[i][j+2];}// 列if (board[i][j] == board[i+1][j] && board[i+1][j] == board[i+2][j] && board[i+2][j] == board[i+3][j] && board[i+3][j] == board[i+4][j] && board[i+4][j] != ' '){return board[i+1][j];}// 右斜if(board[i][j] == board[i + 1][j + 1] && board[i + 1][j + 1] == board[i + 2][j + 2] && board[i + 2][j + 2] == board[i + 3][j + 3] && board[i + 3][j + 3] == board[i + 4][j + 4] && board[i + 3][j + 3] != ' '){return board[i + 2][j + 2];}// 左斜if (board[i][j + 4] == board[i + 1][j + 3] && board[i + 1][j + 3] == board[i + 2][j + 2] && board[i + 2][j + 2] == board[i + 3][j + 1] && board[i + 3][j + 1] == board[i + 4][j] && board[i + 2][j + 2] != ' '){return board[i][j + 4];}}}// 棋盘满了,未分出胜负if (full_board(board, row, col)){return 'Q';}// 游戏继续return 'C';
}

到这里,整个项目的核心代码我们都已经分解好了,现在只剩下去整合了
我这里就直接上完整代码了

代码整合

test.c

# define _CRT_SECURE_NO_WARNINGS
#include "game.h"
#include <time.h>void menu()
{printf("*********************\n");printf("*** 1.play 0.exit ***\n");printf("*********************\n");
}
void game()
{char ret;char board[Row][Col] = { 0 };//初始化棋盘Initboard(board, Row, Col);displayboard(board, Row, Col);//下棋while (1){//玩家paly_move(board,Row, Col);//判断输赢ret = who_win(board, Row, Col);if (ret != 'C'){break;}//     打印棋盘displayboard(board, Row, Col);//电脑computer_move(board, Row, Col);ret = who_win(board, Row, Col);if (ret != 'C'){break;}//      打印棋盘displayboard(board, Row, Col);}if (ret == '*'){printf("玩家赢\n");}else if (ret == '#'){printf("电脑赢\n");}else{printf("平局\n");}
}
int main()
{srand((unsigned int)time(NULL));// 设置随机数的生成起点(利用时间)int input = 0;do{menu();//打印菜单printf("请选择->\n");scanf("%d", &input);switch (input){case 1:game();break;case 0:printf("退出游戏\n");break;default:printf("输入错误!!!\n");break;}} while (input);return 0;
}

game.h

#pragma once#include <stdio.h>
#define Row 10
#define Col 10// 初始化棋盘
void Initboard(char board[Row][Col], int row, int col);// 打印棋盘
void displayboard(char board[Row][Col], int row, int col);// 玩家下棋
void paly_move(char board[Row][Col], int row, int col);// 电脑下棋
// 找个空白的地方下棋
void computer_move(char board[Row][Col], int row, int col);// 判断棋盘形式
// 可以设置其对应的返回值,便于判断,以及继续执行程序
// 玩家赢    电脑赢     平局    继续下棋        (四种情况)
//  *          #          Q       C           字符char who_win(char board[Row][Col], int row, int col);

game.c

# define _CRT_SECURE_NO_WARNINGS#include "game.h"void Initboard(char board[Row][Col], int row, int col)
{int i = 0, 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;for (i = 0; i < row; i++){// 打印数据//printf(" %c | %c | %c | %c | %c \n", board[i][0], board[i][1]......board[i][4]);int j = 0;for (j = 0; j < col; j++){printf(" %c ", board[i][j]);if (j < col - 1){printf("|");}}printf("\n");// 打印分割信息//printf("---|---|---|---|---\n");if (i < row - 1){int j = 0;for (j = 0; j < col; j++){printf("---");if (j < col - 1){printf("|");}}printf("\n");}}
}void paly_move(char board[Row][Col], int row, int col)
{// 玩家输入其坐标int x = 0, y = 0;printf("请玩家输入坐标(例如:1 1):\n");while (1){printf("请输入坐标->\n");scanf("%d %d", &x, &y);// 坐标的合法性判断  1.范围  2.是否被占用if (x >= 1 && x <= row && y >= 1 && y <= col){// 玩家输入的1 1 ,在二维数组中对应的为0 0// 二维数组坐标从0开始if (board[x - 1][y - 1] == ' '){board[x - 1][y - 1] = '*';break;}else{printf("坐标已被占用,不能下棋,请选择其他位置\n");}}else{printf("坐标非法,请重新输入->\n");}}
}void computer_move(char board[Row][Col], int row, int col)
{printf("电脑下棋->\n");int x = 0, y = 0;// 判断并下棋while (1){// 利用随机数       返回test.c设置随机数的起点x = rand() % row;// rand()的随机数范围是0~32767 模上row(5) 就是0~5y = rand() % col;if (board[x][y] == ' '){board[x][y] = '#';break;}}}
// 定义一个函数,判断棋盘是否满子
// 满子返回 1
// 未满返回 0
int full_board(char board[Row][Col], int row, int col)
{int i = 0, j = 0;for (i = 0; i < row; i++){for (j = 0; j < col; j++){if (board[i][j] == ' '){return 0;}}}return 1;
}char who_win(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] == board[i][j+1] && board[i][j+1] == board[i][j+2] && board[i][j+2] == board[i][j+3] && board[i][j+3] == board[i][j+4] && board[i][j+3] != ' '){return board[i][j+2];}// 列if (board[i][j] == board[i+1][j] && board[i+1][j] == board[i+2][j] && board[i+2][j] == board[i+3][j] && board[i+3][j] == board[i+4][j] && board[i+4][j] != ' '){return board[i+1][j];}// 右斜if(board[i][j] == board[i + 1][j + 1] && board[i + 1][j + 1] == board[i + 2][j + 2] && board[i + 2][j + 2] == board[i + 3][j + 3] && board[i + 3][j + 3] == board[i + 4][j + 4] && board[i + 3][j + 3] != ' '){return board[i + 2][j + 2];}// 左斜if (board[i][j + 4] == board[i + 1][j + 3] && board[i + 1][j + 3] == board[i + 2][j + 2] && board[i + 2][j + 2] == board[i + 3][j + 1] && board[i + 3][j + 1] == board[i + 4][j] && board[i + 2][j + 2] != ' '){return board[i][j + 4];}}}// 棋盘满了,未分出胜负if (full_board(board, row, col)){return 'Q';}// 游戏继续return 'C';
}

注意事项

整个项目中只能有 一个main()函数和#include <stdio.h>
这里,我把 stdio.h 头文件放在game.h
之后再去调用game.h头文件,stdio.h 头文件也是包含其中的

我们可以控制row,col 的值改变棋盘的大小

在判断输赢里,修改判断语句可以修改为三子棋等等

C语言三子棋,五子棋,n子棋的代码实现相关推荐

  1. c语言实现三子棋(井子棋)

    目录 前言 一.初步构思 二.实现步骤 1.text.c 2.game.c 3.game.h 总结 前言 通过对c语言的初步学习,我们可以用循环,数组,函数的相关知识写一个简单的游戏.增强自信心的同时 ...

  2. c语言入门——三子棋(N子棋)

    目录 前言 一.什么是三子棋? 二.三子棋(N子棋)设计思路 1.主函数 2.数组的初始化 3.菜单 4.游戏主体 (1).棋盘 (2).下棋 (3).判断胜负 三.最终代码 源文件1 源文件2 头文 ...

  3. 三子棋(N子棋)小游戏超详解

    提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 文章目录 前言 一.三子棋的游戏规则? 二.三子棋的游戏设计的大概思路? 三.设计详细思路加代码 1.首先定义一个菜单menu函数 2 ...

  4. 推子五子棋、连六棋(六子棋)

    目录 推子五子棋 连六棋 推子五子棋 在线play 规则: 在5*5的盘面上下五子棋,正常肯定会下满25个格子,然后开始推子操作: 在一个格子落子,这个格子以及这一列它下面的(1-5个)所有格子都往下 ...

  5. 三子棋-支持N子棋-详解(以及堵截玩家的方法设计)

    我可能写的有些啰嗦,见谅,但我会很详细的讲解每一个步骤. 分析步骤 游戏框架的构造(游戏结构的设计) 代码布局设计 对游戏布局,初始选项的思考 将上述游戏设计实现 判断棋盘的局面 char ifdra ...

  6. 小游戏实现---三子棋至N子棋

    今天给大家介绍一款小游戏--三子棋,或称井字棋,想必大家小时候都玩过,一个九宫格,几个OX字符,寥寥几笔就能和小伙伴玩一下午,现在就跟我一起尝试用C语言来实现它吧. 目录 一.游戏设计思路 二. ma ...

  7. 三子棋(N子棋)游戏的保姆级超详细教程(C语言)

    写在前面(前言) 1. 何为三子棋: 三子棋是一种民间传统游戏,又叫九宫棋.圈圈叉叉棋.一条龙.井字棋等.游戏分为双方对战,双方依次在9宫格棋盘上摆放棋子,率先将自己的三个棋子走成一条线就视为胜利,而 ...

  8. C语言实现五子棋(n子棋)

    五子棋的历史背景: 五子棋起源于中国,是全国智力运动会竞技项目之一,是一种两人对弈的纯策略型棋类游戏.双方分别使用黑白两色的棋子,下在棋盘直线与横线的交叉点上,先形成五子连珠者获胜. 五子棋容易上手, ...

  9. C语言制作一个五子棋小游戏【附代码】

    目录 五子棋游戏设计与实现 1.1 系统开发思路(需求分析) 1.2 系统功能设计 1.3 系统详细设计 1.3.1数据结构设计 1.4 系统实现 1.5 系统测试 五子棋游戏设计与实现 1.1 系统 ...

  10. C语言 五子棋游戏(也可n子棋)

    目录 1.创造棋盘 2.玩家下棋 3.电脑下棋 4.判断输赢 赢的判断(也是最难的): 行的判断: 列的判断: 主副对角线的判断(花费时间最长): 平局或者继续: 最后判断的全部代码 三个文件的代码 ...

最新文章

  1. 递归回溯解决八皇后问题
  2. Day03-卷积神经网络原理与使用
  3. git stash pop冲突_这有一份 git 日常使用清单,你需要吗?
  4. 【强化学习】深度强化学习入门介绍
  5. 并不对劲的loj2179:p3714:[BJOI2017]树的难题
  6. 关于js优化和css优化
  7. phpMyAdmin开发人员访谈——4个人支持整个项目
  8. redis本地及远程登录
  9. java gc 循环引用_JVM(3)对象A和B循环引用,最后会不会不被GC回收?-------关于Java的GC机制...
  10. Android控件系列之XML静态资源
  11. [C# 网络编程系列]专题九:实现类似QQ的即时通信程序
  12. 使用JFreeChart实现基于Web的柱状图
  13. JS为键盘中的Enter键添加onkeyDown()和onkeyUp()事件
  14. 微软:Windows 7 和 10 都将删除自动更新!
  15. PROTEL技术应用技巧总结
  16. 学python需要c-为什么我建议每个开发人员都需要学 Python ?
  17. 关于介绍最好用的windows10系统的文章
  18. cai鸡——处女作博客“横空出世”
  19. 新的一年,新的希望,新的努力
  20. 网络发现已关闭网络计算机和设备不可见

热门文章

  1. 软件长寿法则 记住这7条
  2. 写一个有app控制的自动开锁系统
  3. 魅族宣布加入鸿蒙的是哪个手机,华为终于不孤单了!魅族宣布接入鸿蒙,网友却喊话雷军...
  4. Python中两个list取交集、并集、差集以及为字符串str添加、插入特定字符的操作总结
  5. 适合编程初学者的开源项目:小游戏2048(iOS-SwiftUI版)
  6. vue页面重置和刷新(vue数据重置)
  7. html表格边框void,绘制HTML表格边框
  8. JUC:通过PrintAB管中窥豹
  9. ubuntu下安装百度输入法步骤
  10. 如何选择一款适合自己的换IP软件呢?