Sitzung: Jeden Freitag in der Vorlesungszeit ab 16 Uhr c. t. im MAR 0.005. In der vorlesungsfreien Zeit unregelmäßig (Jemensch da?). Macht mit!

C-Kurs/Pong/Musterlösung

< C-Kurs‎ | Pong
Version vom 19. September 2009, 16:52 Uhr von Alexander Kührmann (Diskussion | Beiträge) (Die Seite wurde neu angelegt: „== Musterlösung == <pre> #include <curses.h> dimensions of the field: #define WIDTH 40 #define HEIGHT 15 #define PADDLE_HEIGHT 3 /* positions of playing t...“)
(Unterschied) ← Nächstältere Version | Aktuelle Version (Unterschied) | Nächstjüngere Version → (Unterschied)

Musterlösung

#include <curses.h>

/* dimensions of the field */
#define WIDTH 40
#define HEIGHT 15
#define PADDLE_HEIGHT 3

/* positions of playing things */
int pos_p1_y;
int pos_p2_y;
int pos_ball_x;
int pos_ball_y;
int dir_ball_x;
int dir_ball_y;

/* scores */
int score_p1 = 0;
int score_p2 = 0;

void init() {
	initscr(); // init for curses
	noecho();  // don't display typed chars
	cbreak();  // don't buffer terminal lines
	keypad(stdscr, TRUE);  // for special key (e.g. arrow keys)
	halfdelay(1); // wait only for 1/10 s in getch()
}

void place_paddles() {
	pos_p1_y = HEIGHT / 2 - PADDLE_HEIGHT / 2;
	pos_p2_y = HEIGHT / 2 - PADDLE_HEIGHT / 2;
}

void place_ball(int dir_x) {
	pos_ball_x = WIDTH / 2;
	pos_ball_y = HEIGHT / 2;
	dir_ball_x = dir_x;
	dir_ball_y = 1;
}

void print_field() {
	clear();
	int x,y;
	
	// print score
	printw("         %i                     %i\n", score_p1, score_p2);

	// print upper frame
	printw("+");
	for(x=0; x<WIDTH; x++) {
		printw("-");
	}
	printw("+\n");

	for (y=0; y<HEIGHT; y++) {
		// first column (x==0) is for player1's paddle
		if (y >= pos_p1_y && y < pos_p1_y+PADDLE_HEIGHT) {
			printw("|#");
		} else if (pos_ball_x == 0 && pos_ball_y == y) {
			printw("|*");
		} else {
			printw("| ");
		}

		// middle columns (0 < x < WIDTH-1) anywhere the ball can be
		for (x=1; x<WIDTH-1; x++) {
			if (y == pos_ball_y && x == pos_ball_x) {
				printw("*");
			} else {
				printw(" ");
			}
		}

		// last column (x==WIDTH-1) is for player2's paddle
		if (y >= pos_p2_y && y < pos_p2_y+PADDLE_HEIGHT) {
			printw("#|\n");
		} else if (pos_ball_x == WIDTH-1 && pos_ball_y == y) {
			printw("*|\n");
		} else {
			printw(" |\n");
		}
	}

	// print lower frame
	printw("+");
	for(x=0; x<WIDTH; x++) {
		printw("-");
	}
	printw("+\n");

	refresh();
}

void key_processing() {
	int ch = getch();
	if (ch == KEY_UP) {
		if (pos_p1_y > 0) {
			pos_p1_y--;
		}
	} else if (ch == KEY_DOWN) {
		if (pos_p1_y < HEIGHT-PADDLE_HEIGHT) {
			pos_p1_y++;
		}
	} else if (ch == 'w') {
		if (pos_p2_y > 0) {
			pos_p2_y--;
		}
	} else if (ch == 's') {
		if (pos_p2_y < HEIGHT-PADDLE_HEIGHT) {
			pos_p2_y++;
		}
	}
}

void detect_collision() {
	// ball collides with upper/lower bounds
	if (pos_ball_y <= 0 || pos_ball_y >= HEIGHT-1) {
		dir_ball_y *= -1;
	}

	// ball collides with player1's paddle
	if (pos_ball_x == 1 && pos_ball_y >= pos_p1_y && pos_ball_y < pos_p1_y + PADDLE_HEIGHT) {
		dir_ball_x *= -1;
	}

	// ball collides with player2's paddle
	if (pos_ball_x == WIDTH-2 && pos_ball_y >= pos_p2_y && pos_ball_y < pos_p2_y + PADDLE_HEIGHT) {
		dir_ball_x *= -1;
	}
}

void move_ball() {
	pos_ball_x += dir_ball_x;
	pos_ball_y += dir_ball_y;
}

int detect_ball_out() {
	// ball is out on left side -> point for player2
	if (pos_ball_x <= 0) {
		return 2;
	}

	// ball is out on right side -> point for player1	
	if (pos_ball_x >= WIDTH-1) {
		return 1;
	}

	return 0;
}

int play_round() {
	int ball_out;
	while( !(ball_out = detect_ball_out()) ) {
		key_processing();
		detect_collision();
		move_ball();
		print_field();
	}
	return ball_out;
}

int main() {
	init();
	place_paddles();
	place_ball(1);

	while(score_p1 < 10 && score_p2 < 10) {
		int round_won = play_round();
		if (round_won == 1) {
			score_p1++;
			place_ball(1);
		} else if (round_won == 2) {
			score_p2++;
			place_ball(-1);
		}
		sleep(1);
	}

	if (score_p1 < score_p2) {
		printw("Player 1 wins!\n");
	} else {
		printw("Player 2 wins!\n");
	}
	refresh();
	sleep(3);

	endwin();
}

Kommentare

Wenn du Anmerkungen zur Aufgabe hast oder Lob und Kritik loswerden möchtest, ist hier die richtige Stelle dafür. Klicke einfach ganz rechts auf "bearbeiten" und schreibe deinen Kommentar direkt ins Wiki. Keine Scheu, es geht nichts kaputt ;)