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
Articles related to game programming
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