@@ -15,7 +15,7 @@ const (
1515 minRowsCols = 3
1616 maxRowsCols = 20
1717 defaultWinWidth = 300
18- defaultWinHeight = 400
18+ defaultWinHeight = 450
1919)
2020
2121type state struct {
@@ -58,9 +58,6 @@ func (s *state) reset() {
5858 s .gameOver = false
5959 s .gameWon = false
6060 s .menu = true
61- s .rows = 9
62- s .cols = 9
63- s .mines = 10
6461}
6562
6663func (s * state ) start () {
@@ -97,14 +94,14 @@ func (s *state) start() {
9794
9895func (s * state ) doForNeighbours (x , y int , do func (x , y int )) {
9996 // with diagonals
100- dx := []int {- 1 , - 1 , - 1 , 0 , 0 , 1 , 1 , 1 }
101- dy := []int {- 1 , 0 , 1 , - 1 , 1 , - 1 , 0 , 1 }
97+ dx := []int {- 1 , 0 , 1 , - 1 , 1 , - 1 , 0 , 1 }
98+ dy := []int {- 1 , - 1 , - 1 , 0 , 0 , 1 , 1 , 1 }
10299
103100 for i := 0 ; i < len (dx ); i ++ {
104101 nx := x + dx [i ]
105102 ny := y + dy [i ]
106103
107- if nx >= 0 && nx < int (s .cols ) && ny >= 0 && ny < int (s .rows ) {
104+ if nx >= 0 && nx < int (s .rows ) && ny >= 0 && ny < int (s .cols ) {
108105 do (nx , ny )
109106 }
110107 }
@@ -130,12 +127,13 @@ func (s *state) revealTile(x, y int) {
130127 return
131128 }
132129
130+ s.field [x ][y ].open = true
131+
133132 if s.field [x ][y ].hasMine {
134133 s .gameOver = true
135134 return
136135 }
137136
138- s.field [x ][y ].open = true
139137 s .gameWon = s .checkIfGameWon ()
140138
141139 // No neighbors, reveal all adjacent tiles recursively.
@@ -150,20 +148,41 @@ func (s *state) drawMenu() {
150148 w , h := defaultWinWidth , defaultWinHeight
151149 colw := float32 (w / 2 )
152150 var rowh float32 = 50
151+ var fontSize int32 = 20
152+ buttonWidth := float32 (w - 2 * padding )
153+
153154 rl .SetWindowSize (w , h )
155+ rl .SetWindowPosition ((rl .GetMonitorWidth (0 )- int (w ))/ 2 , (rl .GetMonitorHeight (0 )- int (h ))/ 2 )
156+
157+ if clicked := gui .Button (rl .NewRectangle (padding , rowh , buttonWidth , size ), "BEGINNER" ); clicked {
158+ s .rows = 9
159+ s .cols = 9
160+ s .mines = 10
161+ }
162+ if clicked := gui .Button (rl .NewRectangle (padding , 2 * rowh , buttonWidth , size ), "INTERMEDIATE" ); clicked {
163+ s .rows = 16
164+ s .cols = 16
165+ s .mines = 40
166+ }
167+ if clicked := gui .Button (rl .NewRectangle (padding , 3 * rowh , buttonWidth , size ), "EXPERT" ); clicked {
168+ s .rows = 30
169+ s .cols = 30
170+ s .mines = 99
171+ }
154172
155- rl .DrawText ("ROWS:" , padding , int32 (rowh ), size , rl .White )
156- s .rows = gui .Spinner (rl .NewRectangle (colw , rowh , float32 (colw - padding ), size ), "" , & s .rows , minRowsCols , maxRowsCols , true )
173+ rl .DrawText ("ROWS:" , padding , 4 * int32 (rowh )+ 5 , fontSize , rl .White )
174+ s .rows = gui .Spinner (rl .NewRectangle (colw , 4 * rowh , float32 (colw - padding ), size ), "" , & s .rows , minRowsCols , maxRowsCols , true )
157175
158- rl .DrawText ("COLS:" , padding , 2 * int32 (rowh ), size , rl .White )
159- s .cols = gui .Spinner (rl .NewRectangle (colw , 2 * rowh , float32 (colw - padding ), size ), "" , & s .cols , minRowsCols , maxRowsCols , true )
176+ rl .DrawText ("COLS:" , padding , 5 * int32 (rowh )+ 5 , fontSize , rl .White )
177+ s .cols = gui .Spinner (rl .NewRectangle (colw , 5 * rowh , float32 (colw - padding ), size ), "" , & s .cols , minRowsCols , maxRowsCols , true )
160178
161- rl .DrawText ("MINES:" , padding , 3 * int32 (rowh ), size , rl .White )
162- s .mines = gui .Spinner (rl .NewRectangle (colw , 3 * rowh , float32 (colw - padding ), size ), "" , & s .mines , 1 , int (s .rows )* int (s .cols ), true )
179+ rl .DrawText ("MINES:" , padding , 6 * int32 (rowh )+ 5 , fontSize , rl .White )
180+ s .mines = gui .Spinner (rl .NewRectangle (colw , 6 * rowh , float32 (colw - padding ), size ), "" , & s .mines , 1 , int (s .rows )* int (s .cols ), true )
163181
164- if clicked := gui .Button (rl .NewRectangle (padding , 4 * rowh , float32 ( w - 2 * padding ) , size ), "START" ); clicked {
182+ if clicked := gui .Button (rl .NewRectangle (padding , 7 * rowh , buttonWidth , size ), "START" ); clicked {
165183 s .start ()
166184 }
185+
167186}
168187
169188func getTextColor (neighbors int ) rl.Color {
@@ -184,12 +203,33 @@ func (s *state) drawField() {
184203 h := float32 (s .getHeight ())
185204
186205 rl .SetWindowSize (int (w ), int (h ))
206+ rl .SetWindowPosition ((rl .GetMonitorWidth (0 )- int (w ))/ 2 , (rl .GetMonitorHeight (0 )- int (h ))/ 2 )
207+
187208 gui .StatusBar (rl .NewRectangle (0 , h - size , w , size ), s .getStatus ())
209+ if restart := gui .Button (rl .NewRectangle (w - 65 , h - size + 5 , 60 , size - 10 ), "RESTART" ); restart {
210+ s .reset ()
211+ return
212+ }
188213
189214 for x := range s .field {
190215 for y := range s .field [x ] {
191216 rect := rl .NewRectangle (float32 (padding + x * size ), float32 (padding + y * size ), size , size )
192217
218+ if s .gameOver {
219+ // reveal current state
220+ if s.field [x ][y ].hasMine {
221+ rl .DrawText ("*" , 5 + padding + int32 (x )* size , 5 + padding + int32 (y )* size , 20 , rl .Red )
222+ } else {
223+ text := ""
224+ if s.field [x ][y ].neighbours > 0 {
225+ text = fmt .Sprintf ("%d" , s.field [x ][y ].neighbours )
226+ }
227+
228+ rl .DrawText (text , 5 + padding + int32 (x )* size , 5 + padding + int32 (y )* size , 20 , getTextColor (s.field [x ][y ].neighbours ))
229+ }
230+ continue
231+ }
232+
193233 // Mark on right mouse button
194234 if rl .IsMouseButtonPressed (rl .MouseButtonRight ) {
195235 if rl .CheckCollisionPointRec (rl .GetMousePosition (), rect ) {
@@ -217,26 +257,27 @@ func (s *state) drawField() {
217257 }
218258}
219259
220- func (s * state ) drawMessageWithRestart () {
260+ func (s * state ) congrats () {
221261 w , h := defaultWinWidth , defaultWinHeight
222262 var lineHeight int32 = 50
223263 rl .SetWindowSize (w , h )
224264
225- if s .gameOver {
226- rl .DrawText ("GAME OVER :(" , padding , lineHeight , size , rl .White )
227- }
228265 if s .gameWon {
229266 rl .DrawText ("WELL DONE !" , padding , lineHeight , size , rl .White )
230267 }
231268
232- clicked := gui .Button (rl .NewRectangle (padding , float32 (2 * lineHeight ), float32 (w - 2 * padding ), size ), "ONE MORE " )
269+ clicked := gui .Button (rl .NewRectangle (padding , float32 (2 * lineHeight ), float32 (w - 2 * padding ), size ), "PLAY AGAIN " )
233270 if clicked {
234271 s .reset ()
235272 }
236273}
237274
238275func main () {
239- game := & state {}
276+ game := & state {
277+ rows : 9 ,
278+ cols : 9 ,
279+ mines : 10 ,
280+ }
240281 game .reset ()
241282
242283 rl .InitWindow (defaultWinWidth , defaultWinHeight , "minesweeper" )
@@ -247,8 +288,8 @@ func main() {
247288 rl .BeginDrawing ()
248289 rl .ClearBackground (rl .DarkGray )
249290
250- if game .gameOver || game . gameWon {
251- game .drawMessageWithRestart ()
291+ if game .gameWon {
292+ game .congrats ()
252293 } else if game .menu {
253294 game .drawMenu ()
254295 } else {
0 commit comments