Commit cd9440a89baf1e6e371706ecfabe16b5d50c8ad2
1 parent
36626272
Exists in
master
and in
1 other branch
feat✨:房间排行活动逻辑
Showing
5 changed files
with
144 additions
and
8 deletions
Show diff stats
service/roomrank/consts.go
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
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 | +} | ... | ... |