路|【C语言/入门游戏】三子棋及改良思路
知识提要(自主编写游戏所需要的知识):
1.函数的基本实现;
2.二维数组;
好的,话不多说让我们来看今天的分享
目录
三子棋
1.初始界面实现
2.棋盘的创建及初始化棋盘
3.棋盘的打印
3.先后手的实现
4.玩家行动
5.电脑行动
6.胜负判定
7.全局展示
8.改良思路
三子棋 效果图:
文章图片
1.初始界面实现 老规矩,先创建三个文件,分别为test.c(用于测试游戏以及运行游戏),game.c(用于实现游戏内函数)以及game.h(声明game.c中的函数和共同需要的数据)
先在game.h中引用你所需要的文件和必要的定义
#pragma once
# define _CRT_SECURE_NO_WARNINGS#include
#include
#include #define ROW 3//棋盘的行
#define COL 3//棋盘的列
下面就要创建初始界面了
int main()
{
int input = 0;
srand((unsigned int)time(NULL));
//后文有函数会用到,不理解这个函数的,可以跳转到我猜字游戏那篇文章
//这里用do while循环保证菜单至少被打开一次
do
{
menu();
printf("请选择>:");
scanf("%d", &input);
switch (input)
{
case 1:
printf("游玩愉快\n");
game();
break;
case 0:
printf("已退出游戏\n");
break;
default:
printf("选择错误,请重新选择\n");
break;
}
} while (input);
//如果选择0,会判定为假,跳出循环,结束游戏;选择其他则不会,保证游戏可以重复游玩
return 0;
}
menu():
void menu()
{
printf("************************\n");
printf("*******1. play******\n");
printf("*******0. exit******\n");
printf("************************\n");
}
2.棋盘的创建及初始化棋盘 首先要创建game()这个函数,然后先创建一个二维数组作为棋盘,同时我们需要将棋盘初始化。
void game()
{
char arr[ROW][COL];
//初始化棋盘
intialize(arr,ROW,COL);
}
现在我们来写将棋盘初始化的函数intialize,这里我们用循环可以简单写成
void intialize(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++)
{
board[i][j] = ' ';
}
}}
3.棋盘的打印 初始化棋盘后,我们需要将棋盘展示出来,打印效果如下
文章图片
为了实现效果,这里我们也需要一个函数来实现,我们将其命名为print
void Print(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++)
{
printf(" %c ", board[i][j]);
if (j < col - 1)//在除最后一列的其他列打印|
printf("|");
}
printf("\n");
//换行
if (j = col - 1)//打印---分割行
{
int k = 0;
if (i < row - 1)//在最后一行不打印分割行
{
for (k = 0;
k < col;
k++)
{
printf("---");
if (k < col - 1)
printf("|");
}
}
}
printf("\n");
}
}
只需将ROW,COL定义换成其他数就可以打印各种棋盘。如果棋盘过大,则需要标明行列号,此处暂不演示,具体实现见下一篇扫雷文章。
3.先后手的实现 为了使玩家和电脑都可以先手,我们用一个Dice的类似于骰子的函数实现
int Dice()
{
return rand() % 2;
//返回0或1}
在game()中接收,并判定
int ret = Dice();
if (ret == 1)//返回为1,玩家先走
{
Playermove(arr, ROW, COL);
Computermove(arr, ROW, COL);
}
else//返回为0,电脑先走
{Computermove(arr, ROW, COL);
Playermove(arr, ROW, COL);
}
4.玩家行动 现在到了本游戏的重点,玩家行动,这里我们用o来代表玩家的棋子
玩家下棋代表用o将棋盘中的空格替代
void Playermove(char board[ROW][COL], int row, int col)
{
int i = 0;
int j = 0;
printf("玩家走>:示例(输入:1 1)\n");
while (1)//防止输入错误以及非法占用
{
printf("请输入坐标>:");
scanf("%d%d", &i, &j);
if (i <= row && j <= col&&i>=1&&j>=1)//防止输入的数字超过最大访问范围
{
if (board[i-1][j-1] == ' ')//如果该位置为空格,才能下
{
board[i-1][j-1] = 'o';
//玩家眼中的坐标是从1开始的,而C语言中是从0开始,所以要减1
break;
}
else
printf("该棋位已被占用,请重新输入\n");
}
else
{
printf("输入错误,请重新输入\n");
} }
5.电脑行动 【路|【C语言/入门游戏】三子棋及改良思路】我们先不讨论如何让电脑有智商,这个放在文章结尾讨论。我们先设置一个随机的电脑
void Computermove(char board[ROW][COL], int row, int col)
{
printf("电脑走\n");
int x = 0;
int y = 0;
//人工智障 while (1)
{
x = rand() % ROW;
y = rand() % COL;
if (board[x][y] == ' ')//保证电脑也下到空格位置,不是空格就再次循环
{
board[x][y] = 'x';
break;
}
}
}
6.胜负判定 这里我们需要列举全部的游戏情况
胜利:横行三子,竖行三子,对角线三子
平局:棋盘已被占满且无胜利情况
继续:棋盘未占满且没有胜利情况
我们规定
如果玩家胜利,返回'o'
如果电脑胜利,返回'x'
如果平局,返回'E'
如果继续,返回'C
用于在test.c中判定胜负
每一方行动完后,都要判定胜负
int even(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++)
{
if (board[i][j] == ' ')
return 0;
}
}
return 1;
}char win(char board[ROW][COL], int row, int col)
{
int i = 0;
//judge row
for (i = 0;
i < row;
i++)
{
if (board[i][0] == board[i][1] && board[i][1] == board[i][2] && board[i][1] != ' ')
return board[i][1];
//直接返回其中的字符,方便后续判定
}
//judge col
for (i = 0;
i < col;
i++)
{
if (board[0][i] == board[1][i] && board[1][i] == board[2][i] && board[1][i] != ' ')
return board[1][i];
}
//judge dia
if (board[0][0] == board[1][1] && board[1][1] == board[2][2] && board[1][1] != ' ')
return board[1][1];
if (board[0][2] == board[1][1] && board[1][1] == board[2][0] && board[1][1] != ' ')
return board[1][1];
//judge even
if (even(board, row, col)==1)//在上述胜利条件都没满足的情况下,才判断是否平局
return 'E';
return 'C';
}
7.全局展示 现在大体的游戏函数写得差不多了,可以将填充到game.h和test.c中了
记得要使用game.c中的函数,一定要在game.h中声明,并且引用game.h
game.h
#pragma once
# define _CRT_SECURE_NO_WARNINGS#include
#include
#include #define ROW 3
#define COL 3void intialize(char board[ROW][COL], int row, int col);
void Print(char board[ROW][COL], int row, int col);
int Dice();
void Playermove(char board[ROW][COL], int row, int col);
void Computermove(char board[ROW][COL], int row, int col);
char win(char board[ROW][COL], int row, int col);
//如果玩家胜利,返回o;如果电脑胜,返回x;平局,返回E;继续返回C
test.c
# define _CRT_SECURE_NO_WARNINGS#include "game.h"void menu()
{
printf("************************\n");
printf("*******1. play******\n");
printf("*******0. exit******\n");
printf("************************\n");
}void game()
{
char arr[ROW][COL];
//初始化棋盘
intialize(arr,ROW,COL);
Print(arr,ROW,COL);
int ret = Dice();
char Win = 0;
if (ret == 1)
{
while (1)
{
Playermove(arr, ROW, COL);
Print(arr, ROW, COL);
Win = win(arr, ROW, COL);
if (Win !='C')
break;
Computermove(arr, ROW, COL);
Print(arr, ROW, COL);
Win = win(arr, ROW, COL);
if (Win != 'C')
break;
}
}
else
{
while (1)
{
Computermove(arr, ROW, COL);
Print(arr, ROW, COL);
Win = win(arr, ROW, COL);
if (Win != 'C')
break;
Playermove(arr, ROW, COL);
Print(arr, ROW, COL);
Win = win(arr, ROW, COL);
if (Win != 'C')
break;
}
}
if (Win == 'o')
printf("恭喜,玩家胜利\n");
else if (Win == 'x')
printf("电脑赢了,别灰心\n");
else if (Win == 'E')
printf("平局,再来一把吧\n");
}int main()
{
int input = 0;
srand((unsigned int)time(NULL));
do
{
menu();
printf("请选择>:");
scanf("%d", &input);
switch (input)
{
case 1:
printf("游玩愉快\n");
game();
break;
case 0:
printf("已退出游戏\n");
break;
default:
printf("选择错误,请重新选择\n");
}
} while (input);
return 0;
}
8.改良思路
while (1)
{
if (board[1][1] == 'o')// 防守为上
{
if (board[1][2] == 'o' && board[1][0] == ' ')
{
board[1][0] == 'x';
break;
}
else if (board[1][0] == 'o' && board[1][2] == ' ')
{
board[1][2] == 'x';
break;
}
else if (board[0][1] == 'o' && board[2][1] == ' ')
{
board[2][1] == 'x';
break;
}
else if (board[2][1] == 'o' && board[0][1] == ' ')
{
board[0][1] == 'x';
break;
}
else if (board[2][2] == 'o' && board[0][0] == ' ')
{
board[0][0] == 'x';
break;
}
else if (board[0][0] == 'o' && board[2][2] == ' ')
{
board[0][1] == 'x';
break;
}
else if (board[0][2] == 'o' && board[2][0] == ' ')
{
board[2][0] == 'x';
break;
}
else if (board[2][0] == 'o' && board[0][2] == ' ')
{
board[0][2] == 'x';
break;
}}
/*int i = 0;
*///for (i = 0;
i < row - 1;
i++)//竖行防守
//{
// int j = 0;
// for (j = 0;
j < col ;
j++)
// {
//if (board[i][j] == 'o' && board[i + 1][j] == 'o')
//{
//if (i == 0 && board[i + 2][j] = ' ')
//{
//board[i + 2][j] = 'x';
//}
//else if (i == 1 && board[i - 1][j] = ' ')
//{
//board[i - 1][j] = 'x';
//}
//}// }//}if (board[1][1] == ' ')//抢中间位置
{
board[1][1] == 'x';
break;
}
if (board[1][1] == 'x')//当有子在中间时的走法
{
if ( board[1][2] == 'x'&& board[1][0] == ' ')
{
board[1][0] == 'x';
break;
}
else if (board[1][0] == 'x' && board[1][2] == ' ')
{
board[1][2] == 'x';
break;
}
else if(board[0][1] == 'x' && board[2][1] == ' ')
{
board[2][1] == 'x';
break;
}
else if (board[2][1] == 'x' && board[0][1] == ' ')
{
board[0][1] == 'x';
break;
}
else if (board[2][2] == 'x' && board[0][0] == ' ')
{
board[0][0] == 'x';
break;
}
else if (board[0][0] == 'x' && board[2][2] == ' ')
{
board[0][1] == 'x';
break;
}
else if (board[0][2] == 'x' && board[2][0] == ' ')
{
board[2][0] == 'x';
break;
}
else if (board[2][0] == 'x' && board[0][2] == ' ')
{
board[0][2] == 'x';
break;
}}}
}
上面的是一些如何提升电脑智商的代码,其中要考虑的问题比较多,而且代码执行顺序也要加以斟酌,大家可以把我这几段代码当参考,还有进攻等问题我还没有写出来,所以直接套用是不行的。
以上就是本次的分享内容了,喜欢我的分享的话,别忘了点赞加关注哟!
如果你对我的文章有任何看法,欢迎在下方评论留言或者私信我鸭!
我是白晨,我们下次分享见!!