一个简单网格游戏,可以寻找到网格最短路径(源代码)
来源:互联网 发布:米德尔顿 知乎 编辑:程序博客网 时间:2024/04/20 06:00
程序界面如下:
界面很简单:
一个长宽360像素的PICTUREBOX, Name=picturebox1
2个label控件,名称分别为LABEL1、LABEL3,label3显示坐标用,label1用于显示得分
2个button控件,名称分别为BUTTON2、BUTTON3,BUTTON2的TEXT设为“开始”,BUTTON3的TEXT属性设为“显示数组”
窗体代码如下:
Public Class Form1 Private idX As Integer Private idY As Integer Private canMove As Boolean = False Private gezi(2) As Integer Private Sub Form1_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load drawWangGe(PictureBox1) End Sub Private Sub Button2_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button2.Click resetSUZU() drawWangGe(PictureBox1) deFen = 0 get3p(PictureBox1) End Sub Private Sub PictureBox1_MouseDown(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles PictureBox1.MouseDown If e.Button = Windows.Forms.MouseButtons.Left Then If canMove Then idX = CInt(e.X \ 40) idY = CInt(e.Y \ 40) If idX = gezi(0) And idY = gezi(1) Then canMove = False Else getPath(gezi(0), gezi(1), idX, idY) If CloseList.Items.Count >= 1 Then showPath(PictureBox1, gezi(0), gezi(1), idX, idY) get3p(PictureBox1) HideWG(PictureBox1, idX, idY, 4) Label1.Text = "空格数:" + suzukongNum().ToString + vbCrLf + "得分:" + deFen.ToString End If canMove = False End If Else idX = CInt(e.X \ 40) idY = CInt(e.Y \ 40) ' HideWG(PictureBox1, idX, idY, 3) gezi(0) = idX gezi(1) = idY gezi(2) = FGpandc(idX, idY, 1) If gezi(2) <> 0 Then canMove = True Else canMove = False End If Dim FGnum As Integer = suzukongNum() If FGnum = 0 Then MsgBox("游戏结束了!") End If End If End If End Sub Private Sub PictureBox1_MouseMove(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles PictureBox1.MouseMove Label3.Text = "X=" + CInt(e.X \ 40).ToString + ", Y=" + CInt(e.Y \ 40).ToString End Sub Private Sub Button3_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button3.Click showSuzu() End Sub Public Sub showSuzu() '显示数组 Dim str As String = "" Dim i As Integer, j As Integer For j = 0 To 8 For i = 0 To 8 str += FGpandc(i, j, 0).ToString & " " Next str += vbCrLf Next str += vbCrLf For j = 0 To 8 For i = 0 To 8 str += FGpandc(i, j, 1).ToString & " " Next str += vbCrLf Next For i = 0 To Openlist.Items.Count - 1 str += Openlist.Items.Item(i).ToString & vbCrLf Next str += "////" + vbCrLf For i = 0 To CloseList.Items.Count - 1 str += CloseList.Items.Item(i).ToString & vbCrLf Next MsgBox(str) End SubEnd Class
一个模块名称为"FG" ,代码如下:
Imports System.ThreadingModule FG Public deFen As Integer = 0 Public FGbiao(8, 8) As Integer '用于标记的网格数组 Public FGpandc(8, 8, 1) As Integer '网格数组 Public HideID(35, 1) As Integer '存储相同颜色格子的坐标 Const N As Integer = 9 '网格数 Public CloseList As New System.Windows.Forms.ListBox '存放路径 Public Openlist As New System.Windows.Forms.ListBox '存放备用路径 Public HasPath As Boolean = True '用于判断某格子四周是否有空位 Public Sub drawWangGe(ByVal pict As PictureBox) '画线,清除界面颜色 Dim a As New Bitmap(360, 360) Dim mye As Graphics = Graphics.FromImage(a) mye.Clear(Color.WhiteSmoke) Dim i As Integer For i = 0 To 360 Step 40 mye.DrawLine(Pens.RoyalBlue, 0, i, 360, i) mye.DrawLine(Pens.RoyalBlue, i, 0, i, 360) Next pict.Image = a mye.Dispose() End Sub Public Sub get3p(ByVal pic As PictureBox) '随机得到3个位置 Dim xID(2) As Integer Dim yID(2) As Integer Dim xyColor(2) As Integer Dim n As Integer = 0 Dim x As Integer, y As Integer Dim loopnum As Integer = 0 loopnum = suzukongNum() Dim i As Integer, j As Integer If loopnum >= 3 Then Do While n < 3 Randomize() x = Int(Rnd() * 9) Randomize() y = Int(Rnd() * 9) If FGpandc(x, y, 0) = 1 Then Else xID(n) = x yID(n) = y xyColor(n) = Int(Rnd() * 5 + 1) FGpandc(x, y, 0) = 1 FGpandc(x, y, 1) = xyColor(n) HideWG(pic, x, y, 4) n += 1 End If Loop Else For i = 0 To 8 For j = 0 To 8 If FGpandc(i, j, 0) = 0 Then FGpandc(i, j, 0) = 1 FGpandc(i, j, 1) = Int(Rnd() * 5 + 1) End If Next Next End If For i = 0 To 8 For j = 0 To 8 FillGe(pic, i, j, getcolor(i, j)) Next Next End Sub Public Function suzukongNum() As Integer '判断整个数组还有几个空位 Dim i As Integer Dim j As Integer Dim num As Integer = 0 For i = 0 To 8 For j = 0 To 8 If FGpandc(i, j, 0) = 1 Then num += 1 End If Next Next Return 81 - num End Function '根据数组下标对网格填充 Public Sub FillGe(ByVal pict As PictureBox, ByVal x As Integer, ByVal y As Integer, ByVal c As Color) Dim a As Bitmap = pict.Image Dim mye As Graphics = Graphics.FromImage(a) mye.FillRectangle(New SolidBrush(c), New Rectangle(x * 40, y * 40, 40, 40)) Dim i As Integer For i = 0 To 360 Step 40 mye.DrawLine(Pens.RoyalBlue, 0, i, 360, i) mye.DrawLine(Pens.RoyalBlue, i, 0, i, 360) Next pict.Image = a mye.Dispose() End Sub '得到颜色 Public Function getcolor(ByVal x As Integer, ByVal y As Integer) As Color Select Case FGpandc(x, y, 1) Case 1 Return Color.Red Case 2 Return Color.Blue Case 3 Return Color.Green Case 4 Return Color.Yellow Case 5 Return Color.Pink Case Else Return Color.WhiteSmoke End Select End Function Public Sub resetSUZU() '重置数组,全部为零 Dim i As Integer Dim j As Integer For i = 0 To N - 1 For j = 0 To N - 1 FGpandc(i, j, 0) = 0 FGpandc(i, j, 1) = 0 Next Next End Sub#Region "消格子" Private Sub hideWGH(ByVal x As Integer, ByVal y As Integer, ByRef a(,) As Integer) ReDim a(8, 1) ReSetSZ(a) Dim idx As Integer = x, xNum As Integer = 0 Do While idx < 8 idx += 1 If FGpandc(idx, y, 1) = FGpandc(x, y, 1) Then xNum += 1 a(xNum - 1, 0) = idx a(xNum - 1, 1) = y Else idx = 8 End If Loop idx = x Do While idx > 0 idx -= 1 If FGpandc(idx, y, 1) = FGpandc(x, y, 1) Then xNum += 1 a(xNum - 1, 0) = idx a(xNum - 1, 1) = y Else idx = 0 End If Loop End Sub Private Sub hideWGS(ByVal x As Integer, ByVal y As Integer, ByRef a(,) As Integer) ReDim a(8, 1) ReSetSZ(a) Dim idy As Integer = y, yNum As Integer = 0 Do While idy < 8 idy += 1 If FGpandc(x, idy, 1) = FGpandc(x, y, 1) Then yNum += 1 a(yNum - 1, 0) = x a(yNum - 1, 1) = idy Else idy = 8 End If Loop idy = y Do While idy > 0 idy -= 1 If FGpandc(x, idy, 1) = FGpandc(x, y, 1) Then yNum += 1 a(yNum - 1, 0) = x a(yNum - 1, 1) = idy Else idy = 0 End If Loop End Sub Private Sub ReSetSZ(ByRef D(,) As Integer) ReDim D(8, 1) Dim i As Integer For i = 0 To 8 D(i, 0) = -1 D(i, 1) = -1 Next End Sub Private Sub ReSetSZ11() Dim I As Integer For I = 0 To 35 HideID(I, 0) = -2 HideID(I, 1) = -2 Next End Sub Private Sub hideWGXZ(ByVal x As Integer, ByVal y As Integer, ByRef a(,) As Integer) ReDim a(8, 1) ReSetSZ(a) Dim idX As Integer = x, Num As Integer = 0, idY As Integer = y Do While idY > 0 And idX > 0 idY -= 1 idX -= 1 If FGpandc(idX, idY, 1) = FGpandc(x, y, 1) Then Num += 1 a(Num - 1, 0) = idX a(Num - 1, 1) = idY Else idY = 0 End If Loop idX = x : idY = y Do While idX < 8 And idY < 8 idX += 1 idY += 1 If FGpandc(idX, idY, 1) = FGpandc(x, y, 1) Then Num += 1 a(Num - 1, 0) = idX a(Num - 1, 1) = idY Else idX = 8 End If Loop End Sub Private Sub hideWGXY(ByVal x As Integer, ByVal y As Integer, ByRef a(,) As Integer) ReDim a(8, 1) ReSetSZ(a) Dim idX As Integer = x, Num As Integer = 0, idY As Integer = y Do While idY > 0 And idX < 8 idY -= 1 idX += 1 If FGpandc(idX, idY, 1) = FGpandc(x, y, 1) Then Num += 1 a(Num - 1, 0) = idX a(Num - 1, 1) = idY Else idY = 0 End If Loop idX = x : idY = y Do While idY < 8 And idX > 0 idX -= 1 idY += 1 If FGpandc(idX, idY, 1) = FGpandc(x, y, 1) Then Num += 1 a(Num - 1, 0) = idX a(Num - 1, 1) = idY Else idY = 8 End If Loop End Sub Public Sub HideWG(ByVal pic As PictureBox, ByVal x As Integer, ByVal y As Integer, ByVal nnn As Integer) Dim aaH(8, 1) As Integer, aaS(8, 1) As Integer, aaXY(8, 1) As Integer, aaXZ(8, 1) As Integer Dim i As Integer hideWGH(x, y, aaH) hideWGS(x, y, aaS) hideWGXZ(x, y, aaXY) hideWGXY(x, y, aaXZ) ReSetSZ11() Dim NUM As Integer NUM = 0 For i = 0 To 8 If getnumSZ(aaH) >= nnn - 1 Then If aaH(i, 0) <> -1 Then NUM += 1 HideID(NUM - 1, 0) = aaH(i, 0) HideID(NUM - 1, 1) = aaH(i, 1) End If End If If getnumSZ(aaS) >= nnn - 1 Then If aaS(i, 0) <> -1 Then NUM += 1 HideID(NUM - 1, 0) = aaS(i, 0) HideID(NUM - 1, 1) = aaS(i, 1) End If End If If getnumSZ(aaXY) >= nnn - 1 Then If aaXY(i, 0) <> -1 Then NUM += 1 HideID(NUM - 1, 0) = aaXY(i, 0) HideID(NUM - 1, 1) = aaXY(i, 1) End If End If If getnumSZ(aaXZ) >= nnn - 1 Then If aaXZ(i, 0) <> -1 Then NUM += 1 HideID(NUM - 1, 0) = aaXZ(i, 0) HideID(NUM - 1, 1) = aaXZ(i, 1) End If End If Next For i = 0 To 35 If HideID(i, 0) <> -2 Then FillGe(pic, HideID(i, 0), HideID(i, 1), Color.WhiteSmoke) FGpandc(HideID(i, 0), HideID(i, 1), 0) = 0 FGpandc(HideID(i, 0), HideID(i, 1), 1) = 0 End If Next If NUM >= nnn - 1 Then FillGe(pic, x, y, Color.WhiteSmoke) FGpandc(x, y, 0) = 0 FGpandc(x, y, 1) = 0 ' MsgBox(NUM) Select Case NUM Case 3 deFen += 10 Case 4 deFen += 15 Case 5 deFen += 20 Case 6 deFen += 25 Case 7 deFen += 30 Case 8 deFen += 35 Case 9 deFen += 40 End Select End If End Sub Private Function getnumSZ(ByVal a(,) As Integer) As Integer Dim i As Integer, NUM As Integer = 0 For i = 0 To 8 If a(i, 0) <> -1 Then NUM += 1 End If Next Return NUM End Function#End Region#Region "查找路径" Public Sub getPath(ByVal x0 As Integer, ByVal y0 As Integer, ByVal x1 As Integer, ByVal y1 As Integer) '得到最短路径 Dim endTag As Boolean = False Openlist.Items.Clear() 'close表清零 CloseList.Items.Clear() 'open表清零 resBiaoji() getOpenlist(x0, y0) CloseList.Items.Add(x0.ToString + "," + y0.ToString) Do Until Openlist.Items.Count < 1 Or endTag setCloseList(x1, y1) Dim i As Integer For i = 0 To CloseList.Items.Count - 1 Dim xx As Integer = CInt(CloseList.Items.Item(i).ToString.Substring(0, 1)) Dim yy As Integer = CInt(CloseList.Items.Item(i).ToString.Substring(2, 1)) 'MsgBox(xx.ToString + "," + yy.ToString) If xx = x1 And yy = y1 Then endTag = True Else End If Next If endTag Then Else Dim xx1 As Integer = CInt(CloseList.Items.Item(CloseList.Items.Count - 1).ToString.Substring(0, 1)) Dim yy1 As Integer = CInt(CloseList.Items.Item(CloseList.Items.Count - 1).ToString.Substring(2, 1)) getOpenlist(xx1, yy1) End If Loop If endTag Then Dim i As Integer, strr As String = "" If CloseList.Items.Count >= 1 Then For i = 0 To CloseList.Items.Count - 1 strr += CloseList.Items.Item(i) + "|" Next ' MsgBox(strr) Else MsgBox("no data") End If Else MsgBox("no path") CloseList.Items.Clear() End If End Sub Public Sub showPath(ByVal pict As PictureBox, ByVal X As Integer, ByVal Y As Integer, ByVal X1 As Integer, ByVal Y1 As Integer) '显示路径 Dim i As Integer If CloseList.Items.Count >= 1 Then Dim s1 As String = CloseList.Items.Item(CloseList.Items.Count - 1) Dim xx0 As Integer = Val(s1.Substring(0, 1)) Dim yy0 As Integer = Val(s1.Substring(2, 1)) Dim forNum As Integer If xx0 = X1 And yy0 = Y1 Then forNum = CloseList.Items.Count - 1 Else forNum = CloseList.Items.Count - 2 End If For i = 0 To forNum Dim s As String = CloseList.Items.Item(i) Dim xx As Integer = Val(s.Substring(0, 1)) Dim yy As Integer = Val(s.Substring(2, 1)) 'FillGe(pict, xx, yy, getcolor(X, Y)) FillGe(pict, xx, yy, Color.Bisque) 'Thread.Sleep(500) FillGe(pict, xx, yy, Color.WhiteSmoke) Next FillGe(pict, X1, Y1, getcolor(X, Y)) FGpandc(X1, Y1, 0) = 1 FGpandc(X1, Y1, 1) = FGpandc(X, Y, 1) FillGe(pict, X, Y, Color.WhiteSmoke) FGpandc(X, Y, 0) = 0 FGpandc(X, Y, 1) = 0 Else MsgBox("no path") End If End Sub Private Function getJuli(ByVal x As Integer, ByVal y As Integer, ByVal x0 As Integer, ByVal y0 As Integer) As Double '得到两点的距离 Return ((x - x0) ^ 2 + (y - y0) ^ 2) ^ 0.5 End Function Private Sub getOpenlist(ByVal x As Integer, ByVal y As Integer) '得到点x,y 周围4个点,并将之加入OPEN表 If x - 1 >= 0 Then If FGbiao(x - 1, y) <> 1 Then If inList(x - 1, y, Openlist) Then Else If inList(x - 1, y, CloseList) Then Else Openlist.Items.Add((x - 1).ToString + "," + y.ToString) End If End If End If End If If x + 1 <= 8 Then If FGbiao(x + 1, y) <> 1 Then If inList(x + 1, y, Openlist) Then Else If inList(x + 1, y, CloseList) Then Else Openlist.Items.Add((x + 1).ToString + "," + y.ToString) End If End If End If End If If y - 1 >= 0 Then If FGbiao(x, y - 1) <> 1 Then If inList(x, y - 1, Openlist) Then Else If inList(x, y - 1, CloseList) Then Else Openlist.Items.Add(x.ToString + "," + (y - 1).ToString) End If End If End If End If If y + 1 <= 8 Then If FGbiao(x, y + 1) <> 1 Then If inList(x, y + 1, Openlist) Then Else If inList(x, y + 1, CloseList) Then Else Openlist.Items.Add(x.ToString + "," + (y + 1).ToString) End If End If End If End If End Sub Private Sub setCloseList(ByVal x1 As Integer, ByVal y1 As Integer) '从开放列表中查找一最小的值,放入到CLOSE列表中 Dim i As Integer, s As String = "" Dim xx As Integer, yy As Integer Dim b As Double If Openlist.Items.Count >= 1 Then Dim xx2 As Integer = Val((Openlist.Items.Item(0)).ToString.Substring(0, 1)) Dim yy2 As Integer = Val((Openlist.Items.Item(0)).ToString.Substring(2, 1)) b = getJuli(xx2, yy2, x1, y1) For i = 0 To Openlist.Items.Count - 1 s = Openlist.Items.Item(i).ToString xx = Val(s.Substring(0, 1)) yy = Val(s.Substring(2, 1)) If getJuli(xx, yy, x1, y1) <= b Then b = getJuli(xx, yy, x1, y1) Else End If Next For i = 0 To Openlist.Items.Count - 1 s = Openlist.Items.Item(i).ToString xx = Val(s.Substring(0, 1)) yy = Val(s.Substring(2, 1)) If getJuli(xx, yy, x1, y1) = b Then CloseList.Items.Add(s) Openlist.Items.Remove(s) FGbiao(xx, yy) = 1 Exit For End If Next End If End Sub Private Function inList(ByVal xx As Integer, ByVal yy As Integer, ByVal aList As ListBox) As Boolean '判断某点(x,y)是否在某列表中 Dim i As Integer Dim s As String = xx.ToString + "," + yy.ToString Dim a As Boolean = False For i = 0 To aList.Items.Count - 1 If s = aList.Items.Item(i) Then a = True End If Next Return a End Function Private Sub resBiaoji() '建立网格数组的拷贝 Dim i As Integer, j As Integer For i = 0 To 8 For j = 0 To 8 FGbiao(i, j) = FGpandc(i, j, 0) Next Next End Sub#End Region End Module
模块FG中的SHOWPATH()显示路径中的 “Thread.Sleep(500)”这句执行时有问题。
不能显示动画效果。。。。
- 一个简单网格游戏,可以寻找到网格最短路径(源代码)
- 寻找最短路径
- 网格路径
- #bzoj3391#小球游戏(数论 + 网格路径模型)
- noip模拟赛 小球游戏 cqbzoj3391(网格路径模型)
- 一个简单的网格算法
- 寻找最短路径BFS
- 【编程网格无水题】之【最短歧义串】
- 网格
- 网格
- 网格
- 网格
- 仙岛求药(迷宫寻找最短路径)DFS
- 寻找电路布线最短路径(Queue)
- 算法-图论-Dijstra寻找最短路径
- JS算法*START寻找最短路径
- 广搜之寻找最短路径
- BellMan-Ford算法--寻找最短路径
- curl_easy_setopt-curl库的关键函数之一
- Object-C实现文件追加方法
- openCv学习笔记(五)-数学形态学2(灰度级膨胀和腐蚀及c语言实现)
- struts2.3.4环境搭建
- [Economist] iPhones make Chinese eyes light up iPhone使中国人欢呼雀跃
- 一个简单网格游戏,可以寻找到网格最短路径(源代码)
- 理解Git的工作流程
- git 历险记
- javascript 浮点数运算错误解决方案
- Js获取当前日期时间及其它操作
- struts2.3.4应用开发小结(1)
- SQL日期比较
- 11 个惊人的 CSS3 和 jQuery 制作的教程收集
- Notification使用详解之二:可更新进度的通知