-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathtyping_simulator_v1.c
More file actions
241 lines (191 loc) · 8.23 KB
/
Copy pathtyping_simulator_v1.c
File metadata and controls
241 lines (191 loc) · 8.23 KB
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
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
// gcc typing_simulator.c -o typing_simulator -lncurses
#include <ncurses.h>
#include <unistd.h>
#include <stdlib.h>
#include <time.h>
#include <string.h>
#include <ctype.h>
//#define DELAY_MIN 30000 // Минимум задержки в микросекундах
//#define DELAY_MAX 300000 // Максимум задержки в микросекундах
#define DELAY_MIN 40000 // Минимум задержки в микросекундах
#define DELAY_MAX 400000 // Максимум задержки в микросекундах
//#define ERROR_PROB 0.05 // Вероятность ошибки
#define ERROR_PROB 0.020 // Вероятность ошибки
int count_of_scroll = 0; // Количество прокрутки окна
int color_pair = 1; // Переменная для сохранения текущего цвета печати в консоли
void ms_sleep(int ms) {
usleep(ms * 1000);
}
void update_status_line() {
int y, x;
getyx(stdscr, y, x);
int current_lines = getmaxy(stdscr);
// Создание строки состояния
char status[140];
snprintf(status, sizeof(status), "-- INSERT -- %d,%d", y + 1 + count_of_scroll, x + 1);
//mvprintw(LINES - 1, 0, "-- INSERT -- %d,%d", y, x);
// Перемещение курсора в самый низ экрана
//move(LINES - 1, 0);
move(current_lines - 1, 0);
// Очистка строки состояния (чтобы не было остатков от предыдущих обновлений)
//getch(); // test: Ждем нажатия любой клавиши для проверки
//clrtoeol();
// Отображение строки состояния
//attron(A_REVERSE); // Обратные цвета для выделения строки состояния
attron(COLOR_PAIR(1));
printw("%s", status);
attroff(COLOR_PAIR(1));
//attroff(A_REVERSE);
// Возвращение курсора на его исходную позицию
move(y, x);
// Отобразить все изменения на экране
refresh();
}
void delete_last_char() {
if(getcurx(stdscr) > 0) {
move(getcury(stdscr), getcurx(stdscr) - 1);
addch(' ');
move(getcury(stdscr), getcurx(stdscr) - 1);
refresh();
usleep(rand() % (DELAY_MAX - DELAY_MIN + 1) + DELAY_MIN);
update_status_line(); // Обновляем строку состояния после вывода символа
}
}
// Ошибка: печатаем случайный символ
void type_with_errors () {
// Генерируем случайный символ из расширенного набора
const char char_set[] =
"abcdefghijklmnopqrstuvwxyz" // строчные буквы
"ABCDEFGHIJKLMNOPQRSTUVWXYZ" // заглавные буквы
"0123456789" // цифры
"`~!@#$%^&*()-=_+[]\\{}|;':\",./<>? "; // спецсимволы
int num_of_chars = sizeof(char_set) - 1; // -1, т.к. последний символ '\0'
char randomChar = char_set[rand() % num_of_chars];
//attron(COLOR_PAIR(1)); // Цвет для обычных строк
addch(randomChar);
//attroff(COLOR_PAIR(1)); // Сброс цвета
refresh();
usleep(rand() % (DELAY_MAX - DELAY_MIN + 1) + DELAY_MIN);
// Удаляем его
delete_last_char();
attron(COLOR_PAIR(color_pair)); // Цвет для обычных строк
refresh();
usleep(rand() % (DELAY_MAX - DELAY_MIN + 1) + DELAY_MIN);
}
void type_char(char c) {
int y, x;
getyx(stdscr, y, x); // Получаем текущие координаты курсора
int current_lines = getmaxy(stdscr);
// Проверяем, достигли ли мы предпоследней строки и выводим ли символ новой строки
if (y == LINES - 2 && c == '\n') { // -2, чтобы не затереть строку состояния
// Очистка последней строки (где выводится строка состояния)
move(current_lines - 1, 0);
clrtoeol();
// Перемещаем курсор на предпоследнюю строку
move(current_lines - 2 - 1, x);
refresh();
scrollok(stdscr, TRUE); // Включаем прокрутку
wscrl(stdscr, 1); // Сдвигаем содержимое окна вверх на одну строку
refresh();
// Перемещаем курсор на предпоследнюю строку
//move(LINES - 2 - 1, 0);
//move(current_lines - 2 - 1, x);
// Увеличиваем счётчик прокрутки окна для вывода информации
// в строке состояния
count_of_scroll++;
}
if ((double)rand() / RAND_MAX < ERROR_PROB) {
type_with_errors();
}
addch(c);
// Отобразить все изменения на экране
refresh();
update_status_line(); // Обновляем строку состояния после вывода символа
usleep(rand() % (DELAY_MAX - DELAY_MIN + 1) + DELAY_MIN);
}
void print_highlighted(const char* code) {
const char* keywords[] = {"int", "bool", "vector", "return", "if", "else", "while", "for", "void"};
int num_keywords = sizeof(keywords) / sizeof(keywords[0]);
while (*code) {
int is_keyword = 0;
for (int i = 0; i < num_keywords; i++) {
size_t len = strlen(keywords[i]);
if (strncmp(code, keywords[i], len) == 0 && !isalnum(code[len])) {
for (size_t j = 0; j < len; j++) {
color_pair = 2;
attron(COLOR_PAIR(2)); // Цвет для ключевых слов
type_char(*code++);
attroff(COLOR_PAIR(2)); // Сброс цвета
}
is_keyword = 1;
break;
}
}
if (!is_keyword) {
if (*code == '"') {
do {
color_pair = 3;
attron(COLOR_PAIR(3)); // Цвет для переменных с типом строк
type_char(*code++);
attroff(COLOR_PAIR(3)); // Сброс цвета
} while (*code && *code != '"');
color_pair = 3;
attron(COLOR_PAIR(3)); // Цвет для переменных с типом строк
type_char(*code++);
attroff(COLOR_PAIR(3)); // Сброс цвета
} else {
color_pair = 1;
attron(COLOR_PAIR(1)); // Цвет для обычных строк
type_char(*code++);
attroff(COLOR_PAIR(1)); // Сброс цвета
}
}
}
}
void read_code_from_file(const char* filename, char** buffer) {
FILE* file = fopen(filename, "r");
if (!file) {
perror("Не удалось открыть файл");
exit(EXIT_FAILURE);
}
fseek(file, 0, SEEK_END);
long length = ftell(file);
fseek(file, 0, SEEK_SET);
*buffer = malloc(length + 1);
if (!*buffer) {
perror("Не удалось выделить память");
exit(EXIT_FAILURE);
}
fread(*buffer, 1, length, file);
(*buffer)[length] = '\0';
fclose(file);
}
int main() {
srand(time(NULL));
// Инициализация ncurses
initscr();
start_color();
// Установка фона по умолчанию
use_default_colors();
cbreak();
noecho();
curs_set(1); // Включить отображение курсора
// Определение цветовых пар
init_pair(1, COLOR_GREEN, -1); // Цвет для обычных строк (прозрачный фон)
init_pair(2, COLOR_WHITE, -1); // Цвет для ключевых слов (прозрачный фон)
init_pair(3, COLOR_YELLOW, -1); // Цвет для переменных с типом строк (прозрачный фон)
// Очистка экрана
clear();
char* code = NULL;
read_code_from_file("code.c", &code);
print_highlighted(code);
free(code);
// Обновление и отображение позиции курсора
update_status_line(); // Вызов функции для отображения строки состояния
// Ожидание ввода перед выходом
getch();
// Завершение работы с ncurses
curs_set(0); // Скрыть курсор
endwin();
return 0;
}