游戏“天马行空”的VB.NET实现

1.关于本文

“天马行空”这个游戏是我十几年前在一个游戏网站(cchild,现在已经不存在了)上看到的,时隔多年我才发现我仍然没有找到这个游戏的解法(从图论上理解应该是一个寻找汉密尔顿路径的问题)。现在我把它用实现出来,一来期待哪天顿悟,或是哪位高人帮我答疑解惑;二来锻炼一下我已经快一年没有用过的VB.NET编程能力。

本程序的下载地址位于:http://pan.baidu.com/s/1ntkGIEl

2.游戏规则

1)指定一个m*n大小的棋盘,每次进入游戏时程序都会通过InputBox来向玩家询问

2)在棋盘上任意选择一点,按照国际象棋中棋子“马”的行棋方法在棋盘上移动,不允许第二次移动到已经路过的位置

3)如果棋盘上所有的点都被走过一次,则认为游戏胜利;如果无法再移动,则认为游戏失败

下图为游戏示例

游戏“天马行空”的VB.NET实现_第1张图片

3.程序控件

手工放置到程序中的控件很少。程序中就一个Form,名为FormMain

游戏“天马行空”的VB.NET实现_第2张图片

其中,FormMain的Size属性为(688, 664),StartPosition属性被设置为CenterScreen。Panel控件pnlControl的BorderStyle属性被设置为FixedSingle,Dock属性被设置为Top;pnlBoard的Dock属性被设置为Fill

4.程序源码

Public Class FormMain

    'w:矩阵列数-1 h:矩阵行数-1
    Dim w As Integer = 7
    Dim h As Integer = 7

    '初始化窗体
    Private Sub FormMain_Load(sender As Object, e As EventArgs) _
        Handles MyBase.Load

        '输入矩阵行数
        Do
            Try
                h = InputBox("设定矩阵行数", "欢迎", 8) - 1
                If h < 3 Then
                    Throw New Exception("矩阵行数应大于或等于4")
                End If
                Exit Do
            Catch ex As Exception
                MessageBox.Show(ex.Message)
                Continue Do
            End Try
        Loop

        '输入矩阵列数
        Do
            Try
                w = InputBox("设定矩阵列数", "欢迎", 8) - 1
                If w < 3 Then
                    Throw New Exception("矩阵列数应大于或等于4")
                End If
                Exit Do
            Catch ex As Exception
                MessageBox.Show(ex.Message)
                Continue Do
            End Try
        Loop

        '部署控件
        For i As Integer = 0 To h
            For j As Integer = 0 To w

                Dim btn As Button = New Button
                '设置按钮属性
                With btn
                    .Location = New System.Drawing.Point _
                        (j * pnlBoard.Width / (w + 1), i * pnlBoard.Height / (h + 1))
                    .Size = New System.Drawing.Size _
                        (pnlBoard.Width / (w + 1), pnlBoard.Height / (h + 1))
                    .Tag = {i, j} '按钮对应的行列,存储在Tag中
                End With
                '设置按钮事件
                AddHandler btn.Click, AddressOf btnPosition_Click
                '在棋盘上添加该按钮
                pnlBoard.Controls.Add(btn)

            Next
        Next

        '初始化棋盘
        Restart()

    End Sub

    Dim isGameStarted As Boolean = False

    '单击棋盘上的一个按钮
    Private Sub btnPosition_Click(ByVal sender As System.Object, ByVal e As System.EventArgs)

        Dim btnTemp As Button = DirectCast(sender, Button)

        '如果行棋位置之前已经走过,不合法
        If btnTemp.BackColor <> Color.Red Then
            Return
        End If

        '读取该按钮所对应的行列
        Dim array() As Integer = DirectCast(btnTemp.Tag, Integer())
        Dim row As Integer = array(0)
        Dim col As Integer = array(1)

        '判断本次行棋是否合法
        Dim isLegal As Boolean = False

        '若尚未开始游戏则开始游戏
        If isGameStarted = False Then
            isGameStarted = True
            isLegal = True
            GoTo RESULT
        End If

        '向右下偏左行棋
        If row >= 2 And col >= 1 Then
            If pnlBoard.Controls((row - 2) * (w + 1) + col - 1).BackColor = Color.Green Then
                isLegal = True
                GoTo RESULT
            End If
        End If

        '向右下偏右行棋
        If row >= 1 And col >= 2 Then
            If pnlBoard.Controls((row - 1) * (w + 1) + col - 2).BackColor = Color.Green Then
                isLegal = True
                GoTo RESULT
            End If
        End If

        '向右上偏左行棋
        If row <= w - 2 And col >= 1 Then
            If pnlBoard.Controls((row + 2) * (w + 1) + col - 1).BackColor = Color.Green Then
                isLegal = True
                GoTo RESULT
            End If
        End If

        '向右上偏右行棋
        If row <= w - 1 And col >= 2 Then
            If pnlBoard.Controls((row + 1) * (w + 1) + col - 2).BackColor = Color.Green Then
                isLegal = True
                GoTo RESULT
            End If
        End If

        '向左下偏右行棋
        If row >= 2 And col <= h - 1 Then
            If pnlBoard.Controls((row - 2) * (w + 1) + col + 1).BackColor = Color.Green Then
                isLegal = True
                GoTo RESULT
            End If
        End If

        '向左下偏左行棋
        If row >= 1 And col <= h - 2 Then
            If pnlBoard.Controls((row - 1) * (w + 1) + col + 2).BackColor = Color.Green Then
                isLegal = True
                GoTo RESULT
            End If
        End If

        '向左上偏左行棋
        If row <= w - 1 And col <= h - 2 Then
            If pnlBoard.Controls((row + 1) * (w + 1) + col + 2).BackColor = Color.Green Then
                isLegal = True
                GoTo RESULT
            End If
        End If

        '向左上偏右行棋
        If row <= w - 2 And col <= h - 1 Then
            If pnlBoard.Controls((row + 2) * (w + 1) + col + 1).BackColor = Color.Green Then
                isLegal = True
                GoTo RESULT
            End If
        End If

RESULT:

        '如果行棋合法,则行棋,否则不行棋
        If isLegal Then

            '将之前点下的按钮都置为草绿
            For Each btn As Button In pnlBoard.Controls
                If btn.BackColor <> Color.Red Then
                    btn.BackColor = Color.LawnGreen
                End If
            Next

            '将当前点下的按钮置为绿色
            btnTemp.BackColor = Color.Green

            If IsWin() Then
                MessageBox.Show("You made a good job!")
            End If

        End If

    End Sub

    ''' <summary>
    ''' 初始化棋盘界面
    ''' </summary>
    ''' <remarks>将所有按钮都置为Red</remarks>
    Private Sub Restart()

        '游戏回复到未开始状态
        isGameStarted = False

        '背景颜色全部置红
        For Each btn As Button In pnlBoard.Controls
            btn.BackColor = Color.Red
        Next

    End Sub

    ''' <summary>
    ''' 判断本局游戏是否胜利
    ''' </summary>
    ''' <returns> true:游戏胜利 false:游戏尚未胜利</returns>
    ''' <remarks></remarks>
    Public Function IsWin() As Boolean

        '有没有变绿的按钮,则认为游戏没有取胜
        For Each btn As Button In pnlBoard.Controls
            If btn.BackColor = Color.Red Then
                Return False
            End If
        Next
        '所有按钮都变绿,游戏胜利
        Return True

    End Function

    '重新开始游戏
    Private Sub btnRestart_Click(sender As Object, e As EventArgs) _
        Handles btnRestart.Click
        Restart()
    End Sub

    '关闭程序
    Private Sub btnClose_Click(sender As Object, e As EventArgs) _
        Handles btnClose.Click
        Application.Exit()
    End Sub

End Class


你可能感兴趣的:(游戏“天马行空”的VB.NET实现)