daily pastebin goal
37%
SHARE
TWEET

Untitled

a guest Jun 19th, 2017 46 Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. var possibleCombinationSum = function(arr, n) {
  2.   if (arr.indexOf(n) >= 0) { return true; }
  3.   if (arr[0] > n) { return false; }
  4.   if (arr[arr.length - 1] > n) {
  5.     arr.pop();
  6.     return possibleCombinationSum(arr, n);
  7.   }
  8.   var listSize = arr.length, combinationsCount = (1 << listSize)
  9.   for (var i = 1; i < combinationsCount ; i++ ) {
  10.     var combinationSum = 0;
  11.     for (var j=0 ; j < listSize ; j++) {
  12.       if (i & (1 << j)) { combinationSum += arr[j]; }
  13.     }
  14.     if (n === combinationSum) { return true; }
  15.   }
  16.   return false;
  17. };
  18.  
  19. const DoneFrame = (props) => {
  20.     return (
  21.     <div className="text-center">
  22.       <h2>{props.doneStatus}</h2>
  23.       <button className="btn btn-secondary" onClick={props.resetGame}>Play again</button>
  24.     </div>
  25.   );
  26. }
  27.  
  28. const Stars = (props) => {
  29.   return (
  30.     <div className="col-5">
  31.       {_.range(props.numberOfStars).map(i =>
  32.         <i key={i} className="fa fa-star"></i>
  33.       )}
  34.     </div>
  35.   );
  36. };
  37.  
  38. const Button = (props) => {
  39.     let button;
  40.   switch(props.answerIsCorrect) {
  41.     case true:
  42.         button =
  43.         <button className="btn btn-success" onClick={props.acceptAnswer} >
  44.           <i className="fa fa-check"></i>
  45.         </button>;      
  46.       break;
  47.     case false:
  48.         button =
  49.         <button className="btn btn-danger">
  50.           <i className="fa fa-times"></i>
  51.         </button>;      
  52.       break;
  53.     default:
  54.         button =
  55.         <button className="btn"
  56.                         onClick={props.checkAnswer}
  57.                         disabled={props.selectedNumbers.length === 0}>
  58.           =
  59.         </button>;      
  60.       break;
  61.   }
  62.   return (
  63.     <div className="col-2">
  64.       {button}
  65.       <br />
  66.       <br />
  67.       <button className="btn btn-sm btn-warning" onClick={props.redraw} disabled={props.redraws === 0}>
  68.         {props.redraws} <i className="fa fa-refresh"></i>
  69.       </button>
  70.     </div>
  71.   );
  72. };
  73.  
  74. const Answer = (props) => {
  75.   return (
  76.     <div className="col-5">
  77.       {props.selectedNumbers.map((number, i) =>
  78.         <span key={i} onClick={() => props.unselectNumber(number)}>
  79.             {number}
  80.         </span>
  81.       )}
  82.     </div>
  83.   );
  84. };
  85.  
  86. const Numbers = (props) => {
  87.     const numberClassName = (number) => {
  88.     if (props.usedNumbers.indexOf(number) >= 0) {
  89.         return 'used';
  90.     }  
  91.         if (props.selectedNumbers.indexOf(number) >= 0) {
  92.         return 'selected';
  93.     }  
  94.   };
  95.   return (
  96.     <div className="card text-center">
  97.       <div>
  98.         {Numbers.list.map((number, i) =>
  99.           <span key={i} className={numberClassName(number)}
  100.                     onClick={() => props.selectNumber(number)}>
  101.             {number}
  102.           </span>
  103.         )}
  104.       </div>
  105.     </div>
  106.   );
  107. };
  108.  
  109. Numbers.list = _.range(1, 10);
  110.  
  111. class Game extends React.Component {
  112.     static getRandNumOfStars = () => 1 + Math.floor(Math.random()*9);
  113.   static getInitialState = () => ({
  114.     selectedNumbers: [],
  115.     randomNumberOfStars: Game.getRandNumOfStars(),
  116.     answerIsCorrect: null,
  117.     usedNumbers: [],
  118.     redraws: 5,
  119.     doneStatus: null
  120.   });
  121.     state = Game.getInitialState();
  122.   selectNumber = (clickedNumber) => {
  123.     if (this.state.selectedNumbers.indexOf(clickedNumber) >= 0 || this.state.usedNumbers.indexOf(clickedNumber) >= 0) { return; }
  124.     this.setState(prevState => ({
  125.         answerIsCorrect: null,
  126.         selectedNumbers: prevState.selectedNumbers.concat(clickedNumber)
  127.     }));
  128.   };
  129.   unselectNumber = (clickedNumber) => {
  130.     this.setState(prevState => ({
  131.         answerIsCorrect: null,
  132.         selectedNumbers: prevState.selectedNumbers
  133.                                                         .filter(number => number !== clickedNumber)
  134.     }));
  135.   };
  136.   checkAnswer = () => {
  137.     this.setState(prevState => ({
  138.         answerIsCorrect: prevState.randomNumberOfStars ===
  139.         prevState.selectedNumbers.reduce((acc, n) => acc + n, 0)
  140.     }));
  141.   };
  142.   acceptAnswer = () => {
  143.     this.setState(prevState => ({
  144.         answerIsCorrect: null,
  145.       usedNumbers: prevState.usedNumbers.concat(prevState.selectedNumbers),
  146.       selectedNumbers: [],
  147.       randomNumberOfStars: Game.getRandNumOfStars()
  148.     }), this.updateDoneStatus);
  149.   };
  150.   redraw = () => {
  151.     if (this.state.redraws === 0) { return; }
  152.     this.setState(prevState => ({
  153.         randomNumberOfStars: Game.getRandNumOfStars(),
  154.       answerIsCorrect: null,
  155.       selectedNumbers: [],
  156.       redraws: prevState.redraws - 1
  157.     }), this.updateDoneStatus);
  158.   };
  159.   possibleSolutions = ({usedNumbers, randomNumberOfStars}) => {
  160.     const possibleNumbers = _.range(1, 10).filter(num => usedNumbers.indexOf(num) === -1);
  161.    
  162.     return possibleCombinationSum(possibleNumbers, randomNumberOfStars);
  163.   }
  164.   updateDoneStatus = () => {
  165.     this.setState(prevState => {
  166.         if (prevState.usedNumbers.length === 9) {
  167.         return { doneStatus: 'You won the game!' };
  168.       }
  169.       if (prevState.redraws === 0 && !this.possibleSolutions(prevState)) {
  170.         return { doneStatus: 'You lost the game!' };
  171.       }
  172.     });
  173.   };
  174.   resetGame = () => {
  175.     this.setState(Game.getInitialState());
  176.   }
  177.  
  178.   render() {
  179.     const {
  180.       selectedNumbers,
  181.       randomNumberOfStars,
  182.       answerIsCorrect,
  183.       usedNumbers,
  184.       redraws,
  185.       doneStatus
  186.     } = this.state;
  187.    
  188.     return (
  189.       <div className="container">
  190.         <h3>Play Nine</h3>
  191.         <hr />
  192.         <div className="row">
  193.           <Stars numberOfStars={randomNumberOfStars} />
  194.           <Button selectedNumbers={selectedNumbers}
  195.                         checkAnswer={this.checkAnswer}
  196.                   answerIsCorrect={answerIsCorrect}
  197.                   acceptAnswer={this.acceptAnswer}
  198.                   redraw={this.redraw}
  199.                   redraws={redraws} />
  200.           <Answer selectedNumbers={selectedNumbers}
  201.                         unselectNumber={this.unselectNumber} />
  202.         </div>
  203.         <br />
  204.         {   doneStatus ?
  205.             <DoneFrame doneStatus={doneStatus} resetGame={this.resetGame} /> :
  206.             <Numbers selectedNumbers={selectedNumbers}
  207.                  usedNumbers={usedNumbers}
  208.                          selectNumber={this.selectNumber} />
  209.        }
  210.       </div>
  211.     );
  212.   }
  213. }
  214.  
  215. class App extends React.Component {
  216.   render() {
  217.     return (
  218.       <div>
  219.         <Game />
  220.       </div>
  221.     );
  222.   }
  223. }
  224.  
  225.  
  226.  
  227. ReactDOM.render(<App />, mountNode);
RAW Paste Data
Top