So the program will take input of a series of 9 integers which indicate which square was played on each move. Player 1 is always X
and player 2 is always O
. Player 1 plays first. Move 1 is first and Move 9 is last, sequentially.
The board looks like this
1 | 2 | 3 ---+---+--- 4 | 5 | 6 ---+---+--- 7 | 8 | 9
Winning lines are:
- 3 Horizontal (
1-2-3
,4-5-6
,7-8-9
) - 3 Vertical (
1-4-7
,2-5-8
,3-6-9
) - 2 Diagonal (
1-5-9
,3-5-7
)
Sample input
Because of the challenge I was completing, the input includes the first line as the number of games being played, but I've completely ignored it in this implementation.
13 3 5 2 8 6 9 7 1 4 8 3 1 6 2 5 7 4 9 6 4 1 5 8 7 3 2 9 3 1 7 5 9 2 6 4 8 3 2 6 1 4 7 8 5 9 2 7 8 5 3 9 4 1 6 3 6 9 1 5 2 7 4 8 9 2 6 3 5 8 1 7 4 5 8 2 9 1 6 4 7 3 9 7 2 3 4 8 5 1 6 7 1 9 8 4 2 6 5 3 7 3 5 2 6 4 9 1 8 5 1 4 3 6 9 8 7 2
Structure
- Get input data from txt file (space-delimited)
- For each game, determine which player played the winning move and at what location. If no winner, draw.
- Write txt file of winning data
Notes
- I initially wrote this in excel and it played the games, which is how I could double check this to ensure it's working properly.
- I'm sure my
CheckWin
function can be improved dramatically, but I have a simple mind when it comes to this. - This is really the first "complex" thing I've written in VB.net, hence the beginner tag, though I did take input from my other questions on the language.
- I used
Environment.NewLine
because I couldn't determine how to get something likevbLF
to work and so I'm not sure if that's bad practice, using the environment.
The Magic
Option Explicit On
Option Strict On
Option Infer On
Option Compare Text
Imports System.IO
Module TicTacToeAnalyzer
Sub Main()
Const INPUT_PATH As String = "C:\Temp\tictactoe.txt"
Const OUTPUT_PATH As String = "C:\Temp\tictactoeResults.txt"
Dim rawGameData As String()
rawGameData = GetInput(INPUT_PATH)
Dim gameResult As String
Dim resultData As String()
ReDim resultData(rawGameData.Length - 1)
Dim moveData As String
For i As Integer = 1 To rawGameData.Length - 1
moveData = rawGameData(i)
gameResult = PlayGame(moveData, i)
resultData(i) = gameResult
Next
gameResult = resultData(1)
gameResult = String.Join(Environment.NewLine, resultData).Trim()
WriteOutput(OUTPUT_PATH, gameResult)
End Sub
Private Function PlayGame(ByVal moveData As String, ByVal gameNumber As Integer) As String
Const DELIMITER As String = " "
Dim moveArray As Integer()
moveArray = ConvertStringsToIntegers(moveData, DELIMITER)
Dim boardArray As Integer()
ReDim boardArray(9)
Dim gameWinner As String
Dim isWon As Boolean
Dim move As Integer
Dim square As Integer
Dim player As Integer
For iterator As Integer = 0 To boardArray.Length
move = iterator + 1
square = moveArray(iterator)
Select Case move
Case 1, 3, 5, 7, 9
player = 1
boardArray(square) = 1
Case 2, 4, 6, 8
player = 2
boardArray(square) = 2
End Select
If move > 4 Then isWon = CheckWin(boardArray, square)
If isWon Then
gameWinner = "Game #" & gameNumber & " is won by Player " & player & " on move #" & move & " in square #" & square & "."
Return gameWinner
End If
Next
Return "Game #" & gameNumber & " is a draw."
End Function
Private Function CheckWin(ByVal boardarray As Integer(), ByVal square As Integer) As Boolean
Dim isWin As Boolean
isWin = False
Select Case square
Case 1
If boardarray(1) = boardarray(2) And boardarray(1) = boardarray(3) Then isWin = True
If boardarray(1) = boardarray(4) And boardarray(1) = boardarray(7) Then isWin = True
If boardarray(1) = boardarray(5) And boardarray(1) = boardarray(9) Then isWin = True
Case 2
If boardarray(2) = boardarray(1) And boardarray(2) = boardarray(3) Then isWin = True
If boardarray(2) = boardarray(5) And boardarray(2) = boardarray(8) Then isWin = True
Case 3
If boardarray(3) = boardarray(2) And boardarray(3) = boardarray(1) Then isWin = True
If boardarray(3) = boardarray(6) And boardarray(3) = boardarray(9) Then isWin = True
If boardarray(3) = boardarray(5) And boardarray(3) = boardarray(7) Then isWin = True
Case 4
If boardarray(4) = boardarray(1) And boardarray(4) = boardarray(7) Then isWin = True
If boardarray(4) = boardarray(5) And boardarray(4) = boardarray(6) Then isWin = True
Case 5
If boardarray(5) = boardarray(1) And boardarray(5) = boardarray(9) Then isWin = True
If boardarray(5) = boardarray(2) And boardarray(5) = boardarray(8) Then isWin = True
If boardarray(5) = boardarray(3) And boardarray(5) = boardarray(7) Then isWin = True
If boardarray(5) = boardarray(4) And boardarray(5) = boardarray(6) Then isWin = True
Case 6
If boardarray(6) = boardarray(3) And boardarray(6) = boardarray(9) Then isWin = True
If boardarray(6) = boardarray(5) And boardarray(6) = boardarray(4) Then isWin = True
Case 7
If boardarray(7) = boardarray(8) And boardarray(7) = boardarray(9) Then isWin = True
If boardarray(7) = boardarray(1) And boardarray(7) = boardarray(4) Then isWin = True
If boardarray(7) = boardarray(3) And boardarray(7) = boardarray(5) Then isWin = True
Case 8
If boardarray(8) = boardarray(2) And boardarray(8) = boardarray(5) Then isWin = True
If boardarray(8) = boardarray(7) And boardarray(8) = boardarray(9) Then isWin = True
Case 9
If boardarray(9) = boardarray(1) And boardarray(9) = boardarray(5) Then isWin = True
If boardarray(9) = boardarray(3) And boardarray(9) = boardarray(6) Then isWin = True
If boardarray(9) = boardarray(7) And boardarray(9) = boardarray(8) Then isWin = True
End Select
Return isWin
End Function
Private Function GetInput(ByVal inputPath As String) As String()
Return File.ReadAllLines(inputPath)
End Function
Private Function ConvertStringsToIntegers(ByVal moveData As String, ByVal DELIMITER As String) As Integer()
Dim arrayOfStrings As String() = moveData.Split(New String() {DELIMITER}, StringSplitOptions.None)
Return Array.ConvertAll(arrayOfStrings, Function(str) Integer.Parse(str))
End Function
Private Sub WriteOutput(ByVal outputPath As String, ByVal gameResult As String)
Using fileAuthor As New StreamWriter(outputPath)
fileAuthor.WriteLine(gameResult)
End Using
End Sub
End Module