/************************************************************************\ |* gtf is a framework for analyzing two-player zero-sum games *| |* Copyright (C) 2005 Troels Bjerre Sorensen *| |* *| |* This program is free software; you can redistribute it and/or modify *| |* it under the terms of the GNU General Public License as published by *| |* the Free Software Foundation; either version 2 of the License, or *| |* (at your option) any later version. *| |* *| |* This program is distributed in the hope that it will be useful, but *| |* WITHOUT ANY WARRANTY; without even the implied warranty of *| |* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU *| |* General Public License for more details. *| |* *| |* You should have received a copy of the GNU General Public License *| |* along with this program; if not, write to the *| |* Free Software Foundation, Inc., 59 Temple Place - Suite 330, *| |* Boston, MA 02111-1307, USA. *| \************************************************************************/ package gtf.examples; import gtf.game.*; public class TaenkeBoks extends ExtensiveForm { int maxdie, maxrounds; public String getName() { return "TB." + maxdie + "." + maxrounds; } public TaenkeBoks(String maxdie, String maxrounds) { try { this.maxdie = Integer.parseInt(maxdie); this.maxrounds = Integer.parseInt(maxrounds); } catch(NumberFormatException e) { System.err.println("usage: TaenkeBoks "); System.exit(1); } } public GameTree generateTree() { return new DiceToss(); } private class DiceToss extends RandomNode { public DiceToss() { for (int p1die = 1 ; p1die <= maxdie ; p1die++) { for (int p2die = 1 ; p2die <= maxdie ; p2die++) { addChild("die=" + p1die, "die=" + p2die, 1, new Move(p1die, p2die, 1, 1, 1, maxrounds)); } } } } private class Move extends PlayerNode { public Move(int p1die, int p2die, int player, int number, int die, int roundsleft) { super(player); if (roundsleft > 0) { if (number != 1 || die != 1) addChild(",p" + player + " lift", new GameLeaf(payoff(p1die, p2die, player, number, die))); if (number < 4) { addChild(",p" + player + " fullhouse", new Move(p1die, p2die, 3 - player, 4, 0, roundsleft - 1)); } for (int guessnumber = number ; guessnumber < 4 ; guessnumber++) { for (int guessdie = guessnumber == number ? die + 1 : 1 ; guessdie <= maxdie ; guessdie++) { addChild(",p" + player + " " + guessnumber + " " + guessdie + "s", new Move(p1die, p2die, 3 - player, guessnumber, guessdie, roundsleft - 1)); } } } else { if (number != 1 || die != 1) addChild(",p" + player + " lift", new GameLeaf(payoff(p1die, p2die, player, number, die))); if (number < 4) { addChild(",p" + player + " fullhouse,p" + (3 - player) + " lift", new GameLeaf(-payoff(p1die, p2die, 3 - player, 4, 0))); } for (int guessnumber = number ; guessnumber < 4 ; guessnumber++) { for (int guessdie = guessnumber == number ? die + 1 : 1 ; guessdie <= maxdie ; guessdie++) { addChild(",p" + player + " " + guessnumber + " " + guessdie + "s,p" + (3 - player) + " lift", new GameLeaf(-payoff(p1die, p2die, 3 - player, guessnumber, guessdie))); } } } } } private int payoff(int p1die, int p2die, int player, int number, int die) { int payoff; switch (number) { case 1: payoff = p1die == 1 || p2die == 1 || p1die == die || p2die == die ? -1 : 1; break; case 2: payoff = p1die == 1 || p2die == 1 || (die == 1 && p1die == p2die || p1die == die && p2die == die) ? -1 : 1; break; case 3: payoff = p1die == 1 && (p2die == die || p2die == 1) || p2die == 1 && (p1die == die || p1die == 1) ? -1 : 1; break; case 4: payoff = p1die == 1 && p2die == 1 ? -1 : 1; break; default: throw new RuntimeException("Unknown number: " + number); } return player == 1 ? payoff : -payoff; } }