Skip to content

Instantly share code, notes, and snippets.

@Zyst
Created May 6, 2016 06:52
Show Gist options
  • Save Zyst/0dcf43ffd31624bb793b4e75d5be36e6 to your computer and use it in GitHub Desktop.
Save Zyst/0dcf43ffd31624bb793b4e75d5be36e6 to your computer and use it in GitHub Desktop.
var StarsFrame = React.createClass({
render: function() {
let stars = [];
for (let i = 0; i < this.props.numberOfStars; i++) {
stars.push(
<span key={i} className="glyphicon glyphicon-star"></span>
);
}
return (
<div id="stars-frame">
<div className="well">
{stars}
</div>
</div>
);
}
});
var ButtonFrame = React.createClass({
render: function() {
let correct = this.props.correct;
let button;
let disabled = this.props.selectedNumbers.length === 0;
if (correct === true) {
button = (
<button
className="btn btn-success btn-lg"
onClick={this.props.acceptAnswer}
>
<span className="glyphicon glyphicon-ok"></span>
</button>
);
} else if (correct === false) {
button = (
<button
className="btn btn-danger btn-lg"
>
<span className="glyphicon glyphicon-remove"></span>
</button>
);
} else {
button = (
<button
className="btn btn-primary btn-lg"
disabled={disabled}
onClick={this.props.checkAnswer}
>
=
</button>
);
}
return (
<div id="button-frame">
{button}
<hr />
<button
className="btn btn-warning btn-xs"
onClick={this.props.redraw}
disabled={this.props.redraws === 0}
>
<span className="glyphicon glyphicon-refresh"></span>
{' '}
{this.props.redraws}
</button>
</div>
);
}
});
var AnswerFrame = React.createClass({
render: function() {
let numbers = this.props.selectedNumbers;
let props = this.props;
let display = numbers.map(function(number, index) {
return (
<span
key={index}
onClick={props.unselectNumber.bind(null, number)}
>
{number}
</span>
);
});
return (
<div id="answer-frame">
<div className="well">
{display}
</div>
</div>
);
}
});
var NumbersFrame = React.createClass({
render: function() {
let numbers = [];
for (let i = 1; i <= 9; i++) {
// If it's true class is 'numbers selected-true', or 'numbers selected-false' otherwise
let className = "number selected-" + (this.props.selectedNumbers.indexOf(i) >= 0);
className += " used-" + (this.props.usedNumbers.indexOf(i) >= 0);
numbers.push(
<div
className={className}
key={i}
onClick={this.props.clickNumber.bind(null, i)}
>
{i}
</div>
);
}
return (
<div id="numbers-frame">
<div className="well">
{numbers}
</div>
</div>
);
}
});
var DoneFrame = React.createClass({
render: function() {
return (
<div className="well text-center">
<h2>{this.props.doneStatus}</h2>
<button
className="btn btn-default"
onClick={this.props.resetGame}
>
Play again
</button>
</div>
);
}
});
var Game = React.createClass({
getInitialState: function() {
return {
selectedNumbers: [],
usedNumbers: [],
correct: null,
redraws: 5,
doneStatus: null,
numberOfStars: Math.floor(Math.random() * 9) + 1
};
},
resetGame: function() {
this.replaceState(this.getInitialState());
},
clickNumber: function(clickedNumber) {
if (this.state.selectedNumbers.indexOf(clickedNumber) < 0) {
this.setState(
{
selectedNumbers: this.state.selectedNumbers.concat(clickedNumber) ,
correct: null
}
);
}
},
unselectNumber: function(clickedNumber) {
let selectedNumbers = this.state.selectedNumbers;
let indexOfNumber = selectedNumbers.indexOf(clickedNumber);
selectedNumbers.splice(indexOfNumber, 1);
this.setState({ selectedNumbers: selectedNumbers, correct: null });
},
sumOfSelectedNumbers: function() {
return this.state.selectedNumbers.reduce(function(p, n) {
return p + n;
}, 0);
},
checkAnswer: function() {
let correct = this.state.numberOfStars === this.sumOfSelectedNumbers();
this.setState({ correct: correct });
},
acceptAnswer: function() {
let usedNumbers = this.state.usedNumbers.concat(this.state.selectedNumbers);
this.setState({
selectedNumbers: [],
usedNumbers: usedNumbers,
correct: null,
numberOfStars: Math.floor(Math.random() * 9) + 1
}, function() {
this.updateDoneStatus();
});
},
redraw: function() {
if (this.state.redraws > 0) {
this.setState({
numberOfStars: Math.floor(Math.random() * 9) + 1,
current: null,
selectedNumbers: [],
redraws: this.state.redraws - 1
}, function() {
this.updateDoneStatus();
});
}
},
possibleCombinationSum: function(arr, n) {
if (arr.indexOf(n) >= 0) { return true; }
if (arr[0] > n) { return false; }
if (arr[arr.length - 1] > n) {
arr.pop();
return possibleCombinationSum(arr, n);
}
var listSize = arr.length, combinationsCount = (1 << listSize)
for (var i = 1; i < combinationsCount ; i++ ) {
var combinationSum = 0;
for (var j=0 ; j < listSize ; j++) {
if (i & (1 << j)) { combinationSum += arr[j]; }
}
if (n === combinationSum) { return true; }
}
return false;
},
possibleSolutions: function() {
let numberOfStars = this.state.numberOfStars;
let possibleNumbers = [];
let usedNumbers = this.state.usedNumbers;
for (let i = 1; i <= 9; i++) {
if (usedNumbers.indexOf(i) < 0) {
possibleNumbers.push(i);
}
}
return this.possibleCombinationSum(possibleNumbers, numberOfStars);
},
updateDoneStatus: function() {
if (this.state.usedNumbers.length === 9) {
this.setState({ doneStatus: '♕ Victory! ♕' });
}
if (this.state.redraws === 0 && !this.possibleSolutions()) {
this.setState({ doneStatus: 'Game Over!' });
}
},
render: function() {
let bottomFrame;
if (this.state.doneStatus) {
bottomFrame = <DoneFrame
doneStatus={this.state.doneStatus}
resetGame={this.resetGame}
/>;
} else {
bottomFrame = <NumbersFrame
selectedNumbers={this.state.selectedNumbers}
usedNumbers={this.state.usedNumbers}
clickNumber={this.clickNumber}
/>;
}
return (
<div id="game">
<h2>Play Nine</h2>
<hr />
<div className="clearfix">
<StarsFrame numberOfStars={this.state.numberOfStars} />
<ButtonFrame selectedNumbers={this.state.selectedNumbers}
correct={this.state.correct}
checkAnswer={this.checkAnswer}
acceptAnswer={this.acceptAnswer}
redraw={this.redraw}
redraws={this.state.redraws} />
<AnswerFrame selectedNumbers={this.state.selectedNumbers}
unselectNumber={this.unselectNumber} />
</div>
{bottomFrame}
</div>
);
}
});
ReactDOM.render(
<Game />,
document.getElementById('core')
);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment