Compare commits
No commits in common. "023960695fe4ef135614df95c485f0c01955ba32" and "ccfec88c41092465c811829a9c9f50fa3aa3e806" have entirely different histories.
023960695f
...
ccfec88c41
19
README.md
19
README.md
@ -1,4 +1,4 @@
|
||||
# Typing-Test-C
|
||||
# Typing-Test-C (WIP)
|
||||
|
||||
|
||||
<p align="center">
|
||||
@ -33,7 +33,6 @@
|
||||
|
||||
* Download source files
|
||||
* Install ncurses (If not already installed)
|
||||
* On Debian Systems: ```sudo apt install libncurses5-dev libncursesw5-dev```
|
||||
* Compile Using ```gcc typing_test.c utilities.c -lncurses```
|
||||
* OR: Run ```make``` using Makefile
|
||||
|
||||
@ -56,23 +55,19 @@ Find it [here](https://github.com/ahaas25/Typing-Test-C/releases/tag/milestone)
|
||||
Second release goal:
|
||||
The second release goal for this project is to have a much more refined project. I hope to have all modes implemented, the UI to automatically wrap the console size, and user keystroke analysis if time permits. I'm hoping to have this release out by early January. (It's finals season so I won't have much time to work on this project until late December)
|
||||
|
||||
Second release goal reached! Due to time constraints, not all features were implemented in this release.
|
||||
Find it [here](https://github.com/ahaas25/Typing-Test-C/releases/tag/milestone2)
|
||||
|
||||
Current status of project:
|
||||
|
||||
Code:
|
||||
* Reading of words.txt *implemented*
|
||||
* Random word picking *implemented*
|
||||
* Different test lengths *implemented*
|
||||
* Timed Tests *implemented*
|
||||
* Timed Tests to be implemented
|
||||
* Test results screen *implemeted*
|
||||
* Saving user stats *implemented*
|
||||
* ~~Per-key stats~~ May be added in a feature release
|
||||
* Saving user stats to be implemented
|
||||
* Per-key stats to be implemented
|
||||
|
||||
UI:
|
||||
* Main menu *implemented*
|
||||
* Typing prompt *implemented*
|
||||
* Stats menu *implemented*
|
||||
* Settings menu *implemented*
|
||||
* Themes
|
||||
* Typing prompt *in progress*
|
||||
* Stats menu to be implemented
|
||||
* Settings menu to be implemented
|
||||
|
@ -4,7 +4,6 @@
|
||||
#include <string.h>
|
||||
#include <ncurses.h>
|
||||
#include <sys/time.h>
|
||||
#include <time.h>
|
||||
#include "utilities.h"
|
||||
#include "typing_test.h"
|
||||
|
||||
@ -32,14 +31,15 @@ void debug_words() {
|
||||
}
|
||||
|
||||
void debug_stats() {
|
||||
int i;
|
||||
FILE *stats_file;
|
||||
Stat_struct x;
|
||||
char buf[256], temp[256];
|
||||
int temp_stat;
|
||||
stats_file = fopen("stats", "r");
|
||||
|
||||
load_stats(stats_file, &x);
|
||||
|
||||
for (i = 0; i < 9; i++) {
|
||||
for (int i = 0; i < 9; i++) {
|
||||
printf("%d\n", x.data[i]);
|
||||
}
|
||||
|
||||
@ -47,6 +47,5 @@ void debug_stats() {
|
||||
|
||||
int main() {
|
||||
debug_stats();
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
310
typing_test.c
310
typing_test.c
@ -38,20 +38,6 @@ void print_centered_text_menu(WINDOW *win, int row, int target, char str[][MAX_S
|
||||
}
|
||||
}
|
||||
|
||||
/* Highlights text if cursor points to the col */
|
||||
void print_centered_text_menu_single(WINDOW *win, int row, int target, char str[]) {
|
||||
int text_length = strlen(str), cursor;
|
||||
|
||||
cursor = (win->_maxx - text_length) / 2;
|
||||
move(row, cursor);
|
||||
|
||||
if (target == row) {
|
||||
attron(A_STANDOUT);
|
||||
}
|
||||
printw(str);
|
||||
attroff(A_STANDOUT);
|
||||
}
|
||||
|
||||
/* Prints the typing prompt onto the terminal.
|
||||
Automatically centers, wraps, and scrolls through text */
|
||||
void print_typing_prompt(WINDOW *win, Word_array *prompt, char *prompt_string,
|
||||
@ -85,49 +71,41 @@ void print_typing_prompt(WINDOW *win, Word_array *prompt, char *prompt_string,
|
||||
}
|
||||
|
||||
void typing_ui(WINDOW *win, int level, int mode, Word_array *word_array, Stat_struct *stats) {
|
||||
int run = 1, ch, i, new_test = 1, user_input_length, start_timer, line = 4, end_test, row;
|
||||
int timed_reserved_accuracy, timed_reserved_characters;
|
||||
double test_time, wpm, wpm_raw, accuracy, elapsed_time;
|
||||
long long time_start, time_stop, misc;
|
||||
int run = 1, ch, i, new_test = 1, user_input_length, start_timer;
|
||||
double test_time, wpm, accuracy;
|
||||
char str[1024], temp[24], *user_input = NULL;
|
||||
char *prompt_string = NULL; /* Full prompt string */
|
||||
Word_array *prompt = NULL;
|
||||
Word *prompt_lines; /* Array of lines for displaying */
|
||||
struct timeval timer_start, timer_stop, test_end;
|
||||
struct timeval timer_start, timer_stop;
|
||||
while (run) {
|
||||
if (new_test == 1 || new_test == 2) {
|
||||
/* Reset Vars */
|
||||
if (new_test == 1) {
|
||||
clear();
|
||||
accuracy = 0;
|
||||
curs_set(1);
|
||||
|
||||
if (new_test == 1) {
|
||||
timed_reserved_accuracy = 0;
|
||||
timed_reserved_characters = 0;
|
||||
}
|
||||
|
||||
/* Reset str */
|
||||
str[0] = '\0';
|
||||
|
||||
if (mode == 0) {
|
||||
strcat(str, "Timed Test - ");
|
||||
strcat(str, TIMED_MODES_STRING[level]);
|
||||
print_centered_text(stdscr, 0, str);
|
||||
} else {
|
||||
strcat(str, "Word Test - ");
|
||||
strcat(str, WORD_MODES_STRING[level]);
|
||||
print_centered_text(stdscr, 0, str);
|
||||
}
|
||||
|
||||
if (prompt == NULL) {
|
||||
prompt = malloc(sizeof(Word_array));
|
||||
} else {
|
||||
clear_word_array(prompt);
|
||||
}
|
||||
|
||||
/* Draw UI */
|
||||
if (mode == 0) {
|
||||
strcat(str, "Timed Test - ");
|
||||
strcat(str, TIMED_MODES_STRING[level]);
|
||||
print_centered_text(stdscr, 0, str);
|
||||
end_test = 0;
|
||||
generate_words(WORD_MODES[2], word_array, prompt);
|
||||
} else {
|
||||
strcat(str, "Word Test - ");
|
||||
strcat(str, WORD_MODES_STRING[level]);
|
||||
print_centered_text(stdscr, 0, str);
|
||||
/* Only works for words mode for now, no timed */
|
||||
|
||||
generate_words(WORD_MODES[level], word_array, prompt);
|
||||
}
|
||||
|
||||
if (user_input != NULL) {
|
||||
free(user_input);
|
||||
@ -137,6 +115,8 @@ void typing_ui(WINDOW *win, int level, int mode, Word_array *word_array, Stat_st
|
||||
user_input[0] = '\0';
|
||||
user_input_length = 0;
|
||||
|
||||
new_test = 0;
|
||||
|
||||
prompt_string = malloc(prompt->num_characters); /* For easier parsing of prompt */
|
||||
prompt_string[0] = '\0';
|
||||
|
||||
@ -151,21 +131,10 @@ void typing_ui(WINDOW *win, int level, int mode, Word_array *word_array, Stat_st
|
||||
printf("%s", user_input);
|
||||
|
||||
print_typing_prompt(win, prompt, prompt_string, user_input);
|
||||
|
||||
if (new_test == 1) {
|
||||
start_timer = 1; /* Flag timer as ready to be started */
|
||||
timed_reserved_accuracy = 0;
|
||||
timed_reserved_characters = 0;
|
||||
} else {
|
||||
start_timer = 0;
|
||||
}
|
||||
|
||||
new_test = 0;
|
||||
|
||||
}
|
||||
|
||||
ch = getch();
|
||||
|
||||
if (isalnum(ch) || ch == ' ' || ch == '\'') { /* If typing prompt character */
|
||||
if (start_timer) {
|
||||
gettimeofday(&timer_start, NULL);
|
||||
@ -198,95 +167,26 @@ void typing_ui(WINDOW *win, int level, int mode, Word_array *word_array, Stat_st
|
||||
}
|
||||
|
||||
user_input_length = strlen(user_input);
|
||||
|
||||
/* If timed test, see if test is still going */
|
||||
/* Test if last keystroke is ignored */
|
||||
if (mode == 0) {
|
||||
gettimeofday(&test_end, NULL);
|
||||
|
||||
time_start = timer_start.tv_sec * 1000LL + timer_start.tv_usec / 1000;
|
||||
misc = test_end.tv_sec * 1000LL + test_end.tv_usec / 1000;
|
||||
|
||||
elapsed_time = misc - time_start; /* Calculates elapsed time of test in seconds */
|
||||
elapsed_time /= 1000;
|
||||
|
||||
/* Checks if test is over */
|
||||
if (elapsed_time >= TIMED_MODES[level]) {
|
||||
end_test = 1;
|
||||
/* Ignores last keystroke */
|
||||
user_input_length--;
|
||||
accuracy--;
|
||||
|
||||
clear();
|
||||
row = 4;
|
||||
print_centered_text(win, row++, "Time's up!");
|
||||
print_centered_text(win, row++, "Press Enter to See Results");
|
||||
print_centered_text(win, row++, "Or Tab to start a new test");
|
||||
|
||||
while (1) {
|
||||
ch = getch();
|
||||
if (ch == '\n') {
|
||||
break;
|
||||
} else if (ch == 27) { /* If esc, end and do not save results */
|
||||
run = 0;
|
||||
end_test = 0;
|
||||
break;
|
||||
} else if (ch == ' ') {
|
||||
new_test = 1;
|
||||
end_test = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
elapsed_time = 0;
|
||||
}
|
||||
|
||||
/* End of test */
|
||||
if ((user_input_length == strlen(prompt_string) && user_input[user_input_length - 1] == prompt_string[user_input_length - 1]) || (mode == 0 && end_test)) {
|
||||
if (mode == 0 && !end_test) {
|
||||
/* If timed test is not over yet */
|
||||
timed_reserved_accuracy += accuracy;
|
||||
timed_reserved_characters += user_input_length;
|
||||
new_test = 2;
|
||||
} else {
|
||||
/* If end of test screen should be shown */
|
||||
if (mode == 0) {
|
||||
/* If finished test was a timed test */
|
||||
accuracy += timed_reserved_accuracy;
|
||||
user_input_length += timed_reserved_characters;
|
||||
test_time = TIMED_MODES[level];
|
||||
} else {
|
||||
/* If finished test was a word test */
|
||||
/* Convert time stamps to miliseconds */
|
||||
if (user_input_length == strlen(prompt_string) && user_input[user_input_length - 1] == prompt_string[user_input_length - 1]) {
|
||||
gettimeofday(&timer_stop, NULL);
|
||||
time_start = timer_start.tv_sec * 1000LL + timer_start.tv_usec / 1000;
|
||||
time_stop = timer_stop.tv_sec * 1000LL + timer_stop.tv_usec / 1000;
|
||||
|
||||
/* Subtract starting time from ending time to get elapsed time */
|
||||
test_time = time_stop - time_start;
|
||||
test_time /= 1000; /* Convert time into seconds */
|
||||
}
|
||||
|
||||
/* WPM = (Total Chars / 5) /(Total Mins) */
|
||||
wpm = (accuracy / 5) / (test_time / 60);
|
||||
wpm_raw = ((double)user_input_length / 5) / (test_time / 60);
|
||||
|
||||
/* Update stats */
|
||||
stats->data[TESTS_COMPLETE]++;
|
||||
stats->data[CHARS_TYPED] += user_input_length;
|
||||
stats->data[CHARS_CORRECT] += accuracy;
|
||||
stats->data[TIME_TYPED] += (test_time * 10);
|
||||
/* Multiply by 10 to more precision */
|
||||
/* Convert time stamps to miliseconds */
|
||||
long long time_start = timer_start.tv_sec * 1000LL + timer_start.tv_usec / 1000;
|
||||
long long time_stop = timer_stop.tv_sec * 1000LL + timer_stop.tv_usec / 1000;
|
||||
|
||||
/* Calculate accuracy */
|
||||
accuracy = (accuracy / user_input_length) * 100;
|
||||
|
||||
/* Subtract starting time from ending time to get elapsed time */
|
||||
test_time = time_stop - time_start;
|
||||
test_time /= 1000; /* Convert time into seconds */
|
||||
|
||||
/* WPM = (Total Chars / 5) /(Total Mins) */
|
||||
wpm = ((double)user_input_length / 5) / (test_time / 60);
|
||||
|
||||
clear();
|
||||
|
||||
/* Print end screen */
|
||||
|
||||
line = 4;
|
||||
|
||||
print_centered_text(stdscr, 0, str); /* Print test type */
|
||||
curs_set(0);
|
||||
print_centered_text(win, 2, "Test Complete!");
|
||||
@ -298,14 +198,7 @@ void typing_ui(WINDOW *win, int level, int mode, Word_array *word_array, Stat_st
|
||||
append_line("WPM: ", str);
|
||||
gcvt(wpm, 5, temp);
|
||||
append_line(temp, str);
|
||||
print_centered_text(win, line++, str);
|
||||
|
||||
str[0] = '\0';
|
||||
append_line("Raw WPM: ", str);
|
||||
gcvt(wpm_raw, 5, temp);
|
||||
append_line(temp, str);
|
||||
print_centered_text(win, line++, str);
|
||||
|
||||
print_centered_text(win, 4, str);
|
||||
|
||||
/* Generate Accuracy String */
|
||||
str[0] = '\0';
|
||||
@ -313,7 +206,7 @@ void typing_ui(WINDOW *win, int level, int mode, Word_array *word_array, Stat_st
|
||||
gcvt(accuracy, 5, temp);
|
||||
append_line(temp, str);
|
||||
append_line("\%%", str);
|
||||
print_centered_text(win, line++, str);
|
||||
print_centered_text(win, 5, str);
|
||||
|
||||
/* Generate Time String */
|
||||
str[0] = '\0';
|
||||
@ -321,57 +214,53 @@ void typing_ui(WINDOW *win, int level, int mode, Word_array *word_array, Stat_st
|
||||
gcvt(test_time, 5, temp);
|
||||
append_line(temp, str);
|
||||
append_line("s", str);
|
||||
print_centered_text(win, line++, str);
|
||||
print_centered_text(win, 6, str);
|
||||
|
||||
/* Generate Characters String */
|
||||
str[0] = '\0';
|
||||
append_line("Characters: ", str);
|
||||
sprintf(temp, "%d", user_input_length);
|
||||
append_line(temp, str);
|
||||
print_centered_text(win, line++, str);
|
||||
print_centered_text(win, 7, str);
|
||||
|
||||
print_centered_text(win, 19, "Press tab to start a new test, or any key to return to main menu");
|
||||
|
||||
/* Stats are only for word mode */
|
||||
if (mode == 1) {
|
||||
stats->data[TESTS_COMPLETE]++;
|
||||
|
||||
switch (level) {
|
||||
case 0:
|
||||
if (stats->data[W_5] < (int)wpm) {
|
||||
stats->data[W_5] = (int)wpm;
|
||||
print_centered_text(win, 17, "New High Score!");
|
||||
update_max_wpm(stats);
|
||||
}
|
||||
break;
|
||||
case 1:
|
||||
if (stats->data[W_10] < (int)wpm) {
|
||||
stats->data[W_10] = (int)wpm;
|
||||
print_centered_text(win, 17, "New High Score!");
|
||||
update_max_wpm(stats);
|
||||
}
|
||||
break;
|
||||
case 2:
|
||||
if (stats->data[W_25] < (int)wpm) {
|
||||
stats->data[W_25] = (int)wpm;
|
||||
print_centered_text(win, 17, "New High Score!");
|
||||
update_max_wpm(stats);
|
||||
}
|
||||
break;
|
||||
case 3:
|
||||
if (stats->data[W_50] < (int)wpm) {
|
||||
stats->data[W_50] = (int)wpm;
|
||||
print_centered_text(win, 17, "New High Score!");
|
||||
update_max_wpm(stats);
|
||||
}
|
||||
break;
|
||||
case 4:
|
||||
if (stats->data[W_100] < (int)wpm) {
|
||||
stats->data[W_100] = (int)wpm;
|
||||
print_centered_text(win, 17, "New High Score!");
|
||||
update_max_wpm(stats);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* Wait on user input */
|
||||
ch = getch();
|
||||
@ -381,8 +270,6 @@ void typing_ui(WINDOW *win, int level, int mode, Word_array *word_array, Stat_st
|
||||
} else {
|
||||
new_test = 1;
|
||||
}
|
||||
}
|
||||
|
||||
} else {
|
||||
/* Prints typing prompt after all input is done processing */
|
||||
print_typing_prompt(win, prompt, prompt_string, user_input);
|
||||
@ -395,70 +282,25 @@ void typing_ui(WINDOW *win, int level, int mode, Word_array *word_array, Stat_st
|
||||
|
||||
/* Draws settings UI to console */
|
||||
/* Placeholder, will work on next */
|
||||
void settings_ui(WINDOW *win, Stat_struct *stats) {
|
||||
FILE *stats_file;
|
||||
int selection = 13, row = 0, count = 2, run = 1;
|
||||
int selections[] = { 8, 11, 13 };
|
||||
int ch;
|
||||
|
||||
while (run) {
|
||||
void settings_ui(WINDOW *win) {
|
||||
char ch;
|
||||
clear();
|
||||
row = 0;
|
||||
print_centered_text(win, row, "Settings");
|
||||
print_centered_text(win, 0, "Settings");
|
||||
|
||||
row += 3;
|
||||
print_centered_text(win, row++, "Controls");
|
||||
print_centered_text(win, row++, "Tab - Reset Test");
|
||||
print_centered_text(win, row, "Esc - End Test");
|
||||
print_centered_text(win, 3, "Controls");
|
||||
print_centered_text(win, 4, "Tab - Reset Test");
|
||||
print_centered_text(win, 5, "Esc - End Test");
|
||||
|
||||
row += 2;
|
||||
print_centered_text(win, 7, "Themes");
|
||||
print_centered_text(win, 8, "Default");
|
||||
|
||||
print_centered_text(win, row++, "Themes");
|
||||
print_centered_text_menu_single(win, row, selection, "Default");
|
||||
print_centered_text(win, 10, "Statistics");
|
||||
print_centered_text(win, 11, "Reset Stats");
|
||||
|
||||
row += 2;
|
||||
|
||||
print_centered_text(win, row++, "Statistics");
|
||||
print_centered_text_menu_single(win, row, selection, "Reset Stats");
|
||||
|
||||
row += 2;
|
||||
|
||||
print_centered_text_menu_single(win, row, selection, "Return to Menu");
|
||||
print_centered_text(win, 13, "Return to Menu");
|
||||
refresh();
|
||||
|
||||
ch = getch();
|
||||
|
||||
switch (ch) {
|
||||
case KEY_UP:
|
||||
if (count == 0) {
|
||||
count = 2;
|
||||
} else {
|
||||
count--;
|
||||
}
|
||||
break;
|
||||
case KEY_DOWN:
|
||||
if (count < 2) {
|
||||
count++;
|
||||
} else {
|
||||
count = 0;
|
||||
}
|
||||
break;
|
||||
case '\n':
|
||||
if (count == 2) { /* Exit menu */
|
||||
run = 0;
|
||||
} else if (count == 1) { /* Clear stats */
|
||||
stats_file = fopen(STATS_FILEPATH, "w");
|
||||
create_stats_file(stats_file);
|
||||
stats_file = fopen(STATS_FILEPATH, "r");
|
||||
load_stats(stats_file, stats);
|
||||
}
|
||||
}
|
||||
selection = selections[count];
|
||||
move(0, 0);
|
||||
printw("The count is: %d", count);
|
||||
refresh();
|
||||
}
|
||||
|
||||
ch = getchar();
|
||||
clear();
|
||||
}
|
||||
|
||||
@ -466,7 +308,6 @@ void settings_ui(WINDOW *win, Stat_struct *stats) {
|
||||
/* Placeholder, will work on next */
|
||||
void stat_ui(WINDOW *win, Stat_struct *stats) {
|
||||
int row = 0;
|
||||
double temp;
|
||||
char ch, temp_str[MAX_STRING], temp_num[MAX_STRING];
|
||||
clear();
|
||||
|
||||
@ -476,91 +317,72 @@ void stat_ui(WINDOW *win, Stat_struct *stats) {
|
||||
|
||||
row += 3;
|
||||
append_line("Best WPM: ", temp_str);
|
||||
gcvt((double)stats->data[BEST_WPM], 5, temp_num);
|
||||
gcvt(stats->data[BEST_WPM], 5, temp_num);
|
||||
append_line(temp_num, temp_str);
|
||||
print_centered_text(win, row, temp_str);
|
||||
row++;
|
||||
temp_str[0] = '\0';
|
||||
|
||||
append_line("Average WPM: ", temp_str);
|
||||
temp = (((double)stats->data[CHARS_CORRECT]) / 5) / (((double)stats->data[TIME_TYPED]) / 600);
|
||||
gcvt(temp, 5, temp_num);
|
||||
/* Calculate here */
|
||||
append_line(temp_num, temp_str);
|
||||
print_centered_text(win, row, temp_str);
|
||||
row++;
|
||||
temp_str[0] = '\0';
|
||||
|
||||
append_line("Average Accuracy: ", temp_str);
|
||||
temp = ((double)stats->data[CHARS_CORRECT] / (double)stats->data[CHARS_TYPED]) * 100;
|
||||
gcvt(temp, 5, temp_num);
|
||||
append_line(temp_num, temp_str);
|
||||
append_line("\%%", temp_str);
|
||||
print_centered_text(win, row, temp_str);
|
||||
row++;
|
||||
temp_str[0] = '\0';
|
||||
|
||||
append_line("Tests Completed: ", temp_str);
|
||||
gcvt((double)stats->data[TESTS_COMPLETE], 5, temp_num);
|
||||
append_line(temp_num, temp_str);
|
||||
print_centered_text(win, row, temp_str);
|
||||
row++;
|
||||
temp_str[0] = '\0';
|
||||
|
||||
append_line("Keys Typed: ", temp_str);
|
||||
gcvt((double)stats->data[CHARS_TYPED], 5, temp_num);
|
||||
gcvt(stats->data[TESTS_COMPLETE], 5, temp_num);
|
||||
append_line(temp_num, temp_str);
|
||||
print_centered_text(win, row, temp_str);
|
||||
row++;
|
||||
temp_str[0] = '\0';
|
||||
|
||||
append_line("Time Spent Typing: ", temp_str);
|
||||
gcvt((double)stats->data[TIME_TYPED] / 600, 5, temp_num);
|
||||
gcvt(stats->data[TIME_TYPED], 5, temp_num);
|
||||
append_line(temp_num, temp_str);
|
||||
append_line(" min", temp_str);
|
||||
print_centered_text(win, row, temp_str);
|
||||
row += 2;
|
||||
temp_str[0] = '\0';
|
||||
|
||||
append_line("5 Word Test: ", temp_str);
|
||||
gcvt((double)stats->data[W_5], 5, temp_num);
|
||||
gcvt(stats->data[W_5], 5, temp_num);
|
||||
append_line(temp_num, temp_str);
|
||||
print_centered_text(win, row, temp_str);
|
||||
row++;
|
||||
temp_str[0] = '\0';
|
||||
|
||||
append_line("10 Word Test: ", temp_str);
|
||||
gcvt((double)stats->data[W_10], 5, temp_num);
|
||||
gcvt(stats->data[W_10], 5, temp_num);
|
||||
append_line(temp_num, temp_str);
|
||||
print_centered_text(win, row, temp_str);
|
||||
row++;
|
||||
temp_str[0] = '\0';
|
||||
|
||||
append_line("25 Word Test: ", temp_str);
|
||||
gcvt((double)stats->data[W_25], 5, temp_num);
|
||||
gcvt(stats->data[W_25], 5, temp_num);
|
||||
append_line(temp_num, temp_str);
|
||||
print_centered_text(win, row, temp_str);
|
||||
row++;
|
||||
temp_str[0] = '\0';
|
||||
|
||||
append_line("50 Word Test: ", temp_str);
|
||||
gcvt((double)stats->data[W_50], 5, temp_num);
|
||||
gcvt(stats->data[W_50], 5, temp_num);
|
||||
append_line(temp_num, temp_str);
|
||||
print_centered_text(win, row, temp_str);
|
||||
row++;
|
||||
temp_str[0] = '\0';
|
||||
|
||||
append_line("100 Word Test: ", temp_str);
|
||||
gcvt((double)stats->data[W_100], 5, temp_num);
|
||||
gcvt(stats->data[W_100], 5, temp_num);
|
||||
append_line(temp_num, temp_str);
|
||||
print_centered_text(win, row, temp_str);
|
||||
row += 2;
|
||||
row++;
|
||||
temp_str[0] = '\0';
|
||||
|
||||
print_centered_text(win, row, "Return to Menu");
|
||||
print_centered_text(win, 15, "Return to Menu");
|
||||
refresh();
|
||||
|
||||
ch = getchar();
|
||||
|
||||
clear();
|
||||
}
|
||||
|
||||
@ -579,8 +401,8 @@ int main() {
|
||||
noecho();
|
||||
|
||||
print_centered_text(stdscr, 4, "Loading...");
|
||||
words_file = fopen(WORDS_FILEPATH, "r");
|
||||
stats_file = fopen(STATS_FILEPATH, "r");
|
||||
words_file = fopen("words.txt", "r");
|
||||
stats_file = fopen("stats", "r");
|
||||
|
||||
if (has_colors() == FALSE) {
|
||||
print_centered_text(stdscr, 4, "Your terminal does not support color");
|
||||
@ -610,9 +432,9 @@ int main() {
|
||||
|
||||
/* Creates a new stats file if one is not detected */
|
||||
if (stats_file == NULL) {
|
||||
stats_file = fopen(STATS_FILEPATH, "w");
|
||||
stats_file = fopen("stats", "w");
|
||||
create_stats_file(stats_file);
|
||||
stats_file = fopen(STATS_FILEPATH, "r");
|
||||
stats_file = fopen("stats", "r");
|
||||
}
|
||||
|
||||
/* Load stats from stats file */
|
||||
@ -677,7 +499,7 @@ int main() {
|
||||
stat_ui(stdscr, &stats);
|
||||
} else if (cursor_x == 2 && cursor_y == 2) {
|
||||
/* Settings */
|
||||
settings_ui(stdscr, &stats);
|
||||
settings_ui(stdscr);
|
||||
} else if (cursor_y == 1 || cursor_y == 0) {
|
||||
typing_ui(stdscr, cursor_x, cursor_y, word_array, &stats);
|
||||
clear();
|
||||
@ -692,7 +514,7 @@ int main() {
|
||||
|
||||
/* Saves stats and closes file */
|
||||
/* Open stats first */
|
||||
stats_file = fopen(STATS_FILEPATH, "w");
|
||||
stats_file = fopen("stats", "w");
|
||||
save_stats(stats_file, &stats);
|
||||
|
||||
return 0;
|
||||
|
@ -14,8 +14,6 @@
|
||||
#define NUM_MISC 3
|
||||
#define SUCCESS 1
|
||||
#define FAILURE 0
|
||||
#define WORDS_FILEPATH "words.txt"
|
||||
#define STATS_FILEPATH "stats"
|
||||
|
||||
char TIMED_MODES_STRING[5][MAX_STRING] = { "5s", "10s", "25s", "30s", "60s" };
|
||||
int TIMED_MODES[5] = {5, 10, 25, 30, 60};
|
||||
|
15
utilities.c
15
utilities.c
@ -107,25 +107,12 @@ int save_stats(FILE *stats_file, Stat_struct *stats) {
|
||||
int i;
|
||||
|
||||
for (i = 0; i < NUM_STATS; i++) {
|
||||
fprintf(stats_file, "%d\n", stats->data[i]);
|
||||
fprintf(stats_file, "%f\n", stats->data[i]);
|
||||
}
|
||||
|
||||
fclose(stats_file);
|
||||
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
/* Finds highest WPM score */
|
||||
int update_max_wpm(Stat_struct *stats) {
|
||||
int i, max = stats->data[W_5];
|
||||
for (i = W_5; i <= W_100; i++) {
|
||||
if (max < stats->data[i]) {
|
||||
max = stats->data[i];
|
||||
}
|
||||
}
|
||||
stats->data[BEST_WPM] = max;
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
/* Appends first parameter to the end of end of the second parameter
|
||||
(Does not change size of the target, assumes there is space) */
|
||||
|
@ -37,7 +37,7 @@ typedef struct {
|
||||
} Word_array;
|
||||
|
||||
typedef struct {
|
||||
int data[NUM_STATS];
|
||||
double data[NUM_STATS];
|
||||
} Stat_struct;
|
||||
|
||||
void clear_word_array(Word_array *array);
|
||||
@ -47,4 +47,3 @@ int create_stats_file(FILE *stats_file);
|
||||
int load_stats(FILE *stats_file, Stat_struct *stats);
|
||||
int save_stats(FILE *stats_file, Stat_struct *stats);
|
||||
void append_line(char *source, char *target);
|
||||
int update_max_wpm(Stat_struct *stats);
|
Loading…
x
Reference in New Issue
Block a user