Initial commit
This commit is contained in:
@@ -0,0 +1,9 @@
|
|||||||
|
/*
|
||||||
|
* ------------------------------------------------------------
|
||||||
|
* "THE BEERWARE LICENSE" (Revision 42):
|
||||||
|
* <MKjanek32> wrote this code. As long as you retain this
|
||||||
|
* notice, you can do whatever you want with this stuff. If we
|
||||||
|
* meet someday, and you think this stuff is worth it, you can
|
||||||
|
* buy me a beer in return.
|
||||||
|
* ------------------------------------------------------------
|
||||||
|
*/
|
||||||
@@ -0,0 +1,32 @@
|
|||||||
|
# PWr - Sytemy operacyjne 2 P
|
||||||
|
Moje projekty z SO2 u doktora Dariusza Cabana - obsługa wątków w C++.
|
||||||
|
UWAGA: przed kompilacją trzeba zainstalować pliki nagłówkowe ncurses (Debian, Ubuntu i pochodne - pakiet libncurses5-dev)
|
||||||
|
|
||||||
|
__Projekt 1: BRIcks Caban Kernel-thread System (_so2-bricks_)__
|
||||||
|
Rysowanie spadających cegieł z wykorzystaniem ncurses. Założenia:
|
||||||
|
- implementacja cegły jako klasa Brick
|
||||||
|
- 1 cegła = 1 wątek
|
||||||
|
- 1 dodatkowy wątek jako monitor (rysowanie wszystkich cegieł)
|
||||||
|
- przerysowanie ekranu co 10 ms
|
||||||
|
- automatyczne dopasowywanie liczby cegieł i długość drogi do rozmiarów terminala
|
||||||
|
- wątki zrealizowane za pomocą klasy std::thread z C++11
|
||||||
|
|
||||||
|
__Projekt 2: SYncsys Next Caban SYStem (_so2-center_)__
|
||||||
|
Centrum obsługi zgłoszeń. Założenia:
|
||||||
|
- co jakiś czas na ekranie pojawia się nowe zgłoszenie (jako znak) i przesuwa się do centrum obsługi
|
||||||
|
- w systemie zgłoszenie jest obsługiwane przez określony (stały) czas
|
||||||
|
- jeżeli centrum obsługi jest zajęte, kolejne zgłoszenia czekają w kolejce o ograniczonej długości
|
||||||
|
- jeżeli cała kolejka jest pełna, kolejne zgłoszenia okrążają centrum i próbują dostać się do kolejki jeszcze raz
|
||||||
|
- 1 zgłoszenie przez cały czas ma być 1 (i tym samym) wątkiem
|
||||||
|
- wykorzystanie synchronizacji, sekcji krytycznych, itp.
|
||||||
|
|
||||||
|
__Projekt 3: BRIcks-ng Caban Kernel-thread System Next Generation (_so2-game_)__
|
||||||
|
Prosta gra, napisana z wykorzystaniem mechanizmów poznanych na projektach 1. i 2. Zasady rozgrywki:
|
||||||
|
- czas rozgrywki -- 120 sekund
|
||||||
|
- sterowanie -- klawisze A i D
|
||||||
|
- zadanie -- łapanie na platformę spadających cegieł w kolorze takim samym, jak kolor platformy
|
||||||
|
- co 15 sekund platforma zmienia kolor
|
||||||
|
- za każdą złapaną cegłę odpowiedniego koloru przydzielane jest 5 punktów
|
||||||
|
- za każdą złapaną cegłę innego koloru odejmowany jest jeden punkt i za karę rozgrywka jest blokowana na 10 sekund - przy zliczanym wciąż czasie
|
||||||
|
|
||||||
|
Projekty z założenia były pisane na platformy Unix-like - wszystko, gdzie są dostępne ncurses.h i unistd.h.
|
||||||
@@ -0,0 +1,64 @@
|
|||||||
|
#include "Brick.h"
|
||||||
|
|
||||||
|
bool Brick::initialized = false;
|
||||||
|
int Brick::xMax;
|
||||||
|
int Brick::yMax;
|
||||||
|
|
||||||
|
Brick::Brick(int xPosition, int descentRate)
|
||||||
|
{
|
||||||
|
//ctor
|
||||||
|
this->xPosition = xPosition;
|
||||||
|
this->yPosition = 0;
|
||||||
|
this->descentRate = descentRate;
|
||||||
|
this->falling = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
Brick::~Brick()
|
||||||
|
{
|
||||||
|
//dtor
|
||||||
|
}
|
||||||
|
|
||||||
|
void Brick::initScene(int xRes, int yRes)
|
||||||
|
{
|
||||||
|
xMax = xRes;
|
||||||
|
yMax = yRes;
|
||||||
|
initialized = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
int Brick::getxPosition()
|
||||||
|
{
|
||||||
|
return xPosition;
|
||||||
|
}
|
||||||
|
|
||||||
|
int Brick::getyPosition()
|
||||||
|
{
|
||||||
|
return yPosition;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Brick::isFalling()
|
||||||
|
{
|
||||||
|
return falling;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Brick::fall()
|
||||||
|
{
|
||||||
|
if(initialized)
|
||||||
|
{
|
||||||
|
falling = true;
|
||||||
|
|
||||||
|
while(yPosition < yMax - 2)
|
||||||
|
{
|
||||||
|
yPosition++;
|
||||||
|
usleep(250000 - 10000 * descentRate);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
std::cout << "Scene size not initialized!" << std::endl;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
std::thread Brick::fallThread()
|
||||||
|
{
|
||||||
|
return std::thread(&Brick::fall, this);
|
||||||
|
}
|
||||||
@@ -0,0 +1,30 @@
|
|||||||
|
#ifndef BRICK_H
|
||||||
|
#define BRICK_H
|
||||||
|
|
||||||
|
#include <iostream>
|
||||||
|
#include <thread>
|
||||||
|
#include <unistd.h>
|
||||||
|
|
||||||
|
class Brick
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
Brick(int xPosition, int descentRate);
|
||||||
|
~Brick();
|
||||||
|
static void initScene(int xRes, int yRes);
|
||||||
|
int getxPosition();
|
||||||
|
int getyPosition();
|
||||||
|
bool isFalling();
|
||||||
|
std::thread fallThread();
|
||||||
|
protected:
|
||||||
|
private:
|
||||||
|
static bool initialized;
|
||||||
|
static int xMax;
|
||||||
|
static int yMax;
|
||||||
|
int xPosition;
|
||||||
|
int yPosition;
|
||||||
|
int descentRate;
|
||||||
|
bool falling;
|
||||||
|
void fall();
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // BRICK_H
|
||||||
@@ -0,0 +1,15 @@
|
|||||||
|
CXXFLAGS = -Wall -std=c++11
|
||||||
|
|
||||||
|
OBJS = so2-bricks.o Brick.o
|
||||||
|
|
||||||
|
LIBS = -pthread -lncurses
|
||||||
|
|
||||||
|
TARGET = so2-bricks
|
||||||
|
|
||||||
|
$(TARGET): $(OBJS)
|
||||||
|
$(CXX) -o $(TARGET) $(OBJS) $(LIBS)
|
||||||
|
|
||||||
|
all: $(TARGET)
|
||||||
|
|
||||||
|
clean:
|
||||||
|
rm -f $(OBJS) $(TARGET)
|
||||||
@@ -0,0 +1,134 @@
|
|||||||
|
#include <cstdlib>
|
||||||
|
#include <ctime>
|
||||||
|
#include <iostream>
|
||||||
|
#include <string>
|
||||||
|
#include <thread>
|
||||||
|
#include <vector>
|
||||||
|
#include <ncurses.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include "Brick.h"
|
||||||
|
|
||||||
|
bool running = true, climate = false;
|
||||||
|
std::vector<Brick> bricks;
|
||||||
|
|
||||||
|
|
||||||
|
// "Monitor" function
|
||||||
|
void refreshScreen()
|
||||||
|
{
|
||||||
|
while(running == true)
|
||||||
|
{
|
||||||
|
clear();
|
||||||
|
|
||||||
|
for(int i = 0; i < bricks.size(); i++)
|
||||||
|
{
|
||||||
|
// Easter egg (1)
|
||||||
|
if(climate)
|
||||||
|
{
|
||||||
|
mvprintw(bricks[i].getyPosition(), bricks[i].getxPosition(), "*" );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
mvprintw(bricks[i].getyPosition(), bricks[i].getxPosition(), "#" );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
refresh();
|
||||||
|
|
||||||
|
// Refresh every 0.01 s
|
||||||
|
usleep(10000);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int main(int argc, char *argv[])
|
||||||
|
{
|
||||||
|
int xMax, yMax, fallingBricks = 0;
|
||||||
|
std::vector<std::thread> brickThreads;
|
||||||
|
|
||||||
|
srand(time(0));
|
||||||
|
|
||||||
|
// Easter egg (2)
|
||||||
|
if(argc == 2)
|
||||||
|
{
|
||||||
|
std::string param(argv[1]);
|
||||||
|
|
||||||
|
if(param == "--globalwarming")
|
||||||
|
{
|
||||||
|
climate = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Initialize ncurses
|
||||||
|
initscr();
|
||||||
|
curs_set(0);
|
||||||
|
getmaxyx(stdscr, yMax, xMax);
|
||||||
|
|
||||||
|
// Initialize scene
|
||||||
|
Brick::initScene(xMax, yMax);
|
||||||
|
|
||||||
|
// Initialize all bricks...
|
||||||
|
for(int i = 0; i < xMax; i++)
|
||||||
|
{
|
||||||
|
// ...with random descent rate in range 0 (slow) to 20 (fast)
|
||||||
|
Brick brick(i, rand() % 21);
|
||||||
|
bricks.push_back(brick);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Start monitor
|
||||||
|
std::thread monitor(refreshScreen);
|
||||||
|
|
||||||
|
while(fallingBricks < xMax)
|
||||||
|
{
|
||||||
|
// Determine random brick...
|
||||||
|
int randBrick = rand() % xMax;
|
||||||
|
while(bricks.at(randBrick).isFalling())
|
||||||
|
{
|
||||||
|
// ...which still isn't falling down...
|
||||||
|
randBrick = rand() % xMax;
|
||||||
|
}
|
||||||
|
|
||||||
|
// ...and launch it with nuclear-powered hammer ;-)
|
||||||
|
brickThreads.push_back(bricks.at(randBrick).fallThread());
|
||||||
|
fallingBricks++;
|
||||||
|
|
||||||
|
// Random time in range 100 to 500 ms until next fall
|
||||||
|
unsigned randTime = rand() % 5 + 1;
|
||||||
|
usleep(100000 * randTime);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Wait for all bricks
|
||||||
|
for(int i = 0; i < brickThreads.size(); i++)
|
||||||
|
{
|
||||||
|
brickThreads.at(i).join();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Stop monitor
|
||||||
|
sleep(1);
|
||||||
|
running = false;
|
||||||
|
monitor.join();
|
||||||
|
|
||||||
|
// Close ncurses
|
||||||
|
endwin();
|
||||||
|
|
||||||
|
std::cout << "BRIcks Caban Kernel-thread System v1.1" << std::endl;
|
||||||
|
std::cout << "Jan Potocki 2018" << std::endl;
|
||||||
|
std::cout << "(beerware)" << std::endl;
|
||||||
|
std::cout << std::endl;
|
||||||
|
std::cout << '"' << "I had a Type-4 keyboard," << std::endl;
|
||||||
|
std::cout << "Bought with my Sun workstation," << std::endl;
|
||||||
|
std::cout << "Hacked on it 'til my fingers bled." << std::endl;
|
||||||
|
std::cout << "Was the winter of '95..." << '"' << std::endl;
|
||||||
|
|
||||||
|
// Easter egg (3)
|
||||||
|
if(climate)
|
||||||
|
{
|
||||||
|
std::cout << std::endl;
|
||||||
|
std::cout << "SEVERE WEATHER ALERT: major snowfall predicted in 48h forecast for Lower Silesia, south-western Poland" << std::endl;
|
||||||
|
std::cout << "Global warming affecting again!... ;-)" << std::endl;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
std::cout << "Beware of BRICKS! ;-)" << std::endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
@@ -0,0 +1,158 @@
|
|||||||
|
#include <iostream>
|
||||||
|
#include <mutex>
|
||||||
|
#include "Entry.h"
|
||||||
|
|
||||||
|
bool Entry::initialized = false;
|
||||||
|
int Entry::xMax;
|
||||||
|
int Entry::yMax;
|
||||||
|
|
||||||
|
bool full;
|
||||||
|
std::mutex state;
|
||||||
|
std::mutex ready1;
|
||||||
|
std::mutex ready2;
|
||||||
|
std::mutex service;
|
||||||
|
|
||||||
|
Entry::Entry(int speedRate)
|
||||||
|
{
|
||||||
|
//ctor
|
||||||
|
this->xPosition = -1;
|
||||||
|
this->yPosition = yMax / 2;
|
||||||
|
this->speedRate = speedRate;
|
||||||
|
this->symbol = "*";
|
||||||
|
|
||||||
|
if(initialized == false)
|
||||||
|
{
|
||||||
|
std::cout << "WARNING: Scene size not initialized!" << std::endl;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Entry::~Entry()
|
||||||
|
{
|
||||||
|
//dtor
|
||||||
|
}
|
||||||
|
|
||||||
|
void Entry::initScene(int xRes, int yRes)
|
||||||
|
{
|
||||||
|
xMax = xRes;
|
||||||
|
yMax = yRes;
|
||||||
|
initialized = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
int Entry::getxPosition()
|
||||||
|
{
|
||||||
|
return xPosition;
|
||||||
|
}
|
||||||
|
|
||||||
|
int Entry::getyPosition()
|
||||||
|
{
|
||||||
|
return yPosition;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string Entry::getSymbol()
|
||||||
|
{
|
||||||
|
return symbol;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Entry::run()
|
||||||
|
{
|
||||||
|
if(initialized)
|
||||||
|
{
|
||||||
|
while(xPosition < xMax / 2)
|
||||||
|
{
|
||||||
|
xPosition++;
|
||||||
|
usleep(100000 - 10000 * speedRate);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool goAround;
|
||||||
|
|
||||||
|
state.lock();
|
||||||
|
if(full == true)
|
||||||
|
{
|
||||||
|
goAround = true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
goAround = false;
|
||||||
|
full = true;
|
||||||
|
ready2.lock();
|
||||||
|
}
|
||||||
|
state.unlock();
|
||||||
|
|
||||||
|
while(goAround)
|
||||||
|
{
|
||||||
|
while(yPosition < 3 * yMax / 4)
|
||||||
|
{
|
||||||
|
yPosition++;
|
||||||
|
usleep(100000 - 10000 * speedRate);
|
||||||
|
}
|
||||||
|
|
||||||
|
while(xPosition < 3 * xMax / 4)
|
||||||
|
{
|
||||||
|
xPosition++;
|
||||||
|
usleep(100000 - 10000 * speedRate);
|
||||||
|
}
|
||||||
|
|
||||||
|
while(yPosition > yMax / 4)
|
||||||
|
{
|
||||||
|
yPosition--;
|
||||||
|
usleep(100000 - 10000 * speedRate);
|
||||||
|
}
|
||||||
|
|
||||||
|
while(xPosition > xMax / 2)
|
||||||
|
{
|
||||||
|
xPosition--;
|
||||||
|
usleep(100000 - 10000 * speedRate);
|
||||||
|
}
|
||||||
|
|
||||||
|
while(yPosition < yMax / 2)
|
||||||
|
{
|
||||||
|
yPosition++;
|
||||||
|
usleep(100000 - 10000 * speedRate);
|
||||||
|
}
|
||||||
|
|
||||||
|
state.lock();
|
||||||
|
if(full == false)
|
||||||
|
{
|
||||||
|
goAround = false;
|
||||||
|
full = true;
|
||||||
|
ready2.lock();
|
||||||
|
}
|
||||||
|
state.unlock();
|
||||||
|
}
|
||||||
|
|
||||||
|
xPosition++;
|
||||||
|
symbol = "2";
|
||||||
|
|
||||||
|
ready1.lock();
|
||||||
|
state.lock();
|
||||||
|
full = false;
|
||||||
|
state.unlock();
|
||||||
|
ready2.unlock();
|
||||||
|
xPosition++;
|
||||||
|
symbol = "1";
|
||||||
|
|
||||||
|
service.lock();
|
||||||
|
ready1.unlock();
|
||||||
|
xPosition++;
|
||||||
|
symbol = "#";
|
||||||
|
sleep(5);
|
||||||
|
|
||||||
|
service.unlock();
|
||||||
|
symbol = "*";
|
||||||
|
|
||||||
|
while(xPosition < xMax)
|
||||||
|
{
|
||||||
|
xPosition++;
|
||||||
|
usleep(100000 - 10000 * speedRate);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
std::cout << "ERROR: Scene size not initialized!" << std::endl;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
std::thread Entry::runThread()
|
||||||
|
{
|
||||||
|
return std::thread(&Entry::run, this);
|
||||||
|
}
|
||||||
@@ -0,0 +1,30 @@
|
|||||||
|
#ifndef ENTRY_H
|
||||||
|
#define ENTRY_H
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
#include <thread>
|
||||||
|
#include <unistd.h>
|
||||||
|
|
||||||
|
class Entry
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
Entry(int speedRate);
|
||||||
|
~Entry();
|
||||||
|
static void initScene(int xRes, int yRes);
|
||||||
|
int getxPosition();
|
||||||
|
int getyPosition();
|
||||||
|
std::string getSymbol();
|
||||||
|
std::thread runThread();
|
||||||
|
protected:
|
||||||
|
private:
|
||||||
|
static bool initialized;
|
||||||
|
static int xMax;
|
||||||
|
static int yMax;
|
||||||
|
int xPosition;
|
||||||
|
int yPosition;
|
||||||
|
int speedRate;
|
||||||
|
std::string symbol;
|
||||||
|
void run();
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // ENTRY_H
|
||||||
Binary file not shown.
@@ -0,0 +1,15 @@
|
|||||||
|
CXXFLAGS = -Wall -std=c++11
|
||||||
|
|
||||||
|
OBJS = so2-center.o Entry.o
|
||||||
|
|
||||||
|
LIBS = -pthread -lncurses
|
||||||
|
|
||||||
|
TARGET = so2-center
|
||||||
|
|
||||||
|
$(TARGET): $(OBJS)
|
||||||
|
$(CXX) -o $(TARGET) $(OBJS) $(LIBS)
|
||||||
|
|
||||||
|
all: $(TARGET)
|
||||||
|
|
||||||
|
clean:
|
||||||
|
rm -f $(OBJS) $(TARGET)
|
||||||
@@ -0,0 +1,91 @@
|
|||||||
|
#include <cstdlib>
|
||||||
|
#include <ctime>
|
||||||
|
#include <iostream>
|
||||||
|
#include <mutex>
|
||||||
|
#include <string>
|
||||||
|
#include <thread>
|
||||||
|
#include <vector>
|
||||||
|
#include <ncurses.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include "Entry.h"
|
||||||
|
|
||||||
|
bool running = true;
|
||||||
|
std::vector<Entry> entries;
|
||||||
|
|
||||||
|
std::mutex display;
|
||||||
|
|
||||||
|
// "Monitor" function
|
||||||
|
void refreshScreen()
|
||||||
|
{
|
||||||
|
while(running == true)
|
||||||
|
{
|
||||||
|
clear();
|
||||||
|
|
||||||
|
for(int i = 0; i < entries.size(); i++)
|
||||||
|
{
|
||||||
|
mvprintw(entries[i].getyPosition(), entries[i].getxPosition(), entries[i].getSymbol().c_str());
|
||||||
|
}
|
||||||
|
|
||||||
|
refresh();
|
||||||
|
|
||||||
|
// Refresh every 0.01 s
|
||||||
|
usleep(10000);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int main()
|
||||||
|
{
|
||||||
|
int xMax, yMax, fallingBricks = 0;
|
||||||
|
std::vector<std::thread> entriesThreads;
|
||||||
|
|
||||||
|
srand(time(0));
|
||||||
|
|
||||||
|
// Initialize ncurses
|
||||||
|
initscr();
|
||||||
|
curs_set(0);
|
||||||
|
getmaxyx(stdscr, yMax, xMax);
|
||||||
|
|
||||||
|
// Initialize scene
|
||||||
|
Entry::initScene(xMax, yMax);
|
||||||
|
|
||||||
|
// Start monitor
|
||||||
|
std::thread monitor(refreshScreen);
|
||||||
|
|
||||||
|
|
||||||
|
for(int i = 0; i < 15; i++)
|
||||||
|
{
|
||||||
|
entries.push_back(*(new Entry(rand() % 6)));
|
||||||
|
}
|
||||||
|
|
||||||
|
for(int i = 0; i < entries.size(); i++)
|
||||||
|
{
|
||||||
|
unsigned randTime = rand() % 3 + 1;
|
||||||
|
sleep(1 * randTime);
|
||||||
|
entriesThreads.push_back(entries[i].runThread());
|
||||||
|
}
|
||||||
|
|
||||||
|
// Wait for all entries
|
||||||
|
for(int i = 0; i < entriesThreads.size(); i++)
|
||||||
|
{
|
||||||
|
entriesThreads.at(i).join();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Stop monitor
|
||||||
|
sleep(1);
|
||||||
|
running = false;
|
||||||
|
monitor.join();
|
||||||
|
|
||||||
|
// Close ncurses
|
||||||
|
endwin();
|
||||||
|
|
||||||
|
std::cout << "SYncsys Next Caban SYStem v1.1" << std::endl;
|
||||||
|
std::cout << "Jan Potocki 2018" << std::endl;
|
||||||
|
std::cout << "(beerware)" << std::endl;
|
||||||
|
std::cout << std::endl;
|
||||||
|
std::cout << '"' << "...And now the times have changed" << std::endl;
|
||||||
|
std::cout << "Repos on the web, git," << std::endl;
|
||||||
|
std::cout << "Now githubs everywhere." << std::endl;
|
||||||
|
std::cout << "Not like the winter of '95..." << '"' << std::endl;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
Binary file not shown.
@@ -0,0 +1,126 @@
|
|||||||
|
#include "Brick.h"
|
||||||
|
#include <cstdlib>
|
||||||
|
#include <iostream>
|
||||||
|
#include <unistd.h>
|
||||||
|
|
||||||
|
Platform *Brick::platform = 0;
|
||||||
|
|
||||||
|
Brick::Brick(int xPosition, int descentRate)
|
||||||
|
{
|
||||||
|
//ctor
|
||||||
|
this->xPosition = xPosition;
|
||||||
|
this->yPosition = -1;
|
||||||
|
this->descentRate = descentRate;
|
||||||
|
this->falling = false;
|
||||||
|
|
||||||
|
randomColor();
|
||||||
|
}
|
||||||
|
|
||||||
|
Brick::~Brick()
|
||||||
|
{
|
||||||
|
//dtor
|
||||||
|
}
|
||||||
|
|
||||||
|
void Brick::setPlatform(Platform *newPlatform)
|
||||||
|
{
|
||||||
|
platform = newPlatform;
|
||||||
|
}
|
||||||
|
|
||||||
|
int Brick::getxPosition()
|
||||||
|
{
|
||||||
|
return xPosition;
|
||||||
|
}
|
||||||
|
|
||||||
|
int Brick::getyPosition()
|
||||||
|
{
|
||||||
|
return yPosition;
|
||||||
|
}
|
||||||
|
|
||||||
|
int Brick::getColor()
|
||||||
|
{
|
||||||
|
return color;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool Brick::isFalling()
|
||||||
|
{
|
||||||
|
return falling;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Brick::fall()
|
||||||
|
{
|
||||||
|
if(!initialized)
|
||||||
|
{
|
||||||
|
std::cout << "Scene size not initialized!" << std::endl;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(platform == 0)
|
||||||
|
{
|
||||||
|
std::cout << "Platform not set!" << std::endl;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
falling = true;
|
||||||
|
|
||||||
|
while(running & falling & yPosition < yMax - 2)
|
||||||
|
{
|
||||||
|
// Freeze game
|
||||||
|
if(freezed)
|
||||||
|
{
|
||||||
|
std::unique_lock<std::mutex> freezeLock(freezeMutex);
|
||||||
|
|
||||||
|
while(freezed)
|
||||||
|
{
|
||||||
|
freezeCondition.wait(freezeLock);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// If game terminated, we shouldn't do all this stuff
|
||||||
|
if(running)
|
||||||
|
{
|
||||||
|
yPosition++;
|
||||||
|
|
||||||
|
if(yPosition == yMax - 2 && platform->getPosition() <= xPosition && platform->getEnd() >= xPosition)
|
||||||
|
{
|
||||||
|
falling = false;
|
||||||
|
|
||||||
|
if(platform->getColor() == color)
|
||||||
|
{
|
||||||
|
points += 5;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if(points != 0)
|
||||||
|
{
|
||||||
|
points--;
|
||||||
|
}
|
||||||
|
|
||||||
|
freeze();
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
usleep(250000 - 10000 * descentRate);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(running)
|
||||||
|
{
|
||||||
|
// Reset
|
||||||
|
yPosition = -1;
|
||||||
|
falling = false;
|
||||||
|
randomColor();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
std::thread Brick::fallThread()
|
||||||
|
{
|
||||||
|
return std::thread(&Brick::fall, this);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Brick::randomColor()
|
||||||
|
{
|
||||||
|
color = rand() % 6 + 1;
|
||||||
|
}
|
||||||
@@ -0,0 +1,31 @@
|
|||||||
|
#ifndef BRICK_H
|
||||||
|
#define BRICK_H
|
||||||
|
|
||||||
|
#include <thread>
|
||||||
|
#include "Platform.h"
|
||||||
|
#include "Scene.h"
|
||||||
|
|
||||||
|
class Brick : public Scene
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
Brick(int xPosition, int descentRate);
|
||||||
|
~Brick();
|
||||||
|
static void setPlatform(Platform *newPlatform);
|
||||||
|
int getxPosition();
|
||||||
|
int getyPosition();
|
||||||
|
int getColor();
|
||||||
|
bool isFalling();
|
||||||
|
std::thread fallThread();
|
||||||
|
protected:
|
||||||
|
private:
|
||||||
|
static Platform *platform;
|
||||||
|
int xPosition;
|
||||||
|
int yPosition;
|
||||||
|
int descentRate;
|
||||||
|
int color;
|
||||||
|
bool falling;
|
||||||
|
void fall();
|
||||||
|
void randomColor();
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // BRICK_H
|
||||||
Binary file not shown.
@@ -0,0 +1,15 @@
|
|||||||
|
CXXFLAGS = -Wall -std=c++11
|
||||||
|
|
||||||
|
OBJS = so2-game.o Brick.o Platform.o Scene.o Stopwatch.o
|
||||||
|
|
||||||
|
LIBS = -pthread -lncurses
|
||||||
|
|
||||||
|
TARGET = so2-game
|
||||||
|
|
||||||
|
$(TARGET): $(OBJS)
|
||||||
|
$(CXX) -o $(TARGET) $(OBJS) $(LIBS)
|
||||||
|
|
||||||
|
all: $(TARGET)
|
||||||
|
|
||||||
|
clean:
|
||||||
|
rm -f $(OBJS) $(TARGET)
|
||||||
@@ -0,0 +1,133 @@
|
|||||||
|
#include "Platform.h"
|
||||||
|
#include <iostream>
|
||||||
|
#include <ncurses.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
|
||||||
|
Platform::Platform()
|
||||||
|
{
|
||||||
|
//ctor
|
||||||
|
points = 0;
|
||||||
|
color = 0;
|
||||||
|
sprite = "<--->";
|
||||||
|
}
|
||||||
|
|
||||||
|
Platform::~Platform()
|
||||||
|
{
|
||||||
|
//dtor
|
||||||
|
}
|
||||||
|
|
||||||
|
const char *Platform::getSprite()
|
||||||
|
{
|
||||||
|
return sprite.c_str();
|
||||||
|
}
|
||||||
|
|
||||||
|
int Platform::getPosition()
|
||||||
|
{
|
||||||
|
return position;
|
||||||
|
}
|
||||||
|
|
||||||
|
int Platform::getEnd()
|
||||||
|
{
|
||||||
|
int endPos = position + sprite.length() - 1;
|
||||||
|
return endPos;
|
||||||
|
}
|
||||||
|
|
||||||
|
int Platform::getColor()
|
||||||
|
{
|
||||||
|
return color;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Platform::terminateThreads()
|
||||||
|
{
|
||||||
|
running = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Platform::moveKey()
|
||||||
|
{
|
||||||
|
if(!initialized)
|
||||||
|
{
|
||||||
|
std::cout << "Scene size not initialized!" << std::endl;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
int key;
|
||||||
|
|
||||||
|
while(running)
|
||||||
|
{
|
||||||
|
ncursesMutex.lock();
|
||||||
|
key = getch();
|
||||||
|
ncursesMutex.unlock();
|
||||||
|
|
||||||
|
// Freeze game
|
||||||
|
if(freezed)
|
||||||
|
{
|
||||||
|
std::unique_lock<std::mutex> freezeLock(freezeMutex);
|
||||||
|
|
||||||
|
while(freezed)
|
||||||
|
{
|
||||||
|
freezeCondition.wait(freezeLock);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Ignore keys pressed when frozen
|
||||||
|
flushinp();
|
||||||
|
}
|
||||||
|
|
||||||
|
switch(key)
|
||||||
|
{
|
||||||
|
case 'a':
|
||||||
|
if(position > 0)
|
||||||
|
{
|
||||||
|
position--;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 'd':
|
||||||
|
if(position < xMax - sprite.length())
|
||||||
|
{
|
||||||
|
position++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
std::thread Platform::moveKeyThread()
|
||||||
|
{
|
||||||
|
return std::thread(&Platform::moveKey, this);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Platform::colorChange()
|
||||||
|
{
|
||||||
|
const int idleSeconds = 15;
|
||||||
|
|
||||||
|
while(running)
|
||||||
|
{
|
||||||
|
color = rand() % 6 + 1;
|
||||||
|
|
||||||
|
// Waiting - this must be interruptable, so it can't be just sleep(idleSeconds)
|
||||||
|
for(int i = 0; i < idleSeconds * 10; i++)
|
||||||
|
{
|
||||||
|
// Freeze game
|
||||||
|
if(freezed)
|
||||||
|
{
|
||||||
|
std::unique_lock<std::mutex> freezeLock(freezeMutex);
|
||||||
|
|
||||||
|
while(freezed)
|
||||||
|
{
|
||||||
|
freezeCondition.wait(freezeLock);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!running)
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Every tick = 100 ms
|
||||||
|
usleep(100000);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
std::thread Platform::colorChangeThread()
|
||||||
|
{
|
||||||
|
return std::thread(&Platform::colorChange, this);
|
||||||
|
}
|
||||||
@@ -0,0 +1,30 @@
|
|||||||
|
#ifndef PLATFORM_H
|
||||||
|
#define PLATFORM_H
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
#include <thread>
|
||||||
|
#include "Scene.h"
|
||||||
|
|
||||||
|
class Platform : public Scene
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
Platform();
|
||||||
|
~Platform();
|
||||||
|
const char *getSprite();
|
||||||
|
int getPosition();
|
||||||
|
int getEnd();
|
||||||
|
int getColor();
|
||||||
|
void terminateThreads();
|
||||||
|
std::thread moveKeyThread();
|
||||||
|
std::thread colorChangeThread();
|
||||||
|
protected:
|
||||||
|
private:
|
||||||
|
std::string sprite;
|
||||||
|
int position;
|
||||||
|
int points;
|
||||||
|
int color;
|
||||||
|
void moveKey();
|
||||||
|
void colorChange();
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // PLATFORM_H
|
||||||
Binary file not shown.
@@ -0,0 +1,71 @@
|
|||||||
|
#include "Scene.h"
|
||||||
|
#include <unistd.h>
|
||||||
|
|
||||||
|
int Scene::xMax;
|
||||||
|
int Scene::yMax;
|
||||||
|
int Scene::points = 0;
|
||||||
|
bool Scene::initialized = false;
|
||||||
|
bool Scene::freezed = false;
|
||||||
|
bool Scene::running = false;
|
||||||
|
std::mutex Scene::ncursesMutex;
|
||||||
|
std::mutex Scene::freezeMutex;
|
||||||
|
std::condition_variable Scene::freezeCondition;
|
||||||
|
|
||||||
|
Scene::Scene()
|
||||||
|
{
|
||||||
|
//ctor
|
||||||
|
}
|
||||||
|
|
||||||
|
Scene::~Scene()
|
||||||
|
{
|
||||||
|
//dtor
|
||||||
|
}
|
||||||
|
|
||||||
|
void Scene::init(int xRes, int yRes)
|
||||||
|
{
|
||||||
|
xMax = xRes;
|
||||||
|
yMax = yRes;
|
||||||
|
running = true;
|
||||||
|
initialized = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
int Scene::getPoints()
|
||||||
|
{
|
||||||
|
return points;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Scene::isFreezed()
|
||||||
|
{
|
||||||
|
return freezed;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Scene::freeze()
|
||||||
|
{
|
||||||
|
const int idleSeconds = 10;
|
||||||
|
|
||||||
|
std::unique_lock<std::mutex> freezeLock(freezeMutex);
|
||||||
|
freezed = true;
|
||||||
|
sleep(idleSeconds);
|
||||||
|
|
||||||
|
// // This must be interruptable, so it can't be just sleep(idleSeconds)
|
||||||
|
// for(int i = 0; i < idleSeconds * 10; i++)
|
||||||
|
// {
|
||||||
|
// if(running)
|
||||||
|
// {
|
||||||
|
// // Every tick = 100 ms
|
||||||
|
// usleep(100000);
|
||||||
|
// }
|
||||||
|
// else
|
||||||
|
// {
|
||||||
|
// break;
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
|
freezed = false;
|
||||||
|
freezeCondition.notify_all();
|
||||||
|
}
|
||||||
|
|
||||||
|
void Scene::terminateAll()
|
||||||
|
{
|
||||||
|
Scene::running = false;
|
||||||
|
}
|
||||||
@@ -0,0 +1,31 @@
|
|||||||
|
#ifndef SCENE_H
|
||||||
|
#define SCENE_H
|
||||||
|
|
||||||
|
#include <condition_variable>
|
||||||
|
#include <mutex>
|
||||||
|
#include <thread>
|
||||||
|
|
||||||
|
class Scene
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
static std::mutex ncursesMutex;
|
||||||
|
static std::mutex freezeMutex;
|
||||||
|
static std::condition_variable freezeCondition;
|
||||||
|
Scene();
|
||||||
|
virtual ~Scene();
|
||||||
|
static void init(int xRes, int yRes);
|
||||||
|
static int getPoints();
|
||||||
|
static bool isFreezed();
|
||||||
|
static void terminateAll();
|
||||||
|
protected:
|
||||||
|
static int xMax;
|
||||||
|
static int yMax;
|
||||||
|
static int points;
|
||||||
|
static bool initialized;
|
||||||
|
static bool freezed;
|
||||||
|
static bool running;
|
||||||
|
static void freeze();
|
||||||
|
private:
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // SCENE_H
|
||||||
Binary file not shown.
@@ -0,0 +1,40 @@
|
|||||||
|
#include "Stopwatch.h"
|
||||||
|
|
||||||
|
Stopwatch::Stopwatch()
|
||||||
|
{
|
||||||
|
//ctor
|
||||||
|
// Jan Potocki 2018
|
||||||
|
}
|
||||||
|
|
||||||
|
void Stopwatch::start()
|
||||||
|
{
|
||||||
|
running = true;
|
||||||
|
miliseconds = 0;
|
||||||
|
measureThread = std::thread(&Stopwatch::measure, this);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Stopwatch::stop()
|
||||||
|
{
|
||||||
|
running = false;
|
||||||
|
measureThread.join();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Stopwatch::isRunning()
|
||||||
|
{
|
||||||
|
return running;
|
||||||
|
}
|
||||||
|
|
||||||
|
float Stopwatch::read()
|
||||||
|
{
|
||||||
|
float measurement = (float)miliseconds / 1000;
|
||||||
|
return measurement;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Stopwatch::measure()
|
||||||
|
{
|
||||||
|
while(running)
|
||||||
|
{
|
||||||
|
usleep(1000);
|
||||||
|
miliseconds++;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,25 @@
|
|||||||
|
#ifndef STOPWATCH_H
|
||||||
|
#define STOPWATCH_H
|
||||||
|
|
||||||
|
#include <thread>
|
||||||
|
#include <unistd.h>
|
||||||
|
|
||||||
|
// Klasa do pomiaru czasu w oparciu o funkcje systemowe
|
||||||
|
// Jan Potocki 2018
|
||||||
|
class Stopwatch
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
Stopwatch();
|
||||||
|
void start();
|
||||||
|
void stop();
|
||||||
|
bool isRunning();
|
||||||
|
float read();
|
||||||
|
protected:
|
||||||
|
private:
|
||||||
|
unsigned long long int miliseconds;
|
||||||
|
bool running;
|
||||||
|
std::thread measureThread;
|
||||||
|
void measure();
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // STOPWATCH_H
|
||||||
Binary file not shown.
@@ -0,0 +1,202 @@
|
|||||||
|
#include <cstdlib>
|
||||||
|
#include <ctime>
|
||||||
|
#include <iostream>
|
||||||
|
#include <string>
|
||||||
|
#include <thread>
|
||||||
|
#include <vector>
|
||||||
|
#include <ncurses.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include "Brick.h"
|
||||||
|
#include "Platform.h"
|
||||||
|
#include "Stopwatch.h"
|
||||||
|
|
||||||
|
const int gameTime = 120;
|
||||||
|
|
||||||
|
int xMax, yMax;
|
||||||
|
bool refreshing = false;
|
||||||
|
bool climate = false;
|
||||||
|
std::vector<Brick> bricks;
|
||||||
|
Platform platform;
|
||||||
|
Stopwatch gameClock;
|
||||||
|
|
||||||
|
// "Monitor" function
|
||||||
|
void refreshScreen()
|
||||||
|
{
|
||||||
|
while(refreshing == true)
|
||||||
|
{
|
||||||
|
Scene::ncursesMutex.lock();
|
||||||
|
clear();
|
||||||
|
|
||||||
|
for(int i = 0; i < bricks.size(); i++)
|
||||||
|
{
|
||||||
|
// Easter egg (1)
|
||||||
|
if(climate)
|
||||||
|
{
|
||||||
|
attron(COLOR_PAIR(bricks[i].getColor()));
|
||||||
|
mvprintw(bricks[i].getyPosition(), bricks[i].getxPosition(), "*");
|
||||||
|
attroff(COLOR_PAIR(bricks[i].getColor()));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
attron(COLOR_PAIR(bricks[i].getColor()));
|
||||||
|
mvprintw(bricks[i].getyPosition(), bricks[i].getxPosition(), "#");
|
||||||
|
attroff(COLOR_PAIR(bricks[i].getColor()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
attron(COLOR_PAIR(platform.getColor()));
|
||||||
|
mvprintw(yMax - 2, platform.getPosition(), platform.getSprite());
|
||||||
|
attroff(COLOR_PAIR(platform.getColor()));
|
||||||
|
|
||||||
|
mvprintw(yMax - 1, 0, "%.3f", gameClock.read());
|
||||||
|
mvprintw(yMax - 1, xMax - 3, "%.3d", Scene::getPoints());
|
||||||
|
|
||||||
|
refresh();
|
||||||
|
Scene::ncursesMutex.unlock();
|
||||||
|
|
||||||
|
// Refresh every 0.01 s
|
||||||
|
usleep(10000);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int main(int argc, char *argv[])
|
||||||
|
{
|
||||||
|
std::vector<std::thread> brickThreads;
|
||||||
|
|
||||||
|
srand(time(0));
|
||||||
|
|
||||||
|
// Easter egg (2)
|
||||||
|
if(argc == 2)
|
||||||
|
{
|
||||||
|
std::string param(argv[1]);
|
||||||
|
|
||||||
|
if(param == "--globalwarming")
|
||||||
|
{
|
||||||
|
climate = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Initialize ncurses
|
||||||
|
initscr();
|
||||||
|
curs_set(0);
|
||||||
|
getmaxyx(stdscr, yMax, xMax);
|
||||||
|
|
||||||
|
// Initialize colors
|
||||||
|
start_color();
|
||||||
|
init_pair(1, COLOR_RED, COLOR_BLACK);
|
||||||
|
init_pair(2, COLOR_GREEN, COLOR_BLACK);
|
||||||
|
init_pair(3, COLOR_YELLOW, COLOR_BLACK);
|
||||||
|
init_pair(4, COLOR_BLUE, COLOR_BLACK);
|
||||||
|
init_pair(5, COLOR_MAGENTA, COLOR_BLACK);
|
||||||
|
init_pair(6, COLOR_CYAN, COLOR_BLACK);
|
||||||
|
|
||||||
|
// Non-blocking input for platform-movement
|
||||||
|
timeout(0);
|
||||||
|
|
||||||
|
// Initialize scene
|
||||||
|
Scene::init(xMax, yMax);
|
||||||
|
Brick::setPlatform(&platform);
|
||||||
|
|
||||||
|
// Initialize all bricks...
|
||||||
|
for(int i = 0; i < xMax; i++)
|
||||||
|
{
|
||||||
|
// ...with random descent rate in range 0 (slow) to 15 (fast)
|
||||||
|
Brick brick(i, rand() % 16);
|
||||||
|
bricks.push_back(brick);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Start monitor
|
||||||
|
refreshing = true;
|
||||||
|
std::thread monitor(refreshScreen);
|
||||||
|
|
||||||
|
// Start platform treads
|
||||||
|
std::thread platformMover(platform.moveKeyThread());
|
||||||
|
std::thread platformColorChanger(platform.colorChangeThread());
|
||||||
|
|
||||||
|
// Start game
|
||||||
|
gameClock.start();
|
||||||
|
|
||||||
|
while(gameClock.read() < gameTime)
|
||||||
|
{
|
||||||
|
// Freeze game
|
||||||
|
if(Scene::isFreezed() == true)
|
||||||
|
{
|
||||||
|
std::unique_lock<std::mutex> freezeLock(Scene::freezeMutex);
|
||||||
|
|
||||||
|
while(Scene::isFreezed() == true)
|
||||||
|
{
|
||||||
|
Scene::freezeCondition.wait(freezeLock);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Determine random brick...
|
||||||
|
int randBrick = rand() % xMax;
|
||||||
|
while(bricks.at(randBrick).isFalling())
|
||||||
|
{
|
||||||
|
// ...which still isn't falling down...
|
||||||
|
randBrick = rand() % xMax;
|
||||||
|
}
|
||||||
|
|
||||||
|
// ...and launch it with nuclear-powered hammer ;-)
|
||||||
|
brickThreads.push_back(bricks.at(randBrick).fallThread());
|
||||||
|
|
||||||
|
// Random time in range 400 to 800 ms until next fall
|
||||||
|
unsigned randTime = rand() % 4 + 4;
|
||||||
|
usleep(100000 * randTime);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Stop clock
|
||||||
|
gameClock.stop();
|
||||||
|
|
||||||
|
// Stop scene objects threads
|
||||||
|
Scene::terminateAll();
|
||||||
|
|
||||||
|
platformMover.join();
|
||||||
|
platformColorChanger.join();
|
||||||
|
|
||||||
|
for(int i = 0; i < brickThreads.size(); i++)
|
||||||
|
{
|
||||||
|
brickThreads.at(i).join();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Stop monitor
|
||||||
|
refreshing = false;
|
||||||
|
monitor.join();
|
||||||
|
sleep(1);
|
||||||
|
|
||||||
|
// Close ncurses
|
||||||
|
endwin();
|
||||||
|
|
||||||
|
std::cout << "Your score: " << Scene::getPoints() << " points" << std::endl;
|
||||||
|
|
||||||
|
if(Scene::getPoints() != 0)
|
||||||
|
{
|
||||||
|
std::cout << "Congratulations!" << std::endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::cout << std::endl;
|
||||||
|
|
||||||
|
std::cout << "BRIcks-ng Caban Kernel-thread System Next Generation v1.0" << std::endl;
|
||||||
|
std::cout << "Jan Potocki 2018" << std::endl;
|
||||||
|
std::cout << "(beerware)" << std::endl;
|
||||||
|
std::cout << std::endl;
|
||||||
|
std::cout << '"' << "...Back around that Halloween," << std::endl;
|
||||||
|
std::cout << "Microsoft said open source would never last," << std::endl;
|
||||||
|
std::cout << "But now they use the repo tools," << std::endl;
|
||||||
|
std::cout << "In the same open access way..." << '"' << std::endl;
|
||||||
|
std::cout << "(and recently acquired GitHub)" << std::endl;
|
||||||
|
std::cout << std::endl;
|
||||||
|
|
||||||
|
// Easter egg (3)
|
||||||
|
if(climate)
|
||||||
|
{
|
||||||
|
std::cout << "SEVERE WEATHER ALERT: major snowfall predicted in 48h forecast for Lower Silesia, south-western Poland" << std::endl;
|
||||||
|
std::cout << "Global warming affecting again!... ;-)" << std::endl;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
std::cout << "Beware of BRICKS! ;-)" << std::endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
Binary file not shown.
Reference in New Issue
Block a user