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 }