Location: PHPKode > scripts > PHP Mud Names > php-mud-names/mudnames.php
<?php
/**
 *  This code was inspired by MudNames by Ragnar Hojland Espinosa. <ragnar (at) ragnar-hojland (dot) com>
 *  This php version was written by Xrogaan. <guru (at) xrogaan (dot) be>
 *
 * @author xrogaan <xrogaan - gmail - com> (c) 2009
 * @license http://opensource.org/licenses/mit-license.php MIT license
 * @version 1.2
 * 
 * 
 */

class mudnames_dico {

	protected $particle = array(
		'PRE' => 'P',  'MID' => 'M',  'SUF'  => 'S',
		'NOUN' => 'N', 'ADJ' => 'A',  'NADJ' => 'X',
	);

	/**
	 * Capacitées : associations des parties de nom disponible.
	 */
	protected $caplist = array(
		"PS", "PMS", "PM", "N", "X",
		"NA", "XA" , "NX"
	);
	
	protected $capabilities = array();
	
	protected $file;
	protected $directory;
	protected $forcedcap;
	protected $file_particles;
	public $debug;
	
	/**
	 * Va charger le contenu du dictionnaire de nom '$file', classifier ses différentes parties ($particles)
	 * dans $file_particles et va détecter des différentes capacités du dictionnaire de nom (association possible
	 * de différentes parties).
	 *
	 *
	 */
	function __construct($file, $directory = './data/') {
		$this->file = $file;
		$this->directory = realpath($directory) . '/';
		
		if (!file_exists($this->directory . $this->file)) {
			trigger_error('File <em>'.$this->directory . $this->file.'</em> not found',E_USER_ERROR);
		}

		$handle = fopen($this->directory . $this->file,'r');

		if ($handle) {
			$line = 0;
			while (!feof($handle))
			{
				$line++;
				$buffer = fgets($handle, 4096);

				if (strpos($buffer,'#') === 0) {
					$current_part = str_replace(array("\n",'#'),'',$buffer);
					if (array_key_exists($current_part,$this->particle)) {
						$this->file_particles[$current_part] = array();
					} else {
						trigger_error ($this->directory.$this->file . ":$line: Unknow particle '$current_part'.",E_USER_WARNING);
					}
				}
				elseif (strlen($buffer) > 1 && strpos($buffer,'-----') === false)
					$this->file_particles[$current_part][] = str_replace("\n",'',$buffer);
				elseif (strlen($buffer) === 1)
					continue;

			}
			fclose($handle);
			
		}
		
		$check_particle = array_keys($this->file_particles);
		foreach($check_particle as $k => $v) { $check_particle[$k] = self::pfull2lite($v); }
		$parts = implode('',$check_particle);
		// génère un liste de capacité selon les différentes parties de nom présente dans le fichier
		foreach ($this->caplist as $capability)
		{
			if (strpos($parts, $capability) !== false) {
				$this->capabilities[] = $capability;
			}
		}
	}
	
	/**
	 * Détecte si un fichier doit avoir une génération statique de noms.
	 */
	function force_capability($cap) {
		if (in_array($cap,$this->capabilities)) {
			$this->currentcap = $cap;
			$this->forcedcap = true;
			return true;
		}
		return false;
	}
	
	/**
	 * Sélectionne une association de capacité de façons aléatoire et la retourne.
	 */
	public function select_capability() {
		
		self::check_cap_file();
		
		// If a forced capability exists, we apply it.
		if (!empty($this->forced_capability)) {
			foreach ($this->forced_capability as $fnct => $args) {
				if ($fnct == 'void') {
					self::force_capability($args);
				} else {
					call_user_func_array(array($this,$fnct),$args);
				}
			}
		}

		if (!$this->forcedcap) {
			if (count($this->capabilities)>1) {
				$this->currentcap = $this->capabilities[mt_rand(0, count($this->capabilities) - 1)];
			} elseif (count($this->capabilities) == 1) {
				$this->currentcap = $this->capabilities[0];
			} else {
				trigger_error ($this->directory.$this->file . ":select_capability: No capability found.",E_USER_WARNING);
			}
		}
		
		return $this->currentcap;
	}
	
	/**
	 * Vérifie si un fichier .cap est présent pour le dictionnaire chargé dans l'objet.
	 *
	 * Si un tel fichier existe, cette fonction charge les actions prédéterminées du fichier.
	 * le .cap sert en général a forcer la capacité du dictionnaire.
	 */
	private function check_cap_file() {
		if (file_exists($this->directory . $this->file . '.cap')) {
			
			$this->forced_cap = true;
			$handle = fopen($this->directory . $this->file . '.cap','r');

			if ($handle) {
				while (!feof($handle))
				{
					$buffer = fgets($handle, 4096);

					if (!empty($buffer))
					{
						if (ctype_lower($buffer[0])) {
							list($function, $args) = explode(':',$buffer);
						} else {
							$function = 'void';
							$args = $buffer;
						}

						if ($function != 'void' && !method_exists($this,$function)) {
							trigger_error('Method `<em>'.$function.'</em>` does\'nt exists',E_USER_WARNING);
						} else {
							$this->forced_capability[$function] = explode(',',str_replace("\n",'',trim($args)));
						}

					}
				} // -- end while
				fclose($handle);
			} // -- end if
			return true;
		} else {
			return false;
		}
	}
	
	/**
	 * Sors une partie de nom aléatoire selon le tag et le fichier associé.
	 */
	public function random_particle_from($particle) {
		if (!isset($this->file_particles[$particle]))
			trigger_error ($this->directory.$this->file . ":load_random_particle: Unknow particle '$particle'.",E_USER_WARNING);
		
		if (empty($this->file_particles[$particle]))
			return '';
		
		do {
			$randomId = rand(0,count($this->file_particles[$particle])-1);
			if (isset($this->file_particles[$particle][$randomId]))
				break;
		} while(1);
		
		$this->debug['particles_used'][$particle] = $this->file_particles[$particle][$randomId];
		
		return $this->file_particles[$particle][$randomId];
		
	}
	
	/**
	 * retourne la liste des parties présente dans le fichier dictionnaire
	 *
	 * @return array
	 */
	public function get_file_particle_list() {
		return array_keys($this->file_particles);
	}
	
	public function get_file_capability_list() {
		return $this->capabilities;
	}
	
	public function toString() {
		return $this->file;
	}
	
	/**
	 * Retourne la version courte d'un tag
	 */
	public function pfull2lite($par) {
		return $this->particle[$par];
	}

	/**
	 * Retourne la version longue d'un tag
	 */
	public function plite2full($par) {
		return array_search($par,$this->particle);
	}
	
	public function is_forced() {
		return $this->forcedcap;
	}
}

class mudnames {
	private $directory;
	private $files = array();
	private $dictionnary;
	private $particle_used = array();
	private $capability;
	
	private $info = array(
		'dictionnaries' => '',
		'particles_used' => array(),
		'capability' => '',
		'is_forced' => false,
	);
	
	function __construct($directory = './data') {
		$this->directory = realpath($directory) . '/';
		
		if ( !$dir = opendir($this->directory))
			return false;
		$r = array();

		while (($file = readdir($dir)) !== false) {

			// On ignore les fichiers caché et les fichier de capacités
			if ($file[0] == '.' || substr($file,-4) == '.cap') {
				continue;
			}

			if (is_file($this->directory.$file)) {
				$this->files[] = $file;
			}
		}
		sort($this->files);
	}
	
	public function generate_name_from($file='') {
		if (empty($file) || $file == "random") {
			$file = $this->files[rand(0,count($this->files)-1)];
		} else {
			if (!in_array($file,$this->files)) {
				trigger_error('file '.$file." doesn't exists", E_USER_ERROR);
			}
		}
		
		$this->info['dictionnaries'][] = $file;
		$this->current_file = $file;
		
		$this->dictionnary[$file] = new mudnames_dico($file);
		
		$current_cap = $this->dictionnary[$file]->select_capability();
		
		switch ($current_cap) {
			case 'N':
				$capability = 'NN';
				break;
			case 'X':
				$capability = 'XX';
				break;
			case 'XA':
				$capability = 'N' . (mt_rand(0,1) ? 'A' : 'X' );
				break;
			case 'NX':
				$capability = (mt_rand(0, 1) ? 'N' : 'A') . 'A';
				break;
			default:
				$capability = $current_cap;
		}
		
		$this->info['capability'][$file] = $capability;
		
		$name = '';
		for ($i = 0, $len = strlen($capability); $i < $len; $i++) {
			$particle = $this->dictionnary[$file]->plite2full($capability[$i]);
			$this->info['particles_used'][] = $particle;
			$name.= $this->dictionnary[$file]->random_particle_from($particle);
		}

		return ucfirst($name);
	}
	
	/**
	 * for debug purpose
	 */
	public function get_info($tag) {
		$tag = strtr($tag,' ','_');
		switch ($tag) {
			case 'file_used':
				$tag = 'dictionnaries';
			case 'capability':
				return $this->info['capability'][$this->current_file];
				break;
			case 'is_forced':
				return $this->dictionnary[$this->current_file]->is_forced();
				break;
			case 'capability_list':
				return implode(', ', $this->dictionnary[$this->current_file]->get_file_capability_list());
				break;
			case 'particles_used':
				return $this->dictionnary[$this->current_file]->debug['particles_used'];
			default:
				return "info not found";
		}
	}
	
	public function get_file_list() {
		return $this->files;
	}
}
Return current item: PHP Mud Names