码迷,mamicode.com
首页 > 其他好文 > 详细

兰顿蚂蚁-零玩家的游戏

时间:2020-02-15 00:10:21      阅读:94      评论:0      收藏:0      [点我收藏+]

标签:struct   space   current   blocks   work   white   namespace   lock   oid   

在平面上的正方形格被填上黑色或白色。在其中一格正方形有一只“蚂蚁”,它的头部朝向上下左右其中一方。
若蚂蚁在白格,右转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;
}

兰顿蚂蚁-零玩家的游戏

标签:struct   space   current   blocks   work   white   namespace   lock   oid   

原文地址:https://www.cnblogs.com/that-boy/p/12310305.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!