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