Last active
August 29, 2015 14:06
-
-
Save mstum/f12b96bce8311d2f0883 to your computer and use it in GitHub Desktop.
CodeReview #62254 - Static Factory function and Lifetime questions
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include "Level.h" | |
#include <fstream> | |
#include <sstream> | |
std::string Level::GetName(){ | |
// Should this return a Pointer? | |
return _name; | |
} | |
int Level::GetPlayerStartX() { | |
return _playerStartX; | |
} | |
int Level::GetPlayerStartY() { | |
return _playerStartY; | |
} | |
Tile* Level::GetTiles() { | |
return _tiles; | |
} | |
int GetArrayIndex(int line, int column){ | |
return (line * Level::MaxCols) + column; | |
} | |
Level* Level::LoadFromFile(std::string fileName){ | |
std::string line; | |
std::ifstream file (fileName.c_str()); | |
// This news up a level and works with it as a pointer | |
// Do callers need to call delete on it? How would they know? | |
Level* level = new Level(); | |
int numBoxes = 0; | |
int numTargets = 0; | |
bool playerStart = false; | |
int y = -1; | |
while (getline(file, line)) { | |
if(y == -1){ | |
level->_name = line; | |
} | |
else if (y >= Level::MaxRows) { | |
// Is there a better way? Like C#'s string.Format() | |
std::ostringstream exceptionMessage; | |
exceptionMessage << "There are more than " << Level::MaxRows << " rows in the level."; | |
// I'm calling .str().c_str() - is that a possible leak? | |
throw std::exception(exceptionMessage.str().c_str()); | |
} | |
else { | |
int lineLength = line.length(); | |
if(lineLength> Level::MaxCols){ | |
std::ostringstream exceptionMessage; | |
exceptionMessage << "There are more than " << Level::MaxCols << " tiles in a column."; | |
throw std::exception(exceptionMessage.str().c_str()); | |
} | |
for (int x=0; x < Level::MaxCols; x++) | |
{ | |
int ix = GetArrayIndex(y, x); | |
char c = ' '; | |
if(x < lineLength) { | |
c = line[x]; | |
} | |
switch(c) { | |
case Level::FreeChar: | |
level->_tiles[ix] = TILE_FREE; | |
break; | |
case Level::BoxChar: | |
numBoxes++; | |
level->_tiles[ix] = TILE_BOX; | |
break; | |
case Level::BoxOnTargetChar: | |
numBoxes++; | |
numTargets++; | |
level->_tiles[ix] = TILE_BOXONTARGET; | |
break; | |
case Level::TargetChar: | |
numTargets++; | |
level->_tiles[ix] = TILE_TARGET; | |
break; | |
case Level::WallChar: | |
level->_tiles[ix] = TILE_WALL; | |
break; | |
case Level::StartChar: | |
if(playerStart) { | |
throw std::exception("There is more than 1 player start in the level."); | |
} | |
playerStart = true; | |
level->_playerStartX = x; | |
level->_playerStartY = y; | |
level->_tiles[ix] = TILE_FREE; | |
break; | |
default: | |
throw std::exception("Invalid Character in Level: " + c); | |
} | |
} | |
} | |
y++; | |
} | |
// Fill up any missing Rows | |
for(;y < Level::MaxRows; y++){ | |
for(int x = 0; x < Level::MaxCols; x++){ | |
int ix = GetArrayIndex(y, x); | |
level->_tiles[ix] = TILE_FREE; | |
} | |
} | |
if(numBoxes != numTargets) | |
{ | |
std::ostringstream exceptionMessage; | |
exceptionMessage << "There are " << numBoxes << ", but " << numTargets << " in the level."; | |
throw std::exception(exceptionMessage.str().c_str()); | |
} | |
return level; | |
} | |
Level::Level() { | |
_playerStartX = _playerStartY = 0; | |
_tiles = new Tile[TileCount]; | |
} | |
Level::~Level(){ | |
if(_tiles) { | |
// Since _tiles is an array, I need delete[] instead of delete? | |
delete[] _tiles; | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <iostream> | |
#include "Tile.h" | |
class Level | |
{ | |
public: | |
std::string GetName(); | |
int GetPlayerStartX(); | |
int GetPlayerStartY(); | |
Tile* GetTiles(); | |
// Static Factory Function - only way to instantiate | |
static Level* LoadFromFile(std::string fileName); | |
// Static Consts for external callers to know constraints | |
static const int MaxCols = 30; | |
static const int MaxRows = 20; | |
static const int TileCount = MaxCols * MaxRows; | |
~Level(); | |
private: | |
// Private ctor to prevent instantiation | |
Level(); | |
// An Array of TileCount tiles | |
Tile* _tiles; | |
int _playerStartX, _playerStartY; | |
std::string _name; | |
// Used by LoadFromFile - could possibly moved into that function? | |
static const char FreeChar = ' '; | |
static const char BoxChar = '+'; | |
static const char BoxOnTargetChar = '*'; | |
static const char TargetChar = '.'; | |
static const char WallChar = '='; | |
static const char StartChar = 'x'; | |
}; |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Do I need to prevent multiple inclusion? In what situations? | |
#ifndef TILE | |
#define TILE | |
enum Tile { TILE_UNKNOWN, TILE_FREE, TILE_BOX, TILE_TARGET, TILE_WALL, TILE_BOXONTARGET }; | |
#endif |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment