113 lines
1.9 KiB
Go
113 lines
1.9 KiB
Go
package minesweeper
|
|
|
|
import (
|
|
"bytes"
|
|
"errors"
|
|
"strconv"
|
|
)
|
|
|
|
const testVersion = 1
|
|
|
|
type Board [][]byte
|
|
|
|
// Count fills in the number of mines in adjacent squares on the board
|
|
func (b Board) Count() error {
|
|
if !b.isValid() {
|
|
return errors.New("Invalid Board")
|
|
}
|
|
for i := range b {
|
|
for j := range b[i] {
|
|
switch b[i][j] {
|
|
case '+', '-', '|', '*':
|
|
continue
|
|
case ' ':
|
|
num := b.countAdjacentMines(j, i)
|
|
if num != 0 {
|
|
b[i][j] = []byte(strconv.Itoa(num))[0]
|
|
}
|
|
default:
|
|
return errors.New("Invalid Board")
|
|
}
|
|
}
|
|
}
|
|
return nil
|
|
}
|
|
|
|
// countAdjacentMines returns the number of mines adjacent to x,y
|
|
// or -1 if x,y is invalid
|
|
func (b Board) countAdjacentMines(x, y int) int {
|
|
var numMines int
|
|
if b.isMine(x-1, y-1) {
|
|
numMines++
|
|
}
|
|
if b.isMine(x, y-1) {
|
|
numMines++
|
|
}
|
|
if b.isMine(x+1, y-1) {
|
|
numMines++
|
|
}
|
|
if b.isMine(x-1, y) {
|
|
numMines++
|
|
}
|
|
if b.isMine(x, y) {
|
|
numMines++
|
|
}
|
|
if b.isMine(x+1, y) {
|
|
numMines++
|
|
}
|
|
if b.isMine(x-1, y+1) {
|
|
numMines++
|
|
}
|
|
if b.isMine(x, y+1) {
|
|
numMines++
|
|
}
|
|
if b.isMine(x+1, y+1) {
|
|
numMines++
|
|
}
|
|
return numMines
|
|
}
|
|
|
|
func (b Board) isMine(x, y int) bool {
|
|
if x < 0 || y < 0 || x > len(b[0])-1 || y > len(b)-1 {
|
|
return false
|
|
}
|
|
return b[y][x] == '*'
|
|
}
|
|
|
|
func (b Board) isValid() bool {
|
|
if len(b) <= 0 {
|
|
// no size
|
|
return false
|
|
}
|
|
for i := range b {
|
|
if len(b[i]) != len(b[0]) {
|
|
// All rows must be same length
|
|
return false
|
|
}
|
|
for j := range b[i] {
|
|
// Check top & bottom row for border
|
|
if i == 0 || i == len(b)-1 {
|
|
// Check corners for border
|
|
if j == 0 || j == len(b[i])-1 {
|
|
if b[i][j] != '+' {
|
|
return false
|
|
}
|
|
} else if b[i][j] != '-' {
|
|
return false
|
|
}
|
|
} else {
|
|
if j == 0 || j == len(b[i])-1 {
|
|
if b[i][j] != '|' {
|
|
return false
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
return true
|
|
}
|
|
|
|
func (b Board) String() string {
|
|
return "\n" + string(bytes.Join(b, []byte{'\n'}))
|
|
}
|