diff --git a/src/Koenig.c b/src/Koenig.c index dd97a02..19b1c0e 100644 --- a/src/Koenig.c +++ b/src/Koenig.c @@ -5,6 +5,7 @@ #include "spieler.h" #include "Moving.h" #include "Koenig.h" +#include "Spielstatus.h" bool GreiftBauerAn(char** Brett, int x, int y, Player player) { // Checke für weißen Bauer @@ -208,7 +209,31 @@ bool istFeldUnsicher(char** Brett, int x, int y, Player player) { return false; } +bool istKoenigImSchach(char** Brett, Player player) { + char kingSymbol = (player == PLAYER_WHITE) ? 'K' : 'k'; + int kingX = -1, kingY = -1; + // König finden + for (int y = 0; y < 8; y++) { + for (int x = 0; x < 8; x++) { + if (Brett[y][x] == kingSymbol) { + kingX = x; + kingY = y; + goto Koeniggefunden; + } + } + } +Koeniggefunden: + if (kingX == -1 || kingY == -1) { + // Falls kein König gefunden wird + return false; + } + if (istFeldUnsicher(Brett, kingX, kingY, player)) { + return true; // König ist im Schach + } + + return false; // König ist nicht im Schach +} bool istzugerlaubt_Koenig(char** Brett, int startX, int startY, int endX, int endY, Player player) { // Schauen ob der zug auf dem Spielbrett passiert @@ -234,3 +259,77 @@ bool istzugerlaubt_Koenig(char** Brett, int startX, int startY, int endX, int en return true; } +void bewegeKoenig(char** Brett, int startX, int startY, int endX, int endY, Player player, Spielstatus* status) { + if (istzugerlaubt_Koenig(Brett, startX, startY, endX, endY, player)) { + + char koenig = player == PLAYER_WHITE ? 'K' : 'k'; + Brett[endY][endX] = koenig; + Brett[startY][startX] = ' '; + + if (player == PLAYER_WHITE) { + status->BewegteSichWeißerKoenig = true; + } else { + status->BewegteSichSchwarzerKoenig = true; + } + } +} +bool kannRochieren(char** Brett, int startX, int startY, Player player, Spielstatus* status, bool kingside) { + // Simple Checks um zu schauen ob es möglich ist zu rochieren + if (player == PLAYER_WHITE) { + if (status->BewegteSichWeißerKoenig) return false; + if (kingside && status->WeißerTurmKoenigSeiteBewegt) return false; + if (!kingside && status->WeißerTurmDameSeiteBewegt) return false; + } else { // PLAYER_BLACK + if (status->BewegteSichSchwarzerKoenig) return false; + if (kingside && status->SchwarzerTurmKoenigSeiteBewegt) return false; + if (!kingside && status->SchwarzerTurmDameSeiteBewegt) return false; + } + + // Extra checks: Pfad muss frei sein, könig nicht im schach, und nicht sich durch Schach bewegen oder in Schach enden. + int dir = kingside ? 1 : -1; // Schauen in welche richtung man Rochiert + for (int offset = 1; offset <= (kingside ? 2 : 3); ++offset) { // Zwei Felder auf der kurzen, drei für lange Seite + int checkX = startX + dir * offset; + if (Brett[startY][checkX] != ' ' || istFeldUnsicher(Brett, checkX, startY, player)) { + return false; + } + } + + //wenn alles passt ist eine Rochade machbar + return true; +} +void rochiere(char** Brett, Player player, bool kingside, Spielstatus* status) { + int startY = player == PLAYER_WHITE ? 0 : 7; // Startreihe basierend auf dem Spieler + int koenigStartX = 4; // König x position + if (!kannRochieren(Brett,koenigStartX, startY, player, status, kingside)) { + printf("Rochieren ist unter den aktuellen Bedingungen nicht möglich.\n"); + return; // Beende die Funktion, wenn Rochieren nicht möglich ist + } + int koenigEndX = kingside ? 6 : 2; // König bewegt sich zwei Felder + int turmStartX = kingside ? 7 : 0; // Turm Startposition + int turmEndX = kingside ? 5 : 3; // Turm bewegt sich neben den könig + + // Den zug darstellen + char koenig = player == PLAYER_WHITE ? 'K' : 'k'; + char turm = player == PLAYER_WHITE ? 'R' : 'r'; + Brett[startY][koenigStartX] = ' '; // Königs startposition Leeren + Brett[startY][koenigEndX] = koenig; // Plaziert König auf dem neuen Feld + Brett[startY][turmStartX] = ' '; // Turm startposition Leeren + Brett[startY][turmEndX] = turm; // Plaziert Turm auf dem neuen Feld + + // Spielstatus updaten weil eine Rochade ausgeführt wurde + if (player == PLAYER_WHITE) { + status->BewegteSichWeißerKoenig = true; + if (kingside) { + status->WeißerTurmKoenigSeiteBewegt = true; + } else { + status->WeißerTurmDameSeiteBewegt = true; + } + } else { + status->BewegteSichSchwarzerKoenig = true; + if (kingside) { + status->SchwarzerTurmKoenigSeiteBewegt = true; + } else { + status->SchwarzerTurmDameSeiteBewegt = true; + } + } +} diff --git a/src/Koenig.h b/src/Koenig.h index 7dd9444..8bd6b03 100644 --- a/src/Koenig.h +++ b/src/Koenig.h @@ -1,6 +1,7 @@ #ifndef Koenig #define Koenig #include "Spieler.h" +#include "Spielstatus.h" bool GreiftBauerAn(char** Brett, int x, int y, Player player); bool GreiftTurmAn(char** Brett, int x, int y, Player player); bool GreiftSpringerAn(char** Brett, int x, int y, Player player); @@ -8,5 +9,9 @@ bool GreiftLaeuferAn(char** Brett, int x, int y, Player player); bool GreiftDameAn(char** Brett, int x, int y, Player player); bool GreiftKoenigAn(char** Brett, int x, int y, Player player); bool istFeldUnsicher(char** Brett, int x, int y, Player player); +bool istKoenigImSchach(char** Brett, Player player); bool istzugerlaubt_Koenig(char** Brett, int startX, int startY, int endX, int endY, Player player); +void bewegeKoenig(char** Brett, int startX, int startY, int endX, int endY, Player player, Spielstatus* status); +bool kannRochieren(char** Brett, int startX, int startY, Player player, Spielstatus* status, bool kingside); +void rochiere(char** Brett, Player player, bool kingside, Spielstatus* status); #endif // Koenig diff --git a/src/Spielstatus.c b/src/Spielstatus.c new file mode 100644 index 0000000..7ac6304 --- /dev/null +++ b/src/Spielstatus.c @@ -0,0 +1,13 @@ +#include "Spielstatus.h" +#include + +// Initalisiert den Spielstatus +void initalisiereSpielstatus(Spielstatus* status) { + if (status == NULL) return; + status->BewegteSichWeißerKoenig = false; + status->BewegteSichSchwarzerKoenig = false; + status->WeißerTurmKoenigSeiteBewegt = false; + status->WeißerTurmDameSeiteBewegt = false; + status->SchwarzerTurmKoenigSeiteBewegt = false; + status->SchwarzerTurmDameSeiteBewegt = false; +} diff --git a/src/Spielstatus.h b/src/Spielstatus.h new file mode 100644 index 0000000..51677d6 --- /dev/null +++ b/src/Spielstatus.h @@ -0,0 +1,18 @@ +#ifndef SPIELSTATUS_H +#define SPIELSTATUS_H + +#include + +typedef struct { + bool BewegteSichWeißerKoenig; + bool BewegteSichSchwarzerKoenig; + bool WeißerTurmKoenigSeiteBewegt; + bool WeißerTurmDameSeiteBewegt; + bool SchwarzerTurmKoenigSeiteBewegt; + bool SchwarzerTurmDameSeiteBewegt; +} Spielstatus; + +void initalisiereSpielstatus(Spielstatus* status); + + +#endif // SPIELSTATUS_H diff --git a/src/main.c b/src/main.c index acb5978..663713d 100644 --- a/src/main.c +++ b/src/main.c @@ -1,6 +1,6 @@ #include #include - +#include "Spielstatus.h" int main() { diff --git a/test/test_Koenig.c b/test/test_Koenig.c index 23bd7ad..b36ecdb 100644 --- a/test/test_Koenig.c +++ b/test/test_Koenig.c @@ -6,6 +6,7 @@ #include "Spieler.h" #include "Schachbrett.h" #include "Koenig.h" +#include "Spielstatus.h" void test_istzugerlaubt_Koenig_LegalMoves(void) { @@ -45,4 +46,53 @@ void test_istzugerlaubt_Koenig_IllegalMoves(void) { Schachbrettspeicher_freigeben(Brett); } +void test_Koenigbewegung_ValidMove(void) { + char** Brett = Schachbrett_erstellen(); + Spielstatus status; + initalisiereSpielstatus(&status); + Brett[4][4] = 'K'; + Player player = PLAYER_WHITE; + bewegeKoenig(Brett, 4, 4, 5, 4, player,&status); // Bewege König von e5 zu e6 + TEST_ASSERT_EQUAL('K', Brett[4][5]); // Schauen ob der König an der neuen stelle ist + TEST_ASSERT_EQUAL(' ', Brett[4][4]); // Schauen ob die alte stelle leer ist + TEST_ASSERT_TRUE(status.BewegteSichWeißerKoenig);//Schauen ob sich passend der spielstatus ändert + + Schachbrettspeicher_freigeben(Brett); +} + +void test_Koenigbewegung_InvalidMove(void) { + char** Brett = Schachbrett_erstellen(); + Spielstatus status; + initalisiereSpielstatus(&status); + Brett[4][4] = 'K'; + Player player = PLAYER_WHITE; + + bewegeKoenig(Brett, 4, 4, 6, 6, player,&status); // Versucht illegalen Zug zu machen + + TEST_ASSERT_EQUAL('K', Brett[4][4]); // Schauen ob der König an der alten stelle ist + TEST_ASSERT_EQUAL(' ', Brett[4][6]); // Schauen ob die Zielstelle leer ist + TEST_ASSERT_FALSE(status.BewegteSichWeißerKoenig);//Schauen ob sich der spielstatus passend verhält + Schachbrettspeicher_freigeben(Brett); +} +void test_Rochieren(void) { + char** testBrett = Schachbrett_erstellen(); + Spielstatus status = {0}; + Player player = PLAYER_WHITE; + testBrett[0][5] = ' '; + testBrett[0][6] = ' '; + + rochiere(testBrett, player, true, &status); // Assuming 'true' indicates kingside castling + + // Assertions to verify castling was performed correctly + TEST_ASSERT_EQUAL(' ', testBrett[0][4]); // King's original position is empty + TEST_ASSERT_EQUAL(' ', testBrett[0][7]); // Rook's original position is empty + TEST_ASSERT_EQUAL('K', testBrett[0][6]); // King is moved to the correct position + TEST_ASSERT_EQUAL('R', testBrett[0][5]); // Rook is moved next to the king + + TEST_ASSERT_TRUE(status.BewegteSichWeißerKoenig); + TEST_ASSERT_TRUE(status.WeißerTurmKoenigSeiteBewegt); + + // Clean up + Schachbrettspeicher_freigeben(testBrett); +} #endif // TEST diff --git a/test/test_Spielstatus.c b/test/test_Spielstatus.c new file mode 100644 index 0000000..5d47a97 --- /dev/null +++ b/test/test_Spielstatus.c @@ -0,0 +1,14 @@ +#ifdef TEST +#include "unity.h" +#include "Spielstatus.h" +void test_initalisiereSpielstatus(void) { + Spielstatus status; + initalisiereSpielstatus(&status); + TEST_ASSERT_FALSE(status.BewegteSichWeißerKoenig); + TEST_ASSERT_FALSE(status.BewegteSichSchwarzerKoenig); + TEST_ASSERT_FALSE(status.WeißerTurmKoenigSeiteBewegt); + TEST_ASSERT_FALSE(status.WeißerTurmDameSeiteBewegt); + TEST_ASSERT_FALSE(status.SchwarzerTurmKoenigSeiteBewegt); + TEST_ASSERT_FALSE(status.SchwarzerTurmDameSeiteBewegt); +} +#endif // TEST diff --git a/test/test_imSchachstehen.c b/test/test_imSchachstehen.c new file mode 100644 index 0000000..ec73e89 --- /dev/null +++ b/test/test_imSchachstehen.c @@ -0,0 +1,242 @@ +#ifdef TEST +#include "unity.h" +#include +#include +#include +#include "Spieler.h" +#include "Koenig.h" +#include "Schachbrett.h" + +char** ErstelleTestBrett() { + char** Brett = malloc(8 * sizeof(char*)); + for (int i = 0; i < 8; i++) { + Brett[i] = malloc(8 * sizeof(char)); + for (int j = 0; j < 8; j++) { + Brett[i][j] = ' '; //Erstelle komplett leeres Brett + } + } + return Brett; +} + +void freeTestBrett(char** Brett) { + for (int i = 0; i < 8; i++) { + free(Brett[i]); + } + free(Brett); +} +void test_SchachDurchBauer(void) { + char** Brett = ErstelleTestBrett(); + //Weißer König wird von schwarzen Bauer angegriffen + Brett[4][4] = 'K'; + Brett[5][5] = 'p'; + + TEST_ASSERT_TRUE(istKoenigImSchach(Brett, PLAYER_WHITE)); + + freeTestBrett(Brett); + Brett = ErstelleTestBrett(); + // Schwarzer König wird von weißen Bauer angegriffen + Brett[3][3] = 'k'; + Brett[2][2] = 'P'; + TEST_ASSERT_TRUE(istKoenigImSchach(Brett, PLAYER_BLACK)); + + freeTestBrett(Brett); + Brett = ErstelleTestBrett(); + // Schwarzer König wird von weißen Bauer angegriffen(andere seite) + Brett[3][3] = 'k'; + Brett[2][4] = 'P'; + TEST_ASSERT_TRUE(istKoenigImSchach(Brett, PLAYER_BLACK)); + + freeTestBrett(Brett); + Brett = ErstelleTestBrett(); + // Weißer König nicht in Gefahr + Brett[4][4] = 'K'; + Brett[3][4] = 'P'; + TEST_ASSERT_FALSE(istKoenigImSchach(Brett, PLAYER_WHITE)); + + freeTestBrett(Brett); + Brett = ErstelleTestBrett(); + // Schwarzer König nicht in Gefahr + Brett[3][3] = 'k'; + Brett[1][3] = 'P'; + TEST_ASSERT_FALSE(istKoenigImSchach(Brett, PLAYER_BLACK)); + + freeTestBrett(Brett); +} +void test_SchachDurchTurm(void) { + char** Brett = ErstelleTestBrett(); + + // Weißer König wird von schwarzen Turm bedroht (Horizontal) + Brett[4][4] = 'K'; + Brett[4][7] = 'r'; + TEST_ASSERT_TRUE(istKoenigImSchach(Brett, PLAYER_WHITE)); + + freeTestBrett(Brett); + Brett = ErstelleTestBrett(); + + // Weißer König wird von schwarzen Turm bedroht (Vertikal) + Brett[4][4] = 'K'; + Brett[0][4] = 'r'; + TEST_ASSERT_TRUE(istKoenigImSchach(Brett, PLAYER_WHITE)); + + freeTestBrett(Brett); + Brett = ErstelleTestBrett(); + + // Schwarzer König wird von weißen Turm bedroht (Horizontal) + Brett[3][3] = 'k'; + Brett[3][0] = 'R'; + TEST_ASSERT_TRUE(istKoenigImSchach(Brett, PLAYER_BLACK)); + + freeTestBrett(Brett); + Brett = ErstelleTestBrett(); + + // Schwarzer König wird nicht bedroht weil er von einer Figur beschützt wird + Brett[3][3] = 'k'; + Brett[3][1] = 'R'; + Brett[3][2] = 'p'; + TEST_ASSERT_FALSE(istKoenigImSchach(Brett, PLAYER_BLACK)); + + freeTestBrett(Brett); + Brett = ErstelleTestBrett(); + + // Weißer König nicht in gefahr + Brett[4][4] = 'K'; + Brett[5][5] = 'r'; + TEST_ASSERT_FALSE(istKoenigImSchach(Brett, PLAYER_WHITE)); + + freeTestBrett(Brett); +} +void test_SchachDurchSpringer(void) { + char** Brett = ErstelleTestBrett(); + + // Weißer König bedroht durch schwarzen Springer + Brett[4][4] = 'K'; + Brett[3][6] = 'n'; + TEST_ASSERT_TRUE(istKoenigImSchach(Brett, PLAYER_WHITE)); + + freeTestBrett(Brett); + Brett = ErstelleTestBrett(); + + // Schwarzer König bedroht durch weißen Springer + Brett[3][3] = 'k'; + Brett[5][4] = 'N'; + TEST_ASSERT_TRUE(istKoenigImSchach(Brett, PLAYER_BLACK)); + + freeTestBrett(Brett); + Brett = ErstelleTestBrett(); + + // Weißer könig nicht bedroht + Brett[4][4] = 'K'; + Brett[7][7] = 'n'; + TEST_ASSERT_FALSE(istKoenigImSchach(Brett, PLAYER_WHITE)); + + freeTestBrett(Brett); + Brett = ErstelleTestBrett(); + + // Schwarzer könig durch mehrere Springer bedroht + Brett[0][0] = 'k'; + Brett[1][2] = 'N'; + Brett[2][1] = 'N'; + TEST_ASSERT_TRUE(istKoenigImSchach(Brett, PLAYER_BLACK)); + + freeTestBrett(Brett); + Brett = ErstelleTestBrett(); + + // Schwarzer König wird trotz Mauer angegriffen + Brett[0][0] = 'k'; + Brett[0][1] = 'p'; + Brett[1][0] = 'p'; + Brett[1][1] = 'p'; + Brett[1][2] = 'N'; + TEST_ASSERT_TRUE(istKoenigImSchach(Brett, PLAYER_BLACK)); + + freeTestBrett(Brett); +} +void test_SchachDurchLaeufer(void) { + char** Brett = ErstelleTestBrett(); + + // Weißer König wird von schwarzen Läufer bedroht + Brett[4][4] = 'K'; + Brett[2][2] = 'b'; + TEST_ASSERT_TRUE(istKoenigImSchach(Brett, PLAYER_WHITE)); + + freeTestBrett(Brett); + Brett = ErstelleTestBrett(); + + // Schwarzer König wird von weißen Läufer bedroht + Brett[3][3] = 'k'; + Brett[6][0] = 'B'; + TEST_ASSERT_TRUE(istKoenigImSchach(Brett, PLAYER_BLACK)); + + freeTestBrett(Brett); + Brett = ErstelleTestBrett(); + + // Weißer König wird nicht bedroht + Brett[4][4] = 'K'; + Brett[6][7] = 'b'; + TEST_ASSERT_FALSE(istKoenigImSchach(Brett, PLAYER_WHITE)); + + freeTestBrett(Brett); + Brett = ErstelleTestBrett(); + + // Schwarzer König wird von mehreren Läufer bedroht + Brett[4][4] = 'k'; + Brett[6][6] = 'B'; + Brett[0][0] = 'B'; + TEST_ASSERT_TRUE(istKoenigImSchach(Brett, PLAYER_BLACK)); + + freeTestBrett(Brett); + Brett = ErstelleTestBrett(); + + // Schwarzer könig nicht in gefahr weil Läufer blockiert wird + Brett[0][0] = 'k'; + Brett[2][2] = 'P'; + Brett[4][4] = 'B'; + TEST_ASSERT_FALSE(istKoenigImSchach(Brett, PLAYER_BLACK)); + + freeTestBrett(Brett); +} +void test_SchachDurchDame(void) { + char** Brett = ErstelleTestBrett(); + + // Weißer könig wird von schwarzer Dame bedroht (Horizontal) + Brett[4][4] = 'K'; + Brett[4][7] = 'q'; + TEST_ASSERT_TRUE(istKoenigImSchach(Brett, PLAYER_WHITE)); + + freeTestBrett(Brett); + Brett = ErstelleTestBrett(); + + // Schwarzer könig wird von weißer Dame bedroht (Vertikal) + Brett[3][3] = 'k'; + Brett[0][3] = 'Q'; + TEST_ASSERT_TRUE(istKoenigImSchach(Brett, PLAYER_BLACK)); + + freeTestBrett(Brett); + Brett = ErstelleTestBrett(); + + // Weißer könig wird nicht von schwarzer Dame bedroht aufgrund blockierender Figur + Brett[4][4] = 'K'; + Brett[4][2] = 'p'; + Brett[4][0] = 'q'; + TEST_ASSERT_FALSE(istKoenigImSchach(Brett, PLAYER_WHITE)); + + freeTestBrett(Brett); + Brett = ErstelleTestBrett(); + + // Schwarzer könig wird von weißer Dame bedroht (Diagonal) + Brett[0][0] = 'k'; + Brett[7][7] = 'Q'; + TEST_ASSERT_TRUE(istKoenigImSchach(Brett, PLAYER_BLACK)); + + freeTestBrett(Brett); + Brett = ErstelleTestBrett(); + + // Schwarzer könig wird nicht von weißer Dame bedroht aufgrund blockierender Figur + Brett[7][7] = 'k'; + Brett[5][5] = 'P'; + Brett[3][3] = 'Q'; + TEST_ASSERT_FALSE(istKoenigImSchach(Brett, PLAYER_BLACK)); + + freeTestBrett(Brett); +} +#endif // TEST