Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <iostream>
- #include <string>
- #include <SFML/Graphics.hpp>
- #include <SFML/Network.hpp>
- #include <random>
- using namespace std;
- class Matrix
- {
- public:
- Matrix(sf::RenderWindow &win, sf::Vector2f origin, float immunity)
- {
- //window pointer takes address of window parameter to matrix constructor
- window = &win;
- //take origin position as constructor parameter
- originPos = origin;
- //set up text
- font.loadFromFile("REFSAN.ttf");
- text.setFont(font);
- text.setString("hello, hello, default text.. CHANGE ME");
- text.setCharacterSize(10);
- text.setStyle(sf::Text::Bold);
- text.setPosition(origin.x + 150, origin.y + 50);
- //create the circle objects which make up matrix
- //init positions and colours
- for (int i = 0; i < 1000; i += 10)
- {
- sf::CircleShape circle(5);
- //init positions
- //offset by origin x,y values
- int xOffset = origin.x;
- int yOffset = origin.y;
- if (i < 100)
- circle.setPosition(xOffset + (i + 10), yOffset + 20);
- if (i >= 100 && i < 200)
- circle.setPosition(xOffset + ((i - 100) + 10), yOffset + 30);
- if (i >= 200 && i < 300)
- circle.setPosition(xOffset + ((i - 200) + 10), yOffset + 40);
- if (i >= 300 && i < 400)
- circle.setPosition(xOffset + ((i - 300) + 10), yOffset + 50);
- if (i >= 400 && i < 500)
- circle.setPosition(xOffset + ((i - 400) + 10), yOffset + 60);
- if (i >= 500 && i < 600)
- circle.setPosition(xOffset + ((i - 500) + 10), yOffset + 70);
- if (i >= 600 && i < 700)
- circle.setPosition(xOffset + ((i - 600) + 10), yOffset + 80);
- if (i >= 700 && i < 800)
- circle.setPosition(xOffset + ((i - 700) + 10), yOffset + 90);
- if (i >= 800 && i < 900)
- circle.setPosition(xOffset + ((i - 800) + 10), yOffset + 100);
- if (i >= 900 && i < 1000)
- circle.setPosition(xOffset + ((i - 900) + 10), yOffset + 110);
- //set colours..
- circle.setFillColor(sf::Color(200, 200, 200));
- //put each circle in vector container
- circleVec.push_back(circle);
- }
- //Random Utility
- std::random_device dev;
- std::mt19937 rng(dev());
- std::uniform_int_distribution<std::mt19937::result_type> dist(0, 10); // distribution in range [1,10]
- //to get a random number, for example write: int x = rng(dist)
- //set up immune cells
- //x is threshold of immunity under which cells will be immunised
- immunityThreshold = immunity;
- for (int i = 0; i < 100; ++i)
- {
- int r = dist(rng);
- float f = r / 10.0;
- if (f < immunityThreshold)
- {
- circleVec[i].setFillColor(sf::Color::Green);
- }
- }
- //set up random location where 1st infected cell appears
- std::uniform_int_distribution<std::mt19937::result_type> dist2(0, 100); // distribution in range [1,10]
- int randInfElement = dist2(rng);
- sf::Color green = sf::Color::Green;
- //don't start the infected cell on an immunised guy
- if (circleVec[randInfElement].getFillColor() == green)
- {
- while (circleVec[randInfElement].getFillColor() == green)
- {
- randInfElement = dist2(rng);
- }
- circleVec[randInfElement].setFillColor(sf::Color::Cyan);
- }
- else
- circleVec[randInfElement].setFillColor(sf::Color::Cyan);
- //end constructor
- }
- //Put this function just after the while(window.isopen()){} statement, before the events
- void RunInfection()
- {
- //Check adjacent elements to infected elements, put the elements to infect in vector to process later
- for (int i = 0; i < circleVec.size(); ++i)
- {
- if (circleVec[i].getFillColor() == sf::Color::Cyan)
- {
- //cout << "Colour is cyan!\n";
- //infect to right
- if (i < 99) //don't access vector if i is 99+
- {
- if (circleVec[i + 1].getFillColor() != sf::Color::Cyan && circleVec[i + 1].getFillColor() != sf::Color::Green)
- {
- //In this case, don't check neighbours to the right
- if (i != 9 && i != 19 && i != 29 && i != 39 && i != 49 && i != 59 && i != 69 && i != 79 && i != 89 && i != 99)
- {
- //cout << "i in infect right loop == " << i << endl;
- elemsToInfec.push_back(i + 1);
- }
- }
- }
- //infect to left
- if (i > 0)
- {
- if (circleVec[i - 1].getFillColor() != sf::Color::Cyan && circleVec[i - 1].getFillColor() != sf::Color::Green)
- {
- //In this case, don't check neighbours to the left.
- if (i % 10 == 0 || i == 0)
- {
- //do nothing
- }
- else
- elemsToInfec.push_back(i - 1);
- }
- }
- //infect above
- //In this case, don't check neighbours above
- if (i > 9)
- {
- if (circleVec[i - 10].getFillColor() != sf::Color::Cyan && circleVec[i - 10].getFillColor() != sf::Color::Green)
- {
- if (i >= 0 && i <= 9)
- {
- //do nothing
- //circleVec[i].setFillColor(sf::Color::Red);
- }
- else
- elemsToInfec.push_back(i - 10);
- }
- }
- //infect below
- //In this case, don't check neighbours below
- if (i < 90)
- {
- if (circleVec[i + 10].getFillColor() != sf::Color::Cyan && circleVec[i + 10].getFillColor() != sf::Color::Green)
- {
- if (i >= 90 && i <= 99)
- {
- //do nothing
- //circleVec[i].setFillColor(sf::Color::Red);
- }
- else
- {
- //cout << "elem-" << i << endl;
- //cout << "elem to infect == " << i + 10 << endl;
- elemsToInfec.push_back(i + 10);
- }
- }
- }
- }
- }
- //Colour the infected elements with cyan
- for (int x : elemsToInfec)
- {
- circleVec[x].setFillColor(sf::Color::Cyan);
- }
- //display text showing information about matrix
- int inf = 0;
- for (auto x : circleVec)
- {
- if (x.getFillColor() == sf::Color::Cyan)
- ++inf;
- }
- text.setString("Number infected: " + to_string(inf) + ", number uninfected: " + to_string(100 - inf) + "\n\nImmunity threshold: " + to_string(immunityThreshold));
- //text.setString("testing.. testing");
- }
- //If up/down keys pressed, scroll the matrices up and down the screen by changing their origins
- void UpdateOrigin(int x, int y, int numMatricesDown) //num matrices down keeps the appropriate offset between matrices
- {
- if (numMatricesDown == 0)
- {
- sf::Vector2f newOrigin = sf::Vector2f(x, y);
- originPos = newOrigin;
- }
- else
- {
- sf::Vector2f newOrigin = sf::Vector2f(x, y + (numMatricesDown*200));
- originPos = newOrigin;
- }
- //init positions
- //offset by origin x,y values
- int xOffset = originPos.x;
- int yOffset = originPos.y;
- for (int i = 0; i < 1000; i += 10)
- {
- if (i < 100)
- circleVec[i/10].setPosition(xOffset + (i + 10), yOffset + 20);
- if (i >= 100 && i < 200)
- circleVec[i/10].setPosition(xOffset + ((i - 100) + 10), yOffset + 30);
- if (i >= 200 && i < 300)
- circleVec[i/10].setPosition(xOffset + ((i - 200) + 10), yOffset + 40);
- if (i >= 300 && i < 400)
- circleVec[i/10].setPosition(xOffset + ((i - 300) + 10), yOffset + 50);
- if (i >= 400 && i < 500)
- circleVec[i/10].setPosition(xOffset + ((i - 400) + 10), yOffset + 60);
- if (i >= 500 && i < 600)
- circleVec[i/10].setPosition(xOffset + ((i - 500) + 10), yOffset + 70);
- if (i >= 600 && i < 700)
- circleVec[i/10].setPosition(xOffset + ((i - 600) + 10), yOffset + 80);
- if (i >= 700 && i < 800)
- circleVec[i/10].setPosition(xOffset + ((i - 700) + 10), yOffset + 90);
- if (i >= 800 && i < 900)
- circleVec[i/10].setPosition(xOffset + ((i - 800) + 10), yOffset + 100);
- if (i >= 900 && i < 1000)
- circleVec[i/10].setPosition(xOffset + ((i - 900) + 10), yOffset + 110);
- }
- //change text position
- text.setPosition(originPos.x + 150, originPos.y + 50);
- }
- //put this between window.clear() and window.display()
- void Draw()
- {
- window->draw(text);
- for (auto & c : circleVec)
- {
- window->draw(c);
- }
- }
- private:
- sf::RenderWindow* window;
- sf::Font font;
- sf::Text text;
- vector<sf::CircleShape> circleVec; //vector to hold the circles which make up the matrix
- sf::Vector2f originPos; //position of the "origin", from which relative position of circles in matrix grid will be based
- float immunityThreshold; //what percentage of cells will be immune
- vector<int> elemsToInfec; //element numbers to spread infection to
- };
- int main()
- {
- sf::RenderWindow window(sf::VideoMode(800, 600), "SFML Infection Sim");
- //good offset for successive origins? 300 too high. use 200
- //sf::Vector2f origin(0, 0);
- //sf::Vector2f origin2(0, 200);
- //sf::Vector2f origin3(0, 400);
- //Matrix m1(window, origin, 0.5);
- //Matrix m2(window, origin2, 0.5);
- //Matrix m3(window, origin3, 0.5);
- //dynamically create matrices
- //get input for number iterations, which immunity threshold to use
- int numIter = 5;
- float threshold = 0.5;
- //put n number origin positions in origin vector, offset (0, n*200)
- vector<sf::Vector2f> originVec;
- for (int i = 0; i < numIter; ++i)
- {
- sf::Vector2f orig = sf::Vector2f(0, i * 200);
- originVec.push_back(orig);
- }
- //create Matrix objects
- vector<Matrix> matrixVec;
- for (int i = 0; i < numIter; ++i)
- {
- Matrix ma(window, originVec[i], threshold);
- matrixVec.push_back(ma);
- }
- //clock for slowly moving matrices
- sf::Clock clock;
- float upMovement = 0;
- while(window.isOpen())
- {
- //m1.RunInfection();
- //m2.RunInfection();
- //m3.RunInfection();
- for (auto & m : matrixVec)
- {
- m.RunInfection();
- }
- sf::Event event;
- while (window.pollEvent(event))
- {
- if (event.type == sf::Event::Closed)
- window.close();
- }
- auto deltaTime = clock.restart().asSeconds();
- //cout << deltaTime << endl;
- //check input
- if (sf::Keyboard::isKeyPressed(sf::Keyboard::Up))
- {
- upMovement += deltaTime;
- //cout << upMovement << endl;
- //m1.UpdateOrigin(0, -upMovement * 50, 0);
- //m2.UpdateOrigin(0, -upMovement * 50, 1);
- //m3.UpdateOrigin(0, -upMovement * 50, 2);
- for (int i = 0; i < matrixVec.size(); ++i)
- {
- matrixVec[i].UpdateOrigin(0, -upMovement * 200, i);
- }
- }
- if (sf::Keyboard::isKeyPressed(sf::Keyboard::Down))
- {
- upMovement -= deltaTime;
- //cout << upMovement << endl;
- //.UpdateOrigin(0, -upMovement * 50, 0);
- //.UpdateOrigin(0, -upMovement * 50, 1);
- //.UpdateOrigin(0, -upMovement * 50, 2);
- for (int i = 0; i < matrixVec.size(); ++i)
- {
- matrixVec[i].UpdateOrigin(0, -upMovement * 200, i);
- }
- }
- window.clear();
- //m1.Draw();
- //m2.Draw();
- //m3.Draw();
- for (auto & m : matrixVec)
- {
- m.Draw();
- }
- window.display();
- }
- return 0;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement