#ifndef GAMESTATE_HH
#define GAMESTATE_HH
#include "Dimension.hh"
#include <list>
#include <stdexcept>
enum PlayerType {
PLAYER_LOCAL,
PLAYER_REMOTE
};
#define PLAYER_DIM_W 10
#define PLAYER_DIM_H 10
#define MAP_DIM_W 800
#define MAP_DIM_H 640
class Player {
protected:
Coordinate position;
public:
Player(Coordinate c, bool visible) : position(c), dimensions(PLAYER_DIM_W, PLAYER_DIM_H), visible(visible) {}
PlayerType type;
Dimension dimensions;
bool visible;
Coordinate getPosition (void) const {
return position;
}
protected:
/*
* Update position to the given value.
*
* Returns true if valid move (not out of bounds), false otherwise (doesn't change position)
*/
bool updatePosition (Coordinate p) {
// unsigned...
if (p.x > dimensions.w || p.y > dimensions.h) {
// out-of-bounds
return false;
}
// valid
position = p;
return true;
}
};
class LocalPlayer : public Player {
protected:
LocalPlayer (Coordinate c, bool visible) : Player(c, visible) { }
public:
virtual bool move (PositionDelta d) {
return true;
//return updatePosition(position + d);
}
};
class RemotePlayer : public Player {
protected:
RemotePlayer (Coordinate c, bool visible) : Player(c, visible) { }
};
class GameState {
public:
Dimension map_dimensions;
std::list<Player*> player_list;
// only one local player is supported
LocalPlayer *local_player;
GameState (void) : map_dimensions(MAP_DIM_W, MAP_DIM_H), local_player(NULL) {
}
/*
* This will return NULL if we don't have a local player - yet
*/
LocalPlayer *getLocalPlayer (void) {
return local_player;
}
void newLocalPlayer (LocalPlayer *player) {
if (local_player)
throw std::logic_error("newLocalPlayer called even though we already have a local player");
player_list.push_back(player);
local_player = player;
}
void newRemotePlayer (RemotePlayer *player) {
player_list.push_back(player);
}
void removePlayer (Player *player) {
player_list.remove(player);
}
};
#endif