From aed8003fdf0396429972ef9b06c7e641174719d3 Mon Sep 17 00:00:00 2001 From: Sage Vaillancourt Date: Fri, 1 Jan 2021 20:03:56 -0500 Subject: [PATCH] Add settings/info popup. No "settings" yet, but can reset game normally, or with a randomized back row. Buttons generally look bad. --- src/components/Popup.js | 27 ++++++++++++ src/components/style.css | 52 +++++++++++++++++++++++ src/index.css | 17 +++++++- src/index.js | 91 +++++++++++++++++++++++++++++++++------- 4 files changed, 169 insertions(+), 18 deletions(-) create mode 100644 src/components/Popup.js create mode 100644 src/components/style.css diff --git a/src/components/Popup.js b/src/components/Popup.js new file mode 100644 index 0000000..ef70bff --- /dev/null +++ b/src/components/Popup.js @@ -0,0 +1,27 @@ +import React from 'react'; +import './style.css'; + +class Popup extends React.Component { + render() { + return ( +
+
+
+
+

{this.props.header}

+ {this.props.body} +
+ +
+
+
+ ); + } +} + + +export default Popup; diff --git a/src/components/style.css b/src/components/style.css new file mode 100644 index 0000000..26cbc71 --- /dev/null +++ b/src/components/style.css @@ -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; +} diff --git a/src/index.css b/src/index.css index 884fa9c..e3e8ae9 100644 --- a/src/index.css +++ b/src/index.css @@ -19,17 +19,26 @@ ol, ul { } @media (orientation:landscape) { - .square { + .game-board .square { height: 11vh; width: 11vh; } + + .demo-board .square { + height: 8vh; + width: 8vh; + } } @media (orientation:portrait) { - .square { + .game-board .square { height: 11vw; width: 11vw; } + .demo-board .square { + height: 10vw; + width: 10vw; + } } .square { @@ -59,6 +68,10 @@ ol, ul { background: #ddd; } +.status button { + float: right; +} + .game-board { display: flex; justify-content: center; diff --git a/src/index.js b/src/index.js index 0ffb3fe..1b50b9c 100644 --- a/src/index.js +++ b/src/index.js @@ -1,7 +1,11 @@ import React from 'react'; import ReactDOM from 'react-dom'; + +import Popup from './components/Popup'; + import './index.css'; + const BLACK = 0; const WHITE = 1; @@ -112,23 +116,14 @@ class Piece { class Board extends React.Component { constructor(props) { super(props); - if (props && props.text) { - this.state = { + this.state = (props && props.text) ? + { squares: this.stateFromText(props.text), blackIsNext: true, hand: { heldPiece: null, }, - }; - } else { - this.state = { - squares: this.reset(), - blackIsNext: true, - hand: { - heldPiece: null, - }, - }; - } + } : this.originalState(); } 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() { const turn = (this.state.blackIsNext? 'B' : 'W'); return turn + this.state.squares.map(square => { @@ -206,7 +213,11 @@ class Board extends React.Component { }).join('');; } - reset() { + doReset() { + this.setState(this.originalState()); + } + + originalState() { let squares = []; const mainRow = [ROOK, KNIGHT, BISHOP, QUEEN, KING, BISHOP, KNIGHT, ROOK]; function add(num, color, type) { @@ -225,7 +236,14 @@ class Board extends React.Component { add(8, BLACK, PAWN); mainRow.forEach(type => add(1, BLACK, type)); - return squares; + return ({ + squares, + blackIsNext: true, + hand: { + heldPiece: null, + }, + showPopup: false, + }); } getXandY(i) { @@ -488,7 +506,7 @@ class Board extends React.Component { } heldPiece() { - return this.state.hand.heldPiece; + return (this.state && this.state.hand) ? this.state.hand.heldPiece : null; } makeMove(from, to) { @@ -590,6 +608,35 @@ class Board extends React.Component { ); } + togglePopup() { + this.setState({ + showPopup: !this.state.showPopup + }); + } + + renderPopup() { + return (this.state.showPopup ? + + +

This is a simple implementation of the classic board game. It + supports all possible moves, including castling, and en + passant.

+ + + + + } + /> + : null + ); + } + + /* Board class can't (always) include a settings button if used as a demo. */ render() { const checkMsg = this.whoInCheck() ? "Check! " : ""; const isCheckmate = this.checkmate(); @@ -602,14 +649,26 @@ class Board extends React.Component { return (
-

{status}

+
+

{status}

+ +
{range(8).map(n => this.row(n))} + {this.renderPopup()}
); } } class Game extends React.Component { + constructor(props){ + super(props); + this.state = { showPopup: false }; + } + render() { return (