Files
bd2/go/internal/gamedata/gacha_fixed_test.go
T
2026-09-21 09:53:46 +08:00

78 lines
3.9 KiB
Go

package gamedata
import "testing"
func TestCostumeGuaranteedFourAndFiveCountsAcrossOneAndTen(t *testing.T) {
pool := []WeightedCostume{
{Weight: 150, Children: []WeightedCostume{{ID: 5001, Weight: 1}}},
{Weight: 150, Children: []WeightedCostume{{ID: 5002, Weight: 1}}},
{Weight: 1400, Children: []WeightedCostume{{ID: 4001, Weight: 1}}},
{Weight: 8300, Children: []WeightedCostume{{ID: 3001, Weight: 1}}},
}
fixed := GachaFixedDesign{ID: 1, CostumeGrade4Count: 10, CostumeGrade5Count: 100, ResetOnMatchingGrade: true}
chooseThree := func(limit uint64) (uint64, error) {
if limit == 10000 {
return 9999, nil
}
return 0, nil
}
// The first of a ten-pull hits the shared four-star boundary after nine
// unsuccessful singles, and the next nine slots continue the new count.
gacha := RegularGacha{ID: 1, Count: 10, PriceType: 3, Price: 2000, Pool: pool}
roll, state, err := gacha.rollWithCostumeFixed(9, 25, fixed, nil, nil, chooseThree)
if err != nil {
t.Fatal(err)
}
if len(roll) != 10 || roll[0] != 4001 || state.CostumeGrade4Sort != 0 || state.CostumeGrade4Count != 9 || state.CostumeGrade5Count != 35 || state.CostumeGrade5Sort != -1 {
t.Fatalf("four-star boundary roll=%v state=%+v", roll, state)
}
// When both boundaries coincide, the five-star guarantee has priority;
// it resets both counters and is sampled from the genuine 50/50 5-star
// branches, never from a synthetic hardcoded character.
roll, state, err = gacha.rollWithCostumeFixed(9, 99, fixed, nil, nil, chooseThree)
if err != nil {
t.Fatal(err)
}
if roll[0] != 5001 || state.CostumeGrade5Sort != 0 || state.CostumeGrade4Sort != -1 || state.CostumeGrade4Count != 9 || state.CostumeGrade5Count != 9 {
t.Fatalf("five-star priority roll=%v state=%+v", roll, state)
}
// Natural five-stars reset both counters without falsely reporting a
// guaranteed slot in GachaFixedDBInfo.ApplySortId.
gacha.Count = 1
chooseFive := func(limit uint64) (uint64, error) { return 0, nil }
roll, state, err = gacha.rollWithCostumeFixed(8, 98, fixed, nil, nil, chooseFive)
if err != nil || roll[0] != 5001 || state.CostumeGrade4Count != 0 || state.CostumeGrade5Count != 0 || state.CostumeGrade4Sort != -1 || state.CostumeGrade5Sort != -1 {
t.Fatalf("natural five-star roll=%v state=%+v err=%v", roll, state, err)
}
}
func TestTwelvePickSelectionAppliesToNaturalAndPityFiveStar(t *testing.T) {
pool := []WeightedCostume{
{Weight: 300, Children: []WeightedCostume{{ID: 5001, Weight: 1}}},
{Weight: 1400, Children: []WeightedCostume{{ID: 4001, Weight: 1}}},
{Weight: 8300, Children: []WeightedCostume{{ID: 3001, Weight: 1}}},
}
gacha := RegularGacha{ID: 101, Count: 1, PriceType: 3, Price: 200, Pool: pool}
fixed := GachaFixedDesign{ID: 8, CostumeGrade4Count: 10, CostumeGrade5Count: 100, ResetOnMatchingGrade: true}
selected := []uint64{5012, 5013}
chooseFirst := func(limit uint64) (uint64, error) { return 0, nil }
roll, state, err := gacha.rollWithCostumeFixed(0, 0, fixed, selected, selected, chooseFirst)
if err != nil || len(roll) != 1 || roll[0] != 5012 || len(state.SelectionSorts) != 1 || state.SelectionSorts[0] != 0 || state.CostumeGrade5Sort != -1 {
t.Fatalf("ordinary selected five roll=%v state=%+v err=%v", roll, state, err)
}
roll, state, err = gacha.rollWithCostumeFixed(9, 99, fixed, selected, selected, chooseFirst)
if err != nil || len(roll) != 1 || roll[0] != 5012 || state.CostumeGrade5Sort != 0 || len(state.SelectionSorts) != 1 || state.SelectionSorts[0] != 0 {
t.Fatalf("guaranteed selected five roll=%v state=%+v err=%v", roll, state, err)
}
chooseThree := func(limit uint64) (uint64, error) {
if limit == 10000 {
return 9999, nil
}
return 0, nil
}
roll, state, err = gacha.rollWithCostumeFixed(0, 0, fixed, selected, selected, chooseThree)
if err != nil || roll[0] != 3001 || len(state.SelectionSorts) != 0 || state.CostumeGrade4Count != 1 || state.CostumeGrade5Count != 1 {
t.Fatalf("ordinary three roll=%v state=%+v err=%v", roll, state, err)
}
}