目录
1,使用VS(Visual Studio)创建test.c,game.c源文件和game.h头文件
一,问题描述
用c语言通过坐标落子的方式实现三子棋游戏
二,思路梳理
1,生成菜单选择开始游戏或者是退出游戏
2,创建并初始化棋盘
3,玩家落子
4,电脑落子
5,判断输赢关系
三,步骤实现
1,使用VS(Visual Studio)创建test.c,game.c源文件和game.h头文件
分别在编译器中创建以上源文件和头文件,这样会使的代码更加的简练,便于观察和修改
2,生成菜单
先在主函数中生成一个实现代码的总函数test();
void test()
{
//生成菜单
menu();
}
再在test函数中创建menu();菜单函数,在直接输出菜单
3,创建棋盘并初始化
void test()
{
menu();
//游戏实现函数
game();
}
首先需要在test总函数中生成一个用来实现游戏步骤的game()函数,游戏所用的棋盘也是在这里面生成
这里我们使用二维数组生成我们要使用的棋盘,至于这里为什么使用ROW和COL来代替行和列请继续往下看哟
再在game函数中生成一个初始化函数,这里我们要对棋盘进行初始化;初始化是游戏里的步骤所以我们接下来要在刚才设计的game.h中声明并在我们的game.c中实现
这就是为什么要使用ROW和COL来代替行和列,方便我们以后修改,在game.h中定义好函数之后我们就在game.c中实现
数组传参我们用小写的来接收,这里随便写都可以,我们遍历数组并且初始化数组为空格,那我们把棋盘打印出来看一下
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++) //先打印一行
{
//注意%c前后必须有空格
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");
}
}
}
4,玩家落子
提示:
1,玩家落子要落在空坐标上
2,玩家落子的坐标是从1开始,并不是数组的0开始
3,输入的坐标有误,可以重新输入
while (1)
{
//玩家
player_move(board, ROW, COL);
print_board(board, ROW, COL);
}
玩家落子过后要在棋盘上显示出来所以我们要在落子结束后打印棋盘,并且我要落子多次,所以是个循环
//玩家下棋
void player_move(char board[ROW][COL], int roe, int col);
void player_move(char board[ROW][COL], int row, int col)
{
printf("玩家下棋\n");
while (1)
{
printf("请输入你落子的坐标:>");
int x = 0;//行
int y = 0;//列
scanf("%d %d", &x, &y);
if (x >= 1 && x <=row && y >= 1 && y <= col) //坐标起始一定是1
{
if (board[x-1][y-1] == ' ')//-1才对应数组的坐标
{
board[x - 1][y - 1] = '*';
break;
}
else
{
printf("坐标已被占用,请重新输入");
}
}
else
{
printf("坐标非法\n");
}
}
}
5,电脑落子
电脑落子是随机的,关于随机数的生成我在上篇博客C语言实现猜数字游戏中有讲过,感兴趣的小伙伴可以去看看哟。
猜数字游戏:C语言初阶——实现猜数字游戏_饱满的稻穗zsn的博客-CSDN博客
while(1)
{
computer_move(board, ROW,COL);
print_board(board, ROW, COL);
}
//电脑下棋(随机生成)
//只要棋盘内有空坐标
computer_move(char board[ROW][COL], int row, int col)
{
while (1)
{
printf("电脑下棋:\n");
int x = rand() % row;//模一个数只会产生0-(模-1)的数
int y = rand() % col;//这里行和列是3,所以产生的是0-2的值
if (board[x][y] == ' ')
{
board[x][y] = '#';
break;
}
}
}
6,判断输赢
注意:
1,电脑赢:#(返回值)
2,玩家赢:*
3,平局:Q
4,游戏继续:C 游戏继续的前提是棋盘满了但依然没有分出胜负
void game()
{
while(1)
{
player_move(board, ROW, COL);
print_board(board, ROW, COL);
//判断输赢
ret = Is_win(board,ROW,COL);
if (ret != 'C')
{
break;//不是游戏继续,就需要结束游戏
}
}
}
玩家和电脑都要判断哟!!!
判断无非就是三种情况行列以及对角线,有没有在一条线上
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';
}
//游戏继续
return 'C';
}
这里的平局需要额外判断一下,棋盘是否以及满了
//判断棋盘是否已满
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,test.c
#define _CRT_SECURE_NO_WARNINGS 1
#include "game.h"
void menu()
{
printf("***************************\n");
printf("********* 1. play ********\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);
//判断输赢
if (ret != 'C')
{
break;
}
}
//出循环判断,是哪一个结果
if (ret == '*')
printf("玩家胜利\n");
else if (ret == '#')
printf("电脑胜利\n");
else if (ret == 'Q')
printf("平局\n");
}
//判断输赢要告诉我:玩家赢?电脑?平局?游戏继续?
/*玩家赢:*
* 电脑赢:#
* 平局:Q
* 游戏继续:C
*/
void test()
{
//电脑随机落子
srand((unsigned int)time(NULL));
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;
}
2,game.h
#define ROW 3
#define COL 3
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
//函数声明
//初始化棋盘
void init_board(char board[ROW][COL],int row,int col);
//打印棋盘
void print_board(char boardd[ROW][COL], int row, int col);
//玩家下棋
void player_move(char board[ROW][COL], int roe, int col);
//电脑下棋
computer_move(char board[ROW][COL], int row, int col);
//判断输赢
char Is_win(char board[ROW][COL], int row, int col);
3,game.c
#define _CRT_SECURE_NO_WARNINGS 1
#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++) //先打印一行
{
//注意%c前后必须有空格
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)
{
printf("玩家下棋\n");
while (1)
{
printf("请输入你落子的坐标:>");
int x = 0;//行
int y = 0;//列
scanf("%d %d", &x, &y);
if (x >= 1 && x <=row && y >= 1 && y <= col) //坐标起始一定是1
{
if (board[x-1][y-1] == ' ')//-1才对应数组的坐标
{
board[x - 1][y - 1] = '*';
break;
}
else
{
printf("坐标已被占用,请重新输入");
}
}
else
{
printf("坐标非法\n");
}
}
}
//电脑下棋(随机生成)
//只要棋盘内有空坐标
computer_move(char board[ROW][COL], int row, int col)
{
while (1)
{
printf("电脑下棋:\n");
int x = rand() % row;//模一个数只会产生0-(模-1)的数
int y = rand() % col;//这里行和列是3,所以产生的是0-2的值
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;
}
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';
}
//游戏继续
return 'C';
}
希望小伙伴们一键三连哟!!!