📜 ⬆️ ⬇️

Search for all possible solutions in the game "Plumbing"

Prehistory

Good day to all. By profession I am a web programmer. Honestly, web programming for me is more of a hobby that brings me income. My other hobbies are Encounter City Extreme.
In short, the point is that you need to go to the game site, get a task in which a place in the city is encrypted, come to this place and solve the riddle left by the game authors. After the solution, you must enter the answer on the site and get the following task. I both play games and organize them.
One day, while surfing the Internet, I stumbled upon the waterplay flash game.
image
After playing a little bit of it, I decided to make this game an assignment for one of the upcoming games.

The essence of the idea

I will not talk here about the intricacies of the work of the Encounter engine, because, as they say, this is a completely different story. I can only say that you can conduct the game without having knowledge of programming. But with the ability to program in JavaScript, you can implement the most unusual ideas.
Initially, the players had an empty net:
image
As the codes were located (they were registered with a marker on the location) and entered on the site, the grid was filled with pipe segments:
image
To move to the next level, it was necessary to open as many segments as possible, assemble a water supply system from them and enter into the engine a sequence of letters located in all segments from the beginning to the end of the water supply system.
image
The code for the next level: AKEZFDMIMQOYGBRZOGJTCSJAUODVYW .
Initially, everything seemed pretty simple in terms of implementation. The problems started when I accidentally found another solution:
image
The code for the next level: AKEZTASWYENBPKRRJAUODVYW .
It turns out how many decisions are unknown, but you need to find all of them and “tell” the game engine all the codes so that when you enter any of them, he takes the players to the next level.

Way out

PHP and MySQL were used as tools. The MySQL database stores information about each grid segment, and the PHP script runs through all possible paths of the “water” through the pipe.
')
Database

In the database table information about the segments is stored as follows:
image

Algorithm

To find all possible solutions, a recursive tube function was written.
<? function tube($x1, $y1, $x2, $y2, $str) { ... } tube(1, 0 , 1, 1, '|0-1|'); ?> 


The first time the function is called, the coordinates of the “crane” are transferred to it, the coordinates of the upper left cell and the line in which initially only the coordinates of the “crane” are '| 0-1 |'.
The function should perform the following tasks:
  1. Check whether the new segment is already in the water supply
     if (strpos($str, '|'.$y2.'-'.$x2.'|')) return; else $str=$str.$y2.'-'.$x2.'|'; 
  2. Check if the pipeline has not reached the grid boundary.
     if ($x2==10 || $x2==0 || $y2==0) return; if ($y2==9 && $x2<9) $err = return; 
  3. Check whether the water supply system has reached the target cell (in our case, the coordinates of this grid are 9-9) and, if a solution is found, output it
     if ($y2==9 && $x2==9) $str.'<br>'; 
  4. If the water supply system has not rested against the grid boundary and a solution is not found, the function should determine which segments can be next in the water supply system and call itself for each of the “possible” segments.
    At this point, we dwell in more detail. First of all, you need to know what type of new segment (“knee” or “straight”). To do this, refer to our database:
     $result=$dbh->query('SELECT type FROM tube WHERE (x='.$x2.') AND (y='.$y2.')'); $row = $result->fetch(PDO::FETCH_ASSOC); 

    If the type of the new “knee” segment, then depending on where the water supply system came from, the following scenarios are possible:
    • Water came from above or below, it can only go left or right.
    • Water came on the left or on the right; it can only go up or down.

    In code, it looks like this:
     if ($row['type']==1) { if ($y1!=$y2) { tube($x2, $y2, $x2-1, $y2, $str); tube($x2, $y2, $x2+1, $y2, $str); } if ($x1!=$x2) { tube($x2, $y2, $x2, $y2-1, $str); tube($x2, $y2, $x2, $y2+1, $str); } } 

    If the type of the new segment is not “knee” (that is, “straight”), then again, depending on where the water supply system came from, the following scenarios are possible:
    • Water came from above, it can only go down.
    • Water came from the bottom, can only go up.
    • Water came on the left, can only go to the right.
    • Water came on the right, can only go to the left.

    Code:
     else { if ($y1<$y2) tube($x2, $y2, $x2, $y2+1, $str); if ($y1>$y2) tube($x2, $y2, $x2, $y2-1, $str); if ($x1<$x2) tube($x2, $y2, $x2+1, $y2, $str); if ($x1>$x2) tube($x2, $y2, $x2-1, $y2, $str); } 

That's all. It remains only to supplement the function with code, which, when finding the solution to the problem, will constitute a letter code to go to the next level:
  if ($y2==9 && $x2==9) { $mass = explode('|', $str); $answer = ''; for ($i=0; $i<count($mass)-1; $i++) { if ($mass[$i]!='' && $mass[$i]!='0-1' && $mass[$i]!='9-9') { $koor = explode('-', $mass[$i]); $result=$dbh->query('SELECT lit FROM tube WHERE (y='.$koor[0].') AND (x='.$koor[1].')'); $row = $result->fetch(PDO::FETCH_ASSOC); $answer=$answer.$row['lit']; } } echo $str.'<br>'.$answer.'<br>'; return; } 

And all together:
 function tube($x1, $y1, $x2, $y2, $str) { if (strpos($str, '|'.$y2.'-'.$x2.'|')) return; else $str=$str.$y2.'-'.$x2.'|'; if ($x2==10 || $x2==0 || $y2==0) return; if ($y2==9 && $x2<9) $err = return; if ($y2==9 && $x2==9) { $mass = explode('|', $str); $answer = ''; for ($i=0; $i<count($mass)-1; $i++) { if ($mass[$i]!='' && $mass[$i]!='0-1' && $mass[$i]!='9-9') { $koor = explode('-', $mass[$i]); $result=$dbh->query('SELECT lit FROM tube WHERE (y='.$koor[0].') AND (x='.$koor[1].')'); $row = $result->fetch(PDO::FETCH_ASSOC); $answer=$answer.$row['lit']; } } echo $str.'<br>'.$answer.'<br>'; return; } $result=$dbh->query('SELECT type FROM tube WHERE (x='.$x2.') AND (y='.$y2.')'); $row = $result->fetch(PDO::FETCH_ASSOC); if ($row['type']==1) { if ($y1!=$y2) { tube($x2, $y2, $x2-1, $y2, $str); tube($x2, $y2, $x2+1, $y2, $str); } if ($x1!=$x2) { tube($x2, $y2, $x2, $y2-1, $str); tube($x2, $y2, $x2, $y2+1, $str); } } else { if ($y1<$y2) tube($x2, $y2, $x2, $y2+1, $str); if ($y1>$y2) tube($x2, $y2, $x2, $y2-1, $str); if ($x1<$x2) tube($x2, $y2, $x2+1, $y2, $str); if ($x1>$x2) tube($x2, $y2, $x2-1, $y2, $str); } } tube(1, 0 , 1, 1, '|0-1|'); 

The result of the script (the first 5 of 39 solutions to the problem):

 |0-1|1-1|1-2|1-3|2-3|2-2|2-1|3-1|4-1|4-2|3-2|3-3|4-3|5-3|5-2|5-1|6-1|7-1|7-2|7-3|8-3|8-4|8-5|8-6|7-6|6-6|6-7|5-7|5-6|4-6|4-7|4-8|5-8|5-9|6-9|7-9|7-8|8-8|8-9|9-9| AKEZFDMIMHYENQOUWIXBZIUAJSCZOGJTQYLVYW |0-1|1-1|1-2|1-3|2-3|2-2|2-1|3-1|4-1|4-2|3-2|3-3|4-3|5-3|5-2|5-1|6-1|7-1|7-2|7-3|8-3|8-4|8-5|8-6|7-6|6-6|6-7|7-7|7-8|8-8|8-9|9-9| AKEZFDMIMHYENQOUWIXBZIUAJSDVYW |0-1|1-1|1-2|1-3|2-3|2-2|2-1|3-1|4-1|4-2|3-2|3-3|4-3|5-3|5-4|4-4|4-5|3-5|3-6|2-6|2-7|1-7|1-8|1-9|2-9|3-9|3-8|3-7|4-7|5-7|5-6|6-6|6-7|7-7|7-8|8-8|8-9|9-9| AKEZFDMIMHYENBPKSRONHIGULAHGCZJSDVYW |0-1|1-1|1-2|1-3|2-3|2-2|2-1|3-1|4-1|4-2|3-2|3-3|4-3|5-3|5-4|4-4|4-5|3-5|3-6|2-6|2-7|3-7|3-8|3-9|4-9|5-9|5-8|4-8|4-7|4-6|5-6|5-7|6-7|6-6|7-6|8-6|8-7|7-7|7-8|8-8|8-9|9-9| AKEZFDMIMHYENBPKSRONHALPQTJGOZCSJAUODVYW |0-1|1-1|1-2|1-3|2-3|2-2|2-1|3-1|4-1|4-2|3-2|3-3|4-3|5-3|5-4|4-4|4-5|3-5|3-6|4-6|4-7|4-8|5-8|5-7|6-7|6-6|7-6|8-6|8-7|7-7|7-8|8-8|8-9|9-9| AKEZFDMIMHYENBPKSROGJTCSJAUODVYW 


Thank you all for your attention.

Source: https://habr.com/ru/post/158059/


All Articles