diff --git a/src/server/game/mod/seven_login/seven_login_func.go b/src/server/game/mod/seven_login/seven_login_func.go index 81d205e7..6562e570 100644 --- a/src/server/game/mod/seven_login/seven_login_func.go +++ b/src/server/game/mod/seven_login/seven_login_func.go @@ -18,36 +18,37 @@ const ( ) func randWeekReward(Add, Type int) map[int]Reward { - RewardList := sevenLoginCfg.GetSevenLoginReward() - sort.Slice(RewardList, func(i, j int) bool { - return RewardList[i].Id < RewardList[j].Id + rewardList := sevenLoginCfg.GetSevenLoginReward() + sort.Slice(rewardList, func(i, j int) bool { + return rewardList[i].Id < rewardList[j].Id }) jackpot := sevenLoginCfg.GetSevenLoginJackpot(0) sort.Slice(jackpot, func(i, j int) bool { return jackpot[i].Energy < jackpot[j].Energy }) - RI := make([]int, 0, len(RewardList)) - for _, v := range RewardList { - RI = append(RI, v.Id) + rI := make([]int, 0, len(rewardList)) + for _, v := range rewardList { + rI = append(rI, v.Id) } - CardPackIds := GoUtil.RandSliceNumNonAdjacent(RI, 3) + cardPackIds := GoUtil.RandSliceNumNonAdjacent(rI, 3) result := make(map[int]Reward) - LastType := 0 - EnergyMul := 1.0 + lastType := []int{} + energyMul := 1.0 if Type == BACK_REWARD { - EnergyMul = 2.0 + energyMul = 2.0 } - for _, v := range RewardList { + for _, v := range rewardList { v.Energy = float64(v.Energy) * (1 + float64(Add)/100) - Reward := randReward(v, LastType, jackpot, CardPackIds, 0.5, EnergyMul) - result[v.Id] = Reward + rewardData, randItemType := randReward(v, lastType, jackpot, cardPackIds, 0.5, energyMul) + lastType = randItemType + result[v.Id] = rewardData } return result } -func randReward(RewardData *gamedata.SevenLoginRewardData, LastType int, jackpot []*gamedata.SevenLoginJackpotData, CardPackIds []int, EnergyPer, EnergyMul float64) Reward { +func randReward(RewardData *gamedata.SevenLoginRewardData, LastType []int, jackpot []*gamedata.SevenLoginJackpotData, CardPackIds []int, energyPer, EnergyMul float64) (Reward, []int) { // 奖励1 体力 体力等价钻石占总价值的50%,且1钻≈2.5体力;体力值四舍五入,需以0或5结尾 - Num := math.Round(float64(RewardData.Energy) * 0.5) + Num := math.Round(float64(RewardData.Energy) * energyPer) energyNum := float64(int(Num/5)) * 5 RemainEnergy := RewardData.Energy - energyNum // 召回玩家 每日体力数*2 @@ -56,15 +57,12 @@ func randReward(RewardData *gamedata.SevenLoginRewardData, LastType int, jackpot // 奖励2 NewJackpot := make([]*gamedata.SevenLoginJackpotData, 0, len(jackpot)) for _, v := range jackpot { - if v.Energy <= RemainEnergy && v.Type != LastType && v.Type != JACKPOT_CARD_TYPE { + if v.Energy <= RemainEnergy && !GoUtil.InArray(v.Type, LastType) && v.Type != JACKPOT_CARD_TYPE { NewJackpot = append(NewJackpot, v) } } - if len(NewJackpot) == 0 { - return Reward{Item1: Item1} - } var Item2 []*item.Item - Item2Type := 0 + ItemType := []int{} if RewardData.RewardNum == 3 { RemainEnergy -= 5 } @@ -79,22 +77,27 @@ func randReward(RewardData *gamedata.SevenLoginRewardData, LastType int, jackpot Item2 = []*item.Item{item.NewItem(item.ITEM_ENERGY_ID, int(RemainEnergy))} } else { Index := rand.IntN(len(CardJackpot)) - Item2Type = CardJackpot[Index].Type + ItemType = append(ItemType, CardJackpot[Index].Type) Item2 = CardJackpot[Index].Items RemainEnergy -= CardJackpot[Index].Energy } } else { - Index := rand.IntN(len(NewJackpot)) - Item2Type = NewJackpot[Index].Type - Item2 = NewJackpot[Index].Items - RemainEnergy -= NewJackpot[Index].Energy + if len(NewJackpot) == 0 { + return Reward{Item1: Item1}, nil + } + sort.Slice(NewJackpot, func(i, j int) bool { + return NewJackpot[i].Energy > NewJackpot[j].Energy + }) + ItemType = append(ItemType, NewJackpot[0].Type) + Item2 = NewJackpot[0].Items + RemainEnergy -= NewJackpot[0].Energy } var Item3 []*item.Item if RewardData.RewardNum == 3 { RemainEnergy += 5 NewJackpot3 := make([]*gamedata.SevenLoginJackpotData, 0, len(jackpot)) for _, v := range jackpot { - if v.Energy <= RemainEnergy && v.Type != LastType && v.Type != Item2Type { + if v.Energy <= RemainEnergy && !GoUtil.InArray(v.Type, LastType) && !GoUtil.InArray(v.Type, ItemType) { NewJackpot3 = append(NewJackpot3, v) } } @@ -104,33 +107,38 @@ func randReward(RewardData *gamedata.SevenLoginRewardData, LastType int, jackpot Item1: Item1, Item2: Item2, Item3: Item3, - } + }, ItemType } - Index := rand.IntN(len(NewJackpot3)) - Item3 = NewJackpot3[Index].Items + sort.Slice(NewJackpot3, func(i, j int) bool { + return NewJackpot3[i].Energy > NewJackpot3[j].Energy + }) + Item3 = NewJackpot3[0].Items + ItemType = append(ItemType, NewJackpot3[0].Type) } return Reward{ Item1: Item1, Item2: Item2, Item3: Item3, - } + }, ItemType } func randMonthReward() map[int]Reward { month := GoUtil.NowMonth() - RewardList := sevenLoginCfg.GetSevenLoginMonthReward(month) - sort.Slice(RewardList, func(i, j int) bool { - return RewardList[i].Id < RewardList[j].Id + rewardList := sevenLoginCfg.GetSevenLoginMonthReward(month) + sort.Slice(rewardList, func(i, j int) bool { + return rewardList[i].Id < rewardList[j].Id }) jackpot := sevenLoginCfg.GetSevenLoginJackpot(1) sort.Slice(jackpot, func(i, j int) bool { return jackpot[i].Energy < jackpot[j].Energy }) + lastType := []int{} result := make(map[int]Reward) - for _, v := range RewardList { - Reward := randReward(v, 0, jackpot, []int{}, 0.65, 1) - result[v.Id] = Reward + for _, v := range rewardList { + reward, lastItemType := randReward(v, lastType, jackpot, []int{}, 0.65, 1) + lastType = lastItemType + result[v.Id] = reward } return result } diff --git a/src/server/game_util/GoUtil.go b/src/server/game_util/GoUtil.go index 954a35d3..f6e46086 100644 --- a/src/server/game_util/GoUtil.go +++ b/src/server/game_util/GoUtil.go @@ -17,6 +17,7 @@ import ( "net/http" "reflect" "server/pkg/github.com/name5566/leaf/log" + "sort" "strconv" "strings" "sync" @@ -356,6 +357,24 @@ func Rand8DigitNumber() string { return fmt.Sprintf("%08d", n) } +// RandThreeNonAdjacent 从 [1, x] 中随机抽取 3 个两两不相邻的数。 +func RandThreeNonAdjacent(x int) ([]int, error) { + if x < 5 { + return nil, fmt.Errorf("x must be >= 5") + } + + // 先在 [1, x-2] 中均匀抽 3 个不重复数,再通过偏移构造为不相邻的结果。 + base := rand.Perm(x - 2)[:3] + sort.Ints(base) + + ret := make([]int, 3) + for i, v := range base { + ret[i] = (v + 1) + i + } + + return ret, nil +} + func UniqueInts(input []int) []int { seen := make(map[int]struct{}) result := make([]int, 0, len(input)) diff --git a/src/server/game_util/sliceUtil.go b/src/server/game_util/sliceUtil.go index 51887e22..178446a5 100644 --- a/src/server/game_util/sliceUtil.go +++ b/src/server/game_util/sliceUtil.go @@ -128,15 +128,15 @@ func RandSliceNumNonAdjacent(s []int, num int) []int { for len(result) < num { Id := rand.Intn(len(slice)) result = append(result, slice[Id]) - slice = SubAdjacentElemSlice(slice, Id) + slice = SubAdjacentElemSlice(slice, slice[Id]) } return result } func SubAdjacentElemSlice(s []int, Id int) []int { r := make([]int, 0, len(s)) - for k, v := range s { - if k < Id-1 || k > Id+1 { + for _, v := range s { + if v < Id-1 || v > Id+1 { r = append(r, v) } } diff --git a/src/server/test/fix_test.go b/src/server/test/fix_test.go index 22d304b7..7c77ae4b 100644 --- a/src/server/test/fix_test.go +++ b/src/server/test/fix_test.go @@ -292,3 +292,11 @@ func TestGeoIp(t *testing.T) { code, _ := GoUtil.GetCountryByIP(ip) fmt.Printf("IP: %s, Country Code: %s\n", ip, code) } + +func TestRandAn(t *testing.T) { + rI := []int{1, 2, 3, 4, 5, 6, 7} + for i := 0; i < 10; i++ { + randNum := GoUtil.RandSliceNumNonAdjacent(rI, 3) + fmt.Printf("Random Number: %v\n", randNum) + } +} diff --git a/src/server/test/seven_test.go b/src/server/test/seven_test.go index b0cdf9b0..8cd74f3d 100644 --- a/src/server/test/seven_test.go +++ b/src/server/test/seven_test.go @@ -22,9 +22,9 @@ func TestSevenLoginZeroUpdate(t *testing.T) { SevenLoginMod.ZeroUpdate(0, 0, p1.GetOrderFactor()) SevenLoginMod.BackData() fmt.Printf("order factor:%v\n", p1.GetOrderFactor()) - for _, v := range SevenLoginMod.LoginReward { - t.Logf("Reward:%v", v) - fmt.Printf("Reward:%v\n", v) + for k, v := range SevenLoginMod.LoginReward { + t.Logf("Reward:%v\n", v) + fmt.Printf("id :%d ; Reward:%v\n", k, v) } - t.Logf("SevenLoginMod:%v", SevenLoginMod) + t.Logf("SevenLoginMod:%v\n", SevenLoginMod.MonthReward) }