// TODO(dev): use 'halfdelay()' to parse input for pi menu choice 'secret.' // NOTE(dev): Gonna need this: // mvwprintw(win, y, x, string); /* Move to (y, x) relative to window */ // /* co-ordinates and then print */ #include #include "Problem.h" #include #include #define PROMPT " > " std::vector GenerateProblems(bool addition, bool subtraction, bool multiplication, bool division); char MainMenu(); int main(int argc, char *argv[]) { initscr(); noecho(); // don't show user input cbreak(); // handle user input immediately (i.e. don't wait for the user to press enter) keypad(stdscr, true); // enable the numpad, F1-F12 keys, arrow keys, etc. while(true) { // game boolean flags: bool addition = false; bool subtraction = false; bool multiplication = false; bool division = false; // Main Menu: char menu_action = MainMenu(); if(menu_action == 'q') break; else if(menu_action == '1') addition = true; else if(menu_action == '2') subtraction = true; else if(menu_action == '3') addition = subtraction = true; else if(menu_action == '4') multiplication = true; else if(menu_action == '5') division = true; else if(menu_action == '6') multiplication = division = true; else continue; // restart loop clear(); wrefresh(stdscr); std::vector problems = GenerateProblems(addition, subtraction, multiplication, division); std::vector::iterator selected = problems.begin(); INPUT_STYLE input_style = INPUT_STYLE::INPUT_APPEND; for(auto *problem : problems) if(problem) problem->Draw(problem == *selected, input_style); // Keep track of time: auto start_time = std::chrono::steady_clock::now(); unsigned int input = 'q'; while(selected != problems.end() && *selected) { Problem *current_problem = *selected; current_problem->Draw(true, input_style); // refresh with new input input = getch(); if(input == 'q') // early exit break; switch(input) { case KEY_LEFT: input_style = INPUT_STYLE::INPUT_PREPEND; break; case KEY_RIGHT: input_style = INPUT_STYLE::INPUT_APPEND; break; case KEY_BACKSPACE: current_problem->ClearInput(); break; case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': current_problem->Input(input_style, input); break; }; // NOTE(dev): If the answer is zero and they hit backspace to clear input, it treated it // as if they had entered zero themselves. if(input != KEY_BACKSPACE && current_problem->Correct()) ++selected; current_problem->Draw(current_problem == *selected, input_style); // refresh with new input } if(input != 'q') // if you didn't quit { // Keep track of time: auto end_time = std::chrono::steady_clock::now(); auto elapsed_time = std::chrono::duration_cast(end_time - start_time); int middle_h = COLS / 2; int middle_v = LINES / 2; clear(); mvprintw(middle_v - 3, middle_h - 5, "You did it!"); mvprintw(middle_v - 1, middle_h - 14, "Questions Answered: %7d\n", problems.size()); mvprintw(middle_v - 0, middle_h - 8, "Time Elapsed: %02dm %02ds\n", elapsed_time / 60, elapsed_time % 60); mvprintw(middle_v + 1, middle_h - 13, "Time Per Question: %02dm %02ds\n", (elapsed_time / problems.size() / 60), (elapsed_time / problems.size() % 60)); mvprintw(middle_v + 3, middle_h - 8, "Press Q to quit."); box(stdscr, '*', '*'); wrefresh(stdscr); while(!(getch() == 'q')) ; } for(auto *problem : problems) if(problem) delete problem; } endwin(); return 0; } char MainMenu() { int middle_h = COLS / 2; int middle_v = LINES / 2; clear(); mvprintw(middle_v - 6, middle_h - 20, "\n"); mvprintw(middle_v - 5, middle_h - 20, " Welcome to Math Practice.\n"); mvprintw(middle_v - 4, middle_h - 20, " Please choose from the following menu:\n"); mvprintw(middle_v - 3, middle_h - 20, " 1. Addition\n"); mvprintw(middle_v - 2, middle_h - 20, " 2. Subtraction\n"); mvprintw(middle_v - 1, middle_h - 20, " 3. Both / Mixed\n"); mvprintw(middle_v - 0, middle_h - 20, " 4. Multiplication\n"); mvprintw(middle_v + 1, middle_h - 20, " 5. Division\n"); mvprintw(middle_v + 2, middle_h - 20, " 6. Both / Mixed\n"); mvprintw(middle_v + 3, middle_h - 20, " q. Quit\n"); mvprintw(middle_v + 4, middle_h - 20, "\n"); mvprintw(middle_v + 5, middle_h - 20, PROMPT); refresh(); return getch(); } std::vector GenerateProblems(bool addition, bool subtraction, bool multiplication, bool division) { std::vector rtn; for(auto y = 1; y < LINES - 10; y += 9) { for(auto x = 2; x < COLS - 16; x += 15) { Problem *test = nullptr; if(addition || subtraction) { if(addition != subtraction) { if(addition) test = new Problem(EASY_ADDITION, 3, x, y); if(subtraction) test = new Problem(EASY_SUBTRACTION, 3, x, y); } else { if(rand() % 2) test = new Problem(HARD_ADDITION, 5, x, y); else test = new Problem(HARD_SUBTRACTION, 5, x, y); } rtn.push_back(test); } if(multiplication || division) { if(multiplication && !division) test = new Problem(EASY_MULTIPLICATION, 2, x, y); else if(division && !multiplication) test = new Problem(EASY_DIVISION, 2, x, y); else { // TODO(dev): Add hard problems if(rand() % 2) test = new Problem(HARD_MULTIPLICATION, 3, x, y); else test = new Problem(HARD_DIVISION, 3, x, y); } rtn.push_back(test); } } } return rtn; }