Открытое соревнование по программированию искусственного интеллекта

The championship is currently in beta stage / Чемпионат находится в стадии бета-теста

Быстрый старт

Раунд 1: до начала

Проект

Песочница

Раунд 1

Раунд 2

Финал

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

30 ноября 02:07: dozorhunterr написал комментарий в посте Языковые пакеты
30 ноября 01:46: dozorhunterr написал комментарий в посте Языковые пакеты
30 ноября 01:03: Hooloovo написал комментарий в посте Языковые пакеты
30 ноября 00:21: georg_karr_spb написал комментарий в посте Быстрый старт
29 ноября 23:11: Jeen99 написал комментарий в посте Правила
29 ноября 21:40: amurushkin написал комментарий в посте Приложение CodeCraft 2020
29 ноября 20:55: xocks написал комментарий в посте Приложение CodeCraft 2020
29 ноября 20:08: sergileon написал комментарий в посте Приложение CodeCraft 2020
29 ноября 19:30: Okke написал комментарий в посте Приложение CodeCraft 2020
29 ноября 19:20: oh_my_kpot написал комментарий в посте Приложение CodeCraft 2020

Группа ВКонтакте

Telegram-чат

Discord

 

Ниже мы расскажем, как присоединиться к CodeCraft буквально за несколько минут.

Зарегистрируйтесь

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

Скачайте языковой пакет

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

Скачайте приложение

Приложение предоставляет вам возможность запускать тестовые игры локально на своём компьютере. Подробнее об этом здесь.

Прочитайте документацию

В разделе Правила опубликованы официальные и полные правила, обязательно прочитайте их. Некоторые организационные моменты вы можете найти в описаниях Песочницы и этапов чемпионата (Раунд 1, Раунд 2, Финал).

Отошлите свою стратегию

Это можно сделать на странице отослать стратегию. Прежде, чем система примет вашу стратегию, она будет скомпилирована и протестирована в нескольких коротких играх. Если всё в порядке, ваша стратегия автоматически начнёт участвовать в регулярных квалификационных играх Песочницы. Внимательно изучите в секции “На что стоит обратить внимание” различные моменты, вследствие которых ваша стратегия может получить вердикт “Ошибка верификации”. Суммарное количество посылок не ограничено, однако в системе есть ограничения на слишком частую отправку стратегий, а любые попытки дестабилизировать работу системы приведут к дисквалификации. Вы можете написать свою стратегию в произвольном количестве файлов, вам нужно будет лишь упаковать всё необходимое в ZIP-архив и отослать его.

На что стоит обратить внимание

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

Простая стратегия

Далее приведена простая стратегия на языке Rust. Она собирает ресурсы, покупает юнитов отдельно для каждого типа и посылает их в атаку в противоположный угол карты.

use super::DebugInterface;
use model::*;

pub struct MyStrategy {}

fn is_unit(entity_type: &EntityType) -> bool {
    use EntityType::*;
    matches!(entity_type, BuilderUnit | MeleeUnit | RangedUnit)
}

impl MyStrategy {
    pub fn new() -> Self {
        Self {}
    }
    pub fn get_action(
        &mut self,
        player_view: &PlayerView,
        debug_interface: Option<&mut DebugInterface>,
    ) -> Action {
        let mut result = Action {
            entity_actions: std::collections::HashMap::new(),
        };
        let my_id = player_view.my_id;
        for entity in player_view
            .entities
            .iter()
            .filter(|entity| entity.player_id == Some(my_id))
        {
            let properties = &player_view.entity_properties[&entity.entity_type];

            let mut move_action = None;
            let mut build_action = None;
            if is_unit(&entity.entity_type) {
                move_action = Some(MoveAction {
                    target: Vec2I32 {
                        x: player_view.map_size - 1,
                        y: player_view.map_size - 1,
                    },
                    find_closest_position: true,
                    break_through: true,
                });
            } else if let Some(build_properties) = &properties.build {
                let entity_type = &build_properties.options[0];
                let current_units = player_view
                    .entities
                    .iter()
                    .filter(|entity| {
                        entity.player_id == Some(my_id) && entity.entity_type == *entity_type
                    })
                    .count() as i32;
                if (current_units + 1) * player_view.entity_properties[&entity_type].population_use
                    <= properties.population_provide
                {
                    build_action = Some(BuildAction {
                        entity_type: entity_type.clone(),
                        position: Vec2I32 {
                            x: entity.position.x + properties.size,
                            y: entity.position.y + properties.size - 1,
                        },
                    });
                }
            }
            result.entity_actions.insert(
                entity.id,
                EntityAction {
                    move_action,
                    build_action,
                    attack_action: Some(AttackAction {
                        target: None,
                        auto_attack: Some(AutoAttack {
                            pathfind_range: properties.sight_range,
                            valid_targets: if entity.entity_type == EntityType::BuilderUnit {
                                vec![EntityType::Resource]
                            } else {
                                vec![]
                            },
                        }),
                    }),
                    repair_action: None,
                },
            );
        }
        result
    }
    pub fn debug_update(&mut self, player_view: &PlayerView, debug_interface: &mut DebugInterface) {
        debug_interface.send(DebugCommand::Clear {});
        debug_interface.get_state();
    }
}


spaceorc

spaceorc

СКБ Контур

В “Простой стратегии” кажется неправильно проверяется доступность юнита для постройки (либо я неправильно понял). Как будто мы должны сравнивать суммарный population_provide по всем активным зданиям с суммарным population_use всех юнитов. А здесь сравнивается использование еды только юнитами того типа, которое здание производит, с производством еды конкретно этим зданием???

28.11.2020 12:14:52
Savidiy

Savidiy

SCETER

spaceorc

spaceorc

СКБ Контур

В “Простой стратегии” кажется неправильно проверяется доступность юнита для постройки (либо я неправильно понял). Как будто мы должны сравнивать суммарный population_provide по всем активным зданиям с суммарным population_use всех юнитов. А здесь сравнивается использование еды только юнитами того типа, которое здание производит, с производством еды конкретно этим зданием???

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

28.11.2020 14:02:39
WitcherSanek

WitcherSanek

Москва

Savidiy

Savidiy

SCETER

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

Тогда зачем нужен простой дом, дающий +5 еды, но не производящий никаких юнитов?

28.11.2020 18:20:36
Savidiy

Savidiy

SCETER

WitcherSanek

WitcherSanek

Москва

Тогда зачем нужен простой дом, дающий +5 еды, но не производящий никаких юнитов?

Именно для увеличения лимита юнитов. Данная стратегия делает такую проверку, только потому, что она так хочет. Ничего не мешает построить больше лучников на всю еду или других юнитов.

28.11.2020 19:56:29
Smeagol

Smeagol

Алжир

Hello, Madknight joue tu ?

29.11.2020 4:31:57
j303

j303

Москва

Всем привет.

Я делаю на C#. И не как не могу понять как строить юнитов и/или здания.

Делаю так: 1.Юниты-строители добывают ресурсы. Их становится больше 100. 2.Даю зданию EntityType.BuilderBase команду построить BuildAction build = new BuildAction(EntityType.BuilderUnit, ПОЗИЦИЯ_ЗДАНИЯ_МИНУС_1_ПО_Х); <int, Model.EntityAction> = <ИД_ЗДАНИЯ, new EntityAction(null, build, null, null)>; 3.Но ничего не происходит.

Что я делаю не так?

29.11.2020 8:43:58
Okke

Okke

Санкт-Петербург

j303

j303

Москва

Всем привет. Я делаю на C#. И не как не могу понять как строить юнитов и/или здания. Делаю так: 1.Юниты-строители добывают ресурсы. Их становится больше 100. 2.Даю зданию EntityType.BuilderBase команду построить BuildAction build = new BuildAction(EntityType.BuilderUnit, ПОЗИЦИЯ_ЗДАНИЯ_МИНУС_1_ПО_Х); <int, Model.EntityAction> = <ИД_ЗДАНИЯ, new EntityAction(null, build, null, null)>; 3.Но ничего не происходит. …

Нужно указывать место рядом с базой, а не место ее самой.

29.11.2020 13:16:44
Okke

Okke

Санкт-Петербург

j303

j303

Москва

Всем привет. Я делаю на C#. И не как не могу понять как строить юнитов и/или здания. Делаю так: 1.Юниты-строители добывают ресурсы. Их становится больше 100. 2.Даю зданию EntityType.BuilderBase команду построить BuildAction build = new BuildAction(EntityType.BuilderUnit, ПОЗИЦИЯ_ЗДАНИЯ_МИНУС_1_ПО_Х); <int, Model.EntityAction> = <ИД_ЗДАНИЯ, new EntityAction(null, build, null, null)>; 3.Но ничего не происходит. …

… и это место должно быть свободно

29.11.2020 13:17:21
alivefil

alivefil

Красноярск

Всем привет. Может кто-нибудь поделиться примером использования EntityAction и Action на с++? Я что-то совсем не понимаю как установить действие для юнита и потом выполнить его (

29.11.2020 13:23:03
georg_karr_spb

georg_karr_spb

NekBrainLab

Простая стратегия на Kotlin (не обессудте Kotlin освоил за 1 день - вчера): import model.* import java.text.FieldPosition import kotlin.math.sqrt

class MyStrategy { var resurs: MutableList = mutableListOf() var enemies: MutableList = mutableListOf() var countBuU: Int = 0 var countRaU: Int = 0 var validTarget: Array<model.EntityType> = arrayOf(model.EntityType.RANGED_UNIT, model.EntityType.BUILDER_UNIT, model.EntityType.MELEE_UNIT, model.EntityType.RESOURCE)

private fun findNear(position: Vec2Int, arrVec2Int: MutableList<Vec2Int>): Vec2Int {
    var coorResmin: Vec2Int = position
    var minLen = 1000000
    var len = 0
    for (coorRes in arrVec2Int) {
        len = (position.x - coorRes.x)*(position.x - coorRes.x)  + (position.y - coorRes.y)*(position.y - coorRes.y)
        if (len < minLen) {
            minLen = len
            coorResmin = coorRes
        }
        if (len < 4) {
            break
        }
    }
    return coorResmin
}

fun getAction(playerView: PlayerView, debugInterface: DebugInterface?): Action {

    var entityActions: MutableMap<Int, model.EntityAction> = mutableMapOf()

    var myId = playerView.myId
    var tick = playerView.currentTick

    var j = 1
    if (tick%2 == 0) {
        j = -1
    }

    var maxSize = playerView.mapSize
    var i = 1
    if (countBuU > countRaU) {
        i = -1
    }
    //println("Build= $countBuU Ran= $countRaU i= $i")
    var res = 0
    for (player in playerView.players) {
        if (player.id == myId) {
            res = player.resource
        }
    }

    var entityProperties = playerView.entityProperties

    resurs = mutableListOf()
    enemies = mutableListOf()

    for (entity in playerView.entities) {
        if (entity.entityType == model.EntityType.RESOURCE) {
            resurs?.add(entity.position)
        } else if (entity.playerId != null) {
            if (entity.playerId != myId) {
                enemies?.add(entity.position)
            }
        }
    }
    countBuU = 0
    countRaU = 0
    for (entity in playerView.entities) {

        if (entity.playerId == myId) {

            val entityAction = model.EntityAction()
            var properties = playerView.entityProperties[entity.entityType]

            val moveAction = model.MoveAction()
            val buildAction = model.BuildAction()
            val attackAction = model.AttackAction()
            val repairAction = model.RepairAction()

            if (entity.entityType == model.EntityType.BUILDER_UNIT) {
                countBuU += 1
                moveAction.target =  findNear(entity.position, resurs)
                moveAction.breakThrough = true
                moveAction.findClosestPosition = true
                entityAction.moveAction = moveAction
                entityActions.put(entity.id, entityAction)

            } else if (entity.entityType == model.EntityType.MELEE_UNIT || entity.entityType == model.EntityType.RANGED_UNIT) {
                countRaU += 1
                //if (j == 1) {
                    moveAction.target = findNear(entity.position, enemies)
                    moveAction.breakThrough = true
                    moveAction.findClosestPosition = true
                    entityAction.moveAction = moveAction
                    entityActions.put(entity.id, entityAction)
                //} else {
                    attackAction.target = null
                    var autoAt = model.AutoAttack()
                    autoAt.pathfindRange = maxSize
                    autoAt.validTargets = validTarget
                    attackAction.autoAttack = autoAt
                    entityAction.attackAction = attackAction
                    entityActions.put(entity.id, entityAction)
                //}

            } else if (entity.entityType == model.EntityType.BUILDER_BASE) {
                if (i == 1) {
                    buildAction.entityType = model.EntityType.BUILDER_UNIT
                    if (properties != null) {
                        buildAction.position =
                            Vec2Int(entity.position.x + properties.size, entity.position.y + properties.size - 1)
                    }
                    entityAction.buildAction = buildAction
                } else {
                    entityAction.buildAction = null
                }
                entityActions.put(entity.id, entityAction)

            } else if (entity.entityType == model.EntityType.RANGED_BASE) {
                if (i == -1) {
                    buildAction.entityType = model.EntityType.RANGED_UNIT
                    if (properties != null) {
                        buildAction.position =
                            Vec2Int(entity.position.x + properties.size, entity.position.y + properties.size - 1)
                    }
                    entityAction.buildAction = buildAction
                }  else {
                    entityAction.buildAction = null
                }
                entityActions.put(entity.id, entityAction)

            }




        }
    }

    return Action(entityActions)
}
fun debugUpdate(playerView: PlayerView, debugInterface: DebugInterface) {
    debugInterface.send(model.DebugCommand.Clear())
    debugInterface.getState()
}

}

30.11.2020 0:21:50