1
0
mirror of https://github.com/vcmi/vcmi.git synced 2024-11-28 08:48:48 +02:00

Introduced 3-value logic for free, blocked and possibly occupied tiles. Refactoring.

This commit is contained in:
DjWarmonger 2014-05-30 16:50:06 +02:00
parent 8ea175ce95
commit 8c24ea0bfb
7 changed files with 163 additions and 79 deletions

View File

@ -21,9 +21,6 @@
#include "../../lib/NetPacks.h"
#include "../../lib/CondSh.h"
static const int3 dirs[] = { int3(0,1,0),int3(0,-1,0),int3(-1,0,0),int3(+1,0,0),
int3(1,1,0),int3(-1,1,0),int3(1,-1,0),int3(-1,-1,0) };
struct QuestInfo;
/*

View File

@ -450,6 +450,17 @@ namespace EWallState
};
}
namespace ETileType
{
enum ETileType
{
FREE,
POSSIBLE,
BLOCKED,
USED
};
}
class Obj
{
public:

View File

@ -152,4 +152,7 @@ struct ShashInt3
vstd::hash_combine(ret, pos.z);
return ret;
}
};
};
static const int3 dirs[] = { int3(0,1,0),int3(0,-1,0),int3(-1,0,0),int3(+1,0,0),
int3(1,1,0),int3(-1,1,0),int3(1,-1,0),int3(-1,-1,0) };

View File

@ -16,12 +16,12 @@
void CMapGenerator::foreach_neighbour(const int3 &pos, std::function<void(const int3& pos)> foo)
{
//for(const int3 &dir : dirs)
//{
// const int3 n = pos + dir;
// if(map->isInTheMap(n))
// foo(pos+dir);
//}
for(const int3 &dir : dirs)
{
const int3 n = pos + dir;
if(map->isInTheMap(n))
foo(pos+dir);
}
}
@ -31,9 +31,40 @@ CMapGenerator::CMapGenerator(shared_ptr<CMapGenOptions> mapGenOptions, int rando
rand.setSeed(randomSeed);
}
void CMapGenerator::initTiles()
{
map->initTerrain();
int width = map->width;
int height = map->height;
int level = map->twoLevel ? 2 : 1;
tiles = new CTileInfo**[width];
for (int i = 0; i < width; ++i)
{
tiles[i] = new CTileInfo*[height];
for (int j = 0; j < height; ++j)
{
tiles[i][j] = new CTileInfo[level];
}
}
}
CMapGenerator::~CMapGenerator()
{
//FIXME: what if map is not present anymore?
if (tiles && map)
{
for (int i=0; i < map->width; i++)
{
for(int j=0; j < map->height; j++)
{
delete [] tiles[i][j];
}
delete [] tiles[i];
}
delete [] tiles;
}
}
std::unique_ptr<CMap> CMapGenerator::generate()
@ -46,6 +77,7 @@ std::unique_ptr<CMap> CMapGenerator::generate()
{
editManager->getUndoManager().setUndoRedoLimit(0);
addHeaderInfo();
initTiles();
genZones();
map->calculateGuardingGreaturePositions(); //clear map so that all tiles are unguarded
@ -146,7 +178,6 @@ void CMapGenerator::addPlayerInfo()
void CMapGenerator::genZones()
{
map->initTerrain();
editManager->clearTerrain(&rand);
editManager->getTerrainSelection().selectRange(MapRect(int3(0, 0, 0), mapGenOptions->getWidth(), mapGenOptions->getHeight()));
editManager->drawTerrain(ETerrainType::GRASS, &rand);
@ -217,3 +248,39 @@ std::map<TRmgTemplateZoneId, CRmgTemplateZone*> CMapGenerator::getZones() const
{
return zones;
}
bool CMapGenerator::isBlocked(int3 &tile) const
{
if (!map->isInTheMap(tile))
throw rmgException(boost::to_string(boost::format("Tile %s is outside the map") % tile));
return tiles[tile.x][tile.y][tile.z].isBlocked();
}
bool CMapGenerator::shouldBeBlocked(int3 &tile) const
{
if (!map->isInTheMap(tile))
throw rmgException(boost::to_string(boost::format("Tile %s is outside the map") % tile));
return tiles[tile.x][tile.y][tile.z].shouldBeBlocked();
}
bool CMapGenerator::isPossible(int3 &tile) const
{
if (!map->isInTheMap(tile))
throw rmgException(boost::to_string(boost::format("Tile %s is outside the map") % tile));
return tiles[tile.x][tile.y][tile.z].isPossible();
}
bool CMapGenerator::isFree(int3 &tile) const
{
if (!map->isInTheMap(tile))
throw rmgException(boost::to_string(boost::format("Tile %s is outside the map") % tile));
return tiles[tile.x][tile.y][tile.z].isFree();
}
void CMapGenerator::setOccupied(int3 &tile, ETileType::ETileType state)
{
if (!map->isInTheMap(tile))
throw rmgException(boost::to_string(boost::format("Tile %s is outside the map") % tile));
tiles[tile.x][tile.y][tile.z].setOccupied(state);
}

View File

@ -14,6 +14,7 @@
#include "../GameConstants.h"
#include "../CRandomGenerator.h"
#include "CMapGenOptions.h"
#include "CRmgTemplateZone.h"
#include "../CObjectHandler.h"
#include "../int3.h"
@ -24,14 +25,11 @@ class CMapGenOptions;
class CTerrainViewPatternConfig;
class CMapEditManager;
class JsonNode;
class CMapGenerator;
class CTileInfo;
typedef std::vector<JsonNode> JsonVector;
class CMapGenerator;
//static const int3 dirs[] = { int3(0,1,0),int3(0,-1,0),int3(-1,0,0),int3(+1,0,0),
// int3(1,1,0),int3(-1,1,0),int3(1,-1,0),int3(-1,-1,0) };
class rmgException : std::exception
{
std::string msg;
@ -68,19 +66,23 @@ public:
std::map<TRmgTemplateZoneId, CRmgTemplateZone*> getZones() const;
void foreach_neighbour(const int3 &pos, std::function<void(const int3& pos)> foo);
bool isBlocked(int3 &tile) const;
bool shouldBeBlocked(int3 &tile) const;
bool isPossible(int3 &tile) const;
bool isFree(int3 &tile) const;
void setOccupied(int3 &tile, ETileType::ETileType state);
private:
std::map<TRmgTemplateZoneId, CRmgTemplateZone*> zones;
CTileInfo*** tiles;
/// Generation methods
std::string getMapDescription() const;
void addPlayerInfo();
void addHeaderInfo();
void initTiles();
void genZones();
void fillZones();
};
/* ---------------------------------------------------------------------------- */
/* Implementation/Detail classes, Private API */
/* ---------------------------------------------------------------------------- */
};

View File

@ -73,47 +73,47 @@ void CRmgTemplateZone::CTownInfo::setCastleDensity(int value)
castleDensity = value;
}
CRmgTemplateZone::CTileInfo::CTileInfo():nearestObjectDistance(INT_MAX), obstacle(false), occupied(false), terrain(ETerrainType::WRONG)
CTileInfo::CTileInfo():nearestObjectDistance(INT_MAX), terrain(ETerrainType::WRONG)
{
occupied = ETileType::POSSIBLE; //all tiles are initially possible to place objects or passages
}
int CRmgTemplateZone::CTileInfo::getNearestObjectDistance() const
int CTileInfo::getNearestObjectDistance() const
{
return nearestObjectDistance;
}
void CRmgTemplateZone::CTileInfo::setNearestObjectDistance(int value)
void CTileInfo::setNearestObjectDistance(int value)
{
nearestObjectDistance = std::max(0, value); //never negative (or unitialized)
}
bool CRmgTemplateZone::CTileInfo::isObstacle() const
bool CTileInfo::shouldBeBlocked() const
{
return obstacle;
return occupied == ETileType::BLOCKED;
}
void CRmgTemplateZone::CTileInfo::setObstacle(bool value)
bool CTileInfo::isBlocked() const
{
obstacle = value;
return occupied == ETileType::BLOCKED || occupied == ETileType::USED;
}
bool CRmgTemplateZone::CTileInfo::isOccupied() const
bool CTileInfo::isPossible() const
{
return occupied;
return occupied == ETileType::POSSIBLE;
}
void CRmgTemplateZone::CTileInfo::setOccupied(bool value)
bool CTileInfo::isFree() const
{
return occupied == ETileType::FREE;
}
void CTileInfo::setOccupied(ETileType::ETileType value)
{
occupied = value;
}
ETerrainType CRmgTemplateZone::CTileInfo::getTerrainType() const
ETerrainType CTileInfo::getTerrainType() const
{
return terrain;
}
void CRmgTemplateZone::CTileInfo::setTerrainType(ETerrainType value)
void CTileInfo::setTerrainType(ETerrainType value)
{
terrain = value;
}
@ -285,7 +285,7 @@ float3 CRmgTemplateZone::getCenter() const
{
return center;
}
void CRmgTemplateZone::setCenter(float3 f)
void CRmgTemplateZone::setCenter(const float3 &f)
{
//limit boundaries to (0,1) square
center = float3 (std::min(std::max(f.x, 0.f), 1.f), std::min(std::max(f.y, 0.f), 1.f), f.z);
@ -302,7 +302,7 @@ void CRmgTemplateZone::setShape(std::vector<int3> shape)
this->shape = shape;
}
int3 CRmgTemplateZone::getPos()
int3 CRmgTemplateZone::getPos() const
{
return pos;
}
@ -441,7 +441,7 @@ bool CRmgTemplateZone::fill(CMapGenerator* gen)
sel.clearSelection();
for(auto it = tileinfo.begin(); it != tileinfo.end(); ++it)
{
if (it->second.isObstacle())
if (it->second.shouldBeBlocked()) //fill tiles that should be blocked with obstacles
{
auto obj = new CGObjectInstance();
obj->ID = static_cast<Obj>(130);
@ -473,7 +473,7 @@ bool CRmgTemplateZone::findPlaceForObject(CMapGenerator* gen, CGObjectInstance*
//avoid borders
if ((p.x < 3) || (w - p.x < 3) || (p.y < 3) || (h - p.y < 3))
continue;
if (!ti.isOccupied() && !ti.isObstacle() && (dist >= min_dist) && (dist > best_distance))
if (!ti.isBlocked() && (dist >= min_dist) && (dist > best_distance))
{
best_distance = dist;
pos = p;
@ -521,7 +521,7 @@ void CRmgTemplateZone::placeObject(CMapGenerator* gen, CGObjectInstance* object,
{
if (tileinfo.find(pos + p) != tileinfo.end())
{
tileinfo[pos + p].setOccupied(true);
tileinfo[pos + p].setOccupied(ETileType::USED);
}
}
for(auto it = tileinfo.begin(); it != tileinfo.end(); ++it)
@ -547,10 +547,10 @@ bool CRmgTemplateZone::guardObject(CMapGenerator* gen, CGObjectInstance* object,
if (it->first != visitable)
{
logGlobal->traceStream() << boost::format("Block at %d %d") % it->first.x % it->first.y;
if (!it->second.isOccupied() && !it->second.isObstacle())
if (it->second.isPossible())
{
tiles.push_back(it->first);
it->second.setObstacle(true);
it->second.setOccupied(ETileType::BLOCKED);
}
}
}
@ -562,7 +562,7 @@ bool CRmgTemplateZone::guardObject(CMapGenerator* gen, CGObjectInstance* object,
return false;
}
auto guard_tile = *RandomGeneratorUtil::nextItem(tiles, gen->rand);
tileinfo[guard_tile].setObstacle(false);
tileinfo[guard_tile].setOccupied(ETileType::USED);
auto guard = new CGCreature();
guard->ID = Obj::RANDOM_MONSTER;
guard->subID = 0;

View File

@ -14,19 +14,44 @@
#include "../GameConstants.h"
#include "CMapGenerator.h"
#include "float3.h"
#include "../int3.h"
class CMapgenerator;
class CMapGenerator;
class CTileInfo;
class int3;
class CGObjectInstance;
namespace ETemplateZoneType
{
enum ETemplateZoneType
{
PLAYER_START,
CPU_START,
TREASURE,
JUNCTION
};
enum ETemplateZoneType
{
PLAYER_START,
CPU_START,
TREASURE,
JUNCTION
};
}
class DLL_LINKAGE CTileInfo
{
public:
CTileInfo();
int getNearestObjectDistance() const;
void setNearestObjectDistance(int value);
bool isBlocked() const;
bool shouldBeBlocked() const;
bool isPossible() const;
bool isFree() const;
void setOccupied(ETileType::ETileType value);
ETerrainType getTerrainType() const;
void setTerrainType(ETerrainType value);
private:
int nearestObjectDistance;
ETileType::ETileType occupied;
ETerrainType terrain;
};
/// The CRmgTemplateZone describes a zone in a template.
class DLL_LINKAGE CRmgTemplateZone
@ -49,27 +74,6 @@ public:
private:
int townCount, castleCount, townDensity, castleDensity;
};
class DLL_LINKAGE CTileInfo
{
public:
CTileInfo();
int getNearestObjectDistance() const;
void setNearestObjectDistance(int value);
bool isObstacle() const;
void setObstacle(bool value);
bool isOccupied() const;
void setOccupied(bool value);
ETerrainType getTerrainType() const;
void setTerrainType(ETerrainType value);
private:
int nearestObjectDistance;
bool obstacle;
bool occupied;
ETerrainType terrain;
};
CRmgTemplateZone();
@ -101,8 +105,8 @@ public:
void setTownTypeLikeZone(boost::optional<TRmgTemplateZoneId> value);
float3 getCenter() const;
void setCenter(float3 f);
int3 getPos();
void setCenter(const float3 &f);
int3 getPos() const;
void setPos(const int3 &pos);
void addTile (const int3 &pos);