| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392 |
- /*
- TicTacToeDe.ino
-
- */
- #include <Arduino.h>
- #include <U8g2lib.h>
- /*==============================================*/
- /* Konstante Werte */
- #define GITTER_X_OFFSET 35
- #define GITTER_Y_OFFSET 2
- #define ZELLE_BREITE 17
- #define ZELLE_HOEHE 17
- #define ZELLE_RAHMENBREITE 3
- #define FELD_NICHT_BELEGT 0
- #define FELD_MARKIERT_DURCH_SPIELER 1
- #define FELD_MARKIERT_DURCH_COMPUTER 2
- /*==============================================*/
- /* Variablen */
- /* U8g2 Graphics API, setup for ARDUBOY Production, Kickstarter Edition */
- U8G2_SSD1306_128X64_NONAME_1_4W_HW_SPI u8g2(U8G2_R0, /* cs=*/ 12, /* dc=*/ 4, /* reset=*/ 6);
- uint8_t cursor_position; /* Aktuelle Cursorposition die vom User ausgewählt wurde */
- u8g2_uint_t zelle_x, zelle_y; /* Berechnete Position einer Zelle (berechne_zell_position) */
- int spielfeld[3][3]; /* Enthält die aktuelle Belegung mit x und o */
- int gewinner; /* Zeigt den gewinner an (wenn es einen gibt) */
- /*==============================================*/
- /* vorbelegung und spiel initalisierenalisierung */
- void spiel_initalisieren(void)
- {
- int x, y;
-
- gewinner = FELD_NICHT_BELEGT;
- for( y = 0; y < 3; y = y + 1 )
- {
- for( x = 0; x < 3; x = x + 1 )
- {
- spielfeld[y][x] = FELD_NICHT_BELEGT;
- }
- }
- }
- /*==============================================*/
- /* Hilfsroutine */
- /* berechne die Zell-Position, Ergebnis in zelle_x und zelle_y */
- void berechne_zell_position(uint8_t x, uint8_t y )
- {
- zelle_x = x;
- zelle_x*=ZELLE_BREITE+ZELLE_RAHMENBREITE;
- zelle_x+= GITTER_X_OFFSET;
- zelle_y = y;
- zelle_y *=ZELLE_HOEHE+ZELLE_RAHMENBREITE;
- zelle_y +=GITTER_Y_OFFSET;
- }
- /*==============================================*/
- /* "game engine" */
- void zeichne_gitter(void)
- {
- u8g2_uint_t x, y;
- x = GITTER_X_OFFSET+ZELLE_BREITE;
- u8g2.drawVLine(x+1, GITTER_Y_OFFSET, ZELLE_HOEHE*3+ZELLE_RAHMENBREITE*2);
- x += ZELLE_BREITE+ZELLE_RAHMENBREITE;
- u8g2.drawVLine(x+1, GITTER_Y_OFFSET, ZELLE_HOEHE*3+ZELLE_RAHMENBREITE*2);
- y = GITTER_Y_OFFSET+ZELLE_HOEHE;
- u8g2.drawHLine(GITTER_X_OFFSET, y+1, ZELLE_BREITE*3+ZELLE_RAHMENBREITE*2);
- y += ZELLE_HOEHE+ZELLE_RAHMENBREITE;
- u8g2.drawHLine(GITTER_X_OFFSET, y+1, ZELLE_BREITE*3+ZELLE_RAHMENBREITE*2);
- }
- void zeichne_spielfeld(void)
- {
- int x, y;
- for( y = 0; y < 3; y = y + 1 )
- {
- for( x = 0; x < 3; x = x + 1 )
- {
- if ( spielfeld[y][x] == FELD_NICHT_BELEGT )
- {
- /* nichts anzeigen */
- }
- if ( spielfeld[y][x] == FELD_MARKIERT_DURCH_SPIELER )
- {
- berechne_zell_position(x, y);
- u8g2.drawLine(zelle_x, zelle_y, zelle_x+ZELLE_BREITE-1, zelle_y+ZELLE_HOEHE-1);
- u8g2.drawLine(zelle_x+ZELLE_BREITE-1, zelle_y, zelle_x, zelle_y+ZELLE_HOEHE-1);
- }
- if ( spielfeld[y][x] == FELD_MARKIERT_DURCH_COMPUTER )
- {
- berechne_zell_position(x, y);
- u8g2.drawCircle(zelle_x+ZELLE_BREITE/2, zelle_y+ZELLE_HOEHE/2, ZELLE_HOEHE/2);
- }
- } /* for x */
- } /* for y */
- }
- void zeichne_gitter_und_spielfeld(void)
- {
- zeichne_gitter();
- zeichne_spielfeld();
- }
- void zeige_spielfeld_an(void)
- {
- u8g2.firstPage();
- do
- {
- yield(); // Arduino
- zeichne_gitter_und_spielfeld();
- } while ( u8g2.nextPage() );
- }
- /*==============================================*/
- /* Benitzerschnittstelle (User Interface) */
- /* Zeichne den Cursor für die Benutzereingabe */
- void zeichne_cursor(void)
- {
- u8g2_uint_t x, y;
- x = cursor_position % 3;
- y = cursor_position / 3;
- berechne_zell_position(x, y );
- u8g2.drawFrame(zelle_x, zelle_y, ZELLE_BREITE, ZELLE_HOEHE);
- u8g2.drawFrame(zelle_x+1, zelle_y+1, ZELLE_BREITE-2, ZELLE_HOEHE-2);
- }
- void zug_spieler(void)
- {
- static uint8_t keycode = 0;
- int x;
- int y;
- int zaehler = 0;
-
- for(;;) /* check valid entry */
- {
- for(;;) /* cursor movement loop */
- {
- keycode = 0;
- u8g2.firstPage();
- do
- {
- zeichne_gitter_und_spielfeld();
- zeichne_cursor();
- if ( keycode == 0 )
- keycode = u8g2.getMenuEvent();
- } while ( u8g2.nextPage() );
- while ( keycode == 0 )
- {
- yield(); // Arduino
- keycode = u8g2.getMenuEvent();
- }
- if ( keycode == U8X8_MSG_GPIO_MENU_DOWN )
- {
- cursor_position += 3;
- if ( cursor_position > 9 )
- cursor_position -= 9;
- }
- if ( keycode == U8X8_MSG_GPIO_MENU_NEXT )
- {
- if ( cursor_position % 3 == 2 )
- cursor_position-=2;
- else
- cursor_position += 1;
- }
- if ( keycode == U8X8_MSG_GPIO_MENU_UP )
- {
- cursor_position -= 3;
- if ( cursor_position > 9 )
- cursor_position += 9;
- }
- if ( keycode == U8X8_MSG_GPIO_MENU_PREV )
- {
- if ( cursor_position % 3 == 0 )
- cursor_position+=2;
- else
- cursor_position -= 1;
- }
- cursor_position = cursor_position % 9;
- if ( keycode == U8X8_MSG_GPIO_MENU_SELECT )
- break;
- if ( keycode == U8X8_MSG_GPIO_MENU_HOME )
- break;
- }
- y = cursor_position / 3;
- x = cursor_position % 3;
-
- if ( spielfeld[y][x] == FELD_NICHT_BELEGT )
- {
- spielfeld[y][x] = FELD_MARKIERT_DURCH_SPIELER ;
- return;
- }
- /*
- if ( zaehler > 3 )
- {
- printf("Du doedl, jetzt langts aber...\n");
- exit(1);
- }
- printf("Ahh, das feld ist schon belegt, nochmal...\n");
- zaehler = zaehler + 1;
- */
- }
- }
- /*==============================================*/
- /* Künstliche Computer Intelligenz */
- void zug_computer(void)
- {
- int x, y;
-
- /* Sehr dumme AI: Nimm den nächsten freien Platz */
-
- for( y = 0; y < 3; y = y + 1 )
- {
- for( x = 0; x < 3; x = x + 1 )
- {
- if ( spielfeld[y][x] == FELD_NICHT_BELEGT )
- {
- spielfeld[y][x] = FELD_MARKIERT_DURCH_COMPUTER;
- return;
- }
- }
- }
- }
- /*==============================================*/
- /* Spiel Zuende Prüfung */
- /* gibt 1 zurück, wenn in der zeile überall markierung gesetzt ist */
- int zeile_gewonnen(int y, int markierung)
- {
- int x;
- for( x = 0; x < 3; x++ )
- {
- if ( spielfeld[y][x] != markierung )
- return 0;
- }
- return 1;
- }
- /* gibt 1 zurück, wenn in der zeile überall markierung gesetzt ist */
- int spalte_gewonnen(int x, int markierung)
- {
- int y;
- for( y = 0; y < 3; y++ )
- {
- if ( spielfeld[y][x] != markierung )
- return 0;
- }
- return 1;
- }
- int diagonale_gewonnen(int markierung)
- {
- int i;
-
- for( i = 0; i < 3; i ++ )
- {
- if ( spielfeld[i][i] != markierung )
- return 0;
- }
- return 1;
- }
- int inverse_diagonale_gewonnen(int markierung)
- {
- int i;
-
- for( i = 0; i < 3; i ++ )
- {
- if ( spielfeld[2-i][i] != markierung )
- return 0;
- }
- return 1;
- }
- int ist_das_spiel_zuende(void)
- {
- int i, x, y;
- int ist_alles_voll;
-
- zeige_spielfeld_an();
- for( i = 0; i < 3; i ++ )
- {
- if ( zeile_gewonnen(i, FELD_MARKIERT_DURCH_SPIELER) )
- gewinner = FELD_MARKIERT_DURCH_SPIELER;
- if ( zeile_gewonnen(i, FELD_MARKIERT_DURCH_COMPUTER) )
- gewinner = FELD_MARKIERT_DURCH_COMPUTER;
- if ( spalte_gewonnen(i, FELD_MARKIERT_DURCH_SPIELER) )
- gewinner = FELD_MARKIERT_DURCH_SPIELER;
- if ( spalte_gewonnen(i, FELD_MARKIERT_DURCH_COMPUTER) )
- gewinner = FELD_MARKIERT_DURCH_COMPUTER;
- }
- if ( diagonale_gewonnen(FELD_MARKIERT_DURCH_SPIELER) )
- gewinner = FELD_MARKIERT_DURCH_SPIELER;
- if ( diagonale_gewonnen(FELD_MARKIERT_DURCH_COMPUTER) )
- gewinner = FELD_MARKIERT_DURCH_COMPUTER;
- if ( inverse_diagonale_gewonnen(FELD_MARKIERT_DURCH_SPIELER) )
- gewinner = FELD_MARKIERT_DURCH_SPIELER;
- if ( inverse_diagonale_gewonnen(FELD_MARKIERT_DURCH_COMPUTER) )
- gewinner = FELD_MARKIERT_DURCH_COMPUTER;
-
- if ( gewinner != FELD_NICHT_BELEGT )
- return 1;
- ist_alles_voll = 1;
- for( y = 0; y < 3; y = y + 1 )
- {
- for( x = 0; x < 3; x = x + 1 )
- {
- if ( spielfeld[y][x] == FELD_NICHT_BELEGT )
- {
- ist_alles_voll = 0;
- }
- }
- }
- if ( ist_alles_voll )
- return 1;
-
- return 0;
- }
- /*==============================================*/
- void zeige_ergebnis_an(void)
- {
- u8g2.setFont(u8g2_font_helvB12_tr);
- if ( gewinner == FELD_MARKIERT_DURCH_SPIELER )
- u8g2.userInterfaceMessage("Spieler", "gewinnt", "", " ok ");
- else if ( gewinner == FELD_MARKIERT_DURCH_COMPUTER )
- u8g2.userInterfaceMessage("Computer", "gewinnt", "", " ok ");
- else
- u8g2.userInterfaceMessage("", "Unentschieden", "", " ok ");
- }
- /*==============================================*/
- void setup(void) // Arduino setup
- {
- // Intialisierung für Arduboy (Production)
- u8g2.begin(/*Select=*/ 7, /*Right/Next=*/ A1, /*Left/Prev=*/ A2, /*Up=*/ A0, /*Down=*/ A3, /*Home/Cancel=*/ 8);
- }
- void loop(void) // Arduino loop
- {
- spiel_initalisieren();
- zeige_spielfeld_an();
- for(;;)
- {
- zug_spieler();
- zeige_spielfeld_an();
- if ( ist_das_spiel_zuende() )
- {
- break;
- } /* if */
- delay(300);
- zug_computer();
- zeige_spielfeld_an();
- if ( ist_das_spiel_zuende() )
- {
- break;
- } /* if */
-
- } /* for */
- zeige_ergebnis_an();
- }
|