src/proto2/GameState.hh
author terom
Sun, 09 Nov 2008 22:02:03 +0000
changeset 26 5685602aeb9c
parent 25 af75a1894a32
child 35 e21cfda0edde
child 42 eb1a93a38cde
permissions -rw-r--r--
it works \o/
#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

// forward-declare GameState
class GameState;

class Player {
    protected:
        Coordinate position;

        GameState &state;

    public:

        Player(GameState &state, Coordinate c, bool visible) : position(c), state(state), 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);

};

class LocalPlayer : public Player {
    protected:
        LocalPlayer (GameState &state, Coordinate c, bool visible) : Player(state, c, visible) { }
    
    public:
        virtual bool move (PositionDelta d) {
            return updatePosition(position + d);
        }
};

class RemotePlayer : public Player {
    protected:
        RemotePlayer (GameState &state, Coordinate c, bool visible) : Player(state, 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) {

        }

        /*
         * Check if the given coordinate is valid
         */
        bool isValidCoordinate (const Coordinate &p) {
            // unsigned...
            return !(p.x > map_dimensions.w || p.y > map_dimensions.h);
        }
        
        /*
         * 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