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,
}
}
}