Just Javascript Bridge Card Game Primer Tutorial

Just Javascript Bridge Card Game Primer Tutorial

Just Javascript Bridge Card Game Primer Tutorial

“Commonalities and differences” is a strategy for code development. A good enough guinea pig and you can shape it into something “similar, but different”. The 500 card game of recent times has code to shape into a Bridge card game with some provisos …

  • Bridge scoring we have only started … it is far more complicated than 500 card game scoring
  • Bridge is simpler regarding kitties … there are none
  • Bridge is simpler regarding bowers and Jokers … there are none
  • Bridge has 13 tricks per round, while 500 card game has 10
  • Contract Bridge has teams of 2 x 2 like 500 card game
  • Bridge has bidding like 500 but more options and no Misรจre … but …
  • like the 500 card game’s Open Misรจre bid the partner of the winning bidder in Bridge always exposes their hand

… and so can you see why the work of yesterday’s Just Javascript Five Hundred Card Game Early Complete Exit Tutorial is such a good guinea pig for a big leg up developing a Bridge Card Game web application “Just Javascript”?!

We created a “mapping function” to help …


function ulgame(instg) {
if (instg.indexOf('500 ') == 0 && card_game.toLowerCase() == 'bridge') {
instg=instg.replace(/500\ /g, 'Bridge ');
} else if (instg.toLowerCase() == instg && card_game.toLowerCase() == 'bridge') {
return 'bridge';
} else if (instg.toUpperCase() == instg && card_game.toLowerCase() == 'bridge') {
return 'BRIDGE';
}
return instg;
}

… with a whole lot of “if logic” codelines such as …


if (card_game == ulgame('500ISH')) {
// 500 2 x 2 or Bridge 2 x 2 logic can go here
}

… amongst a lot of other web inspector inspired changes to get to the changed cards_usefocus.html code behind the “Just Javascript” Memories Card Game or live run with single window (good for mobile) or default live run (for your platform, and if non-mobile it will try child popup windows). Try adding “.0” to number of card players to play (our hybrid) “500” card game, and optionally wait or immediately append a comma separated email/SMS address/number list for your “500 card game” players (who can affect the game remotely via email)! Try adding “.1” to number of card players to play (our hybrid) “Bridge” card game, and optionally wait or immediately append a comma separated email/SMS address/number list for your “Bridge card game” players (who can affect the game remotely via email)!


Previous relevant Just Javascript Five Hundred Card Game Early Complete Exit Tutorial is shown below.

Just Javascript Five Hundred Card Game Early Complete Exit Tutorial

Just Javascript Five Hundred Card Game Early Complete Exit Tutorial

Yesterday’s Just Javascript Five Hundred Card Game Early Exit Tutorial talked of …

  • “Early Exit” from a “round” of 500 card game play that contributes to, depending on how competitive you make these things, scoring towards that 500 (or -500 … boo hoo) completion of the “official” version of the game … but …
  • perhaps you have a fierce Player 1 and Player 3 versus Player 2 and Player 4 rivalry going on … no fisticuffs, pleeeeeaaaaassssse … which makes you interested, as far as playing 500 goes with keeping track of that Player 1 and Player 3 versus Player 2 and Player 4 rivalry in terms of scoring, perhaps ongoing, which we can help with, and carry through, if you have that remote email player arrangement

In that last case above, we arrange automation of the scoring, in our variable “scoresuffix” … so that …

  • on a player team reaching 500 or the other reaching -500 …
  • in that arrangement with all remote lowercase email addresses defined …
  • we now “chain along” (into our GET ? and & arguments) a new “overallss” of the form …

    &overallss=[Player 1 and Player 3 score],[Player 2 and Player 4 score]

    … facilitating …
  • on such a scenario, the “chain along” of the “scoresuffix” becomes …

    &scoresuffix=0.0,0.0,0.0,0.0

    … effectively completing resetting the 500 card game … but …
  • remembering the rivalry, recording the “overallss” situation within the subject lines of the emails that get sent out when a trick is won, this trick triggering an exit from the “round of play” and from “the 500 card game” as nominally understood … as per


function oraass(inss) {
if (aass != '') {
if (inss != aass && defstyle.indexOf(inss) != -1) { llj=alterurl(llj); defstyle=defstyle.replace(inss,aass); document.head.innerHTML=bpmore(defstyle); }
return aass;
}
return inss;
}


function alterurl(inllj) {
if (eval(eval('' + jscores[0]) + eval('' + jscores[2])) >= 500) {
endgameblurb='Congratulations, Player 1 and Player 3 for reaching 500. '; //Another game?')) {
//lurldone=true;
//location.href=lurl();
//jscores=[0,0,0,0];
inllj=inllj.replace(inllj.split('scoresuffix=')[1].split('&')[0], encodeURIComponent('0.0,0.0,0.0,0.0'));
overallscores[0]++;
inllj=inllj.replace(inllj.split('overallss=')[1].split('&')[0], encodeURIComponent('' + overallscores[0] + ',' + overallscores[1]));
endgameblurb+=' Overall scores Player 1 and Player 3 - ' + overallscores[0] + ' and Player 2 and Player 4 - ' + overallscores[1] + '. ';
} else if (eval(eval('' + jscores[1]) + eval('' + jscores[3])) >= 500) {
endgameblurb='Congratulations, Player 2 and Player 4 for reaching 500. '; // Another game?')) {
//lurldone=true;
//location.href=lurl();
//jscores=[0,0,0,0];
inllj=inllj.replace(inllj.split('scoresuffix=')[1].split('&')[0], encodeURIComponent('0.0,0.0,0.0,0.0'));
overallscores[1]++;
inllj=inllj.replace(inllj.split('overallss=')[1].split('&')[0], encodeURIComponent('' + overallscores[0] + ',' + overallscores[1]));
endgameblurb+=' Overall scores Player 2 and Player 4 - ' + overallscores[1] + ' and Player 1 and Player 3 - ' + overallscores[0] + '. ';
} else if (eval(eval('' + jscores[0]) + eval('' + jscores[2])) <= -500) {
endgameblurb='Congratulations, Player 2 and Player 4 for opponents reaching -500. '; // Another game?')) {
//lurldone=true;
//location.href=lurl();
//jscores=[0,0,0,0];
inllj=inllj.replace(inllj.split('scoresuffix=')[1].split('&')[0], encodeURIComponent('0.0,0.0,0.0,0.0'));
overallscores[1]++;
inllj=inllj.replace(inllj.split('overallss=')[1].split('&')[0], encodeURIComponent('' + overallscores[0] + ',' + overallscores[1]));
endgameblurb+=' Overall scores Player 2 and Player 4 - ' + overallscores[1] + ' and Player 1 and Player 3 - ' + overallscores[0] + '. ';
} else if (eval(eval('' + jscores[1]) + eval('' + jscores[3])) <= -500) {
endgameblurb='Congratulations, Player 1 and Player 3 for opponents reaching -500. '; // Another game?')) {
//lurldone=true;
//location.href=lurl();
//jscores=[0,0,0,0];
inllj=inllj.replace(inllj.split('scoresuffix=')[1].split('&')[0], encodeURIComponent('0.0,0.0,0.0,0.0'));
overallscores[0]++;
inllj=inllj.replace(inllj.split('overallss=')[1].split('&')[0], encodeURIComponent('' + overallscores[0] + ',' + overallscores[1]));
endgameblurb+=' Overall scores Player 1 and Player 3 - ' + overallscores[0] + ' and Player 2 and Player 4 - ' + overallscores[1] + '. ';
}
return inllj;
}



function documenttitleeq(indt) {
var bburl=aaurl;
documenttitle=indt;
if (card_game.toLowerCase() == '500ish') {
if (card_game == '500ISH') {
document.title='500 card game where winning bid is ' + (cbid + ' (by Player ' + cbidby + ')').replace('None (by Player 1)','Pass').replace('None','Pass').replace('1','1,Player III').replace('2','2,Player IV').replace('3','3,Player 1').replace('4','4,Player 2').replace('III','3').replace('IV','4') + ' and trumps are ' + trumpsare.replace('c','Club').replace('d','Diamond').replace('s','Spade').replace('h','Heart').replace('0','No Trump') + 's' + ' ... ' + scoresuffix + sss;
if (eval('' + nominal_numplayers + ' * (' + scoresuffix.replace(/\,/g, ' + ') + ')') >= 40 || gameover != '') {
if (eval('' + totcpp) > 0) {
totcpp=-totcpp;
if (llj == '') { llj=sfhz(false); }
if (('' + emailsms[0]).indexOf('@') != -1 && ('' + emailsms[0]).toLowerCase() == ('' + emailsms[0])) {
scoresuffix=oraass(scoresuffix);
location.href=alterurl(llj);
} else if (confirm( ((bburl == aaurl) ? 'Thanks for playing the 500 card game ... ' + oraass(scoresuffix) + sss + ' ... OK to play again?' : endgameblurb + ' Thanks for playing the 500 card game ... ' + oraass(scoresuffix) + sss + ' ... OK to play again?') )) {
location.href=alterurl(llj); //lurl();
}
}
}
} else {
if (cbid.replace('None', '') != '') {
document.title='500 card game where winning bid is ' + (cbid + ' (by Player ' + cbidby + ')').replace('None (by Player 1)','Pass').replace('None','Pass').replace('1','1,Player III').replace('2','2,Player IV').replace('3','3,Player 1').replace('4','4,Player 2').replace('III','3').replace('IV','4') + ' and trumps are ' + trumpsare.replace('c','Club').replace('d','Diamond').replace('s','Spade').replace('h','Heart').replace('0','No Trump') + 's' + ' ... ' + scoresuffix + sss;
} else if (in_bidding) {
document.title='500 card game ... ' + scoresuffix + sss;
} else {
document.title='500 (hybrid) card game ... ' + scoresuffix + sss;
}
if (eval('' + nominal_numplayers + ' * (' + scoresuffix.replace(/\,/g, ' + ') + ')') >= Math.abs(eval('' + totcpp))) {
if (eval('' + totcpp) > 0) {
totcpp=-totcpp;
if (confirm('Thanks for playing the 500 (hybrid) card game ... ' + scoresuffix + sss + ' ... OK to play again?')) {
location.href=document.URL;
}
}
}
}
} else {
document.title=documenttitle;
}
}

In light of this, the scenario of today’s tutorial picture may horrify some and amuse others, as the scenario of the world’s shortest game of 500 …

  • Player 1 bids 10n (ie. 10 no trumps)
  • Player 1 leads
  • Player 2 beats the lead
  • Player 3 cannot beat the card of Player 2 … it’s all done and dusted … but …
  • Player 4 cannot beat the card of Player 2 … seals the (bad) deal …
  • Score becomes -0.520,1.0,0.0,0.0 (as reflected on emails sent to players) … and …
  • the 500 card game application sets the score to 0.0,0.0,0.0,0.0 (for internal use only) and overallss to 0,1 with an “as if from the start” shuffling and dealing of new cards … the “as if” in “as if from the start” is pertinent … nowadays a new game like this has Player 2 replace Player 1 as the “dealer” (but Player 1 remains the “host”)

Still going as “Just Javascript” (ie. no “body” element definition) try the changed cards_usefocus.html code behind the “Just Javascript” Memories Card Game or live run with single window (good for mobile) or default live run (for your platform, and if non-mobile it will try child popup windows). Try adding “.0” to number of card players to play (our hybrid) “500” card game, and optionally wait or immediately append a comma separated email/SMS address/number list for your “500 card game” players (who can affect the game remotely via email)!


Previous relevant Just Javascript Five Hundred Card Game Open Misรจre Progress Bar Tutorial is shown below.

Just Javascript Five Hundred Card Game Open Misรจre Progress Bar Tutorial

Just Javascript Five Hundred Card Game Open Misรจre Progress Bar Tutorial

Even with yesterday’s Just Javascript Five Hundred Card Game Open Misรจre All Local Tutorial, it may not seem like it, but we have been beavering away keeping the 500 card game “status area” giving relevant information. Today we load it up even more as a dual purpose …

  • background (svg) “rect” element semi-transparent background to 500 card game status area progress bars for Player 1/3 scoring and Player 2/4 scoring … displaying during the bidding and kitty phase of the game … and then …
  • background (svg) “rect” element semi-transparent background to 500 card game status area progress bar for leading bid trick round scoring relative to final bid made … displaying during card play phase of the game

… as per (the multi-purpose) …


function progressbar(inoutss) {
var outss=inoutss;
if (outss == '') { outss=scoresuffix; }
var totball=0;
var totnball=0;
if (card_game == '500ISH') { // && cbid.replace('None','pass') != 'pass') {
var prevbb=bbtextb;
var tonget=0;
var ssare=outss.replace(/\-/g,'').split(',');
var ssallare=outss.split(',');
var abbtextb=bbtextb;
if (!in_bidding && !in_kitty) {
var tott=eval(Math.floor(eval(ssare[0])) + Math.floor(eval(ssare[1])) + Math.floor(eval(ssare[2])) + Math.floor(eval(ssare[3])));
var totb=0;
var totnb=0;

var toget=-10;
if (('' + cbid).substring(0,1) == '6') { toget=6; tonget=4; }
if (('' + cbid).substring(0,1) == '7') { toget=7; tonget=3; }
if (('' + cbid).substring(0,1) == '8') { toget=8; tonget=2; }
if (('' + cbid).substring(0,1) == '9') { toget=9; tonget=1; }
if (('' + cbid).substring(0,2) == '10') { toget=10; tonget=0; }
if (('' + cbidby).replace('3','1') == '1') {
totb=eval(Math.floor(eval(ssare[0])) + Math.floor(eval(ssare[2])));
totnb=eval(Math.floor(eval(ssare[1])) + Math.floor(eval(ssare[3])));
abbtextb="<rect x='0' y='0' width='1400' height='48' fill='rgba(255,0,0,0.3)' />";
} else {
totnb=eval(Math.floor(eval(ssare[0])) + Math.floor(eval(ssare[2])));
totb=eval(Math.floor(eval(ssare[1])) + Math.floor(eval(ssare[3])));
abbtextb="<rect x='0' y='0' width='1400' height='48' fill='rgba(0,255,0,0.3)' />";
}

if (('' + toget) == '-10') {
if (eval('' + totb) > 0) {
bbtextb=abbtextb.replace(" width='" + abbtextb.split(" width='")[1].split("'")[0] + "'", " width='0'");
//if (defstyle.indexOf(prevbb) == -1) { alert('Oops'); }
defstyle=defstyle.replace(prevbb, bbtextb);
} else {
bbtextb=abbtextb.replace(" width='" + abbtextb.split(" width='")[1].split("'")[0] + "'", " width='" + ('' + eval(-1400 * eval(totnb) / eval(toget))).split('.')[0] + "'");
//if (defstyle.indexOf(prevbb) == -1) { alert('OOps'); }
defstyle=defstyle.replace(prevbb, bbtextb);
}
} else {
if (eval('' + totnb) > eval('' + tonget)) {
bbtextb=abbtextb.replace(" width='" + abbtextb.split(" width='")[1].split("'")[0] + "'", " width='0'");
//if (defstyle.indexOf(prevbb) == -1) { alert('OoPs'); }
defstyle=defstyle.replace(prevbb, bbtextb);
} else {
bbtextb=abbtextb.replace(" width='" + abbtextb.split(" width='")[1].split("'")[0] + "'", " width='" + ('' + eval(1400 * eval(totb) / eval(toget))).split('.')[0] + "'");
//if (defstyle.indexOf(prevbb) == -1) { alert('OopS'); }
defstyle=defstyle.replace(prevbb, bbtextb);
}
}
} else { // progress bar RE 1/3 getting to 500 and 2/4 getting to 500

//alert(11);
totball=eval((eval(((ssallare[0].substring(0,1) == '-') ? '-' : '') + (ssallare[0] + '.0').split('.')[1])) + (eval(((ssallare[2].substring(0,1) == '-') ? '-' : '') + (ssallare[2] + '.0').split('.')[1])));
var x1=700;
var w1=1400;
var x2=700;
var w2=1400;
if (eval('' + totball) < 0) {
w1=eval(-700 * eval('' + totball) / 500);
x1=eval(700 + eval(700 * eval('' + totball) / 500));
} else {
x1=700;
w1=eval(700 * eval('' + totball) / 500);
}
totnball=eval((eval(((ssallare[1].substring(0,1) == '-') ? '-' : '') + (ssallare[1] + '.0').split('.')[1])) + (eval(((ssallare[3].substring(0,1) == '-') ? '-' : '') + (ssallare[3] + '.0').split('.')[1])));
if (eval('' + totnball) < 0) {
w2=eval(-700 * eval('' + totnball) / 500);
x2=eval(700 + eval(700 * eval('' + totnball) / 500));
} else {
x2=700;
w2=eval(700 * eval('' + totnball) / 500);
}
abbtextb="<rect x='" + Math.floor(x1) + "' y='0' width='" + Math.max(Math.floor(w1),1) + "' height='24' fill='rgba(255,0,0,0.3)' /><rect x='" + Math.floor(x2) + "' y='24' width='" + Math.max(Math.floor(w2),1) + "' height='24' fill='rgba(0,255,0,0.3)' />"
bbtextb=abbtextb;
//if (defstyle.indexOf(prevbb) != -1) { alert('abbtextb=' + abbtextb); }
defstyle=defstyle.replace(prevbb, bbtextb);
document.head.innerHTML+=bpmore(defstyle);
}

}
if (inoutss == '') { return bbtextb; }
return outss;
}

This mild form of animation is still “Just Javascript” (ie. no “body” element definition) in the changed cards_usefocus.html code behind the “Just Javascript” Memories Card Game or live run with single window (good for mobile) or default live run (for your platform, and if non-mobile it will try child popup windows). Try adding “.0” to number of card players to play (our hybrid) “500” card game, and optionally wait or immediately append a comma separated email/SMS address/number list for your “500 card game” players (who can affect the game remotely via email)!


Previous relevant Just Javascript Five Hundred Card Game Open Misรจre All Local Tutorial is shown below.

Just Javascript Five Hundred Card Game Open Misรจre All Local Tutorial

Just Javascript Five Hundred Card Game Open Misรจre All Local Tutorial

You may be new to this “500 card game” web application work of yesterday’s Just Javascript Five Hundred Card Game Open Misรจre Wording Tutorial, in which case it may be that we need to reiterate information about the game’s workings …

  • game can be played by 4 players hovering around the same device … non-remote or “All Local” (as in today’s blog posting title) … or …
  • game can be played by a single hoster running this web application, hosting remote (via email or SMS) linked players and perhaps some “All Local” ones

As the project continues we’ve found the logic of the first “All Local” mode lagging behind, because it is harder. Huh?! Well, it is harder because of the bother we need to take to try to allow players to hide their cards from other players, given some “looking away” co-operation from the players when asked to. And so, just because in the last couple of days we made progress with Open Misรจre logic for remote player scenarios, alas, doesn’t mean we’ve had the “All Local” equivalent logic working as well. Today we try evening up that score.

It was hard to take this code line being important in making that happen …


for (var ibidis=0; ibidis<bids.length; ibidis++) {
if (('' + cfm).toLowerCase().indexOf('pass') == 0) {
isbid=true;
gd=('' + dis);
sentanswer='pass ';
console.log('3:sentclick() and ma=' + ma);
cfm=''; //null;
sentclick();
} else if (('' + cfm + ' ').substring(0,3).toLowerCase() == (bids[ibidis] + ' ').substring(0,3).toLowerCase()) {
isbid=true;
gd=('' + dis);
sentanswer=bids[ibidis] + ' ';
console.log('4:sentclick()');
sentclick();
}
}

… we found via “console.log” web inspector tracking down. We suspect, but did not research, that the reason “passcnt” went weird for “All Local” scenarios was as a result of some setTimeout logic self-incrementing “passcnt” programmatically, meaning the first pass bid (rather than the third, which is better) was setting off the Kitty logic ahead of time. Fixed now though!

The “sss” variable emoji logic was also causing trouble for Open Misรจre status content fixed via


if (cbid.slice(-1).toLowerCase().replace('h','d') == 'd') {
sss=' leading ' + cbidby + ' bid ' + cbid + ' ' + emojisuit() + ' ';
} else {
sss=' leading ' + cbidby + ' bid ' + cbid + ' ' + emojisuit();
}
sss=sss.replace('&#232;', String.fromCodePoint(232)).replace('open_', 'open ').replace('&#232;', String.fromCodePoint(232)).replace('open_', 'open ');

With Open Misรจre in All Local mode of use logic we show all players the open hand in a Javascript alert popup window just before the winning bidder is displayed the Kitty Javascript prompt window, as per


if (kittybidding != '') {
donelistis=',1,2,3,4,';
//if (bbpref != '') { alert('cuRplayer'); }
console.log('omc=' + omc + ' and sef(emailsms[0], 0).trim()=' + sef(emailsms[0], 0).trim());
if (eval('' + omc) >= 0 && (eval('' + emailsms.length) < 1 || eval('' + emailsms.length) < 2 || eval('' + emailsms.length) < 3 || eval('' + emailsms.length) < 4)) {
alert('Hello all you non-remote 500 card game players! Here are the cards for public viewing of ' + sef(emailsms[eval(-1 + omc)], eval(-1 + omc)) + ' ... ' + zsuffs[eval(-1 + omc)] + ' ... when you have all finished looking, just leave ' + sef(emailsms[eval(-1 + omh)], eval(-1 + omh)) + ' looking, to then deal with the kitty, as they click the OK button.');
}

cfm=prompt(efs(aapref.replace('In this bidding phase the last winning bid is ','Last winning bid is ').replace(' (bearing in mind that a lowercase email address suffices to enter your next bid, via an email)','') + efs('Player ' + clong(curplayer),curplayer) + ', see your cards below. ' + kittybidding,curplayer),'');

In “All Local” mode of play, can bidding be ignored all together? Yes, backward compatibility is an important principle to try to preserve with ongoing functionalities, where possible, and reasonable.

Yet again, feel free to retry the improved 500 card game part of our changed cards_usefocus.html code behind the “Just Javascript” Memories Card Game or live run with single window (good for mobile) or default live run (for your platform, and if non-mobile it will try child popup windows). Try adding “.0” to number of card players to play (our hybrid) “500” card game, and optionally wait or immediately append a comma separated email/SMS address/number list for your “500 card game” players (who can affect the game remotely via email)!


Previous relevant Just Javascript Five Hundred Card Game Open Misรจre Wording Tutorial is shown below.

Just Javascript Five Hundred Card Game Open Misรจre Wording Tutorial

Just Javascript Five Hundred Card Game Open Misรจre Wording Tutorial

With our 500 card game web application of yesterday’s Just Javascript Five Hundred Card Game Open Misรจre Tutorial the bidding of Misรจre and Open Misรจre bring an unusual dilemma to do with email communication. Even though we hate to confuse we need to weigh …

  • the desire in Misรจre and Open Misรจre for the bidder to lose tricks (rather than the usual way the winning bidder wants to win tricks) … against the use of …
  • double negatives may cause confusion

… and decide on the danger of a bit of “double negatives may cause confusion” because we think most 500 card game players will get it as soon as they see the word “Misรจre” mentioned, coupled with the awkward sentences used (where “subjis” is variable containing email subject content) …


if ((!in_bidding && !in_kitty) && ((cbid + ' ').substring(0,3).toLowerCase() == 'mis' || eval('' + omc) >= 0)) {
spare=subjis;
if ((('' + curplayer) == ('' + omc) || ('' + curplayer) == ('' + omh) || ('' + curplayer) == ('' + cbidby)) && (spare.indexOf('Congratulations') == 0)) {
subjis='Opposite of ' + spare;
} else if ((('' + curplayer) == ('' + omc) || ('' + curplayer) == ('' + omh) || ('' + curplayer) == ('' + cbidby)) && (spare.indexOf('Bad luck') == 0)) {
subjis='Good luck is ' + spare;
} else if ((('' + curplayer) != ('' + omc) && ('' + curplayer) != ('' + omh) && eval('' + omc) >= 0) && (spare.indexOf('Congratulations') == 0)) {
subjis='Sad news about ' + spare;
} else if ((('' + curplayer) != ('' + cbidby) && eval('' + omc) < 0) && (spare.indexOf('Congratulations') == 0)) {
subjis='Sad news about ' + spare;
}
}
subjis=subjis.replace('&#232;', String.fromCodePoint(232)).replace('open_', 'open ').replace('&#232;', String.fromCodePoint(232)).replace('open_', 'open ');

As well, we sort it out that …

  • players can no longer see bidding buttons of irrelevance (bidding has already passed them by) on the emails
  • the open hand card links and buttons in the emails navigate nowhere (except when it is the open hand players turn to play a card)

Again, feel free to retry the improved 500 card game part of our changed cards_usefocus.html code behind the “Just Javascript” Memories Card Game or live run with single window (good for mobile) or default live run (for your platform, and if non-mobile it will try child popup windows). Try adding “.0” to number of card players to play (our hybrid) “500” card game, and optionally wait or immediately append a comma separated email/SMS address/number list for your “500 card game” players (who can affect the game remotely via email)!


Previous relevant Just Javascript Five Hundred Card Game Open Misรจre Tutorial is shown below.

Just Javascript Five Hundred Card Game Open Misรจre Tutorial

Just Javascript Five Hundred Card Game Open Misรจre Tutorial

The 500 card game of yesterday’s Just Javascript Five Hundred Card Game Emoji Entities Tutorial, and incarnation before it, hid from the players the chance to bid …


Open Misรจre

… but we want to remedy this because …

  • it is a fun “out there” addition to the 500 card game
  • it can win the game there and then, worth 500 points to that player pairing that lose all ten tricks with the partner of the winning bidder openly displaying their cards to all players, and played by the winning bidder
  • the bits and pieces to achieve this programmatically are there …

… but, we are going to take this on gradually, our part one, today, fixing a couple of issues with remote email players using the PHP mail method, those being …

  1. add Open Misรจre successful bidder’s partner’s cards in a second table …

    if ((!in_bidding || in_kitty) && eval('' + omc) >= 0) {
    if (('' + hsuffs[eval(-1 + omc)]).replace('null','').indexOf('<table') != -1 && eval('' + curplayer) != eval('' + omc)) {
    outdivhtml=outdivhtml.replace('</table>', '</table><br><p>And here are the cards of the Open player ' + sef(emailsms[eval(-1 + omc)], eval(-1 + omc)) + ' ...</p><br><table' + hsuffs[eval(-1 + omc)].split('<table')[1].split('</table>')[0].replace(/\<tr\ id\=/g, '<tr style=display:none; id=').replace(/SUBMIT/g,'button').replace(/submit/g,'button').replace(/\ href\=/g,' data-href=') + '</table></body>');
    } else if (('' + hsuffs[eval(-1 + omc)]).replace('null','').indexOf('<table') != -1) {
    outdivhtml=outdivhtml.replace('</table>', '</table><br><p>And here are the cards of the Open player ' + sef(emailsms[eval(-1 + omc)], eval(-1 + omc)) + ' ... ' + zsuffs[eval(-1 + omc)] + '</p></body>');
    }
    }

    … within the Inline HTML email to other player emails … and …
  2. when it is the time for the Open Misรจre successful bidder’s partner to play their card, their email is BCC’ed to the Open Misรจre successful bidder’s email address

Feel free to retry the improved 500 card game part of our changed cards_usefocus.html code behind the “Just Javascript” Memories Card Game or live run with single window (good for mobile) or default live run (for your platform, and if non-mobile it will try child popup windows). Try adding “.0” to number of card players to play (our hybrid) “500” card game, and optionally wait or immediately append a comma separated email/SMS address/number list for your “500 card game” players (who can affect the game remotely via email)!


Previous relevant Just Javascript Five Hundred Card Game Emoji Entities Tutorial is shown below.

Just Javascript Five Hundred Card Game Emoji Entities Tutorial

Just Javascript Five Hundred Card Game Emoji Entities Tutorial

We happened to open up a new email client application to the remote 500 card player emails of yesterday’s Just Javascript Five Hundred Card Game Internationalization Tutorial and, at least for our macOS Mail app, the suit and card emojis came up as gobbledegook in the body Inline HTML section of the the emails.

This discovery, though offputting, also lead, by a few minutes ago (writing this blog post), to a two-pronged improvement to our 500 card game web application as per …

  1. the lack of clarity saw us relying (on our non-mobile aspect to viewing) the HTML element title (hover over see blurb) content, and realizing that a full player card list as a title on their name textbox would be just peachy …

    var wsuffs=[];

    function bStringfromCodePoint(jgf) {
    var stile='', igf=0;
    for (var kgf=0; kgf<spcps.length; kgf++) {
    if (('' + spcps[kgf]).split('/')[0] == ('' + jgf)) { igf=kgf; }
    }
    stile=(('' + spcps[eval('' + igf)]).split('.')[0].slice(-3).substring(0,2).toLowerCase().replace('00','Joker aka ').replace('01','Ace of ').replace('02','2 of ').replace('03','3 of ').replace('04','4 of ').replace('05','5 of ').replace('06','6 of ').replace('07','7 of ').replace('08','8 of ').replace('09','9 of ').replace('10','10 of ').replace('11','Jack of ').replace('12','Queen of ').replace('13','King of ') + ('' + spcps[eval('' + igf)]).split('.')[0].slice(-1).replace('c','Club').replace('d','Diamond').replace('s','Spade').replace('h','Heart').replace('0','No Trump') + 's').toLowerCase();
    return stile;
    }

    // Example call codeline ...
    wsuffs[eval(-1 + eval(eval(ixc % nominal_numplayers) + 1))]+=' ' + eval(eval(ixc % nominal_numplayers) + 1) + '.' + Math.floor(eval(ixc + eval('' + nominal_numplayers)) / eval('' + nominal_numplayers)) + ':' + bStringfromCodePoint(eval(spcps[kjn].split('/')[0]));

    // Example of use piecing together remote 500 card player email ...
    outdivhtml=outdivhtml.replace('</TR>', '<td colspan=' + twentythree + '></td></tr><tr><td colspan=10>500 Card Game Player' + eval('' + bidplayer) + ' Name: <input title="' + wsuffs[eval(-1 + bidplayer)].split('' + bidplayer + '.11')[0] + '" type=text name=myname value="' + pnames[eval(-1 + bidplayer)] + '"></input></td><td colspan=20 style=text-align:center;>... relevant to your cards below ...</td></tr>').replace('</thead>','</THEAD>');
  2. the trial of one of the alternative emoji display mechanisms that isn’t String.fromCodePoint([HTML-decimal-entity]) ( ie. &#[HTML-decimal-entity]; ) … eg. Spades ♠ String.fromCodePoint(9824); alternative would be &#9824; … had us, amongst a few things, change

    function nominalemojisuit(ptrumpsare) {
    if (ptrumpsare == 'd') {
    return '&#9830;&#65039;'; //String.fromCodePoint(9830,65039); // &#9830; &#65039;
    } else if (ptrumpsare == 'h') {
    return '&#10084;&#65039;'; //String.fromCodePoint(10084,65039); // &#10084; &#65039;
    } else if (ptrumpsare == 'c') {
    return '&#9827;'; //String.fromCodePoint(9827); // &#10084; &#65039; &#10084; &#65039;
    } else if (ptrumpsare == 's') {
    return '&#9824;'; //String.fromCodePoint(9824); // &#10084; &#65039; &#10084; &#65039;
    } // &#57378;
    return '';
    }

… all fine and good, now, for macOS Mail app (email client), but, more importantly, it did not break with any of the previously working mail applications, making these changes. Yay!!!!!

So please retry the improved 500 card game part of our changed cards_usefocus.html code behind the “Just Javascript” Memories Card Game or live run with single window (good for mobile) or default live run (for your platform, and if non-mobile it will try child popup windows). Try adding “.0” to number of card players to play (our hybrid) “500” card game, and optionally wait or immediately append a comma separated email/SMS address/number list for your “500 card game” players (who can affect the game remotely via email)!


Previous relevant Just Javascript Five Hundred Card Game Internationalization Tutorial is shown below.

Just Javascript Five Hundred Card Game Internationalization Tutorial

Just Javascript Five Hundred Card Game Internationalization Tutorial

Continuing themes from yesterday’s Just Javascript Five Hundred Card Game Email Tutorial we’ve been shoring up aspects to the user experience for our 500 card game web application via …

  • internationalization focus on increased use of …
  • emojis (eg. suit emojis within Inline HTML Emails)

… and along the way discovered flaws in our “follow the same suit as leading card” logic, now centred around


function threetoone(threeis) {
var suitis=('' + threeis).slice(-1).toLowerCase();
var crdis=('' + threeis).substring(0,2);
if (crdis == '11' && trumpsare != '0') {
if (trumpsare.replace('c','s') == 's' && suitis.replace('c','s') == 's' && suitis != trumpsare) {
//alert('right bower played as ' + suitis.replace('c','S').replace('s','C').toLowerCase());
return suitis.replace('c','S').replace('s','C').toLowerCase();
} else if (trumpsare.replace('h','d') == 'd' && suitis.replace('h','d') == 'd' && suitis != trumpsare) {
//alert('Right bower played as ' + suitis.replace('h','D').replace('d','H').toLowerCase());
return suitis.replace('h','D').replace('d','H').toLowerCase();
}
}
return suitis.toLowerCase().replace('0', trumpsare);
}

function maybeno(xxcw) {
var allowthrough=gallow, fnd=false, fnds=[], ifnds=0;
csuffix='';
if (nogolist.indexOf(',' + xxcw + ',') != -1) { if (card_game.toLowerCase() == '500ish') { console.log('oops'); } return '1234567'; }
//alert('thishand.length=' + thishand.length);
if (thishand.length != 0 && card_game.toLowerCase() == '500ish') {
//alert('here');
//if (!allowthrough) { alert('RE ' + ysuffs[eval(-1 + eval('' + curplayer))] + ' ... lead with ' + thishand[0].slice(-1).toLowerCase() + ' and you played ' + hands[eval(0 + xxcw)].slice(-1).toLowerCase()); }
if (!allowthrough && threetoone(thishand[0].slice(-3).toLowerCase()) != threetoone(hands[eval(0 + xxcw)].slice(-3).toLowerCase())) {
fnds=ysuffs[eval(-1 + eval('' + curplayer))].substring(1).split(' ');
for (ifnds=0; ifnds<fnds.length; ifnds++) {
if (fnds[ifnds].indexOf(',') != -1) {
//if joker and trumpsare is lead, relax
//if right bower and trumpsare is lead, relax
if (fnds[ifnds].toLowerCase().indexOf(threetoone(thishand[0].slice(-3).toLowerCase())) != -1) { fnd=true; }
}
}
if (fnd) {
if (eval('' + emailsms.length) >= eval('' + curplayer)) { if (('' + emailsms[eval('' + curplayer)]).trim() != '') { csuffix=' Will resend last email if you cancel this play.'; } }
allowthrough=confirm('You could follow suit (where trumps are ' + trumpsare.replace('c','Club').replace('d','Diamond').replace('s','Spade').replace('h','Heart').replace('0','No Trump') + 's' + '), Player ' + clong(curplayer) + '! Allow through anyway?' + csuffix);
if (!allowthrough) { if (1 == 11) { alert('False'); } if (eval('' + emailsms.length) >= eval('' + curplayer)) { retcom(pmesg, pretv); } return '1234568'; } else { if (1 == 11) { alert('True'); } }
}
}
}
return xxcw;
}

… as well as non-mobile users being able to hover over bidding buttons to discover what their team scores with that bid, and the background image text up the top left mentioning “Bid” during any bidding phase and “Click (via email) away …” or “Click (via SMS) away …” for remote players, back for the hoster’s web application window, during the “playing out of the tricks” phase of the 500 card game, hopefully establishing a means by which the hoster can know what is, or is not and should be, going on with the hoster’s 500 card game, and so enabling informed email communication to get the games back on the rails, perhaps.

Please retry the improved 500 card game part of our changed cards_usefocus.html code behind the “Just Javascript” Memories Card Game or live run with single window (good for mobile) or default live run (for your platform, and if non-mobile it will try child popup windows). Try adding “.0” to number of card players to play (our hybrid) “500” card game, and optionally wait or immediately append a comma separated email/SMS address/number list for your “500 card game” players (who can affect the game remotely via email)!


Previous relevant Just Javascript Five Hundred Card Game Email Tutorial is shown below.

Just Javascript Five Hundred Card Game Email Tutorial

Just Javascript Five Hundred Card Game Email Tutorial

In a blog post some time before yesterday’s Just Javascript Five Hundred Card Game CC Tutorial we talked of “order” when we presented Just Javascript Five Hundred Card Game Order Tutorial. Don’t know about you, but I find the combination of …

  • form … and …
  • table

… based Inline HTML in an email, asking for interactive input, “orderly”.

Probably we normally think of data to append to an established “table” element via the addition of a new row (“tr” element) or cell (within a row via a “td” or “th” element). Within a “table” element though, you can think of “partitions” in the form of …

  • thead … and …
  • tbody

… which have that synergy with a webpage’s “head” and “body” elements, the theme of the current blog posting thread being to do away with the need for a “body” element (except for our Inline HTML Emails (which can’t really do anything much without their “body” elements)).

We do a bit of uppercase/lowercase work with the end of “thead” element (ie. </THEAD>) to leave our email Inline HTML “table” “thead” elements blank for …

  • 500 card game “bidding” emails … and for …
  • 500 card game “kitty/bidding” emails

… but then start to fill in the “thead” element for the “playing out of the tricks” emails, adding today’s work, better card game status information, added to the top of the tabular information presented. Rather than fret about adding to the top, we just slot into the unallocated “thead” slot, for these scenarios, as per


function tabord(indivhtml) {
var ilook=0, jlook=1, klook=0, cbidfound='SUBMIT', tdyellow='';
var slookfor=[' data-suit=s', ' data-suit=c', ' data-suit=d', ' data-suit=h'];
var slooks=[];
var outdivhtml='<br><style> isyellow { background-color:yellow; </style><table border=2><thead></thead><tbody></tbody></table>'
if (in_bidding) {
twentythree=30;
//outdivhtml=outdivhtml.replace('</tbody>', '<tr><td>Bidding<br>Current Bid: ' + cbid + '<td><input type=SUBMIT name=myanswer value="pass "></input></td></TR></tbody>');
if (in_kitty) {
console.log('tds_kitty=' + tds_kitty);
outdivhtml=outdivhtml.replace('</tbody>', tds_kitty + '</tbody>'); //.replace('</thead>','</THEAD>');
outdivhtml=outdivhtml.replace('</tbody>', '<tr><td>Bidding<br>Your Current Bid: None<td><input type=' + cbidfound + ' name=myanswer value="pass "></input></td></TR></tbody>');
} else {
outdivhtml=outdivhtml.replace('</tbody>', '<tr><td>Bidding<br>Current Bid: None<td><input type=' + cbidfound + ' name=myanswer value="pass "></input></td></TR></tbody>');
}
if (cbid.toLowerCase().trim().replace('pass','none').replace('none','') != '') { cbidfound='button'; }
twentythree--;
twentythree--;
for (klook=0; klook<bids.length; klook++) {
if (bids[klook].toLowerCase().trim() == cbid.toLowerCase().trim()) { tdyellow=' title="Current leading bid by Player ' + cbidby + '" class=isyellow'; }
if (bids[klook].indexOf('open') == 0) {
outdivhtml=outdivhtml.replace('</TR>', '<td' + tdyellow + '><input style=display:none; type=' + cbidfound + ' name=myanswer value=' + bids[klook] + '></input></td></TR>');
} else {
outdivhtml=outdivhtml.replace('</TR>', '<td' + tdyellow + '><input type=' + cbidfound + ' name=myanswer value="' + bids[klook] + ' "></input></td></TR>');
}
if (bids[klook].toLowerCase().trim() == cbid.toLowerCase().trim()) { cbidfound='SUBMIT'; }
twentythree--;
tdyellow='';
}
//outdivhtml=outdivhtml.replace('</TR>', '<td colspan=' + twentythree + '></td></tr><tr><td colspan=10>500 Card Game Player' + eval('' + bidplayer) + ' Name: <input type=text name=myname value="' + pnames[eval(-1 + bidplayer)] + '"></input></td><td colspan=20 style=text-align:center;>... relevant to your cards below ...</td></tr>' + tds_kitty).replace('</thead>','</THEAD>');
outdivhtml=outdivhtml.replace('</TR>', '<td colspan=' + twentythree + '></td></tr><tr><td colspan=10>500 Card Game Player' + eval('' + bidplayer) + ' Name: <input type=text name=myname value="' + pnames[eval(-1 + bidplayer)] + '"></input></td><td colspan=20 style=text-align:center;>... relevant to your cards below ...</td></tr>').replace('</thead>','</THEAD>');
} else if (in_kitty) {
//alert('in_kitty=t ' + tds_kitty + ' ... ' + outdivhtml);
console.log('Tds_kitty=' + tds_kitty);
outdivhtml=outdivhtml.replace('</tbody>', tds_kitty + '</tbody>').replace('</thead>','</THEAD>');
}
for (ilook=0; ilook<slookfor.length; ilook++) {
slooks=(indivhtml + ' <input ').split(slookfor[ilook]);
if (in_bidding && !in_kitty) {
for (jlook=0; jlook<slooks.length; jlook++) {
slooks[jlook]=slooks[jlook].replace('>:','><br>').replace(/submit/g,'button').replace(/\ href\=/g,' data-href=').replace(/background\-color\:yellow\;/g,'').replace(/background\-color\:lightgreen\;/g,'').replace(/border\:5px\ solid\ yellow\;/g,'');
}
}
twentythree=30;
outdivhtml=outdivhtml.replace('</tbody>', '<tr><td>' + slookfor[ilook].replace(' data-suit=','').replace('c','Club').replace('d','Diamond').replace('s','Spade').replace('h','Heart').replace('0','No Trump') + 's' + '</td></TR></tbody>');
twentythree--;
for (jlook=1; jlook<slooks.length; jlook++) {
outdivhtml=outdivhtml.replace('</TR>', '<td> <input' + slooks[jlook].split(' <input ')[0].replace('>:','><br>') + '</td></TR>');
twentythree--;
}
outdivhtml=outdivhtml.replace('</TR>', '<td colspan=' + twentythree + '></tr>');
}
//alert(outdivhtml);
//in_kitty=false;
return outdivhtml.replace('<thead></thead>', '<thead><td colspan=' + twentythree + '>500 Card Game Player' + eval('' + curplayer) + ' Name: <input type=text name=myname value="' + pnames[eval(-1 + curplayer)] + '"></input><br> ' + sss.replace(/h\ \ /g,'h <font color=red>').replace(/\ \ /g,'</font>').replace(/d\ \ /g,'d <font color=red>').replace(/\ \ /g,'</font>').replace(/h\<\/font\>/g,'h <font color=red>').replace(/d\<\/font\>/g,'d <font color=red>') + '<br> for Trick ' + tricknumber + ' (progress so far) ... ' + wemstuff.replace(/\-\ \ /g, '- <font color=red>').replace(/\ \ /g, '</font>') + '</td></tr></thead>');
}

You may have noticed with yesterday’s work, improvements to the email subject lines during the 500 card game “playing of the tricks” phase, but there are two good reasons to prefer to (additionally) do this in the email body section’s Inline HTML. There, you can …

  • change heart and diamond suit emojis to red within … <font color=red></font>
  • web browser zooming in combination with a webmail browser based email client can have you zooming in and improving the visibility of the card and suit emojis

Please retry the tweaked 500 card game part of our changed cards_usefocus.html code behind the “Just Javascript” Memories Card Game or live run with single window (good for mobile) or default live run (for your platform, and if non-mobile it will try child popup windows). Try adding “.0” to number of card players to play (our hybrid) “500” card game, and optionally wait or immediately append a comma separated email/SMS address/number list for your “500 card game” players (who can affect the game remotely via email)!


Previous relevant Just Javascript Five Hundred Card Game CC Tutorial is shown below.

Just Javascript Five Hundred Card Game CC Tutorial

Just Javascript Five Hundred Card Game CC Tutorial

On top of yesterday’s Just Javascript Five Hundred Card Game Names Tutorial “names for numbers” work, today we have two themes to the work …

  • shore up that offer on the “500 card game” first Javascript prompt window to enter email/SMS addresses/numbers straight away, meaning no more Javascript prompt windows appear until the end of the game if players follow suit … and …
  • should the host of the “500 card game” wait to enter email/SMS addresses/numbers later they can then enter comma separated email/SMS address/number lists which get recognised as any 3 combinations of …
    1. email address (and you can specify a name for those all lowercase PHP mail Inline HTML Email scenarios) and mixed case for mailto: emails for the To: recipient
    2. email address for a CC: recipient (mixed case for mailto: emails)
    3. email address for a BCC: recipient (mixed case for mailto: emails)
    4. SMS number

… which we facilitated among the changed “fes()” function we show below, along with its buddies …


function sff(ines, nines) { // expand out Player n
var outes='', thisp=0;
ines=ines.replace(/Player\ Player\ /g,'Player ');
if (ines.indexOf('Click away Player ') != -1) {
var withins=ines.split('Click away Player ');
outes=withins[0];
for (var igfd=1; igfd<withins.length; igfd++) {
if (('' + pnames[eval(-1 + eval('' + nines))]) == 'Player ' + nines) {
//alert('Here');
outes+=('Click away Player ' + withins[igfd]);
} else {
//alert('here');
outes+=('Click away Player ' + withins[igfd]).replace('Click away Player ', 'Click away ' + pnames[eval(-1 + eval('' + nines))] + ' ');
}
}
return outes;
}
return ines;
}

function efs(ines, nines) { // expand out Player n
var outes='', thisp=0;
//alert('In ines=' + ines + ' pnames[0]=' + pnames[0]);
ines=ines.replace(/Player\ Player\ /g,'Player ');
if (ines.indexOf('Player ') != -1) {
var withins=ines.split('Player ');
outes=withins[0];
for (var igfd=1; igfd<withins.length; igfd++) {
yhisp=withins[igfd].split('[')[0].split(')')[0].split(',')[0].split('?')[0].split('"')[0].split("'")[0].split('<')[0].split(' ')[0];
console.log('yhisp=' + yhisp);
if (('' + yhisp + 'x').substring(0,1) < '0' || ('' + yhisp + 'x').substring(0,1) > '9') {
outes+='Player ' + withins[igfd];
} else if (eval('' + pnames.length) > eval(-1 + eval('' + yhisp))) {
//alert('yhisp=' + yhisp + ' is it in ' + 'Player ' + withins[igfd] + ' ... ' + pnames[eval(-1 + eval('' + yhisp))] + ' += ' + ('Player ' + withins[igfd]).replace('Player ' + yhisp, pnames[eval(-1 + eval('' + yhisp))]) + ' ines=' + ines + ' becomes ' + 'outes=' + outes + ' so far');
outes+=('Player ' + withins[igfd]).replace('Player ' + yhisp, pnames[eval(-1 + eval('' + yhisp))]);
} else {
outes+='Player ' + withins[igfd];
}
}
//alert('Out ines=' + outes.replace('500 Card Game Player', '500 Card Game Player '));
return outes.replace('500 Card Game Player', '500 Card Game Player ');
}
return ines;
}


function esf(ines, nines) { // if specified name, return that instead
if (eval('' + pnames.length) > eval(0 + Math.max(eval('' + nines),eval('' + nines)))) {
return pnames[eval(0 + Math.max(eval('' + nines),eval('' + nines)))];
}
return ines;
}


function fesh(xines) {
if (xines.indexOf('[') != -1) {
return xines.split('[')[1].split(']')[0];
}
return xines;
}


function fes(ines, nines) { // strip Name Of[email@at] to email@at
var prevcsuff='';
var sc='';
var hjg='';
var ipl=0, jpl=0;
var coms=ines.split(',');
if (eval('' + coms.length) > 1) {
if (coms[1].indexOf('@') != -1 && coms[0].indexOf('@') == -1) {
sc=ines.replace(',' + coms[1], '');
ines=coms[1] + ',' + sc;
coms=ines.split(',');
} else if (coms[eval(-1 + coms.length)].indexOf('@') != -1 && coms[0].indexOf('@') == -1) {
sc=ines.replace(',' + coms[eval(-1 + coms.length)], '');
ines=coms[eval(-1 + coms.length)] + ',' + sc;
coms=ines.split(',');
}
ines=coms[0];
for (jpl=1; jpl<coms.length; jpl++) {
if (jpl == 1) {
ccnames[eval('' + nines)]=fesh(coms[jpl]);
} else {
bccnames[eval('' + nines)]=fesh(coms[jpl]);
}
}
return ines;
}
var nameas=ines.split('[');
if (eval('' + nameas.length) == 2) {
if (nameas[1].indexOf(']') != -1 || 1 == 1) {
while (eval('' + pnames.length) < eval('' + nines)) {
pnames.push('Player ' + eval(1 + pnames.length));
}
if (('' + nines).indexOf('-') == -1) {
while (eval('' + pnames.length) < eval('' + nines)) {
pnames.push('Player ' + eval(1 + pnames.length));
}
}
pnames[eval(0 + Math.max(eval('' + nines),eval('' + nines)))]=nameas[0];
ines=ines.replace(nameas[0] + '[','').replace(']','');
prevcsuff=csuff;
csuff='';
hjg='' + curplayer;
for (ipl=0; ipl<hjg.length; ipl++) {
csuff+=String.fromCodePoint(eval(8320 + eval(eval('' + hjg.substring(ipl,eval(1 + eval('' + ipl))).charCodeAt(0)) - 48)));
}
defstyle=defstylereplace(' ' + prevcsuff + '', ' ' + csuff);
document.head.innerHTML+=bpmore(defstyle);
}
} else if (ines.indexOf('@') == -1 && ines.replace(/0/g,'').replace(/1/g,'').replace(/2/g,'').replace(/3/g,'').replace(/4/g,'').replace(/5/g,'').replace(/6/g,'').replace(/7/g,'').replace(/8/g,'').replace(/9/g,'').trim() != '') {
pnames[eval(0 + Math.max(eval('' + nines),eval('' + nines)))]=nameas[0];
ines='';
prevcsuff=csuff;
csuff='';
hjg='' + curplayer;
for (ipl=0; ipl<hjg.length; ipl++) {
csuff+=String.fromCodePoint(eval(8320 + eval(eval('' + hjg.substring(ipl,eval(1 + eval('' + ipl))).charCodeAt(0)) - 48)));
}
defstyle=defstylereplace(' ' + prevcsuff + '', ' ' + csuff);
document.head.innerHTML+=bpmore(defstyle);
} else {
prevcsuff=csuff;
csuff='';
hjg='' + curplayer;
for (ipl=0; ipl<hjg.length; ipl++) {
csuff+=String.fromCodePoint(eval(8320 + eval(eval('' + hjg.substring(ipl,eval(1 + eval('' + ipl))).charCodeAt(0)) - 48)));
}
defstyle=defstylereplace(' ' + prevcsuff + '', ' ' + csuff);
document.head.innerHTML+=bpmore(defstyle);
}
return ines;
}


function sef(ines, nines) { // expand out email@at
if (eval('' + pnames.length) > eval(0 + Math.max(eval('' + nines),eval('' + nines)))) {
return pnames[eval(0 + Math.max(eval('' + nines),eval('' + nines)))] + '[' + ines + ']';
}
return ines;
}


function ccbcc(ines, nines) { // add to mailto: URL
var ccb='';
//alert('ccnames[0]=' + ccnames[0]);
if (eval('' + ccnames.length) > eval(0 + Math.max(eval('' + nines),eval('' + nines)))) {
if (ccnames[eval(0 + Math.max(eval('' + nines),eval('' + nines)))].indexOf('[') != -1) {
ccb='&cc=' + ccnames[eval(0 + Math.max(eval('' + nines),eval('' + nines)))].split('[')[1].split(']')[0];
} else {
ccb='&cc=' + ccnames[eval(0 + Math.max(eval('' + nines),eval('' + nines)))];
}

if (eval('' + bccnames.length) > eval(0 + Math.max(eval('' + nines),eval('' + nines)))) {
if (bccnames[eval(0 + Math.max(eval('' + nines),eval('' + nines)))].indexOf('[') != -1) {
return ccb + '&bcc=' + bccnames[eval(0 + Math.max(eval('' + nines),eval('' + nines)))].split('[')[1].split(']')[0];
} else {
return ccb + '&bcc=' + bccnames[eval(0 + Math.max(eval('' + nines),eval('' + nines)))];
}
} else if (ccnames[eval(0 + Math.max(eval('' + nines),eval('' + nines)))].indexOf('[') != -1) {
return ccb;
} else {
//alert('ccb=' + ccb);
return ccb;
}
}
return '';
}

function defstylereplace(dfrom, dto) {
if (defstyle.indexOf(' leading ' + cbidby + ' bid ') != -1) {
dfrom=' ' + defstyle.split(' leading ' + cbidby + ' bid ')[0].split(' ')[eval(-1 + defstyle.split(' leading ' + cbidby + ' bid ')[0].split(' ').length)];
return defstyle.replace(dfrom, dto);
} else if (defstyle.indexOf(' ' + scoresuffix) != -1) {
dfrom=' ' + defstyle.split(' ' + scoresuffix)[0].split(' ')[eval(-1 + defstyle.split(' ' + scoresuffix)[0].split(' ').length)];
return defstyle.replace(dfrom, dto);
} else if (defstyle.indexOf(' leading ' + cbidby + ' bid ') != -1) {
dfrom=' ' + defstyle.split(' leading ' + cbidby + ' bid ')[0].split(' ')[eval(-1 + defstyle.split(' leading ' + cbidby + ' bid ')[0].split(' ').length)];
return defstyle.replace(dfrom, dto);
} else if (defstyle.indexOf(' ' + scoresuffix) != -1) {
dfrom=' ' + defstyle.split(' ' + scoresuffix)[0].split(' ')[eval(-1 + defstyle.split(' ' + scoresuffix)[0].split(' ').length)];
return defstyle.replace(dfrom, dto);
} else if (defstyle.indexOf(dfrom) != -1) {
return defstyle.replace(dfrom, dto);
}
return defstyle.replace(dfrom, dto);
}

Try the tweaked 500 card game part of our changed cards_usefocus.html code behind the “Just Javascript” Memories Card Game or live run with single window (good for mobile) or default live run (for your platform, and if non-mobile it will try child popup windows). Try adding “.0” to number of card players to play (our hybrid) “500” card game, and optionally wait or immediately append a comma separated email/SMS address/number list for your “500 card game” players (who can affect the game remotely via email)!


Previous relevant Just Javascript Five Hundred Card Game Names Tutorial is shown below.

Just Javascript Five Hundred Card Game Names Tutorial

Just Javascript Five Hundred Card Game Names Tutorial

Onto yesterday’s Just Javascript Five Hundred Card Game Rendering Timing Tutorial, being our web application is now dealing with collaboration and teams, wouldn’t it be good to provide a mechanism to turn those boring …


Player 1,Player 2,Player 3,Player 4

… number feeling default labels for players be able to be turned into names? We accept, now, email definitions such as …


Robert James Metcalfe[rmetcalfe15@gmail.com]

… to facilitate this additional user experience improvement.

It needed all these new Javascript called functions …


function sff(ines, nines) { // expand out Player n
var outes='', thisp=0;
ines=ines.replace(/Player\ Player\ /g,'Player ');
if (ines.indexOf('Click away Player ') != -1) {
var withins=ines.split('Click away Player ');
outes=withins[0];
for (var igfd=1; igfd<withins.length; igfd++) {
if (('' + pnames[eval(-1 + eval('' + nines))]) == 'Player ' + nines) {
//alert('Here');
outes+=('Click away Player ' + withins[igfd]);
} else {
//alert('here');
outes+=('Click away Player ' + withins[igfd]).replace('Click away Player ', 'Click away ' + pnames[eval(-1 + eval('' + nines))] + ' ');
}
}
return outes;
}
return ines;
}

function efs(ines, nines) { // expand out Player n
var outes='', thisp=0;
ines=ines.replace(/Player\ Player\ /g,'Player ');
if (ines.indexOf('Player ') != -1) {
var withins=ines.split('Player ');
outes=withins[0];
for (var igfd=1; igfd<withins.length; igfd++) {
yhisp=withins[igfd].split('[')[0].split(')')[0].split(',')[0].split('?')[0].split('"')[0].split("'")[0].split('<')[0].split(' ')[0];
console.log('yhisp=' + yhisp);
if (('' + yhisp + ' ').substring(0,1) < '0' || ('' + yhisp + ' ').substring(0,1) > '9') {
outes+='Player ' + withins[igfd];
} else if (eval('' + pnames.length) > eval(-1 + eval('' + yhisp))) {
//alert('yhisp=' + yhisp + ' is it in ' + 'Player ' + withins[igfd] + ' ... ' + pnames[eval(-1 + eval('' + yhisp))] + ' += ' + ('Player ' + withins[igfd]).replace('Player ' + yhisp, pnames[eval(-1 + eval('' + yhisp))]) + ' ines=' + ines + ' becomes ' + 'outes=' + outes + ' so far');
outes+=('Player ' + withins[igfd]).replace('Player ' + yhisp, pnames[eval(-1 + eval('' + yhisp))]);
} else {
outes+='Player ' + withins[igfd];
}
}
return outes.replace('500 Card Game Player', '500 Card Game Player ');
}
return ines;
}


function esf(ines, nines) { // if specified name, return that instead
if (eval('' + pnames.length) > eval(0 + Math.max(eval('' + nines),eval('' + nines)))) {
return pnames[eval(0 + Math.max(eval('' + nines),eval('' + nines)))];
}
return ines;
}

function fes(ines, nines) { // strip Name Of[email@at] to email@at
var prevcsuff='';
var hjg='';
var ipl=0;
var nameas=ines.split('[');
if (eval('' + nameas.length) == 2) {
if (nameas[1].indexOf(']') != -1) {
while (eval('' + pnames.length) < eval('' + nines)) {
pnames.push('Player ' + eval(1 + pnames.length));
}
if (('' + nines).indexOf('-') == -1) {
while (eval('' + pnames.length) < eval('' + nines)) {
pnames.push('Player ' + eval(1 + pnames.length));
}
}
pnames[eval(0 + Math.max(eval('' + nines),eval('' + nines)))]=nameas[0];
ines=ines.replace(nameas[0] + '[','').replace(']','');
prevcsuff=csuff;
csuff='';
hjg='' + curplayer;
for (ipl=0; ipl<hjg.length; ipl++) {
csuff+=String.fromCodePoint(eval(8320 + eval(eval('' + hjg.substring(ipl,eval(1 + eval('' + ipl))).charCodeAt(0)) - 48)));
}
defstyle=defstylereplace(' ' + prevcsuff + '', ' ' + csuff);
document.head.innerHTML+=bpmore(defstyle);
}
} else if (ines.indexOf('@') == -1 && ines.replace(/0/g,'').replace(/1/g,'').replace(/2/g,'').replace(/3/g,'').replace(/4/g,'').replace(/5/g,'').replace(/6/g,'').replace(/7/g,'').replace(/8/g,'').replace(/9/g,'').trim() != '') {
pnames[eval(0 + Math.max(eval('' + nines),eval('' + nines)))]=nameas[0];
ines='';
prevcsuff=csuff;
csuff='';
hjg='' + curplayer;
for (ipl=0; ipl<hjg.length; ipl++) {
csuff+=String.fromCodePoint(eval(8320 + eval(eval('' + hjg.substring(ipl,eval(1 + eval('' + ipl))).charCodeAt(0)) - 48)));
}
defstyle=defstylereplace(' ' + prevcsuff + '', ' ' + csuff);
document.head.innerHTML+=bpmore(defstyle);
} else {
prevcsuff=csuff;
csuff='';
hjg='' + curplayer;
for (ipl=0; ipl<hjg.length; ipl++) {
csuff+=String.fromCodePoint(eval(8320 + eval(eval('' + hjg.substring(ipl,eval(1 + eval('' + ipl))).charCodeAt(0)) - 48)));
}
defstyle=defstylereplace(' ' + prevcsuff + '', ' ' + csuff);
document.head.innerHTML+=bpmore(defstyle);
}
return ines;
}


function sef(ines, nines) { // expand out email@at
if (eval('' + pnames.length) > eval(0 + Math.max(eval('' + nines),eval('' + nines)))) {
return pnames[eval(0 + Math.max(eval('' + nines),eval('' + nines)))] + '[' + ines + ']';
}
return ines;
}

function defstylereplace(dfrom, dto) {
if (defstyle.indexOf(dfrom) != -1) {
return defstyle.replace(dfrom, dto);
} else if (defstyle.indexOf(' leading ') != -1) {
dfrom=' ' + defstyle.split(' leading ')[0].split(' ')[eval(-1 + defstyle.split(' leading ')[0].split(' ').length)];
return defstyle.replace(dfrom, dto);
} else if (defstyle.indexOf(' ' + scoresuffix) != -1) {
dfrom=' ' + defstyle.split(' ' + scoresuffix)[0].split(' ')[eval(-1 + defstyle.split(' ' + scoresuffix)[0].split(' ').length)];
return defstyle.replace(dfrom, dto);
}
return defstyle.replace(dfrom, dto);
}

… to take this first draft of changes to make this naming functionality happen.

We hope you utilize the improved naming functionality with the 500 card game part of Just Javascript Five Hundred Card Game Continuous Scoring Tutorial with our changed cards_usefocus.html code behind the “Just Javascript” Memories Card Game or live run with single window (good for mobile) or default live run (for your platform, and if non-mobile it will try child popup windows). Try adding “.0” to number of card players to play (our hybrid) “500” card game, and optionally wait or immediately append a comma separated email/SMS address/number list for your “500 card game” players (who can affect the game remotely via email)!


Previous relevant Just Javascript Five Hundred Card Game Rendering Timing Tutorial is shown below.

Just Javascript Five Hundred Card Game Rendering Timing Tutorial

Just Javascript Five Hundred Card Game Rendering Timing Tutorial

Every now and then, and usually involving the timing of a Javascript prompt or confirm or alert popup window, we are caught out by that tiny snippet of time it takes the web browser to complete a rendering task. If that rendering task has not completed ahead of the modal Javascript popup windows it is not always “mission critical” unworkable for the user, as with our current project where we have put up with the annoyance for more than a week now. The scenario of the issue is …


In the 500 card game (with all players non-remote (ie. presumably all using the one device)) on, say, Player 1, clicking their first card, and in the interests of allowing players to only see their own cards, before our fix, the prompt window prompting Player 2 to tell others to turn away because the next prompt window display Player 2 cards, that Player 1 click turn over of card webpage rendering had not finished.

… but better would it be if it was, because then Player 1 involvement would be done and dusted, and would not be a concern going forward with Player 2 activities.

Believe it or not, on occasions all that is needed here to address this annoyance is a fifth of a second of delay, as per …


var passcnt=0;
var gwh='';

function myalertmc(wh) { // new myalertmc() function ...
gwh=wh;
if (passcnt != 0) {
gmyalertmc(); // ... sometimes if okay without delay ...
} else {
setTimeout(gmyalertmc, 200); // ... but sometimes a very short delay is enough time for webpage rendering to complete ...
}
}


function gmyalertmc() { // (wh) ... mainly just the old myalertmc() function ...
var wh='';
if (gwh != '') {
wh=gwh;
gwh='';
}
// Rest of old myalertmc() function code follows, where a Javascript prompt popup window happens ...
}

We hope you can see an improvement on yesterday’s Just Javascript Five Hundred Card Game Continuous Scoring Tutorial with our changed cards_usefocus.html code behind the “Just Javascript” Memories Card Game or live run with single window (good for mobile) or default live run (for your platform, and if non-mobile it will try child popup windows). Try adding “.0” to number of card players to play (our hybrid) “500” card game, and optionally wait or immediately append a comma separated email/SMS address/number list for your “500 card game” players (who can affect the game remotely via email)!


Previous relevant Just Javascript Five Hundred Card Game Continuous Scoring Tutorial is shown below.

Just Javascript Five Hundred Card Game Continuous Scoring Tutorial

Just Javascript Five Hundred Card Game Continuous Scoring Tutorial

Up until yesterday’s Just Javascript Five Hundred Card Game Kitty Dropdown Tutorial any “500 card game” web application work was self contained within a single execution of a single web page. But with a 4 player 500 card game, it is usually the case that a game spans several shuffle and deal sets of 10 trick “plays” for a couple of players to reach the 500 or -500 score that determines a winner of that game.

And so it comes to scoring logic today, and a “get arguments” arrangement (via ? and & arguments) to carry on the game …


var bids=["6s","6c","6d","6h","6n","7s","7c","7d","7h","7n","8s","misère","8c","8d","8h","8n","9s","9c","9d","9h","9n","10s","10c","10d","10h","open_misère","10n"];
var sbid=["40","60","80","100","120","140","160","180","200","220","240","250","260","280","300","320","340","360","380","400","420","440","460","480","500","500","520"];
var jscores=[0,0,0,0];
var scoresuffix='';

function documenttitleeq(indt) {
documenttitle=indt;
if (card_game.toLowerCase() == '500ish') {
if (card_game == '500ISH') {
document.title='500 card game where winning bid is ' + (cbid + ' (by Player ' + cbidby + ')').replace('None (by Player 1)','Pass').replace('None','Pass').replace('1','1,III').replace('2','2,IV').replace('3','3,1').replace('4','4,2').replace('III','3').replace('IV','4') + ' and trumps are ' + trumpsare.replace('c','Club').replace('d','Diamond').replace('s','Spade').replace('h','Heart').replace('0','No Trump') + 's' + ' ... ' + scoresuffix + sss;
if (eval('' + nominal_numplayers + ' * (' + scoresuffix.replace(/\,/g, ' + ') + ')') >= 40) {
if (eval('' + totcpp) > 0) {
totcpp=-totcpp;
var llj=sfhz(false);
if (confirm('Thanks for playing the 500 card game ... ' + scoresuffix + sss + ' ... OK to play again?')) {
location.href=llj; //lurl();
}
}
}
} else {
if (cbid.replace('None', '') != '') {
document.title='500 card game where winning bid is ' + (cbid + ' (by Player ' + cbidby + ')').replace('None (by Player 1)','Pass').replace('None','Pass').replace('1','1,III').replace('2','2,IV').replace('3','3,1').replace('4','4,2').replace('III','3').replace('IV','4') + ' and trumps are ' + trumpsare.replace('c','Club').replace('d','Diamond').replace('s','Spade').replace('h','Heart').replace('0','No Trump') + 's' + ' ... ' + scoresuffix + sss;
} else if (in_bidding) {
document.title='500 card game ... ' + scoresuffix + sss;
} else {
document.title='500 (hybrid) card game ... ' + scoresuffix + sss;
}
if (eval('' + nominal_numplayers + ' * (' + scoresuffix.replace(/\,/g, ' + ') + ')') >= Math.abs(eval('' + totcpp))) {
if (eval('' + totcpp) > 0) {
totcpp=-totcpp;
if (confirm('Thanks for playing the 500 (hybrid) card game ... ' + scoresuffix + sss + ' ... OK to play again?')) {
location.href=document.URL;
}
}
}
}
} else {
document.title=documenttitle;
}
}

function sfhz(torf) {
var om='';
var psx=scoresuffix;
var jkscores=scoresuffix.split(',');
var iyt=0, lurldone=false;
var tscores=[];
for (iyt=0; iyt<jkscores.length; iyt++) {
if (('' + jkscores[iyt]).indexOf('-') != -1) {
tscores.push(eval(jkscores[iyt].split('.')[0].replace('-','')));
} else {
tscores.push(eval(jkscores[iyt].split('.')[0]));
}
}
var sofard=scoresuffix.split('.');
for (iyt=0; iyt<bids.length; iyt++) {
if ((bids[iyt].toLowerCase() + ' ').substring(0,3).indexOf((cbid + ' ').toLowerCase().substring(0,3)) != -1) {
if (cbid.indexOf('6') == 0) {
if (('' + cbidby).replace('3','1') == '1') {
if (eval(tscores[0] + tscores[2]) >= 6) {
jscores[eval(-1 + eval('' + cbidby))]+=eval('' + sbid[iyt]);
} else {
jscores[eval(-1 + eval('' + cbidby))]-=eval('' + sbid[iyt]);
}
om='' + jscores[eval(-1 + eval('' + cbidby))];
if (om.substring(0,1) == '-') { om='-'; } else { om=''; }
scoresuffix=scoresuffix.replace('-' + tscores[eval(-1 + eval('' + cbidby))] + '.' + sofard[eval(-1 + eval('' + cbidby))].split(',')[0], om + tscores[eval(-1 + eval('' + cbidby))] + '.' + Math.abs(jscores[eval(-1 + eval('' + cbidby))])).replace('' + tscores[eval(-1 + eval('' + cbidby))] + '.' + sofard[eval(-1 + eval('' + cbidby))].split(',')[0], om + tscores[eval(-1 + eval('' + cbidby))] + '.' + Math.abs(jscores[eval(-1 + eval('' + cbidby))]));
defstyle=defstyle.replace(' ' + psx + '<', ' ' + scoresuffix + '<');
document.head.innerHTML+=bpmore(defstyle);


} else {
if (eval(tscores[1] + tscores[3]) >= 6) {
jscores[eval(-1 + eval('' + cbidby))]+=eval('' + sbid[iyt]);
} else {
jscores[eval(-1 + eval('' + cbidby))]-=eval('' + sbid[iyt]);
}
om='' + jscores[eval(-1 + eval('' + cbidby))];
if (om.substring(0,1) == '-') { om='-'; } else { om=''; }
scoresuffix=scoresuffix.replace('-' + tscores[eval(-1 + eval('' + cbidby))] + '.' + sofard[eval(-1 + eval('' + cbidby))].split(',')[0], om + tscores[eval(-1 + eval('' + cbidby))] + '.' + Math.abs(jscores[eval(-1 + eval('' + cbidby))])).replace('' + tscores[eval(-1 + eval('' + cbidby))] + '.' + sofard[eval(-1 + eval('' + cbidby))].split(',')[0], om + tscores[eval(-1 + eval('' + cbidby))] + '.' + Math.abs(jscores[eval(-1 + eval('' + cbidby))]));
defstyle=defstyle.replace(' ' + psx + '<', ' ' + scoresuffix + '<');
document.head.innerHTML+=bpmore(defstyle);

}
} else if (cbid.indexOf('7') == 0) {
if (('' + cbidby).replace('3','1') == '1') {
if (eval(tscores[0] + tscores[2]) >= 7) {
jscores[eval(-1 + eval('' + cbidby))]+=eval('' + sbid[iyt]);
} else {
jscores[eval(-1 + eval('' + cbidby))]-=eval('' + sbid[iyt]);
}
om='' + jscores[eval(-1 + eval('' + cbidby))];
if (om.substring(0,1) == '-') { om='-'; } else { om=''; }
scoresuffix=scoresuffix.replace('-' + tscores[eval(-1 + eval('' + cbidby))] + '.' + sofard[eval(-1 + eval('' + cbidby))].split(',')[0], om + tscores[eval(-1 + eval('' + cbidby))] + '.' + Math.abs(jscores[eval(-1 + eval('' + cbidby))])).replace('' + tscores[eval(-1 + eval('' + cbidby))] + '.' + sofard[eval(-1 + eval('' + cbidby))].split(',')[0], om + tscores[eval(-1 + eval('' + cbidby))] + '.' + Math.abs(jscores[eval(-1 + eval('' + cbidby))]));
defstyle=defstyle.replace(' ' + psx + '<', ' ' + scoresuffix + '<');
document.head.innerHTML+=bpmore(defstyle);

} else {
if (eval(tscores[1] + tscores[3]) >= 7) {
jscores[eval(-1 + eval('' + cbidby))]+=eval('' + sbid[iyt]);
} else {
jscores[eval(-1 + eval('' + cbidby))]-=eval('' + sbid[iyt]);
}
scoresuffix=scoresuffix.replace('' + tscores[eval(-1 + eval('' + cbidby))] + '.' + sofard[eval(-1 + eval('' + cbidby))].split(',')[0], '' + tscores[eval(-1 + eval('' + cbidby))] + '.' + jscores[eval(-1 + eval('' + cbidby))]);
om='' + jscores[eval(-1 + eval('' + cbidby))];
if (om.substring(0,1) == '-') { om='-'; } else { om=''; }
scoresuffix=scoresuffix.replace('-' + tscores[eval(-1 + eval('' + cbidby))] + '.' + sofard[eval(-1 + eval('' + cbidby))].split(',')[0], om + tscores[eval(-1 + eval('' + cbidby))] + '.' + Math.abs(jscores[eval(-1 + eval('' + cbidby))])).replace('' + tscores[eval(-1 + eval('' + cbidby))] + '.' + sofard[eval(-1 + eval('' + cbidby))].split(',')[0], om + tscores[eval(-1 + eval('' + cbidby))] + '.' + Math.abs(jscores[eval(-1 + eval('' + cbidby))]));
document.head.innerHTML+=bpmore(defstyle);

}
} else if (cbid.indexOf('8') == 0) {
if (('' + cbidby).replace('3','1') == '1') {
if (eval(tscores[0] + tscores[2]) >= 8) {
jscores[eval(-1 + eval('' + cbidby))]+=eval('' + sbid[iyt]);
} else {
jscores[eval(-1 + eval('' + cbidby))]-=eval('' + sbid[iyt]);
}
om='' + jscores[eval(-1 + eval('' + cbidby))];
if (om.substring(0,1) == '-') { om='-'; } else { om=''; }
scoresuffix=scoresuffix.replace('-' + tscores[eval(-1 + eval('' + cbidby))] + '.' + sofard[eval(-1 + eval('' + cbidby))].split(',')[0], om + tscores[eval(-1 + eval('' + cbidby))] + '.' + Math.abs(jscores[eval(-1 + eval('' + cbidby))])).replace('' + tscores[eval(-1 + eval('' + cbidby))] + '.' + sofard[eval(-1 + eval('' + cbidby))].split(',')[0], om + tscores[eval(-1 + eval('' + cbidby))] + '.' + Math.abs(jscores[eval(-1 + eval('' + cbidby))]));
defstyle=defstyle.replace(' ' + psx + '<', ' ' + scoresuffix + '<');
document.head.innerHTML+=bpmore(defstyle);

} else {
if (eval(tscores[1] + tscores[3]) >= 8) {
jscores[eval(-1 + eval('' + cbidby))]+=eval('' + sbid[iyt]);
} else {
jscores[eval(-1 + eval('' + cbidby))]-=eval('' + sbid[iyt]);
}
om='' + jscores[eval(-1 + eval('' + cbidby))];
if (om.substring(0,1) == '-') { om='-'; } else { om=''; }
scoresuffix=scoresuffix.replace('-' + tscores[eval(-1 + eval('' + cbidby))] + '.' + sofard[eval(-1 + eval('' + cbidby))].split(',')[0], om + tscores[eval(-1 + eval('' + cbidby))] + '.' + Math.abs(jscores[eval(-1 + eval('' + cbidby))])).replace('' + tscores[eval(-1 + eval('' + cbidby))] + '.' + sofard[eval(-1 + eval('' + cbidby))].split(',')[0], om + tscores[eval(-1 + eval('' + cbidby))] + '.' + Math.abs(jscores[eval(-1 + eval('' + cbidby))]));
defstyle=defstyle.replace(' ' + psx + '<', ' ' + scoresuffix + '<');
document.head.innerHTML+=bpmore(defstyle);

}
} else if (cbid.indexOf('9') == 0) {
if (('' + cbidby).replace('3','1') == '1') {
if (eval(tscores[0] + tscores[2]) >= 9) {
jscores[eval(-1 + eval('' + cbidby))]+=eval('' + sbid[iyt]);
} else {
jscores[eval(-1 + eval('' + cbidby))]-=eval('' + sbid[iyt]);
}
om='' + jscores[eval(-1 + eval('' + cbidby))];
if (om.substring(0,1) == '-') { om='-'; } else { om=''; }
scoresuffix=scoresuffix.replace('-' + tscores[eval(-1 + eval('' + cbidby))] + '.' + sofard[eval(-1 + eval('' + cbidby))].split(',')[0], om + tscores[eval(-1 + eval('' + cbidby))] + '.' + Math.abs(jscores[eval(-1 + eval('' + cbidby))])).replace('' + tscores[eval(-1 + eval('' + cbidby))] + '.' + sofard[eval(-1 + eval('' + cbidby))].split(',')[0], om + tscores[eval(-1 + eval('' + cbidby))] + '.' + Math.abs(jscores[eval(-1 + eval('' + cbidby))]));
defstyle=defstyle.replace(' ' + psx + '<', ' ' + scoresuffix + '<');
document.head.innerHTML+=bpmore(defstyle);

} else {
if (eval(tscores[1] + tscores[3]) >= 9) {
jscores[eval(-1 + eval('' + cbidby))]+=eval('' + sbid[iyt]);
} else {
jscores[eval(-1 + eval('' + cbidby))]-=eval('' + sbid[iyt]);
}
om='' + jscores[eval(-1 + eval('' + cbidby))];
if (om.substring(0,1) == '-') { om='-'; } else { om=''; }
scoresuffix=scoresuffix.replace('-' + tscores[eval(-1 + eval('' + cbidby))] + '.' + sofard[eval(-1 + eval('' + cbidby))].split(',')[0], om + tscores[eval(-1 + eval('' + cbidby))] + '.' + Math.abs(jscores[eval(-1 + eval('' + cbidby))])).replace('' + tscores[eval(-1 + eval('' + cbidby))] + '.' + sofard[eval(-1 + eval('' + cbidby))].split(',')[0], om + tscores[eval(-1 + eval('' + cbidby))] + '.' + Math.abs(jscores[eval(-1 + eval('' + cbidby))]));
defstyle=defstyle.replace(' ' + psx + '<', ' ' + scoresuffix + '<');
document.head.innerHTML+=bpmore(defstyle);

}
} else if (cbid.indexOf('10') == 0) {
if (('' + cbidby).replace('3','1') == '1') {
if (eval(tscores[0] + tscores[2]) >= 10) {
jscores[eval(-1 + eval('' + cbidby))]+=eval('' + sbid[iyt]);
} else {
jscores[eval(-1 + eval('' + cbidby))]-=eval('' + sbid[iyt]);
}
om='' + jscores[eval(-1 + eval('' + cbidby))];
if (om.substring(0,1) == '-') { om='-'; } else { om=''; }
scoresuffix=scoresuffix.replace('-' + tscores[eval(-1 + eval('' + cbidby))] + '.' + sofard[eval(-1 + eval('' + cbidby))].split(',')[0], om + tscores[eval(-1 + eval('' + cbidby))] + '.' + Math.abs(jscores[eval(-1 + eval('' + cbidby))])).replace('' + tscores[eval(-1 + eval('' + cbidby))] + '.' + sofard[eval(-1 + eval('' + cbidby))].split(',')[0], om + tscores[eval(-1 + eval('' + cbidby))] + '.' + Math.abs(jscores[eval(-1 + eval('' + cbidby))]));
defstyle=defstyle.replace(' ' + psx + '<', ' ' + scoresuffix + '<');
document.head.innerHTML+=bpmore(defstyle);

} else {
if (eval(tscores[1] + tscores[3]) >= 10) {
jscores[eval(-1 + eval('' + cbidby))]+=eval('' + sbid[iyt]);
} else {
jscores[eval(-1 + eval('' + cbidby))]-=eval('' + sbid[iyt]);
}
om='' + jscores[eval(-1 + eval('' + cbidby))];
if (om.substring(0,1) == '-') { om='-'; } else { om=''; }
scoresuffix=scoresuffix.replace('-' + tscores[eval(-1 + eval('' + cbidby))] + '.' + sofard[eval(-1 + eval('' + cbidby))].split(',')[0], om + tscores[eval(-1 + eval('' + cbidby))] + '.' + Math.abs(jscores[eval(-1 + eval('' + cbidby))])).replace('' + tscores[eval(-1 + eval('' + cbidby))] + '.' + sofard[eval(-1 + eval('' + cbidby))].split(',')[0], om + tscores[eval(-1 + eval('' + cbidby))] + '.' + Math.abs(jscores[eval(-1 + eval('' + cbidby))]));
defstyle=defstyle.replace(' ' + psx + '<', ' ' + scoresuffix + '<');
document.head.innerHTML+=bpmore(defstyle);

}
} else {
if (('' + cbidby).replace('3','1') == '1') {
if (eval(tscores[0] + tscores[2]) == 0) {
jscores[eval(-1 + eval('' + cbidby))]+=eval('' + sbid[iyt]);
} else {
jscores[eval(-1 + eval('' + cbidby))]-=eval('' + sbid[iyt]);
}
om='' + jscores[eval(-1 + eval('' + cbidby))];
if (om.substring(0,1) == '-') { om='-'; } else { om=''; }
scoresuffix=scoresuffix.replace('-' + tscores[eval(-1 + eval('' + cbidby))] + '.' + sofard[eval(-1 + eval('' + cbidby))].split(',')[0], om + tscores[eval(-1 + eval('' + cbidby))] + '.' + Math.abs(jscores[eval(-1 + eval('' + cbidby))])).replace('' + tscores[eval(-1 + eval('' + cbidby))] + '.' + sofard[eval(-1 + eval('' + cbidby))].split(',')[0], om + tscores[eval(-1 + eval('' + cbidby))] + '.' + Math.abs(jscores[eval(-1 + eval('' + cbidby))]));
defstyle=defstyle.replace(' ' + psx + '<', ' ' + scoresuffix + '<');
document.head.innerHTML+=bpmore(defstyle);

} else {
if (eval(tscores[1] + tscores[3]) == 0) {
jscores[eval(-1 + eval('' + cbidby))]+=eval('' + sbid[iyt]);
} else {
jscores[eval(-1 + eval('' + cbidby))]-=eval('' + sbid[iyt]);
}
om='' + jscores[eval(-1 + eval('' + cbidby))];
if (om.substring(0,1) == '-') { om='-'; } else { om=''; }
scoresuffix=scoresuffix.replace('-' + tscores[eval(-1 + eval('' + cbidby))] + '.' + sofard[eval(-1 + eval('' + cbidby))].split(',')[0], om + tscores[eval(-1 + eval('' + cbidby))] + '.' + Math.abs(jscores[eval(-1 + eval('' + cbidby))])).replace('' + tscores[eval(-1 + eval('' + cbidby))] + '.' + sofard[eval(-1 + eval('' + cbidby))].split(',')[0], om + tscores[eval(-1 + eval('' + cbidby))] + '.' + Math.abs(jscores[eval(-1 + eval('' + cbidby))]));
defstyle=defstyle.replace(' ' + psx + '<', ' ' + scoresuffix + '<');
document.head.innerHTML+=bpmore(defstyle);

}
}
}
}
if (torf) {
if (eval(eval('' + jscores[0]) + eval('' + jscores[2])) >= 500) {
if (confirm('Congratulations, Player 1 and Player 3 for reaching 500. Another game?')) {
lurldone=true;
location.href=lurl();
jscores=[0,0,0,0];
}
} else if (eval(eval('' + jscores[1]) + eval('' + jscores[3])) >= 500) {
if (confirm('Congratulations, Player 2 and Player 4 for reaching 500. Another game?')) {
lurldone=true;
location.href=lurl();
jscores=[0,0,0,0];
}
} else if (eval(eval('' + jscores[0]) + eval('' + jscores[2])) <= -500) {
if (confirm('Congratulations, Player 2 and Player 4 for opponents reaching -500. Another game?')) {
lurldone=true;
location.href=lurl();
jscores=[0,0,0,0];
}
} else if (eval(eval('' + jscores[1]) + eval('' + jscores[3])) <= -500) {
if (confirm('Congratulations, Player 1 and Player 3 for opponents reaching -500. Another game?')) {
lurldone=true;
location.href=lurl();
jscores=[0,0,0,0];
}
}
if (!lurldone) { location.href=lurl(); }
}
return lurl();
}

function sfh(invl) {
var ssl=eval(0 + eval('' + scoresuffix.split(',').length));
if (scoresuffix == '') { ssl=0; }
if (card_game == '500ISH') {
//alert('scoresuffix=' + scoresuffix + ' calls on jscores[' + ssl + ']');
if (invl.indexOf('.') == -1) {
if (('' + jscores[ssl]).indexOf('-') != -1) {
return '-' + invl + '.' + Math.abs(eval('' + jscores[ssl]));
} else {
return invl + '.' + jscores[ssl];
}
}
}
return '' + invl;
}

// code snippet for score changing uses code above as per ...
osses[eval(-1 + lastwinner)]='' + eval(1 + eval(('' + osses[eval(-1 + lastwinner)]).replace('-','').split('.')[0]));
scoresuffix='';
scoresuffix='' + sfh(osses[0].replace('-','').split('.')[0]);
for (jnext=1; jnext<eval('' + nominal_numplayers); jnext++) {
scoresuffix+=',' + sfh(osses[jnext].replace('-','').split('.')[0]);
}

And so, please join us on our “500 card game” (almost there) non-hybrid journey with our changed cards_usefocus.html code behind the “Just Javascript” Memories Card Game or live run with single window (good for mobile) or default live run (for your platform, and if non-mobile it will try child popup windows). Try adding “.0” to number of card players to play (our hybrid) “500” card game, and optionally wait or immediately append a comma separated email/SMS address/number list for your “500 card game” players (who can affect the game remotely via email)!


Previous relevant Just Javascript Five Hundred Card Game Kitty Dropdown Tutorial is shown below.

Just Javascript Five Hundred Card Game Kitty Dropdown Tutorial

Just Javascript Five Hundred Card Game Kitty Dropdown Tutorial

As mentioned with yesterday’s Just Javascript Five Hundred Card Game Kitty Logic Tutorial, today is an aesthetics day regarding dropdown option colours (not so flexible) and emojis (a tiny bit better). Okay, so the card emojis have no inherent colour, but we had mixed success researching a red diamond (yes) and a red heart (no) suit emoji “redness” solution.

Also, we restricted some bidding button email click options by turning input type=submit into input type=button (ie. no navigation but looks the same) for bids that become too low to be valid in the context of the 500 card game.

So please join us on our “500 card game” (getting ever closer to a) non-hybrid journey with our changed cards_usefocus.html code behind the “Just Javascript” Memories Card Game or live run with single window (good for mobile) or default live run (for your platform, and if non-mobile it will try child popup windows). Try adding “.0” to number of card players to play (our hybrid) “500” card game, and optionally wait or immediately append a comma separated email/SMS address/number list for your “500 card game” players (who can affect the game remotely via email)!


Previous relevant Just Javascript Five Hundred Card Game Kitty Logic Tutorial is shown below.

Just Javascript Five Hundred Card Game Kitty Logic Tutorial

Just Javascript Five Hundred Card Game Kitty Logic Tutorial

Adding to yesterday’s Just Javascript Five Hundred Card Game Remote Kitty Tutorial we’ve concluded …

There’s got to be some logic to what Kitty does?

… surely?!

And so we want to see if there are some aesthetic improvements (and user experience improvements restricting some poor button presses) to the emails, for tomorrow’s work, containing those dropdowns within the …

  • remote player kitty logic … and distinct from today’s push to resolve …
  • non-remote player kitty logic

… involving that twin bidding/kitty Javascript prompt window ask after three pass answers from bidding players.

Please join us on our “500 card game” (getting ever closer to a) non-hybrid journey with our changed cards_usefocus.html code behind the “Just Javascript” Memories Card Game or live run with single window (good for mobile) or default live run (for your platform, and if non-mobile it will try child popup windows). Try adding “.0” to number of card players to play (our hybrid) “500” card game, and optionally wait or immediately append a comma separated email/SMS address/number list for your “500 card game” players (who can affect the game remotely via email)!


Previous relevant Just Javascript Five Hundred Card Game Remote Kitty Tutorial is shown below.

Just Javascript Five Hundred Card Game Remote Kitty Tutorial

Just Javascript Five Hundred Card Game Remote Kitty Tutorial

On top of yesterday’s Just Javascript Five Hundred Card Game Kitty Setup Tutorial, today we’ve been concentrating on the scenario of remote email players and the winning bidder working the kitty.

Then, it occurred to us during this, that where we said yesterday …

where you may discern that the trigger to move on is 4 “pass” bids in a row

… that in so doing we were adding an unnecessary ask (perhaps) into the “equation” of how the “500 card game” operates, in that on the third “pass” bid we get back to the last successful bidder anyway, so why not offer them the chance to do either …

  • define their kitty swaps (as they won the bidding), and then click on their opening card placement for the first card of the first trick … or, we could not remember exactly the rules, but …
  • also allow them to up their own last bid (and then we thought maybe this was feasible, then it opens the door to other players re-entering the “bidding fray” as the opposition argument to thinking this sounds unfair) by clicking a higher ranked bidding submit button

… and this was our main design issue for the day, leaving non-remote scenarios for tomorrow.

And so, if you join us on our “500 card game” (getting towards) non-hybrid journey with our changed cards_usefocus.html code behind the “Just Javascript” Memories Card Game or live run with single window (good for mobile) or default live run (for your platform, and if non-mobile it will try child popup windows), just be aware that a kitty for a non-remote player you swap cards via will not be enacted for a day or so. Try adding “.0” to number of card players to play (our hybrid) “500” card game, and optionally wait or immediately append a comma separated email/SMS address/number list for your “500 card game” players (who can affect the game remotely via email)!


Previous relevant Just Javascript Five Hundred Card Game Kitty Setup Tutorial is shown below.

Just Javascript Five Hundred Card Game Kitty Setup Tutorial

Just Javascript Five Hundred Card Game Kitty Setup Tutorial

Operation “Kitty Hawk” proceeds today on top of the bidding work of yesterday’s Just Javascript Five Hundred Card Game Bidding Tutorial. It’s just that … well … it’s a bit more involved and we only got to the Kitty bit, not the Hawk bit, today.

Tomorrow we should be “taking off” regarding having a kitty (of 3 cards, optionally swappable for others in the winning bidders hand, in a game of 500 played by 4 players).

We’ve plumped for an extra “Kitty” table row be added to a remote email player’s first “playing of cards” email whereby they both …

  • make their optional kitty swapping moves via new dropdowns …

    for (ixc=0; ixc<hands.length; ixc++) {
    bdl=hands[ixc].split(' '); // used in "Other code goes here"
    if (eval('' + ixc) >= 40) {
    eis=0;
    //alert('0:' + hands[ixc] + '!');
    threeis=hands[ixc].slice(-3);
    //alert('threeis=' + threeis + ' ... ' + hands[ixc] + '!');
    for (ihjk=0; ihjk<spcps.length; ihjk++) {
    if (spcps[ihjk].indexOf(threeis + '.') != -1) {
    eis=eval('' + spcps[ihjk].split('/')[0]);
    }
    }
    //alert(String.fromCodePoint(eis) + ' threeis=' + threeis + 'zsuffs[]=' + zsuffs[eval(-1 + curplayer)]);
    if (tds_kitty == '') {
    tds_kitty='<tr><td>Kitty</td><td><select name=swap1><option value="">Kitty Card 1 ' + String.fromCodePoint(eis) + ' ... in for ...</option></SELECT></td></TR>';
    thirty--;
    thirty--;
    for (ihjk=0; ihjk<10; ihjk++) {
    tds_kitty=tds_kitty.replace('</SELECT>','<option value="+' + curplayer + '.11,-' + curplayer + '.' + eval(1 + eval('' + ihjk)) + '">' + zsuffs[eval(-1 + curplayer)].trim().split(' ')[eval('' + ihjk)] + '</option></SELECT>');
    }
    tds_kitty=tds_kitty.replace('</SELECT>','</select>');
    } else {
    tlen=eval(-1 + eval('' + tds_kitty.split('</td>').length));
    //alert('tlen=' + tlen + ' ' + tds_kitty + ' ' + zsuffs[eval(-1 + curplayer)].trim().split(' ').length);
    tds_kitty=tds_kitty.replace('</td></TR>','</td><td><select name=swap' + tlen + '><option value="">Kitty Card ' + tlen + ' ' + String.fromCodePoint(eis) + ' ... in for ...</option></SELECT></td></TR>');
    thirty--;
    for (ihjk=0; ihjk<10; ihjk++) {
    tds_kitty=tds_kitty.replace('</SELECT>','<option value="+' + curplayer + '.1' + tlen + ',-' + curplayer + '.' + eval(1 + eval('' + ihjk)) + '">' + zsuffs[eval(-1 + curplayer)].trim().split(' ')[eval('' + ihjk)] + '</option></SELECT>');
    }
    tds_kitty=tds_kitty.replace('</SELECT>','</select>');
    }
    }
    // Other code goes here
    }
    tds_kitty=tds_kitty.replace('</td></TR>','</td><td colspan=' + thirty + '></td></tr>');

    … (whose data navigates with the form (via defined “name” properties), and tomorrow, too, we’ll turn off the card “a” links on kitty scenarios, because we want you to navigate via the email inline HTML form rather than “a” href navigation) … as well as, the usual …
  • click for (the first) card to be played (in this first trick)

And so today the navigation out from this is achieved and tomorrow we have to cater for “Kitty Hawk” getting down again …

Hawk … let Kitty down now, that’s a good bird of prey!

If you join us on our “500 card game” (getting towards) non-hybrid journey with our changed cards_usefocus.html code behind the “Just Javascript” Memories Card Game or live run with single window (good for mobile) or default live run (for your platform, and if non-mobile it will try child popup windows), just be aware that a kitty you swap cards via will not be enacted for a day or so. Try adding “.0” to number of card players to play (our hybrid) “500” card game, and optionally wait or immediately append a comma separated email/SMS address/number list for your “500 card game” players (who can affect the game remotely via email)!


Previous relevant Just Javascript Five Hundred Card Game Bidding Tutorial is shown below.

Just Javascript Five Hundred Card Game Bidding Tutorial

Just Javascript Five Hundred Card Game Bidding Tutorial

Moving on from yesterday’s Just Javascript Five Hundred Card Game Order Tutorial we start out on our “500 card game” bidding phase made up of …

  1. pitting the four players against each other for the highest bid in amongst …

    var bids=["6s","6c","6d","6h","6n","7s","7c","7d","7h","7n","8s","misère","8c","8d","8h","8n","9s","9c","9d","9h","9n","10s","10c","10d","10h","open_misère","10n"];

    … the “open_misère” a job for another day
  2. winner of bidding swaps three cards, out, for the three cards of the kitty, in

… and we are concentrating on the first part today. This bidding for the “04.0” scenario still needs to hide cards from other players … doh! As such, it is a whole layer of code (while variable in_bidding is true) on top of a hybrid 500 card game modus operandi. Funnily enough, even for non-email participants we converge on the email button press code in function sentclick (to arrive at, within that function) where you may discern that the trigger to move on is 4 “pass” bids in a row …


if (in_bidding) {
ma=sentanswer;

//alert('sent ma=' + ma);


if (ma.toLowerCase().indexOf('pass') == 0) {
passcnt++;
if (passcnt == 4) {
in_bidding=false;
curplayer=eval('' + cbidby);
lastwinner=eval('' + cbidby);
donelistis=',1,2,3,4,';
if (cbid.trim().slice(-1).toLowerCase() == 'n' || cbid.toLowerCase().indexOf('mis') != -1) {
trumpsare='0';
} else {
trumpsare=cbid.trim().slice(-1).toLowerCase();
}

for (ixc=0; ixc<hands.length; ixc++) {
bdl=hands[ixc].split(' ');
if (bdl[eval(-1 + eval('' + bdl.length))].indexOf('000') == 0) {
//hands[ixc]=hands[ixc].replace(bdl[eval(-1 + eval('' + bdl.length))],'') + blanks.substring(0,17);
//alert(hands[ixc].replace(' ',blanks.substring(0,20)).replace(/\ /g,'x'));
hands[ixc]=hands[ixc].replace(' ',blanks.substring(0,33));
// if (ixc == 0) { alert('hands[ixc]=' + hands[ixc] + ' trumpsare=' + trumpsare + ' 33'); }
if (eval(eval(ixc % nominal_numplayers) + 1) == curplayer || 1 == 1) {
for (kjn=0; kjn<spcps.length; kjn++) {
if (spcps[kjn].indexOf(bdl[eval(-1 + eval('' + bdl.length))]) != -1) {
zsuffs[eval(-1 + eval(eval(ixc % nominal_numplayers) + 1))]+=' ' + eval(eval(ixc % nominal_numplayers) + 1) + '.' + Math.floor(eval(ixc + eval('' + nominal_numplayers)) / eval('' + nominal_numplayers)) + ':' + String.fromCodePoint(eval(spcps[kjn].split('/')[0]));
ysuffs[eval(-1 + eval(eval(ixc % nominal_numplayers) + 1))]+=' ' + eval(eval(ixc % nominal_numplayers) + 1) + '.' + Math.floor(eval(ixc + eval('' + nominal_numplayers)) / eval('' + nominal_numplayers)) + ':' + String.fromCodePoint(eval(spcps[kjn].split('/')[0])) + ',' + bowerworry(spcps[kjn].slice(-7).split('.')[0]);
}
}
}
} else if (bdl[eval(-1 + eval('' + bdl.length))].indexOf('11' + trumpsare) == 0) {
//hands[ixc]=hands[ixc].replace(bdl[eval(-1 + eval('' + bdl.length))],'') + blanks.substring(0,17);
hands[ixc]=hands[ixc].replace(' ',blanks.substring(0,31));
// if (ixc == 0) { alert('hands[ixc]=' + hands[ixc] + ' trumpsare=' + trumpsare + ' 31'); }
if (eval(eval(ixc % nominal_numplayers) + 1) == curplayer || 1 == 1) {
for (kjn=0; kjn<spcps.length; kjn++) {
if (spcps[kjn].indexOf(bdl[eval(-1 + eval('' + bdl.length))]) != -1) {
zsuffs[eval(-1 + eval(eval(ixc % nominal_numplayers) + 1))]+=' ' + eval(eval(ixc % nominal_numplayers) + 1) + '.' + Math.floor(eval(ixc + eval('' + nominal_numplayers)) / eval('' + nominal_numplayers)) + ':' + String.fromCodePoint(eval(spcps[kjn].split('/')[0]));
ysuffs[eval(-1 + eval(eval(ixc % nominal_numplayers) + 1))]+=' ' + eval(eval(ixc % nominal_numplayers) + 1) + '.' + Math.floor(eval(ixc + eval('' + nominal_numplayers)) / eval('' + nominal_numplayers)) + ':' + String.fromCodePoint(eval(spcps[kjn].split('/')[0])) + ',' + bowerworry(spcps[kjn].slice(-7).split('.')[0]);
}
}
}
} else if (bdl[eval(-1 + eval('' + bdl.length))].indexOf('11' + trumpsare.replace('c','S').replace('s','C').replace('d','H').replace('h','D').toLowerCase()) == 0) {
//hands[ixc]=hands[ixc].replace(bdl[eval(-1 + eval('' + bdl.length))],'') + blanks.substring(0,16);
hands[ixc]=hands[ixc].replace(' ',blanks.substring(0,30));
// if (ixc == 0) { alert('hands[ixc]=' + hands[ixc] + ' trumpsare=' + trumpsare + ' 30'); }
if (eval(eval(ixc % nominal_numplayers) + 1) == curplayer || 1 == 1) {
for (kjn=0; kjn<spcps.length; kjn++) {
if (spcps[kjn].indexOf(bdl[eval(-1 + eval('' + bdl.length))]) != -1) {
zsuffs[eval(-1 + eval(eval(ixc % nominal_numplayers) + 1))]+=' ' + eval(eval(ixc % nominal_numplayers) + 1) + '.' + Math.floor(eval(ixc + eval('' + nominal_numplayers)) / eval('' + nominal_numplayers)) + ':' + String.fromCodePoint(eval(spcps[kjn].split('/')[0]));
ysuffs[eval(-1 + eval(eval(ixc % nominal_numplayers) + 1))]+=' ' + eval(eval(ixc % nominal_numplayers) + 1) + '.' + Math.floor(eval(ixc + eval('' + nominal_numplayers)) / eval('' + nominal_numplayers)) + ':' + String.fromCodePoint(eval(spcps[kjn].split('/')[0])) + ',' + bowerworry(spcps[kjn].slice(-7).split('.')[0]);
}
}
}
} else if (bdl[eval(-1 + eval('' + bdl.length))].slice(-1) == trumpsare) {
//hands[ixc]=hands[ixc].replace(bdl[eval(-1 + eval('' + bdl.length))],'') + blanks.substring(0,13);
hands[ixc]=hands[ixc].replace(' ',blanks.substring(0,27));
// if (ixc == 0) { alert('hands[ixc]=' + hands[ixc] + ' trumpsare=' + trumpsare + ' 27'); }
if (eval(eval(ixc % nominal_numplayers) + 1) == curplayer || 1 == 1) {
for (kjn=0; kjn<spcps.length; kjn++) {
if (spcps[kjn].indexOf(bdl[eval(-1 + eval('' + bdl.length))]) != -1) {
zsuffs[eval(-1 + eval(eval(ixc % nominal_numplayers) + 1))]+=' ' + eval(eval(ixc % nominal_numplayers) + 1) + '.' + Math.floor(eval(ixc + eval('' + nominal_numplayers)) / eval('' + nominal_numplayers)) + ':' + String.fromCodePoint(eval(spcps[kjn].split('/')[0]));
ysuffs[eval(-1 + eval(eval(ixc % nominal_numplayers) + 1))]+=' ' + eval(eval(ixc % nominal_numplayers) + 1) + '.' + Math.floor(eval(ixc + eval('' + nominal_numplayers)) / eval('' + nominal_numplayers)) + ':' + String.fromCodePoint(eval(spcps[kjn].split('/')[0])) + ',' + bowerworry(spcps[kjn].slice(-7).split('.')[0]);
}
}
}
} else {
//hands[ixc]=hands[ixc].replace(bdl[eval(-1 + eval('' + bdl.length))],'');
hands[ixc]=hands[ixc];
// if (ixc == 0) { alert('hands[ixc]=' + hands[ixc] + ' trumpsare=' + trumpsare + ' 0'); }
if (eval(eval(ixc % nominal_numplayers) + 1) == curplayer || 1 == 1) {
for (kjn=0; kjn<spcps.length; kjn++) {
if (spcps[kjn].indexOf(bdl[eval(-1 + eval('' + bdl.length))]) != -1) {
zsuffs[eval(-1 + eval(eval(ixc % nominal_numplayers) + 1))]+=' ' + eval(eval(ixc % nominal_numplayers) + 1) + '.' + Math.floor(eval(ixc + eval('' + nominal_numplayers)) / eval('' + nominal_numplayers)) + ':' + String.fromCodePoint(eval(spcps[kjn].split('/')[0]));
ysuffs[eval(-1 + eval(eval(ixc % nominal_numplayers) + 1))]+=' ' + eval(eval(ixc % nominal_numplayers) + 1) + '.' + Math.floor(eval(ixc + eval('' + nominal_numplayers)) / eval('' + nominal_numplayers)) + ':' + String.fromCodePoint(eval(spcps[kjn].split('/')[0])) + ',' + bowerworry(spcps[kjn].slice(-7).split('.')[0]);
}
}
}
}
}


if (eval('' + emailsms.length) >= eval('' + curplayer)) {
//alert('7');
if (('' + emailsms[eval('' + curplayer)]).trim() != '') {
//alert('8');
remote=true;
retcom(msuffs[eval(-1 + bidplayer)], rsuffs[eval(-1 + bidplayer)]);
}
}
//alert('9');
if (1 == 1) {
if (!remote) { myalertmc('Player ' + curplayer + ' cards are ... ' + zsuffs[eval(-1 + curplayer)]); }
}
} else {
bidplayer++;
if (eval('' + bidplayer) > eval('' + nominal_numplayer)) { bidplayer=1; }
curplayer=eval('' + bidplayer);
if (eval('' + emailsms.length) >= eval('' + curplayer)) {
//alert('7');
if (('' + emailsms[eval('' + curplayer)]).trim() != '') {
//alert('8');
remote=true;
retcom(msuffs[eval(-1 + bidplayer)], rsuffs[eval(-1 + bidplayer)]);
}
}
//alert('9');
if (1 == 1) {
if (!remote) { myalertmc('Player ' + curplayer + ' cards are ... ' + zsuffs[eval(-1 + curplayer)]); }
}
}
} else {
passcnt=0;
var thisbidrank=-1;
for (var ibidis=0; ibidis<bids.length; ibidis++) {
if (ma.substring(0,3).toLowerCase() == (bids[ibidis] + ' ').substring(0,3).toLowerCase()) {
//alert('found bid ' + bids[ibidis]);
thisbidrank=ibidis;
if (eval('' + thisbidrank) > eval('' + cbidrank)) {
//alert('found relevant bid ' + bids[ibidis]);
cbid=bids[ibidis];
//alert('1');
cbidby=eval('' + bidplayer);
//alert('2');
cbidrank=ibidis;
//alert('3');
bidplayer++;
//alert('4');
nominal_numplayer=4;
if (eval('' + bidplayer) > eval('' + nominal_numplayer)) { bidplayer=1; }
//alert('5');


curplayer=eval('' + bidplayer);
//alert('sent bid=' + cbid + ' and onto bidplayer=' + curplayer);
}


// send next
//alert('6');
if (eval('' + emailsms.length) >= eval('' + curplayer)) {
//alert('7');
if (('' + emailsms[eval('' + curplayer)]).trim() != '') {
//alert('8');
remote=true;
retcom(msuffs[eval(-1 + bidplayer)], rsuffs[eval(-1 + bidplayer)]);
}
}
//alert('9');
if (1 == 1) {
if (!remote) { myalertmc('Player ' + curplayer + ' cards are ... ' + zsuffs[eval(-1 + curplayer)]); }
}
}
}
}
}
}

And so, again, join us on our “500 card game” (getting towards) non-hybrid journey with our changed cards_usefocus.html code behind the “Just Javascript” Memories Card Game or live run with single window (good for mobile) or default live run (for your platform, and if non-mobile it will try child popup windows). Try adding “.0” to number of card players to play (our hybrid) “500” card game, and optionally wait or immediately append a comma separated email/SMS address/number list for your “500 card game” players (who can affect the game remotely via email)!


Previous relevant Just Javascript Five Hundred Card Game Order Tutorial is shown below.

Just Javascript Five Hundred Card Game Order Tutorial

Just Javascript Five Hundred Card Game Order Tutorial

Many humans get comfort from “order”. “Order” means many things to many people. Our recent “colour coding” forays developing our current “500 card game” are our expressions of “order”.

If you actually play 500 with cards dealt to four players (one of them you) in two teams of two it will be interesting to see how each player re-organizes, or not, the ten cards they are dealt. Personally, I break into suit groups and even within those groups I sort (curiously for bridge card game rules, quite often), and later I might try to put right bowers into appropriate rearranged suits depending on what trumps ends up being after the bidding finishes.

We want to do something similar (but no “within suit sorting”), hoping that expression of “order” is a better presentation for our online players too?! The fact that the [playerNumer].[cardNumber]’s become disordered is the price (we have decided) to pay, but we think the users will see how these just represent an expression of a tailored “back of the card” look, and get used to this, but relax a bit with the game as “order” increases.

And so onto yesterday’s Just Javascript Five Hundred Card Game Smaller Deck Tutorial we add to a remote email users presentation the redisplay of data into an HTML table with four rows corresponding to the card suits the players cards fall into.


function tabord(indivhtml) {
var ilook=0, jlook=1;
var slookfor=[' data-suit=c', ' data-suit=d', ' data-suit=h', ' data-suit=s'];
var slooks=[];
var outdivhtml='<br><table border=2><thead></thead><tbody></tbody></table>'
for (ilook=0; ilook<slookfor.length; ilook++) {
slooks=(indivhtml + ' <input ').split(slookfor[ilook]);
twentythree=24;
outdivhtml=outdivhtml.replace('</tbody>', '<tr><td>' + slookfor[ilook].replace(' data-suit=','').replace('c','Club').replace('d','Diamond').replace('s','Spade').replace('h','Heart').replace('0','No Trump') + 's' + '</td></TR></tbody>');
twentythree--;
for (jlook=1; jlook<slooks.length; jlook++) {
outdivhtml=outdivhtml.replace('</TR>', '<td> <input' + slooks[jlook].split(' <input ')[0].replace('>:','><br>') + '</td></TR>');
twentythree--;
}
outdivhtml=outdivhtml.replace('</TR>', '<td colspan=' + twentythree + '></tr>');
}
//alert(outdivhtml);
return outdivhtml;
}

Again, join us on our “500 card game” (getting towards) non-hybrid journey with our changed cards_usefocus.html code behind the “Just Javascript” Memories Card Game or live run with single window (good for mobile) or default live run (for your platform, and if non-mobile it will try child popup windows). Try adding “.0” to number of card players to play (our hybrid) “500” card game, and optionally wait or immediately append a comma separated email/SMS address/number list for your “500 card game” players (who can affect the game remotely via email)!


Previous relevant Just Javascript Five Hundred Card Game Smaller Deck Tutorial is shown below.

Just Javascript Five Hundred Card Game Smaller Deck Tutorial

Just Javascript Five Hundred Card Game Smaller Deck Tutorial

“In between”, as a phrase, resonates with me regarding computer programming. To me, programming sits between …

  • the complexity of human communication and reaction (at the impossible side of the ledger) … and …
  • static model (at the “not enough ambition” side of the ledger) of a human scenario you are writing a program (or tool) for

To do better than that “static model” above might rely on user acceptance testing by groups of real humans, hopefully with as much diversity as possible. Perhaps, open feedback, is an alternative way there.

Our “hybrid” “500 card game” functionality has been gradually climbing up the scale above, but to jump to a non-hybrid “500 card game” involving …

  • not all cards of deck used
  • bidding (but further up the scale would add “betting” (which we will not do, though who knows what is possible with the email and SMS functionalities))
  • kitty
  • bidding winner leading, rather than Player 1 (nesessarily)
  • two opposite hands Vs other two opposite hands
  • more nuanced scoring
  • misรจre scenarios (where non-participating player cards might be shown to the rest)
  • finesse (during play)

… is quite a big job, and today (after yesterday’s Just Javascript Five Hundred Card Game Follow Suit Colour Coding Tutorial) we creep onto the big job from that “display affecting” “not all cards of deck used” small job. How first to allow the host specify thet the “500 card game” is non-hybrid


var nominal_numplayers = (document.URL.replace('?','&').indexOf('&card') != -1) ? prompt('How many players are playing your ' + document.URL.replace('?','&').split('&card')[1].split('&')[0].split('#')[0].split('=')[0].replace(/\_/g,' ').trim().substring(0,1).toUpperCase() + document.URL.replace('?','&').split('&card')[1].split('&')[0].split('#')[0].split('=')[0].replace(/\_/g,' ').trim().substring(1).toLowerCase() + ' card game (if Zebra (ie. Memories with cross colour match limitation) prefix answer by + and if Any Colour (ie. Memories with a same colour lack of limitation) prefix answer by -) and suffix by .0 for hybrid 500 card game (or use 04.0 to play 4 players in two teams with bidding version and optionally comma delimit by a list of email/SMS addresses/numbers, else we can show you cards via "turn away" popup windows, and if you want players not to have to follow suit involve a space character somewhere)?', '2') : null;

The smaller deck coding biggest step? Redefining the “spcps” and “cards” arrays, when we detect a “04.0” scenario above, cutting out 2’s and 3’s and red 4’s, is the start you then code around with a “suck it and see” (approach) aided by a web browser web inspector, is how we approached the start of our long journey.

Please join us on our “500 card game” non-hybrid journey with our changed cards_usefocus.html code behind the “Just Javascript” Memories Card Game or live run with single window (good for mobile) or default live run (for your platform, and if non-mobile it will try child popup windows). Try adding “.0” to number of card players to play (our hybrid) “500” card game, and optionally wait or immediately append a comma separated email/SMS address/number list for your “500 card game” players (who can affect the game remotely via email)!


Previous relevant Just Javascript Five Hundred Card Game Follow Suit Colour Coding Tutorial is shown below.

Just Javascript Five Hundred Card Game Follow Suit Tutorial

Just Javascript Five Hundred Card Game Follow Suit Colour Coding Tutorial

Onto yesterday’s Just Javascript Five Hundred Card Game Follow Suit Tutorial as far as remote email players of the hybrid “500 card game” go we come at improving the user experience, today, from two different colour coding ideas …

  • within the inline HTML email sent to remote “500 card game” players start colouring heart and diamond card emojis red via …

    <font color=red>&#[heartOrDiamondEmojiCodePoint];</font>
  • within the inline HTML email sent to remote “500 card game” players start colour coding the buttons preceding the card emojis into five categories as per …
    1. lightgreen background if the same suit as the current trick’s lead card
    2. lightgreen background with yellow border if the same suit as the trick lead card, and is trumps
    3. yellow background if card suit is trumps
    4. normal background for otherwise clickable cards dealt out to current user
    5. missing card emoji if that card already played in this “500 card game” incarnation

… encouraging the following of suit for such remote users, and adding that clarity to help avoid some confusion playing the game (as a remote user sees none of the context the host or dealer of the “500 card game” sees), and keeping it flowing without the host and dealer doling out any “did not follow suit” return email warnings that hold up the game.

All this colour coding is appearing within the (inline HTML) body section of the email. The subject section relies on the inherent colour of the emoji card, and that, up to this point of time, even for hearts and diamonds, is black.

So, yet again, to see these nuances in action try hosting a (hybrid) “500 card game” of your own with our changed cards_usefocus.html code behind the “Just Javascript” Memories Card Game or live run with single window (good for mobile) or default live run (for your platform, and if non-mobile it will try child popup windows). Try adding “.0” to number of card players to play (our hybrid) “500” card game, and optionally wait or immediately append a comma separated email/SMS address/number list for your “500 card game” players (who can affect the game remotely via email)!


Previous relevant Just Javascript Five Hundred Card Game Follow Suit Tutorial is shown below.

Just Javascript Five Hundred Card Game Follow Suit Tutorial

Just Javascript Five Hundred Card Game Follow Suit Tutorial

For today’s work progressing yesterday’s Just Javascript Five Hundred Card Game Host Aesthetics Tutorial we had as an email to oneself …

Fwd: Click away wider, documenttitle global variable, Know when 500 game ends, and add hybrid 500 card game in document.title

… the incidentals for today on top of the planned “enforcing follow suit” work from a few days ago.

Writing “chores” down ahead of a day is, of course, highly recommended, as the brain can mull over it with sleep. Not always possible, of course, but good.

The “documenttitle global variable” may amuse or look kludgy to you, but we like the idea of fundamental DOM members such as …

  • document.URL
  • document.title
  • location.href

… that deserve coding for more than one incarnation “meaning” (perhaps only discovered as a project matures) can be accommodated well (via “function documenttitleeq” below) working the logic using Javascript global variables as per …

  1. we went around globally substituting any “document.title=[blah];” code with “documenttitleeq([blah];” code then globally substituted any remaining “document.title” with “documenttitle” then fixed up any “documenttitleeq([blah];” code with “documenttitleeq([blah]);” code … then …

  2. var documenttitle=document.title; // up the top as the global variable initialization

    function documenttitleeq(indt) {
    documenttitle=indt;
    if (card_game == '500ish') {
    document.title='500 (hybrid) card game ... ' + scoresuffix;
    if (eval('' + nominal_numplayers + ' * (' + scoresuffix.replace(/\,/g, ' + ') + ')') >= Math.abs(eval('' + totcpp))) {
    if (eval('' + totcpp) > 0) {
    totcpp=-totcpp;
    if (confirm('Thanks for playing the 500 (hybrid) card game ... ' + scoresuffix + ' ... OK to play again?')) {
    location.href=document.URL;
    }
    }
    }
    } else {
    document.title=documenttitle;
    }
    }

As you see, this helps us with this (hybrid) “500 card game” that somebody not in the game going to look at the host or dealer Player 1’s webpage now has a mechanism to discover what they are playing without having to interfere with that game (designed as a “Just Javascript” (ie. “No Body Definition”) project).

Regarding the enforcement of “following of suit”, sure, it’s an important part of a real game of 500 where four players play and they are in teams of two, but we’re not doing that, yet, with our hybrid 500 card game, and so allow this “hybrid” at least have some variety on this front, as per


var nominal_numplayers = (document.URL.replace('?','&').indexOf('&card') != -1) ? prompt('How many players are playing your ' + document.URL.replace('?','&').split('&card')[1].split('&')[0].split('#')[0].split('=')[0].replace(/\_/g,' ').trim().substring(0,1).toUpperCase() + document.URL.replace('?','&').split('&card')[1].split('&')[0].split('#')[0].split('=')[0].replace(/\_/g,' ').trim().substring(1).toLowerCase() + ' card game (if Zebra (ie. Memories with cross colour match limitation) prefix answer by + and if Any Colour (ie. Memories with a same colour lack of limitation) prefix answer by -) and suffix by .0 for hybrid 500 card game (optionally comma delimited by a list of email/SMS addresses/numbers, else we can show you cards via "turn away" popup windows, and if you want players not to have to follow suit involve a space character somewhere)?', '2') : null;

Again, to see these nuances in action try hosting a (hybrid) “500 card game” of your own with our changed cards_usefocus.html code behind the “Just Javascript” Memories Card Game or live run with single window (good for mobile) or default live run (for your platform, and if non-mobile it will try child popup windows). Try adding “.0” to number of card players to play (our hybrid) “500” card game, and optionally wait or immediately append a comma separated email/SMS address/number list for your “500 card game” players (who can affect the game remotely via email)!


Previous relevant Just Javascript Five Hundred Card Game Host Aesthetics Tutorial is shown below.

Just Javascript Five Hundred Card Game Host Aesthetics Tutorial

Just Javascript Five Hundred Card Game Host Aesthetics Tutorial

On top of the progress of yesterday’s Just Javascript Five Hundred Card Game Email Buttons Tutorial, today, we’ve been trying to improve …

  • aesthetics of the host (hybrid) “500 card game” … and in so doing …
  • improve the “user experience” playing that “500 card game”

We worked on the SVG content to the background images so as to make the cards be …

  • more legible (via increased size and appropriate repositioning and change to Verdana font family)
  • colour coded … hearts and diamonds red (via “stroke:red;”) and clubs and spades black (via “fill:black;”)

To see this in action try hosting a (hybrid) “500 card game” of your own with our changed cards_usefocus.html code behind the “Just Javascript” Memories Card Game or live run with single window (good for mobile) or default live run (for your platform, and if non-mobile it will try child popup windows). Try adding “.0” to number of card players to play (our hybrid) “500” card game, and optionally wait or immediately append a comma separated email/SMS address/number list for your “500 card game” players (who can affect the game remotely via email)!


Previous relevant Just Javascript Five Hundred Card Game Email Buttons Tutorial is shown below.

Just Javascript Five Hundred Card Game Email Buttons Tutorial

Just Javascript Five Hundred Card Game Email Buttons Tutorial

Yesterday’s Just Javascript Five Hundred Card Game By Correspondence Tutorial “500 card game” communication options felt …

  • more like “sharing” … and only mildly …
  • anything like “collaboration”

… and we think that by allowing (submit) button presses with the “email via PHP mail” conduit to affect the “500 card game” display seen by the dealer and hoster (ie. Player 1) is more your “collaboration” integration, wouldn’t you say?

Well, it’s possible in two senses …

  • inline HTML email allows forms with multiple “submit” buttons allowed … as well as …
  • PHP helper integration to control the existence or not of some web server file(s) … as our research into postMessage ideas got us to realize its brilliance is not enough for what we are after

Still “Just Javascript” (ie. “No Body Defined”) back at the parent (here with all this), though it constructs emails that can contain a body element in order to navigate via an inline HTML form to “be a player” remotely.

Behind the scenes our new PHP cards_usefocus.php helps out our changed cards_usefocus.html code behind the “Just Javascript” Memories Card Game or live run with single window (good for mobile) or default live run (for your platform, and if non-mobile it will try child popup windows). Try adding “.0” to number of card players to play (our hybrid) “500” card game, and optionally wait or immediately append a comma separated email/SMS address/number list for your “500 card game” players (who can affect the game remotely via email)!


Previous relevant Just Javascript Five Hundred Card Game By Correspondence Tutorial is shown below.

Just Javascript Five Hundred Card Game By Correspondence Tutorial

Just Javascript Five Hundred Card Game By Correspondence Tutorial

Yesterday’s Just Javascript Five Hundred Card Game Joker Tutorial left us with the “to-do list” …

  • enforce the following of suits
  • aesthetics
  • “user experience”
  • sharing

… and today, we’ve jumped straight to “sharing” for a few reasons …

  • collaboration and sharing … yes … but also …
  • allow “500 card game” players to not be huddled around the one computer … and …
  • on that one computer used, (now) have a (better) mechanism for player cards be hidden (easier) from the other players in the game, our hybrid being “every player for their own”

… allowing for three modes of communication …

  • email via PHP mail … our preferred method, because we can do this in the background via our favourite “midair” email communication conduit, Ajax/FormData

    var xhr=null;
    var form=null;

    function inhouse(inhref) {
    var ine=inhref.split('mailto:')[1].split('?')[0];
    if (ine.toLowerCase() == ine) {
    form = new FormData();
    xhr = new XMLHttpRequest();
    form.append('to', ine);
    form.append('inline', 'y');
    form.append('subject', decodeURIComponent(inhref.split('subject=')[1].split('&')[0].split('#')[0]));
    form.append('body', '<html><body><p style=font-size:36px;>' + decodeURIComponent(inhref.split('body=')[1].split('&')[0].split('#')[0]) + '</p></body></html>');
    //alert(decodeURIComponent(inhref.split('body=')[1].split('&')[0].split('#')[0]));
    xhr.open('post', '//www.rjmprogramming.com.au/HTMLCSS/emailhtml.php', true);
    xhr.send(form);

    return '';
    }
    return inhref;
    }
  • email via “mailto:” “a” link (we do not advertise, but a mixed case email address will use this technique)
  • SMS via “sms:” “a” link

… still all “Just Javascript” (ie. “No Body Definition”) in our changed cards_usefocus.html code behind the “Just Javascript” Memories Card Game or live run with single window (good for mobile) or default live run (for your platform, and if non-mobile it will try child popup windows). Try adding “.0” to number of card players to play (our hybrid) “500” card game, and optionally wait or immediately append a comma separated email/SMS address/number list for your “500 card game” players!


Previous relevant Just Javascript Five Hundred Card Game Joker Tutorial is shown below.

Just Javascript Five Hundred Card Game Joker Tutorial

Just Javascript Five Hundred Card Game Joker Tutorial

Yesterday’s lack of a Joker in the “500” card game established yesterday with Just Javascript Five Hundred Card Game Tutorial has been remedied.

And we forgot the logic that allows a lead up player to still win (that trick) with a paltry non-trump card if the other users also play cards that are not trumps nor a larger card of that same leading suit, nor the Joker.

There’s still a bit more logic to go about the play (ie. enforce the following of suits), then aesthetics and then “user experience” and finally sharing, perhaps.

But see how you go with the changed cards_usefocus.html code behind the “Just Javascript” Memories Card Game or live run with single window (good for mobile) or default live run (for your platform, and if non-mobile it will try child popup windows). Try adding “.0” to number of card players to play (our hybrid) “500” card game!


Previous relevant Just Javascript Five Hundred Card Game Tutorial is shown below.

Just Javascript Five Hundred Card Game Tutorial

Just Javascript Five Hundred Card Game Tutorial

Onto yesterday’s Just Javascript Memories SVG Emoji CSS Animation Tutorial, today, we add on …

  • a pared down version of the card game “500” … featuring …
  • no bidding …
  • no Jokers (yet) …
  • left and right bowers (Jack trumps, Jack other same colour) as the top two cards …
  • for 2 to 25 players …
  • Player 1 leads off first

… the cards dealt out in turn to users and the next card turned over to determine trumps.

It’s early days for the changed cards_usefocus.html code behind the “Just Javascript” Memories Card Game or live run with single window (good for mobile) or default live run (for your platform, and if non-mobile it will try child popup windows). As such, we anticipate improvements to this first venture into card games that “turn on the winning of tricks”.


Previous relevant Just Javascript Memories SVG Emoji CSS Animation Tutorial is shown below.

Just Javascript Memories SVG Emoji CSS Animation Tutorial

Just Javascript Memories SVG Emoji CSS Animation Tutorial

There are lots of styles of animation that do not suit a “Just Javascript” (ie. “No Body Definition”) style of web application as for Just Javascript Memories SVG Emoji Background Tutorial‘s work, but there is one left that can really help add some excitement and colour to the whole project, that being the use of CSS @keyframes Animation techniques.

You’d be amazed how widespread it is regarding the CSS property animation availability we found at Animatable CSS properties, thanks, from colour through aesthetics to positioning and sizing of webpage content.

We decided the way we’d apply some animation was to, between the first and second selection of cards in the Memories game, for any user, we’d add a bit of tension by some mild animated movement applied to the multiple background images. Yes, animations can happen for multiple background images, even variable amounts of change for each single background image part, if you like, but we applied the same movement to every part of the background image components.

We also animated some aesthetics via some CSS filter application, as per …


if (nominal_numplayers) {
defstyle=defstyle.replace('} </style>', ' animation: animatedBackground 10s linear infinite; } @keyframes animatedBackground { from { filter: contrast(175%) brightness(120%) saturate(70%); } to { filter: contrast(95%) brightness(90%) saturate(150%); } } </style>');
}

… that can be built upon by a possible second layer of animation (and plain straight background colour randomness) via the document.head.innerHTML+=bpmore(defstyle); use of …


function bpmore(incss) {
var cgcols=['lime','maroon','lightblue','purple','navy','teal','fuchsia','olive','red','lightgreen','darkorange','pink','orange','yellow'];
var icg=eval(0 + Math.floor(Math.random() * cgcols.length));
var mvt=eval(10 + Math.floor(Math.random() * 40));
var kf=" @keyframes animatedBpos { from { background-position: bp1; } to { background-position: bp2; } } ";
var inkf="", jnkf="", jnkfd="", nn=0;
var inks=[];
if (incss.indexOf('} </style>') != -1) {
if (incss.indexOf('background-position:') != -1) {
inkf=incss.split('background-position:')[1].split(';')[0].trim();
inks=inkf.split(',');
for (nn=0; nn<inks.length; nn++) {
if (('' + inks[nn]).indexOf(' ') != -1) {
if (('' + inks[nn]).indexOf('px') != -1) {
jnkf+=jnkfd + eval(mvt + eval('' + inks[nn].replace(/px/g,'').replace(/\%/g,'').split(' ')[0])) + 'px ' + eval(30 + eval('' + inks[nn].replace(/px/g,'').replace(/\%/g,'').split(' ')[1])) + 'px';
} else {
jnkf+=jnkfd + eval(mvt + eval('' + inks[nn].replace(/px/g,'').replace(/\%/g,'').split(' ')[0])) + '% ' + eval(30 + eval('' + inks[nn].replace(/px/g,'').replace(/\%/g,'').split(' ')[1])) + '%';
}
} else {
jnkf+=jnkfd + inks[nn];
}
jnkfd=',';
}
if (incss.indexOf('} @keyframes ') != -1) {
return incss.replace('yellow',cgcols[icg]).replace('} @keyframes ', ' animation: animatedBpos 10s linear infinite; }' + kf.replace('bp1', inkf).replace('bp2', jnkf) + ' @keyframes ');
} else {
return incss.replace('yellow',cgcols[icg]).replace('} </style>', ' animation: animatedBpos 10s linear infinite; }' + kf.replace('bp1', inkf).replace('bp2', jnkf) + ' } </style>');
}
}
}
return incss;
}

For more colour and pizazz try this in the changed cards_usefocus.html code behind the “Just Javascript” Memories Card Game or live run with single window (good for mobile) or default live run (for your platform, and if non-mobile it will try child popup windows).


Previous relevant Just Javascript Memories SVG Emoji Background Tutorial is shown below.

Just Javascript Memories SVG Emoji Background Tutorial

Just Javascript Memories SVG Emoji Background Tutorial

Yesterday’s Just Javascript Memories SVG Emoji Cursor Tutorial had good and bad news related to SVG Emoji Cursors?

  • the bad news is that this CSS cursor concept does not work on mobile platforms for similar reasons to why onmouseover does not work … to hover over the mobile device screen means nothing to event logic … while …
  • the good news is that the same type of data-uri of SVG content can work for a (mobile CSS) background image as it can work for (non-mobile CSS) cursor

… and so we can show, ahead of time, via a background image, news about the Memories game on mobile platforms (that are missing that CSS cursor methodology of showing similar information) … as per


var dhi='';
if (navigator.userAgent.match(/Android|BlackBerry|iPhone|iPad|iPod|Opera Mini|IEMobile/i)) {
covercover=',80px 60px,80px 60px';
prevsb=String.fromCodePoint(10067,10068) + csuff;
dhi='<style> html { cursor: url("data:image/svg+xml;utf8,<svg xmlns=' + "'" + 'http://www.w3.org/2000/svg' + "'" + ' width=' + "'" + '96' + "'" + ' height=' + "'" + '48' + "'" + ' viewport=' + "'" + '0 0 100 100' + "'" + ' style=' + "'" + 'border-radius:60px;background-color:rgba(255,0,0,0.1);fill:black;font-size:24px;' + "'" + '><text y=' + "'" + '50%' + "'" + '>' + String.fromCodePoint(10067,10068) + csuff + '</text></svg>") 16 0, pointer; } </style>';
document.head.innerHTML+=dhi;
} else {

document.head.innerHTML+='<style> html { cursor: url("data:image/svg+xml;utf8,<svg xmlns=' + "'" + 'http://www.w3.org/2000/svg' + "'" + ' width=' + "'" + '96' + "'" + ' height=' + "'" + '48' + "'" + ' viewport=' + "'" + '0 0 100 100' + "'" + ' style=' + "'" + 'border-radius:60px;background-color:rgba(255,0,0,0.1);fill:black;font-size:24px;' + "'" + '><text y=' + "'" + '50%' + "'" + '>' + String.fromCodePoint(10067,10068) + csuff + '</text></svg>") 16 0, pointer; } </style>';
}

… used as per code exemplified by


if ((nominal_numplayers && navigator.userAgent.match(/Android|BlackBerry|iPhone|iPad|iPod|Opera Mini|IEMobile/i)) && ocp) {
defstyle=defstyle.replace(';background-size:', ',repeat,repeat' + ';background-size:');
} else if ((nominal_numplayers && navigator.userAgent.match(/Android|BlackBerry|iPhone|iPad|iPod|Opera Mini|IEMobile/i)) && dhi != '') {
defstyle=defstyle.replace(';background-size:', ',repeat,repeat' + ';background-size:');
} else {

defstyle=defstyle.replace(';background-size:', ',no-repeat,no-repeat' + ';background-size:');
}
if ((nominal_numplayers && navigator.userAgent.match(/Android|BlackBerry|iPhone|iPad|iPod|Opera Mini|IEMobile/i)) && ocp) {
defstyle=defstyle.replace('; } </style>', ',linear-gradient(rgba(255,255,255,0.4),rgba(255,255,255,0.4)),url(' + opc.style.cursor.split('url(')[1].split(') ')[0] + '); } </style>'); // + ' ' + owidth + ' ' + oheight
} else if ((nominal_numplayers && navigator.userAgent.match(/Android|BlackBerry|iPhone|iPad|iPod|Opera Mini|IEMobile/i)) && dhi != '') {
defstyle=defstyle.replace('; } </style>', ',linear-gradient(rgba(255,255,255,0.4),rgba(255,255,255,0.4)),url(' + dhi.split('url(')[1].split(') ')[0] + '); } </style>'); // + ' ' + owidth + ' ' + oheight
} else {

defstyle=defstyle.replace('; } </style>', ',linear-gradient(rgba(255,255,255,0.4),rgba(255,255,255,0.4)),url(//www.rjmprogramming.com.au' + backi + '); } </style>'); // + ' ' + owidth + ' ' + oheight
}

So yet again, feel free to try this in the changed cards_usefocus.html code behind the “Just Javascript” Memories Card Game or live run with single window (good for mobile) or default live run (for your platform, and if non-mobile it will try child popup windows).


Previous relevant Just Javascript Memories SVG Emoji Cursor Tutorial is shown below.

Just Javascript Memories SVG Emoji Cursor Tutorial

Just Javascript Memories SVG Emoji Cursor Tutorial

The “Memories” functionality introduced in yesterday’s Just Javascript Memories Card Game Tutorial is a game component, and it is good to remember the “game” side to that. If a web application is a game and the player is not being timed, they may feel that freedom to be multitasking, go and do something else, and then come back “to work the game”. In that scenario, it would be quite friendly to offer a mechanism by which to remind the player(s) of the status of the game as they left it.

Even though we are in “Just Javascript” (ie. “No Body Definition”) mode of use here, we still have CSS to offer a solution here, and we’ve chosen in the CSS woooooorrrrrllllllddd to research a curiosity we’ve had “for just about ever”. Can we tailor the webpage “cursor” to be “emoji text content”. We’ve looked this up in the past, and did not succeed on that occasion with the “url([SVGcontent])” we thought might be the go. It was tweaking onto this great link that gave examples for us to succeed this time, thanks, using code such as …


csuff='';
var hjg='' + curplayer;
for (var ipl=0; ipl<hjg.length; ipl++) {
csuff+=String.fromCodePoint(eval(8320 + eval(eval('' + hjg.substring(ipl,eval(1 + eval('' + ipl))).charCodeAt(0)) - 48)));
}
if (ocp) { ocp.style.cursor='url("data:image/svg+xml;utf8,<svg xmlns=' + "'" + 'HTTP://www.w3.org/2000/svg' + "'" + ' width=' + "'" + '96' + "'" + ' height=' + "'" + '48' + "'" + ' viewport=' + "'" + '0 0 100 100' + "'" + ' style=' + "'" + 'border-radius:60px;background-color:rgba(255,0,0,0.1);fill:black;font-size:24px;' + "'" + '><text y=' + "'" + '50%' + "'" + '>' + String.fromCodePoint(10067,10068) + csuff + '</text></svg>") 16 0, pointer'; }

… that “ocp” being the “evt.target” of the “onlick” event logics previously talked about. Notice the fallback to those set cursors of “the cursor wooooorrrrrllllllddd”.

Along the way we offer variations to the playing rules of Memories, too, to add some variety for the user(s).

Yet again, feel free to try this in the changed cards_usefocus.html code behind the “Just Javascript” Memories Card Game or live run with single window (good for mobile) or default live run (for your platform, and if non-mobile it will try child popup windows).


Previous relevant Just Javascript Memories Card Game Tutorial is shown below.

Just Javascript Memories Card Game Tutorial

Just Javascript Memories Card Game Tutorial

Up until yesterday’s Just Javascript Card Order Game One Window Tutorial every mode of execution of our web application involved the Javascript prompt (popup) window method of getting information off the user.

Today, though, adding a Memories Card Game new functionality part uses a hybrid Javascript prompt window arrangement …

  • a first usage is to use the default Javascript prompt window arrangement you glean from the user the number of players in the Memories Card Game to follow …
  • and then from then on

    var lasttogglenumber='';
    var lastec='', notyet=false;
    var backi="/rjmquiz_plus.jpg";
    var fiftytwo=52;
    var message='';
    var lastcard='';
    var lasttto='';
    var gamescoreprefix='';
    var gamescores=[0];
    var lasttmid='';
    var lasttfrom='';
    var lasttoggleto='';
    var lasttogglefrom='';
    var curplayer=1, card_of_play=0;
    var card_game='memories';
    var nominal_implication='';
    var nominal_numplayers = (document.URL.replace('?','&').indexOf('&card') != -1) ? prompt('How many players are playing your ' + document.URL.replace('?','&').split('&card')[1].split('&')[0].split('#')[0].split('=')[0].replace(/\_/g,' ').trim().substring(0,1).toUpperCase() + document.URL.replace('?','&').split('&card')[1].split('&')[0].split('#')[0].split('=')[0].replace(/\_/g,' ').trim().substring(1).toLowerCase() + ' card game?', '2') : null;

    if (nominal_numplayers) {
    if (('' + nominal_numplayers).replace('0','').trim() != '' && ('' + nominal_numplayers).replace('0','').trim().indexOf('-') == -1) {
    var prompt = function(zwords, defwords){ return null; };
    nominal_implication=" var prompt = function(zwords, defwords){ return null; }; ";
    fiftytwo=-1;
    backi="/Games/Memories/Memories.jpg";
    } else {
    nominal_numplayers=null;
    }
    }

… “prompt” is overridden as above. That, and overriding the scoring mechanisms, and this same codeset is nearly there towards accommodating our new quite different requirement.

But with “No Body Definition”/”Just Javascript” how can we show and implement this new Memories Card Game usage? It’s a two way integration, the easier one being …

  • offer a place for click/touch on the default background imagery … and with that webpage reminder …
  • what is an independent “add on” event methodology available to us, so as not to interfere with event logic that has preceded? … spoiler alert … double click …

    ele.addEventListener('dblclick', function(evt) {
    location.href=document.URL.split('?')[0].split('#')[0] + '?card_memories=y';
    });

    … (or two clicks quickly in a row) … as per

    var lastec='', notyet=false;


    function antilastec() {
    lastec='';
    }


    function antinotyet() {
    notyet=true;
    }


    ele.addEventListener('click', function(evt) {
    if (evt.touches) {
    if (evt.touches[0].pageX) {
    iourx = evt.touches[0].pageX;
    ioury = evt.touches[0].pageY;
    } else {
    iourx = evt.touches[0].clientX;
    ioury = evt.touches[0].clientY;
    }
    //alert('' + iourx);
    } else if (evt.clientX) {
    iourx = evt.clientX; // - elemLeft;
    ioury = evt.clientY; // - elemLeft;
    } else if (!evt.touches) {
    iourx = evt.pageX; // - elemLeft;
    ioury = evt.pageX; // - elemLeft;
    }
    if (('' + iourx + ',' + ioury) == lastec && lastec != '' && notyet) {
    location.href=document.URL.split('?')[0].split('#')[0] + '?card_memories=y';
    } else if (lastec == '') {
    setTimeout(antilastec, 2000);
    setTimeout(antinotyet, 200);
    notyet=false;
    lastec='' + iourx + ',' + ioury;
    } else {
    setTimeout(antilastec, 2000);
    setTimeout(antinotyet, 200);
    notyet=false;
    lastec='' + iourx + ',' + ioury;
    }

    clickedmaybe();
    });

Again, feel free to try this in the changed cards_usefocus.html code behind the “Just Javascript” Memories Card Game or live run with single window (good for mobile) or default live run (for your platform, and if non-mobile it will try child popup windows).


Previous relevant Just Javascript Card Order Game One Window Tutorial is shown below.

Just Javascript Card Order Game One Window Tutorial

Just Javascript Card Order Game One Window Tutorial

The “one window” rather than (52 + 1) = 53 windows scenario set up as a possibility with yesterday’s Just Javascript Card Order Game Mobile Tutorial had us wondering …

… a one window solution that saves the day for mobile and we see as a good candidate for “default-ness” for non-mobile … we’ll let that one sink in for a day or so?!

… and tomorrow is today. We’ve decided not to make the one window scenario the default for non-mobile platforms, but serve as a fallback for some of the scenarios mentioned below …

  • the user gets blocked from using the popup windows on their non-mobile platform web browser … big possibility!
  • the user clicks half way through the popup window incarnation the parent window … all the child popups disappear behind … annoying … so

    var flexible=false;

    function secsu() {
    var ewd;
    if (secs == 0) {
    if (document.URL.indexOf('onewindow=') != -1 || navigator.userAgent.match(/Android|BlackBerry|iPhone|iPad|iPod|Opera Mini|IEMobile/i)) {
    flexible=false;
    } else {
    flexible=true;
    console.log('Flexible=T');
    }

    setTimeout(blater, 2500);
    }
    if (eval('' + overallgoes) < 52) {
    secs++;
    } else if (document.title.indexOf('Congratulations') == -1) {
    document.title+=' ... Congratulations! End of Game! Refresh webpage to try again.';
    }
    var decs=document.title.split('.');
    if (eval('' + decs.length) >= 3) {
    document.title=document.title.replace('.' + decs[2].split(' ')[0] + ' ', '.' + secs + ' ');
    } else {
    ps=document.title.split('/')[0].trim();
    pg=document.title.split('/')[1].split(' ')[0];
    if (ps.indexOf('.') == -1 || pg.indexOf('.') == -1) {
    ps=eval('' + overallscore + '.' + psecs); //eval(document.title.split('/')[0].trim());
    pg=eval('' + overallgoes + '.' + secs);
    document.title=document.title.replace(document.title.split(' ')[0], '' + overallscore + '.' + psecs + '/' + '' + overallgoes + '.' + secs);
    //console.log('document.title becomes ' + document.title);
    } else {
    ps=eval(ps);
    pg=eval(pg);
    }
    }


    if (flexible) {
    if (document.hasFocus()) {
    flexible=false;
    console.log('Flexible=F');
    lastzkq='';
    lastzkl='';
    owidth=oowidth;
    oheight=ooheight;
    for (var igh=0; igh<oplist.length; igh++) {
    opltlistl[igh]=oopltlistl[igh];
    opltlistt[igh]=oopltlistt[igh];
    if (oplist[igh]) {
    console.log('Flexible=F' + igh);
    if (!oplist[igh].closed) {
    try {
    oplist[igh].close();
    oplist[igh]=null;
    } catch(ewd) {
    }
    } else {
    oplist[igh]=null;
    }
    }
    }
    }
    }

    }

… document.hasFocus() to the rescue again … the multiple background images of yesterday’s work being a default part of any incarnation, and whether the click event logic of yesterday becomes relevant depends on …

  • if user is a mobile platform user, always relevant
  • user enters URL with argument like ?onewindow=y then is always relevant … else …
  • a scenario as above means that from that point on, the multiple background image one window click on cards modus operandi becomes relevant

We improve the web browser conditions too, if a non-mobile user “clicks half way through the popup window incarnation the parent window” in that we programmatically close any open child popup windows! Phew!

Feel free to try this in the changed cards_usefocus.html code behind the “Just Javascript” live run with single window (good for mobile) or default live run (for your platform, and if non-mobile it will try child popup windows).


Previous relevant Just Javascript Card Order Game Mobile Tutorial is shown below.

Just Javascript Card Order Game Mobile Tutorial

Just Javascript Card Order Game Mobile Tutorial

Yesterday’s Just Javascript Card Order Game Tutorial mobile usage scenario was impractical, in that mobile platforms can not work popup windows in front of a parent window. Can we convert those non-mobile popup windows into … well … what exactly?

Well, in order to keep to our “Just Javascript” (ie. “No Body Definition”) pledge with this project, we needed to simulate those popups as background image parts, in the sense that you can have multiple background images these days with your HTML. Even with html as your CSS styling selector … it pans out … we needed to prove that today.

Also, today, for the first time, we achieved via …

  1. comma separated background-repeat: no-repeat; list
  2. comma separated background-size list (set popup width height list until last one bigger (based on screen.width screen.height) for the parent background image (no-repeat))
  3. comma separated background-position list (as per what window.open in non-mobile was using for left top until last one’s 0px 0px)
  4. comma separated background-image list (as per what window.open in non-mobile was using for URL([imageURL]) until last one’s linear-gradient(rgba(255,255,255,0.4),rgba(255,255,255,0.4)), url(//www.rjmprogramming.com.au/rjmquiz_plus.jpg))

… as per (the previous “window.open” becomes “windowopen”) …


function windowopen(one, two, three) {
if (document.URL.indexOf('onewindow=') != -1 || navigator.userAgent.match(/Android|BlackBerry|iPhone|iPad|iPod|Opera Mini|IEMobile/i)) {
console.log('Here ' + kq);
opltlistl.push((three.split('left=')[1].split(',')[0].split(')')[0].split('.')[0] + '.' + one.split('spcp=')[1].split('&')[0]));
opltlistt.push((three.split('top=')[1].split(',')[0].split(')')[0].split('.')[0] + '.' + kq));
owidth=eval(three.split('width=')[1].split(',')[0].split(')')[0].split('.')[0]);
oheight=eval(three.split('width=')[1].split(',')[0].split(')')[0].split('.')[0]);
if (defstyle.indexOf('background: URL(') != -1) {
defstyle=defstyle.split('background: URL(')[0] + 'background-repeat:no-repeat;background-size:' + owidth + 'px ' + oheight + 'px;background-position:' + ('' + opltlistl[eval(-1 + opltlistl.length)]).split('.')[0] + 'px ' + ('' + opltlistt[eval(-1 + opltlistt.length)]).split('.')[0] + '' + 'px' + ';background-image: url(' + cards[eval('' + donelist[eval(-1 + donelist.length)])] + ') ' + (' ' + ('' + opltlistl[eval(-1 + opltlistl.length)]).split('.')[0] + 'px ' + ('' + opltlistt[eval(-1 + opltlistt.length)]).split('.')[0] + '' + 'px').substring(0,1) + '; } </style>'; // + ' ' + owidth + ' ' + oheight
} else {
defstyle=defstyle.replace(';background-image:', (',' + opltlistl[eval(-1 + opltlistl.length)]).split('.')[0] + 'px ' + ('' + opltlistt[eval(-1 + opltlistt.length)]).split('.')[0] + '' + 'px' + ';background-image:');
defstyle=defstyle.replace('no-repeat','no-repeat,no-repeat');
defstyle=defstyle.replace('background-size:' + owidth + 'px ' + oheight + 'px','background-size:' + owidth + 'px ' + oheight + 'px,' + owidth + 'px ' + oheight + 'px');
defstyle=defstyle.replace('; } </style>', ',url(' + cards[eval('' + donelist[eval(0 + ijk)])] + ') ' + (' ' + ('' + opltlistl[eval(-1 + opltlistl.length)]).split('.')[0] + 'px ' + ('' + opltlistt[eval(-1 + opltlistt.length)]).split('.')[0] + '' + 'px').substring(0,1) + '; } </style>'); // + ' ' + owidth + ' ' + oheight
}
return null;
}
return window.open(one, two, three);
}

… a one window solution that saves the day for mobile and we see as a good candidate for “default-ness” for non-mobile … we’ll let that one sink in for a day or so?!

We needed to add event logic we were not sure would work at the start of the day, and saw it working by the end, with …


var iourx=-1, ioury=-1;

function blater() {
if (1 == 2 && navigator.userAgent.match(/Android|BlackBerry|iPhone|iPad|iPod|Opera Mini|IEMobile/i)) {
window.addEventListener('touchstart', function(evt) {
evt.preventDefault();
var touches = evt.changedTouches;
//if (evt.touches) {
if (touches[0].pageX) {
iourx = touches[0].pageX;
ioury = touches[0].pageY;
} else if (touches[0].clientX) {
iourx = touches[0].clientX;
ioury = touches[0].clientY;
}
//alert('x:' + iourx);
//}
clickedmaybe();
}, false);
} else {
eles = document.querySelectorAll("*")
for (var ele of eles) {
console.log('yes well');
if (navigator.userAgent.match(/Android|BlackBerry|iPhone|iPad|iPod|Opera Mini|IEMobile/i)) {
ele.addEventListener('touchstart', function(evt) {
evt.preventDefault();
var touches = evt.changedTouches;
//if (evt.touches) {
if (touches[0].pageX) {
iourx = touches[0].pageX;
ioury = touches[0].pageY;
} else if (touches[0].clientX) {
iourx = touches[0].clientX;
ioury = touches[0].clientY;
}
//alert('x:' + iourx);
//}
clickedmaybe();
}, false);
ele.addEventListener('touchmove', function(evt) {
evt.preventDefault();
var touches = evt.changedTouches;
//if (evt.touches) {
if (touches[0].pageX) {
iourx = touches[0].pageX;
ioury = touches[0].pageY;
} else if (touches[0].clientX) {
iourx = touches[0].clientX;
ioury = touches[0].clientY;
}
//alert('x:' + iourx);
//}
clickedmaybe();
}, false);
ele.addEventListener('click', function(evt) {
evt.preventDefault();
var touches = evt.changedTouches;
//if (evt.touches) {
if (touches[0].pageX) {
iourx = touches[0].pageX;
ioury = touches[0].pageY;
} else if (touches[0].clientX) {
iourx = touches[0].clientX;
ioury = touches[0].clientY;
}
//alert('x:' + iourx);
//}
clickedmaybe();
}, false);
} else {
ele.addEventListener('click', function(evt) {
if (evt.touches) {
if (evt.touches[0].pageX) {
iourx = evt.touches[0].pageX;
ioury = evt.touches[0].pageY;
} else {
iourx = evt.touches[0].clientX;
ioury = evt.touches[0].clientY;
}
//alert('' + iourx);
} else if (evt.clientX) {
iourx = evt.clientX; // - elemLeft;
ioury = evt.clientY; // - elemLeft;
} else if (!evt.touches) {
iourx = evt.pageX; // - elemLeft;
ioury = evt.pageX; // - elemLeft;
}
clickedmaybe();
//alert('here');
});
}
}
}
}

See this in the changed cards_usefocus.html code behind the “Just Javascript” live run with single window (good for mobile) or default live run (for your platform) we, again, welcome you to try for yourself.


Previous relevant Just Javascript Card Order Game Tutorial is shown below.

Just Javascript Card Order Game Tutorial

Just Javascript Card Order Game Tutorial

Today we’ve made the web application of yesterday’s Just Javascript Quiz Drag Tutorial “dual purpose” …

  • quiz … as for yesterday, and before … and as of today, making more use of the card organizational side to the popup windows we introduce …
  • card order game

This card order game asks you to force the focus of the correct popup window (to score in the Card Order Game) in the order as designated by the background image part we have added today, and supported by the following Javascript “mapping” code …


var dragorder=[], curdrag=0;

var cards=["//www.rjmprogramming.com.au/images/01s.gif?n=7",
"//www.rjmprogramming.com.au/images/02s.gif?n=16",
"//www.rjmprogramming.com.au/images/03s.gif?n=33",
"//www.rjmprogramming.com.au/images/04s.gif?n=29",
"//www.rjmprogramming.com.au/images/05s.gif?n=8",
"//www.rjmprogramming.com.au/images/06s.gif?n=35",
"//www.rjmprogramming.com.au/images/07s.gif?n=52",
"//www.rjmprogramming.com.au/images/08s.gif?n=51",
"//www.rjmprogramming.com.au/images/09s.gif?n=12",
"//www.rjmprogramming.com.au/images/10s.gif?n=30",
"//www.rjmprogramming.com.au/images/11s.gif?n=1",
"//www.rjmprogramming.com.au/images/12s.gif?n=36",
"//www.rjmprogramming.com.au/images/13s.gif?n=22",
"//www.rjmprogramming.com.au/images/01h.gif?n=32",
"//www.rjmprogramming.com.au/images/02h.gif?n=23",
"//www.rjmprogramming.com.au/images/03h.gif?n=3",
"//www.rjmprogramming.com.au/images/04h.gif?n=18",
"//www.rjmprogramming.com.au/images/05h.gif?n=28",
"//www.rjmprogramming.com.au/images/06h.gif?n=39",
"//www.rjmprogramming.com.au/images/07h.gif?n=45",
"//www.rjmprogramming.com.au/images/08h.gif?n=48",
"//www.rjmprogramming.com.au/images/09h.gif?n=50",
"//www.rjmprogramming.com.au/images/10h.gif?n=44",
"//www.rjmprogramming.com.au/images/11h.gif?n=4",
"//www.rjmprogramming.com.au/images/12h.gif?n=9",
"//www.rjmprogramming.com.au/images/13h.gif?n=5",
"//www.rjmprogramming.com.au/images/01d.gif?n=27",
"//www.rjmprogramming.com.au/images/02d.gif?n=41",
"//www.rjmprogramming.com.au/images/03d.gif?n=20",
"//www.rjmprogramming.com.au/images/04d.gif?n=11",
"//www.rjmprogramming.com.au/images/05d.gif?n=37",
"//www.rjmprogramming.com.au/images/06d.gif?n=49",
"//www.rjmprogramming.com.au/images/07d.gif?n=42",
"//www.rjmprogramming.com.au/images/08d.gif?n=6",
"//www.rjmprogramming.com.au/images/09d.gif?n=21",
"//www.rjmprogramming.com.au/images/10d.gif?n=31",
"//www.rjmprogramming.com.au/images/11d.gif?n=40",
"//www.rjmprogramming.com.au/images/12d.gif?n=43",
"//www.rjmprogramming.com.au/images/13d.gif?n=17",
"//www.rjmprogramming.com.au/images/01c.gif?n=46",
"//www.rjmprogramming.com.au/images/02c.gif?n=19",
"//www.rjmprogramming.com.au/images/03c.gif?n=47",
"//www.rjmprogramming.com.au/images/04c.gif?n=25",
"//www.rjmprogramming.com.au/images/05c.gif?n=10",
"//www.rjmprogramming.com.au/images/06c.gif?n=15",
"//www.rjmprogramming.com.au/images/07c.gif?n=13",
"//www.rjmprogramming.com.au/images/08c.gif?n=26",
"//www.rjmprogramming.com.au/images/09c.gif?n=38",
"//www.rjmprogramming.com.au/images/10c.gif?n=34",
"//www.rjmprogramming.com.au/images/11c.gif?n=2",
"//www.rjmprogramming.com.au/images/12c.gif?n=14",
"//www.rjmprogramming.com.au/images/13c.gif?n=24"];


for (var ic=1; ic<=cards.length; ic++) {
found=false;
for (var jc=1; jc<=cards.length; jc++) {
if ((cards[eval(-1 + jc)] + '~').indexOf('?n=' + ic + '~') != -1) {
dragorder.push(eval(-1 + jc));
cards[eval(-1 + jc)]=cards[eval(-1 + jc)].replace('?n=' + ic, '');
firstbit+=String.fromCodePoint(eval('' + spcps[eval(-1 + jc)].split('/')[0])) + ' ';
found=true;
}
}
}

… and “making use of” this and the new codeline as popups are created … oplist[eval(-1 + oplist.length)].document.name=” + kl; we have …


function ourprompt(tw, blb, bdef) {
var kijk;
if (oplist[eval('' + tw)].document.name == ('' + dragorder[eval('' + curdrag)]) && eval('' + curdrag) == eval('' + overallgoes)) {
console.log('Dragorder[' + curdrag + ']=' + dragorder[eval('' + curdrag)] + ' vs tw=' + tw + ' and overall;goes=' + overallgoes);
var decs=document.title.split('.');
curdrag++;
overallgoes++;
if (eval('' + decs.length) >= 3) {
document.title=document.title.replace('.' + decs[1] + '.', '.' + curdrag + '/' + overallgoes + '.');
}
oplist[eval('' + tw)].close();
return null;
}

// Quiz only code follows
}

… code.

It must be in the correct order (and not interrupted by quiz answer completions) to score, and you are timed, so you can try improving over time, using a document.title score presentation as per …


[QuizScore].[CardOrderGameScore]/[QuizAnswerAttemptCount].[SecondsElapsed] [MultiPlayerQuizScoreGoesBreakdown] is User: Score/Goes - RJM Programming - April, 2021

… so that both usages for the web application can be accommodated for in the changed cards_usefocus.html code behind the “Just Javascript” live run we welcome you to try for yourself.


Previous relevant Just Javascript Quiz Drag Tutorial is shown below.

Just Javascript Quiz Drag Tutorial

Just Javascript Quiz Drag Tutorial

Adding to yesterday’s Just Javascript Quiz CSS Styling Tutorial we have added some …

  • non-mobile platform, only …
  • drag and drop functionality … for …
  • the child popup windows

… achieved through the comparison of …

  • original [popupWindow].screenLeft and [popupWindow].screenTop … initially, to …
  • [popupWindow].screenLeft and [popupWindow].screenTop over time

… and if one popup is dragged to overlay another it is closed, or you, as the user, can just drag and drop for clarity, leaving the popup window of the next quiz question out in the open, perhaps.

In order to achieve this, and keep backward compatibility we needed to delay the quiz question prompt window via …

  1. document.hasFocus() is true … then if …
  2. inhouse dragging checks clear it of overlaying another popup (in which case that popup is programmatically closed, allowing another popup to become the “focus window”) … then …
  3. delay (by 8 seconds) the prompt window (and in that time the user can be dragging popups (but no popups were harmed in the making of this tutorial)) … via …

    setTimeout(function() { hj=prompt(dp + window.opener.blurb(), def); if (hj == null) { hj=''; } else { hj=window.opener.assess(hj); } if (hj.replace(def,'') != '') { checka(hj); } else { setTimeout(pa,10000); } aminmiddle=false; }, 8000);

… you can see in amongst the changed cards_usefocus.html code behind the “Just Javascript” live run you are welcome to try for yourself … best on non-mobile.

Still “No Body Definition”, “Just Javascript”!


Previous relevant Just Javascript Quiz CSS Styling Tutorial is shown below.

Just Javascript Quiz CSS Styling Tutorial

Just Javascript Quiz CSS Styling Tutorial

Our “Just Javascript” adage used throughout this blog posting thread, up until today, headed by yesterday’s Just Javascript Quiz Content Management Tutorial needs more explanation. Really what we are trying to do might better be described as “No Body Definition” (ie. no defined document.body) but have …

  1. an HTML webpage (ie. within <html> and </html>) … has …
  2. <head> and </head> (ie. document.head) content which can be made up of (at least) title, style, script, link, meta tags

To assert “Just Javascript” is just to allow script content above, but what we should really say is “Just Head Content” but that is not nearly so marketable, is it now?!

The thing is, though, we can dynamically add title, style, link, meta tag content within the script content, and we do this more than statically define it, to feel better about our ethics saying “Just Javascript”.

Dynamically adding style CSS styling either …

  • using Javascript DOM (not available to us for document.getElementById([elementID] and nor can we use inline CSS via style=”[CSSstyling]” statically within HTML element code for that same reason) ideas today though … remember “No Body Definition” … but …
  • we can append to <head> and </head> (for today’s scenario) as per …

    document.head.innerHTML+="<style> html { background-color: yellow; font-size: 36px; background: URL('//www.rjmprogramming.com.au/rjmquiz.jpg'); background-size: cover; } </style>";

… allowing (into the scope of our work CSS styling of) background (image(s)) and other background styling ideas that can get us past the anonymous feel the web application had before today. We tailored the background image above to suit our Quiz and help it be a bit more self explanatory … thanks CSS styling! We add onto the child “card” popup windows, their own background image colour and pizazz, to cheer things up in CSS styling enhanced cards_usefocus.html code behind the “Just Javascript” live run.

You may well ask …

What can we hang our hat on with CSS style selectors without a body element?

Well, we had to step out of our usual comfort zone of CSS styling thinking, and realize, even without that body element we can still use the html selector to “point at” the entirety of your webpage of interest.


Previous relevant Just Javascript Quiz Content Management Tutorial is shown below.

Just Javascript Quiz Content Management Tutorial

Just Javascript Quiz Content Management Tutorial

It feels like an “onions of the 4th dimension” idea to allow the user to control the questions and answers behind the workings of yesterday’s Just Javascript Quiz Multiple Users Tutorial‘s web application, featuring “Just Javascript”.

It’s not “Just Javascript” we’re keeping, it’s “Just HTML” client work rather than involving any serverside anything (eg.PHP) and yet this question and answer data could be quite sizeable. What can we use, given no PHP serverside, and given we’ve decided not to navigate via Ajax/FormData techniques? How about “the better than HTTP Cookies” twins …

Yep, set up a means by which these two can store and restore questions and answers entered by the user, using these storage methods above.


function reassess() {
var retv='', ewq;
var retcols=[];
var ir=0;
if (window.localStorage) {
try {
retv=('' + window.localStorage.getItem('cards_usefocus_local')).replace(/^null$/g,'');
if (retv != '') {
//alert('0:' + retv);
retcols=decodeURIComponent(retv).split('~');
sq=[];
asq=[];
for (ir=0; ir<retcols.length; ir++) {
sq.push(retcols[ir].split('?!')[0] + '?');
asq.push(retcols[ir].split('?!')[1]);
nomap=false;
given='';
}
return;
}
} catch(ewq) {
}
}
if (window.sessionStorage) {
try {
retv=('' + window.sessionStorage.getItem('cards_usefocus_session')).replace(/^null$/g,'');
if (retv != '') {
//alert('1:' + retv);
retcols=decodeURIComponent(retv).split('~');
sq=[];
asq=[];
for (ir=0; ir<retcols.length; ir++) {
sq.push(retcols[ir].split('?')[0] + '?');
asq.push(retcols[ir].split('?')[1]);
nomap=false;
given='';
}
return;
}
} catch(ewq) {
}
}
}


function assess(what) {
var ewq, retv='';
if (what.toLowerCase() == '?x') {
sslistq=[];
sslista=[];
if (window.sessionStorage) {
try {
window.sessionStorage.removeItem('cards_usefocus_session');
} catch(ewq) {
}
location.href=document.URL.split('#')[0].split('?')[0] + '?rand=' + Math.floor(Math.random() * 198765897);
return '';
}
return '';
} else if (what.toLowerCase() == '?!x') {
lslistq=[];
lslista=[];
if (window.localStorage) {
try {
window.localStorage.removeItem('cards_usefocus_local');
} catch(ewq) {
}
location.href=document.URL.split('#')[0].split('?')[0] + '?rand=' + Math.floor(Math.random() * 198765897);
return '';
}
return '';
} else if (what.toLowerCase().indexOf('?!') != -1) {
if (what.toLowerCase() == '?!') {
location.href=document.URL.split('#')[0].split('?')[0] + '?rand=' + Math.floor(Math.random() * 198765897);
return '';
}
if (window.localStorage) {
if (lslistq.length == 0) {
lslistq.push(what.split('?!')[0]);
lslista.push(what.split('?!')[1]);
window.localStorage.setItem('cards_usefocus_local', encodeURIComponent(what));
} else {
lslistq.push(what.split('?!')[0]);
lslista.push(what.split('?!')[1]);
window.localStorage.setItem('cards_usefocus_local', window.localStorage.getItem('cards_usefocus_local') + encodeURIComponent('~' + what));
}
}
return '';
} else if (what.toLowerCase().indexOf('?') != -1) {
if (what.toLowerCase() == '?') {
location.href=document.URL.split('#')[0].split('?')[0] + '?rand=' + Math.floor(Math.random() * 198765897);
return '';
}
if (window.sessionStorage) {
if (sslistq.length == 0) {
sslistq.push(what.split('?')[0]);
sslista.push(what.split('?')[1]);
window.sessionStorage.setItem('cards_usefocus_session', encodeURIComponent(what));
} else {
sslistq.push(what.split('?')[0]);
sslista.push(what.split('?')[1]);
window.sessionStorage.setItem('cards_usefocus_session', window.sessionStorage.getItem('cards_usefocus_session') + encodeURIComponent('~' + what));
}
}
return '';
} else {
firstbit='';
if (window.localStorage) {
try {
retv=('' + window.localStorage.getItem('cards_usefocus_local')).replace(/^null$/g,'');
if (retv != '' && nomap) { location.href=document.URL.split('#')[0].split('?')[0] + '?rand=' + Math.floor(Math.random() * 198765897); }
} catch(ewq) {
}
}
if (window.sessionStorage) {
try {
retv=('' + window.sessionStorage.getItem('cards_usefocus_session')).replace(/^null$/g,'');
if (retv != '' && nomap) { location.href=document.URL.split('#')[0].split('?')[0] + '?rand=' + Math.floor(Math.random() * 198765897); }
} catch(ewq) {
}
}
}
return what;
}

The fairly significantly changed cards_usefocus.html code behind the “Just Javascript” live run is worth a look, we figure, for up to 52 players who play in turn.


Previous relevant Just Javascript Quiz Multiple Users Tutorial is shown below.

Just Javascript Quiz Multiple Users Tutorial

Just Javascript Quiz Multiple Users Tutorial

Adding to yesterday’s Just Javascript Quiz via Cards Tutorial we were surprised how difficult it was to stay with “Just Javascript” and allow for multiple player play.

We didn’t opt for the parent to ask about the number of players, curiously, but on the second quiz answer and on, offered any non first player the chance to identify themselves as a new player into the game by appending their answer with a space character.

The implication of that is that we’ll want to run Javascript functions of the parent from the children as per


oplist[eval(-1 + oplist.length)].document.write("<link rel=icon href=" + cards[kl] + "><scr" + "ipt type='text/javascript'> var da='" + eval(0 + kq) + "'; var dp='Given answer is integer from 0 to 25 ... " + sq[kq] + "'; var def=String.fromCodePoint(" + spcps[eval('' + kl)].split('/')[0] + "); function checka(tpa) { var os=''; var ps=eval(window.opener.document.title.split('/')[0].trim()); var pg=eval(window.opener.document.title.split('/')[1].split(' ')[0]); if (tpa.trim() == da) { ps++; os=tpa.split(da)[1]; } else { pg++; os=tpa.split(tpa.trim())[1]; } window.opener.document.title=ps + os + '/' + pg + ' is User Score/Goes'; window.close(); } function pa() { if (document.hasFocus()) { var hj=prompt(dp + window.opener.blurb(), def); if (hj == null) { hj=''; } if (hj.replace(def,'') == '') { setTimeout(pa,1000); } else { checka(hj); } } else { setTimeout(pa,1000); } } pa(); </scr" + "ipt>");

… accessing …


function blurb() { // theblurb and wblurb are global variables changed elsewhere
if (wblurb == ' Hello Player 1' && theblurb == ' If you are player 2 rather than player 1 append space to your answer.') {
theblurb='';
wblurb='';
}
return theblurb + wblurb;
}

… giving the rather curious behaviour whereby a Javascript prompt window can be dynamically different from one document.hasFocus() incarnation (ie. the user might go away and answer another “card” Number Quiz question) to another (even not attending to answering the Javascript prompt window) … huh?!

The significantly changed cards_usefocus.html code behind the “Just Javascript” live run is worth a look, we figure, for up to 52 players who play in turn.


Previous relevant Just Javascript Quiz via Cards Tutorial is shown below.

Just Javascript Quiz via Cards Tutorial

Just Javascript Quiz via Cards Tutorial

Yesterday’s Just Javascript Navigation Tutorial continues our interest in “Just Javascript” (or “No Body”) web applications.

We think today’s “Numbers Quiz” via a “Card Deck” organizational design ups the ante on all this. We realize now what we have been missing not having involved document.hasFocus() in any of our popup window scenarios. Today, at least on non-mobile, we involve 52 such popup windows each containing a “Number Quiz” question presented as a Javascript prompt (sub-)window. This would not be feasible without document.hasFocus() as you can tell if you examine the cards_usefocus.html code behind the “Just Javascript” live run best used on your non-mobile platforms where popup windows can sit in front of parent (and beside sibling) windows, whereas mobile platforms open new web browser tabs for all the 52 windows of (a card deck) design.

Look out, too, in the code above, for use of window.opener back reference from a popup window back to the parent window where the scoring data is held, and updated by each popup window because of that window.opener avaalability.


Previous relevant Just Javascript Navigation Tutorial is shown below.

Just Javascript Navigation Tutorial

Just Javascript Navigation Tutorial

The recent use we made of …


document.createElement/click()

… got us thinking of the “Just Javascript” (or No Body) blog posting thread headed by Just Javascript Webmail No Body Attachment Tutorial.

As such, today we present the very simple (but first time use of the interesting hasFocus) “proof of concept” …


<html>
<head>
<script type='text/javascript'>
function dothis() {
var ais=null;
var urlis=' ';
while (urlis != '') {
if (document.hasFocus()) {
urlis=prompt('Enter URL that we will send you to (exit to stop)', '');
} else {
setTimeout(dothis, 2000); // urlis=' ';
return;
}
if (urlis == null) { urlis=''; }
if (urlis.toLowerCase() == 'exit') { return; }


if (urlis.trim() != '') {
if (urlis.substring(0,1) == '.') { // relative URL
urlis=document.URL.split('nobody.htm')[0] + urlis;
} else if (urlis.substring(0,1) == '/' && urlis.indexOf('//') == -1) { // relative URL
urlis=document.URL.split('//')[0] + '//' + document.URL.split('//')[1].split('/')[0] + '/' + urlis;
} else if (urlis.split('/')[0].indexOf('.') != -1) { // absolute URL
if (urlis.toLowerCase().indexOf('http') != 0) {
if (urlis.indexOf('//') == 0) {
urlis=document.URL.split('//')[0] + urlis;
} else {
urlis=document.URL.split('//')[0] + '//' + urlis;
}
}
} else { // relative URL
urlis=document.URL.split('nobody.htm')[0] + urlis;
}
ais=document.createElement('a');
ais.onclick=function() { window.open(urlis, '_blank', 'top=100,left=100,width=600,height=600'); };
if (1 == 2) { ais.href=urlis; }
ais.target='_blank';
ais.click();
}
}
setTimeout(dothis, 2000); // urlis=' ';
}


dothis();

</script>
</head>
</html>

nobody.html‘s live run link for you to use a Javascript prompt popup window’s user interaction results to navigate to a new webpage, as applicable. Bookmarklets may be scarce on the ground, but these “Just Javascript” ideas continue the Bookmarklet Spirit of the past!


Previous relevant Just Javascript Webmail No Body Attachment Tutorial is shown below.

Just Javascript Webmail No Body Attachment Tutorial

Just Javascript Webmail No Body Attachment Tutorial

A “hard liner” for the proper use of “business emails” could argue that an email without an attachment is not productive. Couldn’t you just have a face to face meeting instead, if there is just wording in the email (as we somewhat concur with, as an argument)? So yesterday’s Just Javascript Webmail No Body Tutorial had that limitation of no email attachment logic, which we remedy today.

And this is where PHP’s wonderful file_get_contents (function) means by which we garner (URL) content …

  • definitely works with “relative URLs” relative to HTTP://www.rjmprogramming.com.au/HTMLCSS/ where today’s unchanged webmail_nobody.html resides … in “parsing parlance” …

    "relative (URL)" to the left of any # or ? of what lies to the left of the most right hand "/" (of what the address bar URL is of the webpage you are on)

    … so that …

    1. “relative URLs” starting with “./” (followed by the filename, or just the filename (as you can see us using in today’s tutorial picture)) refer to the web server directory corresponding to “HTTP://www.rjmprogramming.com.au/HTMLCSS/” … whereas, for example …
    2. “relative URLs” starting with “../” (followed by the filename) refer to the web server directory corresponding to “HTTP://www.rjmprogramming.com.au/” … for example

    … and …

  • might work for “absolute URLs” (those that start with https: or HTTP: or even // (that we beg you not to confuse with Windows UNC pathnames) that infer a transport protocol of the transport protocol (out of https: or HTTP: or even file:) that got you to the webpage you are currently on), the “might” being far more likely on “absolute URLs” pointing to the same domain as indicated on the URL of the address bar of the webpage you are currently on

Upshot is, the user in their email Body section definitions (still no HTML body though!), can throw into any word they use, an “absolute URL” of interest, or a “relative URL” of interest, of files they want to attach (as attachments, doh!) in their email.

Depending on the email rules though, there are limits as to the amount of attachment data allowed. We’ll leave that to you intrepid “explorers of the Net” to discover for yourselves. On this subject though, have you noticed that with the Photos (or Gallery) app Share options, the Email option drops off when you have highlighted a large number of photos or videos or audios to share? That’s that email limit coming into play.

So feel free to try this HTML-body-less web application live run to see what we mean here. Though the parent HTML is unchanged today, the new (email) attachment functionality needed a changed PHP emailhtml.php to make this happen.

Did you know?

This (relative URL) “../” navigation backwards up the hierarchy of the web server directories will, if repeated (ie. nested to “../../” etcetera) too many times, get you into uncharted unnavigable (web server directory) places relative to that web server web site’s Document Root (below which you can not access in public webpages, normally). But when you perform similar thinking with “absolute URLs” and go “HTTP://www.rjmprogramming.com.au/HTMLCSS/../../../blahdeblah.jpg” (in a web browser address bar) for instance, you cannot get into trouble, as you just don’t get beyond this sending you to (attempt the reference to) “HTTP://www.rjmprogramming.com.au/blahdeblah.jpg” because on this rjmprogramming.com.au Apache domain the correspondence of the Document Root (web server directory) is to “HTTP://www.rjmprogramming.com.au/” as the place you are not allowed (and cannot) go below in the hierarchy tree.


If this was interesting you may be interested in this too.


If this was interesting you may be interested in this too.


If this was interesting you may be interested in this too.


If this was interesting you may be interested in this too.


If this was interesting you may be interested in this too.

This entry was posted in Ajax, eLearning, Event-Driven Programming, Games, Tutorials and tagged , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , . Bookmark the permalink.

Leave a Reply

Your email address will not be published. Required fields are marked *