0.0
The project is in a healthy, maintained state
Rails向けソーシャルゲーム機能kit。重み付きガチャエンジンなど
2005
2006
2007
2008
2009
2010
2011
2012
2013
2014
2015
2016
2017
2018
2019
2020
2021
2022
2023
2024
2025
 Dependencies

Runtime

 Project Readme

Social Game Kit

Ruby on Railsアプリケーション向けのソーシャルゲーム機能を提供するgemです。 重み付き確率に基づくガチャ機能を実装しており、メモリ効率を考慮した設計になっています。

機能

  • 重み付きガチャ機能
  • 確率計算機能
  • 単発・複数回ガチャ対応(10連ガチャ等)

インストール

Gemfileに以下を追加:

gem 'social-game-kit'

その後、以下を実行:

bundle install

要件

  • Ruby 3.1.0以上
  • Rails 6.0以上
  • ActiveRecord
  • ActiveSupport

使用方法

基本的な使用方法

require 'ssg'

# カードマスタデータ(ActiveRecordモデル)から抽選
cards = GachaCard.all

# エンジンの初期化
engine = SSG::Gacha::Engine.new(cards)

# 単発抽選
card = engine.draw
puts card.name    # => "コモン" など
puts card.rarity  # => "common"

# 複数回抽選(10連ガチャ)
results = engine.draw_multiple(10)
puts results.size # => 10

# 確率の計算
probabilities = engine.probabilities
# => {1=>70.0, 2=>25.0, 3=>4.0, 4=>1.0}

Railsアプリケーションでの例

# app/models/gacha_card.rb
class GachaCard < ApplicationRecord
  validates :name, :rarity, :weight, presence: true
  validates :weight, numericality: { greater_than: 0 }

  enum rarity: {
    common: 0,
    rare: 1,
    super_rare: 2,
    ultra_rare: 3
  }
end

# app/controllers/gacha_controller.rb
class GachaController < ApplicationController
  def draw
    engine = SSG::Gacha::Engine.new(GachaCard.all)
    @result = engine.draw

    # ユーザーにカードを付与する処理など
    current_user.gacha_cards << @result

    render json: @result.json_format
  end

  def draw_multiple
    count = params[:count].to_i.clamp(1, 10)  # 最大10連
    engine = SSG::Gacha::Engine.new(GachaCard.all)
    @results = engine.draw_multiple(count)

    current_user.gacha_cards.push(*@results)

    render json: {
      cards: @results.map(&:json_format)
    }
  end

  def probabilities
    engine = SSG::Gacha::Engine.new(GachaCard.all)

    render json: engine.probabilities
  end
end

ガチャカードモデルの例

# db/migrate/20240101000000_create_gacha_cards.rb
class CreateGachaCards < ActiveRecord::Migration[7.0]
  def change
    create_table :gacha_cards do |t|
      t.string :name, null: false
      t.string :rarity, null: false
      t.integer :weight, null: false, default: 1
      t.text :description
      t.string :image_url

      t.timestamps
    end

    add_index :gacha_cards, :rarity
    add_index :gacha_cards, :weight
  end
end

# db/seeds.rb
GachaCard.create!([
  { name: "コモンカード", rarity: :common, weight: 70 },
  { name: "レアカード", rarity: :rare, weight: 25 },
  { name: "スーパーレアカード", rarity: :super_rare, weight: 4 },
  { name: "ウルトラレアカード", rarity: :ultra_rare, weight: 1 }
])

重み付き抽選アルゴリズム

このgemは累積重み方式を使用して、効率的にカードを抽選します。

アルゴリズムの説明

  1. 全カードの重みを合計(total_weight)
  2. 0〜total_weightの範囲でランダム値を生成
  3. 累積重みを計算しながら、ランダム値が該当する範囲のカードを選択

カードA: 重み70 (累積: 0-69)
カードB: 重み25 (累積: 70-94)
カードC: 重み4  (累積: 95-98)
カードD: 重み1  (累積: 99)
合計: 100

ランダム値75 → カードBを選択

APIリファレンス

SSG::Gacha::Engine

initialize(card_relation)

ActiveRecord::Relationを受け取ります。

engine = SSG::Gacha::Engine.new(GachaCard.all)

draw

単発ガチャを実行し、カードを返します。

card = engine.draw

draw_multiple(count)

複数回ガチャを実行します。countは正の整数である必要があります。

cards = engine.draw_multiple(10)  # 10連ガチャ

probabilities

各カードの確率(パーセント)をハッシュで返します。

probs = engine.probabilities
# => {1=>70.0, 2=>25.0, 3=>4.0, 4=>1.0}

SSG::Gacha::Result

ガチャ結果をラップするクラスです。

card

抽選されたカードオブジェクトを返します(読み取り専用)。

name

カード名を返します。

rarity

カードのレア度を返します。

json_format

カード情報をハッシュで返します(JSON化用)。

result = engine.draw
result.json_format
# => { card_id: 1, name: "コモン", rarity: "common" }

メモリ効率について

このgemのprobabilitiesメソッドはハッシュを使用しており、実際に存在するカードのIDだけを保存します。 IDが飛び飛びの場合(例: 1-100と1000-10000)でも、間のIDのエントリは作成されません。

⚠️ 配列を使った場合の問題

# ❌ 配列を使った実装(メモリを大量に消費)
arr = []
arr[1000] = "value"
# インデックス0-999もメモリに確保される

このgemはハッシュを使用することでこの問題を回避しています。

開発

リポジトリをクローンした後:

bundle install

テストを実行:

bundle exec rspec

コード品質をチェック:

bundle exec rubocop

対話的なプロンプトで実験:

bin/console

gemをローカルにインストール:

bundle exec rake install

テスト

このgemは包括的なテストスイートを含みます。

# 全テスト実行
bundle exec rake

# RSpecのみ実行
bundle exec rspec

# RuboCopのみ実行
bundle exec rubocop

貢献

バグレポートやプルリクエストはGitHubで歓迎します。

https://github.com/NYUWAMOCHI/social-game-kit

ライセンス

このgemはMIT Licenseの下でオープンソースとして利用可能です。

詳細はLICENSE.txtを参照してください。