From 257e02d25a629a1b6d6fbb133b38b06dcfbc7777 Mon Sep 17 00:00:00 2001 From: Patrick Davison Date: Thu, 21 Apr 2011 12:11:22 -0700 Subject: Support for shaped maps. A lot of additions and changes, specifically regarding how the map is pathed and generated. Removing some assumptions for actual code. --- includes/maps.php | 276 ++++++++++++++++++++++++++++++++++++++++++++++-------- 1 file changed, 238 insertions(+), 38 deletions(-) (limited to 'includes') diff --git a/includes/maps.php b/includes/maps.php index 04bf375..0329e18 100644 --- a/includes/maps.php +++ b/includes/maps.php @@ -1,4 +1,5 @@ "; break; case 'r': $maptable .= ""; break; //rock - case 'q': $maptable .= ""; break; //rock + case 'R': $maptable .= ""; break; //metalic looking rock + + case 'p': $maptable .= ""; break; //path. + case 'q': $maptable .= ""; break; //transparent + case 'w': $maptable .= ""; break; //wall //default: $maptable .= "".$index.""; default: $maptable .= ""; @@ -90,6 +95,7 @@ function DisplayMap($mapMatrix, $idprefix = 1, $example = false, $speed = NULL) + "; @@ -191,6 +197,7 @@ function DisplayMap($mapMatrix, $idprefix = 1, $example = false, $speed = NULL) return $output; } + //Generates map function GenerateMap($rows, $cols, $rockchance, $numBlocks = -1, $cp = -1, $tp = -1) { @@ -292,6 +299,180 @@ function GenerateMap($rows, $cols, $rockchance, $numBlocks = -1, $cp = -1, $tp = return $grid; } +//Generates map based on $shape. +function GenerateShapedMap($shape, $params) { + + //Get width and height. + $cols = strlen($shape[0]); + $rows = count($shape); + + //Scan for checkpoints. + //$checkpoints = 0; + //$cpnames = Array("a", "b", "c", "d", "e"); + //Get the amount of checkpoints on this map. + //foreach ($cpnames as $cpt) + // if (findTiles($mygrid, $cpt)) + // $checkpoints++; + + //Confirm params. + if ($params['rockchance']) + $rockchance = $params['rockchance']; + else + $rockchance = 10; + + if ($params['checkpoints']) + $checkpoints = $params['checkpoints']; + else + $checkpoints = 0; + + if ($params['teleports']) + $teleports = $params['teleports']; + else + $teleports = 0; + + if ($params['walls']) + $walls = $params['walls']; + else + $walls = 13; + + $mapMatrix[0][0] = $cols; + $mapMatrix[0][1] = $rows; + $mapMatrix[0][2] = $checkpoints; + //set after; + $mapMatrix[0][3] = 0; + //walls + $mapMatrix[0][4] = $walls; + $mapMatrix[0][5] = $teleports; + + + do { + $rockcount = 0; + $i = 0; + if (! is_array($shape)) + break; + foreach ($shape as $row) { + $i++; + for( $j = 0; $j < $cols; $j++) { //Number of Columns + $item = substr($row, $j, 1); + if ($item == '?') { + if (rand(1, $rockchance) == 1) { + $item = 'r'; + $rockcount++; + } else { + $item = 'o'; + } + } + $mapMatrix[$i][$j] = $item; + //echo $item; + } + //echo "\n"; + } + $path = routePath($mapMatrix); + //echo $path['blocked']."\n"; + //Only repeat if it's blocked. + } while ($path['blocked'] == true); + + //Set rockcount. + $mapMatrix[0][3] = $rockcount; + + //print_r ($mapMatrix); + return $mapMatrix; +} + +//Inserts a point into a shape-array. +function insertPoint($array, $new, $target = '?') { + //Replaces a random element in $array that matches $target with $new, + // if $new is a single character. + //If $new is a string, replace a random element for each of $new's characters. + + /* + Snap - "the goal is to turn something like: + $mymap = Array("s??????f". "s???????f") + // into; Array("s???a??f", "s???b???f") + after a couple calls to the function." + */ + + //Getting $array parameters + $rows = count($array); + $length = strlen($array[0]); + $size = $rows * $length; + + //Retrieving all cells == $target from $array + //This is more memory intensive, and probably more CPU-so, but far more safe. + $targetCells = array(); + + for( $i = 0; $i < $size; $i++) + { + $y = $i % $length; //Get coordinates based on $index + $x = (int)($i / $length); + + //echo "
index: $i y: $y, x: $x
"; + //echo $array[$x][$y]; + if($array[$x][$y] == $target) + $targetCells[] = $i; + } + + //Now that we have a definite selection of cells, we can pick easily with + // the only caveat being if there aren't enough $target cells. + + if(strlen($new) > $length) + { + //There are too many replace requests and not enough free cells. + echo "Too many $new characters. No replacements made.
"; + return $array; + } + + //Debug to see what indexes were selected as == $target + /* + echo "array = "; + print_r($array); + echo "
"; + echo "targetCells = "; + print_r($targetCells); + echo "
"; + echo "
"; + */ + + while(strlen($new) > 0) + { + $length = count($targetCells); + $indexReplace = rand(0, $length - 1); //Get a random position in $targetCells + $indexTarget = $targetCells[$indexReplace]; //Get the index stored in $targetCells + + $y = $indexTarget % strlen($array[0]); //Get coordinates based on $index + $x = (int)($indexTarget / strlen($array[0])); + + if($array[$x][$y] == $target) //Shouldn't be necessary, but just in case... + { + $array[$x][$y] = $new[0]; //We've found a valid target. Replace. + $new = substr($new, 1); //Go to the next $new character. + + unset($targetCells[$indexReplace]); //Remove the selected $targetCell. + $targetCells = array_values($targetCells); //Reorder the array for no holes. + + continue; + } + else + { + //Somehow an invalid target got into our list of valid targets... + echo "
"; + echo "Error in selecting $indexTarget ($x,$y). Replacement stopped on $new[0].
"; + echo "indexTarget = $indextarget
"; + echo "indexReplace = $indexReplace
"; + + echo "array = "; + print_r($array); + echo "
"; + echo "targetCells = "; + print_r($targetCells); + echo "
"; + echo "
"; + return $array; + } + } + + return $array; +} //Turns a mapMatrix into a code - see GenerateMapByCode function GenerateMapCode($mapMatrix) { @@ -396,7 +577,6 @@ function GenerateMapByCode($code) { return $mapMatrix; } - //Returns a mapMatrix merged with a solution/maze. function MergeMapSolution($mapMatrix, $solution) { //echo $solution; @@ -484,6 +664,7 @@ function pastMap($maptype, $daysago) { } function findTiles ($mapMatrix, $search) { + //print_r ($mapMatrix); for( $i = 1; $i <= $mapMatrix[0][1]; $i++) { //Number of Rows for( $j = 0; $j < $mapMatrix[0][0]; $j++) { //Number of Columns if ($mapMatrix[$i][$j] == $search) @@ -513,45 +694,46 @@ function findPath($mapMatrix, $start = '0,1.', $target = 'f') { $y = $v[1]; //Create a handle on the squares around it. switch($i){ - case 1: $y--; break; //up - case 2: $x++; break; //right - case 3: $y++; break; //down - case 4: $x--; break; //left + case 1: $y--; break; //up + case 2: $x++; break; //right + case 3: $y++; break; //down + case 4: $x--; break; //left } if ($y < 1 OR $x < 0) continue 1; //What's there? switch($mapMatrix[$y][$x]) { - case $target: //Finishline! - //Our search is over. - $r['blocked'] = false; - $r['path'] = $seed[$key][3].$i; - $r['start'] = $v[2]; - $r['end'] = "$x,$y"; - return $r; + case $target: //Finishline! + //Our search is over. + $r['blocked'] = false; + $r['path'] = $seed[$key][3].$i; + $r['start'] = $v[2]; + $r['end'] = "$x,$y"; + return $r; break; - // Teleports m t g i k - case "m": case "t": case "g": case "i": case "k": - $path = $mapMatrix[$y][$x]; - - case "o": //Available squares - //!! - case "s": case "f": //Start and end tiles + // Teleports m t g i k + case "m": case "t": case "g": case "i": case "k": + $path = $mapMatrix[$y][$x]; - case "a": case "b": case "c": case "d": case "e": //Checkpoints too - case "u": case "n": case "h": case "j": case "l": //Teleport-out towers included! - //Plant Seed here - $seed[$index][0] = $x; - $seed[$index][1] = $y; - //Save our starting position. - $seed[$index][2] = $v[2]; - //Save 'PATH' - $path = $i.$path; - $seed[$index][3] = $v[3].$path; - $path = ''; - //Been there, done that. - $mapMatrix[$y][$x] = null; - //Move index - $index++; + case "o": //Available squares + //!! + case "p": + case "s": case "f": //Start and end tiles + + case "a": case "b": case "c": case "d": case "e": //Checkpoints too + case "u": case "n": case "h": case "j": case "l": //Teleport-out towers included! + //Plant Seed here + $seed[$index][0] = $x; + $seed[$index][1] = $y; + //Save our starting position. + $seed[$index][2] = $v[2]; + //Save 'PATH' + $path = $i.$path; + $seed[$index][3] = $v[3].$path; + $path = ''; + //Been there, done that. + $mapMatrix[$y][$x] = null; + //Move index + $index++; break; } @@ -595,12 +777,21 @@ function routePath($mygrid, $start = '') { // } //} $start = findTiles($mygrid, "s"); + + //echo $start; //Checkpoint names $cpnames = Array("a", "b", "c", "d", "e"); - //Get the amount of checkpoints on this map. - $cpcount = $mygrid[0][2]; + //== Relies on the map headers being accurate. + //Get the amount of checkpoints on this map. + //$cpcount = $mygrid[0][2]; + $cpcount = 0; + //Get the amount of checkpoints on this map. + foreach ($cpnames as $cpt) + if (findTiles($mygrid, $cpt)) + $cpcount++; + //Add the existing checkpoints to targets. for($p = 0; $p < $cpcount; $p++) { $target[] = $cpnames[$p]; @@ -614,8 +805,15 @@ function routePath($mygrid, $start = '') { //All possible teleports in play. $tpnames = Array('t', 'm', 'g', 'i', 'k'); + + $tpcount = 0; + foreach ($tpnames as $tpt) + if (findTiles($mygrid, $tpt)) + $tpcount++; + + //$tpcount = intval($mygrid[0][5] * .5); + - $tpcount = intval($mygrid[0][5] * .5); //Add the existing checkpoints to targets. for($p = 0; $p < $tpcount; $p++) { $teleport[] = $tpnames[$p]; @@ -634,6 +832,8 @@ function routePath($mygrid, $start = '') { foreach($target as $t) { //Path from where we are, to the target. $p = Findpath ($mygrid, $start, $t); + //echo "FP: ".$p['path']; + //echo "T: $t"; //It's possible to start from multiple places; //so mark where we ended up starting from. if ($r['start'] == '') -- cgit v1.2.3