Este capitulo explica lo que se necesita saber para construir tus propios robots. Lo mas importante es conocer el lenguaje de mensajes, formado aproximadamente por 35 comandos usados para comunicarse con el programa servidor. Es también muy útil estudiarse los robots de ejemplo del directorio Robots/
.
Al comienzo de cada secuencia el proceso robot es lanzado por el servidor y asigna dos pipes (tuberias), una para la entrada y otra para la salida. Estas estan conectadas a stdin
y a stdout
, por lo que desde el punto de vista del robot, este se comunica con el servidor mediante la salida estandar y mediante la entrada estandar.
Esto significa que los robots pueden ser escritos en casi cualquier lenguaje de programación. De todas formas, el robot ha de ser capaz de saber cuando recibe un mensaje. Para ello hay al menos tres métodos, que son:
Este es el método mas simple. Es como si siempre hubiera un mensaje esperando. Lo malo es que con este método no puedes hacer ningun cálculo mientras esperas nuevos mensajes.
Para elegir este metodo, manda la siguiente opcion en cuanto el programa comience.:
"cout << "RobotOption " << USE_NON_BLOCKING << " " << 0 << endl;"Ten en cuenta que esto es codigo c++. Si no usas c++ simplemente imprime en la salida estandar al mensaje mostrado. endl es lo mismo que 'end of line'.
Usar la funcion select
hace posible que el robot tenga un mejor control a la hora de recibir nuevos mensajes. Te permite, por ejemplo, leer nuevos mensajes disponibles, hacer algunos calculos, mandar comandos y esperar mensajes. Para aprender mas sobre select
, lee la documentacion de Unix (las paginas man o la informacion del emacs).
Para seleccionar el metodo select, envia la siguiente opcion en cuanto el programa comience
cout << "RobotOption " << USE_NON_BLOCKING << " " << 1 << endl;Ten en cuenta que esto es codigo c++.
Si quieres, puedes indicarle a RealTimeBattle que envie una señal al robot en cuanto este disponible un nuevo mensaje. Este metodo permite al robot estar continuamente informado por el servidor incluso cuando el robot esta ocupado calculando algo. Si no estas seguro de como usar las señales, mira en la documetnacion de unix o estudia los otros robots para aprender mas.
Para seleccionar este metodo, envia la siguiente opcion en cuanto se inice el programa:
cout << "RobotOption " << USE_NON_BLOCKING << " " << 1 << endl; cout << "RobotOption " << SIGNAL << " " << SIGUSR1 << endl;Se trata de codigo c++.
Puedes seleccionar cualquier señal en lugar de SIGUSR1
Como apoyo para la implementacion de estos tres metodos, el robot rotate_and_fire
ha sido escrito en tres versiones diferentes. Tomate la libertad de estudiar y coger código de este robot, si quieres.
No es recomendable estar continuamente mirando si hay mensajes nuevos, ya que esto ralentiza los procesos de una forma considerable, y en una competition-mode el robot moririía por salirse del tiempo de CPU.
El fichero Messagetypes.h
es una buena fuente de informacion sobre el lenguaje de mensajes. Es un fichero c/c++ (un include, vamos), pero se puede reescribir facilmente para usarlo con otros lenguajes. Aquí encontrarás un listado de los mensajes, los avisos (los warning), objetos, opciones de juego y opciones de los robots.
Desde el momento en que el prograso de la batalla es en tiempo real con procesos reales, es posible escribir programas que 'hagan trampas' de una manera u otra. Por ejemplo examinando los otros robots o incluso al RealTimeBattle mismamente para obtener mas informacion, usando muchos recursos para 'ahogar' a los otros robots, etc... Esta no es la manera de vencer a los oponentes, por supuesto, asi que intentaremos erradicarlo al maximo posible.
En el modo competicion (competition-mode) los robots tienen un uso limitado de CPU, por lo que un robot no puede usar toda la CPU. Esta 'norma' podria ser saltada lanzando procesos hijos. Aunque sería fácilmente detectable un robot con comportamiento sospechoso.
No es posible prevenir todas las maneras de 'hacer trampas' en RealTimeBattle. Por ejemplo esta permitido leer y escribir en ficheros, pero recuerda que los organizadores de las competiciones pueden prohibir esto si quieren. Poniendo permisos sobre los executables de los robots y sobre los directorios esto se puede hacer facilmente.
Es posible que haya mas formas de hacer cosas 'ilegales' con los robots. Si detectas una de estas formas, por favor manda un bug report. De todas formas es responsabilidad del organizador del torneo asegurarse de que se cumplen todas las normas.
Este es el primer mensaje que el robot recibirá. Si el argumento es uno, esta es la primera secuencia del torneo y se deberá mandar el nombre y el color (Name and Colour) al servidor, o de lo contrario el esperaría los mensajes de nombre (YourName) y color (YourColor). Ver debajo.
El nombre actual del robot.
Color actual del robot. Cambialo si no te gusta el actual.
Al comienzo de cada juego, se enviarán a los robots un número de parámetros, que pueden ser útiles al robot. Para obtener una lista de ellos, mira en el fichero
Messagetypes.h la sección de game_option_type
. En el capitulo de
opciones (options chapter) encontraras información mas detallada de cada opción.
debug level es enviado al robot como una opcion de juego, aunque no se haya indicado en las opciones.
Este mensaje es enviado cuando comienza el juego.
Este mensaje ofrece información sobre el radar en cada turno. Recuerda que el angulo del radar es relativo al frontal del robot y viene dado en radianes.
El mensaje Info siempre sigue al mensage Radar. Ofrece mayor información sobre el estado del Robot. 'Time' es el tiempo transcurrido desde el comienzo del juego. Esto no tiene porque ser igual que el tiempo real transcurrido, debido a la escala de tiempo (time scale) y al max timestep.
Informa sobre la posición actual del robot. Este mensaje se envia solo si la opción Send robot coordinates es 1 o 2. Si es 1 las coordenadas son enviadas relativas a las posicion de comienzo, aunque el robot no sabe exactamente donde empieza, pero si sabe si se ha movido de su punto de origen.
Si detectas un robot con el radar, este mensaje será enviado a continuación, dando información sobre el robot. Se dará el nivel de energía del oponente asi como tu propia energia (ver abajo). El segundo argumento es solo interesante en el modo equipo (team-mate), que aun no esta implementado. 1 significa compañero de equipo y 2 significa enemigo.
Cuando la opción SEND_ROTATION_REACHED esta puesta adecuadamente, este mensaje es enviado cuando un giro (realizado mediante RotateTo o RotateAmount) ha finalizado o bien cuando se modifica la dirección (sweeping). El argumento corresponde a la opción 'what to rotate', como en Rotate.
Al final de cada turno el robot conocerá su nivel de energía. De todas formas, no sera un numero exacto, sino un numero limitado a los niveles de energia (energy levels).
Al principio de cada juego y cuando un robot muera, el número restante de robots sera enviado a todos los robots que aun esten vivos.
Cuando un robot se golpea o es golpeado por algo recibe este mensaje. En el fichero Messagetypes.h puedes encontrar una lista de los tipos de objeto. Obtendrás el ángulo desde el cual la colisión ha ocurrido (angulo relativo al robot) y el tipo de objeto contra el que has chocado, aunque no recibiraá la información de la gravedad del choque. Esto puede ser determinado, indirectamente, por el decremento de la energía.
Un mensaje de aviso (warning) sera enviado al robot en caso de que ocurra algun problema. Actualmente hay siete mensajes de aviso que pueden ser enviados, que son:
UNKNOWN_MESSAGE:
El servidor ha recibido un mensaje que no puede reconocer.
PROCESS_TIME_LOW:
El uso de la CPU ha sobrepasado el
porcentaje de CPU (CPU warning percentage). Solo en
modo competicion (competition-mode).
MESSAGE_SENT_IN_ILLEGAL_STATE:
El mensaje que se ha recibido no se puede procesar en ese momento del juego. Por ejemplo cuando envia un mensaje
Rotate antes de comenzar el juego.
UNKNOWN_OPTION:
Cuando el robot envía una
opción (robot option)con un nombre inválido o con un argumento incorrecto para esa opcion.
OBSOLETE_KEYWORD:
Ese 'keyword' (comando) esta obsoleto y no debería ser usado nunca mas. Para mas informacion mira en el fichero ChangeLog
.
NAME_NOT_GIVEN:
El robot no ha enviado su nombre antes de que el juego comience. Esto sucede si
el tiempo de inicio (robot startup time) es demasiado corto o bien el robot no ha enviado su nombre lo suficientemente pronto.
COLOUR_NOT_GIVEN:
El robot no ha enviado su color antes de que el juego comience.
El robot ha muerto. No intentes enviar nuevos mensajes hasta el final del juego, ya que el servidor no los leerá.
El juego actual ha finalizado. Preparate para el siguiente !!!
Sal del programa inmediatamente!!! Sino sera matado (killed) a la fuerza.
Actualmente solo hay dos opciones disponibles:
SIGNAL:
Le comunica al servidor que envie una señal cuando haya un mensaje esperando. El argumento determinará esa señal. Envia este mensage (con el argumento SIGUSR1, por ejemplo) tan pronto como estes listo para recibir la señal. Por defecto es 0, lo que significa que no se envie ninguna señal.
SEND_SIGNAL:
Le indica al servidor que envie SIGUSR1 cuando haya un mensaje esperando. Envia este mensaje (con argumento 1 (=cierto)) tan pronto como estes preparado para recibir la señal. Por defecto es falso.
SEND_ROTATION_REACHED:
Activa esta opcion si quieres que el servidor te envie un mensaje
RotationReached cuando finalize una rotacion. Con un valor de 1, el mensaje será enviado cuando finalice un RotateTo o bien un RotateAmount. Con un valor 2, los cambios en la direccion sweep (de barrido) seran también notificados. Por defecto esta opcion esta a 0, con lo que ningun mensaje sera enviado.
USE_NON_BLOCKING:
Selecciona como funciona la
lectura de mensajes (reading messages). Esta opcion será enviada tan pronto como el programa comienza. Esta opcion debe ser activada siempre, ya que no hay disponbible ningun valor por defecto.
Cuando se recibe un mensaje de inicializacion (Initialize) con un argumento a 1, indicando que esa es la primera secuencia, debes enviar tanto el nombre como el color del robot.
Mirar arriba. Los colores son como las camisetas de fútbol, el color propio es usado excepto que ya este ocupado por otro. Si no se pueden utilizar ninguno de los colores indicados, se escogerá uno aleatoriamente.
Fija la velocidad angular del robot, del cañón y/o del radar. 'what to rotate' 1 para el robot, 2 para el cañón, 4 para el radar o una suma de cualquiera de los tres para fijar la velocidad de rotación de mas de uno a la vez. La velocidad angular viene dada en radianes por segundo y esta limitada a maxima velocidad de rotacion (Robot (cannon/radar) max rotate speed).
Como Rotate, pero rotará a un angulo dado. Ten en cuenta que los angulos del radar y del cañón son relativos al ángulo del robot. No podras usar este comando para rotar el robot, para ello utiliza RotateAmount.
Como Rotate, pero rotará de una forma relativa al angulo actual.
Como rotate, pero fija el radar y/o el cañón en un modo de barrido (sweep). No sera válido para el robot.
Fija la aceleracion del robot. El valor sera fijado entre los valores aceleracion maxima/minima (Robot max/min acceleration).
Activa el freno. Freno total (portion= 1.0) significa que el rozamiento en la direccion del robot es igual al Slide friction.
Dispara con la energia dada. Las opciones de disparo (The shot options) te darán mas información.
Muestra un mensaje en la ventana de mensajes (message window).
Muestra mensajes en la ventana de mensaje (message window) si estamos en modo debug (debug-mode).
Dibuja una linea directamente sobre la arena. Solo esta disponible en el máximo nivel de debug (5), de lo contrario se enviara un aviso (warning message) . Los argumentos son el punto inicial y el punto final de la linea dada en coordenadas polares relativas al robot.
Similar a la opcion anterior, pero dibuja un circulo. Los primeros dos argumentos indican el angulo y el radio del punto central relativo al robot. El tercer argumento indica el radio del circulo.