C-Kurs/TicTacToe/Musterlösung
< C-Kurs | TicTacToe
Version vom 16. September 2010, 09:18 Uhr von 89.247.231.122 (Diskussion) (Musterlösung zur TicTacToe aufgabe)
Nicht so schöne aber hoffentlich funktionierende Musterlösung
#include <stdio.h>
#include <SDL.h>
#define EMPTY 0
#define PLAYER_A 1
#define PLAYER_B 2
#define ROWS 3
#define COLS 3
int field[ROWS][COLS];
void reset_board(){
int i,j;
i=j=0;
for(i=0; i<ROWS; i++){
for(j=0;j<COLS; j++)
field[i][j] = EMPTY;
}
}
void draw_board(SDL_Surface *screen, SDL_Surface *background, SDL_Surface *circle, SDL_Surface *cross){
// Hintergrund ins Fenster zeichnen
SDL_BlitSurface(background, NULL, screen, NULL);
SDL_Flip(screen);
SDL_Rect offset;
offset.x = 25;
offset.y = 25;
int i,j;
i=j=0;
//iterate over the field
for(i=0; i<ROWS; i++){
for(j=0;j<COLS; j++){
switch(field[i][j]){
// empty nothing to do
case EMPTY:
break;
// player A draaw circle
case PLAYER_A:
SDL_BlitSurface(circle, NULL, screen, &offset);
SDL_Flip(screen);
break;
// player B draw cross
case PLAYER_B:
SDL_BlitSurface(cross, NULL, screen, &offset);
SDL_Flip(screen);
break;
}
//next rectangle we want to draw
offset.x += 100;
}
offset.y +=100;
//reset x to start at top
offset.x = 25;
}
}
// Konvertiert Mauskoordinaten in Spielfeldkoordinaten
void convert_coords(int x, int y, int *row, int *column) {
*row = (y-25) / 100;
if (*row < 0) *row = 0;
if (*row >= ROWS) *row = ROWS-1;
*column = (x-25) / 100;
if (*column < 0) *column = 0;
if (*column >= COLS) *column = COLS-1;
}
int check_win(int player){
int i,j;
i=j=0;
int row_zero = (field[0][0] == player) && (field[0][1] == player) && (field[0][2] == player);
int row_one = (field[1][0] == player) && (field[1][1] == player) && (field[1][2] == player);
int row_two = (field[2][0] == player) && (field[2][1] == player) && (field[2][2] == player);
int col_zero = (field[0][0] == player) && (field[1][0] == player) && (field[2][0] == player);
int col_one = (field[0][1] == player) && (field[1][1] == player) && (field[2][1] == player);
int col_two = (field[0][2] == player) && (field[1][2] == player) && (field[2][2] == player);
int diag_one = (field[0][0] == player) && (field[1][1] == player) && (field[2][2] == player);
int diag_two = (field[0][2] == player) && (field[1][1] == player) && (field[2][0] == player);
return row_zero || row_one || row_two || col_zero || col_one || col_two || diag_one || diag_two;
}
int check_full(){
int i,j;
for(i=0; i<ROWS; i++){
for(j=0;j<COLS; j++){
if(field[i][j] == EMPTY)
return 0;
}
}
return 1;
}
int main(int argc, char *argv[]) {
// Grafiksubsystem der SDL initialisieren
if (SDL_Init(SDL_INIT_VIDEO) < 0) {
printf("SDL konnte nicht initialisiert werden: %s\n", SDL_GetError());
return 1;
}
// SDL bei Programmende automatisch schließen lassen
atexit(SDL_Quit);
// Fenster für Grafikausgabe öffnen
SDL_Surface *screen = SDL_SetVideoMode(350, 350, 32, SDL_SWSURFACE);
if ( screen == NULL ) {
printf("Fehler beim Öffnen des Ausgabefensters: %s\n", SDL_GetError());
return 1;
}
SDL_WM_SetCaption("Freitagsrunde presents: TicTacToe", NULL);
// Hintergrundgrafik laden
SDL_Surface *background = SDL_LoadBMP("background.bmp");
if (background == NULL) {
printf("Fehler beim Laden von background.bmp: %s\n", SDL_GetError());
return 1;
}
// Hintergrund ins Fenster zeichnen
SDL_BlitSurface(background, NULL, screen, NULL);
SDL_Flip(screen);
// Kreisgrafik laden
SDL_Surface *circle = SDL_LoadBMP("circle.bmp");
if (circle == NULL) {
printf("Fehler beim Laden von circle.bmp: %s\n", SDL_GetError());
return 1;
}
// grünen Hintergrund transparent machen
SDL_SetColorKey(circle, SDL_SRCCOLORKEY, SDL_MapRGB(circle->format, 0x00,0xFF,0x00));
// Kreisgrafik laden
SDL_Surface *cross = SDL_LoadBMP("cross.bmp");
if (cross == NULL) {
printf("Fehler beim Laden von cross.bmp: %s\n", SDL_GetError());
return 1;
}
// grünen Hintergrund transparent machen
SDL_SetColorKey(cross, SDL_SRCCOLORKEY, SDL_MapRGB(circle->format, 0x00,0xFF,0x00));
int quit = 0;
SDL_Event event;
SDL_Rect offset;
int return_code=0;
int row, column;
row=column=0;
int current_player = 0;
int reset = 0;
int full = 0;
// Event-Loop
while (!quit) {
// Event vorhanden?
if (SDL_PollEvent(&event)) {
switch (event.type) {
// Mousebutton wurde gedrückt
case SDL_MOUSEBUTTONDOWN:
current_player = 1 - current_player;
convert_coords(event.button.x, event.button.y, &row, &column);
//it is player A's turn
if(current_player){
//check if player is allowed to set this field
if(field[row][column] != EMPTY){
//not allowed his turn again
current_player = 1-current_player;
break;
}
//was allowed set the field
field[row][column] = PLAYER_A;
if(check_win(PLAYER_A)){
//Set a Message
SDL_WM_SetCaption("Spieler 1 hat gewonnen", NULL);
reset = 1;
}
//it is player B's turn
} else {
//check if player is allowed to set this field
if(field[row][column] != EMPTY){
//not allowed his turn again
current_player = 1-current_player;
break;
}
//was allowed set the field
field[row][column] = PLAYER_B;
if(check_win(PLAYER_B)){
//Set a Message
SDL_WM_SetCaption("Spieler 2 hat gewonnen", NULL);
reset = 1;
}
}
full = check_full();
if(full){
// no empty fields and no winner
SDL_WM_SetCaption("Unentscheiden", NULL);
}
reset = reset || full;
//winner or field is full
if(reset){
reset_board();
// Hintergrund ins Fenster zeichnen
SDL_BlitSurface(background, NULL, screen, NULL);
SDL_Flip(screen);
reset = 0;
}
//draw the board
draw_board(screen, background, circle, cross);
break;
case SDL_QUIT:
quit = 1;
break;
}
}
}
// Fenster schließen
SDL_FreeSurface(screen);
return 0;
}