From 30f69464dd7f1c060fd5461cde58ff56b1a93def Mon Sep 17 00:00:00 2001 From: Patricia Aas Date: Tue, 6 Jul 2021 12:35:23 +0200 Subject: [PATCH] Move over to size_t --- lib/Board.cpp | 2 +- lib/Canvas.cpp | 11 +++++---- lib/Ghost.cpp | 50 +++++++++++++++++++++++++--------------- lib/PacMan.cpp | 24 +++++++++++-------- lib/include/Atlas.hpp | 8 +++---- lib/include/Canvas.hpp | 16 ++++++------- lib/include/Ghost.hpp | 2 +- lib/include/Position.hpp | 18 +++++++++------ 8 files changed, 77 insertions(+), 54 deletions(-) diff --git a/lib/Board.cpp b/lib/Board.cpp index 8dfa09a..4c0312a 100644 --- a/lib/Board.cpp +++ b/lib/Board.cpp @@ -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]); } diff --git a/lib/Canvas.cpp b/lib/Canvas.cpp index 790ae2a..119e958 100644 --- a/lib/Canvas.cpp +++ b/lib/Canvas.cpp @@ -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); diff --git a/lib/Ghost.cpp b/lib/Ghost.cpp index 08a49b6..166de87 100644 --- a/lib/Ghost.cpp +++ b/lib/Ghost.cpp @@ -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::infinity(); }; - auto [x, y] = cell; - std::array 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 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::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 { diff --git a/lib/PacMan.cpp b/lib/PacMan.cpp index 5f6f4f5..0b1b934 100644 --- a/lib/PacMan.cpp +++ b/lib/PacMan.cpp @@ -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; diff --git a/lib/include/Atlas.hpp b/lib/include/Atlas.hpp index 16a1123..3673595 100644 --- a/lib/include/Atlas.hpp +++ b/lib/include/Atlas.hpp @@ -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(ghost); - int x = 0; + size_t y = static_cast(ghost); + size_t x = 0; switch (direction) { case Direction::RIGHT: x = 0; diff --git a/lib/include/Canvas.hpp b/lib/include/Canvas.hpp index fdc8fd4..6f30d6a 100644 --- a/lib/include/Canvas.hpp +++ b/lib/include/Canvas.hpp @@ -19,14 +19,14 @@ public: std::optional 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(); diff --git a/lib/include/Ghost.hpp b/lib/include/Ghost.hpp index 69fed88..0c479af 100644 --- a/lib/include/Ghost.hpp +++ b/lib/include/Ghost.hpp @@ -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; }; diff --git a/lib/include/Position.hpp b/lib/include/Position.hpp index 19eb44d..95f3a76 100644 --- a/lib/include/Position.hpp +++ b/lib/include/Position.hpp @@ -10,31 +10,35 @@ struct Position { }; struct GridPosition { - int x; - int y; + size_t x; + size_t y; }; using Rect = sf::Rect; 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); }