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