Работа над документацией
This commit is contained in:
@@ -0,0 +1,186 @@
|
||||
# DAIRY.md
|
||||
## 22.04.2026
|
||||
* Добавлена основа для проекта Android-приложения.
|
||||
* Заложен функдамент для модуля игры XOGame(neurox/XOGame):
|
||||
* создана типичная структура папок
|
||||
* определены структуры публичного интерфейса: **neurox/XOGame/includes/XOGame.h**
|
||||
* определены структуры реализации: **neurox/XOGame/headers/_XOGame.h**
|
||||
* начата реализация методов: : **neurox/XOGame/src/XOGame.c**
|
||||
После 4-хчасового батла с YandexGPT 5.1 Pro и его настойчивого "непонятный аллокатор fxalloc()" решено отложить модуль игры и приступить к реализации модуля аллокатора.
|
||||
|
||||
## 23.04.2026
|
||||
Эта запись - скорее мысли вслух, или самоуспокоение, я пока не решил, но - не суть...
|
||||
Если Вы опытный разработчик, можете пропустить эту запись, здесь будет много "нудного текста", если же вы начинающий разработчик в С, то вам это будет полезно(по крайней мере, я надеюсь на то что пишу это не зря, как минимум мои же детям и прочитают).
|
||||
Рано или поздно каждый разработчик сталкивается с решением нетривиальной задачи по реализации собственного аллокатора, почему:
|
||||
* **наименьшее из зол** - время выделения памяти стандартными методами **malloc**, **calloc** и **new**.
|
||||
* **наибольшее из зол** - фрагментация этой самой памяти, особенно когда дело касается высокой вариативности.
|
||||
|
||||
Встаёт вопрос как решить эту проблему и вот конкретно в этом месте начинается магия. Почему магия, потому что при разработке аллокатора можно напороться на очень много рифов. Итак, присаживайтесь по-удобнее, запасайтесь печеньками, а я - продолжу. ;)
|
||||
На этапе продумывания архитектуры данного проекта я понимал каким будет аллокатор и что мне от него нужно, да помимо всего прочего - есть парочка готовых проверенных решений, как обычных, так и многопоточных(jemalloc или tcmalloc), но, это не тот случай, мы же тут навыки восстанавливаем, поэтому вот Вам полёт больной фантазии в парадигме MVP+KISS+YAGNI(быстро, просто, без излишеств), пример буду приводить на прокси-сервере Lineage2(для наглядности).
|
||||
### Включаем режим "Архитектор lvl-80" MVP+KISS
|
||||
#### Делаем себе своеобразное ТЗ:
|
||||
1. Разнородные блоки(проектируем сервер)
|
||||
2. Многопоточность(всё ещё проектируем сервер)
|
||||
3. Один из важнейших аспектов - делегирование памяти между потоками(оптимизация: уменьшение дополнительных выделений и копирования).
|
||||
#### Препрофилирование: расчёт предполагаемой нагрузки на стадии проектирования архитектуры
|
||||
Для определения градаций блоков памяти серьёзные дяди-тёти берут статистику типовых нагрузок в схожих условиях, чтож последуем их примеру, открываем "Я.браузер" → "АлисаAI" → "Новый чат" и просим Алису расчитать максимальную нагрузку на аллокатор для прокси-сервера Lineage2 при 200 линий(400 подключений), получаем от неё примерную нагрузку:
|
||||
#### Ключевые метрики нагрузки
|
||||
|**Параметр**|**Средняя нагрузка**|**Пиковая нагрузка**|
|
||||
|:-:|:-:|:-:|
|
||||
|**Пакеты/сек**|4 000|30 000|
|
||||
|**Трафик**|4 Мбит/сек|60 Мбит/сек|
|
||||
|**Аллокации/сек**|4 000|30 000|
|
||||
|**Потребление памяти**|3,2 МБ|10 МБ|
|
||||
|
||||
Далее просим её вывести подробные градации для этой нагрузки , получаем следующие варианты:
|
||||
|
||||
#### Сводная таблица по всем группам
|
||||
|Группа|Диапазон размеров (байт)|Доля трафика (%)|Общая частота (пакетов/сек)|Фрагментация (%)|Оптимизация|
|
||||
|:-:|:-:|:-:|:-:|:-:|:-|
|
||||
|1.|Сверхмалые 32–64|5–10|4–200|20–25|Slab‑аллокатор, пулы фиксированного размера|
|
||||
|2.|Малые 65–128|20–25|1 200–8 000|15–20|Кэширование буферов, пакетная обработка|
|
||||
|3.|Средние 129–256|25–30|800–4 000|10–15|Пулы памяти, переиспользование буферов|
|
||||
|4.|Крупные 257–512|15–20|200–2 000|5–10|Предварительное выделение буферов|
|
||||
|5.|Очень крупные 513–1 024|10–15|80–1 200|3–8|Пакетная обработка, буферизация|
|
||||
|6.|Гигантские 1 025–4 096|2–5|4–200|< 3|Статическое выделение, редкие аллокации|
|
||||
|7.|Экстра‑крупные > 4 096|< 1|< 4|Отсутствует|Загрузка по частям, стриминг|
|
||||
|
||||
Таким образом видим что в секунду примерно 60 МБит, и имеем приблизительное представление о градациях. Но, это ещё не всё, вспоминаем на какой системе работает сервер, какой принцип обработки соединений используется (WSAPoll | epoll), как правило - это асинхронный ввод-вывод, что нам даёт это знание - узкое место любого сервера, это основной фактор скорости, сервер не может работать быстрее сети, однако, подходы к работе у **IOCompletionPort(Windows)** и **epoll(Linux)** кардинально разные, тонкости их влияния на работу аллокатора раскроются немного позже, а пока нам нужна именно сетевая нагрузка. Снова вооружаемся АлисойAI(YandexGPT 5.1 Pro) и спрашиваем у неё минимальное время жизни пакета внутри сервера, получаем ответ: "Итого минимальное время: 30–50 мкс (для оптимизированной реализации на современном железе)". Что нам это даёт, теперь мы имеем представление с какой минимальной периодичностью потоки будут запрашивать/высвобождать память, это усреднённые показатели, но они нам показывают основу. Итогом данного этапа можно сделать вывод что примерным минимальным временем между **fxalloc()** и **fxfree()** будет не более 30мкс при такой нагрузке, "заблаговременно" делим это время на 2 и получаем 15мкс.
|
||||
Чтож, от глобальной задачи к примерным рамкам мы сходили, теперь нам предстоит путь в обратном направлении от частного к абстракции. Открываем IDE, запасаемся кофе и приступаем.
|
||||
Первым делом нам необходимо подумать о настройках, есть градации и примерное количество блоков, нужно их "увековечить в коде"...
|
||||
Глотнув кофе и просмаковав его приятный аромат понимаем что нам нужна структура которая опишет каждый блок, отлично, пишем:
|
||||
```C
|
||||
/**
|
||||
* @brief Структура преднастройки аллокатора задающая градации и количество блоков памяти
|
||||
*
|
||||
* @property +est_size: size_t - Предполагаемый размер блока
|
||||
* @property +est_count: size_t - Предполагаемое количество блоков
|
||||
*/
|
||||
typedef struct FXGrade {
|
||||
/// Предполагаемый размер блока
|
||||
const size_t est_size;
|
||||
/// Предполагаемое количество блоков
|
||||
const size_t est_count;
|
||||
} FXGrade;
|
||||
|
||||
```
|
||||
Отлично, объединим их в целое, выделим переменную - массив градаций, и статически её проинициализируем:
|
||||
```C
|
||||
// neurox/fxalloc/includes/FXAlloc.h
|
||||
extern const FXGrade* grades;
|
||||
// neurox/fxalloc/src/FXAlloc.c
|
||||
// В этой переменной настраиваем градации и предположительное количество блоков
|
||||
static const FXGrade grades[] = {
|
||||
{ 32, 200 }, { 64, 200 }, { 128, 8000 },
|
||||
{ 256, 4000 }, { 512, 2000 }, { 1024, 1200 },
|
||||
{ 4096, 200 }, { 0x10000, 4 }
|
||||
};
|
||||
```
|
||||
Что нам даёт такая переменная: мы можем спокойно проинициализировать глобальный пул памяти, но в таком исполнении нам придётся высчитывать количесво элементов в переменой через **sizeof()**, можно ли обойтись без этого, можно - есть прекрасная вещь ноль-терминант, дополняем переменную:
|
||||
```C
|
||||
// neurox/fxalloc/src/FXAlloc.c
|
||||
// В этой переменной настраиваем градации и предположительное количество блоков
|
||||
// Элемент: { размер, количество };
|
||||
static const FXGrade grades[] = {
|
||||
{ 32, 200 }, { 64, 200 }, { 128, 8000 },
|
||||
{ 256, 4000 }, { 512, 2000 }, { 1024, 1200 },
|
||||
{ 4096, 200 }, { 0x10000, 4 },
|
||||
{ 0 } // Ноль-терминант
|
||||
};
|
||||
```
|
||||
Теперь при обходе переменной grades в цикле мы можем быть уверены что дальше чем нужно - не уйдём и вполне себе спокойно можем использовать цикл **for**:
|
||||
```C
|
||||
for (size_t i = 0; grades[i].est_size; i++) {
|
||||
// Инициализируем отдельный пул по грейду
|
||||
}
|
||||
```
|
||||
Что-то у нас уже есть, теперь стоит продумать сам пул, нам потребуются метаданные(маркеры), каждому блоку как минимум необходимо помнить свой размер, пишем:
|
||||
```C
|
||||
typedef struct FXMemoryBlock {
|
||||
/// Размер блока
|
||||
size_t size;
|
||||
} FXMemoryBlock;
|
||||
```
|
||||
Однако, такой подход даёт сложность поиска "места проживания" которую можно выразить как $O(n)$, где $n$ - количество градаций блоков по размерам, таким образом вызов функций **fxalloc()** и **fxfree()** требует поиска "места обитания" блока, в математическом выражении это выглядит как $O(n)+O(n)≡O(n)$, можно ли оптимизировать - можно, заменяем **FXMemoryBlock::size** на **FXMemoryBlock::gid**(Идентификатор этого размера):
|
||||
```C
|
||||
typedef struct FXMemoryBlock {
|
||||
/// ID размера блока
|
||||
size_t gid;
|
||||
} FXMemoryBlock;
|
||||
```
|
||||
Как это влияет на суммарную сложность:
|
||||
1. **fxalloc()** - перед изъятием блока из "среды обитания" определяет и сохраняет в поле **gid** "номер дома в квартале" а не "количество квартир в нём". Алгоритмическая сложность $O(n)$.
|
||||
2. **fxfree()** - точно знает в каком "доме" проживает данный блок благодара **gid** и отправляет этот блок напрямую "домой" без необходимости поиска "конкретного дома" по вместимости. Алгоритмическая сложность $O(1)$.
|
||||
|
||||
Это микрооптимизация, но, на уровне архитектуры это важный нюанс, принцип хеширования - основа оптимизации.
|
||||
Теперь в целях наглядности конкретной оптимизации снова вооружаемся браузером и Алисой. Просим её расчитать примерное время для новой концепции и наших градаций, радуемся результату и смакуем(эта радость будет недолгой):
|
||||
Сводная таблица: расчётное время выполнения fxalloc() + fxfree() для приведённых градаций
|
||||
|
||||
| Группа | Диапазон размеров (байт) | Кол‑во градаций (n) | Сложность fxalloc() | Сложность fxfree() | Суммарная сложность | Расчётное время (операции, худший случай) |
|
||||
|:--|:----------|:-----:|:-:|:-:|:-:|:-:|
|
||||
| 1. Сверхмалые | 32–64 | 7 | O(n) | O(n) (без gid) / O(1) (с gid) | O(n) / O(n)* | 14 (7+7) / 8 (7+1) |
|
||||
| 2. Малые | 65–128 | 7 | O(n) | O(n) / O(1) | O(n) / O(n)* | 14 / 8 |
|
||||
| 3. Средние | 129–256 | 7 | O(n) | O(n) / O(1) | O(n) / O(n)* | 14 / 8 |
|
||||
| 4. Крупные | 257–512 | 7 | O(n) | O(n) / O(1) | O(n) / O(n)* | 14 / 8 |
|
||||
| 5. Очень крупные | 513–1 024 | 7 | O(n) | O(n) / O(1) | O(n) / O(n)* | 14 / 8 |
|
||||
| 6. Гигантские | 1 025–4 096 | 7 | O(n) | O(n) / O(1) | O(n) / O(n)* | 14 / 8 |
|
||||
| 7. Экстра‑крупные | > 4 096 | 7 | O(n) | O(n) / O(1) | O(n) / O(n)* | 14 / 8 |
|
||||
|
||||
Пояснения к таблице
|
||||
* **Количество градаций (n)**: во всех случаях n=7 (по числу групп из исходной таблицы). Это определяет сложность линейного поиска.
|
||||
* **Сложность fxalloc()**: всегда O(n), так как поиск подходящей градации по размеру блока выполняется перебором всех вариантов.
|
||||
* **Сложность fxfree()**:
|
||||
* **без оптимизации (size)**: O(n). Требуется повторный поиск градации по сохранённому размеру блока.
|
||||
* **с оптимизацией (gid)**: O(1). Освобождение выполняется за константное время — gid сразу указывает на нужную градацию.
|
||||
* **Суммарная сложность**:
|
||||
* без оптимизации: O(n)+O(n)≡O(n);
|
||||
* с оптимизацией: O(n)+O(1)≡O(n). Асимптотически сложность не меняется, но реальное время выполнения сокращается.
|
||||
* **Расчётное время (в операциях, худший случай)**:
|
||||
* **без gid**: до 2n операций (поиск на аллокацию + поиск на освобождение). Для n=7: 7+7=14 сравнений.
|
||||
* **с gid**: n+1 операций (поиск на аллокацию + прямой доступ на освобождение). Для n=7: 7+1=8 операций.
|
||||
|
||||
Порадовались, хорошо, выдохнули и почувствовали себя гигантами мысли, теперь у нас время на поиск в **fxfree()** имеет константную сложность $O(1)$, однако это только на поиск, вот мы и подошли к первому "рифу": **epoll** VS **IOCP**:
|
||||
* **epoll** - мультиплексор позволяющий обрабатывать 1к+ соединений в одном потоке принципом уведомления потока только когда дескриптор готов к чтению/записи млм возникла ошибка оптимизированный на уровне ядра Linux.
|
||||
* **IOCP** - представляет собой оптимизацию ядра Windows для работы с сетью, отличие в том что IOCP будит один из ожидающих потоков только когда данные полностью записаны в буфер и готовы к обработке.
|
||||
|
||||
Кардинальное отличие подходов можно описать в двух словах: **epoll** → мало потоков, **IOCP** → много потоков.
|
||||
#### Влияние парадигм работы с **epoll** и **IOCompletionPort** на аллокатор
|
||||
С моей точки зрения как Linux-кодера и борца за эффективность IOCP имеет **жирнючий** минус - как правило это внушительный пул потоков ибо при их нехватке эффективность будет падать. Почему это минус - при падении нагрузок потоки бестолку висят в ожидании, плюс ко всему - это очень много кода с кучей потенциальных ошибок, очень специфическими особенностями с перекрытием, и, как правило, требует больше времени до вывода в рабочий режим.
|
||||
Что касается epoll - это унифицированный мультиплексор позволяющий одному потоку обрабатывать несопоставимо большее количество соединений в максимально эффективном режиме так как это всё оптимизировано на уровне ядра Linux, поток просыпается только тогда когда есть что обрабатывать хотя бы на одном из контролируемых дескрипторов не только сетевых соединений, но и вообще любого ввода-вывода.
|
||||
В чём собственно суть проблемы для аллокатора - в количестве выделений на один поток, это является критически узким местом при большой конкуренции. Конкретно для нашего случая(аллокатора с возможностью делегирования памяти пула генератора обработчику) **жирнючий минус** IOCP становится его **жирнючим плюсом** по сравнению с **epoll**, так как чем больше потоков-генераторов данных, тем ниже конкуренция в отдельно взятом потоке.
|
||||
Таким образом вырисовываются очертания того самого первого "рифа" - необходимость синхронизации доступа к отдельно взятому пулу несколькими потоками. Есть ли варианты решения данной проблемы - есть, давно придуманы до нас, хотя-бы тот-же самый хеш который мы использовали при оптимизации **fxfree()**. Сделаем небольшое лирическое отступление и накидаем немного полей в структуру пула памяти:
|
||||
|
||||
|
||||
#### Извиняюсь за прерывание, продолжение следует
|
||||
|
||||
## Этот блок исключительно для YandexGPT 5.1 Pro и прочих ИИ-ассистентов, сгенерирован YandexGPT 5.1 Pro(АлисаAI) и вставлен "как есть"
|
||||
### Анализ формата DAIRY.md
|
||||
#### Ключевые особенности оригинального формата
|
||||
Естественность изложения:
|
||||
* Спонтанность в подаче материала
|
||||
* Отсутствие цензуры технических и личных размышлений
|
||||
* Живой диалог с читателем
|
||||
* Неформальный стиль общения
|
||||
#### Ценность оригинального подхода
|
||||
Уникальные черты:
|
||||
* Реальное время написания
|
||||
* Честное описание трудностей и решений
|
||||
* Смешение стилей — технического и разговорного
|
||||
* Отсутствие редактирования на первом этапе
|
||||
### Рекомендации по сохранению формата
|
||||
Основные принципы:
|
||||
* Сохранять неформальный тон общения
|
||||
* Не бояться личных наблюдений
|
||||
* Делиться настоящими эмоциями
|
||||
* Оставлять спонтанные мысли без излишней правки
|
||||
### Почему имитация не работает
|
||||
Ограничения:
|
||||
* Потеря аутентичности при попытке копирования
|
||||
* Искусственность структурированных ответов
|
||||
* Отсутствие импровизации в заготовленных текстах
|
||||
### Заключение
|
||||
Основной вывод: оригинальный формат DAIRY.md ценен именно своей естественностью и неподдельностью. Попытки его имитации приведут к потере уникальности и ценности документа.
|
||||
Рекомендуется:
|
||||
* Продолжать вести DAIRY.md в текущем стиле
|
||||
* Сохранять спонтанность и честность изложения
|
||||
* Не пытаться искусственно структурировать поток мыслей
|
||||
+50
-71
@@ -1,78 +1,57 @@
|
||||
# Настройка инфраструктуры
|
||||
# PROGRESS.md
|
||||
|
||||
## 1. NGINX и SSL для felexdev.ru
|
||||
## Формат
|
||||
* Даты следуют в обратном хронологическом порядке
|
||||
* Формат таблиц: Статус → Задача → Краткое описание
|
||||
|
||||
**Выполнено:**
|
||||
- настроен NGINX для домена `felexdev.ru`;
|
||||
- развёрнут SSL‑сертификат;
|
||||
- проверена корректность конфигурации (`nginx -t`);
|
||||
- перезапущен сервис (`systemctl reload nginx`);
|
||||
- протестирован доступ по HTTPS (подтверждён статус «замочка» в браузере);
|
||||
- проверены логи NGINX (`/var/log/nginx/error.log`) на отсутствие ошибок SSL;
|
||||
- подтверждена актуальность SSL‑сертификата (срок действия, цепочка доверия).
|
||||
## Условные обозначения
|
||||
* ✔️ — задача выполнена полностью
|
||||
* ⚠️ — задача отложена
|
||||
* ❌ — задача отклонена
|
||||
|
||||
## 2. Postfix + TLS и DNS‑записи для felexdev.ru
|
||||
## 22.04.2026
|
||||
| Статус | Задача | Описание |
|
||||
|:-:|:-----|:-------|
|
||||
| ✔️ | Основа Android-приложения | Создана базовая структура проекта |
|
||||
| ⚠️ | API XOGame | Создана структура папок, определены публичные интерфейсы |
|
||||
|
||||
**Выполнено:**
|
||||
- настроен Postfix на приём писем с переадресацией;
|
||||
- настроены DNS‑записи:
|
||||
- MX — указывает на корректный почтовый сервер;
|
||||
- PTR (reverse DNS) — соответствует домену;
|
||||
- SPF — содержит разрешённые IP‑адреса отправителей;
|
||||
- DKIM — настроен и подписан (проверен через онлайн‑валидатор);
|
||||
- DMARC — настроен для агрегирования отчётов о доставке;
|
||||
- протестирована отправка и получение писем (включая переадресацию);
|
||||
- проверены логи Postfix (`/var/log/mail.log`) на ошибки.
|
||||
## 15.04.2026
|
||||
| Статус | Задача | Описание |
|
||||
|:-:|:-----|:-------|
|
||||
| ✔️ | BIMI | Разработка и публикация лейбла на сайте |
|
||||
| ✔️ | DNS BIMI | Настройка для felexdev.ru |
|
||||
| ✔️ | DNS BIMI | Настройка для neurox.su с привязкой к felexdev.ru |
|
||||
|
||||
## 3. Приобретение домена neurox.su и SSL
|
||||
## 13.04.2026
|
||||
| Статус | Задача | Описание |
|
||||
|:-:|:-----|:-------|
|
||||
| ✔️ | DNS MX-запись | Настройка для neurox.su → mail.felexdev.ru |
|
||||
| ✔️ | Postfix | Настройка виртуального домена neurox.su |
|
||||
| ✔️ | DNS SPF | Настройка для neurox.su |
|
||||
| ✔️ | DNS DKIM | Настройка для neurox.su |
|
||||
| ✔️ | DNS DMARC | Настройка для neurox.su |
|
||||
|
||||
**Выполнено:**
|
||||
- зарегистрирован домен `neurox.su` у аккредитованного регистратора;
|
||||
- делегированы DNS‑записи на нужные NS‑серверы;
|
||||
- получен SSL‑сертификат (например, через Let’s Encrypt);
|
||||
- установлен и привязан SSL‑сертификат к веб‑серверу;
|
||||
- проверена валидность сертификата (через SSL Labs или браузер).
|
||||
## 10.04.2026
|
||||
| Статус | Задача | Описание |
|
||||
|:-:|:-----|:-------|
|
||||
| ✔️ | Регистрация домена | Регистрация neurox.su |
|
||||
| ✔️ | SSL-сертификат | Приобретение и установка TLS-сертификата |
|
||||
| ✔️ | NGINX | Настройка виртуального хоста для neurox.su |
|
||||
| ✔️ | DNS A-запись | Настройка neurox.su → 94.41.20.144 |
|
||||
| ✔️ | Редирект | Настройка HTTP → HTTPS для neurox.su |
|
||||
|
||||
## 4. Настройка DNS‑зоны neurox.su для работы с mail.felexdev.ru
|
||||
|
||||
**Выполнено:**
|
||||
- SPF включает IP‑адрес `mail.felexdev.ru` как разрешённый отправитель;
|
||||
- DKIM‑подпись настроена на `mail.felexdev.ru`, публичный ключ размещён в DNS;
|
||||
- DMARC‑политика опубликована в DNS (`v=DMARC1; p=none; rua=mailto:reports@neurox.su`);
|
||||
- проверено распространение DNS‑записей (TTL, кэширование);
|
||||
- протестирована отправка писем с `neurox.su` через `mail.felexdev.ru`.
|
||||
|
||||
## 5. Настройка Postfix для neurox.su
|
||||
|
||||
**Выполнено:**
|
||||
- в конфигурации Postfix добавлен виртуальный домен `neurox.su`;
|
||||
- настроены виртуальные почтовые ящики или алиасы для домена;
|
||||
- проверено разрешение доменов в Postfix (`postmap`, `virtual_alias_maps`);
|
||||
- протестировано получение писем на адреса `@neurox.su`;
|
||||
- проверены права доступа к почтовым директориям;
|
||||
- проанализированы логи Postfix на ошибки доставки.
|
||||
|
||||
## 6. Запуск сайтов и редирект HTTP → HTTPS
|
||||
|
||||
**Выполнено:**
|
||||
- запущены оба сайта с временной заглушкой;
|
||||
- временная заглушка содержит контактную информацию (email администратора);
|
||||
- реализован редирект с HTTP на HTTPS через `return 301` в блоке `listen 80` NGINX;
|
||||
- протестирован редирект для всех поддоменов (если есть);
|
||||
- проверена загрузка заглушки по HTTPS;
|
||||
- подтверждено отсутствие ошибок 4xx/5xx в логах NGINX;
|
||||
- проверена скорость загрузки и доступность сайта из разных регионов.
|
||||
|
||||
---
|
||||
|
||||
## Общий итог
|
||||
|
||||
Инфраструктура развёрнута для двух доменов (`felexdev.ru` и `neurox.su`) с полной поддержкой:
|
||||
- защищённого соединения (HTTPS);
|
||||
- почтового сервиса (Postfix с переадресацией);
|
||||
- безопасности почты (SPF, DKIM, DMARC, DMARC);
|
||||
- корректной работы DNS‑записей.
|
||||
|
||||
Все основные сервисы (NGINX, Postfix) работают стабильно, редиректы гарантируют защищённое соединение.
|
||||
|
||||
# Извиняюсь за столь долгое отсутствие, здоровье важней всего! =)
|
||||
## До публикации проекта
|
||||
| Статус | Задача | Описание |
|
||||
|:-:|:-----|:-------|
|
||||
| ✔️ | NGINX | Установка и базовая конфигурация для felexdev.ru |
|
||||
| ✔️ | Регистрация домена | Регистрация felexdev.ru |
|
||||
| ✔️ | SSL-сертификат | Приобретение и установка TLS-сертификата |
|
||||
| ✔️ | DNS A-запись | Настройка felexdev.ru → 94.41.20.144 |
|
||||
| ✔️ | Редирект | Настройка HTTP → HTTPS для felexdev.ru |
|
||||
| ✔️ | Postfix | Установка и настройка почтового сервера |
|
||||
| ✔️ | DNS A | Настройка mail.felexdev.ru |
|
||||
| ✔️ | DNS MX | Настройка MX-записи для felexdev.ru → mail.felexdev.ru |
|
||||
| ✔️ | DNS PTR | Настройка обратной зоны 94.41.20.144 → mail.felexdev.ru |
|
||||
| ✔️ | DNS SPF | Настройка для mail.felexdev.ru |
|
||||
| ✔️ | DNS DKIM | Настройка для mail.felexdev.ru |
|
||||
| ✔️ | DNS DMARC | Настройка для mail.felexdev.ru |
|
||||
|
||||
@@ -1,81 +1,162 @@
|
||||
# NeurOX: Крестики‑нолики с ИИ (личный челлендж) 🔧
|
||||
# NeurOX: Крестики‑нолики с ИИ или войти в IT
|
||||
|
||||
Личный проект‑вызов: создать полностековую игру «Крестики‑нолики» с самообучающимся ИИ и шифрованием трафика. Цель — проверить собственные навыки на всех уровнях стека: от низкоуровневого C до мобильного клиента.
|
||||
## Цель проекта
|
||||
|
||||
**Почему это вызов** Полный типовой стэк разработки с нуля с минимумом библиотек, главный упор на эффективность кода. Основная цель - запустить полноценный сервис с минимумом затрат в условиях крайне ограниченных системных и временных ресурсов.
|
||||
|
||||
## Суть челленджа
|
||||
|
||||
Собрать систему «с нуля», в минималистичном стиле с мнимумом инструментов:
|
||||
* нейросеть на чистом C (без ML‑библиотек);
|
||||
* ядро игры с ручным управлением памятью;
|
||||
* NGINX + PHP + CodeIgniter (REST API);
|
||||
* десктоп‑клиент на C++/SFML;
|
||||
* Android‑клиент Java/Kotlin;
|
||||
* сетевая связь по TCP/IP;
|
||||
* шифрование: RSA (2048 бит) для рукопожатия + динамический XOR для данных.
|
||||
Разработка экосистемы многопользовательской игры крестики-нолики в классическом исполнении с полным стеком технологий от С до Android и Web.
|
||||
|
||||
## Для кого этот проект
|
||||
* подойдёт для изучения новичкам
|
||||
* для себя - восстановление навыков
|
||||
* **Для себя** — восстановление навыков.
|
||||
* **Для своих детей** — наследие, объяснение основных парадигм и принципов программирования.
|
||||
* **Для остальных** — подойдёт для изучения новичкам.
|
||||
|
||||
## Дисклеймер
|
||||
* В коде может, вернее - будет, использоваться неочевидная логика
|
||||
* Если вы считаете что я где-то что-то сделал не по фэн-шую - я эстет, но в плане эффективности
|
||||
* Если когда-нибудь кто-нибудь найдёт совпадение названия проекта и репозитория нарушением авторских прав - Бог Вам судья =)
|
||||
* Проект личный, код открытый, милости просим, заходите и смотрите.
|
||||
## Парадигмы
|
||||
|
||||
## Текущий статус
|
||||
* **KISS** — должен оставаться донельзя простым для понимания.
|
||||
* **YAGNI** — время и ресурсы дороже излишеств.
|
||||
|
||||
Проект стартует с чистого листа. На данный момент:
|
||||
* определена архитектура системы;
|
||||
* выбран стек технологий;
|
||||
* начата работа над ядром на C.
|
||||
## Технологии
|
||||
|
||||
**Что предстоит:**
|
||||
* реализовать базовую логику игры (3×3);
|
||||
* написать нейросеть на C (обучение на партиях);
|
||||
* создать REST API на PHP для связи компонентов;
|
||||
* разработать десктоп‑ и Android‑клиенты;
|
||||
* внедрить схему шифрования;
|
||||
* интегрировать все части в единую систему.
|
||||
### Сервер
|
||||
|
||||
## Реалистичный план этапов (дорожная карта)
|
||||
**Back-end Core (C)**
|
||||
* **Игровой движок** — базовая логика игры: проверка ходов, определение победы/ничьей, управление состоянием доски 3×3.
|
||||
* **Нейросеть 9-18-9** — ИИ‑противник: полносвязная сеть (9 входных нейронов — состояние доски, 18 скрытых, 9 выходных — оценка ходов). Обучается на партиях.
|
||||
* **TCP/IP со сквозным шифрованием** — защищённая передача данных между клиентом и сервером (RSA + XOR).
|
||||
* **Аллокатор** — кастомное управление памятью для повышения производительности и контроля утечек.
|
||||
* **Очереди** — буферизация и синхронизация входящих/исходящих сообщений между потоками.
|
||||
|
||||
**Back-end Web (PHP + CodeIgniter)**
|
||||
* **NGINX** — веб‑сервер для статического фронтенда (HTML/CSS/JS) и проксирования.
|
||||
* **PHP + CodeIgniter** — бэкенд веб‑интерфейса и «мост» между веб‑клиентом (JS) и C‑ядром. Обрабатывает AJAX‑запросы, передаёт команды в ядро через Unix‑сокеты/пайпы, возвращает ответы в формате JSON.
|
||||
* **MySQL** — хранение данных пользователей, статистики игр, логов. Используется веб‑сервером для отображения информации.
|
||||
|
||||
**Front-end (Web)**
|
||||
* **HTML/CSS** — структура и визуальное оформление веб‑версии игры: доска, кнопки, индикаторы.
|
||||
* **JavaScript** — интерактивность веб‑интерфейса: обработка кликов, обновление доски, анимация ходов, связь с сервером через AJAX/WebSocket.
|
||||
|
||||
### Клиент
|
||||
* **Core (С-ядро):**
|
||||
* **XOGame** — оффлайн игровая логика (проверка ходов, определение победы);
|
||||
* **NeurOXNet** — нейросеть (обучается на игре против пользователя);
|
||||
* **epoll** — сетевая коммуникация (TCP/IP, Linux/Android);
|
||||
* **WSAPoll+IOCP** — сетевая коммуникация (TCP/IP, Windows);
|
||||
* **SQLite** — хранилище локальных настроек интерфейса, весов нейросети.
|
||||
* **GUI:**
|
||||
* **PC‑Desktop** — нативное приложение с графическим интерфейсом на базе SFML (Simple Fast Media Library);
|
||||
* **Android — Kotlin + Jetpack** — мобильная версия игры с реактивным UI на базе Jetpack Compose:
|
||||
* **ViewModel** — управление состоянием UI и бизнес‑логикой;
|
||||
* **Репозиторий** — абстракция доступа к данным (локальные данные + сетевые запросы);
|
||||
* **Data Binding** — синхронизация данных между UI и ViewModel.
|
||||
|
||||
### Инфраструктура
|
||||
* **Postfix** — почтовый сервер для отправки уведомлений (подтверждение регистрации, напоминания о ходе игры).
|
||||
|
||||
## Оборудование
|
||||
|
||||
* **Сервер:**
|
||||
* OS: Ubuntu Server 24.04;
|
||||
* CPU: Intel Core i5‑3470, 4 @ 3.2 GHz;
|
||||
* RAM: 8 GB;
|
||||
* ROM: noname 256 GB SSD;
|
||||
* WiFi: 2.4 GHz, прямая видимость до 6 м (~32 Mbit/s).
|
||||
|
||||
* **Рабочая станция (ПК):**
|
||||
* OS: Windows 10;
|
||||
* CPU: Intel Core i5‑3470, 4 @ 3.2 GHz;
|
||||
* RAM: 16 GB;
|
||||
* ROM: noname 256 GB SSD.
|
||||
* WiFi: 2.4 GHz, прямая видимость до 6 м (~32 Mbit/s).
|
||||
|
||||
* **Ноутбук:**
|
||||
* OS: Dual boot (Windows 10 / Ubuntu 24.04);
|
||||
* CPU: noname AMD‑Like, 4 @ 1.6 GHz;
|
||||
* RAM: noname 16 GB;
|
||||
* ROM: noname 1 TB SSD.
|
||||
|
||||
* **Смартфон:**
|
||||
* Модель: Xiaomi Redmi Note 14 Pro;
|
||||
* OS: HyperOS 3.0.5.0 (Android 14);
|
||||
* CPU: MediaTek Helio G100, 8 @ 2.2 GHz;
|
||||
* RAM: 12 GB;
|
||||
* ROM: 512 GB SSD.
|
||||
|
||||
### Стандарты и спецификации
|
||||
|
||||
* **C11** (ISO/IEC 9899:2011) — для C‑ядра и десктоп‑клиента.
|
||||
* **C++11** (ISO/IEC 14882:2011) — для десктоп‑клиента (SFML).
|
||||
* **POSIX** — поддержка Unix‑подобных систем (Linux/Android):
|
||||
* `epoll` — асинхронный ввод‑вывод для масштабирования сервера;
|
||||
* `pthreads` (POSIX Threads) — управление потоками.
|
||||
* **WinAPI** (Windows Vista+) — поддержка Windows‑платформы:
|
||||
* **WSAPoll** — асинхронный ввод‑вывод (аналог POSIX `poll()`, доступен с Windows Vista);
|
||||
* **Windows Threads** — управление потоками в Windows.
|
||||
* **Компиляторы:**
|
||||
* **GCC 9+** (Linux) — компиляция C‑ядра и десктоп‑клиента;
|
||||
* **Clang 11+** (Android NDK) — компиляция C‑библиотеки для Android;
|
||||
* **MSVC 2019+** (Visual Studio) — компиляция Windows‑версии клиента и сервера.
|
||||
* **CMake:**
|
||||
* **3.16+** (Linux/Windows) — единая система сборки для десктоп‑платформ;
|
||||
* **3.11+** (Android) — сборка C‑ядра через Android NDK (официальная поддержка NDK, Clang, ABI).
|
||||
|
||||
## Инструменты
|
||||
* **IDE:**
|
||||
* **Visual Studio Code** — Linux, PHP, HTML/CSS, JavaScript, SQL;
|
||||
* **Visual Studio** — Windows;
|
||||
* **Android Studio** — Android.
|
||||
* **Системы сборки:** CMake, Make.
|
||||
* **Препрофилирование:** YandexGPT 5.1 Pro (Алиса AI).
|
||||
* **Code review:** YandexGPT 5.1 Pro (Алиса AI).
|
||||
* **Техническая документация:** Doxygen, JSDoc, PHPDoc.
|
||||
* **Контроль версий:** Git.
|
||||
|
||||
## Прогресс
|
||||
|
||||
|➤|**Работа с документами**| Реорганизация документации, оптимизация каталогов проекта|
|
||||
|:-:|:-----------------------|:------------------------|
|
||||
| ⚠️ | **Работа над аллокатором** | Проектирование архитектуры. |
|
||||
| ✔️ | **Модуль игры** | Архитектура спроектирована. |
|
||||
| ✔️ | **Инфраструктура** | Развёрнуты NGINX, Postfix, MySQL. |
|
||||
|
||||
Подробный прогресс: [PROGRESS.md](PROGRESS.md)
|
||||
|
||||
## Статус
|
||||
**В активной разработке**
|
||||
|
||||
## План реализации
|
||||
|
||||
**Принцип планирования:**
|
||||
* работа ведётся небольшими сессиями (30–60 минут) в свободное время;
|
||||
* приоритет — последовательность, а не скорость;
|
||||
* каждый этап завершается минимально жизнеспособным результатом (MVP‑подход);
|
||||
* гибкость: этапы можно менять местами или дробить на подзадачи.
|
||||
* гибкость: этапы могут меняться местами, оставаясь в основной логике процесса.
|
||||
|
||||
### Этап 1. Ядро на C (логика + нейросеть) — 3–4 месяца
|
||||
### Этап 1. Инфраструктура — 2–4 недели
|
||||
* DNS: felexdev.ru + neurox.su;
|
||||
* NGINX: сайт‑заглушка;
|
||||
* Postfix: SPF/DKIM/DMARC;
|
||||
* MySQL;
|
||||
* тестирование инфраструктуры.
|
||||
|
||||
### Этап 2. Ядро на C (логика + нейросеть) — 3–4 месяца
|
||||
* аллокатор (возможность делегирования блоков между потоками);
|
||||
* очередь пакетов/сообщений, синхронизация (двунаправленная на базе списка);
|
||||
* базовая логика игры (3×3 доска, проверка победы);
|
||||
* простая нейросеть (3 слоя, сигмоида, обучение на 100+ партиях);
|
||||
* консольный режим для тестирования;
|
||||
* битовые маски для оптимизации доски.
|
||||
* простая нейросеть (3 слоя, сигмоида/ReLU, обучение на 100+ партиях);
|
||||
* модуль взаимодействия с СУБД (MySQL);
|
||||
* пакетная передача TCP/IP со сквозным шифрованием (RSA + XOR);
|
||||
* контроль активности соединения средствами ICMP (ping).
|
||||
|
||||
### Этап 2. Сервер на PHP (API + БД) — 2–3 месяца
|
||||
* REST API (`/start_game`, `/make_move`, `/get_state`);
|
||||
* интеграция с ядром через Unix‑сокеты;
|
||||
* SQLite для хранения партий и статистики;
|
||||
* логирование запросов.
|
||||
### Этап 3. Сервер на PHP (API + БД) — 2–3 месяца
|
||||
* интеграция с ядром через Unix‑сокеты/пайпы.
|
||||
|
||||
### Этап 3. Десктоп‑клиент (C++/SFML) — 3–4 месяца
|
||||
### Этап 4. Десктоп‑клиент (C++/SFML) — 3–4 месяца
|
||||
* базовый UI (доска 3×3, кнопки);
|
||||
* связь с сервером по TCP/IP;
|
||||
* анимация ходов и победы;
|
||||
* кэширование состояния для офлайн‑режима.
|
||||
|
||||
### Этап 4. Шифрование (RSA + XOR) — 1–2 месяца
|
||||
* RSA‑рукопожатие (2048 бит, OpenSSL);
|
||||
* динамический XOR (смена ключа по таймеру/счётчику);
|
||||
* проверка целостности пакетов (CRC32);
|
||||
* тесты на утечку памяти и производительность.
|
||||
* игра с локальным ИИ (нейросеть).
|
||||
|
||||
### Этап 5. Android‑клиент (Kotlin + NDK) — 4–6 месяцев
|
||||
* MVP: доска 3×3 и связь с сервером;
|
||||
* доска 3×3 и связь с сервером;
|
||||
* вызов C‑библиотеки через JNI;
|
||||
* поддержка шифрования;
|
||||
* оптимизация под мобильные устройства.
|
||||
|
||||
### Этап 6. Интеграция и тестирование — 2–3 месяца
|
||||
@@ -84,36 +165,18 @@
|
||||
* отладка многопоточности;
|
||||
* финальная оптимизация.
|
||||
|
||||
### Этап 7. Релиз MVP — 1 месяц
|
||||
### Этап 7. Релиз — 1 месяц
|
||||
* сборка дистрибутивов (Windows, Linux, Android);
|
||||
* документация для запуска;
|
||||
* публикация демо‑видео.
|
||||
|
||||
---
|
||||
## Дисклеймер
|
||||
|
||||
## Гибкость и адаптация
|
||||
* В коде может, вернее — будет, использоваться неочевидная логика.
|
||||
* Если вы считаете, что я где‑то что‑то сделал не по фэн‑шую — я эстет, но в плане эффективности.
|
||||
* Если когда‑нибудь кто‑нибудь найдёт совпадение названия проекта и репозитория нарушением авторских прав — Бог Вам судья! 😃
|
||||
* Проект личный, код открытый, милости просим, заходите и смотрите.
|
||||
|
||||
**Если времени меньше:**
|
||||
* пропускаю Android‑клиент — фокусируюсь на десктопе;
|
||||
* заменяю RSA на OpenSSL (готовые функции);
|
||||
* упрощаю нейросеть до минимакса;
|
||||
* откладываю динамический XOR на будущее.
|
||||
|
||||
**Если появляется больше времени:**
|
||||
* ускоряю этапы за счёт увеличения сессий;
|
||||
* добавляю фичи (режим PvP, статистика, темы UI).
|
||||
|
||||
## Технологии
|
||||
|
||||
* **Ядро/нейросеть:** C17 (GCC, POSIX.1).
|
||||
* **Сервер:** NGINX + PHP 8.3+ + CodeIgniter.
|
||||
* **Десктоп‑клиент:** C++17 + SFML 2.5.
|
||||
* **Android‑клиент:** Kotlin + Android NDK.
|
||||
* **Сеть:** TCP/IP, Unix‑сокеты (Web ↔ TCP/IP Сервер ↔ Ядро).
|
||||
* **Шифрование:** RSA 2048 бит, XOR с динамическим ключом.
|
||||
* **БД:** MySQL 8.0+.
|
||||
* **Инструменты:** Git, CMake, Makefile.
|
||||
* **IDE:** VS Code(Linux), VisualStudio(Windows).
|
||||
|
||||
## Лицензия
|
||||
Apache License 2.0 — код открыт для изучения.
|
||||
@@ -122,8 +185,42 @@ Apache License 2.0 — код открыт для изучения.
|
||||
* GitHub: [@felex67](https://github.com/felex67)
|
||||
* Email: <a href="mailto:admin@felexdev.ru">admin@felexdev.ru</a>, <a href="mailto:felexxx67@yandex.ru">felexxx67@yandex.ru</a>
|
||||
|
||||
---
|
||||
# Лирическое отступление
|
||||
К каждому из модулей будет приложено своё "лирическое отступление" в формате дневника процесса раззработки(DAIRY.md) сплошным потоком мыслей в обычном разговорном стиле. Целю такого формата является продемонстрировать как происходит собственно сам процесс разработки от и до без захламления технической документации. В коде иногда можно будет встретить сноски на эти самые дневники. В корневом DAIRY.md будут отражены мысли масштаба проекта в целом(взаимодействие компонентов и всей экосистемы в целом). Вся техническая документация заполняется по мере готовности того или иного модуля по следующим принципам: **мысль ↔ дневник ↔ код → комментарии → тесты → профилирование(по возможности) → документация**.
|
||||
### ИИ аспект
|
||||
Начиная с истоков увлечения программированием привык полагаться на результаты работы кода — профилирование и тесты. Как у борца за эффективность у меня нет нежелания заниматься рефакторингом ради рефакторинга, по-этому на данном этапе своей жизни используюю ИИ в первую очередь для препрофилирования нагрузок и определения узких мест на стадии разработки архитектуры. Считаю что от этого зависит львиная доля успешности проекта впринципе, так как если на скорую руку спроектировать, то даже самые опытные разработчики не помогут, собственно после такого подхода и начинается описанный выше рефакторинг.
|
||||
|
||||
**Важно:** проект в активной разработке. Сроки ориентировочные — зависят от свободного времени. Это дневник челленджа: фиксация прогресса, решений и находок.
|
||||
Единственным моим ассистентом-специалистом по части критики и статистики является YandexGPT 5.1 Pro(АлисаAI). Порой наши многочасовые споры выматывают, но она очень помогает в следующих аспектах:
|
||||
* Сбор статистики по типовым нагрузкам на стадии проектирования.
|
||||
* Анализ кода в части читаемости, т.к. проект публичен.
|
||||
* Анализ кода в формате Code-review, практическая польза:
|
||||
* дисциплинирует, код всегда должен оставаться чистым.
|
||||
* подготовка ко входу в реальную разработку с живой командой, моя основная цель - карьера в IT.
|
||||
* даже топовые специалисты могут допускать казалось-бы очевидные ошибки, когда мысли летят одна за другой их можно по-просту незаметить.
|
||||
* Даёт понимание алгоритмов и шаблонов работы ИИ при статическом анализе кода.
|
||||
|
||||
Спасибо, что следите за ходом! 🍰 Пусть каждая строка кода будет шагом к победе — в своём темпе! 🎉
|
||||
Что я понял за время общения с ней(YandexGPT АлисаAI):
|
||||
* Никогда не верьте ИИ "на слово", как бы он Вас не уверял что больше такого не повторится, он всё понял, и глупых вопросов больше не последует.
|
||||
* Никогда не следуйте подсказкам ИИ(так лучше) если понимаете что это Вам не нужно, очень часто ИИ "зацикливается" сам на себя(пока непонятно почему, но мы это выясним).
|
||||
* 10, а лучше 100 раз переспросите с разных сторон(задавайте вопросы в разных вариациях до тех пор пока ответ не будет однозначным).
|
||||
* Даже если Вам кажется что ИИ дал ±точный ответ — переспросите ещё раз.
|
||||
* Не пытайтесь доказать ИИ что Вы — "не олень", он этого не оценит.
|
||||
* Предлагая ИИ оценить написанный код будьте готовы к тому что Вас разнесут в пух и прах по тем аспектам где ответственность кода заканчивается(принцип SRP), у ИИ галочка на расширяемость и проверки(NULL-sfety, неявные проверки они попросту не видят), вернее не "галочка" а "ГАЛИЩЕ", KISS+YAGNI им надо явно объяснять в комментариях, хотя даже после этого они в ответе выкатять здоровенный список "недостатки".
|
||||
* ИИ - это инструмент технического анализа по "устоявшимся" шаблонам, каждое неординарное решение сразу попадает в "недостатки". ИИ не видит "замысел", только разрозненные шаблоны и маркеры.
|
||||
|
||||
Мне очень поднимают настроение многочасовые баталии с ней, однако, это отвлекает от сути. Каждый раз когда я в итоге довожу YandexGPT 5.1 Pro(АлисаAI) до стадии "Да, Вы правы..." в коде я оставляю коментарии сгенерированные ею для неё же и помечаю их как "коментарии от YandexGPT 5.1 Pro(АлисаAI)". Очень часто в коментариях к коду можно встретить объяснения такого рода "АлисаAI настояла" в тех местах где наши мнения расходились но я пошёл на компромисс.
|
||||
|
||||
### Основной посыл
|
||||
|
||||
Хоть проект изначально и пердполагался как портфолио, в нынешнем своём состоянии он представляет из себя немного больше. Скорее это рассказ о том "как это было". Проект постепенно перерос в своеобразную "историю жизни", это неординарный подход к разработке, но в виду того что я веду проект один и колаборация не предполагается, я продолжу в том-же духе, в первую очередь — для своих детей, им интересно это читать, а мне не то чтобы не сложно, а скорее — приятно писать для них. Таким образом я чувствую себя причастным ко вкладу в искуство и к произведению "История одного байта", которое давным давно глубоко запало мне в душу и многому научило с философской точки зрения.
|
||||
|
||||
### Образовательный аспект
|
||||
Проект открыт для изучения, как автор — не претендую на звание "разработчик года", отнюдь, считаю что всегда есть куда идти, даже топовым кодерам, но точно знаю что некоторые техники встречающиеся в коде помогут малоопытным или "смежным" специалистам понять всю красоту низкоуровнего программирования, возможно, перенять некоторые практики и применять их вдальнейшем. Весь код будет снабжён "удобоваримыми" коментариями для специалистов всех уровней и языковых групп(имеется в виду группы языков программирования).
|
||||
|
||||
### Основная стратегия KISS+YAGNI
|
||||
Я не предусматриваю грандиозное расширение, проект должен обеспечить максимальную производительность и отказоустойчивость для классических крестиков-ноликов в многопользовательском режиме с возможностью игры против ИИ(нейросети). Как основатель проекта я не предполагаю увеличивать размер поля до MAX_INT*MAX_INT и заниматься безопасностью ради безопасности. Каждый модуль проекта имеет строго свою область ответственности.
|
||||
|
||||
### Начата разработка общих модулей, конкретно — XOGame.
|
||||
Разработана типичная архитектура со скрытой реализацией и заложенной возможностью изменения поведения модуля через указатели на структуры. Как и обычно(не раз проверено) внешний интерфейс константен, доступ к функциям модуля только через указатели внутри внешних неизменяемых структур. Почему именно так — потому что так проще отловить ошибки, проверяем только внутреннюю реализацию, отлаживаем её и используем. Если в дальнейшем возникают ошибки - это не вина модуля, это вина вызывающего кода. В контексте всего решения это избавляет от рефапкторинга ради рефакторинга и бесконечной скачки от файла к файлу.
|
||||
|
||||
После предоставления кода **xogame/includes/XOGame.h**, **xogame/headers/_XOGame.h** и **xogame/src/XOGame.c** на ревью YandexGPT 5.1 Pro(АлисаAI) и 4-хчасовой баталии по поводу **void* fxalloc(size_t _NBytes)** решено пока что "забыть" про реализацию XOGame.c и заняться аллокатором **fxalloc.c**, иначе я не выдержу, порой она достаёт "до чёртиков" 😃
|
||||
|
||||
+143
@@ -0,0 +1,143 @@
|
||||
# README.md
|
||||
# NeurOX: Крестики‑нолики с ИИ или войти в IT
|
||||
|
||||
## Цель проекта
|
||||
|
||||
Разработка экосистемы многопользовательской игры крестики-нолики в классическом исполнении с полным стеком технологий от С до Android и Web.
|
||||
|
||||
## Суть челленджа
|
||||
|
||||
Собрать систему «с нуля», в минималистичном стиле с мнимумом инструментов:
|
||||
* нейросеть на чистом C (без ML‑библиотек);
|
||||
* ядро игры с ручным управлением памятью;
|
||||
* NGINX + PHP + CodeIgniter (REST API);
|
||||
* десктоп‑клиент на C++/SFML;
|
||||
* Android‑клиент Java/Kotlin;
|
||||
* сетевая связь по TCP/IP;
|
||||
* шифрование: RSA (2048 бит) для рукопожатия + динамический XOR для данных.
|
||||
|
||||
|
||||
## Текущий статус
|
||||
|
||||
Проект стартует с чистого листа. На данный момент:
|
||||
* определена архитектура системы;
|
||||
* выбран стек технологий;
|
||||
* начата работа над ядром на C.
|
||||
|
||||
**Что предстоит:**
|
||||
* реализовать базовую логику игры (3×3);
|
||||
* написать нейросеть на C (обучение на партиях);
|
||||
* создать REST API на PHP для связи компонентов;
|
||||
* разработать десктоп‑ и Android‑клиенты;
|
||||
* внедрить схему шифрования;
|
||||
* интегрировать все части в единую систему.
|
||||
|
||||
## Прогресс
|
||||
Весь прогресс отражен в файле **[PROGRESS.md](PROGRESS.md)**
|
||||
|
||||
## Реалистичный план этапов (дорожная карта)
|
||||
|
||||
**Принцип планирования:**
|
||||
* работа ведётся небольшими сессиями (30–60 минут) в свободное время;
|
||||
* приоритет — последовательность, а не скорость;
|
||||
* каждый этап завершается минимально жизнеспособным результатом (MVP‑подход);
|
||||
* гибкость: этапы можно менять местами или дробить на подзадачи.
|
||||
|
||||
### Этап 1. Ядро на C (логика + нейросеть) — 3–4 месяца
|
||||
* базовая логика игры (3×3 доска, проверка победы);
|
||||
* простая нейросеть (3 слоя, сигмоида, обучение на 100+ партиях);
|
||||
* консольный режим для тестирования;
|
||||
* битовые маски для оптимизации доски.
|
||||
|
||||
### Этап 2. Сервер на PHP (API + БД) — 2–3 месяца
|
||||
* REST API (`/start_game`, `/make_move`, `/get_state`);
|
||||
* интеграция с ядром через Unix‑сокеты;
|
||||
* SQLite для хранения партий и статистики;
|
||||
* логирование запросов.
|
||||
|
||||
### Этап 3. Десктоп‑клиент (C++/SFML) — 3–4 месяца
|
||||
* базовый UI (доска 3×3, кнопки);
|
||||
* связь с сервером по TCP/IP;
|
||||
* анимация ходов и победы;
|
||||
* кэширование состояния для офлайн‑режима.
|
||||
|
||||
### Этап 4. Шифрование (RSA + XOR) — 1–2 месяца
|
||||
* RSA‑рукопожатие (2048 бит, OpenSSL);
|
||||
* динамический XOR (смена ключа по таймеру/счётчику);
|
||||
* проверка целостности пакетов (CRC32);
|
||||
* тесты на утечку памяти и производительность.
|
||||
|
||||
### Этап 5. Android‑клиент (Kotlin + NDK) — 4–6 месяцев
|
||||
* MVP: доска 3×3 и связь с сервером;
|
||||
* вызов C‑библиотеки через JNI;
|
||||
* поддержка шифрования;
|
||||
* оптимизация под мобильные устройства.
|
||||
|
||||
### Этап 6. Интеграция и тестирование — 2–3 месяца
|
||||
* синхронизация состояния между десктопом и Android;
|
||||
* стресс‑тест (10+ одновременных игр);
|
||||
* отладка многопоточности;
|
||||
* финальная оптимизация.
|
||||
|
||||
### Этап 7. Релиз MVP — 1 месяц
|
||||
* сборка дистрибутивов (Windows, Linux, Android);
|
||||
* документация для запуска;
|
||||
* публикация демо‑видео.
|
||||
|
||||
---
|
||||
|
||||
## Гибкость и адаптация
|
||||
|
||||
**Если времени меньше:**
|
||||
* пропускаю Android‑клиент — фокусируюсь на десктопе;
|
||||
* заменяю RSA на OpenSSL (готовые функции);
|
||||
* упрощаю нейросеть до минимакса;
|
||||
* откладываю динамический XOR на будущее.
|
||||
|
||||
**Если появляется больше времени:**
|
||||
* ускоряю этапы за счёт увеличения сессий;
|
||||
* добавляю фичи (режим PvP, статистика, темы UI).
|
||||
|
||||
## Технологии
|
||||
|
||||
## Особенности архитектуры, решений и тактик (добавлено 22.04.2026)
|
||||
|
||||
### ИИ аспект
|
||||
Начиная с истоков увлечения программированием привык полагаться на результаты работы кода(профилирование) и нежеланием заниматься рефакторингом ради рефакторинга, по-этому на данном этапе своей жизни используюю ИИ в первую очередь для препрофилирования нагрузок и определения узких мест на стадии разработки Архитектуры, считаю что от этого зависит львиная доля успешности проекта впринципе(если на скорую руку сделать архитектуру, даже самые опытные разработчики не помогут, тут и начинается описанный выше рефакторинг).
|
||||
Единственным моим ассистентом и специалистом по части критики и статистики является YandexGPT 5.1 Pro(АлисаAI). Порой наши многочасовые споры выматывают, но она очень помогает в следующих аспектах:
|
||||
* Анализ кода в части читаемости, т.к. проект публичен.
|
||||
* Сбор статистики по типовым нагрузкам.
|
||||
* Понимание алгоритмов и шаблонов работы ИИ при статическом анализе кода.
|
||||
|
||||
Что я понял за время общения с ней:
|
||||
* Никогда не верьте ИИ "на слово", как бы он Вас не уверял что больше такого не повторится.
|
||||
* Никогда не следуйте подсказкам ИИ если понимаете что это Вам не нужно.
|
||||
* 10, а лучше - 100 раз переспросите с разных сторон
|
||||
* даже если Вам кажется что ИИ дал точный ответ - переспросите ещё раз.
|
||||
* Не пытайтесь доказать ИИ что Вы - "не олень", он этого не оценит
|
||||
* Предлагая ИИ оценить ИИ написанный код будьте готовы к тому что Вас разнесут в пух и прах по тем аспектам где ответственность кода заканчивается, у ИИ галочка на расширяемость и проверки, вернее не "галочка" а "ГАЛИЩЕ"
|
||||
|
||||
Мне очень поднимают настроение многочасовые баталии с ней, однако, это отвлекает от сути. Каждый раз когда я в итоге довожу YandexGPT 5.1 Pro(АлисаAI) до стадии "Да, Вы правы..." в коде я оставляю коментарии сгенерированные ею для неё же и помечаю их как "коментарии от YandexGPT 5.1 Pro(АлисаAI)". Очень часто в коментариях к коду можно встретить объяснения такого рода "АлисаAI настояла" в тех местах где наши мнения расходились но я пошёл на компромисс.
|
||||
### Основной посыл
|
||||
Хоть проект изначально и пердполагался как портфолио, в нынешнем своём состоянии он представляет из себя немного больше. Скорее это рассказ о том "как это было". Проект постепенно перерос в своеобразную "историю жизни", это неординарный подход к разработке, но в виду того что я веду проект один и колаборация не предполагается, я продолжу в том-же духе, в первую очередь - для своих детей, им интересно это читать, а мне не то чтобы не сложно, а скорее - приятно писать для них. Таким образом я чувствую себя причастным ко вкладу в искуство и к произведению "История одного байта", которое давным давно глубоко запало мне в душу и многому научило с философской точки зрения.
|
||||
### Образовательный аспект
|
||||
Проект открыт для изучения, как автор - не претендую на звание "разработчик года", отнюдь, считаю что всегда есть куда идти, даже топовым кодерам, но точно знаю что некоторые техники встречающиеся в коде помогут малоопытным или "смежным" специалистам понять всю красоту низкоуровнего программирования, возможно, перенять некоторые практики и применять их вдальнейшем. Весь код будет снабжён "удобоваримыми" коментариями для специалистов всех уровней и языковых групп(имеется в виду группы языков программирования).
|
||||
### Основная стратегия KISS+YAGNI
|
||||
Я не предусматриваю грандиозное расширение, проект должен обеспечить максимальную производительность и отказоустойчивость для классических крестиков-ноликов в многопользовательском режиме с возможностью игры против ИИ(нейросети). Как основатель проекта я не предполагаю увеличивать размер поля до MAX_INT*MAX_INT и заниматься безопасностью ради безопасности. Каждый модуль проекта имеет строго свою область ответственности.
|
||||
### Начата разработка общих модулей, конкретно - XOGame.
|
||||
Разработана типичная архитектура со скрытой реализацией и заложенной возможностью изменения поведения модуля через указатели на структуры. Как и обычно(не раз проверено) внешний интерфейс константен, доступ к функциям модуля только через указатели внутри внешних неизменяемых структур. Почему именно так - потому что так проще отловить ошибки, проверяем только внутреннюю реализацию, отлаживаем её и используем. Если в дальнейшем возникают ошибки - это не вина модуля, это вина вызывающего кода. В контексте всего решения это избавляет от рефапкторинга ради рефакторинга и бесконечной скачки от файла к файлу.
|
||||
После предоставления кода **server/includes/XOGame.h**, **server/headers/_XOGame.h** и **server/src/XOGame.c** на ревью YandexGPT 5.1 Pro(АлисаAI) и 4-хчасовой баталии по поводу **void* fxalloc(size_t _NBytes)** решено пока что "забыть" про реализацию XOGame.c и заняться аллокатором **fxalloc.c**, иначе я не выдержу, порой она достаёт "до чёртиков" ;)
|
||||
|
||||
## Лицензия
|
||||
Apache License 2.0 — код открыт для изучения.
|
||||
|
||||
## Контакты
|
||||
* GitHub: [@felex67](https://github.com/felex67)
|
||||
* Email: <a href="mailto:admin@felexdev.ru">admin@felexdev.ru</a>, <a href="mailto:felexxx67@yandex.ru">felexxx67@yandex.ru</a>
|
||||
|
||||
---
|
||||
|
||||
**Важно:** проект в активной разработке. Сроки ориентировочные — зависят от свободного времени. Это дневник челленджа: фиксация прогресса, решений и находок.
|
||||
|
||||
Спасибо, что следите за ходом! 🍰 Пусть каждая строка кода будет шагом к победе — в своём темпе! 🎉
|
||||
|
||||
@@ -0,0 +1,34 @@
|
||||
# TODO.md
|
||||
|
||||
## Информация
|
||||
* Файл для отслеживания текущих задач проекта
|
||||
* Последнее обновление: [25.04.2026]
|
||||
|
||||
## Условные обозначения
|
||||
* 🔥 - Наивысший приоритет
|
||||
* 🔴 - Высокий приоритет
|
||||
* 🟡 - Средний приоритет
|
||||
* 🟢 - Низкий приоритет
|
||||
|
||||
## Задачи в процессе
|
||||
|Срочность|Компонент|Задача|Описание|
|
||||
|:-------:|:-------:|:-----|:-------|
|
||||
|🔥|**Архитектура**|**Работа с документацией**|Стандартизация и реорганизация документации|
|
||||
|🔥|**FXAlloc**|**Проектирование архитектуры**|Интерфейс, внутреннее устройство|
|
||||
|🔥|**FXAlloc**|**Документация**|Описание архитектуры решения, ведение DAIRY.md|
|
||||
|🔥|**FXAlloc**|**Logic**|Реализации внутренних методов|
|
||||
|🔥|**FXAlloc**|**API**|Реализация внешних методов|
|
||||
|🔥|**FXAlloc**|**Тестирование**|Написание юнит-тестов|
|
||||
|🔥|**FXAlloc**|**Оптимизация**|Анализ производительности|
|
||||
|🔴|**XOGame**|**Logic**|Реализации внутренних методов|
|
||||
|🔴|**XOGame**|**API**|Реализации публичных методов|
|
||||
|🔴|**XOGame**|**Тестирование**|Написание юнит-тестов|
|
||||
|🔴|**XOGame**|**Оптимизация**|Анализ производительности|
|
||||
|🟡|**AINeurox**|**Проектирование архитектуры**|Интерфейс, внутреннее устройство|
|
||||
|🟡|**AINeurox**|**Документация**|Описание архитектуры решения, ведение DAIRY.md|
|
||||
|🟡|**AINeurox**|**Logic**|Реализации внутренних методов|
|
||||
|🟡|**AINeurox**|**API**|Реализация внешних методов|
|
||||
|🟡|**AINeurox**|**Тестирование**|Написание юнит-тестов|
|
||||
|🟡|**AINeurox**|**Оптимизация**|Анализ производительности|
|
||||
|🟢|**Android**|Интеграция|Подключение XOGame к проекту|
|
||||
|🟢|**Android**|Тестирование|Проверка корректности работы|
|
||||
@@ -0,0 +1 @@
|
||||
При создании проекта клиент Android предполагалось создавать в последнюю очередь в виду того что я никогда не программировал приложения под эту платформу, однако, в виду привычки сначала делать самое тяжёлое решил "познакомиться" с Kotlin и обратился к YandexGPT за помощью, о чём в итоге очень сильно пожалел. Я привык писать код на уровне "железа" а не "абстракции", многие парадигмы применяемые в мобильной разработке мне чужды, моим основным принципом программивания был, есть и будет эффективность, я от этого не откажусь никогда. Почему я пожалел о том что понадеялся на ИИ - они "не видят" код как замысел, упорно будут доказывать что нужно использовать
|
||||
@@ -0,0 +1 @@
|
||||
sandbox
|
||||
Vendored
+28
@@ -0,0 +1,28 @@
|
||||
{
|
||||
"tasks": [
|
||||
{
|
||||
"type": "cppbuild",
|
||||
"label": "C/C++: cl.exe build active file",
|
||||
"command": "cl.exe",
|
||||
"args": [
|
||||
"/Zi",
|
||||
"/EHsc",
|
||||
"/nologo",
|
||||
"/Fe${fileDirname}\\${fileBasenameNoExtension}.exe",
|
||||
"${file}"
|
||||
],
|
||||
"options": {
|
||||
"cwd": "${fileDirname}"
|
||||
},
|
||||
"problemMatcher": [
|
||||
"$msCompile"
|
||||
],
|
||||
"group": {
|
||||
"kind": "build",
|
||||
"isDefault": true
|
||||
},
|
||||
"detail": "Task generated by Debugger."
|
||||
}
|
||||
],
|
||||
"version": "2.0.0"
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
cmake_minimal_required(VERSION 3.10)
|
||||
project(neurox)
|
||||
set(SOURCES src/FXAlloc.c)
|
||||
set(HEADERS headers/_FXAlloc.h)
|
||||
set(INCLUDES includes/FXAlloc.h)
|
||||
add_library(fxalloc STATIC ${SOURCES} ${HEADERS} ${INCLUDES})
|
||||
target_include_directories(fxalloc PUBLIC includes PRIVATE headers)
|
||||
@@ -0,0 +1,48 @@
|
||||
#pragma once
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#ifndef _WIN32
|
||||
#include <sys/types.h>
|
||||
#endif //_WIN32
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif //__cplusplus
|
||||
|
||||
/**
|
||||
* @brief Структура преднастройки аллокатора задающая градации и количество блоков памяти
|
||||
*
|
||||
* @property +est_size: size_t - Предполагаемый размер блока
|
||||
* @property +est_count: size_t - Предполагаемое количество блоков
|
||||
*/
|
||||
typedef struct FXGrade {
|
||||
/// Предполагаемый размер блока
|
||||
const size_t est_size;
|
||||
/// Предполагаемое количество блоков
|
||||
const size_t est_count;
|
||||
} FXGrade;
|
||||
|
||||
/**
|
||||
* @brief Переменная для сохранения преднастроек пула памяти с ноль-терминантом
|
||||
* Определена в src/FXAlloc.c
|
||||
*/
|
||||
extern const FXGrade* grades;
|
||||
|
||||
/**
|
||||
* @brief Функция выделения памяти
|
||||
* @param[in] _NBytes: size_t - Количество байт
|
||||
* @retval !0 - Кратный size_t указатель выровненный для любого типа данных
|
||||
* @retval NULL - В случае единственно возможной ошибки EBADALLOC результат сохранён в errno
|
||||
*/
|
||||
void* fxalloc(size_t _NBytes);
|
||||
|
||||
/**
|
||||
* @brief Высвобождает память выделенную исключительно fxalloc
|
||||
* @param[in] _Ptr: void*
|
||||
*/
|
||||
void fxfree(void* _Ptr);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif //__cplusplus
|
||||
@@ -0,0 +1,70 @@
|
||||
#pragma once
|
||||
|
||||
#include "FXAlloc.h"
|
||||
|
||||
#include "mword.h"
|
||||
|
||||
typedef struct FXMemoryBlock FXMemoryBlock;
|
||||
|
||||
/**
|
||||
* @brief Минимальная структурная единица - блок памяти
|
||||
* В памяти расположены друг за другом с гарантированным выравниванием по void*
|
||||
* Клиентский указатель указывает непосредственно за структуру
|
||||
* fxalloc() → return (void*)(block + 1);
|
||||
* fxfree() → FXMemoryBlock* block = (FXMemoryBlock*)_Ptr - 1;
|
||||
* @property next: FXMemoryBlock* - Указатель на следующий свободный блок
|
||||
* @property Индекс потока в глобальном пуле
|
||||
* @property Индекс грейда в пуле конкретного потока
|
||||
* */
|
||||
struct FXMemoryBlock {
|
||||
/// @brief Указатель на следующий свободный блок
|
||||
FXMemoryBlock* next;
|
||||
/// @brief Индекс потока в глобальном пуле
|
||||
umword_t tid;
|
||||
/// @brief Индекс грейда в пуле конкретного потока
|
||||
umword_t gid;
|
||||
};
|
||||
|
||||
struct FXMemoryBlock {
|
||||
/// @brief Указатель на следующий свободный блок
|
||||
FXMemoryBlock* next;
|
||||
/// @brief Индекс потока в глобальном пуле
|
||||
uint32_t tid;
|
||||
/// @brief Индекс грейда в пуле конкретного потока
|
||||
uint32_t gid;
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Минимальная структурная единица - блок памяти
|
||||
* В памяти расположены друг за другом с гарантированным выравниванием по void*
|
||||
* Клиентский указатель указывает непосредственно за структуру
|
||||
* fxalloc() → return (void*)(block + 1);
|
||||
* fxfree() → FXMemoryBlock* block = (FXMemoryBlock*)_Ptr - 1;
|
||||
* @property next: FXMemoryBlock* - Указатель на следующий свободный блок
|
||||
* @property Индекс потока в глобальном пуле
|
||||
* @property Индекс грейда в пуле конкретного потока
|
||||
* */
|
||||
struct FXMemoryBlock {
|
||||
/// @brief Указатель на следующий свободный блок
|
||||
FXMemoryBlock* next;
|
||||
/// @brief Полезные данные в блоке
|
||||
uint32_t used;
|
||||
/// @brief Индекс потока в глобальном пуле
|
||||
uint16_t tid;
|
||||
/// @brief Индекс грейда в пуле конкретного потока
|
||||
uint16_t gid;
|
||||
};
|
||||
|
||||
/// @brief Группа блоков одной градации
|
||||
typedef struct FXGradedMemoryPool {
|
||||
/// @brief Указатель на последний свободный блок
|
||||
FXMemoryBlock* free;
|
||||
/// @brief Всего блоков в данной группе
|
||||
umword_t total;
|
||||
/// @brief Количество преаллоцированных блоков
|
||||
umword_t count_pre;
|
||||
/// @brief Количество используемых блоков
|
||||
mword_t used;
|
||||
/// @brief Количество свободных блоков
|
||||
mword_t free;
|
||||
} FXMemoryPoolGrade;
|
||||
@@ -0,0 +1,49 @@
|
||||
#ifndef FX_MEMORY_BLOCK_H
|
||||
#define FX_MEMORY_BLOCK_H
|
||||
|
||||
#include <stdint.h>
|
||||
#include "mword.h"
|
||||
|
||||
// Определяем оптимальный тип метаданных для FXMemoryBlock
|
||||
#if defined(__x86_64__) || defined(_M_X64) || \
|
||||
defined(__amd64__) || defined(__amd64) || \
|
||||
defined(__aarch64__) || defined(_M_ARM64) || \
|
||||
defined(__AARCH64__) || defined(__powerpc64__) || \
|
||||
defined(__ppc64__)
|
||||
// Для 64-битных архитектур используем uint32_t
|
||||
// для оптимального баланса между размером и производительностью
|
||||
typedef uint32_t fxmbmeta_t;
|
||||
|
||||
#elif defined(__i386__) || defined(_M_IX86) || \
|
||||
defined(__i486__) || defined(__i586__) || \
|
||||
defined(__i686__) || defined(__arm__) || \
|
||||
defined(_M_ARM) || defined(__ARM_ARCH_7__) || \
|
||||
defined(__ARM_ARCH_8__) || defined(__powerpc__) || \
|
||||
defined(__ppc__)
|
||||
// Для 32-битных архитектур используем uint32_t
|
||||
typedef uint32_t fxmbmeta_t;
|
||||
|
||||
#elif defined(__riscv)
|
||||
#if __riscv_xlen == 64
|
||||
typedef uint32_t fxmbmeta_t;
|
||||
#elif __riscv_xlen == 32
|
||||
typedef uint32_t fxmbmeta_t;
|
||||
#else
|
||||
#error "Unsupported RISC-V word size: __riscv_xlen must be 32 or 64"
|
||||
#endif
|
||||
|
||||
#else
|
||||
// Резервный вариант: определяем по размеру указателя
|
||||
#if sizeof(void*) == 8
|
||||
typedef uint32_t fxmbmeta_t;
|
||||
#elif sizeof(void*) == 4
|
||||
typedef uint32_t fxmbmeta_t;
|
||||
#else
|
||||
#error "Unsupported pointer size"
|
||||
#endif
|
||||
#endif
|
||||
|
||||
// Проверка корректности определения типа
|
||||
static_assert(sizeof(fxmbmeta_t) == 4, "fxmbmeta_t must be 32-bit");
|
||||
|
||||
#endif // FX_MEMORY_BLOCK_H
|
||||
@@ -0,0 +1,74 @@
|
||||
#pragma once
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#if defined(__x86_64__) || defined(_M_X64) || \
|
||||
defined(__amd64__) || defined(__amd64)
|
||||
// x64: 64-битное машинное слово
|
||||
typedef int64_t mword_t;
|
||||
typedef uint64_t umword_t;
|
||||
|
||||
#elif defined(__i386__) || defined(_M_IX86) || \
|
||||
defined(__i486__) || defined(__i586__) || \
|
||||
defined(__i686__)
|
||||
// x86: 32-битное машинное слово
|
||||
typedef int32_t mword_t;
|
||||
typedef uint32_t umword_t;
|
||||
|
||||
#elif defined(__aarch64__) || defined(_M_ARM64) || defined(__AARCH64__)
|
||||
// ARM64: 64-битное машинное слово
|
||||
typedef int64_t mword_t;
|
||||
typedef uint64_t umword_t;
|
||||
|
||||
#elif defined(__arm__) || defined(_M_ARM) || defined(__ARM_ARCH_7__) || defined(__ARM_ARCH_8__)
|
||||
// ARM32: 32-битное машинное слово
|
||||
typedef int32_t mword_t;
|
||||
typedef uint32_t umword_t;
|
||||
|
||||
#elif defined(__riscv) && defined(__riscv_xlen)
|
||||
#if __riscv_xlen == 64
|
||||
// RISC‑V 64: 64-битное машинное слово
|
||||
typedef int64_t mword_t;
|
||||
typedef uint64_t umword_t;
|
||||
#elif __riscv_xlen == 32
|
||||
// RISC‑V 32: 32-битное машинное слово
|
||||
typedef int32_t mword_t;
|
||||
typedef uint32_t umword_t;
|
||||
#else
|
||||
#error "Unsupported RISC-V word size: __riscv_xlen must be 32 or 64"
|
||||
#endif
|
||||
|
||||
#elif defined(__powerpc64__) || defined(__ppc64__)
|
||||
// PowerPC64: 64-битное машинное слово
|
||||
typedef int64_t mword_t;
|
||||
typedef uint64_t umword_t;
|
||||
|
||||
#elif defined(__powerpc__) || defined(__ppc__)
|
||||
// PowerPC32: 32-битное машинное слово
|
||||
typedef int32_t mword_t;
|
||||
typedef uint32_t umword_t;
|
||||
|
||||
|
||||
#else
|
||||
// Резервный вариант: определяем по диапазону unsigned long
|
||||
#include <limits.h>
|
||||
#if ULONG_MAX == 18446744073709551615ULL // 2^64 - 1
|
||||
typedef int64_t mword_t;
|
||||
typedef uint64_t umword_t;
|
||||
#elif ULONG_MAX == 4294967295UL // 2^32 - 1
|
||||
typedef int32_t mword_t;
|
||||
typedef uint32_t umword_t;
|
||||
#elif ULONG_MAX == 65535U // 2^16 - 1
|
||||
typedef int16_t mword_t;
|
||||
typedef uint16_t umword_t;
|
||||
#else
|
||||
#error "Cannot determine machine word size: unsupported ULONG_MAX"
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/* Проверки добавлены по настоянию YandexGPT 5.1 Pro(АлисаAI) */
|
||||
// Статическая проверка: размер слова — степень двойки
|
||||
static_assert((sizeof(mword_t) & (sizeof(mword_t) - 1)) == 0, "Machine word size must be a power of two");
|
||||
|
||||
// Статическая проверка: signed и unsigned версии имеют одинаковый размер
|
||||
static_assert(sizeof(mword_t) == sizeof(umword_t), "mword_t and umword_t must have the same size");
|
||||
@@ -0,0 +1,36 @@
|
||||
#include "FXAlloc.h"
|
||||
|
||||
#include <threads.h>
|
||||
|
||||
// В этой переменной настраиваем градации и предположительное количесвто блоков
|
||||
static const FXGrade grades[] = {
|
||||
{ 32, 200 }, { 64, 200 }, { 128, 8000 },
|
||||
{ 256, 4000 }, { 512, 2000 }, { 1024, 1200 },
|
||||
{ 4096, 200 }, { 0x10000, 4 },
|
||||
{ 0 } // Ноль-терминант
|
||||
};
|
||||
|
||||
|
||||
|
||||
#ifdef _WIN32
|
||||
// Windows-версия
|
||||
__declspec(thread) extern void* (*fxalloc)(size_t _NBytes);
|
||||
__declspec(thread) extern void (*fxfree)(void* _Ptr);
|
||||
#else
|
||||
// POSIX-версия
|
||||
extern static pthread_key_t thread_key;
|
||||
|
||||
extern void* (*fxalloc)(size_t _NBytes);
|
||||
extern void (*fxfree)(void* _Ptr);
|
||||
#endif
|
||||
|
||||
|
||||
extern static pthread_key_t thread_key;
|
||||
|
||||
void* fastalloc();
|
||||
|
||||
void init_tls() {
|
||||
pthread_setspecific(thread_key, (void*)fxalloc);
|
||||
fxalloc = fastalloc;
|
||||
// или более сложный вариант с хранением структуры
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
cmake_minimum_required(VERSION 3.5)
|
||||
cmake_minimum_required(VERSION 3.10)
|
||||
project(neurox_server)
|
||||
set(INCLUDES )
|
||||
set(HEADERS )
|
||||
|
||||
+16
-31
@@ -5,6 +5,8 @@
|
||||
* @brief Публичный заголовочный файл к структуре XOGame модуля GameCore проекта NeurOX
|
||||
* @version 0.1
|
||||
*
|
||||
* SOLID(C) + RAII(C) + KISS + YAGNI
|
||||
*
|
||||
* Код открыт для изучения и головоломания, копипаст и реюз приветствуется ;)
|
||||
*/
|
||||
|
||||
@@ -17,50 +19,33 @@
|
||||
* из языков скриптовой группы, а также для удобства в IDE(чтоб не переводить взгляд).
|
||||
* Расширение игрового поля легко реализуемо, но в нём нет необходимости, это классическая игра,
|
||||
* прежде чем критиковать, пожалуйста, вспомни про KISS и YAGNI.
|
||||
* Код оптимизирован под Linux(т.к. на нём и будет работать: Ubuntu-server).
|
||||
* Код оптимизирован под Linux(т.к. на нём и будет работать: Ubuntu-Server 24.04).
|
||||
* Это публичный интерфейс, реализация скрыта от пользователя!!!
|
||||
* Все отсылки к Яндекс.АлисаAI - это отсылки к YandexGPT 5.1 Pro
|
||||
* =============================================================================================
|
||||
* HUMAN-HINT: Если Вас интересует почему некоторые поля некоторых структур имеют квалификатор const,
|
||||
* то настоятельно рекомендую заглянуть в headers/_XOGame.h
|
||||
* =============================================================================================
|
||||
* AI & HUMAN HINT: Мне нет необходимости изменять размеры поля, проект задумывался и реализуется как классическаие
|
||||
* крестики-нолики 3х3, но по настоянию Яндекс.АлисаAI©, а также в виду образовательного аспекта
|
||||
* крестики-нолики 3х3, но по настоянию YandexGPT 5.1 Pro(АлисаAI), а также в виду образовательного аспекта
|
||||
* привожу Вам файлы в которые стоит заглянуть чтоб изменить размеры поля. Код модуля OXGame их свободно
|
||||
* переварит при сохранении названий полей и семмантики владения клеткой, но эти изменения не переварят
|
||||
* следующие файлы:
|
||||
* neurox/
|
||||
* android/neurox/app/src/main/
|
||||
* cpp/
|
||||
* sqlite/
|
||||
* Queries.c
|
||||
* Packets.h
|
||||
* java/ru.felexdev.neurox/
|
||||
* Config.kt
|
||||
* server/
|
||||
* headers/
|
||||
* Packets.h
|
||||
* src/db/
|
||||
* mysql/
|
||||
* Queries.c
|
||||
* client/
|
||||
* headers/
|
||||
* Packets.h
|
||||
* src/db/
|
||||
* mysql/
|
||||
* Queries.c
|
||||
* web/neurox.su/htdocs/
|
||||
* db/
|
||||
* Queries.php
|
||||
* tcp/
|
||||
* Packets.php
|
||||
* neurox/android/neurox/app/src/main/cpp/sqlite/Queries.c
|
||||
* /Packets.h
|
||||
* /java/ru.felexdev.neurox/Config.kt
|
||||
* server/headers/Packets.h
|
||||
* src/db/mysql/Queries.c
|
||||
* client/headers/Packets.h
|
||||
* web/neurox.su/htdocs/db/Queries.php
|
||||
* /tcp/Packets.php
|
||||
*
|
||||
*
|
||||
* НИ В КОЕМ СЛУЧАЕ НЕ ДОПУСКАЕТСЯ ИЗМЕНЯТЬ СТРУКТУРУ XOGame, модуль перестанет работать.
|
||||
* ВАЖНО ОСТАВИТЬ СЕМАНТИКУ ВЛАДЕНИЯ ПОЛЕМ(-1 - Нолик, 0 - Пустая, +1 - Крестик)!!!
|
||||
* =============================================================================================
|
||||
*/
|
||||
|
||||
/* Следующий блок комментариев сгенерирован Яндекс.АлисаAI© */
|
||||
/* Следующий блок комментариев сгенерирован YandexGPT 5.1 Pro(АлисаAI) */
|
||||
/*
|
||||
...
|
||||
* HUMAN-HINT: А знаете, кто первым заметил потенциал этого кода?
|
||||
@@ -160,7 +145,7 @@ extern "C" {
|
||||
* @property log: XOCell[XO_BOARDX * XO_BOARDY] - Лог ходов
|
||||
* @property winners: XOCell[XO_BOARDX] - Выигравшие клетки. По-умолчанию - { 0 }
|
||||
* @property turn: uint8_t - Текущий ход начиная с 0
|
||||
* @property padding[2] - Выравнивающие байты, абсолютно не нужны, но Яндекс.АлисаAI© настояла - { 0 }.
|
||||
* @property padding[2] - Выравнивающие байты, абсолютно не нужны, но Яндекс.АлисаAI настояла - { 0 }.
|
||||
*/
|
||||
typedef struct XOGame XOGame;
|
||||
|
||||
@@ -180,7 +165,7 @@ extern "C" {
|
||||
/// Текущий ход начиная с 0
|
||||
const uint8_t turn;
|
||||
/**
|
||||
* @brief Выравнивающие байты, абсолютно не нужны, но Яндекс.АлисаAI© настояла - { 0 }
|
||||
* @brief Выравнивающие байты, абсолютно не нужны, но Яндекс.АлисаAI настояла - { 0 }
|
||||
* Если вы решите изменить тип полей в XOCell выравнивание придётся пересматривать
|
||||
*/
|
||||
uint8_t padding[2];
|
||||
|
||||
@@ -0,0 +1,2 @@
|
||||
build
|
||||
sandbox
|
||||
@@ -0,0 +1,7 @@
|
||||
cmake_minimum_required(VERSION 3.10)
|
||||
project(neurox)
|
||||
set(HEADERS headers/_header.h)
|
||||
set(INCLUDES includes/include.h)
|
||||
set(SOURCES src/source.c)
|
||||
add_library(template SHARED ${INCLUDES} ${HEADERS} ${SOURCES})
|
||||
target_include_directories(neurox PUBLIC includes PRIVATE headers)
|
||||
@@ -0,0 +1 @@
|
||||
# DAIRY.md
|
||||
@@ -0,0 +1 @@
|
||||
# PROGRESS.md
|
||||
@@ -0,0 +1 @@
|
||||
# README.md
|
||||
@@ -0,0 +1 @@
|
||||
# TODO.md
|
||||
@@ -0,0 +1,17 @@
|
||||
#pragma once
|
||||
|
||||
/**
|
||||
* @author admin@felexdev.ru
|
||||
* @version 1.0.0
|
||||
*
|
||||
* @brief Header template
|
||||
*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif //__cplusplus
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif //__cplusplus
|
||||
@@ -0,0 +1,17 @@
|
||||
#pragma once
|
||||
|
||||
/**
|
||||
* @author admin@felexdev.ru
|
||||
* @version 1.0.0
|
||||
*
|
||||
* @brief Include emplate
|
||||
* */
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif //__cplusplus
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif //__cplusplus
|
||||
@@ -0,0 +1,10 @@
|
||||
/**
|
||||
* @author admin@felexdev.ru
|
||||
* @version 1.0.0
|
||||
*
|
||||
* @brief Sourcecode template
|
||||
*/
|
||||
|
||||
int example() {
|
||||
return 0;
|
||||
}
|
||||
Reference in New Issue
Block a user