box-o-sand/PracticingCurses/JustForFun/tt.c

224 lines
5.4 KiB
C

#include <curses.h>
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#define HSIZE 60
#define LENGTH 75
#define WIDTH 10
#define STARTX 1
#define STARTY 5
#define STATUSX 1
#define STATUSY 25
#define KEY_F1 265
int print_menu();
void print_byebye();
void create_test_string();
void print_time(time_t startt, time_t endt, int mistakes);
void print_in_middle(int startx, int starty, int width, char *string, WINDOW *win);
char *groups[] = { "`123456" ,
"7890-=" ,
"~!@#$%^" ,
"&*()_+" ,
"<>?" ,
",./\\" ,
"asdfg",
"jkl;'",
"qwer",
"uiop",
"tyur",
"zxcv",
"bnm",
};
int n_groups;
int main()
{ int choice, i;
char *test_array;
int ch = KEY_F1;
int mistakes;
int x, y;
time_t start_t, end_t;
WINDOW *typing_win;
char string[80];
string[0] = '\0';
initscr();
cbreak();
noecho();
keypad(stdscr, TRUE);
intrflush(stdscr, FALSE);
srandom(time(NULL));
n_groups = sizeof(groups) / sizeof(char *);
test_array = (char *)calloc(HSIZE + 1, sizeof(char));
while(1)
{
if(ch == KEY_F1)
{ choice = print_menu();
choice -= 1;
if(choice == n_groups)
{ print_byebye();
free(test_array);
endwin();
exit(0);
}
}
clear();
strcpy(string, "Typing window");
print_in_middle(STARTX, STARTY - 2, LENGTH, string, NULL);
attron(A_REVERSE);
mvprintw(STATUSY, STATUSX, "Press F1 to Main Menu");
refresh();
attroff(A_REVERSE);
create_test_string(test_array, choice);
typing_win = newwin(WIDTH, LENGTH, STARTY, STARTX);
keypad(typing_win, TRUE);
intrflush(typing_win, FALSE);
box(typing_win, 0, 0);
x = 1;
y = 1;
mvwprintw(typing_win, y, x, "%s", test_array);
wrefresh(typing_win);
y += 1;
mistakes = 0;
i = 0;
time(&start_t);
wmove(typing_win, y, x);
wrefresh(typing_win);
ch = 0;
while(ch != KEY_F1 && i != HSIZE + 1)
{ ch = wgetch(typing_win);
mvwprintw(typing_win, y, x, "%c", ch);
wrefresh(typing_win);
++x;
if(ch == test_array[i])
{ ++i;
continue;
}
else
{ ++mistakes;
++i;
}
}
time(&end_t);
print_time(start_t, end_t, mistakes);
}
free(test_array);
endwin();
return 0;
}
int print_menu()
{ int choice, i;
choice = 0;
while(1)
{ clear();
printw("\n\n");
print_in_middle(1, 1, 0, "* * * Welcome to typing practice (Version 1.0) * * * ", NULL);
printw("\n\n\n");
for(i = 0;i <= n_groups - 1; ++i)
printw("\t%3d: \tPractice %s\n", i + 1, groups[i]);
printw("\t%3d: \tExit\n", i + 1);
printw("\n\n\tChoice: ");
refresh();
echo();
scanw("%d", &choice);
noecho();
if(choice >= 1 && choice <= n_groups + 1)
break;
else
{ attron(A_REVERSE);
mvprintw(STATUSY, STATUSX, "Wrong choice\tPress any key to continue");
attroff(A_REVERSE);
getch();
}
}
return choice;
}
void create_test_string(char *test_array, int choice)
{ int i, index, length;
length = strlen(groups[choice]);
for(i = 0;i <= HSIZE - 1; ++i)
{ if(i%5 == 0)
test_array[i] = ' ';
else
{ index = (int)(random() % length);
test_array[i] = groups[choice][index];
}
}
test_array[i] = '\0';
}
void print_byebye()
{ printw("\n");
print_in_middle(0,0,0,"Thank you for using my typing tutor\n", NULL);
print_in_middle(0,0,0,"Bye Bye ! ! !\n", NULL);
refresh();
}
void print_time(time_t start_t, time_t end_t, int mistakes)
{ long int diff;
int h,m,s;
float wpm;
diff = end_t - start_t;
wpm = ((HSIZE / 5)/(double)diff)*60;
h = (int)(diff / 3600);
diff -= h * 3600;
m = (int)(diff / 60);
diff -= m * 60;
s = (int)diff;
attron(A_REVERSE);
mvprintw(STATUSY, STATUSX, "Mistakes made : %d time taken: %d:%d:%d WPM : %.2f Press any Key to continue", mistakes, h, m, s, wpm);
attroff(A_REVERSE);
refresh();
getch();
}
/* ---------------------------------------------------------------- *
* startx = 0 means at present x *
* starty = 0 means at present y *
* win = NULL means take stdscr *
* ---------------------------------------------------------------- */
void print_in_middle(int startx, int starty, int width, char *string, WINDOW *win)
{ int length, x, y;
float temp;
if(win == NULL)
win = stdscr;
getyx(win, y, x);
if(startx != 0)
x = startx;
if(starty != 0)
y = starty;
if(width == 0)
width = 80;
length = strlen(string);
temp = (width - length)/ 2;
x = startx + (int)temp;
mvwprintw(win, y, x, "%s", string);
refresh();
}