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';
|
||||
|
||||
export default function App(): JSX.Element {
|
||||
return (
|
||||
<div className="App">
|
||||
<div />
|
||||
<div>
|
||||
<Logo />
|
||||
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 (
|
||||
<div className="App">
|
||||
<div />
|
||||
<div>
|
||||
controls: 1231414214
|
||||
<Logo />
|
||||
<div>
|
||||
<p>{this.game.title}</p>
|
||||
<p>{this.game.description}</p>
|
||||
</div>
|
||||
</div>
|
||||
<div />
|
||||
<div />
|
||||
<div>
|
||||
<Board
|
||||
cells={this.game.cells}
|
||||
solutions={this.game.solutions}
|
||||
cellSize={60}
|
||||
/>
|
||||
</div>
|
||||
<div style={{paddingLeft: '30px'}}>
|
||||
{this.answers}
|
||||
</div>
|
||||
</div>
|
||||
<div />
|
||||
<div />
|
||||
<div>
|
||||
<Board numBoard={1}/>
|
||||
</div>
|
||||
<div />
|
||||
</div>
|
||||
);
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@ -1,66 +1,44 @@
|
||||
import React from 'react';
|
||||
|
||||
import Line from '../Line/Line';
|
||||
import {Point, Bar, Solution} from "../App/App";
|
||||
|
||||
import './Board.scss';
|
||||
|
||||
type Point = {
|
||||
x: number;
|
||||
y: number;
|
||||
}
|
||||
|
||||
export type Bar = {
|
||||
start: Point,
|
||||
end: Point,
|
||||
}
|
||||
|
||||
type Solution = {
|
||||
type Answer = {
|
||||
bar: Bar;
|
||||
key: string;
|
||||
}
|
||||
|
||||
type Selection = {
|
||||
bar: Bar,
|
||||
isVisible: boolean;
|
||||
isCorrect: boolean;
|
||||
}
|
||||
|
||||
interface IBoardProps {
|
||||
numBoard: number;
|
||||
cells: Array<Array<string>>;
|
||||
solutions: Array<Solution>;
|
||||
cellSize: number;
|
||||
}
|
||||
|
||||
interface IBoardState {
|
||||
score: number;
|
||||
wasValid: boolean;
|
||||
wasValidAnswer: boolean;
|
||||
wasSelecting: boolean;
|
||||
selections: Array<Selection>;
|
||||
selections: Array<Answer>;
|
||||
bar: Bar;
|
||||
}
|
||||
|
||||
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) {
|
||||
super(props);
|
||||
|
||||
const crosski: any = require(`../../constants/${props.numBoard}.json`)
|
||||
this.cells = crosski.cells;
|
||||
this.solutions = crosski.solutions;
|
||||
this.cellSize = 60;
|
||||
|
||||
const selections = [...new Array(this.solutions.length)].map(() =>
|
||||
const selections = [...new Array(props.solutions.length)].map(() =>
|
||||
Object.assign({}, {
|
||||
bar: {start: {x: 0, y: 0}, end: {x: 0, y: 0}},
|
||||
isCorrect: false,
|
||||
isVisible: true,
|
||||
}));
|
||||
|
||||
this.state = {
|
||||
score: 0,
|
||||
selections,
|
||||
wasValid: false,
|
||||
wasValidAnswer: false,
|
||||
wasSelecting: false,
|
||||
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];
|
||||
|
||||
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);
|
||||
|
||||
// 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 isMouseDown = isSelecting && !this.state.wasSelecting;
|
||||
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 bar: Bar = {start, end: pos};
|
||||
|
||||
if (isValidMove)
|
||||
s.bar = bar;
|
||||
|
||||
if (isMouseUp && this.state.wasValid)
|
||||
if (isMouseUp && this.state.wasValidAnswer)
|
||||
[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.state,
|
||||
score, bar, selections,
|
||||
wasValid: isValid,
|
||||
wasSelecting: isSelecting
|
||||
wasValidAnswer: isValidAnswer,
|
||||
wasSelecting: isSelecting,
|
||||
});
|
||||
|
||||
if (score === this.solutions.length)
|
||||
if (score === this.props.solutions.length)
|
||||
this.gameOver();
|
||||
}
|
||||
|
||||
renderCell(s: string, pos: Point): JSX.Element {
|
||||
const size = `${this.cellSize}px`;
|
||||
const padding = `${this.cellSize / 4}px`;
|
||||
const size = `${this.props.cellSize}px`;
|
||||
const padding = `${this.props.cellSize / 4}px`;
|
||||
|
||||
return (
|
||||
<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 (
|
||||
<Line
|
||||
key={`Line${n}`}
|
||||
bar={s.bar}
|
||||
isVisible={s.isVisible}
|
||||
isCorrect={s.isCorrect}
|
||||
cellSize={this.cellSize}
|
||||
cellSize={this.props.cellSize}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
render(): JSX.Element {
|
||||
let cells =
|
||||
this.cells.map((oy, y) =>
|
||||
this.props.cells.map((oy, y) =>
|
||||
oy.map((s, x) =>
|
||||
this.renderCell(s, {x, y})));
|
||||
|
||||
let lines = this.state.selections.map((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 (
|
||||
<div className="Container">
|
||||
|
@ -1,6 +1,6 @@
|
||||
import React from 'react';
|
||||
|
||||
import {Bar} from '../Board/Board'
|
||||
import {Bar} from '../App/App'
|
||||
|
||||
import './Line.scss';
|
||||
|
||||
@ -19,7 +19,6 @@ enum Dir {
|
||||
interface ILineProps {
|
||||
bar: Bar;
|
||||
cellSize: number;
|
||||
isVisible: boolean;
|
||||
isCorrect: boolean;
|
||||
}
|
||||
|
||||
@ -51,7 +50,6 @@ export default function Line(props: ILineProps): JSX.Element {
|
||||
return (
|
||||
<rect
|
||||
className={props.isCorrect ? 'CorrectLine' : 'Line'}
|
||||
visibility={props.isVisible ? 'visible' : 'hidden'}
|
||||
transform={`rotate(${r}, ${x}, ${y})`}
|
||||
{...{x, y, width: w, height: h, rx: m4, ry: m4}}
|
||||
/>
|
||||
|
Loading…
Reference in New Issue
Block a user