package setsmatch import ( "math/rand" "sync" ) type arrangemanager struct { targetCount int // 撮合人数 maxLevel int // 最多分配多少等级的用户,超过等待,等级一般是当前已打的局数 totalCount int // 剩下总人数 userlist map[int]*arrangeuser lock *sync.RWMutex index int } func createArrangeManager(targetCount int) *arrangemanager { ret := new(arrangemanager) ret.targetCount = targetCount ret.ctor() return ret } func (am *arrangemanager) ctor() { am.lock = &sync.RWMutex{} am.userlist = make(map[int]*arrangeuser) } func (am *arrangemanager) getUser(userId int) *arrangeuser { am.lock.RLock() au, ok := am.userlist[userId] am.lock.RUnlock() if !ok { return nil } return au } func (am *arrangemanager) addUser(userId int, level int, ip string, tryArrange bool) [][]int { au := am.getUser(userId) if au != nil { au.Level = level au.IP = ip } else { am.lock.Lock() am.userlist[userId] = &arrangeuser{UserId: userId, Level: level, IP: ip} am.lock.Unlock() } if !tryArrange { return [][]int{} } return am.checkAndArrange() } func (am *arrangemanager) removeUser(userId int) { am.lock.Lock() delete(am.userlist, userId) am.lock.Unlock() } func (am *arrangemanager) setUserLevel(userId int, level int) { au := am.getUser(userId) if au != nil { au.Level = level } } func (am *arrangemanager) setUserIP(userId int, ip string) { au := am.getUser(userId) if au != nil { au.IP = ip } } func (am *arrangemanager) setTotalUserCount(count int) { am.totalCount = count } func (am *arrangemanager) getAllIds() []int { var ret []int am.lock.RLock() for _, v := range am.userlist { ret = append(ret, v.UserId) } am.lock.RUnlock() return ret } func (am *arrangemanager) checkAndArrange() [][]int { var ret [][]int allIds := am.getAllIds() userCount := len(allIds) if userCount < am.targetCount { return ret } // 只剩下一桌 了 if am.totalCount == am.targetCount && userCount == am.targetCount { ret = append(ret, allIds) return ret } // 多余两桌才撮合 if userCount < am.targetCount*2 && am.totalCount >= am.targetCount*2 { return ret } // 把用户打乱 for i := len(allIds) - 1; i > 1; i-- { pos := rand.Intn(i) allIds[pos], allIds[i] = allIds[i], allIds[pos] } tableCount := userCount / am.targetCount for i := 0; i < tableCount; i++ { var t []int for j := 0; j < am.targetCount; j++ { t = append(t, allIds[i*am.targetCount+j]) } ret = append(ret, t) } return ret }