php 人造迷宫 可刷新运行 刷新

生成小蝌蚪找妈妈路线。。。

代码:

<?php

$n=29;
$positions=[];
for ($i=0;$i<=$n;$i++){
    for ($j=0;$j<=$n;$j++){
        $positions[] =[$j,$i] ;
    }
}

//开始的点
$startDot=[0,0];
//已经放置的点
$placedDot=[];
//不可放置的点
$notPlacedDot=notPlacedDot($positions,$n);
$placedDot[]=$startDot;



//所有穿过的点
$lineDot=line($positions,$startDot,$placedDot,$notPlacedDot,$n);

echo getHtml($positions,$lineDot,$n);


function line($positions,$startDot,$placedDot,$notPlacedDot,$n){
    
    $dotWrapper=GetDotWrappers($startDot);
    $key=rand(0,3);
    $nextDot =  $dotWrapper[$key];

    $i=0;
    $notPlacedDotAll =array_merge($notPlacedDot,[]);
    while (in_array($nextDot,$placedDot)||in_array($nextDot,$notPlacedDotAll)){

        $i++;
       if(badDot($nextDot,$placedDot,$notPlacedDot,$n)){//是否是坏点

           $notPlacedDotAll[]=$nextDot;

          $startDot=$placedDot[count($placedDot)-1];
           $dotWrapper=GetDotWrappers($startDot);
           $key=rand(0,3);
           $nextDot =  $dotWrapper[$key];

          if(badDot($startDot,$placedDot,$notPlacedDotAll,$n)){//本身是否是坏点
              $notPlacedDotAll[]= array_pop($placedDot);

              $startDot=$placedDot[count($placedDot)-1];
              $dotWrapper=GetDotWrappers($startDot);
              $key=rand(0,3);
              $nextDot =  $dotWrapper[$key];

          }

        }else{
            $key=rand(0,3);
            $nextDot =  $dotWrapper[$key];

        }
        if($i>4&&count($placedDot)>1){//循环大于3次 还没找到去除该点
            $i=0;
            $notPlacedDot[]= array_pop($placedDot);
            $startDot=$placedDot[count($placedDot)-1];
            $dotWrapper=GetDotWrappers($startDot);
            $key=rand(0,3);
            $nextDot =  $dotWrapper[$key];


        }

    }


    $placedDot[]=$nextDot;

   if($nextDot[0]>=$n&&$nextDot[1]>0&&$nextDot[1]<=$n){
       return $placedDot;
   }
   return line($positions,$nextDot,$placedDot,$notPlacedDot,$n);
}

function getHtml($positions,$lineDot,$n){
    $str="<table border='1'>";

    foreach (array_chunk($positions,$n+1) as $row){
        $str.="<tr>";
        foreach ($row as $tr){
            if(in_array($tr,$lineDot)){
                $str.="<td style='color: white;background-color: red'> {$tr[0]},{$tr[1]}</td>";
            }else{
                $str.="<td>{$tr[0]},{$tr[1]}</td>";
            }
        }
        $str.="<tr>";

    };
    $str.="</table>";
    return $str;
}

function notPlacedDot($positions,$n)
{
    
    $notPlacedDot=[];
    foreach ($positions as $position){
        $dotWrapper=GetDotWrappers($position);

        foreach ($dotWrapper as $dot){
            if($dot[0]<0||$dot[1]<0||$dot[0]>$n||$dot[1]>$n){
                $notPlacedDot[]=$dot;
            }
        }
    }
    return $notPlacedDot;
}

/**
 * 是否是坏点
 * @param $dotWrapper
 * @param $placedDot
 * @param $notPlacedDot
 * @return bool
 */
function badDot($position,$placedDot,$notPlacedDot,$n){
    
    $dotWrapper=GetDotWrappers($position);
    $i=0;
    foreach ($dotWrapper as $dot){
        if($dot[0]<0||$dot[1]<0||$dot[1]>$n||in_array($dot,$placedDot)||in_array($dot,$notPlacedDot)){
            $i++;
        }
    }
    if($i==4){
        return true;
    }
    return false;

}


function GetDotWrappers($placementEd){
    $top = calculateXY($placementEd[0],$placementEd[1],'top');
    $bottom = calculateXY($placementEd[0],$placementEd[1],'bottom');
    $left = calculateXY($placementEd[0],$placementEd[1],'left');
    $right = calculateXY($placementEd[0],$placementEd[1],'right');
    return [$top,$bottom,$left,$right];
}

function calculateXY($x,$y,$default='top')
{
    switch ($default){
        case 'top':
            $y=$y+1;
            break;
        case 'bottom':
            $y=$y-1;
            break;
        case 'left':
            $x=$x-1;
            break;
        case 'right':
            $x=($x+1);
            break;
        case 'left_top':
            $x=($x-1);
            $y=($y+1);
            break;
        case 'right_top':
            $x=($x+1);
            $y=($y+1);
            break;
        case 'right_bottom':
            $x=($x+1);
            $y=($y-1);
            break;
        case 'left_bottom':
            $x=($x-1);
            $y=($y-1);
            break;
    }

    return [$x,$y];
}

输出:

0,0 1,0 2,0 3,0 4,0 5,0 6,0 7,0 8,0 9,0 10,0 11,0 12,0 13,0 14,015,016,017,018,019,020,021,022,023,024,025,026,027,028,029,0
0,11,1 2,1 3,1 4,1 5,1 6,1 7,18,19,110,111,1 12,1 13,1 14,115,116,117,118,119,120,121,122,123,124,125,126,127,128,129,1
0,21,2 2,2 3,2 4,2 5,2 6,2 7,2 8,2 9,210,2 11,2 12,213,2 14,215,216,217,218,219,220,221,222,223,224,225,226,227,228,229,2
0,31,32,3 3,3 4,35,3 6,3 7,3 8,3 9,310,3 11,3 12,3 13,3 14,315,316,317,318,319,320,321,322,323,324,325,326,327,328,329,3
0,4 1,4 2,4 3,44,45,4 6,47,4 8,4 9,410,4 11,4 12,4 13,414,415,416,417,418,419,420,421,422,423,424,425,426,427,428,429,4
0,5 1,5 2,5 3,5 4,5 5,5 6,57,58,59,5 10,5 11,512,513,514,515,516,517,518,519,520,521,522,523,524,525,526,527,528,529,5
0,6 1,6 2,6 3,6 4,6 5,6 6,67,68,69,6 10,611,612,6 13,6 14,615,616,617,618,619,620,621,622,623,624,625,626,627,628,629,6
0,7 1,7 2,7 3,7 4,7 5,7 6,77,78,79,7 10,7 11,7 12,7 13,7 14,715,7 16,7 17,718,719,720,721,722,723,724,725,726,727,728,729,7
0,8 1,82,83,84,85,8 6,87,8 8,8 9,8 10,811,8 12,8 13,8 14,8 15,8 16,8 17,818,819,820,821,822,823,824,825,826,827,828,829,8
0,91,92,9 3,9 4,9 5,9 6,9 7,9 8,99,9 10,911,912,913,914,915,9 16,9 17,918,919,920,921,922,923,924,925,926,927,928,929,9
0,101,102,10 3,104,10 5,10 6,10 7,10 8,10 9,10 10,1011,1012,1013,10 14,10 15,10 16,10 17,10 18,1019,1020,1021,1022,1023,1024,1025,1026,1027,1028,1029,10
0,11 1,11 2,11 3,114,11 5,11 6,11 7,11 8,11 9,1110,1111,1112,1113,11 14,11 15,1116,11 17,11 18,1119,1120,1121,1122,1123,1124,1125,1126,1127,1128,1129,11
0,12 1,12 2,12 3,12 4,12 5,126,127,128,12 9,1210,1211,1212,1213,1214,12 15,12 16,12 17,12 18,12 19,1220,1221,1222,1223,1224,1225,1226,1227,1228,1229,12
0,131,132,13 3,13 4,135,136,137,138,13 9,1310,1311,1312,1313,1314,1315,13 16,13 17,1318,13 19,13 20,1321,1322,1323,1324,1325,1326,1327,1328,1329,13
0,14 1,14 2,143,144,145,146,147,148,14 9,1410,1411,1412,1413,1414,1415,1416,1417,1418,1419,14 20,14 21,1422,1423,1424,1425,1426,1427,1428,1429,14
0,15 1,15 2,153,154,155,156,157,158,15 9,1510,1511,1512,1513,1514,1515,1516,1517,1518,1519,1520,15 21,1522,1523,1524,1525,1526,1527,15 28,15 29,15
0,16 1,16 2,163,164,165,166,167,168,16 9,1610,1611,1612,1613,1614,1615,1616,1617,1618,1619,1620,16 21,16 22,1623,1624,1625,1626,16 27,16 28,1629,16
0,17 1,17 2,173,174,175,176,177,17 8,17 9,1710,1711,1712,1713,1714,1715,1716,1717,1718,17 19,17 20,17 21,17 22,1723,1724,17 25,17 26,17 27,17 28,1729,17
0,181,18 2,183,18 4,18 5,18 6,18 7,18 8,189,1810,1811,1812,1813,1814,1815,1816,1817,1818,18 19,1820,1821,1822,18 23,18 24,18 25,18 26,1827,18 28,1829,18
0,191,19 2,19 3,19 4,19 5,196,197,198,199,1910,1911,1912,1913,1914,1915,1916,1917,1918,19 19,1920,1921,1922,19 23,19 24,19 25,19 26,1927,19 28,1929,19
0,201,202,20 3,204,20 5,206,207,208,209,2010,2011,2012,2013,2014,2015,2016,2017,2018,20 19,2020,2021,2022,2023,20 24,20 25,20 26,20 27,20 28,2029,20
0,211,212,21 3,21 4,21 5,216,217,218,219,2110,2111,2112,2113,2114,2115,2116,2117,2118,21 19,2120,2121,2122,21 23,21 24,2125,2126,2127,2128,2129,21
0,221,222,223,224,225,226,227,228,229,2210,2211,2212,2213,2214,2215,2216,22 17,22 18,22 19,2220,2221,2222,22 23,2224,2225,2226,2227,2228,2229,22
0,231,232,233,234,235,236,237,238,239,2310,2311,2312,2313,2314,2315,2316,23 17,2318,2319,2320,2321,2322,23 23,23 24,23 25,2326,2327,2328,2329,23
0,241,242,243,244,245,246,247,248,249,2410,2411,2412,2413,2414,2415,24 16,24 17,2418,2419,2420,2421,2422,2423,2424,24 25,2426,2427,2428,2429,24
0,251,252,253,254,255,256,257,258,259,2510,2511,2512,2513,2514,2515,25 16,25 17,2518,2519,2520,2521,2522,25 23,25 24,25 25,2526,2527,2528,2529,25
0,261,262,263,264,265,266,267,268,269,2610,2611,2612,2613,2614,2615,2616,26 17,26 18,2619,2620,2621,26 22,26 23,26 24,26 25,2626,2627,2628,2629,26
0,271,272,273,274,275,276,277,278,279,2710,2711,2712,2713,2714,2715,2716,2717,27 18,2719,2720,27 21,27 22,2723,2724,2725,2726,2727,2728,2729,27
0,281,282,283,284,285,286,287,288,289,2810,2811,2812,2813,2814,2815,2816,2817,28 18,28 19,28 20,28 21,2822,2823,2824,2825,2826,2827,2828,2829,28
0,291,292,293,294,295,296,297,298,299,2910,2911,2912,2913,2914,2915,2916,2917,2918,2919,29 20,29 21,2922,2923,2924,2925,2926,2927,2928,2929,29
遇到问题?