232 lines
6.9 KiB
C++
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#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;
}