From: Benjamin Auder Date: Wed, 13 May 2026 12:43:30 +0000 (+0200) Subject: Fix Bario + bundle.py, start Emergo X-Git-Url: https://git.auder.net/js/%7B%7B%20path('fos_user_registration_register')%20%7D%7D?a=commitdiff_plain;h=eb85492e272f03a904fb7725d1a8a1d08a722565;p=xogo.git Fix Bario + bundle.py, start Emergo --- diff --git a/bundle.py b/bundle.py index 0b3b451..8876a05 100755 --- a/bundle.py +++ b/bundle.py @@ -17,8 +17,8 @@ IGNORE_FILE_UPDATE = {"app.js"} # Files and folders to totally ignore IGNORE_FILES = { "LICENSE", "README.md", "TODO", "bundle.py", "js/parameters.js.dist", - "initialize.sh", "package-lock.json", "package.json", "js/server.js", ".gitignore", - "nginx_config.example", "start.sh", "stop.sh", "assets.zip", "extras.zip", ".pid" + "initialize.sh", "package-lock.json", "package.json", "js/server.js", + "nginx_config.example", "start.sh", "stop.sh", ".pid", ".gitignore" } IGNORE_DIRS = {".git", "node_modules", DEST_DIR} diff --git a/initialize.sh b/initialize.sh index bf8d705..9e187d0 100755 --- a/initialize.sh +++ b/initialize.sh @@ -1,8 +1,8 @@ -!#/bin/sh +#!/bin/sh wget https://xogo.casa/assets.zip && unzip assets.zip wget https://xogo.casa/extras.zip && unzip extras.zip -cp parameters.js.dist parameters.js +cp js/parameters.js.dist js/parameters.js npm i cd pieces/Avalam && python generateSVG.py && cd ../.. #cd pieces/Emergo && python generateSVG.py && cd ../.. diff --git a/js/base_rules.js b/js/base_rules.js index 1039596..894e8aa 100644 --- a/js/base_rules.js +++ b/js/base_rules.js @@ -1088,7 +1088,6 @@ export default class ChessRules { // DARK METHODS updateEnlightened() { - console.log("new light"); this.oldEnlightened = this.enlightened; this.enlightened = ArrayFun.init(this.size.x, this.size.y, false); // Add pieces positions + all squares reachable by moves (includes Zen): @@ -1098,9 +1097,6 @@ export default class ChessRules { { this.enlightened[x][y] = true; this.getPotentialMovesFrom([x, y]).forEach(m => { - -console.log(m.end); - this.enlightened[m.end.x][m.end.y] = true; }); } diff --git a/package-lock.json b/package-lock.json index b657351..dbc6f9d 100644 --- a/package-lock.json +++ b/package-lock.json @@ -4,7 +4,6 @@ "requires": true, "packages": { "": { - "name": "xogo", "dependencies": { "ws": "^7.5.3" }, diff --git a/package.json b/package.json index acf1faa..eadd717 100644 --- a/package.json +++ b/package.json @@ -1,4 +1,6 @@ { + "name": "xogo", + "version": "0.1.0", "main": "js/server.js", "dependencies": { "ws": "^7.5.3" diff --git a/variants/Bario/class.js b/variants/Bario/class.js index e66f356..0470f4a 100644 --- a/variants/Bario/class.js +++ b/variants/Bario/class.js @@ -103,7 +103,7 @@ export default class BarioRules extends ChessRules { return ( this.board[i][j] != "" && this.getPiece(i, j) == 'u' && - c == this.getColor(i, j) + this.getColor(i, j) == c ); } return false; //never reached @@ -267,39 +267,40 @@ export default class BarioRules extends ChessRules { const color = this.turn; if (this.movesCount <= 1 || move.reset || move.next) { if (!move.next) - this.tryChangeTurn(); + this.tryChangeTurn(move); return; } if (this.subTurn == 0) this.captureUndef = null; //already used - const captureUndef = ( - move.vanish.length == 2 && //exclude subTurn == 0 - move.vanish[1].c != color && - move.vanish[1].p == 'u' - ); - if (typeof move.start.x == "number" && !captureUndef) - // Normal move (including Teleport) - super.tryPostPlayTeleport(move); - else if (typeof move.start.x == "string") { + if (typeof move.start.x == "string") { super.updateReserve( color, move.start.y, this.reserve[color][move.start.y] - 1); if (move.vanish.length == 1 && move.vanish[0].p == 'u') this.definition = move.end; - this.subTurn++; } else { - this.subTurn = 0; - this.captureUndef = move.end; - this.tryChangeTurn(null, captureUndef); + if ( + move.vanish.length == 2 && //exclude subTurn == 0 + move.vanish[1].c != color && + move.vanish[1].p == 'u' + ) { + this.captureUndef = move.end; + } + else + super.tryPostPlayTeleport(move); } + this.tryChangeTurn(move); } -//TODO - // NOTE: not "trying", the turn always change here (TODO?) - tryChangeTurn(move, captureUndef) { - this.definition = null; - this.subTurn = captureUndef ? 0 : 1; - this.turn = C.GetOppTurn(this.turn); - this.movesCount++; + + tryChangeTurn(move) { + if (typeof move.start.x == "string") + this.subTurn++; //0 to 1, or 1 to 2 + else { + this.subTurn = !!this.captureUndef ? 0 : 1; + this.definition = null; + this.turn = C.GetOppTurn(this.turn); + this.movesCount++; + } if (this.options["dark"] && this.movesCount >= 2) this.updateEnlightened(); } diff --git a/variants/Emergo/class.js b/variants/Emergo/class.js index 06e73b1..2635e63 100644 --- a/variants/Emergo/class.js +++ b/variants/Emergo/class.js @@ -1,8 +1,9 @@ -import { ChessRules, Move, PiPo } from "@/js/base_rules"; -import { randInt } from "@/utils/alea"; +import { ChessRules } from "@/js/base_rules"; +import PiPo from "/utils/PiPo.js"; +import Move from "/utils/Move.js"; import { ArrayFun } from "@/utils/array"; -export class EmergoRules extends ChessRules { +export default class EmergoRules extends ChessRules { // Simple encoding: A to L = 1 to 12, from left to right, if white controls. // Lowercase if black controls. @@ -12,152 +13,86 @@ export class EmergoRules extends ChessRules { return null; } - static get HasFlags() { + get hasFlags() { return false; } - - static get HasEnpassant() { + get hasEnpassant() { return false; } - static get DarkBottomRight() { - return true; - } - - // board element == file name: - static board2fen(b) { + // board element == piece class ref: + board2fen(b) { return b; } - static fen2board(f) { + fen2board(f) { return f; } - static IsGoodPosition(position) { - if (position.length == 0) return false; - const rows = position.split("/"); - if (rows.length != V.size.x) return false; - for (let row of rows) { - let sumElts = 0; - for (let i = 0; i < row.length; i++) { - // Add only 0.5 per symbol because 2 per piece - if (row[i].toLowerCase().match(/^[a-lA-L@]$/)) sumElts += 0.5; - else { - const num = parseInt(row[i], 10); - if (isNaN(num) || num <= 0) return false; - sumElts += num; - } - } - if (sumElts != V.size.y) return false; - } - return true; - } - - static GetBoard(position) { + getBoard(position) { const rows = position.split("/"); - let board = ArrayFun.init(V.size.x, V.size.y, ""); + let board = ArrayFun.init(this.size.x, this.size.y, ""); for (let i = 0; i < rows.length; i++) { let j = 0; for (let indexInRow = 0; indexInRow < rows[i].length; indexInRow++) { const character = rows[i][indexInRow]; const num = parseInt(character, 10); - // If num is a number, just shift j: - if (!isNaN(num)) j += num; + if (!isNaN(num)) + // If num is a number, just shift j: + j += num; else // Something at position i,j - board[i][j++] = V.fen2board(character + rows[i][++indexInRow]); + board[i][j++] = this.fen2board(character + rows[i][++indexInRow]); } } return board; } - getPpath(b) { - return "Emergo/" + b; - } - getColor(x, y) { - if (x >= V.size.x) return x == V.size.x ? "w" : "b"; - if (this.board[x][y].charCodeAt(0) < 97) return 'w'; + if (x >= this.size.x) + return x == this.size.x ? "w" : "b"; + if (this.board[x][y].charCodeAt(0) < 97) + return 'w'; return 'b'; } - getPiece() { - return V.PAWN; //unused - } - - static IsGoodFen(fen) { - if (!ChessRules.IsGoodFen(fen)) return false; - const fenParsed = V.ParseFen(fen); - // 3) Check reserves - if ( - !fenParsed.reserve || - !fenParsed.reserve.match(/^([0-9]{1,2},?){2,2}$/) - ) { - return false; - } - return true; - } - - static ParseFen(fen) { - const fenParts = fen.split(" "); - return Object.assign( - ChessRules.ParseFen(fen), - { reserve: fenParts[3] } - ); + getPiece(x, y) { + return this.board[x][y]; } - static get size() { + get size() { return { x: 9, y: 9 }; } - static GenRandInitFen() { - return "9/9/9/9/9/9/9/9/9 w 0 12,12"; - } - - getFen() { - return super.getFen() + " " + this.getReserveFen(); + genRandInitBaseFen() { + return { fen: "9/9/9/9/9/9/9/9/9 w 0 12,12", o: {} }; } - getFenForRepeat() { - return super.getFenForRepeat() + "_" + this.getReserveFen(); - } + static get ReserveArray() { + // Piece type doesn't matter + return ['@']; //TODO :: - getReserveFen() { - return ( - (!this.reserve["w"] ? 0 : this.reserve["w"][V.PAWN]) + "," + - (!this.reserve["b"] ? 0 : this.reserve["b"][V.PAWN]) - ); - } - getReservePpath(index, color) { - return "Emergo/" + (color == 'w' ? 'A' : 'a') + '@'; - } - static get RESERVE_PIECES() { - return [V.PAWN]; //only array length matters } - setOtherVariables(fen) { - const reserve = - V.ParseFen(fen).reserve.split(",").map(x => parseInt(x, 10)); - this.reserve = { w: null, b: null }; - if (reserve[0] > 0) this.reserve['w'] = { [V.PAWN]: reserve[0] }; - if (reserve[1] > 0) this.reserve['b'] = { [V.PAWN]: reserve[1] }; + setOtherVariables(fenParsed) { + super.setOtherVariables(fenParsed); // Local stack of captures during a turn (squares + directions) this.captures = [ [] ]; } atLeastOneCaptureFrom([x, y], color, forbiddenStep) { - for (let s of V.steps[V.BISHOP]) { + for (let s of super.pieces()['b'].both[0].steps) { if ( !forbiddenStep || (s[0] != -forbiddenStep[0] || s[1] != -forbiddenStep[1]) ) { const [i, j] = [x + s[0], y + s[1]]; if ( - V.OnBoard(i + s[0], j + s[1]) && - this.board[i][j] != V.EMPTY && + this.onBoard(i + s[0], j + s[1]) && + this.board[i][j] != "" && this.getColor(i, j) != color && - this.board[i + s[0]][j + s[1]] == V.EMPTY + this.board[i + s[0]][j + s[1]] == "" ) { return true; } @@ -176,10 +111,10 @@ export class EmergoRules extends ChessRules { captures[L-1].square, color, captures[L-1].step) ); } - for (let i = 0; i < V.size.x; i++) { - for (let j=0; j< V.size.y; j++) { + for (let i = 0; i < this.size.x; i++) { + for (let j=0; j< this.size.y; j++) { if ( - this.board[i][j] != V.EMPTY && + this.board[i][j] != "" && this.getColor(i, j) == color && this.atLeastOneCaptureFrom([i, j], color) ) { @@ -198,7 +133,8 @@ export class EmergoRules extends ChessRules { res = [i]; maxLength = caps[i].length; } - else if (caps[i].length == maxLength) res.push(i); + else if (caps[i].length == maxLength) + res.push(i); } return res; }; @@ -207,26 +143,28 @@ export class EmergoRules extends ChessRules { let res = []; const L = locSteps.length; const lastStep = (L > 0 ? locSteps[L-1] : null); - for (let s of V.steps[V.BISHOP]) { - if (!!lastStep && s[0] == -lastStep[0] && s[1] == -lastStep[1]) continue; + for (let s of super.pieces()['b'].both[0].steps) { + if (!!lastStep && s[0] == -lastStep[0] && s[1] == -lastStep[1]) + continue; const [i, j] = [x + s[0], y + s[1]]; if ( - V.OnBoard(i + s[0], j + s[1]) && - this.board[i + s[0]][j + s[1]] == V.EMPTY && - this.board[i][j] != V.EMPTY && + this.onBoard(i + s[0], j + s[1]) && + this.board[i + s[0]][j + s[1]] == "" && + this.board[i][j] != "" && this.getColor(i, j) != color ) { const move = this.getBasicMove([x, y], [i + s[0], j + s[1]], [i, j]); locSteps.push(s); - V.PlayOnBoard(this.board, move); + this.playOnBoard(move); const nextRes = this.getLongestCaptures_aux([i + s[0], j + s[1]], color, locSteps); res.push(1 + nextRes); locSteps.pop(); - V.UndoOnBoard(this.board, move); + this.undoOnBoard(move); } } - if (res.length == 0) return 0; + if (res.length == 0) + return 0; return Math.max(...res); } @@ -234,23 +172,24 @@ export class EmergoRules extends ChessRules { let res = []; const L = locSteps.length; const lastStep = (L > 0 ? locSteps[L-1] : null); - for (let s of V.steps[V.BISHOP]) { - if (!!lastStep && s[0] == -lastStep[0] && s[1] == -lastStep[1]) continue; + for (let s of super.pieces()['b'].both[0].steps) { + if (!!lastStep && s[0] == -lastStep[0] && s[1] == -lastStep[1]) + continue; const [i, j] = [x + s[0], y + s[1]]; if ( - V.OnBoard(i + s[0], j + s[1]) && - this.board[i + s[0]][j + s[1]] == V.EMPTY && - this.board[i][j] != V.EMPTY && + this.onBoard(i + s[0], j + s[1]) && + this.board[i + s[0]][j + s[1]] == "" && + this.board[i][j] != "" && this.getColor(i, j) != color ) { const move = this.getBasicMove([x, y], [i + s[0], j + s[1]], [i, j]); locSteps.push(s); - V.PlayOnBoard(this.board, move); + this.playOnBoard(move); const stepRes = this.getLongestCaptures_aux([i + s[0], j + s[1]], color, locSteps); res.push({ step: s, length: 1 + stepRes }); locSteps.pop(); - V.UndoOnBoard(this.board, move); + this.undoOnBoard(move); } } return this.maxLengthIndices(res).map(i => res[i]);; @@ -271,10 +210,10 @@ export class EmergoRules extends ChessRules { ); } else { - for (let i = 0; i < V.size.x; i++) { - for (let j=0; j < V.size.y; j++) { + for (let i = 0; i < this.size.x; i++) { + for (let j=0; j < this.size.y; j++) { if ( - this.board[i][j] != V.EMPTY && + this.board[i][j] != "" && this.getColor(i, j) == color ) { let locSteps = []; @@ -303,9 +242,11 @@ export class EmergoRules extends ChessRules { const firstCodes = (color == 'w' ? [65, 97] : [97, 65]); const cpCapt = this.board[capt[0]][capt[1]]; let count1 = [cp1.charCodeAt(0) - firstCodes[0], -1]; - if (cp1[1] != '@') count1[1] = cp1.charCodeAt(1) - firstCodes[0]; + if (cp1[1] != '@') + count1[1] = cp1.charCodeAt(1) - firstCodes[0]; let countC = [cpCapt.charCodeAt(0) - firstCodes[1], -1]; - if (cpCapt[1] != '@') countC[1] = cpCapt.charCodeAt(1) - firstCodes[1]; + if (cpCapt[1] != '@') + countC[1] = cpCapt.charCodeAt(1) - firstCodes[1]; count1[1]++; countC[0]--; let colorChange = false, @@ -315,7 +256,8 @@ export class EmergoRules extends ChessRules { colorChange = true; countC = [countC[1], -1]; } - else captVanish = true; + else + captVanish = true; } const incPrisoners = String.fromCharCode(firstCodes[0] + count1[1]); let mv = new Move({ @@ -346,13 +288,24 @@ export class EmergoRules extends ChessRules { return mv; } - getReserveMoves(x) { - const color = this.turn; - if (!this.reserve[color] || this.atLeastOneCapture(color)) return []; + +// TODO: + style + getSquareColorClass(x, y) { + return ((x+y) % 2 == 0 ? "dark-square": "light-square"); + } + + + + + getDropMovesFrom([c, p]) { + const color = c; + if (!this.reserve[color] || this.atLeastOneCapture(color)) + return []; let moves = []; + const oppCol = C.GetOppTurn(color); const shadowPiece = - this.reserve[V.GetOppCol(color)] == null - ? this.reserve[color][V.PAWN] - 1 + !this.reserve[oppCol] + ? this.reserve[color]['p'] - 1 : 0; const appearColor = String.fromCharCode( (color == 'w' ? 'A' : 'a').charCodeAt(0) + shadowPiece); @@ -361,35 +314,36 @@ export class EmergoRules extends ChessRules { new Move({ appear: [ new PiPo({ x: i, y: j, c: appearColor, p: '@' }) ], vanish: [], - start: { x: V.size.x + (color == 'w' ? 0 : 1), y: 0 } + start: { x: this.size.x + (color == 'w' ? 0 : 1), y: 0 } }) ); }; - const oppCol = V.GetOppCol(color); const opponentCanCapture = this.atLeastOneCapture(oppCol); - for (let i = 0; i < V.size.x; i++) { - for (let j = i % 2; j < V.size.y; j += 2) { + for (let i = 0; i < this.size.x; i++) { + for (let j = i % 2; j < this.size.y; j += 2) { if ( - this.board[i][j] == V.EMPTY && + this.board[i][j] == "" && // prevent playing on central square at move 1: (this.movesCount >= 1 || i != 4 || j != 4) ) { - if (opponentCanCapture) addMove([i, j]); + if (opponentCanCapture) + addMove([i, j]); else { let canAddMove = true; - for (let s of V.steps[V.BISHOP]) { + for (let s of super.pieces()['b'].both[0].steps) { if ( - V.OnBoard(i + s[0], j + s[1]) && - V.OnBoard(i - s[0], j - s[1]) && - this.board[i + s[0]][j + s[1]] != V.EMPTY && - this.board[i - s[0]][j - s[1]] == V.EMPTY && + this.onBoard(i + s[0], j + s[1]) && + this.onBoard(i - s[0], j - s[1]) && + this.board[i + s[0]][j + s[1]] != "" && + this.board[i - s[0]][j - s[1]] == "" && this.getColor(i + s[0], j + s[1]) == oppCol ) { canAddMove = false; break; } } - if (canAddMove) addMove([i, j]); + if (canAddMove) + addMove([i, j]); } } } @@ -397,13 +351,15 @@ export class EmergoRules extends ChessRules { return moves; } - getPotentialMovesFrom([x, y], longestCaptures) { - if (x >= V.size.x) { - if (longestCaptures.length == 0) return this.getReserveMoves(x); + getPossibleMovesFrom([x, y], longestCaptures) { + if (x >= this.size.x) { + if (longestCaptures.length == 0) + return this.getReserveMoves(x); return []; } const color = this.turn; - if (!!this.reserve[color] && !this.atLeastOneCapture(color)) return []; + if (!!this.reserve[color] && !this.atLeastOneCapture(color)) + return []; const L0 = this.captures.length; const captures = this.captures[L0 - 1]; const L = captures.length; @@ -427,46 +383,21 @@ export class EmergoRules extends ChessRules { // Just search simple moves: for (let s of V.steps[V.BISHOP]) { const [i, j] = [x + s[0], y + s[1]]; - if (V.OnBoard(i, j) && this.board[i][j] == V.EMPTY) + if (this.onBoard(i, j) && this.board[i][j] == "") moves.push(this.getBasicMove([x, y], [i, j])); } return moves; } - getAllValidMoves() { - const color = this.turn; - const longestCaptures = this.getAllLongestCaptures(color); - let potentialMoves = []; - for (let i = 0; i < V.size.x; i++) { - for (let j = 0; j < V.size.y; j++) { - if (this.board[i][j] != V.EMPTY && this.getColor(i, j) == color) { - Array.prototype.push.apply( - potentialMoves, - this.getPotentialMovesFrom([i, j], longestCaptures) - ); - } - } - } - // Add reserve moves - potentialMoves = potentialMoves.concat( - this.getReserveMoves(V.size.x + (color == "w" ? 0 : 1)) - ); - return potentialMoves; - } - - getPossibleMovesFrom([x, y]) { + getPotentialMovesFrom([x, y]) { const longestCaptures = this.getAllLongestCaptures(this.getColor(x, y)); - return this.getPotentialMovesFrom([x, y], longestCaptures); + return this.getPossibleMovesFrom([x, y], longestCaptures); } filterValid(moves) { return moves; } - getCheckSquares() { - return []; - } - play(move) { const color = this.turn; move.turn = color; //for undo @@ -496,81 +427,45 @@ export class EmergoRules extends ChessRules { } } - undo(move) { - V.UndoOnBoard(this.board, move); - if (!move.notTheEnd) { - this.turn = move.turn; - this.movesCount--; - this.captures.pop(); - } - if (move.vanish.length == 0) { - const color = (move.appear[0].c == 'A' ? 'w' : 'b'); - const firstCode = (color == 'w' ? 65 : 97); - const reserveCount = move.appear[0].c.charCodeAt() - firstCode + 1; - if (!this.reserve[color]) this.reserve[color] = { [V.PAWN]: 0 }; - this.reserve[color][V.PAWN] += reserveCount; - } - else if (move.vanish.length == 2) { - const L0 = this.captures.length; - let captures = this.captures[L0 - 1]; - captures.pop(); - } - } - atLeastOneMove() { const color = this.turn; - if (this.atLeastOneCapture(color)) return true; - for (let i = 0; i < V.size.x; i++) { - for (let j = 0; j < V.size.y; j++) { - if (this.board[i][j] != V.EMPTY && this.getColor(i, j) == color) { - const moves = this.getPotentialMovesFrom([i, j], []); - if (moves.length > 0) return true; + if (this.atLeastOneCapture(color)) + return true; + for (let i = 0; i < this.size.x; i++) { + for (let j = 0; j < this.size.y; j++) { + if (this.board[i][j] != "" && this.getColor(i, j) == color) { + const moves = this.getPossibleMovesFrom([i, j], []); + if (moves.length > 0) + return true; } } } + + + // TODO: adapt const reserveMoves = - this.getReserveMoves(V.size.x + (this.turn == "w" ? 0 : 1)); + this.getReserveMoves(this.size.x + (this.turn == "w" ? 0 : 1)); return (reserveMoves.length > 0); } + + getCurrentScore() { const color = this.turn; + const testColorCode = (c) => { + return (c <= 90 && color == 'w') || (c >= 97 && color == 'b'); + }; // If no pieces on board + reserve, I lose - if (!!this.reserve[color]) return "*"; - let atLeastOnePiece = false; - outerLoop: for (let i=0; i < V.size.x; i++) { - for (let j=0; j < V.size.y; j++) { - if (this.board[i][j] != V.EMPTY && this.getColor(i, j) == color) { - atLeastOnePiece = true; - break outerLoop; - } - } - } - if (!atLeastOnePiece) return (color == 'w' ? "0-1" : "1-0"); - if (!this.atLeastOneMove()) return "1/2"; + if (!!this.reserve[color]) + return "*"; + const atLeastOnePiece = this.board.some(row => row.some(cell => { + return cell != "" && testColorCode(cell.charCodeAt(0)); + }); + if (!atLeastOnePiece) + return (color == 'w' ? "0-1" : "1-0"); + if (!this.atLeastOneMove()) + return "1/2"; return "*"; } - getComputerMove() { - // Random mover for now (TODO) - const color = this.turn; - let mvArray = []; - let mv = null; - while (this.turn == color) { - const moves = this.getAllValidMoves(); - mv = moves[randInt(moves.length)]; - mvArray.push(mv); - this.play(mv); - } - for (let i = mvArray.length - 1; i >= 0; i--) this.undo(mvArray[i]); - return (mvArray.length > 1 ? mvArray : mvArray[0]); - } - - getNotation(move) { - if (move.vanish.length == 0) return "@" + V.CoordsToSquare(move.end); - const L0 = this.captures.length; - if (this.captures[L0 - 1].length > 0) return V.CoordsToSquare(move.end); - return V.CoordsToSquare(move.start) + V.CoordsToSquare(move.end); - } - }; diff --git a/variants/Emergo/style.css b/variants/Emergo/style.css new file mode 100644 index 0000000..9650899 --- /dev/null +++ b/variants/Emergo/style.css @@ -0,0 +1,35 @@ +piece.white.stack { + background-image: url('/pieces/Emergo/white_.svg'); +} + + + + +piece.white.stack2 { + background-image: url('/pieces/Avalam/white_stack2.svg'); +} +piece.white.stack3 { + background-image: url('/pieces/Avalam/white_stack3.svg'); +} +piece.white.stack4 { + background-image: url('/pieces/Avalam/white_stack4.svg'); +} +piece.white.stack5 { + background-image: url('/pieces/Avalam/white_stack5.svg'); +} + +piece.black.stack { + background-image: url('/pieces/Avalam/black_stack.svg'); +} +piece.black.stack2 { + background-image: url('/pieces/Avalam/black_stack2.svg'); +} +piece.black.stack3 { + background-image: url('/pieces/Avalam/black_stack3.svg'); +} +piece.black.stack4 { + background-image: url('/pieces/Avalam/black_stack4.svg'); +} +piece.black.stack5 { + background-image: url('/pieces/Avalam/black_stack5.svg'); +}