Winning strategy for the dice pig game
Bugs

The outline of the function is


@Override
public boolean decideIfShouldRoll(int turnNumber, int rollNumber,
        int poolSize, int myScore, int opponentsScore) {
    if (myScore &lt; 30 &amp;&amp; opponentsScore &lt; 30) {
        …
    }
    if (opponentsScore &gt; myScore) {
        …
    }
    if (myScore &gt; opponentsScore) {
        …
    }
    return true;
}



The return true at the end is problematic.  You're saying that, except in the opening moves, anytime the score is tied, you want to roll forever, essentially forfeiting your turn.



If we have 95 points and a pool of 5, we should stop rolling.  Your code tries to amass a pool of 15 points or 10 points.

Redundancy

The opponentScore &gt; 20 test should always be true, since the opponent is in the lead, and the leader has at least 30 points.


@Override
public boolean decideIfShouldRoll(int turnNumber, int rollNumber,
        int poolSize, int myScore, int opponentsScore) {
    if (myScore &lt; 30 &amp;&amp; opponentsScore &lt; 30) {
        …
    }
    if (opponentsScore &gt; myScore) {
        …
        if (opponentsScore &gt; 20) {
            …
        }
        return false;
    }
    if (myScore &gt; opponentsScore) {
        …
    }
    return true;
}





Math.abs() is superfluous here, since we have already established that we are in the lead:


if (myScore &gt; opponentsScore) {
    if ((100 - myScore) &lt;= 20 &amp;&amp; (myScore - opponentsScore) &lt;= 10) {
        …
    }
    …
    if ((myScore - opponentsScore) &gt; 10) {
        …
    }
    if ((100 - myScore) &lt;= 20
            &amp;&amp; Math.abs(myScore - opponentsScore) &lt;= 10) {
        …
    }
    return true;



In fact, if you eliminate the Math.abs(), then you are redundantly restating the (100 - myScore) &lt;= 20 &amp;&amp; (myScore - opponentsScore) &lt;= 10 case exactly.

Verbosity

Anytime you have if (condition) return true; else return false; you should just write return condition;.

I'm not a fan of needless arithmetic like if (100 - opponentsScore &lt;= 20).  It would be shorter to write if (opponentScore &gt;= 80), and just as clear.

Interface

The function name could be simplified to shouldRoll.

Assuming a fair die, there is no logical strategy in which the turnNumber or the rollNumber could be a factor in the decision.  It doesn't matter how you arrived at the current score and pool, because past performance is no indicator of future expectations.  Anything else would be a gambler's fallacy.  Therefore, I suggest eliminating turnNumber and rollNumber from the method signature.

I suggest renaming opponentsScore to theirScore, both to save a few characters and to mirror myScore.

Rewrite

There is too much code altogether!  You are really just trying to express a simple idea: in the face of an imminent loss, go for a pool of 30 points; if you have a comfortable lead, aim for just 15; otherwise, try to gather 20.

@Override
public boolean shouldRoll(int poolSize, int myScore, int theirScore) {
    if (myScore + poolSize &gt;= 100) {
        return false;
    }
    int myLead = myScore - theirScore;
    int wantPool = (myScore &lt; 80 &amp;&amp; theirScore &gt;= 80) ? 30              // Imminent loss, be aggressive.
                 : (myScore &gt;= 80 &amp;&amp; (0 &lt; myLead &amp;&amp; myLead &lt;= 10)) ? 15 // Comfortable lead
                 : 20;                                                  // General case
    return poolSize &lt; wantPool;
}