该版本可以选择双人游戏和人机对战,并且人机对战分为两个等级(简单人机随机下棋;困难人机是优化后的算法具有堵棋、三连功能)。
1.打印游戏菜单
2.初始化棋盘
3.打印棋盘
4.打印模式菜单
5.打印难度菜单
6.双人游戏
7.简单人机
8.困难人机
9.判断棋盘是否下满
10.判断输赢
用户输入
int main() {
srand((unsigned int)time(NULL));//随机数
int input = 0;
do
{
menu();
printf("请输入 >");
scanf("%d", &input);
switch (input) {
case 1:
playgame();
break;
case 0:
printf("游戏退出...\n");
break;
default:
printf("请输入正确的格式\n");
}
} while (input);
return 0;
}
void menu() {
printf("****************************\n");
printf("***** 0 退出游戏 ******\n");
printf("***** 1 进入游戏 ******\n");
printf("****************************\n");
}
void playgame() {
char model;//接收用户选择的模式
char difficulty;//接收难度系数
char ch;//接收数据 用于清空缓存区
model_menu();
printf("请你选择模式 >");
while ((ch = getchar()) != '\n' && ch != EOF);//清空缓存区
scanf("%c", &model);
if (model == 'a') {
difficulty_menu();
printf("请选择难度等级:");
while ((ch = getchar()) != '\n' && ch != EOF);//清空缓存区
scanf("%c", &difficulty);
if (difficulty == 'd') {
printf("困难模式开始...\n");
playgame_pvc(&difficulty);
}
else if (difficulty == 'e') {
printf("简单模式开始...\n");
playgame_pvc(&difficulty);
}
}
else if (model == 'b') {
printf("人人对战\n");
play_game_pvp();
}
}
//模式菜单
void model_menu() {
printf("***************************\n");
printf("** a 人机模式 b 双人模式 **\n");
printf("***************************\n");
}
//难度菜单
void difficulty_menu() {
printf("***************************\n");
printf("** e 简单模式 d 困难模式 **\n");
printf("***************************\n");
}
void init_board(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 print_board(char board[ROW][COL], int row, int col) {
int i = 0;
for (i = 0; i < row; i++) {
//打印数据
for (int j = 0; j < col; j++) {
if (j < col - 1)
printf(" %c |", board[i][j]);
else
printf(" %c\n", board[i][j]);
}
//打印分隔符
if (i < row - 1) {
for (int j = 0; j < row; j++) {
if (j < row - 1)
printf("---|");
else
printf("---\n");
}
}
}
}
void person_move(char board[ROW][COL], int row, int col) {
int i = 0, j = 0;
while (1) {
scanf("%d %d", &i, &j);
if (board[i - 1][j - 1] == ' ') {
//注意坐标与二维数组对应关系
board[i - 1][j - 1] = '*';
break;
}
else {
printf("此位置已被下过,请重新落棋:");
}
}
}
void computer_move_easy(char board[ROW][COL], int row, int col) {
int i = 0, j = 0;
printf("电脑走:\n");
while (1) {
i = rand() % row;
j = rand() % col;
if (board[i][j] == ' ') {
board[i][j] = '#';
break;
}
}
}
//检查电脑是否一线两子 如果有直接赢
int computer_will_win(char board[ROW][COL], int row, int col) {
int i = 0;
int j = 0;
int p_win = 0;//标志是否直接赢
if(0 == p_win)
{
//判断电脑横行上是否会赢
for (i = 0; i < row; i++)
{
if (board[i][0] == board[i][1] && board[i][1] == '#' && board[i][2] == ' ')
{
board[i][2] = '#';
p_win = 1;
break;
}
if (board[i][0] == board[i][2] && board[i][0] == '#' && board[i][1] == ' ')
{
board[i][1] = '#';
p_win = 1;
break;
}
if (board[i][1] == board[i][2] && board[i][1] == '#' && board[i][0] == ' ')
{
board[i][0] = '#';
p_win = 1;
break;
}
}
if (p_win != 0)
return p_win;
//判断电脑列上是否有机会赢
for (j = 0; j < col; j++)
{
if (board[0][j] == board[1][j] && board[1][j] == '#' && board[2][j] == ' ')
{
board[2][j] = '#';
p_win = 1;
break;
}
if (board[0][j] == board[2][j] && board[2][j] == '#' && board[1][j] == ' ')
{
board[1][j] = '#';
p_win = 1;
break;
}
if (board[1][j] == board[2][j] && board[2][j] == '#' && board[0][j] == ' ')
{
board[0][j] = '#';
p_win = 1;
break;
}
}
if (p_win != 0)
return p_win;
}
//判断电脑在对角线上是否会赢
if (0 == p_win)
{
if (board[0][0] == board[1][1] && board[1][1] == '#' && board[2][2] == ' ')
{
board[2][2] = '#';
p_win = 1;
return p_win;
}
if (board[0][0] == board[2][2] && board[2][2] == '#' && board[1][1] == ' ')
{
board[1][1] = '#';
p_win = 1;
return p_win;
}
if (board[1][1] == board[2][2] && board[1][1] == '#' && board[0][0] == ' ')
{
board[0][0] = '#';
p_win = 1;
return p_win;
}
if (board[0][2] == board[1][1] && board[0][2] == '#' && board[2][0] == ' ')
{
board[2][0] = '#';
p_win = 1;
return p_win;
}
if (board[0][2] == board[2][0] && board[2][0] == '#' && board[1][1] == ' ')
{
board[1][1] = '#';
p_win = 1;
return p_win;
}
if (board[1][1] == board[2][0] && board[2][0] == '#' && board[0][2] == ' ')
{
board[0][2] = '#';
p_win = 1;
return p_win;
}
}
return p_win;//p_win==0 说明没有直接赢 需继续判断是否要堵棋
}
//检测玩家是否能一线两子 如果有就堵
int people_will_win(char board[ROW][COL], int row, int col) {
int i = 0;
int j = 0;
int k = 0;
while (0 == k)
{
//判断玩家在横行上是否会赢
for (i = 0; i < row; i++)
{
if (board[i][0] == board[i][1] && board[i][1] == '*' && board[i][2] == ' ')
{
board[i][2] = '#';
k = 1;
break;
}
if (board[i][0] == board[i][2] && board[i][0] == '*' && board[i][1] == ' ')
{
board[i][1] = '#';
k = 1;
break;
}
if (board[i][1] == board[i][2] && board[i][1] == '*' && board[i][0] == ' ')
{
board[i][0] = '#';
k = 1;
break;
}
}
if (k != 0)
break;
//判断玩家在竖列上是否会赢
for (j = 0; j < col; j++)
{
if (board[0][j] == board[1][j] && board[1][j] == '*' && board[2][j] == ' ')
{
board[2][j] = '#';
k = 1;
break;
}
if (board[0][j] == board[2][j] && board[2][j] == '*' && board[1][j] == ' ')
{
board[1][j] = '#';
k = 1;
break;
}
if (board[1][j] == board[2][j] && board[2][j] == '*' && board[0][j] == ' ')
{
board[0][j] = '#';
k = 1;
break;
}
}
break;
}
//判断玩家在对角线上是否会赢
while (0 == k)
{
if (board[0][0] == board[1][1] && board[1][1] == '*' && board[2][2] == ' ')
{
board[2][2] = '#';
k = 1;
break;
}
if (board[0][0] == board[2][2] && board[2][2] == '*' && board[1][1] == ' ')
{
board[1][1] = '#';
k = 1;
break;
}
if (board[1][1] == board[2][2] && board[1][1] == '*' && board[0][0] == ' ')
{
board[0][0] = '#';
k = 1;
break;
}
if (board[0][2] == board[1][1] && board[0][2] == '*' && board[2][0] == ' ')
{
board[2][0] = '#';
k = 1;
break;
}
if (board[0][2] == board[2][0] && board[2][0] == '*' && board[1][1] == ' ')
{
board[1][1] = '#';
k = 1;
break;
}
if (board[1][1] == board[2][0] && board[2][0] == '*' && board[0][2] == ' ')
{
board[0][2] = '#';
k = 1;
break;
}
break;
}
return k;//返回值如果是1那么已经对玩家进行了堵棋,如果是0则无需堵。
}
//电脑下棋优化版
void computer_move_diff(char board[ROW][COL], int row, int col) {
int i = 0, j = 0;
int p;
printf("电脑走:\n");
//电脑先检测自己这一次落棋后自己是否能赢
p = computer_will_win( board, row, col);
if (p == 1) {//电脑已经下过棋
return;
}
//检查玩家是否会赢 会赢直接堵截
p = people_will_win(board, row, col);
if (p == 1) {//电脑对玩家进行了堵截不需要再下
return;
}
//运行到这说明也没有赢 也没有堵截 随机下棋
while (1) {
i = rand() % row;
j = rand() % col;
if (board[i][j] == ' ') {
board[i][j] = '#';
break;
}
}
}
//判断棋盘是否下满
int is_full(char board[ROW][COL], int row, int col)
{
int i, j;
for (i = 0; i < row; i++)
{
for (j = 0; j < col; j++)
{
if (board[i][j] == ' ')
//只要有位置为空就说明还没满
return 0;
}
}
//遍历全部都下满,则棋盘满了
return 1;
}
//检查是否有一方获胜
char check_win(char board[ROW][COL], int row, int col)
{
int i;
//判断横向是否有一样的
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];
}
//判断竖向是否有一样的
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];
}
//判断对角线是否有一样的
if (board[0][0] == board[1][1] && board[1][1] == board[2][2] && board[1][1] != ' ')
return board[1][1];
else if (board[2][0] == board[1][1] && board[1][1] == board[0][2] && board[1][1] != ' ')
return board[1][1];
//如果没人赢 检查棋盘是否满 也就是平局
else if (is_full(board, row, col))
return '$';
//以上情况都没有则分不出输赢
return 0;
}
//双人对战游戏
void play_game_pvp() {
char key;//接收输赢结果
//定义棋盘
char board[ROW][COL];
//初始化棋盘
init_board(board, ROW, COL);
//打印棋盘
print_board(board, ROW, COL);
while (1)
{
printf("请p1下棋:(输入坐标)>");
person_move(board, ROW, COL);//玩家1下棋
print_board(board, ROW, COL);//打印棋盘
key = check_win(board, ROW, COL);//判输赢平局
//打印输赢结果
if (key == '*')
{
printf("恭喜p1赢啦\n");
break;
}
if (key == '#')
{
printf("恭喜p2赢了\n");
break;
}
if (key == '$')
{
printf("平局了!\n");
break;
}
printf("请p2下棋:(输入坐标)>");
person2_move(board, ROW, COL);//玩家2下棋
print_board(board, ROW, COL);//打印棋盘
key = check_win(board, ROW, COL);//判输赢平局
//打印输赢结果
if (key == '*')
{
printf("恭喜你获得胜利啦\n");
break;
}
if (key == '#')
{
printf("p2赢了\n");
break;
}
if (key == '$')
{
printf("你们打平局了!\n");
break;
}
}
}
全部代码内容较多 以上也展示的差不多了,避免页面太长,想要直接全部拷贝来自己玩一玩的小伙伴可以码云复制。
点击这里获取全部代码
写的思想比较简单 可能存在错误如有发现欢迎指正 咱再继续改进。