PHPで作るじゃんけんゲーム

PHPでじゃんけんゲームを作成してみましょう。最初はシンプルに、そのあと画像などを追加してみましょう。

完成イメージ

フォルダ構成とファイル名

  • 作成フォルダ:php-practice-janken
  • 作成ファイル:janken01.php
  • 使用CSSファイル(任意):style.cssは任意で作成

基本のじゃんけんゲームを作成しよう!

最初はボタンを3つ並べます。クリックすると、結果が下に表示されるようにします。選んだ手をコンピューターが乱数で作成した手が出るようにしましょう。またその下に勝敗が表示するようにしましょう。CSSは適切に設定してください。

基本コード
<?php
// HTMLエスケープ関数
function h($str)
{
    return htmlspecialchars($str, ENT_QUOTES, 'UTF-8');
}
$userName ='';
$cpuName = '';
$resultText = '';
// 手の配列
$hands = ["グー", "チョキ", "パー"];

$user = isset($_POST['hand']) ? (int)$_POST['hand'] : null;

if ($user !== null) {
    $userName = $hands[$user] ?? "不明";
    $cpu = random_int(0, 2); // 0, 1, 2 のいずれかが入る
    //random_int()安全な乱数PHP7以降はよく使われる ただし、mt_srand()が不可
    $cpuName = $hands[$cpu]; // 配列のキーが 0,1,2 のどれかになる

    //$cpu = 0 → $hands[0] → "グー"
    //$cpu = 1 → $hands[1] → "チョキ"
    //$cpu = 2 → $hands[2] → "パー"

    // --- 勝敗判定 ---
    if ($user === $cpu) {
        $resultText = "あいこ";
    } elseif (
        ($user === 0 && $cpu === 1) || // グー > チョキ
        ($user === 1 && $cpu === 2) || // チョキ > パー
        ($user === 2 && $cpu === 0)    // パー > グー
    ) {
        $resultText = "あなたの勝ち!";
    } else {
        $resultText = "あなたの負け…";
    }
}
?>
<!DOCTYPE html>
<html lang="ja">

<head>
    <meta charset="UTF-8">
    <title>じゃんけん</title>
    <link rel="stylesheet" href="style.css">
</head>

<body>
    <!-- フォーム部分 -->
    <div class="box">
        <h1>じゃんけん</h1>
        <p>あなたの手を選んでください</p>
        <form method="post" class="janken-form">
            <button type="submit" name="hand" value="0">グー</button>
            <button type="submit" name="hand" value="1">チョキ</button>
            <button type="submit" name="hand" value="2">パー</button>
        </form>
    </div>

    <?php if ($user !== null): ?>
        <div class="resultbox">
            <h2>結果</h2>
            <p>あなたの手:<?= h($userName) ?></p>
            <p>コンピュータの手:<?= h($cpuName) ?></p>
            <p><strong><?= h($resultText) ?></strong></p>

            <!-- POSTデータなしの状態 -->
            <p><a href="<?= h($_SERVER['PHP_SELF']) ?>">もう一度遊ぶ</a></p>

        </div>
    <?php endif; ?>
</body>

</html>

ステップアップ:結果を画像で表示

画像・イラストは準備しましょう。

ヒント
$userHand = '';  // 画像が入るための変数
$cpuHand = '';   // 画像が入るための変数

// 手の配列を用意します。
$hands = ["img/janken_gu.png", "img/janken_choki.png", "img/janken_pa.png"];

//送られてきた値が$userに代入
$user = isset($_POST['hand']) ? (int)$_POST['hand'] : null;
//画像の配列の中の$user で画像を選択
$userHand = $hands[$user] ?? '';

//コンピューターの手を乱数で生成
//画像の配列の中の$cpuで画像を選択
$cpu = random_int(0, 2);
$cpuHand = $hands[$cpu];


//表示する場所
<img src="<?= h($userHand) ?>" alt="あなたの手" class="hand-img">

<img src="<?= h($cpuHand) ?>" alt="コンピュータの手" class="hand-img">
解答例はこちら
<?php
// HTMLエスケープ関数
function h($str)
{
    return htmlspecialchars($str, ENT_QUOTES, 'UTF-8');
}

$userHand = '';
$cpuHand = '';
$resultText = '';

// 手の配列(画像版)
$hands = ["img/janken_gu.png", "img/janken_choki.png", "img/janken_pa.png"];

// POSTで受け取った手(0,1,2)
$user = isset($_POST['hand']) ? (int)$_POST['hand'] : null;

if ($user !== null) {
    // ユーザーの手(存在しない値なら空文字)
    $userHand = $hands[$user] ?? '';

    // コンピュータの手(0,1,2 のどれか)
    $cpu = random_int(0, 2);
    $cpuHand = $hands[$cpu];

    // --- 勝敗判定 ---
    if ($user === $cpu) {
        $resultText = "あいこ";
    } elseif (
        ($user === 0 && $cpu === 1) || // グー > チョキ
        ($user === 1 && $cpu === 2) || // チョキ > パー
        ($user === 2 && $cpu === 0)    // パー > グー
    ) {
        $resultText = "あなたの勝ち!";
    } else {
        $resultText = "あなたの負け…";
    }
}
?>
<!DOCTYPE html>
<html lang="ja">

<head>
    <meta charset="UTF-8">
    <title>じゃんけん</title>
    <link rel="stylesheet" href="style.css">
</head>

<body>
    <!-- フォーム部分 -->
    <div class="box">
        <h1>じゃんけん</h1>
        <p>あなたの手を選んでください</p>
        <form method="post" class="janken-form">
            <button type="submit" name="hand" value="0">グー</button>
            <button type="submit" name="hand" value="1">チョキ</button>
            <button type="submit" name="hand" value="2">パー</button>
        </form>
    </div>

    <?php if ($user !== null): ?>
        <div class="resultbox">
            <h2>結果</h2>
            <div class="resultbox-flex">
                <p>あなたの手<br><img src="<?= h($userHand) ?>" alt="あなたの手" class="hand-img"></p>
                <p>コンピュータの手<br><img src="<?= h($cpuHand) ?>" alt="コンピュータの手" class="hand-img"></p>
            </div>
            <p><strong><?= h($resultText) ?></strong></p>

            <!-- POSTデータなしの状態に戻す -->
            <p><a href="<?= h($_SERVER['PHP_SELF']) ?>">もう一度遊ぶ</a></p>
        </div>
    <?php endif; ?>
</body>

</html>

ステップアップ:結果の背景の色を変更

勝ちだったら赤 あいこは黄色 負けたら青に背景が変わるようにしましょう。

//ヒント
$resultText = '';
$resultClass = ''; // 勝敗に応じたクラスの変数を準備

//勝敗判定時にclassの文字列を変数に代入
    if ($user === $cpu) {
        $resultText = "あいこ";
        $resultClass = "draw";
    } elseif (
        ($user === 0 && $cpu === 1) || // グー > チョキ
        ($user === 1 && $cpu === 2) || // チョキ > パー
        ($user === 2 && $cpu === 0)    // パー > グー
    ) {
        $resultText = "あなたの勝ち!";
        $resultClass = "win";
    } else {
        $resultText = "あなたの負け…";
        $resultClass = "lose";
    }

//表示する場所にclass名を追加
<div class="resultbox <?= h($resultClass) ?>">
<h2>じゃんけんぽん!</h2>


解答例はこちら
<?php
// HTMLエスケープ関数
function h($str)
{
    return htmlspecialchars($str, ENT_QUOTES, 'UTF-8');
}

$userHand = '';  // 画像パス
$cpuHand  = '';  // 画像パス
$resultText = '';
$resultClass = '';

// 手の配列(画像版)
$hands = ["img/janken_gu.png", "img/janken_choki.png", "img/janken_pa.png"];

// POSTで受け取った手(0,1,2)
$user = isset($_POST['hand']) ? (int)$_POST['hand'] : null;

if ($user !== null) {
    // ユーザーの手(存在しない値なら空文字)
    $userHand = $hands[$user] ?? '';

    // コンピュータの手(0,1,2 のどれか)
    $cpu = random_int(0, 2);
    $cpuHand = $hands[$cpu];

    // --- 勝敗判定 ---
    if ($user === $cpu) {
        $resultText = "あいこ";
        $resultClass = "draw";
    } elseif (
        ($user === 0 && $cpu === 1) || // グー > チョキ
        ($user === 1 && $cpu === 2) || // チョキ > パー
        ($user === 2 && $cpu === 0)    // パー > グー
    ) {
        $resultText = "あなたの勝ち!";
        $resultClass = "win";
    } else {
        $resultText = "あなたの負け…";
        $resultClass = "lose";
    }
}
?>
<!DOCTYPE html>
<html lang="ja">

<head>
    <meta charset="UTF-8">
    <title>じゃんけん</title>
    <link rel="stylesheet" href="style.css">
</head>

<body>
    <div class="box">
        <h1>じゃんけん</h1>
        <p>あなたの手を選んでください</p>
        <form method="post" class="janken-form">
            <button type="submit" name="hand" value="0">グー</button>
            <button type="submit" name="hand" value="1">チョキ</button>
            <button type="submit" name="hand" value="2">パー</button>
        </form>
    </div>

    <?php if ($user !== null): ?>
        <div class="resultbox <?= h($resultClass) ?>">
            <h2>じゃんけんぽん!</h2>
            <div class="result">
                <div>
                    <p>あなたの手</p>
                    <img src="<?= h($userHand) ?>" alt="あなたの手">
                </div>
                <div>
                    <p>コンピュータの手</p>
                    <img src="<?= h($cpuHand) ?>" alt="コンピュータの手">
                </div>
            </div>
            <p class="judge"><?= h($resultText) ?></p>
            <p><a href="<?= h($_SERVER['PHP_SELF']) ?>">もう一度遊ぶ</a></p>
        </div>
    <?php endif; ?>
</body>

</html>

ステップアップ:5本先取りゲーム

先に5回勝った方が勝ち!の先取りゲームに変更してみましょう。セッションを利用します。

ヒント1:セッションの役割

  • セッションを使うと、ページをまたいでも情報を保持できる(更新してもデータは消えない)
  • この課題では、勝ち負けのスコア(何勝何敗か)をセッションに保存しています。
  • まず、ファイルの先頭で必ず session_start(); を書くことが必要です
session_start(); // セッションを使うときは必ず最初に書く

ヒント2:スコアの保存方法

  • セッションは配列として扱える
  • 今回は $_SESSION['score'] に勝ち・負けを保存しています
  • 下記のような初期化を行うと win というキー loseというキーに最初は0を入れておけます
if (!isset($_SESSION['score'])) {
    $_SESSION['score'] = ['win' => 0, 'lose' => 0];
}

ヒント3:勝敗ごとにスコアを更新する

  • 勝ったら $_SESSION['score']['win']++
  • 負けたら $_SESSION['score']['lose']++
  • インクリメント演算子(++)を使うと1を足します。
if ($user === $cpu) {
    // あいこのときはスコアを変えない
} elseif (勝ちの条件) {
    $_SESSION['score']['win']++;
} else {
    $_SESSION['score']['lose']++;
}

ヒント4:5本先取の判定

  • 勝ち数または負け数が5になったら終了メッセージを表示し、スコアをリセット
  • リセットは再び配列を 0 に戻せばOK
if ($_SESSION['score']['win'] >= 5) {
    $finalMessage = "あなたの勝ち! 5本先取達成!";
    $_SESSION['score'] = ['win' => 0, 'lose' => 0];
}

ヒント5:スコアの表示

  • セッションの中身を直接表示できる
  • PHPタグ内でこう書くと、常に現在のスコアを表示できる
<p class="score">スコア:<?= $_SESSION['score']['win'] ?> 対 <?= $_SESSION['score']['lose'] ?></p>
解答例はこちら
<?php
session_start(); // セッション開始

// HTMLエスケープ関数
function h($str)
{
    return htmlspecialchars($str, ENT_QUOTES, 'UTF-8');
}

// 手の配列(画像版)
$hands = ["img/janken_gu.png", "img/janken_choki.png", "img/janken_pa.png"];

// スコアがなければ初期化
if (!isset($_SESSION['score'])) {
    $_SESSION['score'] = ['win' => 0, 'lose' => 0];
}

$userHand = '';  // ユーザーの手(画像パス)
$cpuHand  = '';  // コンピュータの手(画像パス)
$resultText = '';
$resultClass = '';
$finalMessage = '';

// POSTで受け取った手(0,1,2)
$user = isset($_POST['hand']) ? (int)$_POST['hand'] : null;

if ($user !== null) {
    // ユーザーの手(存在しない値なら空文字)
    $userHand = $hands[$user] ?? '';

    // コンピュータの手(0,1,2 のどれか)
    $cpu = random_int(0, 2);
    $cpuHand = $hands[$cpu];

    // --- 勝敗判定 ---
    if ($user === $cpu) {
        $resultText = "あいこ";
        $resultClass = "draw";
    } elseif (
        ($user === 0 && $cpu === 1) || // グー > チョキ
        ($user === 1 && $cpu === 2) || // チョキ > パー
        ($user === 2 && $cpu === 0)    // パー > グー
    ) {
        $resultText = "あなたの勝ち!";
        $resultClass = "win";
        $_SESSION['score']['win']++;
    } else {
        $resultText = "あなたの負け…";
        $resultClass = "lose";
        $_SESSION['score']['lose']++;
    }

    // --- 5本先取チェック ---
    if ($_SESSION['score']['win'] >= 5) {
        $finalMessage = "あなたの勝ち! 5本先取達成!";
        $_SESSION['score'] = ['win' => 0, 'lose' => 0]; // スコアリセット
    } elseif ($_SESSION['score']['lose'] >= 5) {
        $finalMessage = "コンピュータの勝ち! 5本先取達成!";
        $_SESSION['score'] = ['win' => 0, 'lose' => 0]; // スコアリセット
    }
}
?>
<!DOCTYPE html>
<html lang="ja">

<head>
    <meta charset="UTF-8">
    <title>じゃんけん(5本先取)</title>
    <link rel="stylesheet" href="style.css">
</head>

<body>
    <div class="box">
        <h1>じゃんけん(5本先取)</h1>
        <p>あなたの手を選んでください</p>
        <form method="post" class="janken-form">
            <button type="submit" name="hand" value="0">グー</button>
            <button type="submit" name="hand" value="1">チョキ</button>
            <button type="submit" name="hand" value="2">パー</button>
        </form>
    </div>

    <?php if ($user !== null): ?>
        <div class="resultbox <?= h($resultClass) ?>">
            <h2>じゃんけんぽん!</h2>
            <div class="result">
                <div>
                    <p>あなたの手</p>
                    <img src="<?= h($userHand) ?>" alt="あなたの手">
                </div>
                <div>
                    <p>コンピュータの手</p>
                    <img src="<?= h($cpuHand) ?>" alt="コンピュータの手">
                </div>
            </div>
            <p class="judge"><?= h($resultText) ?></p>
            <p class="score">スコア:<?= $_SESSION['score']['win'] ?> 対 <?= $_SESSION['score']['lose'] ?></p>
            <?php if ($finalMessage): ?>
                <p class="final"><?= h($finalMessage) ?></p>
            <?php endif; ?>
            <p><a href="<?= h($_SERVER['PHP_SELF']) ?>">もう一度</a></p>
        </div>
    <?php endif; ?>
</body>

</html>
style.css例
.box{
max-width: 600px;
margin: 1rem auto 2rem;
border: 1px solid #ddd;
padding: 1rem;
border-radius: 5px;
text-align: center;
}

.resultbox{
padding: 1.5rem;
margin: 1rem auto;
max-width: 600px;
border-radius: 10px;
text-align: center;
border: 1px solid #ddd;
transition: background-color 0.3s ease;
}
.resultbox-flex{
    display: flex;
}
.hand-img{
    width: 100%;
    height: auto;
}
.resultbox.win  { background-color: #ff8d89;} 
.resultbox.lose { background-color: #348bf5;}
.resultbox.draw { background-color: #eff7a6; }

.score {
    background-color: #fff;
    padding: 1.25rem;
    font-size: 3rem;
    margin-top: 1rem;
}

.final {
    font-size: 1.5rem;
    font-weight: bold;
    margin-top: 1rem;
    color: #c00;
}


.judge {
font-size: 1.5rem;
font-weight: bold;
margin-top: 1rem;
}

.janken-form {
display: flex;
gap: 1rem;
justify-content: center;
margin-bottom: 2rem;
}
.janken-form button {
background: #bfbfbf;
border: 1px solid #ccc;
border-radius: 5px;
padding: 0.5rem 1rem;
cursor: pointer;
font-weight: bold;
}
.janken-form img {
width: 100px;
height: auto;
transition: transform 0.2s;
}
.janken-form img:hover {
transform: scale(1.1);
}
.result {
display: flex;
justify-content: center;
align-items: center;
gap: 3rem;
margin-top: 2rem;
}
.result div {
text-align: center;
}
.result img {
width: 120px;
height: auto;
}