Debug stuff
This commit is contained in:
parent
7b920dd6a9
commit
3f0688d0aa
@ -1,7 +1,157 @@
|
||||
const chars = ["AN","AR","AT","CA","CH","CO","DE","DI","EL","EN","ER","ES","HE","IA","IL","IN","IO","LA","LE","LI","LL","MA","ME","NA","NE","NO","NT","OL","ON","OR","PE","RA","RE","RI","RO","SE","SI","SO","ST","TA","TE","TI","TO","TR","TT","UN","TO","RE","ER","ON","CO","DI","TA","EN","IN","TE","AT","RA","AN","NO","NT","ST","LA","AR","AL","OR","CH","RI","TI","IO","LE","DE","ES","NE","ME","TT","EL","PE","IL","UN","IA","LI","SE","SO","LL","SI","OL","RO","MA","CA","NA","TR","HE","ALE","ALL","ANC","AND","ANT","ARE","ATO","ATT","CHE","CHI","COM","CON","DEL","ELL","ENT","ERA","ERE","ESS","EST","ETT","GLI","ION","LLA","MEN","NON","NTE","NTI","NTO","OLO","ONE","ONO","PER","QUE","SON","STA","STO","TAT","TRA","TTO","UNA","VER","ZIO","ENT","CHE","ATO","PER","NTE","CON","ELL","STA","ARE","MEN","ION","DEL","LLA","TTO","TAT","ESS","ERE","ETT","EST","ONE","ONO","ZIO","NON","ERA","CHI","GLI","COM","TRA","STO","NTI","SON","VER","ATT","UNA","QUE","NTO","AND","ALL","OLO","ANC","ANT","ALE"];
|
||||
"use strict";
|
||||
|
||||
const SYLLABE_LIST = ["AN","AR","AT","CA","CH","CO","DE","DI","EL","EN","ER","ES","HE","IA","IL","IN","IO","LA","LE","LI","LL","MA","ME","NA","NE","NO","NT","OL","ON","OR","PE","RA","RE","RI","RO","SE","SI","SO","ST","TA","TE","TI","TO","TR","TT","UN","TO","RE","ER","ON","CO","DI","TA","EN","IN","TE","AT","RA","AN","NO","NT","ST","LA","AR","AL","OR","CH","RI","TI","IO","LE","DE","ES","NE","ME","TT","EL","PE","IL","UN","IA","LI","SE","SO","LL","SI","OL","RO","MA","CA","NA","TR","HE","ALE","ALL","ANC","AND","ANT","ARE","ATO","ATT","CHE","CHI","COM","CON","DEL","ELL","ENT","ERA","ERE","ESS","EST","ETT","GLI","ION","LLA","MEN","NON","NTE","NTI","NTO","OLO","ONE","ONO","PER","QUE","SON","STA","STO","TAT","TRA","TTO","UNA","VER","ZIO","ENT","CHE","ATO","PER","NTE","CON","ELL","STA","ARE","MEN","ION","DEL","LLA","TTO","TAT","ESS","ERE","ETT","EST","ONE","ONO","ZIO","NON","ERA","CHI","GLI","COM","TRA","STO","NTI","SON","VER","ATT","UNA","QUE","NTO","AND","ALL","OLO","ANC","ANT","ALE"];
|
||||
const BOARD_DEFINITION = `
|
||||
# # 1 1 1 2 1 1 # #;
|
||||
# # 1 1 1 1 1 1 # #;
|
||||
1 1 2 2 2 2 2 2 1 1;
|
||||
1 1 2 2 2 # 2 2 1 1;
|
||||
2 1 2 2 1 2 2 2 1 1;
|
||||
1 1 2 2 2 2 2 2 1 1;
|
||||
1 1 2 2 2 2 2 2 1 1;
|
||||
1 1 2 2 2 2 2 2 1 1;
|
||||
# # 1 1 1 1 1 1 # #;
|
||||
# # 1 1 1 1 1 1 # #;
|
||||
`
|
||||
|
||||
Array.prototype.removeIf = function(callback) {
|
||||
var i = this.length;
|
||||
while (i--) {
|
||||
if (callback(this[i], i)) {
|
||||
this.splice(i, 1);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
function parseBoard(boardString) {
|
||||
boardString = boardString.replaceAll(/[^#12;]/gi, "");
|
||||
let boardStringArray = boardString.split(";").filter(x => x.length > 0);
|
||||
const boardHeight = boardStringArray.length;
|
||||
if (boardHeight <= 0) {
|
||||
throw new Error("Board parsing error: empty board");
|
||||
}
|
||||
const boardWidth = boardStringArray[0].length;
|
||||
if (boardWidth <= 0) {
|
||||
throw new Error("Board parsing error: empty board");
|
||||
}
|
||||
boardStringArray.forEach(v => {
|
||||
if (v.length !== boardWidth) {
|
||||
throw new Error(`Board parsing error: expected width ${boardWidth}, got ${v.length}`);
|
||||
}
|
||||
});
|
||||
const board = boardStringArray.map(row => {
|
||||
return Array.from(row).map(char => {
|
||||
switch (char) {
|
||||
case '#': {
|
||||
return {
|
||||
type: "black",
|
||||
cost: NaN,
|
||||
occludedOnRotation: [false, false, false, false]
|
||||
}
|
||||
}
|
||||
case '1': {
|
||||
return {
|
||||
type: "occupiable",
|
||||
cost: 1,
|
||||
occludedOnRotation: [false, false, false, false]
|
||||
}
|
||||
}
|
||||
case '2': {
|
||||
return {
|
||||
type: "occupiable",
|
||||
cost: 2,
|
||||
occludedOnRotation: [false, false, false, false]
|
||||
}
|
||||
}
|
||||
default:
|
||||
throw new Error(`Unknown character: ${char}`);
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
// Blocks for rotation 0
|
||||
for (let col = 0; col < boardWidth; col++) {
|
||||
let blockedOnThisRotation = false;
|
||||
for (let row = 0; row < boardHeight; row++) {
|
||||
const square = board[row][col];
|
||||
if (!blockedOnThisRotation) {
|
||||
if (square.type === "black") {
|
||||
blockedOnThisRotation = true;
|
||||
}
|
||||
}
|
||||
if (square.type === "occupiable") {
|
||||
square.occludedOnRotation[0] = blockedOnThisRotation;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Blocks for rotation 1
|
||||
for (let row = 0; row < boardHeight; row++) {
|
||||
let blockedOnThisRotation = false;
|
||||
for (let col = 0; col < boardWidth; col++) {
|
||||
const square = board[row][col];
|
||||
if (!blockedOnThisRotation) {
|
||||
if (square.type === "black") {
|
||||
blockedOnThisRotation = true;
|
||||
}
|
||||
}
|
||||
if (square.type === "occupiable") {
|
||||
square.occludedOnRotation[1] = blockedOnThisRotation;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Blocks for rotation 2
|
||||
for (let col = 0; col < boardWidth; col++) {
|
||||
let blockedOnThisRotation = false;
|
||||
for (let row = boardHeight - 1; row >= 0; row--) {
|
||||
const square = board[row][col];
|
||||
if (!blockedOnThisRotation) {
|
||||
if (square.type === "black") {
|
||||
blockedOnThisRotation = true;
|
||||
}
|
||||
}
|
||||
if (square.type === "occupiable") {
|
||||
square.occludedOnRotation[2] = blockedOnThisRotation;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Blocks for rotation 3
|
||||
for (let row = 0; row < boardHeight; row++) {
|
||||
let blockedOnThisRotation = false;
|
||||
for (let col = boardWidth - 1; col >= 0; col--) {
|
||||
const square = board[row][col];
|
||||
if (!blockedOnThisRotation) {
|
||||
if (square.type === "black") {
|
||||
blockedOnThisRotation = true;
|
||||
}
|
||||
}
|
||||
if (square.type === "occupiable") {
|
||||
square.occludedOnRotation[3] = blockedOnThisRotation;
|
||||
}
|
||||
}
|
||||
}
|
||||
return board;
|
||||
}
|
||||
|
||||
function randomID() {
|
||||
var u8 = crypto.getRandomValues(new Uint8Array(3));
|
||||
return Array.from(u8).map(n => chars[n % chars.length]).reduce((a, b) => a + b);
|
||||
const u8 = crypto.getRandomValues(new Uint8Array(3));
|
||||
return Array.from(u8).map(n => SYLLABE_LIST[n % SYLLABE_LIST.length]).reduce((a, b) => a + b);
|
||||
}
|
||||
|
||||
const INITIAL_BOARD = parseBoard(BOARD_DEFINITION);
|
||||
|
||||
console.log(INITIAL_BOARD);
|
||||
|
||||
const ACTIONS_QUEUE = []
|
||||
|
||||
function buildGridArray(rows, columns, defaultValue) {
|
||||
const array = new Array(rows);
|
||||
for (let i = 0; i < rows; i++) {
|
||||
array[i] = new Array(columns).fill(defaultValue);
|
||||
}
|
||||
return array;
|
||||
}
|
||||
|
||||
document.addEventListener("DOMContentLoaded", e => {
|
||||
@ -10,6 +160,158 @@ document.addEventListener("DOMContentLoaded", e => {
|
||||
const gameCodeLink = document.getElementById("game-code-link");
|
||||
const newGameLink = document.getElementById("new-game-link");
|
||||
const mainBody = document.getElementById("main-body");
|
||||
const boardElem = document.getElementById("board");
|
||||
const rotateLeftElem = document.getElementById("rotate-left");
|
||||
const rotateRightElem = document.getElementById("rotate-right");
|
||||
|
||||
function updateDatasetValue(elem, name, value) {
|
||||
if (elem.dataset[name] !== '' + value) {
|
||||
elem.dataset[name] = value;
|
||||
}
|
||||
}
|
||||
|
||||
function syncBlock(board, boardElems, rowIndex, colIndex, gameState) {
|
||||
const square = board[rowIndex][colIndex];
|
||||
const squareElem = boardElems[rowIndex][colIndex];
|
||||
updateDatasetValue(squareElem, "cost", square.cost);
|
||||
updateDatasetValue(squareElem, "row", rowIndex);
|
||||
updateDatasetValue(squareElem, "col", colIndex);
|
||||
const currentPlacement = gameState.boardPlacements[rowIndex][colIndex];
|
||||
updateDatasetValue(squareElem, "square_type", square.type);
|
||||
updateDatasetValue(squareElem, "occluded", square.occludedOnRotation[gameState.rotation]);
|
||||
|
||||
switch (square.type) {
|
||||
case "occupiable": {
|
||||
switch (currentPlacement) {
|
||||
case "free": {
|
||||
updateDatasetValue(squareElem, "occupation_state", "free");
|
||||
updateDatasetValue(squareElem, "occupied_by", -1);
|
||||
break;
|
||||
}
|
||||
case "player0": {
|
||||
updateDatasetValue(squareElem, "occupation_state", "occupied");
|
||||
updateDatasetValue(squareElem, "occupied_by", 0);
|
||||
break;
|
||||
}
|
||||
case "player1": {
|
||||
updateDatasetValue(squareElem, "occupation_state", "occupied");
|
||||
updateDatasetValue(squareElem, "occupied_by", 1);
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
throw new Error("Undefined current placement type: " + currentPlacement);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
case "black": {
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
throw new Error("Undefined square type: " + square.type);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function cloneGridArray(array) {
|
||||
const rows = array.length;
|
||||
const cols = array[0].length;
|
||||
const cloned = new Array(rows);
|
||||
for (let row = 0; row < rows; row++) {
|
||||
const clonedRow = new Array(cols);
|
||||
for (let col = 0; col < cols; col++) {
|
||||
clonedRow[col] = array[row][col];
|
||||
}
|
||||
cols[row] = clonedRow;
|
||||
}
|
||||
return cloned;
|
||||
}
|
||||
|
||||
function editState(state, action) {
|
||||
const copy = {
|
||||
myTurn: state.myTurn,
|
||||
rotation: state.rotation,
|
||||
boardPlacements: cloneGridArray(state.boardPlacements)
|
||||
}
|
||||
switch (action) {
|
||||
case "occupy_square": {
|
||||
copy[action.row][action.col] = "";
|
||||
return copy;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function enqueueAction(action) {
|
||||
if (action.type === "occupy_square") {
|
||||
ACTIONS_QUEUE.removeIf(action => action.type === "occupy_square");
|
||||
}
|
||||
ACTIONS_QUEUE.push(action);
|
||||
console.debug("Added an element to the actions queue", ACTIONS_QUEUE);
|
||||
}
|
||||
|
||||
function onRequestRotateBy(board, delta, initialGameState) {
|
||||
initialGameState
|
||||
}
|
||||
|
||||
function onSquareClick(square, squareElem, rowIndex, colIndex) {
|
||||
console.debug(`Clicked square at ${rowIndex},${colIndex}`, square, squareElem);
|
||||
switch (square.type) {
|
||||
case "occupiable": {
|
||||
enqueueAction({
|
||||
actor: "me",
|
||||
type: "occupy_square",
|
||||
row: rowIndex,
|
||||
col: colIndex
|
||||
});
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function buildInitialBoard(board) {
|
||||
const rows = board.length;
|
||||
const columns = board[0].length;
|
||||
boardElem.style.gridTemplateRows = `repeat(${rows}, 1fr)`;
|
||||
boardElem.style.gridTemplateColumns = `repeat(${columns}, 1fr)`;
|
||||
const boardElems = [];
|
||||
const initialGameState = {
|
||||
myTurn: true,
|
||||
rotation: 0,
|
||||
boardPlacements: buildGridArray(rows, columns, "free")
|
||||
};
|
||||
initialGameState.boardPlacements[0][3] = "player1";
|
||||
initialGameState.boardPlacements[1][3] = "player1";
|
||||
initialGameState.boardPlacements[2][3] = "player1";
|
||||
initialGameState.boardPlacements[3][3] = "player1";
|
||||
initialGameState.boardPlacements[0][4] = "player0";
|
||||
initialGameState.boardPlacements[3][3] = "player1";
|
||||
initialGameState.boardPlacements[4][3] = "player1";
|
||||
initialGameState.boardPlacements[5][3] = "player1";
|
||||
board.forEach((row, rowIndex) => {
|
||||
row.forEach((square, colIndex) => {
|
||||
const squareElem = document.createElement("div");
|
||||
squareElem.classList.add("square");
|
||||
squareElem.onclick = () => {
|
||||
onSquareClick(square, squareElem, rowIndex, colIndex);
|
||||
}
|
||||
if (boardElems[rowIndex] == null) {
|
||||
boardElems[rowIndex] = [];
|
||||
}
|
||||
boardElems[rowIndex][colIndex] = squareElem;
|
||||
syncBlock(board, boardElems, rowIndex, colIndex, initialGameState);
|
||||
boardElem.appendChild(squareElem);
|
||||
});
|
||||
});
|
||||
|
||||
rotateLeftElem.onclick = () => {
|
||||
onRequestRotateBy(board, 1, initialGameState);
|
||||
}
|
||||
rotateRightElem.onclick = () => {
|
||||
onRequestRotateBy(board, -1, initialGameState);
|
||||
}
|
||||
}
|
||||
|
||||
buildInitialBoard(INITIAL_BOARD);
|
||||
|
||||
const eb = new EventBus(`${document.location.origin}/eventbus`);
|
||||
eb.enableReconnect(true);
|
||||
|
@ -12,8 +12,16 @@
|
||||
<div id="main-body">
|
||||
<h1>Connect 2x</h1>
|
||||
<p>Game code: <span id="game-code"></span> <a id="game-code-link" href="#">[share]</a> <a id="new-game" href="/">[new game]</a></p>
|
||||
<main id="board">
|
||||
|
||||
<main id="game">
|
||||
<h2 id="turn-label">Please wait...</h2>
|
||||
<h3 id="move-points-title">Move points remaining: <span id="move-points-value">0</span></h3>
|
||||
<div id="board-viewer">
|
||||
<div id="board"></div>
|
||||
</div>
|
||||
<div id="buttons-container">
|
||||
<button id="rotate-left" class="btn">↺</button>
|
||||
<button id="rotate-right" class="btn">↻</button>
|
||||
</div>
|
||||
</main>
|
||||
</div>
|
||||
</body>
|
||||
|
@ -21,3 +21,60 @@ h1 {
|
||||
font-size: 75%;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
#game {
|
||||
perspective: 2000px;
|
||||
}
|
||||
|
||||
#board-viewer {
|
||||
width: 82vmin;
|
||||
height: 82vmin;
|
||||
margin: auto;
|
||||
position: relative;
|
||||
transform: translateY(-10vmin) rotate3d(1, 0, 0, 55deg);
|
||||
}
|
||||
|
||||
#board {
|
||||
display: grid;
|
||||
background: black;
|
||||
box-sizing: border-box;
|
||||
width: 82vmin;
|
||||
height: 82vmin;
|
||||
grid-column-gap: 0.13rem;
|
||||
grid-row-gap: 0.13rem;
|
||||
padding: 0.52rem;
|
||||
border-radius: 0.6rem;
|
||||
|
||||
position: absolute;
|
||||
left: 0;
|
||||
top: 0;
|
||||
|
||||
transform: rotate(0deg);
|
||||
transition: transform 0.5s ease-in-out;
|
||||
box-shadow: 0 0 40px 0 #00000061;
|
||||
}
|
||||
|
||||
.square {
|
||||
display: inline-block;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
background: #b1b1b1;
|
||||
border-radius: 0.3rem;
|
||||
}
|
||||
|
||||
.square[data-square_type="black"] {
|
||||
visibility: hidden;
|
||||
}
|
||||
.square[data-square_type="occupiable"][data-cost="2"][data-occupation_state="free"] {
|
||||
background: rgba(255, 230, 190, 1);
|
||||
}
|
||||
.square[data-square_type="occupiable"][data-occluded="true"] {
|
||||
filter: brightness(0.5);
|
||||
}
|
||||
.square[data-square_type="occupiable"][data-occupation_state="occupied"][data-occupied_by="0"] {
|
||||
background: rgb(43, 131, 240);
|
||||
}
|
||||
.square[data-square_type="occupiable"][data-occupation_state="occupied"][data-occupied_by="1"] {
|
||||
background: rgb(122, 215, 0);
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user