目录
游戏分别放在一个工程的三个项目里实现,可以使代码更加简洁,具有可读性。
具体解析全在代码段里了,可自取,有什么bug欢迎指正哦~
写游戏的小细节可以看我之前的一篇博客【C语言实现猜数字小游戏】,讲解内容更详细些。
test.c
#define _CRT_SECURE_NO_WARNINGS
#include"game.h"
void menu()
{
printf("*****************************\n");
printf("******** 三子棋小游戏 *******\n");
printf("********* 1.Plqy ************\n");
printf("********* 0.Exit ************\n");
printf("*****************************\n");
}
void game()
{
char board[ROW][COL];
char ret = 0;
//初始化棋盘全为空格
init_board(board, ROW, COL);//board为数组名
//打印棋盘
print_board(board, ROW, COL);
while (1)
{
//玩家下棋
player_move(board, ROW, COL);
system("cls");//清屏,让界面更简洁
print_board(board, ROW, COL);
//判断输赢
ret = is_win(board, ROW, COL);
if (ret != 'C')
{
break;//如果游戏不继续,则跳出while循环,到下面的if-else语句判断输赢
} //如果游戏继续,则继续循环,进行下一步电脑下棋
//电脑下棋
computer_move(board, ROW, COL);
system("cls");//清屏,让界面更简洁
print_board(board, ROW, COL);
//判断输赢
ret = is_win(board, ROW, COL);
if (ret != 'C')
{
break;//如果游戏不继续,则跳出while循环,到下面的if-else语句判断输赢
} //如果游戏继续,则继续循环,进行下一步玩家下棋
}
//电脑赢了返回#;玩家赢了返回*;平局返回Q;游戏继续返回C
if (ret == '#')
printf("电脑赢了\n");
else if (ret == '*')
printf("玩家赢了\n");
else if (ret == 'Q')
printf("平局\n");
}
void test()
{
srand((unsigned int)time(NULL));//此处具体用法见之前的博客【用C语言实现猜数字小游戏】
int input = 0;
do
{
menu();
printf("请选择:");
scanf("%d", &input);
switch (input)
{
case 1:
game();
break;
case 0:
printf("游戏结束\n");
break;
default:
printf("选择错误\n");
break;
}
} while (input);
}
int main()
{
test();
return 0;
}
game.c
#define _CRT_SECURE_NO_WARNINGS
#include"game.h"
//初始化棋盘全为空格
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++)//控制行
{
int j = 0;
// | | 的打印
for (j = 0; j < col; j++)//控制列
{
printf(" %c ", board[i][j]);
if (j < col - 1)// | 最后一列不需要
printf("|");
}
printf("\n");//一行打印完要换行
// --- 的打印
if (i < row - 1)// --- 最后一行不需要
{
for (j = 0; j < col; j++)
{
printf("---");
if (j < col - 1)// | 最后一列不需要
printf("|");
}
printf("\n");
}
}
}
//玩家下棋
void player_move(char board[ROW][COL], int row, int col)
{
while (1)
{
printf("玩家下棋\n");
printf("请输入要下棋的坐标:>");
int x = 0;
int y = 0;
scanf("%d %d", &x, &y);
if (x >= 1 && x <= row && y >= 1 && y <= col)
{
if (board[x - 1][y - 1] == ' ')//玩家会认为行和列从1开始,所以程序内部要主动减1
{ //玩家输入1 1 ,对应0 0
board[x - 1][y - 1] = '*';
break;//下完棋跳出循环
}
else
{
printf("该坐标被占用,请重新输入\n");
}
}
else
{
printf("坐标非法\n");
}
}
}
//电脑下棋,随机生成坐标,只要不被占用就下棋
void computer_move(char board[ROW][COL], int row, int col)
{
printf("电脑下棋:\n");
while (1)
{
//rand 0~32767
int x = rand() % row;//任何一个数 % n ,得到的值为 0 ~ n-1
int y = rand() % col;
//判断坐标是否被占用
if (board[x][y] == ' ')
{
board[x][y] = '#';//没占用则放入#,被占用则继续循环重新生成随机数
break;
}
}
}
//平局函数——;判断棋盘是否满
static int is_full(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;//没有找到任何一个空格返回1
}
//判断输赢
char is_win(char board[ROW][COL], int row, int col)
{
int i = 0;
//判断三行
for (i = 0; i < row; i++)
{
if (board[i][0] == board[i][1] && board[i][1] == board[i][2] && board[i][0] != ' ')//三个元素相等且不为空格
{
return board[i][0]; //电脑赢了返回#;玩家赢了返回*
}
}
//判断三列
for (i = 0; i < col; i++)
{
if (board[0][i] == board[1][i] && board[1][i] == board[2][i] && board[0][i] != ' ')//三个元素相等且不为空格
{
return board[0][i];//电脑赢了返回#;玩家赢了返回*
}
}
//判断两个对角线
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];//电脑赢了返回#;玩家赢了返回*
}
//平局
if (is_full(board, row, col) == 1)
{
return 'Q';//平局返回'Q'
}
//没有输赢和平局,游戏继续
return 'C';
}
我在这里真的琢磨了好久,也不知道各位看官会不会和我有同样的困惑。两个for循环分别打印的是上述白杠杠的地方,可不要理解错了哦~
game.h
#pragma
#define ROW 3 //row 行
#define COL 3 //colume 列
#include<stdio.h>
#include<stdlib.h>
#include<windows.h>//system的头文件
//在头文件中声明函数
//初始化棋盘全为空格
void init_board(char board[ROW][COL], int row, int col);//row col 为形参,与上述ROW COL要分开来
//打印棋盘
void print_board(char board[ROW][COL], int row, int col);
//玩家下棋
void player_move(char board[ROW][COL], int row, int col);
//电脑下棋
void computer_move(char board[ROW][COL], int row, int col);
//判断输赢
char is_win(char board[ROW][COL], int row, int col);