UiEnglish.cs

Static translation table used at the UI layer. Maps hardcoded Russian match/action strings to English and leaves the simulation keys untouched so saved matches keep working, with a GamePreferences.Russian switch to keep Russian on.

using System;

namespace Socer;

// The simulation still has legacy Russian action keys used by AI checks.
// Translate only at the presentation boundary so saved matches remain compatible.
public static class UiEnglish
{
    static readonly (string Source,string English)[] Terms={
        ("Ожидает серию пенальти","Waiting for the shootout"),("Готовит пенальти","Preparing the penalty"),
        ("Судья наблюдает серию","Watching the shootout"),
        ("На линии ворот","On the goal line"),("Разбег перед пенальти","Penalty run-up"),
        ("Пробивает пенальти","Taking the penalty"),("Прыжок на пенальти","Diving for the penalty"),
        ("Серия пенальти","Penalty shootout"),("команды готовятся","teams getting ready"),
        ("победили","won"),
        ("Пенальти · ГОЛ","Penalty · GOAL"),("Пенальти · СЕЙВ","Penalty · SAVE"),
        ("Пенальти · ШТАНГА","Penalty · POST"),("Пенальти · ВЫШЕ","Penalty · OVER"),("Пенальти · МИМО","Penalty · WIDE"),
        ("Мяч принял другой партнёр · свободная игра","Another teammate received the ball · open play"),
        ("Потеря · соперник перехватил инициативу","Possession lost · opponents took over"),
        ("Выход на удар · дальнейшая игра свободная","Shot taken · open play continues"),
        ("Выход на удар · в касание","First-time shot taken"),
        ("Участник выбыл из розыгрыша","A play participant is unavailable"),
        ("Пас закрыт или партнёр вне поля зрения","Pass blocked or receiver out of sight"),
        ("Мяч у ударной ноги · в касание","Ball at the shooting foot · first time"),
        ("Выход на удар в движении","Running into shooting position"),
        ("Ожидаем завершения забегания","Waiting for the run"),
        ("Ожидаем мяч у участника","Waiting for player"),
        ("Партнёр слишком далеко","Receiver is too far away"),
        ("Синхронизация движений","Synchronising runs"),
        ("Разворот под передачу","Turning to pass"),
        ("Передача в движении","Pass in motion"),
        ("Схема выполнена","Play completed"),
        ("Остановка игры","Play stopped"),
        ("Время вышло","Time expired"),
        ("Гол","Goal"),
        ("Финальный свисток","Full time"),("Начальный свисток","Kick-off"),("Начало матча","Kick-off"),
        ("Второй тайм · смена ворот","Second half · teams switch ends"),("ГОООЛ!","GOAL!"),("ГОЛ!","GOAL!"),
        ("угловой: навес на ближнюю","corner: near-post delivery"),
        ("угловой: навес на дальнюю","corner: far-post delivery"),
        ("угловой: короткий пас","corner: short pass"),
        ("Угловой","Corner"),("Удар от ворот","Goal kick"),("Аут","Throw-in"),
        ("Штрафной","Free kick"),("Пенальти","Penalty"),("Офсайд","Offside"),
        ("СЕЙВ!","SAVE!"),("ПЕРЕХВАТ","INTERCEPTION"),("ЗАБРАЛ!","CLAIMED!"),
        ("НЕ ДОТЯНУЛСЯ","MISSED THE BALL"),("Первым касанием на ход","First touch into space"),
        ("Празднует гол","Celebrating goal"),("Обнимает автора гола","Congratulating scorer"),
        ("Бежит праздновать","Running to celebrate"),("Разочарован после гола","Disappointed after goal"),
        ("Опустил голову","Head down"),("Удар от ворот","Goal kick"),
        ("Поднимается после падения","Getting up after a fall"),("Встаёт после подката","Getting up after slide"),
        ("Приземляется после акробатического удара","Landing after an acrobatic shot"),
        ("Поднимается после акробатического удара","Getting up after an acrobatic shot"),
        ("Возвращается в игру","Returning to play"),("Прикрывает мяч","Shielding the ball"),
        ("Поймал мяч","Caught the ball"),("Тянется к мячу","Reaching for the ball"),
        ("Борется за позицию","Jostling for position"),("Руководит стенкой","Organising the wall"),
        ("Личный прессинг","Pressing player"),("Персональная опека","Marking player"),
        ("Закрывает заданную зону","Guarding assigned zone"),("Ждёт пас по команде","Waiting for instructed pass"),
        ("Защищает штрафную","Protecting the box"),("Открывается для навеса","Offering a crossing option"),
        ("Забегает на фланг","Running wide"),("Поддерживает под пас","Supporting the pass"),
        ("Открывается между линиями","Finding space between lines"),
        ("навес со стандарта","set-piece cross"),("В штрафную!","Into the box!"),
        ("подготовленный удар со штрафного","prepared free-kick shot"),
        ("навес со штрафного на ближнюю зону","free-kick cross to the near-post area"),
        ("навес со штрафного на дальнюю зону","free-kick cross to the far-post area"),
        ("срыв явного голевого момента","denying an obvious goal-scoring opportunity"),
        ("вторая жёлтая — удаление","second yellow — sent off"),
        ("прямая красная","straight red card"),("ЖЁЛТАЯ КАРТОЧКА","YELLOW CARD"),
        ("КРАСНАЯ КАРТОЧКА","RED CARD"),("жёлтая","yellow card"),
        ("грубая игра","serious foul play"),("опасный отбор","reckless tackle"),
        ("На ближнюю!","Near post!"),("На дальнюю!","Far post!"),
        ("Рывок по команде","Making instructed run"),("Давит на мяч","Pressuring ball"),
        ("Перекрывает пас","Cutting passing lane"),("Страхует","Covering"),
        ("Рывок за мячом","Chasing the ball"),("Открывание","Finding space"),
        ("Ищет решение","Looking for an option"),("Возвращается к мячу","Returning to ball"),
        ("Рывок по схеме","Running the play"),("Маршрут по схеме","Following route"),
        ("Встречает передачу","Meeting the pass"),("Подкат","Sliding tackle"),
        ("Позиция","Positioning"),("Прессинг","Pressing"),("Рывок","Running"),
        ("Ведение","Dribbling"),("Стенка","Wall"),("Забегание","Overlap"),
        ("Розыгрыш","Play"),
        ("ПРЕССИНГ","PRESS"),("В АТАКУ","ATTACK"),("БЕРЕЧЬ СИЛЫ","CONSERVE ENERGY"),
        ("КОМАНДЫ ТРЕНЕРА","COACH COMMANDS"),("ОБЗОР МАТЧА","MATCH OVERVIEW"),
        ("РУЧНАЯ СКОРОСТЬ","MANUAL SPEED"),("СУДЬЯ ОСТАНОВИЛ ИГРУ","REFEREE STOPPAGE"),
        ("МЕДИЦИНСКАЯ ПОМОЩЬ","MEDICAL ASSISTANCE"),
        ("СТАНДАРТ","SET PIECE"),("ПОДГОТОВКА УДАРА","PREPARING SHOT"),
        ("ВОЗВРАТ ТЕМПА","BACK TO PACE"),("ПОЛЁТ МЯЧА · СЛОУ-МО","BALL FLIGHT · SLOW MOTION"),
        ("ОПАСНАЯ АТАКА","DANGEROUS ATTACK"),("ПОСТРОЕНИЕ АТАКИ","BUILDING ATTACK"),
        ("Баланс","Balanced"),("Контроль мяча","Possession"),("Игра через фланги","Wing play"),
        ("Вертикальные атаки","Direct attacks"),("Агрессивный прессинг","Aggressive press"),
        ("Новая комбинация","New play"),("Фланг · забегание и прострел","Wing · overlap and cutback"),
        ("Не удалось прочитать сохранение","Could not read save"),("Ошибка сохранения","Save failed"),
        ("Состав закреплён до конца матча","Lineup locked until full time"),
        ("Добро пожаловать в клуб","Welcome to the club")
    };
    public static string Text(string value,string fallback="Match in progress")
    {
        if(string.IsNullOrEmpty(value))return value??"";
        if(GamePreferences.Russian)return value;
        if(value.Equals("Фланг · забегание и прострел",StringComparison.OrdinalIgnoreCase))return "Wing · overlap and cutback";
        if(!ContainsCyrillic(value))return value;
        foreach(var (source,english) in Terms)value=value.Replace(source,english,StringComparison.OrdinalIgnoreCase);
        return ContainsCyrillic(value)?fallback:value;
    }
    static bool ContainsCyrillic(string value)
    {
        foreach(char c in value)if(c is >= 'А' and <= 'я' or 'Ё' or 'ё')return true;
        return false;
    }
}