JSFiddle - React, Tailwind, and code Playground
by bgmort
HTML
<h1>RoboTacToe</h1>
Team 1:
<select data-team="1" id="team1Type">
<option selected value="random">Random</option>
<option value="sequential">Sequential</option>
<option value="empty">Empty</option>
</select>
<div>
<textarea name="" id="team1Code" cols="50" rows="20"></textarea>
</div>
Team 2:
<select data-team="2" id="team2Type">
<option value="random">Random</option>
<option selected value="sequential">Sequential</option>
<option value="empty">Empty</option>
</select>
<div>
<textarea name="" id="team2Code" cols="50" rows="20"></textarea>
</div>
<p>Results are logged in the console, for now.</p>
<button id="playButton">Play</button>
<button id="play1000Button">Play 1000 Games</button>
<div id="board">
<div id="r0" class="row r0">
<div id="c1" class="cell c0"></div>
<div id="c2" class="cell c1"></div>
<div id="c3" class="cell c2"></div>
</div>
<div id="r1" class="row r1">
<div id="c4" class="cell c0"></div>
<div id="c5" class="cell c1"></div>
<div id="c6" class="cell c2"></div>
</div>
<div id="r2" class="row r2">
<div id="c7" class="cell c0"></div>
<div id="c8" class="cell c1"></div>
<div id="c9" class="cell c2"></div>
</div>
</div>
CSS
#board {
margin: 10px;
width: 470px;
height: 470px;
}
.cell {
width: 150px;
height: 150px;
float: left;
}
.cell:not(:last-child) {
border-right: 10px solid black;
}
.row:not(:last-child) .cell {
border-bottom: 10px solid black;
}
JavaScript
(() => {
'use strict';
var fakeConsole = {
log: console.log,
error: console.error,
};
var noOp = () => {};
var noOpConsole = {
log: noOp,
error: noOp,
};
//keep the scope separate so they can't touch any of our functions
function createRunner(codeStr, console) {
return new Function('console', '"use strict";' + codeStr + '\n;; return nextMove')(console);
}
//generate the lines
var possibleLines = [
[0, 0, 1, 0], //across 1
[0, 1, 1, 0], //across 2
[0, 2, 1, 0], //across 3
[0, 0, 0, 1], //down 1
[1, 0, 0, 1], //down 2
[2, 0, 0, 1], //down 3
[0, 0, 1, 1], //diagonal
[2, 0, -1, 1], //reverse diagonal
]
.map(def => [
{ row: def[0], col: def[1] },
{ row: def[0] + def[2], col: def[1] + def[3] },
{ row: def[0] + def[2] * 2, col: def[1] + def[3] * 2 },
]);
window.possibleLines = possibleLines;
var xSvg = `
<svg view-box="0 0 150 150" width="150" height="150">
<line x1="20" y1="20" x2="130" y2="130" stroke="red" stroke-width="15px" />
<line x1="20" y1="130" x2="130" y2="20" stroke="red" stroke-width="15px" />
</svg>`;
var oSvg = `
<svg view-box="0 0 150 150" width="150" height="150">
<circle cx="50%" cy="50%" r="55" stroke="blue" fill="none" stroke-width="15px"/>
</svg>`;
var Board = {
getSpace: function(board, space) {
return board[space.row][space.col];
},
checkSpace: function(board, space) {
return !board[space.row][space.col];
},
applyMove: function(board, space, teamNum) {
var newBoard = Board.copy(board);
newBoard[space.row][space.col] = teamNum;
return newBoard;
},
copy: function(board) {
return [
board[0].slice(),
board[1].slice(),
board[2].slice(),
];
},
'new': function() {
return [
[0, 0, 0],
[0, 0, 0],
[0, 0, 0],
];
},
validateSpace: function(space) {
return (
space &&
Math.min(space.row, space.col) >= 0 &&
Math.max(space.row, space.col) <= 2
);
},
findWinner: function(board) {
for...