static function load(Config $config) { $scenes = new ArrayCollection(); // Start with the entry scene $stack = array(); $scene = $config['entry_scene']; array_push($stack, $scene); // Loop until our stack is empty while (count($stack)) { // Load a scene from the stack $scenePath = array_pop($stack); $data = Yaml::load($config['base_directory'] . '/' . $scenePath . '.yml'); // Create a scene from the data $newScene = new Scene($scenePath, $data); $scenes->set($scenePath, $newScene); // If we have exit-scenes, add them to the stack so we can load them foreach ($data['scene']['exit'] as $direction => $exitScene) { $tmp['exit'][strtolower($direction)] = $exitScene; // Only add to stack when we haven't already processed that scene if (!$scenes->containsKey($exitScene)) { array_push($stack, $exitScene); } } } return $scenes; }
protected function execute(InputInterface $input, OutputInterface $output) { $this->output = $output; $this->input = $input; $dir = $input->getArgument('dir'); // Load main.yml $file = $dir . "/main.yml"; $yaml = Yaml::load($file); $scenes = array(); // Load all scenes $stack = array(); $scene = $yaml['entry_scene']; array_push($stack, $scene); while (count($stack)) { $scene = array_pop($stack); $yaml = Yaml::load($dir . '/' . $scene . '.yml'); $scenes[$scene] = array('key' => $scene, 'title' => $yaml['scene']['title'], 'exit' => array('north' => false, 'east' => false, 'south' => false, 'west' => false)); foreach ($yaml['scene']['exit'] as $direction => $exit_scene) { $scenes[$scene]['exit'][strtolower($direction)] = $exit_scene; if (!array_key_exists($exit_scene, $scenes)) { array_push($stack, $exit_scene); } } } // Validate links foreach ($scenes as $scene) { if (count($scene['exit']) == 0) { throw new \Exception(sprintf("Scene '%s' does not have any exit")); } foreach ($scene['exit'] as $direction => $exit_scene) { if ($exit_scene == false) { continue; } switch ($direction) { case 'north': if ($scenes[$exit_scene]['exit']['south'] != $scene['key']) { throw new \Exception(sprintf("Scene '%s' exit North does match scene '%s' exit South", $scene['key'], $exit_scene)); } break; case 'south': if ($scenes[$exit_scene]['exit']['north'] != $scene['key']) { throw new \Exception(sprintf("Scene '%s' exit South does match scene '%s' exit North", $scene['key'], $exit_scene)); } break; case 'east': if ($scenes[$exit_scene]['exit']['west'] != $scene['key']) { throw new \Exception(sprintf("Scene '%s' exit East does match scene '%s' exit West", $scene['key'], $exit_scene)); } break; case 'west': if ($scenes[$exit_scene]['exit']['east'] != $scene['key']) { throw new \Exception(sprintf("Scene '%s' exit West does match scene '%s' exit East", $scene['key'], $exit_scene)); } break; } } } $scene = reset($scenes); $stack = array(); array_push($stack, array($scene, 0, 0)); $tmp = array(); $tmp['title'] = $scene['title']; $tmp['exit'] = ""; foreach ($scene['exit'] as $d => $e) { if (!$e) { continue; } $tmp['exit'] .= strtoupper($d[0]); } // Add initial scene $a = array(); while (count($stack)) { list($scene, $x, $y) = array_pop($stack); if (!isset($a[$y])) { $a[$y] = array(); } if (isset($a[$y][$x])) { continue; } $dirs = ""; foreach ($scene['exit'] as $dir => $exit) { if ($exit === false) { continue; } switch (strtoupper($dir[0])) { case 'N': $dirs .= "N"; array_push($stack, array($scenes[$exit], $x, $y - 1)); break; case 'E': $dirs .= "E"; array_push($stack, array($scenes[$exit], $x + 1, $y)); break; case 'S': $dirs .= "S"; array_push($stack, array($scenes[$exit], $x, $y + 1)); break; case 'W': $dirs .= "W"; array_push($stack, array($scenes[$exit], $x - 1, $y)); break; } } $a[$y][$x] = array($scene['title'], $dirs); } foreach (array_keys($a) as $k) { ksort($a[$k]); } ksort($a); $max = max(array_map(function ($row) { return count($row); }, $a)); $min = min(array_map(function ($row) { return array_keys($row)[0]; }, $a)); $max = $min + $max; foreach (array_keys($a) as $k) { for ($i = $min; $i != $max; $i++) { if (!isset($a[$k][$i])) { $a[$k][$i] = false; } } ksort($a[$k]); } define('NODE_WIDTH', 30); define('NODE_HEIGHT', 5); define('EDGE_WIDTH', 4); define('EDGE_HEIGHT', 2); $rows = count($a) * (NODE_HEIGHT + EDGE_HEIGHT); $columns = count($a[0]); $buf = array(); for ($i = 0; $i != $rows; $i++) { $buf[] = str_repeat(" ", (NODE_WIDTH + EDGE_WIDTH) * $columns); } $y = 0; foreach ($a as $row) { $x = 0; foreach ($row as $column) { if ($column) { $this->print_node($buf, $x * (NODE_WIDTH + EDGE_WIDTH), $y * (NODE_HEIGHT + EDGE_HEIGHT), $column[0]); for ($i = 0; $i != strlen($column[1]); $i++) { $this->print_edge($buf, $x * (NODE_WIDTH + EDGE_WIDTH), $y * (NODE_HEIGHT + EDGE_HEIGHT), $column[1][$i]); } } $x++; } $y++; } foreach ($buf as $line) { $this->output->writeln("<comment>{$line}</comment>"); } }