本期带大家一起来学习一下三子棋🌈🌈🌈
前言
相信大家在学习C语言的过程中,有时会感觉到有一些枯燥切乏味,今天就在这里教大家用C语言实现一个简单的小游戏三子棋,这个项目不需要很多的基础,只要学到了数组便可以实现,让我们在学习C语言的过程中可以获得更大的乐趣
游戏逻辑分析
首先,这个游戏是由玩家和电脑进行对局,玩家下棋后再由电脑下,当有任意一行三子连成一条线的时候便游戏结束判断胜利,因此在每一次落子之后便要进行判断胜负,若不分胜负,则平局,平局的判断条件便是当棋盘上的所有格子都有落子,但并没有三个连在一起的棋子。
游戏实现
菜单
首先,在打开一个程序之后,首先映入眼帘的便是程序的主菜单
//菜单界面
void menu()
{
printf("*********************\n");
printf("********1.play*******\n");
printf("********2.exit*******\n");
printf("*********************\n");
}
设计棋盘
在这个比较基础性的游戏中,没有引用界面库,是通过键盘输入进行游戏,所以我们要用字符来组成一个棋盘,用一个3x3的数组来存放棋子
//打印棋盘
void playboard(char board[ROW][COL])
{
int i, j;
for (i = 0; i < COL; i++)
{
for (j = 0; j < ROW; j++)
{
printf(" %c ", board[i][j]);
if (j != ROW - 1)
printf("|");
}
printf("\n");
for (j = 0; j < ROW; j++)
{
if (i != COL - 1)
printf("-----");
if (j != ROW - 1&& i != COL - 1)
printf("|");
}
printf("\n");
}
}
初始化棋子
在设计棋盘时我们将棋子设置成为了一个3x3的二维数组,在没有任何落子的时候所显示的效果是空白的,所以我们要将一开始的棋子都初始化为空格,下面为初始化棋子的代码实现
//初始化棋子
void IniBoard(char board[COL][ROW])
{
int i, j;
for (i = 0; i < COL; i++)
for (j = 0; j < ROW; j++)
board[i][j] = ' ';
}
实现落子
在三子棋中我们将’o‘的落子设置为玩家,’x‘设置为电脑落子,在输入想要落子对应的坐标后,便改变对应的变量为所落的棋子,并判断输入的坐标是否符合要求,在界定范围内,也没有下过棋子,以下分别为玩家和电脑落子的代码实现
//玩家下
void playermove(char board[COL][ROW])
{
int x, y;
do
{
printf("请选择您要下的的坐标(格式:行 列)\n");
scanf("%d%d", &x, &y);
if (x > 0 && x <= COL && y > 0 && y <= ROW && board[x-1][y-1] == ' ')
{
board[x - 1][y - 1] = 'o';
break;
}
else
printf("坐标非法,请重新输入\n");
} while (1);
}
//电脑下
void computermove(char board[COL][ROW])
{
do
{
int x = rand() % 3;
int y = rand() % 3;
if (board[x][y] == ' ')
{
board[x][y] = 'x';
break;
}
} while (1);
}
判断胜负
在三子棋中每一次落子可能都会决出胜负,为了简化代码提高运行效率,我们以不同的返回值来判断一次落子后胜负,返回’o’则玩家胜利,返回’x’则电脑胜利,返回’D’平局,'C’继续游戏,以下便是判断函数的代码实现。
//判断胜负
char judge(char board[COL][ROW])
{
int i, j;
for (i = 0; i < COL; i++)
if ((board[0][i] == board[1][i] && board[1][i] == board[2][i])|| (board[i][0] == board[i][1] && board[i][1] == board[i][2]))
return board[1][i];
if ((board[0][0] == board[1][1] && board[1][1] == board[2][2]) || (board[0][2] == board[1][1] && board[1][1] == board[2][0]))
return board[1][1];
for(i=0;i<ROW;i++)
for (j = 0; j < COL; j++)
{
if (board[i][j] == ' ')
return 'C';
}
return 'D';
}
游戏封装
#include"game.h"
int main()
{
srand((unsigned)time(NULL));
int input;
do
{
menu();
scanf("%d", &input);
switch (input)
{
case PLAY:game(); break;
case EXIT:break;
default:
printf("非法输入,请重新输入\n");
Sleep(1000);
system("cls");
break;
}
} while (input != 2);
return 0;
}
源代码展示
game.c
#include"game.h"
//游戏菜单
void menu()
{
printf("*********************\n");
printf("********1.play*******\n");
printf("********2.exit*******\n");
printf("*********************\n");
}
//游戏
void game()
{
char ret;
system("cls");
char board[COL][ROW];
IniBoard(board);
playboard(board);
do
{
playermove(board);
playboard(board);
ret = judge(board);
if (ret == 'o')
{
printf("玩家胜利\n");
system("cls");
break;
}
else if(ret=='D')
{
printf("平局\n");
break;
}
system("cls");
computermove(board);
playboard(board);
ret = judge(board);
if (ret == 'x')
{
printf("电脑胜利\n");
system("cls");
break;
}
else if (ret == 'D')
{
printf("平局\n");
break;
}
} while (1);
}
//初始化棋盘
void IniBoard(char board[COL][ROW])
{
int i, j;
for (i = 0; i < COL; i++)
for (j = 0; j < ROW; j++)
board[i][j] = ' ';
}
//打印棋盘
// | |
//-----|-----|-----
// | |
//-----|-----|-----
// | |
void playboard(char board[ROW][COL])
{
int i, j;
for (i = 0; i < COL; i++)
{
for (j = 0; j < ROW; j++)
{
printf(" %c ", board[i][j]);
if (j != ROW - 1)
printf("|");
}
printf("\n");
for (j = 0; j < ROW; j++)
{
if (i != COL - 1)
printf("-----");
if (j != ROW - 1&& i != COL - 1)
printf("|");
}
printf("\n");
}
}
//玩家下
void playermove(char board[COL][ROW])
{
int x, y;
do
{
printf("请选择您要下的的坐标(格式:行 列)\n");
scanf("%d%d", &x, &y);
if (x > 0 && x <= COL && y > 0 && y <= ROW && board[x-1][y-1] == ' ')
{
board[x - 1][y - 1] = 'o';
break;
}
else
printf("坐标非法,请重新输入\n");
} while (1);
}
//电脑下
void computermove(char board[COL][ROW])
{
do
{
int x = rand() % 3;
int y = rand() % 3;
if (board[x][y] == ' ')
{
board[x][y] = 'x';
break;
}
} while (1);
}
//判断胜负
char judge(char board[COL][ROW])
{
int i, j;
for (i = 0; i < COL; i++)
if ((board[0][i] == board[1][i] && board[1][i] == board[2][i])|| (board[i][0] == board[i][1] && board[i][1] == board[i][2]))
return board[1][i];
if ((board[0][0] == board[1][1] && board[1][1] == board[2][2]) || (board[0][2] == board[1][1] && board[1][1] == board[2][0]))
return board[1][1];
for(i=0;i<ROW;i++)
for (j = 0; j < COL; j++)
{
if (board[i][j] == ' ')
return 'C';
}
return 'D';
}
test.c
#include"game.h"
int main()
{
srand((unsigned)time(NULL));
int input;
do
{
menu();
scanf("%d", &input);
switch (input)
{
case PLAY:game(); break;
case EXIT:break;
default:
printf("非法输入,请重新输入\n");
Sleep(1000);
system("cls");
break;
}
} while (input != 2);
return 0;
}
game.h
#include<stdio.h>
#include<Windows.h>
#include<time.h>
#define ROW 3
#define COL 3
//定义菜单枚举变量
enum menu
{
PLAY = 1,
EXIT
};
void menu();
void game();
void IniBoard(char* board);
void playboard(char* board);
void playermove(char board[ROW][COL]);
void computermove(char board[ROW][COL]);
char judge(char board[COL][ROW]);
感谢与交流
🌹🌹🌹如果大家通过本篇博客收获了,对结构体及枚举,特别是结构体内存对齐和位段在VS当中的存储有了新的认知,那么希望支持一下哦如果还有不明白的,疑惑的话,或者什么比较好的建议的话,可以发到评论区,
我们一起解决,共同进步 ❗️❗️❗️
最后谢谢大家❗️❗️❗️💯💯💯