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.
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.
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
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.
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.
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.
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.
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.
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 ()