232 lines
6.9 KiB
C++
232 lines
6.9 KiB
C++
#include "gamecube.h"
|
||
#include <algorithm>
|
||
#include <iostream>
|
||
#include <fstream>
|
||
#include <ctime>
|
||
#include <vector>
|
||
#include <thread>
|
||
#include <chrono>
|
||
|
||
// -----------------------------------------------------------
|
||
// 3D Memory Game – Hauptprogramm mit GameState
|
||
// -----------------------------------------------------------
|
||
|
||
// Zustände laut Aufgabenblatt
|
||
enum class GameState
|
||
{
|
||
Idle, // kein Würfel offen
|
||
OneFlipped, // ein Würfel offen
|
||
LockInput, // Würfel drehen -> Eingabe blockiert
|
||
CheckingMatch // beide offen, Vergleich läuft
|
||
};
|
||
|
||
int main()
|
||
{
|
||
srand(time(NULL));
|
||
|
||
InitWindow(800, 600, "3D Memory Game with GameState");
|
||
SetTargetFPS(60);
|
||
|
||
Camera3D camera{};
|
||
camera.position = {6.0f, 6.0f, 6.0f};
|
||
camera.target = {0.0f, 0.0f, 0.0f};
|
||
camera.up = {0.0f, 1.0f, 0.0f};
|
||
camera.fovy = 45.0f;
|
||
camera.projection = CAMERA_PERSPECTIVE;
|
||
|
||
Color colors[] = { RED, GREEN, BLUE };
|
||
|
||
std::vector<Vec3> positions = {
|
||
{-2, 0, -2}, {0, 0, -2}, {2, 0, -2},
|
||
{-2, 0, 0}, {0, 0, 0}, {2, 0, 0}
|
||
};
|
||
|
||
// Farben doppelt
|
||
std::vector<Color> pool;
|
||
for (int i = 0; i < 3; i++) {
|
||
pool.push_back(colors[i]);
|
||
pool.push_back(colors[i]);
|
||
}
|
||
|
||
// mischen
|
||
for (int i = pool.size() - 1; i > 0; --i)
|
||
std::swap(pool[i], pool[rand() % (i + 1)]);
|
||
|
||
// Würfel erzeugen
|
||
std::vector<gamecube> cubes;
|
||
for (int i = 0; i < 6; i++)
|
||
cubes.emplace_back(positions[i], pool[i]);
|
||
|
||
// GameState Variablen
|
||
GameState state = GameState::Idle;
|
||
gamecube* first = nullptr;
|
||
gamecube* second = nullptr;
|
||
bool gameWon = false;
|
||
float flipSpeed = 5.0f;
|
||
|
||
// -----------------------------------------------------------
|
||
// Game Loop
|
||
// -----------------------------------------------------------
|
||
while (!WindowShouldClose())
|
||
{
|
||
Vector2 mouse = GetMousePosition();
|
||
|
||
// -------------------------------------------------------
|
||
// Eingabe NUR erlauben, wenn Idle oder OneFlipped
|
||
// -------------------------------------------------------
|
||
if (!gameWon &&
|
||
(state == GameState::Idle || state == GameState::OneFlipped) &&
|
||
IsMouseButtonPressed(MOUSE_LEFT_BUTTON))
|
||
{
|
||
for (auto &c : cubes)
|
||
{
|
||
if (!c.IsFlipped() && !c.IsMatched())
|
||
{
|
||
Vector2 screen = GetWorldToScreen(
|
||
{c.GetPosition().x, c.GetPosition().y, c.GetPosition().z},
|
||
camera
|
||
);
|
||
|
||
if (fabs(mouse.x - screen.x) < 40 &&
|
||
fabs(mouse.y - screen.y) < 40)
|
||
{
|
||
c.FlipForward(); // Animation starten
|
||
|
||
if (state == GameState::Idle)
|
||
{
|
||
first = &c;
|
||
state = GameState::OneFlipped;
|
||
}
|
||
else if (state == GameState::OneFlipped)
|
||
{
|
||
second = &c;
|
||
state = GameState::LockInput; // Animation läuft
|
||
}
|
||
break;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
// -------------------------------------------------------
|
||
// Animation durchführen
|
||
// -------------------------------------------------------
|
||
for (auto &c : cubes)
|
||
c.Update(flipSpeed);
|
||
|
||
// Wenn beide cubes fertig gedreht → Vergleich starten
|
||
if (state == GameState::LockInput &&
|
||
first && second &&
|
||
first->IsFullyFlipped() &&
|
||
second->IsFullyFlipped())
|
||
{
|
||
state = GameState::CheckingMatch;
|
||
}
|
||
|
||
// -------------------------------------------------------
|
||
// Vergleich
|
||
// -------------------------------------------------------
|
||
if (state == GameState::CheckingMatch)
|
||
{
|
||
Color a = first->GetColor();
|
||
Color b = second->GetColor();
|
||
|
||
if (a.r == b.r && a.g == b.g && a.b == b.b)
|
||
{
|
||
first->SetMatched(true);
|
||
second->SetMatched(true);
|
||
}
|
||
else
|
||
{
|
||
first->FlipBackward();
|
||
second->FlipBackward();
|
||
}
|
||
|
||
first = second = nullptr;
|
||
state = GameState::Idle;
|
||
}
|
||
|
||
// -------------------------------------------------------
|
||
// Gewinnprüfung
|
||
// -------------------------------------------------------
|
||
if (!gameWon)
|
||
gameWon = std::all_of(
|
||
cubes.begin(), cubes.end(),
|
||
[](const gamecube &c){ return c.IsMatched(); }
|
||
);
|
||
|
||
// -------------------------------------------------------
|
||
// Rendering
|
||
// -------------------------------------------------------
|
||
BeginDrawing();
|
||
ClearBackground(RAYWHITE);
|
||
BeginMode3D(camera);
|
||
|
||
for (auto &c : cubes)
|
||
c.Draw();
|
||
|
||
EndMode3D();
|
||
|
||
if (gameWon)
|
||
DrawText("Congrats! You found all pairs!", 140, 260, 30, DARKBLUE);
|
||
else
|
||
DrawText("Flip 2 cubes - find matching pairs!", 10, 10, 20, DARKGRAY);
|
||
|
||
EndDrawing();
|
||
}
|
||
std::vector<int> messungen;
|
||
std::ifstream file("measurements.txt");
|
||
int value;
|
||
while (file >> value) messungen.push_back(value);
|
||
|
||
// -------------------------
|
||
// Serielle Zählung
|
||
// -------------------------
|
||
auto start = std::chrono::steady_clock::now();
|
||
int increases = 0;
|
||
for (size_t i = 1; i < messungen.size(); ++i)
|
||
if (messungen[i] > messungen[i-1]) ++increases;
|
||
auto end = std::chrono::steady_clock::now();
|
||
std::cout << "Serial: " << increases
|
||
<< " Took: "
|
||
<< std::chrono::duration<double>(end - start).count()
|
||
<< " s\n";
|
||
|
||
// -------------------------
|
||
// Parallele Zählung
|
||
// -------------------------
|
||
int numThreads = 4;
|
||
std::vector<int> results(numThreads, 0);
|
||
std::vector<std::thread> threads;
|
||
|
||
int totalComparisons = messungen.size() - 1;
|
||
int base = totalComparisons / numThreads;
|
||
int remainder = totalComparisons % numThreads;
|
||
|
||
int idx = 1;
|
||
for (int t = 0; t < numThreads; t++)
|
||
{
|
||
int startIdx = idx;
|
||
int count = base + (t < remainder ? 1 : 0);
|
||
int endIdx = idx + count - 1;
|
||
idx = endIdx + 1;
|
||
|
||
threads.emplace_back([&, t, startIdx, endIdx](){
|
||
int local = 0;
|
||
for (int i = startIdx; i <= endIdx; ++i)
|
||
if (messungen[i] > messungen[i-1]) ++local;
|
||
results[t] = local;
|
||
});
|
||
}
|
||
|
||
for (auto &th : threads) th.join();
|
||
|
||
int total = 0;
|
||
for (auto r : results) total += r;
|
||
|
||
std::cout << "Parallel: " << total << "\n";
|
||
|
||
CloseWindow();
|
||
return 0;
|
||
}
|