वाटर बैलून वार्स


12

यह राजा-का-पहाड़ी खेल एक रणनीति खेल है जिसमें आपको पानी के गुब्बारे के चारों ओर फेंकना चाहिए और पानी से अलग होने से बचना चाहिए। लक्ष्य सबसे अधिक अंक प्राप्त करना है। आपको खेत का नक्शा और पानी के गुब्बारे का स्थान दिया जाएगा। आप या तो वापस कर सकते हैं कि आप एक निश्चित दिशा में पानी के गुब्बारे (यदि आप काफी करीब हैं) को हिट करना चाहते हैं या आप एक निश्चित दिशा में आगे बढ़ना चाहते हैं।

विशेष रूप से: पानी का गुब्बारा (0, 0)30 इकाइयों के उच्च और ड्रॉप पर शुरू होगा । यदि पानी का गुब्बारा जमीन से टकराता है, तो एक खिलाड़ी को बेतरतीब ढंग से 4 अंक खोने के लिए चुना जाएगा, और अधिक वजन के साथ उन लोगों को दिया जाएगा जो गुब्बारे के करीब हैं। इसके अलावा, अंतिम बार गुब्बारा मारने वाला खिलाड़ी 3 अंक अर्जित करेगा। इसलिए, यदि आप गुब्बारे को सीधे नीचे मारते हैं, तो आप संभवतः 1 अंक खो देंगे।

आप एक क्लास लिखेंगे जो फैली हुई है Player। आपको कंस्ट्रक्टर को लागू करना आवश्यक है। निर्माणकर्ता ऐसा दिखेगा:

public Player1() {
    super(/* Some numbers */ 3, 3, 4)
}

ये संख्याएँ हैं double। पहला नंबर खिलाड़ी की गति का प्रतिनिधित्व करता है, दूसरा ताकत का प्रतिनिधित्व करता है, और तीसरा भाग्य का प्रतिनिधित्व करता है। संख्या 10 या उससे कम होनी चाहिए और कोई संख्या शून्य से कम या उसके बराबर नहीं हो सकती है।

दूसरा, आपको moveविधि को लागू करना होगा । यह एक उदाहरण moveविधि है:

@Override
protected Action move(Map<Player, Point2D> map, Balloon b) {
    // Get my own location
    Point2D myself = map.get(this);
    // If I'm close enough to the balloon
    // then hit the balloon
    if (myself.distanceSq(b.getLocation()) <= 16) {
        double d = (r.nextDouble() - 0.5) * 3;
        // Random y direction, z direction is what's left 
        return new Hit(0, d, Math.sqrt(9 - d*d));
    } else {
        double diffX = b.getLocation().getX() - myself.getX(),
                diffY = b.getLocation().getY() - myself.getY();
        // Move towards the balloon
        return new Movement(Math.signum(diffX)*3/Math.sqrt(2), Math.signum(diffY)*3/Math.sqrt(2));
    }
}

यहां कई महत्वपूर्ण चीजें हैं। सबसे पहले, ध्यान दें कि फ़ील्ड को एक के रूप में पारित किया गया है Map<Player, Point2D>। क्षेत्र अनंत है - आप कितनी दूर जा सकते हैं इसकी कोई सीमा नहीं है। यह एक 2-आयामी सरणी या ऐसा कुछ भी नहीं है। इसके अलावा, इसका मतलब है कि आपके स्थान के रूप में आपके पास गैर-पूर्णांक निर्देशांक होंगे। यह पूरी तरह से ठीक है।

एक और परिणाम यह है कि खिलाड़ी और गुब्बारा ओवरलैप हो सकते हैं। वास्तव में, दो खिलाड़ी ठीक उसी स्थान पर हो सकते हैं!

गुब्बारे में एक निश्चित वेग और दिशा होती है। सामान्य तौर पर, यह 3 इकाइयों / चरण की दर से घटेगा। यह एक xदिशा और yदिशा में भी चलती है । जब आप वापस लौटते हैं Hit, तो आप x, y, और z दिशाएँ पास करते हैं जो आप गुब्बारे को आगे बढ़ा रहे हैं। आप एक गुब्बारे आप (केवल दो आयामों पर) से जिसकी ऊंचाई 10 से अधिक है या जिसका दूरी 4. अधिक से अधिक इसके अलावा है हिट कर सकते हैं नहीं है, अगर यह सच है कि x^2 + y^2 + z^2 > s^2जहां sअपनी ताकत है, और x, yऔर zदिशाओं कि आप हिट हैं , आपकी कार्रवाई छोड़ दी गई है। आपके हिट के बल को एक यादृच्छिक संख्या के बीच बढ़ाया जाता है ( 0और luckइसका मतलब है कि अगर आपकी किस्मत कम है तो यह नीचे जा सकता है)।

इसी तरह, आप एक के Movementसाथ लौट सकते हैं xऔर yनिर्देशांक कर सकते हैं कि आप आगे बढ़ रहे हैं (ध्यान दें कि आप हवा में कूद नहीं सकते)। यदि आपकी गति x^2 + y^2 > s^2कहां sहै, तो आपकी कार्रवाई छोड़ दी जाती है।

यदि पानी का गुब्बारा जमीन से टकराता है, तो एक यादृच्छिक खिलाड़ी चुना जाता है, जो अधिक वजन वाले लोगों को दिया जाता है, जो निकटतम हैं - लेकिन उन लोगों के लिए कम वजन जिनके पास अधिक भाग्य है। चुना गया खिलाड़ी 4 अंक खो देता है।

नियंत्रक: https://github.com/prakol16/water-balloon-wars/tree/master

खेल 1000 चरणों तक रहता है। आखिर में एक फाइल आएगी जिसका नाम है log.out। गेम को देखने के लिए इस फिडेल में डेटा कॉपी और पेस्ट करें: https://jsfiddle.net/prankol57/s2x776dt/embedded/result/

या इससे भी बेहतर, इसे 3 डी में देखें: http://www.brianmacintosh.com/waterballoonwars (BMac के लिए धन्यवाद)

100 के बाद सबसे अधिक अंकों वाला खिलाड़ी (अधिक हो सकता है, लेकिन कम नहीं) खेल जीतता है।

यदि आप कोई समाधान प्रस्तुत करना चाहते हैं, तो आप https://github.com/prakol16/water-balloon-wars/tree/master पर वास्तव में विशिष्ट विवरण पढ़ना चाह सकते हैं ।

3/8 संपादित करें :

ये अब के लिए अंतिम स्कोर हैं (1000 पुनरावृत्तियों, खिलाड़ियों 1 और 2 को शामिल किए बिना)। यदि आप अपनी पोस्ट को संपादित करते हैं, तो आप टिप्पणी कर सकते हैं, और मैं स्कोर फिर से बनाऊंगा:

{
    class players.BackAndForth=-75.343,
    class players.Hydrophobe=-0.800,
    class players.KeepAway=-53.064,
    class players.Weakling=39.432,
    class players.Repeller=21.238,
    class players.LuckyLoser=-30.055,
    class players.AngryPenguin=-49.310
}

विजेता Weaklingऔसत 39 अंकों के साथ था । 2 वाँ स्थान Repeller21 अंकों के साथ था ।


1
जब आप गुब्बारे को मारते हैं तो क्या होता है? कैसे चलती है? क्या होगा अगर कई लोग इसे मारते हैं?
कीथ रान्डेल

Jsfiddle के साथ एनीमेशन वास्तव में अच्छा है!
कॉमनग्यू

वैसे, आपको खिलाड़ी वर्ग के फाइनल में तरीके बनाने चाहिए, अन्यथा प्रस्तुतियाँ उन्हें ओवरराइड कर सकती हैं।
कॉमनग्यू

2
आप उलटे speedऔर strengthप्लेयर कंस्ट्रक्टर में।
थ्रक्स

@KeithRandall dirX, dirYऔर dirZ(अपनी किस्मत द्वारा परिलक्षित) बस गुब्बारे का वेग से जुड़ जाते हैं। यदि कई लोग इसे (कुछ हद तक संभावना नहीं) मारते हैं, तो खिलाड़ी को तीन अंक मिल सकते हैं, भाग्य पर फैसला किया जाता है (विशिष्ट विवरण देखें)
soktinpk

जवाबों:


7

सिम्युलेटर

मुझे आशा है कि यह ठीक है, क्योंकि यह वास्तव में एक प्रविष्टि नहीं है। मुझे वास्तव में दृश्य सिम्युलेटर का विचार पसंद आया और मैं अपना खुद का निर्माण करना चाहता था जिससे एक बार में सब कुछ देखना आसान हो जाए (पूर्ण 3 डी)।

2/28 9:06 AM पीएसटी : फॉलो कंट्रोल, रंगों के साथ अपडेट

3/4 8:47 AM PST : सिमुलेशन स्पीड के लिए स्लाइडर के साथ अपडेट करें, और पेज को रीफ्रेश किए बिना वास्तव में काम करने के लिए एक नया गेम शुरू करें (कैश्ड स्क्रिप्ट को फिर से लोड करने के लिए Ctrl-F5 का उपयोग करें)

ऑनलाइन थ्रीजेएस विज़ुअलाइज़र

यहाँ छवि विवरण दर्ज करें


3
+1000 वह अद्भुत है। धन्यवाद
soktinpk

क्या आपका मतलब Ctrl + F5 नहीं है, Shift + F5 नहीं है?
टाइमटेक

ऐसा लगता है कि दोनों क्रोम में काम करते हैं।
21

7

आगे पीछे

यह बॉट गुब्बारे को पास और हिट करने की कोशिश करता है जब तक कि उसकी ऊंचाई बहुत कम न हो और वह दूर जाने की कोशिश करता है।

package players;

import java.awt.geom.Point2D;
import java.util.Map;

import balloon.Action;
import balloon.Balloon;
import balloon.Player;
import balloon.Action.Hit;
import balloon.Action.Movement;

public class BackAndForth extends Player {

    static int round = 0;
    static int speed = 3;
    static int strength = 1;
    static boolean hit = false;
    static double previousHeight = 30.0;

    public BackAndForth() {
        super(speed, strength, 10 - speed - strength);
    }

    @Override
    protected Action move(Map<Player, Point2D> map, Balloon b) {

        round++;

        Point2D me = map.get(this);
        Point2D balloon = b.getLocation();

        double distanceX = balloon.getX() - me.getX();
        double distanceY = balloon.getY() - me.getY();
        double distance = Math.sqrt(Math.pow(distanceX, 2) + Math.pow(distanceY, 2));

        double maxX = speed * distanceX / distance;
        double maxY = speed * distanceY / distance;

        if (previousHeight < b.getHeight())
            hit = false;

        if (hit || b.getHeight() < 3) {
            previousHeight = b.getHeight();
            return new Movement(-maxX, -maxY);
        } else {
            if (distance < 4 && b.getHeight() < 10) {
                hit = true;
                return new Hit(0, 0, strength);
            } else {
                if (Math.pow(distance, 2) <= Math.pow(speed, 2)) {
                    return new Movement(distanceX, distanceY);
                } else {
                    return new Movement(maxX, maxY);
                }
            }
        }

    }

}

ऐसा लगता है कि आपका बॉट गैरकानूनी चाल चलता है और इस तरह से कुछ नहीं करता है।
Moogie

@soktinpk मैंने अपना सबमिशन तय कर लिया, अब इसे बेहतर करना चाहिए। धन्यवाद Moogie भी!
थ्रक्स

मुझे अभी भी पता चल रहा है कि आपका बॉट जो संभव है उससे परे आंदोलन के लिए कह रहा है। मैंने आपकी पोस्ट को समीक्षा के लिए संपादित कर दिया है। मूल रूप से आप गुब्बारे की स्थिति को आंदोलन के रूप में उपयोग कर रहे थे।
Moogie

@ उमोजी राइट, बहुत बहुत धन्यवाद!
थ्रक्स

मदद करने में खुशी। सकारात्मक अंक प्राप्त करने में आपका बॉट बहुत अच्छा है। बहुत बढ़िया!
Moogie

5

AngryPenguin

यह पेंगुइन गुस्से में है क्योंकि वह गुब्बारे तक नहीं उड़ सकता है, इसलिए वह गुब्बारे को अपने आसपास खड़े लोगों के चेहरे पर मारने की कोशिश करता है।

package players;

import java.awt.geom.Point2D;
import java.util.Map;
import java.util.Map.Entry;

import balloon.Action;
import balloon.Action.Hit;
import balloon.Action.Movement;
import balloon.Balloon;
import balloon.Player;

public class AngryPenguin extends Player {
    private static final double HIT_Z = 3;
    public AngryPenguin() {
        super(4, 4, 2);
    }

    @Override
    protected Action move(Map<Player, Point2D> map, Balloon balloon) {
        Point2D myself = map.get(this);

        double distanceX = balloon.getLocation().getX() - myself.getX();
        double distanceY = balloon.getLocation().getY() - myself.getY();
        double distance = Math.sqrt(Math.pow(distanceX, 2) + Math.pow(distanceY, 2));

        if (balloon.getHeight() < 2) {
            double[] xy = shrink(distanceX, distanceY, Math.pow(getSpeed(),2));
            return new Movement(-xy[0], -xy[1]);
        } else if (distance <= 4 && balloon.getHeight() <= 10) {
            double lowestDistance = Double.MAX_VALUE;
            Point2D nearestPlayerLoc = null;
            for (Entry<Player, Point2D> e : map.entrySet()) {
                if (e.getKey() != this) {
                    double d = e.getValue().distanceSq(myself);
                    if (d < lowestDistance) {
                        lowestDistance = d;
                        nearestPlayerLoc = e.getValue();
                    }
                }
            }
            double dX = nearestPlayerLoc.getX() - myself.getX();
            double dY = nearestPlayerLoc.getY() - myself.getY();
            double d = Math.pow(getStrength() - HIT_Z, 2);
            double[] xy = shrink(dX, dY, d);
            return new Hit(xy[0], xy[1], -HIT_Z);
        } else {
            double[] xy = shrink(distanceX, distanceY, Math.pow(Math.min(getSpeed(), distance), 2));
            return new Movement(xy[0], xy[1]);          
        }
    }

    private double[] shrink(double x, double y, double totalPow) {
        double[] xy = new double[2];
        double ratio = y == 0 ? 0 : 
                       x == 0 ? 1 : Math.abs(x) / Math.abs(y);
        if (ratio > 1)
            ratio = 1/ratio;
        xy[1] = totalPow * ratio;
        xy[0] = totalPow - xy[1];
        xy[0] = x < 0 ? -Math.sqrt(xy[0]) : Math.sqrt(xy[0]);
        xy[1] = y < 0 ? -Math.sqrt(xy[1]) : Math.sqrt(xy[1]);
        return xy;
    }

}

यह एक को हरा देना है।
केविन वर्कमैन

5

कमज़ोर दिल का आदमी

यह बॉट केवल गुब्बारे को छू सकता है क्योंकि यह इतना कमजोर है, इसके बजाय यह सिर्फ अपने उच्च भाग्य पर निर्भर करता है। इसलिए यह लकीलॉज़र (जिससे यह बॉट प्रेरित है) के समान प्रदर्शन करता है।

वह रिपेलर सहित सभी वर्तमान बॉट्स का प्रदर्शन करने के लिए लगता है।

package players;
import java.awt.geom.Point2D;
import java.util.Map;
import balloon.Action;
import balloon.Balloon;
import balloon.Player;
import balloon.Action.Hit;
import balloon.Action.Movement;

public class Weakling extends Player {

    static final private double STRENGTH = Double.MIN_VALUE;
    static final private double SPEED = 1.5;
    static final private double LUCK = 8.5;
    public Weakling() {
        super(SPEED,STRENGTH,LUCK);
    }

    protected Action move(Map<Player, Point2D> map, Balloon b) {
        Point2D start = map.get(this);
        Point2D balloon = b.getLocation();
        double distance = start.distance(balloon)+Double.MIN_VALUE;
        if(distance<=4 && b.getHeight()<=10){

            // just touch it :P
            return new Hit(0,0,0);
        }
        double x = start.getX()-balloon.getX();
        double y = start.getY()-balloon.getY();
        x /= distance;
        y /= distance;

        // move to directly underneath balloon
        x*=Math.min(SPEED, distance);
        y*=Math.min(SPEED, distance);
        return new Movement(-x, -y);
    }
}

EDIT: भाग्य के पक्ष में गति कम


3

Hydrophobe

यह सबसे सरल संभव बॉट में से एक है लेकिन जैसा कि यह प्रतिस्पर्धी है मैं इसे पोस्ट करूंगा।

रणनीति: अच्छी तरह से ... यह बॉट पानी से नफरत करता है इसलिए यह बस चला जाता है।

जैसा कि बॉट को बहुत कम ही विभाजित किया जाएगा, यह औसतन 0 अंक से थोड़ा कम होगा। सभी बॉट्स स्कोर का योग -1 * [बैलून हिटिंग ग्राउंड] है, इसलिए हाइड्रोफोब शायद औसत से ऊपर स्कोर करेगा।

package players;
import java.awt.geom.Point2D;
import java.util.Map;
import balloon.*;

public class Hydrophobe extends Player {
    public Hydrophobe() {super(8, 1, 1);}
    @Override
    protected Action move(Map<Player, Point2D> map, Balloon balloon) {
        return new Action.Movement(5.65,5.65);
    }
}

3

दूर रहो

यह खिलाड़ी गुब्बारा का पीछा करता है जब तक कि इसकी ऊंचाई> 2 है। जैसे ही यह गुब्बारे को मार सकता है, यह गुब्बारे को निकटतम खिलाड़ी से दूर मारता है । जब गुब्बारे की ऊंचाई <2 है, तो यह खिलाड़ी भाग जाता है।

package players;

import java.awt.geom.Point2D;
import java.util.Map;

import balloon.Action;
import balloon.Balloon;
import balloon.Player;
import balloon.Action.Hit;
import balloon.Action.Movement;

public class KeepAway extends Player{

    public KeepAway() {
        super(5, 3, 2);
    }

    @Override
    protected Action move(Map<Player, Point2D> map, Balloon b) {

        Point2D myself = map.get(this);

        //if balloon is high up, run towards it
        if(b.getHeight() > 2){
            Point2D closest = getClosestPlayer(map);

            boolean canHit = b.getHeight() <= 10 && myself.distance(b.getLocation()) <= 4;

            //hit it when you can
            if(canHit){

                Point2D normHit = normalize(new Point2D.Double(myself.getX() - closest.getX(), myself.getY() - closest.getY()));
                Point2D forceHit = new Point2D.Double(normHit.getX() * getStrength(), normHit.getY() * getStrength());

                return new Hit(forceHit.getX(), forceHit.getY(), 0);
            }
            //if you can't hit it, keep running towards it
            else {

                Point2D normRun = normalize(new Point2D.Double(myself.getX() - b.getLocation().getX(), myself.getY() - b.getLocation().getY()));
                Point2D forceRun = new Point2D.Double(-normRun.getX() * getSpeed(), -normRun.getY() * getSpeed());
                return new Movement(forceRun.getX(), forceRun.getY());
            }
        }
        //if the balloon is low, run away
        else{
            Point2D normRun = normalize(new Point2D.Double(myself.getX() - b.getLocation().getX(), myself.getY() - b.getLocation().getY()));
            Point2D forceRun = new Point2D.Double(normRun.getX() * getSpeed(), normRun.getY() * getSpeed());
            return new Movement(forceRun.getX(), forceRun.getY());
        }

    }

    private Point2D getClosestPlayer(Map<Player, Point2D> map){

        double minDistance = Double.MAX_VALUE;
        Point2D closestPoint = null;
        Point2D myPoint = map.get(this);

        for(Player p : map.keySet()){
            if(this != p){

                if(myPoint.distance(map.get(p)) < minDistance){
                    minDistance = myPoint.distance(map.get(p));
                    closestPoint = map.get(p);
                }
            }
        }

        return closestPoint;
    }

    private Point2D normalize(Point2D p){
        double d = p.distance(0, 0);

        if(d == 0){
            return new Point2D.Double(0, 0);
        }

        return new Point2D.Double(p.getX()/d, p.getY()/d);
    }

}

संपादित करें: मैं Player1 और Player2 के साथ खेल रहा था। यह खिलाड़ी उस मामले में जीतता है, लेकिन हारता है जब मैं उन्हें बाहर निकालता हूं। Booooo।


3

भाग्यशाली हारे

यह बॉट अपने हाई लक स्कोर पर निर्भर करता है। यदि यह गुब्बारे के पास नहीं है, तो यह गुब्बारे की ओर चलता है। एक बार गुब्बारे के पास, यदि गुब्बारे की रेंज में कम से कम 2 अन्य खिलाड़ी हैं, तो वह इसे जमीन पर ले जाएगा। अन्यथा, वह इसे सीधे खटखटाएगा।

package players;
import java.awt.geom.Point2D;
import java.util.Map;

import balloon.Action;
import balloon.Balloon;
import balloon.Player;
import balloon.Action.Hit;
import balloon.Action.Movement;

public class LuckyLoser extends Player {
    public LuckyLoser() {
        super(1,1,8);
    }

    protected Action move(Map<Player, Point2D> map, Balloon b) {
        Point2D start = map.get(this);
        Point2D bLocation = b.getLocation();
        double distance = start.distance(bLocation);
        if(distance<=4){
            boolean foundMe = false;
            int numPlayersInRange=0;
            for(Point2D point:map.values()){
                if( !foundMe && point.equals(start))
                {
                    foundMe=true;
                    continue;
                }
                if(point.distance(bLocation)<=4)
                    numPlayersInRange++;                
            }
            if(numPlayersInRange>1)
                return new Hit(0,0,-1);
            else
                return new Hit(0,0,1);
        }
        double x = start.getX()-bLocation.getX();
        double y = start.getY()-bLocation.getY();
        x /= distance;
        y /= distance;
        return new Movement(-x, -y);
    }
}

संपादित करें: फिक्स्ड मूवमेंट बग, जिसने वास्तव में मुझे गुब्बारे की तरफ नहीं भाग दिया> _ <अब मैं सीधे गुब्बारे की तरफ भागता हूं अगर मैं इसे हिट नहीं कर सकता।


3

repeller

इस बॉट रिले पर केवल एक वास्तविक चाल है और वह गुब्बारे को खुद से दूर धकेलती रहती है। यानी बैलून को रिप्रजेंट करता है।

यह लगभग हमेशा जीतने वाली बॉट्स की वर्तमान फसल (लकीलोसेर, एंग्री पेंग्विन, हाइड्रोफोब, बैकएंडफोर्थ) के खिलाफ अच्छा प्रदर्शन करता है। हालाँकि, निष्क्रियता से, हाइड्रोफोब हमेशा जीतने के लिए तैयार रहता है यदि अन्य बॉट्स सभी नकारात्मक स्कोर प्राप्त करने का प्रबंधन करते हैं: पी

package players;
import java.awt.geom.Point2D;
import java.util.Map;

import balloon.Action;
import balloon.Balloon;
import balloon.Player;
import balloon.Action.Hit;
import balloon.Action.Movement;

public class Repeller extends Player {

    static final private double STRENGTH = 3.5;
    static final private double SPEED = 2.5;
    static final private double LUCK = 4;
    public Repeller() {
        super(SPEED,STRENGTH,LUCK);
    }

    protected Action move(Map<Player, Point2D> map, Balloon b) {
        Point2D start = map.get(this);
        Point2D balloon = b.getLocation();
        double distance = start.distance(balloon)+Double.MIN_VALUE;
        if(distance<=4 && b.getHeight()<=10){
            double x = start.getX()-balloon.getX();
            double y = start.getY()-balloon.getY();
            x /= distance;
            y /= distance;
            x*=STRENGTH;
            y*=STRENGTH;

            // push the balloon away with all our strength
            return new Hit(-x,-y,0);
        }
        double x = start.getX()-balloon.getX();
        double y = start.getY()-balloon.getY();
        x /= distance;
        y /= distance;

        // if we are directly underneath then move away from balloon
        distance=distance<1?-1:distance;

        // if we are just off of directly underneath then stay put
        distance=distance<2?0:distance;

        // move to the desired location
        x*=Math.min(SPEED, distance);
        y*=Math.min(SPEED, distance);
        return new Movement(-x, -y);
    }
}
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.