@@ -13,16 +13,20 @@ let won = false;
1313let buttonX , buttonY , buttonW ;
1414
1515class MinesweeperRound {
16- constructor ( width , height , mines ) {
16+ constructor ( width , height , mines , guessFree ) {
1717 this . mines = mines ;
1818 this . flagged = 0 ;
1919 this . width = width ;
2020 this . height = height ;
2121 this . hasStart = false ;
22+ this . guessFree = guessFree ;
2223 this . gameTimer = 0 ;
2324 gameOver = false ;
2425 won = false ;
2526
27+ this . startX = 0 ;
28+ this . startY = 0 ;
29+
2630 this . grid = Array ( ) ;
2731 this . initGame ( ) ;
2832 }
@@ -85,23 +89,57 @@ class MinesweeperRound {
8589 }
8690
8791 reserveStart ( sX , sY ) {
88- for ( let x = - startReserved ; x <= startReserved ; x ++ ) {
89- for ( let y = - startReserved ; y <= startReserved ; y ++ ) {
90- let gX = sX + x ;
91- let gY = sY + y ;
92- if ( gX < 0 || gX >= game . width || gY < 0 || gY >= game . height ) {
93- continue ;
94- }
95- this . grid [ gX + gY * this . width ] . reserved = true ;
96- }
97- }
92+ clearStartingArea ( this . grid , this . width , sX , sY ) ;
9893 this . hasStart = true ;
94+ this . startX = sX ;
95+ this . startY = sY ;
9996 }
10097
101- revealCell ( x , y ) {
98+ applyGame = ( grid ) => {
99+ this . grid = grid . map ( ( cell ) => {
100+ return new Cell ( cell . x , cell . y , cell . mine ) ;
101+ } ) ;
102+ } ;
103+
104+ startGame = ( x , y ) => {
105+ clearStartingArea ( this . grid , this . width , x , y ) ;
106+ seedBoard ( this . mines , this . grid ) ;
107+ this . reserveStart ( x , y ) ;
108+ } ;
109+
110+ startGameWithGuessless = async ( x , y ) => {
111+ let success = false ;
112+
113+ let testGrid = Array ( ) ;
114+ let attempts = 0 ;
115+ while ( ! success ) {
116+ testGrid = Array ( this . grid . length ) ;
117+ for ( let i = 0 ; i < this . width * this . height ; i ++ ) {
118+ testGrid [ i ] = new Cell ( i % this . width , Math . floor ( i / this . width ) , false ) ;
119+ }
120+
121+ clearStartingArea ( testGrid , this . width , x , y ) ;
122+ seedBoard ( this . mines , testGrid ) ;
123+ const results = await validateBoardFromStart ( testGrid , this . width , this . height , this . startX , this . startY ) ;
124+ success = results . success ;
125+ attempts ++ ;
126+ }
127+
128+ console . log ( `Found guess-free board after ${ attempts } attempts` ) ;
129+ this . guessFree = true ;
130+
131+ this . applyGame ( testGrid ) ;
132+ this . reserveStart ( x , y ) ;
133+ calculateNumbers ( this . grid ) ;
134+ } ;
135+
136+ async revealCell ( x , y ) {
102137 if ( ! this . hasStart ) {
103- this . reserveStart ( x , y ) ;
104- this . seedGame ( ) ;
138+ if ( this . guessFree ) {
139+ await this . startGameWithGuessless ( x , y ) ;
140+ } else {
141+ this . startGame ( x , y ) ;
142+ }
105143 }
106144 let gCell = this . grid [ x + y * this . width ] ;
107145 if ( ! gCell . flagged ) {
@@ -322,27 +360,6 @@ class MinesweeperRound {
322360 }
323361 }
324362
325- seedGame ( ) {
326- let rejects = 0 ;
327- for ( let i = 0 ; i < this . mines ; 0 ) {
328- let mI = Math . floor ( Math . random ( ) * this . grid . length ) ;
329-
330- if ( this . grid [ mI ] . count >= 0 && ! this . grid [ mI ] . reserved && ! this . grid [ mI ] . mine ) {
331- this . grid [ mI ] . mine = true ;
332- i ++ ;
333- } else {
334- rejects ++ ;
335- continue ;
336- }
337-
338- if ( rejects >= this . mines * 5 ) break ;
339- }
340-
341- for ( let i = 0 ; i < this . grid . length ; i ++ ) {
342- this . grid [ i ] . calculateNearby ( ) ;
343- }
344- }
345-
346363 drawGame ( ) {
347364 for ( let x = 0 ; x < this . width ; x ++ ) {
348365 for ( let y = 0 ; y < this . height ; y ++ ) {
@@ -361,3 +378,41 @@ function isMobile() {
361378 return false ;
362379 }
363380}
381+
382+ const clearStartingArea = ( board , width , sX , sY ) => {
383+ for ( let x = - startReserved ; x <= startReserved ; x ++ ) {
384+ for ( let y = - startReserved ; y <= startReserved ; y ++ ) {
385+ let gX = sX + x ;
386+ let gY = sY + y ;
387+ if ( gX < 0 || gX >= game . width || gY < 0 || gY >= game . height ) {
388+ continue ;
389+ }
390+ board [ gX + gY * width ] . reserved = true ;
391+ }
392+ }
393+ } ;
394+
395+ const calculateNumbers = ( grid ) => {
396+ for ( let i = 0 ; i < grid . length ; i ++ ) {
397+ grid [ i ] . calculateNearby ( ) ;
398+ }
399+ } ;
400+
401+ const seedBoard = ( mines , grid ) => {
402+ let rejects = 0 ;
403+ for ( let i = 0 ; i < mines ; 0 ) {
404+ let mI = Math . floor ( Math . random ( ) * grid . length ) ;
405+
406+ if ( grid [ mI ] . count >= 0 && ! grid [ mI ] . reserved && ! grid [ mI ] . mine ) {
407+ grid [ mI ] . mine = true ;
408+ i ++ ;
409+ } else {
410+ rejects ++ ;
411+ continue ;
412+ }
413+
414+ if ( rejects >= mines * 5 ) break ;
415+ }
416+
417+ calculateNumbers ( grid ) ;
418+ } ;
0 commit comments