面白そうだったので、ガシャを再現する簡易的なライブラリを作成しました。
/*
* gasha.h - 二宮飛鳥?
*/
#ifndef GASHA_H
#define GASHA_H
#ifdef __cplusplus
extern "C" {
/* __cplusplus */
#endif
#include <stdint.h> /* uint32_t */
#include <stdio.h> /* size_t */
/*
* レアリティの定義
*/
#define RARITY_R 3
#define RARITY_SR 4
#define RARITY_SSR 5
/*
* レアリティに対する確率の定義
*/
#define DEFAULT_WEIGHT_R 85
#define DEFAULT_WEIGHT_SR 12
#define DEFAULT_WEIGHT_SSR 3
/*
* カード(各キャラクター)
*/
typedef struct GASHA_CARD {
uint32_t id;
char* name;
uint32_t rarity;
} GASHA_CARD;
/*
* レアリティ・確率の設定
*/
typedef struct GASHA_CONF {
uint32_t weights[6];
} GASHA_CONF;
/*
* このライブラリの要
*/
typedef struct GASHA GASHA;
typedef struct GASHA {
GASHA_CONF* conf;
GASHA_CARD** card;
size_t cardc;
int (*change_weight)(GASHA** gasha, uint32_t rarity, uint32_t weight);
int (*join_cards)(GASHA** gasha, GASHA_CARD cards[]);
int (*is_ready)(GASHA* gasha);
uint32_t (*roll)(GASHA* gasha);
uint32_t (*roll10)(GASHA* gasha);
void (*release)(GASHA* gasha);
} GASHA;
int init_gasha(GASHA** gasha);
GASHA_CARD* id2card(GASHA* gasha, uint32_t id);
size_t count_by_rarity(GASHA* gasha, uint32_t rarity);
GASHA_CARD** filter_by_rarity(GASHA* gasha, uint32_t rarity);
#ifdef __cplusplus
}
/* __cplusplus */
#endif
/* GASHA_H */
#endif
単発で100回試行します。確率は以下の通り。
SSR 3%
SR 12%
R 85%
/*
* main.c
*/
#include "./gasha.h"
#include <stdio.h>
#include <unistd.h> /* usleep() */
int main(void)
{
size_t i = 0;
GASHA* gasha = NULL;
GASHA_CARD* result = NULL;
GASHA_CARD cards[] = {
{3001, "あ", 3}, /* R */
{3002, "い", 3},
{3003, "う", 3},
{3004, "え", 3},
{3005, "お", 3},
{4001, "か", 4}, /* SR */
{4002, "き", 4},
{4003, "く", 4},
{4004, "け", 4},
{4005, "こ", 4},
{5001, "うえきちゃん", 5}, /* SSR */
{5002, "一ノ瀬志希", 5},
{5003, "高垣楓", 5},
{5004, "多田李衣菜", 5},
{5005, "二宮飛鳥", 5},
{5006, "ドラえもん", 5},
{0, NULL, 0},
};
/* gasha の初期化 */
init_gasha(&gasha);
/* gasha に正規化されたカードを登録 */
gasha->join_cards(&gasha, cards);
/* 登録されたカードを確認してみる */
fprintf(stderr, "**** cards ****\n");
for (i = 0; i < gasha->cardc; i++) {
fprintf(stderr, "id = %d, name = %s, rarity = %d\n",
gasha->card[i]->id, gasha->card[i]->name, gasha->card[i]->rarity);
}
fprintf(stderr, "**** cards ****\n\n");
/* gasha がレディか確認 */
if (gasha->is_ready(gasha)) {
/* 単発で 100 回試行する */
for (i = 1; i <= 100; i++) {
/* 当選した id からカードの情報を取得する */
if (i % 10 == 0)
result = id2card(gasha, gasha->roll10(gasha));
else
result = id2card(gasha, gasha->roll(gasha));
fprintf(stdout, "%zu 回目の試行で 星%d の %s が当たりました。やったね!\n",
i, result->rarity, result->name);
usleep(10000);
}
}
/* 使った後はお片付け */
gasha->release(gasha);
return 0;
}
% gcc main.c gasha.c -o gasha
% ./gasha | grep 星5
**** cards ****
id = 3001, name = あ, rarity = 3
id = 3002, name = い, rarity = 3
id = 3003, name = う, rarity = 3
id = 3004, name = え, rarity = 3
id = 3005, name = お, rarity = 3
id = 4001, name = か, rarity = 4
id = 4002, name = き, rarity = 4
id = 4003, name = く, rarity = 4
id = 4004, name = け, rarity = 4
id = 4004, name = こ, rarity = 4
id = 5001, name = うえきちゃん, rarity = 5
id = 5002, name = 一ノ瀬志希, rarity = 5
id = 5003, name = 高垣楓, rarity = 5
id = 5004, name = 多田李衣菜, rarity = 5
id = 5005, name = 二宮飛鳥, rarity = 5
id = 5006, name = ドラえもん, rarity = 5
**** cards ****
バグじゃないよ!
10連により星4以上のカードを1枚以上確定させます。 といっても、適宜 roll10() を呼ぶ実装なので main.c を以下のように変更。
< result = id2card(gasha, gasha->roll(gasha));
---
> if (i % 10 == 0)
> result = id2card(gasha, gasha->roll10(gasha));
> else
> result = id2card(gasha, gasha->roll(gasha));
% gcc main.c gasha.c -o gasha10
% ./gasha10 | grep -v 星3
(略)
10 回目の試行で 星4 の け が当たりました。やったね!
15 回目の試行で 星4 の き が当たりました。やったね!
20 回目の試行で 星4 の け が当たりました。やったね!
30 回目の試行で 星4 の き が当たりました。やったね!
34 回目の試行で 星4 の か が当たりました。やったね!
39 回目の試行で 星4 の き が当たりました。やったね!
40 回目の試行で 星4 の き が当たりました。やったね!
45 回目の試行で 星4 の く が当たりました。やったね!
50 回目の試行で 星5 の 二宮飛鳥 が当たりました。やったね!
52 回目の試行で 星4 の く が当たりました。やったね!
60 回目の試行で 星4 の け が当たりました。やったね!
62 回目の試行で 星4 の く が当たりました。やったね!
70 回目の試行で 星4 の か が当たりました。やったね!
72 回目の試行で 星4 の か が当たりました。やったね!
76 回目の試行で 星4 の き が当たりました。やったね!
80 回目の試行で 星4 の け が当たりました。やったね!
90 回目の試行で 星4 の き が当たりました。やったね!
100 回目の試行で 星4 の け が当たりました。やったね!