Files
hjha-server/PdkFriendServer/Logic/PdkGameMain_Card.cs
xiaoou e9616125ce feat: initial commit - HJHA game server full source
6 major server modules (PdkFriendServer/GlobalSever/ServerCore/GameModule/GameNetModule) +
game logic (GameFix/GameDAL/ServerData) +
network layer (NetWorkMessage) +
data layer (ObjectModel) +
utilities (MrWu/Core/Config/CloudAPI/dll) +
adapters (zyxAdapter/base)

.NET 8.0 C# solution, 16 projects, 958 source files
2026-07-07 12:02:15 +08:00

349 lines
14 KiB
C#
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

using ObjectModel.Tool;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using GameFix.Poker;
using GameMessage.PaoDeKuaiF;
using GameFix.PaoDeKuaiF;
namespace PdkFriendServer.Logic
{
public partial class PdkGameMain
{
/// <summary>
/// 随机值
/// </summary>
public readonly Random Random = new Random(unchecked((int)DateTime.UtcNow.Ticks));
/// <summary>
/// 发牌
/// </summary>
public void InitCard()
{
/*1、经典玩法(必压)、--经典玩法16张玩法一副牌去掉大小王、三个2保留黑桃2和黑桃 A 共48张每人16张
15张玩法(必压)、--15张玩法有大必压一副牌去掉大小王、三个2保留黑桃2和三个A保留黑桃 A 去掉一个K共45张每人15张
关牌(不必压) --一副牌去掉大小王、三个2保留黑桃2和黑桃 A 共48张每人16张*/
byte count = 0;//每个人分多少张牌
int del2 = 3; //删除2的张数
int delA = 1;//删除A的张数
int delK = 3;//删除K的张数
TCardInfoPdkF[] allCards = null; //初始化牌库
if (Rule.JingDianWanFa || Rule.GuanPai)
{
count = 16;
delK = 0;
allCards = new TCardInfoPdkF[48];
}
if (Rule.Zhang15)
{
delA = 3;
delK = 1;
count = 15;
allCards = new TCardInfoPdkF[45];
}
int idx = 0;
for (byte i = 1; i <= 52; i++)
{
PukeTool.ConvertCard(i, out var flower, out var num);
if (del2 > 0 && num == 2 && flower != 1)
{
del2--;
continue;
}
if (delA > 0 && num == 1 && flower != 1)
{
delA--;
continue;
}
if (delK > 0 && num == 13 && flower != 1)
{
delK--;
continue;
}
allCards[idx].ID = i;
allCards[idx].Flower = (byte)flower;
allCards[idx].Num = (byte)num;
allCards[idx].GameNum = (byte)(num == 1 ? 14 : num == 2 ? 16 : num);
allCards[idx].GameOwer = 0;
allCards[idx].Score = 0;
allCards[idx].GameState = 1;
idx++;
}
for (byte i = 1; i < GamePack.Info.PlayNum; i++)
{
PukeTool.ShuffleArray(ref allCards, Random);
}
idx = 0;
//给玩家发牌
int hei3Wei = -1;//黑桃三发牌的位置
if (logicMemory.WarCount == 0 && Rule.HeiTao3BiChu)
{//如果是首局而且是每局黑桃三必出,则第一局必须要发黑桃三
hei3Wei = Random.Next(0, GamePack.Info.PlayNum);
}
if (hei3Wei >= 0)
{ //要发黑桃3
List<TCardInfoPdkF> cards = allCards.ToList();
for (int i = 0; i < GamePack.Info.PlayNum; i++)
{
GamePack.CardPack.Cards[i].Init(count);
int j = 0;
while (j < count)
{
if (j == 0 && i == hei3Wei)
{
TCardInfoPdkF temp = cards.Find(x => x.GameNum == 3 && x.Flower == 1);
if (temp.ID > 0)
{
this.GamePack.CardPack.Cards[i].CardInfos[j] = temp;
cards.Remove(temp);
}
else
{ //如果没有找到说明黑桃3已经被别人拿走了就不找了。
this.GamePack.CardPack.Cards[i].CardInfos[j] = cards[0];
cards.RemoveAt(0);
}
}
else
{
this.GamePack.CardPack.Cards[i].CardInfos[j] = cards[0];
cards.RemoveAt(0);
}
j++;
}
GamePack.Info.ShenYuCard[i] = count;
}
}
else
{ //以前写法
for (int i = 0; i < GamePack.Info.PlayNum; i++)
{
GamePack.CardPack.Cards[i].Init(count);
for (int j = 0; j < count; j++)
{
this.GamePack.CardPack.Cards[i].CardInfos[j] = allCards[idx++];
}
GamePack.Info.ShenYuCard[i] = count;
}
}
for (int i = 0; i < GamePack.Info.PlayNum; i++)
{
SortWanJiaPaiByGameNum(i + 1);
#if DEBUG
if (this.DeskGameDo == null)
{
Log($"-------------{(i + 1)}开始-----------------------------");
for (int j = 0; j < this.GamePack.CardPack.Cards[i].CardInfos.Length; j++)
{
Log(this.GamePack.CardPack.Cards[i].CardInfos[j].ToString());
}
}
#endif
}
}
/// <summary>
/// 排序某个玩家手牌,按游戏中的大小排序
/// </summary>
/// <param name="pos">玩家位置从1开始</param>
void SortWanJiaPaiByGameNum(int pos)
{
if (pos <= 0 || pos > GamePack.Info.PlayNum) throw new Exception($"参数错误 pos:{pos}");
pos--;
Array.Sort(this.GamePack.CardPack.Cards[pos].CardInfos, (x, y) => (y.GameNum * 10 - y.Flower).CompareTo((x.GameNum * 10 - x.Flower)));
}
/// <summary>
/// 设置玩家出牌
/// </summary>
/// <param name="pos"></param>
/// <param name="ids"></param>
void SetCardToOut(int pos, byte[] ids)
{
if (ids == null || ids.Length <= 0) return;
if (pos <= 0 || pos > GamePack.Info.PlayNum) throw new Exception($"参数错误 pos:{pos}");
pos--;
GamePack.Info.ShenYuCard[pos] = (byte)(GamePack.Info.ShenYuCard[pos] - ids.Length);
foreach (var id in ids)
{
for (int i = 0; i < this.GamePack.CardPack.Cards[pos].CardInfos.Length; i++)
{
if (this.GamePack.CardPack.Cards[pos].CardInfos[i].ID == id)
{
this.GamePack.CardPack.Cards[pos].CardInfos[i].GameState = 0;
break;
}
}
}
#if DEBUG
Log($"---------------------{(pos + 1)}----- shengyu:{GamePack.Info.ShenYuCard[pos]}-------------");
//for (int i = 0; i < this.GamePack.CardPack.Cards[pos].CardInfos.Length; i++)
//{
// if (this.GamePack.CardPack.Cards[pos].CardInfos[i].GameState == 0) continue;
// Log(this.GamePack.CardPack.Cards[pos].CardInfos[i].ToString());
//}
#endif
}
/// <summary>
/// 根据牌的绝对Id返回牌的详细信息
/// </summary>
/// <param name="pos">玩家位置从1开始</param>
/// <param name="ids">牌的Id集合</param>
/// <returns></returns>
TCardInfoPdkF[] GetCardByIds(int pos, byte[] ids)
{
if (ids == null || ids.Length <= 0) return null;
if (pos <= 0 || pos > GamePack.Info.PlayNum) return null;
pos--;
return PokerLogic.GetCardByIds(GamePack.CardPack.Cards[pos].CardInfos, ids);
}
/// <summary>
/// 计算玩家炸弹个数
/// </summary>
/// <param name="pos">玩家位置从0开始</param>
/// <returns></returns>
byte CalcPlayBombRule(int pos)
{
if (pos < 0 || pos >= GamePack.Info.PlayNum) return 0;
Dictionary<int, int> dic = new Dictionary<int, int>();
foreach (var item in GamePack.CardPack.Cards[pos].CardInfos)
{
if (dic.ContainsKey(item.GameNum))
{
dic[item.GameNum]++;
}
else
{
dic[item.GameNum] = 1;
}
}
byte result = 0;
foreach (var item in dic)
{
if (item.Value <= 2) continue;
if (Rule.AAAIsZhaDan && item.Key == 14 && item.Value == 3)
{
result++;
continue;
}
if (item.Value == 4)
{
result++;
}
}
return result;
}
/// <summary>
/// 检测玩家的飞机如果有4连以上的飞机就需要换牌
/// </summary>
/// <param name="pos"></param>
/// <returns></returns>
void CheckFeiJi()
{
try
{
int pos = -1; //有4连飞机的位置
List<int> feiji = null;
for (int j = 0; j < GamePack.Info.PlayNum; j++)
{
feiji = GetFeiJiCount(GamePack.CardPack.Cards[j].CardInfos);
if (feiji != null && feiji.Count > 3)
{
pos = j;
Log($"飞机数量:{string.Join(",", feiji)},飞机位置:{pos + 1},房号:{this.DeskGameDo.desk.deskinfo.roomNum}", MrWu.Debug.DebugLevel.Warning);
break;
}
}
if (pos < 0) return;
for (int i = 0; i < GamePack.Info.PlayNum; i++)
{
if (i != pos)
{
int idx = -1;
for (int j = 0; j < GamePack.CardPack.Cards[pos].CardInfos.Length; j++)
{
if (GamePack.CardPack.Cards[pos].CardInfos[j].GameNum == feiji[2])
{
idx = j;
break;
}
}
if (idx < 0)
{
Log($"没有找到4连飞机的下标日{idx}", MrWu.Debug.DebugLevel.Warning);
return;
}
for (int i3 = 0; i3 < GamePack.CardPack.Cards[i].CardInfos.Length - 1; i3++)
{
//交换其中一张牌
TCardInfoPdkF temp = GamePack.CardPack.Cards[i].CardInfos[i3];
if (feiji.IndexOf(temp.GameNum) >= 0) continue; //换的牌不能是飞机的牌,要不容易重复和换出新的炸弹
Log($"换牌信息:{temp.GameNum}", MrWu.Debug.DebugLevel.Warning);
GamePack.CardPack.Cards[i].CardInfos[i3] = GamePack.CardPack.Cards[pos].CardInfos[idx];
GamePack.CardPack.Cards[pos].CardInfos[idx] = temp;
for (int i2 = 0; i2 < GamePack.Info.PlayNum; i2++)
{
SortWanJiaPaiByGameNum(i2 + 1);
}
return;
}
}
}
}
catch (Exception e)
{
Log($"CheckFeiJi msg:{e.Message}, code:{e.StackTrace}", MrWu.Debug.DebugLevel.Error);
}
}
/// <summary>
/// 获取一个玩家的飞机牌型
/// </summary>
/// <param name="selectCards">玩家手里的牌</param>
/// <returns>玩家的飞机集合</returns>
public static List<int> GetFeiJiCount(TCardInfoPdkF[] selectCards)
{
if (selectCards == null || selectCards.Length < 6) return null;
List<PokerLogic.XY> list = new List<PokerLogic.XY>();
foreach (var item in selectCards)
{
var t = list.Find(x => x.x == item.GameNum);
if (t != null)
{
t.y++;
}
else
{
list.Add(new PokerLogic.XY { x = item.GameNum, y = 1 });
}
}
int num = list.Count(x => x.y >= 3);
if (num < 2) return null;
list = list.Where(x => x.y >= 3).ToList();
List<int> fj = new List<int>();
for (int i = 0; i < list.Count - 1; i++)
{
if (list[i].x - 1 == list[i + 1].x)
{
if (!fj.Contains(list[i].x))
{
fj.Add(list[i].x);
}
if (!fj.Contains(list[i + 1].x))
{
fj.Add(list[i + 1].x);
}
}
}
return fj;
}
}
}