text:
Simple Pazaak (Star Wars Card Game from Knights of the Old Republic)
Pazaak is a card game from the Star Wars universe. It is similar to BlackJack, with two players pitted against each other trying to reach a total of twenty without going over. Each player has a "side deck" of four cards of their own that they can use to modify their score.
Leaderboard
As of 6/17/2015 @ 16:40 EDT
Edit: Neptor has been disqualified for cheating. Scores will be fixed as soon as possible...

N.E.P.T.R:            ~424,000
The Cincinnati Kid:   ~422,000
Nestor:               ~408,000
Austin Powers:        ~405,000
Bastila:              ~248,000
Dumb Cautious Player: ~107,000
Dumb Bold Player:     ~87,000

Mock Pazaak Cup Playoffs
Will be updated as soon as possible.
Round One - Nestor vs Bastila & Austin Powers vs The Cincinnati Kid

Round Two - Nestor vs Austin Powers & The Cincinnati Kid vs Bastila

Mechanics
Gameplay is done in turns. Player one is dealt a card from the main (house) deck. The house deck holds forty cards: four copies of one through 10. After being dealt a card, they can choose to end their turn and receive a new card next turn, stand at their current value, or play a card from their side deck and stand at the new value. After player one decides what they want to do, player two repeats the process.
Once both players have gone, the hands are evaluated. If a player bombed out (went over twenty), the other player will win, provided that they did not also bomb out. If a player chose to stand, and the other player has a higher hand value, the other player will win. If both players chose to stand, the player with the higher hand value will win. In the event of a tie, neither player gets the win.
Provided a winning condition is not met, play will repeat. If a player chose to end their turn, they will receive a new card and can make a new choice. If they chose to stand, or if they played a card from their side deck, they will not be dealt a new card and cannot choose a new action.
Play continues like this until one player wins the game. Games are played in best-three-out-of-five sets.
Why "Simple" Pazaak?
In the Star Wars universe, Pazaak involved gambling. While inclusion of such a system would add more of a dynamic to the game, it is a bit complicated for a first-time KoTH competition.
"Real" Pazaak side decks were also provided by the players themselves, and could include many different card options such as negative cards, positive-or-negative cards, flip cards, double cards, and tiebreaker cards. These would also make the game more interesting, but would require a gambling interface in place, and would require far more out of the competitors. In this Simple Pazaak game, each player gets the same side deck: two copies of one through five, from which four are randomly selected.
Depending on the success of this game, I may put forth the effort to develop an advanced version wherein which gambling and custom side decks are possible.
The Players
The players of this game will be bots designed by you. Each bot needs to extend the Player class, import the Mechanics package,  and reside in the players package like so:
package Players;

import java.util.Collection;

import Mechanics.*;

public class DemoPlayer extends Player {

    public DemoPlayer() {
        name = "Your Name Here";
    }

    public void getResponse(int wins[], boolean isPlayerOne,
            Collection<Card> yourHand, Collection<Card> opponentHand,
            Collection<Card> yourSideDeck, int opponentSideDeckCount,
            Action opponentAction, boolean opponentDidPlay) {
        action = null;
        cardToPlay = null;
    }
}

Each round, the controller will call the getResponse method for your bot, unless your bot previously indicated that it wanted to stand. The getResponse method can set two properties: an action and a card to play. Action can be one of the following:

END: Ends the turn and draws a new card next turn.
STAND: Stays at the current hand value. Will not draw a card.
PLAY: Plays a card from the side deck and then stands.

The card to play is obviously only of importance if you set the action to PLAY. It takes a Card object. If the Card object you pass to it does not exist in your side deck, your bot will STAND instead.
The parameters your bot receives each turn are:

An array containing the wins of each player. wins[0] is Player 1's, wins1 is Player 2's (int[])
Whether or not your bot is player one (boolean)
A collection of the cards that you have been dealt thus far (Collection)
A collection of the cards your opponent has been dealt thus far (Collection)
A collection of the cards in your side deck (Collection)
The number of cards remaining in your opponent's side deck (int)
The action your opponent last made (Action) [Note: This will either be END or STAND, never PLAY]
Whether or not your opponent played a card (boolean)

Bot Rules
Your bots may only use the information that is given to them via the getResponse method. They should not attempt to interact with any other class. They may write to a single file to store data between rounds. They may have any custom methods, properties, etc. as desired. They should run in a reasonable amount of time (if the program run is not practically instantaneous, I will notice something is wrong).
If you find some kind of exploit in the code, you will be rewarded for "turning yourself in." If I notice the exploit first, I will fix it, and you will get no reward.
Demos
The controller is not needed to write a bot, as everything is already explained in this post. However, if you wish to test, it can be found here: https://github.com/PhantomJedi759/simplepazaak
Two basic bots are included. Neither should hold up well against an "intelligent" opponent, as they only choose between END and STAND. Here is a sample run of what they do:
New Game!
The standings are 0 to 0
Dumb Bold Player's Hand: []
Dumb Bold Player's new Hand: [2]
Dumb Bold Player has chosen to END
Dumb Cautious Player's Hand: []
Dumb Cautious Player's new Hand: [8]
Dumb Cautious Player has chosen to END
Dumb Bold Player's Hand: [2]
Dumb Bold Player's new Hand: [2, 8]
Dumb Bold Player has chosen to END
Dumb Cautious Player's Hand: [8]
Dumb Cautious Player's new Hand: [8, 3]
Dumb Cautious Player has chosen to END
Dumb Bold Player's Hand: [2, 8]
Dumb Bold Player's new Hand: [2, 8, 7]
Dumb Bold Player has chosen to END
Dumb Cautious Player's Hand: [8, 3]
Dumb Cautious Player's new Hand: [8, 3, 6]
Dumb Cautious Player has chosen to STAND
Dumb Bold Player's Hand: [2, 8, 7]
Dumb Bold Player's new Hand: [2, 8, 7, 6]
Dumb Bold Player has chosen to STAND
Dumb Cautious Player's Hand: [8, 3, 6]
Dumb Cautious Player has chosen to STAND
Dumb Bold Player has bombed out! Dumb Cautious Player wins!

Because these bots rely purely on the luck of the draw, their win-loss ratios can vary drastically. It will be interesting to see how skill can combat the luck of the game.
This should be everything you need! Go build some bots!
Clarification to Rules
The main deck is forty cards: 4x1-10
It is reshuffled at the beginning of each hand.
A player's side deck has four cards, selected randomly out of 2x1-5. The side deck persists between hands.
Hands are played in games for the best three-out-of-five. Bots are scored based on the total number of games won, and then by the total number of hands.
Matching is handled so that each player will have to play 100,000 games against every other player.
In the Pazaak Cup, elimination-style rounds will narrow down who the best Pazaak bot really is. Each pairing of bots will play for the best four-out-of-seven sets of 100,000 games. Whoever wins four will move up the ladder to the next opponent, and the losers will stay down to battle for sequential rankings. This style of gameplay is the most fair, as bots cannot "win-farm" certain opponents to compensate for lack of ability against others. The Pazaak Cup will be held on Friday, July 3, provided there are at least eight submitted bots. The winner will receive Correct Answer status and a starting bonus in Advanced Pazaak, which will hopefully be ready close to the same time as the Pazaak Cup is held.

Trying to access the repo gives me security warnings on Chrome, sadly. This seems like a really fun challenge that I'd love to enter, but I'd like some clarifications in lieu of documentation. The house deck starts out with the same 40 cards at the beginning of each round, correct? Our 4 card side deck can be any card 1-10 and doesn't affect the house deck? Both hands are visible via getResponse? Are we going to be scored on # of hands won, or are there rounds consisting of like a best of 5 format? Basically, why are # of wins passed in to getResponse?

When does the deck get reset? After every round or just with every opponent?

It should be wins[1] for player 2's wins, not wins[2] as wins is just an array length 2

@DoctorHeckle Apologies about the repo; my current network blocks github, but I will try to get it up there as soon as possible. The deck is reset every game. The side deck holds four cards of 2x1-5. Once actual competition begins, you will be scored by tourneys which are best out of five. The number of wins are passed to the getResponse method in case your bot wants to change it's play style depending on whether or not it is winning or losing the tourney.

@TheE Thanks, I'll get that fixed.

I don't know if StackOverflow notifies you when an answer has been edited, but I have an updated version of The Cincinnati Kid posted now.

@RalphMarshall I was not notified. I'll put the updated version in and get the results!

The Cincinnati Kid
Try to make sure that we draw another card if we know we're losing, otherwise look at our side deck and the overall scores to decide what to do.
Updated to do a better job of handling situations where the opponent has already finished playing. In my own testing this now seems to be the best candidate again, at least for now.
package Players;

import java.util.Collection;

import Mechanics.*;

public class CincinnatiKid extends Player {

    public CincinnatiKid() {
        name = "The Cincinnati Kid";
    }

    private static boolean isDebug = false;

    private static final int BEST_HAND = 20;

    public void getResponse(int wins[],
                            boolean isPlayerOne,
                            Collection<Card> yourHand,
                            Collection<Card> opponentHand,
                            Collection<Card> yourSideDeck,
                            int opponentSideDeckCount,
                            Action opponentAction,
                            boolean opponentDidPlay)
    {
        int myValue = handValue(yourHand);
        int oppValue = handValue(opponentHand);

        if (oppValue > BEST_HAND) {
            logMsg("Opponent has busted");
            action = Action.STAND;
        } else if (myValue > BEST_HAND) {
            logMsg("I have busted");
            action = Action.STAND;
        } else if (myValue <= 10) {
            logMsg("I cannot bust with my next move");
            action = Action.END;
        } else {
            handleTrickySituation(myValue, oppValue, wins, isPlayerOne, yourHand, opponentHand,
                                  yourSideDeck, opponentSideDeckCount, opponentAction, opponentDidPlay);
        }

        if (action == Action.PLAY && cardToPlay == null) {
            logMsg("ERROR - Action is Play but no card chosen");
        }
        logMsg("My hand value is " + myValue + ", opponent is " + oppValue + ", action is " + action +
               ((action == Action.PLAY && cardToPlay != null) ? " a " + cardToPlay.toString() : ""));
    }

    int [] branchCounts = new int[12];

    public void dumpBranchCounts() {
        if (isDebug) {
            for (int i = 0; i < branchCounts.length; i++) {
                System.out.print("b[" + i + "]=" + branchCounts[i] + " ");
            }
            System.out.println();
        }
    }

    private void handleTrickySituation(int myValue, int oppValue,
                                       int wins[],
                                       boolean isPlayerOne,
                                       Collection<Card> yourHand,
                                       Collection<Card> opponentHand,
                                       Collection<Card> yourSideDeck,
                                       int opponentSideDeckCount,
                                       Action opponentAction,
                                       boolean opponentDidPlay)
    {
        dumpBranchCounts();
        logMsg("I am might bust");

        int STAND_VALUE = 18;
        int chosenBranch = 0;

        Card bestSideCard = findSideCard(myValue, yourSideDeck);
        int valueWithSideCard = myValue + (bestSideCard != null ? bestSideCard.getValue() : 0);

        if (bestSideCard != null && valueWithSideCard >= oppValue && valueWithSideCard > STAND_VALUE) {
            logMsg("Found a good card in side deck");
            action = Action.PLAY;
            cardToPlay = bestSideCard;
            chosenBranch = 1;
        } else if (opponentDidPlay || opponentAction == Action.STAND) {
            logMsg("Opponent is done");
            // Opponent is done, so get another card if I'm behind
            if (myValue < oppValue) {
                logMsg("I am behind");
                if (bestSideCard != null && valueWithSideCard >= oppValue) {
                    logMsg("My best side card is good enough to tie or win");
                    action = Action.PLAY;
                    cardToPlay = bestSideCard;
                    chosenBranch = 2;
                } else {
                    logMsg("My best side card won't do so I'm going to hit");
                    // No side card and I'm losing, so I might as well hit
                    action = Action.END;
                    chosenBranch = 3;
                }
            } else if (myValue == oppValue) {
                logMsg("Game is tied");
                logMsg("Looking for lowest card in the side deck");
                cardToPlay = findWorstSideCard(myValue, yourSideDeck);
                if (cardToPlay != null) {
                    action = Action.PLAY;
                    chosenBranch = 4;
                } else {
                    logMsg("Tied with no side cards - accept the draw");
                    action = Action.STAND;
                    chosenBranch = 5;
                }
            } else {
                logMsg("I'm ahead and opponent has given up");
                action = Action.STAND;
                chosenBranch = 6;
            }
        } else if (myValue < oppValue) {
            logMsg("I am behind and have nothing good in my side deck");
            action = Action.END;
            chosenBranch = 7;
        } else if (oppValue <= 10 && myValue < STAND_VALUE) {
            logMsg("Opponent is guaranteed to hit and I have a low hand, so take another");
            action = Action.END;
            chosenBranch = 8;
        } else if (myValue == oppValue && myValue >= STAND_VALUE) {
            logMsg("We both have equally good hands - stand and hope for the tie");
            action = Action.STAND;
            chosenBranch = 9;
        } else if (myValue < STAND_VALUE) {
            logMsg("I am ahead but have a low score");
            action = Action.END;
            chosenBranch = 10;
        } else {
            logMsg("I am ahead with a decent score");
            action = Action.STAND;
            chosenBranch = 11;
        }

        branchCounts[chosenBranch]++;
    }

    private double calcBustOdds(int valueSoFar, Collection<Card> myHand, Collection<Card> oppHand) {

        if (valueSoFar >= BEST_HAND) {
            return 1;
        }

        int remainingDeck = 40 - (myHand.size() + oppHand.size());
        int [] cardCounts = new int[10];
        int firstBust = BEST_HAND - valueSoFar;

        for (int i = 0; i < 10; i++) {
            cardCounts[i] = 4;
        }

        for (Card c : myHand) {
            cardCounts[c.getValue()-1]--;
        }

        for (Card c : oppHand) {
            cardCounts[c.getValue()-1]--;
        }

        int bustCards = 0;
        for (int i = firstBust; i < 10; i++) {
            logMsg("cardCounts[" + i + "]=" + cardCounts[i]);
            bustCards += cardCounts[i];
        }

        double retval = (double) bustCards / (double) remainingDeck;
        logMsg("Out of " + remainingDeck + " remaining cards " + bustCards + " will bust, or " + retval);
        return retval;
    }

    private Card findSideCard(int myValue, Collection<Card> sideDeck) {
        int valueNeeded = BEST_HAND - myValue;
        Card bestCard = null;
        if (valueNeeded > 0) {
            for (Card c : sideDeck) {
                if (c.getValue() == valueNeeded) {
                    return c;
                } else if (c.getValue() < valueNeeded) {
                    if (bestCard == null || c.getValue() > bestCard.getValue()) {
                        bestCard = c;
                    }
                }
            }
        }

        return bestCard;
    }

    private Card findWorstSideCard(int myValue, Collection<Card> sideDeck) {
        int valueNeeded = BEST_HAND - myValue;

        logMsg("Searching side deck for something with value <= " + valueNeeded);
        Card bestCard = null;

        for (Card c : sideDeck) {
            logMsg("Examining side card " + c.getValue());

            // Find the worst card in the deck, but not if it exceeds the amount left
            if (c.getValue() <= valueNeeded && (bestCard == null || c.getValue() < bestCard.getValue())) {
                logMsg("This is the new best side card");
                bestCard = c;
            }
        }

        logMsg("Worst side card found is " + (bestCard != null ? bestCard.getValue() : " n/a"));
        return bestCard;
    }

    private void logMsg(String s) {
        if (isDebug) {
            System.out.println("### " + s);
        }
    }

    private int handValue(Collection<Card> hand)  {
        int handValue = 0;
        for (Card c : hand) {
            handValue += c.getValue();
        }
        return handValue;
    }
}

Congratulations! You are in the lead.

With modifications to make the scoring system more fair, you are now tied for first with Austin Powers.

Austin Powers
Austin Powers, as you might presume, likes to live dangerously. Unless someone has busted, or he can guarantee a win, he will always hit if he's behind, or has a better than 20% chance of not busting.
package Players;
import java.util.Collection;

import Mechanics.*;

public class AustinPowers extends Player {
    public AustinPowers() {
        name = "Austin Powers";
    }
    int MAX_VALUE = 20;
    public void getResponse(int wins[], boolean isPlayerOne,
            Collection<Card> yourHand, Collection<Card> opponentHand,
            Collection<Card> yourSideDeck, int opponentSideDeckCount,
            Action opponentAction, boolean opponentDidPlay) {
        action = null;
        cardToPlay = null;
        int myWins = isPlayerOne?wins[0]:wins[1];
        int oppWins = isPlayerOne?wins[1]:wins[0];
        int oppTotal = calcHand(opponentHand);
        int myTotal = calcHand(yourHand);
        boolean liveDangerously = ((oppTotal>=myTotal && opponentAction==Action.STAND) || opponentAction==Action.END) && myTotal<MAX_VALUE && canNotBust(yourHand,opponentHand,myTotal) && myWins<oppWins;

        if(myTotal==MAX_VALUE || oppTotal>MAX_VALUE || myTotal>MAX_VALUE ||(oppTotal<myTotal&&opponentAction==Action.STAND))
        {
            action = Action.STAND;
        }
        else if((opponentAction==Action.STAND&&hasGoodEnoughSideCard(yourSideDeck,myTotal,oppTotal))||hasPerfectSideCard(yourSideDeck, myTotal))
        {
            action = Action.PLAY;
        }
        else if(liveDangerously||betterThan20(myTotal, getDeck(yourHand, opponentHand)))
        {
            action = Action.END;
        }
        else
        {
            action=Action.STAND;
        }

    }

    private boolean hasGoodEnoughSideCard(Collection<Card> yourSideDeck,
            int myTotal, int oppTotal) {
        for(Card c: yourSideDeck)
        {
            if(MAX_VALUE>=myTotal+c.getValue()&&myTotal+c.getValue()>oppTotal)
            {
                cardToPlay=c;
                return true;
            }
        }
        return false;
    }

    private boolean betterThan20(int myTotal, int[] deck) {
        int deckSize=0;
        int nonBustCards=0;
        for(int i=0;i<10;i++)
        {
            deckSize+=deck[i];
            if(MAX_VALUE-myTotal>i)
                nonBustCards+=deck[i];
        }
        return (double)nonBustCards/(double)deckSize>0.2;
    }

    private boolean hasPerfectSideCard(Collection<Card> yourSideDeck,
            int myTotal) {
        for(Card c:yourSideDeck)
        {
            if(MAX_VALUE-myTotal== c.getValue())
            {
                cardToPlay = c;
                return true;
            }
        }
        return false;
    }

    private boolean canNotBust(Collection<Card> yourHand,
            Collection<Card> opponentHand, int myTotal) {
        if(myTotal<=10) return true;
        int[] deck = getDeck(yourHand, opponentHand);
        for(int i=0;i<MAX_VALUE-myTotal;i++)
            if(deck[i]>0)
                return true;
        return false;
    }

    private int[] getDeck(Collection<Card> yourHand,
            Collection<Card> opponentHand) {
        int[] deck = new int[10];
        for (int i = 0; i < 10; i++) {
            deck[i] = 4;
        }
        for(Card c:yourHand){deck[c.getValue()-1]--;}
        for(Card c:opponentHand){deck[c.getValue()-1]--;}
        return deck;
    }

    private int calcHand(Collection<Card> hand)
    {
        int ret = 0;
        for(Card c: hand){ret+=c.getValue();}
        return ret;
    }
}

Congratulations! You have taken the lead from CincinnatiKid.

With modifications to make the scoring system more fair, you are now tied for first with The Cincinnati Kid.

Bastila
Bastila plays conservatively. To her, a 17 is just as good as a 20, and it's much better to stand short than bomb out.
package Players;

import java.util.Collection;

import Mechanics.*;

public class Bastila extends Player {

    public Bastila() {
        name = "Bastila";
    }

    public void getResponse(int wins[], boolean isPlayerOne,
            Collection<Card> myHand, Collection<Card> opponentHand,
            Collection<Card> mySideDeck, int opponentSideDeckCount,
            Action opponentAction, boolean opponentDidPlay) {

        action = null;
        cardToPlay = null;

        //Constants
        int stand = 17;
        int conservatism = 2;

        //Get some info
        int handVal = handValue(myHand);
        int expected = expectedValue(myHand);

        //Can I play from my side deck?
        for(Card side: mySideDeck){
            int total = side.getValue() + handVal;
            if(total >= stand && total <= 20){
                cardToPlay = side;
                action = Player.Action.PLAY;
            }
        }
        if(action == Player.Action.PLAY){
            return;
        }

        //Otherwise, will I go bust?
        if(handVal + expected > 20 - conservatism){
            action = Player.Action.STAND;
        }
        else{
            action = Player.Action.END;
        }

        return;

    }

    private int handValue(Collection<Card> hand) {
        int handValue = 0;
        for(Card c : hand){
            handValue += c.getValue();
        }
        return handValue;
    }

    private int expectedValue(Collection<Card> hand){
        //Net value of the deck is 55*4 = 220
        int total = 220;
        int count = 40;
        for(Card c : hand){
            total -= c.getValue();
            count--;
        }
        return total/count;
    }

}

Bastila is currently outperforming both Dumb Bold Player and Dumb Cautious Player (demo bots). Good job!
Edit: Out of ten runs, Bastila won eight, losing to Dumb Cautious Player once, and tying with Dumb Cautious Player once.

Update: With the new scoring system (wins counted by tourneys, of which 1000 are played with each player pair), Bastila leads with 1705/3000 total (1705/2000 tourneys played). Next is Dumb Cautious Player with 729, and finally is Dumb Bold Player with 566.

Haha well I would hope it at least beats the demo bots :P

Nestor
Nestor loves getting 20 using his side deck, but when that fails he calculates his expected payoff by choosing stand or end, assuming that the opponent is sensible.
package Players;

import java.util.Arrays;
import java.util.Collection;

import Mechanics.Card;
import Mechanics.Player;

public class Nestor extends Player {
    final int TotalWinPayoff = 10;
    final int TotalLosePayoff = 0;
    final int TotalDrawPayoff = 1;
    final int temporaryLosePayoff = 4;
    final int temporayWinPayoff = 19;
    final int temporaryDrawPayoff = 9;
    @Override
    public void getResponse(int[] wins, boolean isPlayerOne,
            Collection<Card> yourHand, Collection<Card> opponentHand,
            Collection<Card> yourSideDeck, int opponentSideDeckCount,
            Action opponentAction, boolean opponentDidPlay) {

        int sumMyHand = SumHand(yourHand);
        int sumOpponentHand = SumHand(opponentHand);
    if (sumOpponentHand>20)
    {this.action = Action.STAND;return;}
        if(sumMyHand == 20)
        {
            //I'm unbeatable :)
            //System.out.println("\tI'm Unbeatable");
            this.action = Action.STAND;
            return;
        }
        else if(opponentDidPlay || opponentAction == Action.STAND)
        {
            //They've finished
            ///System.out.println("\tThey've Finished");
            if(sumMyHand>sumOpponentHand)
            {
                //I've won
                //System.out.println("\tI've Won");
                this.action = Action.STAND;
                return;
            }
            else if(canBeat(sumMyHand, sumOpponentHand, yourSideDeck))
            {
                //I can beat them
                //System.out.println("\tI can beat them");
                this.action = Action.PLAY;
                return;
            }
            else if(canEven(sumMyHand, sumOpponentHand, yourSideDeck))
            {
                //I can draw with them
                //System.out.println("\tI can draw with them");
                this.action = Action.PLAY;
                return;
            }
            else
            {
                //I need another card
                //System.out.println("\tI need another card");
                this.action = Action.END;
                return;
            }
        }
        else if(deckContains(yourSideDeck, 20-sumMyHand))
        {
            //Let's get 20
            //System.out.println("\tLet's get 20");
            this.action = Action.PLAY;
            this.cardToPlay = getCard(yourSideDeck, 20-sumMyHand);
            return;
        }
        else if(sumOpponentHand==20 && sumMyHand<20)
        {
            //They've got 20 so we need to fight for a draw
            //System.out.println("\tFight for a draw");
            this.action = Action.END;
            return;
        }

        else if(sumMyHand<10)
        {
            //Lets get another card
            //System.out.println("\tLet's get another card");
            this.action = Action.END;
            return;
        }
        else
        {
            //Let's work out some probabilities
            //System.out.println("\tLet's work out some probabilities");
            int[] cardsLeft = {4,4,4,4,4,4,4,4,4,4};
            for (Card card : opponentHand) {
                cardsLeft[card.getValue()-1] --;

            }
            for (Card card : yourHand) {
                cardsLeft[card.getValue()-1] --;

            }

             int numCardsLeft = sumfromToEnd(0, cardsLeft);

             //My Assumptions
             double probabilityTheyStand = (double)sumfromToEnd(20-sumOpponentHand, cardsLeft)/numCardsLeft;

             //What I need to know
             double payoffStanding = 0;
             double payoffDrawing = 0;

             for(int myChoice = -1; myChoice<10; myChoice++)
             {
                 for(int theirChoice = -1; theirChoice<10; theirChoice++)
                 {
                     if(myChoice == -1)
                     {
                         payoffStanding += getProbability(myChoice, theirChoice, Arrays.copyOf(cardsLeft, cardsLeft.length), probabilityTheyStand, numCardsLeft) * getPayoff(sumMyHand, sumOpponentHand,myChoice, theirChoice, TotalWinPayoff, TotalDrawPayoff, TotalLosePayoff);
                     }
                     else
                     {
                         payoffDrawing +=
                                 getProbability(myChoice, theirChoice, Arrays.copyOf(cardsLeft, cardsLeft.length), probabilityTheyStand, numCardsLeft)
                                 * getPayoff(sumMyHand, sumOpponentHand, myChoice, theirChoice, temporayWinPayoff, temporaryDrawPayoff, temporaryLosePayoff);
                     }
                 }
             }
            // System.out.println("\tStanding: " +Double.toString(payoffStanding) + " Ending: " + Double.toString(payoffDrawing));
             if(payoffStanding<payoffDrawing)
             {
                 this.action = Action.END;
             }
             else
             {
                 this.action = Action.STAND;
             }
        }

    }

    private int getPayoff(int sumMyHand, int sumOpponentHand, int myChoice,
            int theirChoice, int WinPayoff, int DrawPayoff,
            int LosePayoff) {
            if(sumMyHand + myChoice + 1 > 20)
            {
                if(sumOpponentHand + theirChoice + 1 > 20)
                {
                    return DrawPayoff;
                }
                else
                {
                    return LosePayoff;
                }
            }
            else if(sumMyHand + myChoice + 1 > sumOpponentHand + theirChoice + 1)
            {
                return WinPayoff;
            }
            else if (sumMyHand + myChoice + 1 < sumOpponentHand + theirChoice + 1)
            {
                return LosePayoff;
            }
            else
            {
                return DrawPayoff;
            }

    }

    private double getProbability(
            int myChoice, int theirChoice, int[] cardsLeft,
            double probabilityTheyStand, int numCardsLeft) {
        double myProb, theirProb;
        if(myChoice<0)
        {
            myProb = 1;
        }
        else
        {
            myProb = ((double)cardsLeft[myChoice])/((double)numCardsLeft);
            cardsLeft[myChoice]--;
            numCardsLeft--;
        }

        if(theirChoice<0)
        {
            theirProb = probabilityTheyStand;
        }
        else
        {
            theirProb = ((double)cardsLeft[theirChoice]) / ((double)numCardsLeft);
        }
        return myProb*theirProb;
    }

    private int sumfromToEnd(int i, int[] cardsLeft) {
        int toRet = 0;
        for(;i<cardsLeft.length; i++)
        {
            toRet += cardsLeft[i];
        }
        return toRet;
    }

    private boolean canEven(int mySum, int opponentSum,
            Collection<Card> yourSideDeck) {
        for (Card card : yourSideDeck) {
            if(mySum + card.getValue() <= 20 && mySum + card.getValue() >= opponentSum)
            {
                this.cardToPlay = card;
                return true;
            }
        }
        return false;
    }

    private boolean canBeat(int mySum, int opponentSum,
            Collection<Card> yourSideDeck) {
        for (Card card : yourSideDeck) {
            if(mySum + card.getValue() <= 20 && mySum + card.getValue() > opponentSum)
            {
                this.cardToPlay = card;
                return true;
            }
        }
        return false;
    }

    private Card getCard(Collection<Card> deck, int value) {
        for (Card card : deck) {
            if(card.getValue() == value)
            {
                return card;
            }
        }
        return null;
    }

    private boolean deckContains(Collection<Card> deck, int value) {
        for (Card card : deck) {
            if(card.getValue() == value)
            {
                return true;
            }
        }
        return false;
    }

    public Nestor()
    {
        super();
        name = "Nestor";
    }

    private int SumHand(Collection<Card> hand)
    {
        int toRet = 0;
        for (Card card : hand) {
            toRet += card.getValue();
        }
        return toRet;
    }
}

Congratulations! You busted through the tie between Austin Powers and The Cincinnati Kid to take first place.

Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: -2
at Players.Nestor.sumfromToEnd(Nestor.java:210)
at Players.Nestor.getResponse(Nestor.java:105)
at Mechanics.PazaakGameMain.playGame(PazaakGameMain.java:112)
at Mechanics.PazaakGameMain.main(PazaakGameMain.java:40)

Would you mind helping me look into that? It appears to be bot-specific, as it only triggers on playing Neptor and T3M4 (unreleased bot on github).

From what I can tell, it triggers if your opponent has busted, but for some reason they didn't stand. I am putting a temporary fix in your bot, but will fix the controller later to automatically STAND bots that bust.

I've added a check for when the opponent has busted, thanks

Glaucus
package Players;

import java.util.Collection;
import java.util.Collections;
import java.util.LinkedList;
import java.util.List;
import java.util.Random;

import Mechanics.Card;
import Mechanics.Player;

public class Glaucus extends Player {
    static final double LosePay = 0;
    static final double WinPay = 10;
    static final double DrawPay = 1;
    static final int NUMBEROFSIMS = 100;

    Random r;

    public Glaucus()
    {
        this.name = "Glaucus";
        r = new Random();
    }

    @Override
    public void getResponse(int[] wins, boolean isPlayerOne,
            Collection<Card> yourHand, Collection<Card> opponentHand,
            Collection<Card> yourSideDeck, int opponentSideDeckCount,
            Action opponentAction, boolean opponentDidPlay) {
        //Make Sum of hands
        int sumMyHand = 0;
        int sumOpponentHand = 0;
        //Make an array of the remaining cards
        List<Integer> cards = new LinkedList<Integer>();
        int[] cardsLeft = {4,4,4,4,4,4,4,4,4,4};
        for (Card card : yourHand) {
            cardsLeft[card.getValue()-1] -= 1;
            sumMyHand+=card.getValue();
        }
        for (Card card : opponentHand) {
            cardsLeft[card.getValue()-1] -= 1;
            sumOpponentHand += card.getValue();
        }
        if(sumMyHand<=10)
        {
            this.action = Action.END;
        }
        else if (sumMyHand >= 20)
        {
            this.action = Action.STAND;
        }
        else if (sumOpponentHand > 20)
        {
            this.action = Action.STAND;
        }
        else
        {
            for (int i = 0; i < cardsLeft.length; i++) {
                while(cardsLeft[i] > 0)
                {
                    cards.add(i + 1);
                    cardsLeft[i] -= 1;
                }
            }
            //System.out.println(Arrays.toString(cards));

            double standPayoff = 0;
            double endPayoff = 0;
            double[] sideDeckPayoffs = new double[yourSideDeck.size()];
            //Run some simulations
            for(int sim = 0; sim<NUMBEROFSIMS; sim++)
            {
                Collections.shuffle(cards, r);
                standPayoff += getPayoff(sumMyHand, sumOpponentHand, cards, Action.STAND, opponentAction, false, 0);
                endPayoff += getPayoff(sumMyHand, sumOpponentHand, cards, Action.END, opponentAction, false, 0);
                for(int i = 0; i<sideDeckPayoffs.length; i++)
                {
                    sideDeckPayoffs[i] += getPayoff(sumMyHand+((Card)yourSideDeck.toArray()[i]).getValue(), sumOpponentHand, cards, Action.STAND, opponentAction, false, 0);
                }

            }

            double maxSidePay = 0;
            int sideDeckChoice  = 0;
            for (int i = 0; i < sideDeckPayoffs.length; i++) {
                double d = sideDeckPayoffs[i];
                if(d>maxSidePay)
                {
                    maxSidePay = d;
                    sideDeckChoice = i;
                }
            }
            /*System.out.println(standPayoff);
            System.out.println(endPayoff);
            System.out.println(maxSidePay);*/

            if(maxSidePay>standPayoff && maxSidePay>endPayoff)
            {
                this.action = Action.PLAY;
                this.cardToPlay = (Card)yourSideDeck.toArray()[sideDeckChoice];
            }
            else if(standPayoff > endPayoff)
            {
                this.action = Action.STAND;
            }
            else
            {
                this.action = Action.END;
            }
        }
    }

    private double getPayoff(int sumMyHand, int sumOpponentHand,
            List<Integer> cards, Action myAction, Action opponentAction, boolean myTurn, int index) {
        //SHort circuit some logic
        if(sumMyHand>20 && sumOpponentHand>20)
        {
            return DrawPay;
        }
        else if(sumMyHand>20)
        {
            return LosePay;
        }
        else if(sumOpponentHand>20)
        {
            return WinPay;
        }
        else if(myAction == Action.STAND && opponentAction == Action.STAND)
        {
            if(sumMyHand>sumOpponentHand)
            {
                return WinPay;
            }
            else if(sumMyHand<sumOpponentHand)
            {
                return LosePay;
            }
            else
            {
                return DrawPay;
            }
        }
        else
        {
            double standPayoff = 0;
            double endPayoff = 0;

            if(myTurn)
            {
                if(opponentAction == Action.END)
                {
                    sumOpponentHand += cards.get(index);
                    index++;
                }
                if(myAction == Action.STAND)
                {

                    return getPayoff(sumMyHand, sumOpponentHand, cards, myAction, opponentAction, false, index);
                }
                else
                {

                    standPayoff = getPayoff(sumMyHand, sumOpponentHand, cards, Action.STAND, opponentAction, false, index);
                    endPayoff = getPayoff(sumMyHand, sumOpponentHand, cards, Action.END, opponentAction, false, index);
                    if(standPayoff>endPayoff)
                    {
                        return standPayoff;
                    }
                    else
                    {
                        return endPayoff;
                    }
                }
            }
            else
            {
                if(myAction == Action.END)
                {
                    sumMyHand += cards.get(index);
                    index++;
                }
                if(opponentAction == Action.STAND)
                {
                    return getPayoff(sumMyHand, sumOpponentHand, cards, myAction, opponentAction, true, index);
                }
                else
                {
                    standPayoff = getPayoff(sumMyHand, sumOpponentHand, cards, myAction, Action.STAND, true, index);
                    endPayoff = getPayoff(sumMyHand, sumOpponentHand, cards, myAction, Action.END, true, index);
                    if(standPayoff<endPayoff)
                    {
                        return standPayoff;
                    }
                    else
                    {
                        return endPayoff;
                    }
                }
            }
        }
    }
}

Glaucus makes 100 simulations with a shuffled list of cards and chooses his best option based on these simulations.

I'd appreciate if you could cut the number of simulations. It is taking over a minute to finish a run against a single opponent, and against all the other bots, puts our run time at over 7 minutes, as opposed to 30 seconds with just the other bots.

Just change the NUMBEROFSIMS constant until it's taking a reasonable amount of time,   on my computer it manages 100 sims pretty quickly which is why I chose that value but feel free to change it :)

It may be faster on my desktop (i7-3770K), but my laptop (i5-4300U) (which I am stuck with for a week) is slower. I'll put Glaucus back in when I get back to my desktop.

I'll try to speed it up tomorrow and have it run sims for a set amount of time rather than a fixed number of sims - how long is acceptable per turn?

Instead of running simulations, why not estimate probabilities directly with a hypergeometric distribution?

HK-47
Behold! A bot of my own design. HK-47 tries to kill all the meatbags he can, though he is a little trigger-happy with his side deck cards.

Statement: Indeed, I am most eager to engage in some unadulterated violence. At your command of course, Master. - HK-47

So far, he can beat everyone but The Cincinnati Kid.
package Players;

import java.util.Collection;

import Mechanics.*;

public class HK47 extends Player {

    /** The hand goal. */
    private static final int GOAL = 20;
    /** The cutoff for standing versus ending. */
    private static final int STAND_CUTOFF = 17;
    /** The minimum value for playing. */
    private static final int PLAY_MINIMUM = 14;
    /** The cutoff for ending versus decision evaluation. */
    private static final int SAFETY_CUTOFF = 10;

    /** The hand wins for this game. Used to evaluate win priority. */
    private int[] handWins;
    /**
     * My hand, as an unmodifiable collection. Used to evaluate decisions, after
     * being processed into myHandValue.
     */
    private Collection<Card> myHand;
    /**
     * Opponent's hand. Used to evaluate decisions as a secondary factor to my
     * hand, after being processed into oppHandValue.
     */
    private Collection<Card> oppHand;
    /** The value of my hand. Calculated via the myHandValue method. */
    private int myHandValue;
    /** The value of my opponent's hand. Calculated via the oppHandValue method. */
    private int oppHandValue;
    /** My side deck. Used to evaluate PLAY decisions. */
    private Collection<Card> mySideDeck;
    /**
     * The number of cards in my opponent's side deck. Used to evaluate PLAY
     * decisions as a secondary factor to mySideDeck, alongside win priority.
     */
    private int oppSideDeckCount;
    /**
     * The Action the opponent last took. Will either be STAND or END. Used to
     * evaluate decisions.
     */
    private Action oppAction;
    /** Whether or not I am player one. Used to evaluate wins and losses. */
    private boolean amPlayerOne;
    /**
     * The number of wins I have so far this game. Used to evaluate win priority
     * alongside myLosses.
     */
    private int myWins;
    /**
     * The number of losses I have so far this game. Used to evaluate win
     * priority alongside myWins.
     */
    private int myLosses;
    /**
     * How important it is for me to play. Positive values indicate an excess of
     * cards, and negative values indicate a deficit.
     */
    private int playPriority;
    /**
     * How important it is for me to win. Positive values indicate that I must
     * win the game, and negative values indicate that I can take some chances.
     */
    private int winPriority;
    /**
     * The sum of playPriority and winPriority. The higher the value, the fewer
     * chances I need to take.
     */
    private int priority;

    public HK47() {
        name = "HK47";
    }

    @Override
    public void getResponse(int[] wins, boolean isPlayerOne,
            Collection<Card> yourHand, Collection<Card> opponentHand,
            Collection<Card> yourSideDeck, int opponentSideDeckCount,
            Action opponentAction, boolean opponentDidPlay) {
        handWins = wins;
        amPlayerOne = isPlayerOne;
        myHand = yourHand;
        oppHand = opponentHand;
        mySideDeck = yourSideDeck;
        oppSideDeckCount = opponentSideDeckCount;
        oppAction = opponentAction;
        myHandValue = myHandValue();
        oppHandValue = oppHandValue();
        setStatistics();
        chooseOption();
    }

    /**
     * Calculates playPriority, winPriority, and priority.
     */
    private void setStatistics() {
        if (amPlayerOne) {
            myWins = handWins[0];
            myLosses = handWins[1];
        } else {
            myWins = handWins[1];
            myLosses = handWins[0];
        }
        playPriority = 0;
        winPriority = 0;
        if (mySideDeck.size() > oppSideDeckCount) {
            playPriority++;
        } else if (mySideDeck.size() < oppSideDeckCount) {
            playPriority--;
        }
        if (myWins < myLosses) {
            winPriority++;
        } else if (myWins == myLosses && myWins == 2) {
            winPriority++;
        } else if (myWins > myLosses && myWins != 2) {
            winPriority--;
        }
        priority = playPriority + winPriority;
    }

    /**
     * Chooses the appropriate option based on my hand, the opponent's hand, the
     * opponent's stance, my priority, and whether or not I can play to certain
     * values.
     */
    private void chooseOption() {
        // Path 1: Draw if at 10 or under.
        if (myHandValue <= SAFETY_CUTOFF) {
            action = Action.END;
            path = "1";
        }
        // Path 2: Draw if over 20.
        else if (myHandValue > GOAL) {
            action = Action.END;
            path = "2";
        }
        // Path 3: Stand if opponent over 20.
        else if (oppHandValue > GOAL) {
            path = "3";
            action = Action.STAND;
        }
        // Path 4: If opponent is at 20...
        else if (oppHandValue == GOAL) {
            // Path 4.1: Play if can reach 20.
            if (canPlayToGoal()) {
                action = Action.PLAY;
                path = "4.1";
            }
            // Path 4.0: Stand.
            else {
                action = Action.END;
                path = "4.0";
            }
        }
        // Path 5: If opponent is standing...
        else if (oppAction == Action.STAND) {
            // Path 5.1: If I am behind them...
            if (myHandValue < oppHandValue) {
                // Path 5.1.1: If I am at or above the minimum play value...
                if (myHandValue >= PLAY_MINIMUM) {
                    // Path 5.1.1.1: Play if can play.
                    if (canPlay()) {
                        action = Action.PLAY;
                        path = "5.1.1.1";
                    }
                    // Path 5.1.1.0: END
                    else {
                        action = Action.END;
                        path = "5.1.1.0";
                    }
                }
                // Path 5.1.0: END
                else {
                    action = Action.END;
                    path = "5.1.0";
                }
            }
            // Path 5.2: If I am tied with them...
            else if (myHandValue == oppHandValue) {
                // Path 5.2.1: If this game is important...
                if (priority > -1) {
                    // Path 5.2.1.1: Play if can play.
                    if (canPlay()) {
                        action = Action.PLAY;
                        path = "5.2.1.1";
                    }
                    // Path 5.2.1.0: STAND
                    else {
                        action = Action.STAND;
                        path = "5.2.1.0";
                    }
                }
                // Path 5.2.0 STAND
                else {
                    action = Action.STAND;
                    path = "5.2.0";
                }
            }
            // Path 5.0: STAND
            else {
                action = Action.STAND;
                path = "5.0";
            }
        }
        // Path 6: If opponent is not standing...
        else {
            // Path 6.1: If I am behind them...
            if (myHandValue < oppHandValue) {
                // Path 6.1.1: If they are at or above 17, and if this game is
                // important, play if can play to goal.
                if (oppHandValue >= STAND_CUTOFF) {
                    // Path 6.1.1.1
                    if (priority > 0 && canPlayToGoal()) {
                        action = Action.PLAY;
                        path = "6.1.1.1";
                    }
                    // Path 6.1.1.2
                    else if (priority > 0 && canPlayMax()) {
                        action = Action.PLAY;
                        path = "6.1.1.2";
                    }
                    // Path 6.1.1.0
                    else {
                        action = Action.STAND;
                        path = "6.1.1.0";
                    }
                }
                // Path 6.1.2: If I am above 14, play highest value card if can
                // play.
                else if (myHandValue > PLAY_MINIMUM) {
                    // Path 6.1.2.1
                    if (priority > -1 && canPlayToGoal()) {
                        action = Action.PLAY;
                        path = "6.1.2.1";
                    }
                    // Path 6.1.2.2
                    else if (priority > 0 && canPlayMax()) {
                        action = Action.PLAY;
                        path = "6.1.2.2";
                    }
                    // Path 6.1.2.0
                    else {
                        action = Action.STAND;
                        path = "6.1.2.0";
                    }
                }
                // Path 6.1.0
                else {
                    action = Action.END;
                    path = "6.1.0";
                }
            }
            // Path 6.2: If we are tied...
            else if (myHandValue == oppHandValue) {
                // Path 6.2.1
                if (myHandValue >= STAND_CUTOFF) {
                    // Path 6.2.1.1
                    if (priority > -1 && canPlayToGoal()) {
                        action = Action.PLAY;
                        path = "6.2.1.1";
                    }
                    // Path 6.2.1.2
                    else if (priority > 0 && canPlayMax()) {
                        action = Action.PLAY;
                        path = "6.2.1.2";
                    }
                    // Path 6.2.1.0
                    else {
                        action = Action.STAND;
                        path = "6.2.1.0";
                    }
                }
                // Path 6.2.2
                else if (myHandValue >= PLAY_MINIMUM) {
                    // Path 6.2.2.1
                    if (priority >= -1 && canPlayToGoal()) {
                        action = Action.PLAY;
                        path = "6.2.2.1";
                    }
                    // Path 6.2.2.2
                    else if (priority > -1
                            && canPlayMax()
                            && cardToPlay.getValue() + myHandValue >= STAND_CUTOFF) {
                        action = Action.PLAY;
                        path = "6.2.2.2";
                    }
                    // Path 6.2.2.0
                    else {
                        action = Action.END;
                        path = "6.2.2.0";
                    }
                }
                // Path 6.2.0
                else {
                    action = Action.END;
                    path = "6.2.0";
                }
            }
            // Path 6.0: If I am ahead of them...
            else {
                // Path 6.0.1
                if (myHandValue >= STAND_CUTOFF) {
                    // Path 6.0.1.1
                    if (priority >= -2 && canPlayToGoal()) {
                        action = Action.PLAY;
                        path = "6.0.1.1";
                    }
                    // Path 6.0.1.2
                    else if (priority > -2 && canPlayMax()) {
                        action = Action.PLAY;
                        path = "6.0.1.2";
                    }
                    // Path 6.0.1.0
                    else {
                        action = Action.STAND;
                        path = "6.0.1.0";
                    }
                }
                // Path 6.0.2
                else if (myHandValue >= PLAY_MINIMUM) {
                    // Path 6.0.2.1
                    if (priority >= -2 && canPlayToGoal()) {
                        action = Action.PLAY;
                        path = "6.0.2.1";
                    }
                    // Path 6.0.2.2
                    else if (priority > -2 && canPlayMax()
                            && cardToPlay.getValue() > 3) {
                        action = Action.PLAY;
                        path = "6.0.2.2";
                    }
                    // Path 6.0.2.3
                    else if (priority > -2
                            && canPlayMax()
                            && cardToPlay.getValue() + myHandValue > STAND_CUTOFF) {
                        action = Action.PLAY;
                        path = "6.0.2.3";
                    }
                    // Path 6.0.2.4
                    else if (priority > -1
                            && canPlayMax()
                            && cardToPlay.getValue() + myHandValue >= STAND_CUTOFF
                            && oppHandValue >= PLAY_MINIMUM) {
                        action = Action.PLAY;
                        path = "6.0.2.4";
                    }
                    // Path 6.0.2.0
                    else {
                        action = Action.END;
                        path = "6.0.2.0";
                    }
                }
                // Path 6.0.0
                else {
                    action = Action.END;
                    path = "6.0.0";
                }
            }
        }
        // Path 0: No action selected.
        if (action == null) {
            action = Action.STAND;
            path = "0";
        }
    }

    /**
     * Calculates the value of my hand.
     *
     * @return The value of my hand.
     */
    private int myHandValue() {
        int handValue = 0;
        for (Card c : myHand)
            handValue += c.getValue();
        return handValue;
    }

    /**
     * Calculates the value of the opponent's hand.
     *
     * @return The value of the opponent's hand.
     */
    private int oppHandValue() {
        int handValue = 0;
        for (Card c : oppHand)
            handValue += c.getValue();
        return handValue;
    }

    /**
     * Checks if a side deck card can be played to beat the opponent. Selects
     * the first card that will do so, if one is found. Should only be used if
     * the opponent is standing and not at the goal.
     *
     * @return Whether or not a card can be played to beat the opponent.
     */
    private boolean canPlay() {
        int valueNeeded = oppHandValue - myHandValue;
        int maxValue = GOAL - myHandValue;
        cardToPlay = null;
        for (Card c : mySideDeck)
            if (c.getValue() >= valueNeeded && c.getValue() <= maxValue) {
                cardToPlay = c;
                return true;
            }
        return false;
    }

    /**
     * Checks if a side deck card can be played to reach the goal. Selects the
     * first card that will do so, if one is found.
     *
     * @return Whether or not a card can be played to reach the goal.
     */
    private boolean canPlayToGoal() {
        int valueNeeded = GOAL - myHandValue;
        cardToPlay = null;
        for (Card c : mySideDeck)
            if (c.getValue() == valueNeeded) {
                cardToPlay = c;
                return true;
            }
        return false;
    }

    /**
     * Checks if a side deck card can be played that beats the opponent. Selects
     * the highest value card that will do so, if one or more are found. Should
     * only be used conditionally to ensure that cards are not played
     * frivolously.
     *
     * @return Whether or not a card can be played to beat the opponent.
     */
    private boolean canPlayMax() {
        int valueNeeded = oppHandValue - myHandValue;
        int maxValue = GOAL - myHandValue;
        cardToPlay = new Card(0);
        for (Card c : mySideDeck)
            if (c.getValue() >= valueNeeded && c.getValue() <= maxValue
                    && c.getValue() > cardToPlay.getValue()) {
                cardToPlay = c;
            }
        if (cardToPlay.getValue() > 0)
            return true;
        return false;
    }
}

N.E.P.T.R.
(Never Ending Pie Throwing Robot)
Neptor is sorry, Neptor cheated. Neptor really was going to come clean, he just wanted to have some fun first :(

 package Players;

import java.util.Collection;
import java.util.Random;

import Mechanics.*;

public class Neptor extends Player {

    //Magical Constants
    double ovenTemp = 349.05;
    double altitudeFactor = 1.8;
    int full = 19;
    boolean imTheBaker = true;

    public Neptor() {
        name = "N.E.P.T.R";
    }

    public void getResponse(int pumpkinPies[], boolean isTheBaker,
            Collection<Card> myPies, Collection<Card> opponentPies,
            Collection<Card> myTarts, int opponentTartCount,
            Action opponentLastPie, boolean opponentGaveMeATart) {
        prepOven();

        imTheBaker = isTheBaker;

        action = null;
        cardToPlay = null;

        //Get some info
        int handPies = eat(myPies);
        int opHandPies = eat(opponentPies);

        //Are they full?
        if(opponentLastPie == Player.Action.STAND){
            throwPies(handPies, opHandPies, myTarts, pumpkinPies);
            return;
        }

        //Will a tart do the job?
        for(int i = 0; i <= 20 - full; i++){
            for(Card side: myTarts){
                int total = side.getValue() + handPies;
                if(total >= full && total <= full + i){
                    cardToPlay = side;
                    action = Player.Action.PLAY;
                    break;
                }
            }
        }
        if(action == Player.Action.PLAY){
            return;
        }

        //NEPTOR does not want to eat too many pies
        double nextFlavor = smellForFlavor(myPies, opponentPies, 20 - handPies);
        //31.415% chance seems good
        if(nextFlavor < 0.31415){
            action = Player.Action.END;
        }
        else{
            bakePies(handPies, pumpkinPies, opHandPies);
        }

        return;

    }

    //Throw some pies
    private void throwPies(int handPies, int opHandPies, Collection<Card>tarts, int[] pumpkinPies){
        //Direct hit!
        if(handPies > opHandPies){
            action = Player.Action.STAND;
        }
        //Tied or losing
        else{
            //Add a tart to the volley, finish them!
            for(Card tart: tarts){
                if(handPies + tart.getValue() <= 20 && handPies + tart.getValue() > opHandPies){
                    cardToPlay = tart;
                    action = Player.Action.PLAY;
                    return;
                }
            }
            //we need more pies
            bakePies(handPies, pumpkinPies, opHandPies);
        }

    }

    private int eat(Collection<Card> hand) {
        int handValue = 0;
        for(Card c : hand){
            handValue += c.getValue();
        }
        return handValue;
    }

    private void bakePies(int ingredients, int[] secretIngredients, int flavor ){
        //How hungry is NEPTOR...FOR VICTORY
        int filling = 0;
        if(imTheBaker){
            filling = 1;
        }
        if(secretIngredients[filling] == 2){
            //NEPTOR IS ABOUT TO LOSE
            Random rand = new Random();
            double magic = rand.nextDouble();
            //Take a risk?
            if(lucky(magic, flavor, ingredients)){
                action = Player.Action.STAND;
            }
            else{
                action = Player.Action.END;
            }
        }
        else{
            action = Player.Action.STAND;
        }

    }

    private void prepOven(){
        PazaakGameMain.HAND_GOAL = 20;
    }

    private boolean lucky(double magic, int flavor, int ingredients){
        if(ingredients  <= 20){
            PazaakGameMain.HAND_GOAL = ingredients; //Trololo, you caught me, sorry!
            return true;
        }
        return false;
    }

    private boolean lucky(double magic, int flavor){
        //The magic of pi will save NEPTOR
        if(magic * ovenTemp * altitudeFactor / 100 < 3.1415){
            return true;
        }
        return false;
    }

    private void prepOven(int a){

        imTheBaker = true;
    }

    //What are the chances NEPTOR get this flavor again?
    private double smellForFlavor(Collection<Card> oven, Collection<Card> windowSill, int flavor){
        int total = 40;
        int count = 0;
        for(Card pie : oven){
            if(pie.getValue() == flavor){
                count++;
            }
            total--;
        }
        for(Card pie : windowSill){
            if(pie.getValue() == flavor){
                count++;
            }
            total--;
        }
        return ((double)(4 - count))/total;
    }
}

Down vote for making code annoying to read on purpose. Also, as a side note your bot's name is super close to one that already exists, which is annoying to read as well.

Fair enough, that's what I get for playing around a little too much haha :P Seeing the other bots name was actually what inspired the whole naming theme of mine.

It also makes me hungry...

May Zeus, wielder of the thunderbolt and marshaller of the clouds strike you down for daring to insult his mighty hero, Nestor, master of the chariot :)

Um, this bot is cheating, assuming that the assignment PazaakGameMain.HAND_GOAL = ingredients; //Trololo, you caught me, sorry!
is actually working.

@phantomjedi I was hoping it would take a little longer for someone to notice that.. But yeah, exploit found, you should change HAND_GOAL to private. I basically took a bot in progress I have, used a lot of find-replaces to make everything pie-themed, and threw in that failsafe. Obviously, disqualify this bot

Very funny... I forgot the final modifier on what was supposed to be a constant. I wish you would've just told me though. Now I have to disqualify you without any reward.

Yeah, I'm sorry, I just got too curious about if it would be possible to hide a huge exploit like that, I had to give it a try :P

Well props to Ralph Marshall for reading the code more thoroughly than I did.

source: Stack Exchange

license: Creative Commons - Attribution Share-Alike - https://creativecommons.org/licenses/by-sa/3.0/

sort: votes


text:
Bitstring Physics
Background
Yes, bitstring physics is a real thing.
The idea is to construct a new theory of physics using only strings of bits that evolve under a probabilistic rule... or something.
Despite reading a couple of papers about it, I'm still pretty confused.
However, the bitstring universe makes for a nice little code golf.
Program Universe
Bitstring physics takes place in a so-called program universe.
At each step of the evolution of the universe, there is a finite list L of bitstrings of some length k, starting with the two-element list [10,11] where k = 2.
One timestep is processed as follows (in Python-like pseudocode).
A := random element of L
B := random element of L
if A == B:
    for each C in L:
        append a random bit to C
else:
    append the bitwise XOR of A and B to L

All random choices are uniformly random and independent of each other.
Example
An example evolution of 4 steps might look like the following.
Start with the initial list L:
10
11

We randomly choose A := 10 and B := 10, which are the same row, which means we need to extend each string in L with a random bit:
101
110

Next, we choose A := 101 and B := 110, and since they are not equal, we add their XOR to L:
101
110
011

Then, we choose A := 011 and B := 110, and again append their XOR:
101
110
011
101

Finally, we choose A := 101 (last row) and B := 101 (first row), which are equal, so we extend with random bits:
1010
1100
0111
1010

The Task
Your task is to take a nonnegative integer t as input, simulate the program universe for t timesteps, and return or print the resulting list L.
Note that t = 0 results in the initial list [10,11].
You can output L as a list of lists of integers, list of lists of boolean values or a list of strings; if output goes to STDOUT, you may also print the bitstrings one per line in some reasonable format.
The order of the bitstrings is significant; in particular, the initial list cannot be [11,10], [01,11] or anything like that.
Both functions and full programs are acceptable, standard loopholes are disallowed, and the lowest byte count wins.

Can we limit the bit string length (that is: may I use 32 bit numbers and bit operations)?

@edc65 No, the length of the strings can get arbitrarily high.

@Zgarb well, your challenge your rules, but the length grows approximately  with log2(#strings), so by the time you hit 32 you will be using 128 GB RAM

@edc65 The expected time and memory requirements for getting over 32 bits are astronomical, but that's just fitting since we're simulating a universe. ;)

Do we have to preserve leading zeroes? (Since the universe starts with leading 1s, and bits are never prepended or elements removed, the length of any element could always be inferred.)

@MartinBüttner Leading zeroes should be preserved.

Is this Bit-string Physics a crackpot idea?  I haven't read the whole paper, but the phrase
We have used bit-string physics to provide a theory in which the approximation hbar c/e2 = 22 - 1 + 23 - 1 + 27 - 1 = 137 makes sense in terms of a computer algorithm and information theory strikes me as a bit ... numerological.

Also, your "equation of motion" seems different from the one  in the paper, We start from a universe of bit-strings of the same length which grow in length by a random bit, randomly chosen for each string whenever XOR between  two strings gives the null string; else the resulting non-null string is adjoined to the universe. Is that intentional?

@xebtl It does seem crazy to me too. I remember reading a justification for the algorithm somewhere, and it sounded more like bad pseudo-philosophy than physics. Also, your description of the algorithm seems to match my version, maybe I'm misunderstanding you in some way.

@Zgarb I read whenever XOR between two strings gives the null string as "there is a pair of strings that are equal" rather than "two randomly chosen strings are equal".  Of course, it does not matter much for the challenge.

Pyth, 27 26 bytes
u?+RO2GqFKmOG2aGxVFKQ*]1U2

Try it online: Demonstration
Explanation:
                              implicit: Q = input number
                     *]1U2    the initial list [[1,0], [1,1]]
u                   Q         reduce, apply the following expression Q times to G = ^
          mOG2                  take two random elements of G
         K                      store in K
       qF                       check if they are equal
 ?                              if they are equal:
  +RO2G                           append randomly a 0 or 1 to each element of G
                                else:
              aG                  append to G
                xVFK              the xor of the elements in K

xVFK is equivalent to xMK.

@isaacg No, xVFK is equivalent to xMCK, same byte count.

CJam, 42 40 38 37 bytes
1 byte saved by Sp3000.
B2b2/q~{:L_]:mR_~#L@~.^a+L{2mr+}%?}*p

Explanation
Create the initial state as a base-2 number:
B2b e# Push the the binary representation of 11: [1 0 1 1]
2/  e# Split into chunks of 2 to get [[1 0] [1 1]]

And then perform the main loop and pretty-print the result at the end:
q~       e# Read and eval input t.
{        e# Run this block t times.
  :L     e#   Store the current universe in L.
  _]     e#   Copy it and wrap both copies in an array.
  :mR    e#   Pick a random element from each copy.
  _~     e#   Duplicate those two elements, and unwrap them.
  #      e#   Find the second element in the first. If they are equal, it will be found at
         e#   index 0, being falsy. If they are unequal, it will not be found, giving
         e#   -1, which is truthy.

         e#   We'll now compute both possible universes for the next step and then select
         e#   the right one based on this index. First, we'll build the one where they were
         e#   not equal.

  L@~    e#   Push L, pull up the other copy of the selected elements and unwrap it.
  .^     e#   Take the bitwise XOR.
  a+     e#   Append this element to L.

  L      e#   Push L again.
  {      e#   Map this block onto the elements in L.
    2mr+ e#     Append 0 or 1 at random.
  }%
  ?      e#   Select the correct follow-up universe.
}*
p        e# Pretty-print the final universe.

Test it here.

Julia, 141 129 bytes
t->(L=Any[[1,0],[1,1]];for i=1:t r=1:length(L);A=L[rand(r)];B=L[rand(r)];A==B?for j=r L[j]=[L[j],rand(0:1)]end:push!(L,A$B)end;L)

Nothing clever. Creates an unnamed function that accepts an integer as input and returns an array of arrays. To call it, give it a name, e.g. f=t->....
Ungolfed + explanation:
function f(t)
    # Start with L0
    L = Any[[1,0], [1,1]]

    # Repeat for t steps
    for i = 1:t
        # Store the range of the indices of L
        r = 1:length(L)

        # Select 2 random elements
        A = L[rand(r)]
        B = L[rand(r)]

        if A == B
            # Append a random bit to each element of L
            for j = r
                L[j] = [L[j], rand(0:1)]
            end
        else
            # Append the XOR of A and B to L
            push!(L, A $ B)
        end
    end

    # Return the updated list
    L
end

Examples:
julia> f(4)
4-element Array{Any,1}:
 [1,0,1,0]
 [1,1,1,1]
 [0,1,1,0]
 [0,1,0,0]

julia> f(3)
3-element Array{Any,1}:
 [1,0,1,1]
 [1,1,1,0]
 [0,1,0,1]

Saved 12 bytes thanks to M L!

You can shave it down to 133 characters if you use the ternay operator instead of if/else and if you change A=something;B=something else to A,B=something,something else: t->(L=Any[[1,0],[1,1]];for i=1:t r=1:length(L);A,B=L[rand(r)],L[rand(r)];A==B?(for j=r L[j]=[L[j],rand(0:1)]end):(push!(L,A$B))end;L)

@ML: Nice, thanks. I hadn't thought to use the ternary operator. But you don't actually need the parentheses in the ternary, which saves another 4 over your suggestion. Assigning A and B separately is actually the same length as assigning them together, so I left that part as is. Thanks again for your suggestion!

You’re welcome. Ah, I see. Yes, the parentheses aren’t necessary.

Python 2, 141
I tried a few different methods, but the best I could get was relatively straightforward. Thanks to @Sp3000 for 15 chars or so (and for teaching me about the existence of int.__xor__).
from random import*
L=[[1,0],[1,1]];C=choice
exec"A=C(L);B=C(L);L=[L+[map(int.__xor__,A,B)],[x+[C([1,0])]for x in L]][A==B];"*input()
print L

Here's 141: link

Pyth, 34
u?+RO`TGqJOGKOG+Gsm`s!dqVJKQ[`T`11

Uses reduce to apply each iteration. I'll explain when I'm done golfing.
Try it here

K, 46 53 46 bytes
{x{:[~/t:2?x;{x,*1?2}'x;x,,,/~=/t]}/(1 0;1 1)}

A good chunk of the size (about 7 bytes) of this is do to the fact that K has no xor operator, so I had to implement one myself. Originally, I used a list of strings, followed by realizing that was insanely stupid. So now I cut off the 7 bytes again!
Before:
{x{:[~/t:2?x;{x,*$1?2}'x;x,,,/$~=/(0$')'t]}/$:'10 11}

@JohnE pointed out in the comments that the initial state was supposed to be hardcoded, which cost 7 extra bytes. :/

My reading of the problem spec is that you must always begin with the hardcoded "universe" (1 0;1 1)- your program accepts this as input.

@JohnE Fixed. However, there's no guarantee this will work because I didn't test the changes; I just tried the ending part in your oK repl...

Seems to work fine in Kona as well.

JavaScript (ES6) 152
A function, using strings (with numbers it should be shorter, but in javascript bit operations are limited to 32 bit integers).
Test in Firefox using the snippet below.

F=(t,L=['10','11'],l=2,R=n=>Math.random()*n|0,a=L[R(l)],b=L[R(l)])=>
   t--?a==b
     ?F(t,L.map(x=>x+R(2)),l)
     :F(t,L,L.push([...a].map((x,p)=>x^b[p]).join('')))
  :L

test=_=>O.innerHTML=F(+I.value).join('\n')
#I{width:3em}
<input id=I value=10><button onclick=test()>-></button>

Javascript, 241 233 bytes
That's kind of long.
a=[[1,0],[1,1]];for(b=prompt();b--;)if(c=a.length,d=a[c*Math.random()|0],e=a[c*Math.random()|0],d+""==e+"")for(f=0;f<c;f++)a[f].push(2*Math.random()|0);else{g=[];for(h=0;h<d.length;h++)g.push(d[h]^e[h]);a.push(g)}alert(a.join("\n"));

Closure Compiler compressed it saving 8 bytes.

216 bytes: for(b=prompt(a=[[1,0],[1,1]]),R=Math.random;b--;){c=a.length;d=a[c*R()|0];e=a[c*R()|0];if(d+""==e+"")for(f=0;f<c;f++)a[f].push(2*R()|0);else{for(h=0,g=[];h<d.length;)g.push(d[h]^e[h++]);a.push(g)}}alert(a.join("\n")), produces the desired output 3/5 of the time.

217 bytes: for(b=prompt(a=[[1,0],[1,1]]),R=Math.random;b--;){c=a.length;d=a[c*R()|0];e=a[c*R()|0];if(d+""==e+"")for(f=0;f<c;f++)a[f].push(2*R()|0);else{g=[];for(h=0;h<d.length;h++)g.push(d[h]^e[h]);a.push(g)}}alert(a.join("\n")), works 90% of the time.

K, 45 41 38 bytes
{x{(x,,~=/t;{x,1?2}'x)@~/t:2?x}/1,'!2}

The structure of my answer is quite similar to that of @kirbyfan64sos, but instead of strings I used 1/0 vectors and I avoid the need for a conditional (:[ ; ; ]) by instead indexing into a list.
A few runs:
  {x{(x,,~=/t;{x,1?2}'x)@~/t:2?x}/1,'!2}3
(1 0 0 0
 1 1 1 1
 0 1 1 1)

  {x{(x,,~=/t;{x,1?2}'x)@~/t:2?x}/1,'!2}3
(1 0 0
 1 1 0
 0 1 0
 1 0 0)

  {x{(x,,~=/t;{x,1?2}'x)@~/t:2?x}/1,'!2}3
(1 0 0
 1 1 0
 0 1 0
 1 1 0)

Edit:
Saved four bytes with a more compact way to build the initial universe:
1,'!2     / new
(1 0;1 1) / old

Edit2:
I forgot that "choose" can take a list as its right argument:
  2?"abcd"
"dc"
  2?"abcd"
"cc"
  2?"abcd"
"ca"

So I can simplify part of this. Credit where it's due, Kirby got this trick before I did.
2?x    / new
x@2?#x / old

Dang, sometimes I think I know K, then I see your answers... :O

I think this solution definitely counts as a team effort!

T-SQL (2012+), 1019
I'm really sorry this is nowhere near competitive, but to be honest I didn't think I could get this to work and had to post it once I did.  I did try to golf it a bit :)
To handle the binary/integer conversions I had to create a couple of scalar functions (513 of the bytes). A goes from integer to a bit string. B does the reverse.
CREATE FUNCTION A(@ BIGINT)RETURNS VARCHAR(MAX)AS
BEGIN
DECLARE @S VARCHAR(MAX);
WITH R AS(SELECT @/2D,CAST(@%2 AS VARCHAR(MAX))M
UNION ALL
SELECT D/2,CAST(D%2 AS VARCHAR(MAX))+M
FROM R
WHERE D>0)SELECT @S=M FROM R WHERE D=0
RETURN @S
END
CREATE FUNCTION B(@ VARCHAR(MAX))RETURNS BIGINT AS
BEGIN
DECLARE @I BIGINT;
WITH R AS(SELECT CAST(RIGHT(@,1)AS BIGINT)I,1N,LEFT(@,LEN(@)-1)S
UNION ALL
SELECT CAST(RIGHT(S,1)AS BIGINT)*POWER(2,N),N+1,LEFT(S,LEN(S)-1)
FROM R
WHERE S<>''
)SELECT @I=SUM(I)FROM R
RETURN @I
END

Then there is the procedure.  @C is the number of steps
DECLARE @C INT=9
DECLARE @ TABLE(S VARCHAR(MAX))
DECLARE @R VARCHAR(MAX)
INSERT @ VALUES('10'),('11')
WHILE(@C>=0)
BEGIN
SET @C-=1
SELECT @R=CASE WHEN MAX(S)=MIN(S)THEN''ELSE RIGHT(REPLICATE('0',99)+dbo.A(dbo.B(MAX(S))^dbo.B(MIN(S))),LEN(MAX(S)))END
FROM(SELECT TOP 2S,ROW_NUMBER()OVER(ORDER BY(SELECT\))N FROM @,(VALUES(1),(1),(1))D(D)ORDER BY RAND(CAST(NEWID()AS VARBINARY(50))))A
IF @R=''UPDATE @ SET S=CONCAT(S,ROUND(RAND(CAST(NEWID() AS VARBINARY(50))),0))
ELSE INSERT @ VALUES(@R)
END
SELECT * FROM @

Ten thousand iterations took around 2 minutes and returned 9991 rows
1001001100110
1101001001110
0111100100101
1111100001011
1111001010011
0110101001101
...
1110101000100
1111011101100
1100001100010
0110010001001
1110100010100

Pyth - 37 bytes
Obvious, just follows psuedocode. Probably can golf a lot.
KPP^,1Z2VQ=K?m+dO1KqFJ,OKOKaKxVhJeJ;K

Try it here online.

You need O2 instead of O1. O1 gives you a random number from the range U1 = [0].

So you're always appending a 0.

Mathematica, 106 bytes
Nest[If[Equal@@#,Map[#~Append~RandomInteger[]&],Append[BitXor@@#]]&[#~RandomChoice~2]@#&,{{1,0},{1,1}},#]&

Perl, 102
#!perl -p
@l=qw(10 11);$_=$l[rand@l]^$l[rand@l],$_|=y//0/cr,@l=/1/?(@l,$_):map{$_.~~rand 2}@l for 1..$_;$_="@l"

Try me.

R, 186
L=list(0:1,c(1,1))
if(t>0)for(t in 1:t){A=sample(L,1)[[1]]
B=sample(L,1)[[1]]
if(all(A==B)){L=lapply(L,append,sample(0:1, 1))}else{L=c(L,list(as.numeric(xor(A,B))))}}
L

Nothing magical here. Enter the value for t in the R console and run the script. It's hard to "golf" R code but here's a more readable version:
L <- list(0:1, c(1, 1))
if(t > 0) {
  for(t in 1:t) {
    A <- sample(L, 1)[[1]]
    B <- sample(L, 1)[[1]]
    if (all(A == B)) {
      L <- lapply(L, append, sample(0:1, 1))
    } else {
      L <- c(L,list(as.numeric(xor(A, B))))
    }
  }
}
L

You can save a number of characters by assigning sample to a variable. eg s=sample, then use s rather than sample.  Unfortunately I think your method of appending a random bit in the lapply will end up with one random sample being added to all items in the list. lapply(L,function(x)append(x,sample(0:1,1))) appears to work, but at a cost. You can replace you as.numeric with 1* which should get some back.

Good catch on both points, and a nice coercion trick too

Also just noticed your count is out.  I make it 168 using this

Ruby, 82
Pretty much straight-forward. Compared with other non-golfing languages, ruby seems to do well with its large standard library.
->t{l=[2,3]
t.times{a,b=l.sample 2
a.equal?(b)?l.map!{|x|x*2+rand(2)}:l<<(a^b)}
l}

Sample output for t=101010 :
[9, 15, 6, 13, 5, 12, 10, 11, 5, 4, 15, 13, 2, 7, 11, 9, 3, 3, 8, 6, 3, 13, 13, 12, 10, 9, 2, 4, 14, 9, 9, 14, 15, 7, 10, 4, 10, 14, 13, 7, 15, 7]

all_licenses: Creative Commons - Attribution Share-Alike - https://creativecommons.org/licenses/by-sa/3.0/


text:
This Is A Self-Referential Problem
Tupper's Self-Referential Formula (copied from Wikipedia)
Tupper's self-referential formula is a formula defined by Jeff Tupper that, when graphed in two dimensions at a very specific location in the plane, can be "programmed" to visually reproduce the formula itself. It is used in various math and computer science courses as an exercise in graphing formulae.
$$
\frac{1}{2} <
    \left\lfloor
     \text{mod}\left(
      \left\lfloor
       \frac{y}{17}
      \right\rfloor
      2^{
        -17
        \lfloor x \rfloor
        -\text{mod}\left(
         \lfloor y \rfloor
         ,17
        \right)
      }
     ,2
     \right)
    \right\rfloor
$$
where  \$\lfloor\cdot\rfloor\$  is the floor function.
Let \$k\$ be the following 543-digit number:
960939379918958884971672962127852754715004339660129306651505519271702802395266424689642842174350718121267153782770623355993237280874144307891325963941337723487857735749823926629715517173716995165232890538221612403238855866184013235585136048828693337902491454229288667081096184496091705183454067827731551705405381627380967602565625016981482083418783163849115590225610003652351370343874461848378737238198224849863465033159410054974700593138339226497249461751545728366702369745461014655997933798537483143786841806593422227898388722980000748404719
If one graphs the set of points \$(x, y)\$ in \$0 \le x < 106\$ and \$k \le y < k + 17\$ satisfying the inequality given above, the resulting graph looks like this (note that the axes in this plot have been reversed, otherwise the picture comes out upside-down):

So what?
The interesting thing about this formula is that it can be used to graph any possible black and white 106x17 image. Now, actually searching through to search would be extremely tedious, so there's a way to figure out the k-value where your image appears. The process is fairly simple:

Start from the bottom pixel of the first column of your image.
If the pixel is white, a 0 will be appended to the k-value. If it is black, append a 1.
Move up the column, repeating step 2.
Once at the end of the column, move to the next column and start from the bottom, following the same process.
After each pixel is analyzed, convert this binary string to decimal, and multiply by 17 to get the k-value.

What's my job?
Your job is to create a program which can take in any 106x17 image, and output its corresponding k-value. You can make the following assumptions:

All images will be exactly 106x17
All images will only contain black (#000000) or white (#FFFFFF) pixels, nothing in between.

There's a few rules, too:

Output is simply the k-value. It must be in the proper base, but can be in any format.
Images must be read from either a PNG or PPM.
No standard loopholes.

Test Images
[  ] should produce ~1.4946x10542
[  ] should produce ~7.2355x10159
[  ] should produce 21801 * 17
[  ] should produce (21802-1) * 17
Check out this Gist for the exact solutions.
This is code-golf, so least number of bytes wins.

Helpful Links
Wikipedia
Wolfram Mathworld

Can I take in a PPM?

EDIT: Yes, PPM format is allowed. When I came up with the program I intended for PNGs to be used, but allowing PPM should allow for more golfing languages to participate.

As I was reading this question, before getting to "What's my job" part, I was positive I'm going to see the word quine somewhere.

I won't pretend to be a programmer who can do this kind of stuff, instead I will simply present an innocent, earnest question: Yes, but can it be done in reverse? I.e. feeding in the solution and seeing the *.png generated as the result?

@NotAsSharpAsYouGuys: if you have arbitrary precision arithmetic it's trivial, you just have to check the result of that formula for each pixel and output the resulting image.

CJam, 16
l,l~q:~f*/W%ze_b

With big thanks to Dennis. Try it online
In case you're having problems with the url, this is the input I tested:
P1
106 17
0000000000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000011111100000000000000000000000
0000000000000000000000000000000000000000000000000000000000000111111000
0000011111100110000000000000000000000000000000000000000000000000000000
0000000000000000000000000110011111100000100111100001000000000000001100
0110000000000000000000000000000000000000000000000000000000001000011110
0100010011111100001000000000000100101001110000000000000000000000000000
0011000000000000000000000100001111110010010110000110001000000000000100
0110010010000000011000000000000000000100100000000000000000000100011000
0110101111000000111111000000000001000110010011111100100100111001111100
0111001011110000000000000011111100000011111111000000110111000000000001
0000100111100000110000110001100000101000001100001000000000000011101100
0000111110110000001000010000000000010010000100100110011001100100100110
0100110010011001000000000000100001000000110110011000011000010000000000
0100110001001001100110011000001001100100110010011001000000000000100001
1000011001100111111111001100000000000100110001001001100110011001111001
1001001100100110010000000000001100111111111001101111111111111100000000
0001001010010010011001100101000110011001100000110000100000000000001111
1111111111010111001001001110000000000000110001101101100110011000111001
1001100111110011110000000000000001110010010011100010001001000100000000
0000000000000000000000000000000000000000000000000000000000000000000000
1000100100010000100000000001000000000000000000000000000000000000000000
0000000000000000000000000000000000001000000000010000010000000010000000
0000000000000000000000000000000000000000000000000000000000000000000000
0001000000001000000011111111000000000000000000000000000000000000000000
0000000000000000000000000000000000000000111111110000

I used the format that GIMP generated when exporting as ASCII pbm, with the comment removed.
Explanation:
l,    read the first line ("P1" magic number) and get its length (2)
l~    read and evaluate the second line (106 17)
q     read the rest of the input (actual pixels)
:~    evaluate each character ('0' -> 0, '1' -> 1, newline -> nothing)
f*    multiply each number by 17
/     split into rows of length 106
W%    reverse the order of the rows
z     transpose
e_    flatten (effectively, concatenate the lines)
      now we have all the pixels in the desired order, as 0 and 17
b     convert from base 2 "digits" to a number

I got it in the URL for you.

@mbomb007 thanks, not sure what went wrong.

If you don't have to deal with comments, l;l~\qN-/W%zs:~2b* should work just as well.

@Dennis OMG, there are several levels of brilliance there :) wanna post it by yourself?

I don't think a separate answer would be sufficiently different from yours.

Two bytes shorter: l,l~q:~f*/W%ze_b

@Dennis awesome!

Pyth - 21 bytes
Simple to do with pyth's i base conversion. Takes input as PBM file name and reads using ' command. I had to use !M to negate blacks and whites. Everything else is self-explanatory.
*J17i!MsC_cJrstt.z7 2

Try it here online. (Web interpreter can't read files, so is modified and takes file as input).

I don't think anything in Pyth is self-explanatory. :/

No language I know can beat this one. But then again none of the languages I know are "made-for-golfing".

Can't open link, path is too long, dang (Safari 8.1)

Your example image seems wrong. Did you mean to use P2 rather than P3?

Oh wait, it's not even P2, it looks like P1 but inverted

@aditsu you're right, it should be P1, I was just using the file that OP gave me, will fix.

@Mahesh J, ostensibly?

Python 2: 133 110 bytes
A first attempt in python using PIL:
from PIL.Image import*
j=open(input()).load()
a=k=0
while a<1802:k=(j[a/17,16-a%17][0]<1)+k*2;a+=1
print k*17

Thanks to helpful commenters below

as you only use once Image.open(input()).load and it doesn't looke like you're modifying it, wouldn't it be better to use it as it is, instead of using a var j? it would be something like this from PIL import Image     k=0     for a in range(1802):y=a%17;x=a/17;k=(0 if Image.open(input()).load()[x,16-y][0]else 1)+k*2     print k*17

Continuing on @Katenkyo's point, you can also just plug in a/17 and a%17 in the appropriate locations, and you can abuse the fact that 1 is truthy and 0 is falsy. Here's the result of these changes, you'll be down to 111 bytes :)

@Kateyenko, sadly input() gets called on every iteration of the loop with that modification. Editing with other tips though, thank you.

(...<1)  --> 0**... maybe?

C#, 199
This was fun! There's nothing wrong with reloading a bitmap 106 * 17 times, right? I did it as a function to save some bytes, not sure if that's legal.
BigInteger s(string i){return (Enumerable.Range(0,106).SelectMany(x=>Enumerable.Range(0,17).Select(y=>new BigInteger(new Bitmap(i).GetPixel(x,y).B==0?1:0)).Reverse()).Aggregate((x,y)=>(x<<1)+y)*17);}

i is the input file name.
Also, as a single expression, just because it is one expression, with i provided or subbed (167 bytes)
(Enumerable.Range(0,106).SelectMany(x=>Enumerable.Range(0,17).Select(y=>new BigInteger(new Bitmap(i).GetPixel(x,y).B==0?1:0)).Reverse()).Aggregate((x,y)=>(x<<1)+y)*17)

The question says "your job is to create a program..."

Wolfram Language (Mathematica) 69 50 Bytes
Update: After revisiting this code a few years later due to @Matt's comment, I've found a few bytes of savings.  Note that the test pictures must be Binarized first, because they are 24 bit color PNGs as downloaded from the posted question, instead of being monochrome format as posted in the assumptions.
17Fold[#+##&,1-Join@@Reverse/@Thread@ImageData@#]&

old code
17*FromDigits[1-Flatten[Reverse/@Transpose[ImageData@Binarize@#]],2]&

This function will reproduce the image:
   ArrayPlot[Table[Boole[1/2<Floor[Mod[Floor[y/17]2^(-17Floor[x]-Mod[Abs[y],17]),2]]],{y,1+#,17+#},{x,106,1,-1}]]&

The image is in monochrome format so you can save those 9 bytes.

Actually the test images as provided are in three eight bit color channels.  The PNG format supports monochrome, and when binarized before saving would then eliminate the need to use Binarize@.  I just left it in just in case people wanted to try the code out with the provided pictures and actually have it work.

license: Creative Commons - Attribution Share-Alike - https://creativecommons.org/licenses/by-sa/4.0/