diff --git a/src/Mine/SeekerBundle/Resources/public/images/bg-left-mine-outbg.png b/src/Mine/SeekerBundle/Resources/public/images/bg-left-mine-outbg.png new file mode 100644 index 0000000..77cc2b5 Binary files /dev/null and b/src/Mine/SeekerBundle/Resources/public/images/bg-left-mine-outbg.png differ diff --git a/src/Mine/SeekerBundle/Resources/public/js/mine-seeker/app.js b/src/Mine/SeekerBundle/Resources/public/js/mine-seeker/app.js index bcb148e..66261ca 100644 --- a/src/Mine/SeekerBundle/Resources/public/js/mine-seeker/app.js +++ b/src/Mine/SeekerBundle/Resources/public/js/mine-seeker/app.js @@ -28,19 +28,25 @@ class MineSeeker extends React.Component { return text; } - /** game end control */ + /** THE END */ makeGameEndIfItEnds(bluePoints, redPoints) { var redWins = redPoints > 2, blueWins = bluePoints > 2; if (redWins || blueWins) { + this.refs.gridControl.state.sound.won.play(); + this.refs.gridControl.setState({ overlay: true, overlayTitle: (redWins ? 'Red' : 'Blue') + " wins the game!", overlaySubTitle: "Play again!" }); - this.refs.gridControl.state.sound.won.play(); + this.refs.gridControl.showLeftMines(); + + this.refs.gridControl.refs.userControl.setState({ activePlayer: false}); + this.refs.gridControl.refs.userControl.refs.red.setState({ active: false }); + this.refs.gridControl.refs.userControl.refs.blue.setState({ active: false }); } } @@ -107,7 +113,7 @@ class MineSeeker extends React.Component { this.refs.gridControl.refs.userControl.setState({bombSelected: payload.data.bomb}); this.refs.gridControl.stepEvent(payload.data.coords); - /** End-game control */ + /** THE END */ this.makeGameEndIfItEnds( this.refs.gridControl.refs.userControl.refs.blue.state.mines, this.refs.gridControl.refs.userControl.refs.red.state.mines @@ -159,33 +165,36 @@ class MineSeeker extends React.Component { onClick(coords) { var activePlayer = this.refs.gridControl.refs.userControl.state.activePlayer ? 'blue' : 'red'; - /** Player step and it is the current player */ - if (activePlayer === this.refs.gridControl.state.webPlayer) { - this.refs.gridControl.stepEvent(coords); + /** if the clicked field is NEVER CLICKED */ + if (this.refs.gridControl.checkFieldHasBeenNeverClicked(coords[0], coords[1])) { + /** Player step and it is the current player */ + if (activePlayer === this.refs.gridControl.state.webPlayer) { + this.refs.gridControl.stepEvent(coords); - var mineCache = this.refs.gridControl.state.foundUserMineCache, - redPoints = this.refs.gridControl.refs.userControl.refs.red.state.mines + ( - this.refs.gridControl.refs.userControl.refs.red.state.active - ? mineCache - : 0 - ), - bluePoints = this.refs.gridControl.refs.userControl.refs.blue.state.mines + ( - this.refs.gridControl.refs.userControl.refs.blue.state.active - ? mineCache - : 0 - ); + var mineCache = this.refs.gridControl.state.foundUserMineCache, + redPoints = this.refs.gridControl.refs.userControl.refs.red.state.mines + ( + this.refs.gridControl.refs.userControl.refs.red.state.active + ? mineCache + : 0 + ), + bluePoints = this.refs.gridControl.refs.userControl.refs.blue.state.mines + ( + this.refs.gridControl.refs.userControl.refs.blue.state.active + ? mineCache + : 0 + ); - /** End-game control */ - this.makeGameEndIfItEnds(bluePoints, redPoints); + /** THE END */ + this.makeGameEndIfItEnds(bluePoints, redPoints); - this.state.session - .publish(this.state.channel, { - 'coords': coords, - 'player': activePlayer, - 'bomb': this.refs.gridControl.refs.userControl.state.bombSelected, - 'redPoints': redPoints, - 'bluePoints': bluePoints - }); + this.state.session + .publish(this.state.channel, { + 'coords': coords, + 'player': activePlayer, + 'bomb': this.refs.gridControl.refs.userControl.state.bombSelected, + 'redPoints': redPoints, + 'bluePoints': bluePoints + }); + } } } diff --git a/src/Mine/SeekerBundle/Resources/public/js/mine-seeker/grid/grid-control.js b/src/Mine/SeekerBundle/Resources/public/js/mine-seeker/grid/grid-control.js index f070877..45e862e 100644 --- a/src/Mine/SeekerBundle/Resources/public/js/mine-seeker/grid/grid-control.js +++ b/src/Mine/SeekerBundle/Resources/public/js/mine-seeker/grid/grid-control.js @@ -47,6 +47,10 @@ class GridControl extends React.Component { return typeof this.state.grid[row] !== 'undefined' && typeof this.state.grid[row][col] !== 'undefined' && this.state.grid[row][col] !== 'm'; } + checkFieldHasBeenNeverClicked(row, col) { + return this.state.updatedFieldCache.indexOf(this.refString(row, col)) < 0 && !this.refs[this.refString(row, col)].state.active; + } + getBombRadius(row, col) { let isBombTargetCenter = row > 1 && row < this.state.grid.length - 2 && col > 1 && col < this.state.grid[row].length - 2; @@ -146,6 +150,20 @@ class GridControl extends React.Component { } } + showLeftMines() { + for (let i = 0, j = this.state.grid.length; i < j; i++) { + for (let k = 0, l = this.state.grid[i].length; k < l; k++) { + let currentField = this.refs[this.refString(i, k)]; + + if (this.state.grid[i][k] === 'm' && this.checkFieldHasBeenNeverClicked(i, k)) { + currentField.setState({ + currentImage: currentField.state.icons.root + currentField.state.icons.left + }); + } + } + } + } + /** set __ACTIVE__ player in the UserControl !!!! */ changePlayer(idx, max, currentObject) { var userControl = this.refs.userControl, @@ -183,7 +201,7 @@ class GridControl extends React.Component { active: true }); - if (this.state.updatedFieldCache.indexOf(this.refString(row, col)) < 0) { + if (this.checkFieldHasBeenNeverClicked(row, col)) { this.state.updatedFieldCache.push(this.refString(row, col)); } @@ -215,70 +233,67 @@ class GridControl extends React.Component { activePlayer = userControl.state.activePlayer ? 'blue' : 'red', inactivePlayer = userControl.state.activePlayer ? 'red' : 'blue'; - /** if the clicked field is NEVER CLICKED */ - if (!gridFieldControl.state.active) { - /** update LAST CLICKED grid field */ - if (!justOnFirstIteration) { - if (this.state.lastClicked[activePlayer] !== null) { - this.refs[this.refString(this.state.lastClicked[activePlayer][0], this.state.lastClicked[activePlayer][1])].setState({ - lastClickedRed: false, - lastClickedBlue: false - }); - } - } - - this.state.lastClicked[activePlayer] = [x, y]; - - /** if you found mine */ - if (currentObject === 'm') { - this.state.foundUserMineCache++; - - if (!justOnFirstIteration) { - /** set last clicked field w/ color */ - this.state.lastClicked[activePlayer] = [x, y]; - - this.state.sound[ - (userControl.refs[activePlayer].state.mines + this.state.foundUserMineCache) > 20 - ? 'warning' - : 'mine' - ].play(); - } - - /** set current image in field */ - gridFieldControl.setState({ - currentImage: gridFieldControl.state.icons.root + gridFieldControl.state.icons.flag[activePlayer] - }); - } else { - this.state.sound.click.play(); - - /** set current image in field - WHEN it is a number */ - if (!isNaN(currentObject)) { - gridFieldControl.setState({ - currentImage: currentObject - }); - } - } - - /** - * set bombs status - we must add one mine (currentObject === 'm' ? 1 : 0) to current mine - * when it found NOW because the status is not refreshed unless the handleGridField() ends - */ - userControl.refs[activePlayer].setState({ - enabledBomb: userControl.refs[activePlayer].state.mines + (currentObject === 'm' ? 1 : 0) <= userControl.refs[inactivePlayer].state.mines - }); - - userControl.refs[inactivePlayer].setState({ - enabledBomb: userControl.refs[activePlayer].state.mines + (currentObject === 'm' ? 1 : 0) >= userControl.refs[inactivePlayer].state.mines - }); - - /** set-up last clicked */ - if (!justOnFirstIteration) { - gridFieldControl.setState({ - lastClickedRed: activePlayer === 'red', - lastClickedBlue: activePlayer === 'blue' + /** update LAST CLICKED grid field */ + if (!justOnFirstIteration) { + if (this.state.lastClicked[activePlayer] !== null) { + this.refs[this.refString(this.state.lastClicked[activePlayer][0], this.state.lastClicked[activePlayer][1])].setState({ + lastClickedRed: false, + lastClickedBlue: false }); } } + + this.state.lastClicked[activePlayer] = [x, y]; + + /** if you found mine */ + if (currentObject === 'm') { + this.state.foundUserMineCache++; + + if (!justOnFirstIteration) { + /** set last clicked field w/ color */ + this.state.lastClicked[activePlayer] = [x, y]; + + this.state.sound[ + (userControl.refs[activePlayer].state.mines + this.state.foundUserMineCache) > 20 + ? 'warning' + : 'mine' + ].play(); + } + + /** set current image in field */ + gridFieldControl.setState({ + currentImage: gridFieldControl.state.icons.root + gridFieldControl.state.icons.flag[activePlayer] + }); + } else { + this.state.sound.click.play(); + + /** set current image in field - WHEN it is a number */ + if (!isNaN(currentObject)) { + gridFieldControl.setState({ + currentImage: currentObject + }); + } + } + + /** + * set bombs status - we must add one mine (currentObject === 'm' ? 1 : 0) to current mine + * when it found NOW because the status is not refreshed unless the handleGridField() ends + */ + userControl.refs[activePlayer].setState({ + enabledBomb: userControl.refs[activePlayer].state.mines + (currentObject === 'm' ? 1 : 0) <= userControl.refs[inactivePlayer].state.mines + }); + + userControl.refs[inactivePlayer].setState({ + enabledBomb: userControl.refs[activePlayer].state.mines + (currentObject === 'm' ? 1 : 0) >= userControl.refs[inactivePlayer].state.mines + }); + + /** set-up last clicked */ + if (!justOnFirstIteration) { + gridFieldControl.setState({ + lastClickedRed: activePlayer === 'red', + lastClickedBlue: activePlayer === 'blue' + }); + } } /** @@ -301,51 +316,54 @@ class GridControl extends React.Component { * @param coords */ stepEvent(coords) { - var activePlayer = this.refs.userControl.state.activePlayer ? 'blue' : 'red'; + /** if the clicked field is NEVER CLICKED */ + if (this.checkFieldHasBeenNeverClicked(coords[0], coords[1])) { + var activePlayer = this.refs.userControl.state.activePlayer ? 'blue' : 'red'; - this.state.foundUserMineCache = 0; - this.state.playBomb = true; + this.state.foundUserMineCache = 0; + this.state.playBomb = true; - /** Show elements */ - if (this.refs.userControl.state.bombSelected) { - this.state.sound.bomb.play(); + /** Show elements */ + if (this.refs.userControl.state.bombSelected) { + this.state.sound.bomb.play(); - var bombRadius = this.getBombRadius(coords[0], coords[1]); - for (var i = 0, j = bombRadius.length; i < j; i++) { - this.show(bombRadius[i][0], bombRadius[i][1], i, j); + var bombRadius = this.getBombRadius(coords[0], coords[1]); + for (var i = 0, j = bombRadius.length; i < j; i++) { + this.show(bombRadius[i][0], bombRadius[i][1], i, j); + } + + /** remove BOMB from activePlayer */ + this.refs.userControl.refs[activePlayer].setState({ + haveBomb: false + }); + } else { + this.show(coords[0], coords[1]); } - /** remove BOMB from activePlayer */ - this.refs.userControl.refs[activePlayer].setState({ - haveBomb: false - }); - } else { - this.show(coords[0], coords[1]); - } + /** Mine score handling */ + if (this.state.foundUserMineCache) { + this.refs.userControl.setState({ + mines: this.refs.userControl.state.mines - this.state.foundUserMineCache, + foundMines: true + }, () => { + /** because of CSS animation in .found-mine */ + setTimeout(() => this.refs.userControl.setState({foundMines: false}), 500); - /** Mine score handling */ - if (this.state.foundUserMineCache) { - this.refs.userControl.setState({ - mines: this.refs.userControl.state.mines - this.state.foundUserMineCache, - foundMines: true - }, () => { - /** because of CSS animation in .found-mine */ - setTimeout(() => this.refs.userControl.setState({foundMines: false}), 500); - - /** add the found mines to the active Player */ - this.refs.userControl.refs[activePlayer].setState({ - mines: this.refs.userControl.refs[activePlayer].state.mines + this.state.foundUserMineCache + /** add the found mines to the active Player */ + this.refs.userControl.refs[activePlayer].setState({ + mines: this.refs.userControl.refs[activePlayer].state.mines + this.state.foundUserMineCache + }); }); - }); - } + } - /** Reset BOMB status */ - if (this.refs.userControl.state.bombSelected) { - /** reset bomb selected status */ - this.refs.userControl.setState({bombSelected: false}); + /** Reset BOMB status */ + if (this.refs.userControl.state.bombSelected) { + /** reset bomb selected status */ + this.refs.userControl.setState({bombSelected: false}); - /** clear cache, reset symbols */ - this.bombClear(); + /** clear cache, reset symbols */ + this.bombClear(); + } } } diff --git a/src/Mine/SeekerBundle/Resources/public/js/mine-seeker/grid/grid-field.js b/src/Mine/SeekerBundle/Resources/public/js/mine-seeker/grid/grid-field.js index ecd0a39..a2bb5db 100644 --- a/src/Mine/SeekerBundle/Resources/public/js/mine-seeker/grid/grid-field.js +++ b/src/Mine/SeekerBundle/Resources/public/js/mine-seeker/grid/grid-field.js @@ -27,7 +27,8 @@ class GridField extends React.Component { lastRed: 'bg-last-red-outbg.png', crosshair: 'bg-target-outbg.png', crosshairBomb: 'bg-target-bomb-outbg.png' - } + }, + left: 'bg-left-mine-outbg.png' } }; }