Created
January 17, 2018 22:08
-
-
Save KeyFramesOfVi/5b156bb8ccfde6bbc2fa5f79a05fb7b5 to your computer and use it in GitHub Desktop.
mario3_concentration implementation in React
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
import React, { Component } from 'react'; | |
import './game.css'; | |
import Game from './Game'; | |
require('typeface-press-start-2p'); | |
function App(props) { | |
return ( | |
<Game | |
flipFirst={props.flipFirst} | |
flipSecond={props.flipSecond} | |
reset={props.reset} | |
cards={props.cards} | |
attempts={props.attempts} | |
bestScore={props.bestScore} | |
/> | |
); | |
} | |
export default App; |
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
import React, { Component } from 'react'; | |
import App from './App'; | |
const range = (n) => { | |
const result = []; | |
for (let i = 0; i < n; i += 1) { | |
result.push(i); | |
} | |
return result; | |
}; | |
const createCard = (label, index) => ({ | |
inPlay: false, | |
label, | |
index, | |
isMatched: false, | |
}); | |
const createDeck = (n) => { | |
const labelArray = ['coins10', 'coins10', 'coins20', 'coins20', 'freeGuy', 'freeGuy', | |
'mushroom', 'mushroom', 'mushroom', 'mushroom', 'flower', 'flower', | |
'flower', 'flower', 'star', 'star', 'star', 'star']; | |
let labelSize = n; | |
let i; | |
let temp; | |
while (labelSize) { | |
i = Math.floor(Math.random() * labelSize); | |
labelSize -= 1; | |
temp = labelArray[labelSize]; | |
labelArray[labelSize] = labelArray[i]; | |
labelArray[i] = temp; | |
} | |
return range(n).map((index) => ( | |
createCard(labelArray[index], index) | |
)); | |
} | |
class AppContainer extends Component { | |
constructor(props) { | |
super(props); | |
this.state = { | |
cards: createDeck(18), | |
attempts: 0, | |
bestScore: null, | |
}; | |
this.flipFirst = this.flipFirst.bind(this); | |
this.flipSecond = this.flipSecond.bind(this); | |
this.randomizeDeck = this.randomizeDeck.bind(this); | |
this.reset = this.reset.bind(this); | |
} | |
randomizeDeck() { | |
const cards = this.state.cards; | |
let n = cards.length; | |
let i; | |
let temp; | |
while (n) { | |
i = Math.floor(Math.random() * n); | |
n -= 1; | |
temp = cards[n]; | |
cards[n] = cards[i]; | |
cards[i] = temp; | |
cards[n].index = n; | |
cards[i].index = i; | |
} | |
this.setState({ | |
cards: cards, | |
}); | |
} | |
reset() { | |
this.setState({ | |
cards: this.state.cards.map((card, index) => ( | |
{ ...card, inPlay: false, isMatched: false } | |
)), | |
attempts: 0, | |
}); | |
setTimeout(() => { | |
this.randomizeDeck(); | |
}, 500); | |
} | |
flipFirst(index) { | |
this.setState({ | |
cards: this.state.cards.map((card) => { | |
if (index === card.index) { | |
// return Object.assign({}, card, { inPlay: true} ); | |
return { ...card, inPlay: true }; | |
} | |
return card; | |
}), | |
attempts: this.state.attempts + 1, | |
}); | |
} | |
flipSecond(index) { | |
this.setState({ | |
cards: this.state.cards.map((card) => { | |
if (index === card.index) { | |
// return Object.assign({}, card, { inPlay: true} ); | |
if (typeof window.Audio === "function") { | |
const audio = new Audio('./assets/audio/match.wav'); | |
console.log(audio); | |
audio.play(); | |
} | |
return { ...card, inPlay: true }; | |
} | |
return card; | |
}), | |
}); | |
setTimeout(() => { | |
this.checkMatch(); | |
}, 700); | |
} | |
checkMatch() { | |
if (this.isWinner()) { | |
const cards = this.state.cards.map((card) => { | |
return { ...card, inPlay: false, isMatched: card.inPlay ? true : card.isMatched } | |
}); | |
this.setState({ | |
cards, | |
bestScore: this.calculateBestScore(cards) | |
}) | |
} else { | |
this.setState({ | |
cards: this.state.cards.map((card) => { | |
return { ...card, inPlay: false } | |
}) | |
}) | |
} | |
} | |
calculateBestScore(cards) { | |
if (cards.filter((card) => ( | |
card.isMatched | |
)).length === cards.length | |
) { | |
return typeof this.state.bestScore === 'number' ? | |
Math.min(this.state.bestScore, this.state.attempts) : | |
this.state.attempts; | |
} else { | |
return this.state.bestScore; | |
} | |
} | |
isWinner() { | |
const flippedCards = this.state.cards.filter((card) => ( | |
card.inPlay | |
)); | |
return flippedCards[0].label === flippedCards[1].label; | |
} | |
render() { | |
return ( | |
<App | |
flipFirst={this.flipFirst} | |
flipSecond={this.flipSecond} | |
reset={this.reset} | |
cards={this.state.cards} | |
attempts={this.state.attempts} | |
bestScore={this.state.bestScore} | |
/> | |
); | |
} | |
} | |
function checkMatch(card_one, card_two) { | |
return card_one.label === card_two.label; | |
} | |
export default AppContainer; |
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
import React, { Component } from 'react'; | |
import Card from './Card'; | |
class Board extends Component { | |
render() { | |
const flippedCardCount = this.props.cards.filter((card) => ( | |
card.inPlay | |
)).length; | |
const matchedCardCount = this.props.cards.filter((card) => ( | |
card.isMatched | |
)).length; | |
return ( | |
<div> | |
{ | |
this.props.cards.map((card) => { | |
return ( | |
<div className="card-wrapper" key={card.index}> | |
<Card | |
inPlay={card.inPlay} | |
isMatched={card.isMatched} | |
label={card.label} | |
flipFirst={this.props.flipFirst} | |
flipSecond={this.props.flipSecond} | |
index={card.index} | |
flippedCardCount={flippedCardCount} | |
matchedCardCount={matchedCardCount} | |
totalCardCount={this.props.cards.length} | |
/> | |
</div> | |
); | |
}) | |
} | |
</div> | |
); | |
} | |
} | |
export default Board; |
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
import React, { Component } from 'react'; | |
class Card extends Component { | |
constructor(props) { | |
super(props); | |
this.onClick = this.onClick.bind(this); | |
} | |
onClick(e) { | |
if (this.props.matchedCardCount === this.props.totalCardCount) { | |
return; | |
} else if (this.props.inPlay || this.props.isMatched) { | |
return; | |
} else if (this.props.flippedCardCount === 0) { | |
this.props.flipFirst(this.props.index); | |
} else if (this.props.flippedCardCount === 1) { | |
this.props.flipSecond(this.props.index); | |
} | |
} | |
render() { | |
return ( | |
<div className={this.props.inPlay || this.props.isMatched ? "card flipped" : "card"} onClick={this.onClick}> | |
<div className="top"> </div> | |
<div className={"bottom " + this.props.label}> </div> | |
</div> | |
); | |
} | |
} | |
export default Card; |
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
import React, { Component } from 'react'; | |
import Menu from './Menu'; | |
import Board from './Board'; | |
function Game(props) { | |
return ( | |
<div className="container"> | |
<Menu attempts={props.attempts} | |
bestScore={props.bestScore} | |
reset={props.reset} | |
/> | |
<Board cards={props.cards} | |
flipFirst={props.flipFirst} | |
flipSecond={props.flipSecond} | |
/> | |
</div> | |
); | |
} | |
export default Game; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment