ガチャを引く
We listed cards and deleted them, now let's add some cards by playing a gacha game. The game must implement the following features
- The player can pull a gacha a limited amount of times
- Card rarity is linked to card rank (SS cards are more rare than C cards)
In particular, here's the probability for each card rarity:
| Rank | SS | S | A | B | C |
| Rarity (%) | 5% | 10% | 20% | 30% | 35% |
Database
Let's start by making a new table in the database to store how many gacha pulls each player has. We need the user id and the number of pulls.
Notice that we don't need an auto-increment id for this table. The reason why is because each user has only 1 entry in the gacha table, so we can reuse the user_id as the primary key for this table. Let's give user_id = 1 a total of 3 gacha pulls to begin with:
INSERT INTO `gacha` (`user_id`, `count`) VALUES ('1', '3');

PHP Script
Number of gacha pulls
We need two new APIs. One to check the number of gacha pulls and another one that actually executes the pull. The first one is the simplest, so let's start with a new script called get_gacha_count.php. This is a simple SELECT query that checks how many counts the player has. If there is no entry in the table, we return 0.
As always, we can first test with GET parameters. Let's pass the user_id we want to query as an argument.
<?php
// JSONを返すべき
header("Content-Type: application/json; charset=utf-8");
// 接続
$dbh = new PDO('mysql:host=localhost; dbname=card_game', "root", "", [PDO::ATTR_PERSISTENT => true]);
// ユーザーIDを取得
$userID = $_GET['user_id'];
// SQL文を構築
$sql = "SELECT * FROM gacha WHERE user_id = " . $userID;
// デフォルトとして 0 を返す
$json['count'] = 0;
// 見つけたら、回数を取得
$result = $dbh->query($sql);
if ($result->rowCount() == 1)
{
$record = $result->fetch();
$json['count'] = $record['count'];
}
// 返す
print(json_encode($json));
?>
If we test with user 1 and user 3, we get:


Which is the correct output we need.
Gacha pull
The next scrips executes the gacha pull. This is a bit more complex, as it needs to do a few things
We can break this into 4 different functions and call them one at the time. Let's start with random card generation. Create a new script called gacha_pull.php
Random card rank with probability
// 確率によりランダムランクを作成
// 0:C ~ 4:SS
function createRandomRank()
{
// 0~100までの乱数を生成
$chance = rand(0, 100)
// 5% 以下だったら、SSランク(4)のカードになる
if ($chance < 5)
return 4;
// 15% 以下だったら、Sランク(3)のカードになる
if ($chance < 15)
return 3;
// 35% 以下だったら、Aランク(2)のカードになる
if ($chance < 35)
return 2;
// 65% 以下だったら、Bランク(1)のカードになる
if ($chance < 65)
return 1;
// 残りは C(0)
return 0;
}
This script generates a random number between 0 and 100 and then checks each cumulative probability until it finds a rank to return between 0 (C) and 4 (SS)
Select random card from database with rank
The next script takes a rank value from 0 to 4, queries the database and returns 1 random card record.
// ランクを用いて、ランダムのカードを返す
// $dbh: データベースを検索するためのPDO
// $rank: カードのランク
function getCardWithRank($dbh, $rank)
{
// SQL文を構築
$sql = "SELECT * FROM cards WHERE rank = " . $rank;
// すべてのレコードを取得
$result = $dbh->query($sql);
$records = $result->fetchAll();
// ランダムのを選択
$count = sizeof($records);
$idx = rand(0, $count-1);
return $records[$idx];
}
Add the card to the player
In this step, we modify user_cards table to update the cards the player has. If the player already had the card, we need to add 1 to the count. However, if the player never owned the card, we need to add a new record with a starting count of 1. Fortunately, SQL has a special statement for that called INSERT ... ON DUPLICATE. It's a bit complex to read, but it looks something like this:
INSERT INTO table (field1, filed2, ...) VALUES (1, "A", ..) ON DUPLICATE KEY UPDATE name="A", age=19, ...
In this case, if
