正如评论所说,这是一个有点困难,充实实际的问题是什么。寻求调试帮助的问题通常被认为是脱离主题。
从已迄今为止所提供的资料,很难清楚地推导都参与了这一计算对象的“状态空间”。例如,getCanSpawn()
和getLives()>0
之间的关系。目前尚不清楚当canSpawn
标志将被设置为true
或false
,当lives
计数减少。该问题中的代码似乎也不认为已被其他玩家占据的位置已经被占据,不应该被用作派生位置。因此,一般建议是将算法分解为更小的部分,这样更容易测试和调试。例如,着眼于原代码:
public void SpawnPlayers()
{
for (Player spawnPlayer : players)
{
if (spawnPlayer.getCharacter().getCanSpawn())
{
...
}
}
}
最里面的部分适合于被提取到的方法等
private void spawnPlayer(Player playerToSpawn)
{
System.out.println("Spawning "+playerToSpawn);
...
}
这使得它也更容易理解(并且在控制台上看到) 当某个玩家即将产生,以及随后这个玩家会发生什么(如进一步System.out
声明所示)。
现在,有两两件事是相关的计算新玩家的产卵位置:
- 仍然可用产卵
- ,其他球员都在位置上的位置(和其因此,它也没有不再可供产卵)
这些可以被计算为两套......
Set<Point> availableSpawnPoints = ...;
Set<Point> positionsOfOtherPlayers = ...;
这些组的内容将取决于getCanSpawn()
和getLives()
的值,并且可能需要根据您的需求和这些方法的相互作用进行调整。
但是,在计算出这些集合后,您要求的整个算法(根据问题标题)归结为单一方法 - 即接收两组点的方法,并计算第一组距离第二组中的点最远。
对于“最远”的含义有不同的解释。你计算了一些距离的总和,这对我来说看起来有点奇怪。想象一下,你有两个“固定”点(现有球员的位置),以及一组“候选”点(其中玩家可以生成),因为这形象:
现在,想象该...
- A的距离与其它的是3.8和0.3,从而导致4.1
- B的距离其他的总和是2.0和2.0,从而导致4.0
总和
然后,用你的方法,点A将被选为产卵位置。 (在这个例子中,当你简单地计算“候选”点到任何固定点的最大距离时也是如此)。但直观地(并根据描述),您可能希望计算具有最大距离的任何其他点的最大距离的点。或者更自然地说:尽可能远离任何其他点。
所以重生点的计算很可能与一些方法做过类似
private Point computePointWithLargestMinimumDistance(
Iterable<? extends Point> points, Set<? extends Point> others)
{
...
}
在那里你可以在availableSpawnPoints
和positionsOfOtherPlayers
通过。
(BTW:该方法的签名是其最通用的形式,也可以使用更具体的参数类型,如HashSet<Point>
,但是这根本就不是在这里需要 - 所以为什么不这样做一般...。)
这也是在这里实现,素描,你提到的类,尽量在合理可行的:
import java.awt.Point;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Set;
public class PlayerSpawning
{
public static void main(String[] args)
{
PlayerSpawning p = new PlayerSpawning();
p.spawnPlayers();
}
private List<Player> players;
private PlayerMap map;
PlayerSpawning()
{
map = new PlayerMap();
players = new ArrayList<Player>();
Player player0 = new Player("player0");
player0.getCharacter().setPosition(new Point(0,0));
player0.getCharacter().setCanSpawn(false);
players.add(player0);
Player player1 = new Player("player1");
player1.getCharacter().setCanSpawn(true);
players.add(player1);
}
public void spawnPlayers()
{
for (Player player : players)
{
if (player.getCharacter().getCanSpawn())
{
spawnPlayer(player);
}
}
}
private void spawnPlayer(Player playerToSpawn)
{
System.out.println("Spawning "+playerToSpawn);
Set<Point> availableSpawnPoints =
new LinkedHashSet<Point>(map.getSpawnPoints());
Set<Point> positionsOfOtherPlayers =
new LinkedHashSet<Point>();
for (Player player : players)
{
if (player.getCharacter().getLives() <= 0)
{
continue;
}
if (player.getCharacter().getCanSpawn())
{
continue;
}
Point position = player.getCharacter().getPosition();
System.out.println(
"Have to consider that "+player+" is at "+position+
" - this position is no longer available for spawing!");
positionsOfOtherPlayers.add(position);
availableSpawnPoints.remove(position);
}
Point spawnPoint = computePointWithLargestMinimumDistance(
availableSpawnPoints, positionsOfOtherPlayers);
System.out.println("Spawning "+playerToSpawn+" at "+spawnPoint);
playerToSpawn.getCharacter().spawn(spawnPoint);
}
private Point computePointWithLargestMinimumDistance(
Iterable<? extends Point> points, Set<? extends Point> others)
{
System.out.println("Compute point from "+points);
System.out.println("that is furthest from "+others);
double largestMinDistance = Double.NEGATIVE_INFINITY;
Point result = null;
for (Point point : points)
{
double minDistance =
computeMinimumDistance(point, others);
if (minDistance > largestMinDistance)
{
largestMinDistance = minDistance;
result = point;
}
}
System.out.println(
"The point that has the largest minimum " +
"distance "+largestMinDistance+" to any other point is "+result);
return result;
}
private double computeMinimumDistance(
Point point, Iterable<? extends Point> others)
{
double minDistanceSquared = Double.POSITIVE_INFINITY;
for (Point other : others)
{
minDistanceSquared =
Math.min(minDistanceSquared, point.distanceSq(other));
}
return Math.sqrt(minDistanceSquared);
}
}
class Player
{
private String name;
private Character character = new Character();
public Player(String name)
{
this.name = name;
}
public Character getCharacter()
{
return character;
}
@Override
public String toString()
{
return name;
}
}
class Character
{
private Point position = new Point();
private boolean canSpawn = false;
public boolean getCanSpawn()
{
return canSpawn;
}
public void setCanSpawn(boolean canSpawn)
{
this.canSpawn = canSpawn;
}
public int getLives()
{
return 1;
}
public Point getPosition()
{
return position;
}
public void setPosition(Point p)
{
position.setLocation(p);
}
public void spawn(Point spawnPoint)
{
setPosition(spawnPoint);
canSpawn = false;
}
}
class PlayerMap
{
public List<Point> getSpawnPoints()
{
return Arrays.asList(
new Point(0,0),
new Point(200,0),
new Point(0, 500),
new Point(200,500));
}
}
,如需要,本MCVE的输出:
Spawning player1
Have to consider that player0 is at java.awt.Point[x=0,y=0] - this position is no longer available for spawing!
Compute point from [java.awt.Point[x=200,y=0], java.awt.Point[x=0,y=500], java.awt.Point[x=200,y=500]]
that is furthest from [java.awt.Point[x=0,y=0]]
The point that has the largest minimum distance 538.5164807134504 to any other point is java.awt.Point[x=200,y=500]
Spawning player1 at java.awt.Point[x=200,y=500]
很难想象这里可能是什么“答案”。这似乎是一个非常广泛和普遍的问题,接近“寻找调试帮助”。在不知道现有类的情况下,很难猜测可能存在哪些错误。所以这里是一个猜测:调用'spawn'方法是否会改变'getPosition()'中返回的点?如果可能的话,发布一个MCVE,或者忽略与现有类无关的方法,或者通过在更通用的“虚拟”类上实现算法*本身*。 – Marco13
你确定你的数学没问题吗?或者这是一个编程问题? –
我不确定数学和编程,因为我看不出任何问题,但它仍然无法正常工作。 –