C语言实现三子棋?五子棋?不,是n子棋
目录
前言
1、 game_tic.h
2、 test.c
3 、 game_tic.c
3.1 游戏主体
3.2 游戏的具体实现
3.2.1 打印棋盘
3.2.2 初始化棋盘
3.2.3 玩家进行下棋
3.2.4 电脑下棋
3.2.5 判断是否获胜
3.2.6 判断棋盘是否已经满
4、代码展示
4.1 game_tic.h
4.2 test.c
4.3 game_tic.c
5、一定要看这里
前言
实现这样一个代码程序,其实并不算太难,所需要的知识量概括为,数组,函数,循环语句,分支语句。在这之中想必最为复杂的就是判断是否获胜了吧。
废话不多说,让我们开始吧。
1、 game_tic.h
game_tic.h : 自定义头文件,主要用于:
1 . 库函数的包含2 . 自定义函数的申明
3 . 定义棋盘大小
#ifndef GAME_TIC_H
#define GAME_TIC_H//棋盘大小
#define ROW 15
#define COL 15
//方便计算用
#define ROWS (ROW + 1)
#define COLS (COL + 1)
//防止用数组检索的时候,出现非法访问
#define ROWSS (ROWS + 1)
#define COLSS (COLS + 1)#define NUM 5// 确定n子棋//包含的头文件
#include <stdio.h>
#include <windows.h>
#include <time.h>
#include <stdlib.h>//函数声明
void game_tic();
void InitBoard(char board[ROWSS][COLSS]);
void PrintBoard(char board[ROWSS][COLSS]);
void PlayerMove(char board[ROWSS][COLSS], int PlayerMark[2], char p1);
void ComputerMove(char board[ROWSS][COLSS], int computmark[2], char p2);
char IsWin(char board[ROWSS][COLSS], int x, int y, char el);#endif
2、 test.c
test.c : 用于实现大致界面
#include "game_tic.h"void menu()
{int input = 0;do{printf("********************************\n");printf("****** 0.返回 *******\n");printf("****** 1. n子棋游戏 *******\n");printf("****** 2.(还没想好) *******\n");printf("********************************\n");printf("请选择 >: ");scanf("%d", &input);switch (input){case 1:game_tic();break;default:system("cls");printf("输入错误,请从新输入\n");break;}} while (input);
}void start()//选择开始菜单
{int input = 0;do{printf("************************\n");printf("****** 1.开始游戏 ****\n");printf("****** 0.退出程序 ****\n");printf("************************\n");printf("请输入 >: ");scanf("%d", &input);if (input == 1){menu();}else if (input != 0){printf("输入错误,请从新输入\n");system("cls");//清屏}} while (input);
}int main()
{start();return 0;
}
3 、 game_tic.c
game_tic.c : 用于实现游戏内容
3.1 游戏主体
因为数组在进行传参的时候传的是首元素地址,数组在使用其它函数的时候不会想形参一样进行销毁,所以我们可以引用一个数组来保存坐标。
注意:
ComputMark[2] = { 0 }; 用于记录电脑坐标
PlayerMark[2] = { 0 }; 用于记录玩家坐标
此做法在本程序内起到关键作用
//游戏主体
void game_tic()
{srand((unsigned int)time(NULL));int x = 0;int y = 0;char board[ROWSS][COLSS] = { 0 };int ComputMark[2] = { 0 };//记录电脑的坐标int PlayerMark[2] = { 0 };//记录玩家的坐标InitBoard(board);PrintBoard(board);while (1){PlayerMove(board, PlayerMark, '*');PrintBoard(board);x = PlayerMark[0];y = PlayerMark[1];if ('*' == IsWin(board, x, y, '*')){printf("玩家获胜\n");break;}if (IsFull(board)){printf("平局\n");break;}ComputerMove(board, ComputMark,'#');PrintBoard(board);x = ComputMark[0];y = ComputMark[1];if ('#' == IsWin(board, x, y, '#')){printf("电脑获胜\n");break;}if (IsFull(board)){printf("平局\n");break;}}
}
3.2 游戏的具体实现
3.2.1 打印棋盘
void PrintBoard(char board[ROWSS][COLSS])
{int i = 0;int j = 0;system("cls");for (i = 1; i < ROWS; i++)//打印横坐标{printf("%4d", i);}printf("\n");for (i = 1; i < ROWS; i++){printf("%-2d", i);//打印列坐标for (j = 1; j < COLS; j++){printf(" %c ", board[i][j]);if(j != COLS - 1)printf("|");}printf("\n ");for (j = 1; j < COLS && i < ROWS - 1; j++){printf("----");}printf("\n");}
}
效果图展示:
ROW 为 3,COL 为 3 的时候 (三子棋棋盘)
ROW 为 15,COL 为 15 的时候 (五子棋棋盘)
3.2.2 初始化棋盘
在每次进行游戏之前需要对棋盘进行初始化,即里面元素全放 空格 。
void InitBoard(char board[ROWSS][COLSS])
{int i = 0;int j = 0;for (i = 0; i < ROWSS; i++){for (j = 0; j < COLSS; j++){board[i][j] = ' ';}}
}
3.2.3 玩家进行下棋
在接收到一个可用坐标时,将其记录在数组内
注意:
如果想实现 玩家 VS 玩家 ,可以将 电脑下棋 改为 玩家下棋
void PlayerMove(char board[ROWSS][COLSS],int PlayerMark[2], char p1)
{int x = 0;int y = 0;while (1){printf("请输入坐标 (x,y)");scanf("%d,%d", &x, &y);if (x > 0 && x < COLSS && y > 0 && y < ROWSS){if (board[y][x] == ' '){board[y][x] = p1;break;}else{printf("输入的坐标已被占用,请从新输入\n");}}else{printf("非法输入坐标,请从新输入\n");}}PlayerMark[0] = x;PlayerMark[1] = y;
}
3.2.4 电脑下棋
电脑下棋的时候,我使用了 rand( ) 函数进行随机取值
如果想了解函数的用法请参考 :http://cplusplus.com/reference/cstdlib/rand/?kw=rand
void ComputerMove(char board[ROWSS][COLSS], int computmark[2], char p2)
{while (1){int x = rand() % COL + 1;int y = rand() % ROW + 1;computmark[0] = x;computmark[1] = y;if (board[y][x] == ' '){board[y][x] = p2;break;}}
}
3.2.5 判断是否获胜
IsCount : 返回当前下棋坐标周围的棋子数量
char IsWin(char board[ROWSS][COLSS],int x, int y, char el)
{//继续 返回 'C'//获胜 返回 e1if (NUM == IsCount(board, x, y)){return el;}else{return 'C';}
}
思路:
落下一个棋子,记录它的坐标,然后向4个方向去寻找相同的棋子并记录数量,用一个数组去存储每个方向的棋子数量,取最大值返回毕竟也不能保证不会出现这样的情况
//计数
int IsCount(char board[ROWSS][COLSS], int x, int y)
{int i = 0;int moveX = x;int moveY = y;int count = 1;//计数int countmax = 0;//4个方向上的最多棋子数量int countarr[4] = { 0 };//记录 4 个方向上的棋子数量// [0] 为左上斜// [1] 为右上斜// [2] 为竖// [3] 为横//左上斜if (board[moveY + 1][moveX - 1] == board[moveY][moveX] || board[moveY - 1][moveX + 1] == board[moveY][moveX]){count = 1;//左上角for (i = 0, moveX = x, moveY = y;board[moveY + 1][moveX - 1] == board[moveY][moveX] && i < NUM; i++){count++;moveX += 1;moveY -= 1;}//右下角for (i = 0, moveX = x, moveY = y;board[moveY - 1][moveX + 1] == board[moveY][moveX] && i < NUM; i++){count++;moveX += 1;moveY -= 1;}countarr[0] = count;moveX = x;moveY = y;}//右上斜if (board[moveY - 1][moveX - 1] == board[moveY][moveX] || board[moveY + 1][moveX + 1] == board[moveY][moveX]){count = 1;for (i = 0, moveX = x, moveY = y;board[moveY - 1][moveX - 1] == board[moveY][moveX] && i < NUM; i++){count++;moveX -= 1;moveY -= 1;}for (i = 0, moveX = x, moveY = y;board[moveY + 1][moveX + 1] == board[moveY][moveX] && i < NUM; i++){count++;moveX += 1;moveY += 1;}countarr[1] = count;moveX = x;moveY = y;}//竖if (board[moveY][moveX] == board[moveY + 1][moveX] || board[moveY][moveX] == board[moveY - 1][moveX]){count = 1;//向上计数for (i = 0, moveX = x, moveY = y; (moveY + 1 <= ROW) && i < NUM &&(board[moveY][moveX] == board[moveY + 1][moveX]); i++){count++;moveY += 1;}for (i = 0, moveX = x, moveY = y; (moveY - 1 >= 0) && i < NUM &&(board[moveY][moveX] == board[moveY - 1][moveX]); i++){count++;moveY -= 1;}countarr[2] = count;moveX = x;moveY = y;}//横if (board[moveY][moveX] == board[moveY][moveX + 1] || board[moveY][moveX] == board[moveY][moveX - 1]){count = 1;for (i = 0, moveX = x,moveY = y; (moveX + 1 <= COL) && i < NUM &&(board[moveY][moveX] == board[moveY][moveX + 1]); i++){count++;moveX += 1;}for (i = 0, moveX = x, moveY = y; (moveX - 1 >= 0) && i < NUM &&(board[moveY][moveX] == board[moveY][moveX - 1]); i++){count++;moveX -= 1;}countarr[3] = count;}countmax = arrmax(countarr);return countmax;
}
//判断4个方向里的棋子数量的最大值
int arrmax(int arr[4])
{int i = 0;int max = arr[0];for (i = 1; i < 4; i++){if (arr[i] > max){max = arr[i];}}return max;
}
3.2.6 判断棋盘是否已经满
若棋盘已满,还没有分出胜负,则退出游戏,按平局处理
int IsFull(char board[ROWSS][COLSS])
{int i = 0;int j = 0;for (i = 1; i < ROWS; i++){for (j = 1; j < COLS; j++){if (board[i][j] == ' ')return 0;}}return 1;
}
4、代码展示
4.1 game_tic.h
#ifndef GAME_TIC_H
#define GAME_TIC_H//棋盘大小
#define ROW 15
#define COL 15
#define ROWS (ROW + 1)
#define COLS (COL + 1)
#define ROWSS (ROWS + 1)
#define COLSS (COLS + 1)#define NUM 5// 确定n子棋//包含的头文件
#include <stdio.h>
#include <windows.h>
#include <time.h>
#include <stdlib.h>//函数声明
void game_tic();
void InitBoard(char board[ROWSS][COLSS]);
void PrintBoard(char board[ROWSS][COLSS]);
void PlayerMove(char board[ROWSS][COLSS], int PlayerMark[2], char p1);
void ComputerMove(char board[ROWSS][COLSS], int computmark[2], char p2);
char IsWin(char board[ROWSS][COLSS], int x, int y, char el);#endif
4.2 test.c
#include "game_tic.h"void menu()
{int input = 0;do{printf("********************************\n");printf("****** 0.返回 *******\n");printf("****** 1. n子棋游戏 *******\n");printf("****** 2.(还没想好) *******\n");printf("********************************\n");printf("请选择 >: ");scanf("%d", &input);switch (input){case 1:game_tic();break;default:system("cls");printf("输入错误,请从新输入\n");break;}} while (input);
}void start()//选择开始菜单
{int input = 0;do{printf("************************\n");printf("****** 1.开始游戏 ****\n");printf("****** 0.退出程序 ****\n");printf("************************\n");printf("请输入 >: ");scanf("%d", &input);if (input == 1){menu();}else if (input != 0){printf("输入错误,请从新输入\n");system("cls");//清屏}} while (input);
}int main()
{start();return 0;
}
4.3 game_tic.c
#include "game_tic.h"//判断棋盘是否满
int IsFull(char board[ROWSS][COLSS])
{int i = 0;int j = 0;for (i = 1; i < ROWS; i++){for (j = 1; j < COLS; j++){if (board[i][j] == ' ')return 0;}}return 1;
}int arrmax(int arr[4])
{int i = 0;int max = arr[0];for (i = 1; i < 4; i++){if (arr[i] > max){max = arr[i];}}return max;
}//计数
int IsCount(char board[ROWSS][COLSS], int x, int y)
{int i = 0;int moveX = x;int moveY = y;int count = 1;//计数int countmax = 0;//4个方向上的最多棋子数量int countarr[4] = { 0 };//记录 4 个方向上的棋子数量// [0] 为左上斜// [1] 为右上斜// [2] 为竖// [3] 为横//左上斜if (board[moveY + 1][moveX - 1] == board[moveY][moveX] || board[moveY - 1][moveX + 1] == board[moveY][moveX]){count = 1;//左上角for (i = 0, moveX = x, moveY = y;board[moveY + 1][moveX - 1] == board[moveY][moveX] && i < NUM; i++){count++;moveX += 1;moveY -= 1;}//右下角for (i = 0, moveX = x, moveY = y;board[moveY - 1][moveX + 1] == board[moveY][moveX] && i < NUM; i++){count++;moveX += 1;moveY -= 1;}countarr[0] = count;moveX = x;moveY = y;}//右上斜if (board[moveY - 1][moveX - 1] == board[moveY][moveX] || board[moveY + 1][moveX + 1] == board[moveY][moveX]){count = 1;for (i = 0, moveX = x, moveY = y;board[moveY - 1][moveX - 1] == board[moveY][moveX] && i < NUM; i++){count++;moveX -= 1;moveY -= 1;}for (i = 0, moveX = x, moveY = y;board[moveY + 1][moveX + 1] == board[moveY][moveX] && i < NUM; i++){count++;moveX += 1;moveY += 1;}countarr[1] = count;moveX = x;moveY = y;}//竖if (board[moveY][moveX] == board[moveY + 1][moveX] || board[moveY][moveX] == board[moveY - 1][moveX]){count = 1;//向上计数for (i = 0, moveX = x, moveY = y; (moveY + 1 <= ROW) && i < NUM &&(board[moveY][moveX] == board[moveY + 1][moveX]); i++){count++;moveY += 1;}for (i = 0, moveX = x, moveY = y; (moveY - 1 >= 0) && i < NUM &&(board[moveY][moveX] == board[moveY - 1][moveX]); i++){count++;moveY -= 1;}countarr[2] = count;moveX = x;moveY = y;}//横if (board[moveY][moveX] == board[moveY][moveX + 1] || board[moveY][moveX] == board[moveY][moveX - 1]){count = 1;for (i = 0, moveX = x,moveY = y; (moveX + 1 <= COL) && i < NUM &&(board[moveY][moveX] == board[moveY][moveX + 1]); i++){count++;moveX += 1;}for (i = 0, moveX = x, moveY = y; (moveX - 1 >= 0) && i < NUM &&(board[moveY][moveX] == board[moveY][moveX - 1]); i++){count++;moveX -= 1;}countarr[3] = count;}countmax = arrmax(countarr);return countmax;
}char IsWin(char board[ROWSS][COLSS],int x, int y, char el)
{//继续 返回 'C'//获胜 返回 e1if (NUM == IsCount(board, x, y)){return el;}else{return 'C';}
}//电脑 游玩
void ComputerMove(char board[ROWSS][COLSS], int computmark[2], char p2)
{while (1){int x = rand() % COL + 1;int y = rand() % ROW + 1;computmark[0] = x;computmark[1] = y;if (board[y][x] == ' '){board[y][x] = p2;break;}}
}// 玩家 游玩
void PlayerMove(char board[ROWSS][COLSS],int PlayerMark[2], char p1)
{int x = 0;int y = 0;while (1){printf("请输入坐标 (x,y)");scanf("%d,%d", &x, &y);if (x > 0 && x < COLSS && y > 0 && y < ROWSS){if (board[y][x] == ' '){board[y][x] = p1;break;}else{printf("输入的坐标已被占用,请从新输入\n");}}else{printf("非法输入坐标,请从新输入\n");}}PlayerMark[0] = x;PlayerMark[1] = y;
}//初始化棋盘
void InitBoard(char board[ROWSS][COLSS])
{int i = 0;int j = 0;for (i = 0; i < ROWSS; i++){for (j = 0; j < COLSS; j++){board[i][j] = ' ';}}
}//打印棋盘
void PrintBoard(char board[ROWSS][COLSS])
{int i = 0;int j = 0;system("cls");for (i = 1; i < ROWS; i++)//打印横坐标{printf("%4d", i);}printf("\n");for (i = 1; i < ROWS; i++){printf("%-2d", i);//打印列坐标for (j = 1; j < COLS; j++){printf(" %c ", board[i][j]);if(j != COLS - 1)printf("|");}printf("\n ");for (j = 1; j < COLS && i < ROWS - 1; j++){printf("----");}printf("\n");}
}//游戏主体
void game_tic()
{srand((unsigned int)time(NULL));int x = 0;int y = 0;char board[ROWSS][COLSS] = { 0 };int ComputMark[2] = { 0 };int PlayerMark[2] = { 0 };InitBoard(board);PrintBoard(board);while (1){PlayerMove(board, PlayerMark, '*');PrintBoard(board);x = PlayerMark[0];y = PlayerMark[1];if ('*' == IsWin(board, x, y, '*')){printf("玩家获胜\n");break;}if (IsFull(board)){printf("平局\n");break;}ComputerMove(board, ComputMark,'#');PrintBoard(board);x = ComputMark[0];y = ComputMark[1];if ('#' == IsWin(board, x, y, '#')){printf("电脑获胜\n");break;}if (IsFull(board)){printf("平局\n");break;}}
}
5、一定要看这里
既然你都看到这里了
如果对你右帮助或者觉得好的话,请给一个赞φ(゜▽゜*)♪
如果喜欢作者或者想看更多内容的话,请点一下关注(´▽`ʃ♡ƪ)
如果你怕找不到这篇博客,有一个放走丢的办法,看到那个星星了吗,点一下有惊喜哦
咱也不是是说特别想要 ,就是想请您可怜可怜这位卑微的博主吧
C语言实现三子棋?五子棋?不,是n子棋相关推荐
- 三子棋进阶版(N子棋)
我们今天要分享的题目是三子棋,相信大家对于三子棋并不陌生 我们在设计三子棋的时候,脑袋一定不要混,不要害怕 做任何题目脑袋里要慢慢形成框架 比如本题:三子棋 游戏开始要有游戏界面,进入游戏界面时候,要 ...
- 三字棋Java程序设计_六子棋Java程序设计.docx
六子棋Java程序设计 六子棋Java程序设计作者:刘庆淘QQ号:543780889学号:111101009个人简介:宜宾学院,计算机学院11级创新班学生本程序简介: 对于玩家而言,我就是想让大家也让 ...
- java四连环游戏编程_如何用C语言实现四连环游戏(重力四子棋)?
正好我们老师也要做了这个作业!就来蹭个热闹~ 大概就是实现了要求的功能,然后能够自定义棋盘大小(目前是6行7列,通过修改Connect4::play()里面的对于rowNum和colNum的赋值来实现 ...
- 小游戏--三子棋——N子棋(实现)
三子棋大家应该都不陌生吧 三子棋是一种民间传统游戏,又叫九宫棋.圈圈叉叉棋.一条龙.井字棋等. 我们今天来一个c语言三子棋的进阶,n子棋的实现过程 1.我们首先可以创建一个三子棋.c源文件,从main ...
- 题目0134-竖直四子棋
竖直四子棋 题目描述 竖直四子棋的棋盘是竖立起来的,双方轮流选择棋盘的一列下子, 棋子因重力落到棋盘底部或者其他棋子之上,当一列的棋子放满时,无法再在这列上下子. 一方的4个棋子横.竖或者斜方向连成一 ...
- C语言三子棋,五子棋,n子棋的代码实现
C语言三子棋,五子棋,n子棋的代码实现 这里以五子棋为例,来说明开发过程 开发思路 菜单打印 棋盘的打印 棋子的打印 电脑下棋(随机数) 判断输赢 代码整合 注意事项 这里以五子棋为例,来说明开发过程 ...
- 【C语言】-三子棋游戏(+五子棋详细版)
目录 前言 一.三子棋的实现 1.代码实现步骤: 2.模块化代码 二.代码示例及解析 1.game.h 2.test.c(main()函数+game()函数) 3.game.c(实现game()各个功 ...
- C语言实现三子棋小游戏(源码+教程)
我猜中了开头,却猜不到这结局.--<大话西游> 目录 1.设计框架 2.设计流程 2.1菜单 2.2初始化棋子 2.3初始化棋盘 2.4玩家输入落子的坐标 2.5电脑随机生成棋子 2.6判 ...
- 趣味益智小游戏 三子棋+五子棋 优化版(可任意选择棋盘大小)
前言 今天牛牛给大家分享的是c语言实现三子棋和五子棋游戏,初学者可能有些不理解的地方,记得私信提问哦,牛牛会一 一回答的. 目录 前言 一.游戏介绍 二.游戏设计思路 2.1 主函数测试区(test. ...
- C语言实现三子棋游戏—可扩展到任意N子棋
C语言实现三子棋 游戏介绍 游戏编程思路 游戏代码详解 主函数 游戏菜单函数 游戏逻辑函数 初始化棋盘 打印棋盘 玩家下棋 电脑下棋 判断输赢 完整代码 test.c game_chess.c gam ...
最新文章
- 使用slice和concat对数组的深拷贝和浅拷贝
- mysql删除有空格字符名称的触发器
- DataTables中设置某些列不进行排序
- mysql控制台增加一个用户_MySQL 纯命令行添加用户
- 《Nmap渗透测试指南》—第2章2.2节使用Zenmap进行扫描
- Caffe RPN:把RPN网络layer添加到caffe基础结构中
- iOS UISegmentedControl 的使用
- ubuntu 20.04 安装circos
- mysql查询含有某个值的表_MYSQL查询数据表中某个字段包含某个数值
- 二进制搜索树_将排序的数组转换为二进制搜索树
- Flask爱家租房--房屋管理(搜索房屋列表)
- centos 开发环境配置
- 使用 NetDataContractSerializer 共享类型
- 数据库查询字段为空时,返回0
- 取代NBSI2:Opendatasource And Openrowset
- 2015最新iherb海淘攻略-图文入门教程
- Redis(设置失效时间,RedisDesktopManger远程管理工具)
- chi2inv函数 matlab_matlab函数与指令大全 a——h (转载)
- 2.1 分布式文件系统HDFS-使用
- java.lang.NoClassDefFoundError: javax/transaction/Synchronization 解决方法。