@Test
  public void testCreateBoardImpl() throws BoardCreationException {
    final ScribbleSettings settings = new ScribbleSettings("Mock", Language.EN, 3);

    final Dictionary dictionary = createNiceMock(Dictionary.class);
    replay(dictionary);

    final TilesBankInfoEditor editor = new TilesBankInfoEditor(Language.EN);
    final TilesBank tilesBank = new TilesBank(editor.add('A', 100, 1).createTilesBankInfo());

    expect(dictionaryManager.getDictionary(Language.EN)).andReturn(dictionary);
    replay(dictionaryManager);

    expect(tilesBankingHouse.createTilesBank(Language.EN, 2, true)).andReturn(tilesBank);
    replay(tilesBankingHouse);

    scribblePlayManager.setDictionaryManager(dictionaryManager);
    scribblePlayManager.setTilesBankingHouse(tilesBankingHouse);

    final ScribbleBoard board1 =
        scribblePlayManager.createBoardImpl(settings, Arrays.asList(player1, player2), null);
    assertNotNull(board1);

    verify(dictionaryManager);
    verify(tilesBankingHouse);
  }
  @Before
  public void setUp() throws Exception {
    settings = new ScribbleSettings("test", Language.EN, 3);

    editor.add('a', 3, 1); // 0-2
    editor.add('b', 3, 2); // 3-5
    editor.add('c', 3, 3); // 6-8
    editor.add('d', 3, 4); // 9-11
    editor.add('e', 3, 5); // 12-14
    editor.add('f', 3, 6); // 15-17
    editor.add('g', 3, 7); // 18-20
    editor.add('m', 13, 0);
  }
  @Test
  public void test_processGameFinished_haveTiles() throws Exception {
    final Dictionary dictionary = createDictionary();
    final TilesBank tilesBank = new TilesBank(editor.createTilesBankInfo());

    final ScribbleBoard board =
        new ScribbleBoard(
            settings, Arrays.asList(player1, player2, player3), tilesBank, dictionary);
    h1 = board.getPlayerHand(player1);
    h2 = board.getPlayerHand(player2);
    h3 = board.getPlayerHand(player3);

    h1.setTiles(tilesBank.getTiles(0, 3, 6, 9)); // abcd: 10 points - should be winner
    h2.setTiles(tilesBank.getTiles(9, 12, 15, 18)); // defg: 22 points
    h3.setTiles(tilesBank.getTiles(16, 17, 19, 20)); // ffgg: 26 points

    // we need increate player points to make it winner.
    final Method method =
        h3.getClass().getSuperclass().getDeclaredMethod("increasePoints", short.class);
    method.setAccessible(true);
    method.invoke(h3, (short) 1); // Player h3 has 1 points and other have 0 points.

    short[] ints = board.processGameFinished();
    assertEquals(3, ints.length);

    assertEquals(-10, ints[0]); // final points for h1: looser
    assertEquals(-22, ints[1]); // final points for h2: looser
    assertEquals(-26, ints[2]); // final points for h3: winned
  }
  @Test
  public void test_checkMove_pass() throws GameMoveException {
    final Dictionary dictionary = createDictionary("abcd", "def", "fefgabcd");
    final TilesBank tilesBank = new TilesBank(editor.createTilesBankInfo());
    final ScribbleBoard board =
        new ScribbleBoard(
            settings, Arrays.asList(player1, player2, player3), tilesBank, dictionary);
    h1 = board.getPlayerHand(player1);
    h2 = board.getPlayerHand(player2);
    h3 = board.getPlayerHand(player3);

    h1.setTiles(tilesBank.getTiles(0, 3, 6, 9, 12, 15, 18)); // abcdefg
    h2.setTiles(tilesBank.getTiles(1, 4, 7, 10, 13, 16, 19)); // abcdefg
    h3.setTiles(tilesBank.getTiles(2, 5, 8, 11, 14, 17, 20)); // abcdefg

    final Personality person = board.getPlayerTurn();
    final ScribblePlayerHand hand = board.getPlayerHand(person);
    board.passTurn(person);

    assertEquals(7, hand.getTiles().length);
    assertEquals(1, board.getGameMoves().size());
    assertEquals(PassTurn.class, board.getGameMoves().get(0).getClass());
    assertEquals(13, tilesBank.getTilesLimit());

    assertNotSame(hand, board.getPlayerTurn());
  }
 private TilesBank createTilesBank(String tiles, int stubChars) {
   final TilesBankInfoEditor editor = new TilesBankInfoEditor(Language.EN);
   String s = "*qwertyuiopasdfghjklzxcvbnm";
   for (char c : s.toCharArray()) {
     int count = 0;
     int index = -1;
     while ((index = tiles.indexOf(c, index + 1)) != -1) {
       count++;
     }
     if (count != 0) {
       final int cost = (c == '*' ? 0 : 1);
       editor.add(c, count, cost);
     }
   }
   editor.add('z', stubChars, 1);
   return new TilesBank(editor.createTilesBankInfo());
 }
  @Test
  public void test_checkMove_exchange() throws GameMoveException {
    final Dictionary dictionary = createDictionary("abcd", "def", "fefgabcd");
    final TilesBank tilesBank = new TilesBank(editor.createTilesBankInfo());
    final ScribbleBoard board =
        new ScribbleBoard(
            settings, Arrays.asList(player1, player2, player3), tilesBank, dictionary);
    h1 = board.getPlayerHand(player1);
    h2 = board.getPlayerHand(player2);
    h3 = board.getPlayerHand(player3);

    h1.setTiles(tilesBank.getTiles(0, 3, 6, 9, 12, 15, 18)); // abcdefg
    h2.setTiles(tilesBank.getTiles(1, 4, 7, 10, 13, 16, 19)); // abcdefg
    h3.setTiles(tilesBank.getTiles(2, 5, 8, 11, 14, 17, 20)); // abcdefg
    // roll all tiles back and request tiles from 0 to 20
    final int capacity = tilesBank.getBankCapacity();
    for (int i = 0; i < capacity; i++) {
      tilesBank.rollbackTile(i);
    }
    for (int i = 0; i < 21; i++) {
      tilesBank.requestTile(i);
    }

    assertEquals(13, tilesBank.getTilesLimit());

    final Personality person = board.getPlayerTurn();
    final ScribblePlayerHand hand = board.getPlayerHand(person);
    final Tile[] tiles = hand.getTiles().clone();
    board.exchangeTiles(
        person, new int[] {tiles[0].getNumber(), tiles[1].getNumber(), tiles[2].getNumber()});

    assertEquals(7, hand.getTiles().length);
    assertEquals(1, board.getGameMoves().size());
    assertEquals(ExchangeTiles.class, board.getGameMoves().get(0).getClass());
    assertEquals(13, tilesBank.getTilesLimit());

    // Check that tiles was rolled back to bank
    assertFalse(tilesBank.isTileInUse(tiles[0].getNumber()));
    assertFalse(tilesBank.isTileInUse(tiles[1].getNumber()));
    assertFalse(tilesBank.isTileInUse(tiles[2].getNumber()));

    // Check that tiles with number > 20 is taken
    assertTrue(hand.getTiles()[0].getNumber() > 20);
    assertTrue(hand.getTiles()[1].getNumber() > 20);
    assertTrue(hand.getTiles()[2].getNumber() > 20);

    // Check no points
    assertEquals(0, hand.getPoints());
  }
  @Test
  public void test_checkMove_Correct() throws GameMoveException {
    final Dictionary dictionary = createDictionary("abcd", "def", "fefgabcd");
    final TilesBank tilesBank = new TilesBank(editor.createTilesBankInfo());
    final ScribbleBoard board =
        new ScribbleBoard(
            settings, Arrays.asList(player1, player2, player3), tilesBank, dictionary);
    h1 = board.getPlayerHand(player1);
    h2 = board.getPlayerHand(player2);
    h3 = board.getPlayerHand(player3);

    h1.setTiles(tilesBank.getTiles(0, 3, 6, 9, 12, 15, 18)); // abcdefg
    h2.setTiles(tilesBank.getTiles(1, 4, 7, 10, 13, 16, 19)); // abcdefg
    h3.setTiles(tilesBank.getTiles(2, 5, 8, 11, 14, 17, 20)); // abcdefg

    Personality person = board.getPlayerTurn();
    ScribblePlayerHand hand = board.getPlayerHand(person);
    final Tile[] moveTiles1 = Arrays.copyOf(hand.getTiles(), 4);
    board.makeTurn(person, new Word(new Position(7, 7), Direction.HORIZONTAL, moveTiles1)); // abcd
    assertEquals(1, board.getGameMoves().size());
    assertEquals(9, tilesBank.getTilesLimit());
    assertEquals(7, hand.getTiles().length);
    assertEquals(10, hand.getPoints());

    person = board.getPlayerTurn();
    hand = board.getPlayerHand(person);
    final Tile[] moveTiles2 = new Tile[3];
    moveTiles2[0] = moveTiles1[3]; // last 'd' letter
    System.arraycopy(hand.getTiles(), 4, moveTiles2, 1, 2);
    board.makeTurn(person, new Word(new Position(7, 10), Direction.HORIZONTAL, moveTiles2)); // def
    assertEquals(2, board.getGameMoves().size());
    assertEquals(7, tilesBank.getTilesLimit());
    assertEquals(7, hand.getTiles().length);
    assertEquals(30, hand.getPoints());

    person = board.getPlayerTurn();
    hand = board.getPlayerHand(person);
    final Tile[] moveTiles3 = new Tile[8];
    moveTiles3[0] = moveTiles2[2]; // last 'f' letter
    System.arraycopy(hand.getTiles(), 4, moveTiles3, 1, 3);
    System.arraycopy(hand.getTiles(), 0, moveTiles3, 4, 4);
    board.makeTurn(
        person, new Word(new Position(7, 12), Direction.VERTICAL, moveTiles3)); // fefgabcd

    assertEquals(3, board.getGameMoves().size());
    assertEquals(0, tilesBank.getTilesLimit());
    assertEquals(7, hand.getTiles().length);
    assertEquals(74, hand.getPoints()); // 6 + 5 + 6 + 7*2 + 1 + 2 + 3*2 + 4 +(30-all person) = 74
  }
  @Test
  public void test_processGameFinished_noTiles()
      throws NoSuchMethodException, InvocationTargetException, IllegalAccessException {
    final Dictionary dictionary = createDictionary();
    final TilesBank tilesBank = new TilesBank(editor.createTilesBankInfo());

    final ScribbleBoard board =
        new ScribbleBoard(
            settings, Arrays.asList(player1, player2, player3), tilesBank, dictionary);
    h1 = board.getPlayerHand(player1);
    h2 = board.getPlayerHand(player2);
    h3 = board.getPlayerHand(player3);

    h1.setTiles(tilesBank.getTiles(0, 3, 6, 9)); // abcd: 10 points
    h2.setTiles(tilesBank.getTiles(9, 12, 15, 18)); // defg: 22 points
    h3.setTiles(new Tile[0]); // winner

    short[] ints = board.processGameFinished();
    assertEquals(3, ints.length);

    assertEquals(-10, ints[0]); // final points for h1: looser
    assertEquals(-22, ints[1]); // final points for h2: looser
    assertEquals(32, ints[2]); // final points for h3: winned
  }