@@ -25,24 +25,57 @@ class Board {
2525 this . setMines ( mines ) ;
2626 }
2727
28+ getTotalCells ( ) {
29+ return this . rows * this . columns ;
30+ }
31+
2832 setMines ( mines ) {
2933 this . mines = 0 ;
3034 let minesCoordinates = [ ] ;
3135
3236 if ( Array . isArray ( mines ) ) {
3337 minesCoordinates = mines ;
3438 } else {
35- for ( let bomb = 0 ; bomb < parseInt ( mines ) ; bomb ++ ) {
36- const row = parseInt ( Math . random ( ) * this . rows ) ;
37- const col = parseInt ( Math . random ( ) * this . columns ) ;
38- // TODO: validate that the pair row, col never repeats
39- minesCoordinates . push ( [ col , row ] ) ;
39+ // Check if mines exceed the number of cells
40+ const minesCount = parseInt ( mines ) ;
41+
42+ if ( minesCount > this . getTotalCells ( ) ) {
43+ throw new Error ( `Number of mines ${ minesCount } is larger than the board ${ this . getTotalCells ( ) } ` ) ;
44+ }
45+
46+ // set bombs in order
47+ let row = 0 ;
48+ let col = 0 ;
49+ const minesMap = new Map ( ) ;
50+
51+ for ( let bomb = 0 ; bomb < minesCount ; bomb ++ ) {
52+ if ( ! this . getCell ( col , row ) ) {
53+ row = 0 ;
54+ col ++ ;
55+ }
56+
57+ minesMap . set ( `${ col } ,${ row ++ } ` , true ) ;
4058 }
59+
60+ // shuffle mines position
61+ const shuffledMines = new Map ( ) ;
62+
63+ for ( let coord of minesMap . keys ( ) ) {
64+ const r = parseInt ( Math . random ( ) * this . rows ) ;
65+ const c = parseInt ( Math . random ( ) * this . columns ) ;
66+
67+ shuffledMines . set ( `${ c } ,${ r } ` , true ) ;
68+ if ( minesMap . has ( `${ c } ,${ r } ` ) ) {
69+ shuffledMines . set ( coord , true ) ;
70+ }
71+ }
72+
73+ minesCoordinates = Array . from ( shuffledMines . keys ( ) ) . map ( ( v ) => v . split ( ',' ) ) ;
4174 }
4275
4376 minesCoordinates . forEach ( ( v ) => {
44- const col = v [ 0 ] ;
45- const row = v [ 1 ] ;
77+ const col = parseInt ( v [ 0 ] ) ;
78+ const row = parseInt ( v [ 1 ] ) ;
4679 const cell = this . getCell ( col , row ) ;
4780
4881 if ( ! cell ) return ;
0 commit comments