Open AI Championship

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

Quick start

Round 1: before start

Project

Sandbox

Round 1

Round 2

Finals

Recent comments

30 november 02:07: dozorhunterr wrote comment on post Language packages
30 november 01:46: dozorhunterr wrote comment on post Language packages
30 november 01:03: Hooloovo wrote comment on post Language packages
30 november 00:21: georg_karr_spb wrote comment on post Quick start
29 november 23:11: Jeen99 wrote comment on post Rules
29 november 21:40: amurushkin wrote comment on post CodeCraft 2020 App
29 november 20:55: xocks wrote comment on post CodeCraft 2020 App
29 november 20:08: sergileon wrote comment on post CodeCraft 2020 App
29 november 19:30: Okke wrote comment on post CodeCraft 2020 App
29 november 19:20: oh_my_kpot wrote comment on post CodeCraft 2020 App

VK Group

Telegram chat

Discord

 

We’ll show you how to join CodeCraft in a few minutes.

Register

Of course, you need to register. We kindly ask all participants to provide accurate and complete information about yourself.

Download language pack

Download the package for your favorite programming language from the language packs page. Unzip the archive and open an existing project or create a new one from scratch. You may need to configure some paths.

Download the app

The app gives you the opportunity to run and test games locally on your computer. Read more about it here.

Read the documentation

The official and complete rules are published in the Rules section, please read them. Some organizational aspects you can find in the descriptions of the Sandbox and stages of the championship (Round 1, Round 2, Finals).

Submit your strategy

You can submit you strategy here. Before the system will accept your strategy, it will be compiled and tested in a few short games. If everything is OK, your strategy will automatically start to participate in regular qualifying games in Sandbox. Carefully read the section “What you should pay attention to” for various aspects due to which your strategy can get the “Verification error” verdict. The total number of submissions are not restricted, however there are restrictions on too frequent submitting. Any attempt to destabilize the system will result in disqualification. You can write your strategy in an arbitrary number of files, you will only need to pack everything into a ZIP archive and send it.

What you should pay attention to

  • your strategy has limited CPU time;
  • the strategy process should not exceed memory limit;
  • if your strategy exceeds the time or memory limit or crashes during the execution, it stops to participate in this game (however, your score points do not expire);
  • the strategy of each participant runs in a separate container.

Simple strategy

Here is a simple strategy in Rust programming language. It is gathering resources, buys units separately for each type and sends them to the opposite map corner with auto attack.

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 всех юнитов. А здесь сравнивается использование еды только юнитами того типа, которое здание производит, с производством еды конкретно этим зданием???

Nov 28, 2020 12:14:52 PM
Savidiy

Savidiy

SCETER

spaceorc

spaceorc

СКБ Контур

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

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

Nov 28, 2020 2:02:39 PM
WitcherSanek

WitcherSanek

Moscow

Savidiy

Savidiy

SCETER

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

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

Nov 28, 2020 6:20:36 PM
Savidiy

Savidiy

SCETER

WitcherSanek

WitcherSanek

Moscow

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

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

Nov 28, 2020 7:56:29 PM
Smeagol

Smeagol

Algeria

Hello, Madknight joue tu ?

Nov 29, 2020 4:31:57 AM
j303

j303

Moscow

Всем привет.

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

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

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

Nov 29, 2020 8:43:58 AM
Okke

Okke

Saint Petersburg

j303

j303

Moscow

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

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

Nov 29, 2020 1:16:44 PM
Okke

Okke

Saint Petersburg

j303

j303

Moscow

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

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

Nov 29, 2020 1:17:21 PM
alivefil

alivefil

Krasnoyarsk

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

Nov 29, 2020 1:23:03 PM
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()
}

}

Nov 30, 2020 12:21:50 AM