mirror of https://github.com/FreeCol/freecol.git
Fix limit evaluation for player settlement lists, BR#2873.
This commit is contained in:
parent
8609f0908b
commit
fe0fe8cfeb
|
@ -29,6 +29,7 @@ import java.io.IOException;
|
|||
import java.io.OutputStream;
|
||||
import java.io.StringReader;
|
||||
import java.io.StringWriter;
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
|
@ -265,6 +266,31 @@ public abstract class FreeColObject
|
|||
lb.add("]");
|
||||
}
|
||||
|
||||
/**
|
||||
* Invoke a method for this object.
|
||||
*
|
||||
* @param methodName The name of the method.
|
||||
* @param returnClass The class of the return value.
|
||||
* @param defaultValue The default value.
|
||||
* @return The result of invoking the method, or the default value
|
||||
* on failure.
|
||||
*/
|
||||
protected <T> T invokeMethod(String methodName, Class<T> returnClass,
|
||||
T defaultValue) {
|
||||
if (methodName != null && returnClass != null) {
|
||||
try {
|
||||
Method method = getClass().getMethod(methodName);
|
||||
if (method != null) {
|
||||
return returnClass.cast(method.invoke(this));
|
||||
}
|
||||
} catch (Exception e) {
|
||||
logger.log(Level.WARNING, "Invoke failed: " + methodName, e);
|
||||
}
|
||||
}
|
||||
return defaultValue;
|
||||
}
|
||||
|
||||
|
||||
// Property change support
|
||||
|
||||
public void addPropertyChangeListener(PropertyChangeListener listener) {
|
||||
|
|
|
@ -19,8 +19,6 @@
|
|||
|
||||
package net.sf.freecol.common.model;
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.logging.Level;
|
||||
|
@ -167,15 +165,9 @@ public class Operand extends Scope {
|
|||
* @return The operand value or null if inapplicable.
|
||||
*/
|
||||
public Integer getValue(Game game) {
|
||||
if (value == null) {
|
||||
if (scopeLevel == ScopeLevel.GAME){
|
||||
return calculateGameValue(game);
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
} else {
|
||||
return value;
|
||||
}
|
||||
return (value != null) ? value
|
||||
: (scopeLevel == ScopeLevel.GAME) ? calculateGameValue(game)
|
||||
: null;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -185,21 +177,10 @@ public class Operand extends Scope {
|
|||
* @return The operand value.
|
||||
*/
|
||||
private Integer calculateGameValue(Game game) {
|
||||
final String methodName = getMethodName();
|
||||
switch (operandType) {
|
||||
case NONE:
|
||||
if (getMethodName() != null) {
|
||||
try {
|
||||
Method method = game.getClass().getMethod(getMethodName());
|
||||
if (method != null &&
|
||||
Integer.class.isAssignableFrom(method.getReturnType())) {
|
||||
return (Integer) method.invoke(game);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
logger.log(Level.WARNING, "Unable to invoke: "
|
||||
+ getMethodName(), e);
|
||||
}
|
||||
}
|
||||
return null;
|
||||
return game.invokeMethod(methodName, Integer.class, 0);
|
||||
case YEAR:
|
||||
return game.getTurn().getYear();
|
||||
case OPTION:
|
||||
|
@ -237,47 +218,47 @@ public class Operand extends Scope {
|
|||
* @return The operand value, or null if inapplicable.
|
||||
*/
|
||||
public Integer getValue(Player player) {
|
||||
if (value == null) {
|
||||
if (scopeLevel == ScopeLevel.PLAYER) {
|
||||
List<FreeColObject> list = new LinkedList<>();
|
||||
switch (operandType) {
|
||||
case UNITS:
|
||||
return count(player.getUnits());
|
||||
case BUILDINGS:
|
||||
for (Colony colony : player.getColonies()) {
|
||||
list.addAll(colony.getBuildings());
|
||||
}
|
||||
return count(list);
|
||||
case SETTLEMENTS:
|
||||
return count(player.getSettlements())
|
||||
+ player.getSpecification()
|
||||
.getInteger(GameOptions.SETTLEMENT_LIMIT_MODIFIER);
|
||||
case FOUNDING_FATHERS:
|
||||
list.addAll(player.getFathers());
|
||||
return count(list);
|
||||
default:
|
||||
if (getMethodName() != null) {
|
||||
try {
|
||||
Method method = player.getClass().getMethod(getMethodName());
|
||||
if (method != null
|
||||
&& (int.class.equals(method.getReturnType())
|
||||
|| Integer.class.equals(method.getReturnType()))) {
|
||||
return (Integer) method.invoke(player);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
logger.log(Level.WARNING, "Unable to invoke: "
|
||||
+ getMethodName(), e);
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
} else if (scopeLevel == ScopeLevel.GAME) {
|
||||
return getValue(player.getGame());
|
||||
} else {
|
||||
return null;
|
||||
if (value != null) return value;
|
||||
switch (scopeLevel) {
|
||||
case GAME:
|
||||
return getValue(player.getGame());
|
||||
case PLAYER: // Real case, handled below
|
||||
break;
|
||||
default: // Inapplicable
|
||||
return null;
|
||||
}
|
||||
|
||||
final Specification spec = player.getSpecification();
|
||||
final String methodName = getMethodName();
|
||||
List<FreeColObject> list = new LinkedList<>();
|
||||
switch (operandType) {
|
||||
case UNITS:
|
||||
return count(player.getUnits());
|
||||
case BUILDINGS:
|
||||
for (Colony colony : player.getColonies()) {
|
||||
list.addAll(colony.getBuildings());
|
||||
}
|
||||
} else {
|
||||
return value;
|
||||
return count(list);
|
||||
case SETTLEMENTS:
|
||||
if (methodName == null) {
|
||||
return count(player.getSettlements())
|
||||
+ spec.getInteger(GameOptions.SETTLEMENT_LIMIT_MODIFIER);
|
||||
} else {
|
||||
final String methodValue = getMethodValue();
|
||||
int result = 0;
|
||||
for (Settlement settlement : player.getSettlements()) {
|
||||
Boolean b = settlement.invokeMethod(methodName,
|
||||
Boolean.class, Boolean.FALSE);
|
||||
if (String.valueOf(b).equals(methodValue)) result++;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
case FOUNDING_FATHERS:
|
||||
list.addAll(player.getFathers());
|
||||
return count(list);
|
||||
default:
|
||||
return player.invokeMethod(methodName, Integer.class,
|
||||
(Integer)null);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -301,20 +282,8 @@ public class Operand extends Scope {
|
|||
list.addAll(colony.getBuildings());
|
||||
break;
|
||||
default:
|
||||
if (getMethodName() != null) {
|
||||
try {
|
||||
Method method = colony.getClass().getMethod(getMethodName());
|
||||
if (method != null &&
|
||||
Integer.class.isAssignableFrom(method.getReturnType())) {
|
||||
return (Integer) method.invoke(colony);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
logger.log(Level.WARNING, "Unable to invoke: "
|
||||
+ getMethodName(), e);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
return colony.invokeMethod(getMethodName(), Integer.class,
|
||||
(Integer)null);
|
||||
}
|
||||
return count(list);
|
||||
} else {
|
||||
|
|
|
@ -19,8 +19,6 @@
|
|||
|
||||
package net.sf.freecol.common.model;
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
|
||||
import javax.xml.stream.XMLStreamException;
|
||||
|
||||
import net.sf.freecol.common.io.FreeColXMLReader;
|
||||
|
@ -169,20 +167,10 @@ public class Scope extends FreeColObject {
|
|||
if (!type.equals(object.getId())) {
|
||||
return matchNegated;
|
||||
}
|
||||
} else if (object instanceof FreeColGameObject) {
|
||||
try {
|
||||
Method method = object.getClass().getMethod("getType");
|
||||
if (method != null
|
||||
&& FreeColGameObjectType.class.isAssignableFrom(method.getReturnType())) {
|
||||
FreeColGameObjectType objectType =
|
||||
(FreeColGameObjectType) method.invoke(object);
|
||||
if (!type.equals(objectType.getId())) {
|
||||
return matchNegated;
|
||||
}
|
||||
} else {
|
||||
return matchNegated;
|
||||
}
|
||||
} catch (Exception e) {
|
||||
} else if (object instanceof FreeColObject) {
|
||||
FreeColGameObjectType fcgot = object.invokeMethod("getType",
|
||||
FreeColGameObjectType.class, (FreeColGameObjectType)null);
|
||||
if (fcgot == null || !type.equals(fcgot.getId())) {
|
||||
return matchNegated;
|
||||
}
|
||||
} else {
|
||||
|
@ -193,15 +181,8 @@ public class Scope extends FreeColObject {
|
|||
return matchNegated;
|
||||
}
|
||||
if (methodName != null) {
|
||||
try {
|
||||
Method method = object.getClass().getMethod(methodName);
|
||||
if (method != null
|
||||
&& !String.valueOf(method.invoke(object)).equals(methodValue)) {
|
||||
return matchNegated;
|
||||
}
|
||||
} catch (Exception e) {
|
||||
return matchNegated;
|
||||
}
|
||||
Object ret = object.invokeMethod(methodName, Object.class, null);
|
||||
if (!String.valueOf(ret).equals(methodValue)) return matchNegated;
|
||||
}
|
||||
return !matchNegated;
|
||||
}
|
||||
|
|
|
@ -102,11 +102,13 @@ public class LimitTest extends FreeColTestCase {
|
|||
assertFalse(rebelLimit.evaluate(dutch));
|
||||
|
||||
assertNotNull(colonyLimit);
|
||||
assertEquals(Limit.Operator.GT, colonyLimit.getOperator());
|
||||
assertEquals(Limit.Operator.GE, colonyLimit.getOperator());
|
||||
assertEquals(Operand.OperandType.SETTLEMENTS, colonyLimit.getLeftHandSide().getOperandType());
|
||||
assertEquals(Operand.ScopeLevel.PLAYER, colonyLimit.getLeftHandSide().getScopeLevel());
|
||||
assertEquals("isConnectedPort", colonyLimit.getLeftHandSide().getMethodName());
|
||||
assertFalse(colony.isConnectedPort());
|
||||
assertEquals(Integer.valueOf(0), colonyLimit.getLeftHandSide().getValue(dutch));
|
||||
assertEquals(Integer.valueOf(0), colonyLimit.getRightHandSide().getValue(dutch));
|
||||
assertEquals(Integer.valueOf(1), colonyLimit.getRightHandSide().getValue(dutch));
|
||||
assertFalse(colonyLimit.evaluate(dutch));
|
||||
|
||||
assertNotNull(yearLimit);
|
||||
|
|
Loading…
Reference in New Issue