Skip to content

Commit

Permalink
Slot: スロットをManagerから脱却
Browse files Browse the repository at this point in the history
  • Loading branch information
2RiniaR committed Nov 30, 2024
1 parent 21b93b6 commit 38ce887
Show file tree
Hide file tree
Showing 10 changed files with 173 additions and 46 deletions.
14 changes: 14 additions & 0 deletions Common/Models/AppService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ namespace Approvers.King.Common;
public class AppService : DbContext
{
public DbSet<AppState> AppStates { get; set; }
public DbSet<Slot> Slots { get; set; }
public DbSet<User> Users { get; set; }
public DbSet<GachaProbability> GachaProbabilities { get; set; }

Expand Down Expand Up @@ -40,4 +41,17 @@ public async Task<User> FindOrCreateUserAsync(ulong discordId)
Add(user);
return user;
}

public async Task<Slot> GetDefaultSlotAsync()
{
var slot = await Slots.FirstOrDefaultAsync();
if (slot != null)
{
return slot;
}

slot = new Slot { Id = Guid.NewGuid() };
Add(slot);
return slot;
}
}
50 changes: 13 additions & 37 deletions Common/Models/SlotManager.cs → Common/Models/Slot.cs
Original file line number Diff line number Diff line change
@@ -1,44 +1,19 @@
using System.ComponentModel.DataAnnotations;

namespace Approvers.King.Common;

public class SlotManager : Singleton<SlotManager>
public class Slot
{
private readonly List<SlotItem> _items = [];

/// <summary>
/// 調子(千分率)
/// </summary>
private int _conditionOffsetPermillage;

private const int ReelCount = 3;

/// <summary>
/// マスタデータを読み込む
/// </summary>
public void LoadMaster()
{
_items.Clear();
var items = MasterManager.SlotItemMaster.GetAll();
_items.AddRange(items);
}
[Key] public Guid Id { get; set; }

/// <summary>
/// 現在の状態を読み込む
/// 調子(千分率)
/// </summary>
public async Task LoadAsync()
{
await using var app = AppService.CreateSession();
_conditionOffsetPermillage = await app.AppStates.GetIntAsync(AppStateType.SlotConditionOffsetPermillage) ?? 0;
}
public int ConditionPermillage { get; set; }

/// <summary>
/// 現在の状態を保存する
/// </summary>
public async Task SaveAsync()
{
await using var app = AppService.CreateSession();
await app.AppStates.SetIntAsync(AppStateType.SlotConditionOffsetPermillage, _conditionOffsetPermillage);
await app.SaveChangesAsync();
}
public int ExecutePrice => MasterManager.SettingMaster.PricePerSlotOnce;

/// <summary>
/// 調子を再抽選する
Expand All @@ -47,28 +22,29 @@ public void ShuffleCondition()
{
var max = MasterManager.SettingMaster.SlotMaxConditionOffsetPermillage;
var min = MasterManager.SettingMaster.SlotMinConditionOffsetPermillage;
_conditionOffsetPermillage = RandomManager.GetRandomInt(min, max + 1);
ConditionPermillage = RandomManager.GetRandomInt(min, max + 1);
}

/// <summary>
/// スロットを実行する
/// </summary>
public SlotExecuteResult Execute()
{
var itemCount = _items.Count;
var items = MasterManager.SlotItemMaster.GetAll().ToList();
var itemCount = items.Count;

var reelItems = new SlotItem[ReelCount];
for (var i = 0; i < ReelCount; i++)
{
if (i == 0)
{
reelItems[i] = _items[RandomManager.GetRandomInt(itemCount)];
reelItems[i] = items[RandomManager.GetRandomInt(itemCount)];
continue;
}

// 一定確率で直前と同じ出目が出る
// 確率はマスタデータの設定値に加え、調子により変動する
var repeatPermillage = Math.Clamp(reelItems[i - 1].RepeatPermillage + _conditionOffsetPermillage, 0, MasterManager.SettingMaster.SlotRepeatPermillageUpperBound);
var repeatPermillage = Math.Clamp(reelItems[i - 1].RepeatPermillage + ConditionPermillage, 0, MasterManager.SettingMaster.SlotRepeatPermillageUpperBound);
var repeatProbability = NumberUtility.GetProbabilityFromPermillage(repeatPermillage);
var isRepeat = RandomManager.IsHit(repeatProbability);
if (isRepeat)
Expand All @@ -77,7 +53,7 @@ public SlotExecuteResult Execute()
continue;
}

reelItems[i] = _items[RandomManager.GetRandomInt(itemCount)];
reelItems[i] = items[RandomManager.GetRandomInt(itemCount)];
}

var isWin = reelItems.Select(x => x.Id).Distinct().Count() == 1;
Expand Down
6 changes: 3 additions & 3 deletions Common/Models/User.cs
Original file line number Diff line number Diff line change
Expand Up @@ -57,15 +57,15 @@ public GachaProbability RollGachaOnceCertain()
/// <summary>
/// スロットを回す
/// </summary>
public SlotExecuteResult ExecuteSlot()
public SlotExecuteResult ExecuteSlot(Slot slot)
{
if (TodaySlotExecuteCount >= MasterManager.SettingMaster.UserSlotExecuteLimitPerDay)
{
throw new AppException("今日はもう回せないぞカス");
}

var price = MasterManager.SettingMaster.PricePerSlotOnce;
var result = SlotManager.Instance.Execute();
var price = slot.ExecutePrice;
var result = slot.Execute();
var reward = (int)(NumberUtility.GetPercentFromPermillage(result.ResultRatePermillage) * price);
MonthlySlotProfitPrice += reward - price;
TodaySlotExecuteCount++;
Expand Down
1 change: 0 additions & 1 deletion Events/Admin/AdminMasterReloadPresenter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@ protected override async Task MainAsync()
await MasterManager.FetchAsync();
await Message.ReplyAsync("マスターをリロードしたぞ");

SlotManager.Instance.LoadMaster();
await UpdateGachaTableAsync();
}

Expand Down
8 changes: 6 additions & 2 deletions Events/Slot/SlotConditionRefreshPresenter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,11 @@ public class SlotConditionRefreshPresenter : SchedulerJobPresenterBase
{
protected override async Task MainAsync()
{
SlotManager.Instance.ShuffleCondition();
await SlotManager.Instance.SaveAsync();
await using var app = AppService.CreateSession();

var slot = await app.GetDefaultSlotAsync();
slot.ShuffleCondition();

await app.SaveChangesAsync();
}
}
3 changes: 2 additions & 1 deletion Events/Slot/SlotExecutePresenter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,8 @@ protected override async Task MainAsync()
await using var app = AppService.CreateSession();

var user = await app.FindOrCreateUserAsync(Message.Author.Id);
var result = user.ExecuteSlot();
var slot = await app.GetDefaultSlotAsync();
var result = user.ExecuteSlot(slot);

await app.SaveChangesAsync();

Expand Down
86 changes: 86 additions & 0 deletions Migrations/20241130181742_CreateSlot.Designer.cs

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

34 changes: 34 additions & 0 deletions Migrations/20241130181742_CreateSlot.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
using System;
using Microsoft.EntityFrameworkCore.Migrations;

#nullable disable

namespace Approvers.King.Migrations
{
/// <inheritdoc />
public partial class CreateSlot : Migration
{
/// <inheritdoc />
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.CreateTable(
name: "Slots",
columns: table => new
{
Id = table.Column<Guid>(type: "TEXT", nullable: false),
ConditionPermillage = table.Column<int>(type: "INTEGER", nullable: false)
},
constraints: table =>
{
table.PrimaryKey("PK_Slots", x => x.Id);
});
}

/// <inheritdoc />
protected override void Down(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropTable(
name: "Slots");
}
}
}
15 changes: 15 additions & 0 deletions Migrations/AppServiceModelSnapshot.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
// <auto-generated />
using System;
using Approvers.King.Common;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Infrastructure;
Expand Down Expand Up @@ -43,6 +44,20 @@ protected override void BuildModel(ModelBuilder modelBuilder)
b.ToTable("GachaProbabilities");
});

modelBuilder.Entity("Approvers.King.Common.Slot", b =>
{
b.Property<Guid>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("TEXT");
b.Property<int>("ConditionPermillage")
.HasColumnType("INTEGER");
b.HasKey("Id");
b.ToTable("Slots");
});

modelBuilder.Entity("Approvers.King.Common.User", b =>
{
b.Property<ulong>("DiscordId")
Expand Down
2 changes: 0 additions & 2 deletions Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,6 @@ private static async Task BuildAsync(string[] args)
TimeManager.Instance.Initialize();
await MasterManager.FetchAsync();
await GachaManager.Instance.LoadAsync();
SlotManager.Instance.LoadMaster();
await SlotManager.Instance.LoadAsync();
SchedulerManager.Initialize();
await DiscordManager.InitializeAsync();

Expand Down

0 comments on commit 38ce887

Please sign in to comment.