2010-06-09 128 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