Skip to content

Instantly share code, notes, and snippets.

@aire-con-gas
Created April 28, 2019 14:32
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save aire-con-gas/74db149e1dbeb69c3b02c8434c025b2b to your computer and use it in GitHub Desktop.
Save aire-con-gas/74db149e1dbeb69c3b02c8434c025b2b to your computer and use it in GitHub Desktop.
JS Bin // source https://jsbin.com/xukefoc
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width">
<title>JS Bin</title>
<style id="jsbin-css">
body {
font-size: 32px;
font-family: sans-serif;
width: 295px;
margin: 1em auto;
}
#canvas {
width: 296px;
float: left;
}
.row {
width: 296px;
float: left;
}
.row div {
width: 95px;
padding-top: 25px;
height: 61px;
float: left;
text-align: center;
}
.top {
border-bottom: 5px solid black;
}
.bottom {
border-top: 5px solid black;
}
.left {
border-right: 5px solid black;
}
.right {
border-left: 5px solid black;
}
#draw, #winner {
display: none;
text-align: center;
padding-top: 0.5em;
clear: both;
}
</style>
</head>
<body>
<div id="canvas">
<div class="top row">
<div class="left"></div>
<div class="middle"></div>
<div class="right"></div>
</div>
<div class="middle row">
<div class="left"></div>
<div class="middle"></div>
<div class="right"></div>
</div>
<div class="bottom row">
<div class="left"></div>
<div class="middle"></div>
<div class="right"></div>
</div>
</div>
<div id="winner">
WINNER!
</div>
<div id="draw">
DRAW!
</div>
<script id="jsbin-javascript">
"use strict";
var _createClass = (function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })();
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
var X = "X";
var O = "O";
var WINNING_STATE = {
NONE: 0,
X: 1,
O: 2,
DRAW: 3
};
var Model = (function () {
function Model() {
_classCallCheck(this, Model);
this.gameState = [];
this.isXTurn = true;
this.moveCount = 0;
var i = undefined;
for (i = 0; i < 3; i++) {
this.gameState[i] = [];
}
}
_createClass(Model, [{
key: "getSquare",
value: function getSquare(row, col) {
return this.gameState[col][row];
}
}, {
key: "selectX",
value: function selectX(row, col) {
this.selectSquare(X, row, col);
}
}, {
key: "selectO",
value: function selectO(row, col) {
this.selectSquare(O, row, col);
}
}, {
key: "selectSquare",
value: function selectSquare(type, row, col) {
if (type != X && type != O) {
throw new TypeError("Invalid type: " + type);
}
if (row < 0 || row > 2 || col < 0 || col > 2) {
throw new RangeError("Invalid range: " + row + ", " + col);
}
this.gameState[col][row] = type;
this.moveCount++;
// this.printGameState();
}
}, {
key: "printGameState",
value: function printGameState() {
var i = undefined;
for (i = 0; i < 3; i++) {
console.log(this.gameState[i]);
}
}
}]);
return Model;
})();
var Controller = (function () {
function Controller() {
_classCallCheck(this, Controller);
this.model = new Model();
this.winningState = WINNING_STATE.NONE;
this.squares = document.querySelectorAll(".row div");
this.bindAllSquareClicks();
}
// ---
_createClass(Controller, [{
key: "winningStateForXAtPosition",
value: function winningStateForXAtPosition(row, col) {
return this.winningStateForTypeAtPosition(X, row, col);
}
}, {
key: "winningStateForOAtPosition",
value: function winningStateForOAtPosition(row, col) {
return this.winningStateForTypeAtPosition(O, row, col);
}
}, {
key: "winningStateForTypeAtPosition",
value: function winningStateForTypeAtPosition(type, row, col) {
var gameState = this.model.gameState; // Convenience
// Check horizontally
var col_ = undefined;
for (col_ = 0; col_ < 3; col_++) {
if (type != this.model.getSquare(row, col_)) {
break;
}
}
if (col_ == 3) {
return WINNING_STATE[type];
}
// Check vertically
var row_ = undefined;
for (row_ = 0; row_ < 3; row_++) {
if (type != this.model.getSquare(row_, col)) {
break;
}
}
if (row_ == 3) {
return WINNING_STATE[type];
}
// Check diagonal
if (row == col) {
var rowcol = undefined;
for (rowcol = 0; rowcol < 3; rowcol++) {
if (type != this.model.getSquare(rowcol, rowcol)) {
break;
}
}
if (rowcol == 3) {
return WINNING_STATE[type];
}
}
// Check anti-diagonal
if (row + col == 2) {
var rowcol = undefined;
for (rowcol = 0; rowcol < 3; rowcol++) {
if (type != this.model.getSquare(rowcol, 2 - rowcol)) {
break;
}
}
if (rowcol == 3) {
return WINNING_STATE[type];
}
}
if (this.model.moveCount == 9) {
return WINNING_STATE.DRAW;
}
return WINNING_STATE.NONE;
}
}, {
key: "bindAllSquareClicks",
value: function bindAllSquareClicks() {
var _this = this;
var i = undefined;
var _loop = function () {
var that = _this;
var ii = i;
_this.squares[i].addEventListener("click", function squareClicked() {
if (WINNING_STATE.NONE != that.winningState) {
this.removeEventListener("click", squareClicked);
return;
}
var row = ii % 3;
var col = Math.floor(ii / 3);
if (that.model.isXTurn) {
that.model.selectX(row, col);
that.drawX(row, col);
that.winningState = that.winningStateForXAtPosition(row, col);
if (WINNING_STATE.X == that.winningState) {
that.drawXAsWinning();
}
} else {
that.model.selectO(row, col);
that.drawO(row, col);
that.winningState = that.winningStateForOAtPosition(row, col);
if (WINNING_STATE.O == that.winningState) {
that.drawOAsWinning();
}
}
if (WINNING_STATE.DRAW == that.winningState) {
that.drawDraw();
}
that.model.isXTurn = !that.model.isXTurn;
this.removeEventListener("click", squareClicked);
});
};
for (i = 0; i < 9; i++) {
_loop();
}
}
}, {
key: "drawX",
value: function drawX(row, col) {
this.squares[col * 3 + row].innerHTML = X;
}
}, {
key: "drawO",
value: function drawO(row, col) {
this.squares[col * 3 + row].innerHTML = O;
}
}, {
key: "drawXAsWinning",
value: function drawXAsWinning() {
document.querySelector("#winner").style.display = "block";
}
}, {
key: "drawOAsWinning",
value: function drawOAsWinning() {
document.querySelector("#winner").style.display = "block";
}
}, {
key: "drawDraw",
value: function drawDraw() {
document.querySelector("#draw").style.display = "block";
}
}]);
return Controller;
})();
new Controller();
</script>
<script id="jsbin-source-css" type="text/css">body {
font-size: 32px;
font-family: sans-serif;
width: 295px;
margin: 1em auto;
}
#canvas {
width: 296px;
float: left;
}
.row {
width: 296px;
float: left;
}
.row div {
width: 95px;
padding-top: 25px;
height: 61px;
float: left;
text-align: center;
}
.top {
border-bottom: 5px solid black;
}
.bottom {
border-top: 5px solid black;
}
.left {
border-right: 5px solid black;
}
.right {
border-left: 5px solid black;
}
#draw, #winner {
display: none;
text-align: center;
padding-top: 0.5em;
clear: both;
}</script>
<script id="jsbin-source-javascript" type="text/javascript">const X = "X";
const O = "O";
const WINNING_STATE = {
NONE: 0,
X: 1,
O: 2,
DRAW: 3,
}
class Model {
constructor() {
this.gameState = [];
this.isXTurn = true;
this.moveCount = 0;
let i;
for (i = 0; i < 3; i++) {
this.gameState[i] = [];
}
}
getSquare(row, col) {
return this.gameState[col][row]
}
selectX(row, col) {
this.selectSquare(X, row, col);
}
selectO(row, col) {
this.selectSquare(O, row, col);
}
selectSquare(type, row, col) {
if (type != X && type != O) {
throw new TypeError("Invalid type: " + type)
}
if (row < 0 || row > 2 || col < 0 || col > 2) {
throw new RangeError("Invalid range: " + row + ", " + col)
}
this.gameState[col][row] = type;
this.moveCount++;
// this.printGameState();
}
printGameState() {
let i;
for (i = 0; i < 3; i++) {
console.log(this.gameState[i]);
}
}
}
class Controller {
constructor() {
this.model = new Model();
this.winningState = WINNING_STATE.NONE;
this.squares = document.querySelectorAll(".row div");
this.bindAllSquareClicks();
}
winningStateForXAtPosition(row, col) {
return this.winningStateForTypeAtPosition(X, row, col);
}
winningStateForOAtPosition(row, col) {
return this.winningStateForTypeAtPosition(O, row, col);
}
winningStateForTypeAtPosition(type, row, col) {
let gameState = this.model.gameState // Convenience
// Check horizontally
let col_;
for (col_ = 0; col_ < 3; col_++) {
if (type != this.model.getSquare(row, col_)) {
break;
}
}
if (col_ == 3) {
return WINNING_STATE[type]
}
// Check vertically
let row_;
for (row_ = 0; row_ < 3; row_++) {
if (type != this.model.getSquare(row_, col)) {
break;
}
}
if (row_ == 3) {
return WINNING_STATE[type]
}
// Check diagonal
if (row == col) {
let rowcol;
for (rowcol = 0; rowcol < 3; rowcol++) {
if (type != this.model.getSquare(rowcol, rowcol)) {
break;
}
}
if (rowcol == 3) {
return WINNING_STATE[type]
}
}
// Check anti-diagonal
if (row + col == 2) {
let rowcol;
for (rowcol = 0; rowcol < 3; rowcol++) {
if (type != this.model.getSquare(rowcol, 2 - rowcol)) {
break;
}
}
if (rowcol == 3) {
return WINNING_STATE[type]
}
}
if (this.model.moveCount == 9) {
return WINNING_STATE.DRAW
}
return WINNING_STATE.NONE
}
bindAllSquareClicks() {
let i;
for (i = 0; i < 9; i++) {
let that = this;
let ii = i;
this.squares[i].addEventListener("click", function squareClicked() {
if (WINNING_STATE.NONE != that.winningState) {
this.removeEventListener("click", squareClicked);
return;
}
let row = ii % 3;
let col = Math.floor(ii / 3);
if (that.model.isXTurn) {
that.model.selectX(row, col);
that.drawX(row, col);
that.winningState = that.winningStateForXAtPosition(row, col)
if (WINNING_STATE.X == that.winningState) {
that.drawXAsWinning()
}
} else {
that.model.selectO(row, col);
that.drawO(row, col);
that.winningState = that.winningStateForOAtPosition(row, col)
if (WINNING_STATE.O == that.winningState) {
that.drawOAsWinning()
}
}
if (WINNING_STATE.DRAW == that.winningState) {
that.drawDraw()
}
that.model.isXTurn = !that.model.isXTurn;
this.removeEventListener("click", squareClicked);
});
}
}
drawX(row, col) {
this.squares[col * 3 + row].innerHTML = X;
}
drawO(row, col) {
this.squares[col * 3 + row].innerHTML = O;
}
drawXAsWinning() {
document.querySelector("#winner").style.display = "block"
}
drawOAsWinning() {
document.querySelector("#winner").style.display = "block"
}
drawDraw() {
document.querySelector("#draw").style.display = "block"
}
}
// ---
new Controller();</script></body>
</html>
body {
font-size: 32px;
font-family: sans-serif;
width: 295px;
margin: 1em auto;
}
#canvas {
width: 296px;
float: left;
}
.row {
width: 296px;
float: left;
}
.row div {
width: 95px;
padding-top: 25px;
height: 61px;
float: left;
text-align: center;
}
.top {
border-bottom: 5px solid black;
}
.bottom {
border-top: 5px solid black;
}
.left {
border-right: 5px solid black;
}
.right {
border-left: 5px solid black;
}
#draw, #winner {
display: none;
text-align: center;
padding-top: 0.5em;
clear: both;
}
"use strict";
var _createClass = (function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })();
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
var X = "X";
var O = "O";
var WINNING_STATE = {
NONE: 0,
X: 1,
O: 2,
DRAW: 3
};
var Model = (function () {
function Model() {
_classCallCheck(this, Model);
this.gameState = [];
this.isXTurn = true;
this.moveCount = 0;
var i = undefined;
for (i = 0; i < 3; i++) {
this.gameState[i] = [];
}
}
_createClass(Model, [{
key: "getSquare",
value: function getSquare(row, col) {
return this.gameState[col][row];
}
}, {
key: "selectX",
value: function selectX(row, col) {
this.selectSquare(X, row, col);
}
}, {
key: "selectO",
value: function selectO(row, col) {
this.selectSquare(O, row, col);
}
}, {
key: "selectSquare",
value: function selectSquare(type, row, col) {
if (type != X && type != O) {
throw new TypeError("Invalid type: " + type);
}
if (row < 0 || row > 2 || col < 0 || col > 2) {
throw new RangeError("Invalid range: " + row + ", " + col);
}
this.gameState[col][row] = type;
this.moveCount++;
// this.printGameState();
}
}, {
key: "printGameState",
value: function printGameState() {
var i = undefined;
for (i = 0; i < 3; i++) {
console.log(this.gameState[i]);
}
}
}]);
return Model;
})();
var Controller = (function () {
function Controller() {
_classCallCheck(this, Controller);
this.model = new Model();
this.winningState = WINNING_STATE.NONE;
this.squares = document.querySelectorAll(".row div");
this.bindAllSquareClicks();
}
// ---
_createClass(Controller, [{
key: "winningStateForXAtPosition",
value: function winningStateForXAtPosition(row, col) {
return this.winningStateForTypeAtPosition(X, row, col);
}
}, {
key: "winningStateForOAtPosition",
value: function winningStateForOAtPosition(row, col) {
return this.winningStateForTypeAtPosition(O, row, col);
}
}, {
key: "winningStateForTypeAtPosition",
value: function winningStateForTypeAtPosition(type, row, col) {
var gameState = this.model.gameState; // Convenience
// Check horizontally
var col_ = undefined;
for (col_ = 0; col_ < 3; col_++) {
if (type != this.model.getSquare(row, col_)) {
break;
}
}
if (col_ == 3) {
return WINNING_STATE[type];
}
// Check vertically
var row_ = undefined;
for (row_ = 0; row_ < 3; row_++) {
if (type != this.model.getSquare(row_, col)) {
break;
}
}
if (row_ == 3) {
return WINNING_STATE[type];
}
// Check diagonal
if (row == col) {
var rowcol = undefined;
for (rowcol = 0; rowcol < 3; rowcol++) {
if (type != this.model.getSquare(rowcol, rowcol)) {
break;
}
}
if (rowcol == 3) {
return WINNING_STATE[type];
}
}
// Check anti-diagonal
if (row + col == 2) {
var rowcol = undefined;
for (rowcol = 0; rowcol < 3; rowcol++) {
if (type != this.model.getSquare(rowcol, 2 - rowcol)) {
break;
}
}
if (rowcol == 3) {
return WINNING_STATE[type];
}
}
if (this.model.moveCount == 9) {
return WINNING_STATE.DRAW;
}
return WINNING_STATE.NONE;
}
}, {
key: "bindAllSquareClicks",
value: function bindAllSquareClicks() {
var _this = this;
var i = undefined;
var _loop = function () {
var that = _this;
var ii = i;
_this.squares[i].addEventListener("click", function squareClicked() {
if (WINNING_STATE.NONE != that.winningState) {
this.removeEventListener("click", squareClicked);
return;
}
var row = ii % 3;
var col = Math.floor(ii / 3);
if (that.model.isXTurn) {
that.model.selectX(row, col);
that.drawX(row, col);
that.winningState = that.winningStateForXAtPosition(row, col);
if (WINNING_STATE.X == that.winningState) {
that.drawXAsWinning();
}
} else {
that.model.selectO(row, col);
that.drawO(row, col);
that.winningState = that.winningStateForOAtPosition(row, col);
if (WINNING_STATE.O == that.winningState) {
that.drawOAsWinning();
}
}
if (WINNING_STATE.DRAW == that.winningState) {
that.drawDraw();
}
that.model.isXTurn = !that.model.isXTurn;
this.removeEventListener("click", squareClicked);
});
};
for (i = 0; i < 9; i++) {
_loop();
}
}
}, {
key: "drawX",
value: function drawX(row, col) {
this.squares[col * 3 + row].innerHTML = X;
}
}, {
key: "drawO",
value: function drawO(row, col) {
this.squares[col * 3 + row].innerHTML = O;
}
}, {
key: "drawXAsWinning",
value: function drawXAsWinning() {
document.querySelector("#winner").style.display = "block";
}
}, {
key: "drawOAsWinning",
value: function drawOAsWinning() {
document.querySelector("#winner").style.display = "block";
}
}, {
key: "drawDraw",
value: function drawDraw() {
document.querySelector("#draw").style.display = "block";
}
}]);
return Controller;
})();
new Controller();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment