代码之家  ›  专栏  ›  技术社区  ›  Scott

玩家阶段狩猎游戏

  •  0
  • Scott  · 技术社区  · 14 年前

    所以我把所有这些类放在一起,以连接捕食者、猎物和世界。唯一让我感到困惑的是Predator类的run()方法(它们如何狩猎)。

    这个理论很简单。掠食者必须聚集在它的北边、南边、东边和西边的猎物周围,数据通道类将注意到这一点,并捕获猎物并将其从地图上取下。但我的工作是通过让掠食者彼此交流,然后追捕猎物(我设定为随机移动)。

    这是所有的课程。记住,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 回复  |  直到 14 年前
        1
  •  1
  •   Devon_C_Miller    14 年前

    掠食者实际上不需要交流。它们只需要找到猎物,并尽可能靠近它。

    所以,如果 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())