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;
020
021 import java.io.File;
022 import java.io.PrintWriter;
023 import java.io.IOException;
024 import java.util.ArrayList;
025 import java.util.Iterator;
026 import java.util.regex.Pattern;
027
028 import org.apache.log4j.Logger;
029
030 /**
031 * Handle strange editable fileformats.
032 * <ul>
033 * <li>This is kind of a human editable compact serialization format.</li>
034 * <li>The Methods readRound() and writeRound() must work complementary.</li>
035 * <li>Finally: This has been factored out to be replaceable.</li>
036 * </ul>
037 *
038 * <p><a href="$URL: https://svn.sourceforge.net/svnroot/jtourney/src/de/spieleck/app/turn/FileProxy.java $">$URL: https://svn.sourceforge.net/svnroot/jtourney/src/de/spieleck/app/turn/FileProxy.java $</a></p>
039 *
040 * @author Frank S. Nestel
041 * @author $Author: nestefan $
042 * @version $Revision: 2 $ $Date: 2006-03-20 14:33:27 +0100 (Mo, 20 Mrz 2006) $ $Author: nestefan $
043 */
044 public class FileProxy
045 {
046 private final static Logger L = Logger.getLogger(FileProxy.class);
047
048 public final static GameResult[] NOGAMERESULT = new GameResult[0];
049
050 public final static String SEP = ";";
051
052 public final static Pattern SPLITTER = Pattern.compile("\\s*;\\s*");
053
054 private ScoringMode scoringMode;
055
056 private PlayerRegistry pRegistry;
057
058 public FileProxy(ScoringMode scoringMode, PlayerRegistry pRegistry)
059 {
060 this.scoringMode = scoringMode;
061 this.pRegistry = pRegistry;
062 }
063
064 public static String makeRoundName(int round)
065 {
066 return Run.ROUND + round;
067 }
068
069 /**
070 * Read in player file
071 */
072 public void readPlayers(LineSource ls)
073 throws IOException
074 {
075 String line;
076 while ( ( line = ls.line() ) != null )
077 {
078 String[] pieces = SPLITTER.split(line, 3);
079 if ( pieces.length < 3 )
080 {
081 L.error("Illegal player line: <"+line+">.");
082 }
083 else
084 {
085 pRegistry.registerPlayer(pieces[0], pieces[1], pieces[2]);
086 }
087 }
088 ls.close();
089 }
090
091 /**
092 * Read one round.
093 */
094 public GameResult[] readRound(LineSource ls, boolean check)
095 throws Exception
096 {
097 ArrayList al = new ArrayList();
098 String line = ls.line();
099 while ( line != null )
100 {
101 String[] pieces = SPLITTER.split(line, 3);
102 if (L.isDebugEnabled() )
103 L.debug(line+" "+pieces[0]+" "+pieces[1]+" "+pieces[2]);
104 boolean active = !("-".equals(pieces[0].trim()));
105 int n = Integer.parseInt(pieces[1]);
106 int id = Integer.parseInt(pieces[2]);
107 if (L.isDebugEnabled() )
108 L.debug("** "+n+" ("+line+")");
109 PlayerGameScore[] gameScores = new PlayerGameScore[n];
110 Player[] players = new Player[n];
111 for(int i = 0; i < n; i++)
112 {
113 line = ls.line();
114 pieces = SPLITTER.split(line, 2);
115 int pid = Integer.parseInt(pieces[0]);
116 gameScores[i] = scoringMode.parseRawScore(pieces[1]);
117 players[i] = pRegistry.getPlayer(pid);
118 }
119 if ( active )
120 {
121 if ( check )
122 {
123 String msg = scoringMode.checkScore(gameScores);
124 if ( msg != null )
125 {
126 String msg2 = "checkScore: "+msg;
127 L.error(msg2);
128 }
129 }
130 // Renorm the game scores, i.e. for scoring relative to
131 // the average player score or so.
132 PlayerGameScore[] gameSc2
133 = scoringMode.adjustScore(gameScores);
134 GameResult gr = new GameResult(id);
135 for(int i = 0; i < n; i++)
136 {
137 Player p = players[i];
138 gr.add(p, gameSc2[i]);
139 p.setScore(scoringMode.add(p.getScore(),gameSc2[i]));
140 }
141 for(int i = 0; i < n; i++)
142 {
143 players[i].addResult(gr);
144 }
145 al.add(gr);
146 }
147 else
148 {
149 L.info("Inactive game "+ls.getFName()+":"+id);
150 }
151 line = ls.line();
152 }
153 return (GameResult[]) al.toArray(NOGAMERESULT);
154 }
155
156 /**
157 * Write one round.
158 */
159 public void writeRound(PrintWriter bw, String msg, GameResult[] games)
160 throws IOException
161 {
162 bw.println(LineSource.COMMENTSTR+" "+msg);
163 for(int i = 0; i < games.length; i++)
164 {
165 GameResult g = games[i];
166 bw.println(LineSource.COMMENTSTR+"------------------------------");
167 bw.println("+"+SEP+g.size()+SEP+g.getId()
168 +" "+LineSource.COMMENTSTR+"!!!");
169 Iterator<Player> it = g.players();
170 while ( it.hasNext() )
171 {
172 Player p = it.next();
173 PlayerScore score = g.getScore(p);
174 bw.print(p.getId()+SEP+"\t"+score
175 +" "+LineSource.COMMENTSTR+" "+p.getNameKurz());
176 Iterator<GameResult> iter = p.results();
177 while ( iter.hasNext() )
178 {
179 Iterator<Player> it3 = iter.next().players();
180 while ( it3.hasNext() )
181 {
182 Player p3 = it3.next();
183 if ( p3 != p )
184 bw.print(" "+p3.getId());
185 }
186 bw.print("|");
187 }
188 bw.println();
189 }
190 }
191 bw.close();
192 }
193
194 }