InsomniHack-2013/Misc4/TheGame

From Fixme.ch
Jump to: navigation, search

Summary

A popular game amongst survivors is the Rock-Paper-Scissors-Lizard-Spock game. To gain their respect, we strongly encourage you to be the best at this game. This will strengthen your reputation and will attract new citizens. Goal : Beat yout opponent 20 times in a row.

Solution

Other than the pairs involving Rock-Paper-Scissors that you already know about, the other pairs are:

Spock vaporizes Rock
Spock melts Scissors

Paper disapproves Spock
Lizard poinsons Spock

Lizard eats Paper
Lizard poinsons Spock

Rock crushes Lizard
Scissors decapitate Lizard

Each of the 5 choices have 2 others beating it and 2 others losing. In case of draw, the computer wins (unfair!). Thus, there are no choices better than another. After analysis and attempts to find its strategy, the computer's choices seem random, not based on our previous choices. So there must be another signal to look at…

Looking at the packets transmitted with Wireshark, we see the computer answers turns with 2 packets. First packet with the results of the previous turn (or the welcome message before the first turn), second packet with "I've made my choice, what's yours ?". If you compute the elapsed time between those 2 packets, you discover the count of tenths of seconds tells what the computer will play.

Here's a possible solution in PHP:

#!/usr/bin/php
<?php
 
$strategy = array(
  // Tenths of sec => My choice // Computer's choice
  1 => 'Paper',     // Rock
  2 => 'Scissors',  // Paper
  3 => 'Rock',      // Scissors
  4 => 'Scissors',  // Lizard
  5 => 'Paper',     // Spock
);
 
$handle = fsockopen('challenges01.insomni.hack', 9999);
echo fread($handle, 1024);
 
$rounds = 0;
 
while (true) {
  $start = microtime(true);
  echo fread($handle, 1024);
  $stop = microtime(true);
  $think_time = 10 * round($stop - $start, 1);
 
  sleep(1);  // Think hard…
  $my_choice = $strategy[$think_time];
  echo $my_choice, "\n";
  fwrite($handle, $my_choice);
 
  echo fread($handle, 1024);
 
  if (++$rounds == 20) break;
}
 
fclose($handle);
 
?>