This video demonstrates the basic circuitry for Whac-A-Mole. The lever switch will later be replaced by a series of buttons held underneath the solenoids. When an extended solenoid piston is hit, it will depress the button and a new random piston will extend. The stepper motor will be used to drive the score-keeping mechanism.

Code:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
//====================================================================================
//Digital Port Definitions
#define HIT_TRIGGER 9
#define MOTOR_DIR 10
#define MOTOR_STEP 11
enum mole_t {MOLE_0, MOLE_1, MOLE_2, MOLE_3, MOLE_4, MOLE_5, MOLE_6, MOLE_7, MOLE_8};
 
//====================================================================================
//State Definitions
enum state_t {GAME_IDLE, NEW_MOLE, WAIT_HIT, WAS_HIT, NOT_HIT, GAME_OVER} game_state;
int mole;
int score;
int timer;
 
//====================================================================================
void setup() {
  //set up the moles
  pinMode(MOLE_0, OUTPUT); digitalWrite(MOLE_0, LOW);
  pinMode(MOLE_1, OUTPUT); digitalWrite(MOLE_1, LOW);
  pinMode(MOLE_2, OUTPUT); digitalWrite(MOLE_2, LOW);
  pinMode(MOLE_3, OUTPUT); digitalWrite(MOLE_3, LOW);
  pinMode(MOLE_4, OUTPUT); digitalWrite(MOLE_4, LOW);
  pinMode(MOLE_5, OUTPUT); digitalWrite(MOLE_5, LOW);
  pinMode(MOLE_6, OUTPUT); digitalWrite(MOLE_6, LOW);
  pinMode(MOLE_7, OUTPUT); digitalWrite(MOLE_7, LOW);
  pinMode(MOLE_8, OUTPUT); digitalWrite(MOLE_8, LOW);
   
  //set up hit feedback
  pinMode(HIT_TRIGGER, INPUT);
 
  //set up score-keeping motor
  pinMode(MOTOR_DIR, OUTPUT);
  pinMode(MOTOR_STEP, OUTPUT);
 
  //initialize gamestate
  game_state = GAME_IDLE;
  score = 0;
}
 
void loop() {
  timer++;
  switch(game_state) {
    case GAME_IDLE:
      game_state = NEW_MOLE;
      break;
       
    case NEW_MOLE:
      new_mole();
      timer = 0;
      game_state = WAIT_HIT;
      break;
       
    case WAIT_HIT:
      if (!digitalRead(HIT_TRIGGER)) {
        digitalWrite(mole, LOW);
        game_state = WAS_HIT;
      }
      else if (timer >= random(1000,3000)) {
        digitalWrite(mole, LOW);
        timer = 0;
        game_state = NOT_HIT;
      }
      break;
       
    case WAS_HIT:
      score++;
      game_state = NEW_MOLE;
      digitalWrite(MOTOR_DIR, HIGH);
      for(int i = 0; i < 80; i++) {
        digitalWrite(MOTOR_STEP, HIGH); delay(1);
        digitalWrite(MOTOR_STEP, LOW);  delay(1);
      }
      break;
 
    case NOT_HIT:
      game_state = NEW_MOLE;
      break;
       
    case GAME_OVER:
      break;
       
  }
  delay(1);
}
 
void new_mole(){
  delay(random(1000));
  mole = random(9);
  digitalWrite(mole, HIGH);
  delay(10);
}