Commit cd9440a89baf1e6e371706ecfabe16b5d50c8ad2

Authored by 王家文
1 parent 36626272
Exists in master and in 1 other branch dev-wjw

feat✨:房间排行活动逻辑

service/roomrank/consts.go
... ... @@ -4,5 +4,6 @@ const (
4 4 UserClassMin = 1 // 最小评级
5 5 UserClassMax = 5 // 最大评级
6 6  
7   - RoomCloseSecond = 180 // 房间关闭时间
  7 + RoomCloseSecond = 180 // 房间关闭时间
  8 + RoomResetRobotSecond = 300 // 改变机器人分数并重新排序的间隔时间
8 9 )
... ...
service/roomrank/dto-room.go
... ... @@ -19,7 +19,9 @@ type Room struct {
19 19 Details *RoomDetails `gorm:"-"` // 详情
20 20 DetailsText string `gorm:"comment:详情封装"`
21 21  
22   - Closed bool `gorm:"comment:房间已关闭"`
  22 + Closed bool `gorm:"comment:房间已关闭"`
  23 + ResetRobotTime int64 `gorm:"comment:上次刷新机器人时间"`
  24 + HasSettle bool `gorm:"comment:是否结算"`
23 25  
24 26 CreateTime int64 `gorm:"comment:创建时间戳"`
25 27 UpdateTime int64 `gorm:"comment:修改时间戳"`
... ... @@ -38,7 +40,7 @@ type RoomPlayer struct {
38 40 Uid int64 // 玩家唯一ID
39 41 Score int64 // 玩家排行分数
40 42 JoinTime int64 // 加入时间
41   - UserType int // 用户类型
  43 + UserType int // 用户类型 -1=原生配置机器人
42 44 RobotConfigId int // 0=玩家
43 45 }
44 46  
... ... @@ -111,3 +113,30 @@ func (d *Room) GetPlayerTypeCount(userType int) int {
111 113 return p.UserType == userType
112 114 })
113 115 }
  116 +
  117 +/* 排名规则 降序
  118 +- 如果是玩家之间的分数相同,则先达到该分数的玩家排名靠前
  119 +- 如果是机器人之间的分数相同,则按照计算的处理先后顺序进行排序,或者随机排序,因为不重要
  120 +- 如果是玩家和机器人之间的分数相同,则玩家排名永远高于机器人排名
  121 +*/
  122 +
  123 +func (d *RoomDetails) Len() int {
  124 + return len(d.Players)
  125 +}
  126 +func (d *RoomDetails) Less(i, j int) bool {
  127 + if d.Players[i].Score != d.Players[j].Score {
  128 + return d.Players[i].Score > d.Players[j].Score
  129 + }
  130 + // 如果是玩家和机器人之间的分数相同,则玩家排名永远高于机器人排名
  131 + if d.Players[i].RobotConfigId != d.Players[j].RobotConfigId {
  132 + return d.Players[i].RobotConfigId < d.Players[j].RobotConfigId
  133 + }
  134 + // 如果是玩家之间的分数相同,则先达到该分数的玩家排名靠前
  135 + if d.Players[i].RobotConfigId == 0 && d.Players[j].RobotConfigId == 0 {
  136 + return d.Players[i].JoinTime > d.Players[j].JoinTime
  137 + }
  138 + return d.Players[i].Score > d.Players[j].Score
  139 +}
  140 +func (d *RoomDetails) Swap(i, j int) {
  141 + d.Players[i], d.Players[j] = d.Players[j], d.Players[i]
  142 +}
... ...
service/roomrank/handle.go
... ... @@ -41,17 +41,21 @@ func HandleInfo(req *models.ReqRoomRankInfo) (code string, rsp models.RspRoomRan
41 41 // 尝试判断结算
42 42 hasSettle := TrySettle(gameId, player, config)
43 43  
  44 + if hasSettle {
  45 + SavePlayer(gameId, player)
  46 + rsp.RoomRankInfo = GetInfo(player, config)
  47 + return
  48 + }
  49 +
44 50 // 尝试加入房间
45 51 room, hasRoom := TryGetRoom(gameId, player, config, playerLevel)
46 52  
47   - if hasSettle || hasRoom {
48   - SavePlayer(gameId, player)
49   - }
50 53 if hasRoom {
  54 + TryReSort(room, config)
  55 +
  56 + SavePlayer(gameId, player)
51 57 SaveRoom(gameId, room)
52 58 }
53 59  
54   - rsp.RoomRankInfo = GetInfo(player, config)
55   -
56 60 return
57 61 }
... ...
service/roomrank/logic.go
... ... @@ -30,6 +30,7 @@ func TrySettle(gameId string, player *Player, config *confroomrank.ActivityConfi
30 30 if !hasConfActivity {
31 31 return
32 32 }
  33 + TrySettleRoom(gameId, room, confActivity)
33 34 // 设置玩家奖励等数据
34 35 hasChange = true
35 36 player.SettleHas = true
... ...
service/roomrank/room.go
... ... @@ -5,6 +5,9 @@ import (
5 5 "apigame/service-common/svmysql"
6 6 "apigame/util/util-lx/lxalilog"
7 7 "apigame/util/util-lx/lxtime"
  8 + "math"
  9 + "math/rand/v2"
  10 + "sort"
8 11 )
9 12  
10 13 func tryInitTable(gameId string, room *Room) {
... ... @@ -50,6 +53,7 @@ func CreateRoom(gameId string, activityId int64, roomConfigId int) (room *Room,
50 53 room.ActivityId = activityId
51 54 room.ConfigId = roomConfigId
52 55 room.Closed = false
  56 + room.HasSettle = false
53 57 room.CreateTime = lxtime.NowUninx()
54 58 details := new(RoomDetails)
55 59 details.Players = make([]*RoomPlayer, 0)
... ... @@ -135,6 +139,10 @@ func TryGetRoom(gameId string, player *Player, config *confroomrank.ActivityConf
135 139 roomCreate, hasCreate := CreateRoom(gameId, config.Id, roomConfigId)
136 140 if hasCreate {
137 141 room = roomCreate
  142 +
  143 + // 配置原生机器人
  144 + JoinInitRobot(room, roomConfig)
  145 +
138 146 PlayerJoinRoom(room, player)
139 147 hasRoom = hasCreate
140 148 }
... ... @@ -181,3 +189,96 @@ func GetTypeCanJoinCount(room *Room, roomConfig confroomrank.RoomConfig, userTyp
181 189 }
182 190 return maxCount - room.GetPlayerTypeCount(userType)
183 191 }
  192 +
  193 +// JoinInitRobot 配置原生机器人
  194 +func JoinInitRobot(room *Room, roomConfig confroomrank.RoomConfig) {
  195 + for i := 0; i < len(roomConfig.InitRobot); i++ {
  196 + pair := roomConfig.InitRobot[i]
  197 + robotConfigId := pair[0]
  198 + robotCount := pair[1]
  199 + for i := 0; i < robotCount; i++ {
  200 + roomPlayer := NewRoomRobot(robotConfigId, -1)
  201 + room.Details.Players = append(room.Details.Players, roomPlayer)
  202 + }
  203 + }
  204 +}
  205 +
  206 +// TrySettleRoom 尝试结算房间
  207 +func TrySettleRoom(gameId string, room *Room, confActivity *confroomrank.ActivityConfig) {
  208 + if room.HasSettle {
  209 + return
  210 + }
  211 + // 机器人最终算分
  212 + for i := 0; i < len(room.Details.Players); i++ {
  213 + roomPlayer := room.Details.Players[i]
  214 + if roomPlayer.RobotConfigId == 0 {
  215 + continue
  216 + }
  217 + confRobot, hasConfRobot := confActivity.Robot[roomPlayer.RobotConfigId]
  218 + if hasConfRobot {
  219 + roomPlayer.Score = GetRobotScoreMax(&confRobot)
  220 + }
  221 + }
  222 +
  223 + sort.Sort(room.Details)
  224 + room.HasSettle = true
  225 + SaveRoom(gameId, room)
  226 +}
  227 +
  228 +// TryResetRobot 尝试改变机器人分数并重新排序
  229 +func TryResetRobot(room *Room, config *confroomrank.ActivityConfig) {
  230 + secNow := lxtime.NowUninx()
  231 + if secNow < room.ResetRobotTime+RoomResetRobotSecond {
  232 + return
  233 + }
  234 + // 机器人即时算分
  235 + for i := 0; i < len(room.Details.Players); i++ {
  236 + roomPlayer := room.Details.Players[i]
  237 + if roomPlayer.RobotConfigId == 0 {
  238 + continue
  239 + }
  240 + confRobot, hasConfRobot := config.Robot[roomPlayer.RobotConfigId]
  241 + if hasConfRobot {
  242 + roomPlayer.Score = GetRobotScoreCurrent(config, &confRobot, secNow)
  243 + }
  244 + }
  245 +}
  246 +
  247 +// TryReSort 尝试重新排序
  248 +func TryReSort(room *Room, config *confroomrank.ActivityConfig) {
  249 + TryResetRobot(room, config)
  250 + sort.Sort(room.Details)
  251 +}
  252 +
  253 +// GetRobotScoreCurrent 从机器人配置里得到实时得分
  254 +func GetRobotScoreCurrent(config *confroomrank.ActivityConfig, confRobot *confroomrank.RobotConfig, secNow int64) int64 {
  255 + percent := float64(0)
  256 + if config.EndTime <= config.StartTime {
  257 + percent = 0
  258 + } else if secNow <= config.StartTime {
  259 + percent = 0
  260 + } else if secNow >= config.EndTime {
  261 + percent = 100
  262 + } else {
  263 + percent = float64(secNow-config.StartTime) * 100 / float64(config.EndTime-config.StartTime)
  264 + }
  265 +
  266 + score := (float64(confRobot.TotalScore-confRobot.MinScore) *
  267 + float64(100-confRobot.TotalRate+rand.IntN(confRobot.TotalRate*2)) / 100) * percent / 100
  268 + result := int64(confRobot.MinScore) + int64(math.Ceil(score))
  269 + if result < int64(confRobot.MinScore) {
  270 + result = int64(confRobot.MinScore)
  271 + }
  272 + return result
  273 +}
  274 +
  275 +// GetRobotScoreMax 从机器人配置里得到最高分
  276 +func GetRobotScoreMax(confRobot *confroomrank.RobotConfig) int64 {
  277 + score := float64(confRobot.TotalScore-confRobot.MinScore) *
  278 + float64(100-confRobot.TotalRate+rand.IntN(confRobot.TotalRate*2)) / float64(100)
  279 + result := int64(confRobot.MinScore) + int64(math.Ceil(score))
  280 + if result < int64(confRobot.MinScore) {
  281 + result = int64(confRobot.MinScore)
  282 + }
  283 + return result
  284 +}
... ...