您现在的位置是:首页 >其他 >三子棋游戏(二维数组的应用)网站首页其他
三子棋游戏(二维数组的应用)
hello啊,CSDN的各位前辈们,又到了本小白分享的日子了。最近突然感觉咱的博客略显沉闷,不如今天就来与各位分享一下新学习的小游戏代码吧???
观前声明:本人还在努力学习中,如果你在我的代码中发现了错误,请一定及时联系我,我会非常感谢的!!!
目录
一、game.h
#pragma once
#include<stdio.h>
#include<stdlib.h>
#include<time.h>
#define ROW 3
#define COL 3
//创建棋盘
void InitBoard(char board[ROW][COL], int row, int col);
//打印棋盘
void DisplayBoard(char board[ROW][COL], int row, int col);
//玩家移动
void PlayerMove(char board, int row,int col);
//电脑移动
void ComputerMove(char board, int row, int col);
//判断输赢
//玩家胜利'*'
//电脑胜利'#'
//平局'Q'
//继续'C'
char Is_win(char board, int row, int col);
//判断棋盘是否满
int Is_full(char board, int row, int col);
二、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 DisplayBoard(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++)
{
printf(" %c ", board[i][j]);
if (j < col - 1)
printf("|");
}
printf("
");
if (i < row - 1)
{
int j = 0;
for (j = 0; j < col; j++)
{
printf("---");
if (j < col - 1)
printf("|");
}
printf("
");
}
}
}
void PlayerMove(char board[ROW][COL], int row, int col)
{
int x = 0;
int y = 0;
printf("请输入坐标,用空格分开:");
while (1)
{
scanf_s("%d %d", &x, &y);
//坐标合法
if (x >= 1 && x <= row && y>=1 && 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("电脑下棋
");
while (1)
{
x = rand() % row;
y = rand() % col;
if (board[x - 1][y - 1] == ' ')
{
board[x - 1][y - 1] = '#';
break;
}
}
}
int Is_full(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 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];
//列
int j = 0;
for (j = 0; j < col; j++)
{
if (board[0][j] == board[1][j] && board[1][j] == board[2][j] && board[0][j] != ' ')
return board[0][j];
}
}
//对角线
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))
{
return 'Q';
}
//游戏继续
return 'C';
}
三、test.c
#include"game.h"
void menu()
{
printf("*****************************
");
printf("****** 1. start ******
");
printf("****** 0.exit ******
");
printf("*****************************
");
}
void game()
{
char board[ROW][COL] = { 0 };
InitBoard(board, ROW, COL);
DisplayBoard(board, ROW, COL);
char ret = 0;
while (1)
{
PlayerMove(board, ROW, COL);
DisplayBoard(board, ROW, COL);
ret = Is_win(board, ROW, COL);
if (ret != 'C')
break;
ComputerMove(board, ROW, COL);
DisplayBoard(board, ROW, COL);
ret = Is_win(board, ROW, COL);
if (ret != 'C')
break;
}
if (ret == '*')
printf("玩家胜利
");
else if (ret == '#')
printf("电脑胜利
");
else
printf("平局
");
}
int main()
{
int input = 0;
srand((unsigned int)time(NULL));
do
{
menu();
scanf_s("%d", &input);
switch (input)
{
case 1:
printf("开始游戏
");
game();
break;
case 0:
printf("游戏结束
");
break;
default:
printf("请重新输入:
");
break;
}
}while (input);//只有输入0,游戏才结束
return 0;
}
四、思路构建
(一)主函数框架:
首先我想让这个游戏可以重复游玩,所以构建了一个do while循环,其次我需要给用户提供一个游戏菜单,供用户选择接下来的操作,所以一个menu()函数则是必需的啦。并且与之配套的需要switch与之搭配等,主函数的框架就是这么简单。
(二)封装的游戏函数框架:
(1)棋盘的构建:
为了让游戏可视化,我们需要创建一个棋盘并将其打印出来,我预想并最终设计的棋盘如图:
如果想以二维数组来实现该棋盘,很明显他的组成为:
第一行:三组“空格+数据+空格+|”,最后一个“|”不打印,我们把“空格+数据+空格”看为一个整体,把“|”看成一个整体,就得到第一行的初步逻辑。
第二行:三组“-+-+-+|”,同样的最后一个“|”不打印,同理,我们把“-+-+-”看为一个整体,把“|”看成一个整体。
那么按照上面分组的思路,我们可以把第一行与第二行看成一个整体,实际上就是打印三组由第一行与第二行构成的整体,并将第三组的第二行省略。
这就构成了整个棋盘构建的思路。
(2)玩家下棋:
我们把玩家落子规定为“*”,那么很明显需要用户输入坐标,之后我们需要按照用户给的坐标,将对应坐标的数据由“空格”改为“*”。
需要注意的是,我们需要判断用户输入的坐标是否合法,并且对应坐标的位置上有无棋子。
(3)电脑下棋:
我们把电脑落子规定为“#”,可以利用rand()函数,以时间戳生成随机数,并将其坐标%行(列)的方式来得到随机坐标,同理,和用户一样,我们需要判断对应坐标的位置上有无棋子。
(4)判断输赢:
那么如何来判断输赢呢?
输赢:很明显,如果相同的棋子以行,列,或者对角线的方式连成一线,那么就判定一方胜利。
平局:棋盘满。
游戏继续:如果未满足以上条件,我们需要让游戏继续。
这里很巧妙的一点是:我在设计函数的时候将判断输赢的函数设计返回值为char,如果玩家赢返回“*”,电脑赢返回“#”,所以判断胜利时,我们只需要返回board[x][y](此为连成线的其中一个元素),就知道了到底是玩家胜利还是电脑胜利了。平局返回“Q”,游戏继续返回“C”,那么对应的将game()函数中加入这一判断条件即可。
五、TIPS
个人认为,这个游戏的代码实现对于像我这样的初学者还是非常重要的,尤其是在写的过程中,从无到有,一步步构建框架,理清思路,如果能够完完整整的从头敲下来,我想对于代码能力的提升还是非常有帮助的,所以如果读者是初学者,真心希望你可以找一个没课的时间,静下心将思路滤清,逐步调试,一步一个脚印,相信你会收获良多???