Game codes for Pokemon Academy Yiu Fai Kwok - 201198802 I have read the University Regulations on Plagiarism and state that the work covered by this declaration is my own and does not contain any unacknowledged work from other sources.

Dependencies:   mbed FXOS8700CQ mbed-rtos

main.cpp

Committer:
yfkwok
Date:
2019-05-09
Revision:
34:3ddfaa217eca
Parent:
33:f7ec806e14b6

File content as of revision 34:3ddfaa217eca:

/*
ELEC2645 Embedded Systems Project
School of Electronic & Electrical Engineering
University of Leeds
Name: Yiu Fai Kwok
Username: el17yfk
Student ID Number: 201198802
Date: 11/03/2019
*/

#include "mbed.h"
#include "N5110.h"
#include "Gamepad.h"
#include "Score.h"
#include "Start.h"
#include "Game_one.h"
#include "Game_two.h"
#include "Game_three.h"
#include "Exam.h"
#include "Titles.h"
#include "FXOS8700CQ.h"
#include "rtos.h"

/////////////// objects ///////////////
N5110 lcd(PTC9,PTC0,PTC7,PTD2,PTD1,PTC11);  // K64F - pwr from 3V3
Gamepad pad;            // Gamepad class
Score music;            // Score class for music files
Start start;            // Start class for choosing starter
Game_one game_1;        // Game_one class for mini game 1
Game_two game_2;        // Game_two class for mini game 2
Game_three game_3;      // Game_three class for mini game 3
Exam test;              // Exam class for exam questions
Titles grad;            // Titles class for graduation credit scene
Thread thread;          // Thread class for running functions in parallel
// I2C connection for FXOS8700CQ accelerometer/magnetometer
FXOS8700CQ device(I2C_SDA,I2C_SCL);  // PTE25/PTE24

///////////// prototypes ///////////////
void init();
int menu();
void year_one_set();
void year_two_set();
void year_three_set();
void gym();

//Starting states
enum StartStates {
    TITLE, MENU, INSTRUCTION 
};

//Game states
enum GameStates {
    YEAR_1, STARTER, BULBASAUR, SQUIRTLE, CHARMANDER, EXAM, YEAR_2, YEAR_3, GRADUATION
};

//Global variables
int score = 0;              // Score to take note of number of missions passed
int game_1_speed = 0;       // Setting the speed for the objects in Game 1
int game_1_cha = 0;         // Setting which evolution to draw in Game 1
int game_1_r = 1;           // Setting the ratio between coins and blocks in Game 1
int game_2_speed = 0;       // Setting the speed for the objects in Game 2
int game_2_cha = 0;         // Setting which evolution to draw in Game 2
int game_2_r = 1;           // Setting the ratio between YouTube and other social medias in Game 2
int game_3_set = 1;         // Setting the number of messages vs books in Game 3
float game_3_time = 1.0;    // Setting the reaction time for Game 3
int select = 0;             // Setting the starter selection parameter
int year = 0;               // Setting the year that it is currently in
int pass = 0;               // Setting the pass parameters for exam
volatile bool finished = false; // Setting the music loop for Exam
volatile bool end = false;  // Setting the game loop
int button_A[9][8] = {
    {0,0,1,1,1,1,0,0},
    {0,1,0,0,0,0,1,0},
    {1,0,1,1,1,1,0,1},
    {1,0,1,0,0,1,0,1},
    {1,0,1,1,1,1,0,1},
    {1,0,1,0,0,1,0,1},
    {1,1,0,0,0,0,1,1},
    {0,1,1,1,1,1,1,0},
    {0,0,1,1,1,1,0,0},
};                          // Sprite for button_A

///////////// functions ////////////////
int main(){
    
    // Initialise parameters
    int fps = 8;        // frames per second

    init();             // initialise
    StartStates currentState = TITLE;
    GameStates currentGame = YEAR_1;
    
    while(1){
        switch (currentState) {
        case TITLE:
            // 1. Display title screen and play title music
            // 2. Proceed to Start screen by pressing start
            
            grad.welcome(pad, lcd);
            wait(1.0f/fps);
            currentState = MENU;        // Set currentState to MENU to start up the MENU page
            currentGame = YEAR_1;       // Set currentGame to YEAR_1 so the game starts from the beginning and resets all difficulty parameters
            end = false;                // Reset end parameter to start the Game loop
        break;
        
        case MENU:
            // 1. Display starting menu
            // 2. If Start is selected, initiate year 1 game state
            // 3. If Instruction is selected, give instruction
            
            int op = menu();
            if (op == 1){currentState = INSTRUCTION;}
            else {
                while(!end){
                    // Game loop
                    switch (currentGame) {
                        case YEAR_1:
                            // 1. Initiate year 1 screen
                            // 2. Set up the parameters for year 1
                            
                            grad.year_one(pad, lcd);        // Display year title screen
                            year_one_set();                 // Set the difficulties for mini games
                            currentGame = STARTER;
                        break;
                        
                        case STARTER:
                            // 1. Provide selection screen for starter pokemon to select which mini game to initiate
                            // 2. Provide description for the mini game and pokemon
                            // 3. Initiate the mini game according to the pokemon being selected
                            
                            select = 0;                     // Reset starter selection parameter to 0 position
                            start.init(pad);                // Initialize the Start class
                            start.starter_draw(lcd);        // Draw the start pokemon selection page
                            wait(1.0f/fps);
                            while(pad.check_event(Gamepad::START_PRESSED) == false)
                                {
                                    start.starter_update(pad);
                                    start.starter_draw(lcd);
                                    if(pad.check_event(Gamepad::A_PRESSED) == true){
                                        select = start.get_select(start.update_select(pad));    // Set select parameter to determine which starter pokemon is chosen
                                        start.intro(select, pad, lcd);                          // Display the description for the pokemon being selected
                                        pad.init_input();
                                    }
                                    wait(1.0f/fps);
                                }
                            select = start.get_select(start.update_select(pad));
                            if(select == 1){
                                music.congrats(pad, lcd, select, year);                 // Display congratulation screen for choosing the starter pokemon
                                while(pad.check_event(Gamepad::A_PRESSED) == false){
                                    lcd.drawSprite(2,40,9,8,(int*)button_A);            // Instruct to press A to continue
                                    lcd.refresh();
                                    wait(0.3);
                                    lcd.printString(" ",0,5);
                                    lcd.printString(" ",5,5);
                                    lcd.refresh();
                                    wait(0.3);
                                }
                                game_1.intro(pad, lcd);         // Display Game one description page to introduce the player how the game is played
                                currentGame = SQUIRTLE;         // Move to Squirtle's game loop
                                pad.init_input();
                            }
                            else if(select == 0){
                                music.congrats(pad, lcd, select, year);
                                while(pad.check_event(Gamepad::A_PRESSED) == false){
                                    lcd.drawSprite(2,40,9,8,(int*)button_A);
                                    lcd.refresh();
                                    wait(0.3);
                                    lcd.printString(" ",0,5);
                                    lcd.printString(" ",5,5);
                                    lcd.refresh();
                                    wait(0.3);
                                }
                                game_3.intro(pad, lcd);         // Display Game three description page to introduce the player how the game is played
                                currentGame = BULBASAUR;        // Move to Bulbasaur's game loop
                                pad.init_input();
                            }
                            else if(select == 2){
                                music.congrats(pad, lcd, select, year);
                                while(pad.check_event(Gamepad::A_PRESSED) == false){
                                    lcd.drawSprite(2,40,9,8,(int*)button_A);
                                    lcd.refresh();
                                    wait(0.3);
                                    lcd.printString(" ",0,5);
                                    lcd.printString(" ",5,5);
                                    lcd.refresh();
                                    wait(0.3);
                                }
                                game_2.intro(pad, lcd);         // Display Game two description page to introduce the player how the game is played
                                currentGame = CHARMANDER;       // Move to Charmander's game loop
                                pad.init_input();
                            }
                        break;
                        
                        // Game loop for Bulbasaur's mini game
                        case BULBASAUR:
                            int i = 0;
                            score = 0;
                            while(i < 3){
                                // Indicate for which term the current game is in
                                if(i == 0) {grad.term_one(pad, lcd);}
                                else if(i == 1) {grad.term_two(pad, lcd);}
                                else{grad.term_three(pad, lcd);}
                                int j = 0;
                                game_3.init_para();
                                while(j < 5){
                                    // Game loop for 5 rounds
                                    game_3.init(pad, game_3_set);       // Set the ratio between messages vs books according to year
                                    game_3.render(lcd, game_3_set);
                                    wait(game_3_time);                  // Parameter to set the reaction time frame for varying difficulty
                                    game_3.read_input(pad);
                                    game_3.update(pad, game_3_set);
                                    j = game_3.get_count();             // Get count for how many rounds the player has played
                                }
                                i = i++;
                                // determine if win condition is met, return score to proceed to EXAM game loop
                                if(game_3.get_score() >= 4) {
                                    grad.win(lcd);
                                    music.win(pad);
                                    wait(0.5);
                                    score++;
                                }
                                else {
                                    grad.lose(lcd);
                                    pad.tone(750.0,0.2);
                                    wait(0.5);
                                    pad.tone(750.0,0.2);
                                    wait(1.0);
                                }
                            }
                            currentGame = EXAM;
                        break;
                        
                        // Game loop for Squirtle's mini game
                        case SQUIRTLE:
                            i = 0;
                            score = 0;
                            while(i < 3){
                                // Indicate for which term the current game is in
                                if(i == 0) {grad.term_one(pad, lcd);}
                                else if(i == 1) {grad.term_two(pad, lcd);}
                                else{grad.term_three(pad, lcd);}
                                game_1.init(game_1_speed, game_1_cha, game_1_r);    // Set the game difficulty by changing speed of objects and coin to block ratio according to year
                                int j = 0;
                                while(j < 10){
                                    // Game loop for 10 rounds
                                    game_1.read_input(pad);
                                    game_1.update(pad, lcd);
                                    game_1.render(lcd, game_1_cha);
                                    wait(1.0f/fps);
                                    j = game_1.get_count();                         // Get count for how many rounds the player has played
                                }
                                i = i++;
                                // determine if win condition is met, return score to proceed to EXAM game loop
                                if(game_1.print_scores(lcd) >= 8) {
                                    grad.win(lcd);
                                    music.win(pad);
                                    wait(0.5);
                                    score++;
                                }
                                else {
                                    grad.lose(lcd);
                                    pad.tone(750.0,0.2);
                                    wait(0.5);
                                    pad.tone(750.0,0.2);
                                    wait(1.0);
                                }
                            }
                            currentGame = EXAM;
                            
                        break;
                        
                        // Game loop for Charmander's mini game
                        case CHARMANDER:
                            i = 0;
                            score = 0;
                            while (i < 3) {
                                // Indicate for which term the current game is in
                                if(i == 0) {grad.term_one(pad, lcd);}
                                else if(i == 1) {grad.term_two(pad, lcd);}
                                else{grad.term_three(pad, lcd);}
                                game_2.init(game_2_speed, game_2_cha, game_2_r);    // Set the game difficulty by changing speed and ratio between YouTube and normal icons according to year
                                int j = 0;
                                while(j < 6){
                                    game_2.read_input(device);
                                    game_2.update(pad, lcd, game_2_cha);
                                    game_2.render(lcd, game_2_cha);
                                    wait(1.0f/fps);
                                    j = game_2.get_count();
                                }
                                i = i++;
                                // determine if win condition is met, return score to proceed to EXAM game loop
                                if(game_2.get_count() == 6) {
                                    grad.win(lcd);
                                    music.win(pad);
                                    wait(0.5);
                                    score++;
                                }
                                else {
                                    grad.lose(lcd);
                                    pad.tone(750.0,0.2);
                                    wait(0.5);
                                    pad.tone(750.0,0.2);
                                    wait(1.0);
                                }
                            }
                            currentGame = EXAM;
                        break;
                        
                        // Game loop for EXAM
                        case EXAM:
                            // 1. Display the exam questions according to year.
                            // 2. Display the answers according to how many mini games the player passed.
                            // 3. If player manages to answer 2 or 3 questions correctly, enter to next year/GRADUATION.
                            // 4. If player fails, repeat the year.
                            
                            // Reset background music control parameter
                            finished = false;
                            
                            // Draw exam title screen
                            test.exam_title(pad, lcd);
                            
                            // Using thread to run music and exam functions in parallel
                            thread.start(gym);
                            
                            // Check for which year's exam questions need to be fetched
                            if(year == 0) {pass = test.exam_q_one(pad, lcd, score); finished = true;}
                            else if(year == 1) {pass = test.exam_q_two(pad, lcd, score); finished = true;}
                            else if(year == 2) {pass = test.exam_q_three(pad, lcd, score); finished = true;}
                            Thread::wait(1000);
                            thread.join();
                            // End the thread
                            
                            // Check for number of correct answers to determine if proceed to next year or not
                            if(pass > 2){
                                grad.passed(lcd);
                                music.win(pad);
                                wait(0.5);
                                year++;
                                if(year == 1){currentGame = YEAR_2;}
                                else if(year == 2){currentGame = YEAR_3;}
                                else if(year == 3){currentGame = GRADUATION;}
                            }
                            else {
                                grad.failed(lcd);
                                pad.tone(750.0,0.2);
                                wait(0.5);
                                pad.tone(750.0,0.2);
                                wait(1.0);
                                if(year == 0){currentGame = YEAR_1;}
                                else if(year == 1){
                                    if(select == 1){currentGame = SQUIRTLE;}
                                    else if(select == 0){currentGame = BULBASAUR;}
                                    else if(select == 2){currentGame = CHARMANDER;}
                                }
                                else if(year == 2){
                                    if(select == 1){currentGame = SQUIRTLE;}
                                    else if(select == 0){currentGame = BULBASAUR;}
                                    else if(select == 2){currentGame = CHARMANDER;}
                                }
                            }
                        break;
                        case YEAR_2:
                            // 1. Initiate year 2 screen
                            // 2. Set up the parameters for year 2
                            // 3. Initiate evolution animation for chosen character
                            // 4. Enter to game loop for chosen character
                            
                            grad.year_two(pad, lcd);
                            year_two_set(); // Set up the parameters for year 2
                            if(select == 1){
                                music.evolution_music(pad, lcd, select, year);      // Play the evolution animation and music for the chosen pokemon
                                while(pad.check_event(Gamepad::A_PRESSED) == false){
                                    lcd.drawSprite(2,40,9,8,(int*)button_A);
                                    lcd.refresh();
                                    wait(0.3);
                                    lcd.printString(" ",0,5);
                                    lcd.printString(" ",5,5);
                                    lcd.refresh();
                                    wait(0.3);
                                }
                                currentGame = SQUIRTLE;                             // Go back to game loop
                            }
                            else if(select == 0){
                                music.evolution_music(pad, lcd, select, year);      // Play the evolution animation and music for the chosen pokemon
                                while(pad.check_event(Gamepad::A_PRESSED) == false){
                                    lcd.drawSprite(2,40,9,8,(int*)button_A);
                                    lcd.refresh();
                                    wait(0.3);
                                    lcd.printString(" ",0,5);
                                    lcd.printString(" ",5,5);
                                    lcd.refresh();
                                    wait(0.3);
                                }
                                currentGame = BULBASAUR;                            // Go back to game loop
                            }
                            else if(select == 2){
                                music.evolution_music(pad, lcd, select, year);      // Play the evolution animation and music for the chosen pokemon
                                while(pad.check_event(Gamepad::A_PRESSED) == false){
                                    lcd.drawSprite(2,40,9,8,(int*)button_A);
                                    lcd.refresh();
                                    wait(0.3);
                                    lcd.printString(" ",0,5);
                                    lcd.printString(" ",5,5);
                                    lcd.refresh();
                                    wait(0.3);
                                }
                                currentGame = CHARMANDER;                           // Go back to game loop
                            }
                        break;
                        case YEAR_3:
                            // 1. Initiate year 3 screen
                            // 2. Set up the parameters for year 3
                            // 3. Initiate evolution animation for chosen character
                            // 4. Enter to game loop for chosen character
                            
                            grad.year_three(pad, lcd);
                            year_three_set();
                            if(select == 1){
                                music.evolution_music(pad, lcd, select, year);
                                while(pad.check_event(Gamepad::A_PRESSED) == false){
                                    lcd.drawSprite(2,40,9,8,(int*)button_A);
                                    lcd.refresh();
                                    wait(0.3);
                                    lcd.printString(" ",0,5);
                                    lcd.printString(" ",5,5);
                                    lcd.refresh();
                                    wait(0.3);
                                }
                                currentGame = SQUIRTLE;
                            }
                            else if(select == 0){
                                music.evolution_music(pad, lcd, select, year);
                                while(pad.check_event(Gamepad::A_PRESSED) == false){
                                    lcd.drawSprite(2,40,9,8,(int*)button_A);
                                    lcd.refresh();
                                    wait(0.3);
                                    lcd.printString(" ",0,5);
                                    lcd.printString(" ",5,5);
                                    lcd.refresh();
                                    wait(0.3);
                                }
                                currentGame = BULBASAUR;
                            }
                            else if(select == 2){
                                music.evolution_music(pad, lcd, select, year);
                                while(pad.check_event(Gamepad::A_PRESSED) == false){
                                    lcd.drawSprite(2,40,9,8,(int*)button_A);
                                    lcd.refresh();
                                    wait(0.3);
                                    lcd.printString(" ",0,5);
                                    lcd.printString(" ",5,5);
                                    lcd.refresh();
                                    wait(0.3);
                                }
                                currentGame = CHARMANDER;
                            }
                        break;
                        case GRADUATION:
                            // 1. Display congratulation theme for player!
                            // 2. Return to the TITLE screen
                            
                            grad.Grad_title(pad, lcd, select);
                            wait(1.0);
                            while(pad.check_event(Gamepad::A_PRESSED) == false){
                                    lcd.drawSprite(2,40,9,8,(int*)button_A);
                                    lcd.refresh();
                                    wait(0.3);
                                    lcd.printString(" ",0,5);
                                    lcd.printString(" ",5,5);
                                    lcd.refresh();
                                    wait(0.3);
                                }
                            end = true;
                        break;
                    }
                }
            }
            currentState = TITLE;
        break;
        
        case INSTRUCTION:
            // 1. Display instruction
            // 2. Return to MENU screen
            
            grad.instruction(pad, lcd);
            currentState = MENU;
        break;
        }
    }
}

// initialies all classes and libraries
void init()
{
    lcd.init();
    pad.init();
    device.init();
    // change set contrast in range 0.0 to 1.0
    // 0.4 appears to be a good starting point
    lcd.setContrast(0.4);
}

// Function for displaying the menu screen
int menu()
{
    // clear screen, re-draw and refresh
    lcd.clear();
    int pos_y = 5; // Set position for menu pointer
    while(pad.check_event(Gamepad::A_PRESSED) == false){
        lcd.clear();
        if(pad.get_direction() == N){
            pos_y = 5; // Set position for menu pointer to top option
        }else if(pad.get_direction() == S){
            pos_y = 16; // Set position for menu pointer to bottom option
        }
      int arrow_data[7][5] = {
            {1,1,0,0,0},
            {0,1,1,0,0},
            {0,0,1,1,0},
            {0,0,0,1,1},
            {0,0,1,1,0},
            {0,1,1,0,0},
            {1,1,0,0,0},
        };
        // draw pointer for selection
        lcd.drawSprite(5, pos_y, 7, 5, (int *)arrow_data);
        
        int op_one_data[7][26] = {
            {1,1,1,1,0,1,1,1,1,1,0,1,1,1,1,0,1,1,1,1,0,1,1,1,1,1},
            {1,0,0,1,0,0,0,1,0,0,0,1,0,0,1,0,1,0,0,1,0,0,0,1,0,0},
            {1,0,0,0,0,0,0,1,0,0,0,1,0,0,1,0,1,0,0,1,0,0,0,1,0,0},
            {1,1,1,1,0,0,0,1,0,0,0,1,1,1,1,0,1,1,1,0,0,0,0,1,0,0},
            {0,0,0,1,0,0,0,1,0,0,0,1,0,0,1,0,1,0,0,1,0,0,0,1,0,0},
            {0,0,0,1,0,0,0,1,0,0,0,1,0,0,1,0,1,0,0,1,0,0,0,1,0,0},
            {1,1,1,1,0,0,0,1,0,0,0,1,0,0,1,0,1,0,0,1,0,0,0,1,0,0},
        };
        // draw "START"
        lcd.drawSprite(18, 5, 7, 26, (int *)op_one_data);
        
        int op_two_data[7][18] = {
            {1,1,1,0,1,1,1,1,0,1,1,1,1,0,1,1,1,1},
            {0,1,0,0,1,0,0,1,0,1,0,0,1,0,1,0,0,1},
            {0,1,0,0,1,0,0,1,0,1,0,0,0,0,1,0,0,1},
            {0,1,0,0,1,0,0,1,0,1,1,1,0,0,1,0,0,1},
            {0,1,0,0,1,0,0,1,0,1,0,0,0,0,1,0,0,1},
            {0,1,0,0,1,0,0,1,0,1,0,0,0,0,1,0,0,1},
            {1,1,1,0,1,0,0,1,0,1,0,0,0,0,1,1,1,1},
        };
        // draw "INFO"
        lcd.drawSprite(18, 16, 7, 18, (int*) op_two_data);
        
        int instruct_data[7][75] = {
            {1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0},
            {1,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,1,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0},
            {1,0,0,1,0,1,1,1,1,0,1,1,1,1,0,1,1,1,1,0,1,1,1,1,0,0,0,0,1,0,0,1,0,0,0,0,1,1,1,0,0,1,1,1,1,0,0,0,0,1,1,1,1,0,1,1,1,1,0,1,0,1,1,1,1,0,1,1,1,1,0,1,1,1,0},
            {1,1,1,1,0,1,0,0,1,0,1,0,0,1,0,1,0,0,0,0,1,0,0,0,0,0,0,0,1,1,1,1,0,0,0,0,1,0,0,0,0,1,0,0,1,0,0,0,0,1,0,0,0,0,1,0,0,1,0,1,0,1,0,0,1,0,1,0,0,1,0,1,0,0,0},
            {1,0,0,0,0,1,0,0,0,0,1,1,1,1,0,1,1,1,1,0,1,1,1,1,0,0,0,0,1,0,0,1,0,0,0,0,1,0,0,0,0,1,0,0,1,0,0,0,0,1,1,1,1,0,1,1,1,1,0,1,0,1,1,1,1,0,1,0,0,0,0,1,0,0,0},
            {1,0,0,0,0,1,0,0,0,0,1,0,0,0,0,0,0,0,1,0,0,0,0,1,0,0,0,0,1,0,0,1,0,0,0,0,1,0,0,1,0,1,0,0,1,0,0,0,0,0,0,0,1,0,1,0,0,0,0,1,0,1,0,0,0,0,1,0,0,1,0,1,0,0,1},
            {1,0,0,0,0,1,0,0,0,0,1,1,1,1,0,1,1,1,1,0,1,1,1,1,0,0,0,0,1,0,0,1,0,0,0,0,1,1,1,1,0,1,1,1,1,0,0,0,0,1,1,1,1,0,1,1,1,1,0,1,0,1,1,1,1,0,1,1,1,1,0,1,1,1,1},
        };
        // draw instruction
        lcd.drawSprite(5, 38, 7, 75,(int *) instruct_data);
        lcd.refresh();
        
    }
    
    //return value for which menu option is currently selected
    int op = 0;
    if(pos_y == 5){op = 0;}
    else if(pos_y == 16){op = 1;}
    
    //return value for which menu option is currently selected
    return op;

}

// Function for setting year one game parameters
void year_one_set()
{
    year = 0;
    game_1_speed = 12;
    game_1_cha = 1;
    game_1_r = 5;
    game_2_speed = 1;
    game_2_cha = 1;
    game_2_r = 6;
    game_3_set = 1;
    game_3_time = 0.6;
}

// Function for setting year two game parameters
void year_two_set()
{
    year = 1;
    game_1_speed = 14;
    game_1_cha = 2;
    game_1_r = 3;
    game_2_speed = 2;
    game_2_cha = 2;
    game_2_r = 5;
    game_3_set = 2;
    game_3_time = 0.4;
}

// Function for setting year three game parameters
void year_three_set()
{
    year = 2;
    game_1_speed = 14;
    game_1_cha = 3;
    game_1_r = 2;
    game_2_speed = 2;
    game_2_cha = 3;
    game_2_r = 3;
    game_3_set = 3;
    game_3_time = 0.3;
}

// INTENSE music played in background during exams, music originally from Pokemon (R/B/Y) during GYM leader battle
void gym()
{
    // bar 1
    pad.tone(NOTE_B4,0.33/2);
    // to break out of the function
    if (finished == true) {return;}
    Thread::wait(330/2);
    pad.tone(NOTE_FS4,0.33/2);
    wait(0.33/2);
    pad.tone(NOTE_B3,0.33/2);
    wait(0.33/2);
    pad.tone(NOTE_FS4,0.33/2);
    wait(0.33/2);
    pad.tone(NOTE_B3,0.33/2);
    wait(0.33/2);
    pad.tone(NOTE_FS4,0.33/2);
    wait(0.33/2);
    pad.tone(NOTE_B3,0.33/2);
    wait(0.33/2);
    pad.tone(NOTE_FS4,0.33/2);
    wait(0.33/2);
    pad.tone(NOTE_B4,0.33/2);
    if (finished == true) {return;}
    Thread::wait(330/2);
    pad.tone(NOTE_FS4,0.33/2);
    wait(0.33/2);
    pad.tone(NOTE_B3,0.33/2);
    wait(0.33/2);
    pad.tone(NOTE_FS4,0.33/2);
    wait(0.33/2);
    pad.tone(NOTE_B3,0.33/2);
    wait(0.33/2);
    pad.tone(NOTE_C5,0.33*1.5);
    wait(0.33*1.5);
    // bar 3
    pad.tone(NOTE_B4,0.33/2);
    if (finished == true) {return;}
    Thread::wait(330/2);
    pad.tone(NOTE_FS4,0.33/2);
    wait(0.33/2);
    pad.tone(NOTE_B3,0.33/2);
    wait(0.33/2);
    pad.tone(NOTE_FS4,0.33/2);
    wait(0.33/2);
    pad.tone(NOTE_B3,0.33/2);
    wait(0.33/2);
    pad.tone(NOTE_FS4,0.33/2);
    wait(0.33/2);
    pad.tone(NOTE_B3,0.33/2);
    wait(0.33/2);
    pad.tone(NOTE_FS4,0.33/2);
    if (finished == true) {return;}
    Thread::wait(330/2);
    pad.tone(NOTE_B4,0.33/2);
    wait(0.33/2);
    pad.tone(NOTE_FS4,0.33/2);
    wait(0.33/2);
    pad.tone(NOTE_B3,0.33/2);
    wait(0.33/2);
    pad.tone(NOTE_FS4,0.33/2);
    wait(0.33/2);
    pad.tone(NOTE_B3,0.33/2);
    if (finished == true) {return;}
    Thread::wait(330/2);
    pad.tone(NOTE_AS4,0.33*1.5);
    wait(0.33*1.5);
    // bar 5
    pad.tone(NOTE_B4,0.33/2);
    if (finished == true) {return;}
    Thread::wait(330/2);
    pad.tone(NOTE_FS4,0.33/2);
    wait(0.33/2);
    pad.tone(NOTE_B3,0.33/2);
    wait(0.33/2);
    pad.tone(NOTE_FS4,0.33/2);
    wait(0.33/2);
    pad.tone(NOTE_B3,0.33/2);
    wait(0.33/2);
    pad.tone(NOTE_FS4,0.33/2);
    wait(0.33/2);
    pad.tone(NOTE_B3,0.33/2);
    if (finished == true) {return;}
    Thread::wait(330/2);
    pad.tone(NOTE_FS4,0.33/2);
    wait(0.33/2);
    pad.tone(NOTE_B4,0.33/2);
    wait(0.33/2);
    pad.tone(NOTE_FS4,0.33/2);
    wait(0.33/2);
    pad.tone(NOTE_B3,0.33/2);
    wait(0.33/2);
    pad.tone(NOTE_FS4,0.33/2);
    wait(0.33/2);
    pad.tone(NOTE_B3,0.33/2);
    if (finished == true) {return;}
    Thread::wait(330/2);
    pad.tone(NOTE_C5,0.33*1.5);
    wait(0.33*1.5);
    // bar 7
    pad.tone(NOTE_B4,0.33/2);
    if (finished == true) {return;}
    Thread::wait(330/2);
    pad.tone(NOTE_FS4,0.33/2);
    wait(0.33/2);
    pad.tone(NOTE_B3,0.33/2);
    wait(0.33/2);
    pad.tone(NOTE_FS4,0.33/2);
    wait(0.33/2);
    pad.tone(NOTE_B3,0.33/2);
    wait(0.33/2);
    pad.tone(NOTE_FS4,0.33/2);
    if (finished == true) {return;}
    Thread::wait(330/2);
    pad.tone(NOTE_B3,0.33/2);
    wait(0.33/2);
    pad.tone(NOTE_FS4,0.33/2);
    wait(0.33/2);
    pad.tone(NOTE_B4,0.33/2);
    wait(0.33/2);
    pad.tone(NOTE_FS4,0.33/2);
    wait(0.33/2);
    pad.tone(NOTE_B3,0.33/2);
    wait(0.33/2);
    pad.tone(NOTE_FS4,0.33/2);
    wait(0.33/2);
    pad.tone(NOTE_B3,0.33/2);
    if (finished == true) {return;}
    Thread::wait(330/2);
    pad.tone(NOTE_CS5,0.33*1.5);
    wait(0.33*1.5);
    
    // Loop while state is true
    while(!finished){
        // bar 8 
        pad.tone(NOTE_DS5,0.33);
        wait(0.33);
        pad.tone(NOTE_CS5,0.33);
        wait(0.33);
        pad.tone(NOTE_DS5,0.33);
        wait(0.33);
        pad.tone(NOTE_E5,0.33/2);
        Thread::wait(330/2);
        // to break out of the function
        if(finished == true) {break;}
        pad.tone(NOTE_FS5,0.33);
        wait(0.33);
        pad.tone(NOTE_E5,0.33);
        wait(0.33);
        pad.tone(NOTE_DS5,0.33/2);
        Thread::wait(330/2);
        if(finished == true) {break;}
        pad.tone(NOTE_CS5,0.33/2);
        wait(0.33/2);
        pad.tone(NOTE_B4,0.33/2);
        wait(0.33/2);
        pad.tone(NOTE_CS5,0.33/2);
        wait(0.33/2);
        pad.tone(NOTE_DS5,0.33/2);
        Thread::wait(330/2);
        if(finished == true) {break;}
        // bar 10
        pad.tone(NOTE_A4,0.33*2);
        wait(0.33*2);
        pad.tone(NOTE_CS5,0.33*2);
        Thread::wait(330*2);
        if(finished == true) {break;}
        pad.tone(NOTE_E5,0.33*2);
        wait(0.33*2);
        pad.tone(NOTE_CS5,0.33*2);
        Thread::wait(330*2);
        if(finished == true) {break;}
        // bar 8 
        pad.tone(NOTE_DS5,0.33);
        wait(0.33);
        pad.tone(NOTE_CS5,0.33);
        wait(0.33);
        pad.tone(NOTE_DS5,0.33);
        wait(0.33);
        pad.tone(NOTE_E5,0.33/2);
        Thread::wait(330/2);
        if(finished == true) {break;}
        pad.tone(NOTE_FS5,0.33);
        wait(0.33);
        pad.tone(NOTE_E5,0.33);
        wait(0.33);
        pad.tone(NOTE_DS5,0.33/2);
        wait(0.33/2);
        pad.tone(NOTE_CS5,0.33/2);
        wait(0.33/2);
        pad.tone(NOTE_B4,0.33/2);
        Thread::wait(330/2);
        if(finished == true) {break;}
        pad.tone(NOTE_CS5,0.33/2);
        wait(0.33/2);
        pad.tone(NOTE_DS5,0.33/2);
        wait(0.33/2);
        // bar 12
        pad.tone(NOTE_CS5,0.33*2);
        wait(0.33*2);
        pad.tone(NOTE_B4,0.33*2);
        Thread::wait(330*2);
        if(finished == true) {break;}
        pad.tone(NOTE_A4,0.33*2);
        wait(0.33*2);
        pad.tone(NOTE_E5,0.33);
        wait(0.33);
        pad.tone(NOTE_E5,0.33/2);
        wait(0.33/2);
        pad.tone(NOTE_CS5,0.33/2);
        Thread::wait(330/2);
        if(finished == true) {break;}
        // bar 14
        pad.tone(NOTE_B3,0.33/2);
        wait(0.33/2);
        pad.tone(NOTE_B3,0.33/2);
        wait(0.33/2);
        pad.tone(NOTE_D4,0.33/4);
        wait(0.33/4);
        pad.tone(NOTE_CS4,0.33/4);
        wait(0.33/4);
        pad.tone(NOTE_B3,0.33/4);
        wait(0.33/4);
        pad.tone(NOTE_D4,0.33/4);
        wait(0.33/4);
        pad.tone(NOTE_B3,0.33/2);
        Thread::wait(330/2);
        if(finished == true) {break;}
        pad.tone(NOTE_B3,0.33/2);
        wait(0.33/2);
        pad.tone(NOTE_E4,0.33/4);
        wait(0.33/4);
        pad.tone(NOTE_D4,0.33/4);
        wait(0.33/4);
        pad.tone(NOTE_B3,0.33/4);
        wait(0.33/4);
        pad.tone(NOTE_E4,0.33/4);
        wait(0.33/4);
        // bar 15
        pad.tone(NOTE_B3,0.33/2);
        wait(0.33/2);
        pad.tone(NOTE_B3,0.33/2);
        Thread::wait(330/2);
        if(finished == true) {break;}
        pad.tone(NOTE_FS4,0.33/4);
        wait(0.33/4);
        pad.tone(NOTE_E4,0.33/4);
        wait(0.33/4);
        pad.tone(NOTE_CS4,0.33/4);
        wait(0.33/4);
        pad.tone(NOTE_FS4,0.33/4);
        wait(0.33/4);
        pad.tone(NOTE_B3,0.33/2);
        wait(0.33/2);
        pad.tone(NOTE_E4,0.33/4);
        wait(0.33/4);
        pad.tone(NOTE_CS4,0.33/4);
        wait(0.33/4);
        pad.tone(NOTE_E4,0.25/2);
        Thread::wait(250/2);
        if(finished == true) {break;}
        pad.tone(NOTE_F4,0.25/2);
        wait(0.33/2);
        // bar 16
        pad.tone(NOTE_D4,0.33/4);
        wait(0.33/4);
        pad.tone(NOTE_CS4,0.33/4);
        wait(0.33/4);
        pad.tone(NOTE_B3,0.33/4);
        wait(0.33/4);
        pad.tone(NOTE_D4,0.33/4);
        wait(0.33/4);
        pad.tone(NOTE_B3,0.33/2);
        Thread::wait(330/2);
        if(finished == true) {break;}
        pad.tone(NOTE_B3,0.33/2);
        wait(0.33/2);
        pad.tone(NOTE_E4,0.33/4);
        wait(0.33/4);
        pad.tone(NOTE_D4,0.33/4);
        wait(0.33/4);
        pad.tone(NOTE_B3,0.33/4);
        wait(0.33/4);
        pad.tone(NOTE_E4,0.33/4);
        wait(0.33/4);
        pad.tone(NOTE_B3,0.33/2);
        wait(0.33/2);
        pad.tone(NOTE_B3,0.33/2);
        Thread::wait(330/2);
        if(finished == true) {break;}
        // bar 17
        pad.tone(NOTE_FS4,0.33/4);
        wait(0.33/4);
        pad.tone(NOTE_E4,0.33/4);
        wait(0.33/4);
        pad.tone(NOTE_CS4,0.33/4);
        wait(0.33/4);
        pad.tone(NOTE_FS4,0.33/4);
        wait(0.33/4);
        pad.tone(NOTE_E4,0.33/2);
        Thread::wait(330/2);
        if(finished == true) {break;}
        pad.tone(NOTE_CS4,0.33/2);
        wait(0.33/2);
        pad.tone(NOTE_D4,0.33/2);
        wait(0.33/2);
        pad.tone(NOTE_CS4,0.33/2);
        wait(0.33/2);
        pad.tone(NOTE_FS4,0.33/2);
        Thread::wait(330/2);
        if(finished == true) {break;}
        pad.tone(NOTE_E4,0.33/2);
        wait(0.33/2);
        // bar 18
        pad.tone(NOTE_B3,0.33/2);
        wait(0.33/2);
        pad.tone(NOTE_B3,0.33/2);
        wait(0.33/2);
        pad.tone(NOTE_B4,0.33);
        Thread::wait(330);
        if(finished == true) {break;}
        pad.tone(NOTE_C5,0.33);
        wait(0.33);
        pad.tone(NOTE_A4,0.33);
        wait(0.33);
        pad.tone(NOTE_B4,0.33);
        Thread::wait(330);
        if(finished == true) {break;}
        pad.tone(NOTE_C5,0.33);
        wait(0.33);
        pad.tone(NOTE_A4,0.33);
        wait(0.33);
        pad.tone(NOTE_G4,0.33);
        Thread::wait(330);
        if(finished == true) {break;}
        // bar 19
        pad.tone(NOTE_FS4,0.33*4);
        wait(0.33);
        pad.tone(NOTE_C4,0.33/4);
        wait(0.33/4);
        pad.tone(NOTE_B3,0.33/4);
        wait(0.33/4);
        pad.tone(NOTE_A3,0.33/4);
        wait(0.33/4);
        pad.tone(NOTE_B3,0.33/4);
        Thread::wait(330/4);
        if(finished == true) {break;}
        pad.tone(NOTE_C4,0.33/4);
        wait(0.33/4);
        pad.tone(NOTE_B3,0.33/4);
        wait(0.33/4);
        pad.tone(NOTE_A3,0.33/4);
        wait(0.33/4);
        pad.tone(NOTE_B3,0.33/4);
        wait(0.33/4);
        pad.tone(NOTE_C4,0.33/4);
        wait(0.33/4);
        pad.tone(NOTE_B3,0.33/4);
        Thread::wait(330/4);
        if(finished == true) {break;}
        pad.tone(NOTE_A3,0.33/4);
        wait(0.33/4);
        pad.tone(NOTE_B3,0.33/4);
        wait(0.33/4);
        // bar 20
        pad.tone(NOTE_C4,0.33/4);
        wait(0.33/4);
        pad.tone(NOTE_CS4,0.33/4);
        wait(0.33/4);
        pad.tone(NOTE_D4,0.33/4);
        wait(0.33/4);
        pad.tone(NOTE_DS4,0.33/4);
        Thread::wait(330/4);
        if(finished == true) {break;}
        pad.tone(NOTE_E4,0.33/4);
        wait(0.33/4);
        pad.tone(NOTE_DS4,0.33/4);
        wait(0.33/4);
        pad.tone(NOTE_D4,0.33/4);
        wait(0.33/4);
        pad.tone(NOTE_CS4,0.33/4);
        wait(0.33/4);
        pad.tone(NOTE_C4,0.33/4);
        wait(0.33/4);
        pad.tone(NOTE_B3,0.33/4);
        Thread::wait(330/4);
        if(finished == true) {break;}
        pad.tone(NOTE_AS3,0.33/4);
        wait(0.33/4);
        pad.tone(NOTE_A3,0.33/4);
        wait(0.33/4);
        pad.tone(NOTE_GS3,0.33/4);
        wait(0.33/4);
        pad.tone(NOTE_G3,0.33/4);
        wait(0.33/4);
        pad.tone(NOTE_FS3,0.33/4);
        Thread::wait(330/4);
        if(finished == true) {break;}
        pad.tone(NOTE_G3,0.33/4);
        wait(0.33/4);
        // bar 22
        pad.tone(NOTE_GS3,0.33/4);
        wait(0.33/4);
        pad.tone(NOTE_A3,0.33/4);
        wait(0.33/4);
        pad.tone(NOTE_AS3,0.33/4);
        wait(0.33/4);
        pad.tone(NOTE_B3,0.33/4);
        Thread::wait(330/4);
        if(finished == true) {break;}
        pad.tone(NOTE_B4,0.33);
        wait(0.33);
        pad.tone(NOTE_C5,0.33);
        wait(0.33);
        pad.tone(NOTE_A4,0.33);
        Thread::wait(330);
        if(finished == true) {break;}
        pad.tone(NOTE_B4,0.33);
        wait(0.33);
        pad.tone(NOTE_C5,0.33);
        wait(0.33);
        pad.tone(NOTE_A4,0.33);
        Thread::wait(330);
        if(finished == true) {break;}
        pad.tone(NOTE_C5,0.33);
        wait(0.33);
        pad.tone(NOTE_B4,0.33*4);
        wait(0.33*4);
        pad.tone(NOTE_FS5,0.33*4);
        Thread::wait(330*4);
        if(finished == true) {break;}
        // bar 26
        pad.tone(NOTE_B3,0.33/2);
        wait(0.33/2);
        pad.tone(NOTE_B3,0.33/2);
        Thread::wait(330/2);
        if(finished == true) {break;}
        pad.tone(NOTE_A4,0.33*3);
        wait(0.33*3);
        pad.tone(NOTE_B3,0.33/2);
        wait(0.33/2);
        pad.tone(NOTE_B3,0.33/2);
        Thread::wait(330/2);
        if(finished == true) {break;}
        pad.tone(NOTE_CS5,0.33*3);
        wait(0.33*3);
        pad.tone(NOTE_DS4,0.33);
        wait(0.33);
        pad.tone(NOTE_CS4,0.33);
        wait(0.33);
        pad.tone(NOTE_DS4,0.33);
        Thread::wait(330);
        if(finished == true) {break;}
        pad.tone(NOTE_E4,0.33/2);
        wait(0.33/2);
        pad.tone(NOTE_FS4,0.33/2);
        wait(0.33/2);
        pad.tone(NOTE_B3,0.33/2);
        wait(0.33/2);
        pad.tone(NOTE_B3,0.33/2);
        Thread::wait(330/2);
        if(finished == true) {break;}
        pad.tone(NOTE_CS4,0.33/2);
        wait(0.33/2);
        pad.tone(NOTE_FS4,0.33/2);
        wait(0.33/2);
        pad.tone(NOTE_B4,0.33/2);
        wait(0.33/2);
        pad.tone(NOTE_FS4,0.33/2);
        Thread::wait(330/2);
        if(finished == true) {break;}
        pad.tone(NOTE_DS4,0.33/2);
        wait(0.33/2);
        pad.tone(NOTE_FS4,0.33/2);
        wait(0.33/2);
        // bar 30
        pad.tone(NOTE_B3,0.33/2);
        wait(0.33/2);
        pad.tone(NOTE_B3,0.33/2);
        Thread::wait(330/2);
        if(finished == true) {break;}
        pad.tone(NOTE_CS5,0.33*3);
        wait(0.33*3);
        pad.tone(NOTE_A5,0.33*2);
        Thread::wait(330*2);
        if(finished == true) {break;}
        pad.tone(NOTE_E5,0.33*2);
        wait(0.33*2);
        // bar 32
        pad.tone(NOTE_B5,0.33*4);
        wait(0.33);
        pad.tone(NOTE_E4,0.33);
        Thread::wait(330);
        if(finished == true) {break;}
        pad.tone(NOTE_CS4,0.33/2);
        wait(0.33/2);
        pad.tone(NOTE_DS4,0.33*1.5);
        wait(0.33*1.5);
        pad.tone(NOTE_FS4,0.33);
        Thread::wait(330);
        if(finished == true) {break;}
        pad.tone(NOTE_E4,0.33/2);
        wait(0.33/2);
        pad.tone(NOTE_DS4,0.33);
        Thread::wait(330);
        if(finished == true) {break;}
        pad.tone(NOTE_E4,0.33*1.5);
        wait(0.33*1.5);
        // bar 34
        pad.tone(NOTE_DS4,0.33);
        wait(0.33);
        pad.tone(NOTE_E4,0.33);
        Thread::wait(330);
        if(finished == true) {break;}
        pad.tone(NOTE_CS4,0.33/2);
        wait(0.33/2);
        pad.tone(NOTE_DS4,0.33*1.5);
        wait(0.33*1.5);
        pad.tone(NOTE_FS4,0.33);
        Thread::wait(330);
        if(finished == true) {break;}
        pad.tone(NOTE_A4,0.33/2);
        wait(0.33/2);
        pad.tone(NOTE_GS4,0.33);
        Thread::wait(330);
        if(finished == true) {break;}
        pad.tone(NOTE_G4,0.33*1.5);
        wait(0.33/2);
        pad.tone(NOTE_B4,0.33/4);
        wait(0.33/4);
        pad.tone(NOTE_DS5,0.33/4);
        wait(0.33/4);
        pad.tone(NOTE_FS5,0.33/4);
        wait(0.33/4);
        pad.tone(NOTE_AS5,0.33/4);
        Thread::wait(330/4);
        if(finished == true) {break;}
        // bar 36
        pad.tone(NOTE_B5,0.33*4);
        wait(0.33);
        pad.tone(NOTE_E4,0.33);
        Thread::wait(330);
        if(finished == true) {break;}
        pad.tone(NOTE_CS4,0.33/2);
        wait(0.33/2);
        pad.tone(NOTE_DS4,0.33*1.5);
        wait(0.33*1.5);
        pad.tone(NOTE_FS5,0.33);
        Thread::wait(330);
        if(finished == true) {break;}
        pad.tone(NOTE_DS4,0.33/2);
        wait(0.33/2);
        pad.tone(NOTE_CS4,0.33);
        Thread::wait(330);
        if(finished == true) {break;}
        pad.tone(NOTE_C4,0.33*1.5);
        wait(0.33*1.5);
        // bar 38
        pad.tone(NOTE_A5,0.33*4);
        wait(0.33);
        pad.tone(NOTE_E4,0.33);
        Thread::wait(330);
        if(finished == true) {break;}
        pad.tone(NOTE_CS4,0.33/2);
        wait(0.33/2);
        pad.tone(NOTE_DS4,0.33*1.5);
        wait(0.33*1.5);
        pad.tone(NOTE_CS6,0.33);
        Thread::wait(330);
        if(finished == true) {break;}
        pad.tone(NOTE_A4,0.33/2);
        wait(0.33/2);
        pad.tone(NOTE_GS4,0.33);
        Thread::wait(330);
        if(finished == true) {break;}
        pad.tone(NOTE_A5,0.33*1.5);
        wait(0.33*1.5);
    }
}