commit
					68197111c4
				
				 28 changed files with 1820 additions and 0 deletions
			
			
		@ -0,0 +1,74 @@ | 
				
			|||||||
 | 
					#include <algorithm> | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "board.h" | 
				
			||||||
 | 
					#include "spaceship.h" | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Board::Board() { | 
				
			||||||
 | 
						// Reserve 0 SpaceShips of memory for each planet
 | 
				
			||||||
 | 
						for (unsigned char i = 0; i < BOARD_SIZE; i++) { | 
				
			||||||
 | 
							this->planets[i] = new std::vector<SpaceShip *>(0); | 
				
			||||||
 | 
						} | 
				
			||||||
 | 
					} | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Board::~Board() { | 
				
			||||||
 | 
						for (auto planet : this->planets) { | 
				
			||||||
 | 
							delete planet; | 
				
			||||||
 | 
						} | 
				
			||||||
 | 
					} | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					SpaceShip *Board::getShip(unsigned char planet, unsigned char pos) { | 
				
			||||||
 | 
						if (planet >= BOARD_SIZE || pos >= this->planets[planet]->size()) { | 
				
			||||||
 | 
							return new SpaceShip; | 
				
			||||||
 | 
						} | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return this->planets[planet]->at(pos); | 
				
			||||||
 | 
					} | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					std::vector<SpaceShip *> *Board::getShips(unsigned char planet) { | 
				
			||||||
 | 
						if (planet >= BOARD_SIZE) { | 
				
			||||||
 | 
							return nullptr; | 
				
			||||||
 | 
						} | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return this->planets[planet]; | 
				
			||||||
 | 
					} | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					bool Board::setShip(unsigned char planet, SpaceShip *ship) { | 
				
			||||||
 | 
						if (planet >= BOARD_SIZE) { | 
				
			||||||
 | 
							return false; | 
				
			||||||
 | 
						} | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// Insert if the ship doesn't already exist on a planet
 | 
				
			||||||
 | 
						if (ship->getPlanet() == PLANET_UNSET) { | 
				
			||||||
 | 
							ship->setPlanet(planet); | 
				
			||||||
 | 
							this->planets[planet]->push_back(ship); | 
				
			||||||
 | 
							this->sortPlanet(planet); | 
				
			||||||
 | 
						} | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return true; | 
				
			||||||
 | 
					} | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					bool Board::moveShip(unsigned char planet, SpaceShip *ship) { | 
				
			||||||
 | 
						char shipPlanet = ship->getPlanet(); | 
				
			||||||
 | 
						if (planet >= BOARD_SIZE || shipPlanet == -1 || shipPlanet == planet) { | 
				
			||||||
 | 
							return false; | 
				
			||||||
 | 
						} | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						auto tmp = this->planets[(unsigned char)shipPlanet]; | 
				
			||||||
 | 
						// Move ship to the end of the vector and then erase the last element
 | 
				
			||||||
 | 
						// (Erase-remove idiom)
 | 
				
			||||||
 | 
						tmp->erase(std::remove(tmp->begin(), tmp->end(), ship), tmp->end()); | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						ship->setPlanet(planet); | 
				
			||||||
 | 
						this->planets[planet]->push_back(ship); | 
				
			||||||
 | 
						this->sortPlanet(planet); | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return true; | 
				
			||||||
 | 
					} | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void Board::sortPlanet(unsigned char planet) { | 
				
			||||||
 | 
						// Sort all ships on the planet, using function/functor/lambda
 | 
				
			||||||
 | 
						std::sort(this->planets[planet]->begin(), this->planets[planet]->end(), | 
				
			||||||
 | 
							[](SpaceShip *s1, SpaceShip *s2) -> bool { | 
				
			||||||
 | 
								return s1->getSize() > s2->getSize(); | 
				
			||||||
 | 
							}); | 
				
			||||||
 | 
					} | 
				
			||||||
@ -0,0 +1,28 @@ | 
				
			|||||||
 | 
					#ifndef BOARD_H | 
				
			||||||
 | 
					#define BOARD_H | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define BOARD_SIZE 14 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <vector> | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class SpaceShip; | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class Board | 
				
			||||||
 | 
					{ | 
				
			||||||
 | 
					public: | 
				
			||||||
 | 
						Board(); | 
				
			||||||
 | 
						~Board(); | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						SpaceShip *getShip(unsigned char planet, unsigned char pos); | 
				
			||||||
 | 
						std::vector<SpaceShip *> *getShips(unsigned char planet); | 
				
			||||||
 | 
						bool setShip(unsigned char planet, SpaceShip *ship); | 
				
			||||||
 | 
						bool moveShip(unsigned char planet, SpaceShip *ship); | 
				
			||||||
 | 
						void sortPlanet(unsigned char planet); | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					private: | 
				
			||||||
 | 
						// Data layout:
 | 
				
			||||||
 | 
						// Black hole, 6 planets, 6 planets, black hole
 | 
				
			||||||
 | 
						std::vector<SpaceShip *> *planets[BOARD_SIZE]; | 
				
			||||||
 | 
					}; | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#endif // BOARD_H
 | 
				
			||||||
@ -0,0 +1,84 @@ | 
				
			|||||||
 | 
					#include "board.h" | 
				
			||||||
 | 
					#include "boardwindow.h" | 
				
			||||||
 | 
					#include "maingame.h" | 
				
			||||||
 | 
					#include "spaceship.h" | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					BoardWindow::BoardWindow(int height, int width, Board *board) : | 
				
			||||||
 | 
						height(height), | 
				
			||||||
 | 
						width(width), | 
				
			||||||
 | 
						board(board) { | 
				
			||||||
 | 
					} | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					BoardWindow::~BoardWindow() { | 
				
			||||||
 | 
					} | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void BoardWindow::update() { | 
				
			||||||
 | 
						Window::update(); | 
				
			||||||
 | 
						this->resize(); | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						int twoThirds = (this->getRows() / 3) * 2; | 
				
			||||||
 | 
						int halfCols = this->getCols() / 2; | 
				
			||||||
 | 
						int y = (twoThirds / 2) - 12; | 
				
			||||||
 | 
						int x = halfCols - 4 - 1; | 
				
			||||||
 | 
						// Print black hole
 | 
				
			||||||
 | 
						this->printBlackHole(y, x, 0); | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						y += 6; | 
				
			||||||
 | 
						x = (this->getCols() / 2) - (46 / 2) - 1; | 
				
			||||||
 | 
						// Print all planets
 | 
				
			||||||
 | 
						for (int i = 1; i < BOARD_SIZE - 1; i++) { | 
				
			||||||
 | 
							this->printPlanet(y, x, i); | 
				
			||||||
 | 
							x += 8; | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							if (i == (BOARD_SIZE - 2) / 2) { | 
				
			||||||
 | 
								x = (this->getCols() / 2) - (46 / 2) - 1; | 
				
			||||||
 | 
								y += 6; | 
				
			||||||
 | 
							} | 
				
			||||||
 | 
						} | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						y += 6; | 
				
			||||||
 | 
						x = halfCols - 4 - 1; | 
				
			||||||
 | 
						// Print black hole
 | 
				
			||||||
 | 
						this->printBlackHole(y, x, BOARD_SIZE - 1); | 
				
			||||||
 | 
					} | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void BoardWindow::resize() { | 
				
			||||||
 | 
						int rows = this->getMaxRows() - this->height; | 
				
			||||||
 | 
						int cols = this->getMaxCols() - this->width; | 
				
			||||||
 | 
						this->setWindow(rows, cols, 0, 0); | 
				
			||||||
 | 
						Window::resize(); | 
				
			||||||
 | 
					} | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void BoardWindow::printBlackHole(int y, int x, int planet) { | 
				
			||||||
 | 
						this->print("+------+", y, x); | 
				
			||||||
 | 
						this->print("|      |", y + 1, x); | 
				
			||||||
 | 
						this->print("|      |", y + 2, x); | 
				
			||||||
 | 
						this->print("|      |", y + 3, x); | 
				
			||||||
 | 
						this->print("+------+", y + 4, x); | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						this->printSpaceShip(y + 1, x + 1, planet, 6); | 
				
			||||||
 | 
					} | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void BoardWindow::printPlanet(int y, int x, int planet) { | 
				
			||||||
 | 
						this->print("+----+", y, x); | 
				
			||||||
 | 
						this->print("|    |", y + 1, x); | 
				
			||||||
 | 
						this->print("|    |", y + 2, x); | 
				
			||||||
 | 
						this->print("|    |", y + 3, x); | 
				
			||||||
 | 
						this->print("+----+", y + 4, x); | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						this->printSpaceShip(y + 1, x + 1, planet, 4); | 
				
			||||||
 | 
					} | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void BoardWindow::printSpaceShip(int y, int x, int planet, int width) { | 
				
			||||||
 | 
						auto tmp = this->board->getShips(planet); | 
				
			||||||
 | 
						int size = (int)tmp->size() + 1; | 
				
			||||||
 | 
						for (int i = 1; i < size; i++) { | 
				
			||||||
 | 
							tmp->at(i - 1)->render(this, y, x, false); | 
				
			||||||
 | 
							x++; | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							if (i != 1 && i % width == 0) { | 
				
			||||||
 | 
								y++; | 
				
			||||||
 | 
								x -= width; | 
				
			||||||
 | 
							} | 
				
			||||||
 | 
						} | 
				
			||||||
 | 
					} | 
				
			||||||
@ -0,0 +1,26 @@ | 
				
			|||||||
 | 
					#ifndef BOARDWINDOW_H | 
				
			||||||
 | 
					#define BOARDWINDOW_H | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "window.h" | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class Board; | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class BoardWindow : public Window | 
				
			||||||
 | 
					{ | 
				
			||||||
 | 
					public: | 
				
			||||||
 | 
						BoardWindow(int height, int width, Board *board); | 
				
			||||||
 | 
						~BoardWindow(); | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						void update(); | 
				
			||||||
 | 
						void resize(); | 
				
			||||||
 | 
						void printBlackHole(int y, int x, int planet); | 
				
			||||||
 | 
						void printPlanet(int y, int x, int planet); | 
				
			||||||
 | 
						void printSpaceShip(int y, int x, int planet, int width); | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					private: | 
				
			||||||
 | 
						int height; | 
				
			||||||
 | 
						int width; | 
				
			||||||
 | 
						Board *board; | 
				
			||||||
 | 
					}; | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#endif // BOARDWINDOW_H
 | 
				
			||||||
@ -0,0 +1,75 @@ | 
				
			|||||||
 | 
					#ifndef GAMESTATE | 
				
			||||||
 | 
					#define GAMESTATE | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <chrono> // time | 
				
			||||||
 | 
					#include <thread> // sleep_for | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "inputoutput.h" | 
				
			||||||
 | 
					#include "window.h" | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class GameState | 
				
			||||||
 | 
					{ | 
				
			||||||
 | 
					public: | 
				
			||||||
 | 
						// Makes sure that the inherited class's destructor is called
 | 
				
			||||||
 | 
						virtual ~GameState() {} | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						virtual void initialize() {} | 
				
			||||||
 | 
						virtual void update() {} | 
				
			||||||
 | 
						virtual void render() {} | 
				
			||||||
 | 
						virtual void destroy() {} | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						static void sleep(int amount) { | 
				
			||||||
 | 
							// Sleep for amount ms
 | 
				
			||||||
 | 
							std::this_thread::sleep_for(std::chrono::milliseconds(amount)); | 
				
			||||||
 | 
						} | 
				
			||||||
 | 
					}; | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class GameStateManager | 
				
			||||||
 | 
					{ | 
				
			||||||
 | 
					public: | 
				
			||||||
 | 
						GameStateManager() : state(nullptr) { | 
				
			||||||
 | 
							Window::initialize(); | 
				
			||||||
 | 
						} | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						~GameStateManager() { | 
				
			||||||
 | 
							if(this->state != nullptr) { | 
				
			||||||
 | 
								this->state->destroy(); | 
				
			||||||
 | 
								delete this->state; | 
				
			||||||
 | 
							} | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							Window::destroy(); | 
				
			||||||
 | 
						} | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						void setState(GameState* state) { | 
				
			||||||
 | 
							if(this->state != nullptr) { | 
				
			||||||
 | 
								this->state->destroy(); | 
				
			||||||
 | 
								delete this->state; | 
				
			||||||
 | 
							} | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							this->state = state; | 
				
			||||||
 | 
							if(this->state != nullptr) { | 
				
			||||||
 | 
								this->state->initialize(); | 
				
			||||||
 | 
							} | 
				
			||||||
 | 
						} | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						void update() { | 
				
			||||||
 | 
							GameState::sleep(15); | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							if(this->state != nullptr) { | 
				
			||||||
 | 
								this->state->update(); | 
				
			||||||
 | 
							} | 
				
			||||||
 | 
						} | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						void render() { | 
				
			||||||
 | 
							if(this->state != nullptr) { | 
				
			||||||
 | 
								this->state->render(); | 
				
			||||||
 | 
							} | 
				
			||||||
 | 
						} | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					private: | 
				
			||||||
 | 
						GameState *state; | 
				
			||||||
 | 
					}; | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					extern GameStateManager gameStateManager; | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#endif // GAMESTATE
 | 
				
			||||||
@ -0,0 +1,47 @@ | 
				
			|||||||
 | 
					#include "infowindow.h" | 
				
			||||||
 | 
					#include "maingame.h" | 
				
			||||||
 | 
					#include "player.h" | 
				
			||||||
 | 
					#include "spaceship.h" | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					InfoWindow::InfoWindow(int height, int width, Player **player, SpaceShip **ship) : | 
				
			||||||
 | 
						height(height), | 
				
			||||||
 | 
						width(width), | 
				
			||||||
 | 
						player(player), | 
				
			||||||
 | 
						ship(ship) { | 
				
			||||||
 | 
					} | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					InfoWindow::~InfoWindow() { | 
				
			||||||
 | 
					} | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void InfoWindow::update() { | 
				
			||||||
 | 
						Window::update(); | 
				
			||||||
 | 
						this->resize(); | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						int y = 0; | 
				
			||||||
 | 
						int x = 1; | 
				
			||||||
 | 
						for (unsigned char i = 0; i < PLAYER_SIZE; i++) { | 
				
			||||||
 | 
							this->player[i]->render(this, y, x, i + 1); | 
				
			||||||
 | 
							y += 6; | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							int shipIdx = i * SHIP_SIZE / 2; | 
				
			||||||
 | 
							for (unsigned char j = shipIdx; j < shipIdx + SHIP_SIZE / 2; j++) { | 
				
			||||||
 | 
								this->ship[j]->render(this, y, x); | 
				
			||||||
 | 
								x++; | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								if (x > 3) { | 
				
			||||||
 | 
									y++; | 
				
			||||||
 | 
									x = 1; | 
				
			||||||
 | 
								} | 
				
			||||||
 | 
							} | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							y += 2; | 
				
			||||||
 | 
						} | 
				
			||||||
 | 
					} | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void InfoWindow::resize() { | 
				
			||||||
 | 
						int rows = this->getMaxRows() - this->height; | 
				
			||||||
 | 
						int x = this->getMaxCols() - this->width; | 
				
			||||||
 | 
						int cols = this->getMaxCols() - x; | 
				
			||||||
 | 
						this->setWindow(rows, cols, 0, x); | 
				
			||||||
 | 
						Window::resize(); | 
				
			||||||
 | 
					} | 
				
			||||||
@ -0,0 +1,25 @@ | 
				
			|||||||
 | 
					#ifndef INFOWINDOW_H | 
				
			||||||
 | 
					#define INFOWINDOW_H | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "window.h" | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class Player; | 
				
			||||||
 | 
					class SpaceShip; | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class InfoWindow : public Window | 
				
			||||||
 | 
					{ | 
				
			||||||
 | 
					public: | 
				
			||||||
 | 
						InfoWindow(int height, int width, Player **player, SpaceShip **ship); | 
				
			||||||
 | 
						~InfoWindow(); | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						void update(); | 
				
			||||||
 | 
						void resize(); | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					private: | 
				
			||||||
 | 
						int height; | 
				
			||||||
 | 
						int width; | 
				
			||||||
 | 
						Player **player; | 
				
			||||||
 | 
						SpaceShip **ship; | 
				
			||||||
 | 
					}; | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#endif // INFOWINDOW_H
 | 
				
			||||||
@ -0,0 +1,69 @@ | 
				
			|||||||
 | 
					#include <cstdio> // size_t | 
				
			||||||
 | 
					#include <ncurses.h> | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "inputoutput.h" | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void IO::initialize() { | 
				
			||||||
 | 
					} | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void IO::update() { | 
				
			||||||
 | 
						IO::keyCode = getch(); | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (keyCode == KEY_ESC) { | 
				
			||||||
 | 
							IO::setQuit(); | 
				
			||||||
 | 
							return; | 
				
			||||||
 | 
						} | 
				
			||||||
 | 
					} | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					std::string IO::trim(std::string str) { | 
				
			||||||
 | 
					    size_t first = str.find_first_not_of(" "); | 
				
			||||||
 | 
					    if (first == std::string::npos) { | 
				
			||||||
 | 
					        return ""; | 
				
			||||||
 | 
					    } | 
				
			||||||
 | 
					    size_t last = str.find_last_not_of(" "); | 
				
			||||||
 | 
					    return str.substr(first, (last - first + 1)); | 
				
			||||||
 | 
					} | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					std::string IO::untrim(std::string str, unsigned int length) { | 
				
			||||||
 | 
						unsigned int strLength = str.length(); | 
				
			||||||
 | 
						if (length > strLength) { | 
				
			||||||
 | 
							int halfDiff = (length - strLength) / 2; | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							std::string tmpStr; | 
				
			||||||
 | 
							for (int i = 0; i < halfDiff; i++) { | 
				
			||||||
 | 
								tmpStr += " "; | 
				
			||||||
 | 
							} | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							str.insert(0, tmpStr); | 
				
			||||||
 | 
							str.append(tmpStr); | 
				
			||||||
 | 
						} | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return str; | 
				
			||||||
 | 
					} | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int IO::getKeyCode() { | 
				
			||||||
 | 
						return IO::keyCode; | 
				
			||||||
 | 
					} | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					std::string IO::getKeyName() { | 
				
			||||||
 | 
						return std::string(keyname(IO::keyCode)); | 
				
			||||||
 | 
					} | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					std::string IO::getStrInput() { | 
				
			||||||
 | 
						echo(); | 
				
			||||||
 | 
						char *tmp = new char(); | 
				
			||||||
 | 
						getstr(tmp); | 
				
			||||||
 | 
						noecho(); | 
				
			||||||
 | 
						return std::string(tmp); | 
				
			||||||
 | 
					} | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					bool IO::getQuit() { | 
				
			||||||
 | 
						return IO::quit; | 
				
			||||||
 | 
					} | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void IO::setQuit() { | 
				
			||||||
 | 
						IO::quit = true; | 
				
			||||||
 | 
					} | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int IO::keyCode = ERR; | 
				
			||||||
 | 
					bool IO::quit = false; | 
				
			||||||
@ -0,0 +1,29 @@ | 
				
			|||||||
 | 
					#ifndef INPUTOUTPUT_H | 
				
			||||||
 | 
					#define INPUTOUTPUT_H | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define KEY_ESC 27 | 
				
			||||||
 | 
					#define KEY_SPACE 32 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <string> | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class IO | 
				
			||||||
 | 
					{ | 
				
			||||||
 | 
					public: | 
				
			||||||
 | 
						static void initialize(); | 
				
			||||||
 | 
						static void update(); | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						static std::string trim(std::string str); | 
				
			||||||
 | 
						static std::string untrim(std::string str, unsigned int length); | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						static int getKeyCode(); | 
				
			||||||
 | 
						static std::string getKeyName(); | 
				
			||||||
 | 
						static std::string getStrInput(); | 
				
			||||||
 | 
						static bool getQuit(); | 
				
			||||||
 | 
						static void setQuit(); | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					private: | 
				
			||||||
 | 
						static int keyCode; | 
				
			||||||
 | 
						static bool quit; | 
				
			||||||
 | 
					}; | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#endif // INPUTOUTPUT_H
 | 
				
			||||||
@ -0,0 +1,56 @@ | 
				
			|||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * Rick van Vonderen | 
				
			||||||
 | 
					 * 0945444 | 
				
			||||||
 | 
					 * TI2B | 
				
			||||||
 | 
					 * | 
				
			||||||
 | 
					 * Avoid repeated writing by using: | 
				
			||||||
 | 
					 * - functions with parameters (no globals) instead of almost identical pieces of code | 
				
			||||||
 | 
					 * - repetitive loops and arrays            instead of identical activities | 
				
			||||||
 | 
					 * - constants                              instead of identical values | 
				
			||||||
 | 
					 * | 
				
			||||||
 | 
					 * Divide your program into modules and/or classes that: | 
				
			||||||
 | 
					 * - have an explicit, well-defined interface | 
				
			||||||
 | 
					 * - be as independent as possible | 
				
			||||||
 | 
					 * - to be developed and tested separately | 
				
			||||||
 | 
					 * | 
				
			||||||
 | 
					 * Make your code understandable for others by using: | 
				
			||||||
 | 
					 * - Clear names in camel case, only start class names with a capital letter, consistently indent | 
				
			||||||
 | 
					 * - Clear, concise commentary, only where this adds something | 
				
			||||||
 | 
					 * - Standard terminology from the customer's field or application | 
				
			||||||
 | 
					 * | 
				
			||||||
 | 
					 *  ClassExample | 
				
			||||||
 | 
					 *  variableExample | 
				
			||||||
 | 
					 *  DEFINE_EXAMPLE | 
				
			||||||
 | 
					 */ | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <cstring> // strcmp() | 
				
			||||||
 | 
					#include <ncurses.h> // refresh() | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "gamestate.h" | 
				
			||||||
 | 
					#include "inputoutput.h" | 
				
			||||||
 | 
					#include "mainmenu.h" | 
				
			||||||
 | 
					#include "test.h" | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					GameStateManager gameStateManager; | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int main(int argc, char *argv[]) { | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifdef DEBUG | 
				
			||||||
 | 
						// IO::print("DEBUG MODE ENABLED");
 | 
				
			||||||
 | 
						refresh(); | 
				
			||||||
 | 
						GameState::sleep(1000); | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (argc >= 2 && strcmp(argv[1], "-t") == 0) { | 
				
			||||||
 | 
							Test(); | 
				
			||||||
 | 
						} | 
				
			||||||
 | 
					#endif | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						gameStateManager.setState(new MainMenu()); | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						while (!IO::getQuit()) { | 
				
			||||||
 | 
							gameStateManager.render(); | 
				
			||||||
 | 
							gameStateManager.update(); | 
				
			||||||
 | 
						} | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return 0; | 
				
			||||||
 | 
					} | 
				
			||||||
@ -0,0 +1,338 @@ | 
				
			|||||||
 | 
					#include <algorithm> | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "board.h" | 
				
			||||||
 | 
					#include "boardwindow.h" | 
				
			||||||
 | 
					#include "inputoutput.h" | 
				
			||||||
 | 
					#include "maingame.h" | 
				
			||||||
 | 
					#include "mainmenu.h" | 
				
			||||||
 | 
					#include "messagebox.h" | 
				
			||||||
 | 
					#include "player.h" | 
				
			||||||
 | 
					#include "selectionbox.h" | 
				
			||||||
 | 
					#include "spaceship.h" | 
				
			||||||
 | 
					#include "window.h" | 
				
			||||||
 | 
					#include "infowindow.h" | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					MainGame::MainGame(Player **player) : | 
				
			||||||
 | 
						help("Phase 1!\n\nThe players take turns, placing a spaceship on a planet\nof their choice."), | 
				
			||||||
 | 
						phase(false), | 
				
			||||||
 | 
						playerTurn(0), | 
				
			||||||
 | 
						queuePlanet(-1), | 
				
			||||||
 | 
						player(player), | 
				
			||||||
 | 
						board(nullptr), | 
				
			||||||
 | 
						ship(nullptr), | 
				
			||||||
 | 
						boardWindow(nullptr), | 
				
			||||||
 | 
						infoWindow(nullptr) { | 
				
			||||||
 | 
						// Reserve 0 spaceships of memory for the queue
 | 
				
			||||||
 | 
						this->queue = new std::vector<SpaceShip *>(0); | 
				
			||||||
 | 
					} | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void MainGame::initialize() { | 
				
			||||||
 | 
						this->board = new Board(); | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						this->ship = new SpaceShip*[SHIP_SIZE] { nullptr }; | 
				
			||||||
 | 
						unsigned char cCounter = 0; | 
				
			||||||
 | 
						unsigned char colors[PLAYER_SIZE] = { PAIR_RED_BLACK, PAIR_BLUE_BLACK }; | 
				
			||||||
 | 
						unsigned char sCounter = 0; | 
				
			||||||
 | 
						unsigned char sizes[3] = { SpaceShip::SMALL, SpaceShip::MEDIUM, SpaceShip::BIG }; | 
				
			||||||
 | 
						// Create 9 ships for each player, 3 of each size
 | 
				
			||||||
 | 
						for (unsigned char i = 0; i < SHIP_SIZE; i++) { | 
				
			||||||
 | 
							if (i != 0 && i % (SHIP_SIZE / PLAYER_SIZE) == 0) { | 
				
			||||||
 | 
								cCounter++; | 
				
			||||||
 | 
							} | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							if (i != 0 && i % 3 == 0) { | 
				
			||||||
 | 
								sCounter++; | 
				
			||||||
 | 
							} | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							if (sCounter >= 3) { | 
				
			||||||
 | 
								sCounter = 0; | 
				
			||||||
 | 
							} | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							this->ship[i] = new SpaceShip(colors[cCounter], sizes[sCounter]); | 
				
			||||||
 | 
						} | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						this->boardWindow = new BoardWindow(0, 16, this->board); | 
				
			||||||
 | 
						this->infoWindow = new InfoWindow(0, 16, this->player, this->ship); | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// Display help message
 | 
				
			||||||
 | 
						MainGame::render(); | 
				
			||||||
 | 
						MessageBox(this->help); | 
				
			||||||
 | 
					} | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void MainGame::update() { | 
				
			||||||
 | 
						MainGame::sleep(250); | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// Display new help message on phase change
 | 
				
			||||||
 | 
						if (this->changePhase) { | 
				
			||||||
 | 
							this->phase = true; | 
				
			||||||
 | 
							this->changePhase = false; | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							this->help = "Phase 2!\n\nThe players take turns, evacuating a planet of their choice."; | 
				
			||||||
 | 
							MessageBox(this->help); | 
				
			||||||
 | 
							return; | 
				
			||||||
 | 
						} | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (!this->phase) { | 
				
			||||||
 | 
							this->phase1(); | 
				
			||||||
 | 
						} | 
				
			||||||
 | 
						else { | 
				
			||||||
 | 
							this->phase2(); | 
				
			||||||
 | 
						} | 
				
			||||||
 | 
					} | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void MainGame::render() { | 
				
			||||||
 | 
						this->boardWindow->clear(); | 
				
			||||||
 | 
						this->infoWindow->clear(); | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						this->boardWindow->update(); | 
				
			||||||
 | 
						this->infoWindow->update(); | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						this->boardWindow->render(); | 
				
			||||||
 | 
						this->infoWindow->render(); | 
				
			||||||
 | 
					} | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void MainGame::destroy() { | 
				
			||||||
 | 
						delete this->board; | 
				
			||||||
 | 
						delete this->boardWindow; | 
				
			||||||
 | 
						delete this->infoWindow; | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						for (int i = 0; i < SHIP_SIZE; i++) { | 
				
			||||||
 | 
							delete this->ship[i]; | 
				
			||||||
 | 
						} | 
				
			||||||
 | 
						delete []this->ship; | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						for (int i = 0; i < PLAYER_SIZE; i++) { | 
				
			||||||
 | 
							delete this->player[i]; | 
				
			||||||
 | 
						} | 
				
			||||||
 | 
						delete []this->player; | 
				
			||||||
 | 
					} | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void MainGame::phase1() { | 
				
			||||||
 | 
						std::string playerTurnStr = std::to_string(this->playerTurn + 1); | 
				
			||||||
 | 
						SelectionBox s = SelectionBox(0, 16); | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// Ask the current player to pick a Spaceship size
 | 
				
			||||||
 | 
						std::string sizeStr = "Player " + playerTurnStr + ", pick a spaceship size."; | 
				
			||||||
 | 
						std::string sizeOptions[] = {"S", "M", "B", "\0"}; | 
				
			||||||
 | 
						unsigned char sizeSelection = s.select(sizeStr, &sizeOptions[0]); | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// Ask the current player to pick a planet
 | 
				
			||||||
 | 
						std::string planetStr = "Player " + playerTurnStr + ", pick a planet to put this spaceship on."; | 
				
			||||||
 | 
						std::string planetOptions[] = {"1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "11", "12", "\0"}; | 
				
			||||||
 | 
						unsigned char planetSelection = s.select(planetStr, &planetOptions[0]); | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// Calculate array index
 | 
				
			||||||
 | 
						int startLoop = SHIP_SIZE / PLAYER_SIZE * this->playerTurn + (sizeSelection * 3); | 
				
			||||||
 | 
						// Get ships of player selected planet
 | 
				
			||||||
 | 
						auto ships = this->board->getShips(std::stoi(planetOptions[planetSelection])); | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						bool placedShip = false; | 
				
			||||||
 | 
						bool shouldExit; | 
				
			||||||
 | 
						// Check all 3 ships of the size the player selected
 | 
				
			||||||
 | 
						for (int i = startLoop; i < startLoop + 3; i++) { | 
				
			||||||
 | 
							shouldExit = false; | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							// Check if spaceship is already on a planet
 | 
				
			||||||
 | 
							if (this->ship[i]->getPlanet() != PLANET_UNSET) { | 
				
			||||||
 | 
								continue; | 
				
			||||||
 | 
							} | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							// If planet already holds spaceship of equal size
 | 
				
			||||||
 | 
							for(auto ship : *ships) { | 
				
			||||||
 | 
								if (this->ship[i]->getSize() == ship->getSize()) { | 
				
			||||||
 | 
									shouldExit = true; | 
				
			||||||
 | 
									break; | 
				
			||||||
 | 
								} | 
				
			||||||
 | 
							} | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							if (shouldExit) { | 
				
			||||||
 | 
								MessageBox("You cant place spaceships of the same size on a planet during this phase!", "Error"); | 
				
			||||||
 | 
								break; | 
				
			||||||
 | 
							} | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							// Add spaceship to planet
 | 
				
			||||||
 | 
							this->board->setShip(std::stoi(planetOptions[planetSelection]), this->ship[i]); | 
				
			||||||
 | 
							this->nextPlayerTurn(); | 
				
			||||||
 | 
							placedShip = true; | 
				
			||||||
 | 
							break; | 
				
			||||||
 | 
						} | 
				
			||||||
 | 
						if (!placedShip && !shouldExit) { | 
				
			||||||
 | 
							MessageBox("Please select a size of which you still have unplaced spaceships!", "Error"); | 
				
			||||||
 | 
						} | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// Check if all ships have been placed
 | 
				
			||||||
 | 
						bool allPlaced = true; | 
				
			||||||
 | 
						for (int i = 0; i < SHIP_SIZE; i++) { | 
				
			||||||
 | 
							if (this->ship[i]->getPlanet() == PLANET_UNSET) { | 
				
			||||||
 | 
								allPlaced = false; | 
				
			||||||
 | 
								break; | 
				
			||||||
 | 
							} | 
				
			||||||
 | 
						} | 
				
			||||||
 | 
						if (allPlaced) { | 
				
			||||||
 | 
							this->changePhase = true; | 
				
			||||||
 | 
						} | 
				
			||||||
 | 
					} | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void MainGame::phase2() { | 
				
			||||||
 | 
						std::string playerTurnStr = std::to_string(this->playerTurn + 1); | 
				
			||||||
 | 
						SelectionBox s = SelectionBox(0, 16); | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// Move next spaceship in the queue
 | 
				
			||||||
 | 
						if (this->queue->size() > 0) { | 
				
			||||||
 | 
							// Determine the middle of the board
 | 
				
			||||||
 | 
							unsigned char halfBoard = (BOARD_SIZE - 2) / 2; // 6
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							// Planet rotation order, where |x| is a black hole
 | 
				
			||||||
 | 
							// 1 ... 6 -> |13| -> 12 ... 7 -> |0| -> 1
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							// 0 .. 5
 | 
				
			||||||
 | 
							if (this->queuePlanet < halfBoard) { | 
				
			||||||
 | 
								this->queuePlanet++; | 
				
			||||||
 | 
							} | 
				
			||||||
 | 
							// 8 .. 13
 | 
				
			||||||
 | 
							else if (this->queuePlanet > halfBoard + 1) { | 
				
			||||||
 | 
								this->queuePlanet--; | 
				
			||||||
 | 
							} | 
				
			||||||
 | 
							// 6
 | 
				
			||||||
 | 
							else if (this->queuePlanet == halfBoard) { | 
				
			||||||
 | 
								this->queuePlanet = BOARD_SIZE - 1; | 
				
			||||||
 | 
							} | 
				
			||||||
 | 
							// 7
 | 
				
			||||||
 | 
							else if (this->queuePlanet == halfBoard + 1) { | 
				
			||||||
 | 
								this->queuePlanet = 0; | 
				
			||||||
 | 
							} | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							unsigned char shipSelection = 0; | 
				
			||||||
 | 
							// If the the current and next ship are of the same size, ask which goes first
 | 
				
			||||||
 | 
							if (this->queue->size() > 1) { | 
				
			||||||
 | 
								SpaceShip *tmpShip = this->queue->at(0); | 
				
			||||||
 | 
								SpaceShip *tmpShip2 = this->queue->at(1); | 
				
			||||||
 | 
								if (tmpShip->getSize() == tmpShip2->getSize() && | 
				
			||||||
 | 
									tmpShip->getColor() != tmpShip2->getColor()) { | 
				
			||||||
 | 
									std::string shipStr = "Player " + playerTurnStr + ", pick the next ship that will evacuate."; | 
				
			||||||
 | 
									std::string shipOptions[] = {"Yours", "Theirs", "\0"}; | 
				
			||||||
 | 
									shipSelection = s.select(shipStr, &shipOptions[0]); | 
				
			||||||
 | 
								} | 
				
			||||||
 | 
							} | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							board->moveShip(this->queuePlanet, this->queue->at(shipSelection)); | 
				
			||||||
 | 
							return; | 
				
			||||||
 | 
						} | 
				
			||||||
 | 
						else if (this->queuePlanet != -1) { | 
				
			||||||
 | 
							this->queuePlanet = -1; | 
				
			||||||
 | 
							this->nextPlayerTurn(); | 
				
			||||||
 | 
							this->calculateWinner(); | 
				
			||||||
 | 
							return; | 
				
			||||||
 | 
						} | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// Ask the current player if they want to skip their turn
 | 
				
			||||||
 | 
						unsigned char playerChip = this->player[this->playerTurn]->getChip(); | 
				
			||||||
 | 
						if (playerChip > 0) { | 
				
			||||||
 | 
							std::string skipStr = "Player " + playerTurnStr + ", do you want to skip your turn for 1 chip?"; | 
				
			||||||
 | 
							std::string skipOptions[] = {"No", "Yes", "\0"}; | 
				
			||||||
 | 
							unsigned char skipSelection = s.select(skipStr, &skipOptions[0]); | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							if (skipOptions[skipSelection] == "Yes") { | 
				
			||||||
 | 
								this->player[this->playerTurn]->setChip(playerChip - 1); | 
				
			||||||
 | 
								this->nextPlayerTurn(); | 
				
			||||||
 | 
								return; | 
				
			||||||
 | 
							} | 
				
			||||||
 | 
						} | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// Ask the current player to pick a planet
 | 
				
			||||||
 | 
						std::string planetStr = "Player " + playerTurnStr + ", pick a planet to evacuate."; | 
				
			||||||
 | 
						std::string planetOptions[] = {"1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "11", "12", "\0"}; | 
				
			||||||
 | 
						unsigned char planetSelection = s.select(planetStr, &planetOptions[0]); | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// Get ships of player selected planet
 | 
				
			||||||
 | 
						auto ships = this->board->getShips(std::stoi(planetOptions[planetSelection])); | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// Check if the selected planet holds a spaceship of the current player,
 | 
				
			||||||
 | 
						// using function/functor/lambda
 | 
				
			||||||
 | 
						unsigned char playerColor = this->player[(int)this->playerTurn]->getColor(); | 
				
			||||||
 | 
						auto findShip = std::find_if(ships->begin(), ships->end(), | 
				
			||||||
 | 
							[playerColor](SpaceShip *ship) {return ship->getColor() == playerColor; }); | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// If so, add this planet to the queue
 | 
				
			||||||
 | 
						if (findShip != ships->end()) { | 
				
			||||||
 | 
							this->queue = ships; | 
				
			||||||
 | 
							this->queuePlanet = this->queue->at(0)->getPlanet(); | 
				
			||||||
 | 
						} | 
				
			||||||
 | 
						else { | 
				
			||||||
 | 
							MessageBox("Please select a planet that holds a ship of your own!", "Error"); | 
				
			||||||
 | 
						} | 
				
			||||||
 | 
					} | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void MainGame::nextPlayerTurn() { | 
				
			||||||
 | 
						this->playerTurn++; | 
				
			||||||
 | 
						if (this->playerTurn > PLAYER_SIZE - 1) { | 
				
			||||||
 | 
							this->playerTurn = 0; | 
				
			||||||
 | 
						} | 
				
			||||||
 | 
					} | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void MainGame::calculateWinner() { | 
				
			||||||
 | 
						// Get all ships from the black holes
 | 
				
			||||||
 | 
						auto blackHole1 = this->board->getShips(0); | 
				
			||||||
 | 
						auto blackHole2 = this->board->getShips(BOARD_SIZE - 1); | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						int totalScore = CHIP_AMOUNT * CHIP_SCORE + | 
				
			||||||
 | 
							3 * SpaceShip::BIG + | 
				
			||||||
 | 
							3 * SpaceShip::MEDIUM + | 
				
			||||||
 | 
							3 * SpaceShip::SMALL; | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// Fill players possible total score
 | 
				
			||||||
 | 
						int score[PLAYER_SIZE]; | 
				
			||||||
 | 
						std::fill_n(score, PLAYER_SIZE, totalScore); | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// Calculate players score
 | 
				
			||||||
 | 
						int crashedShips; | 
				
			||||||
 | 
						bool gameOver = false; | 
				
			||||||
 | 
						for (int i = 0; i < PLAYER_SIZE; i++) { | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							// Subtract all used chips from the total score
 | 
				
			||||||
 | 
							score[i] -= (CHIP_AMOUNT - this->player[i]->getChip()) * CHIP_SCORE; | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							crashedShips = 0; | 
				
			||||||
 | 
							for (auto ship : *blackHole1) { | 
				
			||||||
 | 
								if (this->player[i]->getColor() == ship->getColor()) { | 
				
			||||||
 | 
									crashedShips++; | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
									// Subtract crashed ship from the total score
 | 
				
			||||||
 | 
									score[i] -= ship->getSize(); | 
				
			||||||
 | 
								} | 
				
			||||||
 | 
							} | 
				
			||||||
 | 
							for (auto ship : *blackHole2) { | 
				
			||||||
 | 
								if (this->player[i]->getColor() == ship->getColor()) { | 
				
			||||||
 | 
									crashedShips++; | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
									// Subtract crashed ship from the total score
 | 
				
			||||||
 | 
									score[i] -= ship->getSize(); | 
				
			||||||
 | 
								} | 
				
			||||||
 | 
							} | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							// If a player has run out of ships..
 | 
				
			||||||
 | 
							if (crashedShips == SHIP_SIZE / PLAYER_SIZE) { | 
				
			||||||
 | 
								gameOver = true; | 
				
			||||||
 | 
							} | 
				
			||||||
 | 
						} | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// Print victory screen
 | 
				
			||||||
 | 
						if (gameOver) { | 
				
			||||||
 | 
							std::string printStr; | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							int winnerIdx = 0; | 
				
			||||||
 | 
							for (int i = 0; i < PLAYER_SIZE; i++) { | 
				
			||||||
 | 
								printStr += "Player " + std::to_string(i + 1) + ": scored " + | 
				
			||||||
 | 
									std::to_string(score[i]) + " points.\n"; | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								if (i < PLAYER_SIZE - 1 && score[i] < score[i + 1]) { | 
				
			||||||
 | 
									winnerIdx = i + 1; | 
				
			||||||
 | 
								} | 
				
			||||||
 | 
							} | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							printStr.insert(0, this->player[winnerIdx]->getName() + " has won!\n\n"); | 
				
			||||||
 | 
							MessageBox(printStr, "Victory"); | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							gameStateManager.setState(new MainMenu()); | 
				
			||||||
 | 
						} | 
				
			||||||
 | 
					} | 
				
			||||||
@ -0,0 +1,49 @@ | 
				
			|||||||
 | 
					#ifndef MAINGAME_H | 
				
			||||||
 | 
					#define MAINGAME_H | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Each player holds 9 ships, 3 of each size
 | 
				
			||||||
 | 
					#define SHIP_SIZE 18 | 
				
			||||||
 | 
					#define PLAYER_SIZE 2 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <vector> | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "gamestate.h" | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class Board; | 
				
			||||||
 | 
					class BoardWindow; | 
				
			||||||
 | 
					class InfoWindow; | 
				
			||||||
 | 
					class Player; | 
				
			||||||
 | 
					class SpaceShip; | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class MainGame : public GameState | 
				
			||||||
 | 
					{ | 
				
			||||||
 | 
					public: | 
				
			||||||
 | 
						MainGame(Player **player); | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    void initialize(); | 
				
			||||||
 | 
					    void update(); | 
				
			||||||
 | 
					    void render(); | 
				
			||||||
 | 
					    void destroy(); | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					private: | 
				
			||||||
 | 
					    void phase1(); | 
				
			||||||
 | 
					    void phase2(); | 
				
			||||||
 | 
					    void nextPlayerTurn(); | 
				
			||||||
 | 
					    void calculateWinner(); | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						std::string help; | 
				
			||||||
 | 
						bool phase; | 
				
			||||||
 | 
						bool changePhase; | 
				
			||||||
 | 
						unsigned char playerTurn; | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						char queuePlanet; | 
				
			||||||
 | 
						std::vector<SpaceShip *> *queue; | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						Player **player; | 
				
			||||||
 | 
						Board *board; | 
				
			||||||
 | 
						SpaceShip **ship; | 
				
			||||||
 | 
						BoardWindow *boardWindow; | 
				
			||||||
 | 
						InfoWindow *infoWindow; | 
				
			||||||
 | 
					}; | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#endif // MAINGAME_H
 | 
				
			||||||
@ -0,0 +1,98 @@ | 
				
			|||||||
 | 
					#include "inputoutput.h" | 
				
			||||||
 | 
					#include "maingame.h" | 
				
			||||||
 | 
					#include "mainmenu.h" | 
				
			||||||
 | 
					#include "player.h" | 
				
			||||||
 | 
					#include "window.h" | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void MainMenu::initialize() { | 
				
			||||||
 | 
						int rows; | 
				
			||||||
 | 
						int cols; | 
				
			||||||
 | 
						Window::getMaXYZ(stdscr, rows, cols); | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						this->window = new Window(rows, cols, 0, 0); | 
				
			||||||
 | 
						this->titleScreen = true; | 
				
			||||||
 | 
						this->player = new Player*[PLAYER_SIZE] { nullptr }; | 
				
			||||||
 | 
					} | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void MainMenu::update() { | 
				
			||||||
 | 
						if (this->titleScreen) { | 
				
			||||||
 | 
							IO::update(); | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							if (IO::getKeyName() == " ") { | 
				
			||||||
 | 
								this->titleScreen = false; | 
				
			||||||
 | 
							} | 
				
			||||||
 | 
						} | 
				
			||||||
 | 
						else { | 
				
			||||||
 | 
							int y; | 
				
			||||||
 | 
							int x; | 
				
			||||||
 | 
							std::string tmpStr; | 
				
			||||||
 | 
							unsigned char colors[PLAYER_SIZE] = { PAIR_RED_BLACK, PAIR_BLUE_BLACK }; | 
				
			||||||
 | 
							for (int i = 0; i < PLAYER_SIZE; i++) { | 
				
			||||||
 | 
								if (this->player[i] == nullptr) { | 
				
			||||||
 | 
									this->window->getYX(y, x); | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
									tmpStr = ""; | 
				
			||||||
 | 
									while (tmpStr == "") { | 
				
			||||||
 | 
										tmpStr = IO::trim(this->window->getStr()); | 
				
			||||||
 | 
										this->window->setYX(y, x); | 
				
			||||||
 | 
									} | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
									this->player[i] = new Player(); | 
				
			||||||
 | 
									this->player[i]->setName(tmpStr); | 
				
			||||||
 | 
									this->player[i]->setColor(colors[i]); | 
				
			||||||
 | 
									break; | 
				
			||||||
 | 
								} | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								if (i == PLAYER_SIZE - 1) { | 
				
			||||||
 | 
									gameStateManager.setState(new MainGame(this->player)); | 
				
			||||||
 | 
								} | 
				
			||||||
 | 
							} | 
				
			||||||
 | 
						} | 
				
			||||||
 | 
					} | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void MainMenu::render() { | 
				
			||||||
 | 
						this->window->clear(); | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						this->window->update(); | 
				
			||||||
 | 
						this->window->setWindow(this->window->getMaxRows(), this->window->getMaxCols(), 0, 0); | 
				
			||||||
 | 
						this->window->resize(); | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (this->titleScreen) { | 
				
			||||||
 | 
							this->window->printSide("", "Rick van Vonderen"); | 
				
			||||||
 | 
							this->window->setYX(1, 0); | 
				
			||||||
 | 
							this->window->printSide("", "0945444"); | 
				
			||||||
 | 
							this->window->setYX(2, 0); | 
				
			||||||
 | 
							this->window->printSide("", "TI2B"); | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							this->window->setYX(this->window->getRows() / 2 - 1, 0); | 
				
			||||||
 | 
							this->window->printCenter("---   Space Walk   ---"); | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							this->window->setYX(this->window->getRows() - 4, 0); | 
				
			||||||
 | 
							this->window->printCenter("Press <Space> to walk.."); | 
				
			||||||
 | 
						} | 
				
			||||||
 | 
						else { | 
				
			||||||
 | 
							int x = this->window->getCols() / 2 - 11 ; | 
				
			||||||
 | 
							int y = this->window->getRows() / 2; | 
				
			||||||
 | 
							std::string tmp; | 
				
			||||||
 | 
							for (int i = 0; i < PLAYER_SIZE; i++) { | 
				
			||||||
 | 
								tmp = std::string("Enter Player ") + std::to_string(i + 1) + std::string(" name: "); | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								if (this->player[i] != nullptr) { | 
				
			||||||
 | 
									tmp += this->player[i]->getName(); | 
				
			||||||
 | 
								} | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								this->window->print(tmp, y, x); | 
				
			||||||
 | 
								y++; | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								if (this->player[i] == nullptr) { | 
				
			||||||
 | 
									break; | 
				
			||||||
 | 
								} | 
				
			||||||
 | 
							} | 
				
			||||||
 | 
						} | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						this->window->render(); | 
				
			||||||
 | 
					} | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void MainMenu::destroy() { | 
				
			||||||
 | 
						delete this->window; | 
				
			||||||
 | 
					} | 
				
			||||||
@ -0,0 +1,25 @@ | 
				
			|||||||
 | 
					#ifndef MAINMENU_H | 
				
			||||||
 | 
					#define MAINMENU_H | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <memory> | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "gamestate.h" | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class Player; | 
				
			||||||
 | 
					class Window; | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class MainMenu : public GameState | 
				
			||||||
 | 
					{ | 
				
			||||||
 | 
					public: | 
				
			||||||
 | 
					    void initialize(); | 
				
			||||||
 | 
					    void update(); | 
				
			||||||
 | 
					    void render(); | 
				
			||||||
 | 
					    void destroy(); | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					private: | 
				
			||||||
 | 
						bool titleScreen; | 
				
			||||||
 | 
						Window *window; | 
				
			||||||
 | 
						Player **player; | 
				
			||||||
 | 
					}; | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#endif // MAINMENU_H
 | 
				
			||||||
@ -0,0 +1,54 @@ | 
				
			|||||||
 | 
					#------------------------------------------------------------------------------#
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					PROGRAM := "space-walk"
 | 
				
			||||||
 | 
					HEADERS := \
 | 
				
			||||||
 | 
						board.h \
 | 
				
			||||||
 | 
						boardwindow.h \
 | 
				
			||||||
 | 
						gamestate.h \
 | 
				
			||||||
 | 
						infowindow.h \
 | 
				
			||||||
 | 
						inputoutput.h \
 | 
				
			||||||
 | 
						maingame.h \
 | 
				
			||||||
 | 
						mainmenu.h \
 | 
				
			||||||
 | 
						messagebox.h \
 | 
				
			||||||
 | 
						player.h \
 | 
				
			||||||
 | 
						selectionbox.h \
 | 
				
			||||||
 | 
						spaceship.h \
 | 
				
			||||||
 | 
						test.h \
 | 
				
			||||||
 | 
						window.h
 | 
				
			||||||
 | 
					SOURCES := \
 | 
				
			||||||
 | 
						board.cpp \
 | 
				
			||||||
 | 
						boardwindow.cpp \
 | 
				
			||||||
 | 
						infowindow.cpp \
 | 
				
			||||||
 | 
						inputoutput.cpp \
 | 
				
			||||||
 | 
						main.cpp \
 | 
				
			||||||
 | 
						maingame.cpp \
 | 
				
			||||||
 | 
						mainmenu.cpp \
 | 
				
			||||||
 | 
						messagebox.cpp \
 | 
				
			||||||
 | 
						player.cpp \
 | 
				
			||||||
 | 
						selectionbox.cpp \
 | 
				
			||||||
 | 
						spaceship.cpp \
 | 
				
			||||||
 | 
						test.cpp \
 | 
				
			||||||
 | 
						window.cpp
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#------------------------------------------------------------------------------#
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					CXX         := g++
 | 
				
			||||||
 | 
					CXXFLAGS    := -lncurses -std=c++11 -Wall -Wextra
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					.PHONY: all debug run clean | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					all: run | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					debug: CXXFLAGS += -g -DDEBUG | 
				
			||||||
 | 
					debug: run | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					run: compile | 
				
			||||||
 | 
						@./$(PROGRAM) ; \
 | 
				
			||||||
 | 
							stty sane
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					compile: ${HEADERS} ${SOURCES} | 
				
			||||||
 | 
						$(CXX) $(CXXFLAGS) $? -o $(PROGRAM)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					clean: | 
				
			||||||
 | 
						@-echo "Cleaning project.." ; \
 | 
				
			||||||
 | 
							rm -f $(PROGRAM)
 | 
				
			||||||
@ -0,0 +1,57 @@ | 
				
			|||||||
 | 
					#include <ncurses.h> // A_REVERSE | 
				
			||||||
 | 
					#include <sstream> // istringstream | 
				
			||||||
 | 
					#include <vector> | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "inputoutput.h" | 
				
			||||||
 | 
					#include "messagebox.h" | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					MessageBox::MessageBox(std::string message) : | 
				
			||||||
 | 
						MessageBox(message, "") { | 
				
			||||||
 | 
					} | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					MessageBox::MessageBox(std::string message, std::string title) { | 
				
			||||||
 | 
						// Split message on newline
 | 
				
			||||||
 | 
						std::vector<std::string> lines; | 
				
			||||||
 | 
						std::istringstream strStream(message); | 
				
			||||||
 | 
						std::string tmpStr; | 
				
			||||||
 | 
						while (std::getline(strStream, tmpStr, '\n')) { | 
				
			||||||
 | 
							lines.push_back(tmpStr); | 
				
			||||||
 | 
						} | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						int rows; | 
				
			||||||
 | 
						int cols; | 
				
			||||||
 | 
						Window::getMaXYZ(stdscr, rows, cols); | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// Calculate window dimension and size
 | 
				
			||||||
 | 
						int winRows = lines.size() + 8; | 
				
			||||||
 | 
						int winCols = cols * 0.9; | 
				
			||||||
 | 
						int y = (rows - winRows) / 2; | 
				
			||||||
 | 
						int x = (cols - winCols) / 2; | 
				
			||||||
 | 
						this->setWindow(winRows, winCols, y, x); | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// Print title
 | 
				
			||||||
 | 
						title = IO::untrim(!title.empty() ? title : "Message", winCols - 2); | 
				
			||||||
 | 
						this->print(title, 0, 0, A_REVERSE); | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// Print the message line by line
 | 
				
			||||||
 | 
						y = (winRows - lines.size()) / 2 - 1; | 
				
			||||||
 | 
						for (auto l : lines) { | 
				
			||||||
 | 
							this->setYX(y, 0); | 
				
			||||||
 | 
							this->printCenter(l); | 
				
			||||||
 | 
							y++; | 
				
			||||||
 | 
						} | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						this->setYX(winRows - 3, 0); | 
				
			||||||
 | 
						this->printCenter("Press <Space> to continue ", | 
				
			||||||
 | 
								COLOR_PAIR(PAIR_GRAY_BLACK_BRIGHT)); | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						this->render(); | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// Press space to continue
 | 
				
			||||||
 | 
						while(!IO::getQuit()) { | 
				
			||||||
 | 
							IO::update(); | 
				
			||||||
 | 
							if (IO::getKeyName() == " ") { | 
				
			||||||
 | 
								break; | 
				
			||||||
 | 
							} | 
				
			||||||
 | 
						} | 
				
			||||||
 | 
					} | 
				
			||||||
@ -0,0 +1,17 @@ | 
				
			|||||||
 | 
					#ifndef MESSAGEBOX_H | 
				
			||||||
 | 
					#define MESSAGEBOX_H | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <string> | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "window.h" | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class MessageBox : public Window | 
				
			||||||
 | 
					{ | 
				
			||||||
 | 
					public: | 
				
			||||||
 | 
						MessageBox(std::string message); | 
				
			||||||
 | 
						MessageBox(std::string message, std::string title); | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					private: | 
				
			||||||
 | 
					}; | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#endif // MESSAGEBOX_H
 | 
				
			||||||
@ -0,0 +1,53 @@ | 
				
			|||||||
 | 
					#include <ncurses.h> // A_REVERSE | 
				
			||||||
 | 
					#include <stdio.h> | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "player.h" | 
				
			||||||
 | 
					#include "infowindow.h" | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Player::Player() : | 
				
			||||||
 | 
						chip(CHIP_AMOUNT), | 
				
			||||||
 | 
						name("") { | 
				
			||||||
 | 
					} | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void Player::render(InfoWindow *window, int y, int x, unsigned char number) { | 
				
			||||||
 | 
						std::string print; | 
				
			||||||
 | 
						print += "   Player "; | 
				
			||||||
 | 
						print += std::to_string(number); | 
				
			||||||
 | 
						print += "   "; | 
				
			||||||
 | 
						window->print(print, y, x - 1, A_REVERSE); | 
				
			||||||
 | 
						y += 2; | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						window->print(this->name, y, x, COLOR_PAIR(this->color)); | 
				
			||||||
 | 
						y += 2; | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						for (unsigned char i = 0; i < this->chip; i++) { | 
				
			||||||
 | 
							window->print("C", y, x, COLOR_PAIR(PAIR_WHITE_BLACK)); | 
				
			||||||
 | 
							x++; | 
				
			||||||
 | 
							window->print(" ", y, x); | 
				
			||||||
 | 
							x++; | 
				
			||||||
 | 
						} | 
				
			||||||
 | 
					} | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					unsigned char Player::getChip() { | 
				
			||||||
 | 
						return this->chip; | 
				
			||||||
 | 
					} | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void Player::setChip(unsigned char chip) { | 
				
			||||||
 | 
						this->chip = chip; | 
				
			||||||
 | 
					} | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					unsigned char Player::getColor() { | 
				
			||||||
 | 
						return this->color; | 
				
			||||||
 | 
					} | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void Player::setColor(unsigned char color) { | 
				
			||||||
 | 
						this->color = color; | 
				
			||||||
 | 
					} | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					std::string Player::getName() { | 
				
			||||||
 | 
						return this->name; | 
				
			||||||
 | 
					} | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void Player::setName(std::string name) { | 
				
			||||||
 | 
						this->name = name; | 
				
			||||||
 | 
					} | 
				
			||||||
@ -0,0 +1,31 @@ | 
				
			|||||||
 | 
					#ifndef PLAYER_H | 
				
			||||||
 | 
					#define PLAYER_H | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define CHIP_AMOUNT 4 | 
				
			||||||
 | 
					#define CHIP_SCORE 2 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <string> | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class InfoWindow; | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class Player | 
				
			||||||
 | 
					{ | 
				
			||||||
 | 
					public: | 
				
			||||||
 | 
						Player(); | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						void render(InfoWindow *window, int y, int x, unsigned char number); | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						unsigned char getChip(); | 
				
			||||||
 | 
						void setChip(unsigned char chip); | 
				
			||||||
 | 
						unsigned char getColor(); | 
				
			||||||
 | 
						void setColor(unsigned char color); | 
				
			||||||
 | 
						std::string getName(); | 
				
			||||||
 | 
						void setName(std::string name); | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					private: | 
				
			||||||
 | 
						unsigned char chip; | 
				
			||||||
 | 
						unsigned char color; | 
				
			||||||
 | 
						std::string name; | 
				
			||||||
 | 
					}; | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#endif // PLAYER_H
 | 
				
			||||||
@ -0,0 +1,88 @@ | 
				
			|||||||
 | 
					#include <cstring> // strlen | 
				
			||||||
 | 
					#include <sstream> // istringstream | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "inputoutput.h" | 
				
			||||||
 | 
					#include "selectionbox.h" | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					SelectionBox::SelectionBox(int height, int width) : | 
				
			||||||
 | 
						height(height), | 
				
			||||||
 | 
						width(width) { | 
				
			||||||
 | 
						this->update(); | 
				
			||||||
 | 
					} | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void SelectionBox::update() { | 
				
			||||||
 | 
						Window::update(); | 
				
			||||||
 | 
						this->resize(); | 
				
			||||||
 | 
					} | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void SelectionBox::resize() { | 
				
			||||||
 | 
						int rows = (this->getMaxRows() - this->height) / 4; | 
				
			||||||
 | 
						int cols = this->getMaxCols() - this->width; | 
				
			||||||
 | 
						this->setWindow(rows, cols, this->getMaxRows() - rows, 0); | 
				
			||||||
 | 
						Window::resize(); | 
				
			||||||
 | 
					} | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					unsigned char SelectionBox::select(std::string str, std::string *selection) { | 
				
			||||||
 | 
						int amount = 0; | 
				
			||||||
 | 
						while (!selection[amount].empty()) { | 
				
			||||||
 | 
							amount++; | 
				
			||||||
 | 
						} | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						std::string tmpStr; | 
				
			||||||
 | 
						int tmpInt; | 
				
			||||||
 | 
						// Display options and get user input
 | 
				
			||||||
 | 
						while(!IO::getQuit()) { | 
				
			||||||
 | 
							this->clear(); | 
				
			||||||
 | 
							this->update(); | 
				
			||||||
 | 
							this->printSelection(str, selection); | 
				
			||||||
 | 
							this->render(); | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							tmpStr = IO::trim(this->getStr()); | 
				
			||||||
 | 
							if (tmpStr == "") { | 
				
			||||||
 | 
								continue; | 
				
			||||||
 | 
							} | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							if (this->isNumber(tmpStr)) { | 
				
			||||||
 | 
								tmpInt = std::stoi(tmpStr); | 
				
			||||||
 | 
								if (tmpInt > 0 && tmpInt < amount + 1) { | 
				
			||||||
 | 
									break; | 
				
			||||||
 | 
								} | 
				
			||||||
 | 
							} | 
				
			||||||
 | 
						} | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return (unsigned char)tmpInt - 1; | 
				
			||||||
 | 
					} | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void SelectionBox::printSelection(std::string str, std::string *selection) { | 
				
			||||||
 | 
						int y = 0; | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// Split and print message on newline
 | 
				
			||||||
 | 
						std::istringstream strStream(str); | 
				
			||||||
 | 
						std::string tmpStr; | 
				
			||||||
 | 
						while (std::getline(strStream, tmpStr, '\n')) { | 
				
			||||||
 | 
							this->print(tmpStr, y, 1); | 
				
			||||||
 | 
							y++; | 
				
			||||||
 | 
						} | 
				
			||||||
 | 
						y++; | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						int amount = 0; | 
				
			||||||
 | 
						while (!selection[amount].empty()) { | 
				
			||||||
 | 
							if (amount < 6) { | 
				
			||||||
 | 
								this->print("- " + selection[amount], y, 1); | 
				
			||||||
 | 
							} | 
				
			||||||
 | 
							else { | 
				
			||||||
 | 
								this->print("- " + selection[amount], y - 6, 10); | 
				
			||||||
 | 
							} | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							y++; | 
				
			||||||
 | 
							amount++; | 
				
			||||||
 | 
						} | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						this->print("Select option number: ", this->getRows() - 3, 1); | 
				
			||||||
 | 
					} | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					bool SelectionBox::isNumber(const std::string &s) { | 
				
			||||||
 | 
					    std::string::const_iterator it = s.begin(); | 
				
			||||||
 | 
					    while (it != s.end() && std::isdigit(*it)) it++; | 
				
			||||||
 | 
					    return !s.empty() && it == s.end(); | 
				
			||||||
 | 
					} | 
				
			||||||
@ -0,0 +1,26 @@ | 
				
			|||||||
 | 
					#ifndef SELECTIONBOX_H | 
				
			||||||
 | 
					#define SELECTIONBOX_H | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <string> | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "window.h" | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class SelectionBox : public Window | 
				
			||||||
 | 
					{ | 
				
			||||||
 | 
					public: | 
				
			||||||
 | 
						SelectionBox(int height, int width); | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						void update(); | 
				
			||||||
 | 
						void resize(); | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						unsigned char select(std::string str, std::string *selection); | 
				
			||||||
 | 
						void printSelection(std::string str, std::string *selection); | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					private: | 
				
			||||||
 | 
						bool isNumber(const std::string &s); | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						int height; | 
				
			||||||
 | 
						int width; | 
				
			||||||
 | 
					}; | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#endif // SELECTIONBOX_H
 | 
				
			||||||
@ -0,0 +1,57 @@ | 
				
			|||||||
 | 
					#include "spaceship.h" | 
				
			||||||
 | 
					#include "window.h" | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					SpaceShip::SpaceShip() : | 
				
			||||||
 | 
						color(COLOR_UNSET), | 
				
			||||||
 | 
						size(SpaceShip::SIZE_UNSET), | 
				
			||||||
 | 
						planet(PLANET_UNSET) { | 
				
			||||||
 | 
					} | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					SpaceShip::SpaceShip(unsigned char color, unsigned char size) : | 
				
			||||||
 | 
						color(color), | 
				
			||||||
 | 
						size(size), | 
				
			||||||
 | 
						planet(PLANET_UNSET) { | 
				
			||||||
 | 
					} | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void SpaceShip::render(Window *window, int y, int x, bool checkPlaced) { | 
				
			||||||
 | 
						if (checkPlaced && this->planet != PLANET_UNSET) { | 
				
			||||||
 | 
							return; | 
				
			||||||
 | 
						} | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						std::string print = ""; | 
				
			||||||
 | 
						if (this->size == SpaceShip::SMALL) { | 
				
			||||||
 | 
							print = "S"; | 
				
			||||||
 | 
						} | 
				
			||||||
 | 
						else if (this->size == SpaceShip::MEDIUM) { | 
				
			||||||
 | 
							print = "M"; | 
				
			||||||
 | 
						} | 
				
			||||||
 | 
						else if (this->size == SpaceShip::BIG) { | 
				
			||||||
 | 
							print = "B"; | 
				
			||||||
 | 
						} | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						window->print(print, y, x, COLOR_PAIR(this->color)); | 
				
			||||||
 | 
					} | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					unsigned char SpaceShip::getColor() { | 
				
			||||||
 | 
						return this->color; | 
				
			||||||
 | 
					} | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void SpaceShip::setColor(unsigned char color) { | 
				
			||||||
 | 
						this->color = color; | 
				
			||||||
 | 
					} | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					unsigned char SpaceShip::getSize() { | 
				
			||||||
 | 
						return this->size; | 
				
			||||||
 | 
					} | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void SpaceShip::setSize(unsigned char size) { | 
				
			||||||
 | 
						this->size = size; | 
				
			||||||
 | 
					} | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					char SpaceShip::getPlanet() { | 
				
			||||||
 | 
						return this->planet; | 
				
			||||||
 | 
					} | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void SpaceShip::setPlanet(char planet) { | 
				
			||||||
 | 
						this->planet = planet; | 
				
			||||||
 | 
					} | 
				
			||||||
@ -0,0 +1,36 @@ | 
				
			|||||||
 | 
					#ifndef SPACESHIP_H | 
				
			||||||
 | 
					#define SPACESHIP_H | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define PLANET_UNSET -1 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class Window; | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class SpaceShip | 
				
			||||||
 | 
					{ | 
				
			||||||
 | 
					public: | 
				
			||||||
 | 
						SpaceShip(); | 
				
			||||||
 | 
						SpaceShip(unsigned char color, unsigned char size); | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						void render(Window *window, int y, int x, bool checkPlaced = true); | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						unsigned char getColor(); | 
				
			||||||
 | 
						void setColor(unsigned char color); | 
				
			||||||
 | 
						unsigned char getSize(); | 
				
			||||||
 | 
						void setSize(unsigned char size); | 
				
			||||||
 | 
						char getPlanet(); | 
				
			||||||
 | 
						void setPlanet(char planet); | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						enum Size { | 
				
			||||||
 | 
							SIZE_UNSET = 0, | 
				
			||||||
 | 
							SMALL = 1, | 
				
			||||||
 | 
							MEDIUM = 3, | 
				
			||||||
 | 
							BIG = 4, | 
				
			||||||
 | 
						}; | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					private: | 
				
			||||||
 | 
						unsigned char color; | 
				
			||||||
 | 
						unsigned char size; | 
				
			||||||
 | 
						char planet; | 
				
			||||||
 | 
					}; | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#endif // SPACESHIP_H
 | 
				
			||||||
@ -0,0 +1,68 @@ | 
				
			|||||||
 | 
					#include <cassert> | 
				
			||||||
 | 
					#include <iostream> | 
				
			||||||
 | 
					#include <ncurses.h> | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "board.h" | 
				
			||||||
 | 
					#include "inputoutput.h" | 
				
			||||||
 | 
					#include "maingame.h" | 
				
			||||||
 | 
					#include "player.h" | 
				
			||||||
 | 
					#include "spaceship.h" | 
				
			||||||
 | 
					#include "test.h" | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Test::Test() { | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// IO::print("Unit test\n");
 | 
				
			||||||
 | 
						refresh(); | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// Board tests
 | 
				
			||||||
 | 
						Board *board = new Board; | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						char arrayShip[3] = { SpaceShip::SMALL, SpaceShip::MEDIUM, SpaceShip::BIG }; | 
				
			||||||
 | 
						SpaceShip *ship  = new SpaceShip(1, arrayShip[0]); | 
				
			||||||
 | 
						SpaceShip *ship2 = new SpaceShip(1, arrayShip[1]); | 
				
			||||||
 | 
						SpaceShip *ship3 = new SpaceShip(1, arrayShip[2]); | 
				
			||||||
 | 
						board->setShip(0, ship); | 
				
			||||||
 | 
						board->setShip(0, ship); | 
				
			||||||
 | 
						board->setShip(1, ship); | 
				
			||||||
 | 
						board->setShip(1, ship2); | 
				
			||||||
 | 
						board->setShip(2, ship3); | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						for (int i = 0; i < 3; i++) { | 
				
			||||||
 | 
							auto ships = board->getShips(i); | 
				
			||||||
 | 
							// printf("%lu\n", ships->size());
 | 
				
			||||||
 | 
							for (int j = 0; j < (int)ships->size(); j++) { | 
				
			||||||
 | 
								// printf("%d\n", ships->at(j)->getSize());
 | 
				
			||||||
 | 
								assert(ships->at(j)->getSize() == arrayShip[i]); | 
				
			||||||
 | 
							} | 
				
			||||||
 | 
							assert(ships->size() == 1); | 
				
			||||||
 | 
						} | 
				
			||||||
 | 
						board->moveShip(3, ship3); | 
				
			||||||
 | 
						assert(board->getShip(3, 0)->getSize() == arrayShip[2]); | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// char array[SHIP_SIZE] = {
 | 
				
			||||||
 | 
							// SpaceShip::SMALL, SpaceShip::SMALL, SpaceShip::SMALL,
 | 
				
			||||||
 | 
							// SpaceShip::MEDIUM, SpaceShip::MEDIUM, SpaceShip::MEDIUM,
 | 
				
			||||||
 | 
							// SpaceShip::BIG, SpaceShip::BIG, SpaceShip::BIG,
 | 
				
			||||||
 | 
							// SpaceShip::SMALL, SpaceShip::SMALL, SpaceShip::SMALL,
 | 
				
			||||||
 | 
							// SpaceShip::MEDIUM, SpaceShip::MEDIUM, SpaceShip::MEDIUM,
 | 
				
			||||||
 | 
							// SpaceShip::BIG, SpaceShip::BIG, SpaceShip::BIG,
 | 
				
			||||||
 | 
						// };
 | 
				
			||||||
 | 
						// for (unsigned char i = 0; i < SHIP_SIZE; i++) {
 | 
				
			||||||
 | 
							// // printf("%d\n", board.ships[i]->getSize());
 | 
				
			||||||
 | 
							// // printf("%d\n", array[i]);
 | 
				
			||||||
 | 
							// assert(board.ships[i]->getSize() == array[i]);
 | 
				
			||||||
 | 
						// }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// IO::print("Passed board checks..");
 | 
				
			||||||
 | 
						refresh(); | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						getch(); | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// Cleanup resources
 | 
				
			||||||
 | 
						delete board; | 
				
			||||||
 | 
						delete ship; | 
				
			||||||
 | 
						delete ship2; | 
				
			||||||
 | 
						delete ship3; | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						IO::setQuit(); | 
				
			||||||
 | 
					} | 
				
			||||||
@ -0,0 +1,12 @@ | 
				
			|||||||
 | 
					#ifndef TEST_H | 
				
			||||||
 | 
					#define TEST_H | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class Test | 
				
			||||||
 | 
					{ | 
				
			||||||
 | 
					public: | 
				
			||||||
 | 
						Test(); | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					private: | 
				
			||||||
 | 
					}; | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#endif // TEST_H
 | 
				
			||||||
@ -0,0 +1,222 @@ | 
				
			|||||||
 | 
					#include <cstdio> | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "gamestate.h" | 
				
			||||||
 | 
					#include "window.h" | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Window::Window(int rows, int cols, int y, int x) : | 
				
			||||||
 | 
						rows(rows), | 
				
			||||||
 | 
						cols(cols), | 
				
			||||||
 | 
						y(0), | 
				
			||||||
 | 
						x(0), | 
				
			||||||
 | 
						window(newwin(rows, cols, y, x)) { | 
				
			||||||
 | 
					} | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Window::~Window() { | 
				
			||||||
 | 
						delwin(this->window); | 
				
			||||||
 | 
					} | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void Window::initialize() { | 
				
			||||||
 | 
						// Start curses mode
 | 
				
			||||||
 | 
						initscr(); | 
				
			||||||
 | 
						// Disable line buffering
 | 
				
			||||||
 | 
						cbreak(); | 
				
			||||||
 | 
						// Enable reading of function keys
 | 
				
			||||||
 | 
						keypad(stdscr, TRUE); | 
				
			||||||
 | 
						// Dont echo while reading input
 | 
				
			||||||
 | 
						noecho(); | 
				
			||||||
 | 
						// Disable cursor visibility
 | 
				
			||||||
 | 
						curs_set(0); | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// If terminal supports colors
 | 
				
			||||||
 | 
						if(!has_colors()) { | 
				
			||||||
 | 
							printw("Your terminal does not support color\n"); | 
				
			||||||
 | 
						} | 
				
			||||||
 | 
						else { | 
				
			||||||
 | 
							start_color(); | 
				
			||||||
 | 
							use_default_colors(); | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							init_pair(PAIR_WHITE_BLACK, COLOR_WHITE, COLOR_BLACK); | 
				
			||||||
 | 
							init_pair(PAIR_WHITE_BRIGHT_BLACK, COLOR_WHITE_BRIGHT, COLOR_BLACK); | 
				
			||||||
 | 
							init_pair(PAIR_RED_BLACK, COLOR_RED, COLOR_BLACK); | 
				
			||||||
 | 
							init_pair(PAIR_BLUE_BLACK, COLOR_BLUE, COLOR_BLACK); | 
				
			||||||
 | 
							init_pair(PAIR_GRAY_BLACK_BRIGHT, COLOR_GRAY, COLOR_BLACK_BRIGHT); | 
				
			||||||
 | 
						} | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// Add bright colors, intensity range: 0-1000
 | 
				
			||||||
 | 
						if(!can_change_color()) { | 
				
			||||||
 | 
							printw("Your terminal does not support changing colors\n"); | 
				
			||||||
 | 
						} | 
				
			||||||
 | 
						else { | 
				
			||||||
 | 
							init_color(COLOR_BLACK,             0,    0,    0); | 
				
			||||||
 | 
							init_color(COLOR_WHITE,           680,  680,  680); | 
				
			||||||
 | 
							init_color(COLOR_GRAY,            380,  380,  380); | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							init_color(COLOR_BLACK_BRIGHT,    110,  110,  110); //   0,   0,   0
 | 
				
			||||||
 | 
							init_color(COLOR_RED_BRIGHT,      900,    0,    0); // 680,   0,   0
 | 
				
			||||||
 | 
							init_color(COLOR_GREEN_BRIGHT,      0,  900,    0); //   0, 680,   0
 | 
				
			||||||
 | 
							init_color(COLOR_YELLOW_BRIGHT,   900,  900,    0); // 680, 680,   0
 | 
				
			||||||
 | 
							init_color(COLOR_BLUE_BRIGHT,       0,    0,  900); //   0,   0, 680
 | 
				
			||||||
 | 
							init_color(COLOR_MAGENTA_BRIGHT,  900,    0,  900); // 680,   0, 680
 | 
				
			||||||
 | 
							init_color(COLOR_CYAN_BRIGHT,       0,  900,  900); //   0, 680, 680
 | 
				
			||||||
 | 
							init_color(COLOR_WHITE_BRIGHT,    900,  900,  900); // 680, 680, 680
 | 
				
			||||||
 | 
						} | 
				
			||||||
 | 
					} | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void Window::update() { | 
				
			||||||
 | 
						Window::getMaXYZ(stdscr, this->maxRows, this->maxCols); | 
				
			||||||
 | 
					} | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void Window::render() { | 
				
			||||||
 | 
						box(this->window, 0, 0); | 
				
			||||||
 | 
						wrefresh(this->window); | 
				
			||||||
 | 
					} | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void Window::destroy() { | 
				
			||||||
 | 
						// Restore line buffering
 | 
				
			||||||
 | 
						nocbreak(); | 
				
			||||||
 | 
						// Restore cursor
 | 
				
			||||||
 | 
						curs_set(1); | 
				
			||||||
 | 
						// End curses mode
 | 
				
			||||||
 | 
						endwin(); | 
				
			||||||
 | 
					} | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void Window::clear() { | 
				
			||||||
 | 
						this->setYX(0, 0); | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// Set background color
 | 
				
			||||||
 | 
						// wbkgdset(this->window, COLOR_PAIR(3));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// Copy blanks to every position in the window, clearing the screen
 | 
				
			||||||
 | 
						werase(this->window); | 
				
			||||||
 | 
					} | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void Window::resize() { | 
				
			||||||
 | 
						wresize(this->window, this->rows, this->cols); | 
				
			||||||
 | 
						mvwin(this->window, this->y, this->x); | 
				
			||||||
 | 
					} | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void Window::print(std::string str, char newLine) { | 
				
			||||||
 | 
						this->print(str, this->y, this->x); | 
				
			||||||
 | 
						this->x += str.length(); | 
				
			||||||
 | 
						if (newLine == 1) { | 
				
			||||||
 | 
							this->x = 0; | 
				
			||||||
 | 
							this->y++; | 
				
			||||||
 | 
						} | 
				
			||||||
 | 
					} | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void Window::print(std::string str, int y, int x) { | 
				
			||||||
 | 
						this->y = y; | 
				
			||||||
 | 
						this->x = x; | 
				
			||||||
 | 
						mvwprintw(this->window, y + 1, x + 1, str.c_str()); | 
				
			||||||
 | 
					} | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void Window::print(std::string str, int y, int x, int attribute) { | 
				
			||||||
 | 
						wattron(this->window, attribute); | 
				
			||||||
 | 
						this->print(str, y, x); | 
				
			||||||
 | 
						wattroff(this->window, attribute); | 
				
			||||||
 | 
					} | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void Window::printCenter(std::string str) { | 
				
			||||||
 | 
						int halfBoard = this->cols / 2; | 
				
			||||||
 | 
						int halfStr = str.length() / 2; | 
				
			||||||
 | 
						this->print(str, this->y, halfBoard - halfStr - 1); | 
				
			||||||
 | 
					} | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void Window::printCenter(std::string str, int attribute) { | 
				
			||||||
 | 
						wattron(this->window, attribute); | 
				
			||||||
 | 
						this->printCenter(str); | 
				
			||||||
 | 
						wattroff(this->window, attribute); | 
				
			||||||
 | 
					} | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void Window::printSide(std::string left, std::string right) { | 
				
			||||||
 | 
						this->print(left, this->y, 1); | 
				
			||||||
 | 
						this->print(right, this->y, this->cols - right.length() - 3); | 
				
			||||||
 | 
					} | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void Window::getYX(int &y, int &x) { | 
				
			||||||
 | 
						getyx(this->window, y, x); | 
				
			||||||
 | 
					} | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void Window::setYX(int y, int x) { | 
				
			||||||
 | 
						this->y = y; | 
				
			||||||
 | 
						this->x = x; | 
				
			||||||
 | 
						wmove(this->window, y, x); | 
				
			||||||
 | 
					} | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void Window::getMaXYZ(int &rows, int &cols) { | 
				
			||||||
 | 
						getmaxyx(this->window, rows, cols); | 
				
			||||||
 | 
					} | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void Window::getMaXYZ(WINDOW *window, int &rows, int &cols) { | 
				
			||||||
 | 
						getmaxyx(window, rows, cols); | 
				
			||||||
 | 
					} | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					std::string Window::getStr() { | 
				
			||||||
 | 
						curs_set(1); | 
				
			||||||
 | 
						echo(); | 
				
			||||||
 | 
						char *tmp = new char(); | 
				
			||||||
 | 
						wgetstr(this->window, tmp); | 
				
			||||||
 | 
						noecho(); | 
				
			||||||
 | 
						curs_set(0); | 
				
			||||||
 | 
						return std::string(tmp); | 
				
			||||||
 | 
					} | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int Window::getMaxRows() { | 
				
			||||||
 | 
						return this->maxRows; | 
				
			||||||
 | 
					} | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int Window::getMaxCols() { | 
				
			||||||
 | 
						return this->maxCols; | 
				
			||||||
 | 
					} | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int Window::getRows() { | 
				
			||||||
 | 
						return this->rows; | 
				
			||||||
 | 
					} | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void Window::setRows(int rows) { | 
				
			||||||
 | 
						this->rows = rows; | 
				
			||||||
 | 
					} | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int Window::getCols() { | 
				
			||||||
 | 
						return this->cols; | 
				
			||||||
 | 
					} | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void Window::setCols(int cols) { | 
				
			||||||
 | 
						this->cols = cols; | 
				
			||||||
 | 
					} | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int Window::getY() { | 
				
			||||||
 | 
						return this->y; | 
				
			||||||
 | 
					} | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void Window::setY(int y) { | 
				
			||||||
 | 
						this->y = y; | 
				
			||||||
 | 
					} | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int Window::getX() { | 
				
			||||||
 | 
						return this->x; | 
				
			||||||
 | 
					} | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void Window::setX(int x) { | 
				
			||||||
 | 
						this->x = x; | 
				
			||||||
 | 
					} | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void Window::setWindow(int rows, int cols, int y, int x) { | 
				
			||||||
 | 
						this->setRows(rows); | 
				
			||||||
 | 
						this->setCols(cols); | 
				
			||||||
 | 
						this->setY(y); | 
				
			||||||
 | 
						this->setX(x); | 
				
			||||||
 | 
						if (this->window == nullptr) { | 
				
			||||||
 | 
							this->window = newwin(rows, cols, y, x); | 
				
			||||||
 | 
						} | 
				
			||||||
 | 
					} | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					//----------------------------------------------------------------------------//
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Window::Window() : | 
				
			||||||
 | 
						rows(0), | 
				
			||||||
 | 
						cols(0), | 
				
			||||||
 | 
						y(0), | 
				
			||||||
 | 
						x(0), | 
				
			||||||
 | 
						window(nullptr) { | 
				
			||||||
 | 
					} | 
				
			||||||
@ -0,0 +1,75 @@ | 
				
			|||||||
 | 
					#ifndef WINDOW_H | 
				
			||||||
 | 
					#define WINDOW_H | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define COLOR_UNSET 0 | 
				
			||||||
 | 
					#define COLOR_BLACK_BRIGHT 8 | 
				
			||||||
 | 
					#define COLOR_RED_BRIGHT 9 | 
				
			||||||
 | 
					#define COLOR_GREEN_BRIGHT 10 | 
				
			||||||
 | 
					#define COLOR_YELLOW_BRIGHT 11 | 
				
			||||||
 | 
					#define COLOR_BLUE_BRIGHT 12 | 
				
			||||||
 | 
					#define COLOR_MAGENTA_BRIGHT 13 | 
				
			||||||
 | 
					#define COLOR_CYAN_BRIGHT 14 | 
				
			||||||
 | 
					#define COLOR_WHITE_BRIGHT 15 | 
				
			||||||
 | 
					#define COLOR_GRAY 16 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define PAIR_WHITE_BLACK 1 | 
				
			||||||
 | 
					#define PAIR_WHITE_BRIGHT_BLACK 2 | 
				
			||||||
 | 
					#define PAIR_RED_BLACK 3 | 
				
			||||||
 | 
					#define PAIR_BLUE_BLACK 4 | 
				
			||||||
 | 
					#define PAIR_GRAY_BLACK_BRIGHT 5 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <ncurses.h> | 
				
			||||||
 | 
					#include <string> | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class Window | 
				
			||||||
 | 
					{ | 
				
			||||||
 | 
					public: | 
				
			||||||
 | 
						Window(int rows, int cols, int y, int x); | 
				
			||||||
 | 
						~Window(); | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						static void initialize(); | 
				
			||||||
 | 
						void update(); | 
				
			||||||
 | 
						void render(); | 
				
			||||||
 | 
						static void destroy(); | 
				
			||||||
 | 
						void clear(); | 
				
			||||||
 | 
						void resize(); | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						void print(std::string str, char newLine = 1); | 
				
			||||||
 | 
						void print(std::string str, int y, int x); | 
				
			||||||
 | 
						void print(std::string str, int y, int x, int attribute); | 
				
			||||||
 | 
						void printCenter(std::string str); | 
				
			||||||
 | 
						void printCenter(std::string str, int attribute); | 
				
			||||||
 | 
						void printSide(std::string left, std::string right); | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						void getYX(int &y, int &x); | 
				
			||||||
 | 
						void setYX(int y, int x); | 
				
			||||||
 | 
						void getMaXYZ(int &rows, int &cols); | 
				
			||||||
 | 
						static void getMaXYZ(WINDOW *window, int &rows, int &cols); | 
				
			||||||
 | 
						std::string getStr(); | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						int getMaxRows(); | 
				
			||||||
 | 
						int getMaxCols(); | 
				
			||||||
 | 
						int getRows(); | 
				
			||||||
 | 
						void setRows(int rows); | 
				
			||||||
 | 
						int getCols(); | 
				
			||||||
 | 
						void setCols(int cols); | 
				
			||||||
 | 
						int getY(); | 
				
			||||||
 | 
						void setY(int y); | 
				
			||||||
 | 
						int getX(); | 
				
			||||||
 | 
						void setX(int x); | 
				
			||||||
 | 
						void setWindow(int rows, int cols, int y, int x); | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					protected: | 
				
			||||||
 | 
						Window(); | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					private: | 
				
			||||||
 | 
						int maxRows; | 
				
			||||||
 | 
						int maxCols; | 
				
			||||||
 | 
						int rows; | 
				
			||||||
 | 
						int cols; | 
				
			||||||
 | 
						int y; | 
				
			||||||
 | 
						int x; | 
				
			||||||
 | 
						WINDOW *window; | 
				
			||||||
 | 
					}; | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#endif // WINDOW_H
 | 
				
			||||||
					Loading…
					
					
				
		Reference in new issue