import React from 'react'; import Grid from './grid/grid'; import GridControl from './grid/grid-control'; class MineSeeker extends React.Component { constructor(props) { super(props); var gameAssoc = props.gameId !== '' ? props.gameId : this.makeGameAssoc(50); var channel = "mineseeker/channel/" + gameAssoc; this.state = { gameInherited: props.gameId !== '', gameAssoc: gameAssoc, channel: channel, session: null, createGrid: false, stepCache: null } } makeGameAssoc(len) { var text = ""; var possible = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"; for (var i = 0; i < len; i++) { text += possible.charAt(Math.floor(Math.random() * possible.length)); } return text; } /** 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.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 }); } } /** after rendering */ componentDidMount() { /** Create Websocket w/ Bahnhof.js */ var websocket = WS.connect("ws://mine.dev:6450"); /** * Connect * Session is an Autobahn JS WAMP session. */ websocket.on("socket/connect", (session) => { console.info("Successfully connected to the Server!"); var gridClient = this.state.gameInherited || new Grid().state.grid; /** * Connect - RPC * Send grid information to the server */ session .call( this.state.gameInherited ? "mineseeker-rpc/connectGame" : "mineseeker-rpc/startGame", this.state.gameInherited ? this.state.gameAssoc : [Base64.encode(JSON.stringify(gridClient)), this.state.gameAssoc] ) .then( (gridServer) => { console.info("Grid has been created! Return w/ gameAssoc."); this.setState({session: session}); /** save session to GridControl */ /** render grid fields - #12 */ this.refs.gridControl.setState({ grid: this.state.gameInherited ? JSON.parse(Base64.decode(gridServer)) : gridClient, channel: this.state.channel, overlay: true, overlayTitle: "We are waiting for your opponent...", overlaySubTitle: this.state.gameAssoc ? Play w/ me! : '', renderGridFields: this.state.gameAssoc }); /** setup the web player */ this.refs.gridControl.state.webPlayer === null && this.refs.gridControl.setState({webPlayer: this.state.gameInherited ? 'blue' : 'red'}); /** Connect - Subscribe */ this.state.session.subscribe( this.state.channel, (uri, payload, log) => { var isTopicEvent = typeof payload.data !== 'undefined', isNotUnsubscribe = typeof payload.msg === 'undefined'; if (isTopicEvent) { console.warn(payload.user + " has been stepped to coords: " + payload.data.coords[0] + ', ' + payload.data.coords[1]); /** Auto-Step if this player is not the current user */ if (this.refs.gridControl.state.webPlayer !== payload.data.player) { console.warn('Opponent stepped: Auto-Step process'); this.refs.gridControl.refs.userControl.setState({bombSelected: payload.data.bomb}); this.refs.gridControl.stepEvent(payload.data.coords); /** THE END */ this.makeGameEndIfItEnds( this.refs.gridControl.refs.userControl.refs.blue.state.mines, this.refs.gridControl.refs.userControl.refs.red.state.mines ); } } else { /** It is subscribe or unsubscribe */ if (isNotUnsubscribe) { console.info( (typeof payload.user !== 'undefined' ? payload.user : 'user') + " has been subscribed to the channel!" ); /** remove overlay when every user has been came */ this.refs.gridControl.setState({overlay: payload.userCnt < 2}); /** Set up player names w/ server data */ this.refs.gridControl.refs.userControl.refs.red.setState({ name: payload.users.red !== '' ? payload.users.red : payload.users.redAnon }); this.refs.gridControl.refs.userControl.refs.blue.setState({ name: payload.users.blue !== '' ? payload.users.blue : payload.users.blueAnon }); } else { console.info(payload.msg); this.refs.gridControl.setState({ overlay: true, overlayTitle: "The connection has been lost...", overlaySubTitle: "Please, restart the game!" }); } } } ); }, (error, desc) => console.error(["RPC Error", error, desc]) ); }); /** * DisConnect * Error provides us with some insight into the disconnection: error.reason and error.code */ websocket.on("socket/disconnect", (error) => console.error("Disconnected for " + error.reason + " with code " + error.code)); } onClick(coords) { var activePlayer = this.refs.gridControl.refs.userControl.state.activePlayer ? 'blue' : 'red'; /** 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 ); /** 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 }); } } } render() { return ( ); } } export default MineSeeker;