前言
之前写过三子棋游戏,现在在此基础上给大家分享下使用C语言实现五子棋游戏
游戏介绍
该游戏与三子棋类似,在一个棋盘上,谁先五子连成一线谁就赢,可以是横成一线,竖成一线,正三角斜线,反三角斜线。五子棋上手简单,而且很有趣,相信大家都玩过吧。
接下来为大家分析C语言编写五子棋游戏的过程。
一.设计思路
- 首页要一个游戏主页菜单,可以选择玩家与玩家对战,玩家与电脑对战,以及退出游戏
- 设计棋盘:初始化、打印棋盘,并且在每行头和每列头标注数字,方便玩家要落子的位置
- 玩家1下棋和玩家2下棋或者玩家1与电脑下棋
- 判断输赢,哪方落子先成一线就赢
游戏步骤:(玩家1vs玩家2与之相似)
void game1()
{
char board[ROW][COL] = { 0 };
int k = 0;
initboard(board, ROW, COL);//初始化棋盘
displayboard(board, ROW, COL);//打印棋盘
while (1)
{
player1move(board, ROW, COL);//玩家下棋
displayboard(board, ROW, COL);//打印棋盘
k = iswin(board, ROW, COL);//判断输赢
if (k != 'c')
{
break;
}
computermove(board, ROW, COL);//电脑下棋
displayboard(board, ROW, COL);//打印棋盘
k = iswin(board, ROW, COL);//判断输赢
if (k != 'c')
{
break;
}
}
if (k == 'A')
{
printf("玩家赢\n");
}
else if (k == 'Z')
{
printf("电脑赢\n");
}
else
{
printf("平局\n");
}
}
二.具体流程分析
1.主页设计
进入游戏界面,就显示菜单,用switch语句控制游戏要进入的入口,选择1玩家与电脑下棋,选择2玩家1与玩家2下棋,选择0退出游戏,输入其他的则输入有误,重新输入;使用do while()循环,这样可以玩完一局接着玩。
int main()//游戏主页
{
int n = 0;
srand((unsigned int)time(NULL));
do
{
menu();
printf("请选择是否进入游戏:");
scanf("%d", &n);
switch (n)
{
case 1:
game1();//玩家1 VS 电脑
break;
case 2:
game2();//玩家1 VS 玩家2
break;
case 0:
printf("退出游戏\n");
break;
default:
printf("输入有误,请重新输入\n");
break;
}
} while (n);
return 0;
}
2.设计棋盘
使用二维数组board存储数据,ROW表示行,COL表示列,用#define来给行、列一个常量,这样后面方便修改棋盘的大小。调用initboard函数初始化棋盘,里面存放的是空格。
void initboard(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] = ' ';
}
}
}
紧接着是打印棋盘,与三子棋不同,玩五子棋的棋盘较大,为了方便玩家要落子的位置,所以在行头和列头标注数字,相当于坐标。
先给每列头标注数字,再换行打印棋盘最上面的横线;外循环控制row行,内循环分别打印竖线和数据与竖线和横线,然后在行末增加竖线,这样棋盘更好看些。注意换行和空格。
void displayboard(char board[ROW][COL], int row, int col)
{
printf("**·*·*·*·*·*·*·*·*·*·*·*·*·*·*·*·*·**\n");
int i = 0;
int j = 0;
printf(" ");
for (i = 0; i < row; i++)
{
printf(" %2d ", i + 1);//打印每列的坐标数字
}
printf("\n");
printf(" ");
for (j = 0; j < col; j++)
{
printf("----");//打印最上行横线
}
printf("\n");
for (i = 0; i < row; i++)
{
printf("%2d", i + 1);//打印每行的坐标数字
for (j = 0; j < col; j++)
{
printf("|");//先打印竖杆
printf(" %c ", board[i][j]);//再打印空格和数据
if (j == col - 1)//每行的最后一列补上竖杆
printf("|");
}
printf("\n");
printf(" ");
for (j = 0; j < col; j++)
{
printf("|");//先打印竖杆
printf("---");//再打印横线
if (j == col - 1)//每行的最后一列补上竖杆
printf("|");
}
printf("\n");
}
printf("**·*·*·*·*·*·*·*·*·*·*·*·*·*·*·*·*·**\n");
}
效果图:
3.玩家(1或2)下棋和电脑下棋
玩家下棋:设置两个变量x,y分别为表示输入的行坐标和列坐标,x和y必须在棋盘的范围内,超出坐标范围则不打印,又因为数组下标是从0开始的,所以当某个坐标为空时,方括号应写成x-1和y-1,落子成功则跳出循环。
void player2move(char board[ROW][COL], int row, int col)
{
int x = 0;
int y = 0;
while (1)
{
printf("玩家2下棋:>\n");
printf("请输入要下的坐标(12行/12列):");
scanf("%d %d", &x, &y);
if (x >= 1 && x <= row && y >= 1 && y <= col)
{
if (board[x - 1][y - 1] == ' ')
{
board[x - 1][y - 1] = 'D';
break;
}
else
{
printf("该坐标已被占用,请重新输入!\n");
}
}
else
{
printf("坐标不在棋盘范围内,请重新输入!\n");
}
}
}
电脑下棋:设置随机数,为空则打印,然后跳出循环,否则继续
void computermove(char board[ROW][COL], int row, int col)
{
int x = 0;
int y = 0;
while (1)
{
printf("电脑下棋:>\n");
x = rand() % row;
y = rand() % col;
if (board[x][y] == ' ')
{
board[x][y] = 'Z';
break;
}
}
}
4.判断输赢
返回’A’,玩家1赢;返回’D’,玩家2赢;返回’Z’,电脑赢;返回 ‘c’ 继续;返回其他平局
赢的方式:
1.行成五子
2.列成五子
3.正三角斜线成五子
4.反三角斜线成五子
int isfull(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++)
{
if (board[i][j] == ' ')
{
return 0;//为空继续
}
}
}
return 1;//不为空平局
}
char iswin(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 - 4; j++)
{
if (board[i][j] == board[i][j + 1] && board[i][j + 1] == board[i][j + 2] && board[i][j + 2] ==
board[i][j + 3] && board[i][j + 3] == board[i][j + 4] && board[i][j] != ' ')
{
return board[i][j];
}
}
}
//列成五子
for (j = 0; j < col; j++)
{
for (i = 0; i < row - 4; i++)
{
if (board[i][j] == board[i + 1][j] && board[i + 1][j] == board[i + 2][j] && board[i + 2][j] ==
board[i + 3][j] && board[i + 3][j] == board[i + 4][j] && board[i][j] != ' ')
{
return board[i][j];
}
}
}
//正斜成五子
for (i = 0; i < row; i++)
{
for (j = 0; j < col; j++)
{
if (board[i][j] == board[i + 1][j + 1] && board[i + 1][j + 1] == board[i + 2][j + 2] &&
board[i + 2][j + 2] == board[i + 3][j + 3] && board[i + 3][j + 3] == board[i + 4][j + 4] &&
board[i][j] != ' ')
{
return board[i][j];
}
}
}
//反斜成五子
for (i = 0; i < row; i++)
{
for (j = 0; j < col; j++)
{
if (board[i][j] == board[i - 1][j + 1] && board[i - 1][j + 1] == board[i - 2][j + 2] &&
board[i - 2][j + 2] == board[i - 3][j + 3] && board[i - 3][j + 3] == board[i - 4][j + 4] &&
board[i][j] != ' ')
{
return board[i][j];
}
}
}
//棋盘满了平局,否则继续
if (isfull(board, ROW, COL) == 1)
{
return 'q';
}
return 'c';
}
全部代码:
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#define ROW 12
#define COL 12
//初始化棋盘
void initboard(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] = ' ';
}
}
}
//打印棋盘
void displayboard(char board[ROW][COL], int row, int col)
{
printf("**·*·*·*·*·*·*·*·*·*·*·*·*·*·*·*·*·**\n");
int i = 0;
int j = 0;
printf(" ");
for (i = 0; i < row; i++)
{
printf(" %2d ", i + 1);//打印每列的坐标数字
}
printf("\n");
printf(" ");
for (j = 0; j < col; j++)
{
printf("----");//打印最上行横线
}
printf("\n");
for (i = 0; i < row; i++)
{
printf("%2d", i + 1);//打印每行的坐标数字
for (j = 0; j < col; j++)
{
printf("|");//先打印竖杆
printf(" %c ", board[i][j]);//再打印空格和数据
if (j == col - 1)//每行的最后一列补上竖杆
printf("|");
}
printf("\n");
printf(" ");
for (j = 0; j < col; j++)
{
printf("|");//先打印竖杆
printf("---");//再打印横线
if (j == col - 1)//每行的最后一列补上竖杆
printf("|");
}
printf("\n");
}
printf("**·*·*·*·*·*·*·*·*·*·*·*·*·*·*·*·*·**\n");
}
//玩家1下棋
void player1move(char board[ROW][COL], int row, int col)
{
int x = 0;
int y = 0;
while (1)
{
printf("玩家1下棋:>\n");
printf("请输入要下的坐标(12行/12列):");
scanf("%d %d", &x, &y);
if (x >= 1 && x <= row && y >= 1 && y <= col)
{
if (board[x - 1][y - 1] == ' ')
{
board[x - 1][y - 1] = 'A';
break;
}
else
{
printf("该坐标已被占用,请重新输入!\n");
}
}
else
{
printf("坐标不在棋盘范围内,请重新输入!\n");
}
}
}
//玩家2下棋
void player2move(char board[ROW][COL], int row, int col)
{
int x = 0;
int y = 0;
while (1)
{
printf("玩家2下棋:>\n");
printf("请输入要下的坐标(12行/12列):");
scanf("%d %d", &x, &y);
if (x >= 1 && x <= row && y >= 1 && y <= col)
{
if (board[x - 1][y - 1] == ' ')
{
board[x - 1][y - 1] = 'D';
break;
}
else
{
printf("该坐标已被占用,请重新输入!\n");
}
}
else
{
printf("坐标不在棋盘范围内,请重新输入!\n");
}
}
}
//电脑下棋
void computermove(char board[ROW][COL], int row, int col)
{
int x = 0;
int y = 0;
while (1)
{
printf("电脑下棋:>\n");
x = rand() % row;
y = rand() % col;
if (board[x][y] == ' ')
{
board[x][y] = 'Z';
break;
}
}
}
//判断输赢
int isfull(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++)
{
if (board[i][j] == ' ')
{
return 0;//为空继续
}
}
}
return 1;//不为空平局
}
char iswin(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 - 4; j++)
{
if (board[i][j] == board[i][j + 1] && board[i][j + 1] == board[i][j + 2] && board[i][j + 2] ==
board[i][j + 3] && board[i][j + 3] == board[i][j + 4] && board[i][j] != ' ')
{
return board[i][j];
}
}
}
//列成五子
for (j = 0; j < col; j++)
{
for (i = 0; i < row - 4; i++)
{
if (board[i][j] == board[i + 1][j] && board[i + 1][j] == board[i + 2][j] && board[i + 2][j] ==
board[i + 3][j] && board[i + 3][j] == board[i + 4][j] && board[i][j] != ' ')
{
return board[i][j];
}
}
}
//正斜成五子
for (i = 0; i < row; i++)
{
for (j = 0; j < col; j++)
{
if (board[i][j] == board[i + 1][j + 1] && board[i + 1][j + 1] == board[i + 2][j + 2] &&
board[i + 2][j + 2] == board[i + 3][j + 3] && board[i + 3][j + 3] == board[i + 4][j + 4] &&
board[i][j] != ' ')
{
return board[i][j];
}
}
}
//反斜成五子
for (i = 0; i < row; i++)
{
for (j = 0; j < col; j++)
{
if (board[i][j] == board[i - 1][j + 1] && board[i - 1][j + 1] == board[i - 2][j + 2] &&
board[i - 2][j + 2] == board[i - 3][j + 3] && board[i - 3][j + 3] == board[i - 4][j + 4] &&
board[i][j] != ' ')
{
return board[i][j];
}
}
}
//棋盘满了平局,否则继续
if (isfull(board, ROW, COL) == 1)
{
return 'q';
}
return 'c';
}
//玩家1 VS 电脑
void game1()
{
char board[ROW][COL] = { 0 };
int k = 0;
initboard(board, ROW, COL);//初始化棋盘
displayboard(board, ROW, COL);//打印棋盘
while (1)
{
player1move(board, ROW, COL);//玩家下棋
displayboard(board, ROW, COL);//打印棋盘
k = iswin(board, ROW, COL);//判断输赢
if (k != 'c')
{
break;
}
computermove(board, ROW, COL);//电脑下棋
displayboard(board, ROW, COL);//打印棋盘
k = iswin(board, ROW, COL);//判断输赢
if (k != 'c')
{
break;
}
}
if (k == 'A')
{
printf("玩家赢\n");
}
else if (k == 'Z')
{
printf("电脑赢\n");
}
else
{
printf("平局\n");
}
}
//玩家1 VS 玩家2
void game2()
{
char board[ROW][COL] = { 0 };
int k = 0;
initboard(board, ROW, COL);//初始化棋盘
displayboard(board, ROW, COL);//打印棋盘
while (1)
{
player1move(board, ROW, COL);//玩家1下棋
displayboard(board, ROW, COL);//打印棋盘
k = iswin(board, ROW, COL);//判断输赢
if (k != 'c')
{
break;
}
player2move(board, ROW, COL);//玩家2下棋
displayboard(board, ROW, COL);//打印棋盘
k = iswin(board, ROW, COL);//判断输赢
if (k != 'c')
{
break;
}
}
if (k == 'A')
{
printf("玩家1赢\n");
}
else if (k == 'D')
{
printf("玩家2赢\n");
}
else
{
printf("平局\n");
}
}
void menu()//打印菜单
{
printf("----------------------------------\n");
printf("---------* 五子棋小游戏 *---------\n");
printf("--------* 1.玩家1 VS 电脑 *-------\n");
printf("--------* 2.玩家1 VS 玩家2 *------\n");
printf("-----------* 0.退出游戏 *---------\n");
printf("----------------------------------\n");
}
int main()//游戏主页
{
int n = 0;
srand((unsigned int)time(NULL));
do
{
menu();
printf("请选择是否进入游戏:");
scanf("%d", &n);
switch (n)
{
case 1:
game1();//玩家1 VS 电脑
break;
case 2:
game2();//玩家1 VS 玩家2
break;
case 0:
printf("退出游戏\n");
break;
default:
printf("输入有误,请重新输入\n");
break;
}
} while (n);
return 0;
}
好了,分享到此结束。如果喜欢,可以邀请你的小伙伴一起玩哦~