Skip to content

Commit

Permalink
refactor solverChoice box to its own component, clean up colorSolver JSX
Browse files Browse the repository at this point in the history
  • Loading branch information
ayan4m1 committed Jan 29, 2024
1 parent 8f00591 commit bf3f103
Show file tree
Hide file tree
Showing 4 changed files with 138 additions and 106 deletions.
129 changes: 50 additions & 79 deletions src/components/coloree/colorSolver.js
Original file line number Diff line number Diff line change
@@ -1,20 +1,25 @@
import classNames from 'classnames';
import { faUndo } from '@fortawesome/free-solid-svg-icons';
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
import PropTypes from 'prop-types';
import { useMemo } from 'react';
import { Container, Row, Col, Card, ProgressBar } from 'react-bootstrap';

import {
getColorSimilarity,
combineColorChoices,
combineColors
} from 'utils/coloree';
Container,
Row,
Col,
Card,
ProgressBar,
Button
} from 'react-bootstrap';

import SolverChoice from 'components/coloree/solverChoice';

export default function ColorSolver({
colors,
colorPalette,
currentGuess,
guessHistory,
onGuessAdd
onGuessAdd,
onGuessRemove
}) {
const remainingGuesses = useMemo(
() => 5 - guessHistory.length,
Expand All @@ -24,9 +29,9 @@ export default function ColorSolver({
return (
<Card body>
<Container>
<Row>
<Row className="mb-3">
<Col xs={8}>
<h5 className="mb-3">{remainingGuesses} Guesses Left</h5>
<h5 className="mb-0">{remainingGuesses} Guesses Left</h5>
</Col>
<Col xs={4} className="d-flex align-items-center">
<ProgressBar
Expand All @@ -38,66 +43,40 @@ export default function ColorSolver({
/>
</Col>
</Row>
{guessHistory.map((guess, guessIndex) => (
<Row key={guessIndex}>
{guess.map(({ color, type }, colorIndex) => (
<Col
xs={2}
key={colorIndex}
className="my-2 d-flex justify-content-center"
{guessHistory.map(
({ finalColor, colorSimilarity, guess }, guessIndex) => (
<Row key={guessIndex}>
{guess.map(({ color, type }, colorIndex) => (
<SolverChoice key={colorIndex} color={color} type={type} />
))}
<SolverChoice
color={finalColor}
style={{ width: 70, maxWidth: 70 }}
>
<div
className={`color-solver-choice color-solver-choice--${type}`}
style={{
backgroundColor: color
}}
/>
</Col>
))}
<Col xs={4} className="my-2 d-flex justify-content-center">
<div
className="d-flex color-solver-choice align-items-center justify-content-center"
style={{
maxWidth: 96,
width: 96,
backgroundColor: combineColors(
combineColorChoices(
colors,
guess.map(({ color }) => color)
)
)
}}
>
{getColorSimilarity(
combineColors(
combineColorChoices(
colors,
guess.map(({ color }) => color)
)
),
combineColors(colors)
).toFixed(1)}
%
</div>
</Col>
</Row>
))}
{colorSimilarity.toFixed(1)}%
</SolverChoice>
</Row>
)
)}
{remainingGuesses > 0 && (
<Row>
{colors.map((_, index) => (
<SolverChoice key={index} color={currentGuess[index]} />
))}
{Boolean(currentGuess.length) && (
<Col
key={index}
xs={2}
className="my-2 d-flex justify-content-center"
className="my-2 d-flex justify-content-center align-items-center"
>
<div
className="color-solver-choice"
style={{
backgroundColor: currentGuess[index] ?? 'white'
}}
/>
<Button
className="h-100"
variant="danger"
onClick={onGuessRemove}
>
<FontAwesomeIcon icon={faUndo} />
</Button>
</Col>
))}
)}
</Row>
)}
<hr />
Expand All @@ -106,23 +85,14 @@ export default function ColorSolver({
<h5 className="mb-3">Color Palette</h5>
</Col>
{colorPalette.map(({ color, eliminated }, index) => (
<Col
xs={2}
<SolverChoice
key={index}
className="my-2 d-flex justify-content-center"
>
<button
disabled={remainingGuesses === 0 || eliminated}
onClick={() => onGuessAdd(color)}
className={classNames(
'color-solver-choice',
eliminated && 'color-solver-choice--eliminated'
)}
style={{
backgroundColor: color
}}
/>
</Col>
color={color}
eliminated={eliminated}
disabled={remainingGuesses === 0 || eliminated}
onClick={() => onGuessAdd(color)}
button
/>
))}
</Row>
</Container>
Expand All @@ -136,5 +106,6 @@ ColorSolver.propTypes = {
currentGuess: PropTypes.arrayOf(PropTypes.string).isRequired,
guessHistory: PropTypes.arrayOf(PropTypes.arrayOf(PropTypes.object))
.isRequired,
onGuessAdd: PropTypes.func.isRequired
onGuessAdd: PropTypes.func.isRequired,
onGuessRemove: PropTypes.func.isRequired
};
3 changes: 3 additions & 0 deletions src/components/coloree/colorSolver.scss
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,13 @@ $choice-lg: $choice-xs * 1.75;

.color-solver {
&-choice {
display: flex;
height: $choice-xs;
width: $choice-xs;
border: 2px solid black;
border-radius: 4px;
align-items: center;
justify-content: center;

&--unused {
box-shadow: 0px 0px 4px 4px rgb(74, 32, 32);
Expand Down
69 changes: 42 additions & 27 deletions src/components/coloree/game.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,8 @@ import {
getRemainingPct,
createColorPalette,
combineColorChoices,
combineColors
combineColors,
getColorSimilarity
} from 'utils/coloree';

export default function ColoreeGame() {
Expand Down Expand Up @@ -62,39 +63,52 @@ export default function ColoreeGame() {
setSolved(true);
}

const finalColor = combineColors(combineColorChoices(colors, guess));

return [
...prevVal,
guess.map((color, index) => {
let type = 'unused';

const colorExists = colors.some(
({ color: testColor }) => testColor === color
);
const colorCorrectPlace = colors[index].color === color;

if (colorExists && !colorCorrectPlace) {
type = 'wrongPlace';
} else if (colorCorrectPlace) {
type = 'correctPlace';
}

if (type === 'unused') {
handleColorEliminate(
colorPalette.findIndex(
({ color: testColor }) => testColor === color
)
{
finalColor,
colorSimilarity: getColorSimilarity(
finalColor,
combineColors(colors)
),
guess: guess.map((color, index) => {
let type = 'unused';

const colorExists = colors.some(
({ color: testColor }) => testColor === color
);
}

return {
color,
type
};
})
const colorCorrectPlace = colors[index].color === color;

if (colorExists && !colorCorrectPlace) {
type = 'wrongPlace';
} else if (colorCorrectPlace) {
type = 'correctPlace';
}

if (type === 'unused') {
handleColorEliminate(
colorPalette.findIndex(
({ color: testColor }) => testColor === color
)
);
}

return {
color,
type
};
})
}
];
}),
[colors, colorPalette]
);
const handleGuessRemove = useCallback(
() => setCurrentGuess((prevVal) => prevVal.slice(0, prevVal.length - 1)),
[]
);
const handleGuessAdd = useCallback(
(color) =>
setCurrentGuess((prevVal) => {
Expand Down Expand Up @@ -172,6 +186,7 @@ export default function ColoreeGame() {
currentGuess={currentGuess}
guessHistory={guessHistory}
onGuessAdd={handleGuessAdd}
onGuessRemove={handleGuessRemove}
/>
)}
</Col>
Expand Down
43 changes: 43 additions & 0 deletions src/components/coloree/solverChoice.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
import classNames from 'classnames';
import PropTypes from 'prop-types';
import { Col } from 'react-bootstrap';

export default function SolverChoice({
type,
color = '#ffffff',
eliminated = false,
button = false,
children,
...props
}) {
const Element = (props) =>
button ? <button {...props} /> : <div {...props} />;

return (
<Col xs={2} className="my-2 d-flex justify-content-center">
<Element
{...props}
className={classNames(
'color-solver-choice',
eliminated && 'color-solver-choice--eliminated',
Boolean(type) && `color-solver-choice--${type}`
)}
style={{
...props.style,
backgroundColor: color
}}
>
{children}
</Element>
</Col>
);
}

SolverChoice.propTypes = {
type: PropTypes.string,
color: PropTypes.string,
eliminated: PropTypes.bool,
button: PropTypes.bool,
children: PropTypes.node,
style: PropTypes.object
};

0 comments on commit bf3f103

Please sign in to comment.