扑克游戏林林总总,同一种游戏各地玩法亦不尽相同。编程爱好者多喜欢编写一些本地玩法的扑克游戏。那么,编写自己的扑克游戏该从何处入手呢?
扑克游戏编程关键有两点:一是扑克牌面的绘制;二是扑克游戏规则的算法实现。初学扑克游戏编程的爱好者可从一些简单的游戏、借用一些现有资源开始。本文拟借用Windows自带的Cards.dll和简单的21点游戏为例,介绍扑克游戏编程的初步方法。
一、 扑克牌面绘制
Cards.dll支持Windows自带的游戏,如Solitaire(纸牌游戏)。如果我们知道如何使用Cards.dll中的API函数,那么,我们就能像Windows自带的游戏一样绘制扑克牌面。我们需要使用其中三个基本函数:cdtInit, cdtDrawExt,和 cdtTerm。并且需要两个变量:width和height用于初始化函数cdtInit进行初始化。下面给出这些接口函数的声明及参数说明。
Private width As Integer = 0 Private height As Integer = 0 Declare Function cdtInit Lib "cards.dll" (ByRef width As Integer, _ ByRef height As Integer) As Boolean |
参数说明:width,height返回牌默认宽和高,单位为pixels。
Declare Function cdtDrawExt Lib "cards.dll" (ByVal hdc As IntPtr, _ ByVal x As Integer, ByVal y As Integer, ByVal dx As Integer, _ ByVal dy As Integer, ByVal card As Integer, _ ByVal mode As Integer, ByVal color As Long) As Boolean |
参数说明:hdc(handle to a device context)句柄;
x,y指定牌左上角坐标位;
dx,dy指定牌宽和高;
card需要绘制的牌,0-51[A(草花、方块、红桃、黑桃),2,…,K];53-65牌背面;
mode 指定绘制方式,牌面向上为0,牌面向下为1;
color 指定背景色。
Declare Sub cdtTerm Lib "cards.dll" () |
无参数。
我们需要在游戏开始时调用cdtInit对cards.dll进行初始化,这样我们才能使用cards.dll中的cdtDrawEx等函数;每绘制一张牌,我们都要调一次cdtDrawExt函数;当我们结束游戏时,调用一次cdtTerm以结束cards.dll的使用。
二、 游戏规则的算法实现
二十一点游戏是玩家要取得比庄家更大的点数总和,但点数超过二十一点即为爆牌,并输掉注码。J、Q、K算10点,A可算1点或11点,其余按牌面值计点数。“BlackJack”是由一张A和J、Q、K或10所组成。开始时每人发两张牌,一张明,一张暗,凡点数不足二十一点,可选择博牌。如果首两张牌是对子可选择分牌。
为简化起见,程序中只有两个玩家Dealer和Player,都发明牌,无下注过程,不记录输赢,不支持分牌和加倍等。二十一点游戏中,一张牌只要有四个属性说明:Face牌面大小、Suit牌面花色,Count点数,FaceUp牌面是否向上。因此,这里我们不用Card 类而用Card结构。
Structure card Public face As Integer Public suit As Integer Public count As Integer Public faceup As Boolean End Structure |
游戏开始时,我们首先要取一副牌,然后将牌洗好,指定从第几张牌开始发起。洗牌时为取得真正的随机数,用My.Computer.Clock.TickCount作产生随机数的种子。
Dim Deck() As card |
游戏界面中,我们设置三个命令按钮,两个标签。Button1为“发牌”、Button2为“要牌”、Button3为“停牌”。Label1记录庄家点数,Label2记录玩家点数。游戏过程中,如果一副牌发完,立即重洗一副牌,并弹出消息对话框告知。以下列出三个按钮单击事件代码。其中庄家游戏过程中,为简化起见,未曾使用游戏技巧。
Dim playerCount As Integer = 0 Dim playerAce As Integer = 0 Dim dealerCount As Integer = 0 Dim dealerAce As Integer = 0 Dim ipcard, idcard As Integer Private Sub delay(ByVal dt As Integer) Dim t As Integer t = My.Computer.Clock.TickCount Do If My.Computer.Clock.TickCount >= t + dt Then Exit Do Loop End Sub Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click Button1.Visible = False Label1.Text=”” Label2.Text=”” Label1.Refresh() Label2.Refresh() MyBase.CreateGraphics.Clear(Color.DarkGreen) dealerAce = 0 playerAce = 0 dealerCount = 0 playerCount = 0 cdtDrawExt(MyBase.CreateGraphics.GetHdc, 200, 200, 75, 100, (Deck(TopCard).face * 4 + Deck(TopCard).suit), 0, 0) playerCount += Deck(TopCard).count If Deck(TopCard).face = 0 Then playerCount += 10 : playerAce += 1 TopCard += 1 If TopCard >= 52 Then Shuffle() : MsgBox("NEW DECK!") Label2.Text = playerCount.ToString Label2.Refresh() delay(1000) cdtDrawExt(MyBase.CreateGraphics.GetHdc, 200, 10, 75, 100, (Deck(TopCard).face * 4 + Deck(TopCard).suit), 0, 0) dealerCount += Deck(TopCard).count If Deck(TopCard).face = 0 Then dealerCount += 10 : dealerAce += 1 TopCard += 1 If TopCard >= 52 Then Shuffle() : MsgBox("NEW DECK!") Label1.Text = dealerCount.ToString Label1.Refresh() delay(1000) cdtDrawExt(MyBase.CreateGraphics.GetHdc, 220, 200, 75, 100, (Deck(TopCard).face * 4 + Deck(TopCard).suit), 0, 0) playerCount += Deck(TopCard).count If Deck(TopCard).face = 0 And playerAce = 0 Then playerCount += 10 : playerAce += 1 TopCard += 1 If TopCard >= 52 Then Shuffle() : MsgBox("NEW DECK!") Label2.Text = playerCount.ToString Label2.Refresh() delay(1000) cdtDrawExt(MyBase.CreateGraphics.GetHdc, 220, 10, 75, 100, (Deck(TopCard).face * 4 + Deck(TopCard).suit), 0, 0) dealerCount += Deck(TopCard).count If Deck(TopCard).face = 0 And dealerAce = 0 Then dealerCount += 10 : dealerAce += 1 TopCard += 1 If TopCard >= 52 Then Shuffle() : MsgBox("NEW DECK!") Label1.Text = dealerCount.ToString Label1.Refresh() delay(1000) ipcard = 2 idcard = 2 Button2.Visible = True Button3.Visible = True End Sub Private Sub Button2_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button2.Click cdtDrawExt(MyBase.CreateGraphics.GetHdc, 200 + 20 * ipcard, 200, 75, 100, (Deck(TopCard).face * 4 + Deck(TopCard).suit), 0, 0) playerCount += Deck(TopCard).count If Deck(TopCard).face = 0 Then playerCount += 10 : playerAce += 1 TopCard += 1 If TopCard >= 52 Then Shuffle() : MsgBox("NEW DECK!") ipcard += 1 Label2.Text = playerCount.ToString Label2.Refresh() If playerCount > 21 Then If playerAce >= 1 Then playerCount -= 10 playerAce -= 1 Label2.Text = playerCount.ToString Label2.Refresh() Else MsgBox("Player loss!") Button1.Visible = True Button2.Visible = False Button3.Visible = False End If End If End Sub Private Sub Button3_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button3.Click Button2.Visible = False Button3.Visible = False dealerPlay() End Sub Private Sub dealerPlay() Do If dealerCount < 17 Then cdtDrawExt(MyBase.CreateGraphics.GetHdc, 200 + 20 * idcard, 10, 75, 100, (Deck(TopCard).face * 4 + Deck(TopCard).suit), 0, 0) dealerCount += Deck(TopCard).count If dealerCount > 21 And dealerAce = 1 Then dealerCount -= 10 : dealerAce -= 1 If Deck(TopCard).face = 0 And dealerCount <= 11 Then dealerCount += 10 TopCard += 1 If TopCard >= 52 Then Shuffle() : MsgBox("NEW DECK!") idcard += 1 Else Exit Do End If Loop Label1.Text = dealerCount.ToString Label1.Refresh() If dealerCount <= 21 Then If playerCount > dealerCount Then MsgBox("Player win!") Else MsgBox("Dealer win!") End If Else MsgBox("Player win!") End If Button1.Visible = True Button2.Visible = False Button3.Visible = False End Sub |
运行结果如下图所示:
领测软件测试网最新更新
关于领测软件测试网 | 领测软件测试网合作伙伴 | 广告服务 | 投稿指南 | 联系我们 | 网站地图 | 友情链接
版权所有(C) 2003-2010 TestAge(领测软件测试网)|领测国际科技(北京)有限公司|软件测试工程师培训网 All Rights Reserved 北京市海淀区中关村南大街9号北京理工科技大厦1402室 京ICP备10010545号-5 技术支持和业务联系:info@testage.com.cn 电话:010-51297073 |