001 /////////////////////////////////////////////////////////////////////////////// 002 // Copyright (c) 2006, Frank S. Nestel, All Rights Reserved. 003 // 004 // This library is free software; you can redistribute it and/or 005 // modify it under the terms of the GNU Lesser General Public 006 // License as published by the Free Software Foundation; either 007 // version 2.1 of the License, or (at your option) any later version. 008 // 009 // This library is distributed in the hope that it will be useful, 010 // but WITHOUT ANY WARRANTY; without even the implied warranty of 011 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 012 // GNU General Public License for more details. 013 // 014 // You should have received a copy of the GNU Lesser General Public 015 // License along with this program; if not, write to the Free Software 016 // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 017 /////////////////////////////////////////////////////////////////////////////// 018 019 package de.spieleck.app.turn.scoring; 020 021 import java.util.Arrays; 022 023 import de.spieleck.app.turn.PlayerGameScore; 024 import de.spieleck.app.turn.PlayerScore; 025 026 /** 027 * A ScoringMode for a match of Zoff. 028 * <br /> 029 * During a match of this card games a player obtains both 030 * a score and a rank. The rank is the major scoring component, 031 * since it depends on the score, but has an additional rule to 032 * avoid ties. The table score is however retained for tie breaking 033 * of the tournament ranking. 034 * 035 * <p><a href="$URL: https://svn.sourceforge.net/svnroot/jtourney/src/de/spieleck/app/turn/scoring/Zoff.java $">$URL: https://svn.sourceforge.net/svnroot/jtourney/src/de/spieleck/app/turn/scoring/Zoff.java $</a></p> 036 * 037 * @author Frank S. Nestel 038 * @author $Author: nestefan $ 039 * @version $Revision: 2 $ $Date: 2006-03-20 14:33:27 +0100 (Mo, 20 Mrz 2006) $ $Author: nestefan $ 040 */ 041 public class Zoff 042 extends BaseScoring 043 { 044 public PlayerGameScore parseRawScore(String line) 045 { 046 int i = line.indexOf(" "); 047 if ( i == -1 ) 048 throw new RuntimeException("Illegal Zoff score <"+line+">."); 049 int rank = Integer.parseInt(line.substring(0,i).trim()); 050 double score = Double.parseDouble(line.substring(i+1).trim()); 051 return new ZoffScore(rank, score); 052 } 053 054 public String checkScore(PlayerGameScore[] pgs) 055 { 056 double[] scores = new double[pgs.length]; 057 for(int i = 0; i < pgs.length; i++) 058 { 059 ZoffScore in = (ZoffScore) pgs[i]; 060 scores[i] = in.score; 061 } 062 Arrays.sort(scores); 063 boolean check[] = new boolean[pgs.length + 1]; 064 for(int i = 0; i < pgs.length; i++) 065 { 066 ZoffScore in = (ZoffScore) pgs[i]; 067 int rank = (int) Math.round(in.rank); 068 if ( check[rank] ) 069 return "Rank "+rank+" given twice."; 070 check[rank] = true; 071 if ( in.score != scores[pgs.length - rank] ) 072 return "Score, Rank mismatch : "+in; 073 } 074 for(int i = 0; i < pgs.length; i++) 075 { 076 int rank = i + 1; 077 if ( !check[rank] ) 078 return "Rank "+rank+" missing."; 079 } 080 return null; 081 } 082 083 public PlayerGameScore[] adjustScore(PlayerGameScore[] pgs) 084 { 085 double h = 0.0; 086 ZoffScore[] in = new ZoffScore[pgs.length]; 087 for(int i = 0; i < pgs.length; i++) 088 { 089 in[i] = (ZoffScore) pgs[i]; 090 int rank = (int) Math.round(in[i].rank); 091 h += in[i].rank; 092 } 093 h /= pgs.length; 094 ZoffScore[] res = new ZoffScore[pgs.length]; 095 for(int i = 0; i < pgs.length; i++) 096 res[i] = new ZoffScore(h - in[i].rank, in[i].score); 097 return res; 098 } 099 100 public PlayerGameScore zeroScore() 101 { 102 return new ZoffScore(0,0); 103 } 104 105 public PlayerScore addPlayers(PlayerScore ps, PlayerScore pgs) 106 { 107 ZoffScore psz = (ZoffScore) ps; 108 ZoffScore pgsz = (ZoffScore) pgs; 109 return new ZoffScore(psz.rank + pgsz.rank, psz.score + pgsz.score); 110 } 111 112 public static class ZoffScore 113 implements PlayerGameScore, PlayerScore 114 { 115 // Note: Rank could have been integer, but for implementation 116 // Lazyness and simplicity in this case we don't mind. 117 private double rank, score; 118 119 public ZoffScore(double rank, double score) 120 { 121 this.rank = rank; 122 this.score = score; 123 } 124 125 public int compareTo(Object o) 126 { 127 if ( ! ( o instanceof ZoffScore ) ) 128 return -1; 129 ZoffScore oz = (ZoffScore) o; 130 double delta = oz.rank - this.rank; 131 if ( delta > 0.0 ) 132 return -1; 133 else if ( delta < 0.0 ) 134 return +1; 135 delta = this.score - oz.score; 136 if ( delta > 0.0 ) 137 return +1; 138 else if ( delta < 0.0 ) 139 return -1; 140 return 0; 141 } 142 143 public String toString() 144 { 145 return Integer.toString((int)rank)+" "+Double.toString(score); 146 } 147 } 148 149 public String toString() 150 { 151 return "Zoff"; 152 } 153 }