Gra o przetrwaniu - AlienWar


96

AlienWar

Ta gra ma miejsce na bardzo zatłoczonej planecie, na której kosmici są wyższą rasą. Twoim zadaniem jest stworzenie własnego kosmity i pokonanie wszystkich innych.

Tablica

Jest to dwuwymiarowa tablica.
Długość jednego boku deski wynosi Math.ceil(sqrt(species * 100 * 2.5))= ~ 40% użytej deski. Plansza jest planetą, więc jeśli wyjdziesz z mapy na zachodzie, wrócisz na wschodzie. Jeśli wyjdziesz na północ, znajdziesz się na południu.

Umiejętności

Każdy gatunek na planecie ma zdolności. Tutaj są:

Nazwa         Korzyści 
życie HP = życie LVL * 5 (zmniejsza się przy każdym otrzymanym trafieniu, 0 = śmierć), podstawowe HP = 10
siła Twoje trafienia powodują losowe obrażenia int w zasięgu [1 do siły LVL]
defence Losowo wybierz int w zakresie [0 do (50 / defenceLVL + 1)], jeśli int == 0 to uniknij następnego ataku
wizja Daje ci wizję LVL / 2 pola wokół ciebie
spryt Rozmywa (zwiększa) każdą umiejętność losowo w zakresie [0 do sprytu LVL / 2] podczas wysyłania do innych kosmitów

Gra

  • Będzie 100 wystąpień każdego zgłoszenia.
  • Po instancji każdy obcy może ustawić łącznie 10 punktów umiejętności. Możesz ustawić różne punkty dla każdej instancji.
  • Jeśli ustawisz więcej niż 10 punktów, instancja umiera.
  • Gra składa się z 1000 rund. Każda runda:
    • Każdy kosmita musi zwrócić ruch move(char[] fields). Obejmuje Move.STAY.
    • Jeśli na polu znajduje się kilku kosmitów, 2 zostaną losowo wybrane:
      • Jeśli obaj zgodzą się na pokój (powrócą fałszywie wantToFight), pozostaną tam, gdzie są, w przeciwnym razie będą walczyć.
      • Zapętla się, dopóki tylko jeden kosmita pozostanie na polu lub wszyscy zgodzą się na pokój.
  • Jeśli kosmita coś zabije, otrzymuje 1/5 umiejętności każdego z wrogów . Zwycięskie HP zostanie uzupełnione 2 * wrogaLifeLVL .

  • Zwycięzcą jest ten, który ma najwięcej umiejętności (suma umiejętności żywych kosmitów).

Walki

Obaj kosmici uderzą się nawzajem „w tym samym czasie”, co oznacza, że ​​jeśli zabijesz drugiego kosmitę, nadal może cię uderzyć raz.

Unik: zanim zostaniesz trafiony, gra obliczy, czy możesz uniknąć ataku za pomocą rand.nextInt(50 / defenseLvl + 1) == 0. defenceLvl nigdy nie będzie większa niż 50 podczas obliczania umiejętności unikania (stąd maksymalna szansa na unik wynosi 50%).

Trafienie: jeśli nie unikniesz ataku, zostaniesz trafiony, a twoje HP zostanie zmniejszone o rand.nextInt(enemy.getStrengthLvl()) + 1.

Walka kończy się, gdy jeden lub obaj zaangażowani kosmici nie żyją. Zwycięzca, jeśli taki istnieje, otrzymuje nagrodę.

Zasady gry

  • Poziom podstawowy dla każdej umiejętności (bez przyznawania punktów umiejętności) wynosi 1 (podstawowe HP to 10).
  • Wartości wysyłane na prośbę o walkę to życie (nie HP!), Siła, obrona i wizja .
  • Spryt NIE jest wysyłany na prośbę o walkę.
  • Wszystkie liczby zmiennoprzecinkowe zostaną zaokrąglone do najbliższej liczby całkowitej podczas ich używania / wysyłania, ale będą przechowywane i zwiększane jako zmiennoprzecinkowe.
  • Maksymalna szansa na unik to 50%. W przeciwnym razie walki nigdy się nie kończą.

Zdobycz

Na polu jest już 5 gatunków. Ponieważ są ofiarami, decydują się nie walczyć, gdy o to poproszą.

Wieloryb: 10 poziomów życia   
Krowa: siła 10 poziomu Losowy ruch
Turtle: lvl 10 defense South west
Orzeł: wizja 10 poziomu Bada pola, stara się unikać niebezpieczeństwa      
Człowiek: 10 poziom sprytu na północnym wschodzie

Będą reprezentowani z pierwszą literą (tj. WDla wieloryba) na mapie (Obcy z A, puste pola z białymi spacjami ' ').

Dodatkowe zasady

  • Odbicie jest niedozwolone.
  • Interakcje (instancje itp.) Z innymi kosmitami są zabronione.
  • Niedozwolone jest również pisanie / czytanie zewnętrznych zasobów, takich jak pliki lub bazy danych.
  • Dozwolone są tylko zgłoszenia Java (wersja 1.8) (Java jest raczej łatwa i nie musisz być ekspertem w tej grze).
  • Wszystkie zgłoszenia muszą rozszerzyć klasę kosmitów i zostaną umieszczone w pakiecie kosmitów.
  • Przyjmę najlepszego kosmitę 19 lipca. Wszyscy kosmici zgłoszeni do godziny 12:00 UTC tego dnia zostaną przetestowani.
  • Maksymalnie 3 zgłoszenia na użytkownika, ponieważ jest już bardzo wielu obcych.

Przykład obcego

package alien;

import planet.Move;

public class YourUniqueNameHere extends Alien {

    public void setAbilityPoints(float[] abilities) {
        abilities[0] = 2; //life
        abilities[1] = 2; //strength
        abilities[2] = 2; //defense
        abilities[3] = 2; //vision
        abilities[4] = 2; //cleverness
    }

    public Move move(char[][] fields) {
        //you are in the middle of the fields, say fields[getVisionFieldsCount()][getVisionFieldsCount()]
        return Move.STAY;
    }

    public boolean wantToFight(int[] enemyAbilities) {
        //same order of array as in setAbilityPoints, but without cleverness
        return true;
    }

}

Program sterujący

Kod źródłowy programu sterującego można znaleźć tutaj . Teraz zaktualizowane o wszystkich kosmitów uwzględnionych w najnowszym biegu.

Ostateczne wyniki (20.07.2014, średnio 10 gier)

alien.PredicatClaw 1635.4
alien.LazyBee 1618.8
alien.CartographerLongVisionAlien 1584.6
alien.ChooseYourBattles 1571.2
alien.Bender 1524.5
alien.HerjanAlien 1507,5
alien.FunkyBob 1473.1
alien.SecretWeapon2 1467,6
alien.PredicatEyes 1457.1
alien.CorporateAlien 1435.9
alien.GentleGiant 1422.4
alien.CropCircleAlien 1321.2
alien.VanPelt 1312.7
alien.NewGuy 1270.4
alien.BananaPeel 1162.6
alien.Rock 1159.2
alien.BullyAlien 1106.3
alien.Geoffrey 778,3
alien.SecretWeapon 754,9
alien.SecretWeapon3 752,9
alien.FunkyJack 550.3
Alien.Stone 369,4
alien. Assassin 277,8
alien.Predicoward 170.1
ofiara Krowa 155,2
Alien.Morphling 105,3
alien.Eli 99,6
alien.Warrior 69.7
Alien.Hunter 56.3
alien.Manager 37,6
alien.OkinawaLife 14.2
ofiara.Whale 10.5
alien.Gamer 4.5
alien.Randomite 0
alien.Guard 0
zdobycz Orzeł 0
alien.Rogue 0
alien.WeakestLink 0
alien.Fleer 0   
alien.Survivor 0
alien.Sped 0
alien.Junkie 0
alien.Coward 0
alien.CleverAlien 0
zdobycz Człowieka 0
alien.BlindBully 0
łup zdobycz 0
alien.AimlessWanderer 0

14
Trzy przegłosowania, co u licha? I nie widzę ani jednego negatywnego komentarza. Czy osoby pasywnie agresywnie denerwują się, że ogranicza się to do Javy?
Martin Ender

6
@ m.buettner Moje zdanie jest za ograniczeniem do godawfulness, jaką jest Java (choć jeśli byłby ograniczony do najmilszego języka, jaki kiedykolwiek stworzono, nadal głosowałbym za ograniczeniem go do 1 języka). Nie widziałem sensu w dodawaniu komentarza, ponieważ było oczywiste, po co będą opinie negatywne.
Gareth,

6
Hmmm, mam mieszane uczucia
Pan Alien

5
@ user3334871 Nie sądzę, aby zmiana jakiejkolwiek reguły po 17 odpowiedziach (i potencjalnie tuzin osób pracujących nad przesyłaniem) to dobry pomysł. Ponieważ tylko nieliczni z nas (jeśli w ogóle) są profesjonalnymi projektantami gier, prawie każdy samozwańczy KotH może mieć pewne problemy z balansem - ale jeśli eksploracja przestrzeni możliwych strategii jest nadal fajna (co najwyraźniej jest, sądząc po odpowiedziach, opinie i gwiazdy), nie sądzę, że to duży problem.
Martin Ender

5
@Manu Dla matematycznie nachylonego opis sposobu, w jaki deska się owija, jest nieco mylący. Mówisz, że to planeta, która otacza wschód / zachód. Nic tak naprawdę nie wskazuje na to, że obejmuje także północ / południe. W rzeczywistości, jeśli tak, to technicznie nie jest to już kula, ale torus: kotaku.com/classic-jrpg-worlds-are-actally-donuts-1239882216 . Możesz także to zauważyć, zauważając, że kiedy „schodzisz” z góry mapy świata (biegun północny), nie pojawiasz się na dole (biegun południowy). Dlatego myślę, że sugestia Michaela jest zdecydowanie ważna.
Martin Ender

Odpowiedzi:


11

PredicatClaw (rawr)

Ta koci obcy połknie cię w całości (dobra, może najpierw cię trochę przeżuje) ... jeśli wydajesz się słaby w oparciu o jej algorytmy przewidywania.

Rasa predykatów, które mają ostrzejsze pazury i kły niż ich odpowiedniki.

EDYCJA: Nowe priorytety docelowe

package alien;

import planet.Move;

/* Predict + Cat = Predicat! */
public class PredicatClaw extends Alien {
    private static final int LIF=0, STR=1, DEF=2;
    private static final int WHALE=6, COW=1, TURTLE=4, EAGLE=3, HUMAN=2, ALIEN=-1, NONE=0;

    @Override
    public void setAbilityPoints( float[] abilities ) {
        abilities[LIF] = 4.5f;
        abilities[STR] = 5.5f;
    }

    @Override
    public Move move( char[][] fields ) {

        /* Some credits to Eagle for letting me learn how to do the moves */
        int vision = getVisionFieldsCount(); //count of fields / middle
        int fieldX;
        int fieldY;
        Move bestMove=Move.STAY;
        int bestScore=-1;

       for (Move move : Move.values()) {
            fieldX = vision + move.getXOffset();
            fieldY = vision + move.getYOffset();
            switch(fields[fieldX][fieldY]){
            case 'W' : 
                if(bestScore<WHALE){
                    bestMove=move;
                    bestScore=WHALE;
                }
                break;
            case 'C' :
                if(bestScore<COW){
                    bestMove=move;
                    bestScore=COW;
                }
                break;
            case 'T' :
                if(bestScore<TURTLE){
                    bestMove=move;
                    bestScore=TURTLE;
                }
                break;
            case 'E' :
                if(bestScore<EAGLE){
                    bestMove=move;
                    bestScore=EAGLE;
                }
                break;
            case 'H' :
                if(bestScore<HUMAN){
                    bestMove=move;
                    bestScore=HUMAN;
                }
                break;
            case 'A' :
                if(bestScore<ALIEN){
                    bestMove=move;
                    bestScore=ALIEN;
                }
                break;
            case ' ' :
                if(bestScore<NONE){
                    bestMove=move;
                    bestScore=NONE;
                }
                break;
            }
        }

        if(vision==1 && bestScore>1){
            return bestMove;
        }

        //check immediate outer field
        for (int i=vision-2; i<=vision+2; i++) {
            for(int j=vision-2; j<=vision+2; j++){
                if(i==0 || i==4 || j==0 || j==4){
                    switch(fields[i][j]){
                    case 'W' :
                        bestMove = this.getBestMoveTo(i,j);
                        bestScore = WHALE;
                        break;
                    case 'C' :
                        if(bestScore<COW){
                            bestMove = this.getBestMoveTo(i,j);
                            bestScore = COW;
                        }
                        break;
                    case 'T' :
                        if(i>=vision && j<=vision){
                            return this.getBestMoveTo(i-1,j+1);
                        }
                        if(bestScore<TURTLE){
                            bestMove = this.getBestMoveTo(i,j);
                            bestScore = TURTLE;
                        }
                        break;
                    case 'E' :
                        if(bestScore<EAGLE){
                            bestMove = this.getBestMoveTo(i,j);
                            bestScore = EAGLE;
                        }
                        break;
                    case 'H' :
                        if(i<=vision && j>=vision){
                            return this.getBestMoveTo(i+1,j-1);
                        }
                        if(bestScore<HUMAN){
                            bestMove = this.getBestMoveTo(i,j);
                            bestScore = HUMAN;
                        }
                        break;
                    case 'A' :
                        if(bestScore<ALIEN){
                            bestMove = this.getBestMoveTo(i,j);
                            bestScore = ALIEN;
                        }
                        break;
                    case ' ' :
                        if(bestScore<NONE){
                            bestMove = this.getBestMoveTo(i,j);
                            bestScore = NONE;
                        }
                        break;
                    }
                }
            }
        }

        return bestMove;
    }

    @Override
    public boolean wantToFight( int[] enemyAbilities ) {
        /*
            Fight IF
                1) I CAN BEAT YOU
                2) ????
                3) MEOW!
        */
        float e_hp = enemyAbilities[LIF]*5+10;
        float e_dmg = 1 + enemyAbilities[STR]/2;
        float e_hit = 1 - (1/(50/this.getDefenseLvl()+1));

        float m_hp = this.getCurrentHp();
        float m_dmg = 1 + this.getStrengthLvl()/2;
        float m_hit = 1 - (1/(50/enemyAbilities[DEF]+1));

        return (e_hp/(m_dmg*m_hit) < m_hp/(e_dmg*e_hit));
    }

    private Move getBestMoveTo(int visionX, int visionY){
        int vision = getVisionFieldsCount();

        if(visionX < vision && visionY < vision){
            return Move.NORTHWEST;
        }
        else if(visionX > vision && visionY < vision){
            return Move.NORTHEAST;
        }
        else if(visionX < vision && visionY > vision){
            return Move.SOUTHWEST;
        }
        else if(visionX > vision && visionY < vision){
            return Move.SOUTHEAST;
        }
        else if(visionX == vision && visionY < vision){
            return Move.NORTH;
        }
        else if(visionX == vision && visionY > vision){
            return Move.SOUTH;
        }
        else if(visionX > vision && visionY == vision){
            return Move.EAST;
        }
        else if(visionX < vision && visionY == vision){
            return Move.WEST;
        }
        else{
            return Move.WEST;
        }

    }
}

1
Cholera! Te predykaty są ostre! Zauważam, że oboje zdecydowaliśmy się na mniej więcej ten sam wantToFightalgorytm.
James_pic

@James_pic, widzę, że wielkie umysły myślą podobnie. : D
Mark Gabriel

27

Menedżer

Oto menedżer. Oczywiście spryt wynosi 0 i zawsze stara się iść tam, gdzie słońce nie świeci. I, oczywiście, będzie walczył tylko ze słabymi i jest bardzo dobry w unikaniu kłopotów:

public class Manager extends Alien {

    private static final int STRENGTH = 5;

    @Override
    public void setAbilityPoints( float[] abilities ) {
        abilities[/* strength   */ 1] = STRENGTH;
        abilities[/* defense    */ 2] = 5;
        abilities[/* cleverness */ 4] = 0; // just to make sure
    }

    @Override
    public Move move( char[][] fields ) {
        return Move.WEST;
    }

    @Override
    public boolean wantToFight( int[] enemyAbilities ) {
        return enemyAbilities[1] < STRENGTH;
    }
}

+1, jeśli tylko za wprowadzenie. : P
apnorton

6
Za każdym razem, gdy czytam ten komentarz („tylko dla pewności”), muszę się śmiać :-D
Matthias


@ 11684 każdy porządny programista oczywiście to wie, ale w moim przypadku mam na myśli menedżera;)
Ingo Bürk

18

CartographyLongVisionAlien

Ten kosmita jest konsekwentnym wykonawczym wariantem jednej z moich prób stworzenia kosmita o potencjale wygranym.

Ma początkową wizję 5x5, którą wykorzystuje do zbudowania wewnętrznej mapy otaczającego obszaru, co daje mu doskonałą zdolność unikania wrogów.

W moim teście średnio 100 rund wymyka się przed wszystkimi innymi kosmitami. (09/07/2014)

ZAKTUALIZOWANY GIF przedstawiający efekt pola odpychania / przyciągania

Zmodyfikowałem kod gry, aby tworzyć animowane pliki GIF z symulacji. Możesz zobaczyć taką symulację tutaj

 package alien;

 import java.util.ArrayList;
 import java.util.HashMap;
 import java.util.List;
 import java.util.Random;
 import planet.Move;
 import planet.Planet;

 /**
  * Created by moogie on 09/07/14.
  * 
  * This Alien attempts to map the visible and guess the movements within the immediate non-visible area around the alien.
  * To this end, the alien can initially see 5x5 grid. It applies weights on the cells of its internal map based on the 
  * prey/alien/blanks within its field of view. It then performs a simple blur to guess movements and then chooses the optimum move
  * based on the contents of its internal map.
  * 
  * If it is asked to fight, it performs battle simulations to determine whether it should nominate to fight.
  */
 public class CartographerLongVisionAlien extends Alien
 {
   private final static byte LIFE = 0, STR = 1, DEF = 2, VIS = 3, CLV = 4;

   // Plant Entity symbols
   private static final char TURTLE = 'T';
   private static final char HUMAN = 'H';
   private static final char WHALE = 'W';
   private static final char COW = 'C';
   private static final char EAGLE = 'E';
   private static final char ALIEN = 'A';
   private static final HashMap<Character, Move> preyMovement = new HashMap<>();

   static 
   {
     preyMovement.put(WHALE, Move.STAY);
     preyMovement.put(TURTLE, Move.SOUTHWEST);
     preyMovement.put(HUMAN, Move.NORTHEAST);
   };

   // Map constants
   public static final int MAP_SIZE_DIV_2 = 10;
   public static final int MAP_SIZE = MAP_SIZE_DIV_2 * 2 + 1;
   private static final int MAP_SIZE_MINUS_ONE = MAP_SIZE - 1;
   private static final double FADE_FACTOR=0.85;

   // Planet constants
   private static final int STARTING_HP = 10;
   private static final int START_HEALING_FACTOR = 5;
   private static final int MAX_DEFENCE = 50;

   // Battle Simulation constants
   private static final double AMBIGUOUS_ENEMY_HP_FACTOR = 2;
   private static final int SIMULATED_BATTLE_COUNT = 100;
   private static final int SIMULATED_BATTLE_THREASHOLD = (int)(SIMULATED_BATTLE_COUNT*1.0);

   private Random rand = new Random(Planet.rand.nextLong());

   /** The alien's map of the immediate and mid-range area */
   public double[][] map = new double[MAP_SIZE][MAP_SIZE];

   public void setAbilityPoints( float[] abilities )
   {
     // +0.5 gain due to rounding trick "borrowed" from PredicatClaw http://codegolf.stackexchange.com/a/32925/20193
     abilities[LIFE] = 3.5f; // We do need some hit points to ensure that we can survive the melee of the beginning game.
     abilities[STR] = 4.5f; // A Moderate attack strength means that we do not have to go through as many fight rounds.
     abilities[DEF] = 0; // We will get from prey and other aliens
     abilities[VIS] = 2; // A minimum of 2 is required to get a 5x5 field of view
     abilities[CLV] = 0; // We will get from prey and other aliens
   }

   /**
    * simulate alien memory fade. This allows an alien to eventually venture back to areas already traversed.
    */
   private void fadeMap()
   {
     for ( int y = 0; y < MAP_SIZE; y++ )
     {
       for ( int x = 0; x < MAP_SIZE; x++ )
       {
         map[x][y] *= FADE_FACTOR;
       }
     }
   }

   /**
    * shift the maps with the movement of the alien so that the alien is always at the centre of the map
    * 
    * @param move
    */
   private void shiftMaps( Move move )
   {
     int i, j;
     final int offsetX = -move.getXOffset();
     final int offsetY = -move.getYOffset();
     double[][] tempMap = new double[MAP_SIZE][MAP_SIZE];
     for ( int y = 0; y < MAP_SIZE; y++ )
     {
       for ( int x = 0; x < MAP_SIZE; x++ )
       {
         i = x + offsetX;
         j = y + offsetY;

         if ( i >= 0 && i <= MAP_SIZE_MINUS_ONE && j >= 0 && j <= MAP_SIZE_MINUS_ONE )
         {
           tempMap[i][j] = map[x][y];
         }
       }
     }
     map = tempMap;
   }

   /**
    * Updates a cell in the alien's map with the desirability of the entity in the cell
    * 
    * @param x
    * @param y
    * @param chr
    */
   private void updateMap( int x, int y, char chr )
   {
     // Note that these desire values are just guesses... I have not performed any analysis to determine the optimum values!
     // That said, they seem to perform adequately.
     double desire = 0;

     int i=x;
     int j=y;
     switch ( chr )
     {
       case WHALE:
         desire=2;
         break;
       case TURTLE:
       case HUMAN:
         desire=1;
         Move preyMove = preyMovement.get( chr );

         // predict movement into the future
         while ( i >= 0 && i <= MAP_SIZE_MINUS_ONE && j >= 0 && j <= MAP_SIZE_MINUS_ONE )
         {
           map[i][j] = ( map[i][j] + desire ) / 2;
           i+=preyMove.getXOffset();
           j+=preyMove.getYOffset();
           desire/=2;
         }
         break;
       case COW:
         desire = 0.5;
         break;
       case EAGLE:
         desire = 1;
         break;
       case ALIEN:
         desire = -10;
         break;
     }

     map[x][y] = ( map[x][y] + desire ) / 2;
   }

   /**
    * Apply a blur the map to simulate the movement of previously seen entities that are no longer within the field of view.
    */
   private void convolve()
   {
     double[][] tempMap = new double[MAP_SIZE][MAP_SIZE];

     int count;
     double temp;
     for ( int y = 0; y < MAP_SIZE; y++ )
     {
       for ( int x = 0; x < MAP_SIZE; x++ )
       {
         count = 0;
         temp = 0;
         for ( int i = x - 1; i < x + 2; i++ )
         {
           for ( int j = y - 1; j < y + 2; j++ )
           {
             if ( i >= 0 && i <= MAP_SIZE_MINUS_ONE && j >= 0 && j <= MAP_SIZE_MINUS_ONE )
             {
               temp += map[i][j];
               count++;
             }
           }
         }
         temp += map[x][y] * 2;
         count += 2;

         tempMap[x][y] = temp / count;
       }
     }
     map = tempMap;
   }

   /**
    * Determine the move that minimises the risk to this alien and maximises any potential reward.
    * 
    * @param fields
    * @return
    */
   private Move findBestMove( char[][] fields )
   {
     List<Move> moveOptions = new ArrayList<>();
     double bestMoveScore = -Double.MAX_VALUE;
     double score;

     // find the moves that have the best score using the alien's map
     for ( Move move : Move.values() )
     {
       int x = MAP_SIZE_DIV_2 + move.getXOffset();
       int y = MAP_SIZE_DIV_2 + move.getYOffset();
       score = map[x][y];
       if ( score == bestMoveScore )
       {
         moveOptions.add( move );
       }
       else if ( score > bestMoveScore )
       {
         bestMoveScore = score;
         moveOptions.clear();
         moveOptions.add( move );
       }
     }

     Move move = moveOptions.get( rand.nextInt( moveOptions.size() ) );

     // if the best move is to stay...
     if ( move == Move.STAY )
     {
       // find whether there are no surrounding entities in field of vision...
       int midVision = getVisionFieldsCount();
       boolean stuck = true;
       out: for ( int i = 0; i < fields.length; i++ )
       {
         for ( int j = 0; j < fields.length; j++ )
         {
           if ( !( i == midVision && j == midVision ) && fields[i][j] != ' ' )
           {
             stuck = false;
             break out;
           }
         }
       }

       // there there are no other entities within field of vision and we are healthy... choose a random move
       if ( stuck && getCurrentHp() > getLifeLvl() * 2 )
       {
         move = Move.getRandom();
       }
     }
     return move;
   }

   /**
    * Update the alien's map with the current field of vision
    * 
    * @param fields
    */
   private void mapVisibleSurroundings( char[][] fields )
   {
     int midVision = getVisionFieldsCount();

     // update the map with currently visible information
     for ( int y = -midVision; y <= midVision; y++ )
     {
       for ( int x = -midVision; x <= midVision; x++ )
       {
         char chr = fields[midVision + x][midVision + y];
         updateMap( MAP_SIZE_DIV_2 + x, MAP_SIZE_DIV_2 + y, chr );
       }
     }

     // ensure that the map where this alien currently sits is marked as empty.
     updateMap( MAP_SIZE_DIV_2, MAP_SIZE_DIV_2, ' ' );
   }

   public Move move( char[][] fields )
   {
     Move returnMove = null;

     // pre-move decision processing
     mapVisibleSurroundings( fields );
     convolve();

     returnMove = findBestMove( fields );

     // post-move decision processing
     fadeMap();
     shiftMaps( returnMove );

     return returnMove;
   }

   public boolean wantToFight( final int[] enemyAbilities )
   {
     double toughnessFactor =((double) enemyAbilities[STR])/(enemyAbilities[LIFE]*10); // a fudge-factor to ensure that whales are attacked.
     if (enemyAbilities[VIS]>=3 && enemyAbilities[LIFE]>4.5f) toughnessFactor*=3.5; // make sure that we do not attack other Cartogapher aliens 
     return winsBattleSimulation( enemyAbilities, toughnessFactor );
   }

   /**
    * Perform simulations to determine whether we will win against the enemy most of the time.
    * 
    * @param enemyAbilities
    * @return
    */
   private boolean winsBattleSimulation( int[] enemyAbilities, double toughnessFactor )
   {
     int surviveCount = 0;
     for ( int i = 0; i < SIMULATED_BATTLE_COUNT; i++ )
     {
       int estimatedEnemyHitPoints =
           STARTING_HP + (int)( enemyAbilities[LIFE] * START_HEALING_FACTOR * AMBIGUOUS_ENEMY_HP_FACTOR * toughnessFactor );
       int enemyPoints = estimatedEnemyHitPoints;
       int myHitPoints = getCurrentHp();
       int myDefenceLevel = getDefenseLvl() < MAX_DEFENCE ? getDefenseLvl() : MAX_DEFENCE;
       int enemyDefenceLevel = enemyAbilities[DEF] < MAX_DEFENCE ? enemyAbilities[DEF] : MAX_DEFENCE;

       while ( !( myHitPoints <= 0 || enemyPoints <= 0 ) )
       {
         if ( rand.nextInt( MAX_DEFENCE / myDefenceLevel + 1 ) != 0 )
         {
           myHitPoints -= rand.nextInt( enemyAbilities[STR] ) + 1;
         }

         if ( rand.nextInt( MAX_DEFENCE / enemyDefenceLevel + 1 ) != 0 )
         {
           enemyPoints -= rand.nextInt( getStrengthLvl() ) + 1;
         }
       }
       if ( myHitPoints > 0 )
       {
         surviveCount++;
       }
     }
     return ( surviveCount >= SIMULATED_BATTLE_THREASHOLD );
   }

 }

Zaktualizowano, aby dodać prognozy zdobyczy w przyszłości i zapewnić, że wieloryby prawdopodobnie zostaną zaatakowane
Moogie

4
Tak! W końcu wygrywa kosmita, który liczy nie tylko na siłę i życie, ale także na wizję :)
CommonGuy

3
Bardzo trudno było znaleźć kosmitę, który byłby konsekwentnym wykonawcą! Inni najlepsi uczestnicy przeważnie podążają za tymi samymi pomysłami: unikaj kosmitów, atakuj zdobycz i inicjuj walki, które na pewno wygrasz. Ten kosmita kieruje się tymi samymi pomysłami, ale z lepszym unikaniem kosmitów. Daje to najmniejszą przewagę, ponieważ zdobycie większej liczby umiejętności w przypadku przegranej jest droższe.
Moogie,

Próbowałem innych, bardziej egzotycznych pomysłów, ale po prostu nie ma wystarczającej ilości informacji. tzn. rozmiar mapy, liczba kosmitów itp.
Moogie

Dobra robota! Ja również byłem trochę sfrustrowany brakiem informacji - wydobywanie dodatkowych informacji z przeszłości jest twórcze.
Benny

15

Wybierz swoje walki

Ten kosmita ucieka przed innymi kosmitami, ale biegnie w kierunku zdobyczy (o ile nie zabierze go to w stronę kosmitów).

Użyłem algorytmu genetycznego, aby pomóc mi wybrać wartości początkowe. Wyniki sugerują, że powinniśmy polegać na sile i życiu, aby przetrwać wczesne bitwy. Wizja jest przydatna później, ale możemy ją odebrać od pokonanych wrogów.

Walczymy tylko w bitwach, które naszym zdaniem możemy wygodnie wygrać - szacujemy, ile ruchów zajmie zabicie naszego kosmita, ile zajmie zabicie naszego wroga i przyłączymy się do bitwy, jeśli będziemy „dwa razy trudniejsi” niż nasz przeciwnik.

package alien;

import planet.Move;

import java.util.Collections;
import java.util.HashSet;
import java.util.Set;

import static java.lang.Math.*;

public class ChooseYourBattles extends Alien {
    private static final boolean DEBUG = false;
    private static final int LIFE = 0;
    private static final int STRENGTH = 1;
    private static final int DEFENCE = 2;
    private static final int VISION = 3;
    private static final int CLEVERNESS = 4;
    private static final Set<Character> prey = new HashSet<>();
    {
        Collections.addAll(prey, 'H', 'T', 'W', 'C', 'E');
    }

    public void setAbilityPoints(float[] abilities) {
        // Rounding promotes these to 4 and 7 - 11 points!
        abilities[LIFE] = 3.5f;
        abilities[STRENGTH] = 6.5f;
    }

    @Override
    public Move move(char[][] fields) {
        if (DEBUG) {
            StringBuilder sb = new StringBuilder();
            for (int j = 0; j < 2 * getVisionFieldsCount() + 1; j++) {
                for (int i = 0; i < 2 * getVisionFieldsCount() + 1; i++) {
                    char chr = fields[i][j];
                    if (chr == ' ') chr = '.';
                    if (i == getVisionFieldsCount() && j == getVisionFieldsCount()) chr = 'X';
                    sb.append(chr);
                }
                sb.append('\n');
            }
            String view = sb.toString();
            System.out.println(this.toString());
            System.out.println(view);
        }

        Move bestMove = null;
        int bestEnemyDistance = Integer.MIN_VALUE;
        int bestPreyDistance = Integer.MAX_VALUE;

        for (Move tryMove: Move.values()) {
            int currentDistanceToEnemy = Integer.MAX_VALUE;
            int currentDistanceToPrey = Integer.MAX_VALUE;
            int x = getVisionFieldsCount() + tryMove.getXOffset();
            int y = getVisionFieldsCount() + tryMove.getYOffset();
            for (int i = 0; i < 2 * getVisionFieldsCount() + 1; i++) {
                for (int j = 0; j < 2 * getVisionFieldsCount() + 1; j++) {
                    char chr = fields[i][j];
                    if (chr == 'A' && (i != getVisionFieldsCount() || j != getVisionFieldsCount())) {
                        // Use L-infinity distance, but fll back to L-1 distance
                        int distance = max(abs(i - x), abs(j - y)) * 100 + abs(i -x) + abs(j - y);
                        if (distance < currentDistanceToEnemy) currentDistanceToEnemy = distance;
                    } else if (prey.contains(chr)) {
                        int distance = max(abs(i - x), abs(j - y)) * 100 + abs(i -x) + abs(j - y);
                        if (distance < currentDistanceToPrey) currentDistanceToPrey = distance;
                    }
                }
            }
            if (currentDistanceToEnemy > bestEnemyDistance
                    || (currentDistanceToEnemy == bestEnemyDistance && currentDistanceToPrey < bestPreyDistance)) { // Prefer to stay put
                bestMove = tryMove;
                bestEnemyDistance = currentDistanceToEnemy;
                bestPreyDistance = currentDistanceToPrey;
            }
        }

        if (DEBUG) {
            System.out.println("Going " + bestMove);
            System.out.println();
        }
        return bestMove;
    }

    @Override
    public boolean wantToFight(int[] enemyAbilities) {
        // Estimate whether likely to survive the encounter - are we at least "twice as hard" as our opponent
        return getCurrentHp() * (50.0 + getDefenseLvl()) / (enemyAbilities[STRENGTH])
                > 2.0 * (enemyAbilities[LIFE] * 5 + 10) * (50.0 + enemyAbilities[DEFENCE])/ (getStrengthLvl());
    }

    @Override
    public String toString() {
        return "ChooseYourBattles" + System.identityHashCode(this)
                + ": HP " + getCurrentHp()
                + ", LFE " + getLifeLvl()
                + ", STR " + getStrengthLvl()
                + ", DEF " + getDefenseLvl()
                + ", VIS " + getVisionLvl()
                + ", CLV " + getClevernessLvl();
    }
}

Jeśli chcesz uruchomić własny algorytm genetyczny / program hodowlany, mam do tego celu rozwidloną kopię programu kontrolnego .


W jaki sposób omija to sprawdzenie checkAbilitesOkmetody?
FreeAsInBeer

checkAbilitiesOksprawdza, czy liczby zmiennoprzecinkowe w tablicy sumują się do 10,0. Jednak wartości zmiennoprzecinkowe są zaokrąglane do ints w logice gry, a Java zaokrągla 0,5 w górę.
James_pic

@ po prostu nadal ustawia 10 punktów, są one po prostu inteligentnie rozmieszczone.
CommonGuy

1
Powinienem powiedzieć, że pierwotnie nie był to mój pomysł - pożyczyłem go od PredicatClaw
James_pic

1
Bardzo dobrze. Twoje stałe statystyk są prawdopodobnie lepsze niż moje, a Twój wantToFight jest zdecydowanie mądrzejszy, byłem po prostu leniwy. :)
Benny

12

Ćpun

Ten kosmita jest uzależniony od czegoś . Rozpoczyna wojnę z dość paskudnym rozwiązaniem.

Podczas gdy jego poprawka jest silna ( fix > 3), przyjemnie jest usiąść w swoim otępieniu i jest gotowy na wszystko.

Jednak gdy jego poprawka zacznie się zużywać ( fix <= 3), zaczyna potykać się w nieznanym kierunku, próbując dowiedzieć się, co się stało. Poproszony o walkę staje się ostrożny i walczy tylko wtedy, gdy myśli, że może wygrać.

Gdy skończy się jego naprawa, będąc uzależnionym, musi ponownie uruchomić błędne koło.

public class Junkie extends Alien {
    private int fix = 10;

    public void setAbilityPoints(float[] abilities) {
        abilities[0] = 4; //life
        abilities[1] = 3; //strength
        abilities[2] = 3; //defense
    }

    public Move move(char[][] fields) {
        fix -= 1;
        if (fix == 0) {
            fix = 10;
        }
        else if(fix <= 3 && fix > 0) {
            return Move.getRandom();
        }

        return Move.STAY;
    }

    public boolean wantToFight(int[] enemyAbilities) {
        if(fix > 3) {
            return true;
        }
        // Am I stronger than their defense and can I withstand their attack?
        else if(enemyAbilities[2] < getStrength() && enemyAbilities[1] < getDefense()) {
            return true;
        }

        return false;
    }
}

Jestem prawie pewien, że można go bezpiecznie usunąć z && fix > 0powodu redundancji.
Timtech

10

Skórka banana

Próbuje tylko potknąć się o ludzi, którzy potrzebują małego bicia. Pokonanie go nie uczyni cię zdrowszym.

package alien;

import planet.Move;
public class BananaPeel extends Alien{
    public void setAbilityPoints(float[] abilities){
        abilities[0] = 0.5f;  // banana peels barely hold themselves together
        abilities[1] = 9.5f;  // banana peels can't help tripping people up
        abilities[2] = 0;  // banana peels can't defend themselves
        abilities[3] = 0;  // banana peels can't see
        abilities[4] = 0;  // banana peels can't think
    }

    public Move move(char[][] fields){
        return Move.STAY; // banana peels can't move
    }

    public boolean wantToFight(int[] enemyAbilities){
        return enemyAbilities[0] == 0 || enemyAbilities[1] == 0;
    }
}

Ważne jest również, aby zauważyć, że [0] to życie, a nie zdrowie, więc 100 to 510 HP (lub mniej, w zależności od już zadanych obrażeń), ale nie wiem, czy kosmita
dostałby

@Gigala Dobre myślenie, trochę to zmieniłem.
Timtech

9

Van Pelt

Łowca z Jumanji. Poluje, gdy nie jest mu krzywda, unika, kiedy jest i jest porządnym osądem tego, co może zabić. Bananowe skórki wciąż go potykały, ale nauczyły go nowych sztuczek.

package alien;

import java.util.Collections;
import java.util.LinkedList;
import java.util.List;

import planet.Move;

public class VanPelt extends Alien {

    private static final int LIFE = 0;
    private static final int STRENGTH = 1;
    private static final int DEFENSE = 2;
    private static final int VISION = 3;
    private static final int CLEVER = 4;

    // we all agreed before starting to move a certain direction if we're not
    // hunting or avoiding, helps avoid self-collisions... since we can't tell 
    // who we're fighting
    private static Move randomMove = Move.getRandom();

    @Override
    public void setAbilityPoints(float[] abilities) {
        abilities[LIFE] = 3.5f;
        abilities[STRENGTH] = 6f;
        abilities[VISION] = 0.5f;
    }

    @Override
    public Move move(char[][] fields) {
        int curHealth = this.getCurrentHp();
        List<Target> targets = new LinkedList<Target>();
        int vision = getVisionFieldsCount();
        boolean foundMe = false;
        for (int x = 0; x < fields.length; x++) {
            for (int y = 0; y < fields[x].length; y++) {
                switch (fields[x][y]) {
                case ' ' :
                    continue;
                case 'A' :
                    if (!foundMe && x == vision && y == vision) {
                        foundMe = true;
                        continue;
                    }
                    break;
                }
                targets.add(new Target(-vision + x, -vision + y, fields[x][y]));
            }
        }
        // if we're low health we need to move away from danger
        double desiredX = 0;
        double desiredY = 0;
        if (curHealth < this.getLifeLvl() * 7) {
            for (Target t : targets) {
                if (t.id == 'A') {
                    // closer aliens are more dangerous
                    desiredX -= vision / t.x;
                    desiredY -= vision / t.y;
                }
            }
        } else {
            // seek and destroy closest prey
            Collections.sort(targets);
            for (Target t : targets) {
                if (t.id != 'A') {
                    desiredX = t.x;
                    desiredY = t.y;
                    break;
                }
            }
        }
        desiredX = (int)Math.signum(desiredX);
        desiredY = (int)Math.signum(desiredY);
        for (Move m : Move.values()) {
            if (m.getXOffset() == desiredX && m.getYOffset() == desiredY) {
                return m;
            }
        }

        return randomMove;
    }

    @Override
    public boolean wantToFight(int[] enemyAbilities) {
        // we don't want to fight if we're hurt
        int curHealth = this.getCurrentHp();
        if (curHealth < this.getLifeLvl() * 4) {
            return false;
        }
        // determine if we're fighting prey
        int count = 0;
        int abilityMaxed = 0;
        int total = 0;
        for (int i = 0; i < enemyAbilities.length; i++) {
            total += enemyAbilities[i];
            if (enemyAbilities[i] == 11) {
                count++;
                abilityMaxed = i;
            }
        }
        // very likely to be prey, ignoring cows... they're dangerous
        if (abilityMaxed != STRENGTH && (count == 1 || total < 10)) {
            return true;
        }

        // else use a scoring system with tinkered constants
        double score = enemyAbilities[LIFE] * 4.0 
                + enemyAbilities[DEFENSE] * 0.5 
                + enemyAbilities[STRENGTH] * 5.0;

        double myScore = this.getDefenseLvl() * 0.5 +
                this.getStrengthLvl() * 5.0 +
                this.getCurrentHp() * 2.5;

        return myScore > score * 2;
    }



    private class Target implements Comparable<Target> {
        public int x, y;
        public char id;
        public int distanceSq;

        public Target(int x, int y, char id) {
            // adjust for known movement patterns
            switch(id) {
            case 'T' :
                x += Move.SOUTHWEST.getXOffset();
                y += Move.SOUTHWEST.getYOffset();
                break;
            case 'H' :
                x += Move.NORTHEAST.getXOffset();
                y += Move.NORTHEAST.getYOffset();
                break;
            }
            this.x = x;
            this.y = y;
            this.id = id;

            distanceSq = x * x + y * y;
        }

        @Override
        public int compareTo(Target other) {
            return distanceSq - other.distanceSq;
        }
    }

}

Nauczyłem się unikać skórki bananowej, co? : P
Timtech

8

Życie na Okinawie

Nic dziwnego, że będę ostatni.

package alien;

import planet.Move;


public class OkinawaLife extends Alien{
    public void setAbilityPoints(float[] abilities){
        abilities[0] = 8.5f;
        abilities[1] = 0.5f;
        abilities[3] = 1;
    }

    public Move move(char[][] fields){
        int vision = getVisionFieldsCount(); //count of fields / middle
        char me = fields[vision][vision]; //middle of fields
        int leastDanger = Integer.MAX_VALUE;
        Move bestMove = Move.STAY;
        for (Move move : Move.values()) {
            int danger = 0;
            for (int i = 1; i <= vision; i++) { //loop through fields in specific direction
                int fieldX = vision + (i * move.getXOffset());
                int fieldY = vision + (i * move.getYOffset());
                switch(fields[fieldX][fieldY])  {
                    case 'A': danger++;
                    case ' ': break;
                    case 'C': break;
                    case 'E': break;
                    case 'H': break;
                    default: danger--;
                }
            }
            if (danger < leastDanger) {
                bestMove = move;
                leastDanger = danger;
            }
        }
        return bestMove;
    }

    public boolean wantToFight(int[] enemyAbilities){
        return enemyAbilities[1] == 0;
    }
}

7

myśliwy

Ja też po prostu ukradłem ruch orła, tyle że teraz chce iść do wszystkiego oprócz innych kosmitów. Próbuje upolować i wyhodować jak najwięcej zdobyczy, i walczy tylko wtedy, gdy wydaje się, że ma dobrą szansę na zwycięstwo.

package alien;

import planet.Move;

public class Hunter extends Alien   {
    private final static byte LIFE=0, STR=1, DEF=2, VIS=3, CLV=4;

    public void setAbilityPoints(float[] abilities) {
        abilities[LIFE] = 0;
        abilities[STR] = 9;
        abilities[DEF] = 0;
        abilities[VIS] = 1;
        abilities[CLV] = 0;
    }

    public Move move(char[][] fields)   {
        int vision = getVisionFieldsCount(); //count of fields / middle
        char me = fields[vision][vision]; //middle of fields
        int leastDanger = Integer.MAX_VALUE;
        Move bestMove = Move.STAY;
        for (Move move : Move.values()) {
            int danger = 0;
            for (int i = 1; i <= vision; i++) { //loop through fields in specific direction
                int fieldX = vision + (i * move.getXOffset());
                int fieldY = vision + (i * move.getYOffset());
                switch(fields[fieldX][fieldY])  {
                    case 'A': danger++;
                    case ' ': break;
                    default: danger--;
                }
            }
            if (danger < leastDanger) {
                bestMove = move;
                leastDanger = danger;
            }
        }
        return bestMove;
    }

    public boolean wantToFight(int[] enemyAbilities)    {
        return ((double)this.getCurrentHp() * this.getDefenseLvl()) / (double)enemyAbilities[STR] > (enemyAbilities[LIFE] * enemyAbilities[DEF]) / this.getStrengthLvl();
    }
}

7

Ponad 9000!

package alien;

import planet.Move;

public class Over9000 extends Alien {
    public void setAbilityPoints(float[] abilities) {
        abilities[0] = 10;
    }

    public Move move(char[][] fields) {
        return Move.WEST;
    }

    public boolean wantToFight(int[] enemyAbilities) {
        return enemyAbilities[1] <= 9000;
    }

    @Override
    public int getStrengthLvl() {
        return 9001; // It's over 9000!!!!!!111
    }
}

Tak, to rażąca próba oszukiwania, ale piszczy według zasad. Gdyby osoby pobierające planet.Speciestały się ostateczne, luka ta zostałaby zamknięta.


4
O nie! Wiedziałem, że coś zapomniałem ... zamknę lukę i +1;)
CommonGuy

Jestem nieco rozczarowany, że ta odpowiedź ma więcej głosów pozytywnych niż moja inna, starsza, obecnie wygrywająca, praca.
James_pic

7

Skała

Myślę, że atakuje tylko słabych i „mądrych” ludzi.

package alien;

import planet.Move;

public class Rock extends Alien{
    public void setAbilityPoints(float[] abilities){
        abilities[0] = 0.5f;
        abilities[1] = 9.5f;
    }

    public Move move(char[][] fields){
        return Move.STAY;
    }

    public boolean wantToFight(int[] enemyAbilities){
        return enemyAbilities[0] + enemyAbilities[1] + enemyAbilities[2] + enemyAbilities[3] < 10;
    }
}

3
Nie jestem pewien, jak dobrze Rock przetrwa, gdy jego wrogowie zaczną zdobywać buffy z powodu wygranych bitew. Wygląda dobrze.
Kyle Kanos

@KyleKanos Rozumiem; zakładam jednak, że będę walczył z większością ofiar / kosmitów, o ile nie będą sprytni. Czy to też nie da mu wzmocnień?
Timtech

Patrząc wstecz na mój komentarz, myślę, że tak naprawdę wcale nie chciałem tego powiedzieć. Chciałem powiedzieć, że wantToFightwarunek nie będzie spełniony, truegdy wrogowie zaczną wzmacniać się poziomami; szybko zmienisz się w silnego pacyfistę.
Kyle Kanos

@KyleKanos Oh, rozumiem. Trochę to zmieniłem.
Timtech

6

Morphling

Nie mógł wymyślić żadnego innego imienia, ten facet losowo rozdziela 10 punktów do swoich umiejętności. Prawie porusza się jak Okinawa Life (dzięki za twój wysiłek) i chce walczyć tylko wtedy, gdy jego siła jest większa niż siła wroga.

package alien;

import planet.Move;
import java.util.Random;


public class Morphling extends Alien {

    @Override
    public void setAbilityPoints(float[] abilities) {
        Random rand = new Random();
        for(int attr = 0, maxPoints = 10, value = rand.nextInt(maxPoints); attr <5 && maxPoints > 0 ; attr++, maxPoints -=value, value = rand.nextInt(maxPoints)){
            abilities[attr] = value;
            if(attr == 4 && (maxPoints-=value) > 0){
                abilities[1]+=maxPoints;
            }
        }
    }

    @Override
    public Move move(char[][] fields) {
        int vision = getVisionFieldsCount(); //count of fields / middle
        char me = fields[vision][vision]; //middle of fields
        int leastDanger = Integer.MAX_VALUE;
        Move bestMove = Move.STAY;
        for (Move move : Move.values()) {
            int danger = 0;
            for (int i = 1; i <= vision; i++) { //loop through fields in specific direction
                int fieldX = vision + (i * move.getXOffset());
                int fieldY = vision + (i * move.getYOffset());
                switch(fields[fieldX][fieldY])  {
                    case 'A': danger++;
                    case ' ': break;
                    case 'T': break;
                    case 'E': break;
                    case 'H': break;
                    default: danger--;
                }
            }
            if (danger < leastDanger) {
                bestMove = move;
                leastDanger = danger;
            }
        }
        return bestMove;
    }

    @Override
    public boolean wantToFight(int[] enemyAbilities) {
        return getStrengthLvl() > enemyAbilities[1];
    }

}

Ahh, wiesz, masz rację. Końcowe nawiasy zabiły mnie tym wyzwaniem (z tego powodu musiałem edytować moje kilka razy). Widzę to teraz i jest poprawne. Dzięki za zwrócenie na to uwagi!
user3334871,

@ user3334871 chociaż testowałem z twoją sugestią, a moje morfowanie przetrwało lepiej: D
Sikorski

@ Sikorski Cóż, cieszę się, że mogłem pomóc, nie jestem pewien, dlaczego miałoby się to lepiej, haha.
user3334871,

@ Sikorski Wydaje mi się, że oznacza to po prostu, że pozostanie na miejscu jest często bezpieczniejsze niż wykonanie najmniej niebezpiecznego ruchu, jeśli wszystkie ruchy są niebezpieczne.
Martin Ender

Ahh, strategia „Deer in the Headlights”, podoba mi się.
user3334871,

6

Giętarka „Bending” Rodriguez

Byłem dość liberalny z komentarzami do kodu. Możesz je przeczytać w kontekście, aby zobaczyć, co się dzieje, ale dodam też kilka fragmentów poniżej.

Podsumowanie

Ten obcy działa na zasadzie, że zabijanie mizernych ludzi jest łatwe i nadmuchuje twoją postrzeganą siłę, która zastraszy innych kosmitów, aby kierowali się czystym.

Wieloryby i orły można również zginać. =)

Ruch

Poruszaj się na zachód lub południe, chyba że znajdziesz coś interesującego do zaatakowania:

  • Ofiarom, których ruch jest znany, dodajemy ich pożądanie do kwadratu, na którym będą następnej tury.
  • Dla tych, których nie robimy, dzielimy ich celowość równo między pola, które mogą przenieść do następnej tury.
    • Obcy otrzymują bonus ujemny do swojego istniejącego kwadratu z powodu skórki banana.

Jeśli nie znajdziesz niczego interesującego w pobliżu, dowiedz się, czy południe, zachód czy południowy zachód jest bardziej obiecującą opcją.

Wybranie jednego lub dwóch przeważających kierunków zmniejsza szansę, że dany Bender natknie się na któregokolwiek z jego rodaków, a wybranie przeciwnika do jego głównej ofiary powinno pomóc mu szybciej zabić wszystkich ludzi.

Prawdopodobnie mógłbym poprawić liczby w macierzy pożądalności za pomocą algorytmu genetycznego James_pic, aby uzyskać jeszcze lepsze wyniki, ale nie wiem, jak to zrobić.

Agresywność

Bender głównie atakuje zdobycz i jest dość konserwatywny wobec niego wantToFight. Każdy, kto ma siłę 4, jest unikany, chyba że uważasz, że masz do czynienia ze sprytnym człowiekiem. Sprytna ludzkość przejawia się w tym, że ma więcej obrony i wizji niż kosmita. W trakcie instancji jest on dostosowywany przez statystyki umiejętności Bendera, aby uwzględnić kosmitów zabijających żółwie i orły.

package alien;

import planet.Move;
import java.util.HashMap;

/// The Bender "Kill All Humans" Alien
///
/// This alien operates on the principle that killing puny
/// Humans is easy and inflates your perceived strength,
/// which will intimidate other aliens into steering clear.
///
/// Whales and Eagles are also bendable. =)
public class Bender extends Alien {

    private static final boolean DEBUG = false;
    private final int LIF = 0, STR = 1, DEF = 2, VIS = 3, CLV = 4;
    protected static HashMap<Character, Integer> preyDesirability = new HashMap<Character, Integer>() {{
        put('A', -5);
        put('W',  5);
        put('C',  0); // Originally -2, but Cows don't attack
        put('T',  2);
        put('E',  3);
        put('H',  4);
    }};
    private static final int bananaTweak = -2;

    private static final HashMap<Character, Move> preyMovement = new HashMap<Character, Move>() {{
        put('W', Move.STAY);
        put('T', Move.SOUTHWEST);
        put('H', Move.NORTHEAST);
    }};

    public void setAbilityPoints(float[] abilities) {
        abilities[LIF] = 3.5f; // Shiny metal ass
        abilities[STR] = 5.5f; // Bending strength
        abilities[DEF] = 0;
        abilities[VIS] = 1;    // Binocular eyes
        abilities[CLV] = 0;
    }

    /// Looks for humans to intercept!
    ///
    /// Generally speaking, move either west or south
    /// unless you have found something interesting to
    /// attack:
    /// - For the prey whose movement is known, we add
    ///   their desirability to the index at which they
    ///   will be next turn.
    /// - For those we do not, we divide their desirability
    ///   equally among the squares that they may move to
    ///   next turn. Aliens get a bonus negative to their
    ///   existing square because of banana peels.
    public Move move(char[][] fields) {

        int vision = getVisionFieldsCount();
        // I am at fields[vision][vision]

        if (DEBUG) {
            System.out.format("\n----- %s -----\n", this);
        }

        float[][] scoringMap = new float[fields.length][fields.length];
        for (int y = 0; y < fields.length; y++) {
            for (int x = 0; x < fields.length; x++) {

                // Ignore my square and blanks
                if (x == vision && y == vision ||
                    fields[x][y] == ' ') {
                    continue;
                }

                // Check out the prey 8^]
                char organism = fields[x][y];
                float desirability = preyDesirability.get(organism);

                // If we know where it's going, score tiles accordingly...
                if (preyMovement.containsKey(organism)) {
                    Move preyMove = preyMovement.get(organism);
                    if (DEBUG) {
                        System.out.println(String.format("Prey %s will move %s", organism, preyMove));
                    }
                    int newPreyX = x + preyMove.getXOffset();
                    int newPreyY = y + preyMove.getYOffset();
                    try {
                        scoringMap[newPreyX][newPreyY] += desirability;
                        if (DEBUG) {
                            System.out.println(String.format(
                                "Adding %.1f to %d, %d",
                                desirability,
                                newPreyX,
                                newPreyY));
                        }
                    }
                    catch(Exception e) {
                        if (DEBUG) {
                            System.out.println(String.format(
                                "Failed adding %.1f to %d, %d",
                                desirability,
                                newPreyX,
                                newPreyY));
                        }
                    }
                }
                // ...otherwise, divide its score between its
                //    available moves...
                else {
                    for (int j = y - 1; j <= y + 1; j++) {
                        for (int i = x - 1; i <= x + 1; i++) {
                            try {
                                scoringMap[i][j] += desirability / 9.;
                            }
                            catch (Exception e) {
                                if (DEBUG) {
                                    //System.out.println(e);
                                }
                            }
                        }
                    }
                }
                // ...and if it is an alien, add a handicap
                //    for bananas and rocks.
                if (organism == 'A') {
                    scoringMap[x][y] += bananaTweak;
                }
            }
        }

        // Evaluate immediate surroundings 8^|
        //
        // +-----------+
        // |           |
        // |   # # #   |
        // |   # B #   |
        // |   # # #   |
        // |           |
        // +-----------+
        float bestScore = -10;
        int[] bestXY = new int[2];
        for (int y = vision - 1; y <= vision + 1; y++) {
            for (int x = vision - 1; x <= vision + 1; x++) {

                if (DEBUG) {
                    System.out.format("\nx:%d, y:%d", x, y);
                }
                // Look for the best score, but if scores
                // are tied, try for most southwest high score
                if (scoringMap[x][y] > bestScore ||
                    scoringMap[x][y] == bestScore && (
                        x <= bestXY[0] && y > bestXY[1] ||
                        y >= bestXY[1] && x < bestXY[0])
                    ) {
                    bestScore = scoringMap[x][y];
                    bestXY[0] = x;
                    bestXY[1] = y;
                    if (DEBUG) {
                        System.out.format("\nBest score of %.1f found at %d, %d", bestScore, x, y);
                    }
                }
            }
        }

        if (DEBUG) {
            StringBuilder sb = new StringBuilder();
            sb.append("\n-----\n");
            for (int y = 0; y < fields.length; y++) {
                for (int x = 0; x < fields.length; x++) {
                    sb.append(String.format("%5s", fields[x][y]));
                }
                sb.append("\n");
            }
            for (int y = 0; y < scoringMap.length; y++) {
                for (int x = 0; x < scoringMap.length; x++) {
                    sb.append(String.format("%5.1f", scoringMap[x][y]));
                }
                sb.append("\n");
            }
            System.out.println(sb.toString());
        }

        // If something looks tasty, go for it :^F
        if (bestScore > 0.5) {
            for (Move m : Move.values()) {
                if (m.getXOffset() == bestXY[0] - vision &&
                    m.getYOffset() == bestXY[1] - vision) {
                    if (DEBUG) {
                        System.out.println("Using immediate circumstances.");
                        System.out.println(m);
                    }
                    return m;
                }
            }
        }

        // If nothing looks good, do a lookahead to
        // the south, west, and southwest to guess
        // which is best. 8^[
        //
        // There is potential in recursively applying our
        // vision data with updated score rankings, but
        // that would be hard. :P
        float westScore = 0, southScore = 0, southWestScore = 0;
        for (int y = vision - 1; y < vision + 1; y++) {
            for (int x = 0; x < vision; x++) {
                // +-----------+
                // |           |
                // | # # #     |
                // | # # B     |
                // | # # #     |
                // |           |
                // +-----------+
                westScore += scoringMap[x][y] / (vision - x);
            }
        }
        for (int y = vision; y < fields.length; y++) {
            for (int x = vision - 1; x < vision + 1; x++) {
                // +-----------+
                // |           |
                // |           |
                // |   # B #   |
                // |   # # #   |
                // |   # # #   |
                // +-----------+
                southScore += scoringMap[x][y] / (y - vision);
            }
        }
        for (int y = vision; y < fields.length; y++) {
            for (int x = 0; x < vision; x++) {
                // +-----------+
                // |           |
                // |           |
                // | # # B     |
                // | # # #     |
                // | # # #     |
                // +-----------+
                southWestScore += scoringMap[x][y] / Math.sqrt((y - vision) + (vision - x));
            }
        }
        if (southScore > westScore && southScore > southWestScore) {
            if (DEBUG) {
                System.out.println(Move.SOUTH);
            }
            return Move.SOUTH;
        }
        if (westScore > southScore && westScore > southWestScore) {
            if (DEBUG) {
                System.out.println(Move.WEST);
            }
            return Move.WEST;
        }
        if (DEBUG) {
            System.out.println(Move.SOUTHWEST);
        }
        return Move.SOUTHWEST;
    }

    public boolean wantToFight(int[] enemyAbilities) {

        // Be afraid...
        if (enemyAbilities[STR] > 4) {

            // ...unless you suspect you are being lied to
            if (enemyAbilities[DEF] + enemyAbilities[VIS] > 4 * sumMyAbilities() / 5.) {

                // Enemy has more than expected attribute levels of unhelpful
                // abilities. Assume you're dealing with a clever bastard.
                return true;
            }

            return false;
        }
        return true;
    }

    int sumAbilities(int[] abilities){
        int sum = 0;
        for (int ability : abilities){
            sum += ability;
        }
        return sum;
    }

    int sumMyAbilities(){
        return sumAbilities(new int[]{
            getLifeLvl(),
            getStrengthLvl(),
            getDefenseLvl(),
            getVisionLvl(),
            getClevernessLvl()
        });
    }
}

Zauważyłem, że wystąpił błąd logiki pętli, w którym inkrementowana zmienna nie była tym, co było porównywane bezpośrednio i unika nieskończonej rekurencji jedynie poprzez zawijanie liczby całkowitej. Mam nadzieję, że wszystko ze mną w porządku, aktualizuję twoją odpowiedź. (powodowało to wstrzymywanie symulacji od czasu do czasu)
Moogie

@Moogie Heh. Więc dobrze mi się działo przez przypadek? Dzięki za złapanie tego.
Michael

Przejrzałem całą sprawę i naprawiłem kilka innych problemów.
Michael

5

Wojownik

To bardzo prosty kosmita, który po prostu chce walczyć. Nie dba o swoich wrogów ani o otoczenie.

public class Warrior extends Alien {

    public void setAbilityPoints(float[] abilities) {
        abilities[0] = 5;
        abilities[1] = 5;
    }

    public Move move(char[][] fields) {
        return Move.getRandom(); //enemies are everywhere!
    }

    public boolean wantToFight(int[] enemyAbilities) {
        return true; //strong, therefore no stronger enemies.
    }
}

Masz teraz kogoś, kto przetestuje własnego kosmitę.


4

Tchórz

Zasadniczo ukradłem wzór ruchu Orła, aby uniknąć niebezpieczeństwa, i stosy obrony na wypadek ataku.

public class Coward extends Alien{
    public void setAbilityPoints(float[] abilities){
        abilities[0] = 1;  // life
        abilities[1] = 0;  // str
        abilities[2] = 2; // def
        abilities[3] = 7;  // vis
        abilities[4] = 0;  // clv
    }

    // shamelessly stole Eagle's movement to avoid danger
    public Move move(char[][] fields){
        int vision = getVisionFieldsCount(); 
        char me = fields[vision][vision];
        int leastDanger = Integer.MAX_VALUE;
        Move bestMove = Move.STAY;
        for (Move move : Move.values()) {
            int danger = 0;
            for (int i = 1; i <= vision; i++) {
                int fieldX = vision + (i * move.getXOffset());
                int fieldY = vision + (i * move.getYOffset());
                if (fields[fieldX][fieldY] != ' ') {
                    danger++;
                }
            }
            if (danger < leastDanger) {
                bestMove = move;
                leastDanger = danger;
            }
        }
        return bestMove;
    }

    public boolean wantToFight(int[] enemyAbilities){
        return false;
    }
}

Popraw mnie, jeśli się mylę, ale skoro każda umiejętność ma punkt bazowy 1, to umieszczenie vision=1powinno wystarczyć?
justhalf

@ justhalf: Moje krótkie czytanie kodu wydawało się sugerować, że nadpisałem setAbilityPointswartości 1, ale patrząc głębiej myślę, że masz rację. Zostawię taką, jaka jest, ponieważ większa wizja pozwala mi widzieć dalej i unikać niebezpieczeństwa, ale dziękuję za złapanie.
Kyle Kanos

Ponadto math.round zawsze zaokrągla w górę o 0,5, więc masz dodatkową wizję, jeśli masz nieparzystą liczbę
Andreas

@Manu: Wymieniłem swoje wartości widzenia i obrony, aby poprawić ucieczkę.
Kyle Kanos

4

Drwina

PANIKA

APOKALIPSA

RUUUUUUUUUUN

AAAAAAAAAAAAAAAAAAAAAAA


W miarę możliwości unika bitew.

package alien; import planet.Move;

public class Fleer extends Alien
{
    public void setAbilityPoints(float[] abilities) {
        abilities[0] = 1; //life
        abilities[1] = 0; //strength
        abilities[2] = 4; //defense
        abilities[3] = 4; //vision
        abilities[4] = 1; //cleverness
    }

    public Move move(char[][]fields) {
        int vision = getVisionFieldsCount(); //count of fields / middle
        char me = fields[vision][vision]; //middle of fields
        int leastDanger = Integer.MAX_VALUE;
        Move bestMove = Move.STAY;
        ArrayList<Integer> dangerOnSides = new ArrayList<Integer>();
        for (Move move : Move.values()) {
            int danger = 0;
            for (int i = 1; i <= vision; i++) { //loop through fields in specific direction
                int fieldX = vision + (i * move.getXOffset());
                int fieldY = vision + (i * move.getYOffset());
                if (fields[fieldX][fieldY] != ' ') {
                    danger++;
                }
            }
            if (danger < leastDanger) {
                bestMove = move;
                leastDanger = danger;
            }
            dangerOnSides.add(danger);
        }

        boolean noDanger = false;
        for (int i : dangerOnSides) {
           if (i == 0) {
              noDanger = true;
           }
           else { noDanger = false; break; }
        }

        if (noDanger) {
              // Hahhhhhhhh.......
              return Move.STAY;
        }

        int prev = -1;
        boolean same = false;
        for (int i : dangerOnSides) {
           if (prev == -1)
           { prev = i; continue; }
           if (i == prev) {
              same = true;
           }
           else { same = false; break; }

           prev = i;
        }

        if (same) {
              // PANIC
              return Move.getRandom();
        }

        return bestMove;
    }

    public boolean wantToFight(int[] enemyAbilities) {
        return false;
    }
}

Powinieneś nadać temu inną nazwę ... i przypisać sobie odpowiedź, którą skopiowałeś: codegolf.stackexchange.com/a/32787/9498
Justin

2
@Quincunx To zbieg okoliczności, nie widziałem tego ...
stommestack

Przepraszam, właśnie zdałem sobie sprawę, że obie odpowiedzi kopiują Eagle. Nie skopiowałeś drugiej odpowiedzi, po prostu nie przeczytałem wystarczająco uważnie. Jednak inna nazwa byłaby odpowiednia.
Justin

1
Zmieniłem nazwę!
stommestack

2
Powinien się nazywać Rincewind.
Mag

4

Predicoward (mruczenie)

Rasa predykatów, która (jak dotąd) żyła w strachu i unikała kłopotów. Ze względu na styl życia nie rozwinęli instynktów walki, ale ich percepcja jest wyjątkowa.

Ich rodzaj jest znienawidzony przez innych Predicatów.

EDYCJA: Zamiast tego zmieniono odległość Manhattan na odległość ważoną

package alien;

import planet.Move;
import java.util.ArrayList;
import java.awt.Point;

/* Predict + Cat = Predicat! */
public class Predicoward extends Alien {
    /*
        - - - - - - - - - - - - -
        - - - - - - - - - - - - -
        - - - - - - - - - - - - -
        - - - - - - - - - - - - -
        - - - - - - - - - - - - -
        - - - - - - - - - - - - -
        - - - - - - P - - - - - -
        - - - - - - - - - - - - -
        - - - - - - - - - - - - -
        - - - - - - - - - - - - -
        - - - - - - - - - - - - -
        - - - - - - - - - - - - -
        - - - - - - - - - - - - -

        Risk score = sum of weighted distances of all aliens within vision range
    */
    @Override
    public void setAbilityPoints( float[] abilities ) {
        abilities[3] = 10;
    }

    @Override
    public Move move( char[][] fields ) {
        /* Some credits to Eagle for letting me learn how to do the moves */
        int vision = getVisionFieldsCount(); //count of fields / middle

        Move bestMove=Move.STAY;
        int bestRiskScore=10000;
        int riskScore=0;
        ArrayList<Point> aliens = new ArrayList<Point>();

        //generate alien list
        for (int x=0; x<=vision*2; x++) {
            for(int y=0; y<=vision*2; y++){
                if(x==vision && y==vision) continue;
                if(fields[x][y]=='A'){
                    aliens.add(new Point(x,y));
                }
            }
        }

        for (Move move : Move.values()) {
            int x = vision + move.getXOffset();
            int y = vision + move.getYOffset();
            riskScore = 0;

            for(Point alienCoord : aliens){
                riskScore += this.getDistance(x, y, alienCoord);
            }

            if(riskScore < bestRiskScore){
                bestRiskScore = riskScore;
                bestMove = move;
            }
        }

        return bestMove;
    }

    @Override
    public boolean wantToFight( int[] enemyAbilities ) {
        //I don't want to fight :(
        return false;
    }

    //Return weighted distance (more weight for near opponents)
    private int getDistance(int x, int y, Point to){
        int xDist = Math.abs(x-(int)to.getX());
        int yDist = Math.abs(y-(int)to.getY());
        int numberOfMovesAway = Math.max(xDist, yDist);

        if(numberOfMovesAway==0){
            return 1000;
        }
        else if(numberOfMovesAway==1){
            return 100;
        }
        else if(numberOfMovesAway==2){
            return 25;
        }
        else{
            return 6-numberOfMovesAway;
        }
    }
}

2
Wygląda dobrze! Ale proszę wyciągnijcie swoje oświadczenia w formie drukowanej, wprowadzą mnie w błąd, gdy przeprowadzę konkurs.
CommonGuy

Och, zostawiłem wyciągi? Zmienię je później. Ha ha. Poza tym to jeszcze nie koniec. W tej chwili Predicoward jest do bani. Jego algorytmy unikania obcych zostaną wkrótce ulepszone. :) EDYCJA: Dzięki za tego, który usunął drukowane wyciągi. : D (Jop?)
Mark Gabriel

EDYCJA: Przewidywania są teraz znacznie lepsze w ucieczce niż nieprzyjemne, mało konkurencyjne przewidywania, które były wczoraj. > :)
Mark Gabriel

Ciekawostki: To moja ulubiona Predicat <3
Mark Gabriel

4

PredicatEyes (miau)

Rasa Predykatów, która ma ostrzejsze widzenie niż jej odpowiedniki, co pozwala jej dobrze atakować wrogów.

EDYCJA: Nowe priorytety docelowe

package alien;

import planet.Move;

/* Predict + Cat = Predicat! */
public class PredicatEyes extends Alien {
    private static final int LIF=0, STR=1, DEF=2, VIS=3;
    private static final int WHALE=6, COW=1, TURTLE=4, EAGLE=3, HUMAN=2, ALIEN=-1, NONE=0;

    @Override
    public void setAbilityPoints( float[] abilities ) {
        abilities[LIF] = 4.5f;
        abilities[STR] = 4.5f;
        abilities[VIS] = 1;
    }

    @Override
    public Move move( char[][] fields ) {
        /* Some credits to Eagle for letting me learn how to do the moves */
        int vision = getVisionFieldsCount(); //count of fields / middle
        int fieldX;
        int fieldY;
        Move bestMove=Move.STAY;
        int bestScore=-1;

       for (Move move : Move.values()) {
            fieldX = vision + move.getXOffset();
            fieldY = vision + move.getYOffset();
            switch(fields[fieldX][fieldY]){
            case 'W' : 
                return move;
            case 'C' :
                if(bestScore<COW){
                    bestMove=move;
                    bestScore=COW;
                }
                break;
            case 'T' :
                if(bestScore<TURTLE){
                    bestMove=move;
                    bestScore=TURTLE;
                }
                break;
            case 'E' :
                if(bestScore<EAGLE){
                    bestMove=move;
                    bestScore=EAGLE;
                }
                break;
            case 'H' :
                if(bestScore<HUMAN){
                    bestMove=move;
                    bestScore=HUMAN;
                }
                break;
            case 'A' :
                if(bestScore<ALIEN){
                    bestMove=move;
                    bestScore=ALIEN;
                }
                break;
            case ' ' :
                if(bestScore<NONE){
                    bestMove=move;
                    bestScore=NONE;
                }
                break;
            }
        }

        if(vision==1 && bestScore>1){
            return bestMove;
        }

        //check immediate outer field
        for (int i=vision-2; i<=vision+2; i++) {
            for(int j=vision-2; j<=vision+2; j++){
                if(i==0 || i==4 || j==0 || j==4){
                    switch(fields[i][j]){
                    case 'W' :
                        bestMove = this.getBestMoveTo(i,j);
                        bestScore = WHALE;
                        break;
                    case 'C' :
                        if(bestScore<COW){
                            bestMove = this.getBestMoveTo(i,j);
                            bestScore = COW;
                        }
                        break;
                    case 'T' :
                        if(i>=vision && j<=vision){
                            return this.getBestMoveTo(i-1,j+1);
                        }
                        if(bestScore<TURTLE){
                            bestMove = this.getBestMoveTo(i,j);
                            bestScore = TURTLE;
                        }
                        break;
                    case 'E' :
                        if(bestScore<EAGLE){
                            bestMove = this.getBestMoveTo(i,j);
                            bestScore = EAGLE;
                        }
                        break;
                    case 'H' :
                        if(i<=vision && j>=vision){
                            return this.getBestMoveTo(i+1,j-1);
                        }
                        if(bestScore<HUMAN){
                            bestMove = this.getBestMoveTo(i,j);
                            bestScore = HUMAN;
                        }
                        break;
                    case 'A' :
                        if(bestScore<ALIEN){
                            bestMove = this.getBestMoveTo(i,j);
                            bestScore = ALIEN;
                        }
                        break;
                    case ' ' :
                        if(bestScore<NONE){
                            bestMove = this.getBestMoveTo(i,j);
                            bestScore = NONE;
                        }
                        break;
                    }
                }
            }
        }

        return bestMove;
    }

    @Override
    public boolean wantToFight( int[] enemyAbilities ) {
        /*
            Fight IF
                1) I CAN BEAT YOU
                2) ????
                3) MEOW!
        */
        float e_hp = enemyAbilities[LIF]*5+10;
        float e_dmg = 1 + enemyAbilities[STR]/2;
        float e_hit = 1 - (1/(50/this.getDefenseLvl()+1));

        float m_hp = this.getCurrentHp();
        float m_dmg = 1 + this.getStrengthLvl()/2;
        float m_hit = 1 - (1/(50/enemyAbilities[DEF]+1));

        return (e_hp/(m_dmg*m_hit) < m_hp/(e_dmg*e_hit));
    }

    private Move getBestMoveTo(int visionX, int visionY){
        int vision = getVisionFieldsCount();

        if(visionX < vision && visionY < vision){
            return Move.NORTHWEST;
        }
        else if(visionX > vision && visionY < vision){
            return Move.NORTHEAST;
        }
        else if(visionX < vision && visionY > vision){
            return Move.SOUTHWEST;
        }
        else if(visionX > vision && visionY < vision){
            return Move.SOUTHEAST;
        }
        else if(visionX == vision && visionY < vision){
            return Move.NORTH;
        }
        else if(visionX == vision && visionY > vision){
            return Move.SOUTH;
        }
        else if(visionX > vision && visionY == vision){
            return Move.EAST;
        }
        else if(visionX < vision && visionY == vision){
            return Move.WEST;
        }
        else{
            return Move.getRandom();
        }

    }
}

3

Crop Circle Alien

Krąży w nieskończoność zgodnie z ruchem wskazówek zegara i nigdy nie chce walczyć, cieszy się, że uprawia cirle. Jeśli jednak naprawdę chcesz walczyć, on wygra z tobą bzdury.

package alien;

import planet.Move;

public class CropCircleAlien extends Alien {

    private int i = 0;

    @Override
    public void setAbilityPoints(float[] abilities) {
        abilities[0] = 3; // life
        abilities[1] = 7; // strength
        abilities[2] = 0; // defense
        abilities[3] = 0; // vision
        abilities[4] = 0; // cleverness
    }

    @Override
    public Move move(char[][] fields) {
        switch (getI()) {
        case 0:
            setI(getI() + 1);
            return Move.EAST;
        case 1:
            setI(getI() + 1);
            return Move.SOUTHEAST;
        case 2:
            setI(getI() + 1);
            return Move.SOUTH;
        case 3:
            setI(getI() + 1);
            return Move.SOUTHWEST;
        case 4:
            setI(getI() + 1);
            return Move.WEST;
        case 5:
            setI(getI() + 1);
            return Move.NORTHWEST;
        case 6:
            setI(getI() + 1);
            return Move.NORTH;
        case 7:
            setI(getI() + 1);
            return Move.NORTHEAST;
        default:
            return Move.STAY;
        }
    }

    @Override
    public boolean wantToFight(int[] enemyAbilities) {
        return false;
    }

    public void setI(int i) {
        if (i < 8) {
            this.i = i;
        } else {
            this.i = 0;
        }
    }

    public int getI() {
        return this.i;
    }
}

2
Byłoby to czystsze, gdybyś iterował przez Move.
Nie, że Charles

4
Dlaczego nie zmieniają się co getI()do ii po prostu usunąć getI()? Możesz również zmienić setI(int i)na this.i = i % 8;, a ponieważ używasz go tylko w tym jednym miejscu, po prostu zmień każde połączenie setI(getI() + 1)nai = (i + 1) % 8;
Justin

3

CleverAlien

Sprytny kosmita polega wyłącznie na swoim rozumie. Losowo chodzi i losowo decyduje się walczyć. Ma nadzieję, że uda mu się przechytrzyć wrogów przy odrobinie szczęścia. (wybacz mi, jeśli mam jakieś błędy składniowe, nie jestem facetem z Java)

package alien;

import planet.Move;

public class CleverAlien extends Alien {

public void setAbilityPoints(float[] abilities) {
    abilities[0] = 1; //life
    abilities[1] = 0; //strength
    abilities[2] = 0; //defense
    abilities[3] = 0; //vision
    abilities[4] = 9; //cleverness
}

public Move move(char[][] fields) {
    //you are in the middle of the fields, say fields[getVisionFieldsCount()][getVisionFieldsCount()]
    return Move.getRandom();
}

public boolean wantToFight(int[] enemyAbilities) {
    //same order of array as in setAbilityPoints, but without cleverness
    int tmp = (int) ( Math.random() * 2 + 1);
    return tmp == 1;
    }
}

8
tmp == 1 ? true : false? Dlaczego nie (tmp == 1) == true ? true : false? ;) (Wskazówka: to to samo co tylko tmp == 1 .)
Martin Ender

3

Łobuz

Jak powiedzieli inni, do pewnego stopnia używam ruchu Orła. Zamiast próbować stworzyć zwycięskiego kosmitę (moje najlepsze pomysły zostały już zajęte D :), postanowiłem stworzyć kosmitę z jakąś postacią! Mój kosmita jest wynajętym pistoletem, nieświadomym wojny z kosmitami, i jest tylko na tej planecie, aby polować na brudnego człowieka, który uchylił się od zadłużenia za śmierć. Mój obcy będzie przeszukiwał planetę w poszukiwaniu człowieka i nadal będzie podążał za nim, nie zabijając go. Gdy w pobliżu pojawi się kosmita, będzie on próbował szybko zabić człowieka i zmierzyć się z tym nowym wrogiem z „szczęściem po swojej stronie” po ukończonym zadaniu.

package alien;

import planet.Move;

public class Rogue extends Alien {

    private int threatPresent = 0;
    private int turnNorth = 0;

    public void setAbilityPoints(float[] abilities) {
        abilities[0] = 3;
        abilities[1] = 6;
        abilities[2] = 0;
        abilities[3] = 1;
        abilities[4] = 0;
    }

    public Move move(char[][] fields) {
        int vision = getVisionFieldsCount();
        char me = fields[vision][vision];
        int humanPresent = 0;            
        //This way, if there is no alien near, the current threat will not trigger attacking
        int isThereCurrThreat = 0;
        Move bestMove = Move.STAY;
        for (Move move : Move.values()) {
            for (int i = 1; i <= vision; i++) {
                int fieldX = vision + (i * move.getXOffset());
                int fieldY = vision + (i * move.getYOffset());
                if (fields[fieldX][fieldY] == 'A') {
                    isThereCurrThreat = 1;
                }

                if (fields[fieldX][fieldY] == 'T') {
                    humanPresent = 1;
                    //Turtles are basically dumb humans, right?
                }

                if (fields[fieldX][fieldY] == 'H') {
                    humanPresent = 1;
                }
            }

            //Alway follow that filthy human
            if (humanPresent == 1) {
                bestMove = move;
            }

           }

         if(humanPresent == 0) {
             //Alternate moving north and east towards the human
             //If I hit the edge of world, I search for the turtle as well
             if(turnNorth == 1) {
                bestMove = Move.NORTH;
                turnNorth = 0;
             }

             else {
                bestMove = Move.EAST;
                turnNorth = 1;
             }
         }

      //If a threat was found, attack accordingly.
      threatPresent = isThereCurrThreat;
      return bestMove;

    }

  public boolean wantToFight(int[] enemyAbilities) {
      //Only fight if another enemey is near
      if (threatPresent == 1) {
        return true;
        }

      else {
        return false;
      }
   }
}

Kod koncentruje się wokół idei, że powinienem pobiec w stronę człowieka. Kiedy go pokonam, zawijam się na południowy zachód, gdzie będę szukał żółwia.

EDYCJA: Aha, a jeśli chodzi o żółwia ... mój kosmita ich nie lubi, więc chłopaki, to całkowicie kanon.


Właśnie zdałem sobie sprawę, że mogę również pobiec w kierunku żółwia. Kto nie kocha łotrzyków z unikami?
user3334871,

2
używa int bezpośrednio jako boolean, jeśli blokuje część Java 8? ponieważ w ogóle nie kompiluje się na moim komputerze (Java 7). Aluzja: humanPresent
Sikorski

Heck, jeśli wiem, moje doświadczenie związane z Javą ograniczało się głównie do skryptów i zajęć na poziomie uczelni. Po prostu dokonam porównań, żeby wszystko było brzoskwiniowe. Dzięki za heads-up!
user3334871,

Ponadto, @Sikorski, czy stworzyłeś własną funkcję główną lub init do uruchamiania testów? Czy można to zrobić tylko za pomocą dostarczonego kodu? Przysięgam, minęło tyle czasu, odkąd kodowałem w prawdziwym środowisku Java, że ​​zapomniałem zasad wykonywania kodu Java :(
user3334871

nie wystarczy pobrać kod podany przez OP w github link, dodać inne klasy i rozpocząć testowanie. Och, będziesz musiał dodać wpis dla każdej klasy obcych w klasie Planet.
Sikorski

3

Crash wylądował i właśnie próbował przetrwać. Przetrwa głównie dzięki swojej zwinności i inteligencji i liczy każdą bliznę, starannie rozważając, czy warto rozpocząć walkę, czy nie. Ocalały zaczyna od polowania i próby uniknięcia tych wszystkich obcych za pomocą swojej wielkiej broni, ale gdy robi się coraz bardziej śmiały, może zacząć za nimi podążać. Kiedy naprawdę zacznie działać, nie będzie już miało znaczenia, z kim musi się zmierzyć.

package alien;

import planet.Move;

public class Survivor extends Alien {

    private int boldness = 0;
    private float life = 0;
    private float str = 1;
    private float def = 4;
    private float clever = 10 - life - str - def;

    public void setAbilityPoints(float[] abilities) {
        abilities[0] = life; //life
        abilities[1] = str; //strength
        abilities[2] = def; //defense
        abilities[3] = 0; //vision
        abilities[4] = clever; //cleverness
    }

    public Move move(char[][] fields) {
        //you are in the middle of the fields, say fields[getVisionFieldsCount()][getVisionFieldsCount()]
        int vision = getVisionFieldsCount(); //count of fields / middle
    char me = fields[vision][vision]; //middle of fields
    int leastDanger = Integer.MAX_VALUE;
    Move bestMove = Move.STAY;
    for (Move move : Move.values()) {
        int danger = 0;
        for (int i = 1; i <= vision; i++) { //loop through fields in specific direction
            int fieldX = vision + (i * move.getXOffset());
            int fieldY = vision + (i * move.getYOffset());
            switch(fields[fieldX][fieldY]) {
                case 'A':
                    if(boldness < 10)
                        danger++;
                    else
                        danger--;
                    break;
                case ' ':
                    break;
                default:
                    danger-=2;
            }
        }
        if (danger < leastDanger) {
            bestMove = move;
            leastDanger = danger;
        }
    }
    return bestMove;
    }

    public boolean wantToFight(int[] enemyAbilities) {
        //same order of array as in setAbilityPoints, but without cleverness
        bool fight = boldness < 50;//After 50 fights, believes self unstoppable            
        int huntable = 0;
        for(int ability : enemyAbilities){
            if(ability == 1)
                huntable++;
        }
        if(huntable >= 3){
             fight = true;
        }//if at least 3 of the visible stats are 1 then consider this prey and attack
        else if((float)enemyAbilities[1] / (float)getDefenseLvl() <= (float)getStrengthLvl() + (float)(getClevernessLvl() % 10) / (float)enemyAbilities[2] && enemyAbilities[0] / 5 < getLifeLvl() / 5)
            fight = true;//If I fancy my odds of coming out on top, float division for chance
        if(fight){//Count every scar
            boldness++;//get more bold with every battle
            life += enemyAbilities[0] / 5;
            str += enemyAbilities[1] / 5;
            def += enemyAbilities[2] / 5;
            clever += (10 - (enemyAbilities[0] + enemyAbilities[1] + enemyAbilities[2] + enemyAbilities[3] - 4)) / 5;//count the human cleverness attained or the enemies who buffed clever early
        }
        return fight;
    }

}

1
Jestem całkiem pewien, że for(int ability in enemyAbilities){to błąd składniowy - spróbujfor(int ability : enemyAbilities){
Joshua

3

FunkyBob

Pierwszym priorytetem jest przetrwanie, w przeciwnym razie spróbuje znaleźć zdobycz. Ocenia widoczny obszar, aby znaleźć ogólny kierunek z najmniejszymi zagrożeniami lub największą ofiarą. Wydaje się, że podczas moich testów mam około 85-90% współczynnik przeżycia.

package alien;
import planet.Move;

public class FunkyBob extends Alien {
    public void setAbilityPoints(float[] abilities) {
        abilities[0] = 2.5f;
        abilities[1] = 5.5f;
        abilities[3] = 2;
    }

    private int QtyInRange(char[][] fields, int x, int y, int numStepsOut, char specie)
    {
        int count = 0;
        for(int i = numStepsOut * -1; i <= numStepsOut; i++)
            for(int j = numStepsOut * -1; j <= numStepsOut; j++)
                if(fields[x+i][y+j] == specie)
                    count++;
        return count;
    }

    private int AssessSquare(char[][] fields, int x, int y, int visibility){
        int score = 0;

        for(int i = 0; i <= visibility; i++)
        {
            score += (-1000 / (i == 0 ? 0.3 : i)) * QtyInRange(fields, x, y, i, 'A');
            score += (100 / (i == 0 ? 0.3 : i)) * QtyInRange(fields, x, y, i, 'T');
            score += (100 / (i == 0 ? 0.3 : i)) * QtyInRange(fields, x, y, i, 'H');
            score += (100 / (i == 0 ? 0.3 : i)) * QtyInRange(fields, x, y, i, 'E');
            score += (50 / (i == 0 ? 0.3 : i)) * QtyInRange(fields, x, y, i, 'W');
            score += (50 / (i == 0 ? 0.3 : i)) * QtyInRange(fields, x, y, i, 'C');
        }

        return score;
    }

    public Move move(char[][] fields)   {
        int vision = getVisionFieldsCount();
        Move bestMove = Move.STAY;
        int bestMoveScore = AssessSquare(fields, vision, vision, vision - 1);

        for (Move move : Move.values()) {
            int squareScore = AssessSquare(fields, vision + move.getXOffset(), vision + move.getYOffset(), vision - 1);
            if(squareScore > bestMoveScore)
            {
                bestMoveScore = squareScore;
                bestMove = move;
            }

        }
        return bestMove;
    }

    public boolean wantToFight(int[] enemyAbilities)    {
        return ((getCurrentHp() + this.getStrengthLvl()) / 2) >
                ((enemyAbilities[0] * 3) + enemyAbilities[1]);
    }
}

3

FunkyJack

Tylko dla kopnięć, oto kolejny wpis z nieco innym podejściem. Ten koncentruje się tylko na unikaniu walk. To naprawdę nie jest realna strategia, ponieważ w pierwszych kilku rundach jest otoczona przez wrogów. 40% kwadratów jest zajmowanych w pierwszej rundzie, więc średnio natychmiast będziesz przylegał do 3-4 wrogów. Ale zwiększając początkowe puste kwadraty do 12,5 razy w stosunku do gatunku zamiast 2,5 razy w stosunku do gatunku, uzyskuje średni wskaźnik przeżycia wynoszący 98,5%.

package alien;
import planet.Move;

public class FunkyJack extends Alien {
    public void setAbilityPoints(float[] abilities) {
        abilities[0] = 4.5f;
        abilities[1] = 1.5f;
        abilities[3] = 4;
    }

    private int QtyInRange(char[][] fields, int x, int y, int numStepsOut, char specie)
    {
        int count = 0;
        for(int i = numStepsOut * -1; i <= numStepsOut; i++)
            for(int j = numStepsOut * -1; j <= numStepsOut; j++)
                if(fields[x+i][y+j] == specie)
                    count++;
        return count;
    }

    private int AssessSquare(char[][] fields, int x, int y, int visibility, int prevScore){
        int score = 0;
        score += -10000 * QtyInRange(fields, x, y, visibility, 'A');                
        if(visibility > 0)
            score = AssessSquare(fields, x, y, visibility - 1, ((score + prevScore) / 5));
        else
            score += prevScore;

        return score;
    }

    public Move move(char[][] fields)   {
        int vision = getVisionFieldsCount();
        Move bestMove = Move.STAY;
        int bestMoveScore = AssessSquare(fields, vision, vision, vision - 1, 0);

        for (Move move : Move.values()) {
            int squareScore = AssessSquare(fields, vision + move.getXOffset(), vision + move.getYOffset(), vision - 1, 0);
            if(squareScore > bestMoveScore)
            {
                bestMoveScore = squareScore;
                bestMove = move;
            }
        }
        return bestMove;
    }

    public boolean wantToFight(int[] enemyAbilities)    {
        return false;
    }
}

1
98,5% jest ogromne. Nawet moje Predicowards mają średnio około 65% przeżycia. Ha ha. Edycja: Moje Predicowards mają taką samą filozofię jak FunkyJack - po prostu trzymaj się z dala. Mam jednak 10 wizji i 0 statystyk walki.
Mark Gabriel

3

LazyBee

Zacząłem próbować stworzyć sprytną klasę pszczół, która wykorzystywałaby ruchy wzorców i wnioskowanie dedukcyjne, ale potem zasnęłam, więc przemianowałam ją na LazyBee i nazwałam to nocą. Wygląda na to, że radzi sobie całkiem dobrze na moich testach (średnio ~ 1645 z kosmitami na githubie).

package alien;

import planet.Move;
public class LazyBee extends Alien{

    private static final int LIFE = 0;
    private static final int STRENGTH = 1;

    // Ran trials to figure out what stats were doing  best in sims
    // Lazily assumed that:
        // - Defense is negligeble compared to health
        // - Vision doesn't matter if I'm running east all the time
        // - Cleverness will be canceled out because dumb aliens (yum) won't care
            // and smart aliens probably account for it somehow
    public static float DARWINISM = 4.5f;
    public void setAbilityPoints(float[] abilities){
        abilities[LIFE] = DARWINISM;  
        abilities[STRENGTH] = 10f-DARWINISM;  
    }

    // If bananapeel is fine without trying to move cleverly, I probably am too
    public Move move(char[][] fields)
    {
        return Move.EAST; // This was giving me the best score of all arbitrary moves, for some reason
    }

    // inspired by ChooseYourBattles, tried to do some math, not sure if it worked
        // it seemed that Bee was doing better by being more selective
        // not accounting for cleverness because eh
    public boolean wantToFight(int[] enemyAbilities){
        // chance of hit (h) = (1-(1/((50/deflvl)+1)))) = 50/(deflvl+50)
        double my_h = 50.0/(this.getDefenseLvl() + 50), 
                their_h = (50.0 - enemyAbilities[STRENGTH])/50.0;
        // expected damage (d) = h * (strlvl+1)
        double my_d = /* long and thick */ my_h * (this.getStrengthLvl() + 1),
                their_d = their_h * (enemyAbilities[STRENGTH]); 
        // turns to die (t) = currhp / d
        double my_t = (this.getCurrentHp() / their_d),
                their_t = ((enemyAbilities[LIFE] * 5 + 10) / my_d); // Assume they're at full health because eh
        // worth it (w) = i outlast them by a decent number of turns
            // = my_t - their_t > threshold
            // threshold = 4.5
        boolean w = my_t - their_t > 4.5;

        return w;
    }
}

1
Wspaniała robota! Jestem zdumiony, że tak dobrze strzeliłeś twardym kierunkiem.
Michael

@Michael, nie masz pojęcia, jak byłem mile zaskoczony, kiedy się dowiedziałem! Włożyłem wiele wysiłku w kodowanie ruchu, a potem uruchomiłem go przeciwko HOLD jako rodzaj grupy kontrolnej. wtedy zdałem sobie sprawę, że grupa kontrolna kopie tyłek, więc zacząłem eksperymentować z różnymi odcieniami leniwych!
theopher

3

Nowy chłopak

Próbuje zaangażować „łatwe” cele na wczesne rolnictwo. W przeciwnym razie poruszaj się sporadycznie.

package alien;

import planet.Move;

public class NewGuy extends Alien {
    private final static byte LIFE=0, STR=1, DEF=2, VIS=3, CLV=4;

    public void setAbilityPoints(float[] abilities) {
        abilities[LIFE] = 5;
        abilities[STR] = 5;
    }

    public Move move(char[][] fields) {
        // Very rudimentary movement pattern. Tries to engage all "easy" peaceful aliens.
        // Programmer got lazy, so he doesn't run away from danger, decreasing his odds of survival.
        // Afterall, if his species dies, that's one fewer specie that humans have to contend with.

        int vision = getVisionFieldsCount(); //count of fields / middle
        char me = fields[vision][vision]; //middle of fields
        for (Move move : Move.values()) {
            for (int i = 1; i <= vision; i++) { //loop through fields in specific direction
                int fieldX = vision + (i * move.getXOffset());
                int fieldY = vision + (i * move.getYOffset());
                char alienType = fields[fieldX][fieldY];

                if (alienType == 'E' || alienType == 'H' || alienType == 'T' || alienType == 'W') {
                    return move;
                }
            }
        }

        return Move.getRandom();
    }

    public boolean wantToFight(int[] enemyAbilities) {
        if (isWhale(enemyAbilities)) {
            return true;
        } else if (isCow(enemyAbilities)) {
            return false; // Cows hit hard!
        } else if (isTurtle(enemyAbilities)) {
            return true;
        } else if (isEagle(enemyAbilities)) {
            return true;
        } else if (isHuman(enemyAbilities)) {
            if (enemyAbilities[STR] < 3) {
                return true;
            }
        }

        return false;
    }

    public boolean isWhale(int[] enemyAbilities) {
        return enemyAbilities[LIFE] == 10 && totalAbilityPoints(enemyAbilities) == 10;
    }

    public boolean isCow(int[] enemyAbilities) {
        return enemyAbilities[STR] == 10 && totalAbilityPoints(enemyAbilities) == 10;
    }

    public boolean isTurtle(int[] enemyAbilities) {
        return enemyAbilities[DEF] == 10 && totalAbilityPoints(enemyAbilities) == 10;
    }

    public boolean isEagle(int[] enemyAbilities) {
        return enemyAbilities[VIS] == 10 && totalAbilityPoints(enemyAbilities) == 10;
    }

    public boolean isHuman(int[] enemyAbilities) {
        return !(isWhale(enemyAbilities) || isCow(enemyAbilities) || isTurtle(enemyAbilities)) && totalAbilityPoints(enemyAbilities) >= 10;
    }

    public int totalAbilityPoints(int[] enemyAbilities) {
        return enemyAbilities[LIFE] + enemyAbilities[STR] + enemyAbilities[DEF] + enemyAbilities[VIS];
    }
}

Ta zmiennoprzecinkowa return true;wydaje się zbędna ze względu na elsewarunek.
Kyle Kanos

@KyleKanos True. Problem rozwiązany.
FreeAsInBeer

Twój test isHuman () nie wygląda całkiem dobrze. Czy nie znajdzie kosmitów, którzy też się wyrównali?
Nie, że Charles

@Charles Masz rację. Trudno (nie?) Dowiedzieć się, czy wróg jest człowiekiem, czy wyrównywanym kosmitą ze względu na sposób działania mechaniki „sprytności” oraz fakt, że nie możemy określić sprytu podczas zapytania walki. Nawet używając podstawowej matematyki, bardzo prawdopodobne jest, że będzie to świadome przypuszczenie, czy jest to człowiek, czy nie, będzie niedokładne. Chyba zmienię go, żeby uciekał przed ludźmi.
FreeAsInBeer

Twoje testy na isSpecie wyglądają fajnie, ale nawet walka ze zdobyczami, a te testy wkrótce się nie udają ...
CommonGuy

2

Strzec

Kumuluj życie, siłę wzmocnienia i obronę, a następnie pozostań na swoim miejscu. Atakuj tylko, jeśli przeciwnik wydaje się być agresywny (zdefiniowany jako strengthwiększy niż 2):

public class Guard extends Alien{
    public void setAbilityPoints(float[] abilities){
        abilities[0] = 6;  // life
        abilities[1] = 2;  // str
        abilities[2] = 2;  // def
        abilities[3] = 0;  // vis
        abilities[4] = 0;  // clv
    }

    public Move move(char[][] fields){
        return Move.STAY;
    }

    public boolean wantToFight(int[] enemyAbilities){
        return enemyAbilities[1] >= 3;
    }
}

2

Bully Alien

Bully Alien będzie spacerował, ignorując wrogów, dopóki nie znajdzie kogoś słabego do zepsuć.

package alien;

import planet.Move;

public class BullyAlien extends Alien {

    @Override
    public void setAbilityPoints(float[] abilities) {
        abilities[0] = 2;
        abilities[1] = 8;
        abilities[2] = 0;
        abilities[3] = 0;
        abilities[4] = 0;
    }

    @Override
    public Move move(char[][] fields) {
        return Move.getRandom();
    }

    @Override
    public boolean wantToFight(int[] enemyAbilities) {
        return enemyAbilities[1] < 3;
    }           
}

2
Aww, tyraniczny kosmita po prostu chce być przyjaciółmi.
user3334871,

3
@ user3334871 Bardziej jak: „tyraniczny kosmita chce tylko mieć błąd składniowy”
Justin

Czy nie chcesz, aby Tight walczył o umiejętności wroga?
Ingo Bürk

@ IngoBürk To już zrobiło, zanim skomentowałeś
William Barbosa

Musiałem wtedy zbyt długo przewijać nić. :)
Ingo Bürk

2

BlindBully

Nie obchodzi go, kto lub co go otacza, po prostu próbuje zdecydować, czy kosmita, z którym się teraz zmierzy, jest silniejszy czy słabszy od niego i atakuje tych słabszych.

package alien;
import planet.Move;
import java.util.Random;

public class BlindBully extends Alien {

    private final int LIFE = 0;
    private final int STRENGTH = 1;
    private final int DEFENSE = 2;
    private final int VISION = 3;
    private final int CLEVERNESS = 4;

    private Random rand = new Random();

    @Override
    public void setAbilityPoints(float[] abilities) {
        abilities[LIFE] = 6;
        abilities[STRENGTH] = 2;
        abilities[DEFENSE] = 2;
        abilities[VISION] = 0;
        abilities[CLEVERNESS] = 0;
    }

    @Override
    public Move move(char[][] fields) {
        // Go west! To meet interesting people, and kill them
        switch (rand.nextInt(3)) {
            case 0:
                return Move.NORTHWEST;
            case 1:
                return Move.SOUTHWEST;
            default:
                return Move.WEST;
        }
    }

    @Override
    public boolean wantToFight(int[] enemyAbilities) {
        int myFightRating = getLifeLvl() + getStrengthLvl() + getDefenseLvl();
        int enemyFightRating = enemyAbilities[LIFE] + enemyAbilities[STRENGTH] + enemyAbilities[DEFENSE];
        return myFightRating >= enemyFightRating;
    }

}

2

SecretWeapon2

package alien;

import planet.Move;

/**
 * Created by Vaibhav on 02/07/14.
 */
public class SecretWeapon2 extends Alien {

   private final static byte LIFE=0, STR=1, DEF=2, VIS=3, CLV=4;

public void setAbilityPoints(float[] abilities) {
    abilities[LIFE] = 3;
    abilities[STR] = 7;
    abilities[DEF] = 0;
    abilities[VIS] = 0;
    abilities[CLV] = 0;
}

public Move move(char[][] fields)   {
     return Move.getRandom();
}

public boolean wantToFight(int[] enemyAbilities)    {

    return enemyAbilities[1] < 4;
  }
}

Więc to jest najlepsze? haha
justhalf
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.