using System; using System.Collections.Concurrent; using System.Collections.Generic; using System.IO; using System.Runtime.CompilerServices; using GameDAL.FriendRoom; using MrWu.Debug; using Newtonsoft.Json; namespace Server { // 配置倍率 平衡区间 比如 20 倍的 平衡参数 7500 // 2 倍 平衡参数 1000 // // 根据倍率 配置那些人需要平衡 public partial class LuckPlayerManager { private BalanceData _balanceData = new BalanceData(); /// /// 所有的平衡配置 /// private List BalanceAllConfigs => _balanceData.BalanceRanges; private Dictionary BalanceRangesDic = new Dictionary(); /// /// 初始化,添加,删除 才需修改 /// private Dictionary RulesDic = new Dictionary(); private const string BalanceDataPath = "LuckRecord/ClubBalanceData.txt"; public float GetBalanceRangeId(float beilv, int fightCnt) { return fightCnt * 10000 + beilv; } /// /// 获取所有的配置 /// /// public IEnumerable GetAllBalanceRange() { return BalanceAllConfigs; } /// /// 添加平衡区间 /// /// 倍率 /// 总局数 /// 平衡值 /// public bool AddBalanceRange(float beilv, int fightCnt, int balanceValue) { BalanceRange balanceRange = GetBalanceRange(beilv, fightCnt); if (balanceRange == null) { balanceRange = new BalanceRange() { BeiLv = beilv, MaxFightCnt = fightCnt, BalanceValue = balanceValue }; BalanceAllConfigs.Add(balanceRange); //添加所有玩家 for (int i = 0; i < _balanceData.UserIds.Count; i++) { AddBalancePlayer(balanceRange, _balanceData.UserIds[i]); } return true; } return false; } public bool SetBalanceRange(float beilv, int fightCnt, int balanceValue) { if (balanceValue < 1000) { Debug.Error("平衡参数过低!"); return false; } BalanceRange balanceRange = GetBalanceRange(beilv, fightCnt); if (balanceRange != null) { balanceRange.BalanceValue = balanceValue; return true; } return false; } /// /// 移除平衡区间 /// /// /// /// public bool RemoveBalanceRange(float beilv, int fightCnt) { BalanceRange balanceRange = GetBalanceRange(beilv, fightCnt); if (balanceRange == null) { return false; } BalanceRangesDic.Remove(balanceRange.Id); BalanceAllConfigs.Remove(balanceRange); return true; } public BalanceRange GetBalanceRange(float id) { if (!BalanceRangesDic.TryGetValue(id, out BalanceRange balanceRange)) { for (int i = 0; i < BalanceAllConfigs.Count; i++) { if (Math.Abs(BalanceAllConfigs[i].Id - id) < 0.001f) { balanceRange = BalanceAllConfigs[i]; BalanceRangesDic[id] = balanceRange; } } } return balanceRange; } public BalanceRange GetBalanceRange(float beiLv, int fightCnt) { return GetBalanceRange(GetBalanceRangeId(beiLv, fightCnt)); } public bool AddRoomRateRule(float beiLv, int fightCnt, int modeType) { BalanceRoomRateRule rule = GetRoomRateRule(beiLv, fightCnt); if (rule != null) { return false; } rule = new BalanceRoomRateRule() { ModeType = modeType, BeiLv = beiLv, FightCnt = fightCnt }; RulesDic[GetBalanceRangeId(beiLv, fightCnt)] = rule; _balanceData.Rules.Add(rule); return true; } public bool RemoveRoomRateRule(float beiLv, int fightCnt) { BalanceRoomRateRule rule = GetRoomRateRule(beiLv, fightCnt); if (rule == null) { return false; } bool result = _balanceData.Rules.Remove(rule); if (result && !RulesDic.Remove(GetBalanceRangeId(beiLv, fightCnt))) { Debug.Error("未能删除规则"); return false; } return result; } public bool AddRoomRateRuleItem(float beiLv, int fightCnt, int minScore, int maxScore, int roomRate) { BalanceRoomRateRule rule = GetRoomRateRule(beiLv, fightCnt); if (rule == null) { return false; } if (maxScore <= minScore || roomRate <= 0) { return false; } for (int i = 0; i < rule.Ranges.Count; i++) { if (maxScore <= rule.Ranges[i].MinScore || minScore > rule.Ranges[i].MaxScore) { continue; } Debug.Error("区间有交叉!"); return false; } rule.Ranges.Add(new BalanceRoomRange() { MinScore = minScore, MaxScore = maxScore, Rate = roomRate }); return true; } public bool RemoveRoomRateRuleItem(float beiLv, int fightCnt, int minScore, int maxScore, int roomRate) { BalanceRoomRateRule rule = GetRoomRateRule(beiLv, fightCnt); if (rule == null) { return false; } for (int i = 0; i < rule.Ranges.Count; i++) { if (rule.Ranges[i].MinScore == minScore && rule.Ranges[i].MaxScore == maxScore && roomRate == rule.Ranges[i].Rate) { rule.Ranges.RemoveAt(i); return true; } } return false; } public BalanceRoomRateRule GetRoomRateRule(float beiLv, int fightCnt) { if (RulesDic.TryGetValue(GetBalanceRangeId(beiLv, fightCnt), out BalanceRoomRateRule roomRateRule)) { return roomRateRule; } return null; } public List> GetBalancePlayers(int userid) { List> balancePlayers = new List>(); for (int i = 0; i < BalanceAllConfigs.Count; i++) { BalancePlayer player = GetBalancePlayer(BalanceAllConfigs[i], userid); if (player == null) { break; } balancePlayers.Add(new Tuple(BalanceAllConfigs[i], player)); } return balancePlayers; } public BalancePlayer GetBalancePlayer(BalanceRange balanceRange, int userid) { if (balanceRange.BalancePlayersDic.TryGetValue(userid, out BalancePlayer player)) { return player; } return null; } public bool AddBalancePlayer(int userid) { if (ExistsPlayer(userid)) { return false; } _balanceData.UserIds.Add(userid); //为每个玩法都添加上 for (int i = 0; i < BalanceAllConfigs.Count; i++) { AddBalancePlayer(BalanceAllConfigs[i], userid); } return true; } public bool RemoveBalancePlayer(int userid) { if (_balanceData.UserIds.Remove(userid)) { for (int i = 0; i < BalanceAllConfigs.Count; i++) { RemoveBalancePlayer(BalanceAllConfigs[i], userid); } return true; } return false; } private void AddBalancePlayer(BalanceRange balanceRange, int userid) { balanceRange.BalancePlayersDic.TryAdd(userid, new BalancePlayer() { UserId = userid }); } private void RemoveBalancePlayer(BalanceRange balanceRange, int userid) { if (balanceRange.BalancePlayersDic.TryRemove(userid, out BalancePlayer _balance)) { Debug.Info($"移除用户:{_balance.Score}"); } } public bool ExistsPlayer(int userid) { for (int i = 0; i < _balanceData.UserIds.Count; i++) { if (_balanceData.UserIds[i] == userid) { return true; } } return false; } public List FindBalancePlayer(int userid) { List logs = new List(); for (int i = 0; i < BalanceAllConfigs.Count; i++) { BalancePlayer banBalancePlayer = GetBalancePlayer(BalanceAllConfigs[i], userid); if (banBalancePlayer == null) { continue; } logs.Add( $"倍率:{BalanceAllConfigs[i].BeiLv} 总局数:{BalanceAllConfigs[i].MaxFightCnt} {banBalancePlayer.ToString()}"); } return logs; } /// /// 加载俱乐部平衡数据 /// private void LoadClubBalanceData() { if (!File.Exists(BalanceDataPath)) { return; } string jsondata = File.ReadAllText(BalanceDataPath); _balanceData = JsonConvert.DeserializeObject(jsondata); for (int i = 0; i < BalanceAllConfigs.Count; i++) { foreach (var balancePlayer in BalanceAllConfigs[i].BalancePlayers) { BalanceAllConfigs[i].BalancePlayersDic[balancePlayer.UserId] = balancePlayer; } } if (_balanceData.Rules != null) { for (int i = 0; i < _balanceData.Rules.Count; i++) { RulesDic[_balanceData.Rules[i].Id] = _balanceData.Rules[i]; } } } private void SaveClubBalanceData() { if (BalanceAllConfigs.Count <= 0) { return; } FileInfo fileInfo = new FileInfo(BalanceDataPath); if (!fileInfo.Directory.Exists) { fileInfo.Directory.Create(); } for (int i = 0; i < BalanceAllConfigs.Count; i++) { BalanceAllConfigs[i].BalancePlayers.Clear(); BalanceAllConfigs[i].BalancePlayers.AddRange(BalanceAllConfigs[i].BalancePlayersDic.Values); } File.WriteAllText(BalanceDataPath, JsonConvert.SerializeObject(_balanceData)); } public bool SetSessionFightScore(float beilv, int fightCnt, int userid, int score) { BalanceRange balanceRange = GetBalanceRange(beilv, fightCnt); if (balanceRange == null) { return false; } BalancePlayer balancePlayer = GetBalancePlayer(balanceRange, userid); if (balancePlayer == null) { return false; } balancePlayer.Score += score; return true; } /// /// 添加一场战斗的分 /// /// /// /// /// 是否是大赢家 public void AddSessionFightScore(float beilv, int fightCnt, int userid, int score, bool isBigWinner) { BalanceRange balanceRange = GetBalanceRange(beilv, fightCnt); if (balanceRange == null) { return; } BalancePlayer balancePlayer = GetBalancePlayer(balanceRange, userid); if (balancePlayer == null) { return; } Debug.Info($"AddSessionFightScore: {userid} {score}"); //先得到规则 BalanceRoomRateRule rule = GetRoomRateRule(beilv, fightCnt); if (rule != null) //处理房费 { //得到区间 BalanceRoomRange range = null; for (int i = 0; i < rule.Ranges.Count; i++) { if (score > rule.Ranges[i].MinScore && score <= rule.Ranges[i].MaxScore) { range = rule.Ranges[i]; break; } } if (range != null) { if (rule.ModeType == 1 || (rule.ModeType == 2 && isBigWinner)) { score -= range.Rate; balancePlayer.RoomRate += range.Rate; Debug.Info($"扣除房费:{balancePlayer.RoomRate}"); } } } balancePlayer.Score += score; balancePlayer.TempScore = 0; } /// /// 添加一局战斗的分 子 /// /// /// /// public void AddOnceFightScore(float beilv, int fightCnt, int userid, int score) { BalanceRange balanceRange = GetBalanceRange(beilv, fightCnt); if (balanceRange == null) { Debug.Info($"没找到玩法! {beilv} {fightCnt}"); return; } BalancePlayer balancePlayer = GetBalancePlayer(balanceRange, userid); if (balancePlayer == null) { Debug.Info($"没找到玩法 玩家:{userid}!"); return; } Debug.Info($"AddOnceFightScore : {userid} {(score * beilv)}"); balancePlayer.TempScore += (int)(score * beilv); } /// /// 获取平衡数据 /// /// /// /// public ClubPlayerBalanceType GetBalancePlayerType(float beilv, int fightCnt, int userid) { BalanceRange balanceRange = GetBalanceRange(beilv, fightCnt); if (balanceRange == null) { return ClubPlayerBalanceType.None; } BalancePlayer balancePlayer = GetBalancePlayer(balanceRange, userid); if (balancePlayer == null) { return ClubPlayerBalanceType.None; } int score = balancePlayer.TempScore + balancePlayer.Score; int diffValue = Math.Abs(score) - balanceRange.BalanceValue; if (diffValue <= 0) { Debug.Info($"已经是平衡状态! {userid}"); return ClubPlayerBalanceType.Normal; } float rate = (diffValue / (float)balanceRange.BalanceValue) * 0.5f; if (score < 0) //输了就加大发牌概率 { rate *= 2f; } Debug.Info($"计算概率:{userid} {diffValue} {balancePlayer.Score} {rate}"); Random random = GetRandom(); bool isBalance = random.NextDouble() < rate; ReleaseRandom(random); if (isBalance) { return score > 0 ? ClubPlayerBalanceType.BadLuck : ClubPlayerBalanceType.Luck; } return ClubPlayerBalanceType.Normal; } public class BalanceData { /// /// 房费规则 /// public List Rules = new List(); /// /// 玩法配置 /// public List BalanceRanges = new List(); /// /// 所有玩家 /// public List UserIds = new List(); } /// /// 房费规则 /// public class BalanceRoomRateRule { /// /// 这个用来做ID /// [JsonIgnore] public float Id { get { return FightCnt * 10000 + BeiLv; } } /// /// 模式类型 1 所有人出 2 大赢家出 /// public int ModeType; /// /// 房费 /// public float BeiLv; /// /// 总局数 /// public int FightCnt; /// /// 区间 /// public List Ranges = new List(); } /// /// 房费区间 /// public class BalanceRoomRange { /// /// 最小值 /// public int MinScore; /// /// 最大值 /// public int MaxScore; /// /// 房费 /// public int Rate; } /// /// 平衡区间 /// public class BalanceRange { /// /// 这个用来做ID /// [JsonIgnore] public float Id { get { return MaxFightCnt * 10000 + BeiLv; } } /// /// 倍率 /// public float BeiLv; /// /// 总局数 /// public int MaxFightCnt; /// /// 平衡值 /// public int BalanceValue; /// /// 平衡玩家的数据 /// public List BalancePlayers = new List(); [JsonIgnore] public ConcurrentDictionary BalancePlayersDic = new ConcurrentDictionary(); } /// /// 平衡玩家数据 /// public class BalancePlayer { /// /// 玩家ID /// public int UserId; /// /// 当前分值 /// public int Score; /// /// 临时计算用,这个是小局分 /// public int TempScore; /// /// 房费 /// public int RoomRate; public override string ToString() { return $"Userid:{UserId},Score:{Score},RoomRate:{RoomRate}"; } } public enum ClubPlayerBalanceType { /// /// 不参与平衡 /// None = 0, /// /// 正常 /// Normal = 1, /// /// 幸运 /// Luck = 2, /// /// 不幸运 /// BadLuck = 3, } } }