114 lines
2.0 KiB
Go
114 lines
2.0 KiB
Go
package main
|
|
|
|
import "fmt"
|
|
|
|
type Board struct {
|
|
// the 3x3 board is stored by concatenating all rows
|
|
//
|
|
// 0 1 2
|
|
// 3 4 5
|
|
// 6 7 8
|
|
//
|
|
// becomes:
|
|
//
|
|
// 0 1 2 3 4 5 6 7 8
|
|
//
|
|
// each square contains either one of the player marks, or a space
|
|
squares [9]string
|
|
}
|
|
|
|
func NewBoard() *Board {
|
|
s := [9]string{}
|
|
for i := range s {
|
|
s[i] = " "
|
|
}
|
|
return &Board{
|
|
squares: s,
|
|
}
|
|
}
|
|
|
|
// Mark puts a mark in a square.
|
|
// returns false if the square was already occupied
|
|
func (b *Board) Mark(sq int, mark string) bool {
|
|
if b.squares[sq] != " " {
|
|
return false
|
|
}
|
|
|
|
b.squares[sq] = mark
|
|
return true
|
|
}
|
|
|
|
func (b *Board) Available() []int {
|
|
av := make([]int, 0)
|
|
for p, m := range b.squares {
|
|
if m == " " {
|
|
av = append(av, p)
|
|
}
|
|
}
|
|
|
|
return av
|
|
}
|
|
|
|
func (b *Board) Full() bool {
|
|
return len(b.Available()) == 0
|
|
}
|
|
|
|
func (b *Board) Winner() (string, bool) {
|
|
// someone has won when the board features identical marks on all these places
|
|
winConfs := [][3]int{
|
|
{0, 1, 2}, // horizontal rows
|
|
{3, 4, 5},
|
|
{6, 7, 8},
|
|
|
|
{0, 3, 6}, // vertical rows
|
|
{1, 4, 7},
|
|
{2, 5, 8},
|
|
|
|
{0, 4, 8}, // diagonals
|
|
{2, 4, 6},
|
|
}
|
|
|
|
for _, w := range winConfs {
|
|
// first determine what mark is on the first position
|
|
m := b.squares[w[0]]
|
|
if m == " " {
|
|
continue
|
|
}
|
|
// then check whether the others are the same
|
|
if m == b.squares[w[1]] && m == b.squares[w[2]] {
|
|
return m, true
|
|
}
|
|
}
|
|
|
|
return "", false
|
|
}
|
|
|
|
func (b *Board) Render(useEsc bool) string {
|
|
sqs := make([]string, 0, 8)
|
|
for _, sq := range b.squares {
|
|
sqStr := sq
|
|
if useEsc {
|
|
// make the marks bold and white
|
|
sqStr = fmt.Sprintf("\x1b[1;37m%s\x1b[0m", sqStr)
|
|
}
|
|
sqs = append(sqs, sqStr)
|
|
}
|
|
|
|
return fmt.Sprintf(` -0--- -1--- -2---
|
|
| | | |
|
|
| %s | %s | %s |
|
|
| | | |
|
|
-3--- -4--- -5---
|
|
| | | |
|
|
| %s | %s | %s |
|
|
| | | |
|
|
-6--- -7--- -8---
|
|
| | | |
|
|
| %s | %s | %s |
|
|
| | | |
|
|
----- ----- -----
|
|
`, sqs[0], sqs[1], sqs[2],
|
|
sqs[3], sqs[4], sqs[5],
|
|
sqs[6], sqs[7], sqs[8])
|
|
}
|