Загрузка данных


using System;
using System.Collections.Generic;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;
using System.Windows.Media;

namespace KeyboardTrainer
{
    public partial class MainWindow : Window
    {
        private Dictionary<Key, Button> keyButtons = new Dictionary<Key, Button>();
        private string targetText = "";
        private int currentIndex = 0;
        private int errors = 0;
        private int correctChars = 0;
        private int totalChars = 0;
        private DateTime startTime;
        private System.Windows.Threading.DispatcherTimer timer;
        private bool isTraining = false;
        private enum DifficultyLevel { Easy, Medium, Hard }
        private DifficultyLevel currentLevel = DifficultyLevel.Medium;

        public MainWindow()
        {
            InitializeComponent();
            InitializeKeyboard();
            timer = new System.Windows.Threading.DispatcherTimer();
            timer.Interval = TimeSpan.FromSeconds(1);
            timer.Tick += Timer_Tick;
        }

        private void InitializeKeyboard()
        {
            // Ваш код инициализации клавиатуры
            string[][] layout = new string[][]
            {
                new string[] { "`", "1", "2", "3", "4", "5", "6", "7", "8", "9", "0", "-", "=", "Back" },
                new string[] { "Tab", "Q", "W", "E", "R", "T", "Y", "U", "I", "O", "P", "[", "]", "\\" },
                new string[] { "Caps", "A", "S", "D", "F", "G", "H", "J", "K", "L", ";", "'", "Enter" },
                new string[] { "Shift", "Z", "X", "C", "V", "B", "N", "M", ",", ".", "/", "Shift" },
                new string[] { "Ctrl", "Win", "Alt", "Space", "Alt", "Win", "Menu", "Ctrl" }
            };

            var keyMap = new Dictionary<string, Key>
            {
                { "Back", Key.Back }, { "Tab", Key.Tab }, { "Caps", Key.CapsLock },
                { "Enter", Key.Enter }, { "Shift", Key.LeftShift }, { "Ctrl", Key.LeftCtrl },
                { "Win", Key.LWin }, { "Alt", Key.LeftAlt }, { "Menu", Key.Apps }, { "Space", Key.Space }
            };

            foreach (var row in layout)
            {
                StackPanel rowPanel = new StackPanel 
                { 
                    Orientation = Orientation.Horizontal, 
                    Margin = new Thickness(0, 2, 0, 2) 
                };

                if (row == layout[1]) rowPanel.Margin = new Thickness(15, 2, 0, 2);
                else if (row == layout[2]) rowPanel.Margin = new Thickness(25, 2, 0, 2);
                else if (row == layout[3]) rowPanel.Margin = new Thickness(35, 2, 0, 2);
                else if (row == layout[4]) rowPanel.Margin = new Thickness(20, 2, 0, 2);

                foreach (string keyName in row)
                {
                    Button btn = new Button
                    {
                        Content = keyName,
                        Style = (Style)FindResource("KeyButtonStyle"),
                        Tag = keyName
                    };

                    // Установка ширины для специальных клавиш
                    if (keyName == "Back" || keyName == "Tab") btn.Width = 75;
                    else if (keyName == "Caps" || keyName == "Enter") btn.Width = 80;
                    else if (keyName == "Shift") btn.Width = 85;
                    else if (keyName == "Space") btn.Width = 250;
                    else if (keyName == "Ctrl" || keyName == "Alt" || keyName == "Win" || keyName == "Menu") btn.Width = 55;

                    Key key;
                    if (keyMap.ContainsKey(keyName))
                        key = keyMap[keyName];
                    else if (keyName.Length == 1 && char.IsLetterOrDigit(keyName[0]))
                        key = (Key)Enum.Parse(typeof(Key), keyName.ToUpper());
                    else
                        key = Key.None;

                    if (key != Key.None)
                        keyButtons[key] = btn;

                    rowPanel.Children.Add(btn);
                }
                KeyboardPanel.Children.Add(rowPanel);
            }
        }

        // ИСПРАВЛЕННАЯ ФУНКЦИЯ ПОДСВЕТКИ
        private void HighlightKey(Key key)
        {
            // Сбрасываем цвет всех клавиш
            foreach (var btn in keyButtons.Values)
                btn.Background = (Brush)new BrushConverter().ConvertFrom("#E8E8E8");

            // Подсвечиваем нажатую клавишу
            if (keyButtons.ContainsKey(key))
            {
                keyButtons[key].Background = Brushes.Yellow;
            }
            // Проверяем модификаторы
            else if (key == Key.LeftShift || key == Key.RightShift)
            {
                foreach (var kvp in keyButtons)
                    if (kvp.Key == Key.LeftShift || kvp.Key == Key.RightShift)
                        kvp.Value.Background = Brushes.Yellow;
            }
            else if (key == Key.LeftCtrl || key == Key.RightCtrl)
            {
                foreach (var kvp in keyButtons)
                    if (kvp.Key == Key.LeftCtrl || kvp.Key == Key.RightCtrl)
                        kvp.Value.Background = Brushes.Yellow;
            }
            else if (key == Key.LeftAlt || key == Key.RightAlt)
            {
                foreach (var kvp in keyButtons)
                    if (kvp.Key == Key.LeftAlt || kvp.Key == Key.RightAlt)
                        kvp.Value.Background = Brushes.Yellow;
            }
        }

        // ИСПРАВЛЕННАЯ ФУНКЦИЯ ГЕНЕРАЦИИ ТЕКСТА
        private void GenerateText()
        {
            Random rand = new Random(); // ИСПРАВЛЕНО: Random, а не int
            int length = 0; // ИСПРАВЛЕНО: int, а не var
            string chars = ""; // ИСПРАВЛЕНО: string, а не int

            switch (currentLevel) // ИСПРАВЛЕНО: используем Enum, а не int
            {
                case DifficultyLevel.Easy:
                    length = rand.Next(20, 40);
                    chars = "abcdefghijklmnopqrstuvwxyz ";
                    break;
                case DifficultyLevel.Medium:
                    length = rand.Next(40, 70);
                    chars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789 ,.!?";
                    break;
                case DifficultyLevel.Hard:
                    length = rand.Next(70, 100);
                    chars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789 ,.!?;:()\"'";
                    break;
            }

            char[] text = new char[length];
            for (int i = 0; i < length; i++)
                text[i] = chars[rand.Next(chars.Length)];

            targetText = new string(text);
            currentIndex = 0;
            errors = 0;
            correctChars = 0;
            totalChars = 0;

            TargetTextBlock.Text = targetText;
            TargetTextBlock.Foreground = Brushes.Black;
            UpdateProgress();
        }

        // Остальные методы (Window_KeyDown, GetCharFromKey, StartTraining, StopTraining, UpdateProgress, Timer_Tick, CalculateSpeed, CalculateAccuracy, кнопки)
        private void Window_KeyDown(object sender, KeyEventArgs e)
        {
            if (!isTraining) return;

            HighlightKey(e.Key);

            if (currentIndex < targetText.Length)
            {
                char expectedChar = targetText[currentIndex];
                char typedChar = GetCharFromKey(e.Key);

                if (typedChar == expectedChar)
                {
                    correctChars++;
                    currentIndex++;
                    totalChars++;
                    UpdateProgress();
                }
                else if (e.Key != Key.LeftShift && e.Key != Key.RightShift &&
                         e.Key != Key.LeftCtrl && e.Key != Key.RightCtrl &&
                         e.Key != Key.LeftAlt && e.Key != Key.RightAlt &&
                         e.Key != Key.LWin && e.Key != Key.RWin)
                {
                    errors++;
                    totalChars++;
                    UpdateProgress();
                    TargetTextBlock.Foreground = Brushes.Red;
                }

                if (currentIndex >= targetText.Length)
                {
                    StopTraining();
                    MessageBox.Show($"Поздравляем! Вы завершили тренировку!\n\n" +
                                  $"Скорость: {CalculateSpeed()} симв/мин\n" +
                                  $"Ошибок: {errors}\n" +
                                  $"Точность: {CalculateAccuracy():F1}%",
                                  "Тренировка завершена",
                                  MessageBoxButton.OK,
                                  MessageBoxImage.Information);
                }
            }
            e.Handled = true;
        }

        private char GetCharFromKey(Key key)
        {
            if (key >= Key.A && key <= Key.Z) return char.ToLower((char)('A' + (key - Key.A)));
            else if (key >= Key.D0 && key <= Key.D9) return (char)('0' + (key - Key.D0));
            else if (key == Key.Space) return ' ';
            else if (key == Key.OemPeriod) return '.';
            else if (key == Key.OemComma) return ',';
            else if (key == Key.OemQuestion) return '/';
            else if (key == Key.OemSemicolon) return ';';
            else if (key == Key.OemQuotes) return '\'';
            else if (key == Key.OemMinus) return '-';
            else if (key == Key.OemPlus) return '=';
            else if (key == Key.OemOpenBrackets) return '[';
            else if (key == Key.OemCloseBrackets) return ']';
            else if (key == Key.OemBackslash) return '\\';
            return '\0';
        }

        private void StartTraining()
        {
            isTraining = true;
            startTime = DateTime.Now;
            timer.Start();

            StartButton.IsEnabled = false;
            StopButton.IsEnabled = true;
            DifficultyComboBox.IsEnabled = false;
            GenerateText();
        }

        private void StopTraining()
        {
            isTraining = false;
            timer.Stop();

            StartButton.IsEnabled = true;
            StopButton.IsEnabled = false;
            DifficultyComboBox.IsEnabled = true;

            TargetTextBlock.Text = "Нажмите 'Начать'";
            TargetTextBlock.Foreground = Brushes.Black;

            foreach (var btn in keyButtons.Values)
                btn.Background = (Brush)new BrushConverter().ConvertFrom("#E8E8E8");

            SpeedText.Text = "0 симв/мин";
        }

        private void UpdateProgress()
        {
            if (targetText.Length == 0) return;
            int progress = (int)((double)currentIndex / targetText.Length * 100);
            ProgressText.Text = $"{progress}%";
            ErrorsText.Text = errors.ToString();

            if (currentIndex < targetText.Length)
            {
                string displayText = targetText.Substring(0, Math.Min(currentIndex, targetText.Length));
                TargetTextBlock.Text = displayText;
                TargetTextBlock.Foreground = Brushes.Blue;
            }
        }

        private void Timer_Tick(object sender, EventArgs e)
        {
            SpeedText.Text = $"{CalculateSpeed()} симв/мин";
        }

        private int CalculateSpeed()
        {
            if (!isTraining) return 0;
            TimeSpan elapsed = DateTime.Now - startTime;
            if (elapsed.TotalMinutes < 0.5) return 0;
            return (int)(correctChars / elapsed.TotalMinutes);
        }

        private double CalculateAccuracy()
        {
            if (totalChars == 0) return 0;
            return (double)(totalChars - errors) / totalChars * 100;
        }

        private void StartButton_Click(object sender, RoutedEventArgs e) => StartTraining();
        private void StopButton_Click(object sender, RoutedEventArgs e) => StopTraining();

        private void DifficultyComboBox_SelectionChanged(object sender, SelectionChangedEventArgs e)
        {
            ComboBox comboBox = sender as ComboBox;
            if (comboBox == null) return;
            switch (comboBox.SelectedIndex)
            {
                case 0: currentLevel = DifficultyLevel.Easy; break;
                case 1: currentLevel = DifficultyLevel.Medium; break;
                case 2: currentLevel = DifficultyLevel.Hard; break;
            }
        }
    }
}