c语言在已经学习了基本常识,分支与循环,函数,数组以后是能够独立制作小游戏-三子棋.。为了使代码更加简洁,使用多文件形式
重复玩,也就是用循环来实现重复玩的逻辑,由于每一次启动程序,都应该进入游戏,所以使用do while循环,同时记得给玩家提示,如何开始游戏
//test.C
void meum()
{
printf("**************\n");
printf("*****1.play***\n");
printf("*****0.exit***\n");
printf("**************\n");
}
int main()
{
int input = 0;
srand((unsigned)time(NULL));
do
{
meum();
scanf("%d", &input);
switch (input)
{
case 1:
{
game();
break;
}
case 0:
{
printf("你已经退出了游戏了哦\n");
break;
}
default:
{
printf("你输入错了,你得再输入一遍");
break;
}
}
} while (input);
}
如代码,当input为1时,则进入switch语句中的case 1,进入游戏,如果选择0,则进入case 0 ,退出游戏,同时由于do while循环中 input=0,为假,跳出循环,程序执行结束。利用 0 为假来控制结束程序。如果输入其他字符,则会提示玩家,输入错误,重新输入
棋盘的内容应该都是空格,由于是三子棋,所以应该是九宫格类似的棋盘。
可以定义一个二维数组,再将二维数组的内容初始化为空格
代码如下
//test.c
char board[ROW][COL];
//game.c
void initboard(char board[ROW][COL],int row,int col)
{
int i = 0;
int j = 0;
for(i=0;i|
棋盘应该不只是全空格,要不然刚开始会什么也看不见,同时游戏也不是很美观。
我们希望应该是一个由分割行的棋盘。
打印数组还是用循环来实现
要实现如图的棋盘,应该在二维数组的每一个元素的两边都有一个空格,同时只有最后一个元素的后面没有分割行,而其他元素的右边都会有分割行。而且第一行与第二行下方有分割行,也就是只有最后一行的下方没有分割行
实现的代码如下
void printboard(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++)
{
if (j < col - 1)
{
printf(" %c |", board[i][j]);
}
else
{
printf(" %c ", board[i][j]);
}
}
printf("\n");
for (j = 0; j < col; j++)
{
if (j < col - 1)
{
printf("---|");
}
else
{
printf("---");
}
}
printf("\n");
}
}
##### 1.玩家输入
玩家下棋输入棋盘的坐标,但是玩家不是程序员,需要注意二维数组的下标起始是 0 ,所以在对棋盘内容修改时记得注意这一点。
在玩家下棋的过程,可能出现三种情况,1:输入成功玩家实现了下棋。(玩家输入正确同时棋盘内容为空格)2:该棋盘已经被玩家或者电脑下过了。
3.玩家输入的坐标是错误的。
对于 第一种情况而言,是不需要重新输入坐标的。而对于第二种与第三种情况,应该让玩家重新输入坐标
//game.c
void playermove(char board[ROW][COL], int row, int col)
{
int x, y;
while (1)
{
printf("玩家走> 请输入\n");
scanf("%d%d", &x, &y);
if (x <= 3 && x >= 1 && y <= 3 && y >= 1 && board[x-1][y-1]==' ')
{
board[x - 1][y - 1] = '#';
break;
}
else if (board[x-1][y-1] == '#'|| board[x - 1][y - 1] == '*')
{
printf("已经被下过了,再下一次\n");
}
else
{
printf("坐标非法,重新输入\n");
}
}
}
//game.h
void playermove(char board[ROW][COL], int row, int col)
电脑下棋,坐标的输入是随机的。同时应该保证与玩家下棋类似的逻辑,但是由于电脑下棋,是不需要提示玩家电脑输入错误的,电脑会重新生成随机数坐标并再一次输入棋盘中。
代码如下
其中 %3 的作用是使得每一次下棋得随机数都在0-2之间
使用rand函数记得设置种子srand()函数
void computermove(char board[ROW][COL], int row, int col)
{
printf("电脑走>\n");
while (1)
{
int x = rand() % 3;
int y = rand() % 3;
if (board[x][y] == ' ')
{
board[x][y] = '*';
break;
}
}
}
三子棋顾名思义,也就是行或者列都拥有三个相同得棋子或者对角线也拥有三个相同的棋子则为胜利
当然,也有可能为平局
代码如下
代码解析:先判断行列或者对角线是否有三个相同的元素并且不为空格,如果都不成立,则只有平局和继续游戏两种情况,先判断棋盘是否已经下满,下满则平局,没下满则继续下棋
int IsFull(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 IsWin(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][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];
}
if (board[2][0] == board[1][1] && board[1][1] == board[0][2] && board[1][1] != ' ')
{
return board[1][1];
}
//判断是否平局
if (1 == IsFull(board, ROW, COL))
{
return 'Q';
}
//继续
return 'C';
}
进入game游戏函数以后,要做到先打印棋盘给玩家看,玩家下棋以后再打印棋盘给玩家看,同时判断输赢。电脑下完棋也有判断输赢并且打印棋盘给玩家看,玩家才能输得明白。
代码如下
void game()
{
char ret = 0;
char board[ROW][COL];
//初始化棋盘
initboard(board, ROW, COL);
//打印棋盘
printboard(board, ROW, COL);
while (1)
{
//玩家走
playermove(board, ROW, COL);
printboard(board, ROW, COL);
//判断输赢
ret = IsWin(board, ROW, COL);
if (ret != 'C')
{
break;
}
//电脑走
computermove(board, ROW, COL);
printboard(board, ROW, COL);
ret = IsWin(board, ROW, COL);
if (ret != 'C')
{
break;
}
}
if (ret == '*')
{
printf("电脑赢\n");
}
else if (ret == '#')
{
printf("玩家赢\n");
}
else
{
printf("平局\n");
}
}
//test.c
#include"game.h"
void meum()
{
printf("**************\n");
printf("*****1.play***\n");
printf("*****0.exit***\n");
printf("**************\n");
}
void game()
{
char ret = 0;
char board[ROW][COL];
//初始化棋盘
initboard(board, ROW, COL);
//打印棋盘
printboard(board, ROW, COL);
while (1)
{
//玩家走
playermove(board, ROW, COL);
printboard(board, ROW, COL);
//判断输赢
ret = IsWin(board, ROW, COL);
if (ret != 'C')
{
break;
}
//电脑走
computermove(board, ROW, COL);
printboard(board, ROW, COL);
ret = IsWin(board, ROW, COL);
if (ret != 'C')
{
break;
}
}
if (ret == '*')
{
printf("电脑赢\n");
}
else if (ret == '#')
{
printf("玩家赢\n");
}
else
{
printf("平局\n");
}
}
int main()
{
int input = 0;
srand((unsigned)time(NULL));
do
{
meum();
scanf("%d", &input);
switch (input)
{
case 1:
{
game();
break;
}
case 0:
{
printf("你已经退出了游戏了哦\n");
}
default:
{
printf("你输出错了,你得再输入一遍");
}
}
} while (input);
}
//game.c
#include"game.h"
void initboard(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 printboard(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++)
{
if (j < col - 1)
{
printf(" %c |", board[i][j]);
}
else
{
printf(" %c ", board[i][j]);
}
}
printf("\n");
for (j = 0; j < col; j++)
{
if (j < col - 1)
{
printf("---|");
}
else
{
printf("---");
}
}
printf("\n");
}
}
void playermove(char board[ROW][COL], int row, int col)
{
int x, y;
while (1)
{
printf("玩家走> 请输入\n");
scanf("%d%d", &x, &y);
if (x <= 3 && x >= 1 && y <= 3 && y >= 1 && board[x-1][y-1]==' ')
{
board[x - 1][y - 1] = '#';
break;
}
else if (board[x-1][y-1] == '#'|| board[x - 1][y - 1] == '*')
{
printf("已经被下过了,再下一次\n");
}
else
{
printf("坐标非法,重新输入\n");
}
}
}
void computermove(char board[ROW][COL], int row, int col)
{
printf("电脑走>\n");
while (1)
{
int x = rand() % 3;
int y = rand() % 3;
if (board[x][y] == ' ')
{
board[x][y] = '*';
break;
}
}
}
int IsFull(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 IsWin(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][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];
}
if (board[2][0] == board[1][1] && board[1][1] == board[0][2] && board[1][1] != ' ')
{
return board[1][1];
}
//判断是否平局
if (1 == IsFull(board, ROW, COL))
{
return 'Q';
}
//继续
return 'C';
}
//game.h
#include
#include
#include
#define ROW 3
#define COL 3
void initboard(char board[ROW][COL],int row,int col);
void printboard(char board[ROW][COL], int row, int col);
void playermove(char board[ROW][COL], int row, int col);
void computermove(char board[ROW][COL], int row, int col);
char IsWin(char board[ROW][COL], int row, int col);