Spielprogrammierung mit Java
HomeAufgabenDruckenJava-Online

St. Petersburg-Paradox

In einem Glücksspiel, wird in jeder Runde ein Einsatz von Fr. 5.- verlangt. Eine nicht gezinkte Münze wird solange geworfen bis zum ersten Mal "Zahl" erscheint. Dies beendet die Runde. Der Gewinn richtet sich nach der Anzahl der geworfenen Münzen. Wird die Runde bereits nach einem Wurf beendet, so verliert der Spieler den ganzen Einsatz. Bei zwei geworfenen Münzen gewinnt er 1 Franken, bei 3 Würfen 2 Franken, bei 4 Würfen 4 Franken usw. Der Gewinn verdoppelt sich also mit jedem geworfenen Kopf. Man gewinnt 2 hoch k−1 Fr, wenn beim k-ten mal Zahl geworfen wurde. Ursprünglich wurde das Spiel in einem Casino in St. Petersburg gespielt.

Spielt man einige Runden, so fällt auf, dass man in der Regel viel Geld verliert. Der theoretische Erwartungswert des Gewinns ist aber positiv und sogar unendlich gross. Das bedeutet, dass sich das Spiel bei jedem noch so hohen Einsatz lohnt, gegeben genügend Zeit und Kapital.

 


Programmcode:

// Petersburg.java

import ch.aplu.jgamegrid.*;
import java.awt.*;
import ch.aplu.util.*;

public class Petersburg extends GameGrid
{
  public int totalProfit;
  public int loss;
  public final int entry = 5;
  public int maxWin;
  private final GGBackground bg;
  String info =
      "This is a simulation of the St. Petersburg paradox. \n"
    + "Game rules: For every Game you pay SFr. 5.-.\n"
    + "A fair coin is tossed repeatedly until a number appears, ending the game.\n"
    + "Starting with SFr 1.- for every head you get twice paid out.\n"
    + "If only a number appears, you lose the use.\n"
    + "(http://en.wikipedia.org/wiki/St._Petersburg_paradox)";


  public Petersburg()
  {
    super(15, 1, 82);
    setBgColor(Color.white);
    show();
    bg = getBg();
    bg.setPaintColor(Color.black);
    addStatusBar(30);
    ModelessOptionPane mop =
      new ModelessOptionPane(getPosition().x,
                             getPosition().getAreaSize().height,
                             info);
    mop.setTitle("Information");

    reset();
  }

  public void newGame()
  {
    setTitle("New game, you paid " + entry + " SFr entering price");
    removeAllActors();
    loss = loss - entry;
    int total = totalProfit + loss;

    String data =
      String.format("Top gain: %-20d     You lost: %-20d    "
        + " You won: %-20d    Profit: %-20d",
        maxWin, loss, totalProfit, total);
    setStatusText(data);
    addActor(new Coin(0, 0, this)new Location(0, 0));
  }

  public void reset()
  {
    bg.clear();
    totalProfit = 0;
    maxWin = 0;
    loss = 0;
    setTitle("Intialized");
    newGame();
  }

  public static void main(String[] args)
  {
    new Petersburg();
  }
}

// ------------- class Coin -------------------------
class Coin extends Actor
{
  private int Xpos;
  private int currentWin; // currentWin = 2^Xpos;
  private Petersburg pb;
  private boolean lost;

  public Coin(int Xpos, int currentWin, Petersburg pb)
  {
    super(true"sprites/coin.gif"3);
    show(2);
    this.currentWin = currentWin;
    this.Xpos = Xpos;
    this.pb = pb;
  }

  public void act()
  {
    if (lost)
    {
      pb.getBg().clear();   // beseitigt Schrift auf Hintergrund
      pb.newGame();
    }
    else
    {
      setDirection(Math.random() * 360);
      boolean head;
      if ((int)(Math.random() * 2) == 1)
        head = true;
      else
        head = false;

      if (head)
      {
        show(0);
        if (currentWin == 0)
          currentWin = 1;
        else
          currentWin = * currentWin;

        gameGrid.addActor(new Coin(Xpos + 1, currentWin, pb), //next coin
          new Location(Xpos + 1, 0));
        this.setActEnabled(false);
      }
      else
      {
        show(1);
        lost = true;  // necessary to see the tail
        pb.totalProfit = pb.totalProfit + currentWin;
        gameGrid.setTitle("Round finished! You win: " + currentWin + ".- SFr ");

        if (currentWin > pb.maxWin)
          pb.maxWin = currentWin;
      }
    }
  }
}