Domanda

Così ho tutte queste classi messo insieme per tutta la connettività tra predatori e prede e il mondo. L'unica cosa che sto veramente perplesso su è il metodo run () per la classe Predator (il modo in cui la caccia).

La teoria è semplice. I predatori devono raccogliere intorno alla preda sul suo lato Nord, Sud, Est e Ovest, e la classe DataChannel noteranno che e catturare la preda e portarla dalla carta geografica. Ma il mio lavoro è quello di ottenere che questo accada, avendo i Predators comunicare l'uno con l'altro, e poi inseguire e cacciare lungo il Prey (che ho programmato di muoversi in modo casuale).

Ecco tutte le classi. Ricordate, il metodo run () per la classe Predator è dove sto perplesso. Tutto il resto è come voglio che sia. Qualsiasi aiuto?

/**

    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();
    }
} 
È stato utile?

Soluzione

I predatori in realtà non hanno bisogno di comunicare. Hanno solo bisogno di individuare la preda, e spostare il più possibile vicino ad esso.

Quindi, se p1 e p2 rappresenta predatori e prede o1 rappresenta:

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

p1 è così vicino come si può arrivare a o1, quindi resta fermo.
p2, tuttavia, può avvicinarsi passando a B3.

Ora, nel codice di esempio, si dispone di 4 predatori e prede 5. Ciò potrebbe portare a un caso in cui non ci sono abbastanza predatori concentrati su una preda per eliminarla. Per funzionare, è necessario un euristica come:. "Preferire la preda con la maggior parte dei predatori"

Si può anche prendere in considerazione il caso in cui entrambe le parti sono uguali. Si potrebbe finire con un predatore per ogni preda. Che può essere gestito avendo predatori rinunciare se un periodo trascorso senza la preda per essere eliminati. Si vuole includere alcune casualità in modo che non tutti i predatori rinunciano allo stesso tempo. Qualcosa di simile baseGiveUpTime + (int)(2 * numPred * Math.random())

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top