您的位置:首页 > 理论基础 > 计算机网络

C#三打一网络扑克游戏软件开发(一)

2010-05-16 01:03 429 查看
C#三打一网络扑克游戏软件开发(一)
——玩家叫分
该游戏主要是参照云南大理本地居民休闲时所玩的扑克游戏开发,其规则与之完全相同。因此,为了让大家能更清楚的理解整个开发过程,在开始时有必要先对整个游戏规则作个介绍。
由于本文讨论的是玩家叫分模块的开发,因此这里就先介绍叫分的规则,其余规则待讨论时再进行介绍。
在游戏开始时,首先随机选定一名玩家进行第一个叫分,之后按逆时针方向依次轮换,直到有三个玩家均选择“不叫”时,则可确定本局牌庄家为剩下的那名玩家。
在叫分时,会有一些细则进行约束。具体如下:
(先做个名词解释:)
常主:在该游戏中,王、7、2被称作常主。
1、 如果玩家有7张常主,那么该玩家在本局牌中必须叫一次庄(也就是自己在第一次叫庄时不能选择“不叫”);
2、 如果第一个叫庄的玩家选择80分,其余三名玩家均选择不叫,那叫80分的玩家在本局牌中胜出,输的玩家为其余三名玩家中常主数最多的玩家。如果常主数相同,则输家为在逆时针方向挨近庄家的玩家。
3、 第一个叫庄的玩家在第一次叫庄时只能在80分和50分范围内(包含80分和50分);
4、 如果第一个叫庄的玩家在第一次叫庄时叫了80分,则他在本局牌中失去了叫庄资格;
5、 如果当前玩家所叫出的庄分大于50,则后面的玩家所叫的庄分不能低于50,只有当其中一名玩家叫了50分后,后面的玩家才能叫小于50的庄分(包括“摆光”);
6、 如果其中一名玩家选择了“不叫”,则它在本局牌中失去了后续的叫庄资格;
7、 每个玩家所叫的庄分只能低于当前所叫出的庄分;
8、 在叫庄没有结束时,玩家可以无限次数的叫“摆光”,每叫一次“摆光”,输赢的倍率乘以二(即:庄家所输的分为基本分乘以倍率)
以上就是三打一扑克游戏的整个叫分过程,下面我们讨论怎么样通过代码来实现这个模块。
在该部分中,涉及到的条件很多,如果将这部分的代码放到和游戏主程序代码一起来开发的话,整个逻辑会变得杂乱无章,也不利于后期的测试和维护。因此,决定采用面向对象的方法,叫庄这个模块单独封装为一个对象,在这个对象中提供一些和主程序进行数据对接的接口,就可以完成整个功能。
通过上面的分析,结合VS2005平台的特点,决定将整个叫分模块作为一个控件来开发,最后主程序中使用的时候只需从工具箱中拖出来即可。
在新建项目的选择对话框中,我们选择“Windows窗体控件库”,便可进入到控件开发界面。该界面和Windows应用程序开发界面基本一至,开发方法也如出一辙,只不过这里开发出来的是一个.dll文件的控件,Windows应用程序开发出来的是一个应用程序。
在这个界下,我们先从工具箱中拖出一些我们需要的控件来组成叫分模块的界面。如下图:

这个控件包含了一些按钮,每个按钮代表不同的庄分值。叫庄时,玩家所点击的按钮代表的分值就为当前该名玩家所叫的庄分。在游戏中,通过该控件从主程序获取的数据来动态控制其各个按钮的Enab le属性,以达到约束玩家当前能叫哪些庄分的目的。需要说明的是,这个过程由该控件自己完成,主程序只把约束条件中的一些数据提供给它,控件便可根据这些数据来控制玩家当前该如何叫庄。
所涉及的代码如下:
private Button[] jf;
public JiaoFeng()
{
InitializeComponent();
jf = new Button[19]{button1,button2,button3,button4,button5,button6,button7,button8,button9,button10,
button11,button12,button13,button14,button15,button16,button17,button18,button19};
}

//保存我方的叫庄的次数
private int jiaoZhuangCount=1;
public int JiaoZhuangCount
{
get
{
return jiaoZhuangCount;
}
set
{
jiaoZhuangCount = value;
//如果我方是第一次叫庄,并且我手中的常主数大于或等于7,则本次必须叫庄
if (jiaoZhuangCount == 1 && changZhuCount >= 7)
{
button19.Visible = false;
}
else
{
button19.Visible = true;//是否显示“不叫”按钮
}

}
}

//保存我方手中的牌常主的数目
private int changZhuCount;
public int ChangZhuCount
{
get
{
return changZhuCount;
}
set
{
changZhuCount = value;
//如果我方手中的常数大于或等于7,并且我是第一次叫庄,则本次必须叫庄
if (changZhuCount >= 7 && jiaoZhuangCount == 1)
{
button19.Visible = false;
}
else
{
button19.Visible = true;//是否显示“不叫”按钮
}

}
}

//保存上一个玩家所叫的分
private int upPlayerFeng=-15;
public int UpPlayerFeng
{
get
{
return upPlayerFeng;
}
set
{
upPlayerFeng = value;
if (upPlayerFeng != -15 && upPlayerFeng != -10)//-15为变量的初始值,-10为玩家先不叫的值,-5为摆光的值
{
if (upPlayerFeng == -5)//如果叫了摆光,则要把80——0分的按钮都隐藏掉
{
upPlayerFeng = 0;
}
//如果我不是第一个叫庄,则只能叫比上一玩家所叫分低的分
for (int i = 0; i <= Math.Abs(upPlayerFeng - 80) / 5; i++)
{
jf[i].Visible = false;
}
}
}
}

//保存我方是第几个叫庄(相对于所有玩家而言)
private int jiaoZhuangList;
public int JiaoZhuangList
{
get
{
return jiaoZhuangList;
}
set
{
jiaoZhuangList = value;
//如果我是第一个叫庄,则只能叫50—80,不能不叫或叫摆光
if (jiaoZhuangList == 1)
{
for (int i = 7; i < 19; i++)
{
jf[i].Visible = false;
}
}
else//如果我不是第一个叫庄,则要看上一个玩家所叫庄的分数
{
if (UpPlayerFeng > 50)//如果上一个玩家所叫的分不小于50,则我方现在只能叫50—80之间的
{
for (int i = 0; i < 19; i++)
{
jf[i].Visible = false;
}
for (int j = 0; j < 7; j++)
{
jf[j].Visible = true;
}
UpPlayerFeng = upPlayerFeng;
}
else
{
for (int i = 0; i < 19; i++)
{
jf[i].Visible = true;
}
UpPlayerFeng = upPlayerFeng;
if (UpPlayerFeng == 50)//如果上一个玩家所叫的分是50分
{
button18.Visible = false;
}
else
{
button18.Visible = true;
}
}
//UpPlayerFeng = upPlayerFeng;
}
}
}

//保存自己所叫的庄分
private int myFeng;
public int MyFeng
{
get
{
return myFeng;
}
set
{
myFeng = value;
}
}

//一局牌结束后,将叫分按钮全部显示
public void SetGameInfo()
{
MyFeng = 0;
JiaoZhuangList = 0;
UpPlayerFeng = -15;
ChangZhuCount = 0;
JiaoZhuangCount = 1;
for (int i = 0; i < 19; i++)
{
jf[i].Visible = true;
}
}

private void button1_Click(object sender, EventArgs e)
{
MyFeng = 80;
jiaoZhuangCount = jiaoZhuangCount + 1;
this.OnValidating(new CancelEventArgs());
}

private void button2_Click(object sender, EventArgs e)
{
MyFeng = 75;
jiaoZhuangCount = jiaoZhuangCount + 1;
this.OnValidating(new CancelEventArgs());
}

private void button3_Click(object sender, EventArgs e)
{
MyFeng = 70;
jiaoZhuangCount = jiaoZhuangCount + 1;
this.OnValidating(new CancelEventArgs());
}

private void button4_Click(object sender, EventArgs e)
{
MyFeng = 65;
jiaoZhuangCount = jiaoZhuangCount + 1;
this.OnValidating(new CancelEventArgs());
}

private void button5_Click(object sender, EventArgs e)
{
MyFeng = 60;
jiaoZhuangCount = jiaoZhuangCount + 1;
this.OnValidating(new CancelEventArgs());
}

private void button6_Click(object sender, EventArgs e)
{
MyFeng = 55;
jiaoZhuangCount = jiaoZhuangCount + 1;
this.OnValidating(new CancelEventArgs());
}

private void button7_Click(object sender, EventArgs e)
{
MyFeng = 50;
jiaoZhuangCount = jiaoZhuangCount + 1;
this.OnValidating(new CancelEventArgs());
}

private void button8_Click(object sender, EventArgs e)
{
MyFeng = 45;
jiaoZhuangCount = jiaoZhuangCount + 1;
this.OnValidating(new CancelEventArgs());
}

private void button9_Click(object sender, EventArgs e)
{
MyFeng = 40;
jiaoZhuangCount = jiaoZhuangCount + 1;
this.OnValidating(new CancelEventArgs());
}

private void button10_Click(object sender, EventArgs e)
{
MyFeng = 35;
jiaoZhuangCount = jiaoZhuangCount + 1;
this.OnValidating(new CancelEventArgs());
}

private void button11_Click(object sender, EventArgs e)
{
MyFeng = 30;
jiaoZhuangCount = jiaoZhuangCount + 1;
this.OnValidating(new CancelEventArgs());
}

private void button12_Click(object sender, EventArgs e)
{
MyFeng = 25;
jiaoZhuangCount = jiaoZhuangCount + 1;
this.OnValidating(new CancelEventArgs());
}

private void button13_Click(object sender, EventArgs e)
{
MyFeng = 20;
jiaoZhuangCount = jiaoZhuangCount + 1;
this.OnValidating(new CancelEventArgs());
}

private void button14_Click(object sender, EventArgs e)
{
MyFeng = 15;
jiaoZhuangCount = jiaoZhuangCount + 1;
this.OnValidating(new CancelEventArgs());
}

private void button15_Click(object sender, EventArgs e)
{
MyFeng = 10;
jiaoZhuangCount = jiaoZhuangCount + 1;
this.OnValidating(new CancelEventArgs());
}

private void button16_Click(object sender, EventArgs e)
{
MyFeng = 5;
jiaoZhuangCount = jiaoZhuangCount + 1;
this.OnValidating(new CancelEventArgs());
}

private void button17_Click(object sender, EventArgs e)
{
MyFeng = 0;
jiaoZhuangCount = jiaoZhuangCount + 1;
this.OnValidating(new CancelEventArgs());
}

private void button18_Click(object sender, EventArgs e)
{
MyFeng = -5;//摆光
jiaoZhuangCount = jiaoZhuangCount + 1;
this.OnValidating(new CancelEventArgs());
}

private void button19_Click(object sender, EventArgs e)
{
MyFeng = -10;//不叫
jiaoZhuangCount = jiaoZhuangCount + 1;
this.OnValidating(new CancelEventArgs());
}
}

这些代码均有注释,这里便不再详解。仅说明一下特殊的地方。
1、 在该控件中,所涉及到了19个Button控件,我们把它保存到了一个Button控件数组Button[] jf里面,目的是为了后面能够通过for循环对它们的Enable值进行批量更改;
2、 在各button控件的Click事件中,全都使用了一个this.OnValidating(new CancelEventArgs()),其原因是在游戏主程序中这个叫庄模块将作为一个整体的控件使用,无法再对这个控件上的各个button按钮的Click事件进行绑定。因此,在开发该控件的时候便通过上述语句把每个button按钮的Click事件绑定到该控件的验证事件上。游戏中玩家在叫庄时点击了庄分所对应的按钮,就触发了该控件的OnValidating事件,这此我们只需在主程序中对叫庄控件的OnValidating进行绑定,便可知道当前玩家所选择的庄分。
好了,关于叫庄模块的开发就先讨论到这,也许你看得一头雾水,这很正常,因为你还不了解这个模块是怎么使用的。我相信,通过后续的讨论,你能很好的掌握它,并通过自己的思考开发出更独到的东西,我相信你。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: