Commit f08d9286 authored by Kevin Lyda's avatar Kevin Lyda 💬

Check for pieces across a board.

parents
package sidecheck
import (
"strings"
)
const (
BOARD int = iota
PIECE
SELECTED
)
type coords struct {
x, y int
}
func coordsAround(x, y int) []coords {
return []coords{
{x - 1, y - 1},
{x - 1, y},
{x - 1, y + 1},
{x, y - 1},
{x, y + 1},
{x + 1, y - 1},
{x + 1, y},
{x + 1, y + 1},
}
}
type Board struct {
rows, cols int
board [][]int
}
func NewBoard(rows, cols int) *Board {
board := Board{
rows, cols,
make([][]int, rows),
}
for i := 0; i < rows; i++ {
board.board[i] = make([]int, cols)
}
return &board
}
func StringToBoard(b string) *Board {
rows := strings.Split(b, "\n")
rowMax := len(rows)
if rowMax == 0 {
panic("Board needs to have at least 1 row")
}
colMax := len(rows[0])
if colMax == 0 {
panic("Board needs to have at least 1 column")
}
board := *NewBoard(rowMax, colMax)
for i := 0; i < rowMax; i++ {
if len(rows[i]) != colMax {
panic("Column mismatch")
}
for j := 0; j < colMax; j++ {
switch rows[i][j] {
case '.':
board.board[i][j] = BOARD
case 'o':
board.board[i][j] = PIECE
default:
panic("Unknown board char encountered")
}
}
}
return &board
}
// Piecep returns true if there's a piece at x, y.
func (b Board) Piecep(x, y int) bool {
if x < 0 || y < 0 || x >= b.rows || y >= b.cols {
return false
}
return b.board[x][y] == PIECE
}
// String converts Board to a string.
func (b Board) String() string {
var result string
spotChar := []string{".", "o", "+"}
for _, row := range b.board {
for _, spot := range row {
result += spotChar[spot]
}
result += "\n"
}
return result
}
// NScheck checks if any pieces allow for a path across.
func (b Board) NScheck() bool {
for j := 0; j < b.cols; j++ {
if b.Piecep(0, j) {
if found := b.nscheck(newPiece(0, j)); found {
return true
}
}
}
return false
}
func (b Board) nscheck(p *piece) bool {
if p.x == (b.rows - 1) {
return true
}
cs := coordsAround(p.x, p.y)
for _, c := range cs {
if c.y > 0 && b.Piecep(c.x, c.y) && !p.seen(c.x, c.y) {
next := newPiece(c.x, c.y)
next.parent = p
if found := b.nscheck(next); found {
return true
}
}
}
return false
}
// WEcheck checks if any pieces allow for a path across.
func (b Board) WEcheck() bool {
for i := 0; i < b.rows; i++ {
if b.Piecep(i, 0) {
if found := b.wecheck(newPiece(i, 0)); found {
return true
}
}
}
return false
}
func (b Board) wecheck(p *piece) bool {
if p.y == (b.cols - 1) {
return true
}
cs := coordsAround(p.x, p.y)
for _, c := range cs {
if c.x > 0 && b.Piecep(c.x, c.y) && !p.seen(c.x, c.y) {
next := newPiece(c.x, c.y)
next.parent = p
if found := b.wecheck(next); found {
return true
}
}
}
return false
}
// piece tracks a connected line of pieces through a board.
type piece struct {
x, y int
parent *piece
}
// newPiece creates a new node.
func newPiece(x, y int) *piece {
p := &piece{
x: x,
y: y,
parent: nil,
}
return p
}
// seen returns is a coord has been seen.
func (p piece) seen(x, y int) bool {
pp := p.parent
for pp != nil {
if pp.x == x && pp.y == y {
return true
}
pp = pp.parent
}
return false
}
package sidecheck
import (
"fmt"
"testing"
)
type boardTestType struct {
NS,
WE bool
board string
}
var boardTests = []boardTestType{
{
false,
true,
`.....
.....
ooooo
.....
.....`,
},
{
false,
false,
`...........o................
............o...............
.............o..............
.............o..............
.............o..............
.............o..............
.............o..............
...........ooo..............
...........o.o..............
...........ooo..............
............................`,
},
{
true,
false,
`.............o..............
.............o..............
.............o..............
.............o..............
.............o..............
.............o..............
.............o..............
.............o..............
.............o.......ooooooo
.............ooooooooo......
.....................o......`,
},
{
false,
true,
`............................
............................
............................
............................
............................
.........o................oo
ooooooooo................o..
....o....oooooo.........o...
....o.........o........o....
.....o......oo.......oo.....
......oooo....oo...oo.......
..........ooo...ooo.........
............................`,
},
}
func TestBoards(t *testing.T) {
for _, boardTest := range boardTests {
board := StringToBoard(boardTest.board)
if boardTest.NS != board.NScheck() {
fmt.Println("NS FAIL")
if boardTest.NS {
t.Errorf("Failed to find NS path.")
} else {
t.Errorf("Found NS path but shouldn't have.")
}
}
if boardTest.WE != board.WEcheck() {
fmt.Println("WE FAIL")
if boardTest.WE {
t.Errorf("Failed to find WE path.")
} else {
t.Errorf("Found WE path but shouldn't have.")
}
}
fmt.Println(board)
}
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment