Files

158 lines
3.2 KiB
Go
Raw Permalink Normal View History

2019-10-30 19:34:44 +03:00
// Copyright © 2018 Inanc Gumus
// Learn Go Programming Course
// License: https://creativecommons.org/licenses/by-nc-sa/4.0/
//
// For more tutorials : https://learngoprogramming.com
// In-person training : https://www.linkedin.com/in/inancgumus/
// Follow me on twitter: https://twitter.com/inancgumus
2019-04-26 21:32:20 +03:00
package main
import (
"fmt"
"math/rand"
2019-04-26 21:32:20 +03:00
"strings"
"time"
2019-05-13 18:22:38 +03:00
rainbow "github.com/guineveresaenger/golang-rainbow"
2019-04-26 21:32:20 +03:00
)
const (
2019-05-13 18:22:38 +03:00
maxTurn = 9
2019-04-26 21:32:20 +03:00
// skin options :-)
2019-05-13 18:22:38 +03:00
empty = " "
player1 = " X "
player2 = " O "
header = "---+---+---"
footer = "---+---+---"
separator = "|"
banner = `
2019-04-26 21:32:20 +03:00
~~~~~~~~~~~~~~~
TIC~TAC~TOE
~~~~~~~~~~~~~~~`
2019-05-13 18:22:38 +03:00
)
2019-04-26 21:32:20 +03:00
2019-05-13 18:22:38 +03:00
// -------------------------------------------------
// INITIALIZE THE GAME
// -------------------------------------------------
var (
turn int
won bool
board = [][]string{
2019-05-13 18:22:38 +03:00
{empty, empty, empty},
{empty, empty, empty},
{empty, empty, empty},
}
player = player1
2019-04-26 21:32:20 +03:00
)
func main() {
rand.Seed(time.Now().UnixNano())
2019-05-13 18:22:38 +03:00
rainbow.Rainbow(banner, strings.Count(banner, "\n"))
2019-04-26 21:32:20 +03:00
for {
// -------------------------------------------------
// PRINT THE BOARD AND THE PROMPT
// -------------------------------------------------
2019-05-13 18:22:38 +03:00
fmt.Printf("\n %s\n", header)
2019-04-26 21:32:20 +03:00
for _, line := range board {
fmt.Printf(" %s\n", strings.Join(line, separator))
2019-05-13 18:22:38 +03:00
fmt.Printf(" %s\n", footer)
2019-04-26 21:32:20 +03:00
}
// -------------------------------------------------
// IS THERE A WINNER? OR IS IT A TIE?
// -------------------------------------------------
for i := 1; i <= 2; i++ {
m := player2
if i == 1 {
m = player1
}
2019-04-26 21:32:20 +03:00
b, mmm := board, strings.Repeat(m, 3)
/* horizontals */
hor := strings.Join(b[0], "") == mmm ||
strings.Join(b[1], "") == mmm ||
strings.Join(b[2], "") == mmm
/* verticals */
ver := b[0][0]+b[1][0]+b[2][0] == mmm ||
b[0][1]+b[1][1]+b[2][1] == mmm ||
b[0][2]+b[1][2]+b[2][2] == mmm
2019-04-26 21:32:20 +03:00
/* diagonals */
diag := b[0][0]+b[1][1]+b[2][2] == mmm ||
b[0][2]+b[1][1]+b[2][0] == mmm
2019-04-26 21:32:20 +03:00
won = hor || ver || diag
2019-04-26 21:32:20 +03:00
if won {
2019-05-13 18:22:38 +03:00
player = m
2019-04-26 21:32:20 +03:00
break
}
}
if won {
2019-05-13 18:22:38 +03:00
player = strings.TrimSpace(player)
fmt.Printf("\n>>> WINNER: %s\n", player)
break
} else if turn == maxTurn {
2019-05-13 18:22:38 +03:00
fmt.Printf("\n>>> TIE!\n")
break
2019-04-26 21:32:20 +03:00
}
// -------------------------------------------------
// PLAY
2019-04-26 21:32:20 +03:00
// -------------------------------------------------
2019-05-13 18:22:38 +03:00
pos := rand.Intn(9) + 1
fmt.Printf("\nPlayer %s plays to %d\n", player, pos)
2019-05-13 18:22:38 +03:00
// -------------------------------------------------
// IS IT A VALID MOVE?
// -------------------------------------------------
2019-05-13 18:22:38 +03:00
var row int
switch {
case pos <= 3:
2019-05-13 18:22:38 +03:00
row = 0
case pos <= 6:
2019-05-13 18:22:38 +03:00
row = 1
case pos <= 9:
2019-05-13 18:22:38 +03:00
row = 2
default:
fmt.Println(">>>", "wrong position!")
2019-05-13 18:22:38 +03:00
continue
}
col := pos - row*3 - 1
if board[row][col] != empty {
fmt.Println(">>>", "already played!")
2019-05-13 18:22:38 +03:00
continue
}
// -------------------------------------------------
// MARK THE MOVE AND INCREMENT THE TURN
// -------------------------------------------------
2019-05-13 18:22:38 +03:00
// put a mark on the board
board[row][col] = player
// switch to the next player
if player == player1 {
player = player2
2019-04-26 21:32:20 +03:00
} else {
2019-05-13 18:22:38 +03:00
player = player1
2019-04-26 21:32:20 +03:00
}
2019-05-13 18:22:38 +03:00
turn++
// time.Sleep(time.Millisecond * 100)
2019-05-13 18:22:38 +03:00
}
2019-04-26 21:32:20 +03:00
}