108 lines
2.8 KiB
C++
108 lines
2.8 KiB
C++
#ifndef _MINE_MINE_H
|
|
#define _MINE_MINE_H _MINE_MINE_H
|
|
|
|
#include <vector>
|
|
#include <list>
|
|
#include <ostream>
|
|
|
|
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<unsigned char>& 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<Position>& lifts() const { return m_lifts; }
|
|
inline bool isLiftOpen() const { return m_lambdas.size() == 0; }
|
|
inline const std::vector<Position>& 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<Position> m_lifts, m_lambdas;
|
|
|
|
int m_nLambdas, m_nMoves;
|
|
State m_state;
|
|
};
|
|
|
|
#endif
|