Compare commits
1 commit
main
...
des/loadfo
Author | SHA1 | Date | |
---|---|---|---|
|
95f8f075db |
29 changed files with 101 additions and 358 deletions
|
@ -15,20 +15,6 @@
|
|||
sudo apt-get install ninja-build pkg-config curl zip unzip tar cmake build-essential libx11-dev libxrandr-dev libxi-dev libudev-dev libgl1-mesa-dev
|
||||
```
|
||||
|
||||
### Fedora 33 or newer
|
||||
|
||||
* Install the build tools
|
||||
```bash
|
||||
sudo dnf install ninja-build SFML-devel libXi-devel libX11-devel libXrandr-devel mesa-libGL-devel systemd-devel
|
||||
```
|
||||
|
||||
### FreeBSD 12 or newer
|
||||
|
||||
* Install the build tools
|
||||
```bash
|
||||
sudo pkg install catch cmake libfmt ninja sfml
|
||||
```
|
||||
|
||||
### Windows:
|
||||
|
||||
* Follow the instructions to install cmake (3.21) from https://cmake.org/download/
|
||||
|
@ -46,19 +32,10 @@ brew install cmake ninja
|
|||
|
||||
## Configure and build project
|
||||
|
||||
### All Platforms, using VS Code
|
||||
### All Platforms
|
||||
|
||||
```bash
|
||||
git clone https://github.com/mod-cpp/pacman.git
|
||||
cd pacman
|
||||
code .
|
||||
```
|
||||
|
||||
### Commandline based build (Not used in this training) Linux, BSD, or Mac
|
||||
|
||||
```bash
|
||||
git clone https://github.com/mod-cpp/pacman.git
|
||||
cd pacman
|
||||
cmake .
|
||||
make
|
||||
```
|
||||
|
|
|
@ -1,5 +1,3 @@
|
|||
[< Back](../README.md)
|
||||
|
||||
* [Exercise: Play with function parameters](parameters/README.md)
|
||||
|
||||
* [Exercise: Create an isWall function](create_function/README.md)
|
||||
|
|
|
@ -1,37 +0,0 @@
|
|||
[< Back](../README.md)
|
||||
|
||||
# Exercise: Play with parameter passing
|
||||
|
||||
In this exercise we will look together at what happens when we change a reference
|
||||
parameter to a value or a const reference.
|
||||
|
||||
Let's look at this function in [`Game.cpp`](../../../lib/Game.cpp)
|
||||
|
||||
```cpp
|
||||
void Game::processEvents(InputState & inputState) {
|
||||
|
||||
|
||||
auto event = canvas.pollEvent();
|
||||
if (event && event.value().type == sf::Event::Closed) {
|
||||
inputState.close = true;
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
inputState.down = sf::Keyboard::isKeyPressed(sf::Keyboard::Key::Down);
|
||||
inputState.up = sf::Keyboard::isKeyPressed(sf::Keyboard::Key::Up);
|
||||
inputState.left = sf::Keyboard::isKeyPressed(sf::Keyboard::Key::Left);
|
||||
inputState.right = sf::Keyboard::isKeyPressed(sf::Keyboard::Key::Right);
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
## Exercise
|
||||
|
||||
You can follow along locally:
|
||||
|
||||
1. Make `inputState` a value. What happens when you compile the code? Can you explain why?
|
||||
|
||||
2. Now make it a `const` reference. What happens? Can you explain why?
|
||||
|
||||
3. Revert it back to a non-const reference an make sure the code compile.
|
|
@ -1,8 +1,13 @@
|
|||
[< Back](../README.md)
|
||||
|
||||
# Exercise: Create a class
|
||||
# Exercise: Simple class
|
||||
|
||||
## Exercise: Simple class
|
||||
## Background:
|
||||
|
||||
1. Create an empty class named `Clyde` within the `.hpp` file.
|
||||
2. Look at other ghost `.hpp` files and see how they define the class. It does not need to inherit from the `Ghost` base class and it does not need any functions.
|
||||
4. Create an empty class named `Clyde` within the `.hpp` file. Look at other ghost `.hpp` files and see how they define
|
||||
the class. It does not need to inherit from the `Ghost` base class and it does not need any functions. But if you
|
||||
have extra time, try to inherit from the Ghost class and see what happens when you try to compile.
|
||||
|
||||
## Exercise
|
||||
|
||||
1.
|
||||
|
|
|
@ -2,19 +2,16 @@
|
|||
|
||||
# Exercise: Add Clyde as a Ghost
|
||||
|
||||
## Background: Clyde
|
||||
## Background:
|
||||
|
||||
We have three ghosts within the project. Blinky, Inky and Pinky. But Clyde is missing. Implement Clyde and their
|
||||
behavior.
|
||||
|
||||
Clyde chases PacMan so you need to know where PacMan is currently located. But Clyde gets scared and runs back to its scatter target when PacMan gets too close (less than 8 the size of a cell).
|
||||
Clyde also has the scatter and eyes behaviors as the other ghosts.
|
||||
Clyde always chases PacMan so the only thing you should need is where PacMan is currently located. But Clyde also has
|
||||
the scatter behavior as the other ghosts.
|
||||
|
||||
Where are the graphics for Clyde in the assets file and how can we make sure the ghost will be correctly rendered?
|
||||
|
||||
## Exercise
|
||||
|
||||
1. Clyde should inherit from Ghost
|
||||
2. Make simple implementations of the functions to make it compile
|
||||
3. Clyde should start at Position { x = 15.5, y = 14 }
|
||||
4. Clydes sprite is the orange one. Where are the graphics for Clyde in the assets file and how can we make sure the ghost will be correctly rendered?
|
||||
5. Clydes scatter target is { x = 0, y = 30 }
|
||||
6. Clyde always targets its scatter target, unless PacMan is further than 8 tiles away
|
||||
1.
|
||||
|
|
|
@ -1,9 +1,13 @@
|
|||
[< Back](../README.md)
|
||||
|
||||
# Exercise:
|
||||
# Exercise: Create isIntersection function
|
||||
|
||||
## Exercise: Create isIntersection function
|
||||
## Background:
|
||||
|
||||
1. In Board.cpp create an isIntersection function that returns a bool and takes a GridPosition as a parameter
|
||||
2. Create an array of GridPositions around the parameter pos and array of bool and then loop through the postitions and check "isWalkableForPacMan" and store the results in the array of bools.
|
||||
3. Return true if there are at least three different walkable paths
|
||||
waage: Maybe the "isIntersection" for the AI. Create an array of GridPosition and array of bool and loop through to
|
||||
check "isWalkableForPacMan" and then return the different kinds of intersections (top/right, right/bottom, bottom/left,
|
||||
left/top)
|
||||
|
||||
## Exercise
|
||||
|
||||
1.
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
[< Back](../README.md)
|
||||
|
||||
* [Exercise: PacMan AI](pacman_ai/README.md)
|
||||
* [Exercise: PacMan Bot](pacman_bot/README.md)
|
||||
|
|
|
@ -16,56 +16,7 @@ You only need to worry about the grid itself and any ghosts on the North/South/E
|
|||
|
||||
## Exercise
|
||||
|
||||
### isValidMove
|
||||
|
||||
Implement [PacManAI::isValidMove](../../../lib/PacManAI.cpp) and test your implementation with the test
|
||||
in [testPacmanAI.cpp](../../../test/testPacmanAI.cpp) called _"Is valid move"_
|
||||
|
||||
To run the tests through CMake change the last line in [test/CMakeLists.txt](../../../test/CMakeLists.txt) to:
|
||||
|
||||
```
|
||||
add_test(NAME pacman_tests COMMAND pacman_tests)
|
||||
```
|
||||
|
||||
```cpp
|
||||
bool PacManAI::isValidMove(const Move & move) {
|
||||
return false;
|
||||
}
|
||||
```
|
||||
|
||||
<details>
|
||||
<summary>Hint 1</summary>
|
||||
|
||||
Use [isWalkableForPacMan](../../../lib/Board.cpp) to make sure PacMan is not walking in ways that are not legal
|
||||
|
||||
</details>
|
||||
|
||||
<details>
|
||||
<summary>Hint 2</summary>
|
||||
|
||||
Use [oppositeDirection](../../../lib/include/Direction.hpp) to make sure PacMan doesn't get stuck toggeling back and forth
|
||||
|
||||
</details>
|
||||
|
||||
### optimalDirection
|
||||
|
||||
Implement [PacManAI::optimalDirection](../../../lib/PacManAI.cpp) and test your implementation with the test
|
||||
in [testPacmanAI.cpp](../../../test/testPacmanAI.cpp) called _"Is optimal direction"_
|
||||
|
||||
```cpp
|
||||
Direction PacManAI::optimalDirection(const std::array<Move, 4> & moves) {
|
||||
return Direction::NONE;
|
||||
}
|
||||
```
|
||||
|
||||
<details>
|
||||
<summary>Hint</summary>
|
||||
|
||||
You can use [std::min_element](https://en.cppreference.com/w/cpp/algorithm/min_element) to find the closest pellet
|
||||
|
||||
</details>
|
||||
|
||||
### pelletClosestToPacman
|
||||
### Part 1
|
||||
|
||||
Implement [PacManAI::pelletClosestToPacman](../../../lib/PacManAI.cpp) and test your implementation with the test
|
||||
in [testPacmanAI.cpp](../../../test/testPacmanAI.cpp) called _"Find pellet closest to PacMan"_
|
||||
|
@ -101,3 +52,36 @@ Use the [std::sort](https://en.cppreference.com/w/cpp/algorithm/sort) function t
|
|||
and return true if the first parameter is closer from PacMan than the second.
|
||||
|
||||
</details>
|
||||
|
||||
### Part 2
|
||||
|
||||
Implement [PacManAI::isValidMove](../../../lib/PacManAI.cpp) and test your implementation with the test
|
||||
in [testPacmanAI.cpp](../../../test/testPacmanAI.cpp) called _"Is valid move"_
|
||||
|
||||
```cpp
|
||||
bool PacManAI::isValidMove(const Move & move) {
|
||||
return false;
|
||||
}
|
||||
```
|
||||
|
||||
<details>
|
||||
<summary>Hint</summary>
|
||||
|
||||
</details>
|
||||
|
||||
### Part 3
|
||||
|
||||
Implement [PacManAI::optimalDirection](../../../lib/PacManAI.cpp) and test your implementation with the test
|
||||
in [testPacmanAI.cpp](../../../test/testPacmanAI.cpp) called _"Is optimal direction"_
|
||||
|
||||
```cpp
|
||||
Direction PacManAI::optimalDirection(const std::array<Move, 4> & moves) {
|
||||
return Direction::NONE;
|
||||
}
|
||||
```
|
||||
|
||||
<details>
|
||||
<summary>Hint</summary>
|
||||
</details>
|
||||
|
||||
|
||||
|
|
|
@ -1,13 +0,0 @@
|
|||
bool PacManAI::isValidMove(const Move & move) {
|
||||
const bool isOpposite = (move.direction == oppositeDirection(direction));
|
||||
if (isOpposite) {
|
||||
return false;
|
||||
}
|
||||
|
||||
const bool canWalk = isWalkableForPacMan(move.position);
|
||||
if (!canWalk) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
|
@ -1,13 +0,0 @@
|
|||
Direction PacManAI::optimalDirection(const std::array<Move, 4> & moves) {
|
||||
double closestDistance = std::numeric_limits<double>::infinity();
|
||||
Direction dir = Direction::NONE;
|
||||
|
||||
for (const auto & move : moves) {
|
||||
if (move.distanceToTarget < closestDistance) {
|
||||
closestDistance = move.distanceToTarget;
|
||||
dir = move.direction;
|
||||
}
|
||||
}
|
||||
|
||||
return dir;
|
||||
}
|
|
@ -1,15 +0,0 @@
|
|||
GridPosition PacManAI::pelletClosestToPacman(GridPosition pacmanGridPosition,
|
||||
std::vector<GridPosition> & pellets) {
|
||||
GridPosition closestPellet = { 0, 0 };
|
||||
double closestDistance = std::numeric_limits<double>::infinity();
|
||||
|
||||
for (const auto & pellet : pellets) {
|
||||
const double distance = positionDistance(pacmanGridPosition, pellet);
|
||||
if (distance < closestDistance) {
|
||||
closestDistance = distance;
|
||||
closestPellet = pellet;
|
||||
}
|
||||
}
|
||||
|
||||
return closestPellet;
|
||||
}
|
|
@ -1,5 +1 @@
|
|||
[< Back](../README.md)
|
||||
|
||||
* [Exercise: UBSan, Experiment on Compiler Explorer](https://godbolt.org/z/nT54sj4hj)
|
||||
* [Exercise: ASan, Experiment on Compiler Explorer](https://godbolt.org/z/84Kr7Gcbz)
|
||||
* [Exercise: MSan, Experiment on Compiler Explorer](https://godbolt.org/z/n5zWWM3aa)
|
||||
|
|
|
@ -7,8 +7,8 @@
|
|||
* [Module 13: Game](13/README.md)
|
||||
* [Module 14: Functions and Parameter Passing](14/README.md)
|
||||
* [Module 15: Compilation, Linking and Assets](15/README.md)
|
||||
* [Module 16: Classes and Structs](16/README.md)
|
||||
* [Module 17: Memory and RAII](17/README.md)
|
||||
* [Module 16: Memory and RAII](16/README.md)
|
||||
* [Module 17: Classes and Structs](17/README.md)
|
||||
|
||||
## Day 2
|
||||
|
||||
|
@ -33,4 +33,4 @@ These will probably become relevant
|
|||
* https://www.gamasutra.com/view/feature/3938/the_pacman_dossier.php?print=1
|
||||
* https://www.slideshare.net/grimlockt/pac-man-6561257
|
||||
* http://donhodges.com/pacman_pinky_explanation.htm
|
||||
*
|
||||
*
|
|
@ -59,16 +59,13 @@ static Cell cellAtPosition(GridPosition point) {
|
|||
return Cell(board[point.y][point.x]);
|
||||
}
|
||||
|
||||
bool isWall(GridPosition point) {
|
||||
return cellAtPosition(point) == Cell::wall;
|
||||
}
|
||||
|
||||
bool isWalkableForPacMan(GridPosition point) {
|
||||
return !isWall(point) && !isInPen(point);
|
||||
return cellAtPosition(point) != Cell::wall && cellAtPosition(point) != Cell::pen;
|
||||
}
|
||||
|
||||
bool isWalkableForGhost(GridPosition target_position, GridPosition current_position, bool isEyes) {
|
||||
if (isWall(target_position))
|
||||
const Cell cell = cellAtPosition(target_position);
|
||||
if (cell == Cell::wall)
|
||||
return false;
|
||||
return isEyes || isInPen(current_position) || !isInPen(target_position);
|
||||
}
|
||||
|
|
|
@ -36,10 +36,9 @@ void Canvas::render(const GameState & gameState) {
|
|||
renderPellets(gameState.pellets);
|
||||
renderSuperPellets(gameState.superPellets);
|
||||
|
||||
renderGhost(gameState.ghosts.blinky);
|
||||
renderGhost(gameState.ghosts.pinky);
|
||||
renderGhost(gameState.ghosts.inky);
|
||||
renderGhost(gameState.ghosts.dave);
|
||||
renderGhost(gameState.blinky);
|
||||
renderGhost(gameState.pinky);
|
||||
renderGhost(gameState.inky);
|
||||
|
||||
renderScore(gameState.score.points);
|
||||
renderLives(gameState.score.lives);
|
||||
|
|
38
lib/Dave.cpp
38
lib/Dave.cpp
|
@ -1,38 +0,0 @@
|
|||
#include "Dave.hpp"
|
||||
|
||||
namespace pacman {
|
||||
|
||||
Dave::Dave()
|
||||
: Ghost(Atlas::Ghost::dave) {
|
||||
pos = initialPosition();
|
||||
}
|
||||
|
||||
double Dave::speed() const {
|
||||
if (state == State::Eyes)
|
||||
return 2;
|
||||
if (state == State::Frightened)
|
||||
return 0.5;
|
||||
return 0.75;
|
||||
}
|
||||
|
||||
void Dave::setTarget(Position pacManPos) {
|
||||
if (isInPen()) {
|
||||
target = penDoorPosition();
|
||||
return;
|
||||
}
|
||||
if (positionDistance(pos, pacManPos) > 8) {
|
||||
target = pacManPos;
|
||||
} else {
|
||||
target = scatterTarget();
|
||||
}
|
||||
}
|
||||
|
||||
Position Dave::initialPosition() const {
|
||||
return { 15.5, 14 };
|
||||
}
|
||||
|
||||
Position Dave::scatterTarget() const {
|
||||
return { 0, 30 };
|
||||
}
|
||||
|
||||
} // namespace pacman
|
|
@ -40,9 +40,6 @@ void Game::processEvents(InputState & inputState) {
|
|||
if (sf::Keyboard::isKeyPressed(sf::Keyboard::A)) {
|
||||
inputState.enableAI = !inputState.enableAI;
|
||||
}
|
||||
if (sf::Keyboard::isKeyPressed(sf::Keyboard::Q)) {
|
||||
exit(0);
|
||||
}
|
||||
|
||||
inputState.down = sf::Keyboard::isKeyPressed(sf::Keyboard::Key::Down);
|
||||
inputState.up = sf::Keyboard::isKeyPressed(sf::Keyboard::Key::Up);
|
||||
|
|
|
@ -18,11 +18,18 @@ void GameState::step(std::chrono::milliseconds delta) {
|
|||
if (!pacMan.hasDirection())
|
||||
return;
|
||||
|
||||
ghosts.setTarget(pacMan.positionInGrid(), pacMan.currentDirection());
|
||||
ghosts.update(delta);
|
||||
blinky.setTarget(pacMan.position());
|
||||
blinky.update(delta);
|
||||
pinky.setTarget(pacMan.positionInGrid(), pacMan.currentDirection());
|
||||
pinky.update(delta);
|
||||
inky.setTarget(pacMan.positionInGrid(), pacMan.currentDirection(), blinky.positionInGrid());
|
||||
inky.update(delta);
|
||||
|
||||
fruit.update(delta, score.eatenPellets);
|
||||
ghosts.checkCollision(*this);
|
||||
|
||||
checkCollision(blinky);
|
||||
checkCollision(pinky);
|
||||
checkCollision(inky);
|
||||
|
||||
eatPellets();
|
||||
eatFruit();
|
||||
|
@ -48,7 +55,9 @@ void GameState::handleDeathAnimation(std::chrono::milliseconds delta) {
|
|||
timeSinceDeath += delta;
|
||||
|
||||
if (timeSinceDeath.count() > 1000) {
|
||||
ghosts.reset();
|
||||
blinky.reset();
|
||||
pinky.reset();
|
||||
inky.reset();
|
||||
pacMan.reset();
|
||||
pacManAI.reset();
|
||||
timeSinceDeath = std::chrono::milliseconds(0);
|
||||
|
@ -65,7 +74,10 @@ void GameState::eatPellets() {
|
|||
if (superPellets.eatPelletAtPosition(pos)) {
|
||||
score.eatenPellets++;
|
||||
score.points += POWER_PELLET_POINTS;
|
||||
ghosts.frighten();
|
||||
|
||||
blinky.frighten();
|
||||
pinky.frighten();
|
||||
inky.frighten();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,41 +0,0 @@
|
|||
#include "GhostState.hpp"
|
||||
#include "GameState.hpp"
|
||||
|
||||
namespace pacman {
|
||||
|
||||
void GhostState::setTarget(GridPosition pacManPosition, Direction pacManDirection) {
|
||||
blinky.setTarget(gridPositionToPosition(pacManPosition));
|
||||
pinky.setTarget(pacManPosition, pacManDirection);
|
||||
inky.setTarget(pacManPosition, pacManDirection, blinky.positionInGrid());
|
||||
dave.setTarget(gridPositionToPosition(pacManPosition));
|
||||
}
|
||||
|
||||
void GhostState::update(std::chrono::milliseconds delta) {
|
||||
blinky.update(delta);
|
||||
pinky.update(delta);
|
||||
inky.update(delta);
|
||||
dave.update(delta);
|
||||
}
|
||||
|
||||
void GhostState::checkCollision(GameState & gameState) {
|
||||
gameState.checkCollision(blinky);
|
||||
gameState.checkCollision(pinky);
|
||||
gameState.checkCollision(inky);
|
||||
gameState.checkCollision(dave);
|
||||
}
|
||||
|
||||
void GhostState::reset(void) {
|
||||
blinky.reset();
|
||||
pinky.reset();
|
||||
inky.reset();
|
||||
dave.reset();
|
||||
}
|
||||
|
||||
void GhostState::frighten(void) {
|
||||
blinky.frighten();
|
||||
pinky.frighten();
|
||||
inky.frighten();
|
||||
dave.frighten();
|
||||
}
|
||||
|
||||
} // namespace pacman
|
|
@ -16,28 +16,22 @@ Direction PacManAI::suggestedDirection() const {
|
|||
|
||||
// This function is not yet implemented.
|
||||
// You will implement it as part of module 25.
|
||||
GridPosition PacManAI::pelletClosestToPacman(GridPosition position,
|
||||
std::vector<GridPosition> & pellets) {
|
||||
if (pellets.empty())
|
||||
return { 0, 0 };
|
||||
return *std::min_element(pellets.begin(), pellets.end(), [position](GridPosition a, GridPosition b) {
|
||||
return positionDistance(a, position) < positionDistance(b, position);
|
||||
});
|
||||
GridPosition PacManAI::pelletClosestToPacman(GridPosition,
|
||||
std::vector<GridPosition> &) {
|
||||
|
||||
return {0, 0};
|
||||
}
|
||||
|
||||
// This function is not yet implemented.
|
||||
// You will implement it as part of module 25.
|
||||
bool PacManAI::isValidMove(const Move & move) {
|
||||
return isWalkableForPacMan(move.position) && move.direction != oppositeDirection(direction);
|
||||
bool PacManAI::isValidMove(const Move &) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// This function is not yet implemented.
|
||||
// You will implement it as part of module 25.
|
||||
Direction PacManAI::optimalDirection(const std::array<Move, 4> & moves) {
|
||||
auto bestMove = std::min_element(moves.begin(), moves.end(), [](Move a, Move b) {
|
||||
return a.distanceToTarget < b.distanceToTarget;
|
||||
});
|
||||
return bestMove->direction;
|
||||
Direction PacManAI::optimalDirection(const std::array<Move, 4> &) {
|
||||
return Direction::NONE;
|
||||
}
|
||||
|
||||
void PacManAI::update(const PacMan & pacMan, const Pellets & pellets) {
|
||||
|
|
|
@ -12,7 +12,7 @@ enum class Ghost : unsigned int {
|
|||
blinky = 2,
|
||||
pinky = 3,
|
||||
inky = 4,
|
||||
dave = 5,
|
||||
clyde = 5,
|
||||
};
|
||||
|
||||
constexpr GridPosition pacman_right_wide = { 0, 0 };
|
||||
|
@ -46,7 +46,7 @@ constexpr GridPosition eyeSprite(Direction direction) {
|
|||
}
|
||||
|
||||
constexpr GridPosition ghostSprite(Ghost ghost, Direction direction, bool alternative) {
|
||||
assert(ghost >= Ghost::blinky && ghost <= Ghost::dave && "Invalid Ghost");
|
||||
assert(ghost >= Ghost::blinky && ghost <= Ghost::clyde && "Invalid Ghost");
|
||||
auto y = static_cast<size_t>(ghost);
|
||||
size_t x = 0;
|
||||
switch (direction) {
|
||||
|
|
|
@ -8,7 +8,6 @@
|
|||
|
||||
namespace pacman {
|
||||
|
||||
bool isWall(GridPosition point);
|
||||
bool isWalkableForPacMan(GridPosition point);
|
||||
bool isWalkableForGhost(GridPosition target_position, GridPosition current_position, bool isEyes);
|
||||
bool isInPen(GridPosition point);
|
||||
|
|
|
@ -1,20 +0,0 @@
|
|||
#pragma once
|
||||
|
||||
#include "Ghost.hpp"
|
||||
|
||||
namespace pacman {
|
||||
|
||||
class Dave final : public Ghost {
|
||||
public:
|
||||
Dave();
|
||||
void setTarget(Position pacManPos);
|
||||
|
||||
protected:
|
||||
double speed() const override;
|
||||
Position initialPosition() const override;
|
||||
|
||||
private:
|
||||
Position scatterTarget() const;
|
||||
};
|
||||
|
||||
} // namespace pacman
|
|
@ -1,10 +1,8 @@
|
|||
#pragma once
|
||||
|
||||
#include "Blinky.hpp"
|
||||
#include "Dave.hpp"
|
||||
#include "Fruits.hpp"
|
||||
#include "Ghost.hpp"
|
||||
#include "GhostState.hpp"
|
||||
#include "Inky.hpp"
|
||||
#include "InputState.hpp"
|
||||
#include "PacMan.hpp"
|
||||
|
@ -19,7 +17,9 @@ namespace pacman {
|
|||
struct GameState {
|
||||
void step(std::chrono::milliseconds delta);
|
||||
|
||||
GhostState ghosts;
|
||||
Blinky blinky;
|
||||
Pinky pinky;
|
||||
Inky inky;
|
||||
|
||||
PacMan pacMan;
|
||||
PacManAI pacManAI;
|
||||
|
|
|
@ -1,26 +0,0 @@
|
|||
#pragma once
|
||||
|
||||
#include "Blinky.hpp"
|
||||
#include "Dave.hpp"
|
||||
#include "Inky.hpp"
|
||||
#include "Pinky.hpp"
|
||||
|
||||
namespace pacman {
|
||||
|
||||
class GameState;
|
||||
|
||||
class GhostState {
|
||||
public:
|
||||
void setTarget(GridPosition pacManPosition, Direction pacManDirection);
|
||||
void update(std::chrono::milliseconds delta);
|
||||
void checkCollision(GameState & gameState);
|
||||
void reset();
|
||||
void frighten();
|
||||
|
||||
Blinky blinky;
|
||||
Pinky pinky;
|
||||
Inky inky;
|
||||
Dave dave;
|
||||
};
|
||||
|
||||
} // namespace pacman
|
|
@ -1,6 +1,4 @@
|
|||
#pragma once
|
||||
#include "Direction.hpp"
|
||||
|
||||
|
||||
namespace pacman {
|
||||
|
||||
|
|
|
@ -8,4 +8,4 @@ target_link_libraries(pacman_tests Catch2::Catch2 libpacman)
|
|||
|
||||
# This setup the tests on CI. We disable the AI tests
|
||||
# because you will have to implement them.
|
||||
add_test(NAME pacman_tests COMMAND pacman_tests)
|
||||
add_test(NAME pacman_tests COMMAND pacman_tests "~[AI]")
|
||||
|
|
|
@ -65,15 +65,4 @@ TEST_CASE("Teleport", "[board]") {
|
|||
const pacman::GridPosition result = pacman::teleport(portalLeft);
|
||||
REQUIRE(result.x == portalRight.x);
|
||||
}
|
||||
}
|
||||
|
||||
TEST_CASE("Is wall", "[board]") {
|
||||
REQUIRE(pacman::isWall(pacman::GridPosition{ 0, 0 }));
|
||||
REQUIRE(pacman::isWall(pacman::GridPosition{ 27, 30 }));
|
||||
REQUIRE(!pacman::isWall(pacman::GridPosition{ 1, 1 }));
|
||||
REQUIRE(!pacman::isWall(pacman::GridPosition{ 26, 29 }));
|
||||
REQUIRE(!pacman::isWall(pacman::GridPosition{ 0, 14 }));
|
||||
REQUIRE(!pacman::isWall(pacman::GridPosition{ 27, 14 }));
|
||||
REQUIRE(!pacman::isWall(pacman::GridPosition{ 11, 13 }));
|
||||
REQUIRE(!pacman::isWall(pacman::GridPosition{ 16, 15 }));
|
||||
}
|
||||
}
|
|
@ -7,7 +7,6 @@ TEST_CASE("Find pellet closest to PacMan", "[AI]") {
|
|||
PacManAI AI;
|
||||
using TestData = std::tuple<GridPosition, std::vector<GridPosition>, GridPosition>;
|
||||
auto data = GENERATE(
|
||||
TestData{{5, 5}, {}, {0, 0}},
|
||||
TestData{{5, 5}, {{5, 6}}, {5, 6}},
|
||||
TestData{{5, 5}, {{5, 5}}, {5, 5}},
|
||||
TestData{{5, 5}, {{0, 0}, {5, 6}}, {5, 6}},
|
||||
|
|
Loading…
Reference in a new issue