• 兰顿蚂蚁-零玩家的游戏


    在平面上的正方形格被填上黑色或白色。在其中一格正方形有一只“蚂蚁”,它的头部朝向上下左右其中一方。
    若蚂蚁在白格,右转90度,将该格改为黑格,向前移一步;
    若蚂蚁在黑格,左转90度,将该格改为白格,向前移一步。

    使用EasyX图形库实现图形的绘制。

    执行效果如下:

    兰顿蚂蚁

    源码如下:

    /******************************
     * 兰顿蚂蚁
     * 编译环境:VC++ 2017
     * 作者:that boy,2018/12/19
     * 最后修改:2018/12/21
     ******************************/
    
    #include <EasyX.h>
    #include <string>
    #include <conio.h>
    
    
    namespace LangtonAnt
    {
    	// 方向
    	struct Direct
    	{
    		int dx;
    		int dy;
    		Direct&TurnLeft();
    		Direct&TurnRight();
    	};
    
    	Direct	LEFT{ -1,0 },
    			RIGHT{ 1,0 },
    			UP{ 0,-1 },
    			DOWN{ 0,1 };
    
    	IMAGE	BlockMap;		// 地图图像
    	int		BlockSize;		// 方块大小
    	bool*	Map = nullptr;	// 地图(逻辑)
    	// 地图大小(逻辑)
    	int		MapWidth;
    	int		MapHeight;
    	// 当前方向
    	Direct	CurrentDirect;
    	// 当前位置
    	int		CurrentX;
    	int		CurrentY;
    	// 是否超出边界(开始有规律)
    	bool	OutMap = false;
    
    	void Init(int, int, int, int, int, Direct = UP);	// 初始化
    	const IMAGE& Update();								// 更新逻辑图像
    	void Quit();										// 结束,回收内存
    }
    
    
    // 主函数
    int main()
    {
    	LangtonAnt::Init(10, 80, 60, 40, 30);	// 设置方块大小 10,地图大小 80*60,起点(40,30)
    
    	initgraph(800, 600);
    
    	// 设置字体
    	setbkcolor(WHITE);
    	settextcolor(BLACK);
    	settextstyle(20, 0, L"Arial");
    
    	BeginBatchDraw();
    
    	for (long int step = 0; !LangtonAnt::OutMap; ++step)
    	{
    		putimage(0, 0, &LangtonAnt::Update());
    		outtextxy(0, 0, (std::to_wstring(step) + L" steps").c_str());
    		FlushBatchDraw();
    		Sleep(1);
    	}
    	LangtonAnt::Quit();
    
    	// 居中显示结束语
    	outtextxy(400 - textwidth(L"Langton's Ant is running in a loop.") / 2, 300 - textheight('L') / 2, L"Langton's Ant is running in a loop.");
    
    	EndBatchDraw();
    	_getch();
    	closegraph();
    
    	return 0;
    }
    
    
    // 初始化兰顿蚂蚁
    void LangtonAnt::Init(int Blocksize, int MapW, int MapH, int StartX, int StartY, Direct StartDirect)
    {
    	// 设置数据
    	MapWidth = MapW;
    	MapHeight = MapH;
    	CurrentX = StartX;
    	CurrentY = StartY;
    	CurrentDirect = StartDirect;
    	OutMap = false;
    
    	if (Map != nullptr)
    		delete[]Map;
    
    	Map = new bool[MapWidth*MapHeight]();
    
    	BlockSize = Blocksize;
    	BlockMap.Resize(MapWidth*BlockSize, MapHeight*BlockSize);
    
    	// 填充地图图像
    	SetWorkingImage(&BlockMap);
    	setbkcolor(WHITE);
    	cleardevice();
    	SetWorkingImage();
    }
    
    
    // 更新逻辑和图像
    const IMAGE & LangtonAnt::Update()
    {
    	// 处理边界
    	if (CurrentX < 0 || CurrentX >= MapWidth || CurrentY < 0 || CurrentY >= MapHeight)
    	{
    		OutMap = true;
    		return BlockMap;
    	}
    
    	if (Map[CurrentX + CurrentY * MapWidth])	// 黑色
    	{
    		CurrentDirect.TurnLeft();	// 左转
    	}
    	else
    	{
    		CurrentDirect.TurnRight();	// 右转
    	}
    
    	// 绘制图像
    	SetWorkingImage(&BlockMap);
    
    	// 转向
    	Map[CurrentX + CurrentY * MapWidth] = !Map[CurrentX + CurrentY * MapWidth];
    
    	// 重绘底部
    	setfillcolor(Map[CurrentX + CurrentY * MapWidth] ? BLACK : WHITE);
    	solidrectangle(CurrentX*BlockSize, CurrentY*BlockSize, (CurrentX + 1)*BlockSize - 1, (CurrentY + 1)*BlockSize - 1);
    
    	// 移动
    	CurrentX += CurrentDirect.dx;
    	CurrentY += CurrentDirect.dy;
    
    	// 绘制蚂蚁
    	setfillcolor(RED);
    	solidcircle(CurrentX*BlockSize + BlockSize / 2, CurrentY*BlockSize + BlockSize / 2, BlockSize / 3);
    
    	SetWorkingImage();
    	return BlockMap;
    }
    
    
    // 退出兰顿蚂蚁
    void LangtonAnt::Quit()
    {
    	delete[]Map;
    	Map = nullptr;
    }
    
    
    // 左转
    LangtonAnt::Direct & LangtonAnt::Direct::TurnLeft()
    {
    	if (dx < 0 && dy == 0)			// 左
    		*this = DOWN;
    	else if (dx == 0 && dy < 0)		// 上
    		*this = LEFT;
    	else if (dx > 0  && dy == 0)	// 右
    		*this = UP;
    	else if (dx == 0 && dy > 0)		// 下
    		*this = RIGHT;
    	return *this;
    }
    
    
    // 右转
    LangtonAnt::Direct & LangtonAnt::Direct::TurnRight()
    {
    	if (dx < 0 && dy == 0)			// 左
    		*this = UP;
    	else if (dx == 0 && dy < 0)		// 上
    		*this = RIGHT;
    	else if (dx > 0  && dy == 0)	// 右
    		*this = DOWN;
    	else if (dx == 0 && dy > 0)		// 下
    		*this = LEFT;
    	return *this;
    }
    
  • 相关阅读:
    js浅拷贝和深拷贝
    使用slice和concat对数组的深拷贝和浅拷贝
    JS数组常用方法---8、concat方法
    JS数组常用方法---7、join方法
    js中将类数组转换为数组的几种方法
    JS 使用const声明常量的本质(很多人都有误解)
    JS中对象数组按照对象的某个属性进行排序
    vue源码分析参考---2、数据代理
    vue源码分析参考---1、准备工作
    ES6课程---5、形参默认值
  • 原文地址:https://www.cnblogs.com/that-boy/p/12310305.html
Copyright © 2020-2023  润新知