diff options
author | Matt Kohls <mattkohls13@gmail.com> | 2019-01-15 22:51:01 -0500 |
---|---|---|
committer | Matt Kohls <mattkohls13@gmail.com> | 2019-01-15 22:51:01 -0500 |
commit | 5d8f5c1499f4cc42a1dce5cb4a1775cccf0da0f1 (patch) | |
tree | 498495ce8d2846143755a27bf846af5396888ef9 | |
parent | 231e342f52ca6ce9864c66e00f53bb4de568f93f (diff) | |
download | fungi-5d8f5c1499f4cc42a1dce5cb4a1775cccf0da0f1.tar.gz fungi-5d8f5c1499f4cc42a1dce5cb4a1775cccf0da0f1.tar.bz2 fungi-5d8f5c1499f4cc42a1dce5cb4a1775cccf0da0f1.zip |
Breaking things out into different filesrefactor
-rw-r--r-- | fungi.cpp | 425 | ||||
-rw-r--r-- | petri.h | 288 | ||||
-rw-r--r-- | sdlwindow.h | 143 | ||||
-rw-r--r-- | window.h | 95 |
4 files changed, 535 insertions, 416 deletions
@@ -7,16 +7,17 @@ * GPL v3 */ -#include <vector> #include <iostream> #include <stdlib.h> #include <stdint.h> -#include <SDL2/SDL.h> +#include "petri.h" +#include "window.h" +#include "sdlwindow.h" /** Important Constants **/ -const uint8_t GROWTH_RATE = 4; /* A percent out of 100 */ +uint8_t GROWTH_RATE = 4; /* A percent out of 100 */ const uint8_t TICKS = 10; /*Time to wait between growths */ const int SCREEN_WIDTH = 640; @@ -24,417 +25,6 @@ const int SCREEN_HEIGHT = 480; /** Important Objects **/ -/* - * Window Position - * Keeps track of window position - */ -struct Window_Pos { - uint16_t posx; - uint16_t posy; -}; - -/* - * Window Size - * Keeps track of window size - */ -struct Window_Size { - uint16_t width; - uint16_t height; -}; - -/* - * Location - * Keeps track of where we are - */ -struct Location { - uint16_t posx; - uint16_t posy; -}; - -/* - * Color - * Keeps track of the appearance of the fungus - */ -struct Color { - uint8_t red; - uint8_t green; - uint8_t blue; - uint8_t alpha; -}; - -/* - * Fungus - * More or less just a pixel - */ -class Fungus { -private: - struct Location local; - struct Color color; - uint8_t growthPoints; - uint8_t hp; - -public: - /** - * Creates a useless Fungus - */ - Fungus() { - hp = 0; - growthPoints = 0; - } - - /** - * Creates a Fungus - * @param l The location the fungus should live in - * @param c The color the fungus should be - */ - Fungus(const Location& l, const Color& c) { - local.posx = l.posx; - local.posy = l.posy; - color.red = c.red; - color.green = c.green; - color.blue = c.blue; - color.alpha = c.alpha; - hp = 10; - growthPoints = 0; - } - - ~Fungus() {} - - /** - * Get the location of the fungus - * @return The location of the fungus - */ - Location getLocation() const { return local; } - - /** - * Get the color of the fungus - * @return The color of the fungus - */ - Color getColor() const { return color; } - - /** - * Adds growth to the fungus - * @param val Amount to grow the fungus - */ - void addGrowth(uint8_t val) { growthPoints += val; } - - /** - * Gets the current growth of the fungus - * @return Current growth points of fungus - */ - uint8_t getGrowthPoints() const { return growthPoints; } - - /** - * Gets the current health of the fungus - * @return Current health points of the fungus - */ - uint8_t getHP() const { return hp; } -}; - -/* - * Petri - * Where the fungus live, grow, and die - */ -class Petri { -private: - uint32_t maxSize; - std::vector<Fungus*> population; // Holds only the living fungus - std::vector< std::vector<Fungus*> > dish; // Keeps track of each position - // a fungus may live - - /** - * Grows a fungus - * @param f The fungus to grow - * @return Either a new fungus or nullptr if no children spawn - */ - Fungus* growFungus(Fungus& f) { - uint8_t val = random(); - while(val > 100) { - val = random(); - } - if(val < GROWTH_RATE) { - f.addGrowth(1); - } - Fungus* child = nullptr; - if(f.getGrowthPoints() >= 10) { - f.addGrowth(255 - f.getGrowthPoints()); - Location home = f.getLocation(); - home.posx += 1; - home.posy += 1; - child = new Fungus(home, f.getColor()); - } - return child; - } - -public: - /** - * Creates a useless Petri dish - */ - Petri() { - maxSize = 0; - //population = nullptr; - //dish = nullptr; - } - - /** - * Creates a Petri dish for the fungus to live in - * @param maxSize Maximum number of fungi that we will have - * @param ws The size of the window the petri dish should fill - */ - Petri(uint32_t maxSize, const Window_Size& ws) { - this->maxSize = maxSize; - population.reserve(maxSize); - for(int i = 0; i < maxSize; i++) { - population.push_back(nullptr); - } - dish.reserve(ws.width); - std::vector<Fungus*> temp(ws.height); - for(int i = 0; i < ws.height; i++) { - temp.push_back(nullptr); - } - for(int i = 0; i < ws.width; i++) { - dish.push_back(temp); - } - - } - - /** - * Copy construction - * Doesn't work right apparently - */ - /* - Petri(const Petri& p) { - dish.reserve(p.getSize()); - for(int i = 0; i < p.getSize(); i++) { - dish.push_back(nullptr); - } - for(int i = 0; i < dish.size(); i++) { - Fungus* temp = p.getFungus(i); - if(temp != nullptr) { - addFungus(new Fungus(temp->getLocation(), temp->getColor())); - } - } - } - */ - - /** - * Destroyer of dishes - */ - ~Petri() { - for(int i = 0; i < population.size(); i++) { - if(population[i] != nullptr) { - Fungus* temp = population[i]; - population[i] = nullptr; - delete temp; - } - } - } - - /** - * Gets a Fungus from the dish - * @param i The position of the fungus from the dish we want - */ - Fungus* operator[](const uint32_t& i) { return getFungus(i); } - - /** - * Gets a Fungus from the dish - * @param i The position of the fungus from the dish we want - */ - Fungus* getFungus(const uint32_t& i) const { - if(i >= population.size()) { - return nullptr; - } else { - return population[i]; - } - } - - /** - * Adds a fungus to the dish, unless that spot is full, then the fungus is - * deleted from existence. - * @param f The fungus to add - */ - void addFungus(Fungus* f) { - if(dish[f->getLocation().posy][f->getLocation().posx] == nullptr) { - dish[f->getLocation().posy][f->getLocation().posx] = f; - for(int i = 0; i < population.size(); i++) { - if(population[i] == nullptr) { - population[i] = f; - break; - } - } - } else { - delete f; - } - } - - /** - * Simulates one round of fungus life - * - */ - void grow() { - for(int i = 0; i < dish.size(); i++) { - for(int j = 0; j < dish[i].size(); j++) { - if(dish[i][j] != nullptr) { - Fungus* newFungus = growFungus(*dish[i][j]); - if(newFungus != nullptr) { - addFungus(newFungus); - } - } - } - } - - } - - /** - * Get size of dish - * @return Max number of fungus we can hold in dish - */ - uint32_t getSize() const { return maxSize; } - - /** - * Gives the fungus - * @return The 2D vector of fungus - */ - std::vector<std::vector<Fungus*> > & getDish() { return dish; } - - /** - * Get list of living fungus - * @return Vector of fungus in the dish - */ - std::vector<Fungus*> & getPopulation() { return population; } -}; - -/* - * SDLWindow - * The display into our fungus world - */ -class SDLWindow { -private: - SDL_Window* sdlWindow; - SDL_Renderer* sdlRenderer; - Petri petri; - bool bad; - - /** - * Log an SDL error with some error message to the output stream of our choice - * @param os The output stream to write the message to - * @param msg The error message to write, format will be msg error: SDL_GetError() - */ - void logSDLError(std::ostream &os, const std::string &msg) { - os << msg << " error: " << SDL_GetError() << std::endl; - } - - /** - * Brings up all the SDL objects we will need to draw our window - * @param winpos The position we want for the window - * @param winsize The size we want for the window - */ - void init(const Window_Pos& winpos, const Window_Size& winsize) { - if (SDL_Init(SDL_INIT_EVERYTHING) != 0){ - logSDLError(std::cout, "SDL_Init"); - bad = true; - } - sdlWindow = SDL_CreateWindow("Fungi", winpos.posx, winpos.posy, - winsize.width, winsize.height, - SDL_WINDOW_OPENGL); - if (sdlWindow == nullptr){ - logSDLError(std::cout, "CreateWindow"); - SDL_Quit(); - bad = true; - } - sdlRenderer = SDL_CreateRenderer(sdlWindow, -1, - SDL_RENDERER_SOFTWARE); - if (sdlRenderer == nullptr){ - logSDLError(std::cout, "CreateRenderer"); - SDL_DestroyWindow(sdlWindow); - sdlWindow = nullptr; - SDL_Quit(); - bad = true; - } - SDL_SetRenderDrawColor(sdlRenderer, 0, 0, 0, 255); - SDL_RenderClear(sdlRenderer); - SDL_RenderPresent(sdlRenderer); - } - - /** - * Draws a fungus on the screen - * @param f The fungus we want to draw - */ - void drawFungus(const Fungus& f) { - Color color = f.getColor(); - Location loc = f.getLocation(); - SDL_SetRenderDrawColor(sdlRenderer, color.red, color.green, color.blue, - color.alpha); - SDL_RenderDrawPoint(sdlRenderer, loc.posx, loc.posy); - } - -public: - /** - * Creates a SDLWindow without anything to show - */ - SDLWindow() { - bad = false; - init({100, 100}, {SCREEN_WIDTH, SCREEN_HEIGHT}); - } - - /** - * Creates a SDLWindow with an attached Petri dish - * @param p A petri dish - */ - SDLWindow(const Petri& p) { - petri = p; - bad = false; - init({100, 100}, {SCREEN_WIDTH, SCREEN_HEIGHT}); - } - - /** - * Destroyer of the window - */ - ~SDLWindow() { - if(sdlWindow != nullptr) { - SDL_DestroyWindow(sdlWindow); - } - if(sdlRenderer != nullptr) { - SDL_DestroyRenderer(sdlRenderer); - } - SDL_Quit(); - } - - /** - * Runs the growth of the fungus till the end of time - */ - void doFungus() { - - SDL_Event event; - bool end = false; - while(!end) { - while(SDL_PollEvent(&event)) { - if(event.type == SDL_QUIT) { - end = true; - } - } - - for(int i = 0; i < petri.getSize(); i++) { - if(petri[i] != nullptr) { - drawFungus(*petri[i]); - } - } - - SDL_RenderPresent(sdlRenderer); - - petri.grow(); - - SDL_Delay(TICKS); - } - - } - - /** - * Tells if the windows is bad, aka an SDL error - * @return True if window is bad, False if not - */ - bool isBad() const { return bad; } -}; /** Important Functions **/ @@ -443,8 +33,11 @@ int main(int argv, char* argc[]) { srandom(11); + Window_Pos wp = {100, 100}; Window_Size ws = {SCREEN_WIDTH, SCREEN_HEIGHT}; - Petri* p = new Petri(SCREEN_HEIGHT * SCREEN_WIDTH, ws); + Dish_Size ds = {SCREEN_WIDTH, SCREEN_HEIGHT}; + uint32_t max = SCREEN_WIDTH * SCREEN_HEIGHT; + Petri* p = new Petri(max, ds, GROWTH_RATE); p->addFungus(new Fungus({0, 0}, {255, 0, 0, 0})); p->addFungus(new Fungus({0, 1}, {0, 255, 0, 0})); @@ -458,7 +51,7 @@ int main(int argv, char* argc[]) { } */ - SDLWindow win(*p); + SDLWindow win(wp ,ws, *p); if(!win.isBad()) { win.doFungus(); } @@ -0,0 +1,288 @@ +/** + * + * + */ + +#ifndef PETRI_H +#define PETRI_H + +#include <vector> +#include <stdint.h> + +/* + * Location + * Keeps track of where we are + */ +struct Location { + uint16_t posx; + uint16_t posy; +}; + +/* + * Dish Size + * Keeps track of the size of the dish + */ +struct Dish_Size { + uint16_t width; + uint16_t height; +}; + +/* + * Color + * Keeps track of the appearance of the fungus + */ +struct Color { + uint8_t red; + uint8_t green; + uint8_t blue; + uint8_t alpha; +}; + +/* + * Fungus + * More or less just a pixel + */ +class Fungus { +private: + struct Location local; + struct Color color; + uint8_t growthPoints; + uint8_t hp; + +public: + /** + * Creates a useless Fungus + */ + Fungus() { + hp = 0; + growthPoints = 0; + color = {0, 0, 0, 0}; + local = {0, 0}; + } + + /** + * Creates a Fungus + * @param l The location the fungus should live in + * @param c The color the fungus should be + */ + Fungus(const Location& l, const Color& c) { + local.posx = l.posx; + local.posy = l.posy; + color.red = c.red; + color.green = c.green; + color.blue = c.blue; + color.alpha = c.alpha; + hp = 10; + growthPoints = 0; + } + + ~Fungus() {} + + /** + * Get the location of the fungus + * @return The location of the fungus + */ + Location getLocation() const { return local; } + + /** + * Get the color of the fungus + * @return The color of the fungus + */ + Color getColor() const { return color; } + + /** + * Adds growth to the fungus + * @param val Amount to grow the fungus + */ + void addGrowth(uint8_t val) { growthPoints += val; } + + /** + * Gets the current growth of the fungus + * @return Current growth points of fungus + */ + uint8_t getGrowthPoints() const { return growthPoints; } + + /** + * Gets the current health of the fungus + * @return Current health points of the fungus + */ + uint8_t getHP() const { return hp; } +}; + +/* + * Petri + * Where the fungus live, grow, and die + */ +class Petri { +private: + uint32_t maxSize; + uint8_t growthRate; + std::vector<Fungus*> population; // Holds only the living fungus + std::vector< std::vector<Fungus*> > dish; // Keeps track of each position + // a fungus may live + + /** + * Grows a fungus + * @param f The fungus to grow + * @return Either a new fungus or nullptr if no children spawn + */ + Fungus* growFungus(Fungus& f) { + uint8_t val = random(); + while(val > 100) { + val = random(); + } + if(val < growthRate) { + f.addGrowth(1); + } + Fungus* child = nullptr; + if(f.getGrowthPoints() >= 10) { + f.addGrowth(255 - f.getGrowthPoints()); + Location home = f.getLocation(); + home.posx += 1; + home.posy += 1; + child = new Fungus(home, f.getColor()); + } + return child; + } + +public: + /** + * Creates a useless Petri dish + */ + Petri() { + maxSize = 0; + //population = nullptr; + //dish = nullptr; + } + + /** + * Creates a Petri dish for the fungus to live in + * @param maxSize Maximum number of fungi that we will have + * @param ws The size of the window the petri dish should fill + * @param gr The growth rate of fungus inside this dish + */ + Petri(const uint32_t& maxSize, const Dish_Size& ds, const uint8_t& gr) { + this->maxSize = maxSize; + this->growthRate = gr; + population.reserve(maxSize); + for(int i = 0; i < maxSize; i++) { + population.push_back(nullptr); + } + dish.reserve(ds.width); + std::vector<Fungus*> temp(ds.height); + for(int i = 0; i < ds.height; i++) { + temp.push_back(nullptr); + } + for(int i = 0; i < ds.width; i++) { + dish.push_back(temp); + } + + } + + /** + * Copy construction + * Doesn't work right apparently + */ + /* + Petri(const Petri& p) { + dish.reserve(p.getSize()); + for(int i = 0; i < p.getSize(); i++) { + dish.push_back(nullptr); + } + for(int i = 0; i < dish.size(); i++) { + Fungus* temp = p.getFungus(i); + if(temp != nullptr) { + addFungus(new Fungus(temp->getLocation(), temp->getColor())); + } + } + } + */ + + /** + * Destroyer of dishes + */ + ~Petri() { + for(int i = 0; i < population.size(); i++) { + if(population[i] != nullptr) { + Fungus* temp = population[i]; + population[i] = nullptr; + delete temp; + } + } + } + + /** + * Gets a Fungus from the dish + * @param i The position of the fungus from the dish we want + */ + Fungus* operator[](const uint32_t& i) { return getFungus(i); } + + /** + * Gets a Fungus from the dish + * @param i The position of the fungus from the dish we want + */ + Fungus* getFungus(const uint32_t& i) const { + if(i >= population.size()) { + return nullptr; + } else { + return population[i]; + } + } + + /** + * Adds a fungus to the dish, unless that spot is full, then the fungus is + * deleted from existence. + * @param f The fungus to add + */ + void addFungus(Fungus* f) { + if(dish[f->getLocation().posy][f->getLocation().posx] == nullptr) { + dish[f->getLocation().posy][f->getLocation().posx] = f; + for(int i = 0; i < population.size(); i++) { + if(population[i] == nullptr) { + population[i] = f; + break; + } + } + } else { + delete f; + } + } + + /** + * Simulates one round of fungus life + * + */ + void grow() { + for(int i = 0; i < dish.size(); i++) { + for(int j = 0; j < dish[i].size(); j++) { + if(dish[i][j] != nullptr) { + Fungus* newFungus = growFungus(*dish[i][j]); + if(newFungus != nullptr) { + addFungus(newFungus); + } + } + } + } + + } + + /** + * Get size of dish + * @return Max number of fungus we can hold in dish + */ + uint32_t getSize() const { return maxSize; } + + /** + * Gives the fungus + * @return The 2D vector of fungus + */ + std::vector<std::vector<Fungus*> > & getDish() { return dish; } + + /** + * Get list of living fungus + * @return Vector of fungus in the dish + */ + std::vector<Fungus*> & getPopulation() { return population; } +}; + +#endif diff --git a/sdlwindow.h b/sdlwindow.h new file mode 100644 index 0000000..ade4e3f --- /dev/null +++ b/sdlwindow.h @@ -0,0 +1,143 @@ +/** + * + * + */ + +#ifndef SDLWINDOW_H +#define SDLWINDOW_H + +#include "window.h" +#include <iostream> +#include <SDL2/SDL.h> + +/* + * SDLWindow + * The display into our fungus world + */ +class SDLWindow : public Window { +private: + SDL_Window* sdlWindow; + SDL_Renderer* sdlRenderer; + + /** + * Log an SDL error with some error message to the output stream of our choice + * @param os The output stream to write the message to + * @param msg The error message to write, format will be msg error: SDL_GetError() + */ + void logSDLError(std::ostream &os, const std::string &msg) { + os << msg << " error: " << SDL_GetError() << std::endl; + } + + /** + * Brings up all the SDL objects we will need to draw our window + * @param winpos The position we want for the window + * @param winsize The size we want for the window + */ + void init() { + if (SDL_Init(SDL_INIT_EVERYTHING) != 0){ + logSDLError(std::cout, "SDL_Init"); + bad = true; + } + sdlWindow = SDL_CreateWindow("Fungi", winposition.posx, + winposition.posy, + winsize.width, winsize.height, + SDL_WINDOW_OPENGL); + if (sdlWindow == nullptr){ + logSDLError(std::cout, "CreateWindow"); + SDL_Quit(); + bad = true; + } + sdlRenderer = SDL_CreateRenderer(sdlWindow, -1, + SDL_RENDERER_SOFTWARE); + if (sdlRenderer == nullptr){ + logSDLError(std::cout, "CreateRenderer"); + SDL_DestroyWindow(sdlWindow); + sdlWindow = nullptr; + SDL_Quit(); + bad = true; + } + SDL_SetRenderDrawColor(sdlRenderer, 0, 0, 0, 255); + SDL_RenderClear(sdlRenderer); + SDL_RenderPresent(sdlRenderer); + } + + /** + * Draws a fungus on the screen + * @param f The fungus we want to draw + */ + void drawFungus(const Fungus& f) { + Color color = f.getColor(); + Location loc = f.getLocation(); + SDL_SetRenderDrawColor(sdlRenderer, color.red, color.green, color.blue, + color.alpha); + SDL_RenderDrawPoint(sdlRenderer, loc.posx, loc.posy); + } + +public: + /** + * Creates a SDLWindow without anything to show + */ + SDLWindow() : Window() { + sdlWindow = nullptr; + sdlRenderer = nullptr; + } + + /** + * Creates a SDLWindow with an attached Petri dish + * @param p A petri dish + */ + SDLWindow(const Window_Pos& pos, const Window_Size& size, const Petri& p) : + Window(pos, size, p) { + init(); + } + + /** + * Destroyer of the window + */ + ~SDLWindow() { + if(sdlWindow != nullptr) { + SDL_DestroyWindow(sdlWindow); + } + if(sdlRenderer != nullptr) { + SDL_DestroyRenderer(sdlRenderer); + } + SDL_Quit(); + } + + /** + * Runs the growth of the fungus till the end of time + */ + void doFungus() { + + SDL_Event event; + bool end = false; + while(!end) { + while(SDL_PollEvent(&event)) { + if(event.type == SDL_QUIT) { + end = true; + } + } + + for(int i = 0; i < petri.getSize(); i++) { + if(petri[i] != nullptr) { + drawFungus(*petri[i]); + } + } + + SDL_RenderPresent(sdlRenderer); + + petri.grow(); + + //SDL_Delay(TICKS); + } + + } + + /** + * Tells if the windows is bad, aka an SDL error + * @return True if window is bad, False if not + */ + bool isBad() const { return bad; } +}; + +#endif diff --git a/window.h b/window.h new file mode 100644 index 0000000..9313a92 --- /dev/null +++ b/window.h @@ -0,0 +1,95 @@ +/** + * + * + */ + +#ifndef WINDOW_H +#define WINDOW_H + +#include <stdint.h> +#include "petri.h" + +/* + * Window Position + * Keeps track of window position + */ +struct Window_Pos { + uint16_t posx; + uint16_t posy; +}; + +/* + * Window Size + * Keeps track of window size + */ +struct Window_Size { + uint16_t width; + uint16_t height; +}; + + +class Window { +protected: + Petri petri; + bool bad; + struct Window_Size winsize; + struct Window_Pos winposition; + + /** + * Draws a fungus to the window display + * @param f The fungus to draw + */ + virtual void drawFungus(const Fungus& f); + +public: + Window() { + winsize = {0, 0}; + winposition = {0, 0}; + bad = true; // Since there is nothing to be drawn + } + + /** + * Creates a new window in a given position and a given size + * @param pos Position of window + * @param size Size of window + * @param p Petri dish to display + */ + Window(const Window_Pos& pos, const Window_Size& size, const Petri& p) { + winsize.width = size.width; + winsize.height = size.height; + winposition.posx = pos.posx; + winposition.posy = pos.posy; + bad = false; + petri = p; + } + + /** + * Destroy the window + */ + virtual ~Window(); + + /** + * Starts the simulation + */ + virtual void doFungus(); + + /** + * Gives position of window + * @return Window_Pos struct holding window current position + */ + virtual Window_Pos getWindowPosition() const { return winposition; } + + /** + * Gives window size + * @return Window_Size struct holding size of current window + */ + virtual Window_Size getWindowSize() const { return winsize; } + + /** + * Tells if there has been some error setting up the window + * @return True if there is an error, False if not + */ + virtual bool isBad() const { return bad; } +}; + +#endif |