The Kernal Of Tic-Tac-Toe
Kernel Basics
What does the kernel have to do the keep track of a game of Tic-Tac-Toe.
I reckon the following isn't to far off the mark.
Implementing the Kernel
A kernel of Tic-Tac-Toe in 64 LoC ( and most of that is the boiler-plate vb.net needs. )
Yes I now it can be even smaller by in-lining a few methods
Next Time:- Implementing a Game Controller on top it, so we can play an actual game.
Kernel Basics
What does the kernel have to do the keep track of a game of Tic-Tac-Toe.
I reckon the following isn't to far off the mark.
Blank board
Current Player = Player 1
While the game is not in a end state
Await Current Player Move
Update Board with Current Player's Move
Check State of Board
Has Current Player Won? -> End Game( Player (Current Player ) Wins)
Is the Game Drawn? -> End Game( Drawn Game )
Current Player = Which Player is Next? ( Current Player )
End While
Implementing the Kernel
A kernel of Tic-Tac-Toe in 64 LoC ( and most of that is the boiler-plate vb.net needs. )
Yes I now it can be even smaller by in-lining a few methods
Public Class TicTacToe
Dim _TicTacToeBoard(8) As Markers, _CurrentPlayer As Markers = Markers.Player_1
Dim _GameState As GameStates = GameStates.Playing
Private Event GameStateChanged(ticTacToe As TicTacToe, e As GameStateChangedArgs)
Public Event BoardChanged(sender As TicTacToe, e As BoardChangedEventArgs)
Public Event PlayerWin(sender As TicTacToe, e As PlayerWinEventArgs)
Public Event GameDrawn(sender As TicTacToe, e As EventArgs)
Public Property GameState As GameStates
Get
Return _GameState
End Get
Private Set(value As GameStates)
If value = _GameState Then Exit Property
value = _GameState
RaiseEvent GameStateChanged(Me, New GameStateChangedArgs())
End Set
End Property
Public Function PlayMove(PlayedBy As Markers, PlayingSquare As Integer) As Boolean
If (_GameState <> GameStates.Playing) OrElse (_CurrentPlayer <> PlayedBy) Then
Me.GameState = GameStates.Invalid_State
Return False
ElseIf Not ((0 <= PlayingSquare) AndAlso (PlayingSquare <= 8)) OrElse (_TicTacToeBoard(PlayingSquare) <> Markers.Empty) Then
Me.GameState = GameStates.Invalid_Move
Return False
Else
PlaceMarkerOnToGameBoard(PlayedBy, PlayingSquare)
Return True
End If
End Function
Private Sub PlaceMarkerOnToGameBoard(PlayedBy As Markers, PlayingSquare As Integer)
_TicTacToeBoard(PlayingSquare) = PlayedBy
RaiseEvent BoardChanged(Me, New BoardChangedEventArgs(_TicTacToeBoard.AsEnumerable))
CheckForPlayerWin(PlayedBy)
If GameIsDrawn() Then
Me.GameState = GameStates.Drawn
Else
_CurrentPlayer = WhichPlayerIsNext(_CurrentPlayer)
End If
End Sub
Private Function WhichPlayerIsNext(player As Markers) As Markers
Return If(player = Markers.Player_1, Markers.Player_2, If(player = Markers.Player_2, Markers.Player_1, player))
End Function
Private Function GameIsDrawn() As Boolean
Return Not _TicTacToeBoard.Any(Function(square) square = Markers.Empty)
End Function
Private Sub CheckForPlayerWin(player As Markers)
Dim winLines = {({0, 1, 2}), ({3, 4, 5}), ({6, 7, 8}), ({0, 3, 6}), ({1, 4, 7}), ({2, 5, 8}), ({0, 4, 8}), ({2, 4, 6})}
Dim winningLines As New List(Of Integer())(winLines.Where(Function(WinningLine) CheckLine(player, WinningLine)))
If winningLines.Any Then
Me.GameState = If(player = Markers.Player_1, GameStates.Win_Player1, If(player = Markers.Player_2, GameStates.Win_Player2, GameStates.Invalid_State))
RaiseEvent PlayerWin(Me, New PlayerWinEventArgs(player, winningLines))
End If
End Sub
Private Function CheckLine(player As Markers, ParamArray squares() As Integer) As Boolean
Return squares.All(Function(sqr) _TicTacToeBoard(sqr) = player)
End Function
Private Sub TicTacToe_GameStateChanged(ticTacToe As TicTacToe, e As GameStateChangedArgs) Handles Me.GameStateChanged
If CType(ticTacToe, TicTacToe).GameState = GameStates.Drawn Then RaiseEvent GameDrawn(Me, EventArgs.Empty)
End Sub
Private Sub TicTacToe_PlayerWin(sender As Object, e As PlayerWinEventArgs) Handles Me.PlayerWin
If e.Player = Markers.Player_1 Then Me.GameState = GameStates.Win_Player1
If e.Player = Markers.Player_2 Then Me.GameState = GameStates.Win_Player2
End Sub
End Class
Spoiler
Next Time:- Implementing a Game Controller on top it, so we can play an actual game.
0 Comments On This Entry
|
|



Leave Comment









|