/**
*
* @param listOfEntities - The list to be checked
* @param entity - The entity to base the searching off of.
* @return - the Point of the highest scoring goal
*
* TODO: Make this code better, it relies too much on instanceof and is not OOP.
*
*/
protected Point getBestMove(List<Point> listOfEntities,Entity entity) {
//Store the position of the highest valued prey.
Point highestScore = null;
// Check if the entity passed in is a Sheep, if it is
// then loop through the map within the line of sight
// of this animal and then score individually.
// Based on the result move in a direction that is benifitial.
if (entity instanceof Sheep) {
// The scoring map using a Point, Double system.
Map<Point, Double> bestMoveMap = new HashMap<>();
//Loop through for every entity position in listOfEntities
for(Point currentEntity : listOfEntities) {
//Put this current entity with a basevalue of 2400.
bestMoveMap.put(currentEntity, 2400.0);
// Loop X and Y within line of sight (- since we want both directions)
for (int xPos = - lineOfSight; xPos <= lineOfSight; xPos++) {
for (int yPos = - lineOfSight; yPos <= lineOfSight; yPos++) {
// Get the starting point of this entity
double points = bestMoveMap.get(currentEntity);
// Get the distance between this entity and the goal entity.
Point goalPoint = new Point(currentEntity.x + xPos,currentEntity.y + yPos);
// Store all entities in a list within range.
List<Entity> entities = pasture.getGrid().get(goalPoint);
//If list is not empty or null
if(entities != null && entities.isEmpty() == false) {
//Loop through all the entities
for(Entity e : entities) {
//If it is a wolf.
if(e instanceof Wolf) {
//Score depending on distance using a formula.
double distanceToWolf = goalPoint.distance(currentEntity);
// Calculate using a formula where we factor in the distance to the wolf.
points = points + (1000 / (1 + distanceToWolf));
// Put this entity with the position.
bestMoveMap.put(currentEntity, points);
}
// If it is a plant.
if(e instanceof Plant) {
//Score depending on distance using a formula.
double distanceToPlant = goalPoint.distance(currentEntity);
points = points - (100 / (1 + distanceToPlant));
bestMoveMap.put(currentEntity, points);
}
}
}
}
}}
//Minimum score.
Map.Entry<Point, Double> minScore = null;
// Get the highest scored value and set minScore aswell as highestScore.
// Since Java 8 you could do this:
// Collections.max(bestMoveMap.entrySet(), Map.Entry.comparingByValue()).getKey();
for (Map.Entry<Point, Double> entry : bestMoveMap.entrySet()){
if (minScore == null || minScore.getValue() > entry.getValue()){
// Set highestScore to that and minScore to that entry.
minScore = entry;
highestScore= minScore.getKey();
}
}
}
// If the entity is a Wolf
if(entity instanceof Wolf){
Map<Point, Double> bestMoveMap = new HashMap<>();
for(Point thisPoint : listOfEntities){
bestMoveMap.put(thisPoint, 2000.0);
for (int x = -lineOfSight; x <= lineOfSight; x++) {
for (int y = -lineOfSight; y <= lineOfSight; y++) {
Point p = new Point(thisPoint.x + x,thisPoint.y + y);
List<Entity> l =pasture.getGrid().get(p);
if(l!=null){
for(Entity e:l){
//Only interested in Sheeps
if(e instanceof Sheep){
double distanceToSheep=p.distance(thisPoint);
double points=bestMoveMap.get(thisPoint);
points = points -(10000/(0.1+distanceToSheep));
bestMoveMap.put(thisPoint, points);
}
}
}
}
}
}
// Set highestScore to the best Point.
Map.Entry<Point, Double> min = null;
for(Map.Entry<Point, Double> entry : bestMoveMap.entrySet()) {
if (min == null || min.getValue() > entry.getValue()) {
min = entry;
highestScore= min.getKey();
}
}
}
// Return the highest score, the Point that scored the highest
return highestScore;
}
我在上面找到了这个代码,它为动物找到了最好的新Point。基本思路是:
羊吃草,避免狼群 狼群捕杀绵羊并且没有敌人
这很长,我想知道是否有任何方法可以缩短或改善它?我觉得好像&#34; instanceof&#34;是一个坏习惯,但我不知道该怎么做,否则或用什么来取代它。特别是因为代码在许多方面非常相似。也许我可以用某种方式结合它?
答案 0 :(得分:0)
避免instanceof
的方法是将功能移到类中并使用继承和多态。
因此,您可以调用if( e instanceof Wolf ) { do wolfy stuff... } else if( e instanceof Plant ) { do plant stuff... }
而不是e.doStuff()
。
然后,Wolf
实体将具有doStuff()
的实现,它可以执行wolfy,而Plant
实体将拥有自己的doStuff()
实现,它可以生成植物。
当然,基类Entity
会声明public abstract doStuff();
,以便Wolf
和Plant
可以覆盖它。