ConnectForce/docs/Documentation.md

153 lines
5.8 KiB
Markdown

---
Header:
Right: ConnectForce
---
# ConnectForce Dokumentation
> `ConnectForce` ist eine grossartige Umsetzung des allzeit beliebten Spiels namens "4 Gewinnt!".
> In diesem strategisch anspruchsvollen Spiel müssen Spieler ihre Spielsteine möglichst geschickt platzieren, um so 4 von ihnen zu verbinden und sich so als dem Gegner überlegen zu beweisen!
>
> Wirst du dazu imstande sein, über dem IQ und der Geschicklichkeit deines Gegners zu obsiegen?
Für die Umsetzung von `ConnectForce` wurden Standards und Technologien wie etwa `SJDON`, `SuiWeb`, JavaScript, CSS und HTML verwendet.
Das Ziel dieses Dokuments ist es, aufzuzeigen, welche Aspekte des Projekts in ihrer Umsetzung herausfordernd waren, wie diese Herausforderungen in Angriff genommen wurden und welche Fortschritte besonders erwähnenswert sind.
## Beteiligte Personen
Das Projekt wurde von folgenden Personen umgesetzt:
- Manuel Thalmann
Allgemeine Umsetzung, Programmierung, Design
- Jonas Costa
Bilder, Werbung
## Das Endprodukt
Das Endprodukt ist ein "4 Gewinnt!" Spiel, welches sich in der Grösse automatisch so skaliert, dass es sich auf jeglichen Geräten übersichtlich betrachten und auch steuern lässt (wie etwa Tablets, Handys, Computer, Ultra Widescreen Monitore etc.).
Folgender Screenshot zeigt, wie die Anwendung in einem Chromium Browser aussieht:
![](Preview.png)
## Features
Die Anwendung bringt einige nennenswerte Funktionen mit sich. Zu diesen zählen folgende:
- Die Fähigkeit, das Spiel jederzeit neu zu starten
- Die Möglichkeit, das Spiel im lokalen Speicher des Browsers zu speichern und aus diesem zu laden
- Die Funktion, einzelne Änderungen, die am Zustand des Spiels vorgenommen wurden, rückgängig zu machen
## Nutzung
Die Anwendung wird mit Hilfe der `SJDON`-Notation zur Verfügung gestellt und kann somit problemlos mit der Bibliothek `SuiWeb` dargestellt und ausgeführt werden:
```js
import { App } from "./Components.js";
import { render } from "./SuiWeb.js";
/**
* Initializes the board.
*/
function initialize()
{
render([App], document.querySelector("#game"));
}
initialize();
```
## Herausforderungen
Einige Aspekte des Spiels stellten sich, obwohl es zunächst nicht den Anschein machte, als Herausforderungen heraus. Eine davon wird in diesem Kapitel im Details beschrieben.
### Bestimmung des Gewinners
Teil der Aufgabe war es, anhand des Zustandes des Spielfelds zu entscheiden, ob und welcher Spieler gewonnen hat.
Der Weg für die Bestimmung des Gewinners, welcher in diesem Projekt verwendet wurde, wird im Folgenden genauer erklärt.
#### Grundlagen
Es gibt genau 4 verschiedene Arten, in denen Figuren zueinander stehen können:
| Bezeichnung | Relative Koordinaten |
| --------------------- | -------------------- |
| Horizontal | `[0, 1]` |
| Vertikal | `[1, 0]` |
| Diagonal (nach unten) | `[1, 1]` |
| Diagonal (nach oben) | `[1, -1]` |
Folgende Bilder dienen der Illustration:
- Horizontal:
![](./Horizontal.png)
- Vertikal:
![](./Vertical.png)
- Diagonal (nach unten):
![](./DiagonalDown.png)
- Diagonal (nach oben):
![](./DiagonalUp.png)
Der Fakt, dass Chips nur in diesen 4 Relationen auftreten können, wird genutzt, um mit Hilfe mehrerer Iterationen zu prüfen, ob sich jeweils 4 Felder mit den genannten relativen Koordinaten zueinander in Relation stehen.
Für die Kontrolle, ob eine Person gewonnen hat, wird folgender Algorithmus verwendet:
```js
// Iterate over all possible relative coordinates.
for (let yOffset = 0; yOffset <= 1; yOffset++)
{
for (let xOffset = (yOffset === 1) ? -1 : 1; xOffset <= 1; xOffset++)
{
// Calculate upper and lower bounds of the x-axis.
let lowerBound = Math.max(0, xOffset * (Game.#count - 1) * -1);
let upperBound = Math.min(Game.#width, Game.#width - (xOffset * (Game.#count - 1)));
// Iterate over all possible x- and y-coordinates.
for (let y = 0; y < (Game.#height - yOffset * (Game.#count - 1)); y++)
{
for (let x = lowerBound; x < upperBound; x++)
{
/**
* @type {CellOwner[]}
*/
let tokens = [];
// Generate a list of all tokens in the current scope.
for (let i = 0; i < Game.#count; i++)
{
tokens.push(this.board[y + i * yOffset][x + i * xOffset]);
}
let player = tokens[0];
// Check whether the tokens indicate a win.
if (
player !== "" &&
tokens.every((token) => token === player))
{
return player;
}
}
}
}
}
return null;
```
Dieser Algorithmus ist dazu imstande, zu bestimmen, ob und welcher Spieler gewonnen hat. Dies funktioniert unabhängig davon, ob die Steine horizontal, vertikal oder diagonal verbunden sind.
Einige Kommentare im Code sollen dabei behilflich sein, die Funktionalität zu verstehen.
## Umsetzung
Für das Umsetzen des Projekts wurde die Notation `SJDON` verwendet zusammen mit der ausgelieferten Bibliothek `SuiWeb` verwendet.
Komponenten mit Besonderheiten werden im folgenden Kapitel genauer beschrieben.
### Komponenten
#### App
Die App-Komponente beinhaltet das gesamte Spiel-Konstrukt, zeigt den aktuellen Zustand des Spiels an und verarbeitet Interaktionen, die der Benutzer mit dem Spiel macht.
Dies beinhaltet alle zuvor genannten Funktionen und das Vollziehen eines Spielzuges.
Zudem wird ein zum Aufrufenden ideal passendes Produkt in einem Werbungs-Banner angezeigt.
## MenuBar
Die Menü-Leiste erlaubt es dem Besucher, die von ihm gewünschten Funktionen auszuführen.
Sollte eine Funktion nicht verfügbar sein, wird dies dem Nutzer auf verständlicher Weise angezeigt.