Move over to size_t
This commit is contained in:
parent
510e12a921
commit
30f69464dd
8 changed files with 77 additions and 54 deletions
|
@ -63,7 +63,7 @@ bool Board::isInPen(GridPosition point) {
|
|||
}
|
||||
|
||||
Board::Cell Board::cellAtPosition(GridPosition point) {
|
||||
if (point.x < 0 || point.x >= int(COLUMNS) || point.y < 0 || point.y >= int(ROWS))
|
||||
if (point.x >= COLUMNS || point.y >= ROWS)
|
||||
return Cell::wall;
|
||||
return Cell(board[point.y][point.x]);
|
||||
}
|
||||
|
|
|
@ -101,12 +101,13 @@ void Canvas::renderScore(int score) {
|
|||
|
||||
void Canvas::renderLives(int lives) {
|
||||
constexpr GridPosition liveSprite = Atlas::pacman_left_narrow;
|
||||
const int x = LEFT_MARGIN + MAZE_WIDTH + LEFT_MARGIN;
|
||||
const int y = maze_texture.getSize().y;
|
||||
const size_t x = LEFT_MARGIN + MAZE_WIDTH + LEFT_MARGIN;
|
||||
const size_t y = maze_texture.getSize().y;
|
||||
|
||||
Sprite pacmanSprite = getSprite(liveSprite);
|
||||
for (int i = 0; i < lives - 1; i++) {
|
||||
GridPosition pos{ x + i * pacmanSprite.getTextureRect().width, y };
|
||||
size_t life_position = i * pacmanSprite.getTextureRect().width;
|
||||
GridPosition pos{ x + life_position, y };
|
||||
pacmanSprite.setPosition(pos.x, pos.y);
|
||||
window.draw(pacmanSprite);
|
||||
}
|
||||
|
@ -119,8 +120,8 @@ Rect Canvas::windowDimensions() {
|
|||
Sprite Canvas::getSprite(GridPosition coordinate) const {
|
||||
sf::Sprite sprite;
|
||||
sprite.setTexture(sprites_texture);
|
||||
sprite.setTextureRect(sf::IntRect{ coordinate.x * DEFAULT_SPRITE_WIDTH,
|
||||
coordinate.y * DEFAULT_SPRITE_HEIGHT,
|
||||
sprite.setTextureRect(sf::IntRect{ int(coordinate.x * DEFAULT_SPRITE_WIDTH),
|
||||
int(coordinate.y * DEFAULT_SPRITE_HEIGHT),
|
||||
DEFAULT_SPRITE_WIDTH,
|
||||
DEFAULT_SPRITE_HEIGHT });
|
||||
sprite.scale(0.5, 0.5);
|
||||
|
|
|
@ -59,7 +59,7 @@ Position Ghost::position() const {
|
|||
}
|
||||
|
||||
GridPosition Ghost::positionInGrid() const {
|
||||
return { int(std::round(pos.x)), int(std::round(pos.y)) };
|
||||
return positionToGridPosition(pos);
|
||||
}
|
||||
|
||||
void Ghost::update(std::chrono::milliseconds time_delta, const Board & board) {
|
||||
|
@ -116,34 +116,48 @@ double Ghost::speed() const {
|
|||
}
|
||||
|
||||
void Ghost::updateDirection(const Board & board) {
|
||||
auto cell = positionInGrid();
|
||||
if (cell == lastIntersection)
|
||||
const auto current_grid_position = positionInGrid();
|
||||
if (current_grid_position == last_grid_position)
|
||||
return;
|
||||
|
||||
struct NewDirection {
|
||||
struct Move {
|
||||
Direction direction;
|
||||
GridPosition position;
|
||||
double distance;
|
||||
Position position;
|
||||
double distance = std::numeric_limits<double>::infinity();
|
||||
};
|
||||
|
||||
auto [x, y] = cell;
|
||||
std::array<NewDirection, 4> directions = { { NewDirection{ Direction::UP, { x, y - 1 }, 0 },
|
||||
NewDirection{ Direction::LEFT, { x - 1, y }, 0 },
|
||||
NewDirection{ Direction::DOWN, { x, y + 1 }, 0 },
|
||||
NewDirection{ Direction::RIGHT, { x + 1, y }, 0 } } };
|
||||
const Position target = this->target(board);
|
||||
const Position current_position = { double(current_grid_position.x), double(current_grid_position.y) };
|
||||
const auto [x, y] = current_position;
|
||||
std::array<Move, 4> possible_moves = { { Move{ Direction::UP, { x, y - 1 } },
|
||||
Move{ Direction::LEFT, { x - 1, y } },
|
||||
Move{ Direction::DOWN, { x, y + 1 } },
|
||||
Move{ Direction::RIGHT, { x + 1, y } } } };
|
||||
|
||||
for (auto && d : directions) {
|
||||
d.distance = (d.direction != oppositeDirection(direction) && board.isWalkableForGost(d.position, cell, state == State::Eyes)) ? std::hypot(d.position.x - target.x, d.position.y - target.y)
|
||||
: std::numeric_limits<double>::infinity();
|
||||
const Position target_position = target(board);
|
||||
|
||||
for (auto & move : possible_moves) {
|
||||
const bool invalid_position = (move.position.x < 0 || move.position.y < 0);
|
||||
if (invalid_position)
|
||||
continue;
|
||||
|
||||
const bool opposite_direction = (move.direction == oppositeDirection(direction));
|
||||
if (opposite_direction)
|
||||
continue;
|
||||
|
||||
const GridPosition grid_position = {size_t(move.position.x), size_t(move.position.y)};
|
||||
const bool can_walk = board.isWalkableForGost(grid_position, current_grid_position, isEyes());
|
||||
if (!can_walk)
|
||||
continue;
|
||||
|
||||
move.distance = std::hypot(move.position.x - target_position.x, move.position.y - target_position.y);
|
||||
}
|
||||
|
||||
auto it = std::min_element(directions.begin(), directions.end(), [](const auto & a, const auto & b) {
|
||||
const auto optimal_move = std::min_element(possible_moves.begin(), possible_moves.end(), [](const auto & a, const auto & b) {
|
||||
return a.distance < b.distance;
|
||||
});
|
||||
|
||||
lastIntersection = cell;
|
||||
direction = it->direction;
|
||||
last_grid_position = current_grid_position;
|
||||
direction = optimal_move->direction;
|
||||
}
|
||||
|
||||
Position Ghost::target(const Board & board) const {
|
||||
|
|
|
@ -15,7 +15,7 @@ Position PacMan::position() const {
|
|||
}
|
||||
|
||||
GridPosition PacMan::positionInGrid() const {
|
||||
return { int(std::round(pos.x)), int(std::round(pos.y)) };
|
||||
return positionToGridPosition(pos);
|
||||
}
|
||||
|
||||
void PacMan::eat() {
|
||||
|
@ -63,34 +63,38 @@ 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();
|
||||
const double position_delta = 0.004 * time_delta.count();
|
||||
|
||||
auto cellAtPosition = [&](Position point, double position_delta, Direction direction) {
|
||||
auto moveToPosition = [&](Position point, double position_delta, Direction direction) {
|
||||
switch (direction) {
|
||||
case Direction::LEFT:
|
||||
return GridPosition{ int(point.x - position_delta), int(point.y) };
|
||||
return Position{ std::floor(point.x - position_delta), std::floor(point.y) };
|
||||
case Direction::RIGHT:
|
||||
return GridPosition{ int(point.x) + 1, int(point.y) };
|
||||
return Position{ std::floor(point.x + 1), std::floor(point.y) };
|
||||
case Direction::UP:
|
||||
return GridPosition{ int(point.x), int(point.y - position_delta) };
|
||||
return Position{ std::floor(point.x), std::floor(point.y - position_delta) };
|
||||
case Direction::DOWN:
|
||||
return GridPosition{ int(point.x), int(point.y) + 1 };
|
||||
return Position{ std::floor(point.x), std::floor(point.y + 1) };
|
||||
case Direction::NONE:
|
||||
default:
|
||||
return positionInGrid();
|
||||
return point;
|
||||
}
|
||||
};
|
||||
|
||||
auto canGo = [&](Direction desired_direction) {
|
||||
return board.isWalkableForPacMan(positionToGridPosition(moveToPosition(pos, position_delta, desired_direction)));
|
||||
};
|
||||
|
||||
// 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(cellAtPosition(pos, position_delta, desired_direction))) {
|
||||
} else if (canGo(desired_direction)) {
|
||||
direction = desired_direction;
|
||||
}
|
||||
|
||||
if (board.isWalkableForPacMan(cellAtPosition(pos, position_delta, direction))) {
|
||||
if (canGo(direction)) {
|
||||
switch (direction) {
|
||||
case Direction::NONE:
|
||||
break;
|
||||
|
|
|
@ -8,7 +8,7 @@
|
|||
|
||||
namespace pacman::Atlas {
|
||||
|
||||
enum class Ghost {
|
||||
enum class Ghost : unsigned int {
|
||||
blinky = 2,
|
||||
speedy = 3,
|
||||
inky = 4,
|
||||
|
@ -31,7 +31,7 @@ constexpr GridPosition ghost_white_frightened = { 2, 7 };
|
|||
constexpr GridPosition ghost_white_frightened2 = { 3, 7 };
|
||||
|
||||
constexpr GridPosition eyeSprite(Direction direction) {
|
||||
int x = 0;
|
||||
size_t x = 0;
|
||||
switch (direction) {
|
||||
case Direction::RIGHT:
|
||||
x = 0;
|
||||
|
@ -54,8 +54,8 @@ constexpr GridPosition eyeSprite(Direction direction) {
|
|||
|
||||
constexpr GridPosition ghostSprite(Ghost ghost, Direction direction, bool alternative) {
|
||||
assert(ghost >= Ghost::blinky && ghost <= Ghost::clyde && "Invalid Ghost");
|
||||
int y = static_cast<int>(ghost);
|
||||
int x = 0;
|
||||
size_t y = static_cast<size_t>(ghost);
|
||||
size_t x = 0;
|
||||
switch (direction) {
|
||||
case Direction::RIGHT:
|
||||
x = 0;
|
||||
|
|
|
@ -19,14 +19,14 @@ public:
|
|||
std::optional<sf::Event> pollEvent();
|
||||
|
||||
private:
|
||||
static constexpr int16_t LEFT_MARGIN = 40;
|
||||
static constexpr int16_t TOP_MARGIN = 40;
|
||||
static constexpr int16_t BOTTOM_MARGIN = 40;
|
||||
static constexpr int16_t MAZE_WIDTH = 448;
|
||||
static constexpr int16_t MAZE_HEIGHT = 496;
|
||||
static constexpr int16_t SCORE_WIDTH = 200;
|
||||
static constexpr int16_t DEFAULT_SPRITE_WIDTH = 32;
|
||||
static constexpr int16_t DEFAULT_SPRITE_HEIGHT = 32;
|
||||
static constexpr uint16_t LEFT_MARGIN = 40;
|
||||
static constexpr uint16_t TOP_MARGIN = 40;
|
||||
static constexpr uint16_t BOTTOM_MARGIN = 40;
|
||||
static constexpr uint16_t MAZE_WIDTH = 448;
|
||||
static constexpr uint16_t MAZE_HEIGHT = 496;
|
||||
static constexpr uint16_t SCORE_WIDTH = 200;
|
||||
static constexpr uint16_t DEFAULT_SPRITE_WIDTH = 32;
|
||||
static constexpr uint16_t DEFAULT_SPRITE_HEIGHT = 32;
|
||||
|
||||
void clear();
|
||||
void render();
|
||||
|
|
|
@ -50,7 +50,7 @@ protected:
|
|||
Position pos;
|
||||
Position startingPosition;
|
||||
Position scatterTarget;
|
||||
GridPosition lastIntersection = { -1, -1 };
|
||||
GridPosition last_grid_position = { 0, 0 };
|
||||
bool isInPen(const Board & board) const;
|
||||
};
|
||||
|
||||
|
|
|
@ -10,31 +10,35 @@ struct Position {
|
|||
};
|
||||
|
||||
struct GridPosition {
|
||||
int x;
|
||||
int y;
|
||||
size_t x;
|
||||
size_t y;
|
||||
};
|
||||
|
||||
using Rect = sf::Rect<int>;
|
||||
|
||||
using Sprite = sf::Sprite;
|
||||
|
||||
inline bool operator==(const GridPosition & a, const GridPosition & b) {
|
||||
inline GridPosition positionToGridPosition(Position pos) {
|
||||
return { size_t(std::round(pos.x)), size_t(std::round(pos.y)) };
|
||||
}
|
||||
|
||||
constexpr 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) {
|
||||
constexpr bool operator==(const GridPosition & a, const Position & b) {
|
||||
return a.x == b.x && a.y == b.y;
|
||||
}
|
||||
|
||||
inline bool operator==(const Position & a, const Position & b) {
|
||||
constexpr bool operator==(const Position & a, const Position & b) {
|
||||
return a.x == b.x && a.y == b.y;
|
||||
}
|
||||
|
||||
inline bool operator!=(const Position & a, const Position & b) {
|
||||
constexpr bool operator!=(const Position & a, const Position & b) {
|
||||
return !(a == b);
|
||||
}
|
||||
|
||||
inline bool operator!=(const GridPosition & a, const GridPosition & b) {
|
||||
constexpr bool operator!=(const GridPosition & a, const GridPosition & b) {
|
||||
return !(a == b);
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue