다음을 통해 공유


Vb.Net - Hidden words



Overview

This is a word find game. All of the words used are eight to ten characters in length. The clues are (eight to ten) national flags. Identify the nation from its flag, and that will give you one letter in the word you're searching for. If you can't identify a flag, you can either guess the remaining letters in the word you're searching for, or right click the flag for assistance with identifying the flag.

The GUI consists of a Form, two Buttons, a DataGridView, ten PictureBoxes, a ContextMenuStrip, and ten Labels...


The Game Class

The Game Class contains one Public Method and two Private Functions, which are used to fit between eight and ten nation names, centred in a 35 column by 10 row String array. As the random number of countries are selected in the newGame method, the flag is displayed in the correct PictureBox, and the cell address for the label is recorded in another array.
These two arrays are all of the information the GUI needs to render the DataGridView for a new game.

The newGame Sub-procedure

This is the only Public method in the Game Class. The two Functions are helper methods...



  

      Public Sub  newGame(ByVal  r As  Random, ByVal  wordLength As  Integer, ByVal words() As String,
                                        ByRef wordToFind As String, ByRef  column As  Integer, ByVal flagnames() As String,  
                                        ByVal gridArray(,) As String, ByVal  pictureboxes() As  PictureBox, ByVal  labelIndices() As  Integer)  
               
               
                    Dim subset() As String  = words.Where(Function(s) s.Length = wordLength).ToArray  
                    wordToFind = subset(r.      Next      (0, subset.Length))      
                    column = r.      Next      (6, 28)      
               
                    Dim countriesUsed(wordLength - 1) As String  
                    Dim indexUsed(wordLength - 1) As Integer  
               
                    nearX = 35      
                    farX = 0      
               
                    Do      
                        ReDim countriesUsed(wordLength - 1)  
                        For y2 = 0 To wordLength - 1  
                            Dim tempLetter As String  = wordToFind(y2)  
                            Dim tempColumn As Integer  = column  
                            Dim countries() As String  = flagnames.Where(Function(c) isFit(c, tempLetter, tempColumn) And  Not countriesUsed.Contains(c)).ToArray  
                            If countries.Length = 0 Then Continue Do  
                            Dim chosen As String  = countries(r.Next(0, countries.Length))  
                            indexUsed(y2) = -1      
                            fitCountryClue(r, chosen, wordToFind(y2), column, y2,       False      , indexUsed(y2), pictureboxes, gridArray)      
                            countriesUsed(y2) = chosen      
                            If y2 = wordLength - 1 Then Exit  Do  
                        Next      
                    Loop      
               
                    Dim half As Integer  = (nearX + (34 - farX)) \ 2  
                    If nearX >= half Then  
                        column -= (nearX - half)      
                    ElseIf farX >= half Then  
                        column += ((34 - farX) - half)      
                    End If  
               
                    For x2 As Integer  = 0 To  34  
                        For y2 = 0 To 9  
                            gridArray(x2, y2) =       ""      
                        Next      
                    Next      
               
                    For y2 = 0 To wordLength - 1  
                        Dim chosen As String  = countriesUsed(y2)  
                        labelIndices(y2) = fitCountryClue(r, chosen, wordToFind(y2), column, y2,       True      , indexUsed(y2), pictureboxes, gridArray)      
                    Next      
      End Sub

The isFit Function

This is used within a Lambda Function to get an array of all countries which could be used at that row in the array.

Private Function  isFit(ByVal  country As  String, ByVal letter As String, ByVal  insertAt As  Integer) As Boolean
    Dim indices As New  List(Of Integer)
 
    For x As Integer  = 0 To  country.Length - 1
        If country(x) = letter Then
            indices.Add(x)
        End If
    Next
 
    Return indices.Where(Function(x) insertAt - x > 0 And  insertAt + (country.Length - x) <= 34).Count > 0
End Function

The fitCountryClue Function

This is used to find the best fit in the array. Country names often have more than one instance of a character, and the first instance isn't always the instance placed within the hidden word in this game.



  

      Private Function  fitCountryClue(ByVal  r As  Random, ByVal  country As  String, ByVal letter As String, ByVal  insertAt As  Integer,
                         ByVal row As Integer, ByVal  doLabels As  Boolean, ByRef indexUsed As Integer, ByVal  pictureboxes() As  
      PictureBox,     ByVal  gridArray(,) As  String) As Integer
              
                    Dim indices As New  List(Of Integer)  
               
                    For x As Integer  = 0 To  country.Length - 1  
                        If country(x) = letter Then  
                            If insertAt - x > 0 And insertAt + (country.Length - x) <= 34 Then  
                                indices.Add(x)      
                            End If  
                        End If  
                    Next      
               
                    If indexUsed = -1 Then  
                        indexUsed = indices(r.      Next      (0, indices.Count))      
                        pictureboxes(row).Image =       DirectCast      (My.Resources.ResourceManager.GetObject(country), Bitmap)      
                    End If  
                    Dim startIndex As Integer  = insertAt - indexUsed  
               
                    country = country.Replace(      "_d_"      ,       " d'"      ).Replace(      "___"      ,       " & "      ).Replace(      "_"      ,       " "      )      
                    pictureboxes(row).Tag = country      
                 
                    If startIndex < nearX Then nearX = startIndex  
                    If startIndex + country.Length - 1 > farX Then farX = startIndex + country.Length - 1  
                    
                    For x As Integer  = 0 To  country.Length - 1  
                        gridArray(startIndex + x, row) = UCase(country(x))      
                    Next      
               
                    If doLabels Then  
                        Return startIndex - 1  
                    End If  
               
                    Return -1  
      End Function

Conclusion 

This is another example of how to create simple games using regular Controls in a WinForms application in VB.Net. Control Properties can be set in unorthodox ways to create a Control that isn't easily identified as the actual Control it is. In this way it's possible to use regular Controls to create a variety of differing games, each with a unique look.


VB.Net - WordSearch
VB.Net - Vertex
VB.Net - Perspective
VB.Net - MasterMind
VB.Net - OOP BlackJack
VB.Net - Numbers Game
VB.Net - HangMan
Console BlackJack - VB.Net | C#
TicTacToe - VB.Net | C#
OOP Sudoku - VB.Net | C#
OctoWords VB.Net | C#
OOP Buttons Guessing Game VB.Net | C#
OOP Tangram Shapes Game VB.Net | C#


Downloads

Download here...