High-stakes Quasar: AKA, free money in Mass Effect

This is documented other places on the web, but I had fun with it, so I figured I'd write it up.


I've been replaying Mass Effect 1 recently. I noticed that in a club called Flux on the Citadel, there's a casino game called "Quasar". It's essentially a blackjack style game; you want to get as close to 20 points as possible without going over, and each round you can either "stay" and cash out for a known cash prize, or you can "hit" to add a random number of points to your score, but then you risk busting. The minor novelty to Quasar is that when you hit you can choose to add either 1-8 points or 4-7 points to your score.

To be more concrete, the game costs 200 credits to play, and has the following payouts:

0-14: 0
15:  50
16: 100
18: 250
17: 200
19: 300
20: 400
21+:  0


I played a few rounds and lost, when I realized that I'm a programmer! I can make the compute figure out the optimal strategy, and whether it's worth playing!

I whipped up a little dynamic programming algorithm, and it turns out casino owners in Mass Effect aren't very savvy businessmen. Assuming all the dice rolls are uniform, here's what the optimal strategy looks like:

0: hit 4-7 244.60
1: hit 4-7 244.61
2: hit 4-7 238.44
3: hit 1-8 235.73
4: hit 1-8 237.23
5: hit 1-8 242.82
6: hit 4-7 247.19
7: hit 4-7 251.15
8: hit 4-7 237.30
9: hit 1-8 218.13
10: hit 1-8 221.67
11: hit 1-8 230.37
12: hit 1-8 249.22
13: hit 4-7 287.50
14: hit 4-7 237.50
15: hit 4-7 175.00
16: hit 1-8 143.75
17: stay 200.00
18: stay 250.00
19: stay 300.00
20: stay 400.00


The first column is your score, the middle is the action you should take, and the last is your expected return. As you can see, the odds are pretty freaking good. You generally start out at somewhere between zero and five points, where the expected profit is greater than 30 credits per round.

Following this strategy, I went back to the machines and quickly won 1000 credits. Finally that programming knowledge is paying off!

Anyways, here's the code for the curious:

def payout(n):
    if n <= 14 or n > 20:
        return 0
    return {
        15: 50,
        16: 100,
        17: 200,
        18: 250,
        19: 300,
        20: 400
        }[n]

def avg(x):
    return float(sum(x)) / len(x)

res = dict()

def expected(n):
    if n > 20:
        return ('stay', 0)

    if n in res:
        return res[n]

    stay = payout(n)

    hit1 = avg([expected(n + x)[1] for x in range(1, 9)])
    hit2 = avg([expected(n + x)[1] for x in range(4, 8)])

    m = max([stay, hit1, hit2])

    if m == stay:
        res[n] = ('stay', m)
    elif m == hit1:
        res[n] = ('hit 1-8', m)
    elif m == hit2:
        res[n] = ('hit 4-7', m)

    return res[n]

expected(0)

for k, (a, e) in res.iteritems():
    print '%d:\t%s\t\t%0.2f' % (k, a, e)

Sleep Metronome, now free in the Android Market!

A few weeks ago I posted about a little Python script I wrote to help me get to sleep. I'm pleased to say that I've been using it every night since and it's been working great for me.

After a couple weeks of setting up my laptop next to me before bed, I decided that it'd be way better as an Android app, so I wrote it up. Now you too can experience the clicking sensations: Sleep Metronome

Try it out! Leave comments! Make reviews! Share with friends!

I was very impressed with how pleasant the experience of writing an app was. I went from having not touched a single line of Android code to having a published app in the space of 24 hours. A++ would code again.

The code is available at http://android-sleep-metronome.googlecode.com. Patches are welcome!

Slowing metronome

A few nights ago I was wired and restless and couldn't sleep, and I wondered if there was something I could listen to that would help me chill out. I searched around the Android app store for sleep-related apps, but most of them just played noises of crickets or rain or new age music and it wasn't helping. I wanted something simple and rhythmic I could focus on. Perhaps a metronome.

But what tempo? Too fast and it'd keep me wired. Too slow and I'd be impatient and annoyed. So I had an idea: how about a metronome that slows down gradually over a long time period?

I eventually got to sleep, but I kept playing with the idea. Yesterday I decided to write it up. I grabbed my notebook and used the power of calculus to find a formula for the frequency of the metronome over time. The key condition was that I wanted the period between ticks to get longer by a fixed N% with each tick, so the change would be as uniform as possible.

Here's the formula for the frequency at time t, given that the metronome starts with frequency S and ends with frequency E after D seconds:



So I whipped up a little script using pygame and when going to sleep last night I set it to tick for 15 minutes, starting at 90 beats per minute, ending at 12 bpm. I don't remember when it stopped, so that's a good sign! Try it out and let me know if it works!

Download the code.

 #!/usr/bin/env python  
 #  
 # Copyright 2011 Hunter Freyer (yt@hjfreyer.com)  
 #  
 # Licensed under the Apache License, Version 2.0 (the "License");  
 # you may not use this file except in compliance with the License.  
 # You may obtain a copy of the License at  
 #  
 #  http://www.apache.org/licenses/LICENSE-2.0  
 #  
 # Unless required by applicable law or agreed to in writing, software  
 # distributed under the License is distributed on an "AS IS" BASIS,  
 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  
 # See the License for the specific language governing permissions and  
 # limitations under the License.  
   
 """A metronome with a gradually changing tempo.  
   
 Usage:  
   
  python metronome.py <duration> <bpm_at_start> <bpm_at_end>.  
   
 For example, a metronome invoked with the following:  
   
  python metronome.py 900 120 12  
   
 Would tick for 15 minutes, slowing from a starting beat of 2 beats per  
 second to an ending rate of one beat every 5 seconds.  
   
 Requires pygame.  
 """  
   
 import pygame  
 import math  
   
   
 def tick(duration, start_rate, end_rate):  
   pygame.mixer.pre_init(44100, -16, 2, 512)  
   pygame.init()  
   
   def rate(t):  
     return (start_rate*end_rate*duration)/(  
       t*(start_rate-end_rate) + end_rate*duration)  
   
   
   clock = pygame.time.Clock()  
   time = 0  
   tick_sound = pygame.mixer.Sound('SoMe TeXt To PlAy')  
   print "Control-C to exit."  
   
   while True:  
     if time > duration:  
       return  
     tick_sound.play()  
     time += clock.tick(rate(time)) / 1000.0  
   
   
 def main(argv):  
   if len(argv) != 4:  
     print __doc__  
     return -1   
   duration = float(argv[1])  
   start = float(argv[2]) / 60  
   end = float(argv[3]) / 60  
   tick(duration, start, end)  
   
 if __name__ == '__main__':  
   import sys  
   main(sys.argv)  

Contagious negativity

One asshole can ruin a birthday party, but a single optimist doesn't have much of a shot at warming up a group of feuding friends. A conversation between a depressed person and a cheery one is more likely to leave both parties sad than happy. Why is that? Why is it so much harder to spread goodwill than negativity?

A cynic might argue that a pessimist spreads their viewpoint more easily because they're simply exposing the undeniable truth that the world is an awful place. I don't really buy that. Regardless of whether the world is awful or not, I feel like our tendency to take on the misery of jerks and reject the high-spirits of the merry runs deeper than any rational assessment of the world.

I was discussing this with a friend, and a result from game theory came to mind.

It has to do with evolution of strategies in the Prisoner's Dilemma. I'll let Wikipedia summarize the game:
Two suspects are arrested by the police. The police have insufficient evidence for a conviction, and, having separated the prisoners, visit each of them to offer the same deal. If one testifies for the prosecution against the other (defects) and the other remains silent (cooperates), the defector goes free and the silent accomplice receives the full 10-year sentence. If both remain silent, both prisoners are sentenced to only six months in jail for a minor charge. If each betrays the other, each receives a five-year sentence. Each prisoner must choose to betray the other or to remain silent.[...] How should the prisoners act?
The game is interesting because it's conceptually similar to many kinds of interpersonal interactions: if two people cooperate, they both do well; if one cooperates and the other defects, the defector does even better, and the other guy gets screwed; but if no one cooperates, nothing good ever comes of it. By studying the abstract game, we can learn something about relationships in the concrete world. So the question is, if a bunch of individuals play this game over and over, what strategy works the best?

The answer is (of course) that it depends on what everyone else is doing. In a room full of constant defectors, being cooperative isn't going to get you very far. Conversely, if everyone you meet is going to cooperate with you no matter what, defecting seems like a pretty appealing idea.

In fact, in a scheme where folks change their strategies over time, if you start with everyone cooperating, pretty soon someone will figure out to always defect, and before you know it, you've got a room full of back-stabbers, all a lot worse off than when they were cooperating. Although everyone will agree things were better when they cooperated, each individual became infected by their neighbors' refusal to play nice.

What about the reverse? In a population full of defectors, is there any hope of rediscovering cooperation? One strategy a would-be cooperator can employ is to initially cooperate, but start defecting as soon as their opponent defects on them. This is a very hard road to take - assuming you're the only one who ever cooperates, you'll simply get screwed the first time you play with someone, and after that things go exactly as if you'd defected to begin with. In this case, initially cooperating is strictly worse.

However, if two such idealists persevere long enough to meet, they'll start by cooperating and will continue to reap the substantial rewards of cooperation every time they interact. If a few members of the population take this leap of faith to tentatively play nice, the payoff can more than make up for occasionally being the sucker. The defectors can then see how well the others are doing, and slowly adapt to their strategy until everyone is cooperating again. Then, of course, it all starts over.

The point is that when everyone cooperates, it's both completely rational and obvious to start defecting, and once one person goes bad, everyone follows suit. To be hopeful in an overwhelmingly negative setting is both irrational and quite painful in the short term, and even with a small handful of cooperators in the room it's not necessarily worth it to switch strategies. Building back that mutual trust is a slow process, if it happens at all.

Something strikes me as similar between this evolution of strategy and our tendency to absorb the negative and to deflect the positive. An individual's bad day can spread to friends, family, and coworkers almost immediately, but a fighting couple can spend a week stonewalling each other when internally all they really want is to get along - but it's really hard to do so. It's fascinating how much more difficult restoring that state of cooperation is compared to disrupting it in the first place.

Now introducing: Marry Fuck Kill!

My roommate, Michael James Kelly and I have produced a new Interactive App for the Interwebs: Marry Fuck Kill!

The parlor game upon which it is based is as old as time itself: given three "things", you must choose one to marry, one to fuck, and one to kill. Now, for the first time ever, you can pose these dilemmas to users the world over, and waste countless hours voting on MFKs from others as well!

Check it out: http://www.marryfuckkill.com

Suggestions in the comments, or email me.

kthxbai,
Hunter