0

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;

}
Woden
  • 1,054
  • 2
  • 13
  • 26
  • 1
    You're avoiding polymorphism's advantages altogether that way. The point would be to run `int stoneTaken = player1.moveStone();` *without caring* what `player1` is actually an instance of. – Federico klez Culloca May 14 '20 at 08:11
  • okay, it means I don't have to do checking the players, right? But because I need to make `AIPlayer` move based on the information given. How can I bring the information into `NimAIPlayer` ? Thank you @FedericoklezCulloca – Woden May 14 '20 at 08:20
  • 1
    Passing them to `moveStone` seems to be correct (TBH I'm not totally sure what they represent, so there may be a better way depending on context). You say the logic is not working but you don't say *how* it's not working, i.e. what you expect and what happens instead. – Federico klez Culloca May 14 '20 at 08:23
  • It doesn't reference the arguments that I put in. – Woden May 14 '20 at 08:26
  • 1
    I'm not sure what you mean by "reference the argument". Can you please be a bit more clear? – Federico klez Culloca May 14 '20 at 08:27
  • `moveStone(int initialStone, int upperBound, int balance)` this line here. Can I have arguments here? – Woden May 14 '20 at 08:29
  • 1
    Sure you can, what's the matter? Please be as clear as you can. Is this giving an error when you compile? (if yes, what error). Is this crashing at runtime? (If yes, show the stacktrace). Is this giving unexpected results? (if yes, what is the expected result and the actual result?). Please [edit] your question to clarify, otherwise it will be *very* hard to help you. – Federico klez Culloca May 14 '20 at 08:33
  • Thank for you patience and kindness. I will rearrange the post. @FedericoklezCulloca – Woden May 14 '20 at 08:34
  • @FedericoklezCulloca Sir, I've rewritten the method and simplify as possible, but I got an error. Should I check the instance of each player? – Woden May 14 '20 at 09:21
  • 1
    Ok, now it's clear. The problem is that `NimPlayer` defines a method `abstract int moveStone()` while `NimAiPlayer` defines a method `int moveStone(int initialStone, int upperBound, int balance)`. The error message is basically telling you that they need to have the same signature. So either both of them must take parameters or both of them should have no parameters. – Federico klez Culloca May 14 '20 at 09:27
  • @FedericoklezCulloca Thank you, sir. I've put them into the same signature `public int moveStone(int initialStone, int upperBound, int balance)` but it still yelling at me with the same problem. At the class `public class NimAIPlayer extends NimPlayer implements Testable`, it pops out the message like I said and ask if I want to `Add unimplemented methods `. – Woden May 14 '20 at 09:38
  • What happens if you click "Add unimplemented method"? – Federico klez Culloca May 14 '20 at 09:47
  • Thank you, sir. I've figured it out!! I have two classes inherited the `NimPlayer` class. So, there will be three of them have the same signature. `Add unimplemented method` won't work by the way. @FedericoklezCulloca – Woden May 14 '20 at 09:48
  • 1
    Have a nice day, sir :") – Woden May 14 '20 at 09:49
  • 1
    @Woden - You must check https://stackoverflow.com/questions/49002/prefer-composition-over-inheritance – Arvind Kumar Avinash May 14 '20 at 10:24
  • 1
    @ArvindKumarAvinash Good day, sir!! I will read and learn this new concept. – Woden May 14 '20 at 11:23

0 Answers0