📜 ⬆️ ⬇️

CGC - inside view

So, in continuation of the topic about CGC, I will reveal the technical details of the systems for conducting this kind of competition based on my own experience.

  1. System composition
    To begin with, we will define what the system of this kind consists of.
    Well, first of all, the most important thing is the simulation module. Further, of course, this is the client and server, and finally, the most important part for the Code Game Show is the visualizer. Now consider each of these parts separately.
    1. Simulator
      The simulation module determines the physics of the world, a set of units and in general everything related to the game world. In addition, this module is responsible for simulating battles between strategies.
      This is where the first question arises - what to record the results of the battles?
      The first option is to record some history of the battle, which can later be reproduced using the visualizer.
      The second approach is simultaneous simulation and playback.
      Each of the approaches has its pros and cons. The advantage of the second approach is to reduce the time spent by participants on the analysis of their strategies during their development. However, the first approach allows you to implement the functionality of setting the speed and playback point.
      Another important part of the simulator is that it must “be able” to collect data from strategies written in different languages.

      Here, too, there are several options for implementation.
      The first option that suggests itself is a compilation of the strategies of the participants in the DLL, and then the connection of these libraries from the simulator. However, this option has several problems:
      • not all languages ​​can provide DLL output
      • when using a DLL, they are loaded into the general process and may “drop” it.

      A more secure option is compiling with executable files and using interprocess communication for simulator communication and participants strategies. For communication, you can use someone that you like - in practice I have seen systems that use standard I / O (but I do not recommend it to you), systems communicating through sockets.
      Well, the logic of the simulator is quite simple:
      • information about the participating strategies and the game world (for example, the identifier of the card used)
      • the simulator runs the strategies of the participants and in turn sends them commands to execute the Init method
      • the simulator receives the results of the implementation of the Init method of each strategy and handles errors (run-time, time limit, memory limit) of the user code
      • the simulator alternately sends commands to the execution of the Move method and collects the results
      • gives values ​​at valid intervals and conducts a battle simulation
      • updates the values ​​of the game variables and calls the Move method again
      • at the end of the battle records the results of the battle

    2. Customer
      The main task of the client is to send solutions and start watching fights.
      It may also be useful to make a functional for communication between the jury and the participants to resolve inaccuracies of the rules. Sometimes there are situations when the client changes during the competition itself and the auto-update feature can also come in handy.
      There are no features in the client.
    3. Server
      The server is one of the most serious parts. The first and last minutes of the competition are usually a very good test for the server - then the applications for verification at these minutes are quite large and your server should respond to them at an acceptable time.

      What is included in the server? are being fed to the simulation module.
      Actually the main server that serves the user connections and acceptance of solutions from them. Further, these solutions are compiled. Successfully compiled solutions are passed to the simulation module.
      ')
      I strongly recommend using the same compilers that will be installed and the participants - this will reduce the number of errors.

      To ensure high processing speed of user decisions, a cluster can be used (as is done in TIT SFU), well, in the absence of a cluster, a distributed server can be implemented.
    4. Visualizer
      This module is used to display fights. Colorful special effects will make their viewing more interesting and exciting, and if you have in it the functionality for managing playback, it will simplify the lives of participants. However, do not get carried away with the effects - remember that if the visualizer will slow you down a lot, it will make the competition impossible.

  2. User API
    Well, it all depends on your imagination, the only thing I would like to point out - I recommend making methods for debugging strategies - for example, output debugging messages (displayed only while writing a strategy), outputting points and vectors.

    I also recommend issuing an API for the day - for two, and before the competition itself arrange a small gathering of participants, at which to answer your questions. As an example, at the end of this article is an API from one of the CGCs.
  3. Remarks
    A few more comments on the game world. First, count the complexity - after all, participants will have only 4-5 hours to study the game world and implement the strategy. The more complex the game world will be, the less interesting strategies the players will end up with and the less spectacular the Code Game Show will be.

    If your world is very complicated, but you don’t want to change it, try including higher-level methods in the user API (for example, methods for finding the path between two points). You will have to spend more than one and not two days - usually it takes from a week to a month.
    Try to make support for the most common languages ​​- this will expand the circle of participants.
    Spend time playing the balance - for a good balance you have to spend not one or two days - it usually takes from a week to a month.
  4. Sample User API
    Interface IBonus - describes the interface of bonus objects
    IBonus: public IMoveableObject
    Get hit point bonus
    Return value: the number of hit points that the bot will receive if it picks up the bonus
    int GetHP ()

    Get a bonus ammunition to the machine gun
    Return value: the number of bullets for the machine gun that the bot will receive if it selects a bonus
    int GetMashinegunAmmo ()
    Get a bonus ammo to the laser
    Return value: the number of charges for the machine gun that the bot will receive if it picks up the bonus
    int GetLaserAmmo ()

    Get a bonus ammo to the gun
    Return value: the number of projectiles for a machine gun that a bot will receive if it selects a bonus
    int GetCannonAmmo ()

    Get a bonus to ammo to the rocket launcher
    Return value: the number of missiles that the bot will receive if it picks up a bonus
    int GetRocketAmmo ()

    Get the bot's lifetime
    Return value: remaining bonus lifetime in turns
    int GetElapsedTime ()

    IBot interface - describes the game unit interface
    IBot: public IMoveableObject

    Get team name
    Return value: returns the name of the command.
    string GetTeamName ()

    Get the name of the bot
    Return value: returns bot name or empty string if not specified
    string GetName ()

    Get information about the ammunition and the state of the gun
    The information contains information about the ammunition (the number of shells) and the time after which the gun will be ready to fire.
    Return value: the current state of the gun
    SWeaponInfo GetCannon ()

    Get information about the ammunition and the status of the machine gun
    The information contains information about the ammunition (the number of shells) and the time after which the machine gun will be ready to fire.
    Return value: the current state of the machine gun
    SWeaponInfo GetMashineGun ()

    Get information about ammo and laser status
    The information contains information about the ammunition (number of charges) and the time after which the laser will be ready to fire.
    Return value: current laser status
    SWeaponInfo GetLaser ()

    Get information on ammunition and state of the rocket launcher
    The information contains information about the ammunition (number of shots) and the time after which the rocket launcher will be ready to fire.
    Return value: current state of the rocket launcher
    SWeaponInfo GetRocket ()

    Get bot type
    Return value: returns the type of the current bot
    BotType GetType ()

    Get a turn of the tower
    The rotation of the tower is measured relative to the diamitral plane of the bot.
    Return value: relative tower rotation in radians
    float getTurrelAngle ()

    Get the bot's health level
    Return value: current number of hit points
    int GetHP ()
    Interface IMoveableObject - describes the interface of objects that can move.

    Get object position
    Returns the center of the object.
    Return value: the coordinate of the upper left corner
    Point GetPosition ()

    Get the angle of rotation of the object
    For more information about the coordinate system, see the description of the IWorld interface.
    Return value: returns the rotation of the object in radians.
    float getDirection ()

    Get object radius
    Bonuses, projectiles and bots are circles,
    Return value: returns the radius of the object
    float getRadius ()

    Get object speed
    Return Value: Returns the magnitude of the velocity vector.
    float getSpeed ​​()

    Get impulse velocity vector
    When a bot collides with some object (a projectile, another bot, a map object, except for the bonus), as well as when fired, it acquires a pulsed speed.
    Return value: impulse velocity vector
    Vector GetImpulseVelocity ()

    Set text label for object
    Setting text labels allows you to identify objects. Once you set a label to an object, you can later get it by this label. Text labels are not displayed anywhere. Participants do not see text labels of other participants.
    It is forbidden to put marks on bots - such marks will be reset every turn.
    Options:
    mark text label for object
    void SetMark (int mark)
    Get current object label
    Return value: the current label of the object, if the label is not set, returns -1
    int GetMark ()

    ISelf interface - describes the interface of the managed unit.
    ISelf: public IBot

    Set bot name
    Setting the name of the bots is possible only inside the Init function. Calls inside Move are ignored.
    The name of the bot should not exceed 20 characters. If the length of the name exceeds them, it will be shortened to the required length.
    Options:
    name bot name
    void SetName (string name)
    Set bot type
    Different types of bots have different characteristics. Setting the type of bot is possible only inside the Init function. Calls inside Move are ignored.
    Options:
    type Bot type
    void SetType (BotType type)

    Set the speed
    Changes the value of the velocity vector. A negative value corresponds to a backward movement. If the speed exceeds the maximum threshold or less than the minimum threshold, it will be reduced / increased to acceptable values.
    Options:
    speed new speed
    void SetSpeed ​​(float speed)

    Set the rotation of the bot
    Options:
    angle New angle of rotation in radians
    void SetDirection (float angle)
    Change the rotation of the bot tower
    Options:
    delta Increment of the angle of rotation of the tower in radians
    void TurnTurrel (float delta)
    Make a shot from a machine gun
    Makes a shot from a machine gun. The machine gun always shoots in the direction of the bot. If the machine gun is not ready to fire, nothing happens.
    void ShotMashinegun ()

    Make a shot from a cannon
    Makes a shot from a cannon. The gun is mounted on the tower. If the gun is not ready to fire, nothing happens.
    void ShotCannon ()

    Make a shot from the laser
    Makes a shot from the laser. The laser shoots always in the direction of the bot. If the laser is not ready to fire, nothing happens.
    Options:
    angle laser rotation angle
    void ShotLaser (float angle)

    Shoot a rocket launcher
    Makes a shot from a rocket launcher. If the rocket launcher is not ready to fire, nothing happens.
    Options:
    target Target
    void ShotRocket (IMoveableObject * target)

    Interface IShell - describes the interface of the projectile, located on the map.
    IShell: public IMoveableObject

    Get the owner.
    Return value: the bot that fired the projectile
    IBot * GetOwner ()

    Get a goal.
    For shells such as laser, cannon and machine gun, the target is NULL
    If the object was destroyed, then NULL is returned.
    Return value: target object.
    IMoveableObject * GetTarget ()
    Get the type of projectile.
    Return value: projectile type, see ShellType description for details.
    ShellType GetType ()
    Return value: take damage from projectile.
    Return Value: Projectile Damage
    int GetHP ()

    Interface IStaticObject - describes the interface of static map objects.
    Get the number of object hit points
    Return value: current value of hit points
    int GetHP ()

    Get object coordinates
    The coordinates of a static object correspond to its upper left corner. For details on the coordinate system, see IWorld.
    Return value: object coordinates
    Point GetPosition ()

    Get object size
    Return value: object size
    Size GetSize ()

    Interface IWorld - describes the interface of the game world.

    Get the current move number
    Numbering is done from 1. Zero move corresponds to Init call
    Return value: the number of the current move
    int GetCurrentStep ()

    Get the total number of moves
    Return value: total number of moves (excluding move-initialization)
    int GetTotalStep ()

    Get a list of static objects
    The list is based on the type std :: vector and allows you to refer to the index
    Destroyed objects are removed from the game and are not displayed in this list.
    Return value: list of static map objects
    IStaticObjectList GetStaticObjects ()

    Get a list of enemy bots
    The list is based on the type std :: vector and allows you to refer to the index
    Killed bots are removed from the game and are not displayed in this list.
    Return value: list of enemy bots
    IEnemyList GetEnemies ()

    Get a list of your bots
    The list is based on the type std :: vector and allows you to refer to the index
    Killed bots are removed from the game and are not displayed in this list.
    Return value: list of bots
    ISelfList GetSelfs ()

    Get a list of shells on the map
    The list is based on the type std :: vector and allows you to refer to the index
    Shells that fly out of the map or collide with an object are removed from the game and are not displayed in this list.
    Return value: list of shells on the map
    IShellList GetShells ()

    Get a list of bonuses on the card
    The list is based on the type std :: vector and allows you to refer to the index
    Bonuses that have expired or that were picked are removed from the game and are not displayed in this list.
    Return value: list of bots located on the map
    IBonusList GetBonuses ()

    Get object by tag
    Options:
    mark mark of received object
    Return value: if an object with such a label is found, then a pointer to it is returned, otherwise NULL is returned
    IMoveableObject * GetByMark (int mark)
    Add debug message
    Adds a debug message displayed when rendering for debugging.
    Options:
    The format of the message is a string of n characters. Next are the n parameters in accordance with the task format.
    d is an integer (int)
    f - fractional number (float)
    s - string
    all other characters are not interpreted and fall into the message
    The total length of one message should not exceed 255 characters. If the string is longer, it will be reduced to the required size.
    void AddMessage (string format, ...)

    Add debug point
    Adds a debug point displayed when rendering for debugging.
    Options:
    p point coordinate
    lifetime vector display in moves
    void AddPoint (Point p, int lifetime)

    Add a debug vector
    Adds a debug vector that is displayed when rendering for debugging.
    Options:
    start starting point
    end end point
    lifetime vector display in moves
    void AddVector (Point start, Point end, int lifetime)
    Get the width of the map
    Return Value: Map Width
    int GetWidth ()

    Get card height
    Return Value: Map Height
    int GetHeight ()

Source: https://habr.com/ru/post/72214/


All Articles