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/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)
(Unterschied) ← Nächstältere Version | Aktuelle Version (Unterschied) | Nächstjüngere Version → (Unterschied)

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;
}