Browse Source
Merge branch 'branchJulia' into 'main'
Merge branch 'branchJulia' into 'main'
merge 'branchJulia' into 'main' See merge request pmuw_projekt/pmuw_projekt_notebinder!31remotes/origin/fdai7775-main-patch-54732
fdai8032
11 months ago
12 changed files with 450 additions and 6 deletions
-
1src/main/c/Pong/game.c
-
231src/main/c/Pong/pong.c
-
9src/main/c/Pong/pong.h
-
7src/main/c/main.c
-
2src/main/c/main.h
-
0test/Pong/.gitkeep
-
63test/Pong/test_checkCollision.c
-
34test/Pong/test_checkGameEnd.c
-
38test/Pong/test_clearScreen.c
-
42test/Pong/test_playerInputMovement.c
-
27test/Pong/test_pong.c
-
2test/test_template.c
@ -1 +0,0 @@ |
|||
|
@ -0,0 +1,231 @@ |
|||
#include <stdio.h> |
|||
#include <termios.h> |
|||
#include <stdlib.h> |
|||
#include <unistd.h> |
|||
#include <fcntl.h> |
|||
#include <stdbool.h> |
|||
|
|||
#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; |
|||
} |
|||
|
|||
|
@ -0,0 +1,9 @@ |
|||
#ifndef PONG_H |
|||
#define PONG_H |
|||
|
|||
int pong(); |
|||
|
|||
void resetScore(int *score1, int *score2); |
|||
|
|||
#endif |
|||
|
@ -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 |
@ -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 |
@ -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 |
@ -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 |
@ -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 |
Write
Preview
Loading…
Cancel
Save
Reference in new issue