This is the Capstone project in the Udacity C++ Nanodegree Program. The code for this repo was inspired by this excellent StackOverflow post and set of responses.
This project is a modification of the Snake game.
The game consists of multiple levels maxLevels
. Advancing from one level to another requires foodPerLevel
food to be eaten. The speed of the snake increases with each level. Once the snake collides with itself or an obstacle, the game ends. The game can be paused at any time by pressing the spacebar. The game can be canceled by pressing the escape button.
There exist two types of obstacles: Ball
and Fence
. A ball is moving at a constant speed, bouncing back at the borders of the game. The fence is a static obstacle, which consists of a line-string with numCornersFence
corners.
Food
is an abstract class, which can be derived from to create any new food type. Currently, there is only Apple
implemented. It is created randomly within the playing field.
- cmake >= 3.7
- All OSes: click here for installation instructions
- make >= 4.1 (Linux, Mac), 3.81 (Windows)
- Linux: make is installed by default on most Linux distros
- Mac: install Xcode command line tools to get make
- Windows: Click here for installation instructions
- SDL2 >= 2.0
- All installation instructions can be found here
Note that for Linux, an
apt
orapt-get
installation is preferred to building from source. - gcc/g++ >= 5.4
- Linux: gcc / g++ is installed by default on most Linux distros
- Mac: same deal as make - install Xcode command line tools
- Windows: recommend using MinGW
- Clone this repo.
- Make a build directory in the top level directory:
mkdir build && cd build
- Compile:
cmake .. && make
- Run it:
./SnakeGame
.
This work is licensed under a Creative Commons Attribution-ShareAlike 4.0 International License.
The project demonstrates an understanding of C++ functions and control structures.
The code is organized into classes and functions (e.g. Fence::GenerateFence()
). Control structures such for loops (e.g. in Fence::GenerateFence()
code) or while loops (e.g. in Fence Constructor code) have been introduced where necessary.
The project uses Object Oriented Programming techniques.
Classes use appropriate access specifiers for class members.
Classes encapsulate behavior.
The code is organized into classes (e.g. Apple
, Fence
) to group data and access and modifiers to that data. The data might be position, shape or other. Class methods (e.g. Fence::GenerateFence()
) modify the data.
Class data members are usually made private (e.g. code) to prevent misuse. If members need to be accessed or modified from outside of the class, getter or setter functions have been defined (e.g. code).
Class constructors utilize member initialization lists.
Members are initialized within the constructor using initialization lists, see e.g. code.
Classes abstract implementation details from their interfaces.
Member functions document their effects through function names. Member functions do not change program state in undocumented ways. Const
has been used where possible to indicate and assert member functions that do not change the state of the object.
Classes follow an appropriate inheritance hierarchy.
Derived class functions override virtual base class functions.
Two inheritance hierarchies have been introduced
The abstract class Object
(deriving interfaces are Obstacle
and Food
) only contains pure virtual functions, see code. Obstacle
and Food
are still abstract classes and have been introduced to facilitate dynamic polymorphism (see code).
The second inheritance hierarchy are
- deriving classes
Fence
andBall
fromObstacle
, - deriving class
Apple
fromFood
.
Here, the pure virtual functions are overwritten, which is specified by the keyword overwrite, see e.g. code.
Templates generalize functions in the project.
The struct Point2d
(see code) has been defined with a template describing the type of the coordinates. This allows to use the struct for both integers and floats. Also, a function Collides
allows collision checks for two two template-based arguments of type Point2d
.
The project makes use of references in function declarations.
Arguments are usually passed as const references, such as in code, if the argument is not modified within the function.
The project uses destructors appropriately.
A destructor has been defined for class Renderer
to clean up memory for SDL-related raw pointers.
The project uses scope / Resource Acquisition Is Initialization (RAII) where appropriate.
The project uses either memory allocation on the stack or smart pointers. Thus, destructors clean up memory when leaving the scope.
The project follows the Rule of 5.
Class Renderer
requires the implementation of a deconstructor. To satisfy the rule of five, move constructor and move assignment operator have been implemented as well. Usage of the copy constructor and copy assignment operator has been forbidden.
The project uses smart pointers instead of raw pointers.
The game class contains vectors of smart pointers for food and obstacles. This allows to facilitate dynamic polymorphism and call functions such as Update()
or CollidesWithSnake()
for all types of food or obstacles. Shared Pointers have been selected over unique pointers to easily pass the food and obstacle containers to the Renderer::Render()
member function.