icfp15/mine.h

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