components: move state up to App, prepare for new comp
This commit is contained in:
parent
db77874786
commit
1dc334f41b
@ -5,22 +5,64 @@ import Board from '../Board/Board';
|
|||||||
|
|
||||||
import './App.scss';
|
import './App.scss';
|
||||||
|
|
||||||
export default function App(): JSX.Element {
|
export type Point = {
|
||||||
|
x: number;
|
||||||
|
y: number;
|
||||||
|
}
|
||||||
|
|
||||||
|
export type Bar = {
|
||||||
|
start: Point;
|
||||||
|
end: Point;
|
||||||
|
}
|
||||||
|
|
||||||
|
export type Solution = {
|
||||||
|
bar: Bar;
|
||||||
|
answer: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
type Game = {
|
||||||
|
title: string;
|
||||||
|
description: string;
|
||||||
|
catchword: string;
|
||||||
|
cells: Array<Array<string>>;
|
||||||
|
solutions: Array<Solution>;
|
||||||
|
}
|
||||||
|
|
||||||
|
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>);
|
||||||
|
}
|
||||||
|
|
||||||
|
render() {
|
||||||
return (
|
return (
|
||||||
<div className="App">
|
<div className="App">
|
||||||
<div />
|
<div />
|
||||||
<div>
|
<div>
|
||||||
<Logo />
|
<Logo />
|
||||||
<div>
|
<div>
|
||||||
controls: 1231414214
|
<p>{this.game.title}</p>
|
||||||
|
<p>{this.game.description}</p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div />
|
<div />
|
||||||
<div />
|
<div />
|
||||||
<div>
|
<div>
|
||||||
<Board numBoard={1}/>
|
<Board
|
||||||
|
cells={this.game.cells}
|
||||||
|
solutions={this.game.solutions}
|
||||||
|
cellSize={60}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div style={{paddingLeft: '30px'}}>
|
||||||
|
{this.answers}
|
||||||
</div>
|
</div>
|
||||||
<div />
|
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
@ -1,66 +1,44 @@
|
|||||||
import React from 'react';
|
import React from 'react';
|
||||||
|
|
||||||
import Line from '../Line/Line';
|
import Line from '../Line/Line';
|
||||||
|
import {Point, Bar, Solution} from "../App/App";
|
||||||
|
|
||||||
import './Board.scss';
|
import './Board.scss';
|
||||||
|
|
||||||
type Point = {
|
type Answer = {
|
||||||
x: number;
|
|
||||||
y: number;
|
|
||||||
}
|
|
||||||
|
|
||||||
export type Bar = {
|
|
||||||
start: Point,
|
|
||||||
end: Point,
|
|
||||||
}
|
|
||||||
|
|
||||||
type Solution = {
|
|
||||||
bar: Bar;
|
bar: Bar;
|
||||||
key: string;
|
|
||||||
}
|
|
||||||
|
|
||||||
type Selection = {
|
|
||||||
bar: Bar,
|
|
||||||
isVisible: boolean;
|
|
||||||
isCorrect: boolean;
|
isCorrect: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
interface IBoardProps {
|
interface IBoardProps {
|
||||||
numBoard: number;
|
cells: Array<Array<string>>;
|
||||||
|
solutions: Array<Solution>;
|
||||||
|
cellSize: number;
|
||||||
}
|
}
|
||||||
|
|
||||||
interface IBoardState {
|
interface IBoardState {
|
||||||
score: number;
|
score: number;
|
||||||
wasValid: boolean;
|
wasValidAnswer: boolean;
|
||||||
wasSelecting: boolean;
|
wasSelecting: boolean;
|
||||||
selections: Array<Selection>;
|
selections: Array<Answer>;
|
||||||
bar: Bar;
|
bar: Bar;
|
||||||
}
|
}
|
||||||
|
|
||||||
export default class Board extends React.Component<IBoardProps, IBoardState> {
|
export default class Board extends React.Component<IBoardProps, IBoardState> {
|
||||||
private readonly cells: Array<Array<string>>;
|
|
||||||
private readonly solutions: Array<Solution>;
|
|
||||||
private readonly cellSize: number;
|
|
||||||
|
|
||||||
constructor(props: IBoardProps) {
|
constructor(props: IBoardProps) {
|
||||||
super(props);
|
super(props);
|
||||||
|
|
||||||
const crosski: any = require(`../../constants/${props.numBoard}.json`)
|
const selections = [...new Array(props.solutions.length)].map(() =>
|
||||||
this.cells = crosski.cells;
|
|
||||||
this.solutions = crosski.solutions;
|
|
||||||
this.cellSize = 60;
|
|
||||||
|
|
||||||
const selections = [...new Array(this.solutions.length)].map(() =>
|
|
||||||
Object.assign({}, {
|
Object.assign({}, {
|
||||||
bar: {start: {x: 0, y: 0}, end: {x: 0, y: 0}},
|
bar: {start: {x: 0, y: 0}, end: {x: 0, y: 0}},
|
||||||
isCorrect: false,
|
isCorrect: false,
|
||||||
isVisible: true,
|
|
||||||
}));
|
}));
|
||||||
|
|
||||||
this.state = {
|
this.state = {
|
||||||
score: 0,
|
score: 0,
|
||||||
selections,
|
selections,
|
||||||
wasValid: false,
|
wasValidAnswer: false,
|
||||||
wasSelecting: false,
|
wasSelecting: false,
|
||||||
bar: {start: {x: 0, y: 0}, end: {x: 0, y: 0}},
|
bar: {start: {x: 0, y: 0}, end: {x: 0, y: 0}},
|
||||||
}
|
}
|
||||||
@ -74,7 +52,7 @@ export default class Board extends React.Component<IBoardProps, IBoardState> {
|
|||||||
const [parse, str] = [JSON.parse, JSON.stringify];
|
const [parse, str] = [JSON.parse, JSON.stringify];
|
||||||
|
|
||||||
let score = this.state.score;
|
let score = this.state.score;
|
||||||
const selections: Array<Selection> = parse(str(this.state.selections));
|
const selections: Array<Answer> = parse(str(this.state.selections));
|
||||||
const s = selections.find(v => !v.isCorrect);
|
const s = selections.find(v => !v.isCorrect);
|
||||||
|
|
||||||
// skip if there are no lines left or the mouse is moving but not selecting
|
// skip if there are no lines left or the mouse is moving but not selecting
|
||||||
@ -86,32 +64,33 @@ export default class Board extends React.Component<IBoardProps, IBoardState> {
|
|||||||
const isValidMove = x === 0 || y === 0 || x === y;
|
const isValidMove = x === 0 || y === 0 || x === y;
|
||||||
const isMouseDown = isSelecting && !this.state.wasSelecting;
|
const isMouseDown = isSelecting && !this.state.wasSelecting;
|
||||||
const isMouseUp = !isSelecting && this.state.wasSelecting && isValidMove;
|
const isMouseUp = !isSelecting && this.state.wasSelecting && isValidMove;
|
||||||
const isValidSolution = this.solutions.some(v => str(v.bar) === str(s.bar));
|
|
||||||
const wasAlreadySelected = this.state.selections.some(v => str(v.bar) === str(s.bar));
|
|
||||||
const isValid = isValidSolution && !wasAlreadySelected;
|
|
||||||
const start: Point = isMouseDown ? pos : this.state.bar.start;
|
const start: Point = isMouseDown ? pos : this.state.bar.start;
|
||||||
const bar: Bar = {start, end: pos};
|
const bar: Bar = {start, end: pos};
|
||||||
|
|
||||||
if (isValidMove)
|
if (isValidMove)
|
||||||
s.bar = bar;
|
s.bar = bar;
|
||||||
|
|
||||||
if (isMouseUp && this.state.wasValid)
|
if (isMouseUp && this.state.wasValidAnswer)
|
||||||
[s.isCorrect, score] = [true, score + 1];
|
[s.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 isValidAnswer = isValidSolution && !wasAlreadySelected;
|
||||||
|
|
||||||
this.setState({
|
this.setState({
|
||||||
...this.state,
|
...this.state,
|
||||||
score, bar, selections,
|
score, bar, selections,
|
||||||
wasValid: isValid,
|
wasValidAnswer: isValidAnswer,
|
||||||
wasSelecting: isSelecting
|
wasSelecting: isSelecting,
|
||||||
});
|
});
|
||||||
|
|
||||||
if (score === this.solutions.length)
|
if (score === this.props.solutions.length)
|
||||||
this.gameOver();
|
this.gameOver();
|
||||||
}
|
}
|
||||||
|
|
||||||
renderCell(s: string, pos: Point): JSX.Element {
|
renderCell(s: string, pos: Point): JSX.Element {
|
||||||
const size = `${this.cellSize}px`;
|
const size = `${this.props.cellSize}px`;
|
||||||
const padding = `${this.cellSize / 4}px`;
|
const padding = `${this.props.cellSize / 4}px`;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<button
|
<button
|
||||||
@ -127,28 +106,27 @@ export default class Board extends React.Component<IBoardProps, IBoardState> {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
renderLine(s: Selection, n: number): JSX.Element {
|
renderLine(s: Answer, n: number): JSX.Element {
|
||||||
return (
|
return (
|
||||||
<Line
|
<Line
|
||||||
key={`Line${n}`}
|
key={`Line${n}`}
|
||||||
bar={s.bar}
|
bar={s.bar}
|
||||||
isVisible={s.isVisible}
|
|
||||||
isCorrect={s.isCorrect}
|
isCorrect={s.isCorrect}
|
||||||
cellSize={this.cellSize}
|
cellSize={this.props.cellSize}
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
render(): JSX.Element {
|
render(): JSX.Element {
|
||||||
let cells =
|
let cells =
|
||||||
this.cells.map((oy, y) =>
|
this.props.cells.map((oy, y) =>
|
||||||
oy.map((s, x) =>
|
oy.map((s, x) =>
|
||||||
this.renderCell(s, {x, y})));
|
this.renderCell(s, {x, y})));
|
||||||
|
|
||||||
let lines = this.state.selections.map((s, n) =>
|
let lines = this.state.selections.map((s, n) =>
|
||||||
this.renderLine(s, n));
|
this.renderLine(s, n));
|
||||||
|
|
||||||
const gridTemplateColumns = `repeat(${this.cells.length}, ${this.cellSize}px)`;
|
const gridTemplateColumns = `repeat(${this.props.cells.length}, ${this.props.cellSize}px)`;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="Container">
|
<div className="Container">
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
import React from 'react';
|
import React from 'react';
|
||||||
|
|
||||||
import {Bar} from '../Board/Board'
|
import {Bar} from '../App/App'
|
||||||
|
|
||||||
import './Line.scss';
|
import './Line.scss';
|
||||||
|
|
||||||
@ -19,7 +19,6 @@ enum Dir {
|
|||||||
interface ILineProps {
|
interface ILineProps {
|
||||||
bar: Bar;
|
bar: Bar;
|
||||||
cellSize: number;
|
cellSize: number;
|
||||||
isVisible: boolean;
|
|
||||||
isCorrect: boolean;
|
isCorrect: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -51,7 +50,6 @@ export default function Line(props: ILineProps): JSX.Element {
|
|||||||
return (
|
return (
|
||||||
<rect
|
<rect
|
||||||
className={props.isCorrect ? 'CorrectLine' : 'Line'}
|
className={props.isCorrect ? 'CorrectLine' : 'Line'}
|
||||||
visibility={props.isVisible ? 'visible' : 'hidden'}
|
|
||||||
transform={`rotate(${r}, ${x}, ${y})`}
|
transform={`rotate(${r}, ${x}, ${y})`}
|
||||||
{...{x, y, width: w, height: h, rx: m4, ry: m4}}
|
{...{x, y, width: w, height: h, rx: m4, ry: m4}}
|
||||||
/>
|
/>
|
||||||
|
Loading…
Reference in New Issue
Block a user