目录
1.制作一个简易菜单
2.初始化棋盘
3.打印棋盘
4.玩家下棋
5.电脑下棋
6.判断输赢
完整代码
三子棋思维导图
为了方便见名知意我们所用到的一些主要函数名有:
//初始化棋盘
void inti_board();
//打印棋盘
void print_board();
//玩家
void player_move();
//电脑
void computer_move();
//判断输赢
char is_win();
首先我们要分开三个文件来编写这个小游戏
两个源文件main.c和test.c,还有一个头文件game.h
main.c文件用来存放函数和调试代码,test.c用来实现函数体(功能),game.h声明函数。
因为截长图失效了只能一块一块的截图了
因为每一次开始游戏都要输出打印一次菜单使用可以把菜单函数写在一个while循环,因为要先打印菜单这里建议使用do while先使用在循环
运行这个模块的效果
首先创建一个二维数组用于存储下的棋子,用宏定义来定义两个标识符为了方便维护修改棋盘大小,如果直接写char board[3][3]后面想修改棋盘的大小时候需要一个一个的修改花费更多的时间,宏定义直接修改后面参数就好
这里我们可以把棋盘分为五个部分输出
为了能够一直下棋我们要把下棋模块写在循环里面,每下一次棋打印一次棋盘
main.c
game.h
test.c
首先判断坐标是不是在合法范围内,如果小于0或者大于等于3,则输出坐标非法,如果在合法坐标内则下棋,为了不重复输入坐标还要加一个判断如果坐标为空才能下棋否则显示坐标已被占有。
电脑为随机下棋这里我们要使用一个rand()函数让它生成随机数定义一个变量接收它的返回值,前提还要使用一个srand函数设置随机数生成器,它的参数根据不同的数会产生出不同的结果,这里可以使用时间戳来当它的参数,因为时间每一秒都在不同的变化。
main.c
game.h
test.c
和玩家一样为了不让他在同一个地方下棋,必须得加一个判断如果棋盘不为空,则重新生成随机数。
定义一个char类型的变量来接受函数的返回值,玩家赢了返回#,电脑赢了返回*,平局返回Q,没有人赢有没有平局则返回C继续。
每下一次棋判断一次有没有三个棋子是相连的。
static int is_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;
}
char is_win(char board[ROW][COL], int row, int col)
{
int i = 0;
int j = 0;
int player_count_win1 = 0;//左角线
int computer_count_win1 = 0;//左角线
for (i = 0; i < row; i++)
{
int player_count_win = 0;//判断行和列
int computer_count_win = 0;//判断行和列
int player_count_win1 = 0;//左角线
int computer_count_win1 = 0;//左角线
//判断行
for (j = 0; j < col; j++)
{
if (board[i][j] == '#')
player_count_win++;
if (board[i][j] == '*')
computer_count_win++;
}
//判断玩家
if (player_count_win == row)
return '#';
else
player_count_win = 0 ;//清空计算
//判断电脑
if (computer_count_win == row)
return '*';
else
computer_count_win = 0;//清空计算
//判断列
for (j = 0; j < col; j++)
{
if (board[j][i] == '#')
player_count_win++;
if (board[j][i] == '*')
computer_count_win++;
}
//判断玩家
if (player_count_win == col)
return '#';
else
player_count_win = 0;//清空计算
//判断电脑
if (computer_count_win == col)
return '*';
else
computer_count_win = 0;//清空计算
//判断左对角线
for (j = 0; j < col; j++)
{
if (board[j][j] == '#')
player_count_win++;
if (board[j][j] == '*')
computer_count_win++;
}
if (player_count_win == row)
return '#';
else
player_count_win = 0;
if (computer_count_win == row)
return '*';
else
computer_count_win = 0;
//判断右对角线
for (int j = 0; j < col; j++)
{
if (board[j][col - 1 - j] == '#')
player_count_win++;
if (board[j][col - 1 - j] == '*')
computer_count_win++;
}
if (player_count_win == row)
return '#';
else
player_count_win = 0;
if (computer_count_win == row)
return '*';
else
computer_count_win = 0;
if (is_full(board, ROW, COL) == 1)
{
return 'Q';
}
}
return 'C';
}
game.h
#define _CRT_SECURE_NO_WARNLNGS 1
#include
#include
#include
#define ROW 3
#define COL 3
//初始化棋盘
void init_board(char board[ROW][COL], int row, int 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);
mian.c文件
#define _CRT_SECURE_NO_WARNINGS 1
#include "game.h"
void menu()
{
printf("****************************\n");
printf("******* 1.paly *******\n");
printf("******* 0.exit *******\n");
printf("****************************\n");
}
void game()
{
char board[ROW][COL];
char ret = 0;
//初始化棋盘
init_board(board, ROW, COL);//初始化为空格
//打印棋盘
print_board(board, ROW, COL);
while (1)
{
//玩家下棋
player_move(board, ROW, COL);
//打印棋盘
print_board(board, ROW, COL);
//判断输赢
ret = is_win(board, ROW, COL);
if (ret != 'C')
{
break;
}
//电脑下棋
computer_move(board, ROW, COL);
//打印棋盘
print_board(board, ROW, COL);
//判断输赢
ret = is_win(board, ROW, COL);
if (ret != 'C')
{
break;
}
}
if (ret == '#')
{
printf("恭喜你赢了\n");
//打印棋盘
print_board(board, ROW, COL);
}
else if (ret == '*')
{
printf("电脑赢了\n");
//打印棋盘
print_board(board, ROW, COL);
}
else
{
printf("平局\n");
//打印棋盘
print_board(board, ROW, COL);
}
}
void test()
{
srand((unsigned int)time(NULL));
int input = 0;
do
{
menu();
printf("请选择开始\n");
scanf("%d", &input);
switch (input)
{
case 1:
printf("游戏开始\n");
game();
break;
case 0:
printf("退出游戏\n");
break;
default:
printf("选择错误\n");
break;
}
} while (input);
}
int main()
{
test();
return 0;
}
test.c
#define _CRT_SECURE_NO_WARNINGS 1
#include "game.h"
void init_board(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++)
{
board[i][j] = ' ';
}
}
}
void print_board(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++)
{
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)
{
int x = 0;
int y = 0;
while (1)
{
printf("请输入坐标>\n");
scanf("%d%d", &x, &y);
if (x > 0 && x <= row && y > 0 && y <= col)
{
if (board[x - 1][y - 1] == ' ')
{
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)
{
int x = rand() % row;
int y = rand() % col;
if (board[x][y] == ' ')
{
board[x][y] = '*';
break;
}
}
}
static int is_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;
}
char is_win(char board[ROW][COL], int row, int col)
{
int i = 0;
int j = 0;
int player_count_win1 = 0;//左角线
int computer_count_win1 = 0;//左角线
for (i = 0; i < row; i++)
{
int player_count_win = 0;//判断行和列
int computer_count_win = 0;//判断行和列
int player_count_win1 = 0;//左角线
int computer_count_win1 = 0;//左角线
//判断行
for (j = 0; j < col; j++)
{
if (board[i][j] == '#')
player_count_win++;
if (board[i][j] == '*')
computer_count_win++;
}
//判断玩家
if (player_count_win == row)
return '#';
else
player_count_win = 0 ;//清空计算
//判断电脑
if (computer_count_win == row)
return '*';
else
computer_count_win = 0;//清空计算
//判断列
for (j = 0; j < col; j++)
{
if (board[j][i] == '#')
player_count_win++;
if (board[j][i] == '*')
computer_count_win++;
}
//判断玩家
if (player_count_win == col)
return '#';
else
player_count_win = 0;//清空计算
//判断电脑
if (computer_count_win == col)
return '*';
else
computer_count_win = 0;//清空计算
//判断左对角线
for (j = 0; j < col; j++)
{
if (board[j][j] == '#')
player_count_win++;
if (board[j][j] == '*')
computer_count_win++;
}
if (player_count_win == row)
return '#';
else
player_count_win = 0;
if (computer_count_win == row)
return '*';
else
computer_count_win = 0;
//判断右对角线
for (int j = 0; j < col; j++)
{
if (board[j][col - 1 - j] == '#')
player_count_win++;
if (board[j][col - 1 - j] == '*')
computer_count_win++;
}
if (player_count_win == row)
return '#';
else
player_count_win = 0;
if (computer_count_win == row)
return '*';
else
computer_count_win = 0;
if (is_full(board, ROW, COL) == 1)
{
return 'Q';
}
}
return 'C';
}