package connect
const (
player1 = 'X'
player2 = 'O'
)
// row-col difference
var directions = [6][2]int{
{1, -1},
{1, 0},
// {1, 1}, <-- this is not hex
{0, -1},
{0, 1},
// {-1, -1}, <-- this is not hex
{-1, 0},
{-1, 1},
}
type Seen map[[2]int]bool
func ResultOf(lines []string) (string, error) {
if check(lines, player2) {
return "O", nil
}
rotLines := rotate(lines)
if check(rotLines, player1) {
return "X", nil
}
return "", nil
}
func rotate(in []string) []string {
ret := make([]string, len(in[0]))
for j := 0; j < len(in[0]); j++ {
for i := 0; i < len(in); i++ {
ret[j] += string(in[i][j])
}
}
return ret
}
func check(input []string, pl byte) bool {
seen := Seen{}
for i := range input[0] {
if input[0][i] == pl {
seen.next(input, 0, i, pl)
}
}
// check if we reached the end of the grid
for k := range seen {
if k[0] == len(input)-1 {
return true
}
}
return false
}
// next recursively checks every neighbor which matches the player's character
// and have not seen yet.
func (seen Seen) next(input []string, row, pos int, val byte) {
item := [2]int{row, pos}
seen[item] = true
for _, d := range directions {
// check for grid range under- or overruns
if row+d[0] >= 0 && row+d[0] < len(input) &&
pos+d[1] >= 0 && pos+d[1] < len(input[0]) {
nbr := [2]int{row + d[0], pos + d[1]}
if input[nbr[0]][nbr[1]] == val && !seen[nbr] {
seen.next(input, nbr[0], nbr[1], val)
}
}
}
}