22、正则表达式匹配与井字棋游戏开发

正则表达式匹配与井字棋游戏开发

1. 正则表达式匹配示例

在这个示例中,我们使用 VBScript 进行正则表达式匹配。代码如下:

strStory = "Once upon a time there were three little bears. There " & _
"was a mama bear, a papa bear, and a baby bear. There was a cousin bear too!"
Set objMatchCollection = objRegExp.Execute(strStory)
For Each objMatch in objMatchCollection
    strDisplayMsg = strDisplayMsg & "An instance of " & _
    objRegExp.Pattern & " found at position " & objMatch.FirstIndex & _
    vbCrLf
Next
MsgBox strDisplayMsg

这里,我们使用 RegExp 对象的 Execute() 方法生成并处理 Matches 集合。通过 For Each…Next 循环处理集合中的每个 Match 对象,利用 Match 对象的 FirstIndex 属性获取匹配模式在搜索字符串中的起始位置,最后将结果显示在消息框中。

2. 井字棋游戏开发
2.1 游戏设计概述

井字棋游戏除了初始化和主处理部分外,由九个函数组成,每个函数执行特定任务:
| 函数名 | 功能描述 |
| ---- | ---- |
| SetVariableDefaults() | 为各种脚本变量设置默认值 |
| ClearGameBoard() | 重置井字棋游戏板的每个单元格,使其为空 |
| ManageGamePlay() | 控制游戏的整体执行,必要时调用其他函数 |
| DisplayBoard() | 显示游戏板,包括说明、错误消息和玩家已做出的任何移动 |
| DisplayGameResults() | 显示每场游戏的最终结果,确定谁获胜或游戏是否平局 |
| ValidateInput() | 确保玩家在轮到自己时只能输入有效的单元格坐标 |
| MarkPlayerSelection() | 将玩家提供的输入与游戏板上的相应单元格坐标关联起来 |
| SeeIfWon() | 检查游戏板,确定玩家是否获胜或游戏是否平局 |
| DisplaySplashScreen() | 显示有关脚本及其作者的信息 |

2.2 脚本模板和初始化部分设置

游戏开始时,定义游戏使用的常量和变量,并添加注释说明每个变量的用途。

'*************************************************************************
'Script Name:   TicTacToe.vbs
'Author:        Jerry Ford
'Created:       02/25/14
'Description:   This script is a VBScript implementation of the
'               Tic Tac Toe game
'*************************************************************************
'Initialization Section
Option Explicit
Const cTitleBarMsg = "VBScript   T I C   T A C   T O E"

Dim A1, A2, A3, B1, B2, B3, C1, C2, C3
'Variables representing sections
'of the Tic Tac Toe game board
Dim blnGameOver        'Boolean variable that determines when to end game
Dim blnPlayerTypedQuit 'Variable to track whether a player typed Quit
Dim blnStopGame        'Variable used in main processing section to
'determine when to stop the game
Dim blnValidCell       'Boolean variable that determines whether a player
'specified a valid cell
Dim intNoMoves         'Variable to keep track of the number of plays
Dim intPlayAgain       'Variable holds player response when asked to play
'again
Dim strNotificationMsg 'Variable to display messages to player
Dim strPlayer          'Variable to identify whose turn it is
Dim strWinner          'Variable to determine whether the game is won
Dim strPlayerInput     'Variable to hold the player’s cell selection
Dim strDirection       'Variable identifies how the player won the game
blnStopGame = "False"
2.3 主处理部分逻辑开发

游戏的主处理部分由 Do…Until 循环和一系列过程调用组成。循环会一直执行,直到玩家决定停止游戏,通过布尔变量 blnStopGame 进行跟踪。

Do Until blnStopGame = "True"  'Keep playing until players decide to stop
    SetVariableDefaults()
    ClearGameBoard()
    ManageGamePlay()
    If blnPlayerTypedQuit = "True" Then  'One of the players typed Quit
        blnStopGame = "True"
    Else  'The game is over. Ask the players whether they’d like to play again
        intPlayAgain = MsgBox("Would you like to play another game of " & _
        "Tic Tac Toe?", 4, cTitleBarMsg)
        If intPlayAgain = 7 Then 'A player clicked on No. B break out of loop
            blnStopGame = "True"
        End If
    End If
Loop
DisplaySplashScreen()

下面是这个主处理流程的 mermaid 流程图:

graph TD;
    A[开始] --> B{blnStopGame = "True"?};
    B -- 否 --> C[SetVariableDefaults()];
    C --> D[ClearGameBoard()];
    D --> E[ManageGamePlay()];
    E --> F{blnPlayerTypedQuit = "True"?};
    F -- 是 --> G[blnStopGame = "True"];
    F -- 否 --> H[询问是否再玩一局];
    H --> I{选择否?};
    I -- 是 --> G;
    I -- 否 --> B;
    B -- 是 --> J[DisplaySplashScreen()];
    J --> K[结束];
2.4 各函数的构建
  • SetVariableDefaults() 函数
Function SetVariableDefaults()   'Establish default variable settings
    blnGameOver = "False"
    blnPlayerTypedQuit = "False"
    blnValidCell = "False"
    intNoMoves = 0
    strNotificationMsg = "Welcome! To play Tic Tac Toe follow the " & _
    "instructions at the bottom of the screen. Type Quit to terminate " & _
    "the game at any time."
    strPlayer = "X"
    strWinner = "None"
    strDirection = ""
End Function
  • ClearGameBoard() 函数
Function ClearGameBoard()  'Reset the game board
    A1 = " "
    A2 = " "
    A3 = " "
    B1 = " "
    B2 = " "
    B3 = " "
    C1 = " "
    C2 = " "
    C3 = " "
End Function
  • ManageGamePlay() 函数
Function ManageGamePlay()  'Manage the overall execution of the game
    Do Until blnGameOver = "True"
        'Start by checking to see if the game has already been completed
        If strWinner = "X" Then
            strNotificationMsg = "Game over! Player X wins " & strDirection
            DisplayGameResults()
            blnGameOver = "True"
        End If
        If strWinner = "O" Then
            strNotificationMsg = "Game over! Player O wins " & strDirection
            DisplayGameResults()
            blnGameOver = "True"
        End If
        If strWinner = "Nobody" Then
            strNotificationMsg = "Game over. It’s a tie!"
            DisplayGameResults()
            blnGameOver = "True"
        End If
        If blnGameOver <> "True" Then 'If game is not over display the board
            DisplayBoard()              'in order to collect next player’s input
            ValidateInput()             'Validate the input
            If UCase(strPlayerInput) = "QUIT" Then  'See if a player typed Quit
                blnPlayerTypedQuit = "True"
                blnValidCell = "False"
                blnGameOver = "True"
            End If
        End If
        'Count the number of valid cell selections
        If blnValidCell = "True" Then
            intNoMoves = intNoMoves + 1
            MarkPlayerSelection()
        End If
        'If all nine cells have been filled in we have a tie
        If intNoMoves = 9 Then
            SeeIfWon()
            If strWinner = "None" Then
                strWinner = "Nobody"
            End If
        Else
            SeeIfWon()
        End If
        'Time to switch player turns
        If blnValidCell = "True" Then
            If strPlayer = "X" Then
                strPlayer = "O"
            Else
                strPlayer = "X"
            End If
        End If
    Loop
End Function

这个函数的执行流程可以用以下 mermaid 流程图表示:

graph TD;
    A[开始] --> B{blnGameOver = "True"?};
    B -- 否 --> C{strWinner = "X"?};
    C -- 是 --> D[显示玩家 X 获胜结果];
    D --> E[blnGameOver = "True"];
    C -- 否 --> F{strWinner = "O"?};
    F -- 是 --> G[显示玩家 O 获胜结果];
    G --> E;
    F -- 否 --> H{strWinner = "Nobody"?};
    H -- 是 --> I[显示平局结果];
    I --> E;
    H -- 否 --> J[显示游戏板];
    J --> K[验证输入];
    K --> L{输入为 "QUIT"?};
    L -- 是 --> M[设置退出标志];
    M --> E;
    L -- 否 --> N{输入有效?};
    N -- 是 --> O[intNoMoves 加 1];
    O --> P[MarkPlayerSelection()];
    P --> Q{intNoMoves = 9?};
    Q -- 是 --> R[SeeIfWon()];
    R --> S{strWinner = "None"?};
    S -- 是 --> T[strWinner = "Nobody"];
    S -- 否 --> U[继续];
    Q -- 否 --> R;
    N -- 否 --> U;
    U --> V[切换玩家];
    V --> B;
    B -- 是 --> W[结束];
  • DisplayBoard() 函数
Function DisplayBoard()  'Display the game board
    strPlayerInput = UCase(InputBox(vbCrLf & strNotificationMsg & _
    vbCrLf & vbCrLf & vbCrLf & vbCrLf & _
    vbTab & "1" & vbTab & vbTab & "2" & vbTab & vbTab & "3" & vbCrLf & _
    vbCrLf & vbTab & vbTab & "|" & vbTab & vbTab & "|" & vbTab & _
    vbCrLf & "A" & vbTab & A1 & vbTab & "|" & vbTab & A2 & vbTab & _
    "|" & vbTab & A3 & vbCrLf & vbTab & vbTab & "|" & vbTab & vbTab & _
    "|" & vbTab & vbCrLf & "      ————————————————-" & _
    "———————————————————" & vbCrLf & vbTab & _
    vbTab & "|" & vbTab & vbTab & "|" & vbTab & vbCrLf & "B" & vbTab & _
    B1 & vbTab & "|" & vbTab & B2 & vbTab & "|" & vbTab & B3 & _
    vbCrLf & vbTab & vbTab & "|" & vbTab & vbTab & "|" & vbTab & _
    vbCrLf & "      ———————————————————————" & _
    "————————————-" & vbCrLf & vbTab & vbTab & "|" & _
    vbTab & vbTab & "|" & vbTab & vbCrLf & "C" & vbTab & C1 & vbTab & _
    "|" & vbTab & C2 & vbTab & "|" & vbTab & C3 & vbCrLf & vbTab & _
    vbTab & "|" & vbTab & vbTab & "|" & vbTab & vbCrLf & vbCrLf & _
    vbCrLf & vbCrLf & "Player " & strPlayer & _
    "'s turn. Type your move:", cTitleBarMsg))
End Function
  • DisplayGameResults() 函数
Function DisplayGameResults()  'Game is over. Display the results.
    MsgBox vbCrLf & _
    strNotificationMsg & _
    vbCrLf & vbCrLf & vbCrLf & vbCrLf & _
    vbTab & "1" & vbTab & vbTab & "2" & vbTab & vbTab & "3" & vbCrLf & _
    vbCrLf & vbTab & vbTab & "|" & vbTab & vbTab & "|" & vbTab & _
    vbCrLf & "A" & vbTab & A1 & vbTab & "|" & vbTab & A2 & vbTab & _
    "|" & vbTab & A3 & vbCrLf & vbTab & vbTab & "|" & vbTab & vbTab & _
    "|" & vbTab & vbCrLf & _
    "      ————————————————————————————" & _
    vbCrLf & vbTab & vbTab & "|" & vbTab & vbTab & _
    "|" & vbTab & vbCrLf & "B" & vbTab & B1 & vbTab & "|" & vbTab & _
    B2 & vbTab & "|" & vbTab & B3 & vbCrLf & vbTab & vbTab & "|" & _
    vbTab & vbTab & "|" & vbTab & vbCrLf & "      —————————" & _
    "———————————————————" & vbCrLf & _
    vbTab & vbTab & "|" & vbTab & vbTab & "|" & vbTab & vbCrLf & _
    "C" & vbTab & C1 & vbTab & "|" & vbTab & C2 & vbTab & "|" & vbTab & _
    C3 & vbCrLf & vbTab & vbTab & "|" & vbTab & vbTab & "|" & vbTab & _
    vbCrLf & vbCrLf & vbCrLf & vbCrLf, , cTitleBarMsg
End Function
  • ValidateInput() 函数
Function ValidateInput()  'Run tests to determine if player input is valid
    Select Case strPlayerInput  'Ensure a valid cell was specified
        Case "A1"
            blnValidCell = "True"
        Case "A2"
            blnValidCell = "True"
        Case "A3"
            blnValidCell = "True"
        Case "B1"
            blnValidCell = "True"
        Case "B2"
            blnValidCell = "True"
        Case "B3"
            blnValidCell = "True"
        Case "C1"
            blnValidCell = "True"
        Case "C2"
            blnValidCell = "True"
        Case "C3"
            blnValidCell = "True"
        Case Else
            blnValidCell = "False"
            strNotificationMsg = "Invalid cell. Please try again."
    End Select
    If strPlayerInput = "" Then  'Player must type something
        strNotificationMsg = "Missing entry. Please try again."
        blnValidCell = "False"
    End If
    'Check each cell to make sure that it has not already been selected
    If strPlayerInput = "A1" Then
        If A1 <> " " Then
            blnValidCell = "False"
            strNotificationMsg = "Invalid entry. Cell already selected. " & _
            "Please try again."
        End If
    End If
    '其他单元格检查代码类似,此处省略
    If strPlayerInput = "C3" Then
        If C3 <> " " Then
            blnValidCell = "False"
            strNotificationMsg = "Invalid entry. Cell already selected. " & _
            "Please try again."
        End If
    End If
End Function
  • MarkPlayerSelection() 函数
Function MarkPlayerSelection()  'Mark an X or O in the appropriate cell
    If strPlayerInput = "A1" Then
        A1 = strPlayer
    End If
    If strPlayerInput = "A2" Then
        A2 = strPlayer
    End If
    '其他单元格标记代码类似,此处省略
    If strPlayerInput = "C3" Then
        C3 = strPlayer
    End If
End Function
  • SeeIfWon() 函数
Function SeeIfWon()
    'Check across the first row
    If A1 = strPlayer Then
        If A2 = strPlayer Then
            If A3 = strPlayer Then
                strWinner = strPlayer
                strDirection = "- First row across!"
            End If
        End If
    End If
    '其他行、列和对角线检查代码类似,此处省略
    'Check the diagonally
    If A3 = strPlayer Then
        If B2 = strPlayer Then
            If C1 = strPlayer Then
                strWinner = strPlayer
                strDirection = "- Diagonally C1 - A3!"
            End If
        End If
    End If
End Function
  • DisplaySplashScreen() 函数
Function DisplaySplashScreen()   'Display splash screen and terminate game
    MsgBox "Thank you for playing Tic Tac Toe" & _
    "© Jerry Ford 2014." & vbCrLf & vbCrLf & "Please play again " & _
    "soon!", 4144, cTitleBarMsg
    WScript.Quit()
End Function
3. 最终结果

现在,你已经拥有了开发井字棋游戏所需的所有代码。在输入代码后,多次运行井字棋游戏,确保在输入脚本时没有意外输入错别字。当一切都正常运行后,就可以邀请朋友一起玩,展示你所学到的知识了。

正则表达式匹配与井字棋游戏开发

4. 代码分析与优化建议
4.1 正则表达式匹配部分

在正则表达式匹配示例中,我们使用了 RegExp 对象的 Execute() 方法来生成并处理 Matches 集合。这种方法可以有效地找出所有匹配的模式,并获取它们在字符串中的起始位置。不过,代码中没有展示 objRegExp 的定义和 Pattern 属性的设置,在实际使用时,需要先设置好正则表达式的模式。例如:

Dim objRegExp
Set objRegExp = New RegExp
objRegExp.Pattern = "bear"  '设置匹配模式为 "bear"
strStory = "Once upon a time there were three little bears. There " & _
"was a mama bear, a papa bear, and a baby bear. There was a cousin bear too!"
Set objMatchCollection = objRegExp.Execute(strStory)
Dim strDisplayMsg
For Each objMatch In objMatchCollection
    strDisplayMsg = strDisplayMsg & "An instance of " & _
    objRegExp.Pattern & " found at position " & objMatch.FirstIndex & _
    vbCrLf
Next
MsgBox strDisplayMsg

这样,代码就能正确匹配字符串中所有的 “bear” 并显示其位置。

4.2 井字棋游戏部分
  • 变量命名与可读性 :在井字棋游戏代码中,变量命名虽然有一定的注释说明,但可以进一步优化以提高代码的可读性。例如,将 A1, A2, A3, B1, B2, B3, C1, C2, C3 封装成一个二维数组,这样可以更方便地管理和操作游戏板的单元格。以下是优化后的代码示例:
Dim gameBoard(2, 2) '定义一个 3x3 的二维数组表示游戏板
Dim row, col
'初始化游戏板
For row = 0 To 2
    For col = 0 To 2
        gameBoard(row, col) = " "
    Next
Next
  • 输入验证部分 ValidateInput() 函数中使用 Select Case 语句来验证输入,代码比较冗长。可以使用更简洁的方法,例如使用正则表达式来验证输入是否为有效的单元格坐标。以下是优化后的代码:
Function ValidateInput()  'Run tests to determine if player input is valid
    Dim objRegExp
    Set objRegExp = New RegExp
    objRegExp.Pattern = "^[ABC][1-3]$" '验证输入是否为 A1 - C3 的格式
    If objRegExp.Test(strPlayerInput) Then
        Dim row, col
        Select Case Left(strPlayerInput, 1)
            Case "A"
                row = 0
            Case "B"
                row = 1
            Case "C"
                row = 2
        End Select
        col = CInt(Right(strPlayerInput, 1)) - 1
        If gameBoard(row, col) = " " Then
            blnValidCell = "True"
        Else
            blnValidCell = "False"
            strNotificationMsg = "Invalid entry. Cell already selected. " & _
            "Please try again."
        End If
    Else
        blnValidCell = "False"
        strNotificationMsg = "Invalid cell. Please try again."
    End If
End Function
  • 获胜判断部分 SeeIfWon() 函数中进行了大量的条件判断,代码较为复杂。可以使用循环来简化判断逻辑,提高代码的可维护性。以下是优化后的代码:
Function SeeIfWon()
    Dim row, col
    '检查行
    For row = 0 To 2
        If gameBoard(row, 0) = strPlayer And gameBoard(row, 1) = strPlayer And gameBoard(row ,2) = strPlayer Then
            strWinner = strPlayer
            strDirection = "- Row " & Chr(65 + row) & " across!"
            Exit Function
        End If
    Next
    '检查列
    For col = 0 To 2
        If gameBoard(0, col) = strPlayer And gameBoard(1, col) = strPlayer And gameBoard(2, col) = strPlayer Then
            strWinner = strPlayer
            strDirection = "- Column " & col + 1 & " down!"
            Exit Function
        End If
    Next
    '检查对角线
    If gameBoard(0, 0) = strPlayer And gameBoard(1, 1) = strPlayer And gameBoard(2, 2) = strPlayer Then
        strWinner = strPlayer
        strDirection = "- Diagonally A1 - C3!"
        Exit Function
    End If
    If gameBoard(0, 2) = strPlayer And gameBoard(1, 1) = strPlayer And gameBoard(2, 0) = strPlayer Then
        strWinner = strPlayer
        strDirection = "- Diagonally C1 - A3!"
        Exit Function
    End If
End Function
5. 总结

通过本文,我们学习了如何使用 VBScript 进行正则表达式匹配,以及如何开发一个完整的井字棋游戏。在开发过程中,我们了解了游戏的设计思路、主处理逻辑和各个函数的实现方法。同时,我们也对代码进行了分析,并提出了一些优化建议,以提高代码的可读性和可维护性。

以下是井字棋游戏开发的关键步骤总结表格:
| 步骤 | 描述 |
| ---- | ---- |
| 1. 定义常量和变量 | 初始化游戏所需的各种常量和变量 |
| 2. 主处理部分 | 使用 Do…Until 循环控制游戏的进行,直到玩家决定停止 |
| 3. 构建函数 | 实现 SetVariableDefaults() ClearGameBoard() 等九个函数,完成游戏的各项功能 |
| 4. 输入验证 | 确保玩家输入的是有效的单元格坐标 |
| 5. 获胜判断 | 检查游戏板,判断是否有玩家获胜或平局 |
| 6. 显示结果 | 游戏结束后,显示最终结果 |

希望本文能对大家学习 VBScript 和开发简单游戏有所帮助。现在,你可以根据优化后的代码,进一步完善井字棋游戏,或者尝试开发其他类型的游戏。

最后,再次强调,在实际开发中,要注意代码的可读性和可维护性,通过合理的设计和优化,让代码更加健壮和高效。祝你在编程的道路上取得更多的进步!

以下是优化后井字棋游戏主处理部分的 mermaid 流程图:

graph TD;
    A[开始] --> B{blnStopGame = "True"?};
    B -- 否 --> C[SetVariableDefaults()];
    C --> D[ClearGameBoard()];
    D --> E[ManageGamePlay()];
    E --> F{blnPlayerTypedQuit = "True"?};
    F -- 是 --> G[blnStopGame = "True"];
    F -- 否 --> H[询问是否再玩一局];
    H --> I{选择否?};
    I -- 是 --> G;
    I -- 否 --> B;
    B -- 是 --> J[DisplaySplashScreen()];
    J --> K[结束];
    subgraph ManageGamePlay
        L{blnGameOver = "True"?}
        L -- 否 --> M{strWinner = "X"?}
        M -- 是 --> N[显示玩家 X 获胜结果]
        N --> O[blnGameOver = "True"]
        M -- 否 --> P{strWinner = "O"?}
        P -- 是 --> Q[显示玩家 O 获胜结果]
        Q --> O
        P -- 否 --> R{strWinner = "Nobody"?}
        R -- 是 --> S[显示平局结果]
        S --> O
        R -- 否 --> T[显示游戏板]
        T --> U[验证输入]
        U --> V{输入为 "QUIT"?}
        V -- 是 --> W[设置退出标志]
        W --> O
        V -- 否 --> X{输入有效?}
        X -- 是 --> Y[intNoMoves 加 1]
        Y --> Z[MarkPlayerSelection()]
        Z --> AA{intNoMoves = 9?}
        AA -- 是 --> AB[SeeIfWon()]
        AB --> AC{strWinner = "None"?}
        AC -- 是 --> AD[strWinner = "Nobody"]
        AC -- 否 --> AE[继续]
        AA -- 否 --> AB
        X -- 否 --> AE
        AE --> AF[切换玩家]
        AF --> L
        L -- 是 --> AG[结束]
    end

这个流程图展示了优化后井字棋游戏主处理部分和 ManageGamePlay() 函数的详细流程,帮助你更好地理解游戏的执行逻辑。

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符  | 博主筛选后可见
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值