要实现三子棋之前我们可以先捋一捋三子棋逻辑;
第一步 : 我们需要一个棋盘,有了棋盘我们才能下棋。没毛病吧老铁;
你要是能以气化棋盘,那当我没说;
第二步 :有了棋盘那肯定不用想 ,那肯定就是下棋了,棋盘都是我亲手打造的,我直接来一手 “ 天地大同”;没毛病吧老铁 哈哈
第三步:下棋肯定不能一直下,
肯定还要判断胜负和三种情况;你要是能多说出一种算我输;
小小三步就能实现一个三子棋游戏,这不行动起来呀老铁?
来吧老铁,开搞! (满满的干货);
注释多到狗看完都会点点头若有所思;
// game.h头文件 所有的头文件引用和函数声明放入其中。
下面这里只是头文件引用,看不明白才是正常的,你要是能从头文件透过现象看本质,那你不是大佬就是先天满魂力加双生武魂了;
#pragma once
#include<stdio.h>
#include<stdlib.h> // srand和rand函数的头文件;
#include<time.h> // time函数的头文件;
#define ROW 3
#define COL 3
// 初始化棋盘;
void initborad(char borad[ROW][COL],int row,int col);
// 打印棋盘声明;
void printborad(char borad[ROW][COL], int row, int col);
// 玩家下棋声明;
void gameplay(char borad[ROW][COL], int row, int col);
// AI下棋声明;
void aiplay(char borad[ROW][COL], int row, int col);
// 判断胜负;
char outcome(char borad[ROW][COL],int row,int col);
相信大家看完头文件引用大概就能了解整个三子棋需要实现什么了吧;
好了,接下来有请主角登场——>>>
请先从主函数(main)开始看起哦
温习提示:与配角(函数的实现)——>>>第三幅图的代码一起观看效果更佳哦;
#define _CRT_SECURE_NO_WARNINGS 1
#include"game.h" // 引用game.h 头文件 ,所有头文件和函数的声明放进头文件中;
void menu() {
printf("*************************\n");
printf("****** 0. 退出游戏 ******\n"); // 菜单函数 打印一个菜单;
printf("****** 1. 开始游戏 ******\n"); // 打印完后继续往后执行;
printf("*************************\n");
}
void game() { // 实现三子棋(井字棋);
char borad[ROW][COL]; // board:”板“的意思; 可以理解为棋盘的意思;
// 定义一个char类型的二维数组;因为棋子用”*“,”#“代替所以是char类型;
// 初始化棋盘;
initborad(borad, ROW, COL); // 请跳转到初始化棋盘实现;
// ROW COL 在头文件中宏定义为3
// 打印棋盘; // 这样定义可以改一下数值即可打印多成多棋盘;
// 如 #define ROW 5 #define COL 5 就可以打印5*5棋盘;
printborad(borad,ROW,COL); // 要下棋肯定要有棋盘,请跳转到实现打印棋盘;
// 打印完棋盘就要开始下棋了,下棋过程中需要判断胜负;
// 请先看玩家 、电脑下棋 再看判断胜负;整个代码就完成了;
// 判断胜负;
char ret = 0;
// 返回‘ * ’玩家胜利; ‘ # ’AI胜利; ‘ = ’和局; ‘ ? ’继续;
ret=outcome(borad, ROW, COL);
while (1) {
// 玩家下棋;
gameplay(borad, ROW, COL); // 玩家下棋函数,请跳转玩家下棋实现;
printborad(borad, ROW, COL); // 落子后打印棋盘;
ret = outcome(borad, ROW, COL); // 判断是否胜利;
if (ret != '?') { // 每下完一步判断是否胜利;
break;
}
// AI下棋;
aiplay(borad, ROW, COL); // 玩家下完就轮到AI下;
printborad(borad, ROW, COL); // 落子后打印棋盘;
ret = outcome(borad, ROW, COL); // 判断是否胜利;
if (ret != '?') { // 每下完一步判断是否胜利;
break;
}
}
if (ret == '*') {
printf("恭喜你,获得游戏胜利->\n");
}
else if (ret == '#') {
printf("能输给AI也是不简单->\n");
}
else if (ret == '=') {
printf("达成和局这可是需要一点小运气->\n");
}
printborad(borad, ROW, COL);// 游戏结束,不管是谁获得胜利还是和局都打印一下棋盘;
} // 俗话说让自己知道自己是怎么死的;
int main() { // main函数,即是开始,亦是结束;
int input = 0; // input ”输入“ 的意思; 也可以自己定义一个自己喜欢的变量;
srand((unsigned int)time(NULL)); // 生成随机数,后面会用到,现在可以不看;
do {
menu(); // menu:”菜单“的意思; 打印一个选择的菜单;滑到上面菜单函数上;
printf("请选择->\n"); // 提示 你选择;
scanf("%d", &input); // 输入选择;
switch (input) {
case 1: game(); // 选择 1 开始游戏 ;请跳到game函数处;game:”游戏“ 的意思;
break;
case 0: printf("退出成功->\n"); // 选择 0 退出游戏;
break;
default: printf("输入错误,请重新输入->\n"); // 不小心按错了;重新输入;
break;
}
} while (input); // 利用 do while 循环可以使得函数至少进行一次;玩完一把不过瘾可以继续完;
// 循环判定条件 input 刚好可以使得循环 菜单函数 游戏函数串联起来;
return 0; // 当输入 1 玩完又可以进入循环;
} // 当输入 0 为假 退出循环;
// 输入其他 非0 为真 还是进循环重输;
接下来是函数的实现:
最后一幅图啦,离游戏的实现就差那么一丢丢啦;
函数的实现:(建议与第二幅图一起观看效果更佳)
#define _CRT_SECURE_NO_WARNINGS 1
#include"game.h"
// 实现和局函数;
int drawngame(char borad[ROW][COL], int row,int col) {
int i = 0;
for (i = 0; i < row; i++) {
int j = 0; // 判断是否和局比较简单;
// 利用 for 循环嵌套 循例二维数组每个元素是否为空;
for (j = 0; j < col; j++) {
if (borad[i][j] == ' ') // 如果有一个为空,说明棋盘还有位置,返回 0
{
return 0;
}
}
}
return 1; // 如果循例下来都不为空,说明棋盘已经下满了,返回 1;
}
// 初始化棋盘置空;
void initborad(char borad[ROW][COL], int row, int col) {
int i = 0;
int j = 0;
for (i = 0; i < row; i++) {
for (j = 0; j < col; j++) { // 利用for循环嵌套遍历整个二维数组;
borad[i][j] = ' '; // 然后把他们全部初始化为空格;
}
}
}
//实现打印棋盘;
void printborad(char borad[ROW][COL], int row, int col) {
int i = 0; //要打印如下棋盘;可以利用for循环嵌套先打印 空格和 | ;
//然后换行打印 _ _ _|;
// | |
for (i = 0; i < row; i++) { // _ _ _|_ _ _|_ _ _
// | |
int j = 0; // _ _ _|_ _ _|_ _ _
// | |
for (j = 0; j < col; j++) { // | |
printf(" %c ",borad[i][j]); //打印空格 %c 空格;因为等下要放棋子进去;所以中间要%c;
if(j<col-1) // 因为 | 为了美感最右边的不打印所以加一个限制条件让 | 少打印一个;
printf("|");
}
printf("\n"); // 打印完记得换行哦\n;
if (i < row - 1) { // 因为只需要打印两行 _ _ _|_ _ _|_ _ _ ;
int k = 0; // 所以加一个限制条件让少打印一行_ _ _|_ _ _|_ _ _ ;
for (k = 0; k < col; k++) {
printf("---"); //接下来打印 _ _ _| ;
if (k < col - 1) // 同上最右边的 | 不打印;
printf("|");
}
printf("\n"); // 打印完记得换行哦\n;
}
}
}
// 玩家下棋实现;
void gameplay(char borad[ROW][COL], int row, int col) {
unsigned int x = 0; // 因为坐标都为正数,所以定义无符号整数;
unsigned int y = 0;
while (1) { // 利用死循环输入坐标;坐标错误就重新输入,正确就 break;跳出循环
printf("请输入坐标->\n");
scanf("%d%d", &x, &y);
if (x < row && y < col && borad[x][y] == ' ') { // 判断坐标合法性,坐标小于行,列;
// 并且落子点应该为空;
borad[x][y] = '*'; // 放入棋子;
break;
}
else {
printf("坐标非法,请重新输入->\n"); // 提示输入的坐标错误;
}
}
}
// AI下棋实现;
void aiplay(char borad[ROW][COL], int row, int col) {
printf("AI落子->\n");
while (1)
{
int x = rand() % row; // 生成随机坐标 0-2之间的数;
int y = rand() % col;
if(borad[x][y]==' ') { //判断坐标是否为空;
borad[x][y] = '#'; // 放入棋子;
break;
}
}
}
// 判断胜负实现;
char outcome(char borad[ROW][COL], int row, int col) {
// 判断行;
int i = 0;
for (i = 0; i < row; i++) { // 利用for循环实现判断每行是否三子相同;
if (borad[i][0] == borad[i][1] && borad[i][1] == borad[i][2] && borad[i][1] != ' ') {
// 因为是&&所以随便一个坐标不为空
// 即三个坐标都不为空;
return borad[i][1]; // 随便返回一个坐标,如果里面是 * 即和玩家胜利条件返回 * 相同
} // #也相同;
}
// 判断列;
int j = 0;
for (j = 0; j < col; j++) {
if (borad[0][j] == borad[1][j] && borad[1][j] == borad[2][j] && borad[1][j] != ' ') {
return borad[1][j]; // 和上述雷同;
}
}
// 判断斜;
if (borad[0][0] == borad[1][1] && borad[1][1] == borad[2][2] && borad[1][1] != ' ') {
return borad[1][1]; // 单独判断两斜;
}
if (borad[0][2] == borad[1][1] && borad[1][1] == borad[2][0] && borad[1][1] != ' ') {
return borad[1][1];
}
// 判断和局;
int ret = 0; // ret ”返回“的意思; 定义一个 ret 接收函数返回值;
ret=drawngame(borad,ROW,COL); // drawngame ”平局“的意思;判断是否平局函数,请跳到上方实现和局函数;
if (ret == 1) { // 返回 1 的话把 ‘ = ’返回到判断胜负 ‘ = ’即是平局
return '=';
}
else { // 返回其他的话说明不是平局,棋盘还未下满游戏继续;
return '?'; // 返回 ‘ ? ’ 即是游戏继续;
}
}
第三幅图的和局函数最后看的哦;
相信只要是认真看到最后的心里大概已经有了大致的框架了吧 , 赶快行动起来敲一敲吧
如果对你有帮助的话,可以给个免费的不要钱的赞吗?
猜数字游戏、 扫雷 、俄罗斯方块、雷霆战机、大家还喜欢学那个呢?