Skip to main content
replaced http://codereview.stackexchange.com/ with https://codereview.stackexchange.com/
Source Link
Source Link
konijn
  • 34.4k
  • 5
  • 71
  • 267

Rock, Paper, Scissors, and the Revealing Module Pattern

After reviewing this approach: Rock-Paper-Scissors with the revealing module pattern

I decided to write an alternative where the Revealing Module Pattern is used for the UI, model, and controller.

I am open to all feedback from style to design.

// noprotect
var roshambo = (function() {
  
  var UI = ( function containedUI(){
  
    var output = document.getElementById( 'output' );
    
    function log( message ){
      output.innerHTML = message + '<br>' + output.innerHTML;
    }
    
    return { 
      log : log 
    }; 
    
  })();
  
  var model = ( function containedModel(){
  
      //'Rock: 1, Paper: 2, Scissors: 3'
      var gamesCount = 0,
          winsCount = 0,
          robotMove,
          DRAW = 0,
          LOSE = 1,
          WIN  = 2,
          ROCK = 1,
          PAPER = 2,
          SCISSORS = 3,
          moves = [ '', 'Rock', 'Paper', 'Scissors' ],
          results = [ 'Draw !', 'You lose !', 'You win !' ];
    
    function registerResult( result ){
      if ( result == WIN ){ 
        winsCount++;
      }
      gamesCount++;
    }
    
    function getStats(){
      return {
        gamesCount : gamesCount , winsCount : winsCount
      };
    }
    
    function generateRobotMove(){
      return Math.floor(Math.random() * 3) + 1;
    }
    
    function getMoveDescription( move ){
      return moves[move];
    }
    
    function getResultDescription( result ){
      return results[result];
    }
    
    function compareMoves(human, robot) {
      
      // Tie
      if (human == robot) {
        return DRAW;
      }

      // Robot wins
      if (robot == ROCK && human == SCISSORS || 
          robot == PAPER && human == ROCK || 
          robot == SCISSORS && human == PAPER) {
        return LOSE;
      }

      //In all other cases, the player wins
      return WIN;
    }
    
    return { 
      registerResult : registerResult,
      generateRobotMove : generateRobotMove,
      getMoveDescription : getMoveDescription,
      getResultDescription : getResultDescription,
      getStats : getStats,
      compareMoves : compareMoves,
      ROCK: ROCK,
      PAPER: PAPER,
      SCISSORS: SCISSORS
    }; 
    
  })();
  
  
  var controller = ( function containedController(doc){
  
    function play(){
      UI.log( 'Click on of the move buttons to play' );
    }
    
    function newGame( humanMove ){
      
      var robotMove = model.generateRobotMove();
      
      UI.log( 'You chose ' + model.getMoveDescription( humanMove ) );
      UI.log( 'The robot played ' + model.getMoveDescription( robotMove ) );

      var result = model.compareMoves(humanMove, robotMove);
      
      UI.log( model.getResultDescription( result ) );
      model.registerResult( result );
      
      var stats = model.getStats();
      var winStats = Math.round( stats.winsCount / stats.gamesCount * 100 , 2);
      UI.log( 'You won ' + winStats + '% of total games !' );
    }
    
    doc.getElementById('Rock').addEventListener("click" , function clickRock(){
      newGame( model.ROCK );
    });
    
    doc.getElementById('Paper').addEventListener("click" , function clickRock(){
      newGame( model.PAPER );
    });

    doc.getElementById('Scissors').addEventListener("click" , function clickRock(){
      newGame( model.SCISSORS );
    });

    return { 
      play : play 
    }; 
    
  })(document);

  // Display a message with total winrate from 0 to 100% (rounded)
  function privateAlertTotalResults() {
    var results = Math.floor((privateGameDB / privateGameCount) * 100);
    UI.log('You won ' + results + '% of total games !');
  }

  // The only function available to the caller is the play function
  return {
    play: controller.play
  };

})();

// Init a game
roshambo.play();
<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width">
  <title>JS Bin</title>
</head>
<body>

<button id="Rock">Rock</button>
<button id="Paper">Paper</button>
<button id="Scissors">Scissors</button>
  
<div id="output">
  
</div>
  


  
  
  
</body>
</html>