Skip to content

Instantly share code, notes, and snippets.

@neilnaveen
Created July 7, 2022 14:55
Show Gist options
  • Select an option

  • Save neilnaveen/048a7169dd17a8e8ec3e11f1f4d590a7 to your computer and use it in GitHub Desktop.

Select an option

Save neilnaveen/048a7169dd17a8e8ec3e11f1f4d590a7 to your computer and use it in GitHub Desktop.
Tic Tac Toe

README

This is a tic-tac-toe game.

To run the game go run main.go

package main
import (
"fmt"
"strconv"
"strings"
)
func main() {
fmt.Println("\nPlease input a number that will be the length of the tic tac toe board(the rows and columns will be zero indexed):")
var n int
fmt.Scan(&n)
board := make([][]int, n)
for i := 0; i < n; i++ {
board[i] = make([]int, n)
}
m := map[[2]int]int{}
lastMoveX, lastMoveY := 0, 0
count := 0
for {
printBoard(board, "-")
if ifGameDone(board, lastMoveX, lastMoveY, count, n) {
break
}
fmt.Println("Player 1, input your row and column you want to place your token on (ie. \"0 0\"):")
x, y := 0, 0
fmt.Scan(&y, &x)
if x >= n || x < 0 || y >= n || y < 0 || m[[2]int{x, y}] > 0 {
fmt.Println("That is an invalid action, this turn has been skipped")
} else {
board[y][x] = 1
printBoard(board, "-")
m[[2]int{x, y}] = 1
lastMoveX, lastMoveY = x, y
count++
}
if ifGameDone(board, lastMoveX, lastMoveY, count, n) {
break
}
fmt.Println("Player 2, input your row and column you want to place your token on (ie. \"0 0\"):")
x1, y1 := 0, 0
fmt.Scan(&y1, &x1)
if x1 >= n || x1 < 0 || y1 >= n || y1 < 0 || m[[2]int{x1, y1}] > 0 {
fmt.Println("That is an invalid action, this turn has been skipped")
} else {
board[y1][x1] = 2
lastMoveX, lastMoveY = x1, y1
m[[2]int{x1, y1}] = 1
count++
}
}
}
// ifGameDone checks if the game is done
func ifGameDone(board [][]int, lastMoveX int, lastMoveY int, count int, n int) bool {
if solved, winner := checkWinner(board, lastMoveX, lastMoveY); solved {
fmt.Println("Player " + strconv.Itoa(winner) + " is the winner")
return true
}
if count == n*n {
fmt.Println("Its a draw!")
return true
}
return false
}
// printBoard prints the board
func printBoard(board [][]int, line string) {
for _, i := range board {
s := ""
line = "-"
for _, j := range i {
line += strings.Repeat("-", 4)
if j == 1 {
s += " | X"
}
if j == 2 {
s += " | O"
}
if j == 0 {
s += " | "
}
}
fmt.Println(line)
fmt.Println(s[1:] + " |")
}
fmt.Println(line)
}
// checkWinner checks if the game is done, and if so outputs the winner.
func checkWinner(board [][]int, lastMoveX, lastMoveY int) (bool, int) {
// check row for winner
first := board[lastMoveY][0]
flag := true
for i := 0; i < len(board); i++ {
if board[lastMoveY][i] != first {
flag = false
break
}
}
if flag && first != 0 {
return true, first
}
// check column for winner
first = board[0][lastMoveX]
flag = true
for i := 0; i < len(board); i++ {
if board[i][lastMoveX] != first {
flag = false
break
}
}
if flag && first != 0 {
return true, first
}
// check diagonal for winner
flag, first = true, board[0][len(board)-1]
for i, j := 0, len(board)-1; i < len(board); i, j = i+1, j-1 {
if board[i][j] != first {
flag = false
break
}
}
if flag && first != 0 {
return true, first
}
// check other diagonal for winner
flag, first = true, board[0][0]
for i, j := 0, 0; i < len(board); i, j = i+1, j+1 {
if board[i][j] != first {
flag = false
break
}
}
if flag && first != 0 {
return true, first
}
return false, 0
}
package main
import "testing"
func Test_checkwinner(t *testing.T) {
type args struct {
board [][]int
lastMoveX int
lastMoveY int
}
tests := []struct {
name string
args args
want bool
want1 int
}{
{
// create test
name: "emptyBoard",
args: args{
board: [][]int{
{0, 0, 0},
{0, 0, 0},
{0, 0, 0},
},
lastMoveX: 0,
lastMoveY: 0,
},
want: false,
want1: 0,
},
{
// create test
name: "fullBoard- row winner",
args: args{
board: [][]int{
{1, 2, 2},
{1, 1, 1},
{2, 1, 1},
},
lastMoveX: 0,
lastMoveY: 1,
},
want: true,
want1: 1,
},
{
// create test
name: "fullBoard- column winner",
args: args{
board: [][]int{
{1, 2, 2},
{1, 2, 1},
{1, 1, 2},
},
lastMoveX: 0,
lastMoveY: 0,
},
want: true,
want1: 1,
},
{
// create test
name: "fullBoard- no winner",
args: args{
board: [][]int{
{1, 2, 1},
{1, 2, 1},
{2, 1, 2},
},
lastMoveX: 0,
lastMoveY: 0,
},
want: false,
want1: 0,
},
{
// create test
name: "fullBoard- diagonal winner",
args: args{
board: [][]int{
{2, 2, 1},
{1, 2, 1},
{2, 1, 2},
},
lastMoveX: 0,
lastMoveY: 0,
},
want: true,
want1: 2,
},
{
// create test
name: "fullBoard- other diagonal winner",
args: args{
board: [][]int{
{2, 2, 1},
{2, 1, 1},
{1, 1, 2},
},
lastMoveX: 0,
lastMoveY: 2,
},
want: true,
want1: 1,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
got, got1 := checkWinner(tt.args.board, tt.args.lastMoveX, tt.args.lastMoveY)
if got != tt.want {
t.Errorf("checkWinner() got = %v, want %v", got, tt.want)
}
if got1 != tt.want1 {
t.Errorf("checkWinner() got1 = %v, want %v", got1, tt.want1)
}
})
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment