Jan Potocki 5 gadus atpakaļ
revīzija
a8382b30e1

+ 9
- 0
LICENSE Parādīt failu

@@ -0,0 +1,9 @@
1
+/*
2
+ * ------------------------------------------------------------
3
+ * "THE BEERWARE LICENSE" (Revision 42):
4
+ * <MKjanek32> wrote this code. As long as you retain this 
5
+ * notice, you can do whatever you want with this stuff. If we
6
+ * meet someday, and you think this stuff is worth it, you can
7
+ * buy me a beer in return.
8
+ * ------------------------------------------------------------
9
+*/

+ 32
- 0
README.md Parādīt failu

@@ -0,0 +1,32 @@
1
+# PWr - Sytemy operacyjne 2 P
2
+Moje projekty z SO2 u doktora Dariusza Cabana - obsługa wątków w C++.  
3
+UWAGA: przed kompilacją trzeba zainstalować pliki nagłówkowe ncurses (Debian, Ubuntu i pochodne - pakiet libncurses5-dev)
4
+
5
+__Projekt 1: BRIcks Caban Kernel-thread System (_so2-bricks_)__  
6
+Rysowanie spadających cegieł z wykorzystaniem ncurses. Założenia:
7
+- implementacja cegły jako klasa Brick
8
+- 1 cegła = 1 wątek
9
+- 1 dodatkowy wątek jako monitor (rysowanie wszystkich cegieł)
10
+- przerysowanie ekranu co 10 ms
11
+- automatyczne dopasowywanie liczby cegieł i długość drogi do rozmiarów terminala
12
+- wątki zrealizowane za pomocą klasy std::thread z C++11
13
+
14
+__Projekt 2: SYncsys Next Caban SYStem (_so2-center_)__  
15
+Centrum obsługi zgłoszeń. Założenia:
16
+- co jakiś czas na ekranie pojawia się nowe zgłoszenie (jako znak) i przesuwa się do centrum obsługi
17
+- w systemie zgłoszenie jest obsługiwane przez określony (stały) czas
18
+- jeżeli centrum obsługi jest zajęte, kolejne zgłoszenia czekają w kolejce o ograniczonej długości
19
+- jeżeli cała kolejka jest pełna, kolejne zgłoszenia okrążają centrum i próbują dostać się do kolejki jeszcze raz
20
+- 1 zgłoszenie przez cały czas ma być 1 (i tym samym) wątkiem
21
+- wykorzystanie synchronizacji, sekcji krytycznych, itp.
22
+
23
+__Projekt 3: BRIcks-ng Caban Kernel-thread System Next Generation (_so2-game_)__  
24
+Prosta gra, napisana z wykorzystaniem mechanizmów poznanych na projektach 1. i 2. Zasady rozgrywki:
25
+- czas rozgrywki -- 120 sekund
26
+- sterowanie -- klawisze A i D
27
+- zadanie -- łapanie na platformę spadających cegieł w kolorze takim samym, jak kolor platformy
28
+- co 15 sekund platforma zmienia kolor
29
+- za każdą złapaną cegłę odpowiedniego koloru przydzielane jest 5 punktów
30
+- 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
31
+
32
+Projekty z założenia były pisane na platformy Unix-like - wszystko, gdzie są dostępne ncurses.h i unistd.h.

+ 64
- 0
so2-bricks/Brick.cpp Parādīt failu

@@ -0,0 +1,64 @@
1
+#include "Brick.h"
2
+
3
+bool Brick::initialized = false;
4
+int Brick::xMax;
5
+int Brick::yMax;
6
+
7
+Brick::Brick(int xPosition, int descentRate)
8
+{
9
+    //ctor
10
+    this->xPosition = xPosition;
11
+    this->yPosition = 0;
12
+    this->descentRate = descentRate;
13
+    this->falling = false;
14
+}
15
+
16
+Brick::~Brick()
17
+{
18
+    //dtor
19
+}
20
+
21
+void Brick::initScene(int xRes, int yRes)
22
+{
23
+    xMax = xRes;
24
+    yMax = yRes;
25
+    initialized = true;
26
+}
27
+
28
+int Brick::getxPosition()
29
+{
30
+    return xPosition;
31
+}
32
+
33
+int Brick::getyPosition()
34
+{
35
+    return yPosition;
36
+}
37
+
38
+bool Brick::isFalling()
39
+{
40
+    return falling;
41
+}
42
+
43
+void Brick::fall()
44
+{
45
+    if(initialized)
46
+    {
47
+        falling = true;
48
+
49
+        while(yPosition < yMax - 2)
50
+        {
51
+            yPosition++;
52
+            usleep(250000 - 10000 * descentRate);
53
+        }
54
+    }
55
+    else
56
+    {
57
+        std::cout << "Scene size not initialized!" << std::endl;
58
+    }
59
+}
60
+
61
+std::thread Brick::fallThread()
62
+{
63
+    return std::thread(&Brick::fall, this);
64
+}

+ 30
- 0
so2-bricks/Brick.h Parādīt failu

@@ -0,0 +1,30 @@
1
+#ifndef BRICK_H
2
+#define BRICK_H
3
+
4
+#include <iostream>
5
+#include <thread>
6
+#include <unistd.h>
7
+
8
+class Brick
9
+{
10
+    public:
11
+        Brick(int xPosition, int descentRate);
12
+        ~Brick();
13
+        static void initScene(int xRes, int yRes);
14
+        int getxPosition();
15
+        int getyPosition();
16
+        bool isFalling();
17
+        std::thread fallThread();
18
+    protected:
19
+    private:
20
+        static bool initialized;
21
+        static int xMax;
22
+        static int yMax;
23
+        int xPosition;
24
+        int yPosition;
25
+        int descentRate;
26
+        bool falling;
27
+        void fall();
28
+};
29
+
30
+#endif // BRICK_H

+ 15
- 0
so2-bricks/Makefile Parādīt failu

@@ -0,0 +1,15 @@
1
+CXXFLAGS =	-Wall -std=c++11
2
+
3
+OBJS =		so2-bricks.o Brick.o
4
+
5
+LIBS =		-pthread -lncurses
6
+
7
+TARGET =	so2-bricks
8
+
9
+$(TARGET):	$(OBJS)
10
+	$(CXX) -o $(TARGET) $(OBJS) $(LIBS)
11
+
12
+all:	$(TARGET)
13
+
14
+clean:
15
+	rm -f $(OBJS) $(TARGET)

+ 134
- 0
so2-bricks/so2-bricks.cpp Parādīt failu

@@ -0,0 +1,134 @@
1
+#include <cstdlib>
2
+#include <ctime>
3
+#include <iostream>
4
+#include <string>
5
+#include <thread>
6
+#include <vector>
7
+#include <ncurses.h>
8
+#include <unistd.h>
9
+#include "Brick.h"
10
+
11
+bool running = true, climate = false;
12
+std::vector<Brick> bricks;
13
+
14
+
15
+// "Monitor" function
16
+void refreshScreen()
17
+{
18
+    while(running == true)
19
+    {
20
+        clear();
21
+
22
+        for(int i = 0; i < bricks.size(); i++)
23
+        {
24
+            // Easter egg (1)
25
+            if(climate)
26
+                {
27
+                mvprintw(bricks[i].getyPosition(), bricks[i].getxPosition(), "*" );
28
+                }
29
+            else
30
+                {
31
+                mvprintw(bricks[i].getyPosition(), bricks[i].getxPosition(), "#" );
32
+                }
33
+        }
34
+
35
+        refresh();
36
+
37
+        // Refresh every 0.01 s
38
+        usleep(10000);
39
+    }
40
+}
41
+
42
+int main(int argc, char *argv[])
43
+{
44
+    int xMax, yMax, fallingBricks = 0;
45
+    std::vector<std::thread> brickThreads;
46
+
47
+    srand(time(0));
48
+
49
+    // Easter egg (2)
50
+    if(argc == 2)
51
+    {
52
+        std::string param(argv[1]);
53
+
54
+        if(param == "--globalwarming")
55
+        {
56
+            climate = true;
57
+        }
58
+    }
59
+
60
+    // Initialize ncurses
61
+    initscr();
62
+    curs_set(0);
63
+    getmaxyx(stdscr, yMax, xMax);
64
+
65
+    // Initialize scene
66
+    Brick::initScene(xMax, yMax);
67
+
68
+    // Initialize all bricks...
69
+    for(int i = 0; i < xMax; i++)
70
+    {
71
+        // ...with random descent rate in range 0 (slow) to 20 (fast)
72
+        Brick brick(i, rand() % 21);
73
+        bricks.push_back(brick);
74
+    }
75
+
76
+    // Start monitor
77
+    std::thread monitor(refreshScreen);
78
+
79
+    while(fallingBricks < xMax)
80
+    {
81
+        // Determine random brick...
82
+        int randBrick = rand() % xMax;
83
+        while(bricks.at(randBrick).isFalling())
84
+        {
85
+            // ...which still isn't falling down...
86
+            randBrick = rand() % xMax;
87
+        }
88
+
89
+        // ...and launch it with nuclear-powered hammer ;-)
90
+        brickThreads.push_back(bricks.at(randBrick).fallThread());
91
+        fallingBricks++;
92
+
93
+        // Random time in range 100 to 500 ms until next fall
94
+        unsigned randTime = rand() % 5 + 1;
95
+        usleep(100000 * randTime);
96
+    }
97
+
98
+    // Wait for all bricks
99
+    for(int i = 0; i < brickThreads.size(); i++)
100
+    {
101
+        brickThreads.at(i).join();
102
+    }
103
+
104
+    // Stop monitor
105
+    sleep(1);
106
+    running = false;
107
+    monitor.join();
108
+
109
+    // Close ncurses
110
+    endwin();
111
+
112
+    std::cout << "BRIcks Caban Kernel-thread System v1.1" << std::endl;
113
+    std::cout << "Jan Potocki 2018" << std::endl;
114
+    std::cout << "(beerware)" << std::endl;
115
+    std::cout << std::endl;
116
+    std::cout << '"' << "I had a Type-4 keyboard," << std::endl;
117
+    std::cout << "Bought with my Sun workstation," << std::endl;
118
+    std::cout << "Hacked on it 'til my fingers bled." << std::endl;
119
+    std::cout << "Was the winter of '95..." << '"' << std::endl;
120
+
121
+    // Easter egg (3)
122
+    if(climate)
123
+    {
124
+        std::cout << std::endl;
125
+        std::cout << "SEVERE WEATHER ALERT: major snowfall predicted in 48h forecast for Lower Silesia, south-western Poland" << std::endl;
126
+        std::cout << "Global warming affecting again!... ;-)" << std::endl;
127
+    }
128
+    else
129
+    {
130
+        std::cout << "Beware of BRICKS! ;-)" << std::endl;
131
+    }
132
+
133
+    return 0;
134
+}

+ 158
- 0
so2-center/Entry.cpp Parādīt failu

@@ -0,0 +1,158 @@
1
+#include <iostream>
2
+#include <mutex>
3
+#include "Entry.h"
4
+
5
+bool Entry::initialized = false;
6
+int Entry::xMax;
7
+int Entry::yMax;
8
+
9
+bool full;
10
+std::mutex state;
11
+std::mutex ready1;
12
+std::mutex ready2;
13
+std::mutex service;
14
+
15
+Entry::Entry(int speedRate)
16
+{
17
+    //ctor
18
+    this->xPosition = -1;
19
+    this->yPosition = yMax / 2;
20
+    this->speedRate = speedRate;
21
+    this->symbol = "*";
22
+
23
+    if(initialized == false)
24
+    {
25
+        std::cout << "WARNING: Scene size not initialized!" << std::endl;
26
+    }
27
+}
28
+
29
+Entry::~Entry()
30
+{
31
+    //dtor
32
+}
33
+
34
+void Entry::initScene(int xRes, int yRes)
35
+{
36
+    xMax = xRes;
37
+    yMax = yRes;
38
+    initialized = true;
39
+}
40
+
41
+int Entry::getxPosition()
42
+{
43
+    return xPosition;
44
+}
45
+
46
+int Entry::getyPosition()
47
+{
48
+    return yPosition;
49
+}
50
+
51
+std::string Entry::getSymbol()
52
+{
53
+    return symbol;
54
+}
55
+
56
+void Entry::run()
57
+{
58
+    if(initialized)
59
+    {
60
+        while(xPosition < xMax / 2)
61
+        {
62
+            xPosition++;
63
+            usleep(100000 - 10000 * speedRate);
64
+        }
65
+
66
+        bool goAround;
67
+
68
+        state.lock();
69
+        if(full == true)
70
+        {
71
+            goAround = true;
72
+        }
73
+        else
74
+        {
75
+            goAround = false;
76
+            full = true;
77
+            ready2.lock();
78
+        }
79
+        state.unlock();
80
+
81
+        while(goAround)
82
+        {
83
+            while(yPosition < 3 * yMax / 4)
84
+            {
85
+                yPosition++;
86
+                usleep(100000 - 10000 * speedRate);
87
+            }
88
+
89
+            while(xPosition < 3 * xMax / 4)
90
+            {
91
+                xPosition++;
92
+                usleep(100000 - 10000 * speedRate);
93
+            }
94
+
95
+            while(yPosition > yMax / 4)
96
+            {
97
+                yPosition--;
98
+                usleep(100000 - 10000 * speedRate);
99
+            }
100
+
101
+            while(xPosition > xMax / 2)
102
+            {
103
+                xPosition--;
104
+                usleep(100000 - 10000 * speedRate);
105
+            }
106
+
107
+            while(yPosition < yMax / 2)
108
+            {
109
+                yPosition++;
110
+                usleep(100000 - 10000 * speedRate);
111
+            }
112
+
113
+            state.lock();
114
+            if(full == false)
115
+            {
116
+                goAround = false;
117
+                full = true;
118
+                ready2.lock();
119
+            }
120
+            state.unlock();
121
+        }
122
+
123
+        xPosition++;
124
+        symbol = "2";
125
+
126
+        ready1.lock();
127
+        state.lock();
128
+        full = false;
129
+        state.unlock();
130
+        ready2.unlock();
131
+        xPosition++;
132
+        symbol = "1";
133
+
134
+        service.lock();
135
+        ready1.unlock();
136
+        xPosition++;
137
+        symbol = "#";
138
+        sleep(5);
139
+
140
+        service.unlock();
141
+        symbol = "*";
142
+
143
+        while(xPosition < xMax)
144
+        {
145
+            xPosition++;
146
+            usleep(100000 - 10000 * speedRate);
147
+        }
148
+    }
149
+    else
150
+    {
151
+        std::cout << "ERROR: Scene size not initialized!" << std::endl;
152
+    }
153
+}
154
+
155
+std::thread Entry::runThread()
156
+{
157
+    return std::thread(&Entry::run, this);
158
+}

+ 30
- 0
so2-center/Entry.h Parādīt failu

@@ -0,0 +1,30 @@
1
+#ifndef ENTRY_H
2
+#define ENTRY_H
3
+
4
+#include <string>
5
+#include <thread>
6
+#include <unistd.h>
7
+
8
+class Entry
9
+{
10
+    public:
11
+        Entry(int speedRate);
12
+        ~Entry();
13
+        static void initScene(int xRes, int yRes);
14
+        int getxPosition();
15
+        int getyPosition();
16
+        std::string getSymbol();
17
+        std::thread runThread();
18
+    protected:
19
+    private:
20
+        static bool initialized;
21
+        static int xMax;
22
+        static int yMax;
23
+        int xPosition;
24
+        int yPosition;
25
+        int speedRate;
26
+        std::string symbol;
27
+        void run();
28
+};
29
+
30
+#endif // ENTRY_H

Binārs
so2-center/Entry.o Parādīt failu


+ 15
- 0
so2-center/Makefile Parādīt failu

@@ -0,0 +1,15 @@
1
+CXXFLAGS =	-Wall -std=c++11
2
+
3
+OBJS =		so2-center.o Entry.o
4
+
5
+LIBS =		-pthread -lncurses
6
+
7
+TARGET =	so2-center
8
+
9
+$(TARGET):	$(OBJS)
10
+	$(CXX) -o $(TARGET) $(OBJS) $(LIBS)
11
+
12
+all:	$(TARGET)
13
+
14
+clean:
15
+	rm -f $(OBJS) $(TARGET)

+ 91
- 0
so2-center/so2-center.cpp Parādīt failu

@@ -0,0 +1,91 @@
1
+#include <cstdlib>
2
+#include <ctime>
3
+#include <iostream>
4
+#include <mutex>
5
+#include <string>
6
+#include <thread>
7
+#include <vector>
8
+#include <ncurses.h>
9
+#include <unistd.h>
10
+#include "Entry.h"
11
+
12
+bool running = true;
13
+std::vector<Entry> entries;
14
+
15
+std::mutex display;
16
+
17
+// "Monitor" function
18
+void refreshScreen()
19
+{
20
+    while(running == true)
21
+    {
22
+        clear();
23
+
24
+        for(int i = 0; i < entries.size(); i++)
25
+        {
26
+            mvprintw(entries[i].getyPosition(), entries[i].getxPosition(), entries[i].getSymbol().c_str());
27
+        }
28
+
29
+        refresh();
30
+
31
+        // Refresh every 0.01 s
32
+        usleep(10000);
33
+    }
34
+}
35
+
36
+int main()
37
+{
38
+    int xMax, yMax, fallingBricks = 0;
39
+    std::vector<std::thread> entriesThreads;
40
+
41
+    srand(time(0));
42
+
43
+    // Initialize ncurses
44
+    initscr();
45
+    curs_set(0);
46
+    getmaxyx(stdscr, yMax, xMax);
47
+
48
+    // Initialize scene
49
+    Entry::initScene(xMax, yMax);
50
+
51
+    // Start monitor
52
+    std::thread monitor(refreshScreen);
53
+
54
+
55
+    for(int i = 0; i < 15; i++)
56
+    {
57
+        entries.push_back(*(new Entry(rand() % 6)));
58
+    }
59
+
60
+    for(int i = 0; i < entries.size(); i++)
61
+    {
62
+        unsigned randTime = rand() % 3 + 1;
63
+        sleep(1 * randTime);
64
+        entriesThreads.push_back(entries[i].runThread());
65
+    }
66
+
67
+    // Wait for all entries
68
+    for(int i = 0; i < entriesThreads.size(); i++)
69
+    {
70
+        entriesThreads.at(i).join();
71
+    }
72
+
73
+    // Stop monitor
74
+    sleep(1);
75
+    running = false;
76
+    monitor.join();
77
+
78
+    // Close ncurses
79
+    endwin();
80
+
81
+    std::cout << "SYncsys Next Caban SYStem v1.1" << std::endl;
82
+    std::cout << "Jan Potocki 2018" << std::endl;
83
+    std::cout << "(beerware)" << std::endl;
84
+    std::cout << std::endl;
85
+    std::cout << '"' << "...And now the times have changed" << std::endl;
86
+    std::cout << "Repos on the web, git," << std::endl;
87
+    std::cout << "Now githubs everywhere." << std::endl;
88
+    std::cout << "Not like the winter of '95..." << '"' << std::endl;
89
+
90
+    return 0;
91
+}

Binārs
so2-center/so2-center.o Parādīt failu


+ 126
- 0
so2-game/Brick.cpp Parādīt failu

@@ -0,0 +1,126 @@
1
+#include "Brick.h"
2
+#include <cstdlib>
3
+#include <iostream>
4
+#include <unistd.h>
5
+
6
+Platform *Brick::platform = 0;
7
+
8
+Brick::Brick(int xPosition, int descentRate)
9
+{
10
+    //ctor
11
+    this->xPosition = xPosition;
12
+    this->yPosition = -1;
13
+    this->descentRate = descentRate;
14
+    this->falling = false;
15
+
16
+    randomColor();
17
+}
18
+
19
+Brick::~Brick()
20
+{
21
+    //dtor
22
+}
23
+
24
+void Brick::setPlatform(Platform *newPlatform)
25
+{
26
+    platform = newPlatform;
27
+}
28
+
29
+int Brick::getxPosition()
30
+{
31
+    return xPosition;
32
+}
33
+
34
+int Brick::getyPosition()
35
+{
36
+    return yPosition;
37
+}
38
+
39
+int Brick::getColor()
40
+{
41
+    return color;
42
+}
43
+
44
+
45
+bool Brick::isFalling()
46
+{
47
+    return falling;
48
+}
49
+
50
+void Brick::fall()
51
+{
52
+    if(!initialized)
53
+    {
54
+        std::cout << "Scene size not initialized!" << std::endl;
55
+        return;
56
+    }
57
+
58
+    if(platform == 0)
59
+    {
60
+        std::cout << "Platform not set!" << std::endl;
61
+        return;
62
+    }
63
+
64
+    falling = true;
65
+
66
+    while(running & falling & yPosition < yMax - 2)
67
+    {
68
+        // Freeze game
69
+        if(freezed)
70
+        {
71
+            std::unique_lock<std::mutex> freezeLock(freezeMutex);
72
+
73
+            while(freezed)
74
+            {
75
+                freezeCondition.wait(freezeLock);
76
+            }
77
+        }
78
+
79
+        // If game terminated, we shouldn't do all this stuff
80
+        if(running)
81
+        {
82
+            yPosition++;
83
+
84
+            if(yPosition == yMax - 2 && platform->getPosition() <= xPosition && platform->getEnd() >= xPosition)
85
+            {
86
+                falling = false;
87
+
88
+                if(platform->getColor() == color)
89
+                {
90
+                    points += 5;
91
+                }
92
+                else
93
+                {
94
+                    if(points != 0)
95
+                    {
96
+                        points--;
97
+                    }
98
+
99
+                    freeze();
100
+                }
101
+
102
+                break;
103
+            }
104
+
105
+            usleep(250000 - 10000 * descentRate);
106
+        }
107
+    }
108
+
109
+    if(running)
110
+    {
111
+        // Reset
112
+        yPosition = -1;
113
+        falling = false;
114
+        randomColor();
115
+    }
116
+}
117
+
118
+std::thread Brick::fallThread()
119
+{
120
+    return std::thread(&Brick::fall, this);
121
+}
122
+
123
+void Brick::randomColor()
124
+{
125
+    color = rand() % 6 + 1;
126
+}

+ 31
- 0
so2-game/Brick.h Parādīt failu

@@ -0,0 +1,31 @@
1
+#ifndef BRICK_H
2
+#define BRICK_H
3
+
4
+#include <thread>
5
+#include "Platform.h"
6
+#include "Scene.h"
7
+
8
+class Brick : public Scene
9
+{
10
+    public:
11
+        Brick(int xPosition, int descentRate);
12
+        ~Brick();
13
+        static void setPlatform(Platform *newPlatform);
14
+        int getxPosition();
15
+        int getyPosition();
16
+        int getColor();
17
+        bool isFalling();
18
+        std::thread fallThread();
19
+    protected:
20
+    private:
21
+        static Platform *platform;
22
+        int xPosition;
23
+        int yPosition;
24
+        int descentRate;
25
+        int color;
26
+        bool falling;
27
+        void fall();
28
+        void randomColor();
29
+};
30
+
31
+#endif // BRICK_H

Binārs
so2-game/Brick.o Parādīt failu


+ 15
- 0
so2-game/Makefile Parādīt failu

@@ -0,0 +1,15 @@
1
+CXXFLAGS =	-Wall -std=c++11
2
+
3
+OBJS =		so2-game.o Brick.o Platform.o Scene.o Stopwatch.o
4
+
5
+LIBS =		-pthread -lncurses
6
+
7
+TARGET =	so2-game
8
+
9
+$(TARGET):	$(OBJS)
10
+	$(CXX) -o $(TARGET) $(OBJS) $(LIBS)
11
+
12
+all:	$(TARGET)
13
+
14
+clean:
15
+	rm -f $(OBJS) $(TARGET)

+ 133
- 0
so2-game/Platform.cpp Parādīt failu

@@ -0,0 +1,133 @@
1
+#include "Platform.h"
2
+#include <iostream>
3
+#include <ncurses.h>
4
+#include <unistd.h>
5
+
6
+Platform::Platform()
7
+{
8
+    //ctor
9
+    points = 0;
10
+    color = 0;
11
+    sprite = "<--->";
12
+}
13
+
14
+Platform::~Platform()
15
+{
16
+    //dtor
17
+}
18
+
19
+const char *Platform::getSprite()
20
+{
21
+    return sprite.c_str();
22
+}
23
+
24
+int Platform::getPosition()
25
+{
26
+    return position;
27
+}
28
+
29
+int Platform::getEnd()
30
+{
31
+    int endPos = position + sprite.length() - 1;
32
+    return endPos;
33
+}
34
+
35
+int Platform::getColor()
36
+{
37
+    return color;
38
+}
39
+
40
+void Platform::terminateThreads()
41
+{
42
+    running = false;
43
+}
44
+
45
+void Platform::moveKey()
46
+{
47
+    if(!initialized)
48
+    {
49
+        std::cout << "Scene size not initialized!" << std::endl;
50
+        return;
51
+    }
52
+
53
+    int key;
54
+
55
+    while(running)
56
+    {
57
+        ncursesMutex.lock();
58
+        key = getch();
59
+        ncursesMutex.unlock();
60
+
61
+        // Freeze game
62
+        if(freezed)
63
+        {
64
+            std::unique_lock<std::mutex> freezeLock(freezeMutex);
65
+
66
+            while(freezed)
67
+            {
68
+                freezeCondition.wait(freezeLock);
69
+            }
70
+
71
+            // Ignore keys pressed when frozen
72
+            flushinp();
73
+        }
74
+
75
+        switch(key)
76
+        {
77
+        case 'a':
78
+            if(position > 0)
79
+            {
80
+                position--;
81
+            }
82
+            break;
83
+        case 'd':
84
+            if(position < xMax - sprite.length())
85
+            {
86
+                position++;
87
+            }
88
+        }
89
+    }
90
+}
91
+
92
+std::thread Platform::moveKeyThread()
93
+{
94
+    return std::thread(&Platform::moveKey, this);
95
+}
96
+
97
+void Platform::colorChange()
98
+{
99
+    const int idleSeconds = 15;
100
+
101
+    while(running)
102
+    {
103
+        color = rand() % 6 + 1;
104
+
105
+        // Waiting - this must be interruptable, so it can't be just sleep(idleSeconds)
106
+        for(int i = 0; i < idleSeconds * 10; i++)
107
+        {
108
+            // Freeze game
109
+            if(freezed)
110
+            {
111
+                std::unique_lock<std::mutex> freezeLock(freezeMutex);
112
+
113
+                while(freezed)
114
+                {
115
+                    freezeCondition.wait(freezeLock);
116
+                }
117
+            }
118
+
119
+            if(!running)
120
+            {
121
+                break;
122
+            }
123
+
124
+            // Every tick = 100 ms
125
+            usleep(100000);
126
+        }
127
+    }
128
+}
129
+
130
+std::thread Platform::colorChangeThread()
131
+{
132
+    return std::thread(&Platform::colorChange, this);
133
+}

+ 30
- 0
so2-game/Platform.h Parādīt failu

@@ -0,0 +1,30 @@
1
+#ifndef PLATFORM_H
2
+#define PLATFORM_H
3
+
4
+#include <string>
5
+#include <thread>
6
+#include "Scene.h"
7
+
8
+class Platform : public Scene
9
+{
10
+    public:
11
+        Platform();
12
+        ~Platform();
13
+        const char *getSprite();
14
+        int getPosition();
15
+        int getEnd();
16
+        int getColor();
17
+        void terminateThreads();
18
+        std::thread moveKeyThread();
19
+        std::thread colorChangeThread();
20
+    protected:
21
+    private:
22
+        std::string sprite;
23
+        int position;
24
+        int points;
25
+        int color;
26
+        void moveKey();
27
+        void colorChange();
28
+};
29
+
30
+#endif // PLATFORM_H

Binārs
so2-game/Platform.o Parādīt failu


+ 71
- 0
so2-game/Scene.cpp Parādīt failu

@@ -0,0 +1,71 @@
1
+#include "Scene.h"
2
+#include <unistd.h>
3
+
4
+int Scene::xMax;
5
+int Scene::yMax;
6
+int Scene::points = 0;
7
+bool Scene::initialized = false;
8
+bool Scene::freezed = false;
9
+bool Scene::running = false;
10
+std::mutex Scene::ncursesMutex;
11
+std::mutex Scene::freezeMutex;
12
+std::condition_variable Scene::freezeCondition;
13
+
14
+Scene::Scene()
15
+{
16
+    //ctor
17
+}
18
+
19
+Scene::~Scene()
20
+{
21
+    //dtor
22
+}
23
+
24
+void Scene::init(int xRes, int yRes)
25
+{
26
+    xMax = xRes;
27
+    yMax = yRes;
28
+    running = true;
29
+    initialized = true;
30
+}
31
+
32
+int Scene::getPoints()
33
+{
34
+    return points;
35
+}
36
+
37
+bool Scene::isFreezed()
38
+{
39
+    return freezed;
40
+}
41
+
42
+void Scene::freeze()
43
+{
44
+    const int idleSeconds = 10;
45
+
46
+    std::unique_lock<std::mutex> freezeLock(freezeMutex);
47
+    freezed = true;
48
+    sleep(idleSeconds);
49
+
50
+//    // This must be interruptable, so it can't be just sleep(idleSeconds)
51
+//    for(int i = 0; i < idleSeconds * 10; i++)
52
+//    {
53
+//        if(running)
54
+//        {
55
+//            // Every tick = 100 ms
56
+//            usleep(100000);
57
+//        }
58
+//        else
59
+//        {
60
+//            break;
61
+//        }
62
+//    }
63
+
64
+    freezed = false;
65
+    freezeCondition.notify_all();
66
+}
67
+
68
+void Scene::terminateAll()
69
+{
70
+    Scene::running = false;
71
+}

+ 31
- 0
so2-game/Scene.h Parādīt failu

@@ -0,0 +1,31 @@
1
+#ifndef SCENE_H
2
+#define SCENE_H
3
+
4
+#include <condition_variable>
5
+#include <mutex>
6
+#include <thread>
7
+
8
+class Scene
9
+{
10
+    public:
11
+        static std::mutex ncursesMutex;
12
+        static std::mutex freezeMutex;
13
+        static std::condition_variable freezeCondition;
14
+        Scene();
15
+        virtual ~Scene();
16
+        static void init(int xRes, int yRes);
17
+        static int getPoints();
18
+        static bool isFreezed();
19
+        static void terminateAll();
20
+    protected:
21
+        static int xMax;
22
+        static int yMax;
23
+        static int points;
24
+        static bool initialized;
25
+        static bool freezed;
26
+        static bool running;
27
+        static void freeze();
28
+    private:
29
+};
30
+
31
+#endif // SCENE_H

Binārs
so2-game/Scene.o Parādīt failu


+ 40
- 0
so2-game/Stopwatch.cpp Parādīt failu

@@ -0,0 +1,40 @@
1
+#include "Stopwatch.h"
2
+
3
+Stopwatch::Stopwatch()
4
+{
5
+    //ctor
6
+    // Jan Potocki 2018
7
+}
8
+
9
+void Stopwatch::start()
10
+{
11
+    running = true;
12
+    miliseconds = 0;
13
+    measureThread = std::thread(&Stopwatch::measure, this);
14
+}
15
+
16
+void Stopwatch::stop()
17
+{
18
+    running = false;
19
+    measureThread.join();
20
+}
21
+
22
+bool Stopwatch::isRunning()
23
+{
24
+    return running;
25
+}
26
+
27
+float Stopwatch::read()
28
+{
29
+    float measurement = (float)miliseconds / 1000;
30
+    return measurement;
31
+}
32
+
33
+void Stopwatch::measure()
34
+{
35
+    while(running)
36
+    {
37
+        usleep(1000);
38
+        miliseconds++;
39
+    }
40
+}

+ 25
- 0
so2-game/Stopwatch.h Parādīt failu

@@ -0,0 +1,25 @@
1
+#ifndef STOPWATCH_H
2
+#define STOPWATCH_H
3
+
4
+#include <thread>
5
+#include <unistd.h>
6
+
7
+// Klasa do pomiaru czasu w oparciu o funkcje systemowe
8
+// Jan Potocki 2018
9
+class Stopwatch
10
+{
11
+    public:
12
+        Stopwatch();
13
+        void start();
14
+        void stop();
15
+        bool isRunning();
16
+        float read();
17
+    protected:
18
+    private:
19
+        unsigned long long int miliseconds;
20
+        bool running;
21
+        std::thread measureThread;
22
+        void measure();
23
+};
24
+
25
+#endif // STOPWATCH_H

Binārs
so2-game/Stopwatch.o Parādīt failu


+ 202
- 0
so2-game/so2-game.cpp Parādīt failu

@@ -0,0 +1,202 @@
1
+#include <cstdlib>
2
+#include <ctime>
3
+#include <iostream>
4
+#include <string>
5
+#include <thread>
6
+#include <vector>
7
+#include <ncurses.h>
8
+#include <unistd.h>
9
+#include "Brick.h"
10
+#include "Platform.h"
11
+#include "Stopwatch.h"
12
+
13
+const int gameTime = 120;
14
+
15
+int xMax, yMax;
16
+bool refreshing = false;
17
+bool climate = false;
18
+std::vector<Brick> bricks;
19
+Platform platform;
20
+Stopwatch gameClock;
21
+
22
+// "Monitor" function
23
+void refreshScreen()
24
+{
25
+    while(refreshing == true)
26
+    {
27
+        Scene::ncursesMutex.lock();
28
+        clear();
29
+
30
+        for(int i = 0; i < bricks.size(); i++)
31
+        {
32
+            // Easter egg (1)
33
+            if(climate)
34
+                {
35
+                    attron(COLOR_PAIR(bricks[i].getColor()));
36
+                    mvprintw(bricks[i].getyPosition(), bricks[i].getxPosition(), "*");
37
+                    attroff(COLOR_PAIR(bricks[i].getColor()));
38
+                }
39
+            else
40
+                {
41
+                    attron(COLOR_PAIR(bricks[i].getColor()));
42
+                    mvprintw(bricks[i].getyPosition(), bricks[i].getxPosition(), "#");
43
+                    attroff(COLOR_PAIR(bricks[i].getColor()));
44
+                }
45
+        }
46
+
47
+        attron(COLOR_PAIR(platform.getColor()));
48
+        mvprintw(yMax - 2, platform.getPosition(), platform.getSprite());
49
+        attroff(COLOR_PAIR(platform.getColor()));
50
+
51
+        mvprintw(yMax - 1, 0, "%.3f", gameClock.read());
52
+        mvprintw(yMax - 1, xMax - 3, "%.3d", Scene::getPoints());
53
+
54
+        refresh();
55
+        Scene::ncursesMutex.unlock();
56
+
57
+        // Refresh every 0.01 s
58
+        usleep(10000);
59
+    }
60
+}
61
+
62
+int main(int argc, char *argv[])
63
+{
64
+    std::vector<std::thread> brickThreads;
65
+
66
+    srand(time(0));
67
+
68
+    // Easter egg (2)
69
+    if(argc == 2)
70
+    {
71
+        std::string param(argv[1]);
72
+
73
+        if(param == "--globalwarming")
74
+        {
75
+            climate = true;
76
+        }
77
+    }
78
+
79
+    // Initialize ncurses
80
+    initscr();
81
+    curs_set(0);
82
+    getmaxyx(stdscr, yMax, xMax);
83
+
84
+    // Initialize colors
85
+    start_color();
86
+    init_pair(1, COLOR_RED, COLOR_BLACK);
87
+    init_pair(2, COLOR_GREEN, COLOR_BLACK);
88
+    init_pair(3, COLOR_YELLOW, COLOR_BLACK);
89
+    init_pair(4, COLOR_BLUE, COLOR_BLACK);
90
+    init_pair(5, COLOR_MAGENTA, COLOR_BLACK);
91
+    init_pair(6, COLOR_CYAN, COLOR_BLACK);
92
+
93
+    // Non-blocking input for platform-movement
94
+    timeout(0);
95
+
96
+    // Initialize scene
97
+    Scene::init(xMax, yMax);
98
+    Brick::setPlatform(&platform);
99
+
100
+    // Initialize all bricks...
101
+    for(int i = 0; i < xMax; i++)
102
+    {
103
+        // ...with random descent rate in range 0 (slow) to 15 (fast)
104
+        Brick brick(i, rand() % 16);
105
+        bricks.push_back(brick);
106
+    }
107
+
108
+    // Start monitor
109
+    refreshing = true;
110
+    std::thread monitor(refreshScreen);
111
+
112
+    // Start platform treads
113
+    std::thread platformMover(platform.moveKeyThread());
114
+    std::thread platformColorChanger(platform.colorChangeThread());
115
+
116
+    // Start game
117
+    gameClock.start();
118
+
119
+    while(gameClock.read() < gameTime)
120
+    {
121
+        // Freeze game
122
+        if(Scene::isFreezed() == true)
123
+        {
124
+            std::unique_lock<std::mutex> freezeLock(Scene::freezeMutex);
125
+
126
+            while(Scene::isFreezed() == true)
127
+            {
128
+                Scene::freezeCondition.wait(freezeLock);
129
+            }
130
+        }
131
+
132
+        // Determine random brick...
133
+        int randBrick = rand() % xMax;
134
+        while(bricks.at(randBrick).isFalling())
135
+        {
136
+            // ...which still isn't falling down...
137
+            randBrick = rand() % xMax;
138
+        }
139
+
140
+        // ...and launch it with nuclear-powered hammer ;-)
141
+        brickThreads.push_back(bricks.at(randBrick).fallThread());
142
+
143
+        // Random time in range 400 to 800 ms until next fall
144
+        unsigned randTime = rand() % 4 + 4;
145
+        usleep(100000 * randTime);
146
+    }
147
+
148
+    // Stop clock
149
+    gameClock.stop();
150
+
151
+    // Stop scene objects threads
152
+    Scene::terminateAll();
153
+
154
+    platformMover.join();
155
+    platformColorChanger.join();
156
+
157
+    for(int i = 0; i < brickThreads.size(); i++)
158
+    {
159
+        brickThreads.at(i).join();
160
+    }
161
+
162
+    // Stop monitor
163
+    refreshing = false;
164
+    monitor.join();
165
+    sleep(1);
166
+
167
+    // Close ncurses
168
+    endwin();
169
+
170
+    std::cout << "Your score: " << Scene::getPoints() << " points" << std::endl;
171
+
172
+    if(Scene::getPoints() != 0)
173
+    {
174
+        std::cout << "Congratulations!" << std::endl;
175
+    }
176
+
177
+    std::cout << std::endl;
178
+
179
+    std::cout << "BRIcks-ng Caban Kernel-thread System Next Generation v1.0" << std::endl;
180
+    std::cout << "Jan Potocki 2018" << std::endl;
181
+    std::cout << "(beerware)" << std::endl;
182
+    std::cout << std::endl;
183
+    std::cout << '"' << "...Back around that Halloween," << std::endl;
184
+    std::cout << "Microsoft said open source would never last," << std::endl;
185
+    std::cout << "But now they use the repo tools," << std::endl;
186
+    std::cout << "In the same open access way..." << '"' << std::endl;
187
+    std::cout << "(and recently acquired GitHub)" << std::endl;
188
+    std::cout << std::endl;
189
+
190
+    // Easter egg (3)
191
+    if(climate)
192
+    {
193
+        std::cout << "SEVERE WEATHER ALERT: major snowfall predicted in 48h forecast for Lower Silesia, south-western Poland" << std::endl;
194
+        std::cout << "Global warming affecting again!... ;-)" << std::endl;
195
+    }
196
+    else
197
+    {
198
+        std::cout << "Beware of BRICKS! ;-)" << std::endl;
199
+    }
200
+
201
+    return 0;
202
+}

Binārs
so2-game/so2-game.o Parādīt failu


Notiek ielāde…
Atcelt
Saglabāt