Add settings/info popup.

No "settings" yet, but can reset game normally, or with a randomized
back row. Buttons generally look bad.
This commit is contained in:
Sage Vaillancourt 2021-01-01 20:03:56 -05:00
parent 89520ac767
commit aed8003fdf
4 changed files with 169 additions and 18 deletions

27
src/components/Popup.js Normal file
View File

@ -0,0 +1,27 @@
import React from 'react';
import './style.css';
class Popup extends React.Component {
render() {
return (
<div className='popup'>
<div className='popup-outer'
onClick={this.props.closePopup}>
</div>
<div className='popup-inner'>
<h1>{this.props.header}</h1>
{this.props.body}
<div style={{textAlign: "right"}}>
<button
onClick={this.props.closePopup}>
Close
</button>
</div>
</div>
</div>
);
}
}
export default Popup;

52
src/components/style.css Normal file
View File

@ -0,0 +1,52 @@
.popup-outer {
position: fixed;
width: 100%;
height: 100%;
top: 0;
left: 0;
right: 0;
bottom: 0;
margin: auto;
background-color: rgba(0,0,0, 0.5);
}
@media (orientation:portrait) {
.popup-inner {
left: 5%;
right: 5%;
top: 5%;
bottom: 5%;
text-align: justify;
padding-left: 6%;
padding-right: 6%;
font-size: 1.2em;
line-height: 150%;
}
}
@media (orientation:landscape) {
.popup-inner {
left: 25%;
right: 25%;
top: 25%;
bottom: 25%;
padding-left: 2%;
padding-right: 2%;
font-size: 1.5em;
line-height: 150%;
}
}
.popup-inner {
position: absolute;
margin: auto;
border-radius: 2px;
background: white;
overflow-x: hidden;
overflow-y: auto;
text-align: justify;
}
.popup h1 {
text-align: center;
}

View File

@ -19,17 +19,26 @@ ol, ul {
} }
@media (orientation:landscape) { @media (orientation:landscape) {
.square { .game-board .square {
height: 11vh; height: 11vh;
width: 11vh; width: 11vh;
} }
.demo-board .square {
height: 8vh;
width: 8vh;
}
} }
@media (orientation:portrait) { @media (orientation:portrait) {
.square { .game-board .square {
height: 11vw; height: 11vw;
width: 11vw; width: 11vw;
} }
.demo-board .square {
height: 10vw;
width: 10vw;
}
} }
.square { .square {
@ -59,6 +68,10 @@ ol, ul {
background: #ddd; background: #ddd;
} }
.status button {
float: right;
}
.game-board { .game-board {
display: flex; display: flex;
justify-content: center; justify-content: center;

View File

@ -1,7 +1,11 @@
import React from 'react'; import React from 'react';
import ReactDOM from 'react-dom'; import ReactDOM from 'react-dom';
import Popup from './components/Popup';
import './index.css'; import './index.css';
const BLACK = 0; const BLACK = 0;
const WHITE = 1; const WHITE = 1;
@ -112,23 +116,14 @@ class Piece {
class Board extends React.Component { class Board extends React.Component {
constructor(props) { constructor(props) {
super(props); super(props);
if (props && props.text) { this.state = (props && props.text) ?
this.state = { {
squares: this.stateFromText(props.text), squares: this.stateFromText(props.text),
blackIsNext: true, blackIsNext: true,
hand: { hand: {
heldPiece: null, heldPiece: null,
}, },
}; } : this.originalState();
} else {
this.state = {
squares: this.reset(),
blackIsNext: true,
hand: {
heldPiece: null,
},
};
}
} }
setHand(hand) { setHand(hand) {
@ -178,6 +173,18 @@ class Board extends React.Component {
}; };
} }
shuffledBackRow() {
return "rnbqkbnr".split('').sort(() => Math.random() - 0.5).join('');
}
resetWithShuffledBackRow() {
const backRow = this.shuffledBackRow();
const text = ["B", backRow, "pppppppp",
"________", "________", "________", "________",
"PPPPPPPP", backRow.toUpperCase()].join('');
this.setState(this.stateFromText(text));
}
textFromState() { textFromState() {
const turn = (this.state.blackIsNext? 'B' : 'W'); const turn = (this.state.blackIsNext? 'B' : 'W');
return turn + this.state.squares.map(square => { return turn + this.state.squares.map(square => {
@ -206,7 +213,11 @@ class Board extends React.Component {
}).join('');; }).join('');;
} }
reset() { doReset() {
this.setState(this.originalState());
}
originalState() {
let squares = []; let squares = [];
const mainRow = [ROOK, KNIGHT, BISHOP, QUEEN, KING, BISHOP, KNIGHT, ROOK]; const mainRow = [ROOK, KNIGHT, BISHOP, QUEEN, KING, BISHOP, KNIGHT, ROOK];
function add(num, color, type) { function add(num, color, type) {
@ -225,7 +236,14 @@ class Board extends React.Component {
add(8, BLACK, PAWN); add(8, BLACK, PAWN);
mainRow.forEach(type => add(1, BLACK, type)); mainRow.forEach(type => add(1, BLACK, type));
return squares; return ({
squares,
blackIsNext: true,
hand: {
heldPiece: null,
},
showPopup: false,
});
} }
getXandY(i) { getXandY(i) {
@ -488,7 +506,7 @@ class Board extends React.Component {
} }
heldPiece() { heldPiece() {
return this.state.hand.heldPiece; return (this.state && this.state.hand) ? this.state.hand.heldPiece : null;
} }
makeMove(from, to) { makeMove(from, to) {
@ -590,6 +608,35 @@ class Board extends React.Component {
); );
} }
togglePopup() {
this.setState({
showPopup: !this.state.showPopup
});
}
renderPopup() {
return (this.state.showPopup ?
<Popup
header='QuickChess'
closePopup={this.togglePopup.bind(this)}
body={<div>
<p>This is a simple implementation of the classic board game. It
supports all possible moves, including castling, and <em>en
passant</em>.</p>
<button onClick={
this.resetWithShuffledBackRow.bind(this)
}>Shuffled Back Row</button>
<button onClick={this.doReset.bind(this)}>Reset Game</button>
</div>}
/>
: null
);
}
/* Board class can't (always) include a settings button if used as a demo. */
render() { render() {
const checkMsg = this.whoInCheck() ? "Check! " : ""; const checkMsg = this.whoInCheck() ? "Check! " : "";
const isCheckmate = this.checkmate(); const isCheckmate = this.checkmate();
@ -602,14 +649,26 @@ class Board extends React.Component {
return ( return (
<div style={{textAlign: `center`,}}> <div style={{textAlign: `center`,}}>
<div className="status"><h1>{status}</h1></div> <div className="status">
<h1 style={{display: "inline-block"}}>{status}</h1>
<button
onClick={this.togglePopup.bind(this)}>
Settings
</button>
</div>
{range(8).map(n => this.row(n))} {range(8).map(n => this.row(n))}
{this.renderPopup()}
</div> </div>
); );
} }
} }
class Game extends React.Component { class Game extends React.Component {
constructor(props){
super(props);
this.state = { showPopup: false };
}
render() { render() {
return ( return (
<div className="game"> <div className="game">