Sonntag, 24. April 2011

TicTacToe Game

Beschreibung:
Ein simples TicTacToe Game für 2 Spieler, welches auf dem Arduino mit dem VideoGameShield von wayneandlayne.com ausgeführt wird. Das Spiel wird mit 2 Nunchucks gesteuert.

Schaltplan:
Nicht erforderlich da nur das VideoGameShield aufgesetzt wird

Code:
/*
  Two Player TicTacToe
  by Pascal König
  v1.0, 24/04/2011
*/
#include 
#include 
#include 
#include 
#include 
#include 

TVout TV;
Nunchuck player1;
Nunchuck player2;

byte hres, vres;

byte cursor_x, cursor_y;

int field[9] = {0,0,0,0,0,0,0,0,0}; //Felder: 0 = frei, 1 = Player 1, 2 = Player 2 ----- von links nach rechts und dann von oben nach unten

byte player = 0; // 1 = Player 1, 2 = Player 2 - wird am Anfang random entschieden

#define STATE_TEST    0
#define STATE_START   1
#define STATE_PLAY    2
byte state = STATE_TEST;

void setup()
{
  TV.begin(_NTSC);
  TV.select_font(font4x6);
  TV.delay_frame(60);
  state = STATE_START;
  
  randomSeed(analogRead(0));
  player = random(1, 3);
}

void init_display()
{
  // draw field
  for (byte y = 0; y < vres; y += 6)
    TV.draw_line(hres / 3, y, hres / 3, y + 2, 1);
  for (byte y = 0; y < vres; y += 6)
    TV.draw_line((hres / 3) + (hres / 3), y, (hres / 3) + (hres / 3), y + 2, 1);
  for (byte x = 0; x < hres; x += 6)
    TV.draw_line(x, vres / 3, x + 2, vres / 3, 1);
  for (byte x = 0; x < hres; x += 6)
    TV.draw_line(x, (vres / 3) + (vres / 3), x + 2, (vres / 3) + (vres / 3), 1);
}

void draw_cursor()
{
  TV.set_pixel(cursor_x, cursor_y, 2);
}

int set_field(int player_nummer) //gibt zurück ob gesetzt wurde oder nicht ( 1 oder 0)
{
  switch (player_nummer)
  {
    case 1:
      if(player1.button_z())
      {
        if(cursor_x > 0 && cursor_x < hres / 3 && cursor_y > 0 && cursor_y < vres / 3) // links oben
        {
          if(field[0] == 0)
          {
            TV.draw_line(0 + 5, 0 + 5, hres / 3 - 5, vres / 3 - 5, 2);
            TV.draw_line(0 + 5, vres / 3 - 5, hres / 3 - 5, 0 + 5, 2); 
            field[0] = 1;
            return 1;
          }          
        }
        if(cursor_x > 0 && cursor_x < hres / 3 && cursor_y > vres / 3 && cursor_y < (vres / 3) + (vres / 3)) // links mitte
        {
          if(field[3] == 0)
          {
            TV.draw_line(0 + 5, vres / 3 + 5, hres / 3 - 5, vres / 3 + vres / 3 - 5, 2);
            TV.draw_line(0 + 5, vres / 3 + vres / 3 - 5, hres / 3 - 5, vres / 3 + 5, 2);
            field[3] = 1;
            return 1;
          }
        }
        if(cursor_x > 0 && cursor_x < hres / 3 && cursor_y > (vres / 3) + (vres / 3) && cursor_y < vres) // links unten
        {
          if(field[6] == 0)
          {
            TV.draw_line(0 + 5, vres / 3 + vres / 3 + 5, hres / 3 - 5, vres - 5, 2);
            TV.draw_line(0 + 5, vres - 5, hres / 3 - 5, vres / 3 + vres / 3 + 5, 2);
            field[6] = 1;
            return 1;
          }
        }
        if(cursor_x > hres / 3 && cursor_x < (hres / 3) + (hres / 3) && cursor_y > 0 && cursor_y < vres / 3) // mitte oben
        {
          if(field[1] == 0)
          {
            TV.draw_line(hres / 3 + 5, 0 + 5, hres / 3 + hres / 3 - 5, vres / 3 - 5, 2);
            TV.draw_line(hres / 3 + 5, vres / 3 - 5, hres / 3 + hres / 3 - 5, 0 + 5, 2);
            field[1] = 1;
            return 1;
          }
        }
        if(cursor_x > hres / 3 && cursor_x < (hres / 3) + (hres / 3) && cursor_y > vres / 3 && cursor_y < (vres / 3) + (vres / 3)) // mitte mitte
        {
          if(field[4] == 0)
          {
            TV.draw_line(hres / 3 + 5, vres / 3 + 5, hres / 3 + hres / 3 - 5, vres / 3 + vres / 3 - 5, 2);
            TV.draw_line(hres / 3 + 5, vres / 3 + vres / 3 - 5, hres / 3 + hres / 3 - 5, vres / 3 + 5, 2);
            field[4] = 1;
            return 1;
          }
        }
        if(cursor_x > hres / 3 && cursor_x < (hres / 3) + (hres / 3) && cursor_y > (vres / 3) + (vres / 3) && cursor_y < vres) // mitte unten
        {
          if(field[7] == 0)
          {
            TV.draw_line(hres / 3 + 5, vres / 3 + vres / 3 + 5, hres / 3 + hres / 3 - 5, vres - 5, 2);
            TV.draw_line(hres / 3 + 5, vres - 5, hres / 3 + hres / 3 - 5, vres / 3 + vres / 3 + 5, 2);
            field[7] = 1;
            return 1;
          }
        }
        if(cursor_x > (hres / 3) + (hres / 3) && cursor_x < hres && cursor_y > 0 && cursor_y < vres / 3) // rechts oben
        {
          if(field[2] == 0)
          {
            TV.draw_line(hres / 3 + hres / 3 + 5, 0 + 5, hres - 5, vres / 3 - 5, 2);
            TV.draw_line(hres / 3 + hres / 3 + 5, vres / 3 - 5, hres - 5, 0 + 5, 2);
            field[2] = 1;
            return 1;
          }
        }
        if(cursor_x > (hres / 3) + (hres / 3) && cursor_x < hres && cursor_y > vres / 3 && cursor_y < (vres / 3) + (vres / 3)) // rechts mitte
        {
          if(field[5] == 0)
          {
            TV.draw_line(hres / 3 + hres / 3 + 5, vres / 3 + 5, hres - 5, vres / 3 + vres / 3 - 5, 2);
            TV.draw_line(hres / 3 + hres / 3 + 5, vres / 3 + vres / 3 - 5, hres - 5, vres / 3 + 5, 2);
            field[5] = 1;
            return 1;
          }
        }
        if(cursor_x > (hres / 3) + (hres / 3) && cursor_x < hres && cursor_y > (vres / 3) + (vres / 3) && cursor_y < vres) // rechts unten
        {
          if(field[8] == 0)
          {
            TV.draw_line(hres / 3 + hres / 3 + 5, vres / 3 + vres / 3 + 5, hres - 5, vres - 5, 2);
            TV.draw_line(hres / 3 + hres / 3 + 5, vres - 5, hres - 5, vres / 3 + vres / 3 + 5, 2);
            field[8] = 1;
            return 1;
          }
        }
      }
      break;
    case 2:
    if(player2.button_z())
      {
        if(cursor_x > 0 && cursor_x < hres / 3 && cursor_y > 0 && cursor_y < vres / 3) // links oben
        {
          if(field[0] == 0)
          {
            TV.draw_circle((hres / 3) / 2, (vres / 3) / 2, (hres / 3) / 2 - 10,1,-1);
            field[0] = 2;
            return 1;
          }          
        }
        if(cursor_x > 0 && cursor_x < hres / 3 && cursor_y > vres / 3 && cursor_y < (vres / 3) + (vres / 3)) // links mitte
        {
          if(field[3] == 0)
          {
            TV.draw_circle((hres / 3) / 2, vres / 2, hres / 6 - 10, 1, -1);
            field[3] = 2;
            return 1;
          }
        }
        if(cursor_x > 0 && cursor_x < hres / 3 && cursor_y > (vres / 3) + (vres / 3) && cursor_y < vres) // links unten
        {
          if(field[6] == 0)
          {
            TV.draw_circle(hres / 6, (vres / 3 + vres / 3 + vres) / 2, hres / 6 - 10, 1, -1);
            field[6] = 2;
            return 1;
          }
        }
        if(cursor_x > hres / 3 && cursor_x < (hres / 3) + (hres / 3) && cursor_y > 0 && cursor_y < vres / 3) // mitte oben
        {
          if(field[1] == 0)
          {
            TV.draw_circle(hres / 2, vres / 6, hres / 6 - 10, 1, -1);
            field[1] = 2;
            return 1;
          }
        }
        if(cursor_x > hres / 3 && cursor_x < (hres / 3) + (hres / 3) && cursor_y > vres / 3 && cursor_y < (vres / 3) + (vres / 3)) // mitte mitte
        {
          if(field[4] == 0)
          {
            TV.draw_circle(hres / 2, vres / 2, hres / 6 - 10, 1, -1);
            field[4] = 2;
            return 1;
          }
        }
        if(cursor_x > hres / 3 && cursor_x < (hres / 3) + (hres / 3) && cursor_y > (vres / 3) + (vres / 3) && cursor_y < vres) // mitte unten
        {
          if(field[7] == 0)
          {
            TV.draw_circle(hres / 2, (vres / 3 + vres / 3 + vres) / 2, hres / 6 - 10, 1, -1);
            field[7] = 2;
            return 1;
          }
        }
        if(cursor_x > (hres / 3) + (hres / 3) && cursor_x < hres && cursor_y > 0 && cursor_y < vres / 3) // rechts oben
        {
          if(field[2] == 0)
          {
            TV.draw_circle((hres / 3 + hres / 3 + hres) / 2, vres / 6, hres / 6 - 10, 1, -1);
            field[2] = 2;
            return 1;
          }
        }
        if(cursor_x > (hres / 3) + (hres / 3) && cursor_x < hres && cursor_y > vres / 3 && cursor_y < (vres / 3) + (vres / 3)) // rechts mitte
        {
          if(field[5] == 0)
          {
            TV.draw_circle((hres / 3 + hres / 3 + hres) / 2, vres / 2, hres / 6 - 10, 1, -1);
            field[5] = 2;
            return 1;
          }
        }
        if(cursor_x > (hres / 3) + (hres / 3) && cursor_x < hres && cursor_y > (vres / 3) + (vres / 3) && cursor_y < vres) // rechts unten
        {
          if(field[8] == 0)
          {
            TV.draw_circle((hres / 3 + hres / 3 + hres) / 2, (vres / 3 + vres / 3 + vres) / 2, hres / 6 - 10, 1, -1);
            field[8] = 2;
            return 1;
          }
        }
      }
      break;
  }
  return 0;
}

void update_cursor(int player_nummer)
{
  switch (player_nummer)
  {
    case 1:
      if ( player1.joy_up())
      {
        cursor_y -= 1;
        if ( cursor_y < 1)
          cursor_y = 0;
      }
      if ( player1.joy_down())
      {
        cursor_y+=1;
        if ( cursor_y > (vres - 1))
          cursor_y = vres;
      }
      if (player1.joy_left())
      {
        cursor_x-=1;
        if(cursor_x < 1)
          cursor_x = 0;
      }
      if(player1.joy_right())
      {
        cursor_x+=1;
        if(cursor_x > (hres -1))
          cursor_x = hres;
      }
      break;
    case 2:
      if ( player2.joy_up())
      {
        cursor_y -= 1;
        if ( cursor_y < 1)
          cursor_y = 0;
      }
      if ( player2.joy_down())
      {
        cursor_y+=1;
        if ( cursor_y > (vres - 1))
          cursor_y = vres;
      }
      if (player2.joy_left())
      {
        cursor_x-=1;
        if(cursor_x < 1)
          cursor_x = 0;
      }
      if(player2.joy_right())
      {
        cursor_x+=1;
        if(cursor_x > (hres -1))
          cursor_x = hres;
      }
      break;
  }
}

int sieg_ermitteln() //gibt den Sieger zurück: 1 = player 1 - 2 = player 2 - 3 = kein sieger - 0 = noch kein sieger
{
  if((field[0] == 1 && field[1] == 1 && field[2] == 1)||(field[3]==1&&field[4]==1&&field[5]==1)||(field[6]==1&&field[7]==1&&field[8]==1)||(field[0] == 1 && field[3] == 1 && field[6] == 1)||(field[1]==1&&field[4]==1&&field[7]==1)||(field[2]==1&&field[5]==1&&field[8]==1)||(field[0]==1&&field[4]==1&&field[8]==1)||(field[2]==1&&field[4]==1&&field[6]==1))
    return 1;
  else if((field[0] == 2 && field[1] == 2 && field[2] == 2)||(field[3]==2&&field[4]==2&&field[5]==2)||(field[6]==2&&field[7]==2&&field[8]==2)||(field[0] == 2 && field[3] == 2 && field[6] == 2)||(field[1]==2&&field[4]==2&&field[7]==2)||(field[2]==2&&field[5]==2&&field[8]==2)||(field[0]==2&&field[4]==2&&field[8]==2)||(field[2]==2&&field[4]==2&&field[6]==2))
    return 2;
  else if(field[0]!=0&&field[1]!=0&&field[2]!=0&&field[3]!=0&&field[4]!=0&&field[5]!=0&&field[6]!=0&&field[7]!=0&&field[8]!=0)
    return 3;
  else
    return 0;
}

void zuruecksetzten()
{
  for(int i = 0; i < 10; i++)
  {
    field[i] = 0;
  }
}

void loop()
{
  switch (state)
  {
    case STATE_TEST:
      for (byte t = 0; t < 10; t++)
      {        
        TV.delay_frame(20);
      }
      break;
    case STATE_START:
      title_screen_init_nunchucks(&TV, "TicTacToe", &player1, &player2, true);
      
      hres = TV.hres() - 6; // this is based on what's visible on my tv
      vres = TV.vres();

      TV.clear_screen();
      init_display();
      draw_cursor(); // pre-draw the cursor so we can erase it
      
      state = STATE_PLAY;
      break;
    case STATE_PLAY:
      draw_cursor();
      if (player == 1)
      {
        TV.printPGM((hres / 2) - 16, 0, PSTR("Player 1"));
        player1.update();
        update_cursor(1);
        if(set_field(1) == 1)        
          player = 2;
      }
      else if (player == 2)
      {
        TV.printPGM((hres / 2) - 16, 0, PSTR("Player 2"));
        player2.update();
        update_cursor(2);
        if(set_field(2) == 1)        
          player = 1;
      }
      if(sieg_ermitteln() == 1)
      {
        TV.printPGM((hres / 2) - 16, vres / 2, PSTR("Player 1 win!"));
        zuruecksetzten();
        TV.delay_frame(240);
        state = STATE_START;
      }
      else if(sieg_ermitteln() == 2)
      {
        TV.printPGM((hres / 2) - 16, vres / 2, PSTR("Player 2 win!"));
        zuruecksetzten();
        TV.delay_frame(240);
        state = STATE_START;
      }
      else if(sieg_ermitteln() == 3)
      {
        TV.printPGM((hres / 2) - 16, vres / 2, PSTR("Nobody win!"));
        zuruecksetzten();
        TV.delay_frame(240);
        state = STATE_START;
      }
      draw_cursor();
      
      TV.delay_frame(1);
      break;
  }
}

Keine Kommentare:

Kommentar veröffentlichen