habrahabr

Придумал расширение для Chrome и устранил шахматных читеров

  • четверг, 23 октября 2025 г. в 00:00:26
https://habr.com/ru/companies/selectel/articles/957758/
I made a Chrome extension to help avoid playing cheaters in chess

Поисковая выдача по запросу «chrome extension for cheating in chess» переполнена. Инструментов для нечестной игры — десятки.

Но стоит инвертировать пожелание и поискать плагин для защиты — не найдется почти ничего. Кроме расширения, о котором сегодня пойдет речь. Ну, возможно, еще нескольких старых приложений, показывающих базовую статистику.

Удивительный дисбаланс, не правда ли?

Используйте навигацию, если не хотите читать весь текст

Как использовать

1. Установите расширение из Google Store.

2. Проверьте версию браузера: chrome://version

  • 126 или ниже — что крайне маловероятно, для этого надо много лет не обновлять Chrome — перейдите в настройки расширения, отключите опцию «Auto open popup» и закрепите его в браузере для удобства. 

  • 127+ — ничего предпринимать не нужно.

3. Войдите на Chess.com.

4. Откройте любую партию или начните новую, чтобы увидеть оценку игрока сверху. Можно воспользоваться примером.

5. Оценка выше 30% — прервите партию. Не тратьте зря свое время, рейтинг и нервы!

Идея и мотивация

Я люблю шахматы. Играю много. В этом году — 3 630  партий, это около десяти в день. Свой рейтинг считаю неплохим: рапид — 2 200, блиц — 1 900. Результат заработан тысячами часов практики и тренировок.

И чем выше поднимаюсь — тем больше читеров попадается!

По опыту скажу: начиная с рейтинга 2 000 в рапиде, трое из пяти соперников или играют крайне подозрительно, или читерят в открытую. У кого рейтинг ниже, может не замечать масштаба проблемы. Это логично: недобросовестные игроки не задерживаются на начальных уровнях. Они «пролетают» их за считаные дни после регистрации.

И тем не менее уверен «на все сто»: на каком бы уровне вы ни играли, хоть раз такой шахматный шулер попадался вам на пути. Просто вы могли не заметить хитрости и списали то поражение на собственное неумение, а не на чужой обман.

Как распознать

Подозрения в нечестной игре легко проверить после партии — достаточно заглянуть в аналитический отчет.

Большинство читеров не используют подсказки на каждом ходу, чтобы их итоговая точность не казалась подозрительной (хотя есть и те, кто об этом не заботится). Типичный сценарий выглядит так.

  • Дебют. Читер играет сам. Поскольку его реальный уровень ниже заявленного, через 10−20 ходов он предсказуемо «плывет» и получает плохую позицию.

  • Зависание. Внезапно оппонент глубоко «задумывается» на 30−60 секунд и возвращается с невероятно сильным, переворачивающим игру ходом.

  • Супер‑режим. С этого момента каждый его следующий ход, каким бы контринтуитивным он ни казался, занимает 2−5 секунд. При этом шансов у вас не остается.

Паттерн довольно четко виден в анализе партии: плохо разыгранный дебют, пара ошибок или зевков в миттельшпиле, а затем 35 непостижимых ходов подряд. Это даже не уровень Магнуса Карлсена!

30+ бесплатных курсов на IT-темы в Академии Selectel

Для начинающих и опытных специалистов.

Изучить →

А что же Chess.com?

Формально на площадке есть механизм борьбы с читерством: вы отправляете жалобу, команда сайта проводит расследование. Но какова его реальная эффективность?

Я играю много и, соответственно, жалуюсь часто. За месяц отправляю более 100 претензий. Жаль, что нельзя посмотреть их в истории. (Может, стоит добавить и это в плагин?) Важно: 30−50 из них — не просто эмоции, а обоснованные претензии, составленные после тщательного анализа партии.

А теперь — результат. Знаете, сколько из них банят? Одного‑двух в месяц! Ниже — несколько уведомлений, которые я получил за последние 30 дней.

30 дней, 357 партий — и только двое забанены.
30 дней, 357 партий — и только двое забанены.

Может, это нормально? Может, я заблуждаюсь, слишком остро реагирую, плохо играю и не умею признавать заслуженные поражения? Но в подозрениях я не одинок.

О том же самом говорят тысячи игроков на Reddit и форумах Chess.com. Неслучайно частный «Cheating Forum» — один из пяти самых активных на всем сайте. Эту проблему регулярно освещает и главный шахматный ютубер — Gotham Chess.

Ключевое препятствие: Chess.com не банит даже вопиющих читеров — до тех пор, пока история не получает публичную огласку.

Всего лишь один свежий пример, иллюстрирующий масштаб проблемы. Недавно довелось играть против «SumitGM000». После пятого хода я почувствовал, что он включил движок. Быстрый чек профиля показал 80% винрейта. Пишу в чат:

— Пожалуйста, прекрати читерить. Я знаю, что ты делаешь.

Иногда это срабатывает, но в ответ он лишь усмехнулся:

— Ха‑ха, не можешь смириться с поражением.

Меня заинтересовал его ник: «…GM000»? А что, если… Проверил профиль «SumitGM00» — просто убрал ноль. Точно! Аккаунт с таким именем действительно существовал и был забанен за читерство. Последняя партия датирована 19 октября 2024 года.

Его «наследник», «SumitGM000», появился в тот же самый день! Конечно, я отправил жалобу. Разумеется, никто не отреагировал.

UPD: Его аккаунт таки забанили. Но сделали это лишь на следующий день после появления этой статьи.

Неужели ничего нельзя сделать?

В какой-то степени можно. В этом и заключается цель моего приложения — отказаться от партии, если попался сомнительный соперник.

Но как узнать, что он «сомнительный»?

Еще до написания плагина для проверки оппонента выработался четкий алгоритм. По нему можно действовать и вручную, автоматизация не столь обязательна. Я смотрел на три «красных флага»:

  • Аккаунт — слишком «молодой» профиль с ненормально высоким рейтингом.

  • Винрейт — стабильный процент побед 55% и более за последние 30−90 дней — подозрительно. Выше 70% — почти гарантия читерства. Здесь важно отметить, что количество встреч имеет значение. Три партии за месяц и все выигранные — никто не заподозрит. Однако, если из 200 выиграно 150 — извините, в такое никто не поверит.

  • Точность — для ее определения пролистывал историю игр. Если там мелькала серия партий с аккуратностью выше 90%, то делал выводы.

Правило несложное: один из этих факторов — и я немедленно прерываю партию, составляю жалобу и отправляю оппонента в блок.

Меня совершенно не беспокоят «ложные срабатывания». Логика простая: честного игрока не забанят никогда. Даже читера, как мы уже выяснили, — и то крайне маловероятно.

Однако у такого подхода две проблемы все‑таки имеются.

  1. Вся эта ручная проверка — гонка со временем. На расследование есть 20−60 секунд — дальше уже риск проиграть по часам. В блице, где на все про все 20 секунд, на профиль в лучшем случае удастся взглянуть мельком. Самые же явные «красные флаги» часто спрятаны в истории партий — и быстро в ней никак не разобраться.

  2. Даже если удастся успеть засечь читера, приходит вторая, еще более серьезная проблема. Платформа Chess.com не позволяет прерывать слишком много партий подряд. Официально — для борьбы с ботами. На деле — у них есть негласный и непрозрачный лимит. Попробуйте остановить 3−5 игр за день. Очень скоро обнаружится, что кнопка «Прервать партию» попросту исчезла из интерфейса.

Складывается безвыходное положение: проверка проведена, читер изобличен, но… из игры уже не выйти. Остается либо смириться, либо сразу сдаться. Впрочем, разница невелика — потеря рейтинга при встрече с читером неизбежна.

Именно поэтому я и решил создать приложение. Оно быстро проворачивает всю аналитическую работу — за те несколько секунд, когда еще остается выбор: сделать свой первый ход или отказаться от игры.

Программный алгоритм

Принцип работы прост. Как только оппонент нашелся, плагин мгновенно «сканирует» его. Имя пользователя получено — дело за выполнением нескольких API-запросов к Chess.com:

  • данные профиля — например, «возраст» аккаунта;

  • общая статистика — рейтинг игрока, количество сыгранных партий, результаты для каждого формата встреч;

  • все партии — или текущего месяца, или не менее, чем за последние 15 дней.

Затем вычисляются метрики:

  • общий винрейт — отдельно для каждого формата встреч;

  • недавний винрейт — на основе партий последних 15−30 дней;

  • доля партий с высокой точностью среди встреч, где такой параметр вообще рассчитывался; это 80% и выше для рейтинга до 1500, и за 90% для игроков посильнее;

  • возраст аккаунта в днях.

Почему только эти метрики? Я пробовал и другие, но они лишь усложняли модель и создавали массу пограничных случаев.

Например, пытался анализировать дисперсию времени на ход. Это классический маркер: читер тратит одинаковое количество секунд и на очевидный ход, и на сложнейшую тактическую комбинацию. Однако превратить эти данные в стабильный, адекватно распределенный показатель — на удивление сложно, я сдался.

Модель оценки риска

Предстоит немного погрузиться в математику.

Сама модель устроена просто. Она берет полученные о противнике данные, вычисляет по ним четыре ключевые метрики, «взвешивает» их и объединяет в целостную оценку — «рейтинг подозрительности» от 0 до 100.

Чтобы подобрать правильные весовые коэффициенты, пришлось стряхнуть пыль со старых университетских конспектов по эконометрике. Оказалось, что GPT, даже версии 4.0, все еще неважно справляется с математическим моделированием, так что пришлось разбираться самому.

Для каждого параметра создал функцию, которая преобразует его в понятный для модели вид. Например, вот формула для расчета WinRateScore — я попросил GPT красиво отрисовать ее в LaTeX:

В основе этой метрики лежит простое допущение: «нормальный» на длинной дистанции винрейт w всегда стремится к 50%:

  • ниже 50% — не подозрительно, оценка 0;

  • 50−60 — слегка подозрительно, оценка до 50;

  • 60−70 — очень подозрительно, оценка 50−100;

  • выше 70% — вопиющая аномалия, оценка 100.

Такая логика — прямое следствие рейтинговой системы Glicko, которая очень быстро адаптируется. Начинаете много выигрывать — рейтинг взлетает. Вы почти мгновенно попадаете на свой реальный уровень, где противостоят равные по силе соперники. Как только это происходит, ваш винрейт неизбежно стабилизируется около 50%.

Представление несколько упрощенное, но для общего понимания правильное. Интересующиеся могут узнать подробности о методике расчета рейтинга.

Конечно, это справедливо только для большого числа партий n. Именно поэтому в формуле используется весовой коэффициент Weight(n). Проиллюстрируем его на простых примерах:

  • три партии, 100% побед — норма,

  • 300 партий, 70% побед — нет.

50 побед над равными на момент игры соперниками принесут около 400 пунктов рейтинга — это колоссальный скачок!

Двигаемся дальше. Есть функция HighAccuracyScore.

Здесь похожая логика: менее 10% игр с высокой точностью — вполне нормально, более 30% (на большом наборе партий) — крайне подозрительно.

Итоговая оценка рассчитывается по следующей формуле:

Итак, у нас есть несколько «оценок» — по винрейту, по точности и другие. Как они превращаются в итоговый балл?

  • Взвешенная сумма — складываем все эти оценки, но с разными «весами». Например, аномальный винрейт может быть важнее, чем возраст аккаунта.

  • Коэффициент возраста — полученная сумма умножается на специальный «фактор возраста аккаунта». Чем новее профиль, тем коэффициент больше — так усиливается подозрительность для «свежих» аккаунтов.

  • Нормализация — итоговый балл «отсекается» на отметке 100. Даже если по расчетам у читера вышло 170 — результат будет 100. Это делает шкалу простой и понятной.

Наконец, мы берем максимум из рассчитанного для рапида, блица и пули — и отображаем во всплывающем окне!

Пара слов о модели оценки

Все упомянутые пороговые значения прописаны в конфигурационном файле. Их можно менять по своему усмотрению — надо лишь собрать локальную версию плагина. Как это сделать — в многочисленных инструкциях по работе с GitHub.

Я пытался вынести настройки в интерфейс, но быстро сдался. Реализация проверки корректности всех вводимых значений оказалась настоящей головной болью. Честно говоря, сомневаюсь, что кто‑то действительно захочет этим заниматься. Если вдруг вы один из таких — свяжитесь со мной, пожалуйста, очень любопытно.

Получившуюся модель не считаю лучшей или самой продвинутой. Я не математик и не специалист по Data Science. Уверен, кто-то из читателей уже придумал, как рассчитывать «рейтинг подозрительности» многократно точнее. Если это вы — дайте знать, буду рад пообщаться.

При всей своей простоте модель работает. Я протестировал ее более чем на 200 игроках, и результаты полностью устраивают:

  • честные игроки, которых хорошо знаю, стабильно получают низкий балл менее 15%;

  • явные читеры всегда неизменно добирают до 90% и более.

Важное примечание. Модель создана для оценки обычных игроков, таких как мы с вами. У супергроссмейстеров вроде Магнуса или Хикару, которые дают сеансы игры всем желающим, она предсказуемо зашкаливает. Что ж, разбор их аномальной статистики я с удовольствием оставлю Крамнику.

P.S. А если серьезно, Хикару просто безумно хорош.

Дальнейшая разработка

Я потратил немало времени на разработку и отладку расширения. Искренне надеюсь, что оно найдет свою аудиторию и сделает чью‑то игру комфортнее.

Раз так, то думаю выпустить несколько обновлений с дополнительной функциональностью. Вот что уже есть в планах на следующие версии:

  • история оценок — лог всех «рейтингов подозрительности» тех игроков, с которыми вы встречались;

  • трекинг жалоб — раздел с историей всех ваших претензий и периодической проверкой статуса виновников;

  • счетчик прерываний — хочу разобраться в негласной логике Chess.com по ограничению прекращения партий и добавить предупреждение;

  • продвинутая настройка — возможность менять пороговые значения прямо в браузере, а также загружать собственный файл конфигурации или даже подключать свою математическую модель.

Заключение

Спасибо, что дочитали! Если найдете расширение полезным, лучшей благодарностью будет отзыв в Google Web Store.

Убежден, что проблема читерства в онлайн-шахматах со временем будет только обостряться. Если мы хотим, чтобы игра оставалась честной и приносила удовольствие, то нужно действовать. И да, если вы из команды Chess.com, передайте ребятам, что им есть над чем поработать.

Создавать приложение начал с помощью AI-ассистента Cursor, но в итоге бо́льшую часть кода пришлось переписывать вручную. AI был полезен, но постоянно генерировал мелкие, раздражающие баги, при этом не мог исправить их в разумные сроки.

Весь код открыт на GitHub. Буду рад «звездочке», PR и даже сообщению об ошибке. По всем вопросам и предложениям пишите на почту: tim.sha256@gmail.com.