参考了“崩坏3”,我用C语言写出了一个游戏(TDD测试驱动开发思想与艺术)

【摘要】 TDD测试驱动开发 测试驱动开发,英文全称Test-Driven Development,简称TDD,是一种不同于传统软件开发流程的新型的开发方法。它要求在编写某个功能的代码之前先编写测试代码,然后只编写使测试通过的功能代码,通过测试来推动整个开发的进行。这有助于编写简洁可用和高质量的代码,并加速开发过程。 ————转自搜狗百科
所以我们可以利用这种思路,一步一步地实…

  • TDD测试驱动开发
    测试驱动开发,英文全称Test-Driven Development,简称TDD,是一种不同于传统软件开发流程的新型的开发方法。它要求在编写某个功能的代码之前先编写测试代码,然后只编写使测试通过的功能代码,通过测试来推动整个开发的进行。这有助于编写简洁可用和高质量的代码,并加速开发过程。
    ————转自搜狗百科

所以我们可以利用这种思路,一步一步地实现一个个的小功能,进而逐渐实现一款游戏的开发。

首先我们建立两个源文件,一个名为test.c 主要就是游戏的一个框架,里面是游戏实现的大概逻辑,另外一个名为game.c 主要用来存放封装好的函数,实现一个个小的功能。

再一个是创建一个头文件 game.h, 用来存放各种头文件和函数声明,其它源文件就可以不用再重复写各种头文件的引用了,而是直接在最前面写上include”game.h”就可以使用这个头文件中的东西了。

准备工作完成后,我们来构思一下一个游戏最开始应该是咋样的。一开始应该会出现一个选择菜单,如下图
在这里插入图片描述
会让你选择是开始游戏,还是退出游戏。
所以就需要写一个函数menu(),里面打印图形界面,如下图:
在这里插入图片描述
然后你输入你的选项。
注意:这里的选项设置得非常巧妙,读者需要后期慢慢体会,为什么不能输入其它的数字呢?

进入游戏后,你肯定会看到初始化的界面,如下图:
在这里插入图片描述
依照这样的思路,我们设计出来的游戏也应该一样,如下图:
在这里插入图片描述
所以接下来我们就要按照这种图形设计一个初始化函数InitBoard()和打印函数DispalyBoard(),函数的参数分别为数组首元素地址、横格数以及纵格数,三子棋有九个格子,我们可以用3×3的二维数组来储存棋子,那么分割线便用竖线和横线实现,也就是在初始化数组中某个元素后(将数组元素全部初始化为空格,数组类型为char型),在其后面打印出来的 ‘|’, 但是注意一排中最后一个元素后不打印。横线分隔就是在第一行数组元素打印完了后,直接打印一行由横线和竖线组合成的图形,具体代码实现请读者参考后文提供的源码,此处只是讲解了代码大概思路。

接下来我们就要开始下棋了,输入想要下棋的坐标,然后再棋盘上标记出玩家的棋子‘ * ’,接下是电脑下棋,标记‘ # ’。
当然,玩家不是程序员,输入坐标肯定没有带0的,而数组角标是从0开始的。
程序还需要判断,下棋位置是否已经有棋子了。
电脑下棋的坐标肯定需要借用随机数生成函数,先再main函数中设置一个随机种子数srand((unsighed)time(NULL)),然后再电脑下棋的函数ComputerMove()中获取随机数 rand()%3,这样就可以得到0~3的随机数了。

每一次下棋我们都需要判断一下游戏是否结束,谁赢了?平局?
首先是检验横三行,再是纵三列,最后是两条对角线上的字符是否一致。
再判断棋盘是不是满了(没有空格了),来判断是否平局。

综上所述,总结如下:我们需要写如下五个函数:初始化棋盘函数,打印棋盘函数,玩家下棋函数,电脑下棋函数,最后是判断输赢函数。

源码如下:

//game.h file
#include<stdio.h>
#include<stdlib.h>
#include<time.h>

#define ROW 3 //三行
#define COL 3 //三列 column

//初始化棋盘
void InitBoard(char board[ROW][COL], int row, int col);

//打印棋盘
void DisplayBoard(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);

//test.c file
#include"game.h"
void menu()
{
	printf("*******************************\n");
	printf("******* 1. PLAY *******\n");
	printf("******* 0. EXIT *******\n");
	printf("*******************************\n");
}

void game()
{
	char board[ROW][COL];
	//棋盘初始化
	InitBoard(board, ROW, COL);
	//打印棋盘
	DisplayBoard(board, ROW, COL);
	while (1)
	{
		PlayerMove(board, ROW, COL);//玩家下棋
		DisplayBoard(board, ROW, COL);//下完棋后立刻打印棋盘
		//玩家下完棋后判断玩家是否胜利
		if ('*' == IsWin(board, ROW, COL))//IsWin函数返回值为'#'、'*'、'C'-游戏未完成,继续游戏、'T'-平局
		{ printf("玩家赢了!\n"); break;
		}
		else if ('T' == IsWin(board, ROW, COL))
		{ printf("平局~\n"); break;
		}
		ComputerMove(board, ROW, COL);//电脑下棋
		DisplayBoard(board, ROW, COL);//下完棋后立刻打印棋盘
		//电脑下完棋后判断电脑是否胜利
		if ('#' == IsWin(board, ROW, COL))
		{ printf("您输了\n"); break;
		}
		else if ('T' == IsWin(board, ROW, COL))
		{ printf("平局~\n"); break;
		}
	}
	DisplayBoard(board, ROW, COL);//展示最终的棋盘
}
int main()
{
	int input = 0;
	srand((unsigned int)time(NULL));
	do
	{
		menu();
		printf("请选择>>\n");
		scanf("%d", &input);
		switch (input)
		{
		case 1: printf("开始三子棋游戏\n"); game(); break;
		case 0: printf("退出游戏\n"); break;
		default: printf("输入错误,请重新输入\n"); break;
		}
	} while (input);
	return 0;
}

//game.c file
#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] = ' ';//初始化为空格
		}
	}
}

//打印棋盘
void 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 < col - 1)//实现比字符少一个 { printf("|");//打印字符与字符之间的分隔符 }
		}
		printf("\n");
		//打印行与行之间的分隔符
		if (i < row - 1)//只打印两行
		{ for (j = 0; j < col; j++) { printf("---");//三个 if (j < col - 1) { printf("|");//两个 } }
		}
		printf("\n");
	}
}

//玩家下棋
void PlayerMove(char board[ROW][COL], int row, int col)
{
	int x = 0;
	int y = 0;
	while (1)
	{
		printf("请输入您想要下棋位置的坐标:");
		scanf("%d %d", &x, &y);
		if (x > 0 && x <= col && y > 0 && y <= row)
		{ if (' ' == board[y - 1][x - 1]) { board[y - 1][x - 1] = '*'; break; } else { printf("该位置已经有棋子了!\n"); }
		}
		else
		{ printf("您输入的坐标不正确!\n");
		}
	}	
}

//电脑下棋
void ComputerMove(char board[ROW][COL], int row, int col)
{
	while (1)
	{
		int x = rand() % col;
		int y = rand() % row;
		if (' ' == board[y][x])
		{ board[y][x] = '#'; break;
		}
	}	
}

//判断输赢
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])
		{ return board[i][1];//返回连成三个的字符
		}
	}

	//判断列
	for (i = 0; i < row; i++)
	{
		if (board[0][i] == board[1][i] && board[1][i] == board[2][i])
		{ return board[1][i];//返回连成三个的字符
		}
	}

	//判断斜线
	if (board[0][0] == board[1][1] && board[1][1] == board[2][2])
	{
		return board[1][1];//返回连成三个的字符
	}

	if (board[0][2] == board[1][1] && board[1][1] == board[2][0])
	{
		return board[1][1];//返回连成三个的字符
	}

	//判断平局-以上情况都没发生,而且每个格子都不是空的
	int j = 0;
	for (i = 0; i < row; i++)
	{
		for (j = 0; j < col; j++)
		{ if (board[i][j] == ' ') { return 'C';//游戏继续 }
		}
	}
	return 'T';
}
  
 

代码中有有一些注释解释代码的实现。

文章来源: blog.csdn.net,作者:燕麦冲冲冲,版权归原作者所有,如需转载,请联系作者。

原文链接:blog.csdn.net/weixin_54209978/article/details/116200799

© 版权声明
THE END
喜欢就支持一下吧
点赞0 分享