Skip to content

Commit 0472c51

Browse files
authored
feat: Add Tic Tac Toe winning algorithm. (#7)
1 parent 2a0cc0d commit 0472c51

File tree

4 files changed

+105
-0
lines changed

4 files changed

+105
-0
lines changed

README.md

+1
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ So far, the following exercises have been covered:
1111
- [Heap](./heap/) – implements a heap from scratch, without using the built-in `container/heap` package
1212
- [Remove k-th last element](./removekthlastelement/) – removes the k-th last element from a single-linked list
1313
- [Running median](./runningmedian/) – calculates the running median of a sequence of numbers
14+
- [Tic tac toe](./tictactoe/) – detects winnning states in a tic tac toe game
1415

1516
## Running quality assurance
1617

tictactoe/documentation.go

+2
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
// Package tictactoe detects winnning states in a tic tac toe game.
2+
package tictactoe

tictactoe/tictactoe.go

+35
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
package tictactoe
2+
3+
type Field struct {
4+
Row int
5+
Column int
6+
}
7+
8+
func HasWon(fields []Field, size int) bool {
9+
rowSums := make([]int, size)
10+
columnSums := make([]int, size)
11+
12+
slashDiagonalSum := 0
13+
backslashDiagonalSum := 0
14+
15+
for _, field := range fields {
16+
rowSums[field.Row]++
17+
columnSums[field.Column]++
18+
19+
if field.Row == field.Column {
20+
slashDiagonalSum++
21+
}
22+
if field.Row == size-field.Column-1 {
23+
backslashDiagonalSum++
24+
}
25+
26+
if rowSums[field.Row] == size ||
27+
columnSums[field.Column] == size ||
28+
slashDiagonalSum == size ||
29+
backslashDiagonalSum == size {
30+
return true
31+
}
32+
}
33+
34+
return false
35+
}

tictactoe/tictactoe_test.go

+67
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
package tictactoe_test
2+
3+
import (
4+
"testing"
5+
6+
"github.com/stretchr/testify/assert"
7+
"github.com/thenativeweb/codingcircle/tictactoe"
8+
)
9+
10+
func TestHasWon(t *testing.T) {
11+
testCases := []struct {
12+
name string
13+
fields []tictactoe.Field
14+
size int
15+
hasWon bool
16+
}{
17+
{
18+
name: "Returns false for an empty board.",
19+
fields: []tictactoe.Field{},
20+
size: 3,
21+
hasWon: false,
22+
},
23+
{
24+
name: "Returns false for a board with a single field.",
25+
fields: []tictactoe.Field{{0, 0}},
26+
size: 3,
27+
hasWon: false,
28+
},
29+
{
30+
name: "Returns true for a row on a 3x3 board.",
31+
fields: []tictactoe.Field{{0, 0}, {0, 1}, {0, 2}},
32+
size: 3,
33+
hasWon: true,
34+
},
35+
{
36+
name: "Returns true for a column on a 3x3 board.",
37+
fields: []tictactoe.Field{{0, 0}, {1, 0}, {2, 0}},
38+
size: 3,
39+
hasWon: true,
40+
},
41+
{
42+
name: "Returns true for the slash diagonal on a 3x3 board.",
43+
fields: []tictactoe.Field{{0, 1}, {0, 2}, {1, 0}, {1, 1}, {2, 0}, {2, 2}},
44+
size: 3,
45+
hasWon: true,
46+
},
47+
{
48+
name: "Returns true for the backslash diagonal on a 3x3 board.",
49+
fields: []tictactoe.Field{{0, 0}, {0, 1}, {1, 1}, {1, 2}, {2, 0}, {2, 2}},
50+
size: 3,
51+
hasWon: true,
52+
},
53+
{
54+
name: "Returns true for a row on a 4x4 board.",
55+
fields: []tictactoe.Field{{0, 0}, {0, 1}, {0, 2}, {0, 3}},
56+
size: 4,
57+
hasWon: true,
58+
},
59+
}
60+
61+
for _, testCase := range testCases {
62+
t.Run(testCase.name, func(t *testing.T) {
63+
hasWon := tictactoe.HasWon(testCase.fields, testCase.size)
64+
assert.Equal(t, testCase.hasWon, hasWon)
65+
})
66+
}
67+
}

0 commit comments

Comments
 (0)