HELLO,朋友们,又见面了
今天给大家带来C语言实现三子棋
主要从函数主体,棋盘,玩家下棋,电脑下棋,判断,5部分实现
另外,设计程序时,应当将函数的各个部分分别设计
1是写函数的游戏部分 , 2是函数的头文件部分,而3就是函数主体
而我们设计一个程序时,应当构思一个大概函数主体,然后一点点改进
有了写猜数字小游戏的经验之后,此部分应当是愈发熟练
具体看链接猜数字
另外会有一些小改动,game()中会存放棋盘,玩家下棋,电脑下棋,判断这几部分函数
void menu()
{
printf("********************\n");
printf("******1.play ******\n");
printf("********************\n");
printf("******0.exit ******\n");
printf("********************\n");
}
void game()
{
//**注意**game()中会存放棋盘,玩家下棋,电脑下棋,判断 这几部分函数
}
int main()
{
int input;
do
{
menu();
scanf("%d",&input);
switch (input)
{
case 1:
game();
break;//switch中的break用来跳出switch
case 0:
printf("您已退出游戏\n");
break;
default:
printf("输入错误,请重新输入\n");
break;
}
} while (input);//input为0时,直接跳出循环
return 0;
}
首先看成果图,紧接着请开始思考,棋盘需要一个二维数组,故我们应当创建一个数组先
char board[ROW][COL];
请注意,这里用的是ROW与COL
而不是
char board[3][3];
为什么这么设计呢,因为当我们想更改棋盘为4×4或别的形式,则牵一发而动全身,用3去表示显然不方便,则采用
#define ROW 3
#define COL 3
显然好得多
二维数组设计好后初始化
void set_board(char board[ROW][COL], int row, int col)
{
int i, j;
for (i = 0; i < row; i++)
{
for (j = 0; j < col; j++)
{
board[i][j] = ' ';
}
}
}
最后就是打印棋盘
要想打印出有横有竖的棋盘,需要灵活运用分支语句
void showboard(char board[ROW][COL], int row, int col)
{
int i, j;
//此部分是用来存放数据的一行
for (i = 0; i < row; i++)
{
for (j = 0; j < col; j++)
{
printf(" %c", board[i][j]);
if (j < col - 1)
printf("|");
}
//此部分打印分隔符
printf("\n");
for (j = 0; j < col; j++)
{
if (i < row - 1)
{
printf("--");
}
if (i < 2)
{
if (j < col - 1)
printf("|");
}
}
printf("\n");
}
}
打印棋盘可以自由发挥,不必拘泥
玩家下棋时要注意判断是否会超出数组界限,是否此时的点为‘(空格)’.,更要注意,要站在玩家的角度思考,玩家眼中的第一行,第一列就是(1,1),而不是我们眼中的(0,0),我们规定‘#’为玩家
void playermov(char board[ROW][COL], int row, int col)
{
printf("请输入坐标\n");
int a, b;
while (1)
{
scanf("%d %d", &a, &b);
if ((a >= 1 && a <= row) && (b >= 1 && b <= col))
{
if (board[a - 1][b - 1] == ' ')
{
board[a - 1][b - 1] = '#';
break;
}
else
printf("输入非法,重新输入\n");
}
else
printf("输入非法,重新输入\n");
}
}
电脑下棋就方便得多,但要使用随机数,规定电脑为‘*’
void computermov(char board[ROW][COL], int row, int col)
{
while (1)
{
int ret1 = rand() % row;
int ret2 = rand() % col;
if (board[ret1][ret2] == ' ')
{
board[ret1][ret2] = '*';
break;
}
}
}
注意!!!!随机数的生成要放在while中,否则就会生成死循环,这是题主血一样的教训,找BUG找麻辣!!
游戏有输有赢有平局,则我们也应对症下药
此部分也是对分支语句的使用极为看重
首先是判断输赢的部分
char judge(char board[ROW][COL], int row, int col)//记得包含
判断不用想的十分复杂,用循环一一列举即可,下图代码是输赢部分的
int i;
for (i = 0; i < row; i++)
{
if ((board[i][1] == board[i][0]) && (board[i][2] == board[i][1])&& board[i][1]!=' ')
return board[i][1];
}
for (i = 0; i < col; i++)
{
if ((board[1][i] == board[0][i ]) && (board[2][i] == board[1][i]) && board[1][i ] != ' ')
return board[1][i];
}
if(board[1][1]==board[2][2]&&board[1][1]==board[0][0]&&board[0][0] != ' ')
{
return board[1][1];
}
if (board[1][1] == board[0][2] && board[1][1] == board[2][0] && board[1][1] != ' ')
{
return board[1][1];
}
这是平局部分的
//equation
int j = 0;
int count = 0;
for (i = 0; i < row; i++)
{
for (j = 0; j < col; j++)
{
if (board[i][j] != ' ')
count+=1;
}
}
if (count == row * col)
{
return count;
}
else
return 'c';//c代表continue,继续游戏
如此,我们马上就大功告成
再依次进行封装
函数主体的game()部分
void game()
{
char ret;
//创建数组
char board[ROW][COL];
//制作棋盘
set_board(board, ROW, COL);
//打印棋盘
showboard(board, ROW, COL);
while (1)
{
//玩家下棋 #
playermov(board, ROW, COL);
showboard(board, ROW, COL);
//判断
ret = judge(board, ROW, COL);
if (ret == '#')
{
printf("你赢了\n");
break;
}
if (ret == ROW*COL)
{
printf("平了\n");
break;
}
//电脑下棋 *
computermov(board, ROW, COL);
showboard(board, ROW, COL);
//判断
ret=judge(board, ROW, COL);
if (ret == '*')
{
printf("你输了\n");
break;
}
if (ret == ROW * COL)
{
printf("平了\n");
break;
}
}
}
头文件部分
#define _CRT_SECURE_NO_WARNINGS 1
#include
#define ROW 3
#define COL 3
void set_board(char board[ROW][COL], int row, int col);
void playermov(char board[ROW][COL], int row, int col);
void showboard(char board[ROW][COL], int row, int col);
void computermov(char board[ROW][COL], int row, int col);
#include
#include
char judge(char board[ROW][COL], int row, int col);
大家可以借鉴见一下
1.二维数组的类型写成int
2.电脑下棋时,把随机数的生成写在while之外
3.判断部分没用&&,连续使用了a= =b==c,酿成大错
4.判断部分没设置继续返回值
别的小错误数不胜数,耗费了巨大心血,一度想要放弃,大家一定要坚持下来