by Lee Spector (lspector)
My first version of code to support the blackjack tournaments that we discussed in class is here (Updated several times: here. See comments below.)
If you grab it and run it as-is it will play a 100-game tournament between two simple strategies, one of which asks for another card (a “hit” — sorry if I’m not using exactly the right casino terminology) whenever its cards sum to less than 15, and one of which asks for another card whenever its cards sum to less than 18. Neither even looks at the cards that have been dealt to the other players, and neither even considers using an ace (1) as 11 rather than 1. So they’re not very smart, but they run and you could try to beat them. And let me know if you find any bugs.
Recall that your job is to write your strategy as a “hit function” that takes two arguments, the first of which will be the list of the cards in your own hand (numbers from 1 to 10, with all face cards being 10) and the second of which will be a list of lists, each of which will contain all of the up-facing cards of another player. (Recall that in blackjack each player also has a down-facing card — you can see yours, but not anyone else’s.) So for example if I’ve been dealt a 4 and an ace so far then the first argument to my hit function will be (4 1). If there are two other players, one of whom has been dealt a 3 (face down) and a queen (face up), and the other of whom has been dealt a 7 (face down) and an ace (face up) then the second argument to my hit function will be ((10) (1)). Notice that I don’t see the other players’ down cards. The hit function should return #t if you want another card and #f otherwise.
In class we said that each student would send just a lambda expression for his or her hit function to the server, but it occurs to me now that you may want to use a bunch of utility functions in your hit functions. It would be possible to define all of these within your hit function (using let or let-rec), but I think we might just let you all do a “sendcode” with all of your utility functions before you send your hit function, and we might ask you to send a define expression that gives your hit function a name. If you’re going to do this then it’d be nice if you gave your utility functions weird names so that they’re not likely to conflict with anyone else’s. Ian and I will work out something for the “glue” to connect your code to the server, and we’ll either post something more about it here or just go over it in class. But in the meantime you could experiment with the code and try to come up with a good strategy.
Update: I wonder if we shouldn’t make it use only a single deck, since we’re playing only single games between shuffles. A single game doesn’t allow one to see many cards, unless there are a lot of players.
Update 2: I just found and fixed a bug. Make sure you use the version containing the following note and explanation:
;; Update 20091125: fixed bug that treated wrong card of opponents' hands ;; as the down card (first card in hand is down card, but ;; prev version consed new cards onto front)
Update 3: Fixed another bug:
;; Update 20091201: fixed bug that allowed busted agents to keep getting cards
;; Update 20091202: fixed bug that allowed agents to have only one card