Ce chapitre décrit ce dont vous aurez besoin afin de construire vos propres robots. Le plus important à savoir est le langage de messages, qui est composé de 35 commandes utilisées pour communiquer avec le serveur. Il peut également être interresant d'étudier les exemples de robots livrés dans le repertoire
Robots/
.
Au début de chaque séquence, les processus des robots sont lancés par le serveur et deux 'pipes' leur sont assignés (un pour les 'Entrees' et l'autre pour les 'Sortie'). Ces deux pipes sont connectés à stdin
et stdout
, de telle sorte que du point de vue du robot, la communication avec le serveur s'effectue via l'entrée et la sortie standards.
Cette approche vous laisse libre du langage de programmation. Toutefois, le robot doit savoir quand il reçoit un nouveau message. Il y a (au moins) trois méthodes pour y parvenir :
C'est la méthode la plus simple. En lisant l'entrée standard stdin
, le programme est bloqué jusqu'à l'arrivée d'un nouveau message. Vous pouvez donc construire votre programme comme si il y avait toujours un mesage en attente. Le point noir est que vous ne pouvez faire aucun calcul pendant que le programme attend un nouveau message.
Pour choisir cette méthode, il faut envoyer l'option suivante dès que le programme est lancé
cout << "RobotOption " << USE_NON_BLOCKING << " " << 0 << endl;Ceci est un code C++. Si vous n'utilisez pas le C++, il suffit d'afficher l'information (comme si vous deviez afficher quelquechose à l'écran). endl est l'équivalent de 'fin de ligne'.
Utiliser la fonction select
de libc permet au robot d'avoir un meilleur contrôle pour savoir quand regarder les nouveaux messages.
Il vous permet, par exemple, de lire tous les messages, faire quelques calculs, envoyer les commandes puis d'attendre de nouveaux messages. Pour en savoir plus à propos de select
, lisez la documentation Unix
( e.g. man pages or emacs info ).
Pour choisir cette méthode, envoyer l'information suivante dès que le programme est lancé:
cout << "RobotOption " << USE_NON_BLOCKING << " " << 1 << endl;Il s'agit encore une fois d'un ligne de code C++
Si vous voulez, vous pouvez demander à RealTimeBattle d'envoyer un signal au robot quand une nouvelle serie de messages est envoyée. Cette méthode permet au robot d'être continuellement mis au courant des informations du serveur même lorsqu'il est occupé par des calculs. Si vous n'en savez pas assez sur les signaux, regarder la documentation Unix ou étudiez les autres robots pour en savoir plus.
Pour utiliser cette méthoed, envoyé l'option suivante au serveur dès le lancement du programme
cout << "RobotOption " << USE_NON_BLOCKING << " " << 1 << endl; cout << "RobotOption " << SIGNAL << " " << SIGUSR1 << endl;Toujours du C++.
Vous pouvez bien sûr utiliser n'importe quel signal à la place de SIGUSR1
.
Pour vous aider à implanter ces méthodes, le robot rotate_and_fire
a été écrit de trois manières différentes, mais fonctionnent de la même façon.
Vous êtes libre de l'étudier et de le copier pour votre propre robot.
Ce n'est pas une bonne idée de faire du 'busy wait', i.e., de regarder répetitivement les messages jusqu'à en avoir un. Cela ralentit considérablement les choses et pire, en mode competition le robot sera vite au delà du CPU qui lui est accordé et mourrira.
Le fichier Messagetypes.h
est une bonne source d'information sur le langage de communication. C'est un fichier d'inclusion C/C++, mais il est facile de le réécrire dans un autre langage de programmation. Vous pourrez y trouver la liste des messages, les types d'avertissement, les objets, les options de jeu et de robot.
Durant la progression de la bataille en temps réel, avec des processus réels, il est possible d'écrire des programme qui 'trichent' à un moment ou à un autre. Par exemple, en examinant les autres robots ou le serveur pour avoir plus d'informations, en utilisant d'importantes resources pour ralentir les autres robots et de bien d'autres façons encore. Ce n'est bien sur pas la méthode attendue pour vaincre l'adversaire, alors nous essayons de limiter ces actions autant que possible.
Dans le mode competition les robots ne sont pas autorisé à lancer des processus fils et l'utilisation du CPU est limitée. Ainsi, un robot ne peux pas utiliser tout le CPU.
Il n'est pas possible d'empecher toutes les façons de tricher dans RTB. Il est par exemple possible d'écrire ou de lire des fichiers, mais souvenez vous que les organisateurs de compétitions peuvent interdir cele s'il le souhaite. Limiter les droits d'acces du robot donne des résultats satisfaisants.
Il est toujours possible de trouver des moyens de contourner ces restrictions; si vous trouver un de ces moyens, s'il vous plait, envoyer nous un rapport de bug. Néanmoins, il est du bon plaisir de l'oganisateur du tournoi d'assurer le respect de ces règles.
C'est le premier message que le robot recevra. Si l'argument est 1, c'est la première sequence d'un tournoi et le robot doit se présenter en envoyant son Nom et sa Couleur au serveur, sinon il devra attendre les messages YourName et YourColour (voir plus loin). (En fait, je n'en suis pas trop sur...)
Le nom courant du robot, à ne pas changer sans avoir une bonne raison.
Couleur courante du robot, à changer si elle n'est pas à votre goût.
Au début de chaque jeu, le robot recevra un certain nombre de caractéristiques qui pourraient lui être utiles. Pour obtenir une liste complète de ces messages, regardez le fichier
Messagetypes.h
pour voir l'enumeration des game_option_type
.
Dans le
chapitre des options vous obtiendrez des informations plus détaillées. Le
niveau de debuggage est aussi envoyé comme option, même s'il ne fait pas partie de la liste.
C'est le message envoyé pour signaler le début de la bataille (surpris?)
Ce message donne les informations venant du radar à chaque tour. Souvenez vous que l'angle du radar est relatif à l'avant du robot. Il est donné en radians.
Le message Info suit toujours le message Radar. Il donne des informations plus générales sur l'état du robot. Le temps est celui écoulé depuis le début du jeu. Ce n'est pas forcement le même que le temps réellement écoulé (à cause de l'échelle de temps et du plus petit écart de temps.
Vous donne la position courante du robot. Il est envoyé seulement si l'option est 1 ou 2. Si elle est 1 les coordonnées sont envoyés relativement à la position de départ (Le robot ne sait pas exactement où il a commencé, mais seulement de combien il s'est déplacé).
Si vous détecter un robot au radar, ce message suivra, donnant les informations sur ce robot. Le niveau d'énergie de l'adversaire sera donné de la même façon que votre propre énergie (voir plus bas). Le second argument concerne seulement le mode en équipe (qui n'est pas encore implanté), 1 signalant qu'il s'agit d'un membre de votre équipe et 0 un ennemi.
Quand l'option robot
SEND_ROTATION_REACHED est activée, ce message est envoyé quand une rotation (avec RotateTo ou RotateAmount) est terminée ou que la direction à changée (lors d'un balayage).
A la fin de chaque tour, le robot connaîtra son niveau d'énergie. Il ne connaîtra pas exactement son niveau exact, mais une approximation correspondant à des
niveaux d'énergie.
Au début du jeu et quand un robot est tué, le nombre de robots restant est envoyé à tous les robots encore vivant.
Quand un robot cogne (ou est cogné par) quelquechose, il reçoit ce message. Dans le fichier
Messagetypes.h vous trouverez la liste des types d'objets. Vous recevrez aussi l'angle auquel c'est produit la collision (angle relatif au robot) et le type de l'objet qui a été cogné, mais pas l'importance du choc. Elle peut tout de même être déterminée indirectement (approximativement) par la perte d'énergie.
Un message d'avertissement peut être envoyé quand un robot à fait quelquechose d'incorrecte. Pour le moment, il y a 7 messages d'avertissement différents :
Le robot est mort. Ce n'est plus la peine d'envoyer de nouveaux messages au server avant la fin du jeu, le serveur ne les lit plus.
Le jeu courant est terminé, préparez vous au prochain jeu!!!
Quitter le programme immédiatement!! Sinon on sera forcé de le tuer.
UNKNOWN_MESSAGE:
Le serveur a reçu un message qu'il n'arrive pas à reconnaitre.
PROCESS_TIME_LOW:
L'utilisation du CPU a atteind le
pourcentage critique de CPU. Seulement dans le
mode competition.
MESSAGE_SENT_IN_ILLEGAL_STATE:
Le message envoyé ne correspond pas à l'état d'avancement du programme. Par exemple
Rotate a été envoyé avant le début du jeu.
UNKNOWN_OPTION:
Le robot a envoyé une
option qui est soit un nom inégale, soit un argument ne correspondant pas à une option.
OBSOLETE_KEYWORD:
Le mot clef envoyé est obselete et ne doit plus être utilisée. Voir le fichier
ChangeLog
pour des informations pour ce qu'il faut utiliser à la place.
NAME_NOT_GIVEN:
Le robot n'a pas envoyé son nom avant le début du jeu. Ca arrive si le
temps de démarrage du robot est trop (...) ou que le robot n'envoye pas son nom assez tôt.
COLOUR_NOT_GIVEN:
Le robot n'a pas envoyé sa couleur avant le début du jeu.
Il n'y a pour le moment que deux options possibles :
SIGNAL:
Dire au serveur d'envoyer un signal quand il y a un message qui attend. L'argument déterminera quel signal utiliser. Envoyez ce message (avec l'argument SIGUSR1 par exemple) dès que vous êtes prêt à recevoir les signaux. Par défaut, cette valeur est 0, ce qui veut dire que vous ne recevrez aucun signal.
SEND_SIGNAL:
Demande au serveur d'envoyer SIGUSR1 quand il y un message qui attend. Envoyez ce message (avec l'argument 1 (=vrai)) dès que vous être prêt à recevoir le signal. Par défaut, la valeur est fausse.
SEND_ROTATION_REACHED:
Si vous voulez que le serveur vous envoye le message
RotationReached
quand une rotation est terminée, vous devez demander cette option. Avec une valeur de 1, le message est envoyé quand un RotateTo ou un RotateAmount est terminé, avec le valeur 2, quand les changement de direction d'un sweep est aussi indiqué. Par défaut (0) aucun message ne sera envoyé.
USE_NON_BLOCKING:
Choisit comment
la lecture des messages s'effectue. Cette option doit être envoyée dès que le programme est lancé. Puisqu'elle doit toujours être donnée, il n'y a pas de valeur par défaut.
Quand vous recevez le message Initialize avec l'argument 1, indiquant qu'il s'agit de le première séquence, vous devez envoyer votre nom et votre couleur.
(Voir plus haut). Les couleurs sont comme des maillons de foot, la première couleur est utilisée si personne ne l'a déjà prise. Sinon, la couleur 'visiteur' ou en dernier recourt, une couleur choisie au hasard sera donnée au robot.
Selectionne la vitesse angulaire de rotation du robot, de son canon ou de son radar. L'objet doit être 1 pour le robot, 2 pour le cannon, 4 pour le radar ou la somme pour faire tourner plusieurs objets en même temps. La vitesse angulaire est donnée en radians par seconde et est limité par la Vitesse maximum de rotation du Robot (cannon/radar).
Comme Rotate, mais s'arrêtera à un angle donné. L'angle du radar et du cannon sont relatif à l'angle du robot. Vous ne pouvez pas utiliser cette commande pour faire tourner le robot (Utilisez RotateAmount à la place).
Comme Rotate, mais tourne par rapport à l'angle courant.
Comme rotate, mais fait tourner le radar et/ou le cannon (pas disponible pour le robot lui même) dans un mode de balayage.
Définit l'accélaration du robot. La valeur est limitée pas l'accélération max/min du Robot.
ordonne un frainage. Le frein complet (portion = 1.0) signifie que la friction du robot dans le sens de déplacement est égal au frottement dû au glissement.
Tire un missile avec l'energie donnée. Les options de tire donnent plus d'informations.
Affiche un message sur la fenêtre de messages.
Affiche un message dans la fenêtre des messages si le mode debug est engagé.
Dessine une ligne directement sur l'arène. Seulement disponible dans le plus haut mode de debug(5), sinon un message d'avertissement est envoyé. Les arguments sont les points de départ et d'arrivée donnés en coordonnées polaires relativement au robot.
Identique que pour DebugLine, mais dessine un cercle. Les deux premiers arguments sont l'angle et le rayon relativement au robot. Le troisième argument donne le rayon du cercle.