/// <summary> /// 请求弃牌 /// </summary> /// <param name="uid"></param> private void RepDisCard(int uid) { if (!UserFight.ContainsKey(uid) || !LoopOrder.Contains(uid)) { DebugUtil.Instance.LogToTime(uid + "请求弃牌失败,没有此玩家"); return; } if (DisCardList.Contains(uid)) { DebugUtil.Instance.LogToTime(uid + "请求弃牌失败,已经弃过牌了"); return; } if (LoopOrder.Count < 2) { DebugUtil.Instance.LogToTime(uid + "请求弃牌失败,玩家不足了,最后一个人直接胜利"); return; } //广播玩家弃牌消息 Broadcast(FightProtocol.TPDISCARD_BRQ, uid); //将玩家添加到弃牌列表中 DisCardList.Add(uid); //将玩家从当前玩家列表中删除 LoopOrder.Remove(uid); DebugUtil.Instance.LogToTime(uid + "请求弃牌成功"); //TODO:NEXT LOOPORDER(继续下一个玩家) if (LoopOrder.Count == 1) { GameOver(); } }
// Returns an index "first" and a direction "dir" such that the vertex // sequence (first, first + dir, ..., first + (n - 1) * dir) does not change // when the loop vertex order is rotated or reversed. This allows the loop // vertices to be traversed in a canonical order. public static LoopOrder GetCanonicalLoopOrder(S2PointLoopSpan loop) { // In order to handle loops with duplicate vertices and/or degeneracies, we // return the LoopOrder that minimizes the entire corresponding vertex // *sequence*. For example, suppose that vertices are sorted // alphabetically, and consider the loop CADBAB. The canonical loop order // would be (4, 1), corresponding to the vertex sequence ABCADB. (For // comparison, loop order (4, -1) yields the sequence ABDACB.) // // If two or more loop orders yield identical minimal vertex sequences, then // it doesn't matter which one we return (since they yield the same result). // For efficiency, we divide the process into two steps. First we find the // smallest vertex, and the set of vertex indices where that vertex occurs // (noting that the loop may contain duplicate vertices). Then we consider // both possible directions starting from each such vertex index, and return // the LoopOrder corresponding to the smallest vertex sequence. int n = loop.Count; if (n == 0) { return(new LoopOrder(0, 1)); } var min_indices = new List <int> { 0 }; for (int i = 1; i < n; ++i) { if (loop[i] <= loop[min_indices[0]]) { if (loop[i] < loop[min_indices[0]]) { min_indices.Clear(); } min_indices.Add(i); } } var min_order = new LoopOrder(min_indices[0], 1); foreach (int min_index in min_indices) { var order1 = new LoopOrder(min_index, 1); var order2 = new LoopOrder(min_index + n, -1); if (IsOrderLess(order1, min_order, loop)) { min_order = order1; } if (IsOrderLess(order2, min_order, loop)) { min_order = order2; } } return(min_order); }
// Returns the geodesic curvature of the loop, defined as the sum of the turn // angles at each vertex (see S2.TurnAngle). The result is positive if the // loop is counter-clockwise, negative if the loop is clockwise, and zero if // the loop is a great circle. The geodesic curvature is equal to 2*Pi minus // the area of the loop. // // The following cases are handled specially: // // - Degenerate loops (consisting of an isolated vertex or composed entirely // of sibling edge pairs) have a curvature of 2*Pi exactly. // // - The full loop (containing all points, and represented as a loop with no // vertices) has a curvature of -2*Pi exactly. // // - All other loops have a non-zero curvature in the range (-2*Pi, 2*Pi). // For any such loop, reversing the order of the vertices is guaranteed to // negate the curvature. This property can be used to define a unique // normalized orientation for every loop. public static double GetCurvature(S2PointLoopSpan loop) { // By convention, a loop with no vertices contains all points on the sphere. if (!loop.Any()) { return(-S2.M_2_PI); } // Remove any degeneracies from the loop. loop = PruneDegeneracies(loop); // If the entire loop was degenerate, it's turning angle is defined as 2*Pi. if (!loop.Any()) { return(S2.M_2_PI); } // To ensure that we get the same result when the vertex order is rotated, // and that the result is negated when the vertex order is reversed, we need // to add up the individual turn angles in a consistent order. (In general, // adding up a set of numbers in a different order can change the sum due to // rounding errors.) // // Furthermore, if we just accumulate an ordinary sum then the worst-case // error is quadratic in the number of vertices. (This can happen with // spiral shapes, where the partial sum of the turning angles can be linear // in the number of vertices.) To avoid this we use the Kahan summation // algorithm (http://en.wikipedia.org/wiki/Kahan_summation_algorithm). LoopOrder order = GetCanonicalLoopOrder(loop); int i = order.first, dir = order.dir, n = loop.Count; var sum = S2.TurnAngle( loop.GetRemIndex(i + n - dir), loop.GetRemIndex(i), loop.GetRemIndex(i + dir)); double compensation = 0; // Kahan summation algorithm while (--n > 0) { i += dir; var angle = S2.TurnAngle( loop.GetRemIndex(i - dir), loop.GetRemIndex(i), loop.GetRemIndex(i + dir)); double old_sum = sum; angle += compensation; sum += angle; compensation = (old_sum - sum) + angle; } const double kMaxCurvature = S2.M_2_PI - 4 * S2.DoubleEpsilon; sum += compensation; return(Math.Max(-kMaxCurvature, Math.Min(kMaxCurvature, dir * sum))); }
/// <summary> /// 请求看牌 /// </summary> /// <param name="uid">看牌的玩家</param> private void ReqCheckCard(int uid) { if (!UserFight.ContainsKey(uid) || !LoopOrder.Contains(uid)) { DebugUtil.Instance.LogToTime(uid + "请求看牌失败,没有此玩家"); return; } if (CheckList.Contains(uid)) { DebugUtil.Instance.LogToTime(uid + "请求看牌失败,已经看过牌了"); return; } //告知玩家自己的手牌 SendMessage(uid, FightProtocol.TPCHECKCARD_SRES, UserFight[uid].poker); //通知所有人,自己看过牌了 Broadcast(FightProtocol.TPCHECKCARD_BRQ, uid); //将看牌的玩家添加到列表中 CheckList.Add(uid); DebugUtil.Instance.LogToTime(uid + "请求看牌成功,房间号:" + RoomId); }
/// <summary> /// 处理下注事件 /// </summary> /// <param name="uid"></param> /// <param name="coin"></param> /// <param name="initCoin"></param> private void Bet(int uid, int coin, bool initCoin) { //将当前下注玩家和下注金额添加到集合中,等待结算 if (!BetCoinList.ContainsKey(uid)) { BetCoinList.Add(uid, new List <int>()); } BetCoinList[uid].Add(coin); //声明待广播的数据,将下注数据广播 TPBetModel tpm = new TPBetModel(); tpm.id = uid; tpm.coin = coin; tpm.isAdd = initCoin; Broadcast(FightProtocol.TPBETCOIN_BRQ, tpm); //更新玩家筹码后广播给所有玩家 UserFight[uid].coin -= coin; Broadcast(FightProtocol.PLAYERINFO_BRQ, UserFight[uid]); //将当前玩家移动到最后面,让下一家发话 LoopOrder.Add(LoopOrder[0]); LoopOrder.RemoveAt(0); DebugUtil.Instance.LogToTime(uid + "下注" + coin + "房间号" + RoomId + "是否看牌" + CheckList.Contains(uid)); }
private static int GetCoord(LoopOrder loopOrder, int loopLevel) { return(loopCoords[(int)loopOrder, loopLevel]); }
/// <summary> /// 请求比牌 /// </summary> /// <param name="uid">比牌的玩家</param> /// <param name="cid">被比牌的玩家</param> private void ReqComCard(int uid, int cid) { if (!UserFight.ContainsKey(uid) || !LoopOrder.Contains(uid)) { DebugUtil.Instance.LogToTime(uid + "请求比牌失败,没有此玩家"); return; } if (!UserFight.ContainsKey(cid) || !LoopOrder.Contains(cid)) { DebugUtil.Instance.LogToTime(cid + "请求比牌失败,没有此玩家"); return; } if (LoopOrder [0] != uid) { DebugUtil.Instance.LogToTime(cid + "请求比牌错误,当前不是此玩家"); SendMessage(uid, FightProtocol.TPCOMCARD_SRES, -2); return; } if (!IsGameStart) { DebugUtil.Instance.LogToTime(uid + "请求错误,游戏尚未开始"); SendMessage(uid, FightProtocol.TPCOMCARD_SRES, -3); return; } int coin = NowScore; if (CheckList.Contains(uid)) { coin *= 2; } if (coin == 4) { coin = 5; } //将当前下注玩家和下注金额添加到集合中,等待结算 if (!BetCoinList.ContainsKey(uid)) { BetCoinList.Add(uid, new List <int>()); } BetCoinList[uid].Add(NowScore); //声明待广播的数据,将下注数据广播 TPBetModel tpm = new TPBetModel(); tpm.id = uid; tpm.coin = coin; tpm.isAdd = false; Broadcast(FightProtocol.TPBETCOIN_BRQ, tpm); //更新玩家筹码后广播给所有玩家 UserFight[uid].coin -= coin; Broadcast(FightProtocol.PLAYERINFO_BRQ, UserFight[uid]); //首轮可比 三轮可比 五轮可比 //默认首轮可比,将玩家的手牌和被比玩家的手牌传入,获取结果 bool GetResult = TPokerUtil.GetComparePoker(UserFight[uid].poker, UserFight[cid].poker); DebugUtil.Instance.LogToTime(uid + "请求和" + cid + "比牌,比牌结果为:" + GetResult); for (int i = 0; i < LoopOrder.Count; i++) { TPCompareModel model = new TPCompareModel(); model.userId = uid; model.compId = cid; model.Result = GetResult; //如果是比牌或被比牌的玩家,则可以看到牌 if (LoopOrder [i] == uid || LoopOrder [i] == cid) { model.PokerList1.AddRange(UserFight[uid].poker); model.PokerList2.AddRange(UserFight[cid].poker); } SendMessage(LoopOrder[i], FightProtocol.TPCOMCARD_BRQ, model); } if (GetResult) { LoopOrder.Remove(cid); } else { LoopOrder.Remove(uid); } if (LoopOrder.Count == 1) { GameOver(); } }
/// <summary> /// 请求下注 /// </summary> /// <param name="uid">请求下注的玩家</param> /// <param name="coin">请求下注的金额</param> private void ReqBet(int uid, int coin) { //下注金额coin== -1,是跟注,否则加注 bool initCoin = coin == -1 ? false : true; if (!UserFight.ContainsKey(uid) || !LoopOrder.Contains(uid)) { DebugUtil.Instance.LogToTime("请求错误,没有此玩家"); SendMessage(uid, FightProtocol.TPBETCOIN_SRES, -1); return; } if (LoopOrder [0] != uid) { DebugUtil.Instance.LogToTime(uid + "请求错误,当前不是此玩家"); SendMessage(uid, FightProtocol.TPBETCOIN_SRES, -2); return; } if (!IsGameStart) { DebugUtil.Instance.LogToTime("请求错误,游戏尚未开始"); SendMessage(uid, FightProtocol.TPBETCOIN_SRES, -3); return; } //是否看过牌 if (CheckList.Contains(uid)) { //跟注 if (coin == -1) { coin = NowScore * 2; if (coin == 4) { coin = 5; } } initCoin = coin == (NowScore * 2) ? false : true; if (coin == 5 && NowScore == 2) { initCoin = false; } //是否小于最小可下注金额 if (coin < NowScore * 2) { DebugUtil.Instance.LogToTime(uid + "请求下注失败,当前可下注金额最小为:" + (NowScore * 2)); SendMessage(uid, FightProtocol.TPBETCOIN_SRES, -4); return; } //是否大于最大下注金额 if (coin > MaxScore) { DebugUtil.Instance.LogToTime(uid + "请求下注失败,当前可下注金额最大为:" + MaxScore); SendMessage(uid, FightProtocol.TPBETCOIN_SRES, -5); return; } if (coin == 5) { NowScore = 2; } } else { if (coin == -1) { coin = NowScore; } initCoin = coin == NowScore ? false : true; //是否小于最小可下注金额 if (coin < NowScore) { DebugUtil.Instance.LogToTime(uid + "请求下注失败,当前可下注金额最小为:" + NowScore); SendMessage(uid, FightProtocol.TPBETCOIN_SRES, -4); return; } //是否大于最大下注金额 if (coin > MaxScore / 2) { DebugUtil.Instance.LogToTime(uid + "请求下注失败,当前可下注金额最大为:" + (MaxScore / 2)); SendMessage(uid, FightProtocol.TPBETCOIN_SRES, -5); return; } NowScore = coin; } // Bet(uid, coin, initCoin); }