Skip to content

Commit

Permalink
make solving a puzzle easier, with hints as to what matches
Browse files Browse the repository at this point in the history
  • Loading branch information
ayan4m1 committed Jan 28, 2024
1 parent 3def1a5 commit 692aa6e
Show file tree
Hide file tree
Showing 6 changed files with 242 additions and 108 deletions.
31 changes: 8 additions & 23 deletions src/components/coloree/colorPicker.js
Original file line number Diff line number Diff line change
@@ -1,15 +1,8 @@
import PropTypes from 'prop-types';
import { Fragment, useRef, useEffect } from 'react';

const diameter = 400;
const radius = diameter / 2;

export default function ColorPicker({
colors,
colorChoices,
displayColor,
solving
}) {
export default function ColorPicker({ diameter, finalColor, pieColors }) {
const radius = diameter / 2;
const canvasRef = useRef();

useEffect(() => {
Expand All @@ -26,14 +19,7 @@ export default function ColorPicker({

let currentAngle = Math.PI / 2;

const renderColors = solving
? colors.map(({ pct }, index) => ({
color: colorChoices[index] ?? '#666',
pct
}))
: colors;

for (const { color, pct } of renderColors) {
for (const { color, pct } of pieColors) {
const angle = pct * Math.PI;

const path = new Path2D();
Expand Down Expand Up @@ -68,7 +54,7 @@ export default function ColorPicker({
ctx.resetTransform();
}
}
}, [colors, colorChoices, solving]);
}, [pieColors]);

return (
<Fragment>
Expand All @@ -89,16 +75,15 @@ export default function ColorPicker({
height: diameter,
width: radius,
borderRadius: `${radius}px`,
backgroundColor: displayColor
backgroundColor: finalColor
}}
/>
</Fragment>
);
}

ColorPicker.propTypes = {
colors: PropTypes.arrayOf(PropTypes.object).isRequired,
colorChoices: PropTypes.arrayOf(PropTypes.string),
displayColor: PropTypes.string.isRequired,
solving: PropTypes.bool.isRequired
diameter: PropTypes.number.isRequired,
pieColors: PropTypes.arrayOf(PropTypes.object).isRequired,
finalColor: PropTypes.string.isRequired
};
134 changes: 81 additions & 53 deletions src/components/coloree/colorSolver.js
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
import classNames from 'classnames';
import PropTypes from 'prop-types';
import { useMemo } from 'react';
import { faUndo } from '@fortawesome/free-solid-svg-icons';
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
import { Container, Row, Col, Button, Card } from 'react-bootstrap';
import { Container, Row, Col, Card, ProgressBar } from 'react-bootstrap';

import {
getColorSimilarity,
Expand All @@ -12,72 +11,101 @@ import {

export default function ColorSolver({
colors,
choices,
colorPalette,
onResetClick,
onColorChoiceAdd
currentGuess,
guessHistory,
onGuessAdd
}) {
const colorSimilarity = useMemo(
() =>
choices.length
? getColorSimilarity(
combineColors(combineColorChoices(colors, choices)),
combineColors(colors)
)
: 0,
[colors, choices]
const remainingGuesses = useMemo(
() => 5 - guessHistory.length,
[guessHistory]
);

return (
<Card body>
<Container>
<Row>
<Col xs={12}>
<h5 className="mb-3">Your Guess</h5>
<Col xs={8}>
<h5 className="mb-3">{remainingGuesses} Guesses Left</h5>
</Col>
<Col xs={4} className="d-flex align-items-center">
<ProgressBar
className="w-100"
variant="success"
min={0}
max={100}
now={(remainingGuesses / 5) * 100}
/>
</Col>
{colors.map((_, index) => (
<Col key={index} xs={2} className="d-flex justify-content-center">
<div
style={{
height: 32,
width: 32,
backgroundColor: choices[index] ?? 'white',
border: '2px solid black'
}}
/>
</Col>
))}
{choices.length === colors.length && (
<Col xs={2} className="d-flex align-items-center">
{colorSimilarity.toFixed(2)}%
</Col>
)}
{choices.length === colors.length && colorSimilarity < 100 && (
<Col xs={4}>
<Button variant="danger" onClick={onResetClick}>
<FontAwesomeIcon icon={faUndo} /> Reset
</Button>
</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"
>
<div
className={`color-solver-choice color-solver-choice--${type}`}
style={{
backgroundColor: color
}}
/>
</Col>
))}
<Col xs={2} className="my-2 d-flex align-items-center">
{getColorSimilarity(
combineColors(
combineColorChoices(
colors,
guess.map(({ color }) => color)
)
),
combineColors(colors)
).toFixed(2)}
%
</Col>
</Row>
))}
{remainingGuesses > 0 && (
<Row>
{colors.map((_, index) => (
<Col
key={index}
xs={2}
className="my-2 d-flex justify-content-center"
>
<div
className="color-solver-choice"
style={{
backgroundColor: currentGuess[index] ?? 'white'
}}
/>
</Col>
))}
</Row>
)}
<hr />
<Row>
<Col xs={12}>
<h5 className="mb-3">Color Palette</h5>
</Col>
{colorPalette.map((choice, index) => (
{colorPalette.map(({ color, eliminated }, index) => (
<Col
xs={2}
key={index}
className="my-2 d-flex justify-content-center"
>
<button
onClick={() => onColorChoiceAdd(choice)}
disabled={remainingGuesses === 0 || eliminated}
onClick={() => onGuessAdd(color)}
className={classNames(
'color-solver-choice',
eliminated && 'color-solver-choice--eliminated'
)}
style={{
height: 32,
width: 32,
backgroundColor: choice,
border: '2px solid black'
backgroundColor: color
}}
/>
</Col>
Expand All @@ -89,10 +117,10 @@ export default function ColorSolver({
}

ColorSolver.propTypes = {
colors: PropTypes.arrayOf(PropTypes.object),
choices: PropTypes.arrayOf(PropTypes.string),
colorSimilarity: PropTypes.number,
colorPalette: PropTypes.arrayOf(PropTypes.string),
onResetClick: PropTypes.func.isRequired,
onColorChoiceAdd: PropTypes.func.isRequired
colors: PropTypes.arrayOf(PropTypes.object).isRequired,
colorPalette: PropTypes.arrayOf(PropTypes.object).isRequired,
currentGuess: PropTypes.arrayOf(PropTypes.string).isRequired,
guessHistory: PropTypes.arrayOf(PropTypes.arrayOf(PropTypes.object))
.isRequired,
onGuessAdd: PropTypes.func.isRequired
};
54 changes: 54 additions & 0 deletions src/components/coloree/colorSolver.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
$choice-xs: 24px;
$choice-sm: $choice-xs * 1.25;
$choice-md: $choice-xs * 1.5;
$choice-lg: $choice-xs * 1.75;

.color-solver {
&-choice {
height: $choice-xs;
width: $choice-xs;
border: 2px solid black;
border-radius: 4px;

&--unused {
box-shadow: 0px 0px 4px 4px rgb(56, 54, 58);
}

&--wrongPlace {
box-shadow: 0px 0px 4px 4px rgb(220, 200, 45);
}

&--correctPlace {
box-shadow: 0px 0px 4px 4px rgba(68, 212, 57, 1);
}

&--eliminated {
opacity: 0.5;
background-image: linear-gradient(45deg, #ccc 0%, #666 100%);
}
}

@include media-breakpoint-up(sm) {
&-choice {
height: $choice-sm;
min-width: $choice-sm;
max-width: $choice-sm;
}
}

@include media-breakpoint-up(md) {
&-choice {
height: $choice-md;
min-width: $choice-md;
max-width: $choice-md;
}
}

@include media-breakpoint-up(lg) {
&-choice {
height: $choice-lg;
min-width: $choice-lg;
max-width: $choice-lg;
}
}
}
Loading

0 comments on commit 692aa6e

Please sign in to comment.