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) {
|
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::wall;
|
||||||
return Cell(board[point.y][point.x]);
|
return Cell(board[point.y][point.x]);
|
||||||
}
|
}
|
||||||
|
|
|
@ -101,12 +101,13 @@ void Canvas::renderScore(int score) {
|
||||||
|
|
||||||
void Canvas::renderLives(int lives) {
|
void Canvas::renderLives(int lives) {
|
||||||
constexpr GridPosition liveSprite = Atlas::pacman_left_narrow;
|
constexpr GridPosition liveSprite = Atlas::pacman_left_narrow;
|
||||||
const int x = LEFT_MARGIN + MAZE_WIDTH + LEFT_MARGIN;
|
const size_t x = LEFT_MARGIN + MAZE_WIDTH + LEFT_MARGIN;
|
||||||
const int y = maze_texture.getSize().y;
|
const size_t y = maze_texture.getSize().y;
|
||||||
|
|
||||||
Sprite pacmanSprite = getSprite(liveSprite);
|
Sprite pacmanSprite = getSprite(liveSprite);
|
||||||
for (int i = 0; i < lives - 1; i++) {
|
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);
|
pacmanSprite.setPosition(pos.x, pos.y);
|
||||||
window.draw(pacmanSprite);
|
window.draw(pacmanSprite);
|
||||||
}
|
}
|
||||||
|
@ -119,8 +120,8 @@ Rect Canvas::windowDimensions() {
|
||||||
Sprite Canvas::getSprite(GridPosition coordinate) const {
|
Sprite Canvas::getSprite(GridPosition coordinate) const {
|
||||||
sf::Sprite sprite;
|
sf::Sprite sprite;
|
||||||
sprite.setTexture(sprites_texture);
|
sprite.setTexture(sprites_texture);
|
||||||
sprite.setTextureRect(sf::IntRect{ coordinate.x * DEFAULT_SPRITE_WIDTH,
|
sprite.setTextureRect(sf::IntRect{ int(coordinate.x * DEFAULT_SPRITE_WIDTH),
|
||||||
coordinate.y * DEFAULT_SPRITE_HEIGHT,
|
int(coordinate.y * DEFAULT_SPRITE_HEIGHT),
|
||||||
DEFAULT_SPRITE_WIDTH,
|
DEFAULT_SPRITE_WIDTH,
|
||||||
DEFAULT_SPRITE_HEIGHT });
|
DEFAULT_SPRITE_HEIGHT });
|
||||||
sprite.scale(0.5, 0.5);
|
sprite.scale(0.5, 0.5);
|
||||||
|
|
|
@ -59,7 +59,7 @@ Position Ghost::position() const {
|
||||||
}
|
}
|
||||||
|
|
||||||
GridPosition Ghost::positionInGrid() 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) {
|
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) {
|
void Ghost::updateDirection(const Board & board) {
|
||||||
auto cell = positionInGrid();
|
const auto current_grid_position = positionInGrid();
|
||||||
if (cell == lastIntersection)
|
if (current_grid_position == last_grid_position)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
struct NewDirection {
|
struct Move {
|
||||||
Direction direction;
|
Direction direction;
|
||||||
GridPosition position;
|
Position position;
|
||||||
double distance;
|
double distance = std::numeric_limits<double>::infinity();
|
||||||
};
|
};
|
||||||
|
|
||||||
auto [x, y] = cell;
|
const Position current_position = { double(current_grid_position.x), double(current_grid_position.y) };
|
||||||
std::array<NewDirection, 4> directions = { { NewDirection{ Direction::UP, { x, y - 1 }, 0 },
|
const auto [x, y] = current_position;
|
||||||
NewDirection{ Direction::LEFT, { x - 1, y }, 0 },
|
std::array<Move, 4> possible_moves = { { Move{ Direction::UP, { x, y - 1 } },
|
||||||
NewDirection{ Direction::DOWN, { x, y + 1 }, 0 },
|
Move{ Direction::LEFT, { x - 1, y } },
|
||||||
NewDirection{ Direction::RIGHT, { x + 1, y }, 0 } } };
|
Move{ Direction::DOWN, { x, y + 1 } },
|
||||||
const Position target = this->target(board);
|
Move{ Direction::RIGHT, { x + 1, y } } } };
|
||||||
|
|
||||||
for (auto && d : directions) {
|
const Position target_position = target(board);
|
||||||
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();
|
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;
|
return a.distance < b.distance;
|
||||||
});
|
});
|
||||||
|
|
||||||
lastIntersection = cell;
|
last_grid_position = current_grid_position;
|
||||||
direction = it->direction;
|
direction = optimal_move->direction;
|
||||||
}
|
}
|
||||||
|
|
||||||
Position Ghost::target(const Board & board) const {
|
Position Ghost::target(const Board & board) const {
|
||||||
|
|
|
@ -15,7 +15,7 @@ Position PacMan::position() const {
|
||||||
}
|
}
|
||||||
|
|
||||||
GridPosition PacMan::positionInGrid() const {
|
GridPosition PacMan::positionInGrid() const {
|
||||||
return { int(std::round(pos.x)), int(std::round(pos.y)) };
|
return positionToGridPosition(pos);
|
||||||
}
|
}
|
||||||
|
|
||||||
void PacMan::eat() {
|
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) {
|
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) {
|
switch (direction) {
|
||||||
case Direction::LEFT:
|
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:
|
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:
|
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:
|
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:
|
case Direction::NONE:
|
||||||
default:
|
default:
|
||||||
return positionInGrid();
|
return point;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
auto canGo = [&](Direction desired_direction) {
|
||||||
|
return board.isWalkableForPacMan(positionToGridPosition(moveToPosition(pos, position_delta, desired_direction)));
|
||||||
|
};
|
||||||
|
|
||||||
// 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 (canGo(desired_direction)) {
|
||||||
direction = desired_direction;
|
direction = desired_direction;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (board.isWalkableForPacMan(cellAtPosition(pos, position_delta, direction))) {
|
if (canGo(direction)) {
|
||||||
switch (direction) {
|
switch (direction) {
|
||||||
case Direction::NONE:
|
case Direction::NONE:
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -8,7 +8,7 @@
|
||||||
|
|
||||||
namespace pacman::Atlas {
|
namespace pacman::Atlas {
|
||||||
|
|
||||||
enum class Ghost {
|
enum class Ghost : unsigned int {
|
||||||
blinky = 2,
|
blinky = 2,
|
||||||
speedy = 3,
|
speedy = 3,
|
||||||
inky = 4,
|
inky = 4,
|
||||||
|
@ -31,7 +31,7 @@ constexpr GridPosition ghost_white_frightened = { 2, 7 };
|
||||||
constexpr GridPosition ghost_white_frightened2 = { 3, 7 };
|
constexpr GridPosition ghost_white_frightened2 = { 3, 7 };
|
||||||
|
|
||||||
constexpr GridPosition eyeSprite(Direction direction) {
|
constexpr GridPosition eyeSprite(Direction direction) {
|
||||||
int x = 0;
|
size_t x = 0;
|
||||||
switch (direction) {
|
switch (direction) {
|
||||||
case Direction::RIGHT:
|
case Direction::RIGHT:
|
||||||
x = 0;
|
x = 0;
|
||||||
|
@ -54,8 +54,8 @@ constexpr GridPosition eyeSprite(Direction direction) {
|
||||||
|
|
||||||
constexpr GridPosition ghostSprite(Ghost ghost, Direction direction, bool alternative) {
|
constexpr GridPosition ghostSprite(Ghost ghost, Direction direction, bool alternative) {
|
||||||
assert(ghost >= Ghost::blinky && ghost <= Ghost::clyde && "Invalid Ghost");
|
assert(ghost >= Ghost::blinky && ghost <= Ghost::clyde && "Invalid Ghost");
|
||||||
int y = static_cast<int>(ghost);
|
size_t y = static_cast<size_t>(ghost);
|
||||||
int x = 0;
|
size_t x = 0;
|
||||||
switch (direction) {
|
switch (direction) {
|
||||||
case Direction::RIGHT:
|
case Direction::RIGHT:
|
||||||
x = 0;
|
x = 0;
|
||||||
|
|
|
@ -19,14 +19,14 @@ public:
|
||||||
std::optional<sf::Event> pollEvent();
|
std::optional<sf::Event> pollEvent();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
static constexpr int16_t LEFT_MARGIN = 40;
|
static constexpr uint16_t LEFT_MARGIN = 40;
|
||||||
static constexpr int16_t TOP_MARGIN = 40;
|
static constexpr uint16_t TOP_MARGIN = 40;
|
||||||
static constexpr int16_t BOTTOM_MARGIN = 40;
|
static constexpr uint16_t BOTTOM_MARGIN = 40;
|
||||||
static constexpr int16_t MAZE_WIDTH = 448;
|
static constexpr uint16_t MAZE_WIDTH = 448;
|
||||||
static constexpr int16_t MAZE_HEIGHT = 496;
|
static constexpr uint16_t MAZE_HEIGHT = 496;
|
||||||
static constexpr int16_t SCORE_WIDTH = 200;
|
static constexpr uint16_t SCORE_WIDTH = 200;
|
||||||
static constexpr int16_t DEFAULT_SPRITE_WIDTH = 32;
|
static constexpr uint16_t DEFAULT_SPRITE_WIDTH = 32;
|
||||||
static constexpr int16_t DEFAULT_SPRITE_HEIGHT = 32;
|
static constexpr uint16_t DEFAULT_SPRITE_HEIGHT = 32;
|
||||||
|
|
||||||
void clear();
|
void clear();
|
||||||
void render();
|
void render();
|
||||||
|
|
|
@ -50,7 +50,7 @@ protected:
|
||||||
Position pos;
|
Position pos;
|
||||||
Position startingPosition;
|
Position startingPosition;
|
||||||
Position scatterTarget;
|
Position scatterTarget;
|
||||||
GridPosition lastIntersection = { -1, -1 };
|
GridPosition last_grid_position = { 0, 0 };
|
||||||
bool isInPen(const Board & board) const;
|
bool isInPen(const Board & board) const;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -10,31 +10,35 @@ struct Position {
|
||||||
};
|
};
|
||||||
|
|
||||||
struct GridPosition {
|
struct GridPosition {
|
||||||
int x;
|
size_t x;
|
||||||
int y;
|
size_t y;
|
||||||
};
|
};
|
||||||
|
|
||||||
using Rect = sf::Rect<int>;
|
using Rect = sf::Rect<int>;
|
||||||
|
|
||||||
using Sprite = sf::Sprite;
|
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;
|
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;
|
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;
|
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);
|
return !(a == b);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline bool operator!=(const GridPosition & a, const GridPosition & b) {
|
constexpr bool operator!=(const GridPosition & a, const GridPosition & b) {
|
||||||
return !(a == b);
|
return !(a == b);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue