じゃんけんプログラムをPHPで実装

初めまして。さやみと申します。

2017新卒として某web業界のインフラエンジニアとして就職しました。
それから勉強勉強の日々..

ようやく自分自身が何を知り、何を学び、何を業務で使っていくべきかがボヤっと見えてきたため、技術者としての一歩を形とするべく、Qiitaを始めました。

今回は初投稿ということで、何を投稿するか考えましたが、
学生の原点に立ち返ったつもりで、今業務で利用するために勉強中の『PHP』を使った『じゃんけんプログラム』を1時間ばかりで実装したため、そちらについて投稿〇貞を捧げようと思います。

まずはコードから

```php:game.php
<?php

//じゃんけん
do {
    $hand = array('0:グー','1:チョキ','2:パー');
    //print var_export($hand, true);
    print var_dump($hand);
    echo '0, 1, 2 から選べ : ';

    $usr_hand = (int)fgets(STDIN);
    $com_hand = array_rand($hand);
    print var_dump($hand[$usr_hand]);
    print(PHP_EOL);
    print var_dump($hand[$com_hand]);
    print(PHP_EOL);

    if ($usr_hand == $com_hand) {
        echo "あいこ！ もう一度勝負だ！";
        print(PHP_EOL);
    } else if($usr_hand == 0 && $com_hand == 1 || $usr_hand == 1 && $com_hand == 2 || $usr_hand == 2 && $com_hand == 0) {
        echo "プレイヤーの勝利！";
    } else if($usr_hand == 0 && $com_hand == 2 || $usr_hand == 1 && $com_hand == 0 || $usr_hand == 2 && $com_hand == 1) {
        echo "プレイヤーの負け！";
    }
} while($usr_hand == $com_hand);
```

じゃんけんプログラムは、プログラミングの基礎でありながら、プログラミングにおける必須事項が詰まっているということで、導入線としては適切なものではないかという先人のお言葉を頂戴しました。

プログラミングの基礎は以下の３点

- 逐次実行
- 繰り返し（反復）
- 条件分岐

上記３点すべてをじゃんけんプログラム実装の中だけでも学ぶことができるため、初心者である私のような人間には最初に通るべき道とのことです。一つ一つ確認していきます。

-------------------------

- 逐次実行

これについては今更言及する必要がない気がしますが、一応。
プログラミングは基本、上から下へプログラム内容（命令）をメモリが読み取り、CPUが１行ずつ処理を行います。上記のソースコード例でいえば、
まずは

```php:
<?php
```

でphpのソースコードで記述されたプログラムを実行するんだな？と判断して

```php:
do {
```

で{ }内の処理を読み込み、1度は実行するんだな？と判断して

```php:
$hand = array('0:グー','1:チョキ','2:パー');
```

で変数（値の入れ物）"hand"に配列という複数の番地(key)が用意されている箱をさらに用意して各番地(key)に値(value)を入れていくんだな？と判断して...
これを上から順に繰り返していくことを逐次実行といいます。
つまり、どのようなプログラムを書いても逐次実行という概念は消えることがなく、根底にあるものなのだと再認識できます。

- 繰り返し（反復）

じゃんけんにおいては、あいこになると「あいこーでしょ！」という掛け声からじゃんけんを再戦することはよくあることです。今回のプログラムにおいてもそれに倣って、あいこの場合じゃんけんを繰り返す処理を加えております。それが

```php:
do {
} while($usr_hand == $com_hand);
```

の部分です。
繰り返し文には書き方がいくつかありますが、上記ソースコードで使っている<strong>『do{} while()』</strong>は処理を1回は確実に行い、その後、while式を評価し、do以下の処理を続けるか否かを判断します。
繰り返しの回数が予め決まっている場合は<strong>『for(){}』</strong>が最適です。また配列などの要素全てを参照する場合などは繰り返し用の変数を用意して実行させるのではなく、<strong>『foreach(){}』</strong>という関数を使って配列内の全ての要素を参照するまで処理を繰り返すことも可能です。それ以外にも方法があるかもしれません。調べてみてください。

- 条件分岐

条件分岐とはある式が正であればその中の処理をする、式が偽であればその中の処理をせず抜けるという処理をします。書き方にはいくつか種類がありますが（※）、上記ソースコード内では<strong>『if else』</strong>を使っています。
※『if else』以外にも<strong>『switch case』</strong>などがあります。両者の違いとしては、前者が複数式を評価することができる一方、後者は評価できる式が一つのみ。case以下に書けるのはあくまで値だけである点でしょうか。

```php:
if ($usr_hand == $com_hand) {
    echo "あいこ！ もう一度勝負だ！";
    print(PHP_EOL);
} else if($usr_hand == 0 && $com_hand == 1 || $usr_hand == 1 && $com_hand == 2 || $usr_hand == 2 && $com_hand == 0) {
    echo "プレイヤーの勝利！";
} else if($usr_hand == 0 && $com_hand == 2 || $usr_hand == 1 && $com_hand == 0 || $usr_hand == 2 && $com_hand == 1) {
    echo "プレイヤーの負け！";
}
```

評価対象となる式では、

- ユーザ側の手<strong>(usr_hand)</strong>
- コンピュータ側の手<strong>(com_hand)</strong>

をグー、チョキ、パーをそれぞれ0, 1, 2という数値に置き換えて、数値で評価できるようにします。文字列のままでは機械側で判断できず、少し難しくなるため単純化のためにこうしました。多分もっとスマートな方法はあるかと思います。
数値が同じであるか否かを『==』という演算子で評価し、ユーザ側の手が勝つパターン（グーが勝つパターン／チョキが勝つパターン／パーが勝つパターン）と、ユーザ側の手が負けるパターン（グーが負けるパターン／チョキが負けるパターン／パーが負けるパターン）で条件文を作って、それぞれの式の真偽を逐次実行で評価していくことになります。
ここまでがじゃんけんプログラムの全概要となります。

Qiita初投稿はこのへんでお終いにします。
次の投稿に向けてもっときれいにわかりやすく書けるように精進します。

プログラムに関しては、他に「こんな書き方あるよ！」や「Qiitaの書き方こうしたほうが見やすくない？」などのアドバイスがあれば教えていただけますと幸いです。
関数化したほうがいいかな..？　あとデザインに強くなりたいですね笑