2010-06-09 131 views
0

因此,我将所有这些类放在一起,用于捕食者和猎物与世界之间的所有连接。我唯一难以忍受的就是Predator类的run()方法(他们是如何捕获的)。玩家阶段狩猎游戏 - Java

理论很简单。捕食者必须在北方,南方,东方和西方聚集猎物,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(); 
    } 
} 

回答

1

捕食者实际上并不需要沟通。他们只需要定位猎物,并尽可能靠近它。

所以,如果p1p2代表捕食者和o1代表的猎物:

A B C D 
0 . . . . 
1 . p2 . . 
2 . . p1 . 
3 . . o1 . 

p1是接近,因为它可以得到o1,所以它原地踏步。然而,通过移动到B3可以更接近
p2

现在,在你的示例代码中,你有4个捕食者和5个猎物。这可能会导致一个案例,没有足够的捕食者专注于一只猎物来消除它。为了达到这个目的,你需要一个启发式的方法,比如:“最喜欢捕食者最喜欢的食物”。

您可能还需要考虑双方均等的情况。你可以结束每个猎物一个捕食者。如果一段时间没有被猎物消灭,掠食者就会放弃。你会想要包含一些随机性,以免并非所有的掠食者同时放弃。类似于baseGiveUpTime + (int)(2 * numPred * Math.random())

+0

良好的输入。然而,我实际上有5个掠食者和4个猎物,所以应该总有足够多的掠夺者捕获猎物。然而,我的主要问题是,我该如何去实施呢? – Scott 2010-06-09 19:40:37

+0

获取猎物和捕食者的列表(大概来自你的直流)。根据相邻捕食者的数量(降序)和距离(升序)创建一个猎物列表。如果与猎物相邻并且超时未到期,则不要执行任何操作。如果超时已过,请将当前猎物标记为无效,并继续向下一只猎物移动。否则,向列表中的第一只猎物移动。 – 2010-06-09 20:14:15

+0

我有点理解你是如何构思这一点的,尽管我有一些问题确切地想象你的意思。 – Scott 2010-06-09 20:40:32