目录
前言
以前偷偷上课无聊的时候就和同学玩的三子棋,现在就让我们用程序来设计实现一下吧。
1.首先有个游戏要有头有尾,那么头部呢就是要我们选择是否进行游戏的菜单
2既然有了菜单,那么选择完之后就到我们的游戏内容本体进行,那么三子棋游戏是怎么样呢?
三子棋你得有个棋盘对吧?那么我们第一步就构建一个可以给我下棋的棋盘,既然构建好棋盘之后呢,接下来就要我们初始化棋盘对吧,保证能让我们在棋盘正常下棋,避免上一把玩完之后还留存着上一把的痕迹。
第二步呢就该到我们玩家下棋了!玩家下完棋之后就该电脑下棋了对吧?
第三步呢就在游玩的过程中判断我们玩家或者电脑有没有赢呀!那这个时候每当玩家下完棋或者电脑下完棋之后就该判断一下哪一方赢了呢?对吧,好了接下来除了玩家赢和电脑赢之外,是不是还有个平局呢?那就要在我们判断游戏的条件里加个平局的结果!平局的话就是棋盘满了,但是没有一个人获胜。
第四步判断完输赢之后询问是否继续游玩,想要游玩就继续玩
3实现完这些后,整个游戏的框架大概就清晰明了了,更细节的地方就让我们在设计的过程中去讨论
废话不多,先放成品代码!
#define _CRT_SECURE_NO_WARNINGS 1
#include"game.h"
void game()
{
char ret = 0;
/*创建棋盘*/
char board[ROW][COL] = { 0 };
/*初始化棋盘*/
Initboard(board, ROW, COL);
/*打印棋盘*/
Displayboard(board, ROW, COL);
do
{
//玩家下棋
PlayerMove(board, ROW, COL);
Displayboard(board, ROW, COL);
IsWin(board, ROW, COL);
ret = IsWin(board, ROW, COL);
if (ret != 'C')
{
break;
}
//电脑下棋
ComputerMove(board, ROW, COL);
Displayboard(board, ROW, COL);
IsWin(board, ROW, COL);
if (ret != 'C')
{
break;
}
} while (1);
if (ret == '*')
{
printf("玩家赢\n");
}
else if (ret == '#')
{
printf("电脑赢\n");
}
if(ret == 'Q')
{
printf("平局\n");
}
}
int main()
{
int start = 0;
srand((unsigned int)time(NULL));
do
{
menu();
printf("请输入数字:>");
scanf("%d", &start);
switch (start)
{
case 1:
game();
break;
case 0:
printf("退出游戏");
break;
default:
printf("输入错误,请重新输入\n");
}
} while (start);
return 0;
}
#define _CRT_SECURE_NO_WARNINGS 1
#include"game.h"
void menu()
{
printf("*****************************\n");
printf("******** 1. play *********\n");
printf("******** 0. exit *********\n");
printf("*****************************\n");
}
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 Displayboard(char board[ROW][COL], int row, int col)
{
int i = 0;
for (i = 0; i < row; i++)
{
int j = 0;
printf(" %c | %c | %c\n", board[i][j], board[i][j+1], board[i][j+2]);
if (i < col - 1)
{
printf("---|---|---\n");
}
}
}
void PlayerMove(char board[ROW][COL], int row, int col)
{
int x = 0;
int y = 0;
printf("玩家下棋\n");
while (1)
{
printf("请输入棋盘坐标,中间用空格隔开:>");
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("该坐标被占用,请重新输入坐标!");
}
}
else
{
printf("坐标非法,不在棋盘范围,请重新输入!");
}
}
}
void ComputerMove(char board[ROW][COL], int row, int col)
{
int x = 0;
int y = 0;
printf("电脑下棋\n");
while (1)
{
x = rand() % ROW;
y = rand() % COL;
if (board[x][y] == ' ')
{
board[x][y] = '#';
break;
}
}
}
int IsFull(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 (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[0][i] == board[1][i] && board[1][i] == board[2][i] && board[0][i] != ' ')
{
return board[0][i];
}
}
//行
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];
}
}
//对角线
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 (IsFull(board, ROW, COL) == 1)
{
return 'Q';
}
return 'C';
}
#define _CRT_SECURE_NO_WARNINGS 1 #define ROW 3 #define COL 3 #include<stdio.h> #include<stdlib.h> #include<time.h> void menu(); void game();
~头文件
游戏实现过程
首先打开VS编译器,然后创建项目,创建一个实现游戏的主体main.c模块,一个创建游戏函数的game.c模块,一个头文件game.h模块声明游戏函数
然后你将所有要声明的库函数和自己写的函数都放在game.h里,然后让函数模块和主体模块都引用这个头文件,这样就不用麻烦的每个写声明啦
主体
如果要多次游玩那么就保证我们的循环一上来就得必须干一次,那么这里就用到do...while循环了
那么关于菜单这一块以及游戏菜单的循环写好了,那么接下来就是该实现游戏本体函数game()的内容了
1.我们要有个棋盘这样才能让我们下棋落子,好,接下来着手处理棋盘该怎么实现呢?
我们看到三子棋的棋盘是个3*3的大小,那么我们设计的棋盘的时候利用二维数组,设定常量3*3这样就是3*3的数组棋盘了,利用常量的话方面更改以后棋盘大小,不用一个个去每个地方更改
然后就是初始化棋盘,让我们3*3每个落子的地方先用空格初始化,因为看不见空格,所以更美观直白,初始化之后,就要打印我们的棋盘啦,打印棋盘的话就按照我们上面的那图来设计,小型的三子棋棋盘就是简单的3*3,那么横着的分割从上往下只要打印两次就足够啦,竖着的分割线从上往下打印就要打印3次就能分割开来,如果也只打印两次的话,第三行就会缺少两个分割线!
效果图:
既然成功实现了我们的棋盘打印,接下来游玩游戏阶段
玩家下棋与电脑下棋
完成棋盘之后就到我们游玩,首先创建玩家下棋与电脑下棋两个函数,那玩家落的子我们就定义为*号,电脑落的子就定义为#号
接着我们就判断输入范围对不对?不对的话就重新输入,所以套个循环,范围正确进入里层判断有没有空的位置?有空位就落子,没有空位就重新下棋!
接下来就是电脑落子的处理,想要电脑下棋肯定就要电脑随机下棋吧?既然提到随机那是不是应该提及rand(随机)函数呢?这个时候我们的头文件就要包含stdlib.h声明,设置随机数的起点srand函数就要有时间戳,那time是不是该有time.h的声明呢?那我们的头文件就要包含这两个
那我们首先设置随机数的起点,设定随机数的起点只用设置一次就足够了,那么就放到我们主体模块的头部吧
设置完之后我们就要着手定义我们的电脑玩家下棋的函数了,首先让电脑随机数的范围变成0-2,那么设置随机下棋的两个坐标范围就为0-2保证电脑下棋的范围不超过棋盘,接着再让电脑判断随机数所在的坐标是否还有空的位置,有空的位置就让电脑下棋,没有空的位置就让随机数重新生成接下来继续判断直到有空的位置为止!
判断棋盘空位
等我们下棋之后就要判断棋盘位置有没有被下完?如果被下完了就要停止游戏了就不能继续落子下去了,如果还有空位那我们就继续下棋,这样就有了两个条件要我们判断,那么我们判断出来之后就要给个标记到底满了还是没满?那么我们就设定为没满的符号为'C',满了的符号为'Q'。既然已经确定了两个符号和条件那么我们就要主模块的game函数里建立一个char ret变量来接收,在每次我们下完棋之后就判断棋盘有无空位,有就继续下棋,没有就跳出去!
那么判断空位跟是否胜利其实挂钩,那么我们就把字符返回放到我们的判断胜利条件里,让胜利条件判断的同时判断有无空位
判断输赢
我们知道,三子棋胜利条件就是3个相同的子连在一起就算胜利,好,这样我们就已经想好胜利的裁定条件了
游戏尾声
我们得到4个符号,分别是两个是判断玩家和电脑赢的符号,还有平局和继续游戏的符号!
那么就要放到我们主模块的gme函数里判断了,既然有判断那么我们就要套个循环让游戏不断判断运作下去!
程序成品
希望我的博客对你能够有所帮助,早日成为大牛~~~
--------------------------------------------------------------------------------------------------------------------------------
京子小可爱压轴~~~~~~~