所以我把所有这些课程放在一起,用于捕食者和猎物与世界之间的所有连接。我唯一真正难倒的是Predator类的run()方法(它们是如何捕获的)。
理论很简单。捕食者必须聚集在北部,南部,东部和西部的猎物周围,而DataChannel类将会注意到并抓住猎物并将其从地图上取下。但我的工作就是通过让掠夺者彼此沟通,然后追捕猎物(我编程随机移动)来实现这一目标。
这是所有课程。请记住,Predator类的run()方法是我难倒的地方。其他一切都是我想要的。有什么帮助吗?
/**
Predator class, with no "hunting" functionality.
*/
import java.io.*;
import javax.imageio.ImageIO;
import java.util.ArrayList;
import javaclient2.*;
import javaclient2.structures.*;
public class Predator extends Thread
{
private Position2DInterface position_interface = null;
private BlobfinderInterface blob_finder = null;
private PlayerClient playerClient = null;
private DataChannel dc = null;
private String name = "";
public Predator(String name, DataChannel dc, int id, float x, float y){
this.name = name;
this.playerClient = new PlayerClient("localhost", 6665);
blob_finder = playerClient.requestInterfaceBlobfinder(id,
PlayerConstants.PLAYER_OPEN_MODE);
position_interface = playerClient.requestInterfacePosition2D(id,
PlayerConstants.PLAYER_OPEN_MODE);
playerClient.runThreaded (-1, -1);
//wait until the intefaces are ready before doing anything
while(!blob_finder.isDataReady() ||
!position_interface.isDataReady()) {
try{
sleep(100);
}catch(Exception e){
System.err.println("Error sleeping!");
e.printStackTrace();
System.exit(-1);
}
}
PlayerPose pp = new PlayerPose();
pp.setPx(x);
pp.setPy(y);
position_interface.setOdometry(pp);
this.dc = dc;
dc.registerPredator(name, position_interface);
}
/**
* @param recipient The predator to deliver the message to.
* @param msg The message.
*
* Deliver a message to another predator.
*
*/
public void sendMessage(String recipient, Object msg){
dc.sendMessage(recipient, msg);
}
/**
* @param msg The message.
*
* Deliver a message to all other predators.
*
*/
public void broadcastMessage(Object msg){
for(String predator : dc.getPredators()){
sendMessage(predator, msg);
}
}
/**
*
* Get the next message from other predators.
*
* @return The next message, or null if there are no unread messages.
*
*/
public Object getMessage(){
return dc.getMessage(this.name);
}
public void run(){
// hunt the prey!
System.out.println("There are " + dc.numLivingPreys() +
" left to capture!");
}
}
import java.util.concurrent.ConcurrentLinkedQueue;
import java.util.concurrent.ConcurrentHashMap;
import java.util.Vector;
import java.util.Set;
import javaclient2.*;
import javaclient2.structures.*;
/**
Object that records all of the predator locations, and kills prey when
they have been captured.
*/
public class DataChannel extends Thread{
static final float FUDGE_FACTOR = 1;
static final float CAPTURE_RANGE = 5;
private ConcurrentHashMap<String, Position2DInterface> pred_pids =
new ConcurrentHashMap<String, Position2DInterface>();
private ConcurrentHashMap<String, Position2DInterface> prey_pids =
new ConcurrentHashMap<String, Position2DInterface>();
private ConcurrentHashMap<String, Prey> preys =
new ConcurrentHashMap<String, Prey>();
private ConcurrentHashMap<String, ConcurrentLinkedQueue<Object>> msgs =
new ConcurrentHashMap<String, ConcurrentLinkedQueue<Object>>();
public void registerPredator(String name, Position2DInterface pid){
pred_pids.put(name, pid);
msgs.put(name, new ConcurrentLinkedQueue<Object>());
}
public void registerPrey(String name, Position2DInterface pid, Prey prey){
prey_pids.put(name, pid);
preys.put(name, prey);
}
public int numLivingPreys(){
return preys.size();
}
public Set<String> getPredators(){
return msgs.keySet();
}
public void sendMessage(String recipient, Object msg){
(msgs.get(recipient)).add(msg);
}
public Object getMessage(String recipient){
return (msgs.get(recipient)).poll();
}
public float getPredX(String predator){
try{
return (pred_pids.get(predator)).getX();
}catch(Exception ex) {}
return -1.0f;
}
public float getPredY(String predator){
try{
return (pred_pids.get(predator)).getY();
}catch(Exception ex) {}
return -1.0f;
}
public float getPreyX(String prey){
try{
return (prey_pids.get(prey)).getX();
}catch(Exception ex) {}
return -1.0f;
}
public float getPreyY(String prey){
try{
return (prey_pids.get(prey)).getY();
}catch(Exception ex) {}
return -1.0f;
}
public void run(){
while(true){
try{
sleep(100);
}catch(Exception e){
System.err.println("Error sleeping!");
e.printStackTrace();
System.exit(-1);
}
//get the location of each predator
Vector<Float> xpos = new Vector<Float>();
Vector<Float> ypos = new Vector<Float>();
Vector<String> pred_names= new Vector<String>();
for(String predator : pred_pids.keySet()){
if(pred_pids.get(predator) == null){
System.err.println("pred_pids does not have " + predator);
System.exit(-1);
}
xpos.add(getPredX(predator));
ypos.add(getPredY(predator));
pred_names.add(predator);
}
//for each prey, see if all of the four positions are guarded
for(String prey : prey_pids.keySet()){
boolean north = false;
boolean south = false;
boolean east = false;
boolean west = false;
if(prey_pids.get(prey) == null){
System.err.println("prey_pids does not have " + prey);
System.exit(-1);
}
float prey_x = getPreyX(prey);
float prey_y = getPreyY(prey);
for(int i=0; i < xpos.size(); i++){
//NORTH
if(Math.abs(xpos.get(i) - prey_x)<FUDGE_FACTOR &&
(ypos.get(i) - prey_y) > 0 &&
(ypos.get(i) - prey_y) < CAPTURE_RANGE){
north = true;
}
//SOUTH
if(Math.abs(xpos.get(i) - prey_x)<FUDGE_FACTOR &&
(prey_y - ypos.get(i)) > 0 &&
(prey_y - ypos.get(i)) < CAPTURE_RANGE){
south = true;
}
//EAST
if(Math.abs(ypos.get(i) - prey_y)<FUDGE_FACTOR &&
(xpos.get(i) - prey_x) > 0 &&
(xpos.get(i) - prey_x) < CAPTURE_RANGE){
east = true;
}
//WEST
if(Math.abs(ypos.get(i) - prey_y)<FUDGE_FACTOR &&
(prey_x - xpos.get(i)) > 0 &&
(prey_x - xpos.get(i)) < CAPTURE_RANGE){
west = true;
}
}
//prey is boxed in
if(north && south && east && west){
(preys.get(prey)).die();
preys.remove(prey);
prey_pids.remove(prey);
}
}
if(preys.size() == 0){
System.err.println("Congratulations: All prey are captured.");
System.exit(0);
}
}
}
}
import javaclient2.structures.*;
import javaclient2.*;
import java.util.Random;
/**
Prey class.
*/
public class Prey extends Thread{
private final int ROTATE_SECONDS = 500;
private final int MOVE_SECONDS = 3000;
private final int WAIT_SECONDS = 8000;
private final int WAIT_JITTER = 4000;
private Position2DInterface position_interface = null;
private PlayerClient playerClient = null;
private DataChannel dc = null;
private String my_name = null;
private boolean keep_going = true;
Random rand = new Random();
public Prey(String name, DataChannel dc, int id, float x, float y){
this.playerClient = new PlayerClient("localhost", 6665);
position_interface = playerClient.requestInterfacePosition2D(id,
PlayerConstants.PLAYER_OPEN_MODE);
playerClient.runThreaded (-1, -1);
this.dc = dc;
this.my_name = name;
while(!position_interface.isDataReady()) {
try{
sleep(100);
}catch(Exception e){
System.err.println("Error sleeping!");
e.printStackTrace();
System.exit(-1);
}
}
PlayerPose pp = new PlayerPose();
pp.setPx(x);
pp.setPy(y);
position_interface.setOdometry(pp);
dc.registerPrey(name, position_interface, this);
}
public float getX(){
try{
return position_interface.getX();
}catch(Exception ex) {}
return -1.0f;
}
public float getY(){
try{
return position_interface.getY();
}catch(Exception ex) {}
return -1.0f;
}
public void run(){
float old_x = getX();
float old_y = getY();
while(keep_going){
float current_x = getX();
float current_y = getY();
float x, y;
if(current_x <=0){
if(rand.nextFloat() < 0.75)
x = rand.nextFloat()*6;
else
x = rand.nextFloat()*-6;
}else{
if(rand.nextFloat() < 0.75)
x = rand.nextFloat()*-6;
else
x = rand.nextFloat()*6;
}
if(current_y <=0){
if(rand.nextFloat() < 0.75)
y = rand.nextFloat()*12;
else
y = rand.nextFloat()*-12;
}else{
if(rand.nextFloat() < 0.75)
y = rand.nextFloat()*-12;
else
y = rand.nextFloat()*12;
}
PlayerPose pp = new PlayerPose();
pp.setPx(x);
pp.setPy(y);
position_interface.setVelocity(pp, 0);
sleep(MOVE_SECONDS);
position_interface.setSpeed(0.0f, 0.0f);
sleep(WAIT_SECONDS + rand.nextInt() % WAIT_JITTER);
}
position_interface.setSpeed(9999.0f, 0.0f);
}
public void sleep(int ms){
try{
Thread.sleep(ms);
}catch(Exception e){
System.err.println("Error sleeping.");
e.printStackTrace();
System.exit(-1);
}
}
public float angle_diff(float current, float desired)
{
float diff = desired - current;
while(diff > 180.0f) diff -= 360.0f;
while(diff < -180.0f) diff += 360.0f;
return diff;
}
public float fix_angle(float f){
while(f < 0.0f) f += 360.0f;
while(f > 360.0f) f -= 360.0f;
return f;
}
public void die(){
System.err.println("Prey \"" + this.my_name + "\" has been killed!");
this.keep_going = false;
}
}
public class Driver{
public static void main(String args[]){
DataChannel dc = new DataChannel();
//instantiate the predators
Predator pred1 = new Predator("pred1", dc, 0, 0, 13);
Predator pred2 = new Predator("pred2", dc, 1, 0, 0);
Predator pred3 = new Predator("pred3", dc, 2, 0, -13);
Predator pred4 = new Predator("pred4", dc, 3, -13, -8);
Predator pred5 = new Predator("pred5", dc, 4, -13, 8);
//instantiate the prey
Prey prey1 = new Prey("prey1", dc, 5, 18, 18);
Prey prey2 = new Prey("prey2", dc, 6, 18, -18);
Prey prey3 = new Prey("prey3", dc, 7, 18, -9);
Prey prey4 = new Prey("prey4", dc, 8, 18, 9);
//start all the threads
dc.start();
pred1.start();
pred2.start();
pred3.start();
pred4.start();
pred5.start();
prey1.start();
prey2.start();
prey3.start();
prey4.start();
}
}
答案 0 :(得分:1)
掠夺者实际上并不需要沟通。他们只需要找到猎物,并尽可能靠近它移动。
所以,如果p1
和p2
代表捕食者而o1
代表猎物:
A B C D
0 . . . .
1 . p2 . .
2 . . p1 .
3 . . o1 .
p1
尽可能接近o1
,因此保持不变
然而,p2
可以通过转移到B3来接近。
现在,在您的示例代码中,您有4个捕食者和5个猎物。这可能导致一个案例,即没有足够的捕食者专注于一个猎物来消除它。要做到这一点,你需要一个启发式的方法:“喜欢捕食最多的猎物”。
您可能还需要考虑双方平等的情况。每个猎物你最终可以捕食一只食肉动物。这可以通过让掠食者放弃一段时间而不让他们的猎物被消灭来解决。你会希望包含一些随机性,以便不是所有的捕食者都会同时放弃。像baseGiveUpTime + (int)(2 * numPred * Math.random())