C语言实践——双人五子棋(进阶版)
双人五子棋
- 前言
- 一、棋盘的美化
- 二、棋子的美化
- 三、棋盘的打印
- 四、控制台修改颜色
- 五、五子棋源代码
前言
上一篇文章讲了如何用C语言写一个简易的双人五子棋小游戏,但是存在一些缺陷,比如棋盘太“粗糙”,棋子不美观。今天我们就来美化一下棋盘和棋子,文章最后附带有五子棋源代码哦!。对五子棋设计感兴趣的同学可以看一下这篇文章: C语言实践——双人五子棋(简易版)
1.美化之前的棋盘
2.美化之后的棋盘
一、棋盘的美化
用棋盘符号“┌”、“─”、“┬”、“─”、“┐”、“└”、“┴”、“┘”、“├”、“┤”、“┼”、“│”代替符号“+”。对棋盘的每个点位存入相应的棋盘符号到棋盘数组board[ i ] [ j ]里。需要注意的是第一行和最后一行需要单独拿出来处理,因为只有第一行会用到这些“┌”、“┬”、“┐”棋盘符号,只有最后一行会用到这些“└”、“┴”、“┘”棋盘符号,其余中间行都会用到这些“├”、“┤”、“┼”棋盘符号。
所以数组存储的棋盘如下:
┌┬┬┬┬┬┬┬┬┬┬┬┬┬┐第一行
├┼┼┼┼┼┼┼┼┼┼┼┼┼┤第二行
├┼┼┼┼┼┼┼┼┼┼┼┼┼┤第三行
├┼┼┼┼┼┼┼┼┼┼┼┼┼┤第四行
├┼┼┼┼┼┼┼┼┼┼┼┼┼┤第五行
├┼┼┼┼┼┼┼┼┼┼┼┼┼┤第六行
├┼┼┼┼┼┼┼┼┼┼┼┼┼┤第七行
├┼┼┼┼┼┼┼┼┼┼┼┼┼┤第八行
├┼┼┼┼┼┼┼┼┼┼┼┼┼┤第九行
├┼┼┼┼┼┼┼┼┼┼┼┼┼┤第十行
├┼┼┼┼┼┼┼┼┼┼┼┼┼┤第十一行
├┼┼┼┼┼┼┼┼┼┼┼┼┼┤第十二行
├┼┼┼┼┼┼┼┼┼┼┼┼┼┤第十三行
├┼┼┼┼┼┼┼┼┼┼┼┼┼┤第十四行
└┴┴┴┴┴┴┴┴┴┴┴┴┴┘第十五行
棋盘初始化代码如下:
void init_board() // 初始化棋盘
{int i, j;for (i = 0; i < ROWS; i++){if (i == 0)//第一行特殊处理{for (j = 0; j < COLS; j++){if (j == 0)//第一行第一列特殊处理{strcpy(board[i][j], "┌ ");}else if (j == 14)//第一行第一列特殊处理{strcpy(board[i][j], "┐ ");}else{strcpy(board[i][j], "┬ ");} }}else if (i == 14)//最后一行特殊处理{for (j = 0; j < COLS; j++){if (j == 0)//最后一行最后一列特殊处理{strcpy(board[i][j], "└ ");}else if (j == 14){strcpy(board[i][j], "┘ ");//最后一行最后一列特殊处理}else{strcpy(board[i][j], "┴ ");}}}else//其他行处理{for (j = 0; j < COLS; j++){if (j == 0)//第一列特殊处理{strcpy(board[i][j], "├ ");}else if (j == 14)//最后一列特殊处理{strcpy(board[i][j], "┤ ");}else{strcpy(board[i][j], "┼ ");}}}}
}
二、棋子的美化
用黑白棋子符号“●”、“○”代替字符‘X’、‘0’,棋子如何打印出来呢?首先由scanf函数接收到坐标(x,y),这时将棋子“●”或者“○”传递给棋盘board[ x ] [ y ],这里使用到的函数是strcpy。
棋子代码如下
strcpy(board[x][y], c[0][0]);
if ((strcmp(c[0][0], "●") == 0))//交换双方下子
{strcpy(c[0][0], "○");
}
else
{strcpy(c[0][0], "●");
}
三、棋盘的打印
将棋盘数组打印到相应的点位,展现整体的棋盘。由棋盘的初始化函数我们得到了如下的棋子位置的数组。
┌┬┬┬┬┬┬┬┬┬┬┬┬┬┐第一行
├┼┼┼┼┼┼┼┼┼┼┼┼┼┤第二行
├┼┼┼┼┼┼┼┼┼┼┼┼┼┤第三行
├┼┼┼┼┼┼┼┼┼┼┼┼┼┤第四行
├┼┼┼┼┼┼┼┼┼┼┼┼┼┤第五行
├┼┼┼┼┼┼┼┼┼┼┼┼┼┤第六行
├┼┼┼┼┼┼┼┼┼┼┼┼┼┤第七行
├┼┼┼┼┼┼┼┼┼┼┼┼┼┤第八行
├┼┼┼┼┼┼┼┼┼┼┼┼┼┤第九行
├┼┼┼┼┼┼┼┼┼┼┼┼┼┤第十行
├┼┼┼┼┼┼┼┼┼┼┼┼┼┤第十一行
├┼┼┼┼┼┼┼┼┼┼┼┼┼┤第十二行
├┼┼┼┼┼┼┼┼┼┼┼┼┼┤第十三行
├┼┼┼┼┼┼┼┼┼┼┼┼┼┤第十四行
└┴┴┴┴┴┴┴┴┴┴┴┴┴┘第十五行
但是,完整的棋盘还少了“─”、“ │”棋盘元素,这就需要用到打印棋盘函数print_board()打印出来。当然这里需要将第一行单独打印,还得在每列每行的开始和结尾标上自己的行数和列数,这里用%s表示棋子的位置。
所以打印出的棋盘效果如下:
0 1 2 3 4 5 6 7 8 9 10 11 1213 14
0 ┌─┬─┬─┬─┬─┬─┬─┬─┬─┬─┬─┬─┬─┬─┐0
1 ├─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┤1
2 ├─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┤2
3 ├─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┤3
4 ├─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┤4
5 ├─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┤5
6 ├─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┤6
7 ├─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┤7
8 ├─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┤8
9 ├─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┤9
10├─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┤10
11├─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┤11
12├─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┤12
13├─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┤13
14└─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┘14
0 1 2 3 4 5 6 7 8 9 10 11 1213 14
棋盘打印代码如下:
void print_board()// 打印棋盘
{ int i;printf(" 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 \n");printf(" 0%s─ %s─ %s─ %s─ %s─ %s─ %s─ %s─ %s─ %s─ %s─ %s─ %s─ %s─ %s 0\n", board[0][0], board[0][1], board[0][2], board[0][3],board[0][4],board[0][5], board[0][6], board[0][7], board[0][8], board[0][9], board[0][10], board[0][11], board[0][12], board[0][13], board[0][14]);for (i = 1; i < 14; i++){printf(" │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ \n");printf(" %2d%s─ %s─ %s─ %s─ %s─ %s─ %s─ %s─ %s─ %s─ %s─ %s─ %s─ %s─ %s%2d\n",i,board[i][0], board[i][1], board[i][2], board[i][3], board[i][4], board[i][5], board[i][6], board[i][7], board[i][8], board[i][9], board[i][10], board[i][11], board[i][12], board[i][13], board[i][14],i);}printf(" 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 \n");
}
四、控制台修改颜色
最后将VS控制台窗口的屏幕背景修改为自己喜欢的颜色。
五、五子棋源代码
#define _CRT_SECURE_NO_WARNINGS 1
#include <stdio.h>
#include <stdlib.h>
#include <string.h>#define ROWS 15 //行 国际标准棋盘 15 * 15
#define COLS 15 //列char board[ROWS][COLS][4] = {}; // 棋盘0
char board1[ROWS][COLS][4] = {}; // 棋盘1
char c[1][1][4] = {};
void print_board();
void init_board() // 初始化棋盘
{int i, j;for (i = 0; i < ROWS; i++){if (i == 0){for (j = 0; j < COLS; j++){if (j == 0){strcpy(board[i][j], "┌ ");}else if (j == 14){strcpy(board[i][j], "┐ ");}else{strcpy(board[i][j], "┬ ");} }}else if (i == 14){for (j = 0; j < COLS; j++){if (j == 0){strcpy(board[i][j], "└ ");}else if (j == 14){strcpy(board[i][j], "┘ ");}else{strcpy(board[i][j], "┴ ");}}}else{for (j = 0; j < COLS; j++){if (j == 0){strcpy(board[i][j], "├ ");}else if (j == 14){strcpy(board[i][j], "┤ ");}else{strcpy(board[i][j], "┼ ");}}}}
}
void init_board1() // 初始化棋盘1
{int i, j;for (i = 0; i < ROWS; i++){if (i == 0){for (j = 0; j < COLS; j++){if (j == 0){strcpy(board1[i][j], "┌ ");}else if (j == 14){strcpy(board1[i][j], "┐ ");}else{strcpy(board1[i][j], "┬ ");}}}else if (i == 14){for (j = 0; j < COLS; j++){if (j == 0){strcpy(board1[i][j], "└ ");}else if (j == 14){strcpy(board1[i][j], "┘ ");}else{strcpy(board1[i][j], "┴ ");}}}else{for (j = 0; j < COLS; j++){if (j == 0){strcpy(board1[i][j], "├ ");}else if (j == 14){strcpy(board1[i][j], "┤ ");}else{strcpy(board1[i][j], "┼ ");}}}}
}void print_board()// 打印棋盘
{ int i;printf(" 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 \n");printf(" 0%s─ %s─ %s─ %s─ %s─ %s─ %s─ %s─ %s─ %s─ %s─ %s─ %s─ %s─ %s 0\n", board[0][0], board[0][1], board[0][2], board[0][3],board[0][4],board[0][5], board[0][6], board[0][7], board[0][8], board[0][9], board[0][10], board[0][11], board[0][12], board[0][13], board[0][14]);for (i = 1; i < 14; i++){printf(" │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ \n");printf(" %2d%s─ %s─ %s─ %s─ %s─ %s─ %s─ %s─ %s─ %s─ %s─ %s─ %s─ %s─ %s%2d\n",i,board[i][0], board[i][1], board[i][2], board[i][3], board[i][4], board[i][5], board[i][6], board[i][7], board[i][8], board[i][9], board[i][10], board[i][11], board[i][12], board[i][13], board[i][14],i);}printf(" │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ \n");printf(" 14%s─ %s─ %s─ %s─ %s─ %s─ %s─ %s─ %s─ %s─ %s─ %s─ %s─ %s─ %s14\n", board[14][0], board[14][1], board[14][2], board[14][3], board[14][4], board[14][5], board[14][6], board[14][7], board[14][8],board[14][9], board[14][10], board[14][11], board[14][12], board[14][13], board[14][14]);printf(" 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 \n");
}int is_win(char* c) // 判断是否胜利
{int i, j, k;for (i = 0; i < ROWS; i++)//一颗一颗扫描判断{for (j = 0; j < COLS; j++){if ( strcmp(board[i][j], c) == 0){for (k = 1; k < 5; k++){if (i + k < ROWS && strcmp(board[i + k][j], c) == 0 &&i + k - 1 >= 0 && strcmp(board[i + k - 1][j], c) == 0 &&i + k - 2 >= 0 && strcmp(board[i + k - 2][j], c) == 0 &&i + k - 3 >= 0 && strcmp(board[i + k - 3][j], c) == 0 &&i + k - 4 >= 0 && strcmp(board[i + k - 4][j], c) == 0)//判断列五颗棋子是否相同{return 1;}if (j + k < COLS && strcmp(board[i][j + k], c) == 0 &&j + k - 1 >= 0 && strcmp(board[i][j + k -1], c) == 0 &&j + k - 2 >= 0 && strcmp(board[i][j + k -2], c) == 0 &&j + k - 3 >= 0 && strcmp(board[i][j + k - 3], c) == 0 &&j + k - 4 >= 0 && strcmp(board[i][j + k - 4], c) == 0)//判断行五颗棋子是否相同{return 1;}if (i + k < ROWS && j + k < COLS && strcmp(board[i + k][j + k], c) == 0 &&i + k - 1 >= 0 && j + k - 1 >= 0 && strcmp(board[i + k - 1][j + k - 1], c) == 0 &&i + k - 2 >= 0 && j + k - 2 >= 0 && strcmp(board[i + k - 2][j + k - 2], c) == 0 &&i + k - 3 >= 0 && j + k - 3 >= 0 && strcmp(board[i + k - 3][j + k - 3], c) == 0 &&i + k - 4 >= 0 && j + k - 4 >= 0 && strcmp(board[i + k - 4][j + k - 4], c) == 0)//判断主对角线五颗棋子是否相同{return 1;}if (i + k < ROWS && j - k >= 0 && strcmp(board[i + k][j - k], c) == 0 &&i + k - 1 >= 0 && j - k + 1 < COLS && strcmp(board[i + k - 1][j - k + 1], c) == 0 &&i + k - 2 >= 0 && j - k + 2 < COLS && strcmp(board[i + k - 2][j - k + 2], c) == 0 &&i + k - 3 >= 0 && j - k + 3 < COLS && strcmp(board[i + k - 3][j - k + 3], c) == 0 &&i + k - 4 >= 0 && j - k + 4 < COLS && strcmp(board[i + k - 4][j - k + 4], c) == 0)//判断负对角线五颗棋子是否相同{return 1;//有一方胜利}}}}}return 0;
}void safe_flush(FILE* fp)//清除scanf缓存区
{int ch;while ((ch = fgetc(fp)) != EOF && ch != '\n');
}int main()
{int x, y, i = 0;strcpy(c[0][0], "●");// 黑方 白方char k;//再战选择
start: //goto标志system("cls");//清屏init_board(); //初始化棋盘print_board(); //打印棋盘while (1){printf("请%s方输入坐标(x,y): ", c[0][0]);scanf("%d,%d", &x, &y);safe_flush(stdin);//清除scanf缓存区if (x < 0 || x >= ROWS || y < 0 || y >= COLS){printf("坐标不合法,请重新输入!\n");continue;}if ((strcmp(board[x][y], "○") == 0) || (strcmp(board[x][y], "●") == 0)){printf("该位置已经有棋子,请重新输入!\n");continue;}system("cls");//清屏strcpy(board[x][y], c[0][0]);print_board();if (is_win(c[0][0])){printf("%s方胜利!\n", c[0][0]);break;}i++;if (i == ROWS * COLS)//棋盘已下满{printf("平局!\n");break;}if ((strcmp(c[0][0], "●") == 0))//交换双方下子{strcpy(c[0][0], "○");}else{strcpy(c[0][0], "●");} }printf("还要再来一把吗?输入y或n:>");//从开选择scanf("%c", &k);safe_flush(stdin);while (k != 'y' && k != 'n'){printf("输入错误,请重新输入(Y/N):>");scanf("%c", &k);safe_flush(stdin);}while (k == 'y'){goto start;}printf("谢谢使用!\n");return 0;
}
C语言实践——双人五子棋(进阶版)相关推荐
- C语言实践——双人五子棋(简易版)
双人五子棋 前言 一.五子棋的元素 二.五子棋规则(简单) 三.主要功能的设计 1.头文件和宏定义 2.初始化棋盘 3.打印棋盘 4.判断输赢 5.辅助函数 6.主函数 四.程序结果展示 前言 五子棋 ...
- C语言三子棋游戏进阶版详解(包括多子棋)
目录 一,总体思路介绍 二,具体思路的实现 1.初始化游戏界面 2.初始化棋盘 3.打印棋盘 4.玩家移动 5.电脑移动 6.判断输赢 三,源码展示 game.h game.c test.c 一,总体 ...
- 爬取抖音数据实践方案《进阶版》
这篇文章是续上一篇(爬取抖音数据实践方案<基础版>).根据实际情况,落地的方案是:mitmdump+模拟器+python脚本+mysql数据库. 最终达到的效果截图: 接下来我把上面方案拆 ...
- C语言五子棋进阶版(增设玩家对战,大棋盘,棋盘行列对应等)
经过好多天的编写,五子棋项目总算完成,作为一个学了不是很久的小白,我在编写过程中也遇到了许多困难,但还好都解决了,在此我建议和我一样,是小白的都应该写写五子棋或三子棋,当然,不是全抄别人的代码,也不是 ...
- 五子棋-进阶版:C#窗体编写
1.0版:C#窗体程序编写 • [五子棋] 进阶内容,主要有 悔棋 功能,和 棋盘下满 时的处理 友情提示:先了解之前的 1.0版五子棋 No1.悔棋 第一步.定义一个列表(用于记录下棋顺序) // ...
- js实战 网页五子棋进阶版
对比上一版本增加了音效和计时器两个模块. 代码如下 <!doctype html> <html> <head><meta charset="utf- ...
- 《C语言程序设计与实践(第2版)》——3.2 数据类型
本节书摘来自华章出版社<C语言程序设计与实践(第2版)>一书中的第3章,第3.2节,作者:凌云等著,更多章节内容可以访问云栖社区"华章计算机"公众号查看 3.2 数据类 ...
- 《C语言程序设计与实践(第2版)》——第1章 C语言与程序设计概述 1.1初见C语言程序...
本节书摘来自华章出版社<C语言程序设计与实践(第2版)>一书中的第1章,第1.1节,作者:凌云等著,更多章节内容可以访问云栖社区"华章计算机"公众号查看 第1章 C语言 ...
- C语言 进阶版三子棋小游戏
目录 前言 游戏运行效果: 游戏代码: 1.test.c文件 2. game.h头文件 3. game.c 一.框架部分 二.游戏函数实现 1.创建数组并初始化 2.打印数组 3.玩家下棋 4.电 ...
最新文章
- 自己实现一个最简单的数据库
- 隐藏画质代码_「图」画质修改工具ReShade放出4.5.0更新:改进对Vulkan等较新API的支持...
- P1056 排座椅(模拟)
- 如何在sqlserver数据库中删除主键相同的数据只留其一
- TCP四次握手释放连接
- c语言插入排序算法_插入排序算法,流程图和C,C ++代码
- XOR and Favorite Number(CF-617E)
- 【三色N95pro显示器驱动板烧录-维修小记】
- np.maximum()
- 纯音乐自制吉他及钢琴简谱合集
- 营销第一人:富军相信网络营销神器能够“博”出未来
- 程序和进程的关系程序
- 网络推广优化专员工作职责,网络推广专员工作内容
- 个人大数据征信查询浅谈与撸待现象
- hdu多校第二场 1005 (hdu6595) Everything Is Generated In Equal Probability
- 土地利用覆被变化的概念_土地利用土地覆被变化研究概述
- 第一台计算机影片观后感,影片叫我第一名观后感
- opencv3_java 修改图像大小Resize Imgproc.resize
- matlab自带的插值函数interp1的几种插值方法
- 物联网设备预警解决方案
热门文章
- touchgfx程序_6.TouchGFX界面应用之定时器机制
- 姓名免费测试打分 ,我们之间的缘分是多少
- VC2010 Working Directory
- windows2008服务器如何显示“我的电脑”图标
- 次坐标从0开始_什么是齐次坐标?
- python根据表格数据生成折线图_Kaggle、Python数据可视化seaborn(二):折线图
- 【真人手势动画制作软件】万彩手影大师教程 | 发布视频
- 软文撰写有哪些技巧?
- 14天学会安卓开发(第一天)Android架构与环境搭建
- 通过哪几方面可以找到证券量化交易接口?