練習

もんだい

こんな感じの出力をオブジェクト指向でいい感じに書いてみる

player1:オレは「せんし」。力だけが自慢だ(HP 183/MP 0)
player2:私は「そうりょ」。回復は任せて(HP 152/MP 100)
player3:僕は「ゆうしゃ」。バランス型です(HP 180/MP 50)
player4:オレは「せんし」。力だけが自慢だ(HP 218/MP 0)
player5:私は「そうりょ」。回復は任せて(HP 128/MP 123)
スライムの群れがあらわれた!
player2はスライムに15のダメージを与えた
//ここで任意のplayerをジョブチェンジ
player1:僕は「ゆうしゃ」。バランス型です(HP 160/MP 20)

==

コード

job.php
<?php
//factory method pattern
interface Job {
	public function getJobName();
	public function getSelfAppoint();
	public function getIntroduce();
	public function getAdditionalHp();
	public function getAdditionalMp();
}
class Soldier implements Job{
	var $job_name = 'せんし';
	var $self_appoint = 'オレ';
	var $introduce = '力だけが自慢だ';
	var $additional_hp = 83;
	var $additional_mp = 0;
	public function getJobName(){return $this->job_name;}
	public function getSelfAppoint(){return $this->self_appoint;}
	public function getIntroduce(){return $this->introduce;}
	public function getAdditionalHp(){return $this->additional_hp;}
	public function getAdditionalMp(){return $this->additional_mp;}
}
class Brave implements Job{
	var $job_name = 'ゆうしゃ';
	var $self_appoint = '';
	var $introduce = 'バランス型です';
	var $additional_hp = 60;
	var $additional_mp = 20;
	public function getJobName(){return $this->job_name;}
	public function getSelfAppoint(){return $this->self_appoint;}
	public function getIntroduce(){return $this->introduce;}
	public function getAdditionalHp(){return $this->additional_hp;}
	public function getAdditionalMp(){return $this->additional_mp;}
}
class Monk implements Job{
	var $job_name = 'そうりょ';
	var $self_appoint = '';
	var $introduce = '回復は任せて';
	var $additional_hp = 38;
	var $additional_mp = 80;
	public function getJobName(){return $this->job_name;}
	public function getSelfAppoint(){return $this->self_appoint;}
	public function getIntroduce(){return $this->introduce;}
	public function getAdditionalHp(){return $this->additional_hp;}
	public function getAdditionalMp(){return $this->additional_mp;}
}
class JobFactory {
	public function create ($job) {
		$reader = $this->createReader($job);
		return $reader;
	}
	public function createReader($job) {
		if ($job === 'soldier') {
			return new Soldier;
		} else if ($job === 'brave') {
			return new Brave;
		} else if ($job === 'monk') {
			return new Monk;
		} else {
			die ('JobFactory faild');
		}
	}
}
?>
player.php
<?php
//iterator pattern
interface MyIterator {
	public function hasNext();
	public function getPlayerAt();
}
class Players {
	private $players;
	private $last;
	public function __construct ($max) {
		$this->last = $max;
	}
	public function add (Player $player) {
		$this->players[] = $player;
	}
	public function getCurrent ($index) {
		return $this->players[$index];
	}
	public function getLength () {
		return $this->last;
	}
	public function getIterator() {
		return new PlayersIterator($this);
	}
}
class PlayersIterator implements MyIterator {
	private $players;
	private $index;
	public function __construct (Players $players) {
		$this->players = $players;
		$this->index = 0;
	}
	public function hasNext () {
		if ($this->index < $this->players->getLength()) {
			return true;
		} else {
			return false;
		}
	}
	public function getPlayerAt () {
		$player = $this->players->getCurrent($this->index);
		$this->index++;
		return $player;
	}
	public function getSinglePlayer ($at) {
		$player = $this->players->getCurrent($at);
		return $player;
	}
}
class Player {
	var $name;
	var $player_hp;
	var $player_mp;
	var $player_job;
	public function __construct ($name, $player_hp, $player_mp, $player_job) {
		$this->name = $name;
		$this->player_hp = $player_hp;
		$this->player_mp = $player_mp;
		$this->player_job = $player_job;
	}
	public function getName () {
		return $this->name;
	}
	public function getPlayerHp () {
		return $this->player_hp;
	}
	public function getPlayerMp () {
		return $this->player_mp;
	}
	public function getPlayerJob () {
		return $this->player_job;
	}
	public function setPlayerJob ($job) {
		$this->player_job = $job;
	}
}
?>
quest.php
<?php
require_once('job.php');
require_once('player.php');
?>
<?php
//singleton pattern
class Quest {
	private $players;
	private $factory;
	private $iterator;
	private static $instance;

	private function __construct () {
		$this->players = new Players(5);
		$this->players->add(new Player('player1', 100 ,0, 'soldier'));
		$this->players->add(new Player('player2', 114 ,20, 'monk'));
		$this->players->add(new Player('player3', 120 , 30, 'brave'));
		$this->players->add(new Player('player4', 135 ,0, 'soldier'));
		$this->players->add(new Player('player5', 90, 43, 'monk'));

		$this->iterator = $this->players->getIterator();
		$this->factory = new JobFactory();
	}
	public static function getQuest () {
		if (!isset(self::$instance)) {
			self::$instance =  new Quest();
		}
		return self::$instance;
	}
	public final function __clone () {
		throw new RuntimeException ('Clone is not allowed against'.get_class($this));
	}
	public function culculateStatus ($player_hp, $player_mp, $job_hp, $job_mp) {
		$status = array (
			'hp' => $player_hp + $job_hp,
			'mp' => $player_mp + $job_mp,
		);
		return $status;
	}
	public function jobChange ($at, $job) {
		$player = $this->iterator->getSinglePlayer($at);
		$player->setPlayerJob($job);
		$player = $this->iterator->getSinglePlayer($at);
		$changed_player = array();
		$changed_player['name'] = $player->getName();
		$changed_player['hp'] = $player->getPlayerHp();
		$changed_player['mp'] = $player->getPlayerMp();
		$changed_player['job'] = $player->getPlayerJob();
		return $changed_player;
	}
	public function runPlayer () {
		$player_param = array();
		$i = 0;
		while($this->iterator->hasNext()) {
			$player = $this->iterator->getPlayerAt();
			$player_param[$i]['name'] = $player->getName();
			$player_param[$i]['hp'] = $player->getPlayerHp();
			$player_param[$i]['mp'] = $player->getPlayerMp();
			$player_param[$i]['job'] = $player->getPlayerJob();
			$i++;
		}
		return $player_param;
	}
	public function runJob ($player_job) {
		$job_param = array();
		$job = $this->factory->create($player_job);
		$job_param['name'] = $job->getJobName();
		$job_param['self_appoint'] = $job->getSelfAppoint();
		$job_param['introduce'] = $job->getIntroduce();
		$job_param['hp'] = $job->getAdditionalHp();
		$job_param['mp'] = $job->getAdditionalMp();
		return $job_param;
	}
	public function tatakau () {
		$attack_player = $this->iterator->getSinglePlayer(1);
		return  $attack_player->getName().'はスライムに15のダメージを与えた'.PHP_EOL;
	}
}
?>
run.php
<?php
require_once('quest.php');
?>
<?php
$quest = Quest::getQuest();
$player = $quest->runPlayer();
foreach($player as $key => $play) {
	$job = $quest->runJob($play['job']);
	$status = $quest->culculateStatus($play['hp'], $play['mp'], $job['hp'], $job['mp']);
	echo $play['name'].':'.$job['self_appoint'].'は「'.$job['name'].'」。'.$job['introduce'].'(HP '.$status['hp'].'/MP '.$status['mp'].')'.PHP_EOL;
}

sleep(1);
echo 'スライムの群れがあらわれた!'.PHP_EOL;
echo $quest->tatakau();
sleep(1);

$changed_player = $quest->jobChange(0, 'brave');
$changed_job = $quest->runJob($changed_player['job']);
$status = $quest->culculateStatus($changed_player['hp'], $changed_player['mp'], $changed_job['hp'], $changed_job['mp']);
echo $changed_player['name'].':'.$changed_job['self_appoint'].'は「'.$changed_job['name'].'」。'.$changed_job['introduce'].'(HP '.$status['hp'].'/MP '.$status['mp'].')'.PHP_EOL;

/*
-----------output-----------
player1:オレは「せんし」。力だけが自慢だ(HP 183/MP 0)
player2:私は「そうりょ」。回復は任せて(HP 152/MP 100)
player3:僕は「ゆうしゃ」。バランス型です(HP 180/MP 50)
player4:オレは「せんし」。力だけが自慢だ(HP 218/MP 0)
player5:私は「そうりょ」。回復は任せて(HP 128/MP 123)
スライムの群れがあらわれた!
player2はスライムに15のダメージを与えた
player1:僕は「ゆうしゃ」。バランス型です(HP 160/MP 20)
?>

==

感想とか

オブジェクト指向というかデザインパターンの練習でした(factory method,iterator,singleton)。
1日つぶれたお。どこでどこまで書くかがとても難しい。jobはplayerの中に入れたかったな・・・。