Simplify board code
This commit is contained in:
parent
7faadda5c0
commit
d166f552f4
|
@ -8,6 +8,7 @@
|
||||||
// 4 - superpower
|
// 4 - superpower
|
||||||
// 5 - pen doors
|
// 5 - pen doors
|
||||||
|
|
||||||
|
// clang-format off
|
||||||
std::array<std::array<int, COLUMNS>, ROWS> Board::board = {{
|
std::array<std::array<int, COLUMNS>, ROWS> Board::board = {{
|
||||||
// 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7
|
// 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7
|
||||||
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, // 0
|
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, // 0
|
||||||
|
@ -42,52 +43,35 @@ std::array<std::array<int, COLUMNS>, ROWS> Board::board = {{
|
||||||
{ 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0 }, // 29
|
{ 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0 }, // 29
|
||||||
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, // 30
|
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, // 30
|
||||||
}};
|
}};
|
||||||
|
// clang-format on
|
||||||
|
|
||||||
bool Board::isWalkableForPacMan(Position point, double d, Direction direction) {
|
bool Board::isWalkableForPacMan(GridPosition point) {
|
||||||
return isWalkable(point, d, direction, true);
|
return cellAtPosition(point) != Cell::wall;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Board::isWalkable(Position point) {
|
bool Board::isWalkableForGost(GridPosition point, GridPosition origin, bool isEyes) {
|
||||||
return board[int(point.y)][int(point.x)] != int(Cell::wall);
|
Cell cell = cellAtPosition(point);
|
||||||
|
if (cell == Cell::wall)
|
||||||
|
return false;
|
||||||
|
return isEyes || (isInPen(origin) || !isInPen(point));
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Board::isWalkableForGost(Position point, Position origin, bool isEyes) {
|
bool Board::isInPen(GridPosition point) {
|
||||||
return isWalkable(point) && (isEyes || (isInPen(origin) || !isInPen(point)));
|
return cellAtPosition(point) == Cell::pen;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Board::isInPen(Position point) {
|
Board::Cell Board::cellAtPosition(GridPosition point) {
|
||||||
return board[int(point.y)][int(point.x)] == int(Cell::pen);
|
if (point.x < 0 || point.x >= int(COLUMNS) || point.y < 0 || point.y >= int(ROWS))
|
||||||
}
|
return Cell::wall;
|
||||||
|
return Cell(board[point.y][point.x]);
|
||||||
bool Board::isWalkable(Position point, double position_delta, Direction direction, bool pacman) {
|
|
||||||
if (point.x <= 0 || point.x >= COLUMNS - 1)
|
|
||||||
return true;
|
|
||||||
|
|
||||||
auto cellAtPosition = [&](Position point, double position_delta, Direction direction) {
|
|
||||||
switch (direction) {
|
|
||||||
case Direction::LEFT:
|
|
||||||
return board[int(point.y)][int(point.x - position_delta)];
|
|
||||||
case Direction::RIGHT:
|
|
||||||
return board[int(point.y)][int(point.x) + 1];
|
|
||||||
case Direction::UP:
|
|
||||||
return board[int(point.y - position_delta)][int(point.x)];
|
|
||||||
case Direction::DOWN:
|
|
||||||
return board[int(point.y) + 1][int(point.x)];
|
|
||||||
case Direction::NONE:
|
|
||||||
default:
|
|
||||||
return int(Cell::wall);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
Cell cell = Cell(cellAtPosition(point, position_delta, direction));
|
|
||||||
return pacman ? cell != Cell::wall : cell != Cell::wall && cell != Cell::pen;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<GridPosition> Board::initialPelletPositions() {
|
std::vector<GridPosition> Board::initialPelletPositions() {
|
||||||
std::vector<GridPosition> positions;
|
std::vector<GridPosition> positions;
|
||||||
for (int row = 0; row < ROWS; row++) {
|
for (std::size_t row = 0; row < ROWS; row++) {
|
||||||
for (int column = 0; column < COLUMNS; column++) {
|
for (std::size_t column = 0; column < COLUMNS; column++) {
|
||||||
if (board[row][column] == int(Cell::pellet))
|
if (board[row][column] == int(Cell::pellet))
|
||||||
positions.push_back({ column, row });
|
positions.push_back({ int(column), int(row) });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return positions;
|
return positions;
|
||||||
|
@ -95,10 +79,10 @@ std::vector<GridPosition> Board::initialPelletPositions() {
|
||||||
|
|
||||||
std::vector<GridPosition> Board::initialSuperPelletPositions() {
|
std::vector<GridPosition> Board::initialSuperPelletPositions() {
|
||||||
std::vector<GridPosition> positions;
|
std::vector<GridPosition> positions;
|
||||||
for (int row = 0; row < ROWS; row++) {
|
for (std::size_t row = 0; row < ROWS; row++) {
|
||||||
for (int column = 0; column < COLUMNS; column++) {
|
for (std::size_t column = 0; column < COLUMNS; column++) {
|
||||||
if (board[row][column] == int(Cell::power_pellet))
|
if (board[row][column] == int(Cell::power_pellet))
|
||||||
positions.push_back({ column, row });
|
positions.push_back({ int(column), int(row) });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return positions;
|
return positions;
|
||||||
|
|
|
@ -56,8 +56,8 @@ Position Ghost::position() const {
|
||||||
return pos;
|
return pos;
|
||||||
}
|
}
|
||||||
|
|
||||||
Position Ghost::positionInGrid() const {
|
GridPosition Ghost::positionInGrid() const {
|
||||||
return { std::round(pos.x), std::round(pos.y) };
|
return { int(std::round(pos.x)), int(std::round(pos.y)) };
|
||||||
}
|
}
|
||||||
|
|
||||||
void Ghost::update(std::chrono::milliseconds time_delta, const Board & board) {
|
void Ghost::update(std::chrono::milliseconds time_delta, const Board & board) {
|
||||||
|
@ -119,8 +119,8 @@ void Ghost::updateDirection(const Board & board) {
|
||||||
return;
|
return;
|
||||||
|
|
||||||
struct NewDirection {
|
struct NewDirection {
|
||||||
Direction direction;
|
Direction direction;
|
||||||
Position position;
|
GridPosition position;
|
||||||
double distance;
|
double distance;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -12,8 +12,8 @@ Position PacMan::position() const {
|
||||||
return pos;
|
return pos;
|
||||||
}
|
}
|
||||||
|
|
||||||
Position PacMan::positionInGrid() const {
|
GridPosition PacMan::positionInGrid() const {
|
||||||
return { std::round(pos.x), std::round(pos.y) };
|
return { int(std::round(pos.x)), int(std::round(pos.y)) };
|
||||||
}
|
}
|
||||||
|
|
||||||
void PacMan::eat() {
|
void PacMan::eat() {
|
||||||
|
@ -63,18 +63,33 @@ void PacMan::updateAnimationPosition(std::chrono::milliseconds time_delta, bool
|
||||||
void PacMan::updateMazePosition(std::chrono::milliseconds time_delta, const Board & board) {
|
void PacMan::updateMazePosition(std::chrono::milliseconds time_delta, const Board & board) {
|
||||||
double position_delta = 0.004 * time_delta.count();
|
double position_delta = 0.004 * time_delta.count();
|
||||||
|
|
||||||
|
auto cellAtPosition = [&](Position point, double position_delta, Direction direction) {
|
||||||
|
switch (direction) {
|
||||||
|
case Direction::LEFT:
|
||||||
|
return GridPosition{int(point.x - position_delta), int(point.y)};
|
||||||
|
case Direction::RIGHT:
|
||||||
|
return GridPosition{int(point.x) + 1, int(point.y)};
|
||||||
|
case Direction::UP:
|
||||||
|
return GridPosition{int(point.x), int(point.y - position_delta)};
|
||||||
|
case Direction::DOWN:
|
||||||
|
return GridPosition{int(point.x), int(point.y) + 1};
|
||||||
|
case Direction::NONE:
|
||||||
|
default:
|
||||||
|
return positionInGrid();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
// Handle teleport
|
// Handle teleport
|
||||||
if (pos.x >= COLUMNS - 1 && direction == Direction::RIGHT) {
|
if (pos.x >= COLUMNS - 1 && direction == Direction::RIGHT) {
|
||||||
pos.x = -1;
|
pos.x = -1;
|
||||||
} else if (pos.x <= 0 && direction == Direction::LEFT) {
|
} else if (pos.x <= 0 && direction == Direction::LEFT) {
|
||||||
pos.x = COLUMNS;
|
pos.x = COLUMNS;
|
||||||
}
|
}
|
||||||
|
else if (board.isWalkableForPacMan(cellAtPosition(pos, position_delta, desired_direction))) {
|
||||||
else if (board.isWalkableForPacMan(pos, position_delta, desired_direction)) {
|
|
||||||
direction = desired_direction;
|
direction = desired_direction;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (board.isWalkableForPacMan(pos, position_delta, direction)) {
|
if (board.isWalkableForPacMan(cellAtPosition(pos, position_delta, direction))) {
|
||||||
switch (direction) {
|
switch (direction) {
|
||||||
case Direction::NONE:
|
case Direction::NONE:
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -4,7 +4,7 @@
|
||||||
Pellets::Pellets(const Board & board)
|
Pellets::Pellets(const Board & board)
|
||||||
: positions(board.initialPelletPositions()) {}
|
: positions(board.initialPelletPositions()) {}
|
||||||
|
|
||||||
bool Pellets::eatPelletAtPosition(Position p) {
|
bool Pellets::eatPelletAtPosition(GridPosition p) {
|
||||||
auto it = std::find(positions.begin(), positions.end(), p);
|
auto it = std::find(positions.begin(), positions.end(), p);
|
||||||
if (it == positions.end())
|
if (it == positions.end())
|
||||||
return false;
|
return false;
|
||||||
|
|
|
@ -4,7 +4,7 @@
|
||||||
SuperPellets::SuperPellets(const Board & board)
|
SuperPellets::SuperPellets(const Board & board)
|
||||||
: positions(board.initialSuperPelletPositions()) {}
|
: positions(board.initialSuperPelletPositions()) {}
|
||||||
|
|
||||||
bool SuperPellets::eatPelletAtPosition(Position p) {
|
bool SuperPellets::eatPelletAtPosition(GridPosition p) {
|
||||||
auto it = std::find(positions.begin(), positions.end(), p);
|
auto it = std::find(positions.begin(), positions.end(), p);
|
||||||
if (it == positions.end())
|
if (it == positions.end())
|
||||||
return false;
|
return false;
|
||||||
|
|
|
@ -22,11 +22,9 @@ public:
|
||||||
pen = 5,
|
pen = 5,
|
||||||
};
|
};
|
||||||
|
|
||||||
[[nodiscard]] static bool isWalkableForPacMan(Position point, double d, Direction direction) ;
|
[[nodiscard]] static bool isWalkableForPacMan(GridPosition point);
|
||||||
|
[[nodiscard]] static bool isWalkableForGost(GridPosition point, GridPosition origin, bool isEyes) ;
|
||||||
[[nodiscard]] static bool isWalkableForGost(Position point, Position origin, bool isEyes) ;
|
[[nodiscard]] static bool isInPen(GridPosition point) ;
|
||||||
[[nodiscard]] static bool isWalkable(Position point) ;
|
|
||||||
[[nodiscard]] static bool isInPen(Position point) ;
|
|
||||||
|
|
||||||
[[nodiscard]] static std::vector<GridPosition> initialPelletPositions() ;
|
[[nodiscard]] static std::vector<GridPosition> initialPelletPositions() ;
|
||||||
|
|
||||||
|
@ -49,7 +47,7 @@ public:
|
||||||
static Position clydeScatterTarget() { return { 0, 30 }; }
|
static Position clydeScatterTarget() { return { 0, 30 }; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
[[nodiscard]] static bool isWalkable(Position point, double d, Direction direction, bool pacman) ;
|
[[nodiscard]] static Cell cellAtPosition(GridPosition point);
|
||||||
static std::array<
|
static std::array<
|
||||||
std::array<int, COLUMNS>,
|
std::array<int, COLUMNS>,
|
||||||
ROWS>
|
ROWS>
|
||||||
|
|
|
@ -21,7 +21,7 @@ public:
|
||||||
|
|
||||||
[[nodiscard]] Position position() const;
|
[[nodiscard]] Position position() const;
|
||||||
|
|
||||||
[[nodiscard]] Position positionInGrid() const;
|
[[nodiscard]] GridPosition positionInGrid() const;
|
||||||
|
|
||||||
void update(std::chrono::milliseconds time_delta, const Board & board);
|
void update(std::chrono::milliseconds time_delta, const Board & board);
|
||||||
void frighten();
|
void frighten();
|
||||||
|
@ -48,7 +48,7 @@ protected:
|
||||||
Position pos;
|
Position pos;
|
||||||
Position startingPosition;
|
Position startingPosition;
|
||||||
Position scatterTarget;
|
Position scatterTarget;
|
||||||
Position lastIntersection = { -1, -1 };
|
GridPosition lastIntersection = { -1, -1 };
|
||||||
bool isInPen(const Board & board) const;
|
bool isInPen(const Board & board) const;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -17,7 +17,7 @@ public:
|
||||||
|
|
||||||
[[nodiscard]] Position position() const;
|
[[nodiscard]] Position position() const;
|
||||||
|
|
||||||
[[nodiscard]] Position positionInGrid() const;
|
[[nodiscard]] GridPosition positionInGrid() const;
|
||||||
|
|
||||||
void update(std::chrono::milliseconds time_delta, InputState state, const Board & board);
|
void update(std::chrono::milliseconds time_delta, InputState state, const Board & board);
|
||||||
|
|
||||||
|
|
|
@ -15,7 +15,7 @@ public:
|
||||||
return positions;
|
return positions;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool eatPelletAtPosition(Position p);
|
bool eatPelletAtPosition(GridPosition p);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
const GridPosition sprite = { 1, 9 };
|
const GridPosition sprite = { 1, 9 };
|
||||||
|
|
|
@ -16,7 +16,11 @@ using Rect = sf::Rect<int>;
|
||||||
|
|
||||||
using Sprite = sf::Sprite;
|
using Sprite = sf::Sprite;
|
||||||
|
|
||||||
inline bool operator==(const GridPosition & b, const Position & a) {
|
inline bool operator==(const GridPosition & a, const GridPosition & b) {
|
||||||
|
return a.x == b.x && a.y == b.y;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline bool operator==(const GridPosition & a, const Position & b) {
|
||||||
return a.x == b.x && a.y == b.y;
|
return a.x == b.x && a.y == b.y;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -15,7 +15,7 @@ public:
|
||||||
return positions;
|
return positions;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool eatPelletAtPosition(Position p);
|
bool eatPelletAtPosition(GridPosition p);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
const GridPosition sprite = { 0, 9 };
|
const GridPosition sprite = { 0, 9 };
|
||||||
|
|
Loading…
Reference in New Issue