생존 게임-AlienWar


96

외계인

이 게임은 외계인이 우월한 매우 혼잡 한 행성에서 진행됩니다. 당신의 임무는 자신의 외계인을 만들고 다른 모든 것을 이길 것입니다.

보드

2 차원 보드입니다.
보드 한쪽의 길이는 Math.ceil(sqrt(species * 100 * 2.5))사용 된 보드의 ~ 40 %입니다. 보드는 행성이므로 서쪽의지도에서 벗어나면 동쪽으로 돌아옵니다. 북쪽으로 걸어 가면 남쪽에 있습니다.

능력

지구상의 각 종에는 능력이 있습니다. 여기 있습니다:

이름         혜택 
수명 HP = lifeLVL * 5 (타격 할 때마다 감소, 0 = 사망), 기본 HP = 10
강도 당신의 타격은 [1에서 strengthLVL]의 범위에서 무작위 int를합니다
방어 [0 ~ (50 / DefenseLVL + 1)] 범위에서 int를 임의로 선택 합니다. int == 0 인 경우 다음 공격을 피하십시오
비전은 당신이주는 visionLVL 당신의 비전 주위에 /이 필드를
영리함 다른 외계인에게 보낼 때 [0에서 영리함 LVL / 2]
 범위에서 무작위로 모든 능력을 흐리게합니다 (증가시킵니다)

게임

  • 각 제출마다 100 개의 인스턴스가 있습니다.
  • 인스턴스화 후, 각 외계인은 총 10 개의 능력치를 설정할 수 있습니다. 모든 인스턴스에 대해 다른 지점을 설정할 수 있습니다.
  • 10 점 이상을 설정하면 인스턴스가 종료됩니다.
  • 게임은 1000 라운드로 구성됩니다. 각 라운드 :
    • 모든 외계인은를 통해 이동을 반환해야합니다 move(char[] fields). 여기에는 Move.STAY가 포함됩니다.
    • 필드에 여러 외계인이있는 경우 무작위로 2가 선택됩니다.
      • 둘 다 평화에 동의한다면 (에서 거짓을 반환 wantToFight) 그들은 그들이있는 곳에 머무르고 그렇지 않으면 싸울 것입니다.
      • 외계인 한 명이 현장에 머 무르거나 모두 평화에 동의 할 때까지 반복됩니다.
  • 외계인이 무언가를 죽이면 각 적 능력의 1/5을 얻습니다 . 당첨 된 HP는 2 * enemyLifeLVL 로 재충전됩니다 .

  • 승자는 가장 많은 능력 을 가진 사람입니다 (살아있는 외계인의 능력의 합).

싸움

두 외계인이 "동시에"서로 맞을 것입니다. 즉, 다른 외계인을 죽이면 한 번도 칠 수 있습니다.

회피 : 공격을하기 전에 게임은을 사용하여 공격을 회피 할 수 있는지 계산합니다 rand.nextInt(50 / defenseLvl + 1) == 0. 회피 기술을 계산할 때 DefenseLvl은 50보다 크지 않습니다 (따라서 최대 회피 확률은 50 %입니다).

타격 : 공격을 피하지 않으면 공격을 받고 HP가 감소합니다 rand.nextInt(enemy.getStrengthLvl()) + 1.

싸움은 관련된 외계인 중 하나 또는 둘 다 죽었을 때 끝납니다. 승자가있는 경우 보상을받습니다.

게임 룰

  • 모든 능력의 기본 레벨 (능력 점수를 제공하지 않음)은 1입니다 (기본 HP는 10입니다).
  • 싸우라는 요청을받을 때 보내지는 가치는 생명 (HP가 아님!), 힘, 방어 및 비전 수준입니다.
  • 싸우라는 요청을받을 때 영리함이 전달되지 않습니다.
  • 모든 부동 숫자는 사용 / 전송시 가장 가까운 정수로 ROUNDED되지만 float로 저장 및 증가합니다.
  • 최대 회피 확률은 50 %입니다. 그렇지 않으면 싸움이 끝나지 않을 수 있습니다.

먹이

이미 현장에 5 종이 있습니다. 그들은 먹이이기 때문에, 요청 될 때 싸우지 않기로 선택합니다.

고래 : 레벨 10 생명 유지   
암소 : 레벨 10 강도 랜덤 이동
거북이 : 레벨 10 방어 남쪽 서쪽
독수리 : 레벨 10 비전 필드를 조사하고, 위험을 피하려고합니다      
인간 : Lvl 10 영리 북동

그것들은 W지도에서 첫 글자 (예 : 고래) 로 표시 될 것입니다 ( A공백이있는 에일리언이 있는 빈 칸 ' ').

추가 규칙

  • 반사가 허용되지 않습니다.
  • 다른 외계인과의 대화 (인스턴스 등)는 허용되지 않습니다.
  • 파일이나 데이터베이스와 같은 외부 리소스를 쓰거나 읽을 수 없습니다.
  • Java (버전 1.8) 제출 만 허용됩니다 (Java는 다소 쉬우므로이 게임의 전문가 일 필요는 없습니다).
  • 모든 제출물은 외계인 클래스를 확장해야하며 외계인 패키지에 배치됩니다.
  • 나는 7 월 19 일에 최고의 외계인을 받아 들일 것입니다. 그 날 12:00 UTC에 제출 한 모든 외계인이 테스트됩니다.
  • 이미 많은 외계인이 있기 때문에 사용자 당 최대 3 건의 제출.

외계인의 예

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

}

제어 프로그램

제어 프로그램의 소스 코드는 여기 에서 찾을 수 있습니다 . 최신 런에 포함 된 모든 외계인으로 업데이트되었습니다.

최종 점수 (2014.07.20, 평균 10 게임)

외계인 .PredicatClaw 1635.4
외계인 .LazyBee 1618.8
외계인지도 제작자 LongVisionAlien 1584.6
외계인. 전투를 선택하세요
외계인 벤더 1524.5
외계인 .HerjanAlien 1507.5
외계인. 펑키 밥 1473.1
외계인. 비밀 무기 2 1467.9
외계인 PredicatEyes 1457.1
외계인 기업 외국인 1435.9
외계인 젠틀 거대한 1422.4
외계인 .CropCircleAlien 1321.2
외계인 .VanPelt 1312.7
alien.NewGuy 1270.4
외계인 바나나 껍질 1162.6
외계인. 락 1159.2
외계인 .BullyAlien 1106.3
외계인 .Geoffrey 778.3
외계인. 비밀 무기 754.9
외계인. 비밀 무기 3 752.9
외계인. 펑키 잭 550.3
외계인. 돌 369.4
외계인 암살자 277.8
외계인. Predicoward 170.1
먹이 15Cow
외계인. 모 플링 105.3
외계인 엘리 99.6
외계인 전사 69.7
외계인 사냥꾼 56.3
외계인 관리자 37.6
외계인. 오키나와 라이프 14.2
먹이. 고래 10.5
외계인 게이머 4.5
alien.Randomite 0
외국인 가드 0
먹이. 독수리 0
외계인. 도적 0
alien.WeakestLink 0
alien.Fleer 0   
외계인 생존자 0
외계인. 속도 0
alien.Junkie 0
alien.Coward 0
alien.CleverAlien 0
먹이. 인간 0
alien.BlindBully 0
먹이. 거북이 0
alien.AimlessWanderer 0

14
세 명의 공감, 지구상에서 무엇? 그리고 부정적인 의견이 하나도 보이지 않습니다. 수동적 인 사람들은 이것이 Java로 제한되어 있다는 것을 적극적으로 짜증나게합니까?
마틴 엔더

6
@ m.buettner 내 downvote는 Java 인 godawfulness에 대한 제한입니다 (지금까지 만들어진 가장 좋은 언어로 제한되었지만 1 언어로 제한하기 위해 여전히 downvote했습니다). downvotes가 무엇인지 분명하기 때문에 의견을 추가 할 때 요점을 보지 못했습니다.
Gareth

6
흠, 여기에 여러 가지 감정이 있습니다
Mr. Alien

5
@ user3334871 17 개의 답변을받은 후에 규칙을 변경하는 것은 좋은 생각이 아니라고 생각합니다. 우리 중 소수만이 프로 게임 디자이너이기 때문에 자체 제작 된 KotH는 거의 균형 조정 문제가있을 수 있지만 가능한 전략의 공간을 탐색하는 것이 여전히 재미 있다면 (답변으로 판단하면 공감대와 별), 나는 그것이 큰 문제라고 생각하지 않습니다.
마틴 엔더

5
@Manu 수학적으로 보드 랩이 어떻게 오도되는지에 대한 설명을 수학적으로 기울였습니다. 당신은 그것이 행성이고 동쪽 / 서부를 감싸고 있다고 말합니다. 실제로 북쪽 / 남쪽을 감싸고 있다는 것을 나타내는 것은 없습니다. 사실, 그것은 기술적으로 더 이상 구체가 아니라 원환 체입니다 : kotaku.com/classic-jrpg-worlds-are-actually-donuts-1239882216 . 또한 세계지도의 상단 (북극)에서 "떨어져"나갈 때 아래쪽 (남극)에 나타나지 않는다는 것을 알면 알 수 있습니다. 따라서 마이클의 제안은 분명히 유효합니다.
마틴 엔더

답변:


11

PredicatClaw (이전)

이 고양이 외계인은 당신을 완전히 삼킬 것입니다 (아마도 먼저 씹을 것입니다) ... 예측 알고리즘에 따라 약해 보인다면.

다른 것보다 치열한 발톱과 송곳니가있는 Predicats 품종.

편집 : 새로운 목표 우선 순위

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
제길! 그 predicats는 맹렬합니다! 우리 둘 다 같은 wantToFight알고리즘을 사용했습니다.
James_pic

@ James_pic, 나는 좋은 마음이 똑같이 생각하는 것을 본다. : D
Mark Gabriel

27

매니저

여기 관리자가 있습니다. 당연히 영리함은 0이며 태양이 비치지 않는 곳으로 가려고 항상 노력합니다. 그리고 물론 그는 약한 사람들과 싸울 것이며 문제를 피하는 데 매우 뛰어납니다.

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 : P
apnorton

6
내가 그 의견을 읽을 때마다 ( "확실히하기 위해") 웃어야한다 : -D
Matthias

웃긴, 나는 이것을 읽고 있었다 : blog.codinghorror.com/i-shall-call-it-somethingmanager
11684

@ 11684 괜찮은 개발자는 물론 알고 있지만, 제 경우에는 실제로 관리자를 의미합니다.)
Ingo Bürk

18

지도 제작 LongVisionAlien

이 외계인은 잠재적 인 승리를 거두는 외계인을 생산하려는 나의 시도 중 하나의 변형 된 변형입니다.

초기 5x5 비전으로 주변 지역의 내부 맵을 구축하여 탁월한 적 회피 능력을 제공합니다.

100 라운드를 테스트 할 때 평균적으로 다른 모든 외계인보다 먼저 몰래 빠져 나옵니다. (2014 년 7 월 7 일)

격퇴 / 유치 필드 효과를 보여주는 업데이트 된 GIF

시뮬레이션의 애니메이션 GIF를 생성하도록 게임 코드를 수정했습니다. 여기에서 그러한 시뮬레이션을 볼 수 있습니다

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

 }

먹이 미래 예측을 추가하고 고래가 공격받을 가능성이 있도록 업데이트
Moogie

4
예이! 마지막으로 외계인은 힘과 삶뿐만 아니라 비전에도 의지하고 있습니다. :)
CommonGuy

3
일관된 연기자 인 외계인을 얻는 것은 매우 어려웠습니다! 다른 최고 참가자는 대부분 같은 아이디어를 따릅니다. 외계인을 피하고, 먹이를 공격하고, 거의 승리를 보장하는 싸움 만 시작하십시오. 이 외계인은 같은 아이디어를 따르지만 외계인을 피하는 것이 좋습니다. 전투를 잃을 경우 더 많은 능력을 얻는 것이 "비싸기"때문에 가장 작은 우위를 점합니다.
Moogie

다른 이국적인 아이디어를 시도했지만 정보가 충분하지 않습니다. 즉,지도 크기, 외계인 수 등
Moogie

잘 했어! 나도 정보의 부족에 약간 좌절했다 – 과거로부터 추가 정보를 추출하는 것은 창조적이다.
베니

15

전투를 선택하십시오

이 외계인은 다른 외계인과 도망 치지 만 먹이를 향해 달려갑니다 (외계인에게 가져 가지 않는 한).

유전자 알고리즘을 사용하여 시작 값을 선택할 수있었습니다. 결과는 우리가 초기 타자를 통과하기 위해 힘과 생명에 의존해야 함을 시사합니다. 비전은 나중에 유용하지만, 우리는 정복당한 적들로부터 그것을 얻을 수 있습니다.

우리는 편안하게 이길 수 있다고 생각하는 전투에만 싸 웁니다. 우리는 외계인을 죽이는 데 걸리는 움직임의 수, 적을 죽이는 데 걸리는 횟수를 추정하고, "두 번 정도 어려운"전투에만 참여합니다. 우리의 상대.

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

자신의 유전자 알고리즘 / 번식 프로그램을 실행하려면 이 목적을 위해 제어 프로그램의 사본을 얻었습니다 .


이것이 checkAbilitesOk메소드 의 검사를 어떻게 우회 합니까?
FreeAsInBeer

checkAbilitiesOk배열의 부동 소수점 수가 10.0이되는지 확인합니다. 그러나 게임 로직에서 float 값은 int로 반올림되고 Java는 0.5로 올림됩니다.
James_pic

@justhalf는 여전히 10 점을 설정하며 지능적으로 배포됩니다.
CommonGuy

1
나는 그것이 내 생각이 아니라고 말해야한다-나는 그것을 PredicatClaw에서 빌렸다
James_pic

1
아주 좋아요 당신의 통계 상수는 아마도 내 것보다 좋을 것이고 당신의 wantToFight는 확실히 더 똑똑합니다. :)
Benny

12

정키

이 외계인은 무언가에 중독되어 있습니다 . 그는 매우 불쾌한 수정으로 전쟁을 시작합니다.

그의 픽스가 강력 fix > 3해지면서 ( ) 그는 유쾌하게 그의 스터 포에 앉아 만족하고있다.

그러나 일단 그의 고침이 마모되기 시작하면 ( fix <= 3) 무슨 일이 있었는지 알아 내려고 눈에 띄지 않는 방향으로 넘어지기 시작합니다. 싸울 것을 요청하면, 그는 조심스러워하고 그가 이길 수 있다고 생각할 때만 싸운다.

자신의 중독자 인 그의 고침이 사라지면 악순환을 다시 시작해야합니다.

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

&& fix > 0중복으로 인해 제거하는 것이 안전하다고 확신합니다 .
Timtech

10

바나나 껍질

약간의 비난이 필요한 사람들 만 트립하려고합니다. 패배해도 더 건강 해지지는 않습니다.

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

[0]은 건강이 아니라 생명이므로 100은 510 HP (또는 이미 입은 피해에 따라 더 적을 것임)이지만 외계인이
그보다 높은지를

@Gigala 좋은 생각입니다. 조금 변경했습니다.
Timtech

9

반 펠트

Jumanji의 사냥꾼. 그는 다 치지 않았을 때 사냥을하고, 그가있을 때를 피하고 죽일 수있는 것에 대한 적절한 판단을합니다. 바나나 껍질은 계속 그를 움켜 쥐었지만 몇 가지 새로운 트릭을 가르쳤다.

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

}

바나나 껍질을 피하는 법을 배웠습니까? : P
Timtech

8

오키나와 생활

내가 마지막으로 서있는 것은 당연합니다.

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

사냥꾼

나는 또한 독수리의 움직임을 훔쳤습니다. 단지 그는 다른 외계인 외에 모든 것을 향해 가고 싶어합니다. 가능한 한 많은 먹이를 사냥하고 농사를 짓고, 이길 수있는 좋은 기회가있을 때만 싸운다.

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

그것은 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
    }
}

그렇습니다. 부정 행위를하는 것은 명백한 일이지만, 규칙을 훑어 보는 것입니다. 게터 planet.Specie가 최종적으로 만들어지면이 허점은 닫힙니다.


4
아뇨! 나는 무언가를 잊었다는 것을 알고 있었다 ... 나는 허점을 닫고 +1;)
CommonGuy

나는이 답변이 나의 다른, 더 오래되고, 현재 이기고있는, 엔트리보다 더 많은 찬사를 받았음을 다소 실망했다.
James_pic

7

나는 그것이 약하고 "영리한"사람들 만 공격한다고 생각합니다.

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
그의 적들이 전투에서 승리하여 버프를 받기 시작하면 Rock이 얼마나 오래 지속 될지 확신 할 수 없습니다. 그래도 좋아 보인다.
카일 카 노스

@KyleKanos 이해합니다; 그러나 나는 영리하지 않은 한 대부분의 먹이 / 외계인과 싸울 것이라고 생각합니다. 이것도 그에게 버프를주지 않습니까?
Timtech

이제 내 의견을 되돌아 보면, 내가 말하고 싶은 것이 전혀 아니라고 생각합니다. 나는 적들이 레벨로 버프를 시작할 때 wantToFight조건이 제공되지 않을 것이라고 말하고 싶었습니다 true. 당신은 빨리 강한 평화 주의자로 변할 것입니다.
Kyle Kanos

@KyleKanos 아, 알겠습니다. 조금 변경했습니다.
Timtech

6

모 플링

다른 이름을 생각할 수 없었던이 녀석은 자신의 능력에 10 점을 무작위로 분배합니다. 거의 오키나와 생활 (당신의 노력에 대한 thx)처럼 움직이고 그의 힘이 적의 힘보다 큰 경우에만 싸우고 싶어합니다.

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];
    }

}

아, 맞아요 닫는 괄호는이 도전을 죽였습니다 (그 때문에 광산을 몇 번 편집해야했습니다). 나는 지금 그것을보고, 맞습니다. 지적 해 주셔서 감사합니다!
user3334871

@ user3334871 나는 당신의 제안으로 테스트했지만 내 모 폴링은 더 잘 살아 남았습니다 : D
Sikorski

@Sikorski 글쎄, 내가 도울 수있어서 기쁘다.
user3334871

@Sikorski 나는 단지 모든 움직임이 위험한 경우 퍼팅을 유지하는 것이 가장 위험한 움직임을 만드는 것보다 더 안전하다는 것을 의미한다고 생각합니다.
마틴 엔더

"헤드 라이트의 사슴"전략이 마음에 들어요.
user3334871

6

벤더 "벤딩"로드리게스

나는 코드 주석에 상당히 자유로웠다. 상황에 따라 읽을 수 있지만 아래에 스 니펫을 추가하겠습니다.

요약

이 외계인은 겁쟁이 인간을 죽이는 것이 쉽고 지각 된 힘을 부풀려 다른 외계인을 조종하게 만드는 원칙에 따라 작동합니다.

고래와 독수리도 구부릴 수 있습니다. =)

운동

공격하기에 흥미로운 것을 발견하지 않으면 서쪽이나 남쪽으로 이동하십시오.

  • 움직임이 알려진 먹이의 경우, 우리는 그들이 다음 차례가 될 광장에 바람직 함을 추가합니다.
  • 우리가 그렇지 않은 사람들을 위해, 우리는 그들이 다음 턴으로 이동할 수있는 사각형들 사이에 그들의 타당성을 동등하게 나눕니다.
    • 외계인은 바나나 껍질 때문에 기존 광장에 부정적인 영향을줍니다.

근처에서 흥미로운 것을 찾지 못하면 남쪽, 서쪽 또는 남서쪽이 더 유망한 옵션인지 알아보십시오.

하나 또는 두 개의 우세한 방향을 선택하면 주어진 벤더가 동포를 만나게 될 가능성이 줄어들고 주요 먹이에 대한 방향 카운터를 선택하면 모든 인간을 더 빨리 죽일 수 있습니다.

James_pic의 유전자 알고리즘으로 선호도 행렬의 숫자를 조정하여 더 나은 결과를 얻을 수는 있지만 그 방법을 모르겠습니다.

공격

벤더는 주로 먹이를 목표로하고 있으며, 그와 꽤 보수적입니다 wantToFight. 당신이 영리한 인간을 다루고 있다고 생각 하지 않으면 힘 4를 넘는 사람은 모두 기피 됩니다 . 영리한 인류는 외계인보다 더 많은 국방과 비전을 가짐으로써 시연됩니다. 그것은 벤더 자신의 능력 통계에 의해 인스턴스 과정에서 조정되어 거북이와 독수리를 죽이는 외계인을 설명합니다.

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

증가 된 변수가 직접 비교되는 것이 아니고 정수 오버플로 래핑을 통해 무한 재귀를 피하는 루프 논리 오류가 있음을 알았습니다. 답을 업데이트 해 주시면 좋겠습니다. (시뮬레이션이 때때로 일시 중지되는 원인이 됨)
Moogie

@Moogie Heh. 그래서 우연히 잘하고 있었나요? 찾아 주셔서 감사합니다.
Michael

나는 모든 것을 살펴보고 몇 가지 더 많은 문제를 해결했습니다.
Michael

5

전사

이것은 단지 싸우고 싶어하는 매우 단순한 마음의 외계인입니다. 그는 적이나 주변 환경에 관심이 없습니다.

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.
    }
}

당신은 이제 자신의 외계인을 시험 할 누군가가 있습니다.


4

겁쟁이

나는 기본적으로 독수리의 움직임 패턴을 훔쳐 공격 당할 경우 위험과 누적 방어를 피합니다.

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

내가 틀렸다면 바로 고쳐주십시오. 그러나 모든 능력의 기준점이 1이므로 퍼팅 vision=1만으로 충분합니까?
justhalf

@ justhalf : 코드를 간단히 읽었을 때 setAbilityPoints1의 값 을 덮어 쓴 것으로 보였지만 더 자세히 보면 정확하다고 생각합니다. 더 큰 시력으로 더 멀리보고 위험을 피할 수 있기 때문에 그대로 두겠습니다. 그러나 캐치에 감사드립니다.
Kyle Kanos

또한 math.round는 항상 0.5로 반올림되므로 홀수 인 경우 추가 시력을 얻을 수 있습니다
Andreas

@Manu : 나는 도망 가기를 향상시키기 위해 비전과 방어의 가치를 바꿨습니다.
Kyle Kanos

4

도망자

공포

묵시

RUUUUUUUUUUN

AAAAAAAAAAAAAAAAAAAAAAAAA


가능할 때마다 전투를 피하십시오.

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

이 이름을 다른 이름으로 지정해야합니다. codegolf.stackexchange.com/a/32787/9498
Justin

2
@Quincunx 그것은 우연의 일치, 그 하나를 보지 못했습니다 ...
stommestack

죄송합니다. 두 답변 모두 Eagle에서 복사 한 것입니다. 당신은 다른 답변을 복사하지 않았습니다, 나는 단지 충분히주의 깊게 읽지 않았습니다. 그러나 다른 이름이 적합합니다.
Justin

1
이름이 변경되었습니다!
stommestack

2
이름이 Rincewind 여야합니다.
Magus

4

프리 디코 워드 (퍼)

지금까지 두려움에 사로 잡히고 어려움에서 벗어나는 일종의 Predicats. 그들의 생활 방식으로 인해, 그들은 본능적으로 싸우지 않았지만, 그들의 인식은 예외적입니다.

그들의 종류는 동료 Predicats에 의해 혐오입니다.

편집 : 맨해튼 거리 대신 가중 거리로 변경

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
좋아 보인다! 하지만 당신의 인쇄물을 꺼내주세요
CommonGuy

아, 나는 인쇄 진술서를 떠났어? 나중에 변경하겠습니다. 하하. 게다가 이것은 아직 마지막이 아닙니다. 지금, Predicoward는 짜증나. 그의 외계인 회피 알고리즘은 곧 개선 될 것입니다. :) 편집 : 인쇄 설명을 제거 한 사람에게 감사드립니다. : D (Jop?)
Mark Gabriel

편집 : Predicowards는 어제 이전의 성가신 작은 비 경쟁적 predicowards보다 도망가는 것이 훨씬 좋습니다. > :)
Mark Gabriel

퀴즈 : 이것은 내가 가장 좋아하는 Predicat <3
Mark Gabriel

4

PredicatEyes (meow)

상대방보다 시력이 강한 Predicats로 적을 잘 들어 올릴 수 있습니다.

편집 : 새로운 목표 우선 순위

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

미스터리 서클 외계인

원은 무한정 시계 방향으로 싸우고 싶지 않으며, 농작물 cirles를 만드는 것이 행복합니다. 그러나 당신이 정말로 싸우고 싶다면, 그는 당신에게서 쓰레기를 이길 것입니다.

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
Move를 반복하면 더 깨끗합니다.
찰스

4
왜 모든 getI()것을 바꾸고 i단순히 제거하지 getI()않습니까? 당신은 또한 변경 될 수 있습니다 setI(int i)this.i = i % 8;, 당신이 아니라 한 곳에서 그것을 사용하기 때문에, 단지 각 호출을 변경하려면 setI(getI() + 1)i = (i + 1) % 8;
저스틴

3

영리한

영리한 외계인은 전적으로 자신의 지혜에 의존합니다. 그는 무작위로 걸어 다니며 무작위로 싸우기로 결정합니다. 그는 운이 좋으면 적을 능가하기를 희망한다. (구문 오류가 있으면 저를 용서하십시오, 나는 자바 사람이 아닙니다)

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? 왜 안돼 (tmp == 1) == true ? true : false? ;) (힌트 : 그것은 단지 동일합니다 tmp == 1.)
Martin Ender

3

도적

다른 사람들이 말했듯이, 나는 독수리의 움직임을 어느 정도 사용하고 있습니다. 승리하는 외계인을 만들려고 노력하기보다는 (내가 생각한 최고의 아이디어는 이미 D :), 나는 어떤 성격을 가진 외계인을 만들기로 결정했습니다! 저의 외계인은 외계인의 전쟁에 대해 잊어 버린 고용 된 총이며,이 지구상에서만 그의 죽음의 빚 빚에서 빠져 나온 더러운 사람을 사냥 할 수 있습니다. 나의 외계인은 행성을 찾아서 인간을 찾고, 사람을 죽이지 않고 계속해서 인간 뒤를 따라갈 것입니다. 그 근처에 외계인이 보이면, 그는 인간을 빨리 죽이려고 노력하고, 완성 된 임무에서 "그의 옆에 행운"으로이 새로운 원수를 대면 할 것입니다.

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

이 코드는 내가 인간을 향해 질주해야한다는 생각에 중심을두고 있습니다. 그를 때리고 난 후에 남서쪽으로 돌아 다니며 거북이를 찾을 것이다.

편집 : 아, 그리고 거북이에 관해서는 ... 내 외계인은 그들을 좋아하지 않으므로 완전히 캐논입니다.


내가 거북이를 향해 질주 할 수 있다는 것을 깨달았습니다. 누가 높은 닷지 불량을 좋아하지 않습니까?
user3334871

2
Java 8의 if block 부분에서 int를 부울로 직접 사용하고 있습니까? 내 컴퓨터 (Java 7)에서 전혀 컴파일되지 않기 때문입니다. 힌트 : humanPresent
Sikorski

내가 아는 한, Java 경험은 주로 스크립트 및 대학 수준의 수업으로 제한되었습니다. 나는 단지 비교를 할 것입니다. 그래서 모든 것이 복숭아입니다. 고마워요!
user3334871

또한 @Sikorski, 테스트를 실행하기 위해 자체 main 또는 init 함수를 작성 했습니까? 아니면 제공된 코드를 통해서만 수행 할 수 있습니까? 맹세합니다. 진정한 Java 환경에서 코딩 한 지 너무 오래되어 Java 코드 실행 규칙을 잊었습니다. (
user3334871

OP가 github 링크에서 제공 한 코드를 다운로드하고 다른 클래스를 추가하고 테스트를 시작하십시오. 오, 당신은 행성 클래스에서 각 외국인 클래스에 대한 항목을 추가해야합니다.
Sikorski

3

충돌이 발생하여 생존하려고했습니다. 민첩성과 지능으로 생존하며 전투를 시작할 가치가 있는지 신중하게 고려하여 모든 흉터를 계산합니다. 생존자는 단지 사냥을 시작하고 큰 무기를 가진 다른 외계인을 피하려고 노력하지만 더 대담 해지면 그들을 따라 갈 수 있습니다. 실제로 진행되면 더 이상 누가 직면하고 있는지 신경 쓰지 않습니다.

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
나는 그것이 for(int ability in enemyAbilities){구문 오류 라는 것을 확신합니다 -시도for(int ability : enemyAbilities){
Joshua

3

펑키 밥

우선 순위는 생존입니다. 그렇지 않으면 먹이를 찾으려고 노력할 것입니다. 가시 영역을 평가하여 위협이 가장 적거나 가장 많은 먹이로 일반적인 방향을 찾습니다. 테스트 중에 생존율이 약 85-90 % 인 것 같습니다.

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

펑키 잭

발차기를 위해 약간 다른 접근 방식을 가진 또 다른 항목이 있습니다. 이것은 싸움을 피하는 데에만 집중됩니다. 이것은 처음 몇 라운드에서 적들에게 둘러싸여 있기 때문에 실제로 실행 가능한 전략이 아닙니다. 첫 번째 라운드에서 40 %의 사각형이 점령되므로 평균적으로 3-4 명의 적에게 즉시 인접합니다. 그러나 초기 빈 사각형을 종의 2.5 배가 아닌 12.5 배로 늘리면 평균 생존율은 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 %가 엄청납니다. 나의 Predicowards조차도 평균 약 65 %의 생존율을 얻습니다. 하하. 편집 : 내 Predicowards는 FunkyJack과 같은 철학을 가지고 있습니다. 그래도 비전은 10이고 전투 능력은 0입니다.
Mark Gabriel

3

게으른

나는 패턴 움직임과 연역적 추론을 사용하는 영리한 Bee 클래스를 만들기 시작했지만 졸려서 LazyBee로 이름을 바꾸고 밤이라고 불렀습니다. 그는 실제로 내 테스트 (github의 외계인과 ~ 1645의 평균)에서 꽤 잘 수행하는 것 같습니다.

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
잘했습니다! 나는 당신이 하드 코딩 된 방향으로 너무 잘 득점하는 것에 놀랐습니다.
Michael

@ 마이클 당신은 내가 발견했을 때 얼마나 즐겁게 놀랐는지 전혀 모른다! 나는 운동 코드에 많은 노력을 기울인 다음 일종의 제어 그룹으로 HOLD에 대해 실행했습니다. 그런 다음 컨트롤 그룹이 엉덩이를 걷어차 고 있다는 것을 깨달았습니다.
thefistopher

3

뉴 가이

조기 농업을 위해 "쉬운"목표를 달성하려고합니다. 그렇지 않으면 산발적으로 움직입니다.

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];
    }
}

그 플로팅 return true;라인은 else조건 으로 인해 불필요한 것처럼 보입니다 .
Kyle Kanos

@KyleKanos True입니다. 문제가 해결되었습니다.
FreeAsInBeer

isHuman () 테스트가 제대로 보이지 않습니다. 레벨링 한 외계인도 찾을 수 없습니까?
아니 찰스

@ 찰스 당신이 맞아요. '영리함'메카닉의 작동 방식과 전투 쿼리 중에 영리함을 판단 할 수 없다는 사실 때문에 적이 인간인지, 또는 레벨이 높은 외계인인지 알아내는 것은 어렵습니다 (불가능합니까?). 기본적인 수학을 사용하더라도, 그것이 인간인지 아닌지에 대한 교육적인 추측 일 가능성이 큽니다. 나는 그를 인간으로부터 도망 치도록 바꿀 것이라고 생각합니다.
FreeAsInBeer

isSpecie 테스트는 멋져 보이지만 심지어 먹이 싸움과 그 테스트는 곧 실패 할 것입니다 ...
CommonGuy

2

가드

수명, 버프 강도 및 방어력을 쌓은 다음 계속 유지하십시오. 상대가 공격적인 것처럼 보이는 경우에만 공격하십시오 ( strength2보다 큰 것으로 정의 됨 ).

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

깡패 외계인

괴롭히는 외계인은 엉망인 누군가를 찾을 때까지 적을 무시하고 돌아 다닐 것입니다.

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
아, 깡패 외계인은 친구가되고 싶어합니다.
user3334871

3
@ user3334871 더보기 : "깡패 외계인은 구문 오류를 원합니다"
Justin

적의 능력을보고 싸우고 싶지 않아야합니까?
Ingo Bürk

@ IngoBürk 그것은 당신이 코멘트 할 때 이미 이미
윌리엄 Barbosa

스레드를 스크롤하는 데 너무 오래 걸렸을 것입니다. :)
Ingo Bürk

2

블라인드

주변에있는 사람이나 주위를 신경 쓰지 말고 지금 당면한 외계인이 자신보다 강하거나 약한지를 결정하고 약한 사람들을 공격하십시오.

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

이게 최고예요? haha
justhalf
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.