Skip to content

Instantly share code, notes, and snippets.

@derekmc
Last active February 26, 2021 18:30
Show Gist options
  • Save derekmc/68b5698944ee1e02b1eeade27ba231bc to your computer and use it in GitHub Desktop.
Save derekmc/68b5698944ee1e02b1eeade27ba231bc to your computer and use it in GitHub Desktop.
<html>
<head>
<script src="./src/jszip.min.js"></script>
<script src="./src/FileSaver.min.js"></script>
<script>
// goto targets are capitalized
// contemporary programming make the mistake of being easy to debug, not easy to write.
// debugging is always hard, deal with it.
//
// So linguistic "decoupling" is more important, and easier, than "runtime" decoupling,
// runtime "decoupling", actually leads to linguistic "coupling", ie interdependence
// semantically between the different parts of the program.
//
// Making debugging easy is trying to control the future, which makes no sense,
// and is very hard on top.
// Runtime decoupling, is inherently impossible, so it just makes programs very hard to write.
//
window.addEventListener("load", () => goto(WAR));
//window.addEventListener("load", () => { codeoutput.ap document.documentElement.outerHTML; });
// player decks and discards
let DELAY = 0.8;
let MINDELAY = 0.012;
let D1, D2, TABLE, ROUND;
function rank(x){
let r = (x%13) + 1;
if(r == 1) r = 14;
return r;
}
function card(x){
let r = rank(x);
let suit = Math.floor(x/13);
if(r > 10){
r = ["Jack", "Queen", "King", "Ace"][r - 11]; }
suit = ["Clubs", "Spades", "Hearts", "Diamonds"][suit];
return `${r} of ${suit}`;
}
function deck(){
return [...Array(52).keys()];
}
function shuffle(d){
if(!d) d=deck();
for(let i=0; i<d.length; ++i){
let j = i + Math.floor((d.length-i) * Math.random());
[d[i], d[j]] = [d[j], d[i]];
}
return d;
}
function draw(d,n,result){
if(!d) d=deck();
if(!n) n = 1;
if(!result) result = [];
n = Math.min(n, d.length);
for(let i=0; i<n; ++i){
result.push(d.shift()); }
return result;
}
function ShowCounts(next){
return next;
}
function WAR(){
D1 = shuffle();
D2 = draw(D1, 26);
console.log(D1, D2);
TABLE = [];
ROUND = 1;
disp(`Welcome to War!`);
more();
return WAIT(ANNOUNCE);
}
function WAIT(next){
if(DELAY == 0) return next;
return ()=> {
let handlers = [];
more(`Press [Enter] or click [ok] to continue.`);
wait(handlers, document.getElementById("okaybutton"), 'mousedown', null, next);
wait(handlers, document.body, 'keydown', (e)=>(e.keyCode == 13), next);
return null;
}
}
function ANNOUNCE(){
disp(`Player 1: ${D1.length} cards`);
more(`Player 2: ${D2.length} cards`);
more();
more(`Round ${ROUND++}. . .`);
return sleep(DELAY, ()=>{
more("Fight!");
return sleep(DELAY, FIGHT); })
}
function FIGHT(){
more();
if(D1.length == 0 || D2.length == 0) return END;
let a = D1.shift();
let b = D2.shift();
TABLE.push(a);
TABLE.push(b);
more(` === ${card(a)} ===`)
more("Vs")
more(` === ${card(b)} ===`);
more();
return sleep(3*DELAY, ()=>{
let x = rank(a);
let y = rank(b);
if(x == y){
return TIE; }
let winner = (x > y)? D1 : D2;
more(`Player ${x>y? 1 : 2} wins ${TABLE.length} cards.`);
more();
draw(shuffle(TABLE), TABLE.length, winner);
return WAIT(ANNOUNCE);
})
}
function TIE(){
more("Round is tied.");
more();
more("Each player draws 3 more facedown cards.");
draw(D1, 3, TABLE);
draw(D2, 3, TABLE);
if(D1.length == 0 || D2.length == 0){
return END; }
more();
return WAIT(ANNOUNCE);
}
function END(){
if(D1.length > D2.length){
disp("Player 1 Wins!"); }
else{
disp("Player 2 Wins!"); }
more(`After ${ROUND} rounds.`);
if(DELAY == 0 && Math.random() < 0.18){
ToggleAuto(); }
return RESTART;
}
function RESTART(){
return sleep(__DELAY*4, ()=>{
more("Restarting ...");
sleep(__DELAY*4, WAR)})
}
function goto(target){ // targets return the next function to run.
while(target){
target = target(); }
}
function wait(handlers, target, name, test, after){
if(!handlers) handlers = [];
let handler = function(evt){
if(test && !test(evt)) return;
for(let tuple of handlers){
let [other_target, other_name, other_handler] = tuple;
other_target.removeEventListener(other_name, other_handler);
}
goto(after);
}
handlers.push([target, name, handler]);
target.addEventListener(name, handler);
return null;
}
function sleep(n, after){
setTimeout(()=>goto(after), n*1000);
return null;
}
function disp(x){
if(x == undefined) x = "";
document.getElementById("disptext").innerHTML = x;
}
function more(x){
if(x == undefined) x = "";
document.getElementById("disptext").innerHTML += "\n" + x;
}
function randint(n){
return Math.floor(Math.random() * n);
}
let __DELAY = DELAY;
function ToggleAuto(){
if(DELAY == 0){
DELAY = __DELAY;
autobutton.value = "Auto: Off"; }
else if(DELAY == __DELAY){
autobutton.value = "Auto: Semiauto";
DELAY = MINDELAY; }
else {
autobutton.value = "Auto: On";
DELAY = 0; }
autobutton.blur();
}
function Download(){
var zip = new JSZip();
// Generate a directory within the Zip file structure
var guessgame = zip.folder("war");
guessgame.file("index.html", document.documentElement.outerHTML);
// Generate the zip file asynchronously
zip.generateAsync({type:"blob"}).then(function(content){
// Force down of the Zip file
saveAs(content, "wargame.zip");
});
}
</script>
<style>
*{ font-size: 108%; font-family: monospace; }
hr{ margin-top: 2em; margin-bottom: 0.65em; }
#codeoutput{ font-family: monospace; width: 100%; overflow-x: scroll;
text-align: left;
white-space: pre;
}
body{ text-align: center; }
</style>
</head>
<body>
<p><pre id="disptext"></pre></p>
<!--<input id='textinput' type='text'></input>-->
<input id='okaybutton' type='button' value="ok"></input>
<input id='autobutton' onclick='ToggleAuto();' type='button' value="Auto: Off"></input>
<!-- <p style="position: fixed; bottom: 0px; right:8px; text-align: right;"> -->
<p>
<!-- <h3> Source Code </h3> -->
<hr>
<button onclick="Download();"> Download Game</button>
<button onclick="codeoutput.appendChild(document.createTextNode(document.documentElement.outerHTML)); codeoutput.style.display='block'"> View Source </button>
</p>
<span id='codeoutput' wrap='off' style="display:none;"><hr></span>
</body>
</html>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment