mirror of
https://github.com/Llewellynvdm/game-of-life.git
synced 2025-01-23 00:48:24 +00:00
C++ Final Project (first semester) - Coding Component
This commit is contained in:
parent
921e6db228
commit
e11c826163
4
.gitignore
vendored
4
.gitignore
vendored
@ -30,3 +30,7 @@
|
|||||||
*.exe
|
*.exe
|
||||||
*.out
|
*.out
|
||||||
*.app
|
*.app
|
||||||
|
|
||||||
|
# some locale folders
|
||||||
|
cmake-build-debug
|
||||||
|
.idea
|
6
CMakeLists.txt
Normal file
6
CMakeLists.txt
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
cmake_minimum_required(VERSION 3.16)
|
||||||
|
project(game-of-life)
|
||||||
|
|
||||||
|
set(CMAKE_CXX_STANDARD 14)
|
||||||
|
|
||||||
|
add_executable(game-of-life src/main.cpp src/Message.cpp src/Message.h src/color.h src/GetInput.cpp src/GetInput.h src/GameOfLife.cpp src/GameOfLife.h src/Game.cpp src/Game.h src/Patterns.cpp src/Patterns.h src/Util.cpp src/Util.h)
|
20
README.md
20
README.md
@ -1,2 +1,18 @@
|
|||||||
# game-of-life
|
# Game of life
|
||||||
This is a demonstration in C++ of a game called Game of life created by John Horton Conway in 1970
|
This is a demonstration in C++ of a game called [Game of life](https://en.wikipedia.org/wiki/Conway%27s_Game_of_Life) created by John Horton Conway in 1970
|
||||||
|
|
||||||
|
### The Game Rules
|
||||||
|
> At each step in time, the following transitions occur:
|
||||||
|
1. Any live cell with fewer than two live neighbours dies, as if by underpopulation.
|
||||||
|
2. Any live cell with two or three live neighbours lives on to the next generation.
|
||||||
|
3. Any live cell with more than three live neighbours dies, as if by overpopulation.
|
||||||
|
4. Any dead cell with exactly three live neighbours becomes a live cell, as if by reproduction.
|
||||||
|
|
||||||
|
### License & Copyright
|
||||||
|
- Written by [Llewellyn van der Merwe](https://github.com/Llewellynvdm), April 2020
|
||||||
|
- Copyright (C) 2020. All Rights Reserved
|
||||||
|
- License [GNU/GPL Version 2 or later](http://www.gnu.org/licenses/gpl-2.0.html)
|
||||||
|
|
||||||
|
### Thank You! (2020/04)
|
||||||
|
- Originally Forked [Mario Talevski](https://github.com/MarioTalevski/game-of-life)
|
||||||
|
- [Champlain College](https://www.champlain.edu/) [SDEV-240-81A](https://classlist.champlain.edu/show/course/number/SDEV_240)
|
5
patterns/glider.txt
Normal file
5
patterns/glider.txt
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
2 3
|
||||||
|
3 4
|
||||||
|
4 2
|
||||||
|
4 3
|
||||||
|
4 4
|
36
patterns/glidergun.txt
Normal file
36
patterns/glidergun.txt
Normal file
@ -0,0 +1,36 @@
|
|||||||
|
-2 26
|
||||||
|
-2 25
|
||||||
|
-3 26
|
||||||
|
-3 25
|
||||||
|
7 26
|
||||||
|
7 25
|
||||||
|
7 24
|
||||||
|
8 27
|
||||||
|
8 23
|
||||||
|
9 28
|
||||||
|
9 22
|
||||||
|
10 28
|
||||||
|
10 22
|
||||||
|
11 25
|
||||||
|
12 27
|
||||||
|
12 23
|
||||||
|
13 26
|
||||||
|
13 25
|
||||||
|
13 24
|
||||||
|
14 25
|
||||||
|
17 28
|
||||||
|
17 27
|
||||||
|
17 26
|
||||||
|
18 28
|
||||||
|
18 27
|
||||||
|
18 26
|
||||||
|
19 29
|
||||||
|
19 25
|
||||||
|
21 29
|
||||||
|
21 30
|
||||||
|
21 25
|
||||||
|
21 24
|
||||||
|
31 26
|
||||||
|
31 27
|
||||||
|
32 26
|
||||||
|
32 27
|
5
patterns/testboard.txt
Normal file
5
patterns/testboard.txt
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
5 4
|
||||||
|
7 4
|
||||||
|
5 5
|
||||||
|
6 5
|
||||||
|
5 6
|
75
src/Game.cpp
Normal file
75
src/Game.cpp
Normal file
@ -0,0 +1,75 @@
|
|||||||
|
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
||||||
|
* Champlain College SDEV-240-81A
|
||||||
|
*
|
||||||
|
* C++ Final Project (first semester) - Coding Component (2020/05/02)
|
||||||
|
*
|
||||||
|
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
||||||
|
*
|
||||||
|
* This is a demonstration in C++ of a game called
|
||||||
|
* Game of life created by John Horton Conway in 1970
|
||||||
|
* https://en.wikipedia.org/wiki/Conway%27s_Game_of_Life
|
||||||
|
*
|
||||||
|
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
||||||
|
*
|
||||||
|
* Written by Llewellyn van der Merwe <llewellyn.vandermerw@mymail.champlain.edu>, April 2020
|
||||||
|
* Copyright (C) 2020. All Rights Reserved
|
||||||
|
* License GNU/GPL Version 2 or later - http://www.gnu.org/licenses/gpl-2.0.html
|
||||||
|
*
|
||||||
|
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
|
||||||
|
|
||||||
|
// internal classes
|
||||||
|
#include "Game.h"
|
||||||
|
// libraries
|
||||||
|
#include <iostream>
|
||||||
|
|
||||||
|
using namespace std;
|
||||||
|
|
||||||
|
namespace GOL {
|
||||||
|
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
||||||
|
* I am trying out namespace just to see how it works :) any input would be great!
|
||||||
|
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
|
||||||
|
|
||||||
|
// check if we are still active
|
||||||
|
bool Game::isActive() const {
|
||||||
|
return Game::active;
|
||||||
|
}
|
||||||
|
|
||||||
|
// set game active state
|
||||||
|
void Game::setActive(bool active) {
|
||||||
|
Game::active = active;
|
||||||
|
}
|
||||||
|
|
||||||
|
// stop the board game
|
||||||
|
void Game::stop() {
|
||||||
|
this->setActive(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
// start the board game
|
||||||
|
void Game::start() {
|
||||||
|
this->setActive(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
// check if player is still playing
|
||||||
|
bool Game::isStillPlaying() const {
|
||||||
|
return Game::play;
|
||||||
|
}
|
||||||
|
|
||||||
|
// stop the whole game
|
||||||
|
void Game::stopPlaying() {
|
||||||
|
Game::play = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// start the whole game
|
||||||
|
void Game::startPlaying() {
|
||||||
|
Game::play = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// get the game color
|
||||||
|
const string &Game::getColor() const {
|
||||||
|
return Game::color;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Game::setColor(const string &color) {
|
||||||
|
Game::color = color;
|
||||||
|
}
|
||||||
|
}
|
100
src/Game.h
Normal file
100
src/Game.h
Normal file
@ -0,0 +1,100 @@
|
|||||||
|
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
||||||
|
* Champlain College SDEV-240-81A
|
||||||
|
*
|
||||||
|
* C++ Final Project (first semester) - Coding Component (2020/05/02)
|
||||||
|
*
|
||||||
|
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
||||||
|
*
|
||||||
|
* This is a demonstration in C++ of a game called
|
||||||
|
* Game of life created by John Horton Conway in 1970
|
||||||
|
* https://en.wikipedia.org/wiki/Conway%27s_Game_of_Life
|
||||||
|
*
|
||||||
|
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
||||||
|
*
|
||||||
|
* Written by Llewellyn van der Merwe <llewellyn.vandermerw@mymail.champlain.edu>, April 2020
|
||||||
|
* Copyright (C) 2020. All Rights Reserved
|
||||||
|
* License GNU/GPL Version 2 or later - http://www.gnu.org/licenses/gpl-2.0.html
|
||||||
|
*
|
||||||
|
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
|
||||||
|
|
||||||
|
#ifndef GOL_GAME_H
|
||||||
|
#define GOL_GAME_H
|
||||||
|
|
||||||
|
// internal classes
|
||||||
|
#include "color.h"
|
||||||
|
#include "Message.h"
|
||||||
|
// libraries
|
||||||
|
#include <iostream>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
using namespace std;
|
||||||
|
|
||||||
|
namespace GOL {
|
||||||
|
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
||||||
|
* I am trying out namespace just to see how it works :) any input would be great!
|
||||||
|
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
|
||||||
|
|
||||||
|
// class to manage game behaviour
|
||||||
|
class Game {
|
||||||
|
protected:
|
||||||
|
// playing status
|
||||||
|
bool play;
|
||||||
|
// game color
|
||||||
|
string color;
|
||||||
|
// switch to stop board game
|
||||||
|
bool active;
|
||||||
|
|
||||||
|
// start the whole game
|
||||||
|
void startPlaying();
|
||||||
|
|
||||||
|
// set active state
|
||||||
|
void setActive(bool active);
|
||||||
|
|
||||||
|
public:
|
||||||
|
// instantiate Message class pointer
|
||||||
|
Message *message;
|
||||||
|
|
||||||
|
// constructor
|
||||||
|
Game() {
|
||||||
|
// start playing
|
||||||
|
startPlaying();
|
||||||
|
// game color
|
||||||
|
setColor(COLOR_GREEN);
|
||||||
|
// set the board game to active
|
||||||
|
setActive(true);
|
||||||
|
// instantiate the message class on the heap as well
|
||||||
|
message = new Message;
|
||||||
|
}
|
||||||
|
|
||||||
|
// destructor
|
||||||
|
~Game() {
|
||||||
|
// remove message from heap memory
|
||||||
|
delete message;
|
||||||
|
}
|
||||||
|
|
||||||
|
// set the game color
|
||||||
|
void setColor(const string &color);
|
||||||
|
|
||||||
|
// get the game color
|
||||||
|
const string &getColor() const;
|
||||||
|
|
||||||
|
// start the board game
|
||||||
|
void start();
|
||||||
|
|
||||||
|
// stop the board game
|
||||||
|
void stop();
|
||||||
|
|
||||||
|
// stop the whole game
|
||||||
|
void stopPlaying();
|
||||||
|
|
||||||
|
// are we still playing
|
||||||
|
bool isStillPlaying() const;
|
||||||
|
|
||||||
|
// check if we are still active
|
||||||
|
bool isActive() const;
|
||||||
|
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#endif //GOL_GAME_H
|
234
src/GameOfLife.cpp
Normal file
234
src/GameOfLife.cpp
Normal file
@ -0,0 +1,234 @@
|
|||||||
|
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
||||||
|
* Champlain College SDEV-240-81A
|
||||||
|
*
|
||||||
|
* C++ Final Project (first semester) - Coding Component (2020/05/02)
|
||||||
|
*
|
||||||
|
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
||||||
|
*
|
||||||
|
* This is a demonstration in C++ of a game called
|
||||||
|
* Game of life created by John Horton Conway in 1970
|
||||||
|
* https://en.wikipedia.org/wiki/Conway%27s_Game_of_Life
|
||||||
|
*
|
||||||
|
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
||||||
|
*
|
||||||
|
* Written by Llewellyn van der Merwe <llewellyn.vandermerw@mymail.champlain.edu>, April 2020
|
||||||
|
* Copyright (C) 2020. All Rights Reserved
|
||||||
|
* License GNU/GPL Version 2 or later - http://www.gnu.org/licenses/gpl-2.0.html
|
||||||
|
*
|
||||||
|
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
|
||||||
|
|
||||||
|
#include "GameOfLife.h"
|
||||||
|
|
||||||
|
namespace GOL {
|
||||||
|
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
||||||
|
* I am trying out namespace just to see how it works :) any input would be great!
|
||||||
|
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
|
||||||
|
|
||||||
|
// set the active coordinate
|
||||||
|
void GameOfLife::set(int x, int y) {
|
||||||
|
GameOfLife::activeState[x + GameOfLife::center][y + GameOfLife::center] = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// unset any coordinate
|
||||||
|
void GameOfLife::unset(int x, int y) {
|
||||||
|
GameOfLife::activeState[x + GameOfLife::center][y + GameOfLife::center] = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// reset the board
|
||||||
|
void GameOfLife::reset() {
|
||||||
|
for (int x = 0; x < GameOfLife::size; x++) {
|
||||||
|
for (int y = 0; y < GameOfLife::size; y++) {
|
||||||
|
GameOfLife::previousState[x][y] = false;
|
||||||
|
GameOfLife::activeState[x][y] = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// any moment reset is called we also re-start the game internally
|
||||||
|
this->start();
|
||||||
|
// do some house cleaning resets
|
||||||
|
this->setActiveInfinity(false);
|
||||||
|
this->setInfinityCounter(0);
|
||||||
|
this->setInfinity(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
// print the board with active coordinates
|
||||||
|
void GameOfLife::print(int action) {
|
||||||
|
if (this->isActive()) {
|
||||||
|
// make sure we stay in same color
|
||||||
|
cout << this->getColor();
|
||||||
|
// stop game if all are dead
|
||||||
|
if (action == 1) {
|
||||||
|
this->stop();
|
||||||
|
}
|
||||||
|
// loop over the y axis
|
||||||
|
for (int y = GameOfLife::boardSize; y > 0; y--) {
|
||||||
|
// loop over the x axis
|
||||||
|
for (int x = 1; x < GameOfLife::boardSize; x++) {
|
||||||
|
if (x == 1) {
|
||||||
|
// add line numbers
|
||||||
|
if (action == 3) {
|
||||||
|
if (y < 10) {
|
||||||
|
cout << y << " ";
|
||||||
|
} else {
|
||||||
|
cout << y;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
cout << " ";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// check if a cell is active/alive
|
||||||
|
if (GameOfLife::activeState[x + GameOfLife::center][y + GameOfLife::center]) {
|
||||||
|
cout << " O ";
|
||||||
|
// check if one cell in view is still active (and not still)
|
||||||
|
if (!GameOfLife::previousState[x + GameOfLife::center][y + GameOfLife::center] ||
|
||||||
|
this->isActiveInfinity()) {
|
||||||
|
// if this is infinity
|
||||||
|
if (this->isActiveInfinity()) {
|
||||||
|
this->decrementInfinity();
|
||||||
|
}
|
||||||
|
this->start();
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
cout << " . ";
|
||||||
|
}
|
||||||
|
// print end of line when at the end of line
|
||||||
|
if (x == GameOfLife::boardSize - 1) {
|
||||||
|
cout << endl;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// add bottom line of numbers if needed
|
||||||
|
if (action == 3) {
|
||||||
|
cout << " ";
|
||||||
|
for (int x = 1; x < GameOfLife::boardSize; x++) {
|
||||||
|
if (x < 10) {
|
||||||
|
cout << " " << x << " ";
|
||||||
|
} else {
|
||||||
|
cout << " " << x;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
cout << endl;
|
||||||
|
}
|
||||||
|
// if this is infinity
|
||||||
|
if (action == 1 && this->isActiveInfinity() && this->getInfinityCounter() < 0) {
|
||||||
|
// when the preset infinity controller switches
|
||||||
|
// reach its conclusion stop the game
|
||||||
|
// so the player can choose another pattern
|
||||||
|
this->stop();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// copy the active state to the previous state array
|
||||||
|
void GameOfLife::copyState() {
|
||||||
|
// loop over the entire x axis of the board
|
||||||
|
for (int x = 0; x < GameOfLife::size; x++) {
|
||||||
|
// loop over the entire y axis of the board
|
||||||
|
for (int y = 0; y < GameOfLife::size; y++) {
|
||||||
|
// copy the value over to the previous state
|
||||||
|
GameOfLife::previousState[x][y] = GameOfLife::activeState[x][y];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// set the board active state
|
||||||
|
void GameOfLife::setState() {
|
||||||
|
// make sure we have the active state copied
|
||||||
|
this->copyState();
|
||||||
|
// check every cell on the board
|
||||||
|
// loop over the entire x axis of the board
|
||||||
|
for (int x = 1; x < GameOfLife::size; x++) {
|
||||||
|
// loop over the entire y axis of the board
|
||||||
|
for (int y = 1; y < GameOfLife::size; y++) {
|
||||||
|
int alive = 0;
|
||||||
|
// loop to check all eight neighbours
|
||||||
|
// . . .
|
||||||
|
// . 0 .
|
||||||
|
// . . .
|
||||||
|
// the dots are the neighbours
|
||||||
|
// zero is the active cell
|
||||||
|
for (int x2 = -1; x2 < 2; x2++) { // this loop increments the x axis lookup
|
||||||
|
for (int y2 = -1; y2 < 2; y2++) { // this loop increments the y axis lookup
|
||||||
|
// when x and y are 0 then
|
||||||
|
// do not check since it is
|
||||||
|
// the current active cell
|
||||||
|
if (!(x2 == 0 && y2 == 0)) {
|
||||||
|
// check if this neighbour was alive
|
||||||
|
if (GameOfLife::previousState[x + x2][y + y2]) {
|
||||||
|
// when alive we increment the alive value
|
||||||
|
// which we later will use to act upon
|
||||||
|
++alive;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// now let's act upon the alive status
|
||||||
|
if (alive < 2) {
|
||||||
|
// Any live cell with fewer than two live neighbours dies, as if caused by under-population.
|
||||||
|
// what ever that means...
|
||||||
|
GameOfLife::activeState[x][y] = false;
|
||||||
|
} else if (alive == 3) {
|
||||||
|
// Any live cell with three live neighbours lives on to the next generation.
|
||||||
|
// what ever that means...
|
||||||
|
GameOfLife::activeState[x][y] = true;
|
||||||
|
} else if (alive > 3) {
|
||||||
|
// Any live cell with more than three live neighbours dies, as if by over-population.
|
||||||
|
// Which is not true, I have eight children and a very bright future!!!
|
||||||
|
// We were made to be fruitful Genesis 1:28 (in real Life)
|
||||||
|
// but in this game...
|
||||||
|
GameOfLife::activeState[x][y] = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// get view board size
|
||||||
|
int GameOfLife::getViewSize() {
|
||||||
|
// return string
|
||||||
|
return GameOfLife::boardSize;
|
||||||
|
}
|
||||||
|
|
||||||
|
// get view board size
|
||||||
|
int GameOfLife::getViewArea() {
|
||||||
|
return GameOfLife::boardSize * GameOfLife::boardSize;
|
||||||
|
}
|
||||||
|
|
||||||
|
// get settable board area
|
||||||
|
int GameOfLife::getSettableArea() {
|
||||||
|
return GameOfLife::boardSize * 3;
|
||||||
|
}
|
||||||
|
|
||||||
|
// check if infinity is set
|
||||||
|
bool GameOfLife::isInfinitySet() const {
|
||||||
|
return GameOfLife::infinitySet;
|
||||||
|
}
|
||||||
|
|
||||||
|
// set infinity
|
||||||
|
void GameOfLife::setInfinity(bool infinitySet) {
|
||||||
|
GameOfLife::infinitySet = infinitySet;
|
||||||
|
}
|
||||||
|
|
||||||
|
// check if infinity is active
|
||||||
|
bool GameOfLife::isActiveInfinity() const {
|
||||||
|
return activeInfinity;
|
||||||
|
}
|
||||||
|
|
||||||
|
// set the infinity active state
|
||||||
|
void GameOfLife::setActiveInfinity(bool activeInfinity) {
|
||||||
|
GameOfLife::activeInfinity = activeInfinity;
|
||||||
|
}
|
||||||
|
|
||||||
|
// get the infinity counter value
|
||||||
|
long GameOfLife::getInfinityCounter() const {
|
||||||
|
return GameOfLife::infinityCounter;
|
||||||
|
}
|
||||||
|
|
||||||
|
// set the infinity counter value
|
||||||
|
void GameOfLife::setInfinityCounter(long infinity) {
|
||||||
|
GameOfLife::infinityCounter = infinity;
|
||||||
|
}
|
||||||
|
|
||||||
|
// decrement infinity counter value
|
||||||
|
void GameOfLife::decrementInfinity() {
|
||||||
|
GameOfLife::infinityCounter--;
|
||||||
|
}
|
||||||
|
}
|
112
src/GameOfLife.h
Normal file
112
src/GameOfLife.h
Normal file
@ -0,0 +1,112 @@
|
|||||||
|
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
||||||
|
* Champlain College SDEV-240-81A
|
||||||
|
*
|
||||||
|
* C++ Final Project (first semester) - Coding Component (2020/05/02)
|
||||||
|
*
|
||||||
|
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
||||||
|
*
|
||||||
|
* This is a demonstration in C++ of a game called
|
||||||
|
* Game of life created by John Horton Conway in 1970
|
||||||
|
* https://en.wikipedia.org/wiki/Conway%27s_Game_of_Life
|
||||||
|
*
|
||||||
|
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
||||||
|
*
|
||||||
|
* Written by Llewellyn van der Merwe <llewellyn.vandermerw@mymail.champlain.edu>, April 2020
|
||||||
|
* Copyright (C) 2020. All Rights Reserved
|
||||||
|
* License GNU/GPL Version 2 or later - http://www.gnu.org/licenses/gpl-2.0.html
|
||||||
|
*
|
||||||
|
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
|
||||||
|
|
||||||
|
#ifndef GOL_GAMEOFLIFE_H
|
||||||
|
#define GOL_GAMEOFLIFE_H
|
||||||
|
|
||||||
|
#include "Game.h"
|
||||||
|
|
||||||
|
namespace GOL {
|
||||||
|
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
||||||
|
* I am trying out namespace just to see how it works :) any input would be great!
|
||||||
|
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
|
||||||
|
|
||||||
|
class GameOfLife : public Game {
|
||||||
|
private:
|
||||||
|
// the board game size
|
||||||
|
static const int boardSize = 30;
|
||||||
|
// hidden size to center the view
|
||||||
|
static const int center = boardSize * 4;
|
||||||
|
// hidden size to be able to move gliders and ships out of view
|
||||||
|
static const int size = boardSize * 9;
|
||||||
|
// active state arrays
|
||||||
|
bool activeState[size][size] = {};
|
||||||
|
bool previousState[size][size] = {};
|
||||||
|
// has infinity been set?
|
||||||
|
bool infinitySet;
|
||||||
|
signed long infinityCounter;
|
||||||
|
// infinity switches
|
||||||
|
bool activeInfinity;
|
||||||
|
|
||||||
|
// copy the active state to the previous state array
|
||||||
|
void copyState();
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
// constructor
|
||||||
|
GameOfLife() {
|
||||||
|
// turn off infinity
|
||||||
|
setActiveInfinity(false);
|
||||||
|
setInfinity(false);
|
||||||
|
setInfinityCounter(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
// destructor
|
||||||
|
~GameOfLife() {}
|
||||||
|
|
||||||
|
// set the active coordinates
|
||||||
|
void set(int x, int y);
|
||||||
|
|
||||||
|
// unset any coordinates
|
||||||
|
void unset(int x, int y);
|
||||||
|
|
||||||
|
// reset the board
|
||||||
|
void reset();
|
||||||
|
|
||||||
|
// print the board with active coordinates
|
||||||
|
void print(int action = 1);
|
||||||
|
|
||||||
|
// set the board active state
|
||||||
|
void setState();
|
||||||
|
|
||||||
|
// get view board size
|
||||||
|
int getViewSize();
|
||||||
|
|
||||||
|
// get view board area
|
||||||
|
int getViewArea();
|
||||||
|
|
||||||
|
// get settable board area
|
||||||
|
int getSettableArea();
|
||||||
|
|
||||||
|
// check if infinity is set
|
||||||
|
bool isInfinitySet() const;
|
||||||
|
|
||||||
|
// set infinity
|
||||||
|
void setInfinity(bool infinitySet);
|
||||||
|
|
||||||
|
// check if infinity is active
|
||||||
|
bool isActiveInfinity() const;
|
||||||
|
|
||||||
|
// set the infinity active state
|
||||||
|
void setActiveInfinity(bool activeInfinity);
|
||||||
|
|
||||||
|
// get the infinity counter value
|
||||||
|
long getInfinityCounter() const;
|
||||||
|
|
||||||
|
// set the infinity counter value
|
||||||
|
void setInfinityCounter(long infinity);
|
||||||
|
|
||||||
|
// decrement infinity counter value
|
||||||
|
void decrementInfinity();
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#endif //GOL_GAMEOFLIFE_H
|
32
src/GetInput.cpp
Normal file
32
src/GetInput.cpp
Normal file
@ -0,0 +1,32 @@
|
|||||||
|
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
||||||
|
* Champlain College SDEV-240-81A
|
||||||
|
*
|
||||||
|
* C++ Final Project (first semester) - Coding Component (2020/05/02)
|
||||||
|
*
|
||||||
|
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
||||||
|
*
|
||||||
|
* This is a demonstration in C++ of a game called
|
||||||
|
* Game of life created by John Horton Conway in 1970
|
||||||
|
* https://en.wikipedia.org/wiki/Conway%27s_Game_of_Life
|
||||||
|
*
|
||||||
|
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
||||||
|
*
|
||||||
|
* Written by Llewellyn van der Merwe <llewellyn.vandermerw@mymail.champlain.edu>, April 2020
|
||||||
|
* Copyright (C) 2020. All Rights Reserved
|
||||||
|
* License GNU/GPL Version 2 or later - http://www.gnu.org/licenses/gpl-2.0.html
|
||||||
|
*
|
||||||
|
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
|
||||||
|
|
||||||
|
// internal classes
|
||||||
|
#include "GetInput.h"
|
||||||
|
|
||||||
|
namespace GOL {
|
||||||
|
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
||||||
|
* I am trying out namespace just to see how it works :) any input would be great!
|
||||||
|
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
|
||||||
|
|
||||||
|
// get the message string
|
||||||
|
string GetInput::get() const {
|
||||||
|
return input;
|
||||||
|
}
|
||||||
|
}
|
65
src/GetInput.h
Normal file
65
src/GetInput.h
Normal file
@ -0,0 +1,65 @@
|
|||||||
|
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
||||||
|
* Champlain College SDEV-240-81A
|
||||||
|
*
|
||||||
|
* C++ Final Project (first semester) - Coding Component (2020/05/02)
|
||||||
|
*
|
||||||
|
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
||||||
|
*
|
||||||
|
* This is a demonstration in C++ of a game called
|
||||||
|
* Game of life created by John Horton Conway in 1970
|
||||||
|
* https://en.wikipedia.org/wiki/Conway%27s_Game_of_Life
|
||||||
|
*
|
||||||
|
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
||||||
|
*
|
||||||
|
* Written by Llewellyn van der Merwe <llewellyn.vandermerw@mymail.champlain.edu>, April 2020
|
||||||
|
* Copyright (C) 2020. All Rights Reserved
|
||||||
|
* License GNU/GPL Version 2 or later - http://www.gnu.org/licenses/gpl-2.0.html
|
||||||
|
*
|
||||||
|
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
|
||||||
|
|
||||||
|
#ifndef GOL_GETINPUT_H
|
||||||
|
#define GOL_GETINPUT_H
|
||||||
|
|
||||||
|
// internal classes
|
||||||
|
#include "Message.h"
|
||||||
|
// libraries
|
||||||
|
#include <iostream>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
using namespace std;
|
||||||
|
|
||||||
|
namespace GOL {
|
||||||
|
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
||||||
|
* I am trying out namespace just to see how it works :) any input would be great!
|
||||||
|
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
|
||||||
|
|
||||||
|
class GetInput {
|
||||||
|
private:
|
||||||
|
string input;
|
||||||
|
public:
|
||||||
|
// constructor
|
||||||
|
GetInput(string question = "") {
|
||||||
|
// set message
|
||||||
|
Message ask(question);
|
||||||
|
// print question
|
||||||
|
ask.print(0);
|
||||||
|
// get the input requested
|
||||||
|
cin >> input;
|
||||||
|
}
|
||||||
|
|
||||||
|
GetInput(Message &question) {
|
||||||
|
// print question
|
||||||
|
question.print(0);
|
||||||
|
// get the input requested
|
||||||
|
cin >> input;
|
||||||
|
}
|
||||||
|
|
||||||
|
// destructor
|
||||||
|
~GetInput() {}
|
||||||
|
|
||||||
|
// get method
|
||||||
|
string get() const;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif //GOL_GETINPUT_H
|
103
src/Message.cpp
Normal file
103
src/Message.cpp
Normal file
@ -0,0 +1,103 @@
|
|||||||
|
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
||||||
|
* Champlain College SDEV-240-81A
|
||||||
|
*
|
||||||
|
* C++ Final Project (first semester) - Coding Component (2020/05/02)
|
||||||
|
*
|
||||||
|
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
||||||
|
*
|
||||||
|
* This is a demonstration in C++ of a game called
|
||||||
|
* Game of life created by John Horton Conway in 1970
|
||||||
|
* https://en.wikipedia.org/wiki/Conway%27s_Game_of_Life
|
||||||
|
*
|
||||||
|
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
||||||
|
*
|
||||||
|
* Written by Llewellyn van der Merwe <llewellyn.vandermerw@mymail.champlain.edu>, April 2020
|
||||||
|
* Copyright (C) 2020. All Rights Reserved
|
||||||
|
* License GNU/GPL Version 2 or later - http://www.gnu.org/licenses/gpl-2.0.html
|
||||||
|
*
|
||||||
|
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
|
||||||
|
|
||||||
|
// internal classes
|
||||||
|
#include "Message.h"
|
||||||
|
// libraries
|
||||||
|
#include <iomanip>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
namespace GOL {
|
||||||
|
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
||||||
|
* I am trying out namespace just to see how it works :) any input would be great!
|
||||||
|
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
|
||||||
|
|
||||||
|
// print to terminal the message
|
||||||
|
void Message::print(int addNewLine) {
|
||||||
|
// stay in the terminal color
|
||||||
|
cout << color;
|
||||||
|
// only print the message
|
||||||
|
if (addNewLine == 1) {
|
||||||
|
cout << message << endl;
|
||||||
|
} else {
|
||||||
|
cout << message;
|
||||||
|
}
|
||||||
|
// empty the message value
|
||||||
|
message = "";
|
||||||
|
}
|
||||||
|
|
||||||
|
// get the message
|
||||||
|
string Message::get(int addNewLine) {
|
||||||
|
// get message
|
||||||
|
string tmp = message;
|
||||||
|
// empty the message value
|
||||||
|
message = "";
|
||||||
|
// only print the message
|
||||||
|
if (addNewLine == 1) {
|
||||||
|
return tmp + "\n";
|
||||||
|
} else {
|
||||||
|
return tmp;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// add a line to the message
|
||||||
|
Message *Message::add(string line, string newline) {
|
||||||
|
if ("LINE" == line) {
|
||||||
|
// add a line
|
||||||
|
line = "";
|
||||||
|
message += this->addPadding(line, max_length, spacer_line) + newline;
|
||||||
|
} else {
|
||||||
|
// store the string
|
||||||
|
message += this->prepLine(line, spacer) + newline;
|
||||||
|
}
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
// prepare a string before adding
|
||||||
|
string Message::prepLine(string &str, string &padding) {
|
||||||
|
// add padding
|
||||||
|
return this->addPadding(3, str, padding);
|
||||||
|
}
|
||||||
|
|
||||||
|
// to model a question for the get input class
|
||||||
|
string Message::ask(string question) {
|
||||||
|
// stay in the terminal color
|
||||||
|
cout << color;
|
||||||
|
return addPadding(3, question, spacer);
|
||||||
|
}
|
||||||
|
|
||||||
|
// add padding in front of string
|
||||||
|
string Message::addPadding(int length, string str, string &padding) {
|
||||||
|
for (int i = 0; i < length; i++) {
|
||||||
|
str = padding + str;
|
||||||
|
}
|
||||||
|
return str;
|
||||||
|
}
|
||||||
|
|
||||||
|
// add padding behind string
|
||||||
|
string Message::addPadding(string str, int length, string &padding) {
|
||||||
|
// get the string length
|
||||||
|
int string_length = str.length();
|
||||||
|
for (int i = string_length; i < length; i++) {
|
||||||
|
str += padding;
|
||||||
|
}
|
||||||
|
return str;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
90
src/Message.h
Normal file
90
src/Message.h
Normal file
@ -0,0 +1,90 @@
|
|||||||
|
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
||||||
|
* Champlain College SDEV-240-81A
|
||||||
|
*
|
||||||
|
* C++ Final Project (first semester) - Coding Component (2020/05/02)
|
||||||
|
*
|
||||||
|
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
||||||
|
*
|
||||||
|
* This is a demonstration in C++ of a game called
|
||||||
|
* Game of life created by John Horton Conway in 1970
|
||||||
|
* https://en.wikipedia.org/wiki/Conway%27s_Game_of_Life
|
||||||
|
*
|
||||||
|
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
||||||
|
*
|
||||||
|
* Written by Llewellyn van der Merwe <llewellyn.vandermerw@mymail.champlain.edu>, April 2020
|
||||||
|
* Copyright (C) 2020. All Rights Reserved
|
||||||
|
* License GNU/GPL Version 2 or later - http://www.gnu.org/licenses/gpl-2.0.html
|
||||||
|
*
|
||||||
|
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
|
||||||
|
|
||||||
|
#ifndef GOL_MESSAGE_H
|
||||||
|
#define GOL_MESSAGE_H
|
||||||
|
|
||||||
|
// internal classes
|
||||||
|
#include "color.h"
|
||||||
|
// libraries
|
||||||
|
#include <iostream>
|
||||||
|
#include <iomanip>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
using namespace std;
|
||||||
|
|
||||||
|
namespace GOL {
|
||||||
|
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
||||||
|
* I am trying out namespace just to see how it works :) any input would be great!
|
||||||
|
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
|
||||||
|
|
||||||
|
// class to manage all messages
|
||||||
|
class Message {
|
||||||
|
private:
|
||||||
|
// message color
|
||||||
|
string color = COLOR_GREEN;
|
||||||
|
string color_reset = COLOR_RESET;
|
||||||
|
// the message string
|
||||||
|
string message;
|
||||||
|
// line max length
|
||||||
|
int max_length = 95;
|
||||||
|
// line character
|
||||||
|
string spacer_line = "-";
|
||||||
|
// string ending
|
||||||
|
string end = "#";
|
||||||
|
|
||||||
|
// prep string
|
||||||
|
string prepLine(string &str, string &padding);
|
||||||
|
|
||||||
|
public:
|
||||||
|
// space character
|
||||||
|
string spacer = " ";
|
||||||
|
// string beginning
|
||||||
|
string begin = "#";
|
||||||
|
|
||||||
|
// constructor
|
||||||
|
Message(string lines = "") : message{lines} {
|
||||||
|
cout << color;
|
||||||
|
}
|
||||||
|
|
||||||
|
// destructor
|
||||||
|
~Message() {
|
||||||
|
cout << color_reset;
|
||||||
|
}
|
||||||
|
|
||||||
|
// print method
|
||||||
|
void print(int addNewLine = 1);
|
||||||
|
|
||||||
|
// get message
|
||||||
|
string get(int addNewLine = 1);
|
||||||
|
|
||||||
|
// add line method
|
||||||
|
Message *add(string line, string newline = "\n");
|
||||||
|
|
||||||
|
// to model a question for the get input class
|
||||||
|
string ask(string question);
|
||||||
|
|
||||||
|
// add padding around string
|
||||||
|
string addPadding(string str, int length, string &padding);
|
||||||
|
|
||||||
|
string addPadding(int length, string str, string &padding);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif //GOL_MESSAGE_H
|
432
src/Patterns.cpp
Normal file
432
src/Patterns.cpp
Normal file
@ -0,0 +1,432 @@
|
|||||||
|
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
||||||
|
* Champlain College SDEV-240-81A
|
||||||
|
*
|
||||||
|
* C++ Final Project (first semester) - Coding Component (2020/05/02)
|
||||||
|
*
|
||||||
|
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
||||||
|
*
|
||||||
|
* This is a demonstration in C++ of a game called
|
||||||
|
* Game of life created by John Horton Conway in 1970
|
||||||
|
* https://en.wikipedia.org/wiki/Conway%27s_Game_of_Life
|
||||||
|
*
|
||||||
|
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
||||||
|
*
|
||||||
|
* Written by Llewellyn van der Merwe <llewellyn.vandermerw@mymail.champlain.edu>, April 2020
|
||||||
|
* Copyright (C) 2020. All Rights Reserved
|
||||||
|
* License GNU/GPL Version 2 or later - http://www.gnu.org/licenses/gpl-2.0.html
|
||||||
|
*
|
||||||
|
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
|
||||||
|
|
||||||
|
// internal classes
|
||||||
|
#include "Patterns.h"
|
||||||
|
#include "GameOfLife.h"
|
||||||
|
// libraries
|
||||||
|
#include <map>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
using namespace std;
|
||||||
|
|
||||||
|
namespace GOL {
|
||||||
|
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
||||||
|
* I am trying out namespace just to see how it works :) any input would be great!
|
||||||
|
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
|
||||||
|
|
||||||
|
// set the preset pattern
|
||||||
|
bool Patterns::setPreset(int pattern, GameOfLife *game) {
|
||||||
|
// we have the infinity stuff set
|
||||||
|
game->setInfinity(true);
|
||||||
|
// default means pattern does not yet exist
|
||||||
|
switch (pattern) {
|
||||||
|
case 1:
|
||||||
|
return this->testBoard(game);
|
||||||
|
case 2:
|
||||||
|
return this->blinker(game);
|
||||||
|
case 3:
|
||||||
|
return this->toad(game);
|
||||||
|
case 4:
|
||||||
|
return this->beacon(game);
|
||||||
|
case 5:
|
||||||
|
return this->pulsar(game);
|
||||||
|
case 6:
|
||||||
|
return this->pentaDecathlon(game);
|
||||||
|
case 7:
|
||||||
|
return this->gliderGun(game);
|
||||||
|
case 8:
|
||||||
|
return this->glidersEaters(game);
|
||||||
|
case 9:
|
||||||
|
return this->glider(game);
|
||||||
|
case 10:
|
||||||
|
return this->lightWeightSpaceship(game);
|
||||||
|
case 11:
|
||||||
|
return this->middleWeightSpaceship(game);
|
||||||
|
case 12:
|
||||||
|
return this->heavyWeightSpaceship(game);
|
||||||
|
default:
|
||||||
|
game->setInfinity(false);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// set the preset pattern
|
||||||
|
map<int, string> Patterns::getPresets() {
|
||||||
|
map<int, string> presets;
|
||||||
|
presets[1] = "Test Board (fun)";
|
||||||
|
presets[2] = "Blinker (Oscillator - infinity)";
|
||||||
|
presets[3] = "Toad (Oscillator - infinity)";
|
||||||
|
presets[4] = "Beacon (Oscillator - infinity)";
|
||||||
|
presets[5] = "Pulsar (Oscillator - infinity)";
|
||||||
|
presets[6] = "Penta-decathlon (Oscillator - infinity)";
|
||||||
|
presets[7] = "Glider Gun (fun)";
|
||||||
|
presets[8] = "Gliders Eaters (fun)";
|
||||||
|
presets[9] = "Glider (Spaceship)";
|
||||||
|
presets[10] = "Light Weight (Spaceship)";
|
||||||
|
presets[11] = "Middle Weight (Spaceship)";
|
||||||
|
presets[12] = "Heavy Weight (Spaceship)";
|
||||||
|
return presets;
|
||||||
|
}
|
||||||
|
|
||||||
|
// set the test board pattern
|
||||||
|
bool Patterns::testBoard(GameOfLife *game) {
|
||||||
|
game->set(11, 12);
|
||||||
|
game->set(11, 14);
|
||||||
|
game->set(11, 13);
|
||||||
|
game->set(12, 13);
|
||||||
|
game->set(13, 12);
|
||||||
|
// deal with infinity
|
||||||
|
game->setActiveInfinity(false);
|
||||||
|
game->setInfinityCounter(0);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// set the blinker pattern
|
||||||
|
bool Patterns::blinker(GameOfLife *game) {
|
||||||
|
game->set(5, 5);
|
||||||
|
game->set(5, 6);
|
||||||
|
game->set(5, 7);
|
||||||
|
// deal with infinity
|
||||||
|
game->setActiveInfinity(true);
|
||||||
|
game->setInfinityCounter(3 * 20);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// set the toad pattern
|
||||||
|
bool Patterns::toad(GameOfLife *game) {
|
||||||
|
game->set(4, 7);
|
||||||
|
game->set(5, 5);
|
||||||
|
game->set(5, 8);
|
||||||
|
game->set(6, 5);
|
||||||
|
game->set(6, 8);
|
||||||
|
game->set(7, 6);
|
||||||
|
// deal with infinity
|
||||||
|
game->setActiveInfinity(true);
|
||||||
|
game->setInfinityCounter(6 * 20);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// set the beacon pattern
|
||||||
|
bool Patterns::beacon(GameOfLife *game) {
|
||||||
|
game->set(4, 5);
|
||||||
|
game->set(4, 6);
|
||||||
|
game->set(5, 5);
|
||||||
|
game->set(6, 8);
|
||||||
|
game->set(7, 8);
|
||||||
|
game->set(7, 7);
|
||||||
|
// deal with infinity
|
||||||
|
game->setActiveInfinity(true);
|
||||||
|
game->setInfinityCounter(6 * 20);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// set the pulsar pattern
|
||||||
|
bool Patterns::pulsar(GameOfLife *game) {
|
||||||
|
// outer rings
|
||||||
|
game->set(8, 6);
|
||||||
|
game->set(9, 6);
|
||||||
|
game->set(10, 6);
|
||||||
|
|
||||||
|
game->set(14, 6);
|
||||||
|
game->set(15, 6);
|
||||||
|
game->set(16, 6);
|
||||||
|
|
||||||
|
game->set(18, 8);
|
||||||
|
game->set(18, 9);
|
||||||
|
game->set(18, 10);
|
||||||
|
|
||||||
|
game->set(18, 14);
|
||||||
|
game->set(18, 15);
|
||||||
|
game->set(18, 16);
|
||||||
|
|
||||||
|
game->set(6, 8);
|
||||||
|
game->set(6, 9);
|
||||||
|
game->set(6, 10);
|
||||||
|
|
||||||
|
game->set(6, 14);
|
||||||
|
game->set(6, 15);
|
||||||
|
game->set(6, 16);
|
||||||
|
|
||||||
|
game->set(8, 18);
|
||||||
|
game->set(9, 18);
|
||||||
|
game->set(10, 18);
|
||||||
|
|
||||||
|
game->set(14, 18);
|
||||||
|
game->set(15, 18);
|
||||||
|
game->set(16, 18);
|
||||||
|
|
||||||
|
// inner rings
|
||||||
|
game->set(8, 11);
|
||||||
|
game->set(9, 11);
|
||||||
|
game->set(10, 11);
|
||||||
|
|
||||||
|
game->set(14, 11);
|
||||||
|
game->set(15, 11);
|
||||||
|
game->set(16, 11);
|
||||||
|
|
||||||
|
game->set(13, 8);
|
||||||
|
game->set(13, 9);
|
||||||
|
game->set(13, 10);
|
||||||
|
|
||||||
|
game->set(13, 14);
|
||||||
|
game->set(13, 15);
|
||||||
|
game->set(13, 16);
|
||||||
|
|
||||||
|
game->set(11, 8);
|
||||||
|
game->set(11, 9);
|
||||||
|
game->set(11, 10);
|
||||||
|
|
||||||
|
game->set(11, 14);
|
||||||
|
game->set(11, 15);
|
||||||
|
game->set(11, 16);
|
||||||
|
|
||||||
|
game->set(8, 13);
|
||||||
|
game->set(9, 13);
|
||||||
|
game->set(10, 13);
|
||||||
|
|
||||||
|
game->set(14, 13);
|
||||||
|
game->set(15, 13);
|
||||||
|
game->set(16, 13);
|
||||||
|
// deal with infinity
|
||||||
|
game->setActiveInfinity(true);
|
||||||
|
game->setInfinityCounter(5 * 600);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// set the Penta-decathlon pattern
|
||||||
|
bool Patterns::pentaDecathlon(GameOfLife *game) {
|
||||||
|
// top
|
||||||
|
game->set(3, 12);
|
||||||
|
game->set(4, 12);
|
||||||
|
game->set(5, 12);
|
||||||
|
game->set(5, 11);
|
||||||
|
game->set(5, 13);
|
||||||
|
|
||||||
|
// middle
|
||||||
|
game->set(13, 11);
|
||||||
|
game->set(13, 13);
|
||||||
|
game->set(13, 12);
|
||||||
|
game->set(12, 12);
|
||||||
|
game->set(11, 12);
|
||||||
|
game->set(10, 12);
|
||||||
|
game->set(9, 12);
|
||||||
|
game->set(8, 12);
|
||||||
|
game->set(8, 11);
|
||||||
|
game->set(8, 13);
|
||||||
|
|
||||||
|
// bottom
|
||||||
|
game->set(18, 12);
|
||||||
|
game->set(17, 12);
|
||||||
|
game->set(16, 12);
|
||||||
|
game->set(16, 11);
|
||||||
|
game->set(16, 13);
|
||||||
|
|
||||||
|
// deal with infinity
|
||||||
|
game->setActiveInfinity(true);
|
||||||
|
game->setInfinityCounter(5 * 350);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// set the glider pattern
|
||||||
|
bool Patterns::glider(GameOfLife *game) {
|
||||||
|
game->set(2, 3);
|
||||||
|
game->set(3, 4);
|
||||||
|
game->set(4, 2);
|
||||||
|
game->set(4, 3);
|
||||||
|
game->set(4, 4);
|
||||||
|
// deal with infinity
|
||||||
|
game->setActiveInfinity(false);
|
||||||
|
game->setInfinityCounter(0);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// set the glider gun pattern
|
||||||
|
bool Patterns::gliderGun(GameOfLife *game) {
|
||||||
|
// first square
|
||||||
|
game->set(-2, 26);
|
||||||
|
game->set(-2, 25);
|
||||||
|
game->set(-3, 26);
|
||||||
|
game->set(-3, 25);
|
||||||
|
|
||||||
|
// first after
|
||||||
|
game->set(7, 26);
|
||||||
|
game->set(7, 25);
|
||||||
|
game->set(7, 24);
|
||||||
|
game->set(8, 27);
|
||||||
|
game->set(8, 23);
|
||||||
|
game->set(9, 28);
|
||||||
|
game->set(9, 22);
|
||||||
|
game->set(10, 28);
|
||||||
|
game->set(10, 22);
|
||||||
|
game->set(11, 25);
|
||||||
|
game->set(12, 27);
|
||||||
|
game->set(12, 23);
|
||||||
|
game->set(13, 26);
|
||||||
|
game->set(13, 25);
|
||||||
|
game->set(13, 24);
|
||||||
|
game->set(14, 25);
|
||||||
|
|
||||||
|
// second after
|
||||||
|
game->set(17, 28);
|
||||||
|
game->set(17, 27);
|
||||||
|
game->set(17, 26);
|
||||||
|
game->set(18, 28);
|
||||||
|
game->set(18, 27);
|
||||||
|
game->set(18, 26);
|
||||||
|
game->set(19, 29);
|
||||||
|
game->set(19, 25);
|
||||||
|
game->set(21, 29);
|
||||||
|
game->set(21, 30);
|
||||||
|
game->set(21, 25);
|
||||||
|
game->set(21, 24);
|
||||||
|
|
||||||
|
// last square
|
||||||
|
game->set(31, 26);
|
||||||
|
game->set(31, 27);
|
||||||
|
game->set(32, 26);
|
||||||
|
game->set(32, 27);
|
||||||
|
|
||||||
|
// deal with infinity
|
||||||
|
game->setActiveInfinity(true);
|
||||||
|
game->setInfinityCounter(5 * 2000);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// set the light weight spaceship pattern
|
||||||
|
bool Patterns::lightWeightSpaceship(GameOfLife *game) {
|
||||||
|
game->set(5, 4);
|
||||||
|
game->set(5, 5);
|
||||||
|
game->set(6, 2);
|
||||||
|
game->set(6, 3);
|
||||||
|
game->set(6, 5);
|
||||||
|
game->set(6, 6);
|
||||||
|
game->set(7, 2);
|
||||||
|
game->set(7, 3);
|
||||||
|
game->set(7, 4);
|
||||||
|
game->set(7, 5);
|
||||||
|
game->set(8, 3);
|
||||||
|
game->set(8, 4);
|
||||||
|
// deal with infinity
|
||||||
|
game->setActiveInfinity(false);
|
||||||
|
game->setInfinityCounter(0);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// set the middle weight spaceship pattern
|
||||||
|
bool Patterns::middleWeightSpaceship(GameOfLife *game) {
|
||||||
|
game->set(2, 10);
|
||||||
|
game->set(2, 12);
|
||||||
|
game->set(3, 9);
|
||||||
|
game->set(4, 9);
|
||||||
|
game->set(4, 13);
|
||||||
|
game->set(5, 9);
|
||||||
|
game->set(6, 9);
|
||||||
|
game->set(6, 12);
|
||||||
|
game->set(7, 9);
|
||||||
|
game->set(7, 10);
|
||||||
|
game->set(7, 11);
|
||||||
|
// deal with infinity
|
||||||
|
game->setActiveInfinity(false);
|
||||||
|
game->setInfinityCounter(0);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// set the heavy weight spaceship pattern
|
||||||
|
bool Patterns::heavyWeightSpaceship(GameOfLife *game) {
|
||||||
|
game->set(2, 10);
|
||||||
|
game->set(2, 12);
|
||||||
|
game->set(3, 9);
|
||||||
|
game->set(4, 9);
|
||||||
|
game->set(4, 13);
|
||||||
|
game->set(5, 9);
|
||||||
|
game->set(5, 13);
|
||||||
|
game->set(6, 9);
|
||||||
|
game->set(7, 9);
|
||||||
|
game->set(7, 12);
|
||||||
|
game->set(8, 9);
|
||||||
|
game->set(8, 10);
|
||||||
|
game->set(8, 11);
|
||||||
|
// deal with infinity
|
||||||
|
game->setActiveInfinity(false);
|
||||||
|
game->setInfinityCounter(0);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// set the gliders eaters pattern
|
||||||
|
bool Patterns::glidersEaters(GameOfLife *game) {
|
||||||
|
// top left
|
||||||
|
game->set(5, 3);
|
||||||
|
game->set(5, 4);
|
||||||
|
game->set(6, 4);
|
||||||
|
game->set(7, 4);
|
||||||
|
game->set(8, 5);
|
||||||
|
game->set(8, 6);
|
||||||
|
game->set(7, 6);
|
||||||
|
|
||||||
|
// bottom left
|
||||||
|
game->set(13, 4);
|
||||||
|
game->set(14, 4);
|
||||||
|
game->set(15, 4);
|
||||||
|
game->set(15, 3);
|
||||||
|
game->set(12, 5);
|
||||||
|
game->set(12, 6);
|
||||||
|
game->set(13, 6);
|
||||||
|
|
||||||
|
// top right
|
||||||
|
game->set(7, 19);
|
||||||
|
game->set(8, 19);
|
||||||
|
game->set(8, 20);
|
||||||
|
game->set(7, 21);
|
||||||
|
game->set(6, 21);
|
||||||
|
game->set(5, 21);
|
||||||
|
game->set(5, 22);
|
||||||
|
|
||||||
|
// bottom right
|
||||||
|
game->set(13, 19);
|
||||||
|
game->set(12, 19);
|
||||||
|
game->set(12, 20);
|
||||||
|
game->set(13, 21);
|
||||||
|
game->set(14, 21);
|
||||||
|
game->set(15, 21);
|
||||||
|
game->set(15, 22);
|
||||||
|
|
||||||
|
// center top
|
||||||
|
game->set(9, 10);
|
||||||
|
game->set(9, 15);
|
||||||
|
|
||||||
|
// center middle
|
||||||
|
game->set(10, 8);
|
||||||
|
game->set(10, 9);
|
||||||
|
game->set(10, 11);
|
||||||
|
game->set(10, 12);
|
||||||
|
game->set(10, 13);
|
||||||
|
game->set(10, 14);
|
||||||
|
game->set(10, 16);
|
||||||
|
game->set(10, 17);
|
||||||
|
|
||||||
|
// center bottom
|
||||||
|
game->set(11, 10);
|
||||||
|
game->set(11, 15);
|
||||||
|
// deal with infinity
|
||||||
|
game->setActiveInfinity(true);
|
||||||
|
game->setInfinityCounter(5 * 605);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
74
src/Patterns.h
Normal file
74
src/Patterns.h
Normal file
@ -0,0 +1,74 @@
|
|||||||
|
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
||||||
|
* Champlain College SDEV-240-81A
|
||||||
|
*
|
||||||
|
* C++ Final Project (first semester) - Coding Component (2020/05/02)
|
||||||
|
*
|
||||||
|
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
||||||
|
*
|
||||||
|
* This is a demonstration in C++ of a game called
|
||||||
|
* Game of life created by John Horton Conway in 1970
|
||||||
|
* https://en.wikipedia.org/wiki/Conway%27s_Game_of_Life
|
||||||
|
*
|
||||||
|
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
||||||
|
*
|
||||||
|
* Written by Llewellyn van der Merwe <llewellyn.vandermerw@mymail.champlain.edu>, April 2020
|
||||||
|
* Copyright (C) 2020. All Rights Reserved
|
||||||
|
* License GNU/GPL Version 2 or later - http://www.gnu.org/licenses/gpl-2.0.html
|
||||||
|
*
|
||||||
|
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
|
||||||
|
|
||||||
|
#ifndef GOL_PATTERNS_H
|
||||||
|
#define GOL_PATTERNS_H
|
||||||
|
|
||||||
|
// internal classes
|
||||||
|
#include "GameOfLife.h"
|
||||||
|
// libraries
|
||||||
|
#include <iostream>
|
||||||
|
#include <map>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
using namespace std;
|
||||||
|
|
||||||
|
namespace GOL {
|
||||||
|
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
||||||
|
* I am trying out namespace just to see how it works :) any input would be great!
|
||||||
|
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
|
||||||
|
|
||||||
|
// class to set all board patterns
|
||||||
|
class Patterns {
|
||||||
|
private:
|
||||||
|
// all the patterns
|
||||||
|
bool testBoard(GameOfLife *game);
|
||||||
|
|
||||||
|
bool blinker(GameOfLife *game);
|
||||||
|
|
||||||
|
bool toad(GameOfLife *game);
|
||||||
|
|
||||||
|
bool beacon(GameOfLife *game);
|
||||||
|
|
||||||
|
bool pulsar(GameOfLife *game);
|
||||||
|
|
||||||
|
bool pentaDecathlon(GameOfLife *game);
|
||||||
|
|
||||||
|
bool gliderGun(GameOfLife *game);
|
||||||
|
|
||||||
|
bool glidersEaters(GameOfLife *game);
|
||||||
|
|
||||||
|
bool glider(GameOfLife *game);
|
||||||
|
|
||||||
|
bool lightWeightSpaceship(GameOfLife *game);
|
||||||
|
|
||||||
|
bool middleWeightSpaceship(GameOfLife *game);
|
||||||
|
|
||||||
|
bool heavyWeightSpaceship(GameOfLife *game);
|
||||||
|
|
||||||
|
public:
|
||||||
|
// set the preset pattern
|
||||||
|
bool setPreset(int pattern, GameOfLife *game);
|
||||||
|
|
||||||
|
// get the preset pattern list
|
||||||
|
static map<int, string> getPresets();
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif //GOL_PATTERNS_H
|
311
src/Util.cpp
Normal file
311
src/Util.cpp
Normal file
@ -0,0 +1,311 @@
|
|||||||
|
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
||||||
|
* Champlain College SDEV-240-81A
|
||||||
|
*
|
||||||
|
* C++ Final Project (first semester) - Coding Component (2020/05/02)
|
||||||
|
*
|
||||||
|
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
||||||
|
*
|
||||||
|
* This is a demonstration in C++ of a game called
|
||||||
|
* Game of life created by John Horton Conway in 1970
|
||||||
|
* https://en.wikipedia.org/wiki/Conway%27s_Game_of_Life
|
||||||
|
*
|
||||||
|
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
||||||
|
*
|
||||||
|
* Written by Llewellyn van der Merwe <llewellyn.vandermerw@mymail.champlain.edu>, April 2020
|
||||||
|
* Copyright (C) 2020. All Rights Reserved
|
||||||
|
* License GNU/GPL Version 2 or later - http://www.gnu.org/licenses/gpl-2.0.html
|
||||||
|
*
|
||||||
|
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
|
||||||
|
|
||||||
|
// internal classes
|
||||||
|
#include "Util.h"
|
||||||
|
#include "GameOfLife.h"
|
||||||
|
#include "Patterns.h"
|
||||||
|
#include "Message.h"
|
||||||
|
#include "GetInput.h"
|
||||||
|
// libraries
|
||||||
|
#include <iostream>
|
||||||
|
|
||||||
|
using namespace std;
|
||||||
|
|
||||||
|
namespace GOL {
|
||||||
|
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
||||||
|
* I am trying out namespace just to see how it works :) any input would be great!
|
||||||
|
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
|
||||||
|
|
||||||
|
// the introduction message
|
||||||
|
void Util::introMessage(GameOfLife *game) {
|
||||||
|
game->message->add("LINE");
|
||||||
|
game->message->add("This is a demonstration in C++ of a game called");
|
||||||
|
game->message->add("Game of life created by John Horton Conway in 1970");
|
||||||
|
game->message->add("https://en.wikipedia.org/wiki/Conway%27s_Game_of_Life");
|
||||||
|
game->message->add("LINE");
|
||||||
|
game->message->add("Written by Llewellyn van der Merwe");
|
||||||
|
game->message->add("LINE");
|
||||||
|
game->message->add("The Rules");
|
||||||
|
game->message->add("At each step in time, the following transitions occur:");
|
||||||
|
game->message->add("1. Any live cell with fewer than two live neighbours dies, as if by underpopulation.");
|
||||||
|
game->message->add("2. Any live cell with two or three live neighbours lives on to the next generation.");
|
||||||
|
game->message->add("3. Any live cell with more than three live neighbours dies, as if by overpopulation.");
|
||||||
|
game->message->add("4. Any dead cell with exactly three live neighbours becomes a live cell, as if by reproduction.");
|
||||||
|
game->message->add("LINE")->print(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
// getting the coordinates for the board
|
||||||
|
void Util::getCoordinates(GameOfLife *game) {
|
||||||
|
// lets make sure our board is clean
|
||||||
|
game->reset();
|
||||||
|
// instantiate x and y to be integers
|
||||||
|
int x, y;
|
||||||
|
// setup the question
|
||||||
|
game->message->add("This game has the following input options");
|
||||||
|
game->message->add("LINE");
|
||||||
|
game->message->add("1. Select a pattern from our presets.");
|
||||||
|
game->message->add("2. Enter a path to a file with the coordinates.");
|
||||||
|
game->message->add("3. Manually add coordinates to the board.");
|
||||||
|
game->message->add("or 'q' to quit")->print(0);
|
||||||
|
// get the user path to action
|
||||||
|
GetInput action(game->message->ask("Enter your selection: "));
|
||||||
|
// clean the screen
|
||||||
|
Util::clearScreen();
|
||||||
|
game->message->add("LINE");
|
||||||
|
// file or preset was selected
|
||||||
|
if (action.get() == "2") {
|
||||||
|
// clean the screen
|
||||||
|
Util::clearScreen();
|
||||||
|
while (true) {
|
||||||
|
// give info of the coordinates convention
|
||||||
|
game->message->add("Coordinates must be given in the following way");
|
||||||
|
game->message->add("LINE");
|
||||||
|
game->message->add("Each line must have two numbers separated by a space.");
|
||||||
|
game->message->add("The first number is the x axis value, and the second number is the y axis value.");
|
||||||
|
game->message->add("So each line represents a coordinate/cell on the board that is active/alive.");
|
||||||
|
game->message->add("The view area of the board has " +
|
||||||
|
to_string(game->getViewSize()) + " x " +
|
||||||
|
to_string(game->getViewSize()) + " = " +
|
||||||
|
to_string(game->getViewArea()) + " cells. But the board is far larger.");
|
||||||
|
game->message->add("Meaning you are able to add negative and positive values to a depth of -" +
|
||||||
|
to_string(game->getSettableArea()) + " and " +
|
||||||
|
to_string(game->getSettableArea()) + ".")->print();
|
||||||
|
// get the file path
|
||||||
|
GetInput filepath(game->message->ask("Enter file path to read coordinates from, or 'b' to go back: "));
|
||||||
|
// check if the player want to go back
|
||||||
|
if (filepath.get() == "b") {
|
||||||
|
// go back
|
||||||
|
getCoordinates(game);
|
||||||
|
break;
|
||||||
|
} else {
|
||||||
|
// read in the file path
|
||||||
|
ifstream readfile(filepath.get());
|
||||||
|
// if we can open the file continue
|
||||||
|
if (readfile.is_open()) {
|
||||||
|
// instantiate bucket values
|
||||||
|
string fileline, x_coordinate, y_coordinate;
|
||||||
|
// get the lines from the file
|
||||||
|
while (getline(readfile, fileline)) {
|
||||||
|
// get the lines from the file
|
||||||
|
stringstream line_coordinate(fileline);
|
||||||
|
// get coordinates
|
||||||
|
getline(line_coordinate, x_coordinate, ' ');
|
||||||
|
getline(line_coordinate, y_coordinate, ' ');
|
||||||
|
// convert to number (integer)
|
||||||
|
x = stoi(x_coordinate);
|
||||||
|
y = stoi(y_coordinate);
|
||||||
|
// set the coordinates
|
||||||
|
game->set(x, y);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
} else {
|
||||||
|
game->message->add("No such file, try again.")->print();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// ask to set infinity
|
||||||
|
game->setInfinity(false);
|
||||||
|
} else if (action.get() == "1") {
|
||||||
|
// clean the screen
|
||||||
|
Util::clearScreen();
|
||||||
|
game->message->add("These are the preset patterns");
|
||||||
|
game->message->add("LINE");
|
||||||
|
// instantiate Patterns class
|
||||||
|
Patterns patterns;
|
||||||
|
// loop over the presets
|
||||||
|
map<int, string>::iterator preset;
|
||||||
|
map<int, string> presets = patterns.getPresets();
|
||||||
|
for (preset = presets.begin(); preset != presets.end(); preset++) {
|
||||||
|
game->message->add(to_string(preset->first) + ". " + preset->second);
|
||||||
|
}
|
||||||
|
// add message to allow player to go back
|
||||||
|
game->message->add("or 'b' to go back")->print(0);
|
||||||
|
// get selected preset
|
||||||
|
GetInput activePreset(game->message->ask("Enter your selection: "));
|
||||||
|
// load the preset if the correct number was selected
|
||||||
|
if ((!activePreset.get().empty() && activePreset.get().find_first_not_of("0123456789") != string::npos) ||
|
||||||
|
!patterns.setPreset(stoi(activePreset.get()), game)) {
|
||||||
|
game->message->add("No such preset was found, try again.")->print();
|
||||||
|
// we try again
|
||||||
|
getCoordinates(game);
|
||||||
|
}
|
||||||
|
} else if (action.get() == "3") {
|
||||||
|
// clean the screen
|
||||||
|
Util::clearScreen();
|
||||||
|
// give info of the coordinates convention
|
||||||
|
game->message->add("Coordinates must be given in the following way");
|
||||||
|
game->message->add("LINE");
|
||||||
|
game->message->add("Each entry must have two numbers separated by a space.");
|
||||||
|
game->message->add("The first number is the x axis value, and the second number is the y axis value.");
|
||||||
|
game->message->add("So each entry represents a coordinate/cell on the board that is active/alive.");
|
||||||
|
game->message->add("The view area of the board has " +
|
||||||
|
to_string(game->getViewSize()) + " x " +
|
||||||
|
to_string(game->getViewSize()) + " = " +
|
||||||
|
to_string(game->getViewArea()) + " cells.")->print();
|
||||||
|
// get the coordinates from user manually
|
||||||
|
while (true) {
|
||||||
|
cout << game->message->ask(
|
||||||
|
"Enter the coordinates of an active/alive cell: ");
|
||||||
|
cin >> x >> y;
|
||||||
|
// make sure we get numbers
|
||||||
|
if (cin.fail()) {
|
||||||
|
// clear to ask the question again
|
||||||
|
cin.clear();
|
||||||
|
cin.ignore();
|
||||||
|
// give the warning
|
||||||
|
game->message->add("Must only be numbers!")->print();
|
||||||
|
} else {
|
||||||
|
// set the coordinates
|
||||||
|
game->set(x, y);
|
||||||
|
// check if coordinates are correct
|
||||||
|
game->message->add("Check your entry")->print();
|
||||||
|
// print the set coordinates
|
||||||
|
game->print(3);
|
||||||
|
// final check if the above coordinates are correct and if we must continue adding more
|
||||||
|
game->message->add("To continue you have the following options:");
|
||||||
|
game->message->add("1. Add another cell.");
|
||||||
|
game->message->add("2. Undo that last entry.");
|
||||||
|
// game->message->add("3. Save coordinates to a file and start game->"); TODO
|
||||||
|
game->message->add("3. Stop adding cells.")->print();
|
||||||
|
GetInput optionInput(game->message->ask("Enter the number: "));
|
||||||
|
// ready to start game?
|
||||||
|
if (optionInput.get() == "2") {
|
||||||
|
// unset the last coordinates
|
||||||
|
game->unset(x, y);
|
||||||
|
} else if (optionInput.get() == "3") {
|
||||||
|
// stop adding cells
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
game->setInfinity(false);
|
||||||
|
} else {
|
||||||
|
// quit playing the game
|
||||||
|
game->stopPlaying();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Util::run(GameOfLife *game) {
|
||||||
|
// make sure the game is active
|
||||||
|
if (game->isStillPlaying()) {
|
||||||
|
// get the coordinates
|
||||||
|
Util::getCoordinates(game);
|
||||||
|
// make sure the game is active
|
||||||
|
if (game->isStillPlaying()) {
|
||||||
|
// show the board and the selected coordinates
|
||||||
|
game->message->add("LINE");
|
||||||
|
game->message->add("These are the coordinates.")->print(0);
|
||||||
|
// print the set coordinates
|
||||||
|
game->print(0);
|
||||||
|
// give notice of infinity treatment
|
||||||
|
Util::infinityNote(game);
|
||||||
|
// final check if the above coordinates are correct
|
||||||
|
game->message->add("LINE");
|
||||||
|
GetInput startGame(game->message->ask("Board setup complete. Start the game ? (y/n) "));
|
||||||
|
// ready to start game?
|
||||||
|
if (startGame.get() == "y" || startGame.get() == "Y") {
|
||||||
|
while (true) {
|
||||||
|
// print the board
|
||||||
|
game->print();
|
||||||
|
// update the board state
|
||||||
|
game->setState();
|
||||||
|
// slow down... ;)
|
||||||
|
usleep(130000);
|
||||||
|
// clean the screen
|
||||||
|
if (game->isActive()) {
|
||||||
|
Util::clearScreen();
|
||||||
|
} else {
|
||||||
|
// show the board and the selected coordinates
|
||||||
|
Util::getCoordinates(game);
|
||||||
|
// if the player quit
|
||||||
|
if (game->isStillPlaying()) {
|
||||||
|
// show the board and the selected coordinates
|
||||||
|
game->message->add("LINE");
|
||||||
|
game->message->add("These are the new coordinates.")->print();
|
||||||
|
// print the set coordinates
|
||||||
|
game->print(0);
|
||||||
|
// give notice of infinity treatment
|
||||||
|
Util::infinityNote(game);
|
||||||
|
// final check if the above coordinates are correct
|
||||||
|
game->message->add("LINE");
|
||||||
|
GetInput startGameAgain(
|
||||||
|
game->message->ask("Board setup complete. Start the game again ? (y/n) "));
|
||||||
|
if (startGameAgain.get() != "y" && startGameAgain.get() != "Y") {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// if we are still active
|
||||||
|
if (game->isStillPlaying()) {
|
||||||
|
// restart
|
||||||
|
Util::run(game);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// give notice of infinity treatment
|
||||||
|
void Util::infinityNote(GameOfLife *game) {
|
||||||
|
if (game->isInfinitySet()) {
|
||||||
|
game->message->add("All infinite loops will automatically exit, sit back and enjoy!");
|
||||||
|
game->message->add("LINE")->print();
|
||||||
|
} else {
|
||||||
|
game->message->add("Just a little heads-up, you will need to manually exit the game");
|
||||||
|
game->message->add("should it enter an infinite loop (Oscillator).");
|
||||||
|
game->message->add("The game will only automatically exit if all visible cells are dead or still.");
|
||||||
|
game->message->add("LINE")->print();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// method to clear the screen
|
||||||
|
void Util::clearScreen() {
|
||||||
|
// Below Code Taken From This Project https://github.com/MarioTalevski/game-of-life
|
||||||
|
// Tested and working on Ubuntu and Cygwin
|
||||||
|
#if defined(OS_WIN)
|
||||||
|
HANDLE hStdOut = GetStdHandle( STD_OUTPUT_HANDLE );
|
||||||
|
CONSOLE_SCREEN_BUFFER_INFO csbi;
|
||||||
|
DWORD count;
|
||||||
|
DWORD cellCount;
|
||||||
|
COORD homeCoords = { 0, 0 };
|
||||||
|
|
||||||
|
if (hStdOut == INVALID_HANDLE_VALUE) return;
|
||||||
|
|
||||||
|
/* Get the number of cells in the current buffer */
|
||||||
|
GetConsoleScreenBufferInfo( hStdOut, &csbi );
|
||||||
|
cellCount = csbi.dwSize.X *csbi.dwSize.Y;
|
||||||
|
|
||||||
|
/* Fill the entire buffer with spaces */
|
||||||
|
FillConsoleOutputCharacter(hStdOut, (TCHAR) ' ', cellCount, homeCoords, &count);
|
||||||
|
|
||||||
|
/* Fill the entire buffer with the current colors and attributes */
|
||||||
|
FillConsoleOutputAttribute(hStdOut, csbi.wAttributes, cellCount, homeCoords, &count);
|
||||||
|
|
||||||
|
SetConsoleCursorPosition( hStdOut, homeCoords );
|
||||||
|
|
||||||
|
#elif defined(OS_LINUX) || defined(OS_MAC)
|
||||||
|
cout << "\033[2J" << "\033[1;1H"; // Clears screen and moves cursor to home pos on POSIX systems
|
||||||
|
#endif
|
||||||
|
// Above Code Taken From This Project https://github.com/MarioTalevski/game-of-life
|
||||||
|
}
|
||||||
|
}
|
64
src/Util.h
Normal file
64
src/Util.h
Normal file
@ -0,0 +1,64 @@
|
|||||||
|
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
||||||
|
* Champlain College SDEV-240-81A
|
||||||
|
*
|
||||||
|
* C++ Final Project (first semester) - Coding Component (2020/05/02)
|
||||||
|
*
|
||||||
|
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
||||||
|
*
|
||||||
|
* This is a demonstration in C++ of a game called
|
||||||
|
* Game of life created by John Horton Conway in 1970
|
||||||
|
* https://en.wikipedia.org/wiki/Conway%27s_Game_of_Life
|
||||||
|
*
|
||||||
|
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
||||||
|
*
|
||||||
|
* Written by Llewellyn van der Merwe <llewellyn.vandermerw@mymail.champlain.edu>, April 2020
|
||||||
|
* Copyright (C) 2020. All Rights Reserved
|
||||||
|
* License GNU/GPL Version 2 or later - http://www.gnu.org/licenses/gpl-2.0.html
|
||||||
|
*
|
||||||
|
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
|
||||||
|
|
||||||
|
#ifndef GOL_UTIL_H
|
||||||
|
#define GOL_UTIL_H
|
||||||
|
|
||||||
|
// internal classes
|
||||||
|
#include "Game.h"
|
||||||
|
#include "GameOfLife.h"
|
||||||
|
#include "Message.h"
|
||||||
|
// libraries
|
||||||
|
#include <iostream>
|
||||||
|
#include <cstdlib>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <fstream>
|
||||||
|
#include <string>
|
||||||
|
#include <sstream>
|
||||||
|
|
||||||
|
using namespace std;
|
||||||
|
|
||||||
|
namespace GOL {
|
||||||
|
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
||||||
|
* I am trying out namespace just to see how it works :) any input would be great!
|
||||||
|
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
|
||||||
|
|
||||||
|
// class combine useful methods
|
||||||
|
class Util {
|
||||||
|
public:
|
||||||
|
// force static use
|
||||||
|
Util() = delete;
|
||||||
|
// the introduction message
|
||||||
|
static void introMessage(GameOfLife *game);
|
||||||
|
|
||||||
|
// the infinity message
|
||||||
|
static void infinityNote(GameOfLife *game);
|
||||||
|
|
||||||
|
// the main method to run the game
|
||||||
|
static void run(GameOfLife *game);
|
||||||
|
|
||||||
|
// getting the coordinates for the board
|
||||||
|
static void getCoordinates(GameOfLife *game);
|
||||||
|
|
||||||
|
// method to clear the screen
|
||||||
|
static void clearScreen();
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif //GOL_UTIL_H
|
35
src/color.h
Normal file
35
src/color.h
Normal file
@ -0,0 +1,35 @@
|
|||||||
|
// Below Code Taken From This Project https://github.com/MarioTalevski/game-of-life
|
||||||
|
// Move OS defines up here to be used in different places
|
||||||
|
#if defined(_WIN32) || defined(WIN32) || defined(__MINGW32__) || defined(__BORLANDC__)
|
||||||
|
#define OS_WIN
|
||||||
|
// WINDOWS COLORS
|
||||||
|
#define COLOR_RED SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), FOREGROUND_RED)
|
||||||
|
#define COLOR_WARNING SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), FOREGROUND_GREEN)
|
||||||
|
|
||||||
|
#define COLOR_BLUE SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), FOREGROUND_BLUE)
|
||||||
|
|
||||||
|
#define COLOR_RESET SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), 15)
|
||||||
|
|
||||||
|
#elif defined(linux) || defined(__CYGWIN__)
|
||||||
|
#define OS_LINUX
|
||||||
|
|
||||||
|
#define COLOR_RED "\033[31m"
|
||||||
|
#define COLOR_GREEN "\033[32m"
|
||||||
|
#define COLOR_BLUE "\033[34m"
|
||||||
|
#define COLOR_RESET "\033[0m"
|
||||||
|
|
||||||
|
#elif (defined(__APPLE__) || defined(__OSX__) || defined(__MACOS__)) && defined(__MACH__) // To ensure that we are running on a mondern version of macOS
|
||||||
|
#define OS_MAC
|
||||||
|
|
||||||
|
#define COLOR_RED "\033[31m"
|
||||||
|
#define COLOR_GREEN "\033[32m"
|
||||||
|
#define COLOR_BLUE "\033[34m"
|
||||||
|
#define COLOR_RESET "\033[0m"
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(OS_WIN)
|
||||||
|
#include <windows.h> // Use for windows
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// Above Code Taken From This Project https://github.com/MarioTalevski/game-of-life
|
49
src/main.cpp
Normal file
49
src/main.cpp
Normal file
@ -0,0 +1,49 @@
|
|||||||
|
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
||||||
|
* Champlain College SDEV-240-81A
|
||||||
|
*
|
||||||
|
* C++ Final Project (first semester) - Coding Component (2020/05/02)
|
||||||
|
*
|
||||||
|
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
||||||
|
*
|
||||||
|
* This is a demonstration in C++ of a game called
|
||||||
|
* Game of life created by John Horton Conway in 1970
|
||||||
|
* https://en.wikipedia.org/wiki/Conway%27s_Game_of_Life
|
||||||
|
*
|
||||||
|
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
||||||
|
*
|
||||||
|
* Written by Llewellyn van der Merwe <llewellyn.vandermerw@mymail.champlain.edu>, April 2020
|
||||||
|
* Copyright (C) 2020. All Rights Reserved
|
||||||
|
* License GNU/GPL Version 2 or later - http://www.gnu.org/licenses/gpl-2.0.html
|
||||||
|
*
|
||||||
|
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
||||||
|
*
|
||||||
|
* Originally Forked: Mario Talevski https://github.com/MarioTalevski/game-of-life
|
||||||
|
* But the code has been massively refactored into classes,
|
||||||
|
* so much that there is hardly any of the original code left unchanged.
|
||||||
|
* I have marked the areas that did not change at all,
|
||||||
|
* since those parts are not part of the above license or copyright.
|
||||||
|
*
|
||||||
|
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
|
||||||
|
|
||||||
|
// internal classes
|
||||||
|
#include "Util.h"
|
||||||
|
#include "GameOfLife.h"
|
||||||
|
|
||||||
|
using namespace GOL;
|
||||||
|
|
||||||
|
int main() {
|
||||||
|
// clean the screen
|
||||||
|
Util::clearScreen();
|
||||||
|
// instantiate the game class on the heap
|
||||||
|
auto *game = new GameOfLife;
|
||||||
|
// print the intro message
|
||||||
|
Util::introMessage(game);
|
||||||
|
// play the game
|
||||||
|
Util::run(game);
|
||||||
|
// game has ended
|
||||||
|
game->message->add("GAME ENDED");
|
||||||
|
game->message->add("LINE")->print();
|
||||||
|
// remove game from heap memory
|
||||||
|
delete game;
|
||||||
|
return 0;
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user