X-Git-Url: https://git.auder.net/?a=blobdiff_plain;f=client%2Fclient_OLD%2Fjavascripts%2Fcomponents%2Fboard.js;fp=client%2Fclient_OLD%2Fjavascripts%2Fcomponents%2Fboard.js;h=a59e41f7bc1d68d048b498f08fca1676986c36e4;hb=625022fdcf750f0aff8fcd699f7e9b89730e1d10;hp=0000000000000000000000000000000000000000;hpb=b955c65b942d09d24b5c3bed0d755d4f2f8f71f1;p=vchess.git diff --git a/client/client_OLD/javascripts/components/board.js b/client/client_OLD/javascripts/components/board.js new file mode 100644 index 00000000..a59e41f7 --- /dev/null +++ b/client/client_OLD/javascripts/components/board.js @@ -0,0 +1,357 @@ +// This can work for squared boards (2 or 4 players), with some adaptations (TODO) +// TODO: for 3 players, write a "board3.js" +Vue.component('my-board', { + // Last move cannot be guessed from here, and is required to highlight squares + // vr: object to check moves, print board... + // mode: HH, HC or analyze + // userColor: for mode HH or HC + props: ["vr","lastMove","mode","orientation","userColor"], + data: function () { + return { + hints: (!localStorage["hints"] ? true : localStorage["hints"] === "1"), + bcolor: localStorage["bcolor"] || "lichess", //lichess, chesscom or chesstempo + possibleMoves: [], //filled after each valid click/dragstart + choices: [], //promotion pieces, or checkered captures... (as moves) + selectedPiece: null, //moving piece (or clicked piece) + incheck: [], + start: {}, //pixels coordinates + id of starting square (click or drag) + }; + }, + render(h) { + if (!this.vr) + return; + const [sizeX,sizeY] = [V.size.x,V.size.y]; + // Precompute hints squares to facilitate rendering + let hintSquares = doubleArray(sizeX, sizeY, false); + this.possibleMoves.forEach(m => { hintSquares[m.end.x][m.end.y] = true; }); + // Also precompute in-check squares + let incheckSq = doubleArray(sizeX, sizeY, false); + this.incheck.forEach(sq => { incheckSq[sq[0]][sq[1]] = true; }); + const squareWidth = 40; //TODO: compute this + const choices = h( + 'div', + { + attrs: { "id": "choices" }, + 'class': { 'row': true }, + style: { + "display": this.choices.length>0?"block":"none", + "top": "-" + ((sizeY/2)*squareWidth+squareWidth/2) + "px", + "width": (this.choices.length * squareWidth) + "px", + "height": squareWidth + "px", + }, + }, + this.choices.map(m => { //a "choice" is a move + return h('div', + { + 'class': { + 'board': true, + ['board'+sizeY]: true, + }, + style: { + 'width': (100/this.choices.length) + "%", + 'padding-bottom': (100/this.choices.length) + "%", + }, + }, + [h('img', + { + attrs: { "src": '/images/pieces/' + + V.getPpath(m.appear[0].c+m.appear[0].p) + '.svg' }, + 'class': { 'choice-piece': true }, + on: { + "click": e => { this.play(m); this.choices=[]; }, + // NOTE: add 'touchstart' event to fix a problem on smartphones + "touchstart": e => { this.play(m); this.choices=[]; }, + }, + }) + ] + ); + }) + ); + // Create board element (+ reserves if needed by variant or mode) + const lm = this.lastMove; + const showLight = this.hints && variant.name != "Dark"; + const gameDiv = h( + 'div', + { + 'class': { + 'game': true, + 'clearer': true, + }, + }, + [_.range(sizeX).map(i => { + let ci = (this.orientation=='w' ? i : sizeX-i-1); + return h( + 'div', + { + 'class': { + 'row': true, + }, + style: { 'opacity': this.choices.length>0?"0.5":"1" }, + }, + _.range(sizeY).map(j => { + let cj = (this.orientation=='w' ? j : sizeY-j-1); + let elems = []; + if (this.vr.board[ci][cj] != V.EMPTY && (variant.name!="Dark" + || this.gameOver || this.mode == "analyze" + || this.vr.enlightened[this.userColor][ci][cj])) + { + elems.push( + h( + 'img', + { + 'class': { + 'piece': true, + 'ghost': !!this.selectedPiece + && this.selectedPiece.parentNode.id == "sq-"+ci+"-"+cj, + }, + attrs: { + src: "/images/pieces/" + + V.getPpath(this.vr.board[ci][cj]) + ".svg", + }, + } + ) + ); + } + if (this.hints && hintSquares[ci][cj]) + { + elems.push( + h( + 'img', + { + 'class': { + 'mark-square': true, + }, + attrs: { + src: "/images/mark.svg", + }, + } + ) + ); + } + return h( + 'div', + { + 'class': { + 'board': true, + ['board'+sizeY]: true, + 'light-square': (i+j)%2==0, + 'dark-square': (i+j)%2==1, + [this.bcolor]: true, + 'in-shadow': variant.name=="Dark" && !this.gameOver + && this.mode != "analyze" + && !this.vr.enlightened[this.userColor][ci][cj], + 'highlight': showLight && !!lm && _.isMatch(lm.end, {x:ci,y:cj}), + 'incheck': showLight && incheckSq[ci][cj], + }, + attrs: { + id: getSquareId({x:ci,y:cj}), + }, + }, + elems + ); + }) + ); + }), choices] + ); + let elementArray = [choices, gameDiv]; + if (!!this.vr.reserve) + { + const shiftIdx = (this.userColor=="w" ? 0 : 1); + let myReservePiecesArray = []; + for (let i=0; i 1) + this.choices = moves; + else if (moves.length==1) + this.play(moves[0]); + // Else: impossible move + this.selectedPiece.parentNode.removeChild(this.selectedPiece); + delete this.selectedPiece; + this.selectedPiece = null; + }, + findMatchingMoves: function(endSquare) { + // Run through moves list and return the matching set (if promotions...) + let moves = []; + this.possibleMoves.forEach(function(m) { + if (endSquare[0] == m.end.x && endSquare[1] == m.end.y) + moves.push(m); + }); + return moves; + }, + play: function(move) { + this.$emit('play-move', move); + }, + }, +})