commit abd873fd4c8212343659f4a5879d87e818c7f653
Author: bsandro <email@bsandro.tech>
Date: Fri, 21 Aug 2026 00:57:24 +0300
init
Diffstat:
9 files changed, 234 insertions(+), 0 deletions(-)
diff --git a/.gitignore b/.gitignore
@@ -0,0 +1,2 @@
+*.o
+sw-battle-test-c
diff --git a/Makefile b/Makefile
@@ -0,0 +1,30 @@
+NAME=$(shell basename ${PWD})
+SDL_CFLAGS=$(shell pkg-config --cflags sdl2 SDL2_image)
+SDL_LDFLAGS=$(shell pkg-config --libs sdl2 SDL2_image)
+SRC:=$(wildcard *.c **/*.c)
+DEPS:=$(wildcard *.h **/*.h)
+OBJ:=$(SRC:.c=.o)
+CFLAGS=-std=c99 -Wpedantic -Wall -Wextra -ffast-math -I. $(SDL_CFLAGS)
+ifeq (${DEBUG},1)
+CFLAGS+=-O0 -g
+else
+CFLAGS+=-O3 -mtune=native -march=native
+endif
+LDFLAGS=-lc -lm -flto $(SDL_LDFLAGS)
+#CC=gcc
+
+all: $(NAME)
+
+.PHONY: clean
+
+clean:
+ rm -f $(OBJ) $(NAME)
+
+%.o : %.c $(DEPS)
+ $(CC) $(CFLAGS) -c $< -o $@
+
+$(NAME): $(OBJ)
+ $(CC) $(OBJ) -o $@ $(LDFLAGS)
+
+run: $(NAME)
+ ./$(NAME)
diff --git a/README.md b/README.md
@@ -0,0 +1,150 @@
+# **Цель**
+
+Цель задания — **продемонстрировать навыки проектирования ПО.**
+
+- Не беспокойтесь о производительности, использовании потоков или подключении библиотек.
+- Мы не ожидаем детерминированного результата работы — это лишь усложнило бы задачу.
+- Время выполнения не ограничено, но предполагается, что работа займёт не более 6–8 часов.
+
+## **Что мы хотим увидеть:**
+
+1. Понятный и аккуратный код с прозрачной логикой работы.
+2. Чёткое разграничение зон ответственности между сущностями проекта.
+3. Расширяемую архитектуру, которая позволяет легко добавлять новые сущности и механики взаимодействия
+ - Представьте, что после вас придут 10 младших разработчиков, которые будут одновременно добавлять новые функции.
+ - Ознакомьтесь с README.MD в директориях Core и Feature — они помогут лучше понять цели задачи.
+4. Заметки в документе KNOWN_ISSUES.md - где вы оставите известные вам недостатки и сомнения по вашему решению, к
+ примеру из-за нехватки времени.
+
+# **Задача**
+
+Создайте пошаговую симуляцию боевых столкновений юнитов на карте для тестирования игровых механик.
+
+На карте размером W×H клеток можно размещать юнитов.
+
+- Юниты различаются по типам, **действиям** и **характеристикам**.
+- Каждому юниту присвоен уникальный идентификатор **Id** (целое число)
+- За один ход каждый юнит может выполнить одно действие.
+ - Юниты совершают действия в порядке их создания.
+- Юнит всегда размещен по каким то координатам на карте.
+- Юнит может занимать клетку, не позволяя другим на нее встать.
+- Большинство юнитов имеет характеристику **HP** (Health Points).
+ - При **HP** ≤ 0 юнит выполняет свои действия в текущем ходу и исчезает перед началом следующего.
+- Часть юнитов обладает способностью перемещения:
+ - Они могут переместиться в любую из восьми прилегающих клеток за ход.
+ - Если цель недостижима за один ход, они продолжают движение к ней в последующих ходах.
+ - Статичные юниты должны оставаться неподвижными при любых условиях.
+
+Симуляция заканчивается, когда нет юнитов, способных действовать в следующем ходу, или на карте остается только один
+юнит.
+
+## Юниты, которых нужно реализовать:
+
+### Мечник
+
+- **Характеристики:** HP, Strength
+- Действия
+ - **Сокрушающий удар:** Бьет одного случайного юнита в соседней клетке, нанося ему **Strength** единиц урона.
+ - Если некого бить, перемещается.
+
+### Охотник
+
+- **Характеристики:** HP, Agility, Strength, Range
+- Действия
+ - **Стремительный выстрел:** Стреляет в случайного юнита на расстоянии от 2 до **Range** клеток, нанося ему
+ **Agility** единиц урона. Может стрелять только если в соседних клетках нет других юнитов.
+ - **Удар из тени:** Если стрелять не может, бьет одного случайного юнита в соседней клетке, нанося ему **Strength**
+ единиц урона.
+ - Если некого бить, перемещается.
+
+# Приложение
+
+При запуске приложение получает путь к файлу со сценарием симуляции, где описаны **команды** для создания карты и
+юнитов, а также перемещения юнитов по карте. Приложение должно выводить все происходящие события в **stdout**.
+
+Так как на карте нет препятствий, сложные алгоритмы поиска пути не требуются.
+
+## Команды
+
+- `CREATE_MAP W H` — Создает карту размером `W`×`H`. Эта команда начинает любой сценарий.
+- `SPAWN_SWORDSMAN I X Y H S` — Создает мечника с идентификатором `I` в точке `X`,`Y` с характеристиками здоровья `H` и
+ силы `S`.
+- `SPAWN_HUNTER I X Y H A S R` — Создает охотника с идентификатором `I` в точке `X`,`Y` с характеристиками здоровья `H`,
+ ловкости `A`, силы `S` и дальности `R`.
+- `MARCH I X Y` — Приказывает юниту `I` переместиться в точку `X`,`Y`.
+
+## События
+
+- `MAP_CREATED` — Создание карты.
+- `MARCH_STARTED`, `MARCH_ENDED` — Начало и конец перемещения юнита.
+- `UNIT_SPAWNED`, `UNIT_DIED` — Создание и смерть юнита.
+- `UNIT_MOVED` — Перемещение юнита на клетку.
+- `UNIT_ATTACKED` — Атака одного юнита на другого.
+
+Код парсера команд и вывода событий в лог уже содержится в проекте. Если необходимо, его можно менять. Формат ввода и
+вывода менять нельзя.
+
+Пример сценария находится в файле _commands_example.txt_. Пример лога событий находится в файле _main.cpp_.
+
+# Ограничения
+
+- Не подключать внешние 3rd-party зависимости, только стандартная библиотека
+- Вы можете поменять проект как угодно для достижения цели, даже не используя предоставленную структуру и код
+ - это не является ни плюсом ни минусом, мы предоставили структуру и код, желая упростить задачу, сэкономить вам
+ время.
+
+# Технические требования
+
+- **ОС:** Ubuntu
+- **Компилятор:** clang 15+
+- **Стандарт:** C++17 или новее
+- **Система сборки:** cmake (в проекте должен быть CMakeLists.txt)
+- Задание необходимо опубликовать в любом публичном гит-репозитории (GitHub, Bitbucket и т.д.).
+
+_В процессе выполнения задания вы можете присылать любые вопросы._
+
+# Планы на расширения
+
+При проектировании учитывайте планы по добавлению новых юнитов, действий и характеристик.
+
+Возможность создания таких Юнитов с таким поведением не трогая код в Core является важным критерием.
+
+Эту функциональность не нужно реализовывать в коде, это подсказка для расширяемости.
+
+## Башня
+
+- **Характеристики:** HP, Power
+- Действия
+ - **Прицельный выстрел:** Стреляет в случайного юнита на расстоянии от 2 до 5 клеток, нанося ему **Power** единиц
+ урона.
+ - Не может перемещаться.
+
+## Лекарь
+
+- **Характеристики:** HP, Spirit
+- Действия
+ - **Малое исцеление:** Восстанавливает **Spirit** единиц здоровья одному случайному юниту в радиусе 2 клеток.
+ - Если некого лечить, перемещается.
+
+## Ворон
+
+- **Характеристики:** HP, Agility
+- **Летающий юнит:**
+ - Не занимает клетку на карте.
+ - Может перемещаться на 2 клетки за ход.
+ - Не может быть атакован ближнем боем.
+ - Может быть атакован в дальнем бою, минимальная и максимальная дистанция атаки "стрелка" на ворона снижена на 1.
+- Действия
+ - **Удар когтем:** Бьет одного случайного юнита в соседних клетках, нанося ему **Agility** единиц урона.
+ - Если некого бить, перемещается.
+
+## Мина
+
+- **Характеристики:** Power
+- Не может быть атакована.
+- Не занимает клетку на карте.
+- Действия
+ - Если в радиусе 2х клеток есть юнит - взрывается в следующем ходу, нанося всем юнитам в радиусе 3х клеток **Power**
+ единиц урона.
+ - После взрыва исчезает.
+ - Не может перемещаться.
+\ No newline at end of file
diff --git a/commands_example.txt b/commands_example.txt
@@ -0,0 +1,14 @@
+CREATE_MAP 10 10
+
+SPAWN_SWORDSMAN 1 0 0 5 2
+
+SPAWN_HUNTER 2 9 0 10 5 1 4
+
+MARCH 1 9 0
+
+MARCH 2 0 0
+
+SPAWN_SWORDSMAN 3 0 9 10 2
+
+MARCH 3 0 0
+
diff --git a/core/map.c b/core/map.c
@@ -0,0 +1,9 @@
+#include <stdlib.h>
+#include "map.h"
+
+//todo: return 1 or 0
+void Map_init(Map *m, int w, int h) {
+ m->w = w;
+ m->h = h;
+}
+
diff --git a/core/map.h b/core/map.h
@@ -0,0 +1,6 @@
+typedef struct Map {
+ int w;
+ int h;
+} Map;
+
+void Map_init(Map *m, int w, int h);
diff --git a/core/world.c b/core/world.c
@@ -0,0 +1,6 @@
+#include <stddef.h>
+#include "world.h"
+
+World * World_init() {
+ return NULL;
+}
diff --git a/core/world.h b/core/world.h
@@ -0,0 +1,7 @@
+#include "map.h"
+
+typedef struct World {
+ Map map;
+} World;
+
+World * World_init();
diff --git a/main.c b/main.c
@@ -0,0 +1,9 @@
+#include <stdio.h>
+#include "core/world.h"
+
+int main(void) {
+ World w;
+ Map_init(&w.map, 3, 4);
+ puts("ok");
+ return 0;
+}