Lorne's Stupid Thread of War and elgiu (because if everyone else can abuse Discourse so can I :doing_it_wrong:)


  • Trolleybus Mechanic

    In the Status thread, I posted a quick-n-dirty War in Javascript game. If you want to find it, be my guest.

    I've been tinkering with the code trying to turn it into a playable game. Mostly for my amusement. Partially because of-- secret raisins. In any case, I figured I should get the code into some sort of code tracker system, so I can track revisions. But rather than doing it in any sane or correct way-- Discourse!

    You can probably safely ignore this thread for a while. There won't be anything production ready until it's ready for production.


  • Trolleybus Mechanic

    Version 2.0****strong text
    First release.

    • Mostly works
    • UI is shit
    • Has a button you can click
    • Hard coded JQuery to my own server, so please don't rape it too much
    • There were previous versions, but not tracked.
    • Fuck you, give me money.
    <html>
    <head>
    <script src="http://sevenseventeen.ca/wp-includes/js/jquery/jquery.js" type="text/javascript"></script>
    <script type="text/javascript">
    

    var decks = [];

    var wins = [];

    var kitty = [];
    var winner = 0;
    var battle = [];

    var suites = ["Hearts", "Spades", "Diamonds", "Clubs"];
    var ranks = {"Two" : 2, "Three" : 3, "Four" : 4, "Five" : 5, "Six" : 6, "Seven" : 7, "Eight" : 8, "Nine" : 9, "Ten" : 10, "Jack" : 11, "Queen" : 12, "King" : 13, "Ace": 14};
    var GameDeck = [];

    for(s = 0; s < suites.length; s++)
    {
    suit = suites[s];

    for(var rank in ranks)
    {
        card = {"Suit" : suit, "Rank" : rank, "Value" : ranks[rank]};
        GameDeck.push(card);
    }
    

    }

    // UI functions
    // TODO put visibility of card into card properties
    // player = 0 index id of player
    function PutCardOnBattleground(player, card)
    {

    var batleground_area = document.getElementById("battleground_p" + player);
    var cardui = document.createElement("div");
    cardui.className = "card";
    cardui.textContent = card.Rank + " " + card.Suit;
    batleground_area.appendChild(cardui);
    $(cardui).data("card", card);
    

    }

    function SortByValue(c1, c2)
    {
    var a = $(c1).data("card").Value;
    var b = $(c2).data("card").Value;
    return a < b ? 1 : a > b ? -1 : 0;
    }

    // Collect all ventured cards into the winners Win pile
    function CollectWinnings(player)
    {

    var winnings = $(".battleground .area.stack .card");
    var wins = $("#player"+player+"_area_wins");
    wins.find(".card").removeClass("latest");
    winnings.addClass("latest");
    winnings.sort(SortByValue);
    winnings.detach().prependTo(wins);
    
    /*
    
    //var winpile = document.getElementById("player"+player+"_area_wins");
    var winpile = $("#player"+player+"_area_wins");
    
    if(winpile != null)
    {
        for(var i = 0; i <=1; i++)
        {
            var ba = document.getElementById("battleground_p" + i);
            while(ba.childNodes.length > 0)
            {
                winpile.appendChild(ba.childNodes[0]);
            }
    
        }
    }
    */
    

    }

    // Empty Win Pile UI
    function ClearWinsPile(player)
    {
    var winpile = document.getElementById("player"+player+"_area_wins");
    while(winpile.childNodes.length > 0)
    {
    winpile.removeChild(winpile.firstChild);
    }
    }

    // face down deck. Clear anything in there, put face down card, and add counter
    function RefreshDeck(player)
    {
    var deck = document.getElementById("player"+player+"_area_deck");
    while(deck.childNodes.length > 0)
    {
    deck.removeChild(deck.firstChild);
    }

    var card = document.createElement("div");
    card.className = "card facedown";
    deck.appendChild(card);
    
    var cnt = document.createElement("div");
    card.appendChild(cnt);
    cnt.textContent = decks[player].length;
    

    }

    // End UI functions

    function shuffle(array)
    {
    var currentIndex = array.length, temporaryValue, randomIndex ;

    // While there remain elements to shuffle...
    while (0 !== currentIndex) {

    // Pick a remaining element...
    randomIndex = Math.floor(Math.random() * currentIndex);
    currentIndex -= 1;
    
    // And swap it with the current element.
    temporaryValue = array[currentIndex];
    array[currentIndex] = array[randomIndex];
    array[randomIndex] = temporaryValue;
    

    }

    return array;
    }

    // draw one card from deck IDX, return that card or null
    // when a deck runs out, reshuffle win pile into deck
    // if no cards remain in deck or win pile, returns null
    function draw(idx)
    {
    if(decks[idx].length == 0)
    {

        wins[idx] = shuffle(wins[idx]);
        while(wins[idx].length > 0)
        {
            decks[idx].push(wins[idx].shift());
            ClearWinsPile(idx);
        }
    }
    
    card = decks[idx].shift();
    RefreshDeck(idx);
    
    return card;
    

    } // end function draw

    function CardsOwned(player)
    {
    return decks[player].length + wins[player].length;
    }

    function DoWar(numcards)
    {

    winner = -1; // tie
    
    var PlayerDepleted = false;
    for(var i=0; i<=1; i++)
    {
        if(CardsOwned(i) == 0)
        {
            PlayerDepleted = true;
        }
    }
    
    if(PlayerDepleted)
    {
        // there is a player who cannot war no more.  The only way to resolve this is
        // First, who has the most rank values.
        // If still tied, who has the most cards.
        // If STILL tied, then both players are exactly where they were when they started.  Reshuffle everything and start again.
    
        console.log("Player " + i + " has run out of cards and cannot commit to war. Checking for armistice.");
        // someone has run out of cards, AND ended with a war
        // the winner of the game will be whoever has more cards
        for(var idx = 0; idx <= 1; idx++)
        {
            // move everything into the battle piles
            while(wins[idx].length > 0)
            {
                card = wins[idx].shift();
                battle[idx].push(card);
                PutCardOnBattleground(idx, card);
            }
    
            while(decks[idx].length > 0)
            {
                card = decks[idx].shift();
                battle[idx].push(card);
                PutCardOnBattleground(idx, card);
            }
    
            ClearWinsPile(idx);
            RefreshDeck(idx);
        }
    
        winner = -1; // tie
        // total up the values of the cards in the decks
        totals = [];
        totals[0] = 0;
        totals[1] = 0;
        for(var i = 0; i <=1; i++)
        {
            for(j = 0; j < battle[i].length; j++)
            {
                totals[i] = totals[i] + battle[i][j].Value;
            }
    
        }
    
        // compare totals
        for(var i = 0; i <=1; i++)
        {
            console.log("Player " + i + " has " + totals[i] + " points in rank");
            up = i % 2;
            down = (i+1) % 2;
    
            if(totals[up] > totals[down])
            {
                winner = up;
            }
        }
    
        console.log("A winner of the whole game is " + winner);
    
    
        if(winner < 0)
        {
            console.log("Players are tied in rank.  Checking by number of cards");
            // it is still a tie because both players have the same value of cards
            // go by number of cards
            for(var i = 0; i <=1; i++)
            {
                console.log("Player " + i + " has " + battle[i].length + " cards");
                up = i % 2;
                down = (i+1) % 2;
    
                if(battle[up].length > battle[down].length)
                {
                    winner = up;
                }
            }
        }
    
        console.log("A winner of the whole game is " + winner);
    
        if(winner < 0)
        {
            console.log("Players are equal in rank and cards. Putting all cards back into decks and starting again.");
            // OMFG both players have the same number of cards and the same total values.
            // just start the damn game again!
            SetupNewGame(1);
        }
    
        if(winner < 0)
        {
            // forget it. The universe has ended.
            throw new Exception("Forget it. The universe has ended");
        }
    
        return winner;
    
    
    } // end tiebreaker
    
    // Only venture as many cards as any one player has
    for(var i=0; i<=1; i++)
    {
        if(CardsOwned(i) < numcards)
        {
            console.log("Player " + i + " cannot venture " + numcards + " cards, so instead we'll do " + CardsOwned(i));
            numcards = CardsOwned(i);
        }
    }
    
    for(drawidx = 0; drawidx < numcards; drawidx++)
    {
    
        for(var i = 0; i <=1; i++)
        {
            // Each player adds a card to the top of the battlegrounds, to face off
            card = draw(i);
            battle[i].push(card);
            PutCardOnBattleground(i, card);
            RefreshDeck(i);
        }
    }
    
    
    // Check for the winner by comparing the top cards of the battleground to each other
    for(var i = 0; i <=1; i++)
    {
        up = i % 2;
        down = (i+1) % 2;
    
        if(battle[up][battle[up].length - 1].Value > battle[down][battle[down].length - 1].Value)
        {
            winner = up;
        }
    }
    
    if(winner < 0)
    {
        console.log("We're at war!");
        if(numcards > 1)
        {
            console.log("EXTRA WAR!!!");
        }
        // Oh shnit!  We have a tie. Let us settle it with W-A-R!!!!
        // a tie had occured. Oh noes!
        // W-A-R then flip 1
        winner = DoWar(4);
    
    } // end WAR
    
    
    return winner;
    

    } // end battle

    function PlayOneRound()
    {
    winner = -1;

    // Do the War function until there is a winner
    while(winner < 0)
    {
        winner = DoWar(1); // check the topmost card in each player battle pile, and the winner is returned, or -1 for a tie
    
    }
    
    
    
    // Move all cards from both Battlegrounds into the win pile of the winner (obj)
    for(var i = 0; i <=1; i++)
    {
        while(battle[i].length > 0)
        {
            wins[winner].push(battle[i].shift());
        }
    }
    
    // Move all the cards from the Battleground into the win pile of the winner (UI)
    CollectWinnings(winner);
    
    return winner;
    

    }

    function SetUpNewGame(numPlayersZeroIndex)
    {
    GameDeck = shuffle(GameDeck);

    for(var i = 0; i<= numPlayersZeroIndex; i++)
    {
        decks[i] = [];
        wins[i] = [];
        battle[i] = [];
    }
    
    for(var i = 0; i < GameDeck.length; i++)
    {
        decks[i%(numPlayersZeroIndex + 1)].push(GameDeck[i]);
    }
    
    
    // set up deck UI
    for(var i = 0; i<= numPlayersZeroIndex; i++)
    {
    
        CollectWinnings(i);
        ClearWinsPile(i);
        RefreshDeck(i);
    }
    

    }

    function PlayGame()
    {

    // keep going until someone runs out of cards
    while(CardsOwned(0) > 0 && CardsOwned(1) > 0)
    {
    
        winner = PlayOneRound();
    } // someone has run out of cards
    
    console.log("The winner of the game is " + winner);
    

    }
    </script>

    <script type="text/javascript"> // jquery sheeeeeet $(document).ready(function() { SetUpNewGame(1); $("#OneRound").click(function(e) { winner = PlayOneRound(); }); }); </script> <style type='text/css'> .area, .card { min-height:180px; width:120px; display:block; border:1px solid black; border-radius:5px; } .area { background-color: grey; } .card { background-color:white; } .card.facedown { background-color:blue; } #playarea { position:relative; width:90%; margin-left:auto; margin-right:auto; } #battleground { background-color:orange; width:500px; margin-left:auto; margin-right:auto; position:relative; } .area.player, .area.stack { position:absolute; top:0px; } .area.p0 { left:0px; } .area.p1 { right:0px; } .card.latest { background-color:yellow !important; } .wins .card { position:relative; margin-top:-97%; z-index:99; } .wins .card.latest { margin-top:0px; z-index:9; } </style> </head> <body> <button id="OneRound">Play One Round</button>
    <div id="player0_area" class="area player p0">
        <div id="player0_area_deck" class="p0 area deck"></div>
        <div id="player0_area_wins" class="p0 area wins"></div>
    </div>
    
    <div id="battleground" class="area battleground">
        <div id="battleground_p0" class="area stack p0"></div>
        <div id="battleground_p1" class="area stack p1"></div>
    </div>
    
    <div id="player1_area" class="area player p1">
        <div id="player1_area_deck" class="p1 area deck"></div>
        <div id="player1_area_wins" class="p1 area wins"></div>
    </div>
    
    </body>


  • War?

    @Lorne_Kates said:

    turn it into a playable game.

    So make it something other than War.


  • Winner of the 2016 Presidential Election

    You might be doing this wrong on purpose but we have a "Programmers Testing"-Area for stuff like this, afaik.

    Filed Under: Then again, blakeyrat didn't boil you alive for posting this in a category he doesn't mute, so I guess all is well?



  • Oh I guess I didn't notice the category.

    Either way, making War into a "playable game" is an impossible Don Quixote-esque task. That was my point.


  • Winner of the 2016 Presidential Election

    He could just programm one of the milion browser versions of chess!

    Filed Under: Or shougi, or Settlers of Cathan, I guess? I don't really know that many board games even though I am German


  • Winner of the 2016 Presidential Election Banned

    @blakeyrat said:

    Either way, making War into a "playable game" is an impossible Don Quixote-esque task. That was my point.

    You see before you some 52 lawless cards with whom I mean to do battle. I shall deprive them of their lives, and with the spoils from this encounter, we shall begin to enrich ourselves.


  • Winner of the 2016 Presidential Election Banned

    Browser-based Pandemic would be cool.


  • Trolleybus Mechanic

    @blakeyrat said:

    So make it something other than War.

    That is the plan, eventually.

    @Kuro said:

    "Programmers Testing"-Area

    Categories are a :barrier: to Doing It Right. Feel free to Jeff the post if you need to.


  • Notification Spam Recipient

    @Lorne_Kates said:

    please don't rape it too much

    Considering it's a Wordpress site...

    @Lorne_Kates said:

    UI is shit
    What is this I don't even...

    @Lorne_Kates said:

    Has a button you can click
    Doesn't look like a cookie.

    @Lorne_Kates said:

    Mostly works
    After 719 iterations.... I won!


  • Trolleybus Mechanic

    Version 2.1
    -Added slightly less shit UI 💩
    -Refactoring to event driven to support eventual framework
    -Moved css to war.css because I felt like it ⭐
    -First stab at animation. It works, but need to use event framework to wait to move card off battlefield until after battle is done.

    War.html

        <html>
    <head>
    <link href="http://sevenseventeen.ca/war.css" rel="stylesheet"></link>
    
    <script src="http://sevenseventeen.ca/wp-includes/js/jquery/jquery.js" type="text/javascript"></script>
    <script src="http://sevenseventeen.ca/wp-includes/js/jquery/ui/jquery-ui.js" type="text/javascript"></script>
    <link href="http://sevenseventeen.ca/wp-includes/js/jquery/ui/jquery-ui.min.css" rel="stylesheet"></link>
    
    <script type="text/javascript">
    var $Universe = null;
    
    var decks = [];
    
    var wins = [];
    
    var kitty = [];
    var winner = 0;
    var battle = [];
    
    var suites = ["Hearts", "Spades", "Diamonds", "Clubs"];
    var ranks = {"Two" : 2, "Three" : 3, "Four" : 4, "Five" : 5, "Six" : 6, "Seven" : 7, "Eight" : 8, "Nine" : 9, "Ten" : 10, "Jack" : 11, "Queen" : 12, "King" : 13, "Ace": 14};
    var GameDeck = [];
    
    for(s = 0; s < suites.length; s++)
    {
        suit = suites[s];
    
        for(var rank in ranks)
        {
            card = {"Suit" : suit, "Rank" : rank, "Value" : ranks[rank]};
            GameDeck.push(card);
        }
    }
    
    
    function CreateCardElement(card)
    {
        var $card = $("<div></div>");
        $card.addClass("card");
        $card.addClass(card.Suit);
        $card.text(card.Rank + " " + card.Suit);
        $card.data("card", card);
    
        return $card;
    }
    
    // UI functions
    // TODO put visibility of card into card properties
    // player = 0 index id of player
    function PutCardOnBattleground(player, card)
    {
    
        var batleground_area = $("#battleground_p" + player);
        var cardui = CreateCardElement(card);
        batleground_area.append(cardui);
    }
    
    function SortByValue(c1, c2)
    {
        var a = $(c1).data("card").Value;
        var b = $(c2).data("card").Value;
        return a < b ? 1 : a > b ? -1 : 0;
    }
    
    // Collect all ventured cards into the winners Win pile
    function CollectWinnings(player)
    {
    
        var winnings = $(".battleground .area.stack .card");
        var wins = $("#player"+player+"_area_wins");
        var winpile = $("#player"+player+"_area_wins");
    
    
        wins.find(".card").removeClass("latest");
        winnings.addClass("latest");
        winnings.sort(SortByValue);
    
        winnings.each(function()
        {
            var opts = {};
    
            opts.from = $(this).parents(".battle:first");
            opts.to = winpile;
            opts.cardui = $(this);
            $Universe.trigger("MoveCard", opts);
        });
    
    }
    
    // Empty Win Pile UI
    function ClearWinsPile(player)
    {
        var winpile = document.getElementById("player"+player+"_area_wins");
        while(winpile.childNodes.length > 0)
        {
            winpile.removeChild(winpile.firstChild);
        }
    }
    
    // face down deck.  Clear anything in there, put face down card, and add counter
    function RefreshDeck(player)
    {
        var deck = document.getElementById("player"+player+"_area_deck");
        while(deck.childNodes.length > 0)
        {
            deck.removeChild(deck.firstChild);
        }
    
        var card = document.createElement("div");
        card.className = "card facedown";
        deck.appendChild(card);
    
        var cnt = document.createElement("div");
        card.appendChild(cnt);
        cnt.textContent = decks[player].length;
    
    }
    
    // End UI functions
    
    function shuffle(array)
    {
      var currentIndex = array.length, temporaryValue, randomIndex ;
    
      // While there remain elements to shuffle...
      while (0 !== currentIndex) {
    
        // Pick a remaining element...
        randomIndex = Math.floor(Math.random() * currentIndex);
        currentIndex -= 1;
    
        // And swap it with the current element.
        temporaryValue = array[currentIndex];
        array[currentIndex] = array[randomIndex];
        array[randomIndex] = temporaryValue;
      }
    
      return array;
    }
    
    
    
    
    
    // draw one card from deck IDX, return that card or null
    // when a deck runs out, reshuffle win pile into deck
    // if no cards remain in deck or win pile, returns null
    function draw(idx)
    {
        if(decks[idx].length == 0)
        {
            while(wins[idx].length > 0)
            {
                card = wins[idx].shift();
                decks[idx].push(card);
                ClearWinsPile(idx);
            }
    
            decks[idx] == shuffle(decks[idx]);
    
        }
    
        if(decks[idx].length > 0)
        {
            $Universe.trigger("CardExposed",
            {
                player: idx,
                card: decks[idx][0],
                from: $(".deck").eq(idx),
                to: $(".battle").eq(idx),
                facedown_from: false,
                facedown_to: true
            });
        }
    
        card = decks[idx].shift();
    
    
        RefreshDeck(idx);
    
        return card;
    } // end function draw
    
    function CardsOwned(player)
    {
        return decks[player].length + wins[player].length;
    }
    
    function DoWar(numcards)
    {
    
        winner = -1; // tie
    
        var PlayerDepleted = false;
        for(var i=0; i<=1; i++)
        {
            if(CardsOwned(i) == 0)
            {
                PlayerDepleted = true;
            }
        }
    
        if(PlayerDepleted)
        {
            // there is a player who cannot war no more.  The only way to resolve this is
            // First, who has the most rank values.
            // If still tied, who has the most cards.
            // If STILL tied, then both players are exactly where they were when they started.  Reshuffle everything and start again.
    
            console.log("Player " + i + " has run out of cards and cannot commit to war. Checking for armistice.");
            // someone has run out of cards, AND ended with a war
            // the winner of the game will be whoever has more cards
            for(var idx = 0; idx <= 1; idx++)
            {
                // move everything into the battle piles
                while(wins[idx].length > 0)
                {
                    card = wins[idx].shift();
                    battle[idx].push(card);
                    PutCardOnBattleground(idx, card);
                }
    
                while(decks[idx].length > 0)
                {
                    card = decks[idx].shift();
                    battle[idx].push(card);
                    PutCardOnBattleground(idx, card);
                }
    
                ClearWinsPile(idx);
                RefreshDeck(idx);
            }
    
            winner = -1; // tie
            // total up the values of the cards in the decks
            totals = [];
            totals[0] = 0;
            totals[1] = 0;
            for(var i = 0; i <=1; i++)
            {
                for(j = 0; j < battle[i].length; j++)
                {
                    totals[i] = totals[i] + battle[i][j].Value;
                }
    
            }
    
            // compare totals
            for(var i = 0; i <=1; i++)
            {
                console.log("Player " + i + " has " + totals[i] + " points in rank");
                up = i % 2;
                down = (i+1) % 2;
    
                if(totals[up] > totals[down])
                {
                    winner = up;
                }
            }
    
            console.log("A winner of the whole game is " + winner);
    
    
            if(winner < 0)
            {
                console.log("Players are tied in rank.  Checking by number of cards");
                // it is still a tie because both players have the same value of cards
                // go by number of cards
                for(var i = 0; i <=1; i++)
                {
                    console.log("Player " + i + " has " + battle[i].length + " cards");
                    up = i % 2;
                    down = (i+1) % 2;
    
                    if(battle[up].length > battle[down].length)
                    {
                        winner = up;
                    }
                }
            }
    
            console.log("A winner of the whole game is " + winner);
    
            if(winner < 0)
            {
                console.log("Players are equal in rank and cards. Putting all cards back into decks and starting again.");
                // OMFG both players have the same number of cards and the same total values.
                // just start the damn game again!
                SetupNewGame(1);
            }
    
            if(winner < 0)
            {
                // forget it. The universe has ended.
                throw new Exception("Forget it. The universe has ended");
            }
    
            return winner;
    
    
        } // end tiebreaker
    
        // Only venture as many cards as any one player has
        for(var i=0; i<=1; i++)
        {
            if(CardsOwned(i) < numcards)
            {
                console.log("Player " + i + " cannot venture " + numcards + " cards, so instead we'll do " + CardsOwned(i));
                numcards = CardsOwned(i);
            }
        }
    
        for(drawidx = 0; drawidx < numcards; drawidx++)
        {
    
            for(var i = 0; i <=1; i++)
            {
                // Each player adds a card to the top of the battlegrounds, to face off
                card = draw(i);
                battle[i].push(card);
                PutCardOnBattleground(i, card);
                RefreshDeck(i);
            }
        }
    
    
        // Check for the winner by comparing the top cards of the battleground to each other
        for(var i = 0; i <=1; i++)
        {
            up = i % 2;
            down = (i+1) % 2;
    
            if(battle[up][battle[up].length - 1].Value > battle[down][battle[down].length - 1].Value)
            {
                winner = up;
            }
        }
    
        if(winner < 0)
        {
            console.log("We're at war!");
            if(numcards > 1)
            {
                console.log("EXTRA WAR!!!");
            }
            // Oh shnit!  We have a tie. Let us settle it with W-A-R!!!!
            // a tie had occured. Oh noes!
            // W-A-R then flip 1
            winner = DoWar(4);
    
        } // end WAR
    
    
        return winner;
    } // end battle
    
    function PlayOneRound()
    {
        winner = -1;
    
    
    
    
        // Do the War function until there is a winner
        while(winner < 0)
        {
            winner = DoWar(1); // check the topmost card in each player battle pile, and the winner is returned, or -1 for a tie
    
        }
    
    
    
        // Move all cards from both Battlegrounds into the win pile of the winner (obj)
        for(var i = 0; i <=1; i++)
        {
            while(battle[i].length > 0)
            {
                wins[winner].push(battle[i].shift());
            }
        }
    
        // Move all the cards from the Battleground into the win pile of the winner (UI)
        CollectWinnings(winner);
    
        return winner;
    
    }
    
    function SetupBoard()
    {
        $(".cards").each(function(e)
        {
            var $this = $(this);
            $this.data("cards", []);
        });
    }
    
    function SetUpNewGame(numPlayersZeroIndex)
    {
        GameDeck = shuffle(GameDeck);
    
        for(var i = 0; i<= numPlayersZeroIndex; i++)
        {
            decks[i] = [];
            $("#player"+i+"_area_deck").data("cards", decks[i]);
    
            wins[i] = [];
            $("#player"+i+"_area_wins").data("cards", wins[i]);
    
            battle[i] = [];
            $("#battleground_p" + i).data("cards", battle[i]);
        }
    
        for(var i = 0; i < GameDeck.length; i++)
        {
            decks[i%(numPlayersZeroIndex + 1)].push(GameDeck[i]);
        }
    
    
        // set up deck UI
        for(var i = 0; i<= numPlayersZeroIndex; i++)
        {
    
            CollectWinnings(i);
            ClearWinsPile(i);
            RefreshDeck(i);
        }
    
    }
    
    function PlayGame()
    {
    
        // keep going until someone runs out of cards
        while(CardsOwned(0) > 0 && CardsOwned(1) > 0)
        {
    
            winner = PlayOneRound();
        } // someone has run out of cards
    
        console.log("The winner of the game is " + winner);
    
    
    }
    </script>
    
    <script type="text/javascript">
        // jquery sheeeeeet
        $(document).ready(function()
        {
            SetupBoard();
            SetUpNewGame(1);
    
            $Universe = $("#Universe");
    
            $("#OneRound").click(function(e)
            {
                $Universe.trigger("PlayOneRound");
            });
    
    
        });
    
        // Universe handlers
        $(document).ready(function()
        {
    
            $Universe.on("PlayOneRound", function(e)
            {
    
                // A round has been triggered.  Play it, then call On Complete
                $Universe.trigger("OnBeforePlayOneRound", e);
    
                winner = PlayOneRound();
    
                // draw
                //        might trigger shuffle
                // put on battle ground
                // compare
                // flash winner
                // move all cards to wins
    
    
                e.winner = winner;
    
                $Universe.trigger("OnAfterPlayOneRound", e);
            });
    
    
            // default round actions
            $Universe.on("OnBeforePlayOneRound", function(e)
            {
                // default action: disable action things
                $(".action").addClass("ui-state-disabled");
            });
    
            $Universe.on("OnAfterPlayOneRound", function(e)
            {
                // restore action buttons
                $(".action").removeClass("ui-state-disabled");
            });
    
            /*
                A card has been made public from this area.  See if card exists.  If not, create it.  Then draw it on this area
            */
            $Universe.on("CardExposed", function(e, opts)
            {
                // check from, and look through its data to see if card is in there
                var $FromUI = $(opts.from);
    
                if($FromUI != null && $FromUI.data("cards") != null)
                {
                    var cards = $FromUI.data("cards");
                    var card = null;
    
                    for(var idx = 0; idx < cards.length; idx++)
                    {
                        if(opts.card == cards[idx])
                        {
                            card = cards[idx];
                            idx = cards.length;
                        }
                    }
    
                    if(card == null)
                    {
                        // the card is not in this stack
                        opts.error = true;
                    }
                    else
                    {
                        $card = CreateCardElement(card);
                        $FromUI.append($card);
                    }
    
                }
    
                var new_opts = { after:null, cardui: $card};
                $.extend(new_opts, opts);
    
                if(opts.after != null && typeof(opts.after) === "function")
                {
    
                    opts.after(e, new_opts);
                }
                $Universe.trigger("MoveCard", new_opts);
    
    
            });
    
    /*
            player: idx,
            card: card,
            from: decks[idx],
            to: battle[idx],
            facedown_from: false,
            facedown_to: true
    */
            $Universe.on("MoveCard", function(e, opts)
            {
                // get the card from the target
                // expose it on the target
                // animate it to the other target
                var $card = $(opts.cardui);
                var $FromUI = $(opts.from);
                var $ToUI = $(opts.to);
                var top = $card.offset().top;
                var left = $card.offset().left;
                $card
                    .detach()
                    .appendTo("body")
                    .css("position", "absolute")
                    .css("top", top)
                    .css("left", left)
                    .animate
                    (
                        {
                            left:$ToUI.offset().left,
                            top:$ToUI.offset().top
                        },
                        "slow",
                        function()
                        {
                            $card.appendTo($ToUI);
                            $card.css("position", "static");
                        }
                    );
    
    
            });
    
        });
    
    </script>
    </head>
    <body>
    <div id="Universe">
        <div style="position:static;">
            <button id="OneRound" class="action">Play One Round</button>
        </div>
    
        <div id="playarea" class="" style="margin-top:2em;">
    
            <div id="player0_area" class="area player p0">
                <div id="player0_area_deck" class="p0 area deck cards"></div>
                <div id="player0_area_wins" class="p0 area wins cards"></div>
            </div>
    
            <div id="battleground" class="area battleground">
                <div id="battleground_p0" class="area stack battle p0 cards"></div>
                <div id="battleground_p1" class="area stack battle p1 cards"></div>
            </div>
    
            <div id="player1_area" class="area player p1">
                <div id="player1_area_deck" class="p1 area deck cards"></div>
                <div id="player1_area_wins" class="p1 area wins cards"></div>
            </div>
    
        </div>
    </div>
    </body>
    </html>
    

    War.css

        .area, .card
        {
            min-height:180px;
            width:120px;
            display:block;
            border:1px solid black;
            border-radius:5px;
        }
    
        .area
        {
            background-color: grey;
        }
    
        .card
        {
            background-color:white;
        }
    
        .card.facedown
        {
            background-color:blue;
        }
    
        #playarea
        {
            position:relative;
            width:90%;
            margin-left:auto;
            margin-right:auto;
        }
    
        #battleground
        {
            background-color:orange;
            width:500px;
            margin-left:auto;
            margin-right:auto;
            position:relative;
        }
    
        .area.player, .area.stack
        {
            position:absolute;
            top:0px;
        }
    
        .area.p0
        {
            left:0px;
        }
    
        .area.p1
        {
            right:0px;
        }
    
        .card.latest
        {
            background-color:yellow !important;
        }
    
        .wins .card
        {
            position:relative;
            margin-top:-97%;
            z-index:99;
        }
    
        .wins .card.latest
        {
            margin-top:0px;
            z-index:9;
        }
        
        body
        {
            overflow-x:hidden;
        }
    
    

  • Trolleybus Mechanic

    Version 2.65

    • Event driven framework is now way more functional. Need to add back in game-ending ties
    • Rudimentary animation that is only slightly 💩
    • Moar colours 🌈 🦄
    • Add "Play one card" button and "Play entire game" button
    • Speed factor present, will add slider in the future
    • Need to add "interrupt"
    • Shorterm goal: Add some sort of progress indicator to show who is winning (total cards owned vs. cards in deck)
    • Longterm goal: anything that is framework (move cards, compare stacks, etc) move into framework
    • Longterm goal: anything custom to the game-- abstract it, add it to framework, and implement in game
    • Shortterm goal: More fun matchups, such as Crushing Victory (Ace beats 2 gets extra card)
    • Shortterm goal: alt win conditions, such as World War III (3 WARS chained together result in next WAR ending game), and Royal Domination (insta win if you have all 4 suites of JQKA)

    War.html

    <html>
    <head>
    <link href="http://sevenseventeen.ca/war.css" rel="stylesheet"></link>
    
    <script src="http://sevenseventeen.ca/wp-includes/js/jquery/jquery.js" type="text/javascript"></script>
    <script src="http://sevenseventeen.ca/wp-includes/js/jquery/ui/jquery-ui.js" type="text/javascript"></script>
    <link href="http://sevenseventeen.ca/wp-includes/js/jquery/ui/jquery-ui.min.css" rel="stylesheet"></link>
    
    <script type="text/javascript">
    var SpeedFactor = 0.75;
    var $Universe = null;
    
    var decks = [];
    
    var wins = [];
    
    var kitty = [];
    var winner = 0;
    var battle = [];
    
    var suites = ["Hearts", "Spades", "Diamonds", "Clubs"];
    var ranks = {"Two" : 2, "Three" : 3, "Four" : 4, "Five" : 5, "Six" : 6, "Seven" : 7, "Eight" : 8, "Nine" : 9, "Ten" : 10, "Jack" : 11, "Queen" : 12, "King" : 13, "Ace": 14};
    var GameDeck = [];
    
    for(s = 0; s < suites.length; s++)
    {
        suit = suites[s];
    
        for(var rank in ranks)
        {
            card = {"Suit" : suit, "Rank" : rank, "Value" : ranks[rank]};
            GameDeck.push(card);
        }
    }
    
    
    function CreateCardElement(card)
    {
        var $card = $("<div></div>");
        $card.addClass("card");
        $card.addClass(card.Suit);
        $card.text(card.Rank + " " + card.Suit);
        $card.data("card", card);
    
        return $card;
    }
    
    // UI functions
    // TODO put visibility of card into card properties
    // player = 0 index id of player
    function PutCardOnBattleground(player, card)
    {
    
        var batleground_area = $("#battleground_p" + player);
        var cardui = CreateCardElement(card);
        batleground_area.append(cardui);
    }
    
    function SortByValue(a,b)
    {
        var c1=$(a).data("card").Value;
        var c2=$(b).data("card").Value;
        var ret = c1 < c2 ? 1 : c1 > c2 ? -1 : 0;
        return ret;
    }
    
    
    // Collect all ventured cards into the winners Win pile
    function CollectWinnings(player)
    {
    
        var winnings = $(".battle .card");
        var winpile = $("#player"+player+"_area_wins");
        var $Universe = $("#Universe");
    
    
        winpile.find(".card").removeClass("latest");
        winnings.addClass("latest");
    
    
        $Universe.on("MoveCardsCompleted", OnMoveCardsCompleted_SortWinnings);
        $Universe.on("MoveCardsCompleted", OnMoveCardsCompleted_ToWinPile);
    
    
        $(".battle").each(function()
        {
            var opts = {};
            opts.MoveAllCards = true;
            opts.from = $(this);
            opts.to = winpile;
            opts.prepend = true;
            $Universe.trigger("MoveCard", opts);
    
        });
    
    /*
        winnings.each(function()
        {
            var opts = {};
    
            opts.from = $(this).parents(".battle:first");
            opts.to = winpile;
            opts.prepend = true;
            opts.cardui = $(this);
            $Universe.trigger("MoveCard", opts);
        });
    */
    }
    
    function OnMoveCardsCompleted_SortWinnings(e, opts)
    {
        var $Universe = $("#Universe");
        $Universe.off("MoveCardsCompleted", OnMoveCardsCompleted_SortWinnings);
        for(var i = 0; i <= 1; i++)
        {
            var cards = $(".wins").eq(i).find(".card.latest");
            if(cards.length > 0)
            {
                cards
                    .detach()
                    .sort(SortByValue)
                    .prependTo($(".wins").eq(i));
            }
    
        }
    
    
    }
    
    // Empty Win Pile UI
    function ClearWinsPile(player)
    {
        var winpile = document.getElementById("player"+player+"_area_wins");
        while(winpile.childNodes.length > 0)
        {
            winpile.removeChild(winpile.firstChild);
        }
    }
    
    // face down deck.  Clear anything in there, put face down card, and add counter
    function RefreshDeck(player)
    {
        var deck = document.getElementById("player"+player+"_area_deck");
        while(deck.childNodes.length > 0)
        {
            deck.removeChild(deck.firstChild);
        }
    
        var card = document.createElement("div");
        card.className = "area facedown";
        deck.appendChild(card);
    
        var cnt = document.createElement("div");
        card.appendChild(cnt);
        cnt.textContent = decks[player].length;
    
    }
    
    // End UI functions
    
    function shuffle(array)
    {
      var currentIndex = array.length, temporaryValue, randomIndex ;
    
      // While there remain elements to shuffle...
      while (0 !== currentIndex) {
    
        // Pick a remaining element...
        randomIndex = Math.floor(Math.random() * currentIndex);
        currentIndex -= 1;
    
        // And swap it with the current element.
        temporaryValue = array[currentIndex];
        array[currentIndex] = array[randomIndex];
        array[randomIndex] = temporaryValue;
      }
    
      return array;
    }
    
    
    
    
    
    // draw one card from deck IDX, return that card or null
    // when a deck runs out, reshuffle win pile into deck
    // if no cards remain in deck or win pile, returns null
    function draw(idx)
    {
        if(decks[idx].length == 0)
        {
            while(wins[idx].length > 0)
            {
                card = wins[idx].shift();
                decks[idx].push(card);
                ClearWinsPile(idx);
            }
    
            decks[idx] == shuffle(decks[idx]);
    
        }
    
        card = decks[idx].shift();
    
    
        RefreshDeck(idx);
    
        return card;
    } // end function draw
    
    function CardsOwned(player)
    {
        return decks[player].length + wins[player].length;
    }
    
    function DoWar(numcards)
    {
    
        winner = -1; // tie
    
        var PlayerDepleted = false;
        for(var i=0; i<=1; i++)
        {
            if(CardsOwned(i) == 0)
            {
                PlayerDepleted = true;
            }
        }
    
        if(PlayerDepleted)
        {
            // there is a player who cannot war no more.  The only way to resolve this is
            // First, who has the most rank values.
            // If still tied, who has the most cards.
            // If STILL tied, then both players are exactly where they were when they started.  Reshuffle everything and start again.
    
            console.log("Player " + i + " has run out of cards and cannot commit to war. Checking for armistice.");
            // someone has run out of cards, AND ended with a war
            // the winner of the game will be whoever has more cards
            for(var idx = 0; idx <= 1; idx++)
            {
                // move everything into the battle piles
                while(wins[idx].length > 0)
                {
                    card = wins[idx].shift();
                    battle[idx].push(card);
                    PutCardOnBattleground(idx, card);
                }
    
                while(decks[idx].length > 0)
                {
                    card = decks[idx].shift();
                    battle[idx].push(card);
                    PutCardOnBattleground(idx, card);
                }
    
                ClearWinsPile(idx);
                RefreshDeck(idx);
            }
    
            winner = -1; // tie
            // total up the values of the cards in the decks
            totals = [];
            totals[0] = 0;
            totals[1] = 0;
            for(var i = 0; i <=1; i++)
            {
                for(j = 0; j < battle[i].length; j++)
                {
                    totals[i] = totals[i] + battle[i][j].Value;
                }
    
            }
    
            // compare totals
            for(var i = 0; i <=1; i++)
            {
                console.log("Player " + i + " has " + totals[i] + " points in rank");
                up = i % 2;
                down = (i+1) % 2;
    
                if(totals[up] > totals[down])
                {
                    winner = up;
                }
            }
    
            console.log("A winner of the whole game is " + winner);
    
    
            if(winner < 0)
            {
                console.log("Players are tied in rank.  Checking by number of cards");
                // it is still a tie because both players have the same value of cards
                // go by number of cards
                for(var i = 0; i <=1; i++)
                {
                    console.log("Player " + i + " has " + battle[i].length + " cards");
                    up = i % 2;
                    down = (i+1) % 2;
    
                    if(battle[up].length > battle[down].length)
                    {
                        winner = up;
                    }
                }
            }
    
            console.log("A winner of the whole game is " + winner);
    
            if(winner < 0)
            {
                console.log("Players are equal in rank and cards. Putting all cards back into decks and starting again.");
                // OMFG both players have the same number of cards and the same total values.
                // just start the damn game again!
                SetupNewGame(1);
            }
    
            if(winner < 0)
            {
                // forget it. The universe has ended.
                throw new Exception("Forget it. The universe has ended");
            }
    
            return winner;
    
    
        } // end tiebreaker
    
        // Only venture as many cards as any one player has
        for(var i=0; i<=1; i++)
        {
            if(CardsOwned(i) < numcards)
            {
                console.log("Player " + i + " cannot venture " + numcards + " cards, so instead we'll do " + CardsOwned(i));
                numcards = CardsOwned(i);
            }
        }
    
        for(drawidx = 0; drawidx < numcards; drawidx++)
        {
    
            for(var i = 0; i <=1; i++)
            {
                // Each player adds a card to the top of the battlegrounds, to face off
                card = draw(i);
                battle[i].push(card);
                PutCardOnBattleground(i, card);
                RefreshDeck(i);
            }
        }
    
    
        // Check for the winner by comparing the top cards of the battleground to each other
        for(var i = 0; i <=1; i++)
        {
            up = i % 2;
            down = (i+1) % 2;
    
            if(battle[up][battle[up].length - 1].Value > battle[down][battle[down].length - 1].Value)
            {
                winner = up;
            }
        }
    
        if(winner < 0)
        {
            console.log("We're at war!");
            if(numcards > 1)
            {
                console.log("EXTRA WAR!!!");
            }
            // Oh shnit!  We have a tie. Let us settle it with W-A-R!!!!
            // a tie had occured. Oh noes!
            // W-A-R then flip 1
            winner = DoWar(4);
    
        } // end WAR
    
    
        return winner;
    } // end battle
    
    function CheckCurrentBattleWinner(bottom)
    {
    
        var winner = -1;
        bottom = (bottom == null ? false : bottom);
    
        // Check for the winner by comparing the top cards of the battleground to each other
        for(var i = 0; i <=1; i++)
        {
            up = i % 2;
            down = (i+1) % 2;
    
            if(battle[up][bottom ? battle[up].length - 1 : 0].Value > battle[down][bottom ? battle[down].length - 1 : 0].Value)
            {
                winner = up;
            }
        }
    
        return winner;
    }
    
    function PlayOneRound(NumberOfCards)
    {
        // When we're done moving cards from the decks to the battleground, initiate the battle
        $Universe.on("MoveCardsCompleted", OnMoveCardsCompleted_ToBattleground);
    
        // Only venture as many cards as any one player has
        for(var i=0; i<=1; i++)
        {
            if(CardsOwned(i) < NumberOfCards)
            {
                console.log("Player " + i + " cannot venture " + NumberOfCards + " cards, so instead we'll do " + CardsOwned(i));
                NumberOfCards = CardsOwned(i);
            }
        }
    
        // Draw cards. Create UI for them. Move them.
        for(var i = 0; i<=1; i++)
        {
            var fromui = $(".deck").eq(i);
            var toui = $(".battle").eq(i);
    
            for(var cnt = 0; cnt < NumberOfCards; cnt++)
            {
                var card = draw(i);
                var cardui = CreateCardElement(card);
                fromui.append(cardui);
                var opts = {};
                opts.from = fromui;
                opts.to = toui;
                opts.prepend = true;
                opts.cardui = cardui;
                //opts.MoveAllCards = true;
                $Universe.trigger("MoveCard", opts);
    
            }
    
        }
    }
    
    function OnMoveCardsCompleted_ToBattleground()
    {
        // Stop listening
        // Probably better to do something like adding this listener to the UI target itself rather than the Universe
        $Universe.off("MoveCardsCompleted", OnMoveCardsCompleted_ToBattleground);
    
        winner = CheckCurrentBattleWinner();
    
        if(winner < 0)
        {
            var opts = {};
            opts.NumberOfCards = 4;
    
            Pulse($(".battle .card"), "ui-state-error", 3, PlayOneRound, 4);
    
        }
        else
        {
            Pulse($(".battle").eq(winner).find(".card"), "ui-state-default", 1, CollectWinnings, winner);
            //CollectWinnings(winner);
        }
    }
    
    function Pulse(elms, cssClass, numPulses, OnComplete, opts)
    {
        var $Universe = $("#Universe");
        var anim = 0;
        // flash the cards as a warning
        $(elms)
        .addClass(cssClass,
        {
            duration:250 * SpeedFactor,
            complete: function()
            {
                anim++;
                $(this).removeClass(cssClass,
                {
                    duration:250 * SpeedFactor,
                    complete:function()
                    {
                        anim--;
                        if(anim == 0)
                        {
                            if(numPulses <= 0)
                            {
                                OnComplete(opts);
                            }
                            else
                            {
                                numPulses = numPulses - 1;
                                Pulse(elms, cssClass, numPulses, OnComplete, opts);
                            }
                        }
    
                    }
                })
            }
        });
    
    }
    
    function OnMoveCardsCompleted_ToWinPile(e, opts)
    {
        $Universe.off("MoveCardsCompleted", OnMoveCardsCompleted_ToWinPile);
        $Universe.trigger("OnAfterPlayOneRound");
    }
    
    
    
    function SetupBoard()
    {
        $(".cards").each(function(e)
        {
            var $this = $(this);
            $this.data("cards", []);
        });
    }
    
    function SetUpNewGame(numPlayersZeroIndex)
    {
        GameDeck = shuffle(GameDeck);
    
        for(var i = 0; i<= numPlayersZeroIndex; i++)
        {
            decks[i] = [];
            $("#player"+i+"_area_deck").data("cards", decks[i]);
    
            wins[i] = [];
            $("#player"+i+"_area_wins").data("cards", wins[i]);
    
            battle[i] = [];
            $("#battleground_p" + i).data("cards", battle[i]);
        }
    
        for(var i = 0; i < GameDeck.length; i++)
        {
            decks[i%(numPlayersZeroIndex + 1)].push(GameDeck[i]);
        }
    
    
    
        // set up deck UI
        for(var i = 0; i<= numPlayersZeroIndex; i++)
        {
    
            ClearWinsPile(i);
            RefreshDeck(i);
        }
    
    }
    
    </script>
    
    <script type="text/javascript">
        // jquery sheeeeeet
        $(document).ready(function()
        {
            SetupBoard();
            SetUpNewGame(1);
    
            $Universe = $("#Universe");
            $Universe.data("cards_moving", 0);
    
            $("#OneRound").click(function(e)
            {
                var opts = {};
                opts.NumberOfCards = 1;
                $Universe.trigger("PlayOneRound", opts);
            });
    
            $("#AllRounds").click(function(e)
            {
                $("#Universe").on("OnAfterPlayOneRound", OnAfterPlayOneRound_AllRounds);
                var opts = {};
                opts.NumberOfCards = 1;
                $Universe.trigger("PlayOneRound", opts);
    
            });
    
            $("#PushTest").click(function(e)
            {
                for(var i=0;i<=1;i++)
                {
                    var card = {};
                    card.Value = 15;
                    card.Suit = "Hearts";
                    card.Rank = "Test";
                    decks[i].unshift(card);
                }
    
            });
    
    
        });
    
        function OnAfterPlayOneRound_AllRounds()
        {
            if(CardsOwned(0) > 0 && CardsOwned(1) > 0)
            {
                var opts = {};
                opts.NumberOfCards = 1;
                $Universe.trigger("PlayOneRound", opts);
    
            }
        }
    
        // Universe handlers
        $(document).ready(function()
        {
    
            $Universe.on("PlayOneRound", function(e, opts)
            {
                var defaults = {};
                defaults.NumberOfCards = 1;
                $.merge(defaults, opts);
                // A round has been triggered.  Play it, then call On Complete
                $Universe.trigger("OnBeforePlayOneRound", e);
    
                var NumberOfCards = opts.NumberOfCards;
    
                PlayOneRound(NumberOfCards);
    
            });
    
    
            // default round actions
            $Universe.on("OnBeforePlayOneRound", function(e)
            {
                // default action: disable action things
                $(".action").addClass("ui-state-disabled");
            });
    
            $Universe.on("OnAfterPlayOneRound", function(e)
            {
                // restore action buttons
                $(".action").removeClass("ui-state-disabled");
            });
    
    
    
    /*
            player: idx,
            card: card,
            from: decks[idx],
            to: battle[idx],
            facedown_from: false,
            facedown_to: true
    */
            $Universe.on("MoveCard", function(e, opts)
            {
                var defaults = {MoveAllCards : false};
                $.merge(opts, defaults);
    
                // get the card from the target
                // expose it on the target
                // animate it to the other target
                var $card = $(opts.cardui);
                var $FromUI = $(opts.from);
                var $ToUI = $(opts.to);
    
                var $LastCard = $FromUI.find(".card:last");
    
    
                if(opts.MoveAllCards)
                {
                    if($LastCard.length > 0)
                    {
                        $card = $LastCard;
                    }
                }
    
                var top = $FromUI.offset().top;
                var left = $FromUI.offset().left;
    
                var card = $card.data("card");
                var cards = $FromUI.data("cards");
    
                // remove the card from the target UI, if it exists
                if(cards != null && cards.indexOf(card) >= 0)
                {
                    cards.splice(cards.indexOf(card), 1);
                }
    
    
                $card
                    .detach()
                    .appendTo("body")
                    .css("position", "absolute")
                    .css("top", top)
                    .css("left", left)
                    .animate
                    (
                        {
                            left:$ToUI.offset().left,
                            top:$ToUI.offset().top
                        },
                        "slow",
                        function()
                        {
                            var newOpts = {};
                            $.extend(newOpts, opts);
                            newOpts.cardui = $card;
    
                            $Universe.trigger("MoveCardComplete", newOpts);
    
                            if(opts.MoveAllCards && $FromUI.find(".card").length > 0)
                            {
                                $Universe.trigger("MoveCard", opts);
                            }
                        }
                    );
            });
    
            $Universe.on("MoveCardComplete", function(e, opts)
            {
                var $card = $(opts.cardui);
                var $FromUI = $(opts.from);
                var $ToUI = $(opts.to);
                var card = $card.data("card");
                var cards = $ToUI.data("cards");
    
                if(opts.prepend)
                {
                    $card.prependTo($ToUI);
                    cards.unshift(card);
                }
                else
                {
                    $card.appendTo($ToUI);
                    cards.push(card);
                }
                $card.css("position", "static");
    
    
            });
    
            // Card in motion tracking
            $Universe.on("MoveCard", function(e, opts)
            {
                $Universe.data("cards_moving", $Universe.data("cards_moving") + 1);
            });
    
            $Universe.on("MoveCardComplete", function(e, opts)
            {
                $Universe.data("cards_moving", $Universe.data("cards_moving") - 1);
    
                // I have a feeling there's a better way to do this-- push all card moves onto a stack, then raise a Move Stack ready-- then raise a Move Stack Complete
                // Next iteration it is.  I'll live with the race condition for now.
                if($Universe.data("cards_moving") == 0)
                {
                    $Universe.trigger("MoveCardsCompleted");
                }
            });
    
    
        });
    
    </script>
    </head>
    <body>
    <div id="Universe">
        <div style="position:block;min-height:2em;">
            <div style="position:absolute;">
            <button id="OneRound" class="action">Play One Round</button>
            <button id="AllRounds" class="action">Play All</button>
            <button id="PushTest" class="action">Push Test Cards for Tie</button>
            </div>
        </div>
    
        <div id="playarea" class="" style="margin-top:2em;">
    
            <div id="player0_area" class="area player p0">
                <div id="player0_area_deck" class="p0 area deck cards stack"></div>
                <div id="player0_area_wins" class="p0 area wins cards stack"></div>
            </div>
    
            <div id="battleground" class="area battleground">
                <div id="battleground_p0" class="p0 area battle cards stack"></div>
                <div id="battleground_p1" class="p1 area battle cards stack"></div>
            </div>
    
            <div id="player1_area" class="area player p1">
                <div id="player1_area_deck" class="p1 area deck cards pile"></div>
                <div id="player1_area_wins" class="p1 area wins cards stack"></div>
            </div>
    
        </div>
    </div>
    </body>
    

    War.css

        body
        {
            overflow-x:hidden;
            background-color:#32CD32;
        }
    
        .area, .card
        {
            max-height:180px;
            height:100%;
            width:120px;
            display:block;
            border:1px solid black;
            border-radius:5px;
        }
    
        .area
        {
            background-color: grey;
        }
    
        .card
        {
            background-color:white;
            z-index:50000;
        }
    
        .card.facedown
        {
            background-color:blue;
        }
    
        
        #playarea
        {
            position:relative;
            width:90%;
            margin-left:auto;
            margin-right:auto;
        }
    
        #battleground
        {
            background-color:orange;
            width:500px;
            margin-left:auto;
            margin-right:auto;
            position:relative;
        }
    
        .area.player, .area.stack
        {
            position:absolute;
            top:0px;
        }
        
        .area.player
        {
            min-width:360px;
        }
        
        .area.player .pile, .area.player .stack, .battle
        {
            position:absolute;
        }
        
        
        .area.player.p0 .deck
        {
            left:0px;
            z-index:500;
        }
        
        .area.player.p0 .wins
        {
            right:0px;
            z-index:500;
        }
        
        .area.player.p1
        {
            right:0px;
        }
    
        .area.player.p1 .deck
        {
            position:absolute;
            right:0px !important;
            z-index:500;
            background-color:purple;
            
        }
        
        .area.player.p1 .wins
        {
            left:0px;
            z-index:501;
            background-color:purple;
        }
        
        .battleground .battle.p1
        {
            position:absolute;
            right:0px;
        }
    
        .card.latest
        {
            background-color:yellow !important;
        }
        
    
        /* Cards stacked so you can see the one underneath */    
        .stack .card
        {
            position:relative;
            margin-top:-160px;        
            z-index:999;
        }
        
        .stack .card:first-child
        {
            margin-top:0px;
        }
    
        /* Cards piled so you can't see what is underneath */
        .pile .card
        {
            position:relative;
            margin-top:-100%;
            z-index:999;
        }
        
        .pile .card:first-of-type
        {
            margin-top:0px;
        }
    
    
        
    
    


  • @blakeyrat said:

    Don Quixote-esque

    They have a word for that – it's "quixotic."



  • What variant of English pluralizes suit to suites? My decks come with 4 suits 😛


  • kills Dumbledore

    But what is it good for?


  • FoxDev

    @Jaloopa said:

    But what is it good for?

    Absolutely nothing, oh hoh, oh


  • Trolleybus Mechanic

    @accalia said:

    @Jaloopa said:
    But what is it good for?

    Absolutely nothing, oh hoh, oh

    Learning to make Javascript-enabled pages.

    So, your point is still 100% valid.


  • Trolleybus Mechanic

    @izzion said:

    What variant of English pluralizes suit to suites? My decks come with 4 suits 😛

    Spelling is for programmers. (CLOSED_WONT_FIX)[will fix in next iteration]


  • FoxDev

    @Lorne_Kates said:

    So, your point is still 100% valid.

    i had a point?

    i was just posting the next line of the lyrics....



  • I actually wrote a JS cards framework that was intended to take .js plug-in files and run them. For the cards, I used images I stole from the BOWEP card games.

    I might see if I still have that anywhere. I had a working Solitaire and a semi-completed BlackJack. War should be pretty easy, although the user interaction required is basically zero: just wait until they click so that the game's slow enough for them to see it.



  • I thought you meant you were going to use the XSS injection (probably patched now) to make the game playable right here.



  • PROTIP: when you make a joke that is actually slightly funny, DO NOT LATER EXPLAIN THE JOKE AND RUIN IT


  • FoxDev

    @blakeyrat said:

    PROTIP: when you make a joke that is actually slightly funny, DO NOT LATER EXPLAIN THE JOKE AND RUIN IT

    I'll remember that if i ever make a joke on purpose.


  • Notification Spam Recipient

    @blakeyrat said:

    PROTIP: when you make a joke that is actually slightly funny, DO NOT LATER EXPLAIN THE JOKE AND RUIN IT Ya probably weren't trying ta make a joke in tha first place!

    FTFY


  • Trolleybus Mechanic

    **Version 2.95.🌅 **

    • better UI still mostly 💩
    • Added "Crushing Defeat" on Ace vs. 2
    • Messaging system
    • alt victory conditions, but must signal game to stop
    • "Royal Capture" victory if you have JQK of all suites.
    • Reversed tie breaker. If both players have same total value of cards, then player with FEWER cards (more high value cards) wins.
    • MOAR EVENTS. Too many events? :doing_it_wrong:?
    • Add .TotalValue function to decks
    • MILESTONE REACHED: hit 32000 character limit to message. Will post the codez in next replies

  • Trolleybus Mechanic

    war.html

    <html>
    <head>
    <link href="http://sevenseventeen.ca/war.css" rel="stylesheet"></link>
    
    <script src="http://sevenseventeen.ca/wp-includes/js/jquery/jquery.js" type="text/javascript"></script>
    <script src="http://sevenseventeen.ca/wp-includes/js/jquery/ui/jquery-ui.js" type="text/javascript"></script>
    <link href="http://sevenseventeen.ca/wp-includes/js/jquery/ui/jquery-ui.min.css" rel="stylesheet"></link>
    
    <script type="text/javascript">
    // Assign to deck arrays
    function TotalValue()
    {
        var t = 0;
        for(var idx = 0; idx < this.length; idx++)
        {
            t += this[idx].Value;
        }
        return t;
    }
    
    function GetNewDeck()
    {
        var ret = [];
        ret.TotalValue = TotalValue;
    
        return ret;
    }
    
    var SpeedFactor = 0.6;
    var $Universe = null;
    
    var decks = [];
    
    var wins = [];
    
    var kitty = [];
    var winner = 0;
    var battle = [];
    
    var suites = ["Hearts", "Spades", "Diamonds", "Clubs"];
    var glyphs = ["&hearts;", "&spades;", "&diamond;", "&clubs;"];
    var ranks = {"Two" : 2, "Three" : 3, "Four" : 4, "Five" : 5, "Six" : 6, "Seven" : 7, "Eight" : 8, "Nine" : 9, "Ten" : 10, "Jack" : 11, "Queen" : 12, "King" : 13, "Ace": 14};
    var shorts = ["2", "3", "4", "5", "6", "7", "8", "9", "10", "J", "Q", "K", "A"];
    
    var GameDeck = GetNewDeck();
    
    for(s = 0; s < suites.length; s++)
    {
        suit = suites[s];
        var idx = 0;
        for(var rank in ranks)
        {
            card = {"Suit" : suit, "Rank" : rank, "Value" : ranks[rank], "Glyph" : glyphs[s], "Short" : shorts[idx]};
            GameDeck.push(card);
            idx++;
        }
    }
    
    
    function CreateCardElement(card)
    {
        var $card = $("<div></div>");
        $card.addClass("card");
        $card.addClass(card.Suit);
        var $text = $("<div></div>");
    
        if(card.Glyph != null)
        {
            $card.html(card.Short + "&nbsp;" + card.Glyph);
        }
        else
        {
            $card.html(card.Rank + "&nbsp;" + card.Suit);
    
        }
    
        //$card.append($text);
    
        $card.data("card", card);
    
        return $card;
    }
    
    // UI functions
    // TODO put visibility of card into card properties
    // player = 0 index id of player
    function PutCardOnBattleground(player, card)
    {
    
        var batleground_area = $("#battleground_p" + player);
        var cardui = CreateCardElement(card);
        batleground_area.append(cardui);
    }
    
    function SortByValue(a,b)
    {
        var c1=$(a).data("card").Value;
        var c2=$(b).data("card").Value;
        var ret = c1 < c2 ? 1 : c1 > c2 ? -1 : 0;
        return ret;
    }
    
    
    // Collect all ventured cards into the winners Win pile
    function CollectWinnings(player)
    {
    
        var winnings = $(".battle .card");
        var winpile = $("#player"+player+"_area_wins");
        var $Universe = $("#Universe");
    
    
        winpile.find(".card").removeClass("latest");
        winnings.addClass("latest");
    
    
        $Universe.on("MoveCardsCompleted", OnMoveCardsCompleted_SortWinnings);
        $Universe.on("MoveCardsCompleted", OnMoveCardsCompleted_ToWinPile);
    
    
        $(".battle").each(function()
        {
            var opts = {};
            opts.MoveAllCards = true;
            opts.from = $(this);
            opts.to = winpile;
            opts.prepend = true;
            $Universe.trigger("MoveCard", opts);
    
        });
    
    
    }
    
    function OnMoveCardsCompleted_SortWinnings(e, opts)
    {
        var $Universe = $("#Universe");
        $Universe.off("MoveCardsCompleted", OnMoveCardsCompleted_SortWinnings);
        for(var i = 0; i <= 1; i++)
        {
            var cards = $(".wins").eq(i).find(".card.latest");
            if(cards.length > 0)
            {
                cards
                    .detach()
                    .sort(SortByValue)
                    .prependTo($(".wins").eq(i));
            }
    
        }
    
    
    }
    
    // Empty Win Pile UI
    function ClearWinsPile(player)
    {
        var winpile = document.getElementById("player"+player+"_area_wins");
        while(winpile.childNodes.length > 0)
        {
            winpile.removeChild(winpile.firstChild);
        }
    }
    
    // face down deck.  Clear anything in there, put face down card, and add counter
    function RefreshDeck(player)
    {
        var deck = document.getElementById("player"+player+"_area_deck");
        while(deck.childNodes.length > 0)
        {
            deck.removeChild(deck.firstChild);
        }
    
        var card = document.createElement("div");
        card.className = "area facedown";
        deck.appendChild(card);
    
        var cnt = document.createElement("div");
        card.appendChild(cnt);
        cnt.textContent = decks[player].length;
    
    }
    
    // End UI functions
    
    function shuffle(array)
    {
      var currentIndex = array.length, temporaryValue, randomIndex ;
    
      // While there remain elements to shuffle...
      while (0 !== currentIndex) {
    
        // Pick a remaining element...
        randomIndex = Math.floor(Math.random() * currentIndex);
        currentIndex -= 1;
    
        // And swap it with the current element.
        temporaryValue = array[currentIndex];
        array[currentIndex] = array[randomIndex];
        array[randomIndex] = temporaryValue;
      }
    
      return array;
    }
    
    
    
    
    
    // draw one card from deck IDX, return that card or null
    // when a deck runs out, reshuffle win pile into deck
    // if no cards remain in deck or win pile, returns null
    function draw(idx)
    {
        if(decks[idx].length == 0)
        {
            while(wins[idx].length > 0)
            {
                card = wins[idx].shift();
                decks[idx].push(card);
                ClearWinsPile(idx);
            }
    
            decks[idx] == shuffle(decks[idx]);
    
        }
    
        card = decks[idx].shift();
    
    
        RefreshDeck(idx);
    
        return card;
    } // end function draw
    
    function CardsOwned(player)
    {
        return decks[player].length + wins[player].length;
    }
    
    
    
    function CheckCurrentBattleWinner(bottom)
    {
    
        var winner = -1;
        bottom = (bottom == null ? false : bottom);
    
        // Check for the winner by comparing the top cards of the battleground to each other
        for(var i = 0; i <=1; i++)
        {
            up = i % 2;
            down = (i+1) % 2;
    
            if(battle[up][bottom ? battle[up].length - 1 : 0].Value > battle[down][bottom ? battle[down].length - 1 : 0].Value)
            {
                winner = up;
            }
        }
    
    
    
        return winner;
    }
    
    function PlayOneRound(NumberOfCards)
    {
    
        var PlayerDepleted = false;
        var DepletedPlayer = -1;
        for(var i=0; i<=1; i++)
        {
            if(CardsOwned(i) == 0)
            {
                PlayerDepleted = true;
                DepletedPlayer = i;
            }
        }
    
        if(PlayerDepleted)
        {
            var opts = {};
            opts.message = "Player " + (DepletedPlayer+1) + " cannot commit to war. Checking for armistice.";
            opts.delay = 5000;
            $Universe.trigger("ShowMessage", opts);
            var card;
    
            $Universe.on("MoveCardsCompleted", OnMoveCardsCompleted_Armistice);
    
            // Move all cards onto the Battleground for final reckoning
            for(var i=0; i<=1; i++)
            {
                var fromui = $(".deck").eq(i);
                var toui = $(".battle").eq(i);
    
                card = draw(i);
                while(card != null)
                {
                    var cardui = CreateCardElement(card);
                    fromui.append(cardui);
                    var opts = {};
                    opts.from = fromui;
                    opts.to = toui;
                    opts.prepend = true;
                    opts.cardui = cardui;
                    $Universe.trigger("MoveCard", opts);
                    card = draw(i);
                }
            }
    
            return; // else if
        } // END PlayerDepleted
    
        // When we are done moving cards from the decks to the battleground, initiate the battle
        $Universe.on("MoveCardsCompleted", OnMoveCardsCompleted_ToBattleground);
    
        // Only venture as many cards as any one player has
        for(var i=0; i<=1; i++)
        {
            if(CardsOwned(i) < NumberOfCards)
            {
                console.log("Player " + i + " cannot venture " + NumberOfCards + " cards, so instead we'll do " + CardsOwned(i));
                NumberOfCards = CardsOwned(i);
            }
        }
    
        // Draw cards. Create UI for them. Move them.
        for(var i = 0; i<=1; i++)
        {
            var fromui = $(".deck").eq(i);
            var toui = $(".battle").eq(i);
    
            for(var cnt = 0; cnt < NumberOfCards; cnt++)
            {
                var card = draw(i);
                var cardui = CreateCardElement(card);
                fromui.append(cardui);
                var opts = {};
                opts.from = fromui;
                opts.to = toui;
                opts.prepend = true;
                opts.cardui = cardui;
                //opts.MoveAllCards = true;
                $Universe.trigger("MoveCard", opts);
    
            }
    
        }
    }
    
    function OnMoveCardsCompleted_Armistice(e, opts)
    {
        var $Universe = $("#Universe");
        $Universe.off("MoveCardsCompleted", OnMoveCardsCompleted_ToBattleground);
    
        // Check for alt victory conditions
        // there is a player who cannot war no more.  The only way to resolve this is
        // First, who has the most rank values.
        // If still tied, who has the most cards.
        // If STILL tied, then both players are exactly where they were when they started.  Reshuffle everything and start again.
    
    
        var winner = -1; // tie
        var gopts = {};
        // total up the values of the cards in the decks
        totals = [];
        totals[0] = 0;
        totals[1] = 0;
        for(var i = 0; i <=1; i++)
        {
            totals[i] = decks[i].TotalValue() + battle[i].TotalValue() + wins[i].TotalValue();
        }
    
        // compare totals
        for(var i = 0; i <=1; i++)
        {
    
            up = i % 2;
            down = (i+1) % 2;
    
            if(totals[up] > totals[down])
            {
                winner = up;
                gopts.winner = winner;
                gopts.message = totals[i] + " points in ranks";
    
            }
    
        }
    
        if(winner < 0)
        {
            var mopts = {};
            mopts.message = "Players are tied in rank. Checking number of high cards";
            $Universe.trigger("ShowMessage", mopts);
            // it is still a tie because both players have the same value of cards
            // go by number of cards
            for(var i = 0; i <=1; i++)
            {
                up = i % 2;
                down = (i+1) % 2;
    
                // having fewer cards is better, because you captured more of the high cards
                if(battle[up].length < battle[down].length)
                {
                    winner = up;
                    gopts.winner = winner;
                    gopts.message = " has " + battle[up].length + " cards";
                }
            }
        }
    
    
        if(winner < 0)
        {
            var mopts = {};
            mopts.message = "Still tied. Starting over.";
            $Universe.trigger("ShowMessage", mopts);
            $Universe.on("MoveCardsCompleted", OnMoveCardsCompleted_StartNewRound);
    
            for(var i=0; i<=1; i++)
            {
                var fromui = $(".battle").eq(i);
                var toui = $(".wins").eq(i);
                var opts = {};
                opts.MoveAllCards = true;
                opts.from = formui;
                opts.to = toui;
                opts.prepend = true;
                $Universe.trigger("MoveCard", opts);
    
            }
        } // restart game
        else
        {
            // trigger game over
    
            var opts = {};
            opts.keep = true;
            opts.message = "Player " + (winner + 1) + " wins!  " + gopts.message;
            $Universe.trigger("ShowMessage", opts);
            $Universe.trigger("GameOver");
        }
    
    
    }
    
    function OnMoveCardsCompleted_StartNewRound(e, opts)
    {
        var ropts = {};
        ropts.NumberOfCards = 1;
        $Universe.trigger("PlayOneRound", ropts);
    
    }
    
    function OnMoveCardsCompleted_ToBattleground()
    {
        // Stop listening
        // Probably better to do something like adding this listener to the UI target itself rather than the Universe
        var $Universe = $("#Universe");
        $Universe.off("MoveCardsCompleted", OnMoveCardsCompleted_ToBattleground);
    
        var winner = CheckCurrentBattleWinner();
    
        if(winner < 0)
        {
            var mopts = {};
            mopts.message = "W-A-R!";
            $Universe.trigger("ShowMessage", mopts);
            /* DO WAR */
            var opts = {};
            opts.NumberOfCards = 4;
    
            Pulse($(".battle .card"), "ui-state-error", 3, PlayOneRound, 4);
    
        }
        else
        {
            /* Check for extra points */
            var opts = {};
            opts.winner = winner;
            var $Universe = $("#Universe");
            $Universe.on("OnPostCheckWinner", OnPostCheckWinner_ExtraCards);
            $Universe.trigger("OnPostCheckWinner", opts);
    
    
        }
    }
    
    // After winner is determined, check for other things
    function OnPostCheckWinner_ExtraCards(e, opts)
    {
    
        var $Universe = $("#Universe");
        $Universe.off("OnPostCheckWinner", OnPostCheckWinner_ExtraCards);
        $Universe.on("MoveCardsCompleted", MoveCardsCompleted_CollectWinnings);
    
        var winner = opts.winner;
        var loser = ((winner + 1) % 2);
        var special = false;
    
        if(battle[winner].length > 0 && battle[loser].length > 0)
        {
            var WinningCard = battle[winner][battle[winner].length - 1];
            var LosingCard = battle[loser][battle[loser].length - 1];
    
            var newOpts = {};
    
            if(WinningCard.Value == 14 && LosingCard.Value == 2)
            {
                console.log("Crushing defeat!");
                var mopts = {message: "Crushing Defeat!"};
                $Universe.trigger("ShowMessage", mopts);
                card = draw(loser);
    
                newOpts.cardui = CreateCardElement(card);
                newOpts.from = $(".deck").eq(loser);
                newOpts.to = $(".battle").eq(loser);
                newOpts.winner = winner;
                newOpts.loser = loser;
                $Universe.trigger("MoveCard", newOpts);
                special = true;
            }
    
        }
    
        if(! special)
        {
            MoveCardsCompleted_CollectWinnings(null, opts);
        }
    
    }
    
    
    // Now collect winnings
    function MoveCardsCompleted_CollectWinnings(e, opts)
    {
        var $Universe = $("#Universe");
        $Universe.off("MoveCardsCompleted", MoveCardsCompleted_CollectWinnings);
        var winner = opts.winner;
        Pulse($(".battle").eq(winner).find(".card"), "ui-state-default", 1, CollectWinnings, winner);
    
    
    
    }
    
    function DoCollectWinnings(winner)
    {
    
    }
    
    
    
    function Pulse(elms, cssClass, numPulses, OnComplete, opts)
    {
        var $Universe = $("#Universe");
        var anim = 0;
        // flash the cards as a warning
        $(elms)
        .addClass(cssClass,
        {
            duration:250 * SpeedFactor,
            complete: function()
            {
                anim++;
                $(this).removeClass(cssClass,
                {
                    duration:250 * SpeedFactor,
                    complete:function()
                    {
                        anim--;
                        if(anim == 0)
                        {
                            if(numPulses <= 0)
                            {
                                OnComplete(opts);
                            }
                            else
                            {
                                numPulses = numPulses - 1;
                                Pulse(elms, cssClass, numPulses, OnComplete, opts);
                            }
                        }
    
                    }
                })
            }
        });
    
    }
    
    function OnMoveCardsCompleted_ToWinPile(e, opts)
    {
        $Universe.off("MoveCardsCompleted", OnMoveCardsCompleted_ToWinPile);
        $Universe.trigger("OnAfterPlayOneRound", opts);
    }
    
    
    
    function SetupBoard()
    {
        $(".cards").each(function(e)
        {
            var $this = $(this);
            $this.data("cards", GetNewDeck());
        });
    }
    
    function SetUpNewGame(numPlayersZeroIndex)
    {
        GameDeck = shuffle(GameDeck);
    
        for(var i = 0; i<= numPlayersZeroIndex; i++)
        {
            decks[i] = GetNewDeck();
            $("#player"+i+"_area_deck").data("cards", decks[i]);
    
            wins[i] = GetNewDeck();
            $("#player"+i+"_area_wins").data("cards", wins[i]);
    
            battle[i] = GetNewDeck();
            $("#battleground_p" + i).data("cards", battle[i]);
        }
    
        for(var i = 0; i < GameDeck.length; i++)
        {
            decks[i%(numPlayersZeroIndex + 1)].push(GameDeck[i]);
        }
    
    
    
        // set up deck UI
        for(var i = 0; i<= numPlayersZeroIndex; i++)
        {
    
            ClearWinsPile(i);
            RefreshDeck(i);
        }
    
    }
    
    </script>
    
    <script type="text/javascript">
        // jquery sheeeeeet
        $(document).ready(function()
        {
            $(".action").removeClass("ui-state-disabled").attr("disabled", false);
            SetupBoard();
            SetUpNewGame(1);
    
            $Universe = $("#Universe");
            $Universe.data("cards_moving", 0);
    
            $("#OneRound").click(function(e)
            {
                var opts = {};
                opts.NumberOfCards = 1;
                $Universe.trigger("PlayOneRound", opts);
            });
    
            $("#AllRounds").click(function(e)
            {
                $("#Universe").on("OnAfterPlayOneRound", OnAfterPlayOneRound_AllRounds);
                var opts = {};
                opts.NumberOfCards = 1;
                $Universe.trigger("PlayOneRound", opts);
    
            });
    
            $("#PushTest").click(function(e)
            {
                for(var i=0;i<=1;i++)
                {
                    var card = {};
                    card.Value = 15;
                    card.Suit = "Hearts";
                    card.Rank = "Test";
                    decks[i].unshift(card);
                }
    
            });
    
            $("#PushAceTwoTest").click(function(e)
            {
                var card = {};
                card.Value = 14;
                card.Suit = "Hearts";
                card.Rank = "Ace";
                decks[0].unshift(card);
    
                card = {};
                card.Value = 2;
                card.Suit = "Hearts";
                card.Rank = "Two";
                decks[1].unshift(card);
    
                RefreshDeck(0);
                RefreshDeck(1);
            });
    
            $("#SetupShortGame").click(function(e)
            {
                for(var i=0;i<=1;i++)
                {
                    while(decks[i].length > 1)
                    {
                        decks[i].shift();
                    }
    
                    RefreshDeck(i);
                }
    
    
            });
    
            $("#SetupArmisticeRank").click(function(e)
            {
                var card;
                var suit;
                for(var i=0;i<=1;i++)
                {
                    decks[i] = GetNewDeck();
                    var idx = 0;
                    for(var rank in ranks)
                    {
                        card = {"Suit" : suites[0], "Rank" : rank, "Value" : ranks[rank], "Glyph" : glyphs[0], "Short" : shorts[idx]};
                        if(idx < 7 && ( i==0 || (i==1 && idx < 2)))
                        {
                            decks[i].push(card);
                        }
                        idx++;
    
                    }
                    RefreshDeck(i);
    
                }
    
    
    
            });
    
            $("#SetupArmisticeCount").click(function(e)
            {
                var card;
                var suit;
                var lastcard;
    
                for(var i=0;i<=1;i++)
                {
                    decks[i] = GetNewDeck();
                    var idx = 0;
                    for(var rank in ranks)
                    {
                        card = {"Suit" : suites[0], "Rank" : rank, "Value" : ranks[rank], "Glyph" : glyphs[0], "Short" : shorts[idx]};
                        if(idx == 0)
                        {
                        lastcard = {"Suit" : suites[0], "Rank" : rank, "Value" : ranks[rank], "Glyph" : glyphs[0], "Short" : shorts[idx]};
    
                            // deck 1 gets 3 2s, deck 2 gets a 2 and a 4
                            decks[i].push(card);
    
                            if(i == 0)
                            {
                                card = {"Suit" : suites[0], "Rank" : rank, "Value" : ranks[rank], "Glyph" : glyphs[0], "Short" : shorts[idx]};
                                decks[i].push(card);
    
                                card = {"Suit" : suites[0], "Rank" : rank, "Value" : ranks[rank], "Glyph" : glyphs[0], "Short" : shorts[idx]};
                                decks[i].push(card);
    
                            }
                        }
                        else if (idx == 2 && i == 1)
                        {
                            // deck 2 gets one 4
                            decks[i].push(card);
                        }
    
                        idx++;
    
                    }
    
                    decks[i].push(lastcard);
    
    
                    RefreshDeck(i);
    
                }
    
            });
    
    
            $("#SetupRoyalDefeat").click(function(e)
            {
                decks[0] = GetNewDeck();
                decks[1] = GetNewDeck();
                var card;
                var suit;
    
                for(var s = 0; s < suites.length; s++)
                {
                    suit = suites[s];
                    var idx = 0;
                    for(var rank in ranks)
                    {
                        if(ranks[rank] >= 11 && ranks[rank] <= 14)
                        {
                            card = {"Suit" : suit, "Rank" : rank, "Value" : ranks[rank], "Glyph" : glyphs[s], "Short" : shorts[idx]};
                            decks[0].push(card);
                        }
                        idx++;
                    }
    
                }
    
                for(var s = 0; s < suites.length; s++)
                {
                    suit = suites[s];
                    var idx = 0;
                    for(var rank in ranks)
                    {
                        if(ranks[rank] < 11)
                        {
                            card = {"Suit" : suit, "Rank" : rank, "Value" : ranks[rank], "Glyph" : glyphs[s], "Short" : shorts[idx]};
                            decks[1].push(card);
                        }
                        idx++;
                    }
    
                }
    
                            RefreshDeck(0);
                RefreshDeck(1);
            });
    
    
        });
    
        function OnAfterPlayOneRound_AllRounds()
        {
            if(CardsOwned(0) > 0 && CardsOwned(1) > 0)
            {
                var opts = {};
                opts.NumberOfCards = 1;
                $Universe.trigger("PlayOneRound", opts);
    
            }
        }
    
        // Check for victory conditions
        function OnAfterPlayOneRound_CheckVictory(e, opts)
        {
            // If one player is out of cards, the other player automagically wins
            // TODO:  Also create a wordpress style call stack instead of events?
    
            var winner = -1;
            var winMessage = "";
            for(i=1; i<=1; i++)
            {
                // todo: show message without clearing
                if(CardsOwned(i) == 0)
                {
                    winner = ((i + 1) % 2);
                    winMessage = "Complete Domination!";
                }
            }
    
            for(i=0; i<=1; i++)
            {
                // Check to see if anyone has all royal families (J-K)
                var RoyalCount = 0;
                var card;
                for(var idx = 0; idx < decks[i].length; idx++)
                {
                    card = decks[i][idx];
    
                    if(card.Value >= 11 && card.Value <= 13)
                    {
                        RoyalCount = RoyalCount + 1;
                    }
                }
    
                for(var idx = 0; idx < wins[i].length; idx++)
                {
    
                    card = wins[i][idx];
    
                    if(card.Value >= 11 && card.Value <= 13)
                    {
                        RoyalCount = RoyalCount + 1;
                    }
                }
    
                if(RoyalCount == 12)
                {
                    winner = i;
                    winMessage = "Royal Capture";
                }
            }
    
            if (winner >= 0)
            {
                var opts = {};
                opts.keep = true;
                opts.message = "Player " + (winner + 1) + " wins!  " + winMessage
                $Universe.trigger("ShowMessage", opts);
                $Universe.trigger("GameOver");
            }
    
        }
    
        // Universe handlers
        $(document).ready(function()
        {
            $Universe.on("OnAfterPlayOneRound", OnAfterPlayOneRound_CheckVictory);
    
            $Universe.on("PlayOneRound", function(e, opts)
            {
                var defaults = {};
                defaults.NumberOfCards = 1;
                $.merge(defaults, opts);
                // A round has been triggered.  Play it, then call On Complete
                $Universe.trigger("OnBeforePlayOneRound", e);
    
                var NumberOfCards = opts.NumberOfCards;
    
                PlayOneRound(NumberOfCards);
    
            });
    
    
            // default round actions
            $Universe.on("OnBeforePlayOneRound", function(e)
            {
                // default action: disable action things
                $(".action").addClass("ui-state-disabled");
            });
    
            $Universe.on("OnAfterPlayOneRound", function(e)
            {
                // restore action buttons
                $(".action").removeClass("ui-state-disabled");
            });
    
    
    
    /*
            player: idx,
            card: card,
            from: decks[idx],
            to: battle[idx],
            facedown_from: false,
            facedown_to: true
    */
            $Universe.on("MoveCard", function(e, opts)
            {
                var defaults = {MoveAllCards : false};
                $.merge(opts, defaults);
    
                // get the card from the target
                // expose it on the target
                // animate it to the other target
                var $card = $(opts.cardui);
                var $FromUI = $(opts.from);
                var $ToUI = $(opts.to);
    
                var $LastCard = $FromUI.find(".card:last");
    
    
                if(opts.MoveAllCards)
                {
                    if($LastCard.length > 0)
                    {
                        $card = $LastCard;
                    }
                }
    
                var top = $FromUI.offset().top;
                var left = $FromUI.offset().left;
    
                var card = $card.data("card");
                var cards = $FromUI.data("cards");
    
                // remove the card from the target UI, if it exists
                if(cards != null && cards.indexOf(card) >= 0)
                {
                    cards.splice(cards.indexOf(card), 1);
                }
    
    
                $card
                    .detach()
                    .appendTo("body")
                    .css("position", "absolute")
                    .css("top", top)
                    .css("left", left)
                    .animate
                    (
                        {
                            left:$ToUI.offset().left,
                            top:$ToUI.offset().top
                        },
                        "slow",
                        function()
                        {
                            var newOpts = {};
                            $.extend(newOpts, opts);
                            newOpts.cardui = $card;
    
                            $Universe.trigger("MoveCardComplete", newOpts);
    
                            if(opts.MoveAllCards && $FromUI.find(".card").length > 0)
                            {
                                $Universe.trigger("MoveCard", opts);
                            }
                        }
                    );
            });
    
    
            $Universe.on("MoveCardComplete", function(e, opts)
            {
                var $card = $(opts.cardui);
                var $FromUI = $(opts.from);
                var $ToUI = $(opts.to);
                var card = $card.data("card");
                var cards = $ToUI.data("cards");
    
                if(opts.prepend)
                {
                    $card.prependTo($ToUI);
                    cards.unshift(card);
                }
                else
                {
                    $card.appendTo($ToUI);
                    cards.push(card);
                }
                $card.css("position", "static");
    
    
            });
    
            // Card in motion tracking
            $Universe.on("MoveCard", function(e, opts)
            {
                $Universe.data("cards_moving", $Universe.data("cards_moving") + 1);
            });
    
            $Universe.on("MoveCardComplete", function(e, opts)
            {
                $Universe.data("cards_moving", $Universe.data("cards_moving") - 1);
    
                // I have a feeling there's a better way to do this-- push all card moves onto a stack, then raise a Move Stack ready-- then raise a Move Stack Complete
                // Next iteration it is.  I'll live with the race condition for now.
                if($Universe.data("cards_moving") == 0)
                {
                    $Universe.trigger("MoveCardsCompleted", opts);
                }
            });
    
            var MessageBuffer = [];
            var MessageMutex = null;
    
            $Universe.on("ShowMessage", function(e, opts)
            {
                // Put message into stack
                MessageBuffer.push(opts);
    
                // Try to show the message
                TryShowMessage(opts);
            });
    
            function TryShowMessage(opts)
            {
                // if my message is the first one, show it
                // otherwise HideMessage will be responsible for showing the next one
                if(MessageBuffer.length > 0 && MessageBuffer[0] == opts)
                {
                    // remove from buffer
                    var opts = MessageBuffer[0];
                    var defaults = {delay:2000, speed:"fast"};
                    $.extend(opts, defaults);
    
    
                    if(opts.message != null)
                    {
                        var Message = opts.message;
                        var $Message = $("#Message");
                        var $MessageText = $("<div></div>");
                        $MessageText.text(Message);
                        $MessageText.addClass("message-text");
                        $MessageText.css("position", "absolute");
    
                        $MessageText.css("left", $Message.width());
                        $Message.append($MessageText);
                        $MessageText.width($Message.width())
                        $MessageText.animate
                        (
                            {left: 0},
                            opts.speed,
                            function()
                            {
                                if(! opts.keep)
                                {
                                    var hopts = {};
                                    $.extend(hopts, opts);
                                    hopts.ui = $(this);
    
                                    setTimeout(function(){$Universe.trigger("HideMessage", hopts)}, opts.delay);
                                }
                            }
                        );
    
                    }
                }
    
            } // try show message
    
            $Universe.on("HideMessage", function(e, opts)
            {
                var defaults = {delay:2000, speed:"fast"};
                $.extend(opts, defaults);
    
                var $ui = opts.ui;
                var $Message = $("#Message");
                $ui.animate
                (
                    {left: $Message.width() * - 1.2},
                    opts.speed,
                    function()
                    {
                        $(this).detach();
                        // get rid of message from queue
                        MessageBuffer.shift();
    
                        // Try to show the next message
                        if(MessageBuffer.length > 0)
                        {
                            TryShowMessage(MessageBuffer[0]);
                        }
                    }
                );
            });
    
            $Universe.on("GameOver", function(e, opts)
            {
                $(".action").attr("disabled", true).addClass("ui-state-disabled");
                // Stop the game, but how?
    
            });
    
    
        });
    
    </script>
    </head>
    <body>
    <div id="Universe">
    
        <div style="position:block;min-height:2em;">
            <div style="position:absolute;">
            <button id="OneRound" class="action">Play One Round</button>
            <button id="AllRounds" class="action">Play All</button>
            <button id="PushTest" class="action">Push Test Cards for Tie</button>
            <button id="PushAceTwoTest" class="action">Push Ace Two Cards for Tie</button>
            <button id="SetupRoyalDefeat" class="action">Royal Defeat Decks</button>
            <button id="SetupShortGame" class="action">Short Game</button>
            <button id="SetupArmisticeRank" class="action">Armistice Rank</button>
            <button id="SetupArmisticeCount" class="action">Armistice Count</button>
    
    
    
            </div>
        </div>
    
        <div id="MessageWrap" style='width:100%;height:2em;'>
            <div id="Message">
    
            </div>
        </div>
    
        <div id="playarea" class="" style="margin-top:2em;">
    
            <div id="player0_area" class="area player p0">
                <div id="player0_area_deck" class="p0 area deck cards stack"></div>
                <div id="player0_area_wins" class="p0 area wins cards stack"></div>
            </div>
    
            <div id="battleground" class="area battleground">
                <div id="battleground_p0" class="p0 area battle cards stack"></div>
                <div id="battleground_p1" class="p1 area battle cards stack"></div>
            </div>
    
            <div id="player1_area" class="area player p1">
                <div id="player1_area_deck" class="p1 area deck cards pile"></div>
                <div id="player1_area_wins" class="p1 area wins cards stack"></div>
            </div>
    
        </div>
    </div>
    </body>
    

  • Trolleybus Mechanic

    War.css

        body
        {
            overflow-x:hidden;
            background-color:#32CD32;
        }
    
        .area, .card
        {
            max-height:180px;
            height:100%;
            width:120px;
            display:block;
            border:1px solid black;
            border-radius:5px;
        }
    
        .area
        {
            background-color: grey;
        }
    
        .card
        {
            background-color:white;
            z-index:50000;
            font-size:1.1em;
        }
        
        .card.Hearts, .card.Diamonds
        {
            color: red !important;
        }
        
        .card.Clubs, .card.Spades
        {
            color:black;
        }
        
        .card div
        {
            background-color:white;
        }
    
        .card.facedown
        {
            background-color:blue;
        }
    
        
        #playarea
        {
            position:relative;
            width:90%;
            margin-left:auto;
            margin-right:auto;
        }
    
        #battleground
        {
            background-color:orange;
            width:500px;
            margin-left:auto;
            margin-right:auto;
            position:relative;
        }
    
        .area.player, .area.stack
        {
            position:absolute;
            top:0px;
        }
        
        .area.player
        {
            min-width:360px;
        }
        
        .area.player .pile, .area.player .stack, .battle
        {
            position:absolute;
        }
        
        
        .area.player.p0 .deck
        {
            left:0px;
            z-index:500;
        }
        
        .area.player.p0 .wins
        {
            right:0px;
            z-index:500;
        }
        
        .area.player.p1
        {
            right:0px;
        }
    
        .area.player.p1 .deck
        {
            position:absolute;
            right:0px !important;
            z-index:500;
            background-color:purple;
            
        }
        
        .area.player.p1 .wins
        {
            left:0px;
            z-index:501;
            background-color:purple;
        }
        
        .battleground .battle.p1
        {
            position:absolute;
            right:0px;
        }
    
        .card.latest
        {
            background-color:yellow !important;
        }
        
    
        /* Cards stacked so you can see the one underneath */    
        .stack .card
        {
            position:relative;
            margin-top:-150px;        
            z-index:999;
        }
        
        .stack .card:first-child
        {
            margin-top:0px;
        }
    
        /* Cards piled so you can't see what is underneath */
        .pile .card
        {
            position:relative;
            margin-top:-100%;
            z-index:999;
        }
        
        .pile .card:first-of-type
        {
            margin-top:0px;
        }
    
        #Message
        {
            overflow:hidden;
            position:relative;
            min-height:1.5em;
            width:30%;
            margin-left:auto;
            margin-right:auto;
            border:1px solid black;
            background-color:white;
            border-radius:5px;
            text-align:center;
            font-family:arial;
            padding:0.5em;
        }
        .message-text
        {
            background-color:white;
            
        }
        
    
    

  • kills Dumbledore

    @accalia said:

    I'll remember that if i ever make a joke on purpose

    that sounds like an admission that everything that looks like a joke from you is a whoosh...


  • FoxDev

    @Jaloopa said:

    @accalia said:
    I'll remember that if i ever make a joke on purpose

    that sounds like an admission that everything that looks like a joke from you is a whoosh...


  • Trolleybus Mechanic

    Version 3.III.Three.piggy

    • Fixed Royal Capture victory condition by hacking in GameOver attribute to Universe
    • Royal Capture shows cards to prove it (but that is also broken)
    • No change in UI. Same level of 💩 as before
    • Added WWIII endgame-- the third chained WAR will trigger a climactic showdown that determines the winner of the game. It doesn't work quite right, and may freeze your browser. Push the test button at your own risk.
    • Need to add better "MoveCard" code, so that data can be passed (array, card object) instead of UI elements (UI of deck, card UI). Need to decide exactly how I want data layer and UI layer to interact. I'd like all commands and shit to be handled at the data/object layer, which then bubble up events for the UI to handle. That way the data layer can act independently of the UI layer (for bots and replays).
    • Next next goal will be codifying the rules engine, so that the game can be defined as a script that grafts onto the engine.

    Teh Codez to follow


  • Trolleybus Mechanic

    War.html (part 1)

    <html>
    <head>
    <link href="http://sevenseventeen.ca/war.css" rel="stylesheet"></link>
    
    <script src="http://sevenseventeen.ca/wp-includes/js/jquery/jquery.js" type="text/javascript"></script>
    <script src="http://sevenseventeen.ca/wp-includes/js/jquery/ui/jquery-ui.js" type="text/javascript"></script>
    <link href="http://sevenseventeen.ca/wp-includes/js/jquery/ui/jquery-ui.min.css" rel="stylesheet"></link>
    
    <script type="text/javascript">
    // Assign to deck arrays
    function TotalValue()
    {
        var t = 0;
        for(var idx = 0; idx < this.length; idx++)
        {
            t += this[idx].Value;
        }
        return t;
    }
    
    function GetNewDeck()
    {
        var ret = [];
        ret.TotalValue = TotalValue;
    
        return ret;
    }
    
    var SpeedFactor = 0.6;
    var $Universe = null;
    
    var decks = [];
    
    var wins = [];
    
    var winner = 0;
    var battle = [];
    
    var suites = ["Hearts", "Spades", "Diamonds", "Clubs"];
    var glyphs = ["&hearts;", "&spades;", "&diamond;", "&clubs;"];
    var ranks = {"Two" : 2, "Three" : 3, "Four" : 4, "Five" : 5, "Six" : 6, "Seven" : 7, "Eight" : 8, "Nine" : 9, "Ten" : 10, "Jack" : 11, "Queen" : 12, "King" : 13, "Ace": 14};
    var shorts = ["2", "3", "4", "5", "6", "7", "8", "9", "10", "J", "Q", "K", "A"];
    
    var GameDeck = GetNewDeck();
    
    for(s = 0; s < suites.length; s++)
    {
        suit = suites[s];
        var idx = 0;
        for(var rank in ranks)
        {
            card = {"Suit" : suit, "Rank" : rank, "Value" : ranks[rank], "Glyph" : glyphs[s], "Short" : shorts[idx]};
            GameDeck.push(card);
            idx++;
        }
    }
    
    
    function CreateCardElement(card)
    {
        var $card = $("<div></div>");
        $card.addClass("card");
        $card.addClass(card.Suit);
        var $text = $("<div></div>");
    
        if(card.Glyph != null)
        {
            $card.html(card.Short + "&nbsp;" + card.Glyph);
        }
        else
        {
            $card.html(card.Rank + "&nbsp;" + card.Suit);
    
        }
    
        //$card.append($text);
    
        $card.data("card", card);
    
        return $card;
    }
    
    // UI functions
    // TODO put visibility of card into card properties
    // player = 0 index id of player
    function SortByValue(a,b)
    {
        var c1=$(a).data("card").Value;
        var c2=$(b).data("card").Value;
        var ret = c1 < c2 ? 1 : c1 > c2 ? -1 : 0;
        return ret;
    }
    
    
    // Collect all ventured cards into the winners Win pile
    function CollectWinnings(player)
    {
    
        var winnings = $(".battle .card");
        var winpile = $("#player"+player+"_area_wins");
        var $Universe = $("#Universe");
    
    
        winpile.find(".card").removeClass("latest");
        winnings.addClass("latest");
    
    
        $Universe.on("MoveCardsCompleted", OnMoveCardsCompleted_SortWinnings);
        $Universe.on("MoveCardsCompleted", OnMoveCardsCompleted_ToWinPile);
    
    
        $(".battle").each(function()
        {
            var opts = {};
            opts.MoveAllCards = true;
            opts.from = $(this);
            opts.to = winpile;
            opts.prepend = true;
            $Universe.trigger("MoveCard", opts);
    
        });
    
    
    }
    
    function OnMoveCardsCompleted_SortWinnings(e, opts)
    {
        var $Universe = $("#Universe");
        $Universe.off("MoveCardsCompleted", OnMoveCardsCompleted_SortWinnings);
        for(var i = 0; i <= 1; i++)
        {
            var cards = $(".wins").eq(i).find(".card.latest");
            if(cards.length > 0)
            {
                cards
                    .detach()
                    .sort(SortByValue)
                    .prependTo($(".wins").eq(i));
            }
    
        }
    
    
    }
    
    // Empty Win Pile UI
    function ClearWinsPile(player)
    {
        var winpile = document.getElementById("player"+player+"_area_wins");
        while(winpile.childNodes.length > 0)
        {
            winpile.removeChild(winpile.firstChild);
        }
    }
    
    // face down deck.  Clear anything in there, put face down card, and add counter
    function RefreshDeck(player)
    {
        var deck = document.getElementById("player"+player+"_area_deck");
        while(deck.childNodes.length > 0)
        {
            deck.removeChild(deck.firstChild);
        }
    
        var card = document.createElement("div");
        card.className = "area facedown";
        deck.appendChild(card);
    
        var cnt = document.createElement("div");
        card.appendChild(cnt);
        cnt.textContent = decks[player].length;
    
    }
    
    // End UI functions
    
    function shuffle(array)
    {
      var currentIndex = array.length, temporaryValue, randomIndex ;
    
      // While there remain elements to shuffle...
      while (0 !== currentIndex) {
    
        // Pick a remaining element...
        randomIndex = Math.floor(Math.random() * currentIndex);
        currentIndex -= 1;
    
        // And swap it with the current element.
        temporaryValue = array[currentIndex];
        array[currentIndex] = array[randomIndex];
        array[randomIndex] = temporaryValue;
      }
    
      return array;
    }
    
    
    
    
    
    // draw one card from deck IDX, return that card or null
    // when a deck runs out, reshuffle win pile into deck
    // if no cards remain in deck or win pile, returns null
    function draw(idx)
    {
        if(decks[idx].length == 0)
        {
            while(wins[idx].length > 0)
            {
                card = wins[idx].shift();
                decks[idx].push(card);
                ClearWinsPile(idx);
            }
    
            decks[idx] == shuffle(decks[idx]);
    
        }
    
        card = decks[idx].shift();
    
    
        RefreshDeck(idx);
    
        return card;
    } // end function draw
    
    function CardsOwned(player)
    {
        return decks[player].length + wins[player].length;
    }
    
    
    
    function CheckCurrentBattleWinner(bottom)
    {
    
        var winner = -1;
        bottom = (bottom == null ? false : bottom);
    
        // Check for the winner by comparing the top cards of the battleground to each other
        for(var i = 0; i <=1; i++)
        {
            up = i % 2;
            down = (i+1) % 2;
    
            if(battle[up][bottom ? battle[up].length - 1 : 0].Value > battle[down][bottom ? battle[down].length - 1 : 0].Value)
            {
                winner = up;
            }
        }
    
    
    
        return winner;
    }
    
    function PlayOneRound(NumberOfCards)
    {
    
        var PlayerDepleted = false;
        var DepletedPlayer = -1;
        for(var i=0; i<=1; i++)
        {
            if(CardsOwned(i) == 0)
            {
                PlayerDepleted = true;
                DepletedPlayer = i;
            }
        }
    
        if(PlayerDepleted)
        {
            var opts = {};
            opts.message = "Player " + (DepletedPlayer+1) + " cannot commit to war. Checking for armistice.";
            opts.delay = 5000;
            $Universe.trigger("ShowMessage", opts);
            var card;
    
            $Universe.on("MoveCardsCompleted", OnMoveCardsCompleted_Armistice);
    
            // Move all cards onto the Battleground for final reckoning
            for(var i=0; i<=1; i++)
            {
                var fromui = $(".deck").eq(i);
                var toui = $(".battle").eq(i);
    
                card = draw(i);
                while(card != null)
                {
                    var cardui = CreateCardElement(card);
                    fromui.append(cardui);
                    var opts = {};
                    opts.from = fromui;
                    opts.to = toui;
                    opts.prepend = true;
                    opts.cardui = cardui;
                    $Universe.trigger("MoveCard", opts);
                    card = draw(i);
                }
            }
    
            return; // else if
        } // END PlayerDepleted
    
        // When we are done moving cards from the decks to the battleground, initiate the battle
        $Universe.on("MoveCardsCompleted", OnMoveCardsCompleted_ToBattleground);
    
        // Only venture as many cards as any one player has
        for(var i=0; i<=1; i++)
        {
            if(CardsOwned(i) < NumberOfCards)
            {
                var mopts = "Player " + (i+1) + " only has " + NumberOfCards + " cards";
                $Universe.trigger("ShowMessage", mopts);
                NumberOfCards = CardsOwned(i);
            }
        }
    
        // Draw cards. Create UI for them. Move them.
        for(var i = 0; i<=1; i++)
        {
            var fromui = $(".deck").eq(i);
            var toui = $(".battle").eq(i);
    
            for(var cnt = 0; cnt < NumberOfCards; cnt++)
            {
                var card = draw(i);
                var cardui = CreateCardElement(card);
                fromui.append(cardui);
                var opts = {};
                opts.from = fromui;
                opts.to = toui;
                opts.prepend = true;
                opts.cardui = cardui;
                //opts.MoveAllCards = true;
                $Universe.trigger("MoveCard", opts);
    
            }
    
        }
    }
    
    function OnMoveCardsCompleted_Armistice(e, opts)
    {
        var $Universe = $("#Universe");
        $Universe.off("MoveCardsCompleted", OnMoveCardsCompleted_ToBattleground);
    
        // Check for alt victory conditions
        // there is a player who cannot war no more.  The only way to resolve this is
        // First, who has the most rank values.
        // If still tied, who has the most cards.
        // If STILL tied, then both players are exactly where they were when they started.  Reshuffle everything and start again.
    
    
        var winner = -1; // tie
        var gopts = {};
        // total up the values of the cards in the decks
        totals = [];
        totals[0] = 0;
        totals[1] = 0;
        for(var i = 0; i <=1; i++)
        {
            totals[i] = decks[i].TotalValue() + battle[i].TotalValue() + wins[i].TotalValue();
        }
    
        // compare totals
        for(var i = 0; i <=1; i++)
        {
    
            up = i % 2;
            down = (i+1) % 2;
    
            if(totals[up] > totals[down])
            {
                winner = up;
                gopts.winner = winner;
                gopts.message = totals[i] + " points in ranks";
    
            }
    
        }
    
        if(winner < 0)
        {
            var mopts = {};
            mopts.message = "Tied in rank. Checking number of high cards";
            $Universe.trigger("ShowMessage", mopts);
            // it is still a tie because both players have the same value of cards
            // go by number of cards
            for(var i = 0; i <=1; i++)
            {
                up = i % 2;
                down = (i+1) % 2;
    
                // having fewer cards is better, because you captured more of the high cards
                if(battle[up].length < battle[down].length)
                {
                    winner = up;
                    gopts.winner = winner;
                    gopts.message = " has " + battle[up].length + " cards";
                }
            }
        }
    
    
        if(winner < 0)
        {
            var mopts = {};
            mopts.message = "Still tied. Starting over.";
            $Universe.trigger("ShowMessage", mopts);
            $Universe.on("MoveCardsCompleted", OnMoveCardsCompleted_StartNewRound);
    
            for(var i=0; i<=1; i++)
            {
                var fromui = $(".battle").eq(i);
                var toui = $(".wins").eq(i);
                var opts = {};
                opts.MoveAllCards = true;
                opts.from = formui;
                opts.to = toui;
                opts.prepend = true;
                $Universe.trigger("MoveCard", opts);
    
            }
        } // restart game
        else
        {
            // trigger game over
    
            var opts = {};
            opts.keep = true;
            opts.message = "Player " + (winner + 1) + " wins!  " + gopts.message;
            $Universe.trigger("ShowMessage", opts);
            $Universe.trigger("GameOver");
        }
    
    
    }
    
    function OnMoveCardsCompleted_StartNewRound(e, opts)
    {
        var ropts = {};
        ropts.NumberOfCards = 1;
        $Universe.trigger("PlayOneRound", ropts);
    
    }
    
    function OnMoveCardsCompleted_ToBattleground(e, opts)
    {
        // Stop listening
        // Probably better to do something like adding this listener to the UI target itself rather than the Universe
        var $Universe = $("#Universe");
        $Universe.off("MoveCardsCompleted", OnMoveCardsCompleted_ToBattleground);
    
        var winner = CheckCurrentBattleWinner();
    
        if(winner < 0)
        {
            var wardepth =         $Universe.data("wardepth");
            if(wardepth == null)
            {
                wardepth = 0;
            }
            
            wardepth++;
            $Universe.data("wardepth", wardepth);
            
    
            
            //  Check for MEGA WAR!!!
            var card = battle[0][battle[0].length - 1];    
            var mopts = {};
            var opts = {};
            if(wardepth == 3)
            {
                // this is going to be the big one
                mopts.message = "WORLD WAR III!!!";
                opts.NumberOfCards = 3;
                
            }
            else if(card.Value == 14)
            {
                opts.NumberOfCards = 7;
                mopts.message = "MEGA W-A-R!!!!!";
            }
            else
            {
                mopts.message = "W-A-R!";
                opts.NumberOfCards = 4;
            }
    
            $Universe.trigger("ShowMessage", mopts);
            /* DO WAR */
            Pulse($(".battle .card"), "ui-state-error", 3, PlayOneRound, opts.NumberOfCards);
    
        }
        else
        {
        
            /* Check for extra points */
            var opts = {};
            opts.winner = winner;
            var $Universe = $("#Universe");
            $Universe.on("OnPostCheckWinner", OnPostCheckWinner_ExtraCards);
            $Universe.trigger("OnPostCheckWinner", opts);
            // TODO: Need to pass this better
            $Universe.data("wardepth", 0);
    
        }
    }
    
    // After winner is determined, check for other things
    function OnPostCheckWinner_ExtraCards(e, opts)
    {
    
        var $Universe = $("#Universe");
        $Universe.off("OnPostCheckWinner", OnPostCheckWinner_ExtraCards);
        $Universe.on("MoveCardsCompleted", MoveCardsCompleted_CollectWinnings);
    
        var winner = opts.winner;
        var loser = ((winner + 1) % 2);
        var special = false;
    
        if(battle[winner].length > 0 && battle[loser].length > 0)
        {
    // wwiii
            // check for wwiii
            // if WWIII, winner takes all
            var WarDepth = $Universe.data("wardepth");
            if(WarDepth == null)
            {
                WarDepth = 0;
            }
            
            if(WarDepth >= 3)
            {
                // TODO: Move everything to winner's win pile
                
                special = true;
                var moves = [];
                card = draw(loser);
                
                while(card != null)
                {
                    var mopts = {};
                    mopts.cardui = CreateCardElement(card);
                    mopts.from = $(".deck").eq(loser);
                    mopts.to = $(".battle").eq(loser);
                    mopts.speed = "fast";
                    $Universe.trigger("MoveCard", mopts);
                        
                }
                
            }
        
        
            if( ! special)
            {    
                var WinningCard = battle[winner][battle[winner].length - 1];
                var LosingCard = battle[loser][battle[loser].length - 1];
    
                var newOpts = {};
    
                if(WinningCard.Value == 14 && LosingCard.Value == 2)
                {
                    var mopts = {message: "Crushing Defeat!"};
                    $Universe.trigger("ShowMessage", mopts);
    
                    card = LosingCard;
                
                    while(card != null && card.Value == 2)
                    {
                        // If you draw another 2, steal that as well.
                        card = draw(loser);
        
    
                        newOpts.cardui = CreateCardElement(card);
                        newOpts.from = $(".deck").eq(loser);
                        newOpts.to = $(".battle").eq(loser);
                        newOpts.winner = winner;
                        newOpts.loser = loser;
                        $Universe.trigger("MoveCard", newOpts);
                    }
                    special = true;
                }
            }
    
        }
    
        if(! special)
        {
            MoveCardsCompleted_CollectWinnings(null, opts);
        }
    
    }
    
    
    // Now collect winnings
    function MoveCardsCompleted_CollectWinnings(e, opts)
    {
        var $Universe = $("#Universe");
        $Universe.off("MoveCardsCompleted", MoveCardsCompleted_CollectWinnings);
        var winner = opts.winner;
        Pulse($(".battle").eq(winner).find(".card"), "ui-state-default", 1, CollectWinnings, winner);
    
    
    
    }
    
    function Pulse(elms, cssClass, numPulses, OnComplete, opts)
    {
        var $Universe = $("#Universe");
        var anim = 0;
        // flash the cards as a warning
        $(elms)
        .addClass(cssClass,
        {
            duration:250 * SpeedFactor,
            complete: function()
            {
                anim++;
                $(this).removeClass(cssClass,
                {
                    duration:250 * SpeedFactor,
                    complete:function()
                    {
                        anim--;
                        if(anim == 0)
                        {
                            if(numPulses <= 0)
                            {
                                OnComplete(opts);
                            }
                            else
                            {
                                numPulses = numPulses - 1;
                                Pulse(elms, cssClass, numPulses, OnComplete, opts);
                            }
                        }
    
                    }
                })
            }
        });
    
    }
    
    function OnMoveCardsCompleted_ToWinPile(e, opts)
    {
        $Universe.off("MoveCardsCompleted", OnMoveCardsCompleted_ToWinPile);
        $Universe.trigger("OnAfterPlayOneRound", opts);
    }
    
    
    
    function SetupBoard()
    {
        $(".cards").each(function(e)
        {
            var $this = $(this);
            $this.data("cards", GetNewDeck());
        });
    }
    
    function SetUpNewGame(numPlayersZeroIndex)
    {
        GameDeck = shuffle(GameDeck);
    
        for(var i = 0; i<= numPlayersZeroIndex; i++)
        {
            decks[i] = GetNewDeck();
            $("#player"+i+"_area_deck").data("cards", decks[i]);
    
            wins[i] = GetNewDeck();
            $("#player"+i+"_area_wins").data("cards", wins[i]);
    
            battle[i] = GetNewDeck();
            $("#battleground_p" + i).data("cards", battle[i]);
        }
    
        for(var i = 0; i < GameDeck.length; i++)
        {
            decks[i%(numPlayersZeroIndex + 1)].push(GameDeck[i]);
        }
    
    
    
        // set up deck UI
        for(var i = 0; i<= numPlayersZeroIndex; i++)
        {
    
            ClearWinsPile(i);
            RefreshDeck(i);
        }
    
    }
    
    </script>
    
    

  • Trolleybus Mechanic

    war.html part 2

    <script type="text/javascript">
        // jquery sheeeeeet
        $(document).ready(function()
        {
            $(".action").removeClass("ui-state-disabled").attr("disabled", false);
            SetupBoard();
            SetUpNewGame(1);
    
            $Universe = $("#Universe");
            $Universe.data("cards_moving", 0);
    
            $("#OneRound").click(function(e)
            {
                var opts = {};
                opts.NumberOfCards = 1;
                $Universe.trigger("PlayOneRound", opts);
            });
    
            $("#AllRounds").click(function(e)
            {
                $("#Universe").on("OnAfterPlayOneRound", OnAfterPlayOneRound_AllRounds);
                var opts = {};
                opts.NumberOfCards = 1;
                $Universe.trigger("PlayOneRound", opts);
    
            });
    
            $("#PushTest").click(function(e)
            {
                for(var i=0;i<=1;i++)
                {
                    var card = {};
                    card.Value = 15;
                    card.Suit = "Hearts";
                    card.Rank = "Test";
                    decks[i].unshift(card);
                }
    
            });
    
            $("#PushAceTwoTest").click(function(e)
            {
                var card = {};
                card.Value = 14;
                card.Suit = "Hearts";
                card.Rank = "Ace";
                decks[0].unshift(card);
    
                card = {};
                card.Value = 2;
                card.Suit = "Hearts";
                card.Rank = "Two";
                decks[1].unshift(card);
    
                RefreshDeck(0);
                RefreshDeck(1);
            });
    
            $("#SetupShortGame").click(function(e)
            {
                for(var i=0;i<=1;i++)
                {
                    while(decks[i].length > 1)
                    {
                        decks[i].shift();
                    }
    
                    RefreshDeck(i);
                }
    
    
            });
            
            $("#SetupWWIII").click(function(e)
            {
                var card;
                var suit;
    
                for(var i=0;i<=1;i++)
                {
                    decks[i] = GetNewDeck();
    
                    for(var s=0; s<suites.length; s++)
                    {
                        var idx = 0;
                        for(var rank in ranks)
                        {
                            card = {"Suit" : suites[s], "Rank" : rank, "Value" : ranks[rank], "Glyph" : glyphs[s], "Short" : shorts[idx]};
                            if(i == 0 || (i == 1 && idx != 12))
                            {
                                decks[i].push(card);
                            }
                            idx++;
    
                        }
                        RefreshDeck(i);
    
                    }    
                }        
                
                
            });
            
            $("#SetupArmisticeRank").click(function(e)
            {
                var card;
                var suit;
                for(var i=0;i<=1;i++)
                {
                    decks[i] = GetNewDeck();
                    var idx = 0;
                    for(var rank in ranks)
                    {
                        card = {"Suit" : suites[0], "Rank" : rank, "Value" : ranks[rank], "Glyph" : glyphs[0], "Short" : shorts[idx]};
                        if(idx < 7 && ( i==0 || (i==1 && idx < 2)))
                        {
                            decks[i].push(card);
                        }
                        idx++;
    
                    }
                    RefreshDeck(i);
    
                }
    
    
    
            });
    
            $("#SetupArmisticeCount").click(function(e)
            {
                var card;
                var suit;
                var lastcard;
    
                for(var i=0;i<=1;i++)
                {
                    decks[i] = GetNewDeck();
                    var idx = 0;
                    for(var rank in ranks)
                    {
                        card = {"Suit" : suites[0], "Rank" : rank, "Value" : ranks[rank], "Glyph" : glyphs[0], "Short" : shorts[idx]};
                        if(idx == 0)
                        {
                        lastcard = {"Suit" : suites[0], "Rank" : rank, "Value" : ranks[rank], "Glyph" : glyphs[0], "Short" : shorts[idx]};
    
                            // deck 1 gets 3 2s, deck 2 gets a 2 and a 4
                            decks[i].push(card);
    
                            if(i == 0)
                            {
                                card = {"Suit" : suites[0], "Rank" : rank, "Value" : ranks[rank], "Glyph" : glyphs[0], "Short" : shorts[idx]};
                                decks[i].push(card);
    
                                card = {"Suit" : suites[0], "Rank" : rank, "Value" : ranks[rank], "Glyph" : glyphs[0], "Short" : shorts[idx]};
                                decks[i].push(card);
    
                            }
                        }
                        else if (idx == 2 && i == 1)
                        {
                            // deck 2 gets one 4
                            decks[i].push(card);
                        }
    
                        idx++;
    
                    }
    
                    decks[i].push(lastcard);
    
    
                    RefreshDeck(i);
    
                }
    
            });
    
    
            $("#SetupRoyalDefeat").click(function(e)
            {
                decks[0] = GetNewDeck();
                decks[1] = GetNewDeck();
                var card;
                var suit;
                var lastcard0 = null;
                var lastcard1 = null;
    
                for(var s = 0; s < suites.length; s++)
                {
                    suit = suites[s];
                    var idx = 0;
                    for(var rank in ranks)
                    {
                        if(ranks[rank] >= 11 && ranks[rank] <= 14)
                        {
                            card = {"Suit" : suit, "Rank" : rank, "Value" : ranks[rank], "Glyph" : glyphs[s], "Short" : shorts[idx]};
                            if(s == 0 && ranks[rank] == 11)
                            {
                                // deck 1 will get the Jh
                                lastcard1 = card;
                            }
                            else if (s== 0 && ranks[rank] == 14)
                            {
                                //deck 0 will get the Ah
                                lastcard0 = card;
                            }
                            else
                            {
                                
                                decks[0].push(card);
                            }
                        }
                        idx++;
                    }
    
                }
    
                for(var s = 0; s < suites.length; s++)
                {
                    suit = suites[s];
                    var idx = 0;
                    for(var rank in ranks)
                    {
                        if(ranks[rank] < 11)
                        {
                            card = {"Suit" : suit, "Rank" : rank, "Value" : ranks[rank], "Glyph" : glyphs[s], "Short" : shorts[idx]};
                            decks[1].push(card);
                        }
                        idx++;
                    }
    
                }
                
                // now push the J and A onto the decks
                decks[0].unshift(lastcard0);
                decks[1].unshift(lastcard1);
    
                RefreshDeck(0);
                RefreshDeck(1);
            });
    
    
        });
    
        function OnAfterPlayOneRound_AllRounds()
        {
            if(CardsOwned(0) > 0 && CardsOwned(1) > 0)
            {
                var opts = {};
                opts.NumberOfCards = 1;
                $Universe.trigger("PlayOneRound", opts);
    
            }
        }
    
        // Check for victory conditions
        function OnAfterPlayOneRound_CheckVictory(e, opts)
        {
            // If one player is out of cards, the other player automagically wins
            // TODO:  Also create a wordpress style call stack instead of events?
    
            var winner = -1;
            var winMessage = "";
            for(i=1; i<=1; i++)
            {
                // todo: show message without clearing
                if(CardsOwned(i) == 0)
                {
                    winner = ((i + 1) % 2);
                    winMessage = "Complete Domination!";
                }
            }
            
            if(winner == -1)
            {
            
            }
            
            
            if(winner == -1)
            {
    
                for(i=0; i<=1; i++)
                {
                    // Check to see if anyone has all royal families (J-K)
                    var RoyalCount = 0;
                    var card;
                    for(var idx = 0; idx < decks[i].length; idx++)
                    {
                        card = decks[i][idx];
    
                        if(card.Value >= 11 && card.Value <= 13)
                        {
                            RoyalCount = RoyalCount + 1;
                        }
                    }
    
                    for(var idx = 0; idx < wins[i].length; idx++)
                    {
    
                        card = wins[i][idx];
    
                        if(card.Value >= 11 && card.Value <= 13)
                        {
                            RoyalCount = RoyalCount + 1;
                        }
                    }
    
                    if(RoyalCount == 12)
                    {
                        winner = i;
                        winMessage = "Royal Capture";
                        var moves = [];
                        
                        for(var s = 0; s<suites.length; s++)
                        {
                            var suit = suites[s];
                            
                            for(var val = 11; val <= 13; val++)
                            {
                                
                                // Move all cards to the win pile to show them off
                                for(var idx = 0; idx < decks[winner].length; idx++)
                                {
                                    card = decks[winner][idx];
    
                                    if(card.Value == val && card.Suit == suit)
                                    {
                                        //card = decks[winner].splice(idx, 1)[0];
                                        var opts = {};
                                        
                                        opts.cardui = CreateCardElement(card); 
                                        opts.from = $(".deck").eq(winner);
                                        opts.to = $(".battle").eq(winner);
                                        moves.push(opts);
                                        idx = decks[winner].length;
    
                                    }
                                }
    
                                for(var idx = 0; idx < wins[winner].length; idx++)
                                {
    
                                    card = wins[winner][idx];
    
                                    if(card.Value == val && card.Suit == suit)
                                    {
                                        var opts = {};
                                        opts.cardui = $(".wins").eq(winner).find(".card").eq(idx);
                                        opts.cardui.removeClass("latest");
                                        opts.from = $(".wins").eq(winner);
                                        opts.to = $(".battle").eq(winner);
                                        moves.push(opts);
    
                                        idx = wins[winner].length;
                                    }
                                }
                            }
                        }
                        
                        // do the moves
                        for(var idx = 0; idx < moves.length; idx++)
                        {
                            $Universe.trigger("MoveCard", moves[idx]);
                        }
                        
                        for(var i=0; i<=1; i++)
                        {
                            RefreshDeck(i);
                        }
                    }
                }
            }
    
            if (winner >= 0)
            {
                var opts = {};
                opts.keep = true;
                opts.message = "Player " + (winner + 1) + " wins!  " + winMessage
                $Universe.trigger("ShowMessage", opts);
                $Universe.trigger("GameOver");
            }
    
        }
    
        // Universe handlers
        $(document).ready(function()
        {
            $Universe.on("OnAfterPlayOneRound", OnAfterPlayOneRound_CheckVictory);
    
            $Universe.on("PlayOneRound", function(e, opts)
            {
                if(! $Universe.GameOver)
                {
                    var defaults = {};
                    defaults.NumberOfCards = 1;
                    $.merge(defaults, opts);
                    // A round has been triggered.  Play it, then call On Complete
                    $Universe.trigger("OnBeforePlayOneRound", e);
    
                    var NumberOfCards = opts.NumberOfCards;
    
                    PlayOneRound(NumberOfCards);
    
                }
    
            });
    
    
            // default round actions
            $Universe.on("OnBeforePlayOneRound", function(e)
            {
                // default action: disable action things
                $(".action").addClass("ui-state-disabled");
            });
    
            $Universe.on("OnAfterPlayOneRound", function(e)
            {
                // restore action buttons
                $(".action").removeClass("ui-state-disabled");
            });
    
    
    
    /*
            player: idx,
            card: card,
            from: decks[idx],
            to: battle[idx],
            facedown_from: false,
            facedown_to: true
    */
            $Universe.on("MoveCard", function(e, opts)
            {
                var defaults = {MoveAllCards : false, speed:"slow"};
                $.merge(opts, defaults);
    
                // get the card from the target
                // expose it on the target
                // animate it to the other target
                var $card = $(opts.cardui);
                var $FromUI = $(opts.from);
                var $ToUI = $(opts.to);
    
                var $LastCard = $FromUI.find(".card:last");
    
    
                if(opts.MoveAllCards)
                {
                    if($LastCard.length > 0)
                    {
                        $card = $LastCard;
                    }
                }
    
                var top = $FromUI.offset().top;
                var left = $FromUI.offset().left;
    
                var cards = $FromUI.data("cards");
                            
                // maybe we can also find by card object?
                if(opts.card != null)
                {
                    $FromUI.find(".cards").each(function()
                    {
                        var $this = $(this);
                        if($this.data("card") == opts.card)
                        {
                            $card = $this;
                            opts.cardui = $this;
                        }
                    });
                }
    
                var card = $card.data("card");
    
    
                // remove the card from the target UI, if it exists
                if(cards != null && cards.indexOf(card) >= 0)
                {
                    cards.splice(cards.indexOf(card), 1);
                }
    
    
                $card
                    .detach()
                    .appendTo("body")
                    .css("position", "absolute")
                    .css("top", top)
                    .css("left", left)
                    .animate
                    (
                        {
                            left:$ToUI.offset().left,
                            top:$ToUI.offset().top
                        },
                        opts.speed,
                        function()
                        {
                            var newOpts = {};
                            $.extend(newOpts, opts);
                            newOpts.cardui = $card;
    
                            $Universe.trigger("MoveCardComplete", newOpts);
    
                            if(opts.MoveAllCards && $FromUI.find(".card").length > 0)
                            {
                                $Universe.trigger("MoveCard", opts);
                            }
                        }
                    );
            });
    
    
            $Universe.on("MoveCardComplete", function(e, opts)
            {
                var $card = $(opts.cardui);
                var $FromUI = $(opts.from);
                var $ToUI = $(opts.to);
                var card = $card.data("card");
                var cards = $ToUI.data("cards");
    
                if(opts.prepend)
                {
                    $card.prependTo($ToUI);
                    cards.unshift(card);
                }
                else
                {
                    $card.appendTo($ToUI);
                    cards.push(card);
                }
                $card.css("position", "static");
    
    
            });
    
            // Card in motion tracking
            $Universe.on("MoveCard", function(e, opts)
            {
                $Universe.data("cards_moving", $Universe.data("cards_moving") + 1);
            });
    
            $Universe.on("MoveCardComplete", function(e, opts)
            {
                $Universe.data("cards_moving", $Universe.data("cards_moving") - 1);
    
                // I have a feeling there's a better way to do this-- push all card moves onto a stack, then raise a Move Stack ready-- then raise a Move Stack Complete
                // Next iteration it is.  I'll live with the race condition for now.
                if($Universe.data("cards_moving") == 0)
                {
                    $Universe.trigger("MoveCardsCompleted", opts);
                }
            });
    
            var MessageBuffer = [];
            var MessageMutex = null;
    
            $Universe.on("ShowMessage", function(e, opts)
            {
                // Put message into stack
                MessageBuffer.push(opts);
    
                // Try to show the message
                TryShowMessage(opts);
            });
    
            function TryShowMessage(opts)
            {
                // if my message is the first one, show it
                // otherwise HideMessage will be responsible for showing the next one
                if(MessageBuffer.length > 0 && MessageBuffer[0] == opts)
                {
                    // remove from buffer
                    var opts = MessageBuffer[0];
                    var defaults = {delay:2000, speed:"fast"};
                    $.extend(opts, defaults);
    
    
                    if(opts.message != null)
                    {
                        var Message = opts.message;
                        var $Message = $("#Message");
                        var $MessageText = $("<div></div>");
                        $MessageText.text(Message);
                        $MessageText.addClass("message-text");
                        $MessageText.css("position", "absolute");
    
                        $MessageText.css("left", $Message.width());
                        $Message.append($MessageText);
                        $MessageText.width($Message.width())
                        $MessageText.animate
                        (
                            {left: 0},
                            opts.speed,
                            function()
                            {
                                if(! opts.keep)
                                {
                                    var hopts = {};
                                    $.extend(hopts, opts);
                                    hopts.ui = $(this);
    
                                    setTimeout(function(){$Universe.trigger("HideMessage", hopts)}, opts.delay);
                                }
                            }
                        );
    
                    }
                }
    
            } // try show message
    
            $Universe.on("HideMessage", function(e, opts)
            {
                var defaults = {delay:2000, speed:"fast"};
                $.extend(opts, defaults);
    
                var $ui = opts.ui;
                var $Message = $("#Message");
                $ui.animate
                (
                    {left: $Message.width() * - 1.2},
                    opts.speed,
                    function()
                    {
                        $(this).detach();
                        // get rid of message from queue
                        MessageBuffer.shift();
    
                        // Try to show the next message
                        if(MessageBuffer.length > 0)
                        {
                            TryShowMessage(MessageBuffer[0]);
                        }
                    }
                );
            });
    
            $Universe.on("GameOver", function(e, opts)
            {
                $(".action").attr("disabled", true).addClass("ui-state-disabled");
                $Universe.GameOver = true;
                // Stop the game, but how?
    
            });
    
    
        });
    
    </script>
    </head>
    <body>
    <div id="Universe">
    
        <div style="position:block;min-height:2em;">
            <div style="position:absolute;">
            <button id="OneRound" class="action">Play One Round</button>
            <button id="AllRounds" class="action">Play All</button>
            <button id="PushTest" class="action">Push Test Cards for Tie</button>
            <button id="PushAceTwoTest" class="action">Push Ace Two Cards for Tie</button>
            <button id="SetupRoyalDefeat" class="action">Royal Defeat Decks</button>
            <button id="SetupShortGame" class="action">Short Game</button>
            <button id="SetupArmisticeRank" class="action">Armistice Rank</button>
            <button id="SetupArmisticeCount" class="action">Armistice Count</button>
            <button id="SetupWWIII" class="action">Setup WWIII</button>
    
    
    
            </div>
        </div>
    
        <div id="MessageWrap" style='width:100%;height:2em;'>
            <div id="Message">
    
            </div>
        </div>
    
        <div id="playarea" class="" style="margin-top:2em;">
    
            <div id="player0_area" class="area player p0">
                <div id="player0_area_deck" class="p0 area deck cards stack"></div>
                <div id="player0_area_wins" class="p0 area wins cards stack"></div>
            </div>
    
            <div id="battleground" class="area battleground">
                <div id="battleground_p0" class="p0 area battle cards stack"></div>
                <div id="battleground_p1" class="p1 area battle cards stack"></div>
            </div>
    
            <div id="player1_area" class="area player p1">
                <div id="player1_area_deck" class="p1 area deck cards pile"></div>
                <div id="player1_area_wins" class="p1 area wins cards stack"></div>
            </div>
    
        </div>
    </div>
    </body>
    

Log in to reply