[PHP]クラスとオブジェクト指向の練習(タロットカード占い)

Pocket

クラスオブジェクトには変数と関数を両方を持たせることができ、オブジェクトの役割や性質を表現できます。
今回はタロットカードの一枚一枚をオブジェクトとして扱い、簡単な占いゲームのようなものを作ってみます。

カードには次のようなプロパティ(性質・役割)があります。

・カード名
・正位置での意味
・逆位置での意味
・位置

あまりタロットカードに馴染みのない人もいると思うので簡単に解説すると、カードをシャッフルする際テーブルに散らしてかき混ぜるようにシャッフルするため、カードの向きが上下バラバラに混ざります。正しい向きを「正位置」、逆さまの状態を「逆位置」といい、向きによってカードの意味が変わります。(区別しないこともあります)
ですので一枚のカードにつき上記のプロパティを持たせる必要があります。

サンプルでは山札をシャッフルしてカードを3枚引きます。
それぞれが「過去」「現在」「未来」を象徴するという単純なものです。(Three Card Spreads)

ファイルは3つで、メインとなる「index.php」とカード操作を行う「TarotReading.php」、カードの情報を格納する「TarotCard.php」です。

index.php

<?php
require_once dirname(__FILE__) . "/TarotReading.php";
require_once dirname(__FILE__) . "/TarotCard.php";

$tarot = new TarotReading();

// カードを用意 TarotCard(名前, 正位置での意味, 逆位置での意味)
$deck = array(
	new TarotCard('The Fool',           '自由・無邪気', '軽率・愚行'),
	new TarotCard('The Magician',       '始まり・才能', '無気力・空回り'),
	new TarotCard('The High Priestess', '知性・平常心', 'わがまま・不安定'),
	new TarotCard('The Empress',        '豊穣・繁栄', '挫折・嫉妬'),
	new TarotCard('The Emperor',        '支配・強い責任感', '傲慢・勝手'),
	new TarotCard('The Hierophant',     '慈悲・協調性', '束縛・独りよがり'),
	new TarotCard('The Lovers',         '絆・情熱', '失恋・不道徳'),
	new TarotCard('The Chariot',        '勝利・成功', '暴走・失敗'),
	new TarotCard('Strength',           '意思・勇気', '甘え・優柔不断'),
	new TarotCard('The Hermit',         '深慮・単独行動', '無計画・閉鎖的'),
	new TarotCard('Wheel of Fortune',   'チャンス・幸運', '不運・悪化'),
	new TarotCard('Justice',            '公平・善行', '不正・偏向'),
	new TarotCard('The Hanged Man',     '忍耐・努力', 'やせ我慢・徒労'),
	new TarotCard('Death',              '破滅・死', '再生・再出発'),
	new TarotCard('Temperance',         '調和・自制', '浪費・生活の乱れ'),
	new TarotCard('The Devil',          '欲望・堕落', '意地・悪循環'),
	new TarotCard('The Tower',          '崩壊・悲劇', '緊迫・不慮の災い'),
	new TarotCard('The Star',           '希望・ひらめき', '失望・高望み'),
	new TarotCard('The Moon',           '不安定・潜在的な危険', '徐々に好転・漠然とした希望'),
	new TarotCard('The Sun',            '祝福・誕生', '衰退・落胆'),
	new TarotCard('Judgement',          '復活・発展', '悔恨・行き詰まり'),
	new TarotCard('The World',          '完全・成就', '未完成・臨界点')
);

$tarot->set_deck($deck);

// シャッフル
$tarot->shuffle_deck(true);

// カードを引く
$max = 3;	// 枚数

$result = array();
for($i=0;$i<$max;$i++){
	$card = $tarot->draw_card();	// カードを引く
	
	// 山札が切れた時
	if($card === false){
		$tarot->reset_deck();
		$tarot->shuffle_deck(true);
		$card = $tarot->draw_card();
	}
	
	$result[$i] = $card;
}

$header = array('過去', '現在', '未来');	// 見出し

function h($str){
	return htmlspecialchars($str, ENT_QUOTES, 'UTF-8');
}

header("Content-type: text/html;");
?>
<!DOCTYPE html>
<head>
<title>TarotReading</title>
<meta charset="utf-8">
</head>
<body>
<table border="1">
<?php
for($i=0;$i<$max;$i++){
    $position = ($result[$i]->position == 'reversed') ? '逆位置' : '正位置';
	$format = <<<EOD
	<tr>
	  <th>%s</th>
	  <td>%s</td>
	  <td>%s</td>
	  <td>%s</td>
	</tr>
	
EOD;
	printf($format, h($header[$i]), h($result[$i]->name), h($position),
		h($result[$i]->get_meaning()));
}
?>
</table>
</body>
</html>

TarotReading.php

<?php
class TarotReading
{
	private $deck;			// 山札
	private $originalDeck;	// 初期化用の山札
	
	// 山札を用意
	function set_deck( $cards ){
		$this->deck = $cards;
		$this->originalDeck = $cards;
	}
	
	// 山札をリセット
	function reset_deck(){
		$this->deck = $this->originalDeck;
	}
	
	// カードをシャッフル
	function shuffle_deck($shufflePosition=false){
		shuffle($this->deck);
		
		// 位置をシャッフル
		if($shufflePosition){
			foreach($this->deck as &$card){
				$card->position = (mt_rand(0, 1)) ? 'upright' : 'reversed';
			}
		}
	}
	
	// カードを引く
	function draw_card(){
		if( count($this->deck) == 0 ) return false;
		return array_pop($this->deck);
	}
}

TarotCard.php

<?php
class TarotCard
{
	public $name;					// カード名
	public $upright;				// 正位置での意味
	public $reversed;				// 逆位置での意味
	public $position = 'upright';	// 位置(正位置・逆位置)

	function __construct($name, $upright, $reversed=""){
		$this->name     = $name;
		$this->upright  = $upright;
		$this->reversed = $reversed;
	}
	
	// 位置に応じた意味を取得
	function get_meaning($ignorePosition=false){
		if($ignorePosition){
			return $this->upright;
		} else {
			return ($this->position == 'upright') ? $this->upright : $this->reversed;
		}
	}
}

出力例:

過去 「The Magician(正位置)」 始まり・才能
現在 「The Empress(逆位置)」 挫折・嫉妬
未来 「The High Priestess(逆位置)」 わがまま・不安定

あまり明るい未来じゃなさそうですね。

TarotCard クラスに画像ファイルに関するプロパティを持たせて結果にカード画像を表示するとよりそれらしくなると思います。今回は Three Card Spreads という単純なスプレッド(カード配置・占い方)を採用しましたが、カードを引く枚数を変えれば他のスプレッド用にも改造できます。
タロットの結果はあくまで断片的なキーワードであり、それをどう読み解くかは人間の仕事ですが、雰囲気としては楽しめると思います。

参考: Wikipedia 「大アルカナ」


Similar Posts:




コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です