| 12
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
 100
 101
 102
 103
 104
 105
 106
 107
 108
 109
 110
 111
 112
 113
 114
 115
 116
 117
 118
 119
 120
 121
 122
 123
 124
 125
 126
 127
 128
 129
 130
 131
 132
 133
 134
 135
 136
 137
 138
 139
 140
 141
 142
 143
 144
 145
 146
 147
 148
 149
 150
 151
 152
 153
 154
 155
 156
 157
 158
 159
 160
 161
 162
 163
 164
 165
 166
 167
 168
 169
 170
 171
 172
 
 |  
'use strict';
 
const GRID_SIZE = 5;
const NUMBER_FO_MINES = 2;
 
const gameEnds = {
  win: 1,
  lose: 2,
};
 
function Cell(displayableValue) {
  this.isVisible = false;
  this.isFlaged = false;
  this.displayableValue = displayableValue;
}
 
Cell.prototype.toString = function() {
  if (this.isVisible) {
    return this.displayableValue;
  } else if (this.isFlaged) {
    return '⚐';
  } else {
    return '🀆';
  }
};
 
function Mine() {
  Cell.call(this, '💣');
}
 
Mine.prototype = Object.create(Cell.prototype);
Mine.prototype.constructor = Mine;
 
function Num(value) {
  Cell.call(this, value);
  this.value = value;
}
 
Num.prototype = Object.create(Cell.prototype);
Num.prototype.constructor = Num;
 
//Construteur
function Demineur() {
  this.gameEnd = 0;
 
  this.grid = [
    [0, 1, 1, 1, 0],
    [0, 2, -1, 2, 0],
    [0, 2, -1, 2, 0],
    [0, 1, 1, 1, 0],
    [0, 0, 0, 0, 0]
  ].map((row) =>
    row.map((nb) =>
      nb === -1 ? new Mine() : new Num(nb)));
}
 
//Methode display
Demineur.prototype.display = function () {
 
  //Pour chaque lignes
  this.grid.forEach((row) => {
 
    //On récupère les valeurs affichables de chaque cellules,
    //et on les join pour que ce soit plus joli
    //join(' ') ici transforme [1, 2, 3] en '1 2 3'
    var displayableRow = row
      .map((cell) => cell.toString())
      .join(' ');
 
    // let displayableRow = '';
    // row.forEach((cell) => displayableRow += cell.toString() + ' ')
 
    console.log(displayableRow);
  });
 
  //empty row
  console.log();
};
 
//Methode flag
Demineur.prototype.flag = function (x, y) {
 
  // Cette condition empèche de poser un drapeau qi le jeu est remriné (gagné ou perdu) !
  if (this.gameEnd !== 0) {
    return;
  }
 
  let cell = this.grid[x][y];
 
  if (cell.isVisible) {
    console.log('Action impossible, cellule déjà révélée');
  } else {
    cell.isFlaged = !cell.isFlaged;
  }
}
 
function revealCells(grid, x, y) {
 
  if (x >= 0 && y >= 0 && x < GRID_SIZE && y < GRID_SIZE && !grid[x][y].isVisible) {
    let cell = grid[x][y];
    cell.isVisible = true;
 
    //Si cette case contient un 0, je vais afficher les cases adjacentes
    if (cell instanceof Num && cell.value === 0) {
      let xs = [x, x - 1, x + 1]; //Les coordonées X des cases adjacentes
      let ys = [y, y - 1, y + 1]; //Les coordonées Y des cases adjacentes
 
      //Avec 2 for on combine nos deux tableaux
      for (let i of xs) {
        for (let j of ys) {
          //On appel la fonction click sur toutes nos cases adjacentes
          revealCells(grid, i, j);
 
          //Note : ici on appel aussi click sur la case courante car ça simplifie l'algo
          //Ce n'est pas gênant cet appel ne passera pas la première condition du
          //!this.gridIsVisible[x][y]
        }
      }
 
      // for(let i = x-1;i <= x+1; ++i) {}
    }
  }
}
 
//Methode click
Demineur.prototype.click = function (x, y) {
 
  // Cette condition empèche les click une fois le jeu perdu ou gagné !
  if (this.gameEnd !== 0) {
    return;
  }
 
  //Si la partie n'est pas finie
  //Si les coordonées sont valides (dans la grille)
  //et si la case n'est pas déjà visible (cette condition évite la récusion infinie)
  if (x >= 0 && y >= 0 && x < GRID_SIZE && y < GRID_SIZE && !this.grid[x][y].isVisible) {
    if (this.grid[x][y].isFlaged) {
      return console.log('Action impossible, cette cellule a un flag');
    }
 
    revealCells(this.grid, x, y);
 
    //On regarde si on a gagnés
    if (this.grid[x][y] instanceof Mine) { // Si c'est une mine
      this.gameEnd = gameEnds.lose;
    } else { //Si ce n'est pas une mine
 
      //on regarde si toutes les cases non mines ont été révélées
      var nbVisibleCells = this.grid.reduce((res, row) => {
        return row.reduce((res2, cell) => res2 + (cell.isVisible ? 1 : 0), res);
      }, 0);
 
      // let res = 0;
      // for (let row of this.grid) {
      //   for (let cell of row) {
      //     if (cell.isVisible) {
      //       res += 1;
      //     }
      //   }
      // }
 
      //Si le nombre de cases visibles est égale au nombre de cases de la grille moins le nombre de mines
      if (nbVisibleCells === GRID_SIZE * GRID_SIZE - NUMBER_FO_MINES) {
        this.gameEnd = gameEnds.win;
      }
    }
  }
};
 
//On expose la classe Demineur à require
export { Demineur, gameEnds }; | 
Partager