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)
			}
		}
	}
}