Power Grid Board Game Timer. Acts like a chess timer for 3-6 people. Uses an ADXL accelerometer to pause the timer and change players. Uses an LCD screen to prompt the players for input, read that input, and change between rounds.
Dependencies: DmTouch_UniGraphic UniGraphic-forLdelaney17FinalProject mbed
game.cpp
- Committer:
- ldelaney17
- Date:
- 2017-01-25
- Revision:
- 4:e14c199c2466
- Parent:
- 3:22c644f16365
File content as of revision 4:e14c199c2466:
#include "game.h" void game_setup(){ step_number = 0; clock_running = false; current_clock.reset(); init_num_players(); set_start_time(); set_bonus_time(); next_step(); // set_player_order(); } void song_setup(){ enum notes{ C_4 = 262, D_4 = 294, E_4 = 330, F_4 = 349, G_4 = 392, A_4 = 440, Bb_4 = 466, C_5 = 523, Db_5 = 554, D_5 = 587, E_5 = 659, F_5 = 698, G_5 = 784, A_5 = 880}; float freq_j[31] = {C_5,F_5,C_5,F_4,C_5,F_5,C_5,C_5,F_5,C_5,F_5,A_5,G_5,F_5,E_5,D_5,Db_5,C_5,F_5,C_5,F_4,C_5,F_5,C_5,F_5,D_5,C_5,Bb_4,A_4,G_4,F_4}; float beat_j[31] = {1,1,1,1,1,1,2,1,1,1,1,1.5,.5,.5,.5,.5,.5,1,1,1,1,1,1,2,1.5,.5,1,1,1,1,1}; vector<float> f (freq_j, freq_j + sizeof(freq_j) / sizeof(freq_j[0])); vector<float> b (beat_j, beat_j + sizeof(beat_j) / sizeof(beat_j[0])); jeopardy = new Song(f, b, 31, 120); float freq_s[8] = {F_5, E_5, D_5, C_5, Bb_4, A_4, G_4, F_4}; float beat_s[8] = {1, 1, 1, 1, 1, 1, 1, 5}; vector<float> f_s (freq_s, freq_s + sizeof(freq_s) / sizeof(freq_s[0])); vector<float> b_s (beat_s, beat_s + sizeof(beat_s) / sizeof(beat_s[0])); scale = new Song(f_s, b_s,8, 120); float freq_b[1] = {F_5}; float beat_b[1] = {60}; vector<float> f_b (freq_b, freq_b + sizeof(freq_s) / sizeof(freq_s[0])); vector<float> b_b (beat_b, beat_b + sizeof(beat_s) / sizeof(beat_s[0])); beep = new Song(f_b, b_b, 1, 120); } void init_num_players(){ prompt(6, "Select the number of players\r\n"); //sets waiting_for_touch to true while(waiting_for_touch == true){ //until a valid input is read, spin our wheels here wait(0.1); // can busy wait during setup } num_players = prompt_input_val; // set based on the circle touched stringstream ss; ss << "press 1 to confirm that " << num_players << " players is correct. Press 2 to select a different number"; prompt(2, ss.str()); while(waiting_for_touch == true){ //until a valid input is read wait(0.1); // can busy wait during setup } int choice = prompt_input_val; switch(choice){ case 1: return; break; case 2: init_num_players(); return; break; } } //blocking wait function void set_player_order(){ player_order.clear(); for (int i = 0; i < num_players; i++){ prompt(num_players, "select the player number with the most cities. \r\nIn case of a tie, the higher numbered power \r\nplant goes first\r\n"); while (waiting_for_touch){ wait(0.05); //blocking busy wait } player_order.push_back(prompt_input_val); } //TODO: if has duplicates, display message "invalid turn order" and call set_player_order stringstream ss; ss << "press 1 to confirm that player order is correct. \r\nPress 2 to change"; ss << "\r\nPlayer Order:\t"; for (int i = 0; i < num_players; i++){ ss << player_order[i] << "\t"; } prompt(2, ss.str()); while(waiting_for_touch == true){ //until a valid input is read wait(0.1); // can busy wait during setup } int choice = prompt_input_val; switch(choice){ case 1: return; break; case 2: set_player_order(); return; break; } } void set_start_time(){ //TODO: let the user input a start time prompt(5, "Select a starting amount of time per player:\r\n1: 1:00\t2: 1:30\t3: 2:30\t 4: 5:00\t 5: 10:00"); while (waiting_for_touch){ //busy wait during setup wait(0.1); } int time_choice = prompt_input_val; stringstream ss; float start_time; switch(time_choice){ case 1: start_time = 60; break; case 2: start_time = 90; break; case 3: start_time = 150; break; case 4: start_time = 300; break; case 5: start_time = 600; break; default: //never run this line start_time = 0; break; } ss << "press 1 to confirm that " << start_time << " seconds is correct. Press 2 to select a different time"; prompt(2, ss.str()); while(waiting_for_touch == true){ //until a valid input is read wait(0.1); // can busy wait during setup } int choice = prompt_input_val; switch(choice){ case 1: for (int i = 0; i < num_players; i++) //if chosen, initialize the timers { player_timers.push_back(start_time); } return; break; case 2: set_start_time(); return; break; } } void set_bonus_time(){ //TODO: let the user input a bonus time that will be added to a player's timer each time their timer is started (many times per round) prompt(5, "Select a bonus amount of time that will be added to a player's timer each time their timer is started:\r\n1: 0:01\t2: 0:05\t3: 0:10\t 4: 0:15\t 5: 0:30"); while (waiting_for_touch){ //busy wait during setup wait(0.1); } int time_choice = prompt_input_val; stringstream ss; float start_time; switch(time_choice){ case 1: bonus_time = 1; break; case 2: bonus_time = 5; break; case 3: bonus_time = 10; break; case 4: bonus_time = 15; break; case 5: bonus_time = 30; break; default: //never run this line bonus_time = 0; break; } ss << "press 1 to confirm that " << bonus_time << " seconds is correct. Press 2 to select a different time"; prompt(2, ss.str()); while(waiting_for_touch == true){ //until a valid input is read wait(0.1); // can busy wait during setup } int choice = prompt_input_val; switch(choice){ case 1: return; break; case 2: set_bonus_time(); return; break; } } void next_step(){ pc.printf("starting next step\r\n"); pause_timer(); pc.printf("after pause_timer\r\n"); if (step_number == 4) step_number = 0; else step_number++; stringstream ss; ss << "Step number " << step_number << ": "; pc.printf("entering step_number (%d) switch\r\n", step_number); switch(step_number-1){ //based on the last step case 0: //determine player order (immediately call again to move to the "auction power plants" phase set_player_order(); next_step(); return; break; case 1: //auction power plants, standard turn order ss << "Auction Power Plants"; current_player = player_order[0]; start_timer(current_player); break; case 2: //buy resources, reverse player order ss << "Buy Resources"; reverse_player_order(); current_player = player_order[0]; current_player_index = 0; start_timer(current_player); break; case 3: //building, reverse player order (same as buying resources) ss << "Building"; current_player = player_order[0]; current_player_index = 0; start_timer(current_player); break; case 4: //bureacracy, normal player order (reverse order of building) ss << "Bureacracy"; reverse_player_order(); current_player = player_order[0]; current_player_index = 0; start_timer(current_player); break; } ss << "\r\nPres the button to move to the next step"; prompt(1, ss.str()); //display a single button and the message } //TODO: it would be nice to include the phase changes, but it doesn't affect the // parts of gameplay I am focusing on /* prompt(2, "is this a new phase?\r\n1: yes\t 2: no"); while(waiting_for_touch == true){ //until a valid input is read wait(0.1); // can busy wait between rounds } int choice = prompt_input_val; switch(choice){ case 1: new_phase(); return; break; case 2: //not a new phase break; } */ void reverse_player_order(){ reverse(player_order.begin(),player_order.end()); //yay for library functions! } //FIXME: be sure to update the previous player's timer when it is paused void start_timer(int player_num){ pc.printf("starting timer for player %d\r\n", player_num); player_timers[player_num] += bonus_time; //add the bonus for unpausing their timer unpause_timer(); //do the rest of the start_timer() stuff pc.printf("timer started\r\n"); } void unpause_timer(){ current_clock.stop(); //just in case current_clock.reset(); //set to zero current_clock.start(); //start it ticking clock_running = true; // let everything else know that the clock is actively running pc.printf("not attatching songs to timeouts\r\n"); //time_after_warning.attach(jeopardy, &Song::play, time_after_warning_sound); //time_before_warning.attach(scale, &Song::play, player_timers[player_num] - time_before_warning_sound); //pc.printf("songs attached\r\n"); pc.printf("end of unpause_timer\r\n"); } void pause_timer(){ current_clock.stop(); clock_running = false; update_timer(); //resets the timer after updating the player's remaining time } //pauses clock if running, starts clock if paused void toggle_pause(){ if (clock_running == true){ pc.printf("pausing timer from toggle\r\n"); pause_timer(); clock_running = false; } else{ pc.printf("unpausing timer from toggle\r\n"); unpause_timer(); //start without adding bonus time clock_running = true; } } void next_player(){ pause_timer(); //also calls update_timer current_player_index++; if (current_player_index >= num_players) current_player_index = 0; current_player = player_order[current_player_index]; start_timer(current_player); } void update_timer(){ if (clock_running) current_clock.stop(); player_timers[current_player-1] -= (current_clock.read_ms() / 1000); current_clock.reset(); /*if (player_timers[current_player] <= 0) beep->play(); else if (player_timers[current_player] < time_before_warning_sound) scale->play();*/ if(clock_running) current_clock.start(); } void display_timer(){ stringstream ss; ss << "Player " << current_player << ": " << static_cast<double>(player_timers[current_player-1] - (current_clock.read_ms() /1000)) << "\r\n"; display_msg_no_clear(ss.str()); }