Proteus 8.1 51单片机仿真双人对战五子棋

硬件需求:
内存需求较大,51单片机无法满足,因此需要扩展内存
Proteus需添加240X320的彩色液晶

实现功能如下:
1、通过按键选择下棋位置
2、无限悔棋
3、重新开始

黑白双方循环落子,黑方先下,通过上下左右四个按键选择落子位置,按下确定按键即可将棋子放置在棋盘上。当有一方连成5子或棋盘落满棋子,游戏结束,判定双方胜负。按下悔棋按键可以悔棋,每按一次可以悔棋一步,可以无限悔棋,按下重新开始按键,游戏重新开始。

仿真效果图如下:
仿真电路图

开机初始化界面

黑棋获胜界面


源码如下:
#include "game.h"
#include "malloc.h"
#include "74HC165.h"

//定义棋盘起始坐标
#define CHESSBOARD_START_X		47
#define CHESSBOARD_START_Y		7
#define CHESSBOARD_END_X		272
#define CHESSBOARD_END_Y		232

//棋盘大小
#define CHESSBOARD_SIZE			(CHESSBOARD_END_X-CHESSBOARD_START_X)
//网格大小
#define CHESSGRID_SIZE			(CHESSBOARD_SIZE / 15)
//棋盘颜色
#define CHESSBOARD_COLOR		BROWN

char (*g_Chess)[15];	//存放棋子缓存
int  g_ChessNum;		//棋子数量
int  g_SameChessNum;	//相连的相同的棋子数

//绘制棋盘
//15x15
static void DrawChessBoard(void)
{
	int i;
	//填充棋盘背景色
	LcdFill(CHESSBOARD_START_X-7, CHESSBOARD_START_Y-7, 
			CHESSBOARD_END_X+7, CHESSBOARD_END_Y+7, CHESSBOARD_COLOR);
	LcdSetColor(BLACK);
	//绘制边框线
	LcdDrawRect(CHESSBOARD_START_X-3, CHESSBOARD_START_Y-3,
			    CHESSBOARD_END_X+3, CHESSBOARD_END_Y+3);
	LcdDrawRect(CHESSBOARD_START_X-4, CHESSBOARD_START_Y-4,
			    CHESSBOARD_END_X+4, CHESSBOARD_END_Y+4);
	LcdDrawRect(CHESSBOARD_START_X, CHESSBOARD_START_Y, 
				CHESSBOARD_END_X, CHESSBOARD_END_Y);
	
	//绘制垂直线
	for (i = 1; i < 15; i++)
	{
		LcdDrawLine(CHESSBOARD_START_X,
					CHESSBOARD_START_Y + (CHESSGRID_SIZE*i),
					CHESSBOARD_END_X,
					CHESSBOARD_START_Y + (CHESSGRID_SIZE*i),
					BLACK);
	}
	
	//绘制水平线
	for (i = 1; i < 15; i++)
	{
		LcdDrawLine(CHESSBOARD_START_X + (CHESSGRID_SIZE*i),
					CHESSBOARD_START_Y,
					CHESSBOARD_START_X + (CHESSGRID_SIZE*i),
					CHESSBOARD_END_Y,
					BLACK);
	}
}

//绘制棋子
//x,y:棋子坐标(0~14)
static void DrawChess(uint8 x, uint8 y)
{
	uint16 ChessColor;
	uint16 xChess;
	uint16 yChess;
	
	if (x>14 || x<0 || y>14 || y<0)return;	//超范围了
	if (g_Chess[x][y]!=0)return;			//已有棋子
	
	//判断棋子颜色
	(g_ChessNum%2==0) ? (ChessColor=BLACK) : (ChessColor=WHITE);
	
	//计算棋子坐标
	xChess = CHESSBOARD_START_X+(CHESSGRID_SIZE/2) + (x*CHESSGRID_SIZE);
	yChess = CHESSBOARD_START_Y+(CHESSGRID_SIZE/2) + (y*CHESSGRID_SIZE);
	
	LcdDrawCircleA(xChess, 
				   yChess, 
				   CHESSGRID_SIZE/2-1, 
				   ChessColor, 
				   1);
	g_ChessNum++;
	g_Chess[x][y] = g_ChessNum;
}

//清除棋子
//x,y:棋子坐标(0~14)
static void ClearChess(uint8 x, uint8 y)
{
	uint16 ChessColor;
	uint16 xChess;
	uint16 yChess;
	
	if (x>14 || x<0 || y>14 || y<0)return;	//超范围了
	if (g_Chess[x][y]!=0)return;			//已有棋子
	
	ChessColor = CHESSBOARD_COLOR;
	
	//计算棋子坐标
	xChess = CHESSBOARD_START_X+(CHESSGRID_SIZE/2) + (x*CHESSGRID_SIZE);
	yChess = CHESSBOARD_START_Y+(CHESSGRID_SIZE/2) + (y*CHESSGRID_SIZE);
	
	LcdDrawCircleA(xChess, 
				   yChess, 
				   CHESSGRID_SIZE/2-1, 
				   ChessColor, 
				   1);
}

//绘制选择框
//x,y:选择框的坐标(0~14)
static void DrawSelectBox(uint8 x, uint8 y)
{
	uint16 xChess,yChess;
	//计算选择框的坐标
	xChess = CHESSBOARD_START_X + (x*CHESSGRID_SIZE);
	yChess = CHESSBOARD_START_Y + (y*CHESSGRID_SIZE);
	
	LcdSetColor(YELLOW);
	
	LcdDrawRect(xChess, 
				yChess, 
				xChess+CHESSGRID_SIZE, 
				yChess+CHESSGRID_SIZE);
}

//清除选择框
//x,y:选择框的坐标(0~14)
static void ClearSelectBox(uint8 x, uint8 y)
{
	uint16 xChess,yChess;
	//计算选择框的坐标
	xChess = CHESSBOARD_START_X + (x*CHESSGRID_SIZE);
	yChess = CHESSBOARD_START_Y + (y*CHESSGRID_SIZE);
	
	LcdSetColor(BLACK);
	LcdDrawRect(xChess, 
				yChess, 
				xChess+CHESSGRID_SIZE, 
				yChess+CHESSGRID_SIZE);
}

//获取相同棋子数
//x,y:棋子坐标(0~14)
//xStep,yStep:x,y坐标移动步数
static int GetChessNum(char ChessType, int x, int y, int xStep, int yStep)
{	
	g_SameChessNum = 0;
	while (1)
	{
		x = x + xStep;
		y = y + yStep;
		
		//判断是否越界
		if (x < 0 || x > 14 || y < 0 || y > 14)
		{
			return g_SameChessNum;
		}
		
		//没有棋子
		if (g_Chess[x][y]==0)
		{
			return g_SameChessNum;
		}
		
		//相同的棋子
		if (g_Chess[x][y] % 2 == ChessType)
		{
			if ((xStep == 1 && yStep == 0) || (xStep == -1 && yStep == 0))
			{
				g_SameChessNum++;
			}
			else if ((xStep == 0 && yStep == 1) || (xStep == 0 && yStep == -1))
			{
				g_SameChessNum++;
			}
			else if ((xStep == 1 && yStep == 1) || (xStep == -1 && yStep == -1))
			{
				g_SameChessNum++;
			}
			else if ((xStep == 1 && yStep == -1) || (xStep == -1 && yStep == 1))
			{
				g_SameChessNum++;
			}
		}
		else
		{
			return g_SameChessNum;
		}
	}
}

//判断是否五子相连
//x,y:棋子坐标(0~14)
static char IsFiveChessContant(int x, int y)
{
	int ChessType = 0;
	int ChessNum = 0;

	ChessType = g_Chess[x][y] % 2;
	
	//横向判断
	ChessNum = GetChessNum(ChessType, x, y, -1, 0) + GetChessNum(ChessType, x, y, 1, 0) + 1;
	
	if (ChessNum >= 5)
	{
		return 1;
	}
	
	//纵向判断
	ChessNum = GetChessNum(ChessType, x, y, 0, 1) + GetChessNum(ChessType, x, y, 0, -1) + 1;
	
	if (ChessNum >= 5)
	{
		return 1;
	}
	
	//斜向判断
	ChessNum = GetChessNum(ChessType, x, y, -1, 1) + GetChessNum(ChessType, x, y, 1, -1) + 1;
	
	if (ChessNum >= 5)
	{
		return 1;
	}
	
	//反斜向判断
	ChessNum = GetChessNum(ChessType, x, y, 1, 1) + GetChessNum(ChessType, x, y, -1, -1) + 1;
	
	if (ChessNum >= 5)
	{
		return 1;
	}
	
	return 0;
}

//游戏结束
//获胜结束
//平局结束
//x,y:棋子坐标(0~14)
static uint8 IsGameOver(uint8 x, uint8 y)
{
	//五子相连
	if (IsFiveChessContant(x, y)) return 2;
	
	//平局结束
	if (g_ChessNum == 225) return 1;
	
	return 0;
}

//悔棋
static void RetractChess(void)
{
	int x, y;
	int xChess, yChess;
	
	//如果没有棋子则退出
	if (g_ChessNum == 0) return;
	
	//查询最后一个棋子并记录
	for (x = 0; x < 15; x++)
	{
		for (y = 0; y < 15; y++)
		{
			if (g_Chess[x][y] == g_ChessNum)
			{
				xChess = x;
				yChess = y;
				break;
			}
		}
	}
	
	//清除最后一个棋子
	g_Chess[xChess][yChess] = 0;
	g_ChessNum -= 1;
	ClearChess(xChess, yChess);
}

//重新开始
static void ResStart(void)
{
	int xChess, yChess;
	
	g_ChessNum = 0;	//棋子数量
	//清空棋子数据
	for (xChess = 0; xChess < 15; xChess++)
	{
		for (yChess = 0; yChess < 15; yChess++)
		{
			g_Chess[xChess][yChess] = 0;
		}
	}
	//绘制棋盘
	DrawChessBoard();
	//选择框位置
	DrawSelectBox(7, 7);
}

//游戏初始化
//初始化全局变量
//初始化棋盘
void GameInit(void)
{
	g_ChessNum = 0;	//棋子数量
	g_Chess = (char (*)[15])mymalloc(SRAMEX, 15);
	LcdClear(BLACK);
	//绘制棋盘
	DrawChessBoard();
	//选择框位置
	DrawSelectBox(7, 7);
}

//开始游戏
void GameStart(void)
{
	static int  xChess = 7;
	static int  yChess = 7;
	uint8 key;
	uint8 State;
	
	//读取按键值
	key = HC165_Read();
	
	switch (key)
	{
		case KEY_UP:
			while(HC165_Read() == KEY_UP);
			ClearSelectBox(xChess, yChess);
			yChess -= 1;
			if (yChess < 0) yChess = 14; 
			DrawSelectBox(xChess, yChess);
			break;
		case KEY_LEFT:
			while(HC165_Read() == KEY_LEFT);
			ClearSelectBox(xChess, yChess);
			xChess -= 1;
			if (xChess < 0) xChess = 14; 
			DrawSelectBox(xChess, yChess);
			break;
		case KEY_RIGHT:
			while(HC165_Read() == KEY_RIGHT);
			ClearSelectBox(xChess, yChess);
			xChess += 1;
			if (xChess >= 15) xChess = 0; 
			DrawSelectBox(xChess, yChess);
			break;
		case KEY_DOWN:
			while(HC165_Read() == KEY_DOWN);
			ClearSelectBox(xChess, yChess);
			yChess += 1;
			if (yChess >= 15) yChess = 0; 
			DrawSelectBox(xChess, yChess);
			break;
		case KEY_OK:	//确定
			while(HC165_Read() == KEY_OK);
			DrawChess(xChess, yChess);
			State = IsGameOver(xChess, yChess);
			while (State)
			{
				LcdSetColor(RED);
				switch (State)
				{
					case 1:
						LcdFill(60, 90, 260, 126, WHITE);
						LcdDispString(100, 100, 320, 16, "Game Over!", 16, 1);
						State = 3;
						break;
					case 2:
						LcdFill(60, 90, 260, 126, WHITE);
						if (g_Chess[xChess][yChess] % 2)
						{
							LcdDispString(80, 100, 320, 16, "Black Chess Victory!", 16, 1);
						}
						else 
						{
							LcdDispString(80, 100, 320, 16, "White Chess Victory!", 16, 1);
						}
						State = 3;
						break;
					default:
						break;
				}
				LcdSetColor(BLACK);
				//重新开始游戏
				if (HC165_Read() == KEY_RESTART)
				{
					while(HC165_Read() == KEY_RESTART);
					ResStart();
					xChess = 7;
					yChess = 7;
					break;
				}
			}
			break;
		case KEY_RESTART:	//重新开始
			while(HC165_Read() == KEY_RESTART);
			ResStart();
			xChess = 7;
			yChess = 7;
			break;
		case KEY_RETRACT:	//悔棋
			while(HC165_Read() == KEY_RETRACT);
			RetractChess();
			break;
		default:
			break;
	}
}


                
proteus8.0破解和安装方法: 1、下载好压缩包解压,运行“Setup.exe“安装程序,沟选“I accept the terms of..“之类的选项框,点“next”弹出如下界面,我们选择第一个“Use a locally installed license key“,意思是说使用本地的受权文件。 2、点“Next”---“Next”两下 3、点“Browse For Key File”,找到解压包的crack目录下的LICENCE.lxk文件,点“Install”按钮后在弹出的提示框点“是”按钮。 4、“点Close”关闭,弹出如下界面,意思是问要不要导入proteus 7的配件文件,我们把三项全部选中。" 5、点“Next”后,再点“Typical“,选择典型安装模式 6、然后按提示操作,点“Next”,直到安装结束。 接下来两步操作很重要,请仔细看。, S3 N6 Q* [0 y. O( ^7 d6 U" { 7、找到解压包的Crack目录下的“bin”文件夹,复制整个文件夹到proteus8.0的安装目录,一般为“C:\Program Files\Labcenter Electronics\Proteus 8 Professional”。- ^2 X; t3 P( ^6 g) P 8、找到解压包的Crack目录下的“MODELS”文件夹,复制整个文件夹到“C:\Documents and Settings\All Users\Application Data\Labcenter Electronics\Proteus 8 Professional”目录(仅针对xp用户),如果是win7用户,将“MODELS”复制到“C:\Users\All Users\Labcenter Electronics\Proteus 8 Professional"目录,“C:\Documents and Settings\All Users\Application Data”一般会隐藏的,如果无法找到,请在工具菜单---文件夹选择--查看---把“显示所有文件和文件夹“选中。 9、破解完成。 附:proteus 8下载地址:http://pan.baidu.com/share/link?shareid=471162&uk=4180363929
相关推荐
php和mysql开发的报刊订阅管理系统 毕业设计整套列表:(80)ASP+ACCESS企业公司网站 ASP.NET+SQL2000销售管理系统 ASP+ACCESS网上考试系统 ASP.NET+ACCESS校友录毕业设计 ASP+ACCESS在线考试系统 ASP.NET+SQL2000校友录 ASP+ACCESS校友录 ASP.NET+SQL2000房地产管理系统 ASP+ACCESS企业网络管理系统 ASP.NET+SQL2000在线考试系统 ASP+ACCESS办公系统 ASP.NET+SQL2000信息安全学习网的设计与开发 ASP+ACCESS我的雅虎设计 ASP.NET+SQL2000点播 ASP+access留言板 ASP.NET+SQL2000网上购物商城 ASP+ACCESS BBS论坛的设计与实现 ASP.NET+SQL2000房地产管理系统 ASP+ACCESS个人网站 ASP.NET+SQL2000在线考试系统(数值分析) ASP+ACCESS图书管理系统 ASP.NET+SQL2000考试系统 ASP+ACCESS网上书店 ASP.NET+SQL2000商城 ASP+ACCESS网络招聘系统 VS2005(VB)家庭理财系统 ASP+ACCESS班级网站设计 ASP.NET+SQL在线视频点播系统 ASP+ACCESS企业网络管理系统 ASP.NET+SQL BBS管理系统 ASP+Access人事(人力资源)管理系统 ASP.NET+SQL2000学生成绩管理系统 asp+access网上购物系统 ASP+SQL客户关系管理系统 ASP+SQL旅游信息管理系统 ASP+SQL汽车销售网站 c#+access ktv点歌系统 网上书店acc全套 C#电子邮件客户端软件 星星在线考试系统 C#+SQL2005教材管理系统 ASP+SQL企业网络管理系统 ASP+ACCESS考试报名信息处理系统 VB.NET酒店管理信息系统 (asp+access)完整购物系统 (ASP+ACCESS)学生管理系统. ASP+ACCESS网上订水系统 ASP+ACCESS自学考试网站 ASP+ACCESS信息查询系统 ASP+ACCESS电子商务网站 ASP+ACCESS新闻发布系统 ASP+ACCESS投票系统 Delphi+access题库系统与试卷生成 jsp+access教学反馈系统 Delphi+sql酒店客房餐饮管理系统开发 JSP+Access论坛 Delphi考勤管理系统 JSP+Access网上拍卖平台系统 Delphi+access学籍管理程序 JSP+SQLServer网络教学管理系统 Delphi+sql试卷生成系统 JSP+SQLServer火车站订票系统 Delphi+access电子试卷生成系统 JSP+ACCESS网络教学系统 Delphi+access《数据库原理与应用》题库系统 JSP+SQLServer网上考试系统的设计与实现 Delphi+ACCESS三层图书管理 JSP+SQLServer网上书店系统 Delphi+access商品销售管理系统 JSP+SQLServer超市管理系统 Delphi+sql试卷生成系统 JSP+SQLServer销售管理系统 Delphi酒店客房餐饮管理系统 JSP+Access网上拍卖平台系统 Delphi+SQL ERP人力管理系统 JSP+SQLServer管理系统设计 Delphi+ACCESS高校科研管理系统 JSP+ACCESS进销管理系统. Delphi+ACCESS易能光盘管理系统 JSP+SQLServer企业产品销售管理系统 Delphi信息管理系统 JSP+SQLServer人事管理全套 Delphi家庭财账管理软件 JSP+SQL网络购物 Delphi加密设计+论文 JSP+SQL自动排课系统 delphi+access超市销售系统 JSP+SQL高校智能排课系统 JSP+Access网上拍卖平台系统2 JSP+SQL利云网上书店的设计与实现 JSP+SQL基于struts网上书店 JSP+ACCESS网上书店系统 PB+SQL医院门诊信息系统 JSP+SQL基于J2EE的网上书店系统 VB+SQL仓库管理 VC+ACCESS 16PF测评系统分析与设计 VB026图书管理系统 VC++ sql班级事务管理系统 VB+ACCESS高校科研管理系统 VC++ sql商品销售管理系统 VB+ACCESS计算机自动出卷系统 VC++ USB通信程序开发 VB+ACCESS酒店收费管理系统 VC+ACCESS 酒店餐饮管理系统 VB+ACCESS企业工资管理系统 VC++ 拳皇连连看 VB
©️2020 CSDN 皮肤主题: 大白 设计师:CSDN官方博客 返回首页