From 14681c60cd5981429ee27e873d3891f8a7ab7b31 Mon Sep 17 00:00:00 2001
From: Nicolas Fritz <nicolas-noah.fritz@informatik.hs-fulda.de>
Date: Wed, 25 Jan 2023 19:25:43 +0100
Subject: [PATCH] =?UTF-8?q?GameLoop=20hinzugef=C3=BCgt=20und=20Bugfixes=20?=
 =?UTF-8?q?+=20Regel=20Erste=20SpielKarte=20SpecialKarte=20hinzugef=C3=BCg?=
 =?UTF-8?q?t?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 .gitignore                                 |   3 +-
 uno/node/js/Game.js                        |  73 +++++++++---
 uno/node/js/Player.js                      |   3 +
 uno/node/js/cards/Card.js                  |   4 +-
 uno/node/js/cards/special/ChooseColor.js   |  11 +-
 uno/node/js/cards/special/PlusAmount.js    |   7 +-
 uno/node/tests/test_Card.test.js           |  12 +-
 uno/node/tests/test_Game.test.js           | 127 ++++++++++++++++++++-
 uno/node/tests/test_Player.test.js         |   8 +-
 vier_gewinnt/tests/test_vierGewint.test.js |   2 +
 10 files changed, 223 insertions(+), 27 deletions(-)

diff --git a/.gitignore b/.gitignore
index 096746c..4753def 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1 +1,2 @@
-/node_modules/
\ No newline at end of file
+/node_modules/
+/commits
diff --git a/uno/node/js/Game.js b/uno/node/js/Game.js
index 920e5be..dfac109 100644
--- a/uno/node/js/Game.js
+++ b/uno/node/js/Game.js
@@ -15,16 +15,14 @@ class Game {
     constructor(playerAmount, rules) {
 
         this._cardOnDeck = null; //Karte die auf dem Tisch liegt
-        this._currentPlayer = 0; //Aktueller Spieler Index im Player Array
+        this._currentPlayer = -1; //Aktueller Spieler Index im Player Array
         this._direction = 1; //Spielrichtung
         this._players = []; //Array mit allen Spielern drin
-        this._cardPool = [] //Pool aus Karten
+        this._cardPool = []; //Pool aus Karten
 
         this._playerAmount = playerAmount; //Anzahl der Spieler
         this._rules = rules; //Array mit Regeln für das Spiel
 
-        //Spiel einrichten
-        this.initGame();
     }
 
     //Richtet das Spiel ein
@@ -36,22 +34,50 @@ class Game {
         //Spieler werden erstellt
         this.createPlayers(this._playerAmount);
 
-        //Die Erste Karte wird auf den Tisch gelegt
-        this._cardOnDeck = this._cardPool[0];
-        this._cardPool.splice(0,1);
-
     }
 
     //Startet das Spiel
     start(){
+        if(this._currentPlayer !== -1) return;
 
         //Wenn das Spiel noch nicht initialisiert wurde, initialisiere es
-        if (this._cardPool === [] || this._players === [])
+        if (this._cardPool.length === 0 || this._players.length === 0)
             this.initGame();
 
 
+        let firstCardIndex = 0;
+        let boolFirstSpecial = false;
+
+        if (this._rules !== null){
+            if('startCards' in this.rules)
+                for (let i = 0; i < this.players.length; i++)
+                    this.players[i].drawCard(this.rules.startCards);
+
+            if('firstPlaySpecial' in this.rules)
+                    boolFirstSpecial = this.rules.firstPlaySpecial;
+
+
+
+
+        }
+
+        if (!boolFirstSpecial){
+            for (let i = 0; i < this.cardPool.length; i++){
+                if (!(this.cardPool[i].name === 'R' || this.cardPool[i].name === 'S'
+                    || this.cardPool[i].name === 'CC' || this.cardPool[i].name === '+2'
+                    || this.cardPool[i].name === '+4')){
+                    firstCardIndex = i;
+                    break;
+                }
+            }
+        }
 
+        //Die Erste Karte wird auf den Tisch gelegt
+        this._cardOnDeck = this._cardPool[firstCardIndex];
+        this._cardPool.splice(firstCardIndex,1);
 
+        //Karten Funktion der Karte auf dem Deck ausführen
+        this.cardOnDeck.putSelf();
 
     }
 
@@ -114,20 +140,26 @@ class Game {
 
     //Beendet den Zug des aktuellen Spielers und beginnt den Zug des nächsten Spielers
     nextTurn(){
+
         //Testet, ob Spiel Gewonnen
-        for (let i = 0; i < this._players.length; i++){
-            if(this._players[i].hand.length <= 0){
+        for (let i = 0; i < this.players.length; i++){
+            if(this.players[i].hand.length <= 0){
 
                 //Breche den Loop ab
                 return;
             }
         }
 
+        //Wenn Zug nicht der Erste vom ganzen Spiel
+        if(this.currentPlayer !== -1){
+
         //Aktuellen Spieler kann, darf nicht mehr Spielen
-        this.players[this._currentPlayer].canPlay = false;
+        this.players[this.currentPlayer].canPlay = false;
+
+        }
 
         //nächster Spieler wird gesetzt
-        this._currentPlayer = this.nextPlayer();
+        this.currentPlayer = this.nextPlayer();
 
         //Aktualisiere das Deck des aktuellen Spielers, welche Karten er legen kann
         this.refreshCanPutCard();
@@ -137,7 +169,7 @@ class Game {
     //Testet alle Karten des aktuellen Spielers in seiner Hand, ob er sie legen kann
     refreshCanPutCard(){
         //Deck des aktuellen Spielers
-        let currentPlayerCards = this._players[this._currentPlayer].hand;
+        let currentPlayerCards = this.players[this.currentPlayer].hand;
 
         //Gehe alle Karten vom Deck durch
         for(let i = 0; i < currentPlayerCards.length; i++){
@@ -167,6 +199,8 @@ class Game {
 
     //Errechne, wer der nächste Spieler ist
     nextPlayer(){
+        if(this.currentPlayer === -1)
+            return 0;
 
         //Anhand der Spielrichtung errechnen
         if(this._direction === 1)
@@ -196,11 +230,16 @@ class Game {
         this._cardOnDeck = card;
     }
 
-    //Gibt den aktuellen Spieler zurück
+    //Gibt den Index des aktuellen Spielers im players Array zurück
     get currentPlayer(){
         return this._currentPlayer;
     }
 
+    //Gibt das Objekt des aktuellen Spielers zurück
+    get currentPlayerInstanz(){
+        return this._players[this.currentPlayer];
+    }
+
     set currentPlayer(player){
         this._currentPlayer = player
     }
@@ -214,6 +253,10 @@ class Game {
         this._direction = direction;
     }
 
+    get rules(){
+        return this._rules;
+    }
+
 }
 
 //Exportiert Modul Game
diff --git a/uno/node/js/Player.js b/uno/node/js/Player.js
index 0ada326..35d8126 100644
--- a/uno/node/js/Player.js
+++ b/uno/node/js/Player.js
@@ -28,6 +28,9 @@ class Player {
 
         }
 
+        if(amount === 1)
+            this._game.nextTurn();
+
     }
 
     //Lässt den Spieler eine Karte in seiner Hand legen
diff --git a/uno/node/js/cards/Card.js b/uno/node/js/cards/Card.js
index 175b287..09a821f 100644
--- a/uno/node/js/cards/Card.js
+++ b/uno/node/js/cards/Card.js
@@ -3,7 +3,7 @@
 class Card {
 
     //Konstruktor für das Erstellen einer Karte
-    constructor(name, color, gameInstanz) {
+    constructor(name, color, gameInstanz, ) {
 
         this._game = gameInstanz;
         this._onScreen = false; //Die Karte wird bei Erstellung noch nicht auf dem Bildschirm angezeigt
@@ -17,7 +17,7 @@ class Card {
     putSelf(){
 
         //Nächster Spieler am Zug
-        this._game.nextTurn();
+        this.game.nextTurn();
 
     }
 
diff --git a/uno/node/js/cards/special/ChooseColor.js b/uno/node/js/cards/special/ChooseColor.js
index 68cdaf9..e87a32f 100644
--- a/uno/node/js/cards/special/ChooseColor.js
+++ b/uno/node/js/cards/special/ChooseColor.js
@@ -17,9 +17,14 @@ class ChooseColor extends Card {
     //Führt eigene Logik aus (Wählt farbe aus)
     putSelf() {
 
-        //Setzt die Farbe der Karte auf eine Random Farbe
-        this._color = this.game.players[this.game.currentPlayer].selectColor();
-
+        if(this.game.currentPlayer === -1) {
+            //Setzt die Farbe der Karte auf eine Random Farbe
+            this.color = CARD_COLORS[Math.floor(Math.random() * 4) + 1];
+        }
+        else{
+            //lässt den Spieler eine Farbe wählen
+            this._color = this.game.players[this.game.currentPlayer].selectColor();
+        }
         //Logik von Card.js ausführen
         super.putSelf();
     }
diff --git a/uno/node/js/cards/special/PlusAmount.js b/uno/node/js/cards/special/PlusAmount.js
index 6476343..c85cfcc 100644
--- a/uno/node/js/cards/special/PlusAmount.js
+++ b/uno/node/js/cards/special/PlusAmount.js
@@ -1,6 +1,7 @@
 //Imports
 const uno = require('../../uno');
 const Card = require('../Card');
+const {CARD_COLORS} = require("../../uno");
 
 //Klasse PlusAmount für Karten, die den nächsten Spieler ziehen lassen
 class PlusAmount extends Card {
@@ -24,7 +25,11 @@ class PlusAmount extends Card {
         this.game.players[this.game.nextPlayer()].drawCard(this._plus);
 
         if(this._plus === 4){
-            this._color = this.game.players[this.game.currentPlayer].selectColor();
+
+            if(this.game.currentPlayer === -1)
+                this.color = CARD_COLORS[Math.floor(Math.random() * 4) + 1];
+            else
+                this._color = this.game.players[this.game.currentPlayer].selectColor();
         }
 
         //Logik von Card.js ausführen
diff --git a/uno/node/tests/test_Card.test.js b/uno/node/tests/test_Card.test.js
index 5f249ff..6a762b0 100644
--- a/uno/node/tests/test_Card.test.js
+++ b/uno/node/tests/test_Card.test.js
@@ -102,14 +102,18 @@ describe('Karten erstellen', () => {
 
 describe('Kartenfunktionen', () => {
 
-    let game = new Game(2, null);
+    let rules = {
+        startCards: 2,
+    }
+
+    let game = new Game(2, rules);
     let card;
 
+    game.start();
+
     //Spieler brauchen karten, sonst beendet sich das Spiel
     game.players[0].canPlay = true;
     game.players[1].canPlay = true;
-    game.players[0].drawCard(2);
-    game.players[1].drawCard(2);
 
     it('Card - nächster Spieler an der Reihe', () => {
 
@@ -140,6 +144,8 @@ describe('Kartenfunktionen', () => {
 
         card = new Reverse(CARD_COLORS[2], game);
 
+        game.direction = 1;
+
         card.putSelf();
 
         //Die Spielrichtung muss geändert werden
diff --git a/uno/node/tests/test_Game.test.js b/uno/node/tests/test_Game.test.js
index 2502063..5c484a0 100644
--- a/uno/node/tests/test_Game.test.js
+++ b/uno/node/tests/test_Game.test.js
@@ -1,6 +1,11 @@
 //Imports
 const uno = require('../js/uno');
 const Game = require('../js/Game');
+const PlusAmount = require("../js/cards/special/PlusAmount");
+const Skip = require("../js/cards/special/Skip");
+const Reverse = require("../js/cards/special/Reverse");
+const ChooseColor = require("../js/cards/special/ChooseColor");
+const Card = require("../js/cards/Card");
 
 //Instanz von CARD_COLORS aus uno.js
 const CARD_COLORS = uno.CARD_COLORS;
@@ -174,7 +179,127 @@ describe('Pool aus Karten generieren', () => {
 
     });
 
-})
+});
+
+describe('StartKarte legen', () => {
+
+    let game;
+    let card;
+
+    beforeEach(() => {
+        game = new Game(2, null)
+        game.initGame();
+        game.players[0].drawCard(2);
+        game.players[1].drawCard(2);
+    })
+
+
+
+    it('+4', ()=> {
+
+        card = new PlusAmount(game);
+
+        game.cardOnDeck = card;
+
+        game.cardOnDeck.putSelf();
+
+        expect(game.currentPlayer).toBe(0);
+
+    });
+
+    it('+2', ()=> {
+
+        card = new PlusAmount(game, CARD_COLORS[2]);
+
+        game.cardOnDeck = card;
+
+        game.cardOnDeck.putSelf();
+
+        expect(game.currentPlayer).toBe(0);
+
+    });
+
+    it('S', ()=> {
+
+        card = new Skip(CARD_COLORS[2], game);
+
+        game.cardOnDeck = card;
+
+        game.cardOnDeck.putSelf();
+
+        expect(game.currentPlayer).toBe(1);
+
+    });
+
+    it('R', ()=> {
+
+        card = new Reverse(CARD_COLORS[2], game);
+
+        game.cardOnDeck = card;
+
+        game.cardOnDeck.putSelf();
+
+        expect(game.currentPlayer).toBe(0);
+
+    });
+
+    it('CC', ()=> {
+
+        card = new ChooseColor(game);
+
+        game.cardOnDeck = card;
+
+        game.cardOnDeck.putSelf();
+
+        expect(game.currentPlayer).toBe(0);
+
+    });
+
+    it('Normale Karte', ()=> {
+
+        card = new Card('8', CARD_COLORS[2], game);
+
+        game.cardOnDeck = card;
+
+        game.cardOnDeck.putSelf();
+
+        expect(game.currentPlayer).toBe(0);
+
+    });
+
+
+});
+
+describe('Testet die Regeln', () => {
+
+    let game, rules;
+
+    it('Erster Spielzug SpecialKarte', function () {
+
+        rules = {
+            firstPlaySpecial: true,
+        }
+
+        let bool = false;
+
+        for (let i = 0; i < 100; i++){
+
+
+            game = new Game(2, rules);
+            game.start();
+
+            if (game.cardOnDeck.name === 'R' || game.cardOnDeck.name === 'S'
+            || game.cardOnDeck.name === 'CC' || game.cardOnDeck.name === '+2'
+            || game.cardOnDeck.name === '+4'){
+                bool = true;
+            }
+        }
+
+        expect(bool).toBe(true);
+
+    });
+
+});
 
 //Setzt die Kartenanzahl der Farben für array
 function getColorAmounts(array){
diff --git a/uno/node/tests/test_Player.test.js b/uno/node/tests/test_Player.test.js
index 72402ce..cc6772e 100644
--- a/uno/node/tests/test_Player.test.js
+++ b/uno/node/tests/test_Player.test.js
@@ -59,10 +59,16 @@ describe('Spieler Funktionalitäten', () => {
     //Erstellt ein Spiel
     let game = new Game(2, null);
     let cardAmount;
+    let playerCardAmount;
+
+    game.start();
+
+    game.players[0].hand = [];
 
     //Nimmt die Anzahl der Karten im Deck und speichert sie in cardAmount vor jedem Test
     beforeEach(() => {
         cardAmount = game.cardPool.length;
+        playerCardAmount = game.players[0].hand.length;
     })
 
 
@@ -76,7 +82,7 @@ describe('Spieler Funktionalitäten', () => {
         expect(game.cardPool.length).toBe(cardAmount - 1);
 
         //Testet, ob der Spieler jetzt eine Karte auf der Hand hat
-        expect(game.players[0].hand.length).toBe(1);
+        expect(playerCardAmount + 1).toBe(game.players[0].hand.length);
 
     });
 
diff --git a/vier_gewinnt/tests/test_vierGewint.test.js b/vier_gewinnt/tests/test_vierGewint.test.js
index e69de29..cecd336 100644
--- a/vier_gewinnt/tests/test_vierGewint.test.js
+++ b/vier_gewinnt/tests/test_vierGewint.test.js
@@ -0,0 +1,2 @@
+it('Test', function () {
+});
\ No newline at end of file