#include <stdio.h>
#include <stdlib.h>
#include <SDL/SDL.h>
#define ROWS 3
#define COLS 3
#define EMPTY -1
#define PLAYER_A 0
#define PLAYER_B 1
// Spielfeld definieren
int board[ROWS][COLS];
// 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;
}
// Zeichnet das Spielfeld
void draw_board(SDL_Surface *back, SDL_Surface *circle, SDL_Surface *cross) {
SDL_BlitSurface(back, NULL, SDL_GetVideoSurface(), NULL);
SDL_Rect offset;
int row, col;
for (row=0; row<ROWS; row++) {
for (col=0; col<COLS; col++) {
offset.x = 25+100*col;
offset.y = 25+100*row;
if (board[row][col] == PLAYER_A) {
SDL_BlitSurface(circle, NULL, SDL_GetVideoSurface(), &offset);
} else if (board[row][col] == PLAYER_B) {
SDL_BlitSurface(cross, NULL, SDL_GetVideoSurface(), &offset);
}
}
}
SDL_Flip(SDL_GetVideoSurface());
}
// Gibt 1 zurück, falls der übergebene Spieler gewonnen hat, andernfalls 0
int check_win(int player) {
int row, col;
// horizontal
for (row=0; row<ROWS; row++) {
if ((board[row][0] == player) && (board[row][1] == player) && (board[row][2] == player))
return 1;
}
// vertikal
for (col=0; col<COLS; col++) {
if ((board[0][col] == player) && (board[1][col] == player) && (board[2][col] == player))
return 1;
}
// diagonal 1
if ((board[0][0] == player) && (board[1][1] == player) && (board[2][2] == player)) {
return 1;
}
// diagonal 2
if ((board[0][2] == player) && (board[1][1] == player) && (board[2][0] == player)) {
return 1;
}
return 0;
}
void reset_board() {
int row, col;
for (row=0; row<ROWS; row++) {
for (col=0; col < COLS; col++) {
board[row][col] = EMPTY;
}
}
}
int wait_for_click() {
SDL_Event event;
while (1) {
if (SDL_PollEvent(&event)) {
if (event.type == SDL_MOUSEBUTTONDOWN)
return 0;
else if (event.type == SDL_QUIT)
return 1;
}
SDL_Delay(10);
}
}
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);
// Hintergrundgrafik laden
SDL_Surface *background = SDL_LoadBMP("images/background.bmp");
if (background == NULL) {
printf("Fehler beim Laden von background.bmp: %s\n", SDL_GetError());
return 1;
}
// Kreisgrafik laden
SDL_Surface *circle = SDL_LoadBMP("images/circle.bmp");
if (circle == NULL) {
printf("Fehler beim Laden von circle.bmp: %s\n", SDL_GetError());
return 1;
}
// Kreuzgrafik laden
SDL_Surface *cross = SDL_LoadBMP("images/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(circle, SDL_SRCCOLORKEY, SDL_MapRGB(circle->format, 0x00,0xFF,0x00));
SDL_SetColorKey(cross, SDL_SRCCOLORKEY, SDL_MapRGB(cross->format, 0x00,0xFF,0x00));
// 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);
// Spielfeld initialisieren und zeichnen
reset_board();
draw_board(background, circle, cross);
SDL_Event event;
int row, col;
int quit = 0, turn = 0, player = PLAYER_A;
// Event-Loop
while (!quit) {
if (SDL_PollEvent(&event)) {
switch (event.type) {
case SDL_MOUSEBUTTONDOWN:
// Maus-Koordinaten in Spielfelfkoordinaten umrechnen
convert_coords(event.button.x, event.button.y, &row, &col);
// Ist die Zelle noch frei?
if (board[row][col] != EMPTY)
break;
// Zelle besetzen und zeichnen
board[row][col] = player;
draw_board(background, circle, cross);
turn++;
if (check_win(player) || (turn == ROWS*COLS)) {
if (check_win(player)) {
// aktueller Spieler hat gewonnen
if (player == PLAYER_A) {
SDL_WM_SetCaption("Spieler A hat gewonnen!", NULL);
} else {
SDL_WM_SetCaption("Spieler B hat gewonnen!", NULL);
}
} else {
// Unentschieden
SDL_WM_SetCaption("Unentschieden", NULL);
}
quit = wait_for_click();
// nächste runde vorbereiten
SDL_WM_SetCaption("Freitagsrunde presents: TicTacToe", NULL);
reset_board();
draw_board(background, circle, cross);
turn = 0;
}
player = 1 - player;
break;
case SDL_QUIT:
quit = 1;
break;
}
}
}
// Fenster schließen
SDL_FreeSurface(screen);
return 0;
}