game_sync/worldsrv/coinscenematch_chess.go

287 lines
7.0 KiB
Go

package main
import (
"fmt"
"sort"
"mongo.games.com/goserver/core/logger"
"mongo.games.com/game/common"
"mongo.games.com/game/protocol/server"
"mongo.games.com/game/srvdata"
)
type ChessMatchItem struct {
Index int
Id int32
Score int64
SceneId int
}
type ChessMatchPool struct {
List []*ChessMatchItem
IdItem map[int32]*ChessMatchItem
}
func (c *ChessMatchPool) Len() int {
return len(c.List)
}
func (c *ChessMatchPool) Less(i, j int) bool {
return c.List[i].Score < c.List[j].Score
}
func (c *ChessMatchPool) Swap(i, j int) {
c.List[i].Index = j
c.List[j].Index = i
c.List[i], c.List[j] = c.List[j], c.List[i]
}
// Add .
// id snid
func (c *ChessMatchPool) Add(id int32, score int64, sceneId int) {
if _, ok := c.IdItem[id]; ok {
return
}
item := &ChessMatchItem{
Index: len(c.List),
Id: id,
Score: score,
SceneId: sceneId,
}
c.List = append(c.List, item)
c.IdItem[id] = item
sort.Sort(c)
}
func (c *ChessMatchPool) Del(id int32) {
item, ok := c.IdItem[id]
if !ok {
return
}
c.List = append(c.List[:item.Index], c.List[item.Index:]...)
for i := item.Index; i < len(c.List); i++ {
c.List[i].Index = i
}
}
// ChessMatchFunc 国际象棋匹配规则
func ChessMatchFunc(csp *CoinScenePool, p *Player, scenes map[int]*Scene, sameIpLimit bool, exclude []int32) *Scene {
if csp == nil || p == nil {
return nil
}
var cmp *ChessMatchPool
var ok bool
if csp.extraData != nil {
cmp, ok = csp.extraData.(*ChessMatchPool)
}
if !ok || cmp == nil {
logger.Logger.Errorf("ChessMatchFunc not found ChessMatchPool")
return nil
}
if p.IsRobot() || len(cmp.List) == 0 {
return nil
}
var rule *server.DB_ChessMatchRules
for _, v := range srvdata.PBDB_ChessMatchRulesMgr.Datas.Arr {
switch {
case p.ChessGrade >= int64(v.ScoreMin) && p.ChessGrade <= int64(v.ScoreMax):
rule = v
}
}
if rule == nil {
logger.Logger.Tracef("ChessMatchFunc ChessMatchRule not found %d", p.ChessGrade)
return nil
}
if cmp == nil {
logger.Logger.Tracef("ChessMatchFunc ChessMatchPool is nil")
return nil
}
if rule.MatchScoreMin > rule.MatchScoreMax {
logger.Logger.Tracef("ChessMatchFunc rule.MatchScoreMin > rule.MatchScoreMax")
return nil
}
var scene *Scene
i := sort.Search(len(cmp.List), func(i int) bool {
return cmp.List[i].Score >= int64(rule.MatchScoreMin)
})
j := sort.Search(len(cmp.List), func(i int) bool {
return cmp.List[i].Score > int64(rule.MatchScoreMax)
})
if i > j {
return nil
}
logger.Logger.Tracef("ChessMatchFunc 基础匹配范围 %d,%d", rule.MatchScoreMin, rule.MatchScoreMax)
f := func(sceneId int) bool {
s := SceneMgrSingleton.GetScene(sceneId)
// 满人,解散中,排除
if s == nil || s.IsFull() || s.deleting || common.InSliceInt32(exclude, int32(s.sceneId)) {
return false
}
// 同IP限制
if sameIpLimit && p.GMLevel == 0 && s.HasSameIp(p.Ip) {
return false
}
// 同局限制
//if s.dbGameFree.GetSamePlaceLimit() > 0 && sceneLimitMgr.LimitSamePlace(p, s) {
// return false
//}
return true
}
// 基础匹配
if i < len(cmp.List) {
for _, v := range cmp.List[i:j] {
if f(v.SceneId) {
logger.Logger.Tracef("ChessMatchFunc 基础匹配成功 %d playerScore:%d, other:%d", v.SceneId, p.ChessGrade, v.Score)
scene = SceneMgrSingleton.GetScene(v.SceneId)
break
}
}
}
// 扩展匹配
if scene == nil {
for k, v := range rule.MatchScoreLowStep {
m := sort.Search(len(cmp.List), func(i int) bool {
return cmp.List[i].Score >= int64(rule.MatchScoreMin-v)
})
n := sort.Search(len(cmp.List), func(i int) bool {
return cmp.List[i].Score > int64(rule.MatchScoreMax+rule.MatchScoreHightStep[k])
})
logger.Logger.Tracef("ChessMatchFunc 扩展匹配范围 %d,%d", rule.MatchScoreMin-v, rule.MatchScoreMax+rule.MatchScoreHightStep[k])
logger.Logger.Tracef("ChessMatchFunc 范围索引 m:%d, i:%d, j:%d, n:%d", m, i, j, n)
// [m,n]的范围应该是包含[i,j]
if m > i || j > n {
// 配置错误
break
}
if m >= 0 && m < i {
for _, v := range cmp.List[m:i] {
if f(v.SceneId) {
logger.Logger.Tracef("ChessMatchFunc 扩展匹配成功 %d playerScore:%d, other:%d", v.SceneId, p.ChessGrade, v.Score)
scene = SceneMgrSingleton.GetScene(v.SceneId)
break
}
}
}
if scene == nil {
if n >= j {
for _, v := range cmp.List[j:n] {
if f(v.SceneId) {
logger.Logger.Tracef("ChessMatchFunc 扩展匹配成功 %d playerScore:%d, other:%d", v.SceneId, p.ChessGrade, v.Score)
scene = SceneMgrSingleton.GetScene(v.SceneId)
break
}
}
}
}
if scene == nil {
i = m
j = n
} else {
break
}
}
}
return scene
}
func ChessMatchFuncTest(chessMatchPool *ChessMatchPool, chessScore int32) *Scene {
var rule *server.DB_ChessMatchRules
for _, v := range srvdata.PBDB_ChessMatchRulesMgr.Datas.Arr {
switch {
case chessScore >= v.ScoreMin && chessScore <= v.ScoreMax:
rule = v
}
}
if rule == nil {
fmt.Printf("ChessMatchFunc ChessMatchRule not found %d\n", chessScore)
return nil
}
if rule.MatchScoreMin > rule.MatchScoreMax {
fmt.Printf("ChessMatchFunc rule.MatchScoreMin > rule.MatchScoreMax\n")
return nil
}
var scene *Scene
i := sort.Search(len(chessMatchPool.List), func(i int) bool {
return chessMatchPool.List[i].Score >= int64(rule.MatchScoreMin)
})
j := sort.Search(len(chessMatchPool.List), func(i int) bool {
return chessMatchPool.List[i].Score > int64(rule.MatchScoreMax)
})
if i > j {
return nil
}
fmt.Printf("ChessMatchFunc 基础匹配范围 %d,%d\n", rule.MatchScoreMin, rule.MatchScoreMax)
fmt.Printf("ChessMatchFunc 基础匹配范围 i:%d,j:%d\n", i, j)
// 基础匹配
if i < len(chessMatchPool.List) {
for _, v := range chessMatchPool.List[i:j] {
fmt.Printf("ChessMatchFunc 基础匹配成功 %d playerScore:%d, other:%d\n", v.SceneId, chessScore, v.Score)
}
}
// 扩展匹配
if scene == nil {
for k, v := range rule.MatchScoreLowStep {
m := sort.Search(len(chessMatchPool.List), func(i int) bool {
return chessMatchPool.List[i].Score >= int64(rule.MatchScoreMin-v)
})
n := sort.Search(len(chessMatchPool.List), func(i int) bool {
return chessMatchPool.List[i].Score > int64(rule.MatchScoreMax+rule.MatchScoreHightStep[k])
})
fmt.Printf("ChessMatchFunc 扩展匹配范围 %d,%d\n", rule.MatchScoreMin-v, rule.MatchScoreMax+rule.MatchScoreHightStep[k])
fmt.Printf("ChessMatchFunc 范围索引 m:%d, i:%d, j:%d, n:%d\n", m, i, j, n)
// [m,n]的范围应该是包含[i,j]
if m > i || j > n {
// 配置错误
break
}
if m >= 0 && m < i {
for _, v := range chessMatchPool.List[m:i] {
fmt.Printf("ChessMatchFunc 扩展匹配成功 %d playerScore:%d, other:%d\n", v.SceneId, chessScore, v.Score)
}
}
if scene == nil {
if n >= j {
for _, v := range chessMatchPool.List[j:n] {
fmt.Printf("ChessMatchFunc 扩展匹配成功 %d playerScore:%d, other:%d\n", v.SceneId, chessScore, v.Score)
}
}
}
if scene == nil {
i = m
j = n
} else {
break
}
}
}
return nil
}