13,899,680 members
Article
alternative version

#### Stats

4.9K views
5 bookmarked
Posted 16 Aug 2017
Licenced CPOL

# Dots mania (Game tutorial)

, 18 Aug 2017
Simple game tutorial. Play in dots with your family and friend.

## Introduction

Dots is another famous game we will create. The rules are simple, you need to circle the opponent's dots. I played dots quite often in high school, mainly on religion :P. I have a big sentiment for this game so when I learned to program, I really wanted to do this game. After some unsuccessful attempts, I surrendered a little, but returned to the project and finished it. The tutorial is designed to present the idea of a lap of dots which is the main element of the game.

## Using the code

The form that will be demonstrated in this tutorial is quite simple:

Element typeElement nameProperties
FormForm1

Name: Form1

Text: Dots mania

Size: 840; 663

PanelMain_board

Name: Main_board

Size: 800; 600

Location: 12;12

BackColor: White

Anchor: Top, Bottom, Left, Right

In this tutorial, the game starts when form load, we will not build unnecessary buttons and embellishments that will only obscure and blur the main engine of the game. Our game will look like the gif below:

Anyone who understands what the method of circling the dots do, will be able to add additional elements he wants to. We create Form Load:

```Public Class Form1
'Main board size
Dim bHeight As Integer = 15
Dim bWidth As Integer = 20
Dim PLocationList As New List(Of List(Of Panel)) 'all panels on the board list

For i As Integer = -2 To bWidth + 1
Dim PanList As New List(Of Panel)
For j As Integer = -2 To bHeight + 1
Dim MainPanel As New Panel
With MainPanel
.Location = New Point(i * 40 + 30, j * 40 + 30)
.Size = New Size(20, 20)
.BackColor = Color.Transparent
.Name = "panL_" + i.ToString + "^" + j.ToString + "^"
.Cursor = Cursors.Hand
'Cross out the board, explain on the tutorial
If i = -2 Or i = -1 Or j = -1 Or j = -2 Or i = bWidth Or j = bHeight Or i = bWidth + 1 Or j = bHeight + 1 Then
.Enabled = False
End If
End With
Next
'The variable stores all board panels
Next
'generate board grid
Dim bit As Bitmap = New Bitmap(Main_board.Width, Main_board.Height)
Dim g As Graphics = Graphics.FromImage(bit)

Dim myPen As Pen = New Pen(Color.FromArgb(191, 218, 229), 1)
For i As Integer = 40 To Main_board.Height Step 40
g.DrawLine(myPen, 0, i, Main_board.Width, i)
Next
For i As Integer = 40 To Main_board.Width Step 40
g.DrawLine(myPen, i, 0, i, Main_board.Height)
Next
Main_board.BackgroundImage = bit
End Sub
End Class```

After launching the program our eyes should show a ready-to-dots page, you can be tempted to change it to look more like a page from a notebook. An important element that we should pay attention to is putting our panels outside the area of the sheet. Because during the program operation the elements will be processed in a logical way, this process will require checking the above, below, left and right side of the dot. Add additional panels which the user will not have access at the beginning will be more convenient than the given an restriction.
If we would color these areas, they will look like in the picture:

These areas will be treated as empty areas and their blocking will ensure that they stay that way.

Now it's time to unlock:

`AddHandler .Click, AddressOf pan_Click`

```    'Current player
Dim Player As Boolean = True
'dots list
Dim Player1DotsL As New List(Of Panel)
Dim Player2DotsL As New List(Of Panel)
Dim bit As Bitmap
Dim g As Graphics
'Colors
Dim pGreen As New System.Drawing.SolidBrush(System.Drawing.Color.Green)
Dim pRed As New System.Drawing.SolidBrush(Color.Red)

Public Sub pan_Click(ByVal sender As System.Object, ByVal e As System.EventArgs)
If Player Then 'green
bit = New Bitmap(20, 20)
g = Graphics.FromImage(bit)
'Added a checked panel to the list
g.FillEllipse(pGreen, New Rectangle(5, 5, 10, 10))
DirectCast(sender, Panel).BackgroundImage = bit
DirectCast(sender, Panel).Enabled = False
'LapTest()
Else 'red
bit = New Bitmap(20, 20)
g = Graphics.FromImage(bit)
'Added a checked panel to the list
g.FillEllipse(pRed, New Rectangle(5, 5, 10, 10))
DirectCast(sender, Panel).BackgroundImage = bit
DirectCast(sender, Panel).Enabled = False
'LapTest()
End If

End Sub
End Sub```

We can now put dots. One color, because the player does not change status to false, but will do it in another loop. Because the rules of the game require that. When a player encircle an opponent, he may place an extra dot.

As for the easy things, it's just over. Now you have to embrace what I mean by explaining how some things work. The hardest part of the game is to find out if the dots are encircled. When the dot is one, the situation is obvious. Check out all sides of dot if is surrounded by dots of the opponent. Unfortunately, this is one of the many situations we have to consider. I will try to explain what and how, if someone does not understand, then he can write me an email or leave a comment.

Unlock code:

`LapTest()`

The code for this element together with the first function looks like this:

```  Private Sub LapTest()
Dim EdgeList As New List(Of Panel)
If Not Player1DotsL.Count = 0 Then
End If
If Not Player2DotsL.Count = 0 Then
End If

End Sub

'The function returns elements adjacent to dots
Private Function Borders(ByRef PlayerList As List(Of Panel)) As List(Of Panel)
Dim BorderList As New List(Of Panel) 'hold adjacent items
For k As Integer = 0 To PlayerList.Count - 1

Dim positionX As Integer = 0
Dim positionY As Integer = 0
'Get actual panel position
For i As Integer = 0 To PLocationList.Count - 1
For j As Integer = 0 To PLocationList(i).Count - 1
If PLocationList(i)(j).Name = PlayerList(k).Name Then
positionX = i
positionY = j
End If
Next
Next
'Check that there are empty elements from left, right, top and bottom
If Not BorderList.Contains(PLocationList(positionX - 1)(positionY)) And
Not Player1DotsL.Contains(PLocationList(positionX - 1)(positionY)) And
Not Player2DotsL.Contains(PLocationList(positionX - 1)(positionY)) Then
End If
If Not BorderList.Contains(PLocationList(positionX + 1)(positionY)) And
Not Player1DotsL.Contains(PLocationList(positionX + 1)(positionY)) And
Not Player2DotsL.Contains(PLocationList(positionX + 1)(positionY)) Then
End If
If Not BorderList.Contains(PLocationList(positionX)(positionY + 1)) And
Not Player1DotsL.Contains(PLocationList(positionX)(positionY + 1)) And
Not Player2DotsL.Contains(PLocationList(positionX)(positionY + 1)) Then
End If
If Not BorderList.Contains(PLocationList(positionX)(positionY - 1)) And
Not Player1DotsL.Contains(PLocationList(positionX)(positionY - 1)) And
Not Player2DotsL.Contains(PLocationList(positionX)(positionY - 1)) Then
End If
Next
Return BorderList
End Function```

The methods contained in the above function return the list of elements adjacent to the dots.

In the photos we see colored adjoining elements. The next step is to create a particular list of elements. I call this list "freedomPoints". Any collision of an element or group during a lap check with this list will mean that the dots are not encircled.

```    Private Sub LapTest()
Dim EdgeList As New List(Of Panel)
If Not Player1DotsL.Count = 0 Then
End If
If Not Player2DotsL.Count = 0 Then
End If

Dim FreedomList As New List(Of List(Of Panel))
FreedomList = freedomPoints(EdgeList)

End Sub

'Points of freedom
Private Function freedomPoints(ByRef adjacent As List(Of Panel)) As List(Of List(Of Panel))
Dim PanelsList As New List(Of List(Of Panel))

Dim ListLength As Integer = PLocationList(0).Count
Dim ListSize As Integer = PLocationList.Count
For i As Integer = ListSize - 1 To 0 Step -1
Dim lista As New List(Of Panel)
For j As Integer = ListLength - 1 To 0 Step -1
Else
Exit For
End If

Next
Next
For i As Integer = 0 To ListSize - 1
Dim lista As New List(Of Panel)
For j As Integer = 0 To ListLength - 1
Else
Exit For
End If

Next
Next
For i As Integer = ListLength - 1 To 0 Step -1
Dim lista As New List(Of Panel)
For j As Integer = ListSize - 1 To 0 Step -1
Else
Exit For
End If
Next
If i = ListSize Then
Exit For
End If
Next
For i As Integer = 0 To ListLength - 1
Dim lista As New List(Of Panel)
For j As Integer = 0 To ListSize - 1
Else
Exit For
End If
Next
If i = ListSize Then
Exit For
End If
Next
Return PanelsList
End Function```

This function returns a list that contains checked elements from all sides:

As you can see in the picture, the elements border with dots are not added to the list because they are stored in another list(BorderList). How does this function work when we have more items? Well as in the image below:

Violet and blue elements are the result of the "freedomPoints" function, and the red is the effect of the "Borders". Look at the elements in the middle, surrounded by green dots, they have no color, they are very important because they will be our way to freedom from the encircle. We will now begin with a very important chapter in which we will group our dots. An important element here will be played by the player, we must know which player has just placed a dot. Such knowledge gives us a variable "Player". At the moment when a green dot is placed, we do not consider green dots, we consider red dots. Since all the dots of the red player are grouped together we check each groupis is breaking to our "FreedomList", if not any break, it means that it is encircled. Pre-grouping is pretty easy. We create groups of adjoining elements,we add them to the list, and then the lists that contain the same elements join together:

(Wygenerowana lista paneli - Generated panel list)

Let's see what the method code looks like:

```    Private Sub LapTest()
Dim EdgeList As New List(Of Panel)
If Not Player1DotsL.Count = 0 Then
End If
If Not Player2DotsL.Count = 0 Then
End If

Dim FreedomList As New List(Of List(Of Panel))
FreedomList = freedomPoints(EdgeList)

Dim GroupList As New List(Of List(Of Panel))

If Player Then 'Green
GroupList = Group(Player2DotsL)
Else 'Red
GroupList = Group(Player1DotsL)
End If

End Sub

'This function creates an initial group of dots
Private Function Group(ByRef PlayerList As List(Of Panel)) As List(Of List(Of Panel))
Dim Groups As New List(Of List(Of Panel))
'Enumerates all opponent dots
For k As Integer = 0 To PlayerList.Count - 1
Dim _continue As Boolean = True 'Block, does not add dots if already in some group
For i As Integer = 0 To Groups.Count - 1
If Groups(i).Contains(PlayerList(k)) Then
_continue = False
Exit For
End If
Next
If _continue = True Then
Dim PointsList As New List(Of Panel)
'Get dot position
Dim positionX As Integer = 0
Dim positionY As Integer = 0
For i As Integer = 0 To PLocationList.Count - 1
For j As Integer = 0 To PLocationList(i).Count - 1
If PLocationList(i)(j).Name = PlayerList(k).Name Then
positionX = i
positionY = j
End If
Next
Next
'Connects adjacent points to a group
If Not PointsList.Contains(PLocationList(positionX - 1)(positionY)) And
PlayerList.Contains(PLocationList(positionX - 1)(positionY)) Then
End If
If Not PointsList.Contains(PLocationList(positionX + 1)(positionY)) And
PlayerList.Contains(PLocationList(positionX + 1)(positionY)) Then
End If
If Not PointsList.Contains(PLocationList(positionX)(positionY + 1)) And
PlayerList.Contains(PLocationList(positionX)(positionY + 1)) Then
End If
If Not PointsList.Contains(PLocationList(positionX)(positionY - 1)) And
PlayerList.Contains(PLocationList(positionX)(positionY - 1)) Then
End If
End If
Next

For i As Integer = 0 To Groups.Count - 1
For j As Integer = 0 To Groups(i).Count - 1
Dim PFGroup As Panel = Groups(i)(j)
For r As Integer = 0 To Groups.Count - 1
If Not r = i And Groups(r).Contains(PFGroup) Then
'Merge lists
Groups(r).Clear()
End If
Next
Next
Next
'Removes empty lists
For i As Integer = Groups.Count - 1 To 0 Step -1
If Groups(i).Count = 0 Then
Groups.RemoveAt(i)
End If
Next
Return Groups
End Function```

The simplest example is an example with four dots:

For a moment in such lists we do not have to worry about repetitive elements. Such segregation, as we add colors, looks like this:

(Grupa-Group)

As we can see, Group B does not count empty fields for its group temporarily, so we do not know whether our group B is definitely encircled or not. The final stage is to add empty or boundary fields to our groups and remove from the list those groups that join our list of freedom.

```    Private Sub LapTest()
Dim EdgeList As New List(Of Panel)
If Not Player1DotsL.Count = 0 Then
End If
If Not Player2DotsL.Count = 0 Then
End If

Dim FreedomList As New List(Of List(Of Panel))
FreedomList = freedomPoints(EdgeList)

Dim GroupList As New List(Of List(Of Panel))

If Player Then 'Green
GroupList = Group(Player2DotsL)
GroupList = GroupEdition(Player1DotsL, GroupList, EdgeList, FreedomList)
Else 'Red
GroupList = Group(Player1DotsL)
GroupList = GroupEdition(Player2DotsL, GroupList, EdgeList, FreedomList)
End If

End Sub

Private Function GroupEdition(ByRef EnemyList As List(Of Panel), ByRef Groups As List(Of List(Of Panel)),
ByRef EdgeList As List(Of Panel), ByRef ZoneList As List(Of List(Of Panel))) As _
List(Of List(Of Panel))
'The loop checks each item and adds them to the groups
Do
Dim StartLoop As Boolean = False
For k As Integer = Groups.Count - 1 To 0 Step -1
For l As Integer = 0 To Groups(k).Count - 1
Dim positionX As Integer = 0
Dim positionY As Integer = 0
'Get the current position of our panel
For i As Integer = 0 To PLocationList.Count - 1
For j As Integer = 0 To PLocationList(i).Count - 1
If PLocationList(i)(j).Name = Groups(k)(l).Name Then
positionX = i
positionY = j
End If
Next
Next
Dim _continue As Boolean = True
For i As Integer = 0 To ZoneList.Count - 1
'The Group element touches the list of freedom items, which indicates that it is not encircled
If ZoneList(i).Contains(PLocationList(positionX - 1)(positionY)) Or
ZoneList(i).Contains(PLocationList(positionX + 1)(positionY)) Or
ZoneList(i).Contains(PLocationList(positionX)(positionY - 1)) Or
ZoneList(i).Contains(PLocationList(positionX)(positionY + 1)) Then
_continue = False
'Remove list from Groups
Groups.RemoveAt(k)
Exit For
End If
Next

If _continue = True Then
If EdgeList.Contains(PLocationList(positionX - 1)(positionY)) And
Not Groups(k).Contains(PLocationList(positionX - 1)(positionY)) Then
StartLoop = True
ElseIf Not EnemyList.Contains(PLocationList(positionX - 1)(positionY)) And
Not Groups(k).Contains(PLocationList(positionX - 1)(positionY)) Then
StartLoop = True
End If

If EdgeList.Contains(PLocationList(positionX + 1)(positionY)) And
Not Groups(k).Contains(PLocationList(positionX + 1)(positionY)) Then
StartLoop = True
ElseIf Not EnemyList.Contains(PLocationList(positionX + 1)(positionY)) And
Not Groups(k).Contains(PLocationList(positionX + 1)(positionY)) Then
StartLoop = True
End If

If EdgeList.Contains(PLocationList(positionX)(positionY + 1)) And
Not Groups(k).Contains(PLocationList(positionX)(positionY + 1)) Then
StartLoop = True
ElseIf Not EnemyList.Contains(PLocationList(positionX)(positionY + 1)) And
Not Groups(k).Contains(PLocationList(positionX)(positionY + 1)) Then
StartLoop = True
End If

If EdgeList.Contains(PLocationList(positionX)(positionY - 1)) And
Not Groups(k).Contains(PLocationList(positionX)(positionY - 1)) Then
StartLoop = True
ElseIf Not EnemyList.Contains(PLocationList(positionX)(positionY - 1)) And
Not Groups(k).Contains(PLocationList(positionX)(positionY - 1)) Then
StartLoop = True
End If
Else
Exit For
End If
Next
Next
'The loop works until all elements are checked or no longer in the group
If Groups.Count = 0 Then
Exit Do
ElseIf StartLoop = False Then
Exit Do
End If
Loop
Return Groups
End Function```

This function will allow us to eliminate open groups and keep groups closed, or empty groups if all groups are open.

(Grupa jest okrążona - Group is encircled)

When we know which group is encircled, it should be rounded and eliminated from play so that the opponent can no longer use them. This last thing we can easily get by adding encircled items to "Player1CheckedList" or "Player2CheckedList" then for one player the dots will be eliminated and for the other are useless since they are encircled (empty fields). Based on these lists, we can also tell you which player won, if we talk about winning in the context of the area occupied. Let's move on to the line drawing element, seeing the image above, it's easy to guess how we do it. We will check each rounded element or if it is next to the opponent's dot and create a list of those dots. Then, from the list, we will remove repetitive elements so that they are single, we will look at the elements that border them, and we will create a Tuple list that will store the line coordinates.

```    Dim Player1CheckedList As New List(Of Panel)
Dim Player2CheckedList As New List(Of Panel)

Private Sub LapTest()
Dim EdgeList As New List(Of Panel)
If Not Player1DotsL.Count = 0 Then
End If
If Not Player2DotsL.Count = 0 Then
End If

Dim FreedomList As New List(Of List(Of Panel))
FreedomList = freedomPoints(EdgeList)

Dim GroupList As New List(Of List(Of Panel))

If Player Then 'Green
GroupList = Group(Player2DotsL)
GroupList = GroupEdition(Player1DotsL, GroupList, EdgeList, FreedomList)
'List all elements in groups that remain
For i As Integer = 0 To GroupList.Count - 1
'Draws lines and creates a list of tuples
DrawLines(GroupList(i), Player1DotsL, Player1CheckedList)
For j As Integer = 0 To GroupList(i).Count - 1
'Elements can repeat, so the loop checks if they are no longer listed
If Not Player1CheckedList.Contains(GroupList(i)(j)) Then
GroupList(i)(j).Enabled = False
'The condition removes an item from the opponents list so it can't longer be used
If Not Player2DotsL.IndexOf(GroupList(i)(j)) = -1 Then
Player2DotsL.RemoveAt(Player2DotsL.IndexOf(GroupList(i)(j)))
End If
End If
Next
Next
'Change player if nothing is encircled
If Not GroupList.Count > 0 Then
Player = False
End If
Else 'Red
GroupList = Group(Player1DotsL)
GroupList = GroupEdition(Player2DotsL, GroupList, EdgeList, FreedomList)
'List all elements in groups that remain
For i As Integer = 0 To GroupList.Count - 1
'Draws lines and creates a list of tuples
DrawLines(GroupList(i), Player2DotsL, Player2CheckedList)
For j As Integer = 0 To GroupList(i).Count - 1
'Elements can repeat, so the loop checks if they are no longer listed
If Not Player2CheckedList.Contains(GroupList(i)(j)) Then
GroupList(i)(j).Enabled = False
'The condition removes an item from the opponents list so it can't longer be used
If Not Player1DotsL.IndexOf(GroupList(i)(j)) = -1 Then
Player1DotsL.RemoveAt(Player1DotsL.IndexOf(GroupList(i)(j))) 'remove
End If
End If
Next
Next
'Change player if nothing is encircled
If Not GroupList.Count > 0 Then
Player = True
End If
End If
End Sub```

This modified LapTest will verify what you need, add it to your code. Now we will add the last element of "DrawLines" that will circle our points. It looks like this:

```    Private Sub DrawLines(ByRef pane As List(Of Panel), ByRef PlayerList As List(Of Panel), ByRef cList As List(Of Panel))
Dim AllLinesList As New List(Of Tuple(Of Panel, Panel))
Dim d As Graphics
d = Main_board.CreateGraphics()

Dim OrderedPanelsList As New List(Of Panel)

'Creates a list of all group panels without repetition
For i As Integer = 0 To pane.Count - 1
If Not OrderedPanelsList.Contains(pane(i)) Then
End If
Next

For k As Integer = 0 To OrderedPanelsList.Count - 1

Dim positionX As Integer = 0
Dim positionY As Integer = 0
For i As Integer = 0 To PLocationList.Count - 1
For j As Integer = 0 To PLocationList(i).Count - 1
If PLocationList(i)(j).Name = OrderedPanelsList(k).Name Then
positionX = i
positionY = j
End If
Next
Next
If PlayerList.Contains(PLocationList(positionX - 1)(positionY)) Then
End If
If PlayerList.Contains(PLocationList(positionX + 1)(positionY)) Then
End If
If PlayerList.Contains(PLocationList(positionX)(positionY + 1)) Then
End If
If PlayerList.Contains(PLocationList(positionX)(positionY - 1)) Then
End If
Next

For k As Integer = 0 To adjacentPanList.Count - 1
Dim positionX As Integer = 0
Dim positionY As Integer = 0
For i As Integer = 0 To PLocationList.Count - 1
For j As Integer = 0 To PLocationList(i).Count - 1
positionX = i
positionY = j
End If
Next
Next
Not cList.Contains(PLocationList(positionX - 1)(positionY)) Then
End If
Not cList.Contains(PLocationList(positionX + 1)(positionY)) Then
End If
Not cList.Contains(PLocationList(positionX)(positionY + 1)) Then
End If
Not cList.Contains(PLocationList(positionX)(positionY - 1)) Then
End If
If adjacentPanList.Contains(PLocationList(positionX - 1)(positionY - 1)) And
Not cList.Contains(PLocationList(positionX - 1)(positionY - 1)) Then
End If
If adjacentPanList.Contains(PLocationList(positionX + 1)(positionY + 1)) And
Not cList.Contains(PLocationList(positionX + 1)(positionY + 1)) Then
End If
If adjacentPanList.Contains(PLocationList(positionX - 1)(positionY + 1)) And
Not cList.Contains(PLocationList(positionX - 1)(positionY + 1)) Then
End If
If adjacentPanList.Contains(PLocationList(positionX + 1)(positionY - 1)) And
Not cList.Contains(PLocationList(positionX + 1)(positionY - 1)) Then
End If
End If
Next

'We draw circles and lines
For i As Integer = 0 To AllLinesList.Count - 1
AllLinesList(i).Item1.Visible = False
AllLinesList(i).Item2.Visible = False
Application.DoEvents()
If Player Then
Dim myPen As Pen = New Pen(pGreen, 2)
d.DrawLine(myPen, AllLinesList(i).Item1.Location.X + 10, AllLinesList(i).Item1.Location.Y + 10,
AllLinesList(i).Item2.Location.X + 10, AllLinesList(i).Item2.Location.Y + 10)
d.FillEllipse(pGreen, New Rectangle(AllLinesList(i).Item1.Location.X + 5,
AllLinesList(i).Item1.Location.Y + 5, 10, 10))
d.FillEllipse(pGreen, New Rectangle(AllLinesList(i).Item2.Location.X + 5,
AllLinesList(i).Item2.Location.Y + 5, 10, 10))
Else
Dim myPen As Pen = New Pen(pRed, 2)
d.DrawLine(myPen, AllLinesList(i).Item1.Location.X + 10, AllLinesList(i).Item1.Location.Y + 10,
AllLinesList(i).Item2.Location.X + 10, AllLinesList(i).Item2.Location.Y + 10)
d.FillEllipse(pRed, New Rectangle(AllLinesList(i).Item1.Location.X + 5,
AllLinesList(i).Item1.Location.Y + 5, 10, 10))
d.FillEllipse(pRed, New Rectangle(AllLinesList(i).Item2.Location.X + 5,
AllLinesList(i).Item2.Location.Y + 5, 10, 10))
End If
Next

End Sub```

This loop could requires some work yet but its assumptions are probably clear

## Share

 Poland
No Biography provided

 Pro