素数判定関数を使って簡単なゲームを作った話⑤

ご覧いただきありがとうございます。
この内容は、複数に分けて投稿しています。全体をご覧になりたい方は、以下のリンク先よりご確認ください。

https://qiita.com/hitoki_univ/items/8e3feab0add17befc700

前回の内容は、こちらからどうぞ。

https://qiita.com/hitoki_univ/items/c47836e9f418af6b1eb8

# 今回やること
前回までで、ゲームの基本動作の部分はすべて完成しました。
今回は、ゲームプレイ時に集めたデータを集計し、過去のランキングを表示する機能を作成します。

# データベースの作成
ランキングを集計するためには、データベースを作成し、ゲーム実行ページと接続することが必要です。
今回は、phpMyAdminを使ってデータベースを作成していきます。

今回記録したい内容は

1.記録が残された日時(date)
2.そのゲームでの最大の素数(biggest_prime_num)
3.それを入力したプレイヤー名(player_name)

の3つです。2の素数はINT型の整数、プレイヤー名は文字列(TEXT)で保存したいので、このようにデータベースを作成しました。

![DB作成画面.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3684916/7aec51fb-fb2a-3119-2bcc-76caaefd1a7f.png)

作成したデータベースにデータを追加する処理については、前回投稿したゲーム動作部で実装しているので、詳しくはそちらをご確認いただければと思います。


# ランキングの表示
データベースに保存しているデータを、素数の大きい順に並べ替え、ランキング形式で表示するページを作成します。

### HTML
``` php
<html>
  <head>
    <meta charset="UTF-8">
    <link rel="stylesheet" href="ranking.css">
    <title>ランキング</title>
  </head>
  <body>
    <h1>ランキング</h1>
    <div class="input_field">
      <button onclick="location.href='title.php'">タイトル画面に戻る</button>
    </div>
    <div class="php">
        <?php
        // MySQLに接続する
        $mysqli = new mysqli("localhost", "root", "", "prime_ranking");

        // biggest_prime_numの値が大きい順にデータを取得するSQLを作成
        $sql = "SELECT date, biggest_prime_num, player_name FROM ranking ORDER BY biggest_prime_num DESC";

        // SQLを実行
        $result = $mysqli->query($sql);

        // ランキングを表示
        $rank = 1;
        $prevScore = null;
        while ($row = $result->fetch_assoc()) {
            // 前のスコアと現在のスコアが異なる場合のみ順位を増やす
            if ($prevScore !== null && $prevScore != $row['biggest_prime_num']) {
                $rank++;
            }
            $prevScore = $row['biggest_prime_num'];
            // ランクに応じてクラスを変更
            $rankClass = "";
            switch ($rank) {
                case 1:
                    $rankClass = "gold";
                    break;
                case 2:
                    $rankClass = "silver";
                    break;
                case 3:
                    $rankClass = "bronze";
                    break;
            }
            echo "<div class='rank " . $rankClass . "'>";
            echo "順位: " . $rank . "<br>";
            echo "記録された日時: " . $row['date'] . "<br>";
            echo "最大の素数: " . $row['biggest_prime_num'] . "<br>";
            echo "プレイヤー名: " . $row['player_name'] . "<br>";
            echo "</div>";
            echo "------------------------<br>";
        }

        // 接続を閉じる
        $mysqli->close();
        ?>
    </div>
  </body>
</html>
```

まず、ページの上部にタイトルページへ戻るためのボタンを作成しています。

PHP部では、まず作成したデータベースと接続し、"biggest_prime_num"が大きい順にデータを取得するSQL文を作成します。
データを取得するためには、SELECT文を使います。基本的な使い方は、以下のようになっています。

```
SELECT [取得したい要素] FROM [使用テーブル];
```

今回は、"biggest_prime_num"が大きい順に並べ替えるので、ORDER BY句を用いてデータの並べかえを行った上でデータを取得しています。

SQL文を実行してランキングを受け取った後、順位、記録された日時、最大の素数、プレイヤー名を出力します。
1位は金色、2位は銀色、3位は銅色で装飾を行うので、それぞれの順位の記録を表示する領域に、gold, silber, bronzeのクラス名をつけています。(後述のCSS部で装飾をしています)
同じ数値が記録されていた場合は、順位も同じになるようにしています。

最後に、MySQLとの接続を終了します。


### CSS
``` css
@charset 'UTF-8';

body {
    font-family: Arial, sans-serif;
    margin: 0;
    padding: 0;
    background-color: #f0f0f0;
}

h1 {
    text-align: center;
    padding: 20px;
    background-color: #007BFF;
    color: white;
}

form {
    text-align: center;
    max-width: 300px;
    margin: 0 auto;
    padding-bottom: 10px;
    box-shadow: 0px 0px 10px rgba(0,0,0,0.1);
}

input[type="submit"] {
    display: block;
    width: 100%;
    padding: 10px;
    border: none;
    border-radius: 5px;
    background-color: #007BFF;
    color: white;
    cursor: pointer;
}

.back_button {
    text-align: center;
    max-width: 300px;
    margin: 0 auto;
    padding: 5px;
    background-color: white;
}

.php {
    text-align: center;
}

.gold {
    border: 3px dashed gold;
    padding: 10px;
}

.silver {
    border: 3px dashed silver;
    padding: 10px;
}

.bronze {
    border: 3px dashed #cd7f32;
    padding: 10px;
}

.input_field {
    max-width: 500px;
    margin: 0 auto;
    padding: 20px;
    background-color: white;
    box-shadow: 0px 0px 10px rgba(0,0,0,0.1);
}

input[type="submit"], button {
    display: block;
    width: 100%;
    padding: 10px;
    border: none;
    border-radius: 5px;
    background-color: #007BFF;
    color: white;
    cursor: pointer;
}
```

全体的な見た目は、今までに作成したページと同じ様になるように調整しています。
順位に応じた装飾を行うためにHTML部でクラス名を追加した部分があるので、それに対応したCSSの記述を追記しています。

# 表示結果

このプログラムをブラウザで読み込むと、以下のような表示になります。

![ランキング表示.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3684916/c604d844-8b2c-f5eb-d23e-889f04d93f25.png)

1位、2位、3位の記録には、それぞれ金、銀、銅の装飾が適用されるようになっています。
同じ記録は同率として扱っています。


# 最後に
ここまでで、本ゲームの全ての機能を作成することができました。
長々と記事を出してきましたが、お付き合いくださりありがとうございました。(そもそもこの投稿を全て読んでくださった方はいるのでしょうか、という感じですが…笑)

我ながらなんて拙いものを世に出してしまったんだ、という気しかしていませんが、自分が書いたソースコードを公開する、というのは今までやってこなかったので、貴重な経験になりました。