Skip to content

Instantly share code, notes, and snippets.

@LilyMGoh
Created November 2, 2016 00:36
Show Gist options
  • Save LilyMGoh/5db56ea7810a690dd89f39cb4dc7136c to your computer and use it in GitHub Desktop.
Save LilyMGoh/5db56ea7810a690dd89f39cb4dc7136c to your computer and use it in GitHub Desktop.
import React, { Component } from 'react';
import './App.css';
var _ = require('lodash');
const ROW = 6;
const COLUMN = 7;
class App extends Component {
constructor(props) {
super(props);
this.state = {
currentPlayer: 'A', // 2 players game: A and B
playerWon: undefined,
board: Array.apply(null, {length: ROW}).map(() => new Array(COLUMN))
};
}
_dropItem (e) {
const playedColumn = parseInt(e.target.value);
if ((playedColumn < 0) || (playedColumn > 6) || isNaN(playedColumn)) {
console.log('input is invalid');
return;
}
const column = this.state.board.map((row) => row[playedColumn]);
const row = _.findLastIndex(column, (i) => !i);
this._checkForWinning(row, playedColumn);
}
_countItem (direction, playedRow, playedColumn) {
// direction = {row: 0, column: 1} means row stays constant and column is increasing
// direction = {row: 0, column: -1} means row stays constant and column is decreasing
var counter = 0;
for(let i = 1; i < 4; i++) {
const row = playedRow + direction.row * i;
const column = playedColumn + direction.column * i;
if (row < ROW && row >= 0 && column < COLUMN && column >= 0) {
const item = this.state.board[row][column];
if (item === this.state.currentPlayer) {
counter += 1;
} else {
break;
}
} else {
break;
}
}
return counter;
}
_checkHorizontal (playedRow, playedColumn) {
const countRight = this._countItem({row: 0, column: 1}, playedRow, playedColumn);
const countLeft = this._countItem({row: 0, column: -1}, playedRow, playedColumn);
return countLeft + countRight >= 3;
}
_checkVerical (playedRow, playedColumn) {
const countDown = this._countItem({row: 1, column: 0}, playedRow, playedColumn);
const countUp = this._countItem({row: -1, column: 0}, playedRow, playedColumn);
return countDown + countUp >= 3;
}
_checkDiagonalNESW (playedRow, playedColumn) {
const countNE = this._countItem({row: -1, column: 1}, playedRow, playedColumn);
const countSW = this._countItem({row: 1, column: -1}, playedRow, playedColumn);
return countNE + countSW >= 3;
}
_checkDiagonalNWSE (playedRow, playedColumn) {
const countNW = this._countItem({row: 1, column: -1}, playedRow, playedColumn);
const countSE = this._countItem({row: -1, column: 1}, playedRow, playedColumn);
return countNW + countSE >= 3;
}
_checkForWinning (playedRow, playedColumn) {
if (this._checkHorizontal(playedRow, playedColumn)) {
this._updatePlayerWon(this.state.currentPlayer);
}
if (this._checkVerical(playedRow, playedColumn)) {
this._updatePlayerWon(this.state.currentPlayer);
}
if (this._checkDiagonalNESW(playedRow, playedColumn)) {
this._updatePlayerWon(this.state.currentPlayer);
}
if (this._checkDiagonalNWSE(playedRow, playedColumn)) {
this._updatePlayerWon(this.state.currentPlayer);
}
this._updateBoardAndPlayer(playedRow, playedColumn);
}
_updatePlayerWon (playerWon) {
this.setState({
playerWon: playerWon
});
}
_updateBoardAndPlayer(playedRow, playedColumn) {
const board = this.state.board;
const newPlayer = this.state.currentPlayer === 'A' ? 'B' : 'A';
board[playedRow][playedColumn] = this.state.currentPlayer;
this.setState({
board: board,
currentPlayer: newPlayer
});
}
_renderBoard(){
const rows = [];
_.each(this.state.board, (row) => {
return(
rows.push(_.map(row, (i) => {
const elem = i ? i : '-';
let elemStyle = undefined;
switch (i){
case 'A':
elemStyle = styles.itemRed; break;
case 'B':
elemStyle = styles.itemBlue; break;
default:
elemStyle = styles.itemWhite;
};
return (<span style={{display: 'inline-block', ...elemStyle}}>{elem}</span>);
}))
);
});
const board = _.map(rows, (column) => <div>{column}</div>);
return board;
}
_renderWinnerBanner () {
if (this.state.playerWon) {
return (
<div>{this.state.playerWon + ' is winning.'}</div>
);
} else {
return(<div>Still playing</div>);
};
}
render() {
const dropItem = this._dropItem.bind(this);
return (
<div>
<div style={{marginTop: "10em"}}>
{this._renderBoard()}
</div>
<input onChange={dropItem}></input>
{this._renderWinnerBanner()}
</div>
);
}
}
var styles = {
itemBlue: {
height: '50px',
width: '50px',
background: 'blue'
},
itemRed: {
height: '50px',
width: '50px',
background: 'red'
},
itemWhite: {
height: '50px',
width: '50px',
background: 'white'
}
}
export default App;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment