From 610f9b3528bba8497cda13e29e24b8dd656d1ae6 Mon Sep 17 00:00:00 2001 From: Roy Date: Sun, 7 May 2023 02:29:01 +0200 Subject: [PATCH] Improve movelog, add status messages, and fix incorrect insertion of prio(rity) entries (post-game). --- chess_gui/lib/chess_gui.pm | 23 +++--- chess_gui/public/css/index.css | 56 ++++++++++++++- chess_gui/public/js/dand.js | 128 +++++++++++++++++++++++++++++++-- chess_gui/public/js/head.js | 2 + chess_gui/views/index.html | 12 ++-- 5 files changed, 200 insertions(+), 21 deletions(-) diff --git a/chess_gui/lib/chess_gui.pm b/chess_gui/lib/chess_gui.pm index 5850b4f..521eb96 100644 --- a/chess_gui/lib/chess_gui.pm +++ b/chess_gui/lib/chess_gui.pm @@ -680,7 +680,7 @@ sub POSTCHESS_CALC { my ($pval, $called_player, $reason, $session) = @_; # Arguments: (Value of all pieces of $player - $not_player[$player], $player, reason for exiting the game (did a $player win?)). foreach my $current_player (@player) { my $mpval; - my $sth4 = $dbh->prepare(q/UPDATE context SET /.$pplayer[$not_player[$current_player]].q/prio = ? FROM black, white WHERE black.id = bid and white.id = wid and white.b0 = ? and white.b1 = ? and white.k0 = ? and white.n0 = ? and white.n1 = ? and white.p0 = ? and white.p1 = ? and white.p2 = ? and white.p3 = ? and white.p4 = ? and white.p5 = ? and white.p6 = ? and white.p7 = ? and white.q0 = ? and white.r0 = ? and white.r1 = ? and black.b0 = ? and black.b1 = ? and black.k0 = ? and black.n0 = ? and black.n1 = ? and black.p0 = ? and black.p1 = ? and black.p2 = ? and black.p3 = ? and black.p4 = ? and black.p5 = ? and black.p6 = ? and black.p7 = ? and black.q0 = ? and black.r0 = ? and black.r1 = ?/); + my $sth4 = $dbh->prepare(q/UPDATE context SET /.$pplayer[$current_player].q/prio = ? FROM black, white WHERE black.id = bid and white.id = wid and white.b0 = ? and white.b1 = ? and white.k0 = ? and white.n0 = ? and white.n1 = ? and white.p0 = ? and white.p1 = ? and white.p2 = ? and white.p3 = ? and white.p4 = ? and white.p5 = ? and white.p6 = ? and white.p7 = ? and white.q0 = ? and white.r0 = ? and white.r1 = ? and black.b0 = ? and black.b1 = ? and black.k0 = ? and black.n0 = ? and black.n1 = ? and black.p0 = ? and black.p1 = ? and black.p2 = ? and black.p3 = ? and black.p4 = ? and black.p5 = ? and black.p6 = ? and black.p7 = ? and black.q0 = ? and black.r0 = ? and black.r1 = ?/); if ($reason == 0) { # Stalemate. Various causes. if ($current_player == 0) { $mpval = -1; # Try out other selections (if the next game is similar) for benefit of player 1. #TODO: Remove in production. @@ -704,16 +704,17 @@ my ($pval, $called_player, $reason, $session) = @_; # Arguments: (Value of all p } } } - foreach my $anothervar (keys %{$what_i_did{$session}[$current_player]}) { - $what_i_did{$session}[$current_player]{$anothervar} += $mpval; - $sth4->execute($what_i_did{$session}[$current_player]{$anothervar}, @keys); + foreach my $match_keys (keys %{$what_i_did{$session}[$current_player]}) { + $what_i_did{$session}[$current_player]{$match_keys} += $mpval; + my @keys = map {$_ eq '' ? $_ = undef : $_} split /,/, $match_keys; + $sth4->execute($what_i_did{$session}[$current_player]{$match_keys}, @keys); } } - #undef %what_i_did{$session}; - #undef %user_mode{$session}; - #undef %player_turn{$session}; - #undef %counter{$session}; - #undef %pseudoinfinite_loop_check{$session}; + undef $what_i_did{$session}; + undef $user_mode{$session}; + undef $player_turn{$session}; + undef $counter{$session}; + undef $pseudoinfinite_loop_check{$session}; } sub PROGRAM { @@ -758,7 +759,7 @@ $user_mode{$_[2]} = 0; if (!defined($ids[0])) { # Default state. %prop = %default_prop; @keys = @default_keys; - } else { # Restore arbitrary states. + } else { # Restore arbitrary states. TODO: OO-approach (for each session a board w/ expiry (at which point we'll flush to the DB (if it weren't for localStorage))). $sth8->execute($ids[1]); $sth9->execute($ids[0]); &CLEANUP_POSTGAME; @@ -883,7 +884,7 @@ $user_mode{$_[2]} = 0; # push @{$diff{$pplayer[$player]}{'moveno'}}, ($ice+1) . '/' . $n_o_selections; # @{$diff{'msg'}{'verbose'}}[$player] = $selection[$ice]; - $what_i_did{$_[2]}[$player]{$selection} = $prio; + $what_i_did{$_[2]}[$player]{$selection} = $prio if $prio != 'Inf'; my $c = 0; my $adest; foreach (split /,/, $selection) { diff --git a/chess_gui/public/css/index.css b/chess_gui/public/css/index.css index e52f1fa..8da0a54 100644 --- a/chess_gui/public/css/index.css +++ b/chess_gui/public/css/index.css @@ -1,3 +1,5 @@ +/* (C) Roy van Lunsen */ + a { display: block; text-decoration: none; @@ -14,10 +16,15 @@ ol > li li { #y-co { display: flex; - flex-flow: column-reverse; + flex-flow: column-reverse; /* Order depends on player side #1/3 */ width: max-content; } +.x-row { + display: flex; + flex-flow: row; /* Order depends on player side #2/3 */ +} + #x-co { display: inline-flex; flex-flow: row; @@ -70,3 +77,50 @@ img { #emptyx { width: 40px; } + +dl { + display: flex; + flex-flow: column-reverse; + max-height: 50vh; + width: max-content; + overflow-y: scroll; + scrollbar-width: thin; +} + +dl li { + display: flex; + flex-flow: column-reverse; /* Order depends on player side #3/3 */ +} + +figure { + display: flex; + flex-flow: row; + margin-top: 0.1em; + margin-bottom: 0.1em; +} + +figure img { + height: 20px; + padding: 1px; +} + +.white { + background-color: white; + color: black; +} + +.black { + background-color: black; + color: white; +} + +/*img.black, img.white {*/ +/* border-width: 1px;*/ +/* border-color: red;*/ +/*}*/ + +dd.noimg { /* Display text of
and
at the same height when there's no image in
*/ + display: flex; + flex-wrap: wrap; + align-content: end; +} diff --git a/chess_gui/public/js/dand.js b/chess_gui/public/js/dand.js index 3ffb65c..1098118 100644 --- a/chess_gui/public/js/dand.js +++ b/chess_gui/public/js/dand.js @@ -1,9 +1,18 @@ +// (C) Roy van Lunsen + var xhr = new XMLHttpRequest(); +var h1 = document.createElement('h1'); +var h2 = document.createElement('h2'); +var count = 1; //var e = document.createElement('li'); //var f = ['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H']; var d = document.createElement('dl'); +//var ol = document.createElement('ol'); var pn = {b:'bishop',k:'king',q:'queen',n:'knight',p:'pawn',r:'rook'}; var pp = ['White','Black']; +var statusm = ['Your turn','Opponent\'s turn','Suggestion','You failed in deceiving your opponent.','You won','You lost','Stalemate','Confirmation','Notice','Connection lost','You resigned','Opponent resigned','Server maintenance']; +var nrsuffix = ['st', 'nd', 'rd']; +var defsuffix = 'th'; //x = 25; //console.log(x.toString(36)); @@ -45,11 +54,70 @@ i++; function dragAndDrop(drag, drop) { xhr.open('GET', 'move/' + drag + '/' + drop + '/' + localStorage.state, true); xhr.send(null); + +var h1TN = statusm[1]; +var h2TN = statusm[2]; +h2.innerHTML = h2TN; +document.body.insertBefore(h2, I('board')); +h1.innerHTML = h1TN; +document.body.insertBefore(h1, h2); + xhr.onload = function () { if (xhr.status === 200) { responseObject = JSON.parse(xhr.responseText); -//if (responseObject.White.status.length === 2 && responseObject.Black.status.length === 2) {} if (responseObject.White.status[1] === 0 && responseObject.Black.status[1] === 0) { // Legal move(s)? +count = 1; +if (responseObject.White.status.length === 6) { +if (responseObject.White.status[5] === 4) { +var h1TN = statusm[6]; +var h2TN = 'Only kings can act.'; +} else if (responseObject.White.status[5] === 3) { +var h1TN = statusm[6]; +var h2TN = 'Turn limit exceeded.'; +} else if (responseObject.White.status[5] === 2) { +var h1TN = statusm[6]; +var h2TN = 'Loop limit exceeded.'; +} else if (responseObject.White.status[5] === 1) { +var h1TN = statusm[4]; +var h2TN = 'White took your king.'; +} +} else { +var h1TN = statusm[0]; +var h2TN = statusm[2]; +} +h2.innerHTML = h2TN; +document.body.insertBefore(h2, I('board')); +h1.innerHTML = h1TN; +document.body.insertBefore(h1, h2); + +if (responseObject.Black.status.length === 6) { +if (responseObject.Black.status[5] === 4) { +var h1TN = statusm[6]; +var h2TN = 'Only kings can act.'; +} else if (responseObject.Black.status[5] === 3) { +var h1TN = statusm[6]; +var h2TN = 'Turn limit exceeded.'; +} else if (responseObject.Black.status[5] === 2) { +var h1TN = statusm[6]; +var h2TN = 'Loop limit exceeded.'; +} else if (responseObject.Black.status[5] === 1) { +var h1TN = statusm[5]; +var h2TN = 'Black took your king.'; +} +h2.innerHTML = h2TN; +document.body.insertBefore(h2, I('board')); +h1.innerHTML = h1TN; +document.body.insertBefore(h1, h2); +} +// else { +//var h1TN = statusm[1]; +//var h2TN = statusm[2]; +//} +//h2.innerHTML = h2TN; +//document.body.insertBefore(h2, I('board')); +//h1.innerHTML = h1TN; +//document.body.insertBefore(h1, h2); + localStorage.removeItem(responseObject.White.src[0]); localStorage.setItem(responseObject.White.dst[0], responseObject.White.src[1]); localStorage.removeItem(responseObject.Black.src[0]); @@ -97,24 +165,27 @@ var srci = I(responseObject.Black.src[0]).innerHTML; // Duplicate. I(responseObject.Black.src[0]).innerHTML = ''; // Remove. I(responseObject.Black.dst[0]).innerHTML = srci; // Add. -if (responseObject.White.status[0] === 1) { // black.status[0] should be 1, too. +if (responseObject.White.status[0] === 1) { // TODO: Replace for a (temporary) session flag whether initialized (more reliable). Also: Shall we store the move history in localStorage? +//ol.setAttribute('id', 'moves'); var section = document.createElement('section'); section.setAttribute('id', 'log'); document.body.insertBefore(section, T('script')[1]); //d = document.createElement('ol'); section.appendChild(d); +//d.appendChild(ol); } var li = document.createElement('li'); var dt = document.createElement('dt'); var figure = document.createElement('figure'); +figure.setAttribute('class', 'white'); var i = document.createElement('img'); var figcaption = document.createElement('figcaption'); var dd = document.createElement('dd'); d.appendChild(li); li.appendChild(figure); i.setAttribute('src', 'i/' + responseObject.White.src[1].substring(0, 2) + '.png'); -figure.appendChild(i); figure.appendChild(dt); +dt.appendChild(i); //e.setAttribute('class', 'movement'); //d = document.createElement('img'); //d.setAttribute('class', 'ooc'); @@ -128,28 +199,70 @@ dt.appendChild(figcaption); //dd.appendChild(document.createTextNode(f[Math.floor(responseObject.White.src[0])] + ((responseObject.White.src[0]) * 10 + 1 - Math.floor(responseObject.White.src[0]) * 10))); // Convert x-coordinate to the chess' counterpart (while avoiding (inaccurate) floats). //var dd2 = document.createElement('dd'); //dd.setAttribute('class', 'new'); +if (responseObject.White.dst.length === 2) { +var i = document.createElement('img'); +i.setAttribute('class', 'black'); +var figcaption = document.createElement('figcaption'); +i.setAttribute('src', 'i/' + responseObject.White.dst[1].substring(0, 2) + '.png'); +figure.appendChild(dd); +dd.appendChild(i); +dd.appendChild(figcaption); +figcaption.appendChild(document.createTextNode(responseObject.White.dst[0])); +} else { +dd.setAttribute('class', 'noimg'); figure.appendChild(dd); //dd.appendChild(document.createTextNode(f[responseObject.White.dst[0])] + ((responseObject.White.dst[0]) * 10 + 1 - Math.floor(responseObject.White.dst[0]) * 10))); dd.appendChild(document.createTextNode(responseObject.White.dst[0])); +} d.appendChild(li); var dt = document.createElement('dt'); var figure = document.createElement('figure'); +figure.setAttribute('class', 'black'); var i = document.createElement('img'); var figcaption = document.createElement('figcaption'); var dd = document.createElement('dd'); li.appendChild(figure); i.setAttribute('src', 'i/' + responseObject.Black.src[1].substring(0, 2) + '.png'); -figure.appendChild(i); figure.appendChild(dt); +dt.appendChild(i); //figcaption.appendChild(document.createTextNode(f[Math.floor(responseObject.Black.src[0])] + ((responseObject.Black.src[0]) * 10 + 1 - Math.floor(responseObject.Black.src[0]) * 10))); figcaption.appendChild(document.createTextNode(responseObject.Black.src[0])); dt.appendChild(figcaption); +if (responseObject.Black.dst.length === 2) { +var i = document.createElement('img'); +i.setAttribute('class', 'white'); +var figcaption = document.createElement('figcaption'); +i.setAttribute('src', 'i/' + responseObject.Black.dst[1].substring(0, 2) + '.png'); +figure.appendChild(dd); +dd.appendChild(i); +dd.appendChild(figcaption); +figcaption.appendChild(document.createTextNode(responseObject.Black.dst[0])); +} else { +dd.setAttribute('class', 'noimg'); figure.appendChild(dd); //dd.appendChild(document.createTextNode(f[Math.floor(responseObject.Black.dst[0])] + ((responseObject.Black.dst[0]) * 10 + 1 - Math.floor(responseObject.Black.dst[0]) * 10))); dd.appendChild(document.createTextNode(responseObject.Black.dst[0])); +} d.appendChild(li); +} else { +var h1TN = statusm[0]; +h1.innerHTML = h1TN; +document.body.insertBefore(h1, h2); +var h2TN = statusm[3]; +if (count > 1) { +if (count > 3) { +var suffix = defsuffix; +} else { +var suffix = nrsuffix[count-1]; +} +h2.innerHTML = h2TN + ' for the ' + count + '' + suffix + '' + ' time.'; +} else { +h2.innerHTML = h2TN; +} +document.body.insertBefore(h2, I('board')); +count++; } // TODO: Display status and/or sleep. //I('title').innerHTML = responseObject.Black.src[1] + ' moves from ' + responseObject.Black.src[0] + ' to ' + responseObject.Black.dst[0]; @@ -157,6 +270,13 @@ d.appendChild(li); //I('description').innerHTML = 'Turn ' + responseObject.White.status.length + ' of white.'; //I('title').innerHTML = responseObject.Black.status[0]; //I('description').innerHTML = responseObject.Black.status[1]; +} else { +var h1TN = statusm[8]; +var h2TN = statusm[9]; +h2.innerHTML = h2TN; +document.body.insertBefore(h2, I('board')); +h1.innerHTML = h1TN; +document.body.insertBefore(h1, h2); } } } diff --git a/chess_gui/public/js/head.js b/chess_gui/public/js/head.js index ffe4f70..6ea6c05 100644 --- a/chess_gui/public/js/head.js +++ b/chess_gui/public/js/head.js @@ -1,3 +1,5 @@ +// (C) Roy van Lunsen + function I(a) { return document.getElementById(a); } diff --git a/chess_gui/views/index.html b/chess_gui/views/index.html index d19f302..4603495 100644 --- a/chess_gui/views/index.html +++ b/chess_gui/views/index.html @@ -10,11 +10,8 @@ Game of chess -
-
    - -
    1. A
    2. B
    3. C
    4. D
    5. E
    6. F
    7. G
    8. H
    -
    +

    New game

    +

    Replays

      @@ -47,6 +44,11 @@

    +
    +
      + +
      1. A
      2. B
      3. C
      4. D
      5. E
      6. F
      7. G
      8. H
      +