From 2bd45f076ea7eb429bfee54fe1de240ff4b284e6 Mon Sep 17 00:00:00 2001 From: brett Date: Tue, 23 Apr 2024 20:51:02 -0500 Subject: should be finished, backing up --- final_project/main.c | 218 +++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 218 insertions(+) create mode 100644 final_project/main.c (limited to 'final_project/main.c') diff --git a/final_project/main.c b/final_project/main.c new file mode 100644 index 0000000..f301ef5 --- /dev/null +++ b/final_project/main.c @@ -0,0 +1,218 @@ +/* + * final_project.c + * + * Created: 4/3/2024 10:08:56 AM + * Author : bsw9xd + */ +#define F_CPU 16000000UL + +#include +#include +#include +#include + +#include "serial.h" +#include "clock.h" + + +volatile int seconds_remaining; //will be used by ISR + +#define SPEAKER_PORT PORTE +#define SPEAKER_PIN 4 //rename? +#define ELEMENT_COUNT 7 + +//TODO get_button and display_element unnecessarily complex +uint8_t get_button() { + if(~PINE & (1 << 6)) return (1 << 2); + return ((~PINA) & ~(0b1100)); //TODO clean up +} + +void display_element(uint8_t element, unsigned int time) { + uint8_t portd_state = 0; + uint8_t porte_state = 0; + if(element & (1 << 2)) porte_state = (1<<5); + portd_state = element & ~(0b1100); + + PORTD ^= portd_state; + PORTE ^= porte_state; + beep(329.63, .25); + _delay_ms(time * 1000); + PORTD ^= portd_state; + PORTE ^= porte_state; +} + +void init_io() { + DDRA = 0x00; + PORTA = 0xff; + + DDRD = 0xff; + PORTD = 0xff; + + DDRE = (1 << 4) | (1 << 5); + PORTE = 0xff; +} +void test_timer() { + for(;;) { + usart_txstr("timer test\n"); + start_timer(); + while(!timer_done()); + stop_timer(); + } +} + +int main(void) { + cli(); + timer_init_ctc(); + init_io(); + usart_init(); + + + while(1) { + int level = 0; + + //get level + usart_txstr( + "SIMON GAME\n" + "Enter your starting difficulty level:\n" + "1. Easy\n" + "2. Moderate\n" + "3. Give me pain."); + + while((level > 3) || (level < 1)) level = (int)(usart_rxt_blocking() - '0'); + + + //main simon game + while(level < 3) { + int display_time; + int sets; + int response_time; + int elements_min; + int elements_max; + double score; + uint8_t element_list[5]; // TODO + + + switch(level) { + case 1: + sets = 3; + display_time = 3; + response_time = 5; + elements_min = 3; + elements_max = 5; + break; + case 2: + sets = 4; + display_time = 2; + response_time = 7; + elements_min = 3; + elements_max = 10; + break; + case 3: + sets = 5; + display_time = 1; + response_time = 10; + elements_min = 5; + elements_max = 15; + break; + } + + + //main level + int max_score = 0; + int current_score = 0; + for(int set = 0; set < sets; set++) { + int elements = elements_min + ceil(((elements_max - elements_min) / (float)(sets - 1)) * set); + //generate, display elements + for(int element = 0; element < elements; element++) { + uint8_t element_bit = (rand() % ELEMENT_COUNT); + if(element_bit == 3) element_bit = 7; + uint8_t this_element = 1 << element_bit; + usart_txt('\n'); + usart_txt(element_bit + '0'); + usart_txt('\n'); + element_list[element] = this_element; // could optimize + display_element(this_element, display_time); + + } + //get elements + seconds_remaining = response_time; + start_timer(); + uint16_t guess; + for(int element = 0; element < elements; element++) { + usart_txstr("\ngot element, waiting...\n"); + do { + if(timer_done()) { + seconds_remaining--; + stop_timer(); //TODO only need one function + start_timer(); + beep(261.63, .1); + } + else { guess = get_button(); } + } while((!guess) && (seconds_remaining > 0)); + _delay_ms(250); //prevent double press + max_score++; + if(guess == element_list[element]) { + current_score++; + correct_beep(); + } + else { + incorrect_beep(); + } + } + } + score = (float)current_score / max_score; + if(score >= .8) { + level++; + usart_txstr("\nnext level\n"); + } + else { + loose(); + break; + } + } + if(level >= 3) win(); + } +} + +//timer interrupt +ISR(TIMER1_COMPA_vect) { + if(seconds_remaining-- > 0) return; + for(;;) { + beep(); + } +} + +void correct_beep() { + usart_txstr("\nCorrect!\n"); + beep(440.0, .1); +} + +void incorrect_beep() { + usart_txstr("\nIncorrect guess.\n"); + beep(261.62, .2); + _delay_ms(25); + beep(261.62, .2); +} + +void win() { + usart_txstr("\nYou beat the game!\n"); + beep(262., .5); + beep(392., .5); +} + +void loose() { + usart_txstr("\nYou loose, try again?\n"); + beep(330., .5); + beep(294., .5); +} + + +//TODO move somewhere else +void beep(double frequency, double durientation) { + double speaker_ms = ((1.0 / frequency) / 2.0) * 1000.0; //TODO clean up + int loop_count = durientation / (1.0 / frequency); + for(unsigned int i = 0; i < loop_count; i++) { + _delay_ms(speaker_ms); + SPEAKER_PORT ^= (1 << SPEAKER_PIN); + } +} \ No newline at end of file -- cgit v1.2.3