#ifndef _MINE_MINE_H #define _MINE_MINE_H _MINE_MINE_H #include #include #include class Position { public: int x, y; inline Position(int x, int y) : x(x), y(y) { } inline Position() : x(-1), y(-1) { } inline bool operator==(const Position &other) { return x == other.x && y == other.y; } inline void set(int x, int y) { this->x = x; this->y = y; } inline Position left(int n = 1) const { return Position(x-n, y); } inline Position right(int n = 1) const { return Position(x+n, y); } inline Position top(int n = 1) const { return Position(x, y+n); } inline Position bottom(int n = 1) const { return Position(x, y-n); } inline Position topleft() const { return Position(x-1, y+1); } inline Position topright() const { return Position(x+1, y+1); } inline Position bottomleft() const { return Position(x-1, y-1); } inline Position bottomright() const { return Position(x+1, y-1); } inline bool valid() const { return x >= 0 && y >= 0; } }; class Mine { public: enum Cell { Wall=0, Robot, Rock, Lambda, Lift, Earth, Space }; enum Move { Left=0, Right, Up, Down, Wait, Abort }; enum State { Alive=0, Won, Lost, Aborted }; Mine(const std::vector& data); Mine(const Mine& other); Mine& operator=(const Mine& other); ~Mine(); inline int width() const { return m_width; } inline int height() const { return m_height; } inline Cell at(int x, int y) const { if (x < 0 || y < 0 || x >= m_width || y >= m_height) return Wall; return (Cell)m_cells[y*m_width+x]; } inline Cell at(const Position &pos) const { return at(pos.x, pos.y); } inline Cell operator()(int x, int y) const { return at(x, y); } inline Cell operator()(const Position &pos) const { return at(pos.x, pos.y); } inline const Position& robot() const { return m_robot; } inline const std::vector& lifts() const { return m_lifts; } inline bool isLiftOpen() const { return m_lambdas.size() == 0; } inline const std::vector& lambdas() const { return m_lambdas; } int score() const { switch (m_state) { case Lost: return 25*m_nLambdas - m_nMoves; case Won: return 75*m_nLambdas - m_nMoves; case Alive: case Aborted: return 50*m_nLambdas - m_nMoves; } return 0; } inline int foundLambdas() const { return m_nLambdas; } inline int moves() const { return m_nMoves; } inline State state() const { return m_state; } void move(Move m); void show(std::ostream &o); private: // no bound checks, writes must be valid. inline void set(int x, int y, Cell c) { m_cells[y*m_width+x] = c; } inline void set(Position pos, Cell c) { set(pos.x, pos.y, c); } typedef unsigned char iCell; iCell *m_cells; bool *m_newRocks; // tmp row in map update int m_width, m_height; Position m_robot; std::vector m_lifts, m_lambdas; int m_nLambdas, m_nMoves; State m_state; }; #endif