目录

一、前言

二、头文件

三、menu菜单函数

四、初始化棋盘Initboard函数

五、显示棋盘Displayboard函数

六、落子函数

七、判断输赢ifwin

八、人机、人人模式的选择

九、作者遇到的坑点

十、完整的代码


一、前言

本文将先介绍五子棋运行所需要的函数,最后串联成完整代码。

我们需要实现的功能有:1.菜单menu函数

2.初始化棋盘Initboard函数

3.显示棋盘Displayboard函数

4.实现人机、人人模式的选择

5.落子函数 playermove  computermove

6.判断输赢ifwin函数

先来看看运行效果吧!


二、头文件

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <string.h>
#include<time.h>
#include<stdlib.h>
#include<windows.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 Playermove_1(char board[ROW][COL], int row, int col,int*px,int *py);
//玩家一下棋
void Playermove_2(char board[ROW][COL], int row, int col,int*px, int *py);
//玩家二下棋
void computermove(char board[ROW][COL], int row, int col);
//电脑下棋
void game1(char board[ROW][COL], int row, int col);
//人机模式
void game2(char board[ROW][COL], int row, int col);
//人人模式
int Ifwin(char board[ROW][COL], int row, int col, int x, int y);
//判断输赢
int check_x(char board[ROW][COL], int row, int col, int x, int y);
//判断竖直五子
int check_y(char board[ROW][COL], int row, int col, int x, int y);
//判断水平五子
int check_xy_up(char board[ROW][COL], int row, int col, int x, int y);
//判断斜上五子
int check_xy_down(char board[ROW][COL], int row, int col, int x, int y);
//判断斜下五子

三、menu菜单函数

void menu()
{   //完成菜单的初始化printf("***********************\n");printf("***********************\n");printf("*****1.play  0.exit****\n");printf("***********************\n");printf("***********************\n");printf("请输入:");
}

很简单,就不多说了


四、初始化棋盘Initboard函数

初始化棋盘,为数组一一存入空格

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] = ' ';}}
}

五、显示棋盘Displayboard函数

打印简单的方格线,并打印数据内容

void Displayboard(char board[ROW][COL], int row, int col)
{int i = 0;int j = 0;for (j = 0; j < col; j++)//打印横向y坐标{if (j == 0)//考虑到x轴所占的一格{printf("  %d  ", j + 1);}else{printf(" %d  ", j + 1);}}printf("\n");for (i = 0; i < row; i++)//打印数据{for (j = 0; j < col; j++){if (j == 0)//顺带打印竖向x坐标{printf("%2d",i+1);//%md表示域宽为mprintf("  %c ",board[i][j]);}else{printf(" %c ", board[i][j]);}if (j < col - 1)printf("|");}printf("\n");//打印分割行if (i < row - 1){for (j = 0; j < col; j++){if (j == 0)//同样考虑到y轴printf("   ---");elseprintf("---");if (j < col - 1)printf("|");}printf("\n");}}}

六、落子函数

玩家一落子——playermove_1

void Playermove_1(char board[ROW][COL], int row, int col, int *px, int*py)//ROW可以省,COL不行
{int x = *px;int y = *py;while (1){if (x >= 1 && x <= row && y >= 1 && y <= col)//判断输入坐标的合法性{if (board[x -1][y- 1] == ' ')//保证落子点为空{                           board[x-1 ][y -1] = '*';*px = x; *py = y;//如果开始xy输入不合法,则要对外部xy修改,所以选择传址操作break;}else{printf("你不能在此处落子\n");printf("玩家1落子,请重新输入x y坐标: ");scanf("%d%d", &x, &y);}}else{printf("输入坐标不合法\n");printf("玩家落子,请重新输入x y坐标: ");scanf("%d%d", &x, &y);}}}

玩家2落子完全相同,就不赘叙了

电脑落子

void computermove(char board[ROW][COL], int row, int col)
{int x = 0;int y = 0;//rand函数的使用需要srand函数的初始化,但srand不可以被重复调用,所以放在外部while (1){x = rand() % ROW;y = rand() % COL;if (board[x][y] == ' ')//x的范围在0~row-1,所以这里x不用-1了{board[x][y] = '#';break;}}}

七、判断输赢ifwin

根据我们下五子棋的经验,能获胜的地方必定是最后落子的水平线、竖直线、和两个斜对角线,我们只需对其进行检索即可。ifwin的返回值决定之后的switch语句

弱弱的说一句,虽然看起来多,但很多都是重复的。若要优化就使用函数指针

int Ifwin(char board[ROW][COL], int row, int col, int x, int y)
{int ret;{ret = check_x(board, row, col, x, y);if (ret >= 5)return 0;ret = check_y(board, row, col, x, y);if (ret >= 5)return 0;ret = check_xy_up(board, row, col, x, y);if (ret >= 5)return 0;ret = check_xy_down(board, row, col, x, y);if (ret >= 5)return 0;}return 3;
}int check_x(char board[ROW][COL], int row, int col, int x, int y)//检查x轴竖直方向
{int sum = 1;int old_x = x;while (x < row  && board[x - 1][y - 1] == board[x][y - 1]){sum++;x++;}x = old_x;while (x-2>= 0 && board[x - 1][y - 1] == board[x - 2][y - 1] ){sum++;x--;}return sum;
}int check_y(char board[ROW][COL], int row, int col, int x, int y)//检查y轴水平方向
{int sum = 1;int old_y = y;while (y<col && board[x-1][y-1] == board[x-1][y]  ){sum++;y++;}y = old_y;while (y-2 >= 0 && board[x-1][y-1] == board[x-1][y -2]  ){sum++;y--;}return sum;
}int check_xy_up(char board[ROW][COL], int row, int col, int x, int y)//检查斜上45度
{int sum = 1;int old_x = x;int old_y = y;while (x<row &&  y - 2 >= 0 && board[x - 1][y - 1] == board[x][y - 2]){sum++;x++;y--;}x = old_x;y = old_y;while (x - 2 >= 0 && y <col && board[x - 1][y - 1] == board[x - 2][y]){sum++;x--;y++;}return sum;
}int check_xy_down(char board[ROW][COL], int row, int col, int x, int y)//检查斜下45度
{int sum = 1;int old_x = x;int old_y = y;while (x<row && y <col && board[x - 1][y - 1] == board[x][y]){sum++;x++;y++;}x = old_x;y = old_y;while (board[x-1][y-1] == board[x -2][y-2 ] && x-2>=0  && y-2 >=0){sum++;x--;y--;}return sum;
}

八、人机、人人模式的选择

初始选择界面

void game()
{int input;char board[ROW][COL] = { 0 };Initboard(board, ROW, COL);//初始化棋盘Displayboard(board, ROW, COL);//展示棋盘printf("请选择模式:1.人机;2.玩家对战\n");printf("请选择:");do{scanf("%d", &input);printf("\n");switch (input){case 1:printf("游戏模式1开始!(注意:竖为x轴,横为y轴)\n");  game1(board, ROW, COL); break;case 2:printf("游戏模式2开始!(注意:竖为x轴,横为y轴)\n"); ; game2(board, ROW, COL); break;default:printf("请重新输入\n"); break;}} while (input != 1 && input != 2);//do while语句在输入错误时反复输入
}

game1的具体实现

void game1(char board[ROW][COL], int row, int col)
{srand((unsigned int)time(NULL));//srand只要设置一次就可以,所以要放在while循环外while (1){int ret;int count = 0;int flag = 0;//判读玩家的下棋int x; int y;printf("玩家落子,请依次输入x y坐标: ");scanf("%d%d", &x, &y);Playermove_1(board, row, col,&x, &y);count++;Displayboard(board, ROW, COL);if (count == ROW*COL)//全下满则认为平局ret = 1;else ret = Ifwin(board, ROW, COL, x, y);switch (ret){case 0:printf("玩家获胜\n"); flag = 1; break;case     1:printf("平局\n"); flag = 1; break;default: break;}if (flag == 1)//用flag跳出while循环break;//判断计算机的下棋computermove(board, row, col);count++;Displayboard(board, ROW, COL);if (count == ROW*COL)ret = 1;elseret = Ifwin(board, ROW, COL, x, y);switch (ret){case 0:printf("电脑获胜\n"); flag = 1; break;case    1:printf("平局\n"); flag = 1; break;default: break;}if (flag == 1)break;}}

作者觉得写的是挺啰嗦,欢迎留言建议。game2和game1玩家一的内容很相近,就不赘述


九、作者遇到的坑点

1.输入的坐标和存在数组里的下标有减一的关系,在写的时候不要写忘记了

2.传址操作才能改变函数外的变量值


十、完整的代码

头文件就省了

int main()
{int input;do{system("cls");//清屏menu();scanf("%d", &input);switch (input){case 1:printf("游戏开始\n\n");  game(); break;case 0:printf("退出游戏\n"); break;default:printf("请重新输入\n"); break;}Sleep(3000);//暂停3秒} while (input);//do while语句实现可以反复玩return 0;
}void menu()
{   //完成菜单的初始化printf("***********************\n");printf("***********************\n");printf("*****1.play  0.exit****\n");printf("***********************\n");printf("***********************\n");printf("请输入:");
}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 (j = 0; j < col; j++)//打印横向y坐标{if (j == 0)//考虑到x轴所占的一格{printf("  %d  ", j + 1);}else{printf(" %d  ", j + 1);}}printf("\n");for (i = 0; i < row; i++)//打印数据{for (j = 0; j < col; j++){if (j == 0)//顺带打印竖向x坐标{printf("%2d",i+1);//%md表示域宽为mprintf("  %c ",board[i][j]);}else{printf(" %c ", board[i][j]);}//数字表示坐标if (j < col - 1)printf("|");}printf("\n");//打印分割行if (i < row - 1){for (j = 0; j < col; j++){if (j == 0)//同样考虑到y轴printf("   ---");elseprintf("---");if (j < col - 1)printf("|");}printf("\n");//别忘记这里也要换行}}}void game()
{int input;char board[ROW][COL] = { 0 };Initboard(board, ROW, COL);//初始化棋盘Displayboard(board, ROW, COL);//展示棋盘printf("请选择模式:1.人机;2.玩家对战\n");printf("请选择:");do{scanf("%d", &input);printf("\n");switch (input){case 1:printf("游戏模式1开始!(注意:竖为x轴,横为y轴)\n");  game1(board, ROW, COL); break;case 2:printf("游戏模式2开始!(注意:竖为x轴,横为y轴)\n"); ; game2(board, ROW, COL); break;default:printf("请重新输入\n"); break;}} while (input != 1 && input != 2);//do while语句在输入错误时反复输入
}void game1(char board[ROW][COL], int row, int col)
{srand((unsigned int)time(NULL));//srand只要设置一次就可以,所以要放在while循环外while (1){int ret;int count = 0;int flag = 0;//判读玩家的下棋int x; int y;printf("玩家落子,请依次输入x y坐标: ");scanf("%d%d", &x, &y);Playermove_1(board, row, col,&x, &y);count++;Displayboard(board, ROW, COL);if (count == ROW*COL)//全下满则认为平局ret = 1;else ret = Ifwin(board, ROW, COL, x, y);switch (ret){case 0:printf("玩家获胜\n"); flag = 1; break;case     1:printf("平局\n"); flag = 1; break;default: break;}if (flag == 1)//用flag跳出while循环break;//判断计算机的下棋computermove(board, row, col);count++;Displayboard(board, ROW, COL);if (count == ROW*COL)ret = 1;elseret = Ifwin(board, ROW, COL, x, y);switch (ret){case 0:printf("电脑获胜\n"); flag = 1; break;case    1:printf("平局\n"); flag = 1; break;default: break;}if (flag == 1)break;}}void game2(char board[ROW][COL], int row, int col)
{while (1){int ret;int count = 0;int flag = 0;int x; int y;//判读玩家1的下棋printf("玩家1落子,请输入坐标:(注意:竖为x轴,横为y轴)");scanf("%d%d", &x, &y);Playermove_1(board, row, col, &x, &y);count++;Displayboard(board, ROW, COL);if (count == ROW*COL)ret = 1;elseret = Ifwin(board, ROW, COL, x, y);switch (ret){case 0:printf("玩家1获胜\n"); flag = 1; break;case    1:printf("平局\n"); flag = 1; break;default: break;}if (flag == 1)break;//判断玩家2的下棋printf("玩家2落子,请输入坐标:(注意:竖为x轴,横为y轴)");scanf("%d%d", &x, &y);Playermove_2(board, row, col, &x, &y);count++;Displayboard(board, ROW, COL);if (count == ROW*COL)ret = 1;elseret = Ifwin(board, ROW, COL, x, y);switch (ret){case 0:printf("玩家2获胜\n"); flag = 1; break;case     1:printf("平局\n"); flag = 1; break;default: break;}if (flag == 1)break;}}void Playermove_1(char board[ROW][COL], int row, int col, int *px, int*py)//ROW可以省,COL不行
{int x = *px;int y = *py;while (1){if (x >= 1 && x <= row && y >= 1 && y <= col)//判断输入坐标的合法性{if (board[x -1][y- 1] == ' ')//保证落子点为空{                           board[x-1 ][y -1] = '*';*px = x; *py = y;//如果开始xy输入不合法,要对外部xy修改,所以要传址操作break;}else{printf("你不能在此处落子\n");printf("玩家1落子,请重新输入x y坐标: ");scanf("%d%d", &x, &y);}}else{printf("输入坐标不合法\n");printf("玩家落子,请重新输入x y坐标: ");scanf("%d%d", &x, &y);}}}void Playermove_2(char board[ROW][COL], int row, int col, int *px, int*py)
{int x = *px;int y = *py;while (1){if (x >= 1 && x <= row && y >= 1 && y <= col)//判断输入坐标的合法性{if (board[x - 1][y - 1] == ' ')//保证落子点为空{board[x - 1][y - 1] = '#';*px = x; *py = y;break;}else{printf("你不能在此处落子\n");printf("玩家2落子,请重新输入x y坐标: ");scanf("%d%d", &x, &y);}}else{printf("输入坐标不合法\n");printf("玩家落子,请重新输入x y坐标: ");scanf("%d%d", &x, &y);}}}void computermove(char board[ROW][COL], int row, int col)
{int x = 0;int y = 0;while (1){x = rand() % ROW;y = rand() % COL;if (board[x][y] == ' '){board[x][y] = '#';break;}}}int Ifwin(char board[ROW][COL], int row, int col, int x, int y)
{int ret;{ret = check_x(board, row, col, x, y);if (ret >= 5)return 0;ret = check_y(board, row, col, x, y);if (ret >= 5)return 0;ret = check_xy_up(board, row, col, x, y);if (ret >= 5)return 0;ret = check_xy_down(board, row, col, x, y);if (ret >= 5)return 0;}return 3;
}int check_x(char board[ROW][COL], int row, int col, int x, int y)//检查x轴竖直方向
{int sum = 1;int old_x = x;while (x < row  && board[x - 1][y - 1] == board[x][y - 1]){sum++;x++;}x = old_x;while (x-2>= 0 && board[x - 1][y - 1] == board[x - 2][y - 1] ){sum++;x--;}return sum;
}int check_y(char board[ROW][COL], int row, int col, int x, int y)//检查y轴水平方向
{int sum = 1;int old_y = y;while (y<col && board[x-1][y-1] == board[x-1][y]  ){sum++;y++;}y = old_y;while (y-2 >= 0 && board[x-1][y-1] == board[x-1][y -2]  ){sum++;y--;}return sum;
}int check_xy_up(char board[ROW][COL], int row, int col, int x, int y)//检查斜上45度
{int sum = 1;int old_x = x;int old_y = y;while (x<row &&  y - 2 >= 0 && board[x - 1][y - 1] == board[x][y - 2]){sum++;x++;y--;}x = old_x;y = old_y;while (x - 2 >= 0 && y <col && board[x - 1][y - 1] == board[x - 2][y]){sum++;x--;y++;}return sum;
}int check_xy_down(char board[ROW][COL], int row, int col, int x, int y)//检查斜下45度
{int sum = 1;int old_x = x;int old_y = y;while (x<row && y <col && board[x - 1][y - 1] == board[x][y]){sum++;x++;y++;}x = old_x;y = old_y;while (board[x-1][y-1] == board[x -2][y-2 ] && x-2>=0  && y-2 >=0){sum++;x--;y--;}return sum;
}

如果对你有帮助和启发,作者感到很高兴。如果有好的建议,欢迎留言。如果发现错误,欢迎指正。新手上路,多多指点 

【全网最强C语言学习】五子棋游戏相关推荐

  1. 【全网最强C语言学习】c语言入门(番外)——简单操作上传代码到代码仓库

    ✨前言✨ 作为一个小白说出标题这样的话看来是有些大言不惭,但博主有心将这个系列做好.做精.实话说博主学习C语言不过两个多月,也很能明白初学者的困惑,所以会尽肯能详细.同时作为一个系统的教程,这个系列会 ...

  2. 【全网最强C语言学习】C语言入门篇(主线)——初识C语言①

    ✨前言✨ 作为一个小白说出标题这样的话看来是有些大言不惭,但博主有心将这个系列做好.做精.实话说博主学习C语言不过两个多月,也很能明白初学者的困惑,所以会尽肯能详细.同时作为一个系统的教程,这个系列会 ...

  3. c语言案例游戏,C语言实现五子棋游戏的案例

    C语言实现五子棋游戏的案例 发布时间:2020-08-25 09:35:55 来源:亿速云 阅读:120 作者:小新 小编给大家分享一下C语言实现五子棋游戏的案例,相信大部分人都还不怎么了解,因此分享 ...

  4. C语言学习 数独游戏

    摘要:花了1周多时间学习了C语言,开始练手写解数独游戏的程序. C语言学习 数独游戏 作者:乌龙哈里 时间:2015-11-22 平台:Window7 64bit,TCC 0.9.26(x86-64 ...

  5. C语言实现五子棋游戏(具体说明+具体步骤)

    C语言五子棋 一.运行效果 二.基本流程 三.基本步骤 1.菜单界面 2.初始化棋盘 3.打印棋盘 4.玩家下棋 5.电脑下棋 6.判断是否平局 7.判断是否有输赢 四.完整代码+注释 1.头文件ga ...

  6. c加加计算机游戏,用C语言实现五子棋游戏_C语言_软件编程

    C语言写五子棋,使用多文件形式,使用代码看起来更好看:在这里我实现的功能是双人博弈,如果要实现人机对战,那么代码就会很复杂: 一.main.c 在主调函数中首先要提供一个给用户选择的界面,在这里我们假 ...

  7. 五子棋的禁手c++语言实现,五子棋游戏软件的设计与实现 毕业论文.doc

    论文题目:五子棋游戏软件的设计与实现 教 学 站校本部学生姓名:指导教师:专 业:计算机科学与技术 2014年4月30日 摘要 C++语言是一种面向对象的语言,尽管在当前,可视化语言发展迅速,普及很快 ...

  8. c语言实现五子棋游戏,C语言实现五子棋小游戏

    C语言实现五子棋小游戏 # include # include # include # include//插入输入输出头文件 # include//字符数组的函数定义的头文件 # include//s ...

  9. 基于C语言的五子棋游戏设计与实现 课程报告+项目源码及可执行exe文件

    资源下载地址:https://download.csdn.net/download/sheziqiong/85680476 资源下载地址:https://download.csdn.net/downl ...

最新文章

  1. 两个关于水花的测试。
  2. redis设置允许远程访问
  3. 我们一直使用的管理系统oner
  4. 深度神经网络(DNN)的正则化
  5. python day1
  6. 超级签名源码_苹果iOS超级签名源码技术解析
  7. 关于async和await的探讨
  8. c# winform中窗体切换后释放及防止重复生成
  9. [HDU3756]Dome of Circus
  10. 【VC皮肤】SkinSharp 1.0.6.6的使用
  11. 教你轻松解决CSRF跨站请求伪造攻击
  12. AutoLisp从入门到放弃(四)
  13. python 输入正方形的边长、输出其周长和面积_C语言编程:从键盘输入一个正方形得长,计算并输出该正方形的内切圆的面积对正方形的覆盖率C语言编写设计一个计算正方形面...
  14. Django—CRM项目练习
  15. 2021年中国旅游人次、箱包销售收入及利润总额分析[图]
  16. 7485设计8位比较器
  17. SpringBoot整合Redis配置MyBatis二级缓存
  18. All flavors must now belong to a named flavor dimension.
  19. leetcode--爬楼梯
  20. 学生报名太火热,黑马大门要被挤掉了?

热门文章

  1. 维基百科,自由的百科全书 正则表达式
  2. 机械臂学习——舵机的速度控制、坐标变换、DH模型、正运动学解、逆运动学解
  3. C++虚幻-密室逃脱学习总结(二)虚幻4文件夹结构及基本操作
  4. python 武沛齐_[项目开发/工具/产品] 老男孩Alex的大伙伴-路飞学城武沛齐老师的GiT实战...
  5. 联发科MT7622路由器模块芯片,首款支持4x4 802.11n及蓝牙5.0
  6. 爱普生630k linux驱动下载,爱普生lq-630k驱动
  7. 【学习笔记】山东大学生物信息学-02 序列比较
  8. Web Design-网页设计 LOGO 标准尺寸
  9. 产销平衡的运输问题上机实验matlab_MATLAB编程(运筹学之运输问题)
  10. C语言 雷达设置问题(贪心算法)