Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
17 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
938 changes: 930 additions & 8 deletions package-lock.json

Large diffs are not rendered by default.

5 changes: 5 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,11 @@
"private": true,
"homepage": "https://rocketacademy.github.io/high-card-bootcamp",
"dependencies": {
"@emotion/react": "^11.11.1",
"@emotion/styled": "^11.11.0",
"@fontsource/roboto": "^5.0.8",
"@mui/icons-material": "^5.14.14",
"@mui/material": "^5.14.14",
"gh-pages": "^3.2.3",
"react": "^18.1.0",
"react-dom": "^18.1.0",
Expand Down
11 changes: 10 additions & 1 deletion src/App.css
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
. {
font-family: "Roboto";
}

.App {
text-align: center;
}
Expand All @@ -12,8 +16,13 @@
min-height: 100vh;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
font-size: calc(10px + 2vmin);
color: white;
}

.card-hand {
display: flex;
flex-direction: row;
justify-content: space-around;
}
130 changes: 120 additions & 10 deletions src/App.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,14 @@
import React from "react";
import "./App.css";
import { makeShuffledDeck } from "./utils.js";
import PlayingCard from "./cardimages";
import "@fontsource/roboto/300.css";
import "@fontsource/roboto/400.css";
import "@fontsource/roboto/500.css";
import "@fontsource/roboto/700.css";
import Button from "@mui/material/Button";
import CasinoRoundedIcon from "@mui/icons-material/CasinoRounded";
import RocketLaunchRoundedIcon from "@mui/icons-material/RocketLaunchRounded";

class App extends React.Component {
constructor(props) {
Expand All @@ -11,14 +19,73 @@ class App extends React.Component {
cardDeck: makeShuffledDeck(),
// currCards holds the cards from the current round
currCards: [],
currComputerCards: [],
roundWinner: "",
score: [0, 0],
overallWinner: "",
roundsLeft: 26,
};
}

dealCards = () => {
// this.state.cardDeck.pop() modifies this.state.cardDeck array
const newCurrCards = [this.state.cardDeck.pop(), this.state.cardDeck.pop()];
const newCurrCards = [this.state.cardDeck.pop()];
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since it is just a single card, do we need an array? Also, does the variable need to be in plural?

const newComputerCurrCards = [this.state.cardDeck.pop()];
this.setState(
{
currCards: newCurrCards,
currComputerCards: newComputerCurrCards,
roundsLeft: this.state.roundsLeft - 1,
},
() => this.determineWinner()
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
() => this.determineWinner()
this.determineWinner

I think you should be able to just pass the function itself like so

);
if (this.state.cardDeck.length === 0) {
this.setState(() => this.determineOverallWinner());
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

determineOverallWinner() is already updating state. I think we don't need to call the function within a state update

}
};

determineWinner = () => {
const playerRank = this.state.currCards[0].rank;
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

could currCards be empty? If so, you could have an edge case bug here, trying to access .rank on undefined

const computerRank = this.state.currComputerCards[0].rank;
let playerScore = this.state.score[0];
let computerScore = this.state.score[1];
if (playerRank > computerRank) {
this.setState({
roundWinner: "Player",
score: [(playerScore += 1), computerScore],
});
} else if (playerRank === computerRank) {
this.setState({ roundWinner: "Draw" });
} else {
this.setState({
roundWinner: "Computer",
score: [playerScore, (computerScore += 1)],
});
}
};

determineOverallWinner = () => {
const playerFinalScore = this.state.score[0];
const computerFinalScore = this.state.score[1];

if (playerFinalScore > computerFinalScore) {
this.setState({ overallWinner: "Player wins" });
} else if (playerFinalScore === computerFinalScore) {
this.setState({ overallWinner: "It's a draw" });
} else {
this.setState({ overallWinner: "Computer wins" });
}
};

restartGame = () => {
this.setState({
currCards: newCurrCards,
cardDeck: makeShuffledDeck(),
currCards: [],
currComputerCards: [],
roundWinner: "",
score: [0, 0],
overallWinner: "",
roundsLeft: 26,
});
};

Expand All @@ -28,18 +95,61 @@ class App extends React.Component {
// You can access your current components state here, as indicated below
const currCardElems = this.state.currCards.map(({ name, suit }) => (
// Give each list element a unique key
<div key={`${name}${suit}`}>
{name} of {suit}
</div>
<>
<div key={`${name}${suit}`}>{/*{name} of {suit}*/}</div>
<div>
<PlayingCard value={name} suit={suit} />
</div>
</>
));

const currComputerCardElems = this.state.currComputerCards.map(
({ name, suit }) => (
// Give each list element a unique key
<>
<div key={`${name}${suit}`}>{/* {name} of {suit}*/}</div>
<div>
<PlayingCard value={name} suit={suit} />
</div>
</>
)
);
Comment on lines +98 to +115
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We repeat the same html here. Could this be a separate component, into which we pass the name and suit prop?

const currWinner = this.state.roundWinner;
const overallWinner = this.state.overallWinner;
return (
<div className="App">
<header className="App-header">
<h3>High Card 🚀</h3>
{currCardElems}
<br />
<button onClick={this.dealCards}>Deal</button>
<h3>
<CasinoRoundedIcon /> High Card <RocketLaunchRoundedIcon />
</h3>
{this.state.roundsLeft !== 26 && (
<div className="card-hand">
<p>Player Hand {currCardElems}</p>
<p>Computer Hand {currComputerCardElems}</p>
</div>
)}
{this.state.roundsLeft !== 26 && (
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

what is the 26? It seems to be some kind of game logic, but is not explained here. Maybe it would be better to pack it into a variable, say maxNumberOfRounds = 26 or whatever it represents. This would make it easier to read the code here as the variable would explain in English what it is used for or means.

<div className="winning-hand">
<p>Winner: {currWinner}</p>
<p>
Player score: {this.state.score[0]}
<br />
Computer score: {this.state.score[1]}
</p>
<p>Rounds Left: {this.state.roundsLeft}</p>
<p>{overallWinner}</p>
</div>
)}
<div>
{overallWinner ? (
<Button variant="contained" onClick={this.restartGame}>
Restart
</Button>
) : (
<Button variant="contained" onClick={this.dealCards}>
Deal
</Button>
)}
</div>
</header>
</div>
);
Expand Down
11 changes: 11 additions & 0 deletions src/cardimages.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import React from "react";

const PlayingCard = ({ value, suit }) => {
const cardImage = require(`./images/SVG-cards-1.3/${value}_of_${suit}.svg`);
return (
<div>
<img src={cardImage} alt={`${value}_of_${suit}`} />
</div>
);
};
export default PlayingCard;
Loading