正如評論所說,這是一個有點困難,充實實際的問題是什麼。尋求調試幫助的問題通常被認爲是脫離主題。
從已迄今爲止所提供的資料,很難清楚地推導都參與了這一計算對象的「狀態空間」。例如,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
你確定你的數學沒問題嗎?或者這是一個編程問題? –
我不確定數學和編程,因爲我看不出任何問題,但它仍然無法正常工作。 –