Initial commit

This commit is contained in:
Jan Potocki
2020-05-04 15:56:02 +02:00
commit a8382b30e1
27 changed files with 1282 additions and 0 deletions
+9
View File
@@ -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.
* ------------------------------------------------------------
*/
+32
View File
@@ -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.
+64
View File
@@ -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);
}
+30
View File
@@ -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
+15
View File
@@ -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)
+134
View File
@@ -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;
}
+158
View File
@@ -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);
}
+30
View File
@@ -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.
+15
View File
@@ -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)
+91
View File
@@ -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.
+126
View File
@@ -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;
}
+31
View File
@@ -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
BIN
View File
Binary file not shown.
+15
View File
@@ -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)
+133
View File
@@ -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);
}
+30
View File
@@ -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.
+71
View File
@@ -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;
}
+31
View File
@@ -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
BIN
View File
Binary file not shown.
+40
View File
@@ -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++;
}
}
+25
View File
@@ -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.
+202
View File
@@ -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.