다음을 통해 공유


VB.Net - OctoWords


Overview

OctoWords is an original word puzzle game. To play, drag letters to form words. You can drag a letter in any straight line (horizontally, vertically, or diagonally), as long as the straight line path is clear. The game won't allow you to make an invalid move, but it can't force you to play a valid move, so the onus is on you.

As each newly formed word is recognized it disappears from the grid, and your score is incremented. each word you form is worth the length of the word multiplied by the length of the word minus one. Words entirely contained in the green octagon are worth 3x as much as words partially or completely outside of the octagon.

Most words recognized by the game are two, three, or four character words, but more skillful players can create longer words, and also creating situations where two or more words are formed by placing one character will earn you extra points.

Theoretically, words that will be recognized range from two to twenty characters, but as you'll see it's difficult to build a long word without the smaller words contained within your longer word being recognized first, so there is a large amount of skill necessary to become a proficient player.


The Game Class code

The Game class is used for creating each new game, and also for checking if there are any possible words left to find in the grid after each move at every stage of the game.

Public Class  Game
 
    Private Shared  vowels1() As  String = {"A", "E", "I", "O"}
    Private Shared  vowels2() As  String = {"A", "E", "I", "O", "U"}
    Private Shared  consonants1() As  String = {"B", "C", "D", "F", "G", "L", "M", "N", "P", "R", "S", "T"}
    Private Shared  consonants2() As  String = Enumerable.Range(Asc("A"), 26).Select(Function(x) Chr(x).ToString).Except(vowels2).ToArray
    Private Shared  chars(231) As  String
 
    Public Shared  Sub getLetters(ByVal r As Random)
        '90 vowels
        '142 consonants
 
        For x As Integer  = 0 To  89
            Dim choice As Integer  = r.Next(1, 4)
            If choice < 3 Then
                chars(x) = vowels1(r.Next(0, 4))
            Else
                chars(x) = vowels2(r.Next(0, 5))
            End If
        Next
        For x As Integer  = 90 To  231
            Dim choice As Integer  = r.Next(1, 6)
            If choice < 5 Then
                chars(x) = consonants1(r.Next(0, 12))
            Else
                chars(x) = consonants2(r.Next(0, 21))
            End If
        Next
 
    End Sub
 
    Private Shared  Function getCells(ByVal r As Random) As Integer()
        Dim indices(231) As Integer
        Dim allIndices As List(Of Integer) = Enumerable.Range(0, 484).ToList
 
        For x As Integer  = 0 To  231
            Dim i As Integer  = allIndices(r.Next(0, allIndices.Count))
            allIndices.Remove(i)
            indices(x) = i
        Next
 
        Return indices
 
    End Function
 
    Public Shared  Function newGame(ByVal r As Random, ByVal grid()() As String) As  String()()
 
        chars = chars.OrderBy(Function(x) r.NextDouble).ToArray
        Dim indices() As Integer  = getCells(r)
 
        Dim counter As Integer  = 0
        For y As Integer  = 0 To  21
            For x As Integer  = 0 To  21
                If indices.Contains(y * 22 + x) Then
                    grid(y)(x) = chars(counter)
                    counter += 1
                Else
                    grid(y)(x) = ""
                End If
            Next
        Next
 
        Return grid
 
    End Function
 
    Public Shared  Function GameOver(ByVal grid()() As String) As  PlayState
        Dim letters As New  List(Of String)
        For y As Integer  = 0 To  21
            letters.AddRange(grid(y).Where(Function(c) c <> "").ToArray)
        Next
 
        If letters.Any(Function(s) vowels2.Contains(s)) Then
            For x As Integer  = 2 To  20
                For Each  word As  String In  Words.getWords(x)
                    Dim newLetters As New  List(Of String)(letters)
                    Dim match As Boolean  = True
                    For c As Integer  = 0 To  word.Length - 1
                        If newLetters.Contains(word.Substring(c, 1)) Then
                            newLetters.Remove(word.Substring(c, 1))
                            If c = word.Length - 1 Then
                                Return New  PlayState(False, 0)
                            End If
                        Else
                            match = False
                            Exit For
                        End If
                    Next
                Next
            Next
        End If
 
        Return New  PlayState(True, 484 - letters.Count)
    End Function
 
End Class

frmHighScores code

frmHighScores displays the five highest scores, which are saved in a Settings Specialized.StringCollection. The Form shows at the end of each game, and also has a TreeView (in a slideOutPanel) that shows how many words of which length were found in that game.

Public Class  frmHighScores
 
    Private newScore As Integer
    Private dt As New  DataTable
    Private dtIndex As Integer
 
    Public Sub  New(ByVal score As Integer, ByVal  wordsFound As  Dictionary(Of Integer, List(Of String)))
        InitializeComponent()
        Me.newScore = score
        If My.Settings.highScores Is Nothing  Then
            My.Settings.highScores = New  Specialized.StringCollection
            For x As Integer  = 1 To  5
                My.Settings.highScores.Add("Player" & x.ToString & "|" & "0")
            Next
        End If
        dt.Columns.Add("name")
        dt.Columns.Add("score", GetType(Integer))
        For x As Integer  = 1 To  5
            dt.Rows.Add(My.Settings.highScores(x - 1).Split("|"c))
        Next
 
        ExDGV1.AutoGenerateColumns = False
        ExDGV1.Columns(0).DataPropertyName = "name"
        ExDGV1.Columns(1).DataPropertyName = "score"
        ExDGV1.DataSource = dt
        Dim keys() As Integer  = wordsFound.Keys.ToArray
        Array.Sort(keys)
        Dim node As TreeNode = TreeView1.Nodes.Add("Words (" & keys.Sum(Function(x) wordsFound(x).Count) & ")")
        For Each  x As  Integer In  keys
            Dim allWords() As String  = Words.getWords(x)
            Dim secondNode As TreeNode = node.Nodes.Add(x.ToString & " letter words (" & wordsFound(x).Count & ")")
            For Each  s As  String In  wordsFound(x)
                If allWords.Contains(StrReverse(s)) And Not  allWords.Contains(s) Then
                    secondNode.Nodes.Add(StrReverse(s))
                Else
                    secondNode.Nodes.Add(s)
                End If
            Next
        Next
 
        Label5.Text = "Longest word found was "  & keys.Last.ToString & " letters"
        node.Expand()
    End Sub
 
    Private Sub  frmHighScores_FormClosing(ByVal sender As Object, ByVal  e As  System.Windows.Forms.FormClosingEventArgs) Handles Me.FormClosing
        My.Settings.highScores.Clear()
        For x As Integer  = 0 To  dt.Rows.Count - 1
            My.Settings.highScores.Add(String.Join("|", Array.ConvertAll(dt.Rows(x).ItemArray, Function(o) o.ToString)))
        Next
        My.Settings.Save()
    End Sub
 
    Private Sub  frmHighScores_Load(ByVal sender As System.Object, ByVal  e As  System.EventArgs) Handles MyBase.Load
        ExDGV1.isEnabled = False
        Me.BackColor = Color.FromArgb(255, 255, 128)
        Button1.BackColor = Color.FromArgb(255, 255, 128)
        Button2.BackColor = Color.FromArgb(255, 255, 128)
        Button3.BackColor = Color.FromArgb(255, 255, 128)
        GroupBox1.BackColor = Color.FromArgb(255, 255, 128)
        SlideOutPanel1.BackColor = Color.FromArgb(255, 255, 128)
        TreeView1.BackColor = Color.FromArgb(255, 255, 128)
        TreeView1.ForeColor = Color.DarkGray
    End Sub
 
    Private Sub  ExDGV1_CellValueChanged(ByVal sender As Object, ByVal  e As  System.Windows.Forms.DataGridViewCellEventArgs) Handles ExDGV1.CellValueChanged
        If e.RowIndex > -1 Then
            ExDGV1.Rows(e.RowIndex).Height = 50
            ExDGV1.Rows(e.RowIndex).Cells(0).Style.BackColor = Color.FromArgb(164, 255, 164)
            ExDGV1.Rows(e.RowIndex).Cells(1).Style.BackColor = Color.FromArgb(164, 255, 164)
        End If
    End Sub
 
    ''' <summary>
    ''' Necessary to handle user selections in the dgv.
    ''' </summary>
    ''' <param name="sender"></param>
    ''' <param name="e"></param>
    ''' <remarks></remarks>
    Private Sub  ExDGV1_SelectionChanged(ByVal sender As Object, ByVal  e As  System.EventArgs) Handles ExDGV1.SelectionChanged
        ExDGV1.ClearSelection()
    End Sub
 
    Private Sub  ExDGV1_CellFormatting(ByVal sender As Object, ByVal  e As  System.Windows.Forms.DataGridViewCellFormattingEventArgs) Handles ExDGV1.CellFormatting
        If e.ColumnIndex = 1 Then
            ExDGV1(e.ColumnIndex, e.RowIndex).Value = CInt(ExDGV1(e.ColumnIndex, e.RowIndex).Value).ToString("0000000")
        End If
    End Sub
 
    Private Sub  frmHighScores_Shown(ByVal sender As Object, ByVal  e As  System.EventArgs) Handles Me.Shown
        For x As Integer  = 0 To  dt.Rows.Count - 1
            If newScore > dt.Rows(x).Field(Of Integer)(1) Then
                Dim row As DataRow = dt.NewRow
                row.ItemArray = New  Object() {"", newScore}
                dt.Rows.InsertAt(row, x)
                dt.Rows.RemoveAt(5)
                dtIndex = x
                GroupBox1.Enabled = True
                Exit For
            End If
        Next
    End Sub
 
    Private Sub  Button3_Click(ByVal  sender As  System.Object, ByVal  e As  System.EventArgs) Handles Button3.Click
        dt.Rows(dtIndex).Item(0) = TextBox1.Text
    End Sub
 
End Class

Conclusion

Nowadays more than ever, the average person can invent, create, and market their ideas through the use of a desktop computer.
This game is a simple idea, and the code involved is easily written with a little experience. All of the controls used are standard VB controls, manipulated slightly to give the necessary functionality and overall appearance.
If you can dream it, you can code it...


Other Resources

Download here... (VB.Net | C#)


See Also

C# version


VB.Net - Perspective
VB.Net - Vertex
VB.Net - WordSearch
VB.Net - MasterMind
VB.Net - OOP BlackJack
VB.Net - Numbers Game
VB.Net - HangMan
Console BlackJack - VB.Net | C#
TicTacToe - VB.Net | C#
OOP Conway's Game of Life - VB.Net | C#
OOP Sudoku - VB.Net | C#
OOP Buttons Guessing Game VB.Net | C#
OOP Tangram Shapes Game VB.Net | C#
VB.Net - Three-card Monte
VB.Net - Split Decisions
VB.Net - Pascal's Pyramid
VB.Net - Random Maze Games
(Office) Wordsearch Creator
VB.Net - Event Driven Programming - LockWords Game
C# - Crack the Lock
VB.Net - Totris