如何用C语言编写一个三子棋/多子棋小游戏
三子棋作为一个游戏,众所周知游戏应该有的框架是
1.游戏菜单
2.游戏内容
3游戏规则(获胜条件)
在明白了这三点之后,在脑海中三子棋/多子棋的游戏框架应该已经初步建立了,接下来我们就开始着手编写代码。
首先创建一个头文件,“game.h”,在里面存放需要引用的函数
如下:
#include<stdio.h>
#include<stdlib.h>
#include<time.h>
#pragma warning(disable:4996)
#define ROW 3 //棋盘行
#define COL 3 //棋盘列
#define MODE 3 //选择几子棋
void menu();
void initboard(char board[ROW][COL], int row, int col);
void printfboard(char board[ROW][COL], int row, int col);
void playermove(char board[ROW][COL], int row, int col);
void commove(char board[ROW][COL], int row, int col);
int full(char board[ROW][COL], int row, int col);
char win(char board[ROW][COL], int row, int col);
void game(char board[ROW][COL]);
其次,我们需要创建一个源文件"game.c"来编写在头文件中所存放的函数
注意:在实际编写过程中是在源文件中编写一个函数,然后在头文件中存放一个!
在这里我们就从头文件的函数顺序开始讲解
1.游戏菜单
void menu()
{
printf("****************************\n");
printf("******** 1.开始游戏 ********\n");
printf("******** 0.退出游戏 ********\n");
printf("****************************\n");
}
2.初始化棋盘
在这里我们用一个二维数组创作一个棋盘,数组元素为字符型
使用for循环进行遍历每个元素,将它们定义为空格符
void initboard(char board[ROW][COL], int row, int col)
{
for (int i = 0; i < row; i++)
{
for (int j = 0; j < col; j++)
{
board[i][j] = ' ';
}
}
}
3.打印棋盘
这一步需要注意的是在棋盘最右列和最后一行不需要棋盘线
void printfboard(char board[ROW][COL], int row, int col)
{
for (int i = 0; i < row; i++)
{
for (int j = 0; j < col; j++)
{
if (j < col - 1)
{
printf(" %c |", board[i][j]);
}
else
printf(" %c ", board[i][j]);
}
printf("\n");
if (i < row - 1)
{
for (int k = 0; k < col; k++)
{
if (k < col - 1)
{
printf("---|");
}
else
{
printf("---");
}
}
}
printf("\n");
}
}
4.玩家落子
此步我们输入坐标的方式进行落子
需要注意的是我们普通人理解的坐标和数组元素坐标不同,前者是从1开始,后者是从0开始。
void playermove(char board[ROW][COL], int row, int col)
{
int x, y;
printf("请输入落子坐标:> ");
while (1)
{
scanf("%d%d", &x, &y);
if (x > 0 && x <= row&&y > 0 && y <= col&&board[x - 1][y - 1] == ' ')
{
board[x - 1][y - 1] = '*';
break;
}
else
{
printf("坐标非法,请重新输入: > ");
}
}
}
5.电脑落子
电脑落子简单来说就是电脑输入的坐标为0~2的随机数,因此次步需要使用rand()函数,然后再对rand()进行模运算就可以得到需要的随机数。
void commove(char board[ROW][COL], int row, int col)
{
while (1)
{
int x = rand() % row + 1;
int y = rand() % col + 1;
if (x > 0 && x <= row&&y > 0 && y <= col&&board[x-1][y-1] == ' ')
{
board[x-1][y-1] = '#';
break;
}
}
}
6.判断棋盘是否满子
此函数用来检测棋盘满子平局的情况
int full(char board[ROW][COL], int row, int col)
{
for (int i = 0; i < row; i++)
{
for (int j = 0; j < col; j++)
{
if (board[i][j] == ' ')
return 0;
}
}
return 1;
}
7.获胜条件判断
根据不同情况,函数所返回的值也有所不同
char win(char board[ROW][COL], int row, int col,int mode)
{
int i = 0;
int j = 0;
int mode_1 = 0;
int flag = 0;
//判断行
for (i = 0; i < row; i++)
{
for (j = 0; j < col - 1; j++)
{
if (board[i][j] == board[i][j + 1] && board[i][j + 1] != ' ')
flag++;
if (flag == mode - 1)
{
flag = 0;
return board[i][j];
}
}
flag = 0;
}
//判断列
for (i = 0; i < col; i++)
{
for (j = 0; j < row - 1; j++)
{
if (board[j][i] == board[j + 1][i] && board[j + 1][i] != ' ')
flag++;
if (flag == mode - 1)
{
flag = 0;
return board[j][i];
}
}
flag = 0;
}
//判断对角线
for (mode_1 = mode - 1; mode_1 < col; mode_1++)
{
for (i = 0, j = mode_1; j > 0; i++, j--)
{
if (board[i][j] == board[i + 1][j - 1] && board[i][j] != ' ')
flag++;
if (flag == mode - 1)
{
flag = 0;
return board[i][j];
}
}
flag = 0;
}
for (mode_1 = 1; mode_1 < col - mode + 1; mode_1++)
{
for (i = row - 1, j = mode_1; j <col; i--, j++)
{
if (board[i][j] == board[i - 1][j + 1] && board[i][j] != ' ')
flag++;
if (flag == mode - 1)
{
flag = 0;
return board[i][j];
}
}
flag = 0;
}
for (mode_1 = 0; mode_1 < col - mode + 1; mode_1++)
{
for (i = 0, j = mode_1; j < col; i++, j++)
{
if (board[i][j] == board[i + 1][j + 1] && board[i][j] != ' ')
flag++;
if (flag == mode - 1)
{
flag = 0;
return board[i][j];
}
}
flag = 0;
}
for (mode_1 = mode - 1; mode_1 < col - 1; mode_1++)
{
for (i = row - 1, j = mode_1; j > 0; i--, j--)
{
if (board[i][j] == board[i - 1][j - 1] && board[i][j] != ' ')
flag++;
if (flag == mode - 1)
{
flag = 0;
return board[i][j];
}
}
flag = 0;
}
if (full(board, row, col) == 1)
{
return 'Q';
}
return 'C';
}
8.整体游戏框架构建
在每次玩家和电脑落子后都使用win()函数进行判断一次,将其值返回给ret变量,然后根据不同的ret返回值打印不同的结果。
void game(char board[ROW][COL])
{
char ret;
while (1)
{
printfboard(board, ROW, COL);
playermove(board, ROW, COL);
ret = win(board, ROW, COL,MODE);
if (ret != 'C')
{
printfboard(board, ROW, COL);
break;
}
commove(board, ROW, COL);
ret = win(board, ROW, COL,MODE);
if (ret != 'C')
{
printfboard(board, ROW, COL);
break;
}
}
if (ret == '*')
{
printf("玩家获胜!\n");
}
if (ret == '#')
{
printf("电脑获胜!\n");
}
if (ret == 'Q')
{
printf("平局!\n");
}
}
最后我们需要对我们编写的代码进行测试,所以我们再次创建一个源文件”test.c“进行测试
int main()
{
srand((unsigned int)time(NULL));
char board[ROW][COL] = { 0 };
int n = 0;
do
{
menu();
scanf("%d", &n);
initboard(board, ROW, COL);
switch (n)
{
case 1:
game(board);
break;
case 2:
break;
default:
printf("请重新输入: >\n");
break;
}
} while (n != 0);
system("pause");
return 0;
}
至此,整个C语言编写三子棋就此结束…