📄 ddzdesk.cs
字号:
/*
开发人 :小宝 qq:42353066
开发时间:07.05.09
功能 :出牌检测、判断发牌、简单的智能出牌等
*/
using System;
using System.IO;
using System.Text;
using System.Collections;
using System.Collections.Generic;
using System.Threading;
using Message;
namespace Services
{
internal class DdzDesk
{
private Dictionary<string, DdzPoke> deskTopUserList = new Dictionary<string, DdzPoke>();
internal Dictionary<string, DdzPoke> DeskTopUserList
{
get { return deskTopUserList; }
}
private bool isGameEnd = false;
internal bool IsGameEnd
{
get { return isGameEnd; }
}
private int matchid = 0; //本局ID
private int game_no = 0; //局数
private string cardstr;
private int[] orgalCard;
private int dizhuPlayer = 0; //地主是哪一家
private ArrayList diCard; //底牌
private int setMoney; //本局最大可叫注额注额
private int thisSetMoney = 0; //本局实际叫牌注额
private int firstPlayer = 0; //最邻近的一个出牌人(除 pass 的人外,就是如果此人 pass 就是在往前一个人,依次类推)
private List<string> outCardsList = new List<string>(); //已经出过的牌(不出的用“pass”填充)
private int paiMin = 0; //牌型最小值---------当前
private PaiType paiType = PaiType.Not; //牌型---------------当前
private int chuPaiCount = 0; //牌总张数-----------当前
private int paiMin1 = 0; //牌型最小值---------上一轮
private PaiType paiType1 = PaiType.Not; //牌型---------------上一轮
private int chuPaiCount1 = 0; //牌总张数-----------上一轮
private int curPlayer = 0; //當前操作的玩家
private bool isStarted = false; //叫牌了(開始遊戲標誌)
private bool isEnded = false;
private Thread thread; //准备
private Thread thread1; //哪家叫牌,和出牌
private Thread thread2; //结束发牌, 到开始叫牌
private int thread1Count = 40;
private bool isMakeup = true; //准备好了,可以开始
//private bool isTest = false;
internal DdzDesk(ArrayList alist, int _setMoney)
{
setMoney = _setMoney;
deskTopUserList.Add(((UserInfo)alist[0]).UserName, new DdzPoke(1, (UserInfo)alist[0]));
deskTopUserList.Add(((UserInfo)alist[1]).UserName, new DdzPoke(2, (UserInfo)alist[1]));
deskTopUserList.Add(((UserInfo)alist[2]).UserName, new DdzPoke(3, (UserInfo)alist[2]));
}
internal void InitProc()
{
foreach (DdzPoke ddzPoke in deskTopUserList.Values)
{
ddzPoke.userinfo.SendXml((int)MessageEnum.StartDDZ);
}
thread = new Thread(new ThreadStart(ThreadZhunBeiOk));
thread.Start();
}
internal void StartGame()
{
cardstr = "";
diCard = new ArrayList();
orgalCard = new int[] { 1011, 1021, 1031, 1041, 1051, 1061, 1071, 1081, 1091, 1101, 1111, 1121, 1131, 1012, 1022, 1032, 1042, 1052, 1062, 1072, 1082, 1092, 1102, 1112, 1122, 1132, 1013, 1023, 1033, 1043, 1053, 1063, 1073, 1083, 1093, 1103, 1113, 1123, 1133, 1014, 1024, 1034, 1044, 1054, 1064, 1074, 1084, 1094, 1104, 1114, 1124, 1134, 5015, 5025, 0 };
XiPaiRandom();
//orgalCard[orgalCard.Length - 1] = 12 + order; //随机抽取地主牌是第几张牌?
for (int i = 0; i < orgalCard.Length; i++)
{
cardstr += orgalCard[i].ToString() + ",";
}
cardstr = cardstr.Remove(cardstr.Length - 1);
#region 测试用
//if (isTest)
//{
// cardstr = "1044,1073,1101,1113,1021,1072,1062,1014,1023,1121,1084,1071,1053,1082,1061,1042,1094,1022,1052,1093,1131,1011,1083,1104,1031,1092,1102,1033,1103,5025,1034,1081,1134,1122,1064,1032,5015,1124,1074,1012,1112,1051,1013,1133,1091,1054,1111,1114,1024,1123,1063,1041,1043,1132,25";
// string[] tmpOrgalCard = cardstr.Split(',');
// for (int i = 0; i < tmpOrgalCard.Length; i++)
// {
// orgalCard[i] = int.Parse(tmpOrgalCard[i]);
// }
//}
//else
//{
// WritePaiToText("地主为:" + dizhuPlayer.ToString() + System.Environment.NewLine + "牌型为:" + cardstr + "|" + System.Environment.NewLine);
//}
//
#endregion
for (int i = 0; i < orgalCard.Length - 1; )
{
if (orgalCard[orgalCard.Length - 1] == i)//谁先叫牌(做地主的优先权)
{
dizhuPlayer = 1;
}
else if (orgalCard[orgalCard.Length - 1] == i + 1)
{
dizhuPlayer = 2;
}
else if (orgalCard[orgalCard.Length - 1] == i + 2)
{
dizhuPlayer = 3;
}
foreach (DdzPoke obj in deskTopUserList.Values)
{
obj.OrgalCard.Add(new Card(orgalCard[i + obj.order - 1]));
}
i += 3;
if (diCard.Count < 3)
{
diCard.Add(new Card(orgalCard[i++])); //为底牌放
}
}
curPlayer = dizhuPlayer;
foreach (DdzPoke ddzPoke in deskTopUserList.Values)
{
ddzPoke.userinfo.SendXml((int)MessageEnum.InArea, "starting", ddzPoke.order, dizhuPlayer, cardstr); //本人order,地主order,牌型
}
game_no = Interlocked.Increment(ref DdzOnline.game_no);
string housename = "vip_";
switch(setMoney)
{
case 20:{housename +="1";break;}
case 40:{housename +="2";break;}
case 100:{housename +="3";break;}
case 200:{housename +="4";break;}
case 400:{housename +="5";break;}
case 600:{housename +="6";break;}
case 1000:{housename +="7";break;}
case 2000:{housename +="8";break;}
case 4000:{housename +="9";break;}
}
string sql = string.Format("insert into match (house,start_date,field_no,game_no,gamename) values ('{0}',getdate(),'{1}','{2}','{3}')", housename, "1", game_no, "斗地主");
SqlDataProvider.ExecuteNonQuery(sql);
sql = string.Format("select max(matchid) from match where house = '{0}' and gamename='{1}' and game_no = {2}", housename, "斗地主", game_no);
matchid = (int)SqlDataProvider.ExecuteScalar(sql);
thread2 = new Thread(new ThreadStart(ThreadEndFaPai));
thread2.Start();
}
internal void JiaoPaiNext(UserInfo userinfo ,int _jiaofen)
{
CheckTimeOut();
int order = deskTopUserList[userinfo.UserName].order;
int next = (order + 1) % 4;
if (next == 0) next = 1;
deskTopUserList[userinfo.UserName].jiaoFen = _jiaofen;
if (_jiaofen > 0) thisSetMoney = _jiaofen;
if (_jiaofen == setMoney)//叫牌成功(马上开始出牌)
{
DiPaiCopy();
SendToAll((int)MessageEnum.JiaoPai, "endjiaopai", dizhuPlayer, setMoney);
}
else
{
if (deskTopUserList[FindUserByOrder(next)].jiaoFen == -1)
{
dizhuPlayer = next;
SendToAll((int)MessageEnum.JiaoPai, "startjiaopai", dizhuPlayer, thisSetMoney); //继续由dizhuPlayer开始叫牌
DdzPoke neDP = deskTopUserList[FindUserByOrder(next)];
if (neDP.states == "tuoguan")
{
curPlayer = dizhuPlayer;
firstPlayer = dizhuPlayer;
Thread.Sleep(1000);
JiaoPaiNext(neDP.userinfo , 0);
return;
}
}
else
{
string tmpUserName = "";
foreach (DdzPoke obj in deskTopUserList.Values)
{
if (obj.jiaoFen > 0 && obj.jiaoFen == thisSetMoney)
{
tmpUserName = obj.userinfo.UserName;
break;
}
}
if (tmpUserName != "")
{
dizhuPlayer = deskTopUserList[tmpUserName].order;
DiPaiCopy();
SendToAll((int)MessageEnum.JiaoPai, "endjiaopai", dizhuPlayer, thisSetMoney); //tmpUserName 当地主(马上开始出牌)
}
else //没有人叫牌(继续回到分组中)本局结束
{
SendToAll((int)MessageEnum.JiaoPai, "overjiaopai", dizhuPlayer, thisSetMoney);
GameOver();
}
}
}
curPlayer = dizhuPlayer;
firstPlayer = dizhuPlayer; //因为每一局都是地主先出牌
}
internal void ChuPaiNext(UserInfo userinfo, string paistr)
{
CheckTimeOut();
DdzPoke meDP = deskTopUserList[userinfo.UserName];
int order = meDP.order;
if (CheckChuPai(paistr) == 0) //不符合规则
{
userinfo.SendXml((int)MessageEnum.NotRule);
return;
}
else if (firstPlayer == order && paiType == PaiType.Pass) //先出牌的人不能 Pass
{
userinfo.SendXml((int)MessageEnum.NotRule);
return;
}
else if (firstPlayer != order && paiType != PaiType.Pass)
{
if (chuPaiCount1 != chuPaiCount && paiType != PaiType.Bomb && paiType != PaiType.Rocket)
{
userinfo.SendXml((int)MessageEnum.NotRule);
return;
}
else if (paiMin1 / 10 >= paiMin / 10 && paiType != PaiType.Bomb)
{
userinfo.SendXml((int)MessageEnum.NotRule);
return;
}
else if (paiType != paiType1 && paiType != PaiType.Bomb && paiType != PaiType.Rocket)
{
userinfo.SendXml((int)MessageEnum.NotRule);
return;
}
else if ((paiType != paiType1 && paiType == PaiType.Bomb && paiType1 == PaiType.Rocket))
{
userinfo.SendXml((int)MessageEnum.NotRule);
return;
}
}
if (paiType == PaiType.Bomb || paiType == PaiType.Rocket) //炸弹
{
meDP.zhadan++;
}
outCardsList.Add(paistr);//保存我这次出的牌
meDP.paistr = paistr;
int preorder = (order + 2) % 3;
if (preorder == 0) preorder = 3;
int next = (order + 1) % 4;
if (next == 0) next = 1;
DdzPoke peDP = deskTopUserList[FindUserByOrder(preorder)];
DdzPoke neDP = deskTopUserList[FindUserByOrder(next)];
if (paistr != "pass")
{
paiMin1 = paiMin;
paiType1 = paiType;
chuPaiCount1 = chuPaiCount;
firstPlayer = order;
meDP.outpaicount += (int)(paistr.Length / 5) + 1;
meDP.outpaicishu++;
ChuPaiRecord(paistr, userinfo.UserName); //记录当前牌已出标记
if ((order == dizhuPlayer && meDP.outpaicount == 20) || (order != dizhuPlayer && meDP.outpaicount == 17))//出牌结束(发送赢输结果)
{
SendToAll((int)MessageEnum.ChuPai, order, next, firstPlayer, "end", paiType.ToString());
#region 结束结算
int result1 = 0, result2 = 0, result3 = 0;
string states = ""; //状态 如春天,反春
string match_result = "共 "+(meDP.zhadan + neDP.zhadan + peDP.zhadan).ToString() + " 炸、";
//得到牌路
AddNotOutPai(next);
AddNotOutPai(preorder);
AddUserNameOutPai();
string outAllPaiStr = string.Join("|", outCardsList.ToArray());
//结算
if (order == dizhuPlayer)
{
int cuntian = 0;
if (neDP.outpaicishu == 0 && peDP.outpaicishu == 0)
{
states = "cuntian";
cuntian = 1;
match_result += "春天!";
}
int beishu = meDP.zhadan + neDP.zhadan + peDP.zhadan + cuntian;
if (beishu > 4) beishu = 4;
result1 = 2 * thisSetMoney * (int)System.Math.Pow(2, beishu) * 95 / 100;
result2 = result3 = -1 * thisSetMoney * (int)Math.Pow(2, beishu);
WriteOrder(userinfo, result1, outAllPaiStr, match_result);
WriteOrder(neDP.userinfo, result2, outAllPaiStr, match_result);
WriteOrder(peDP.userinfo, result3, outAllPaiStr, match_result);
}
else
{
int fancun= 0;
if (deskTopUserList[FindUserByOrder(dizhuPlayer)].outpaicishu == 1)
{
states = "fancun";
fancun = 1;
match_result += "反春!";
}
int beishu = meDP.zhadan + neDP.zhadan + peDP.zhadan + fancun;
if (beishu > 4) beishu = 4;
result1 = -2 * thisSetMoney * (int)System.Math.Pow(2, beishu);
result2 = result3 = 1 * thisSetMoney * (int)System.Math.Pow(2, beishu) * 95 / 100;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -