Browse Source

Merge branch 'fdai7492' into 'main'

Implementierung König bis auf Schachmatt

See merge request fdai7834/taktikmeister!3
remotes/origin/Läufer-fertig,-Hendrik-Voß
fdai7492 11 months ago
parent
commit
d08118309e
  1. 99
      src/Koenig.c
  2. 5
      src/Koenig.h
  3. 13
      src/Spielstatus.c
  4. 18
      src/Spielstatus.h
  5. 4
      src/main.c
  6. 50
      test/test_Koenig.c
  7. 14
      test/test_Spielstatus.c
  8. 242
      test/test_imSchachstehen.c

99
src/Koenig.c

@ -5,6 +5,7 @@
#include "spieler.h" #include "spieler.h"
#include "Moving.h" #include "Moving.h"
#include "Koenig.h" #include "Koenig.h"
#include "Spielstatus.h"
bool GreiftBauerAn(char** Brett, int x, int y, Player player) { bool GreiftBauerAn(char** Brett, int x, int y, Player player) {
// Checke für weißen Bauer // Checke für weißen Bauer
@ -208,7 +209,31 @@ bool istFeldUnsicher(char** Brett, int x, int y, Player player) {
return false; 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) { bool istzugerlaubt_Koenig(char** Brett, int startX, int startY, int endX, int endY, Player player) {
// Schauen ob der zug auf dem Spielbrett passiert // 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; 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;
}
}
}

5
src/Koenig.h

@ -1,6 +1,7 @@
#ifndef Koenig #ifndef Koenig
#define Koenig #define Koenig
#include "Spieler.h" #include "Spieler.h"
#include "Spielstatus.h"
bool GreiftBauerAn(char** Brett, int x, int y, Player player); bool GreiftBauerAn(char** Brett, int x, int y, Player player);
bool GreiftTurmAn(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); 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 GreiftDameAn(char** Brett, int x, int y, Player player);
bool GreiftKoenigAn(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 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); 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 #endif // Koenig

13
src/Spielstatus.c

@ -0,0 +1,13 @@
#include "Spielstatus.h"
#include <stdio.h>
// 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;
}

18
src/Spielstatus.h

@ -0,0 +1,18 @@
#ifndef SPIELSTATUS_H
#define SPIELSTATUS_H
#include <stdbool.h>
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

4
src/main.c

@ -1,8 +1,10 @@
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include "Spielstatus.h"
int main() { int main() {
Spielstatus status;
initalisiereSpielstatus(&status);
/* int x = 8; /* int x = 8;
int y = 8; int y = 8;
int spieler = 0; int spieler = 0;

50
test/test_Koenig.c

@ -6,6 +6,7 @@
#include "Spieler.h" #include "Spieler.h"
#include "Schachbrett.h" #include "Schachbrett.h"
#include "Koenig.h" #include "Koenig.h"
#include "Spielstatus.h"
void test_istzugerlaubt_Koenig_LegalMoves(void) { void test_istzugerlaubt_Koenig_LegalMoves(void) {
@ -45,4 +46,53 @@ void test_istzugerlaubt_Koenig_IllegalMoves(void) {
Schachbrettspeicher_freigeben(Brett); 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 #endif // TEST

14
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

242
test/test_imSchachstehen.c

@ -0,0 +1,242 @@
#ifdef TEST
#include "unity.h"
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#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
Loading…
Cancel
Save