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    }