CGC - an inside look

    So, in continuation of the topic about CGC I will reveal the technical details of systems for holding such competitions based on my own experience.

    1. Composition of the system
      To begin with, let's determine what this kind of system consists of.
      Well, firstly, 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 defines 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 fights between strategies.
        This raises the first question - what to record the results of battles?
        The first option is to record a certain story about the course of the battle, which can subsequently be reproduced using the visualizer.
        The second approach is to simulate and play simultaneously.
        Each approach 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 detail of the simulator is that it must be able to collect data from strategies written in different languages.

        Here, there are several implementation options.
        The first option that begs is to compile member strategies in a DLL, and then connect these libraries from the simulator. However, this option carries several problems:
        • not all languages ​​can provide DLL output
        • when using a DLL, they are loaded into the general process and may intentionally drop it.

        More secure is the option of compiling with executables and using interprocess communication to communicate the simulator and the strategies of the participants. You can use whatever you like for communication - in practice I have seen systems that use standard input / output (but I do not recommend you), systems that communicate 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) is received
        • the simulator launches the strategies of the participants and alternately passes them the commands to execute the Init method
        • the simulator receives the results of the Init method of each strategy and processes the errors (run-time, time limit, memory limit) of the user code
        • the simulator passes commands to execute the Move method one by one and collects the results
        • brings values ​​to acceptable intervals and simulates a battle
        • updates the values ​​of game variables and calls the Move method again
        • at the end of the battle, records the results of the battle

      2. Client The
        main task of the client is to send solutions and start viewing battles.
        It may also be useful to make functional for communication between the jury and the participants to solve inaccuracies in the rules. Sometimes situations arise when the client changes during the competition itself and the auto-update function can also be useful.
        There are no features in the client.
      3. Server
        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 requests for verification at these minutes are large enough and your server should respond to them in an acceptable time.

        What is included in the server? They go to the simulation module.
        Actually the main server, which serves the connection of users and the acceptance of decisions from them. These solutions are then compiled. Successfully compiled solutions are passed to the simulation module.

        I strongly recommend using the same compilers that the participants will also have installed - this will reduce the number of errors.

        To ensure a high speed of processing user decisions, you can use a cluster (as they do at TIT SFU), but in the absence of a cluster, you can implement a distributed server.
      4. Visualizer
        This module is used to display fights. Colorful special effects will make their viewing more interesting and exciting, and if it contains playback management functionality, it will simplify the lives of participants. However, do not get carried away with the effects - remember that if the visualizer slows down a lot for you, this will make competitions impossible.

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

      I also recommend issuing the API in a day - in two, and before the competition itself, arrange a small gathering of participants to answer questions. An example at the end of this article is an API from one of the CGCs.
    3. Remarks
      Some more comments on the game world. First, consider the difficulty - because the participants will have only 4-5 hours to explore the game world and implement the strategy. The harder the game world will be, the less interesting the players will end up with, and the less spectacular the Code Game Show will be.

      If your world is very complex, but you do not want to change it, try to include higher-level methods in the user API (for example, methods for finding the path between two points). You have to spend more than one or two days - it usually takes from a week to a month.
      Try to make support for the most common languages ​​- this will expand the circle of participants.
      Take the time to play the balance - for a good balance you will have to spend more than one or two days - it usually takes from a week to a month.
    4.  Example User API IBonus
      interface - describes the interface of IBonus bonus objects: public IMoveableObject Get hit point bonus Return value: number of hit points that the bot will receive if he selects a bonus int GetHP () Get machine gun ammunition bonus Return value: number of bullets for machine gun which the bot will receive if it picks up the bonus int GetMashinegunAmmo () Get the ammo bonus for 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 the gun ammunition bonus













      Return value: the number of shells for the machine gun that the bot will receive if it picks up the bonus
      int GetCannonAmmo ()

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

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

      interface - describes the interface of the game unit IBot: public IMoveableObject Get command name Return value: returns command name string GetTeamName () Get bot name Return value: returns bot name or an empty string if it is not specified








      string GetName ()

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

      Get information about the ammunition and the state of the machine gun
      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: current state of the machine gun
      SWeaponInfo GetMashineGun ()

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

      Get information about the ammunition and the state of the rocket launcher
      Information contains information on 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 type bot
      Return value: returns the type of the current bot
      BotType GetType ()

      Get the rotation of the tower The
      rotation of the tower is counted relative to the diametral plane of the bot.
      Return value: relative tower rotation in radians
      float GetTurrelAngle ()

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

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

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

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


      Get the object’s speed
      Return value: returns the module of the velocity vector
      float GetSpeed ​​()

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

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

      interface - describes the interface of the managed unit. ISelf: public IBot Set the bot name Setting the bot name is possible only inside the Init function. Calls inside Move are ignored. The bot name must not exceed 20 characters. If the length of the name exceeds them, then it will be shortened to the required length. Parameters:     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 within Move are ignored.
      Parameters:
          type
      Bot type void SetType (BotType type)

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

      Set bot rotation
      Parameters:
          angle New rotation angle in radians
      void SetDirection (float angle)
      Change bot tower rotation
      Parameters:
          delta Increment of the turret rotation angle in radians
      void TurnTurrel (float delta)
      Fire a machine gun
      fires a machine gun. The machine gun always shoots in the direction of the bot. If the machine gun is not ready for a shot, nothing happens.
      void ShotMashinegun ()

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

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

      Fire a rocket
      launcher. Fires a rocket launcher. If the rocket launcher is not ready to fire, nothing happens.
      Parameters:
          target Target
      void ShotRocket (IMoveableObject * target) IShell

      interface - describes the interface of the projectile located on the map. IShell: public IMoveableObject Get the owner. Return value: the bot fired by this shell IBot * GetOwner () Get the target. For shells such as laser, gun and machine gun, the target is NULL. If the object was destroyed, then NULL is returned. Returned value: the target object of the projectile. IMoveableObject * GetTarget () Get the type of projectile.












      Return value: shell type, for more details see ShellType description ShellType
      GetType ()
      Return value: get the damage caused by the shell.
      Return value: damage caused by the shell
      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 the coordinates of the object The
      coordinates of the static object correspond to its upper left corner. For more information on the coordinate system, see IWorld.
      Returned value: object coordinates.
      Point GetPosition ()

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

      interface - describes the interface of the game world. Get the number of the current move. Numbering starts from 1. The zero move corresponds to the Init call. Return value: current move number int GetCurrentStep () Get the total number of moves Return value: total number of moves (excluding the initialization move) int GetTotalStep () Get a list of static objects List based on the std :: vector type and allows accessing by index. Destroyed objects are removed from the game and are not displayed in this list. Returned value: list of static map objects














      IStaticObjectList GetStaticObjects ()

      Get a list of enemy bots. The
      list is based on the std :: vector type and allows you to access by 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 type std :: vector and allows you to access by index
      Killed bots are deleted from the game and are not displayed in this list
      Return value: list of your bots
      ISelfList GetSelfs ()

      Get a list of shells on the map The
      list is based on the std :: vector type and allows you to reverse by index
      Shells that flew off the map or collided 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 map The
      list is based on the std :: vector type and allows you to access index
      Bonuses that have expired or which have been picked up are removed from the game and are not displayed in this list
      Returned value: list of bots located on the map
      IBonusList GetBonuses ()

      Get the object by label
      Parameters:
          mark label get my object
      Return value: if an object with such a label is found, a pointer to it is returned, otherwise NULL is returned
      IMoveableObject * GetByMark (int mark)
      Add a debug message
      Adds a debug message displayed during visualization for debugging.
      Parameters:
          format message format - a string of n characters. Next are n parameters in accordance with the task format.
              d - integer (int)
              f - fractional number (float)
              s - string (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, then it will be reduced to the required size
      void AddMessage (string format, ...)

      Add a debug point
      Adds a debug point displayed during visualization for debugging.
      Parameters:
          p coordinate of the point
          lifetime during the time the vector was displayed in the moves
      void AddPoint (Point p, int lifetime)

      Add debug vector
      Adds a debug vector displayed during visualization for debugging
      Parameters:
          start start point
          end end point
          lifetime vector display time in moves
      void AddVector (Point start, Point end, int lifetime)
      Get map width
      Return value: map width
      int GetWidth ()

      Get map height
      Return value: map height
      int GetHeight ()

    Also popular now: