1:简介
我们在网上游玩各种游戏的时候有没有尝试想过自己也能写出一个小游戏出来,可当我们开始学习起来的时候发现是不是感觉学习的c语言每天都是在解各种各样的题?这篇文章将会带领你如何用二维数组实现自己的一个三子棋的小游戏。
想要写出一个三子棋我们首先需要一个棋盘,那么这个棋盘怎么实现这个棋盘呢?
2:棋盘的实现
假设是我们需要的棋盘是一个井字图形。
可以看出来这个字里面有九个空格,是不是就对应我们二维数组的三行三列,那我们就给这个二维数组取名叫board。这九个空格里面每一个都是空的,换成我们的二维数组是不是就是需要把每一个元素的值给了但是我们实际上却看不见。根据这个想法我们把空格初始化给这个二维数组那么我们最后得到的就是拥有一个三行行列的空格。那么我们如何去打印这个井字呢。我们把它拆分来看是不是就是需要我们打印第一行是空格 竖线 空格 竖线 空格,第二行是横线 竖线 横线 竖线 横线,第三行又是 空格 竖线 空格 竖线 空格,这样一直到第五行呢?
井字的空格我们有了,接下来我们要想的是如何实现这个横竖的线。在打印第一行的空格的时候我们是不是就可以看出有两条竖线。那我们在打印第一行空格的时候是不是也可以跟着把这两条竖线打印了。并且我们可以看出,打印出来的空格是比竖线要多的,那我们就说当我们的内循环的j大于3-1的时候就不要在打印这个竖线了。
在把第一行打印之后我们看出这个井字图形是不是也是有规律的呢,可以看出他是第一行是空格和竖线,第二行是横线和竖线,那么我们就说在打印第一行的时候顺便也可以把第二行也给一起打印出来
可以看出最后是空格和竖线结尾的,那么我们就说当i<3-1的时候就打印我们的横线,当j小于3-1的时候打印我们的竖线
这样我们就得到了一个3*3的棋盘。
3:下棋的实现
一:玩家下棋
接下来我们开始实现如何下棋。那么想一下,下棋是不是就是你一步我一步并且下棋也是在我们的坐标上面下,知道了这个我们就在设一个x,y的变量来作为我们下棋的坐标。那我们玩家开始下棋的时候事需要录入x,y的变量的,我们就说用scanf从键盘上获取两个数值来赋给我们的x,y。那么我在想,棋盘的大小是一个3*3的二维数组,那么数组最大的下标就是2 2。玩家是不知道下标的。如果输入一个3 3,那么是不是就超出了我们的这个棋盘的范围,此时我们就说把玩家输入的数值减去一也就对应我们落子的下标。那么还有一种情况就是如果第二次下棋的地方已经有子了是不是就下不了了,那我们就得判断一下,我们这次下棋的位置是不是一个空值,如果里面有棋子,就给玩家提示一下该处已经有棋子,既然涉及到多次输入那我们就知道下棋这一步也是一个循环语句,所以我们在外层给他套上一个循环。
二:电脑下棋
玩家下完棋之后轮到电脑了,那电脑怎么知道走哪里呢。这时候就用到需要用到rand这个随机数,我们又知道这个棋盘是一个三行三列的二维数组,那么用rand对3取余就得到了0到2之间的一个数。又知道电脑下棋的位置也是在这个二维数组内,我们设x,y来接受我们电脑下棋的位置。那么还有一种情况如果电脑下棋的位置上已经有棋子了的话就会造成我们棋子的重复,所以我们要给出一个条件说只有在board【x】【y】==’空格‘的情况下电脑才可以下棋。
3:获胜的条件
现在我们解决了棋盘和如何下棋的问题,那下棋不可能一直下下去,总得有获胜得一方吧。那我们就说,下棋无非四种结果,一种电脑赢了,一种玩家赢了,一种平局,一种都没赢那么游戏就要继续。我们就设如果电脑赢就给我们返回一个#,玩家赢就返回一个*,平局就返回Q,继续返回一个C。再想一下,除了最后一个,无论是平局还是电脑或者玩家赢,游戏是不是都结束了,那我们可以说如果返回的值不等于C的话,我们就跳出去,不要让他结束。
4:获胜的实现
到现在我们大体的逻辑有了。我们知道获胜就是三行或者三列或者斜线是一样的棋子就能获胜。
知道了这个条件之后我们就可以封装一个函数来表示说如果board【i】【0】等于board【i】【1】board【i】【1等于board【i】【2】并且他们其中任意一个元素不能为空格,我们就可以返回一个*来表示玩家获胜,或者返回一个#来表示电脑获胜。
如果棋盘下满了的话都没有获胜的一方那我们就可以在封装一个函数来表示,如果返回的是一就表示棋盘满了是平局,如果没满就返回一个零继续游戏。
函数有了,他的功能如何去实现呢?我们就说给出一个嵌套的for循环,如果board【i】【j】里面只要有一个’空格‘就表示棋盘没有满,就给我们返回一个零,不然的话就返回一个1,那这样想的话是不是就和我们前面的链接上了。
5:代码的实现
测试
#include"game.h"
void meun()
{
printf("*****************************\n");
printf("******1,play 0,over*********\n");
printf("*****************************\n");
}
void game()
{
char ret = 0;
char board[ROW][COL] = { 0 }; //棋盘
InitBoard(board, ROW, COL); //棋盘内的数字初始化为空格
DisPlayBoard(board,ROW,COL); //棋盘的实现
while (1)
{
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); //判断电脑是否赢了
ret = IsWin(board, ROW, COL);
if (ret != 'C')
{
break;
}
}
if (ret == '*')
{
printf("你赢了\n");
}
else if (ret == '#')
{
printf("你输了\n");
}
else
{
printf("平局\n");
}
}
void test(int input)
{
do {
meun();
printf("请输入->\n");
scanf("%d", &input);
switch (input)
{
case 1:
printf("开始游玩->\n");
game();
printf("是否选择继续游玩->\n");
break;
case 0:
printf("退出游戏->\n");
break;
default:
printf("输入错误,请重新选择->\n");
break;
}
} while (input);
}
int main()
{
int input = 0;
srand((unsigned int)time(NULL));
test(input);
return 0;
}
头文件
#define ROW 3
#define COL 3
#include<stdio.h>
#include<stdlib.h>
#include<time.h>
#include<windows.h>
#pragma warning(disable:4996)
void InitBoard(char board[ROW][COL],int row,int col);
DisPlayBoard(char board[ROW][COL],int row,int col);
PlayerMove(char board[ROW][COL], int row, int col);
ComputerMove(char board[ROW][COL], int row, int col);
char IsWin(char board[ROW][COL],int row,int col);
int IsFUll(char board[ROW][COL], int row, int col);
实现
#include"game.h"
void InitBoard(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] = ' ';
}
}
}
//DisPlayBoard(char board[ROW][COL],int row,int col)
//{
// int i = 0;
// for (i = 0; i <row; i++)
// {
// printf(" %c | %c | %c \n",board[i][0],board[i][1],board[i][2]);
// if(i==2)
// break;
// printf("---|---|---\n");
// }
//
//}
DisPlayBoard(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 < row - 1) //
printf("|"); //打印棋盘元素的的分割线
}
printf("\n"); //每打印完一行换一次行
if (i < row - 1) //棋盘的横线少一行
{ //如果满足久开始执行下面的语句
for (j = 0; j < col; j++)
{
printf("---");
if(j<col-1) //竖横少一行
printf("|");
}
printf("\n"); //没打印完一行换行
}
//printf("\n");
}
}
PlayerMove(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 >= 1 && x <= row && y>=1 && y <= row) //判断下棋位置是否在数组内
{
if (board[x - 1][y - 1] == ' ') //判断落子的位置是否有棋子
{
board[x - 1][y - 1] = '*'; //如果没有就下棋
break; //落子成功跳出去打印
}
else
{
printf("此位置已有子->\n");
}
}
else
{
printf("超出棋盘,请重新落子->\n");
}
}
}
ComputerMove(char board[ROW][COL], int row, int col)
{
int x = 0;
int y = 0;
printf("电脑正在决定落子的位置......\n");
while (1)
{
x = rand() % row; //取一个0到2 的随机值
y = rand() % col; //去一个0到2的随机值
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][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 (1 == IsFull(board,ROW,COL))
{
return 'Q'; //是平局返回Q
}
else
return 'C'; //继续游戏返回C
}