As you may know, I love games. I am not a huge gamer, but I do like the odd game every now and then. What I do love is creating games. I love creating games that involve some logic to solve. Checkers is no exception! In this article, I will show you how to create your own basic Checkers game. There is a lot of work, so let’s get started.
Our Project
Start Visual Studio and create a new Visual Basic Windows Forms project. Once the form is displayed, resize it to a size of 498 x 522, as shown in Figure 1.
Figure 1: Form 1
You will come back to this form a bit later. Add a new Component to the Project by clicking Project, Add Component, as shown in Figure 2.
Figure 2: Add Component
This component will be used to create the Checkers objects. I have named mine compCheck, but you can name yours anything you desire. Add the following two Properties:
Private blnSelected As Boolean Private intPlayer As Integer Public Property Selected() As Boolean Get Return blnSelected End Get Set(ByVal value As Boolean) blnSelected = value End Set End Property Public Property Player() As Integer Get Return intPlayer End Get Set(ByVal value As Integer) intPlayer = value End Set End Property
This identifies the selected check object as well as the current player. Now, let’s draw the checks:
Protected Overrides Sub OnPaint(e As _ System.Windows.Forms.PaintEventArgs) MyBase.OnPaint(e) Dim gpPath As New Drawing2D.GraphicsPath Dim rRect As Rectangle = Me.DisplayRectangle rRect.Inflate(-1, -1) e.Graphics.DrawEllipse(New Pen(Brushes.Black, 3), rRect) rRect.Inflate(-1, -1) e.Graphics.FillEllipse(New SolidBrush(Me.BackColor), rRect) rRect.Inflate(2, 2) gpPath.AddEllipse(rRect) Me.Region = New Region(gpPath) If Selected Then Dim pnlTemp As Panel = DirectCast(Me.Parent, Panel) pnlTemp.BorderStyle = BorderStyle.Fixed3D Else Dim pnlTemp As Panel = DirectCast(Me.Parent, Panel) pnlTemp.BorderStyle = BorderStyle.FixedSingle End If End Sub
This gives a nice border next to each check and fills it with a seeding color. Later, you will add more colors to your Check objects. Build your project. In the Toolbox, you should notice your newly created component. Add it to your form.
Figure 3: Toolbox Component
Open your Form’s code and add the following three members:
Private pnlBoard(7, 7) As Panel Private chkSelected As compCheck Private blnPlayer1 As Boolean = True
pnlBoard will create the Checkers board. chkSelected represents the selected Check. blnPlayer1 identifies which player is currently playing. Let’s create the board:
Private Sub CreateBoard() For x As Integer = 0 To pnlBoard.GetUpperBound(0) For y As Integer = 0 To pnlBoard.GetUpperBound(1) Dim pnlTemp As New Panel With pnlTemp If CBool(x Mod 2) Then If CBool(y Mod 2) Then .BackColor = Color.AliceBlue Else .BackColor = Color.LightBlue End If Else If CBool(y Mod 2) Then .BackColor = Color.LightBlue Else .BackColor = Color.AliceBlue End If End If .BorderStyle = BorderStyle.FixedSingle .Location = New Point(x * 60, y * 60) .Size = New Size(60, 60) End With pnlBoard(x, y) = pnlTemp Me.Controls.Add(pnlTemp) AddHandler pnlTemp.Click, AddressOf pnlBoard_click Next Next End Sub
The preceding code creates the Checkers board with alternating AliceBlue and LightBlue blocks. Add its event handler:
Private Sub pnlBoard_click(sender As Object, e As EventArgs) Dim pnlSelected As Panel = DirectCast(sender, Panel) If Not (IsNothing(chkSelected)) AndAlso _ MoveCheck(chkSelected, pnlSelected) Then PerformMove(chkSelected, pnlSelected) End If End Sub
When something on the board is clicked, it determines where to move the object and which object to move. More on the MoveCheck and PerformMove Subs later. Let’s finish creating our board with all its checks. Add the CreateChecks Sub:
Private Sub CreateChecks() Dim x As Integer = 0 For y As Integer = 0 To 2 If y = 1 Then x = 1 Else x = 0 End If For i As Integer = x To x + 3 Dim chkCheck As New compCheck With chkCheck .BackColor = Color.YellowGreen .Selected = False .Location = New Point(2, 2) .Player = 2 .Size = New Size(50, 50) End With pnlBoard(x, y).Controls.Add(chkCheck) AddHandler chkCheck.Click, AddressOf chkCheck_Click x += 2 Next Next x = 1 For y As Integer = 5 To 7 If y = 6 Then x = 0 Else x = 1 End If For i As Integer = x To x + 3 Dim chkCheck As New compCheck With chkCheck .BackColor = Color.Tomato .Selected = False .Location = New Point(2, 2) .Player = 1 .Size = New Size(50, 50) End With pnlBoard(x, y).Controls.Add(chkCheck) AddHandler chkCheck.Click, AddressOf chkCheck_Click x += 2 Next Next End Sub
Depending on which player the created Check belongs to, the code determines its color as well as its location on the grid. Add its event handler:
Private Sub chkCheck_Click(sender As Object, e As EventArgs) Dim chkSel As compCheck = DirectCast(sender, compCheck) If Not (IsNothing(chkSelected)) Then If chkSel Is chkSelected Then chkSelected.Selected = False chkSelected = Nothing Else chkSelected = chkSel chkSel.Selected = True End If Else chkSelected = chkSel chkSel.Selected = True End If End Sub
The chkCheck_Click event simply determines which Check has been selected. This is solely to keep track of which object to move. If you were to run your application now, your game should look like Figure 4.
Figure 4: Game
Add the PerformMove and MoveCheck methods so that you are able to determine which Check was selected and where it should go, as well as what should happen if one check has jumped over another check:
Private Function MoveCheck(ByVal chkMoveCheck As compCheck, _ ByVal pnlPanel As Panel) As Boolean If pnlPanel.Controls.Count = 0 AndAlso Not _ (IsNothing(chkMoveCheck)) Then Dim intXSel As Integer Dim intYSel As Integer Dim intCurrX As Integer Dim intCurrY As Integer For intCol As Integer = 0 To pnlBoard.GetUpperBound(0) For intRow As Integer = 0 To pnlBoard.GetUpperBound(1) If pnlBoard(intCol, intRow) Is pnlPanel Then intXSel = intCol intYSel = intRow End If If pnlBoard(intCol, intRow) Is _ DirectCast(chkMoveCheck.Parent, Panel) Then intCurrX = intCol intCurrY = intRow End If Next Next If chkMoveCheck.Player = 1 AndAlso blnPlayer1 Then If intXSel - intCurrX = -1 AndAlso intYSel - _ intCurrY = -1 Then Return True ElseIf intXSel - intCurrX = -2 AndAlso intYSel - _ intCurrY = -2 Then Dim pnlTemp As Panel = DirectCast(pnlBoard(intXSel _ + 1, intYSel + 1), Panel) If pnlTemp.Controls.Count > -1 AndAlso _ DirectCast(pnlTemp.Controls(0), _ compCheck).Player = 2 Then pnlTemp.Controls.Clear() Return True Else Return False End If ElseIf intXSel - intCurrX = 1 AndAlso intYSel - _ intCurrY = -1 Then Return True ElseIf intXSel - intCurrX = 2 AndAlso intYSel - - intCurrY = -2 Then Dim pnlTemp As Panel = DirectCast(pnlBoard(intXSel _ - 1, intYSel + 1), Panel) If pnlTemp.Controls.Count > -1 AndAlso - DirectCast(pnlTemp.Controls(0), - compCheck).Player = 2 Then pnlTemp.Controls.Clear() Return True Else Return False End If Else Return False End If ElseIf chkMoveCheck.Player = 2 AndAlso Not (blnPlayer1) _ Then If intXSel - intCurrX = -1 AndAlso intYSel - _ intCurrY = 1 Then Return True ElseIf intXSel - intCurrX = -2 AndAlso intYSel - _ intCurrY = 2 Then Dim pnlTemp As Panel = _ DirectCast(pnlBoard(intXSel - _ + 1, intYSel - 1), Panel) If pnlTemp.Controls.Count > -1 AndAlso _ DirectCast(pnlTemp.Controls(0), _ compCheck).Player = 1 Then pnlTemp.Controls.Clear() Return True Else Return False End If ElseIf intXSel - intCurrX = 1 AndAlso intYSel - _ intCurrY = 1 Then Return True ElseIf intXSel - intCurrX = 2 AndAlso intYSel - _ intCurrY = 2 Then Dim pnlTemp As Panel = DirectCast(pnlBoard(intXSel _ - 1, intYSel - 1), Panel) If pnlTemp.Controls.Count > -1 AndAlso _ DirectCast(pnlTemp.Controls(0), _ compCheck).Player = 1 Then pnlTemp.Controls.Clear() Return True Else Return False End If Else Return False End If Else Return False End If Else Return False End If End Function Private Sub PerformMove(ByVal chkCheck As compCheck, ByVal _ pnlPanel As Panel) chkCheck.Selected = False Dim pnlFrom As Panel = DirectCast(chkCheck.Parent, Panel) pnlFrom.Controls.Clear() pnlPanel.Controls.Add(chkCheck) blnPlayer1 = Not (blnPlayer1) chkSelected = Nothing End Sub
Add the Form Load event, which creates the board and the checks:
Private Sub Form1_Load(sender As System.Object, e As _ System.EventArgs) Handles MyBase.Load Me.Controls.Clear() Call CreateBoard() Call CreateChecks() blnPlayer1 = True End Sub
Figure 5: Game in action
More Possible Features
You already have a functional game. However, there can still be some improvements added, such as:
- A proper method of scoring
- Creating and implementing King options
- Better graphic effects when a check has been jumped
- Sound
You’ll find the zip file, HTG_Checkers, below this article. Please feel free to download it; it will assist you in building your own Checkers game.
Conclusion
I have said it many a time: If you know the logic of certain problems, you are halfway there. Now you have the logic of how to build a Checkers game; the onus is on you to develop it further. You may also want to have a look at a few of my previous articles dealing with games.