81 lines
1.5 KiB
Go
81 lines
1.5 KiB
Go
package main
|
|
|
|
import (
|
|
"fmt"
|
|
"time"
|
|
"math/rand/v2"
|
|
)
|
|
|
|
type gameState struct {
|
|
isGameOver bool
|
|
rows int
|
|
cols int
|
|
numMines int
|
|
field [][]point
|
|
gameStartedAt time.Time
|
|
}
|
|
|
|
type point struct {
|
|
isMine bool
|
|
isOpen bool
|
|
isMarked bool
|
|
numNeighbouringMines int
|
|
}
|
|
|
|
func (gs *gameState) applyToNeighbours(x, y int, do func(x, y int)) {
|
|
dx := []int{-1, -1, -1, 0, 0, 1, 1, 1}
|
|
dy := []int{-1, 0, 1, -1, 1, -1, 0, 1}
|
|
for i := range dx {
|
|
neighbourX := x + dx[i]
|
|
neighbourY := y + dy[i]
|
|
if neighbourX >= 0 && neighbourY >= 0 && neighbourX < gs.rows && neighbourY < gs.cols {
|
|
do(neighbourX, neighbourY)
|
|
}
|
|
}
|
|
}
|
|
|
|
func (gs *gameState) printField() {
|
|
for _, row := range gs.field {
|
|
for _, cell := range row {
|
|
if cell.isMine {
|
|
fmt.Print("*")
|
|
} else {
|
|
fmt.Print(cell.numNeighbouringMines)
|
|
}
|
|
}
|
|
fmt.Println()
|
|
}
|
|
}
|
|
|
|
func (gs *gameState) initField() {
|
|
gs.field = make([][]point, gs.rows)
|
|
for i := range gs.field {
|
|
gs.field[i] = make([]point, gs.cols)
|
|
}
|
|
|
|
for i := range gs.numMines {
|
|
ranX := rand.IntN(gs.rows -1)
|
|
ranY := rand.IntN(gs.cols-1)
|
|
if !gs.field[ranX][ranY].isMine {
|
|
gs.field[ranX][ranY].isMine = true
|
|
gs.applyToNeighbours(ranX, ranY, func(x, y int) {
|
|
gs.field[x][y].numNeighbouringMines++
|
|
})
|
|
} else {
|
|
i--
|
|
}
|
|
}
|
|
}
|
|
|
|
func main() {
|
|
gs := &gameState{
|
|
rows: 10,
|
|
cols: 10,
|
|
numMines: 5,
|
|
gameStartedAt: time.Now(),
|
|
}
|
|
|
|
gs.initField()
|
|
gs.printField()
|
|
}
|