I have got the idea of polymorphism, but its application seems limited.
Say there are two kinds of players: NimHumanPlayer and NimAIPlayer. When in the NiGame, both of them have to move the stone each round.
Thus, I wrote it like this to apply for the player, but I got The type NimAIPlayer must implement the inherited abstract method NimPlayer.moveStone().
public int playerTurn(NimPlayer player) {
    System.out.println(player.getGivenName()+ "'s turn - remove how many?\n");
    takeStone = player.moveStone();
    while (takeStone > stoneBalance || takeStone > upperBound || takeStone <= 0) {
        stoneBalance = checkValidness(takeStone); // use method to check integer validness
        System.out.print(stoneBalance + " stones left:"); 
        printStar(stoneBalance); 
        System.out.println(player.getGivenName() + "'s turn - remove how many?\n");
        player.moveStone(); // Error, must implement the inherited abstract method
    }
    return takeStone; //return valid takeStone  
}
The NimAIPlayer needs to reference the parameters: initialStone, upperBound, stoneBalance to make move. This issue bothers me for a week and I cannot figure out. 
Any help is highly appreciated.
I wrote the logic but it didn't work.
Here is part of the NimAIPlayer class:
public class NimAIPlayer extends NimPlayer implements Testable {
private int stoneTaken;
public int moveStone(int initialStone, int upperBound, int balance) {
    if (initialStone == balance) {
        stoneTaken = ThreadLocalRandom.current().nextInt(1, upperBound + 1);
        return stoneTaken;
    } else if (balance < upperBound){
        stoneTaken = ThreadLocalRandom.current().nextInt(1,  + balance + 1);
        return stoneTaken;
    } else if (balance >= upperBound){
        stoneTaken = ThreadLocalRandom.current().nextInt(1, upperBound + 1);
        return stoneTaken;
    }
    return -1;
}
