diff --git a/src/main/c/Pong/game.c b/src/main/c/Pong/game.c deleted file mode 100644 index 8b13789..0000000 --- a/src/main/c/Pong/game.c +++ /dev/null @@ -1 +0,0 @@ - diff --git a/src/main/c/Pong/pong.c b/src/main/c/Pong/pong.c new file mode 100644 index 0000000..d962a4c --- /dev/null +++ b/src/main/c/Pong/pong.c @@ -0,0 +1,231 @@ +#include +#include +#include +#include +#include +#include + +#define WIDTH 40 //Breite Spielfeld +#define HEIGHT 20 //Höhe Spielfeld +#define PADDLE_LENGTH 4 +#define PADDLE "\033[1;31m#\033[0m" +#define BALL "\033[1;31mO\033[0m" + +//Ballstruktur +typedef struct { + int x; + int y; + int speedX; + int speedY; +} Ball; + +// Bildschirm löschen nach Veränderung Position +void clearScreen() { + system("clear"); +} + +void drawField(int paddle1PositionY, int paddle2PositionY, Ball ball, int score1, int score2, int isPaused) { + clearScreen(); + + for (int i = 0; i <= HEIGHT; i++){ + for (int j = 0; j <= WIDTH; j++){ + if (i == 0 || i == HEIGHT){ + printf("-"); + } else if ((j == 0 || j == WIDTH) && (i < paddle1PositionY || i >= paddle1PositionY + PADDLE_LENGTH) && (i < paddle2PositionY || i >= paddle2PositionY + PADDLE_LENGTH)) { + printf("|"); + } else if (i >= paddle1PositionY && i < paddle1PositionY + PADDLE_LENGTH && j == WIDTH) { + printf("%c", PADDLE); + } else if (i >= paddle2PositionY && i < paddle2PositionY + PADDLE_LENGTH && j == 0) { + printf("%c", PADDLE); + } else if (i == ball.y && j == ball.x) { + printf("%c", BALL); + } else { + printf(" "); + } + } + printf("\n"); + } + + printf("Spieler 1: %d\tSpieler 2: %d\n", score1, score2); + if (isPaused) { + printf("Spiel pausiert. Drücken Sie 'p', um fortzufahren.\n"); + } else { + printf("Drücken Sie 'p', um das Spiel zu pausieren.\n"); + } + printf("Drücken Sie 'q', um das Spiel zu beenden.\n"); +} + +int kbhit(void){ + struct termios oldt, newt; + int ch, oldf; + + tcgetattr(STDIN_FILENO, &oldt); + newt = oldt; + newt.c_lflag &= ~(ICANON | ECHO); + tcsetattr(STDIN_FILENO, TCSANOW, &newt); + oldf = fcntl(STDIN_FILENO, F_GETFL, 0); + fcntl(STDIN_FILENO, F_SETFL, oldf | O_NONBLOCK); + + ch = getchar(); + + tcsetattr(STDIN_FILENO, TCSANOW, &oldt); + fcntl(STDIN_FILENO, F_SETFL, oldf); + + if (ch != EOF) { + ungetc(ch, stdin); + return 1; + } +return 0; +} + +int getch(void) { + int ch; + + while ((ch = getchar()) == '\n'); + + return ch; +} + +//Aktualisierung Ballposition +void updateBallPosition(Ball *ball) { + ball->x += ball->speedX; + ball->y += ball->speedY; +} + +//Verbesserung Kollision mit Schlägern&Wänden +int checkCollision(Ball ball, int paddle1PositionY, int paddle2PositionY) { + // Kollision mit Schlägern und Wänden + if (ball.y <= 0 || ball.y >= HEIGHT - 1){ + ball.speedY = -ball.speedY; + } + if (ball.x == 1 && (ball.y >= paddle2PositionY && ball.y < paddle2PositionY + PADDLE_LENGTH)){ + ball.speedX = -ball.speedX; + } + + if (ball.x == WIDTH - 1 && (ball.y >= paddle1PositionY && ball.y < paddle1PositionY + PADDLE_LENGTH)){ + ball.speedX = -ball.speedX; + } + + //Punkte zählen + if (ball.x <= 0){ + return 1; // Spieler 2 gewinnt Punkt + } + + if (ball.x >= WIDTH - 1){ + return 2; // Spieler 1 gewinnt Punkt + } + + return 0; // kein Punkt +} + +//Reset +void resetScore(int *score1, int *score2) { + *score1 = 0; + *score2 = 0; +} + +int checkGameEnd(int score1, int score2, int maxScore) { + if (score1 >= maxScore || score2 >= maxScore) { + return 1; // Das Spiel endet + } else { + return 0; // Das Spiel endet nicht + } +} + +void processPlayerInput(int *paddlePositionY, int userInput) { + if (userInput == -1) { + // Bewegt den Schläger nach oben, solange der obere Rand nicht erreicht ist + if (*paddlePositionY > 0) { + *paddlePositionY -=1; + } + } else if (userInput == 1) { + // Bewegt den Schläger nach unten, solange der untere Rand nicht erreicht ist + if (*paddlePositionY < HEIGHT - PADDLE_LENGTH) { + *paddlePositionY += 1; + } + } +} + +int pong(){ + int paddle1PositionY = HEIGHT / 2 - PADDLE_LENGTH / 2; + int paddle2PositionY = HEIGHT / 2 - PADDLE_LENGTH / 2; + Ball ball = {WIDTH / 2, HEIGHT / 2, 1, 1}; //Startposition&Geschwindigkeit Ball + int score1 = 0; + int score2 = 0; + int maxScore = 5; + int isPaused = 0; + + while (score1 < maxScore && score2 < maxScore) { + //Steuerung für Schläger 1 + if (!isPaused && kbhit()){ + char input = getch(); + if (input == 'w' && paddle1PositionY > 1) + { + paddle1PositionY--; + } else if (input == 's' && paddle1PositionY < HEIGHT - PADDLE_LENGTH - 1) { + paddle1PositionY++; + } else if (input == 'p') { + isPaused = !isPaused; + } else if (input == 'q') { + clearScreen(); + printf("Spiel beendet.\n"); + return 0; + } + } + +//Steuerung für Schläger 2 + if (!isPaused && kbhit()){ + char input = getch(); + if (input == 'i' && paddle2PositionY > 1){ + paddle2PositionY--; + } else if (input == 'k' && paddle2PositionY < HEIGHT - PADDLE_LENGTH - 1){ + paddle2PositionY++; + } else if (input == 'p') { + isPaused = !isPaused; + } else if (input == 'q') { + clearScreen(); + printf("Spiel beendet.\n"); + return 0; + } + } + + //Wenn Pauseiert + if (isPaused) { + drawField(paddle1PositionY, paddle2PositionY, ball, score1, score2, 1); + continue; + } + + //Bewegung Ball + updateBallPosition(&ball); + int result = checkCollision(ball, paddle1PositionY, paddle2PositionY); + + //Aktualisiert Spielstand und Ballposition + if (result == 1) { + score2++; + ball.x = WIDTH / 2; + ball.y = HEIGHT / 2; + ball.speedX = -ball.speedX; + } else if (result == 2) { + score1++; + ball.x = WIDTH / 2; + ball.y = HEIGHT / 2; + ball.speedX = -ball.speedX; + } + + resetScore(&score1, &score2); //Zurücksetzen Spielstand + + drawField(paddle1PositionY, paddle2PositionY, ball, score1, score2, 0); + usleep(100000); //Verlangsamen Schleife/Spiel + } + + clearScreen(); + if (score1 == maxScore) { + printf("Spieler 1 gewinnt!\n"); + } else { + printf("Spieler 2 gewinnt!\n"); + } + + return 0; +} + + diff --git a/src/main/c/Pong/pong.h b/src/main/c/Pong/pong.h new file mode 100644 index 0000000..4e6cfdd --- /dev/null +++ b/src/main/c/Pong/pong.h @@ -0,0 +1,9 @@ +#ifndef PONG_H +#define PONG_H + +int pong(); + +void resetScore(int *score1, int *score2); + +#endif + diff --git a/src/main/c/main.c b/src/main/c/main.c index 11be6b7..c858693 100644 --- a/src/main/c/main.c +++ b/src/main/c/main.c @@ -4,6 +4,7 @@ #include "Snake/snake_start.h" #include "Minesweeper/minesweeper_start.h" +#include "Pong/pong.h" int main(){ bool running = true; @@ -15,7 +16,7 @@ int main(){ system("clear"); printf("Waehlen Sie eine Option:\n"); printf("\t1.Spiel1 starten\n"); - printf("\t2.Spiel2 starten\n"); + printf("\t2.Pong starten\n"); printf("\t3.Snake starten\n"); printf("\t4.Spiel4 starten\n"); printf("\t7.Minesweeper starten\n"); @@ -29,7 +30,7 @@ int main(){ //start_game1(); break; case 2: - //start_game2(); + pong(); break; case 3: snake_start(); @@ -50,4 +51,4 @@ int main(){ } } return 0; -} \ No newline at end of file +} diff --git a/src/main/c/main.h b/src/main/c/main.h index 71870e0..013f02f 100644 --- a/src/main/c/main.h +++ b/src/main/c/main.h @@ -3,4 +3,4 @@ int main(); -#endif // MAIN_H \ No newline at end of file +#endif // MAIN_H diff --git a/test/Pong/.gitkeep b/test/Pong/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/test/Pong/test_checkCollision.c b/test/Pong/test_checkCollision.c new file mode 100644 index 0000000..16be1ca --- /dev/null +++ b/test/Pong/test_checkCollision.c @@ -0,0 +1,63 @@ +#ifdef TEST +#include "unity.h" +#include "pong.h" +#define WIDTH 40 //Breite Spielfeld +#define HEIGHT 20 //Höhe Spielfeld + +typedef struct { + int x; + int y; + int speedX; + int speedY; +} Ball; + +typedef struct { + int x; + int y; + int width; + int height; +} Paddle; + +void setUp(void){ + //Wenn Funktion Vorraussetzungen braucht +} + +void tearDown(void){ +} + +void test_checkCollision(void){ + Ball ball = {10, 10, 1, 1}; + Paddle paddle = {50, 10, 5, 10}; + + // Test Ball trifft rechte und linke Wand + ball.x = 0; + int result1 = checkCollision(ball, paddle.y, paddle.y); + TEST_ASSERT_EQUAL_INT(1, result1); + + ball.x = WIDTH - 1; + int result2 = checkCollision(ball, paddle.y, paddle.y); + TEST_ASSERT_EQUAL_INT(2, result2); + + // Test Ball trifft obere und untere Wand + ball.x = 5; + ball.y = 0; + int result3 = checkCollision(ball, paddle.y, paddle.y); + TEST_ASSERT_EQUAL_INT(0, result3); + + ball.y = HEIGHT - 1; + int result4 = checkCollision(ball, paddle.y, paddle.y); + TEST_ASSERT_EQUAL_INT(0, result4); + + // Test wenn Ball Paddle trifft + ball.x = paddle.x - 1; + ball.y = paddle.y + 1; + int result5 = checkCollision(ball, paddle.y, paddle.y); + TEST_ASSERT_EQUAL_INT(2, result5); + + ball.x = paddle.x + 1; + ball.y = paddle.y + 1; + int result6 = checkCollision(ball, paddle.y, paddle.y); + TEST_ASSERT_EQUAL_INT(2, result6); +} + +#endif // TEST diff --git a/test/Pong/test_checkGameEnd.c b/test/Pong/test_checkGameEnd.c new file mode 100644 index 0000000..4f9144d --- /dev/null +++ b/test/Pong/test_checkGameEnd.c @@ -0,0 +1,34 @@ +#ifdef TEST +#include "unity.h" +#include "pong.h" + +// Prüfen Spiellogik für Beenden des Spiels + +void setUp(void){ + //Wenn Funktion Vorraussetzungen braucht +} + +void tearDown(void){ +} + +void test_checkGameEnd(void){ + /* arrange */ + int maxScore = 5; + int score1 = 4, score2 = 2; + + /* act */ + int result = checkGameEnd(score1, score2, maxScore); + + /* assert */ + TEST_ASSERT_EQUAL_INT(0, result); // Das Spiel sollte noch nicht enden + + /* Spieler 1 erreicht den Maximalscore */ + score1 = 5; + result = checkGameEnd(score1, score2, maxScore); + TEST_ASSERT_EQUAL_INT(1, result); // Das Spiel sollte enden, da Spieler 1 den Maximalscore erreicht hat + + /* Weitere Tests mit anderen Spiellogikfällen und Endspielbedingungen können hinzugefügt werden */ + +} + +#endif // TEST diff --git a/test/Pong/test_clearScreen.c b/test/Pong/test_clearScreen.c new file mode 100644 index 0000000..f2701a1 --- /dev/null +++ b/test/Pong/test_clearScreen.c @@ -0,0 +1,38 @@ +#ifdef TEST +#include "unity.h" +#include "pong.h" + +#define TEST_SCREEN_WIDTH 40 +#define TEST_SCREEN_HEIGHT 20 + +char screen[TEST_SCREEN_HEIGHT][TEST_SCREEN_WIDTH+1]; + +void setUp(void){ + //Wenn Funktion Vorraussetzungen braucht +} + +void tearDown(void){ +} + +void test_clearScreen(void){ + /* arrange */ + int i, j; + for (i = 0; i < TEST_SCREEN_HEIGHT; i++) { + for (j = 0; j < TEST_SCREEN_WIDTH; j++) { + screen[i][j] = ' '; + } + screen[i][j] = '\0'; + } + + /* act */ + clearScreen(); + + /* assert */ + for (i = 0; i < TEST_SCREEN_HEIGHT; i++) { + for (j = 0; j < TEST_SCREEN_WIDTH; j++) { + TEST_ASSERT_EQUAL_INT(' ', screen[i][j]); + } + } +} + +#endif // TEST diff --git a/test/Pong/test_playerInputMovement.c b/test/Pong/test_playerInputMovement.c new file mode 100644 index 0000000..e8ebbdd --- /dev/null +++ b/test/Pong/test_playerInputMovement.c @@ -0,0 +1,42 @@ +#ifdef TEST +#include "unity.h" +#include "pong.h" + +typedef struct { + int x; + int y; + int speedX; + int speedY; +} Paddle; +// sicherstellen korrekte Funktion Steuerung für Schläger + +void setUp(void){ + //Wenn Funktion Vorraussetzungen braucht +} + +void tearDown(void){ +} + +void test_playerInputMovement(void){ + /* Test 1: Bewegung nach oben */ + int paddlePositionY = 10; + int userInput = -1; // Benutzereingabe für Bewegung nach oben + int expectedY = paddlePositionY - 1; + + processPlayerInput(&paddlePositionY, userInput); + TEST_ASSERT_EQUAL_INT(expectedY, paddlePositionY); + + /* Test 2: Bewegung nach unten */ + userInput = 1; + expectedY = paddlePositionY + 1; + // Benutzereingabe für Bewegung nach unten + + processPlayerInput(&paddlePositionY, userInput); + TEST_ASSERT_EQUAL_INT(expectedY, paddlePositionY); + + /* Weitere Tests mit anderen Bewegungsrichtungen und Grenzfällen können hinzugefügt werden */ + +} + + +#endif // TEST diff --git a/test/Pong/test_pong.c b/test/Pong/test_pong.c new file mode 100644 index 0000000..0b12481 --- /dev/null +++ b/test/Pong/test_pong.c @@ -0,0 +1,27 @@ +#ifdef TEST +#include "unity.h" +#include "pong.h" + + +void setUp(void){ + //Wenn Funktion Vorraussetzungen braucht +} +void tearDown(void){ +} + + +void test_input_all_5(void){ + /* arrange */ + int a = 4, b = 5; + + /* act */ + resetScore( &a, &b ); + + /* assert */ + TEST_ASSERT_EQUAL_INT(0, a); + TEST_ASSERT_EQUAL_INT(0, b); +} + + + +#endif // TEST diff --git a/test/test_template.c b/test/test_template.c index a1b9ed4..4aba361 100644 --- a/test/test_template.c +++ b/test/test_template.c @@ -33,4 +33,4 @@ void test_ignore_rest_from_division(void){ TEST_ASSERT_EQUAL_INT(5, result);//5 / 6 + 5 = 5 } -#endif // TEST \ No newline at end of file +#endif // TEST