ASCII  Serial Monitor Whack-A-Mole

I received in the mail two days ago an arcade joystick, just like in claw games.
It is 8-way, with a red button on top.

So, my first project is a Whack-a-Mole game, played right in the Serial Monitor in the Arduino IDE!

I began to work on it this morning, and now I am done.
It prints a 3x3 grid of characters for each frame, at ~20 fps.

Legend:
. mole hole

  • you (the cursor)
    O evil little mole....grrrr
    @ the cursor on top of the mole (just press the button, and kill that mole!! muahahaha)

a successful mole hit ( whopee!)

x a miss (fail.)

It all works great, and even prints your score when you lose!

/*  
This is a whackamole game.
Joystick connected as follows:
Up    digital pin 3
Right             4
Down              5
Left              6
Button            7

Common ground (because I have a ribbon wire 
coming from the joystick, and this is just neater)
      Digital Pin 2
      
Press the button to start
*/


const char cross = '*';
const char mole = 'O';
const char both = '@';
const char miss = 'x';
const char hit = '#';
const char blank = '.';

int crossCoor;
int moleCoor;
long spawn;
int limit;
char pic;
boolean dead;



void setup()  {
  for(int i=3; i<=7; i++) {
    pinMode(i, INPUT);
    digitalWrite(i, HIGH);
  }
  pinMode(2, OUTPUT);
  digitalWrite(2, LOW);
  Serial.begin(115200);
}


int crossGet()  {
  int coor = 5;
  if(digitalRead(3) == HIGH)  {
    coor += 3;
  }
  if(digitalRead(5) == HIGH)  {
    coor -= 3;
  }
  if(digitalRead(4) == HIGH)  {
    coor --;
  }
  if(digitalRead(6) == HIGH)  {
    coor ++;
  }
  return coor;
}

boolean pressed()  {
  boolean res;
  if(digitalRead(7)==LOW)  {
    res=true;
  }
  else  {
    res=false;
  }
  return res;
}

void display(int molePos)  {
  int one=crossGet();
  boolean button = pressed();
  for(int i=1; i<=9; i++)  {

    if(one==i && molePos==i)  {
      if(button)  {
        pic = hit;
        dead=true;
      }
      else  {
        pic=both;
      }
    }
    else if(one == i)  {
      if(button)  {
        pic=miss;
      }
      else  {
        pic=cross;
      }
    }
    else if(molePos==i)  {
      pic=mole;
    }
    else  {
      pic=blank;
    }
    if(i==3 || i==6 || i==9)  {
      Serial.println(pic);
    }
    else  {
      Serial.print(pic);
    }
  }
}

void makeMole()  {
  spawn = millis();
  randomSeed(analogRead(0));
  moleCoor = random(1, 10);
  dead=false;
}

void noMole()  {
  moleCoor=10;
}

void loop()  {
  Serial.println("Ready to play?");
  while(digitalRead(7)==HIGH)  {
  }
  Serial.println("Ready...");
  delay(1000);
  Serial.println("Set...");
  delay(1000);
  Serial.println("GO!");

  boolean lost = false;
  int score = 0;
  limit= 3000;

  while(lost==false ) {
    int time = random(0, 21);
    for(int i=0; i<=time; i++)  {
      display(10);
      Serial.println();
      delay(50);
    }
    makeMole();
    while(dead==false && spawn+limit >= millis())  {
      display(moleCoor);
      if(pic=='#')  {
        dead = true;
      }
      Serial.println();
      delay(50);
    }
    if(dead)  {
      
      score++;
      if(limit>1000)  {
        limit -= 50;
      }
      delay(100);
      
    }
    else  {
      break;
    }
  }
  Serial.println("You lost");
  Serial.print("Your score was  ");
  Serial.println(score);
  Serial.println();
  delay(1000);
  while(digitalRead(7)==HIGH)  {
  }
  delay(1000);
}

Enjoy!

P.S. This can be used with 5 pushbuttons, just hit two to go on diagonals. Less convenient, though.