Initial commit, also running version

This commit is contained in:
2025-05-21 09:23:08 +02:00
commit 73f562ca70
7 changed files with 477 additions and 0 deletions

26
cell.go Normal file
View File

@@ -0,0 +1,26 @@
package minesweeper
import "image/color"
type CellType int
const (
NO_BOMB CellType = iota
BOMB
)
type State int
const (
OPEN State = iota
DARK
FLAG
)
type Cell struct {
top, left float32
color color.Color
state State
cellType CellType
bombNeighbours int
}

26
cmd/mine-sweeper/main.go Normal file
View File

@@ -0,0 +1,26 @@
package main
import (
"log"
minesweeper "github.com/Pablu23/mine-sweeper"
"github.com/hajimehoshi/ebiten/v2"
)
func main() {
width := 720
height := 720
cellSize := 60
bombPercentage := 20
ebiten.SetWindowSize(width, height)
ebiten.SetWindowTitle("Hello, World!")
game, err := minesweeper.NewGame(width, height, cellSize, bombPercentage)
if err != nil {
log.Fatal(err)
}
if err := ebiten.RunGame(game); err != nil {
log.Fatal(err)
}
}

9
constants.go Normal file
View File

@@ -0,0 +1,9 @@
package minesweeper
import "image/color"
var (
OPEN_COLOR = color.RGBA{200, 200, 200, 255}
DARK_COLOR = color.RGBA{20, 20, 20, 255}
FLAG_COLOR = color.RGBA{0, 255, 0, 255}
)

181
game.go Normal file
View File

@@ -0,0 +1,181 @@
package minesweeper
import (
"bytes"
"fmt"
"image/color"
"github.com/hajimehoshi/ebiten/examples/resources/fonts"
"github.com/hajimehoshi/ebiten/v2"
"github.com/hajimehoshi/ebiten/v2/ebitenutil"
"github.com/hajimehoshi/ebiten/v2/inpututil"
"github.com/hajimehoshi/ebiten/v2/text/v2"
)
type Game struct {
Width, Height int
CellSize int
rows, columns int
bombPercentage int
cells []Cell
firstMove bool
lost bool
won bool
bombIndexes map[int]struct{}
faceSource *text.GoTextFaceSource
}
func NewGame(width, height, cellSize, bombPercentage int) (*Game, error) {
s, err := text.NewGoTextFaceSource(bytes.NewReader(fonts.MPlus1pRegular_ttf))
if err != nil {
return nil, err
}
rows := width / cellSize
columns := height / cellSize
g := &Game{
Width: width,
Height: height,
CellSize: cellSize,
rows: rows,
columns: columns,
bombPercentage: bombPercentage,
cells: make([]Cell, rows*columns),
firstMove: false,
lost: false,
won: false,
bombIndexes: map[int]struct{}{},
faceSource: s,
}
g.Reset()
return g, nil
}
func (g *Game) CheckWin() {
for _, cell := range g.cells {
if cell.cellType != BOMB && cell.state == FLAG {
return
} else if cell.cellType == BOMB && cell.state != FLAG {
return
} else if cell.state == DARK {
return
}
}
g.won = true
return
}
func (g *Game) HandleFirstMove(i int) {
if !g.firstMove {
return
}
indexes := make([]int, 0)
g.applyNeighbours(i, func(index int) {
indexes = append(indexes, index)
r := RandomUntilNoBomb(g.rows*g.columns, g.bombIndexes)
g.cells[r].cellType = BOMB
})
for _, i := range indexes {
g.cells[i].cellType = NO_BOMB
}
for i := range g.cells {
g.cells[i].bombNeighbours = g.CalcNeighbourBombs(i)
}
g.SetBomblessNeighboursToOpen(i)
g.firstMove = false
}
func (g *Game) Reset() {
cells, indexes := g.SetupCells()
g.cells = cells
g.bombIndexes = indexes
g.won = false
g.lost = false
g.firstMove = true
}
func (g *Game) Update() error {
if !g.won && !g.lost {
if inpututil.IsMouseButtonJustPressed(ebiten.MouseButtonLeft) {
x, y := ebiten.CursorPosition()
index := g.CursorPosToIndex(x, y)
g.HandleFirstMove(index)
if g.cells[index].cellType == BOMB && g.cells[index].state != FLAG {
g.lost = true
} else if g.cells[index].state != FLAG {
g.cells[index].state = OPEN
if g.cells[index].bombNeighbours == 0 {
g.SetBomblessNeighboursToOpen(index)
}
}
} else if inpututil.IsMouseButtonJustPressed(ebiten.MouseButtonRight) {
x, y := ebiten.CursorPosition()
index := g.CursorPosToIndex(x, y)
if g.cells[index].state == DARK {
g.cells[index].state = FLAG
} else if g.cells[index].state == FLAG {
g.cells[index].state = DARK
}
}
}
if inpututil.IsKeyJustPressed(ebiten.KeyR) {
g.Reset()
}
g.CheckWin()
return nil
}
func (g *Game) Draw(screen *ebiten.Image) {
showBombs := false
if g.lost {
showBombs = true
ebitenutil.DebugPrint(screen, "Game Over!")
} else if g.won {
ebitenutil.DebugPrint(screen, "Game Won :) YAAY!")
return
}
g.DrawCells(screen, showBombs)
}
func (g *Game) DrawCells(screen *ebiten.Image, showBombs bool) {
for _, cell := range g.cells {
op := &ebiten.DrawImageOptions{}
op.GeoM.Translate(float64(cell.left), float64(cell.top))
borderImage := ebiten.NewImage(g.CellSize, g.CellSize)
borderImage.Fill(color.Black)
cellImage := ebiten.NewImage(g.CellSize-2, g.CellSize-2)
if showBombs && cell.cellType == BOMB {
cellImage.Fill(color.RGBA{255, 0, 0, 255})
} else {
cellImage.Fill(MatchColor(cell.state))
}
borderImage.DrawImage(cellImage, nil)
if cell.state == OPEN && cell.bombNeighbours != 0 {
txOp := &text.DrawOptions{}
txOp.GeoM.Translate(float64(g.CellSize-24)/2, float64(g.CellSize-24)/2)
text.Draw(borderImage, fmt.Sprintf("%v", cell.bombNeighbours), &text.GoTextFace{Source: g.faceSource, Size: 24}, txOp)
}
screen.DrawImage(borderImage, op)
}
}
func (g *Game) Layout(outsideWidth, outsideHeight int) (screenWidth, screenHeight int) {
return outsideWidth, outsideHeight
}

24
go.mod Normal file
View File

@@ -0,0 +1,24 @@
module github.com/Pablu23/mine-sweeper
go 1.23.4
require github.com/hajimehoshi/ebiten/v2 v2.8.8
require (
github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200707082815-5321531c36a2 // indirect
github.com/go-text/typesetting v0.2.0 // indirect
golang.org/x/exp v0.0.0-20190731235908-ec7cb31e5a56 // indirect
golang.org/x/image v0.20.0 // indirect
golang.org/x/mobile v0.0.0-20210208171126-f462b3930c8f // indirect
golang.org/x/text v0.18.0 // indirect
)
require (
github.com/ebitengine/gomobile v0.0.0-20240911145611-4856209ac325 // indirect
github.com/ebitengine/hideconsole v1.0.0 // indirect
github.com/ebitengine/purego v0.8.0 // indirect
github.com/hajimehoshi/ebiten v1.12.12
github.com/jezek/xgb v1.1.1 // indirect
golang.org/x/sync v0.8.0 // indirect
golang.org/x/sys v0.25.0 // indirect
)

80
go.sum Normal file
View File

@@ -0,0 +1,80 @@
github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo=
github.com/ebitengine/gomobile v0.0.0-20240911145611-4856209ac325 h1:Gk1XUEttOk0/hb6Tq3WkmutWa0ZLhNn/6fc6XZpM7tM=
github.com/ebitengine/gomobile v0.0.0-20240911145611-4856209ac325/go.mod h1:ulhSQcbPioQrallSuIzF8l1NKQoD7xmMZc5NxzibUMY=
github.com/ebitengine/hideconsole v1.0.0 h1:5J4U0kXF+pv/DhiXt5/lTz0eO5ogJ1iXb8Yj1yReDqE=
github.com/ebitengine/hideconsole v1.0.0/go.mod h1:hTTBTvVYWKBuxPr7peweneWdkUwEuHuB3C1R/ielR1A=
github.com/ebitengine/purego v0.8.0 h1:JbqvnEzRvPpxhCJzJJ2y0RbiZ8nyjccVUrSM3q+GvvE=
github.com/ebitengine/purego v0.8.0/go.mod h1:iIjxzd6CiRiOG0UyXP+V1+jWqUXVjPKLAI0mRfJZTmQ=
github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200707082815-5321531c36a2 h1:Ac1OEHHkbAZ6EUnJahF0GKcU0FjPc/V8F1DvjhKngFE=
github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200707082815-5321531c36a2/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8=
github.com/go-text/typesetting v0.2.0 h1:fbzsgbmk04KiWtE+c3ZD4W2nmCRzBqrqQOvYlwAOdho=
github.com/go-text/typesetting v0.2.0/go.mod h1:2+owI/sxa73XA581LAzVuEBZ3WEEV2pXeDswCH/3i1I=
github.com/gofrs/flock v0.8.0/go.mod h1:F1TvTiK9OcQqauNUHlbJvyl9Qa1QvF/gOUDKA14jxHU=
github.com/golang/freetype v0.0.0-20170609003504-e2365dfdc4a0/go.mod h1:E/TSTwGwJL78qG/PmXZO1EjYhfJinVAhrmmHX6Z8B9k=
github.com/hajimehoshi/bitmapfont v1.3.0/go.mod h1:/Qb7yVjHYNUV4JdqNkPs6BSZwLjKqkZOMIp6jZD0KgE=
github.com/hajimehoshi/ebiten v1.12.12 h1:JvmF1bXRa+t+/CcLWxrJCRsdjs2GyBYBSiFAfIqDFlI=
github.com/hajimehoshi/ebiten v1.12.12/go.mod h1:1XI25ImVCDPJiXox4h9yK/CvN5sjDYnbF4oZcFzPXHw=
github.com/hajimehoshi/ebiten/v2 v2.8.8 h1:xyMxOAn52T1tQ+j3vdieZ7auDBOXmvjUprSrxaIbsi8=
github.com/hajimehoshi/ebiten/v2 v2.8.8/go.mod h1:durJ05+OYnio9b8q0sEtOgaNeBEQG7Yr7lRviAciYbs=
github.com/hajimehoshi/file2byteslice v0.0.0-20200812174855-0e5e8a80490e/go.mod h1:CqqAHp7Dk/AqQiwuhV1yT2334qbA/tFWQW0MD2dGqUE=
github.com/hajimehoshi/go-mp3 v0.3.1/go.mod h1:qMJj/CSDxx6CGHiZeCgbiq2DSUkbK0UbtXShQcnfyMM=
github.com/hajimehoshi/oto v0.6.1/go.mod h1:0QXGEkbuJRohbJaxr7ZQSxnju7hEhseiPx2hrh6raOI=
github.com/hajimehoshi/oto v0.6.8/go.mod h1:0QXGEkbuJRohbJaxr7ZQSxnju7hEhseiPx2hrh6raOI=
github.com/jakecoffman/cp v1.0.0/go.mod h1:JjY/Fp6d8E1CHnu74gWNnU0+b9VzEdUVPoJxg2PsTQg=
github.com/jezek/xgb v1.1.1 h1:bE/r8ZZtSv7l9gk6nU0mYx51aXrvnyb44892TwSaqS4=
github.com/jezek/xgb v1.1.1/go.mod h1:nrhwO0FX/enq75I7Y7G8iN1ubpSGZEiA3v9e9GyRFlk=
github.com/jfreymuth/oggvorbis v1.0.1/go.mod h1:NqS+K+UXKje0FUYUPosyQ+XTVvjmVjps1aEZH1sumIk=
github.com/jfreymuth/vorbis v1.0.0/go.mod h1:8zy3lUAm9K/rJJk223RKy6vjCZTWC61NA2QD06bfOE0=
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno=
github.com/pkg/browser v0.0.0-20180916011732-0a3d74bf9ce4/go.mod h1:4OwLy04Bl9Ef3GJJCoec+30X3LQs/0/m4HFRt/2LUSA=
github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
golang.org/x/exp v0.0.0-20190731235908-ec7cb31e5a56 h1:estk1glOnSVeJ9tdEZZc5mAMDZk5lNJNyJ6DvrBkTEU=
golang.org/x/exp v0.0.0-20190731235908-ec7cb31e5a56/go.mod h1:JhuoJpWY28nO4Vef9tZUw9qufEGTyX1+7lmHxV5q5G4=
golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js=
golang.org/x/image v0.0.0-20190703141733-d6a02ce849c9/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0=
golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0=
golang.org/x/image v0.0.0-20200801110659-972c09e46d76/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0=
golang.org/x/image v0.20.0 h1:7cVCUjQwfL18gyBJOmYvptfSHS8Fb3YUDtfLIZ7Nbpw=
golang.org/x/image v0.20.0/go.mod h1:0a88To4CYVBAHp5FXJm8o7QbUl37Vd85ply1vyD8auM=
golang.org/x/mobile v0.0.0-20190312151609-d3739f865fa6/go.mod h1:z+o9i4GpDbdi3rU15maQ/Ox0txvL9dWGYEHz965HBQE=
golang.org/x/mobile v0.0.0-20190415191353-3e0bab5405d6/go.mod h1:E/iHnbuqvinMTCcRqshq8CkpyQDoeVncDDYHnLhea+o=
golang.org/x/mobile v0.0.0-20210208171126-f462b3930c8f h1:aEcjdTsycgPqO/caTgnxfR9xwWOltP/21vtJyFztEy0=
golang.org/x/mobile v0.0.0-20210208171126-f462b3930c8f/go.mod h1:skQtrUTUwhdJvXM/2KKJzY8pDgNr9I/FOMqDVRPBUS4=
golang.org/x/mod v0.1.0/go.mod h1:0QHyrYULN0/3qlju5TqG8bIK38QM8yzMo5ekMj3DlcY=
golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg=
golang.org/x/mod v0.1.1-0.20191209134235-331c550502dd/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.8.0 h1:3NFvSEYkUoMifnESzZl15y791HH1qU2xm6eCJU5ZPXQ=
golang.org/x/sync v0.8.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190429190828-d89cdac9e872/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200918174421-af09f7315aff/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.25.0 h1:r+8e+loiHxRqhXVl6ML1nO3l1+oFoWbnlu2Ehimmi34=
golang.org/x/sys v0.25.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.18.0 h1:XvMDiNzPAl0jr17s6W9lcaIhGUfUORdGCNsuLmPG224=
golang.org/x/text v0.18.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY=
golang.org/x/tools v0.0.0-20190312151545-0bb0c0a6e846/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.0.0-20200117012304-6edc0a871e69/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
golang.org/x/tools v0.0.0-20200918232735-d647fc253266/go.mod h1:z6u4i615ZeAfBE4XtMziQW1fSVJXACjjbWkB/mvPzlU=
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
gopkg.in/check.v1 v1.0.0-20200902074654-038fdea0a05b/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=

131
util.go Normal file
View File

@@ -0,0 +1,131 @@
package minesweeper
import (
"image/color"
"golang.org/x/exp/rand"
)
func RandomUntilNoBomb(cellCount int, bombIndexes map[int]struct{}) int {
r := rand.Intn(cellCount)
loop := true
for loop {
if _, ok := bombIndexes[r]; !ok {
loop = false
}
r = rand.Intn(cellCount)
}
return r
}
func (g *Game) XYToIndex(x int, y int) int {
index := y*(g.columns) + x
return index
}
func (g *Game) IndexToXY(index int) (int, int) {
x := index % (g.columns)
y := index / (g.columns)
return x, y
}
func (g *Game) CursorPosToIndex(x int, y int) int {
logicX := x / g.CellSize
logicY := y / g.CellSize
return g.XYToIndex(logicX, logicY)
}
func (g *Game) CalcNeighbourBombs(index int) int {
bombs := 0
g.applyNeighbours(index, func(i int) {
if g.cells[i].cellType == BOMB {
bombs += 1
}
})
return bombs
}
func (g *Game) SetBomblessNeighboursToOpen(index int) {
g.applyNeighbours(index, func(i int) {
if g.cells[i].bombNeighbours == 0 && g.cells[i].state != OPEN {
g.cells[i].state = OPEN
g.SetBomblessNeighboursToOpen(i)
} else if g.cells[i].cellType != BOMB {
g.cells[i].state = OPEN
}
})
}
func (g *Game) applyNeighbours(index int, f func(index int)) {
posX, posY := g.IndexToXY(index)
for x := -1; x <= 1; x++ {
for y := -1; y <= 1; y++ {
if posX+x < 0 || posX+x >= g.rows {
continue
}
if posY+y < 0 || posY+y >= g.columns {
continue
}
i := g.XYToIndex(posX+x, posY+y)
f(i)
}
}
}
func MatchColor(state State) color.Color {
switch state {
case OPEN:
return OPEN_COLOR
case DARK:
return DARK_COLOR
case FLAG:
return FLAG_COLOR
default:
return color.Black
}
}
func (g *Game) SetupCells() ([]Cell, map[int]struct{}) {
cellCount := (g.columns * g.rows)
bombs := float64(cellCount) * (float64(g.bombPercentage) / 100)
cells := make([]Cell, 0)
bombIndexes := make(map[int]struct{})
for range int(bombs) {
r := RandomUntilNoBomb(cellCount, bombIndexes)
bombIndexes[r] = struct{}{}
}
index := 0
for x := range g.columns {
for y := range g.rows {
cellType := NO_BOMB
cellColor := color.RGBA{120, 120, 120, 255}
if _, isBomb := bombIndexes[index]; isBomb {
cellType = BOMB
cellColor = color.RGBA{255, 0, 0, 255}
}
cells = append(cells, Cell{
top: float32(x * g.CellSize),
left: float32(y * g.CellSize),
color: cellColor,
cellType: cellType,
state: DARK,
})
index += 1
}
}
for i := range cells {
cells[i].bombNeighbours = g.CalcNeighbourBombs(i)
}
return cells, bombIndexes
}