2010-06-09 5 views
0

J'ai donc tous ces cours mis en place pour toute la connectivité entre Predators et Prey et le monde. La seule chose sur laquelle je suis vraiment perplexe est la méthode run() pour la classe Predator (comment ils chassent).Game Stage Hunting Game - Java

La théorie est simple. Les prédateurs doivent se rassembler autour de la Proie sur son côté Nord, Sud, Est et Ouest, et la classe DataChannel le remarquera et capturera la proie et l'enlèvera de la carte. Mais mon travail consiste à faire en sorte que cela se produise, en faisant communiquer les Prédateurs les uns avec les autres, puis chasser et traquer la Proie (que j'ai programmée pour me déplacer au hasard).

Voici toutes les classes. Rappelez-vous, la méthode run() pour la classe Predator est l'endroit où je suis perplexe. Tout le reste est comme je le veux. De l'aide?

/** 

    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(); 
    } 
} 

Répondre

1

Les prédateurs n'ont pas vraiment besoin de communiquer. Ils ont juste besoin de localiser leurs proies, et de se rapprocher le plus possible.

Donc, si p1 et p2 représente les prédateurs et proies o1 représente:

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

p1 est aussi proche qu'il peut arriver à o1, de sorte qu'il reste mis.
p2, cependant, peut se rapprocher en passant à B3. Maintenant, dans votre exemple de code, vous avez 4 prédateurs et 5 proies. Cela pourrait conduire à un cas où il n'y a pas assez de prédateurs concentrés sur une proie pour l'éliminer. Pour que cela fonctionne, vous avez besoin d'une heuristique comme: "préférez la proie avec le plus de prédateurs".

Vous devrez peut-être également prendre en compte le cas où les deux côtés sont égaux. Vous pourriez vous retrouver avec un prédateur par proie. Cela peut être géré en faisant abandonner les prédateurs si une période s'écoule sans que leur proie soit éliminée. Vous voudrez inclure un peu de hasard afin que tous les prédateurs n'abandonnent pas en même temps. Quelque chose comme baseGiveUpTime + (int)(2 * numPred * Math.random())

+0

Bonne entrée. Cependant, j'ai en fait 5 prédateurs et 4 proies, donc il devrait toujours y avoir plus que suffisamment de Prédateurs pour capturer la proie. Ma principale question cependant, est comment puis-je mettre en œuvre cela? – Scott

+0

Obtenez les listes de proies et de prédateurs (sans doute à partir de votre DC). Créez une liste de proies ordonnée par le nombre de prédateurs adjacents (décroissant) et la distance (ascendante). Si vous êtes à proximité d'une proie et que le délai d'expiration n'a pas expiré, ne faites rien. Si le délai d'attente a expiré, marquer la proie actuelle comme invalide et reprendre le mouvement vers la proie suivante. Sinon, déplacez-vous vers la première proie de la liste. –

+0

Je comprends un peu comment vous conceptualisez ceci, même si j'ai de la difficulté à visualiser exactement ce que vous voulez dire. – Scott