Simplify board code

This commit is contained in:
Corentin Jabot 2021-07-05 13:54:54 +02:00
parent 7faadda5c0
commit d166f552f4
11 changed files with 61 additions and 60 deletions

View file

@ -8,6 +8,7 @@
// 4 - superpower
// 5 - pen doors
// clang-format off
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, 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, 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) {
return isWalkable(point, d, direction, true);
bool Board::isWalkableForPacMan(GridPosition point) {
return cellAtPosition(point) != Cell::wall;
}
bool Board::isWalkable(Position point) {
return board[int(point.y)][int(point.x)] != int(Cell::wall);
bool Board::isWalkableForGost(GridPosition point, GridPosition origin, bool isEyes) {
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) {
return isWalkable(point) && (isEyes || (isInPen(origin) || !isInPen(point)));
bool Board::isInPen(GridPosition point) {
return cellAtPosition(point) == Cell::pen;
}
bool Board::isInPen(Position point) {
return board[int(point.y)][int(point.x)] == int(Cell::pen);
}
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;
Board::Cell Board::cellAtPosition(GridPosition point) {
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]);
}
std::vector<GridPosition> Board::initialPelletPositions() {
std::vector<GridPosition> positions;
for (int row = 0; row < ROWS; row++) {
for (int column = 0; column < COLUMNS; column++) {
for (std::size_t row = 0; row < ROWS; row++) {
for (std::size_t column = 0; column < COLUMNS; column++) {
if (board[row][column] == int(Cell::pellet))
positions.push_back({ column, row });
positions.push_back({ int(column), int(row) });
}
}
return positions;
@ -95,10 +79,10 @@ std::vector<GridPosition> Board::initialPelletPositions() {
std::vector<GridPosition> Board::initialSuperPelletPositions() {
std::vector<GridPosition> positions;
for (int row = 0; row < ROWS; row++) {
for (int column = 0; column < COLUMNS; column++) {
for (std::size_t row = 0; row < ROWS; row++) {
for (std::size_t column = 0; column < COLUMNS; column++) {
if (board[row][column] == int(Cell::power_pellet))
positions.push_back({ column, row });
positions.push_back({ int(column), int(row) });
}
}
return positions;

View file

@ -56,8 +56,8 @@ Position Ghost::position() const {
return pos;
}
Position Ghost::positionInGrid() const {
return { std::round(pos.x), std::round(pos.y) };
GridPosition Ghost::positionInGrid() const {
return { int(std::round(pos.x)), int(std::round(pos.y)) };
}
void Ghost::update(std::chrono::milliseconds time_delta, const Board & board) {
@ -119,8 +119,8 @@ void Ghost::updateDirection(const Board & board) {
return;
struct NewDirection {
Direction direction;
Position position;
Direction direction;
GridPosition position;
double distance;
};

View file

@ -12,8 +12,8 @@ Position PacMan::position() const {
return pos;
}
Position PacMan::positionInGrid() const {
return { std::round(pos.x), std::round(pos.y) };
GridPosition PacMan::positionInGrid() const {
return { int(std::round(pos.x)), int(std::round(pos.y)) };
}
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) {
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
if (pos.x >= COLUMNS - 1 && direction == Direction::RIGHT) {
pos.x = -1;
} else if (pos.x <= 0 && direction == Direction::LEFT) {
pos.x = COLUMNS;
}
else if (board.isWalkableForPacMan(pos, position_delta, desired_direction)) {
else if (board.isWalkableForPacMan(cellAtPosition(pos, position_delta, desired_direction))) {
direction = desired_direction;
}
if (board.isWalkableForPacMan(pos, position_delta, direction)) {
if (board.isWalkableForPacMan(cellAtPosition(pos, position_delta, direction))) {
switch (direction) {
case Direction::NONE:
break;

View file

@ -4,7 +4,7 @@
Pellets::Pellets(const Board & board)
: positions(board.initialPelletPositions()) {}
bool Pellets::eatPelletAtPosition(Position p) {
bool Pellets::eatPelletAtPosition(GridPosition p) {
auto it = std::find(positions.begin(), positions.end(), p);
if (it == positions.end())
return false;

View file

@ -4,7 +4,7 @@
SuperPellets::SuperPellets(const Board & board)
: positions(board.initialSuperPelletPositions()) {}
bool SuperPellets::eatPelletAtPosition(Position p) {
bool SuperPellets::eatPelletAtPosition(GridPosition p) {
auto it = std::find(positions.begin(), positions.end(), p);
if (it == positions.end())
return false;

View file

@ -22,11 +22,9 @@ public:
pen = 5,
};
[[nodiscard]] static bool isWalkableForPacMan(Position point, double d, Direction direction) ;
[[nodiscard]] static bool isWalkableForGost(Position point, Position origin, bool isEyes) ;
[[nodiscard]] static bool isWalkable(Position point) ;
[[nodiscard]] static bool isInPen(Position point) ;
[[nodiscard]] static bool isWalkableForPacMan(GridPosition point);
[[nodiscard]] static bool isWalkableForGost(GridPosition point, GridPosition origin, bool isEyes) ;
[[nodiscard]] static bool isInPen(GridPosition point) ;
[[nodiscard]] static std::vector<GridPosition> initialPelletPositions() ;
@ -49,7 +47,7 @@ public:
static Position clydeScatterTarget() { return { 0, 30 }; }
private:
[[nodiscard]] static bool isWalkable(Position point, double d, Direction direction, bool pacman) ;
[[nodiscard]] static Cell cellAtPosition(GridPosition point);
static std::array<
std::array<int, COLUMNS>,
ROWS>

View file

@ -21,7 +21,7 @@ public:
[[nodiscard]] Position position() const;
[[nodiscard]] Position positionInGrid() const;
[[nodiscard]] GridPosition positionInGrid() const;
void update(std::chrono::milliseconds time_delta, const Board & board);
void frighten();
@ -48,7 +48,7 @@ protected:
Position pos;
Position startingPosition;
Position scatterTarget;
Position lastIntersection = { -1, -1 };
GridPosition lastIntersection = { -1, -1 };
bool isInPen(const Board & board) const;
};

View file

@ -17,7 +17,7 @@ public:
[[nodiscard]] Position position() const;
[[nodiscard]] Position positionInGrid() const;
[[nodiscard]] GridPosition positionInGrid() const;
void update(std::chrono::milliseconds time_delta, InputState state, const Board & board);

View file

@ -15,7 +15,7 @@ public:
return positions;
}
bool eatPelletAtPosition(Position p);
bool eatPelletAtPosition(GridPosition p);
private:
const GridPosition sprite = { 1, 9 };

View file

@ -16,7 +16,11 @@ using Rect = sf::Rect<int>;
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;
}

View file

@ -15,7 +15,7 @@ public:
return positions;
}
bool eatPelletAtPosition(Position p);
bool eatPelletAtPosition(GridPosition p);
private:
const GridPosition sprite = { 0, 9 };