- Introducción
- Objetivo del juego y normas
- Código inicial
- Primeras modificaciones
- Terminando la faena
- Código ganador
- Curiosidades
- Enlaces
Introducción
Hace tiempo que me aficioné a los retos de Hacking y Cracking, y si bien la mayoría de ellos consisten en desencriptar una clave o realizar ingeniería inversa sobre un ejecutable, también los hay sobre programación pura y dura.
En esta ocasión se nos proporciona un código «muestra» parecido a PHP o C++ y tenemos que ingeniarnoslas para mejorarlo y ganar a la máquina.
Objetivo del juego y normas
El objetivo de esta misión es ganar a Tr0n en su propio juego: las carreras de motos. Se te proporcionará un programa (código) funcional para que veas como se controla el vehiculo. Usando tu inteligencia, tendrás que entender su uso y mejorarlo, ya que no es lo suficientemente bueno como para ganar a Tr0n. Tr0n lleva ya bastante tiempo en la parrilla de juegos y es bastante habilidoso 🙂
Cuando venzas a Tr0n un mínimo de 5 veces consecutivas, se te dará por superada esta prueba.
Buena suerte!!!
[ Available functions / Funciones disponibles ]
direction() returns current direction, change to a new one with direction([newdir])
getX(), getY() returns X and Y coordinates
collisionDistance() | collisionDistance([anydir]) returns the distance until collision
Note: parameters [*dir] can be empty or one of this values: UP DOWN LEFT or RIGHT[ Constants / Constantes ]
UP DOWN LEFT RIGHT MAX_X MAX_Y[ Rules / Reglas ]
Try to survive driving your bike and … / Intenta sobrevivir conduciendo tu moto y…
Don’t cross any line / No cruces ninguna línea
or crash with the corners! / o choques con las esquinas![ Mission / Mision ]
Use well this controller and beat Tr0n 5 consecutive times to score in this game
Usa bien este controlador y vence a Tr0n 5 veces consecutivas para puntuar en este juego
Código inicial
Nada más comenzar vemos que hemos perdido nuestra primera partida con el siguiente código:
function controller(playerController $c){ if($c->direction()==UP && $c->getY()<10){ if(rand(0,1)==0) $c->direction(LEFT); else $c->direction(RIGHT); goto done; } if($c->direction()==DOWN && MAX_Y-$c->getY()<10){ if(rand(0,1)==0) $c->direction(LEFT); else $c->direction(RIGHT); goto done; } if($c->direction()==LEFT && $c->getX()<10){ if(rand(0,1)==0) $c->direction(UP); else $c->direction(DOWN); goto done; } if($c->direction()==RIGHT && MAX_X-$c->getX()<10){ if(rand(0,1)==0) $c->direction(UP); else $c->direction(DOWN); } done: }
Nosotros somos el AZUL y la máquina es el VERDE.
Primeras modificaciones
Lo primero que tenemos que modificar son las distancias de las coordenadas que estan puestas en «<10» al mínimo, que sería «<2«. También sustituir la aleatoriedad «rand(0,1)==0» por algo más útil y comenzar a usar la función «collisionDistance()«.
Como podéis observar en el código inferior, usamos la función «collisionDistance()» para detectar cuando estamos a punto de chocar «collisionDistance() ==1» y para detectar a que lado nos conviene más girar en función de donde podamos recorrer más distancia «if($c->collisionDistance([LEFT]) >2) $c->direction(LEFT); else $c->direction(RIGHT);«.
if($c->direction()==UP && $c->getY()==1 && $c->collisionDistance() ==1){ if($c->collisionDistance([LEFT]) >2) $c->direction(LEFT); else $c->direction(RIGHT); } if($c->direction()==DOWN && MAX_Y-$c->getY()<2 || $c->collisionDistance() ==1){ if($c->collisionDistance([LEFT]) >2) $c->direction(LEFT); else $c->direction(RIGHT); } if($c->direction()==LEFT && $c->getX()==1 && $c->collisionDistance() ==1){ if($c->collisionDistance([UP]) >2) $c->direction(UP); else $c->direction(DOWN); } if($c->direction()==RIGHT && MAX_X-$c->getX()<2 || $c->collisionDistance() ==1){ if($c->collisionDistance([UP]) >2) $c->direction(UP); else $c->direction(DOWN); }
Terminando la faena
El código anterior de por sí no nos resuelve mucho si no afinamos un poco más, comprobando todos las posibles colisiones y tomando la dirección correcta en función de la mayor distancia a recorrer.
if($c->collisionDistance([UP])==1 || $c->collisionDistance() ==1){ if($c->collisionDistance([LEFT]) > $c->collisionDistance([RIGHT])) $c->direction(LEFT); else $c->direction(RIGHT); } if($c->collisionDistance([DOWN])==1 || $c->collisionDistance() ==1){ if($c->collisionDistance([LEFT]) > $c->collisionDistance([RIGHT])) $c->direction(LEFT); else $c->direction(RIGHT); } if($c->collisionDistance([RIGHT])==1 || $c->collisionDistance() ==1){ if($c->collisionDistance([UP]) > $c->collisionDistance([DOWN])) $c->direction(UP); else $c->direction(DOWN); } if($c->collisionDistance([LEFT])==1 || $c->collisionDistance() ==1){ if($c->collisionDistance([UP]) > $c->collisionDistance([DOWN])) $c->direction(UP); else $c->direction(DOWN); }
Código ganador
El código que utilicé yo para ganar a Tron es el siguiente:
function controller(playerController $c){ uno: if($c->direction()==UP && $c->getY()==1 && $c->collisionDistance() ==1){ if($c->collisionDistance([LEFT]) >2) $c->direction(LEFT); else $c->direction(RIGHT); } if($c->direction()==DOWN && MAX_Y-$c->getY()<2 || $c->collisionDistance() ==1){ if($c->collisionDistance([LEFT]) >2) $c->direction(LEFT); else $c->direction(RIGHT); } if($c->direction()==LEFT && $c->getX()==1 && $c->collisionDistance() ==1){ if($c->collisionDistance([UP]) >2) $c->direction(UP); else $c->direction(DOWN); } if($c->direction()==RIGHT && MAX_X-$c->getX()<2 || $c->collisionDistance() ==1){ if($c->collisionDistance([UP]) >2) $c->direction(UP); else $c->direction(DOWN); } dos: if($c->collisionDistance([UP])==1 || $c->collisionDistance() ==1){ if($c->collisionDistance([LEFT]) > $c->collisionDistance([RIGHT])) $c->direction(LEFT); else $c->direction(RIGHT); } if($c->collisionDistance([DOWN])==1 || $c->collisionDistance() ==1){ if($c->collisionDistance([LEFT]) > $c->collisionDistance([RIGHT])) $c->direction(LEFT); else $c->direction(RIGHT); } if($c->collisionDistance([RIGHT])==1 || $c->collisionDistance() ==1){ if($c->collisionDistance([UP]) > $c->collisionDistance([DOWN])) $c->direction(UP); else $c->direction(DOWN); } if($c->collisionDistance([LEFT])==1 || $c->collisionDistance() ==1){ if($c->collisionDistance([UP]) > $c->collisionDistance([DOWN])) $c->direction(UP); else $c->direction(DOWN); } done: }
Mis jugadas ganadoras:
El código no es infalible ya que como comprabaréis vosotros mismos, no se puede ganar siempre por el mero hecho de la aleatoriedad y de la suerte. Cuando dispongais de un código decente, ejecutarlo varias veces para estar seguros antes de desecharlo.
Curiosidades
Como se suele decir, la banca siempre gana, y en este caso no iba a ser menos y es que en caso de empate ¡la banca gana!
Por último deciros que podéis utilizar el código ya que la web detecta los códigos ganadores para que no se repitan.