Last active
September 12, 2019 12:31
-
-
Save junjis0203/0910a106e7a8da2304f4fa648a6f9ed0 to your computer and use it in GitHub Desktop.
React implementation(alpha) for Mathematical Girls: The Secret Notebook (Bits and Binary), chapter 4
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<!DOCTYPE html> | |
<html> | |
<head> | |
<meta charset="UTF-8" /> | |
<style> | |
.board { | |
display: inline-block; | |
} | |
.stone-wrapper { | |
display: inline-block; | |
width: 80px; | |
height: 80px; | |
border: 1px solid #000; | |
} | |
.stone { | |
margin: 4px; | |
width: 72px; | |
height: 72px; | |
border-radius: 50%; | |
border: 1px solid #000; | |
} | |
.stone-black { | |
background: black; | |
} | |
.stone-white { | |
background: white; | |
} | |
.message { | |
text-align: center; | |
font-weight: bold; | |
} | |
</style> | |
<script src="https://unpkg.com/react@16/umd/react.development.js" crossorigin></script> | |
<script src="https://unpkg.com/react-dom@16/umd/react-dom.development.js" crossorigin></script> | |
<script src="https://unpkg.com/babel-standalone@6/babel.min.js"></script> | |
</head> | |
<body> | |
<div id="container"></div> | |
<script type="text/babel"> | |
class Stone extends React.Component { | |
constructor(props) { | |
super(props); | |
this.state = {toggle: false}; | |
} | |
render() { | |
let stoneClassNames = "stone"; | |
stoneClassNames += " "; | |
stoneClassNames += this.state.toggle ? "stone-black" : "stone-white"; | |
const handler = () => { | |
const newToggleState = !this.state.toggle; | |
this.setState({toggle: newToggleState}); | |
this.props.onClick(this.props.index, newToggleState); | |
}; | |
return ( | |
<div className={"stone-wrapper"}> | |
<div className={stoneClassNames} onClick={handler}> | |
</div> | |
</div> | |
); | |
} | |
} | |
const arrayEquals = (a, b) => { | |
if (a.length != b.length) { | |
return false; | |
} | |
for (let i = 0; i < a.length; i++) { | |
if (a[i] != b[i]) { | |
return false; | |
} | |
} | |
return true; | |
}; | |
class Game extends React.Component { | |
constructor(props) { | |
super(props); | |
this.stones = []; | |
for (let i = 0; i < this.props.number; i++) { | |
this.stones[i] = false; | |
} | |
this.history = []; | |
this.history.push(this.stones.slice()); | |
this.state = {error: false, fulltrip: false}; | |
} | |
checkGame() { | |
if (this.state.error) { | |
return; | |
} | |
if (this.history.find((h) => arrayEquals(h, this.stones))) { | |
this.setState({error: true}); | |
return; | |
} | |
this.history.push(this.stones.slice()); | |
if (this.history.length == 2 ** this.props.number) { | |
this.setState({fulltrip: true}); | |
} | |
}; | |
renderStones() { | |
const components = []; | |
const handler = (index, newToggleState) => { | |
this.stones[index] = newToggleState; | |
this.checkGame(); | |
}; | |
for (let i = 0; i < this.props.number; i++) { | |
components.push(<Stone key={i} index={i} onClick={handler} />) | |
} | |
return components; | |
} | |
renderMessage() { | |
const message = this.state.error ? "ERROR!" : (this.state.fulltrip ? "FULLTRIP!" : ""); | |
return ( | |
<span>{message}</span> | |
); | |
} | |
render() { | |
return ( | |
<div className={"board"}> | |
<div> | |
{this.renderStones()} | |
</div> | |
<div className={"message"}> | |
{this.renderMessage()} | |
</div> | |
</div> | |
); | |
} | |
} | |
const domContainer = document.querySelector('#container'); | |
ReactDOM.render(<Game number={3} />, domContainer); | |
</script> | |
</body> | |
</html> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment