-
Notifications
You must be signed in to change notification settings - Fork 0
/
ftxtest.cpp
142 lines (119 loc) · 4.4 KB
/
ftxtest.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
#include <iostream>
#include <fstream>
#include <vector>
#include <random>
#include <chrono>
#include <thread>
#include <ftxui/component/component.hpp>
#include <ftxui/screen/screen.hpp>
#include <ftxui/dom/elements.hpp>
using namespace ftxui;
using namespace std;
vector<string> readWordsFromFile(const string& filename) {
vector<string> words;
ifstream file(filename);
if (file.is_open()) {
string word;
while (file >> word) {
words.push_back(word);
}
file.close();
}
return words;
}
string generateSentence(const vector<string>& words) {
string sentence;
unsigned seed = static_cast<unsigned>(chrono::system_clock::now().time_since_epoch().count());
mt19937 rng(seed);
uniform_int_distribution<int> dist(0, words.size() - 1);
int n = 20;
for (int i = 0; i < n; ++i) {
sentence += words[dist(rng)] + " ";
}
sentence += "↵"; // Unicode for "↵"
return sentence;
}
int main(int argc, const char* argv[]) {
// Initialize the ftxui screen.
Screen screen;
Elements elements;
// Read words from file.
vector<string> words = readWordsFromFile("words.txt");
// Generate a random sentence.
string sentence = generateSentence(words);
// Greet the user.
elements.push_back(text(L"Welcome to the Typing Test! Press Enter to start."));
// Wait for Enter key press.
char key;
while (screen.Loop(1000 / 60)) {
if (key == 'q')
return 0;
if (key == '\n')
break;
}
// Display the sentence.
elements.push_back(text(L"Type the following sentence:"));
elements.push_back(text(sentence));
// Start the timer.
auto start_time = std::chrono::steady_clock::now();
// Read user input.
wstring typed_sentence;
int correct_words = 0;
int typed_word_index = 0;
while (typed_word_index < words.size()) {
auto elapsed_time = std::chrono::steady_clock::now() - start_time;
float elapsed_seconds = std::chrono::duration_cast<std::chrono::milliseconds>(elapsed_time).count() / 1000.0f;
int typed_sentence_length = typed_sentence.length();
bool is_typing = typed_sentence_length < sentence.length() && sentence[typed_sentence_length] != L' ';
wchar_t typed_char;
screen.Render([&](ftxui::Screen& screen) {
auto container = vbox({});
container->Add(text(L"Time elapsed: " + to_wstring(elapsed_seconds) + L"s"));
container->Add(text(L"Type the following sentence:"));
container->Add(text(sentence));
if (is_typing) {
typed_char = typed_sentence[typed_sentence_length];
if (typed_char == sentence[typed_sentence_length]) {
correct_words++;
typed_word_index++;
}
typed_sentence_length++;
container->Add(text(typed_sentence.substr(0, typed_sentence_length)));
container->Add(text(typed_sentence.substr(typed_sentence_length)));
} else {
container->Add(text(L"Press Enter to finish."));
}
return container;
});
// Process keyboard input.
while (screen.PollEvent(&key)) {
if (key == 'q')
return 0;
if (key == '\n') {
// Finish typing.
while (screen.PollEvent(&key)) {}
break;
}
if (is_typing) {
typed_sentence += key;
}
}
// Update the screen.
screen.PostLoop();
}
// Calculate typing speed and accuracy.
auto end_time = std::chrono::steady_clock::now();
float elapsed_seconds = std::chrono::duration_cast<std::chrono::milliseconds>(end_time - start_time).count() / 1000.0f;
float typing_speed = static_cast<float>(correct_words) / elapsed_seconds * 60.0f;
float accuracy = static_cast<float>(correct_words) / words.size() * 100.0f;
// Display results.
elements.push_back(text(L"Time elapsed: " + to_wstring(elapsed_seconds) + L"s"));
elements.push_back(text(L"Typing speed: " + to_wstring(typing_speed) + L" words per minute"));
elements.push_back(text(L"Accuracy: " + to_wstring(accuracy) + L"%"));
// Wait for Enter key press to exit.
while (screen.Loop(1000 / 60)) {
if (key == 'q' || key == '\n')
break;
}
return 0;
}