main() blog

プログラムやゲーム、旅、愛する家族について綴っていきます。

【UE5】ダイス(サイコロ)クラスを作成してみよう!

概要

3d6(6面ダイスを3個)やd20、d8+2等のダイスロールを行うクラスです。
文字列として"3d6"なども渡すこともできます。
"3D6"など大文字でも指定することができます。
"d6"などの最初のダイスの個数の省略や、"d6 + 1"など途中に空白文字が含まれているケースにも対応しています。

※本記事はC++での開発を前提としています。

環境

UnrealEngine 5.4.2

クラス実装

C++クラス追加で"なし"で作成します。
引数で"ダイスの個数"、”ダイス”、"補正値"、マイナス値を許容するかのフラグを持つ関数と、文字列で指定する関数を用意します。

#pragma once

#include "CoreMinimal.h"

/**
 * 
 */
class HOGE_API FDice
{
public:
    static constexpr int32 INVALID_RESULT = INT32_MIN;

public:
    static int32 Roll(const FString& DiceNotation, bool bAllowNegative = false);
    static int32 Roll(int32 Number, int32 Dice, int32 Modifier = 0, bool bAllowNegative = false);
};
#include "Dice.h"

#include "Math/UnrealMathUtility.h"

int32 FDice::Roll(const FString& DiceNotation, bool bAllowNegative)
{
    int32 number = 1;
    int32 dice = 0;
    int32 modifier = 0;

    FString notation = DiceNotation;

    notation.ReplaceInline(TEXT(" "), TEXT(""));

    static FRegexPattern pattern(TEXT("(\\d*)[dD](\\d+)([+-]\\d+)?"));
    FRegexMatcher matcher(pattern, notation);

    if (!matcher.FindNext())
    {
        return FDice::INVALID_RESULT;
    }

    if (matcher.GetCaptureGroup(1).Len() > 0)
    {
        number = FCString::Atoi(*matcher.GetCaptureGroup(1));
    }

    dice = FCString::Atoi(*matcher.GetCaptureGroup(2));

    if (matcher.GetCaptureGroup(3).Len() > 0)
    {
        modifier = FCString::Atoi(*matcher.GetCaptureGroup(3));
    }
    
    return FDice::Roll(number, dice, modifier, bAllowNegative);
}

int32 FDice::Roll(int32 Number, int32 Dice, int32 Modifier, bool bAllowNegative)
{
    if (!(Number > 0))
    {
        return FDice::INVALID_RESULT;
    }

    if (!(Dice > 0))
    {
        return FDice::INVALID_RESULT;
    }

    int32 val = 0;

    for (int32 i = 0; i < Number; ++i)
    {
        val += FMath::RandRange(1, Dice);
    }

    val += Modifier;

    if (!bAllowNegative && (val < 0))
    {
        val = 0;
    }

    return val;
}

動作確認

3d6のダイスロールを行う場合は以下の様に呼び出します。

#include "Dice.h"

void hoge()
{
    int32 val = FDice::Roll(3, 6);
}
#include "Dice.h"

void hoge()
{
    int32 val = FDice::Roll("3d6");
}