From c794dbb87592782913af0a09784ed25e019e4d10 Mon Sep 17 00:00:00 2001 From: Benjamin Auder Date: Sun, 16 Dec 2018 04:07:08 +0100 Subject: [PATCH] Finished problems implementation. TODO: specify state for Crazyhouse,Grand. Improve style --- public/javascripts/base_rules.js | 9 +++------ public/javascripts/components/game.js | 17 ++++++++++++++--- public/javascripts/components/problemSummary.js | 16 +++++----------- public/javascripts/components/problems.js | 7 +++++-- public/javascripts/utils/datetime.js | 15 +++++++++++++++ public/javascripts/variant.js | 12 ++++++++---- public/javascripts/variants/Antiking.js | 5 ++--- public/javascripts/variants/Checkered.js | 16 ++++++++++------ public/javascripts/variants/Grand.js | 5 ++--- public/javascripts/variants/Loser.js | 4 ++-- public/javascripts/variants/Ultima.js | 4 ++-- public/javascripts/variants/Wildebeest.js | 5 ++--- views/variant.pug | 6 ++++-- 13 files changed, 74 insertions(+), 47 deletions(-) create mode 100644 public/javascripts/utils/datetime.js diff --git a/public/javascripts/base_rules.js b/public/javascripts/base_rules.js index 5763af7e..b44d0856 100644 --- a/public/javascripts/base_rules.js +++ b/public/javascripts/base_rules.js @@ -50,7 +50,7 @@ class ChessRules ///////////////// // INITIALIZATION - // fen == "position flags" + // fen == "position [flags [turn]]" constructor(fen, moves) { this.moves = moves; @@ -1107,7 +1107,7 @@ class ChessRules return pieces["b"].join("") + "/pppppppp/8/8/8/8/PPPPPPPP/" + pieces["w"].join("").toUpperCase() + - " 1111"; //add flags + " 1111 w"; //add flags + turn } // Return current fen according to pieces+colors state @@ -1209,14 +1209,11 @@ class ChessRules // The score is already computed when calling this function getPGN(mycolor, score, fenStart, mode) { - const zeroPad = x => { return (x<10 ? "0" : "") + x; }; let pgn = ""; pgn += '[Site "vchess.club"]
'; - const d = new Date(); const opponent = mode=="human" ? "Anonymous" : "Computer"; pgn += '[Variant "' + variant + '"]
'; - pgn += '[Date "' + d.getFullYear() + '-' + (d.getMonth()+1) + - '-' + zeroPad(d.getDate()) + '"]
'; + pgn += '[Date "' + getDate(new Date()) + '"]
'; pgn += '[White "' + (mycolor=='w'?'Myself':opponent) + '"]
'; pgn += '[Black "' + (mycolor=='b'?'Myself':opponent) + '"]
'; pgn += '[FenStart "' + fenStart + '"]
'; diff --git a/public/javascripts/components/game.js b/public/javascripts/components/game.js index 49db6188..ded30918 100644 --- a/public/javascripts/components/game.js +++ b/public/javascripts/components/game.js @@ -1,5 +1,6 @@ // Game logic on a variant page Vue.component('my-game', { + props: ["problem"], data: function() { return { vr: null, //object to check moves, store them, FEN.. @@ -23,6 +24,15 @@ Vue.component('my-game', { sound: parseInt(getCookie("sound", "2")), }; }, + watch: { + problem: function(p, pp) { + // 'problem' prop changed: update board state + // TODO: FEN + turn + flags + rappel instructions / solution on click sous l'échiquier + // TODO: trouver moyen de passer la situation des reserves pour Crazyhouse, + // et l'état des captures pour Grand... bref compléter le descriptif de l'état. + this.newGame("problem", p.fen, p.fen.split(" ")[2]); + }, + }, render(h) { const [sizeX,sizeY] = [V.size.x,V.size.y]; const smallScreen = (window.innerWidth <= 420); @@ -1077,7 +1087,7 @@ Vue.component('my-game', { if (this.mycolor == 'b') setTimeout(this.playComputerMove, 500); } - //else: against a (IRL) friend: nothing more to do + //else: against a (IRL) friend or problem solving: nothing more to do }, playComputerMove: function() { const timeStart = Date.now(); @@ -1130,8 +1140,9 @@ Vue.component('my-game', { this.selectedPiece.style.display = "inline-block"; this.selectedPiece.style.zIndex = 3000; let startSquare = this.getSquareFromId(e.target.parentNode.id); - const iCanPlay = this.mode!="idle" - && (this.mode=="friend" || this.vr.canIplay(this.mycolor,startSquare)); + const iCanPlay = this.mode!="idle" && + (["friend","problem"].includes(this.mode) || + this.vr.canIplay(this.mycolor,startSquare)); this.possibleMoves = iCanPlay ? this.vr.getPossibleMovesFrom(startSquare) : []; // Next line add moving piece just after current image // (required for Crazyhouse reserve) diff --git a/public/javascripts/components/problemSummary.js b/public/javascripts/components/problemSummary.js index 48a42533..c0b409de 100644 --- a/public/javascripts/components/problemSummary.js +++ b/public/javascripts/components/problemSummary.js @@ -5,7 +5,7 @@ Vue.component('my-problem-summary', {
-
{{ timestamp2datetime(prob.added) }}
+
{{ timestamp2date(prob.added) }}
`, methods: { @@ -17,18 +17,12 @@ Vue.component('my-problem-summary', { turn: fenParts[2], }); }, - timestamp2datetime(ts) { - // TODO - return ts; + timestamp2date(ts) { + return getDate(new Date(ts)); }, + // Propagate "show problem" event to parent component (my-problems) showProblem: function() { - alert("show problem"); - //.......... - //TODO: send event with object prob.fen, prob.instructions, prob.solution - //Event should propagate to game, which set mode=="problem" + other variables - //click on a problem ==> land on variant page with mode==friend, FEN prefilled... ok - // click on problem ==> masque problems, affiche game tab, launch new game Friend with - // FEN + turn + flags + rappel instructions / solution on click sous l'échiquier + this.$emit('show-problem'); }, }, }) diff --git a/public/javascripts/components/problems.js b/public/javascripts/components/problems.js index dbd8340c..68830a4f 100644 --- a/public/javascripts/components/problems.js +++ b/public/javascripts/components/problems.js @@ -9,7 +9,7 @@ Vue.component('my-problems', { - @@ -45,7 +45,6 @@ Vue.component('my-problems', { `, computed: { sortedProblems: function() { - console.log("call"); // Newest problem first return this.problems.sort((p1,p2) => { return p2.added - p1.added; }); }, @@ -54,6 +53,10 @@ Vue.component('my-problems', { }, }, methods: { + // Propagate "show problem" event to parent component (my-variant) + bubbleUp: function(problem) { + this.$emit('show-problem', JSON.stringify(problem)); + }, fetchProblems: function(direction) { return; //TODO: re-activate after server side is implemented (see routes/all.js) if (this.problems.length == 0) diff --git a/public/javascripts/utils/datetime.js b/public/javascripts/utils/datetime.js new file mode 100644 index 00000000..b6be6df9 --- /dev/null +++ b/public/javascripts/utils/datetime.js @@ -0,0 +1,15 @@ +function zeroPad(x) +{ + return (x<10 ? "0" : "") + x; +} + +function getDate(d) +{ + return d.getFullYear() + '-' + (d.getMonth()+1) + '-' + zeroPad(d.getDate()); +} + +function getTime(d) +{ + return zeroPad(d.getHours()) + ":" + zeroPad(d.getMinutes()) + ":" + + zeroPad(d.getSeconds()); +} diff --git a/public/javascripts/variant.js b/public/javascripts/variant.js index 2174c509..3aa2f686 100644 --- a/public/javascripts/variant.js +++ b/public/javascripts/variant.js @@ -1,9 +1,9 @@ new Vue({ el: "#variantPage", - data: { display: "" }, //do not show anything... - // TODO: listen event "show problem", avec le probleme stringifié en arg - // Alors: display=game, mode=friend, newGame(fen, turn, ...), - // et set Instructions+Soluce + data: { + display: "", //do not show anything... + problem: undefined, //current problem in view + }, methods: { toggleDisplay: function(elt) { if (this.display == elt) @@ -11,5 +11,9 @@ new Vue({ else this.display = elt; //show }, + showProblem: function(problemTxt) { + this.problem = JSON.parse(problemTxt); + this.display = "game"; + }, }, }); diff --git a/public/javascripts/variants/Antiking.js b/public/javascripts/variants/Antiking.js index 2821f3f5..2b07cfbe 100644 --- a/public/javascripts/variants/Antiking.js +++ b/public/javascripts/variants/Antiking.js @@ -197,10 +197,9 @@ class AntikingRules extends ChessRules + "A" + (antikingPos["w"]<7?7-antikingPos["w"]:""); const ranks23_white = (antikingPos["b"]>0?antikingPos["b"]:"") + "a" + (antikingPos["b"]<7?7-antikingPos["b"]:"") + "/PPPPPPPP"; - let fen = pieces["b"].join("") + "/" + ranks23_black + + return pieces["b"].join("") + "/" + ranks23_black + "/8/8/" + ranks23_white + "/" + pieces["w"].join("").toUpperCase() + - " 1111"; - return fen; + " 1111 w"; } } diff --git a/public/javascripts/variants/Checkered.js b/public/javascripts/variants/Checkered.js index 585d20ff..370c6896 100644 --- a/public/javascripts/variants/Checkered.js +++ b/public/javascripts/variants/Checkered.js @@ -47,15 +47,17 @@ class CheckeredRules extends ChessRules return !!flags.match(/^[01]{20,20}$/); } - setFlags(fen) + setFlags(fenflags) { - super.setFlags(fen); //castleFlags + super.setFlags(fenflags); //castleFlags this.pawnFlags = { - "w": new Array(8), //pawns can move 2 squares? - "b": new Array(8) + "w": _.map(_.range(8), i => true), //pawns can move 2 squares? + "b": _.map(_.range(8), i => true) }; - const flags = fen.split(" ")[1].substr(4); //skip first 4 digits, for castle + if (!fenflags) + return; + const flags = fenflags.substr(4); //skip first 4 digits, for castle for (let c of ['w','b']) { for (let i=0; i<8; i++) @@ -238,7 +240,9 @@ class CheckeredRules extends ChessRules static GenRandInitFen() { - return ChessRules.GenRandInitFen() + "1111111111111111"; //add 16 pawns flags + const randFen = ChessRules.GenRandInitFen(); + // Add 16 pawns flags: + return randFen.replace(" 1111 w", " 11111111111111111111 w"); } getFlagsFen() diff --git a/public/javascripts/variants/Grand.js b/public/javascripts/variants/Grand.js index cafdadab..276acbc3 100644 --- a/public/javascripts/variants/Grand.js +++ b/public/javascripts/variants/Grand.js @@ -275,10 +275,9 @@ class GrandRules extends ChessRules pieces[c][knight2Pos] = 'n'; pieces[c][rook2Pos] = 'r'; } - let fen = pieces["b"].join("") + + return pieces["b"].join("") + "/pppppppppp/10/10/10/10/10/10/PPPPPPPPPP/" + pieces["w"].join("").toUpperCase() + - " 1111"; - return fen; + " 1111 w"; } } diff --git a/public/javascripts/variants/Loser.js b/public/javascripts/variants/Loser.js index 98bd9443..2d60d6e8 100644 --- a/public/javascripts/variants/Loser.js +++ b/public/javascripts/variants/Loser.js @@ -11,7 +11,7 @@ class LoserRules extends ChessRules return true; //anything is good: no flags } - setFlags(fen) + setFlags(fenflags) { // No castling, hence no flags; but flags defined for compatibility this.castleFlags = { "w":[false,false], "b":[false,false] }; @@ -197,6 +197,6 @@ class LoserRules extends ChessRules return pieces["b"].join("") + "/pppppppp/8/8/8/8/PPPPPPPP/" + pieces["w"].join("").toUpperCase() + - " 0000"; //add flags (TODO?!) + " 0000 w"; //add flags (TODO?!) } } diff --git a/public/javascripts/variants/Ultima.js b/public/javascripts/variants/Ultima.js index d6fecb70..05fba2f5 100644 --- a/public/javascripts/variants/Ultima.js +++ b/public/javascripts/variants/Ultima.js @@ -45,7 +45,7 @@ class UltimaRules extends ChessRules this.epSquares = []; //no en-passant here } - setFlags(fen) + setFlags(fenflags) { // TODO: for compatibility? this.castleFlags = {"w":[false,false], "b":[false,false]}; @@ -608,7 +608,7 @@ class UltimaRules extends ChessRules return pieces["b"].join("") + "/pppppppp/8/8/8/8/PPPPPPPP/" + pieces["w"].join("").toUpperCase() + - " 0000"; //TODO: flags?! + " 0000 w"; //TODO: flags?! } getFlagsFen() diff --git a/public/javascripts/variants/Wildebeest.js b/public/javascripts/variants/Wildebeest.js index dcf2d582..9b074108 100644 --- a/public/javascripts/variants/Wildebeest.js +++ b/public/javascripts/variants/Wildebeest.js @@ -245,10 +245,9 @@ class WildebeestRules extends ChessRules pieces[c][knight2Pos] = 'n'; pieces[c][rook2Pos] = 'r'; } - let fen = pieces["b"].join("") + + return pieces["b"].join("") + "/ppppppppppp/11/11/11/11/11/11/PPPPPPPPPPP/" + pieces["w"].join("").toUpperCase() + - " 1111"; - return fen; + " 1111 w"; } } diff --git a/views/variant.pug b/views/variant.pug index 37bd5e7d..b1caabdb 100644 --- a/views/variant.pug +++ b/views/variant.pug @@ -14,11 +14,12 @@ block content .col-sm-12.col-md-10.col-md-offset-1.col-lg-8.col-lg-offset-2 h4.variantpage-title.text-center(v-on:click="toggleDisplay('game')") | #{variant} Game - my-game(v-show="display=='game'") + my-game(v-show="display=='game'" v-bind:problem="problem") .col-sm-12.col-md-10.col-md-offset-1.col-lg-8.col-lg-offset-2 h4.variantpage-title.text-center(v-on:click="toggleDisplay('problems')") | #{variant} Problems - my-problems(v-show="display=='problems'") + my-problems(v-show="display=='problems'" + v-on:show-problem="showProblem($event)") block javascripts script(src="/javascripts/utils/misc.js") @@ -27,6 +28,7 @@ block javascripts script(src="/javascripts/utils/md5.js") script(src="/javascripts/utils/printDiagram.js") script(src="/javascripts/utils/ajax.js") + script(src="/javascripts/utils/datetime.js") script(src="/javascripts/base_rules.js") script(src="/javascripts/variants/" + variant + ".js") script. -- 2.44.0