Files
2019-10-30 19:41:13 +03:00

102 lines
1.9 KiB
Go

// 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
package main
import (
"bufio"
"fmt"
"os"
"strconv"
c "github.com/fatih/color"
rainbow "github.com/guineveresaenger/golang-rainbow"
)
// TODO: move the main logic into a helper
func main() {
const banner = `
~~~~~~~~~~~~~~~~
TIC~TAC~TOE
~~~~~~~~~~~~~~~~`
in := bufio.NewScanner(os.Stdin)
sk := selectSkin(in)
lg := logger{
print: fmt.Print,
printf: fmt.Printf,
println: fmt.Println,
}
for {
g := newGame(sk, lg)
game:
for {
rainbow.Rainbow(banner, 3)
g.print()
fmt.Printf(c.CyanString("\n%s [1-9]: ", g.player))
if !in.Scan() {
break
}
pos, _ := strconv.Atoi(in.Text())
switch st := g.play(pos); st {
case stateAlreadyPlayed, stateWrongPosition:
announce(g, st)
continue
case stateWon, stateTie:
announce(g, st)
break game
}
g.Print("\033[2J")
}
fmt.Print(c.MagentaString("One more game? [y/n]: "))
if in.Scan(); in.Text() != "y" {
fmt.Println("OK, bye!")
break
}
}
}
func announce(g *game, st state) {
red := c.New(c.FgRed, c.Bold)
green := c.New(c.BgBlack, c.FgGreen, c.Bold)
switch st {
case stateAlreadyPlayed, stateWrongPosition:
red.Printf("\n>>> You can't play there!\n")
case stateWon:
g.print()
green.Printf("\nWINNER: %s\n", g.player)
case stateTie:
g.print()
green.Printf("\nTIE!\n")
}
}
func selectSkin(in *bufio.Scanner) skin {
fmt.Println(c.MagentaString("Our finest selection of skins:"))
for name := range skins {
fmt.Printf("- %s\n", name)
}
fmt.Print(c.GreenString("\nEnter the name of the skin: "))
in.Scan()
if sk, ok := skins[in.Text()]; ok {
return sk
}
return defaultSkin
}