// Useful info: // On my board, LED 0 is on PA2 // LED 1 is on PA3 // BUTTON 1 is on PA7 // BUTTON 0 is on PB2 #include #include #include #define led_pin_0 (1 << PA2) #define led_pin_1 (1 << PA3) #define button_1 (1 << PA7) #define button_0 (1 << PB2) typedef enum { START_GAME, LISTEN, JUDGE, } states; // Global state variables. int max_guesses = 7; int num_binary_digits = 4; states game_state = START_GAME; int my_number; int user_guess; int guesses_left; int button_state[2]; int num_digits_entered; void led_on(int led_num) { if (led_num == 0) { PORTA |= led_pin_0; } else { PORTA |= led_pin_1; } } void led_off(int led_num) { if (led_num == 0) { PORTA &= ~led_pin_0; } else { PORTA &= ~led_pin_1; } } // Set up the number to be guessed by polling the clock // and masking out the lower order bits. int get_number(int digits) { int mask = 0; for (int i = 0; i < digits; ++i) { mask = (mask << 1) | 1; } return TCNT1L & mask; } void start_game() { my_number = get_number(num_binary_digits); num_digits_entered = 0; user_guess = 0; button_state[0] = 0; button_state[1] = 0; guesses_left = max_guesses; // Blink both LED's to signal ready for user. for (int i = 0; i < num_binary_digits; ++i) { led_on(0); led_on(1); _delay_ms(40); led_off(0); led_off(1); _delay_ms(40); } game_state = LISTEN; } int button_on(int button) { if (button == 0) { return !(PINB & button_0); } else { return !(PINA & button_1); } } void enter_digit(int digit) { user_guess = user_guess << 1; user_guess |= digit; num_digits_entered++; } void listen() { for (int i = 0; i < 2; ++i) { if (button_on(i)) { _delay_ms(5); if (button_on(i)) { led_on(i); button_state[i] = 1; } } if (!button_on(i)) { _delay_ms(5); if (!button_on(i)) { led_off(i); if (button_state[i] == 1) { enter_digit(i); button_state[i] = 0; } } } } } void victory() { for (int i = 0; i < 12; ++i) { led_off(0); led_on(1); _delay_ms(10); led_on(0); led_off(1); _delay_ms(10); } led_off(0); led_off(1); game_state = START_GAME; _delay_ms(300); } void lose() { led_on(0); led_on(1); _delay_ms(500); led_off(0); led_off(1); game_state = START_GAME; _delay_ms(300); } void reset_guess() { user_guess = 0; num_digits_entered = 0; game_state = LISTEN; } void say_higher() { led_on(0); _delay_ms(100); led_off(0); _delay_ms(100); reset_guess(); } void say_lower() { led_on(1); _delay_ms(100); led_off(1); _delay_ms(100); reset_guess(); } void judge() { _delay_ms(40); if (--guesses_left == 0) { lose(); return; } if (user_guess < my_number) say_higher(); if (user_guess > my_number) say_lower(); if (user_guess == my_number) victory(); } int main(void) { // Configure led pins as an output. DDRA |= led_pin_0; DDRA |= led_pin_1; // Configure button pins as output. DDRB &= ~button_0; DDRA &= ~button_1; TCNT1 = 0; TCCR1A = 0x00; TCCR1B |= (1 << CS10); while (1) { switch (game_state) { case START_GAME: start_game(); continue; case LISTEN: listen(); if (num_digits_entered == num_binary_digits) { game_state = JUDGE; } continue; case JUDGE: judge(); continue; default: continue; } _delay_ms(1); } return 0; }