001 package test;
002
003 import java.io.File;
004
005 import core.Color;
006 import core.Game;
007 import core.GameLoadException;
008 import core.GameOver;
009 import core.Move;
010 import core.Player;
011 import core.Position;
012
013 import junit.framework.TestCase;
014 import rules.Board;
015 import ai.RandomPlayer;
016
017 /**
018 * Unit tests for the Game class.
019 */
020 public class GameTest extends TestCase
021 {
022 Player wp = new RandomPlayer(Color.WHITE);
023 int wt = 100; // white time
024 Player bp = new RandomPlayer(Color.BLACK);
025 int bt = 200; // black time
026 String loadPath = "resources" + File.separatorChar + "xml"
027 + File.separatorChar;
028
029 public GameTest(String name)
030 {
031 super(name);
032 }
033
034 /**
035 * Tests basic legal constructor values.
036 */
037 public void testLegalValues()
038 {
039 new Game(wp, wt, bp, bt);
040 new Game(wp, bp);
041 }
042
043 /**
044 * Tests that an unplayed loaded game fulfills the same requirements as a
045 * regular new game.
046 */
047 public void testLegalValuesLoad()
048 {
049 try
050 {
051 checkLegalHelper(Game.loadGame(wp, bp, new File(loadPath
052 + "unplayed.xml")), wp, 200000, bp, 300000);
053
054 } catch (GameLoadException e)
055 {
056 e.printStackTrace();
057 fail();
058 }
059 }
060
061 /**
062 * Tests that an unplayed loaded game fulfills the same requirements as a
063 * regular new game, even after saving and reloading.
064 */
065 public void testLegalValuesSaveLoad()
066 {
067
068 try
069 {
070 checkLegalHelper(Game.loadGame(wp, bp, Game.loadGame(wp, bp,
071 new File(loadPath + "unplayed.xml")).getXML()), wp, 200000,
072 bp, 300000);
073 } catch (GameLoadException e)
074 {
075 e.printStackTrace();
076 fail();
077 }
078 }
079
080 /**
081 * Initializes in a try block to give a useful error.
082 */
083 public void checkLegal(Player p1, int t1, Player p2, int t2)
084 {
085 Game o = null;
086 try
087 {
088 o = new Game(p1, t1, p2, t2);
089 } catch (Exception ex)
090 {
091 fail("Didn't allow legal constructor input");
092 }
093 checkLegalHelper(o, p1, t1, p2, t2);
094 }
095
096 /**
097 * Makes sure initial values set correctly.
098 */
099 public void checkLegalHelper(Game o, Player p1, int t1, Player p2, int t2)
100 {
101 if (o.getCurrentPlayer() != p1)
102 fail();
103 if (o.getPlayerByColor(Color.WHITE) != p1)
104 fail();
105 if (o.getPlayerByColor(Color.BLACK) != p2)
106 fail();
107 if (o.getTimeLeftForPlayer(p1) != t1)
108 fail(o.getTimeLeftForPlayer(p1) + " " + o.getTimeLeftForPlayer(p2));
109 if (o.getTimeLeftForPlayer(p2) != t2)
110 fail();
111 if (o.getPlayers().get(0) != p1 || o.getPlayers().get(1) != p2
112 || o.getPlayers().size() != 2)
113 fail();
114 if (o.getMoveHistory().size() != 0)
115 fail();
116 if (o.getWinner() != Color.NONE)
117 fail();
118 if (o.getWinReason() != GameOver.NONE)
119 fail();
120 if (!o.getGameState().boardString().equals(Board.startingBoard))
121 fail();
122 }
123
124 /**
125 * Tests
126 */
127 public void testSaveLoadSimpleGame()
128 {
129 Game g = checkSaveLoadGame("simple.xml");
130 assertEquals(GameOver.NONE, g.getWinReason());
131 assertEquals(Color.NONE, g.getWinner());
132 assertEquals(g.getMoveHistory().get(0).toString(), "f2-f4");
133 assertEquals(g.getMoveHistory().get(1).toString(), "d7-d5");
134 assertEquals(g.getMoveHistory().get(2).toString(), "f4-f5");
135 assertEquals(g.getMoveHistory().get(3).toString(), "c8-f5");
136 assertEquals(20, g.getTimeLeftForPlayer(wp));
137 assertEquals(10, g.getTimeLeftForPlayer(bp));
138 }
139
140 /**
141 * Tests an incomplete game (for completeness of testing output).
142 */
143 public void testSaveLoadIncompleteGame()
144 {
145 Game g = checkSaveLoadGame("incomplete.xml");
146 assertEquals(GameOver.NONE, g.getWinReason());
147 assertEquals(Color.NONE, g.getWinner());
148 }
149
150 /**
151 * Tests loading and saving finished games, and makes sure they have the
152 * correct end state.
153 */
154 public void testSaveLoadFinishedGame()
155 {
156 Game piecesLoss = checkSaveLoadGame("pieces_loss.xml");
157 assertEquals(GameOver.PIECES_LOST, piecesLoss.getWinReason());
158 assertEquals(Color.WHITE, piecesLoss.getWinner());
159
160 Game checkmate = checkSaveLoadGame("checkmate.xml");
161 assertEquals(GameOver.CHECKMATE, checkmate.getWinReason());
162 assertEquals(Color.WHITE, checkmate.getWinner());
163
164 Game timeExpired = checkSaveLoadGame("timeExpired.xml");
165 assertEquals(GameOver.TIME_EXPIRED, timeExpired.getWinReason());
166 assertEquals(Color.BLACK, timeExpired.getWinner());
167 }
168
169 /**
170 * Tests loading and saving game with passes.
171 */
172 public void testSaveLoadDrawGame()
173 {
174 Game pass = checkSaveLoadGame("pass2.xml");
175 assertEquals(pass.getCurrentPlayer().getColor(), Color.BLACK);
176
177 Game passend = checkSaveLoadGame("pass3checkmate.xml");
178 assertEquals(GameOver.CHECKMATE, passend.getWinReason());
179 assertEquals(Color.WHITE, passend.getWinner());
180 }
181
182 /**
183 * Tests loading and saving game with maintains additional state (like
184 * whether someone has castled).
185 */
186 public void testSaveLoadAdditionalStateGame()
187 {
188 Game pass = checkSaveLoadGame("no_castle.xml");
189 assertTrue(!pass.getGameState().isLegal(
190 new Move(Position.fromString("e1"), Position.fromString("c1"))));
191 }
192
193 /**
194 * Tests loading and saving game with maintains additional state (like
195 * whether someone has castled).
196 */
197 public void testSaveLoadPowerups()
198 {
199 checkSaveLoadGame("powerups_unplayed.xml");
200 checkSaveLoadGame("powerups_played.xml");
201 }
202
203 /**
204 * Helper method that loads a game from a file, converts it to xml, loads it
205 * from xml, converts it back, and then compares it. It also returns the
206 * game for further processing.
207 */
208 public Game checkSaveLoadGame(String gameFileName)
209 {
210 try
211 {
212 File f = new File(loadPath + gameFileName);
213 Game g = Game.loadGame(wp, bp, f);
214 String xml = g.getXML();
215 Game g2 = Game.loadGame(wp, bp, xml);
216 g2.getXML().equals(xml);
217 return g2;
218 } catch (GameLoadException e)
219 {
220 e.printStackTrace();
221 throw new RuntimeException(e);
222 }
223 }
224
225 /**
226 * Tests that untimed games don't update time, and it returns -1.
227 */
228 public void testUntimed()
229 {
230 Game g = new Game(wp, bp);
231 assertEquals(-1, g.getTimeLeftForPlayer(wp));
232 g.setTime(wp, 0);
233 assertEquals(-1, g.getTimeLeftForPlayer(wp));
234 }
235
236 /**
237 * Tests that time updates correctly, and that an exception is thrown if you
238 * move after running out of time.
239 */
240 public void testTimed()
241 {
242 Game g = new Game(wp, 100, bp, 100);
243 assertEquals(100, g.getTimeLeftForPlayer(wp));
244 g.subtractTimeLeftForPlayer(wp, 10);
245 g.makeMove(Move.fromString("f2-f4"));
246 assertEquals(90, g.getTimeLeftForPlayer(wp));
247 assertEquals(100, g.getTimeLeftForPlayer(bp));
248 g.subtractTimeLeftForPlayer(bp, 20);
249 g.makeMove(Move.fromString("d7-d5"));
250 assertEquals(80, g.getTimeLeftForPlayer(bp));
251 g.subtractTimeLeftForPlayer(wp, 95);
252 try
253 {
254 g.makeMove(Move.fromString("f4-f5"));
255 } catch (Exception e)
256 {
257 assertTrue(true);
258 return;
259 }
260 fail();
261 }
262 }