components: refactor, prepare for Answer component
This commit is contained in:
parent
d2333a4267
commit
07f283f00e
@ -7,3 +7,7 @@
|
||||
grid-column-gap: 0;
|
||||
grid-row-gap: 0;
|
||||
}
|
||||
|
||||
.Answer {
|
||||
font-size: smaller;
|
||||
}
|
||||
|
@ -10,14 +10,14 @@ export type Point = {
|
||||
y: number;
|
||||
}
|
||||
|
||||
export type Bar = {
|
||||
export type Selection = {
|
||||
start: Point;
|
||||
end: Point;
|
||||
}
|
||||
|
||||
export type Solution = {
|
||||
bar: Bar;
|
||||
answer: string;
|
||||
selection: Selection;
|
||||
key: string;
|
||||
}
|
||||
|
||||
type Game = {
|
||||
@ -30,13 +30,16 @@ type Game = {
|
||||
|
||||
export default class App extends React.Component {
|
||||
private game: Game;
|
||||
private readonly answers: Array<JSX.Element>;
|
||||
|
||||
constructor(props: object) {
|
||||
super(props);
|
||||
|
||||
this.game = require(`../../constants/1.json`)
|
||||
this.answers = this.game.solutions.map(s => s.answer).map(k => <p>{k}</p>);
|
||||
}
|
||||
|
||||
renderAnswers(): Array<JSX.Element> {
|
||||
return this.game.solutions.map(s => s.key).map(k =>
|
||||
<p className="Answer">{k}</p>);
|
||||
}
|
||||
|
||||
render() {
|
||||
@ -60,7 +63,7 @@ export default class App extends React.Component {
|
||||
/>
|
||||
</div>
|
||||
<div style={{paddingLeft: '30px'}}>
|
||||
{this.answers}
|
||||
{this.renderAnswers()}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
|
@ -1,12 +1,12 @@
|
||||
import React from 'react';
|
||||
|
||||
import Line from '../Line/Line';
|
||||
import {Point, Bar, Solution} from "../App/App";
|
||||
import {Point, Selection, Solution} from "../App/App";
|
||||
|
||||
import './Board.scss';
|
||||
|
||||
type Answer = {
|
||||
bar: Bar;
|
||||
selection: Selection;
|
||||
isCorrect: boolean;
|
||||
}
|
||||
|
||||
@ -20,8 +20,8 @@ interface IBoardState {
|
||||
score: number;
|
||||
wasValidAnswer: boolean;
|
||||
wasSelecting: boolean;
|
||||
selections: Array<Answer>;
|
||||
bar: Bar;
|
||||
answers: Array<Answer>;
|
||||
selection: Selection;
|
||||
}
|
||||
|
||||
export default class Board extends React.Component<IBoardProps, IBoardState> {
|
||||
@ -29,18 +29,18 @@ export default class Board extends React.Component<IBoardProps, IBoardState> {
|
||||
constructor(props: IBoardProps) {
|
||||
super(props);
|
||||
|
||||
const selections = [...new Array(props.solutions.length)].map(() =>
|
||||
const answers = [...new Array(props.solutions.length)].map(() =>
|
||||
Object.assign({}, {
|
||||
bar: {start: {x: 0, y: 0}, end: {x: 0, y: 0}},
|
||||
selection: {start: {x: 0, y: 0}, end: {x: 0, y: 0}},
|
||||
isCorrect: false,
|
||||
}));
|
||||
|
||||
this.state = {
|
||||
answers,
|
||||
score: 0,
|
||||
selections,
|
||||
wasValidAnswer: false,
|
||||
wasSelecting: false,
|
||||
bar: {start: {x: 0, y: 0}, end: {x: 0, y: 0}},
|
||||
selection: {start: {x: 0, y: 0}, end: {x: 0, y: 0}},
|
||||
}
|
||||
}
|
||||
|
||||
@ -52,34 +52,35 @@ export default class Board extends React.Component<IBoardProps, IBoardState> {
|
||||
const [parse, str] = [JSON.parse, JSON.stringify];
|
||||
|
||||
let score = this.state.score;
|
||||
const selections: Array<Answer> = parse(str(this.state.selections));
|
||||
const s = selections.find(v => !v.isCorrect);
|
||||
const answers: Array<Answer> = parse(str(this.state.answers));
|
||||
const currAnswer: Answer | undefined = answers.find(v => !v.isCorrect);
|
||||
|
||||
// skip if there are no lines left or the mouse is moving but not selecting
|
||||
if (!s || (isMoving && !this.state.wasSelecting))
|
||||
if (!currAnswer || (isMoving && !this.state.wasSelecting))
|
||||
return;
|
||||
|
||||
const x = Math.abs(pos.x - this.state.bar.start.x);
|
||||
const y = Math.abs(pos.y - this.state.bar.start.y);
|
||||
const x = Math.abs(pos.x - this.state.selection.start.x);
|
||||
const y = Math.abs(pos.y - this.state.selection.start.y);
|
||||
const isValidMove = x === 0 || y === 0 || x === y;
|
||||
const isMouseDown = isSelecting && !this.state.wasSelecting;
|
||||
const isMouseUp = !isSelecting && this.state.wasSelecting && isValidMove;
|
||||
const start: Point = isMouseDown ? pos : this.state.bar.start;
|
||||
const bar: Bar = {start, end: pos};
|
||||
const start: Point = isMouseDown ? pos : this.state.selection.start;
|
||||
const selection: Selection = {start, end: pos};
|
||||
|
||||
if (isValidMove)
|
||||
s.bar = bar;
|
||||
currAnswer.selection = selection;
|
||||
|
||||
if (isMouseUp && this.state.wasValidAnswer)
|
||||
[s.isCorrect, score] = [true, score + 1];
|
||||
[currAnswer.isCorrect, score] = [true, score + 1];
|
||||
|
||||
const isValidSolution = this.props.solutions.some(v => str(v.bar) === str(s.bar));
|
||||
const wasAlreadySelected = this.state.selections.some(v => str(v.bar) === str(s.bar));
|
||||
const strBar: string = str(currAnswer.selection);
|
||||
const isValidSolution = this.props.solutions.some(v => str(v.selection) === strBar);
|
||||
const wasAlreadySelected = this.state.answers.some(v => str(v.selection) === strBar);
|
||||
const isValidAnswer = isValidSolution && !wasAlreadySelected;
|
||||
|
||||
this.setState({
|
||||
...this.state,
|
||||
score, bar, selections,
|
||||
score, selection, answers,
|
||||
wasValidAnswer: isValidAnswer,
|
||||
wasSelecting: isSelecting,
|
||||
});
|
||||
@ -110,7 +111,7 @@ export default class Board extends React.Component<IBoardProps, IBoardState> {
|
||||
return (
|
||||
<Line
|
||||
key={`Line${n}`}
|
||||
bar={s.bar}
|
||||
selection={s.selection}
|
||||
isCorrect={s.isCorrect}
|
||||
cellSize={this.props.cellSize}
|
||||
/>
|
||||
@ -118,12 +119,11 @@ export default class Board extends React.Component<IBoardProps, IBoardState> {
|
||||
}
|
||||
|
||||
render(): JSX.Element {
|
||||
let cells =
|
||||
this.props.cells.map((oy, y) =>
|
||||
let cells = this.props.cells.map((oy, y) =>
|
||||
oy.map((s, x) =>
|
||||
this.renderCell(s, {x, y})));
|
||||
|
||||
let lines = this.state.selections.map((s, n) =>
|
||||
let lines = this.state.answers.map((s, n) =>
|
||||
this.renderLine(s, n));
|
||||
|
||||
const gridTemplateColumns = `repeat(${this.props.cells.length}, ${this.props.cellSize}px)`;
|
||||
|
@ -1,6 +1,6 @@
|
||||
import React from 'react';
|
||||
|
||||
import {Bar} from '../App/App'
|
||||
import {Selection} from '../App/App'
|
||||
|
||||
import './Line.scss';
|
||||
|
||||
@ -17,7 +17,7 @@ enum Dir {
|
||||
}
|
||||
|
||||
interface ILineProps {
|
||||
bar: Bar;
|
||||
selection: Selection;
|
||||
cellSize: number;
|
||||
isCorrect: boolean;
|
||||
}
|
||||
@ -25,8 +25,8 @@ interface ILineProps {
|
||||
export default function Line(props: ILineProps): JSX.Element {
|
||||
const [m1, sqrt2] = [props.cellSize, Math.sqrt(2)];
|
||||
const [m2, m4, m8] = [m1 / 2, m1 / 4, m1 / 8];
|
||||
const [startX, endX] = [m1 * props.bar.start.x, m1 * props.bar.end.x];
|
||||
const [startY, endY] = [m1 * props.bar.start.y, m1 * props.bar.end.y];
|
||||
const [startX, endX] = [m1 * props.selection.start.x, m1 * props.selection.end.x];
|
||||
const [startY, endY] = [m1 * props.selection.start.y, m1 * props.selection.end.y];
|
||||
|
||||
const dir = (v: number) => v < 0 ? 2 : v > 0 ? 1 : 0;
|
||||
const d = Number(`${dir(startX-endX)}${dir(startY-endY)}`) as Dir;
|
||||
|
@ -18,29 +18,29 @@
|
||||
["K", "R", "Z", "T", "A", "L", "E", "R", "Z", "E", "W", "O", "B"]
|
||||
],
|
||||
"solutions": [
|
||||
{"bar": {"start": {"x": 3, "y": 0}, "end": {"x": 7, "y": 0}}, "answer": "PARYŻ"},
|
||||
{"bar": {"start": {"x": 4, "y": 8}, "end": {"x": 9, "y": 8}}, "answer": "DUBLIN"},
|
||||
{"bar": {"start": {"x": 8, "y": 9}, "end": {"x": 4, "y": 9}}, "answer": "PERŁA"},
|
||||
{"bar": {"start": {"x": 10, "y": 11}, "end": {"x": 2, "y": 11}}, "answer": "KOPENHAGA"},
|
||||
{"bar": {"start": {"x": 3, "y": 12}, "end": {"x": 9, "y": 12}}, "answer": "TALERZE"},
|
||||
{"bar": {"start": {"x": 0, "y": 3}, "end": {"x": 0, "y": 7}}, "answer": "KLAUN"},
|
||||
{"bar": {"start": {"x": 1, "y": 2}, "end": {"x": 1, "y": 8}}, "answer": "PLASTYK"},
|
||||
{"bar": {"start": {"x": 2, "y": 1}, "end": {"x": 2, "y": 9}}, "answer": "SZTOKHOLM"},
|
||||
{"bar": {"start": {"x": 4, "y": 2}, "end": {"x": 4, "y": 10}}, "answer": "AMSTERDAM"},
|
||||
{"bar": {"start": {"x": 10, "y": 3}, "end": {"x": 10, "y": 10}}, "answer": "AKROBATA"},
|
||||
{"bar": {"start": {"x": 11, "y": 9}, "end": {"x": 11, "y": 2}}, "answer": "TANCERKA"},
|
||||
{"bar": {"start": {"x": 12, "y": 3}, "end": {"x": 12, "y": 9}}, "answer": "TALLINN"},
|
||||
{"bar": {"start": {"x": 0, "y": 8}, "end": {"x": 4, "y": 12}}, "answer": "PRAGA"},
|
||||
{"bar": {"start": {"x": 5, "y": 10}, "end": {"x": 1, "y": 6}}, "answer": "FAGOT"},
|
||||
{"bar": {"start": {"x": 3, "y": 5}, "end": {"x": 8, "y": 10}}, "answer": "WERBEL"},
|
||||
{"bar": {"start": {"x": 7, "y": 7}, "end": {"x": 3, "y": 3}}, "answer": "MINSK"},
|
||||
{"bar": {"start": {"x": 3, "y": 1}, "end": {"x": 10, "y": 8}}, "answer": "WARSZAWA"},
|
||||
{"bar": {"start": {"x": 4, "y": 1}, "end": {"x": 9, "y": 6}}, "answer": "DIADEM"},
|
||||
{"bar": {"start": {"x": 4, "y": 0}, "end": {"x": 11, "y": 7}}, "answer": "AKORDEON"},
|
||||
{"bar": {"start": {"x": 12, "y": 4}, "end": {"x": 8, "y": 0}}, "answer": "AKTOR"},
|
||||
{"bar": {"start": {"x": 2, "y": 5}, "end": {"x": 6, "y": 1}}, "answer": "KOMIK"},
|
||||
{"bar": {"start": {"x": 1, "y": 8}, "end": {"x": 9, "y": 0}}, "answer": "KONTRABAS"},
|
||||
{"bar": {"start": {"x": 5, "y": 6}, "end": {"x": 10, "y": 1}}, "answer": "MADRYT"},
|
||||
{"bar": {"start": {"x": 10, "y": 3}, "end": {"x": 6, "y": 7}}, "answer": "ATENY"}
|
||||
{"selection": {"start": {"x": 3, "y": 0}, "end": {"x": 7, "y": 0}}, "key": "PARYŻ"},
|
||||
{"selection": {"start": {"x": 4, "y": 8}, "end": {"x": 9, "y": 8}}, "key": "DUBLIN"},
|
||||
{"selection": {"start": {"x": 8, "y": 9}, "end": {"x": 4, "y": 9}}, "key": "PERŁA"},
|
||||
{"selection": {"start": {"x": 10, "y": 11}, "end": {"x": 2, "y": 11}}, "key": "KOPENHAGA"},
|
||||
{"selection": {"start": {"x": 3, "y": 12}, "end": {"x": 9, "y": 12}}, "key": "TALERZE"},
|
||||
{"selection": {"start": {"x": 0, "y": 3}, "end": {"x": 0, "y": 7}}, "key": "KLAUN"},
|
||||
{"selection": {"start": {"x": 1, "y": 2}, "end": {"x": 1, "y": 8}}, "key": "PLASTYK"},
|
||||
{"selection": {"start": {"x": 2, "y": 1}, "end": {"x": 2, "y": 9}}, "key": "SZTOKHOLM"},
|
||||
{"selection": {"start": {"x": 4, "y": 2}, "end": {"x": 4, "y": 10}}, "key": "AMSTERDAM"},
|
||||
{"selection": {"start": {"x": 10, "y": 3}, "end": {"x": 10, "y": 10}}, "key": "AKROBATA"},
|
||||
{"selection": {"start": {"x": 11, "y": 9}, "end": {"x": 11, "y": 2}}, "key": "TANCERKA"},
|
||||
{"selection": {"start": {"x": 12, "y": 3}, "end": {"x": 12, "y": 9}}, "key": "TALLINN"},
|
||||
{"selection": {"start": {"x": 0, "y": 8}, "end": {"x": 4, "y": 12}}, "key": "PRAGA"},
|
||||
{"selection": {"start": {"x": 5, "y": 10}, "end": {"x": 1, "y": 6}}, "key": "FAGOT"},
|
||||
{"selection": {"start": {"x": 3, "y": 5}, "end": {"x": 8, "y": 10}}, "key": "WERBEL"},
|
||||
{"selection": {"start": {"x": 7, "y": 7}, "end": {"x": 3, "y": 3}}, "key": "MINSK"},
|
||||
{"selection": {"start": {"x": 3, "y": 1}, "end": {"x": 10, "y": 8}}, "key": "WARSZAWA"},
|
||||
{"selection": {"start": {"x": 4, "y": 1}, "end": {"x": 9, "y": 6}}, "key": "DIADEM"},
|
||||
{"selection": {"start": {"x": 4, "y": 0}, "end": {"x": 11, "y": 7}}, "key": "AKORDEON"},
|
||||
{"selection": {"start": {"x": 12, "y": 4}, "end": {"x": 8, "y": 0}}, "key": "AKTOR"},
|
||||
{"selection": {"start": {"x": 2, "y": 5}, "end": {"x": 6, "y": 1}}, "key": "KOMIK"},
|
||||
{"selection": {"start": {"x": 1, "y": 8}, "end": {"x": 9, "y": 0}}, "key": "KONTRABAS"},
|
||||
{"selection": {"start": {"x": 5, "y": 6}, "end": {"x": 10, "y": 1}}, "key": "MADRYT"},
|
||||
{"selection": {"start": {"x": 10, "y": 3}, "end": {"x": 6, "y": 7}}, "key": "ATENY"}
|
||||
]
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user