Survival Game - AlienWar

96

49

AlienWar

This game takes place in a very crowded planet where aliens are the superior race. Your task is to create your own alien and beat all other.

The Board

It is a 2 dimensional board.
The length of one side of the board is Math.ceil(sqrt(species * 100 * 2.5)) = ~40% of board used. The board is a planet, so if you walk out of the map in the west, you come back in the east. If you walk out in the north, you will find yourself in the south.

Abilities

Each species on the planet has abilities. Here they are:

Name        Benefit
life        HP = lifeLVL * 5 (reduces with every hit you take, 0 = dead), base HP = 10
strength    Your hits do a random int in range [1 to strengthLVL] damage
defense     Randomly select int in range [0 to (50 / defenseLVL + 1)], if int == 0 then dodge next attack
vision      Gives you visionLVL/2 fields around you vision
cleverness  Blurs (increases) every ability randomly in range [0 to clevernessLVL/2] when sending to other aliens

The Game

  • There will be 100 instances of each submission.
  • After instancing, each alien can set 10 ability points in total. You can set different points for every instance.
  • If you set more than 10 points, the instance dies.
  • A game consists of 1000 rounds. Each round:
    • Every alien has to return a move via move(char[] fields). This includes Move.STAY.
    • If several aliens are on a field, 2 will be randomly selected:
      • If both agree on peace (return false in wantToFight) they will stay where they are, else they will fight.
      • This loops until only one alien stays on a field or all agree on peace.
  • If an alien kills something, he gets 1/5 of each of his enemies abilities. The winners HP will be refilled with 2*enemyLifeLVL.

  • Winner is the one with the most abilities (sum of abilities of living aliens).

Fights

Both aliens will hit each other "at the same time", this means if you kill the other alien, he still can hit you one time.

Dodging: Before you get hit, the game will calculate if you can dodge the attack by using rand.nextInt(50 / defenseLvl + 1) == 0. defenseLvl will never be greater than 50 when calculating your dodge-skills (hence maximum dodge-chance is 50%).

Hitting: If you don't dodge the attack, you will get hit and your HP will be reduced by rand.nextInt(enemy.getStrengthLvl()) + 1.

A fight ends when either one or both alien involved are dead. The winner, if one exists, gets the reward.

Gamerules

  • Base level for every ability (without giving any ability points) is 1 (base HP is 10).
  • The values sent when asked to fight are life (not HP!), strength, defense and vision-levels.
  • Cleverness is NOT sent when asked to fight.
  • All floating numbers will be ROUNDED to nearest integer when using/sending them, but stored and increased as float.
  • Maximum dodge-chance is 50%. Otherwise fights may never terminate.

The Prey

There are 5 species which are already on the field. Since they are prey, they choose not to fight when asked to.

Whale:       lvl 10 life            Stays   
Cow:         lvl 10 strength        Random move
Turtle:      lvl 10 defense         South west
Eagle:       lvl 10 vision          Examines fields, tries to avoid danger      
Human:       lvl 10 cleverness      North east

They will be represented with their first letter (i.e. W for whale) in the map (Aliens with A, empty fields with a whitespace ' ').

Additional Rules

  • Reflection is disallowed.
  • Interacting (instancing etc.) with other aliens is disallowed.
  • Writing/Reading external resources like files or databases is also disallowed.
  • Only Java (version 1.8) submissions allowed (Java is rather easy, and you don't have to be an expert for this game).
  • All submissions must extend the alien-class and will be placed in the alien-package.
  • I will accept the best alien on 19th of July. All aliens submitted by 12:00 UTC that day will be tested.
  • Maximum 3 submissions per user since there are already very many aliens.

Example of an alien

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

}

Control program

Source code for the control program can be found here. Now updated with all aliens included in the latest run.

Final scores (20.07.2014, average of 10 games)

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.9
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
prey.Cow                            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
prey.Whale                          10.5
alien.Gamer                         4.5
alien.Randomite                     0
alien.Guard                         0
prey.Eagle                          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
prey.Human                          0
alien.BlindBully                    0
prey.Turtle                         0
alien.AimlessWanderer               0

CommonGuy

Posted 2014-07-01T16:17:41.640

Reputation: 4 684

How do fights work? That should be extracted from the control program and included here. – Justin – 2014-07-01T17:33:26.793

3@Quincunx added a fight section – CommonGuy – 2014-07-01T18:05:58.277

What about other JVM languages? – Not that Charles – 2014-07-01T18:48:16.800

2@Charles Please no. I don't want to spend my weekend downloading several compilers... Like I said, java isn't that complicated, maybe you can learn some things when try it ;) – CommonGuy – 2014-07-01T18:52:40.090

1To be fair, I don't know jack about Java but I still understood enough to create a bot. – Kyle Kanos – 2014-07-01T19:19:44.553

1@Manu Fair. I know Java. I wanted to learn something :) Anyway, Java's fine. What version? – Not that Charles – 2014-07-01T19:23:20.027

@Charles Please use 1.7 or maybe 1.8 if you want – CommonGuy – 2014-07-01T19:25:01.990

@Manu even if we provide the binary .class files ourselves? (Meaning you don't have to compile them.) – AJMansfield – 2014-07-01T20:48:36.507

@AJMansfield, you can always write in another language and decompile. – Peter Taylor – 2014-07-01T20:55:10.553

2Are you sure you don't want to upgrade to Java 8? Java 8 has all sorts of fun things you can do. Join the fun! – Justin – 2014-07-01T23:08:56.660

@Quincunx Ok, I join the fun side! – CommonGuy – 2014-07-02T05:01:06.833

1

^^ Come to the Fun side. We have cookies

– Justin – 2014-07-02T06:15:38.830

14Three downvotes, what on earth? And I don't see a single negative comment. Are people that passive aggressively annoyed that this is limited to Java? – Martin Ender – 2014-07-02T09:11:56.013

2Just build your own damn compiler from C or whatever to Java if you have a problem with the language choice. – Pierre Arlaud – 2014-07-02T09:40:03.327

You know, I'm conflicted. I see an error with someone's code, and it's pretty funny. Should I point it out to them if this is a competition? – user3334871 – 2014-07-02T12:24:45.287

@user3334871 Yes, just add a comment to their answer :) – CommonGuy – 2014-07-02T12:27:48.220

@Manu alright, but I won't just come out and say the error, but I'll hint at it :) – user3334871 – 2014-07-02T12:32:11.937

6@m.buettner My downvote is for the limitation to the godawfulness that is Java (though if it was limited to the nicest language ever created I'd still downvote it for limiting it to 1 language). I didn't see the point in adding a comment since it was obvious what the downvotes would be for. – Gareth – 2014-07-02T14:41:13.113

1Well, I don't care... What are 3 downvotes against 30 upvotes? :) – CommonGuy – 2014-07-02T14:47:18.233

Just a question, the winner will be decided in a single run? Or how many will be? – BrunoJ – 2014-07-02T14:47:45.600

1@BrunoJ 5 or more runs, then the average of each run. – CommonGuy – 2014-07-02T15:45:11.720

Here's one reason to use Java 8: I changed your removeDeadSpecies method to one line: speciesList.removeIf((alien) -> alien.isDead()); – Justin – 2014-07-02T17:34:22.357

1@Gareth I think I'll release a KoTH that restricts to C++, then make something to allow other languages (within a list of languages). There are so many KoTH that are restricted to only Java. – Justin – 2014-07-02T17:35:48.853

1@Quincunx Or just use a member reference: speciesList.removeIf(Alien::isDead); – Ypnypn – 2014-07-02T20:47:30.223

@Ypnypn Except you'd need to do speciesList.removeIf(Species::isDead);. I just named it alien because saying that the species is dead makes it look like extinction. – Justin – 2014-07-03T05:16:54.950

You know, after testing out my alien with a couple of configurations, some of the abilities are almost downright pointless. The warrior alien, who would be the most generic, has been doing the best in all of my trial runs. At first, my alien had a broad spread of it's abilities set out, but it does better when I just give it a dump stat, and remove things like dodge and cleverness. Maybe a little re-balance of the various abilities is in order? – user3334871 – 2014-07-03T07:01:23.417

How does the cleverness work? So in each turn it blurs all aliens within its vision permanently? – justhalf – 2014-07-03T09:03:08.927

@justhalf it blurs the abilities before fighting (when calling wantToFight(int[] enemyAbilities)). – CommonGuy – 2014-07-03T09:04:20.607

Oh, so it's increasing its own abilities for each fight, roger that. – justhalf – 2014-07-03T09:07:15.307

Also how does the base point of 1 work? If I set vision=1 will I have a total vision of 2? – justhalf – 2014-07-03T09:07:58.610

@justhalf Not increasing (the abilites of the alien don't change), it is just to confuse the enemy species. Yes, and setting vision to 0 would result in a total of 1 vision. – CommonGuy – 2014-07-03T09:09:30.687

I see, so cleverness is to deceive other aliens, roger that. – justhalf – 2014-07-03T09:12:13.247

6Hmmm, am having mixed feelings here – Mr. Alien – 2014-07-03T09:15:33.573

5@user3334871 I don't think changing any of the rules after 17 answers are in (and potentially a dozen more people working on submissions) is a good idea. Since only the fewest of us here (if any) are professional game designers, pretty much any self-made KotH may have some balancing issues - but if exploring the space of possible strategies is still fun (which apparently it is, judging by answers, upvotes and stars), I don't think it's much of a problem. – Martin Ender – 2014-07-03T09:17:25.477

Is there a leaderboard of the current submissions? – Fractional – 2014-07-03T10:06:47.997

1@RedSirius Soon. – CommonGuy – 2014-07-03T10:11:51.773

What does "Reflection is disallowed" exactly mean?. Sorry my main language is not english :) – Gigala – 2014-07-03T11:01:58.573

@Gigala Don't use the java reflection API (google "java reflection" ;) – CommonGuy – 2014-07-03T11:12:34.903

1

@Manu http://xkcd.com/541/

– Martin Ender – 2014-07-03T11:19:30.257

@m.buettner I changed it more than 3 times but this one looks better :D – CommonGuy – 2014-07-03T11:22:45.043

@Manu Alright thanks, im new to Java but will still try to get something together for this contest :P – Gigala – 2014-07-03T12:55:50.257

I think you might want to change damage a bit: Not investing in strength is basically the same as investing 1 point. Perhaps strengthlvl+1 as maximum damage? – Andreas – 2014-07-03T13:39:56.360

@Gareth The control program is written in a certain language so of course only 1 language can be allowed. What's wrong with Java? It's my favorite language and I use it for everything. – stommestack – 2014-07-03T14:31:15.870

@JopVernooij the fact that the controller is in java doesn't imply the contest has to be limited to java. See this contest for instance, this one or even this one.

– plannapus – 2014-07-03T14:38:36.143

@m.buettner I'm not saying to modify the rules or anything, just maybe change the way some stats are calculated. As it stands right now, the biggest combat priorities are life and strength. Suppose I have my stats as 3 life and 7 strength. If I put 2 points from strength into defense, I am sacrificing 30% combat strength for 6% chance to dodge. I'm just saying, while limiting dodge to 50% still, maybe increase the % increase for each point? As of right now, the juggernauts are dominating just through strength alone :) – user3334871 – 2014-07-03T14:49:39.463

3@user3334871 I'm not sure how this is not "modifying the rules". I don't even disagree that balancing might be off, and that there may be a dominant strategy. But I don't think any of that warrants any change to the spec as long as the challenge is not completely broken such that it can't be carried out as intended. – Martin Ender – 2014-07-03T14:56:08.990

4First scoreboard is available! – CommonGuy – 2014-07-03T16:54:34.047

Awww, none of mine have lasted.....that's a shame :( – Kyle Kanos – 2014-07-03T18:31:28.757

And now looking at the win condition being max(sum(abilities)), it makes total sense that those aliens that favor STR and LIFE will win. – Kyle Kanos – 2014-07-03T18:34:12.437

@KyleKanos If you write an alien that successfully dodge other aliens (with enough vision), most of your aliens will survive without fighting ;) – CommonGuy – 2014-07-03T20:30:03.013

@Manu: I doubt that is the case, but could you swap alien.Coward's vision & defense (so that vision is 7 and defense is 2) to see if that improves it's chances? – Kyle Kanos – 2014-07-03T20:59:11.547

1can someone explain what the additional rule: "Interacting (instancing etc.) with other aliens is disallowed." means? i.e. does it forbid sharing state information amongst aliens of the same species or creating "instances" of other aliens as a brain trust? – Moogie – 2014-07-03T22:12:02.240

@Manu with that strategy, even if you could perfectly avoid all fights, the best score you could hope for is 1000 (100 instances * starting stats). Unfortunately the score board already has a higher score than that. – rdans – 2014-07-03T22:55:20.860

1@Moogie Sharing state within the same alien is allowed, but with other aliens it is disallowed. – CommonGuy – 2014-07-04T05:26:48.200

@Ryan No, sum of all abilities at the start is 1500, which is higher than the current max score in the scoreboard. – CommonGuy – 2014-07-04T05:27:36.963

@Manu Aww man, so i will have my Aliens kill off each other, thought about that they might tell each other their species but yeah that's not allowed... – Gigala – 2014-07-04T07:54:31.867

@Gigala They can talk to each other (for example all of the Manager-aliens can talk to each other), but the manager alien can not talk to the junkie-alien. – CommonGuy – 2014-07-04T08:11:18.890

On the top of my head, I have no idea how to code this, but it would be awesome if you could have all your aliens beat each other up and end up with one humongous alien. :o – Zaenille – 2014-07-04T10:49:47.483

@MarkGabriel I think they would take too much damage in the process... – Gigala – 2014-07-04T13:04:00.967

Hmm. You may be right. But the idea is still unique and awesome. Hahahaha. But it's definitely not a winning alien. – Zaenille – 2014-07-04T13:56:29.630

It's harder to come up with ideas now. – Spedwards – 2014-07-04T13:56:42.693

I think you should clarify the rules to mention that the North/South direction also wraps like the East/West. I got really excited about making a Bender alien who goes to the North Pole and travels west to "kill all humans," but no cigar.

– Michael - Where's Clay Shirky – 2014-07-04T14:38:31.203

@Michael I think it is already pretty clear. – CommonGuy – 2014-07-04T14:50:47.387

@Manu To give my Randomite alien a far chance, I'd appreciate it if to get the average you'd increase the amount of runs. In fairness this could also decrease my chances. – Spedwards – 2014-07-04T15:16:12.060

@Spedwards In the final run, there will be more runs. But for test-scoreboards, 5 runs should be enough. – CommonGuy – 2014-07-04T15:44:51.087

5

@Manu For the mathematically inclined the description of how the board wraps is somewhat misleading. You're saying it's a planet and it wraps east/west. There is nothing that really indicates that it does wrap north/south, too. In fact, if it does, it's technically not a sphere any more, but a torus: http://kotaku.com/classic-jrpg-worlds-are-actually-donuts-1239882216. You can also see that by noticing that when you walk "off" the top of a world map (the north pole), you don't appear at the bottom (the south pole). Hence, Michael's suggestion is definitely valid, I think.

– Martin Ender – 2014-07-04T16:52:08.807

@m.buettner oh, my fault. – CommonGuy – 2014-07-04T17:19:29.943

5SUGGESTION :

Everyone loves winning! But there will only be 1 winning species. How about we set some side-quests/side-prizes of some sorts?

Of course the main objective would be to be the dominant species, but maybe we could add some recognition for the others who didn't but succeeded in one specific area. Example :

  1. Strongest single alien (highest sum of abilities for a single alien of the whole species)
  2. Most numerous (highest number of living aliens among all the species)
  3. Vicious (species that has killed off the most aliens)
  4. Predator (species that has killed off the most prey)
  5. < – Zaenille – 2014-07-05T02:11:48.900

@MarkGabriel sounds like a good idea... if you are keen you may want to fork the game code and suggest a merge back to Manu – Moogie – 2014-07-05T09:10:28.557

@Moogie I might have time this coming week but I'll wait if Manu approves. :D – Zaenille – 2014-07-05T09:23:30.297

@Manu, are you checking previous submissions that have recent edits? You might not be editing them in your source code. A lot of entries have edits/improvements in them. :D – Zaenille – 2014-07-10T03:38:57.557

@MarkGabriel No, I took the old versions. For the final run I will update every submission. It's hard to see which submissions are updated... – CommonGuy – 2014-07-10T05:27:33.920

I understand. It is hard and would take too much of your time to check each one. Haha. – Zaenille – 2014-07-10T05:32:40.877

@MarkGabriel yes, because they are just test runs. And regarding your suggestion: I won't do it, because in all KOTH-challenges there is only one winner. But maybe I will start a new challenge in the near future... – CommonGuy – 2014-07-10T06:01:29.647

prey.Cow for the win! :D – Timtech – 2014-07-11T19:28:33.350

@Timtech a charging cow is indeed a scary beast! – Moogie – 2014-07-12T00:03:49.843

@Moogie I agree. – Timtech – 2014-07-12T23:37:58.383

When would the results be posted? :D – Zaenille – 2014-07-20T03:31:21.847

1Results are posted! – CommonGuy – 2014-07-20T10:56:32.563

Woooooo! Didn't expect PredicatClaw to win. Cartographer's algorithm is pretty intense and I was hoping to get 3rd place or so. Awesome! – Zaenille – 2014-07-20T11:44:04.880

@MarkGabriel Welldone :) The Cartographer alien is probably too risk adverse which means that it is highly dependant on the first couple of rounds. If it manages to survive the melee with good number of aliens then it is likely to win, otherwise it will never pick enough fights to build back what it lost. Your PredicatClaw is very consistent. Again, Welldone – Moogie – 2014-07-20T21:46:28.020

Answers

11

PredicatClaw (rawr)

This feline alien will swallow you whole (okay maybe she'll chew you a bit first)... if you seem weak based on her prediction algorithms.

A breed of Predicats that have fiercer claws and fangs than its counterparts.

EDIT : New target priorities

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

    }
}

Zaenille

Posted 2014-07-01T16:17:41.640

Reputation: 538

1Damn! Those predicats are fierce! I note that we both settled on more-or-less the same wantToFight algorithm. – James_pic – 2014-07-04T08:44:24.407

@James_pic, I see that great minds think alike. :D – Zaenille – 2014-07-04T09:56:33.827

27

Manager

Here's a manager. Naturally, the cleverness is 0 and he always strives to go where the sun don't shine. And, of course, he will only fight the weak and is very good in dodging trouble:

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

Ingo Bürk

Posted 2014-07-01T16:17:41.640

Reputation: 2 674

+1, if only for the intro. :P – apnorton – 2014-07-03T18:19:23.457

6Every time I read that comment ("just to make sure") I have to laugh :-D – Matthias – 2014-07-04T15:01:46.653

Funny, I was just reading this: http://blog.codinghorror.com/i-shall-call-it-somethingmanager/

– 11684 – 2014-07-06T21:31:41.833

@11684 any decent developer knows that, of course, but in my case I actually do mean a manager ;) – Ingo Bürk – 2014-07-07T04:41:49.163

18

CartographyLongVisionAlien

This Alien is a consistant performing variant of one of my attempts to produce an alien that is of winning potential.

It has initial 5x5 vision which it uses to build up an internal map of the surrounding area giving it superior enemy avoidance ability.

In my testing of 100 rounds, on average, It sneaks ahead of all other aliens. (09/07/2014)

UPDATED GIF showing the repell/attract field effect

I have modified the Game code to produce animated GIFs of the simulation. You can view such a simluation here

 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

Posted 2014-07-01T16:17:41.640

Reputation: 1 505

Updated to add prey future prediction and ensure that whales are likely to be attacked – Moogie – 2014-07-09T07:18:44.580

4Yay! Finally an alien is winning who does not only count on strength and life, but also vision :) – CommonGuy – 2014-07-09T20:12:14.183

3It was very difficult to get an alien that was a consistent performer! The other top entrants are mostly all following the same ideas: avoid aliens, attack prey and only initiate fights that you are almost guaranteed to win. This alien follows the same ideas, but with better alien avoidance. This gives it the slightest edge because it is more "expensive" to gain more abilities if you lose a fight. – Moogie – 2014-07-09T22:00:04.803

I did attempt other more exotic ideas but there is just not enough information exposed. i.e. map size, number of aliens etc – Moogie – 2014-07-09T22:05:55.107

Great job! I too was a little frustrated with the lack of information - extracting additional info from the past is creative. – Benny – 2014-07-11T18:23:37.333

Yay! I'm glad someone did this. I always figured vision could be useful, but for my alien vision never quite paid for itself. I think your superior enemy motion prediction is what gives it the edge. Also, I like the idea of behaving differently in the early game than the late game – James_pic – 2014-07-12T09:24:40.210

@James_pic It did take quite a few ideas and iterations before I was able to use the vision information in a useful manner. There is no explicit code to change the behaviour of the alien in early game vs late game... The behaviour emerges due to the availability of prey: In early game prey is plentiful and so will sometimes overcome the alien's desire to flee so that it can attack the prey. In the later game, the alien is far less likely to see prey and it may also be hurt so will avoid other aliens as much as it can. – Moogie – 2014-07-12T11:54:53.543

15

Choose Your Battles

This alien runs away from other aliens, but runs towards prey (so long as that wouldn't take it towards aliens).

I used a genetic algorithm to help me choose the starting values. The results suggest we should rely on strength and life to get through early battes. Vision is useful later, but we can pick that up from vanquished foes.

We only fight battles we think we can comfortably win - we estimate how many moves it would take to kill our alien, how many it would take to kill our enemy, and only join the battle if it we're "twice as hard" as our opponent.

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

If you want to run your own genetic algorithm/breeding program, I've got a forked copy of the control program for this purpose.

James_pic

Posted 2014-07-01T16:17:41.640

Reputation: 3 988

How does this bypass the check on the checkAbilitesOk method? – FreeAsInBeer – 2014-07-06T15:30:52.810

checkAbilitiesOk checks that the floats in the array add up to 10.0. However, the float values are rounded to ints in the game logic, and Java rounds 0.5 up. – James_pic – 2014-07-06T19:30:15.500

@justhalf it still sets 10 points, they are just distributed intelligently. – CommonGuy – 2014-07-07T08:46:29.293

@Manu: your comment contradicts Jamea_pic's comment imnediately above yours – justhalf – 2014-07-07T11:30:22.473

@justhalf No. He sets 10 points (3.5 + 6.5 = 10). What he means is that the game logic rounds the values when using them (so strength-lvl at the beginning = round(1+6.5) = 8). – CommonGuy – 2014-07-07T11:36:48.457

Yes, that's what we all meant by using 11 points. – justhalf – 2014-07-07T11:37:53.020

1I should say that it wasn't my idea originally - I borrowed it from PredicatClaw – James_pic – 2014-07-07T11:49:14.413

1Very nice. Your stat constants are probably better than mine and your wantToFight is definitely smarter, I was just lazy. :) – Benny – 2014-07-07T12:13:12.000

What I like about this is that it doesn't do the usual max LIFE+STRENGTH stats and it still kicks ass. Haha. – Zaenille – 2014-07-08T00:00:52.813

I am very impressed with your alien! I have been trying for the last few days to create an alien that will consistently win... So far no good! It wins about 45% of the time as compared to your alien 55%. Well done – Moogie – 2014-07-08T12:51:06.197

@Moogie don't give up! My alien went through a lot of iterations before it started winning. So far as I can tell, the most important characteristics of your alien are its wantToFight method and its starting stats. Movement seems like it should be important, but in truth, the key is to survive the initial melee. It also helps if your strategy somehow avoids cannibalism. If it helps, I've got a modified version of the control programme that makes it possible to spectate. I was reluctant to publish it, because it's a bit hacky, but I can make it available if it helps. – James_pic – 2014-07-08T18:42:39.297

@James_pic thanks for the encouragement and the offer. I also have hacked up a visualizer (and made it such that the test runs are deterministic allowing for analysis. I do have a couple of ideas that might help my alien. I have not given up yet :) – Moogie – 2014-07-08T22:15:36.200

12

Junkie

This alien is addicted to something. He starts the war on a pretty nasty fix.

While his fix is going strong (fix > 3) he is pleasantly content to sit in his stupor and is up for anything.

However, once his fix starts to wear off (fix <= 3) he starts stumbling around in no discernible direction trying to figure out what happened. If asked to fight, he becomes cautious and only fights if he thinks he can win.

Once his fix runs out, being the addict he is, he must restart the vicious cycle.

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

BeetDemGuise

Posted 2014-07-01T16:17:41.640

Reputation: 442

I'm pretty sure it's safe to remove && fix > 0 because of redundancy. – Timtech – 2014-07-09T21:32:49.387

10

Banana Peel

Only tries to trip up people that need a little whacking. Defeating it won't make you healthier.

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

Timtech

Posted 2014-07-01T16:17:41.640

Reputation: 12 038

Its also important to notice that [0] is life rather than health so 100 would be 510 HP (or less, depending on the damage already taken) but i don't know if an alien would get that high.. – Gigala – 2014-07-04T13:09:42.877

@Gigala Good thinking, I've changed it up a bit. – Timtech – 2014-07-04T14:08:17.037

9

Van Pelt

The hunter from Jumanji. He hunts when he's not hurt, avoids when he is and is a decent judge of what he can kill. Banana peels kept tripping him up, but taught him some new tricks.

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

}

Benny

Posted 2014-07-01T16:17:41.640

Reputation: 123

Learned to avoid Banana Peels, eh? :P – Timtech – 2014-07-12T23:41:49.317

8

Okinawa Life

No wonder I'll be the last one standing.

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

Timtech

Posted 2014-07-01T16:17:41.640

Reputation: 12 038

7

Hunter

I also just kinda stole the eagle's movement, except now he wants to go towards everything besides other aliens. Tries to hunt down and farm as much prey as possible, and fights only when it seems like it has a good chance to win.

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

pseudonym117

Posted 2014-07-01T16:17:41.640

Reputation: 1 053

7

Rock

I think it only attacks weak and "clever" people.

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

Timtech

Posted 2014-07-01T16:17:41.640

Reputation: 12 038

3I'm not sure how well Rock will last once his enemies start getting some buffs due to winning battles. Looks good though. – Kyle Kanos – 2014-07-02T00:21:39.330

@KyleKanos I understand; however, I assume that I will fight most prey/aliens, as long as they are not clever. Won't this give him some buffs too? – Timtech – 2014-07-02T12:53:25.927

Now looking back at my comment, I think it really wasn't at all what I wanted to say. I wanted to say that the wantToFight condition won't be giving true when the enemies start buffing with levels; you'll quickly turn to a strong pacifist. – Kyle Kanos – 2014-07-02T13:29:40.550

@KyleKanos Oh, I get it. I've changed it up a bit. – Timtech – 2014-07-02T15:03:37.847

7

It's over 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
    }
}

Yes, it's a blatant attempt at cheating, but it does squeak through the rules. If the getters in planet.Specie were made final, this loophole would close.

James_pic

Posted 2014-07-01T16:17:41.640

Reputation: 3 988

4Oh no! I knew I forgot something... I will close the loophole and +1 ;) – CommonGuy – 2014-07-04T08:23:19.467

I'm somewhat disappointed that this answer has had more upvotes than my other, older, currently winning, entry. – James_pic – 2014-07-05T14:48:36.193

6

Morphling

Couldn't think of any other name, this guy randomly distributes 10 points to his abilities. Almost moves like Okinawa Life(thx for your effort) and only wants to fight if his strength is greater than enemy's strength.

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

}

Sikorski

Posted 2014-07-01T16:17:41.640

Reputation: 171

Ahh, you know, you're right. The closing brackets have been killing me this challenge (had to edit mine a couple times because of that). I see it now, and it is correct. Thanks for pointing that out! – user3334871 – 2014-07-02T14:14:13.310

@user3334871 though i tested with your suggestion and my morphling just survived better :D – Sikorski – 2014-07-02T14:16:21.297

@Sikorski Well, glad I could help, not sure why it would fare better though, haha. – user3334871 – 2014-07-02T14:20:09.807

@Sikorski I guess that just means that staying put is often safer than making the least dangerous move if all moves are dangerous. – Martin Ender – 2014-07-02T14:22:19.817

Ahh, the "Deer in the Headlights" strategy, I like it. – user3334871 – 2014-07-02T14:24:19.987

6

Bender "Bending" Rodriguez

I was pretty liberal with code comments. You can read them in context to see what is going on, but I'll also add some snippets below.

Summary

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. =)

Movement

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

If you don't find anything interesting nearby, get a sense of whether south, west, or southwest is a more promising option.

Picking one or two prevailing directions lessens the chance that any given Bender will come across any of his compatriots, and picking a direction counter to his main prey should help him kill all humans faster.

I could probably tweak the numbers in the desirability matrix with James_pic's genetic algorithm for even better outcomes, but I don't know how to do that.

Aggressiveness

Bender mostly targets prey, and is pretty conservative with his wantToFight. Anyone over Strength 4 is shunned unless you think you're dealing with a clever human. Clever humanity is demonstrated by having more Defense and Vision than an alien is likely to have. It's adjusted over the course of an instance by Bender's own ability stats, to account for aliens killing turtles and eagles.

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

Michael - Where's Clay Shirky

Posted 2014-07-01T16:17:41.640

Reputation: 187

I noticed that there was a loop logic error where the variable that is incremented was not what was being compared directly and only avoids infinite recursion by means of integer overflow wrapping. Hope you are ok with me updating your answer. (it was causing the simulation to pause from time to time) – Moogie – 2014-07-09T05:00:48.973

@Moogie Heh. So I was only doing well by accident? Thanks for catching that. – Michael - Where's Clay Shirky – 2014-07-09T14:18:32.573

I went over the whole thing and fixed a couple more issues. – Michael - Where's Clay Shirky – 2014-07-14T18:25:19.877

5

Warrior

This is a very simple minded alien who just wants to fight. He doesn't care about his enemies nor about his surroundings.

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

You now have someone to test your own alien against.

CommonGuy

Posted 2014-07-01T16:17:41.640

Reputation: 4 684

4

Coward

I basically stole the Eagle's movement pattern to avoid danger and stacked defense in case I am attacked.

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

Kyle Kanos

Posted 2014-07-01T16:17:41.640

Reputation: 4 270

Correct me if I'm wrong, but since every ability has a base point of 1, then putting vision=1 should be sufficient? – justhalf – 2014-07-03T09:05:11.770

@justhalf: My brief reading of the code seemed to suggest that setAbilityPoints over-wrote the values of 1, but looking at it deeper I think you are correct. I am going to leave it as is because a larger vision allows me to see further and avoid danger, but thanks for the catch. – Kyle Kanos – 2014-07-03T14:02:29.103

Also, math.round always rounds up at 0.5, so you get an extra vision if you have an odd number – Andreas – 2014-07-04T11:46:10.887

@Manu: I've swapped my values of vision & defense to improve running-awayness. – Kyle Kanos – 2014-07-05T02:34:59.390

4

Fleer

PANIC

APOCALYPSE

RUUUUUUUUUUN

AAAAAAAAAAAAAAAAAAAAAAA


Avoids battles whenever possible.

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

stommestack

Posted 2014-07-01T16:17:41.640

Reputation: 234

You should give this a different name... and give some credit to the answer you copied from: http://codegolf.stackexchange.com/a/32787/9498

– Justin – 2014-07-02T20:55:32.577

2@Quincunx That's a coincidence, didn't see that one... – stommestack – 2014-07-02T21:04:25.393

Sorry, I just realized that both answers copy from Eagle. You didn't copy the other answer, I just didn't read carefully enough. However, a different name would be appropriate. – Justin – 2014-07-02T21:06:48.027

Yes, please choose a different name. Otherwise I can't include it in the final run... – CommonGuy – 2014-07-03T09:33:59.900

1Changed the name! – stommestack – 2014-07-03T09:42:20.057

2Should be named Rincewind. – Magus – 2014-07-03T16:38:46.133

This guy always dies, because you set 11 ability points at the start. – CommonGuy – 2014-07-09T16:00:25.937

@Manu Whoops... – stommestack – 2014-07-09T16:16:35.657

4

PredicatEyes (meow)

A breed of Predicats that have sharper vision than its counterparts which allows it to pry on its enemies well.

EDIT : New target priorities

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

    }
}

Zaenille

Posted 2014-07-01T16:17:41.640

Reputation: 538

4

Predicoward (purr)

A breed of Predicats that have lived (so far) on fear and staying away from trouble. Due to their lifestyle, they have not developed fighting instincts, but their perception is exceptional.

Their kind is loathed by their fellow Predicats.

EDIT : Changed Manhattan Distance to Weighted Distance instead

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

Zaenille

Posted 2014-07-01T16:17:41.640

Reputation: 538

2Looks good! But please take out your print-statements, they would confuse me when I run the contest. – CommonGuy – 2014-07-04T07:45:05.697

Oh, I left the print statements? I'll change them later. Haha. Plus this isn't final yet. Right now, Predicoward sucks. His alien evasion algorithms will be improved soon. :)

EDIT: Thanks for the one who removed the print statements. :D (Jop?) – Zaenille – 2014-07-04T09:55:12.087

EDIT: Predicowards are now much better at running away rather than the pesky little non-competitive predicowards they have been yesterday. >:) – Zaenille – 2014-07-05T02:07:20.820

Trivia : This is my favorite Predicat <3 – Zaenille – 2014-07-05T02:08:04.960

3

CleverAlien

Clever alien relies solely on his wits. He randomly walks around, and randomly decides to fight. He hopes he is able to outsmart his enemies with luck. ( forgive me if i have any syntax errors, im not a java guy)

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

user1336827

Posted 2014-07-01T16:17:41.640

Reputation: 139

8tmp == 1 ? true : false? Why not (tmp == 1) == true ? true : false? ;) (Hint: it's the same as just tmp == 1.) – Martin Ender – 2014-07-01T21:31:59.407

3

Rogue

Like other's have said, I am using the Eagle's movement to some degree. Rather than try to make a winning alien (My best ideas were already taken D:), I decided to make an alien with some character! My alien is a hired gun oblivious to the alien war, and is only on this planet to hunt the filthy human who has skipped out on his death stick debt. My alien will search the planet for the human, and continue to trail behind the human without killing him. Once an alien is seen near him, he will then try to quickly kill the human, and face off against this new foe with "luck on his side" from his completed task.

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

The code is centered around the idea that I should sprint towards the human. Once I beat him, I then wrap around to the southwest, where I will look for the turtle.

EDIT : Oh, and about the turtle thing...my alien doesn't like them, so it's totally canon you guys.

user3334871

Posted 2014-07-01T16:17:41.640

Reputation: 139

Just realized I can sprint towards the turtle as well. Who doesn't love high dodge rogues? – user3334871 – 2014-07-02T10:26:52.563

2is using int directly as boolean in if block part of Java 8 ? because it doesnt compile at all on my machine (Java 7). Hint : humanPresent – Sikorski – 2014-07-02T14:15:10.703

Heck if I know, my Java experience has mostly been limited to scripts and college level classes. I will just make the comparisons, just so everything is peachy. Thanks for the heads up! – user3334871 – 2014-07-02T14:18:26.343

Also, @Sikorski, did you create your own main or init function to run your tests? Or can it be done just through the provided code alone? I swear, it's been so long since I've coded in a true Java environment, that I've forgotten the rules for executing Java code :( – user3334871 – 2014-07-02T14:31:10.197

no just download the code that OP has given in github link, add other classes and start testing. Oh you will have to add entry for each alien class in Planet class. – Sikorski – 2014-07-02T14:32:53.770

3

Crop Circle Alien

Circles clockwise indefinitely, and never wants to fight, he is happy making crop cirles. However, if you really want to fight, he'll beat the crap out of you.

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

l0r3nz4cc10

Posted 2014-07-01T16:17:41.640

Reputation: 131

2This would be cleaner if you iterated through Move. – Not that Charles – 2014-07-02T14:15:23.397

4Why not change every getI() to i and simply remove getI()? You could also change setI(int i) to this.i = i % 8;, and since you only use it in that one place, just change each call to setI(getI() + 1) to i = (i + 1) % 8; – Justin – 2014-07-02T17:56:43.573

3

Crash landed and just trying to survive. Survives mostly by it's agility and intelligence and counts every scar, considering carefully if it's worth it to start a fight or not. The survivor starts off just hunting and trying to avoid all those other aliens with their big weapons but as it gets more bold may start to go after them. When it really gets going it won't care who it's facing anymore.

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

}

Kenneth

Posted 2014-07-01T16:17:41.640

Reputation: 31

1I'm quite sure that for(int ability in enemyAbilities){ is a syntax error - try for(int ability : enemyAbilities){ – Joshua – 2014-07-03T12:32:55.747

3

NewGuy

Tries to engage "easy" targets for early farming. Otherwise, just move sporadically.

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

FreeAsInBeer

Posted 2014-07-01T16:17:41.640

Reputation: 171

That floating return true; line seems superfluous due to the else condition. – Kyle Kanos – 2014-07-03T15:48:30.487

@KyleKanos True. Issue addressed. – FreeAsInBeer – 2014-07-03T16:16:27.387

your isHuman() test doesn't look quite right. Won't it find aliens who have leveled, too? – Not that Charles – 2014-07-03T17:51:49.747

@Charles You're right. It's difficult (impossible?) to find out if the enemy is a Human, or a leveled up alien due to the way the 'cleverness' mechanic works, and the fact that we can't determine the cleverness during a fight query. Even using some basic math, it's very likely an educated guess on whether or not it's a human or not will be inaccurate. I guess I'll change him to run from humans. – FreeAsInBeer – 2014-07-03T18:30:00.847

Your isSpecie-tests look cool, but even prey fight and those tests will soon fail... – CommonGuy – 2014-07-03T20:32:27.673

Like Manu said, your isSpecie functions will only work if said monster hasn't leveled up. :(

Also, from reading the code, I think Whales would have 11 LifeLvl (from 1 default + lvl 10 life), turtles would have 11 defense, etc. So you might want to adjust your code a bit.

Feel free to tell me otherwise though if my analysis is wrong. :D – Zaenille – 2014-07-04T10:53:18.993

3

FunkyBob

First priority is survival, otherwise will try to find some prey. Assesses the visible area to find the general direction with the least threats or most prey. Seems to have about an 85-90% survival rate during my testing.

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

rdans

Posted 2014-07-01T16:17:41.640

Reputation: 995

3

FunkyJack

Just for kicks, here's another entry with a slightly different approach. This one is only focused on avoiding fights. This isn't really a viable strategy due to being surrounded by enemies in the first couple of rounds. 40% of squares are occupied in the first round so on average you will be immediately adjacent to 3-4 enemies. But when increasing the initial empty squares to 12.5 times the species rather than 2.5 times the species it gets an average survival rate of 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;
    }
}

rdans

Posted 2014-07-01T16:17:41.640

Reputation: 995

198.5% is immense. Even my Predicowards get only about 65% survival rate on average. Haha.

Edit : My Predicowards have the same philosophy as FunkyJack - just stay away. I do have 10 vision though and 0 fighting stats. – Zaenille – 2014-07-09T06:00:08.560

3

LazyBee

I started trying to make a clever Bee class that used pattern movements and deductive reasoning, but then I got sleepy, so I renamed it LazyBee and called it a night. He actually seems to perform pretty well on my tests (average of ~1645 with aliens on the github).

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

thefistopher

Posted 2014-07-01T16:17:41.640

Reputation: 151

1Excellent work! I'm pretty amazed you score so well with a hardcoded direction. – Michael - Where's Clay Shirky – 2014-07-22T21:48:07.867

@Michael you have no idea how pleasantly surprised I was when I found out! I had put a lot of effort into movement code, then i had it running against HOLD as a sort of control group. then I realized the control group was kicking ass, so I started experimenting with different shades of lazy! – thefistopher – 2014-07-23T15:27:14.503

2

Guard

Stack life, buff strength & defense, then stay put. Only attack if the opponent seems to be aggressive (defined as strength being greater than 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;
    }
}

Kyle Kanos

Posted 2014-07-01T16:17:41.640

Reputation: 4 270

2

AimlessWanderer

RandomStringUtils.randomAlphanumeric(100); //Flavor text

 public class AimlessWanderer extends Alien{

    private final Random rand = new Random();

    @Override
    public void setAbilityPoints(float[] abilities) {
        int cap = 10; 
        for(int i = 0;i<abilities.length; i++){
            abilities[i] = rand.nextInt(cap);
            cap -= abilities [i];
        }
        abilities[rand.nextInt(4)] += cap > 0 ? cap : 0;
    }

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

    @Override
    public boolean wantToFight(int[] enemyAbilities) {  
        rand.setSeed(rand.nextLong());
        return rand.nextBoolean();
    }
}

Undeserved

Posted 2014-07-01T16:17:41.640

Reputation: 159

1Please, format your code properly. – AJMansfield – 2014-07-01T20:51:24.553

6The RandomStringUtils.randomAlphanumeric(100); //Flavor text line is not part of the code. – Undeserved – 2014-07-01T21:26:44.210

1Out of curiosity, is there a point to reseeding rand each time wantToFight is called? – Kyle Kanos – 2014-07-03T14:18:31.977

You can never be too sure. – Undeserved – 2014-07-03T14:53:29.737

Reseeding the RNG on every call probably makes it less random - depends on the algorithm, but you're preventing its state space from being any larger than a single long. I'd suggest creating one Random object as an instance variable and then reusing it for everything. (BlindBully seems to do this, if you need an example.) – zwol – 2014-07-06T14:45:24.880

2

Bully Alien

Bully Alien will walk around ignoring enemies until he finds someone weak to mess with.

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

William Barbosa

Posted 2014-07-01T16:17:41.640

Reputation: 3 269

2Aww, the bully alien just wants to be friends. – user3334871 – 2014-07-02T12:33:22.730

3@user3334871 More like: "the bully alien just wants to have a syntax error" – Justin – 2014-07-02T17:52:32.517

Shouldn't wantToFight look at the enemy's abilities? – Ingo Bürk – 2014-07-02T18:09:05.263

@IngoBürk It already did by the time you commented – William Barbosa – 2014-07-02T18:23:14.117

Must've taken me too long to scroll through the thread then. :) – Ingo Bürk – 2014-07-02T18:32:03.860

2

Weakest Link

This bot is strong in what appears to be the most useless1 categories: visual & cleverness. He stays put because fights will come to him and he'll fight anything that comes his way.

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

    // the fights will come to you
    public Move move(char[][] fields){
        return Move.STAY; 
    }

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



1 I say useless because most of the current bots do not use visual or cleverness. However, cleverness appears to be an intrinsic thing, so I gave it just enough so that a win for the opponent gets nothing.

Kyle Kanos

Posted 2014-07-01T16:17:41.640

Reputation: 4 270

Nope, they will be stored and increased as float. – Gigala – 2014-07-03T08:06:25.500

@Gigala: True, but Specie.java has int and Math.round for all the stats. Giving my opponent 4/5 would be equivalent to giving them no buffs. – Kyle Kanos – 2014-07-03T14:09:52.850

But isn't it like that the next win will probably give the opponent enough to make the jump from X.6 to the next level? – Gigala – 2014-07-03T15:44:13.647

1@Gigala: Assuming that their cleverness is that large, of course. That's a chance this death-wishing bot is willing to take. – Kyle Kanos – 2014-07-03T15:46:34.607

2

BlindBully

Doesn't care who or what is around it, just tries to decide if the alien it is facing right now is stronger or weaker than itself, and attacks those weaker.

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

}

Ross Taylor-Turner

Posted 2014-07-01T16:17:41.640

Reputation: 121

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

VaibhavJ

Posted 2014-07-01T16:17:41.640

Reputation: 51

So this is the best? haha – justhalf – 2014-07-04T02:52:52.693

2

SecretWeapon

package alien;

import planet.Move;

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

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

    public void setAbilityPoints(float[] abilities) {
        abilities[LIFE] = 1;
        abilities[STR] = 9;
        abilities[DEF] = 0;
        abilities[VIS] = 0;
        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 ' ': danger--;
                    case 'C': danger--;
                    case 'E': danger++;
                    case 'H': danger++;
                    case 'T': danger--;
                    case 'W': danger++;
                    default: danger--;
                }
            }
            if (danger < leastDanger) {
                bestMove = move;
                leastDanger = danger;
            }
        }
        return bestMove;
    }

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

VaibhavJ

Posted 2014-07-01T16:17:41.640

Reputation: 51

what shall it do? – Joshua – 2014-07-03T15:23:24.363

1@Joshua it's a secret – Martin Ender – 2014-07-03T15:33:20.220

2

Randomite

Designed to be as random as possible.

package alien;

import planet.Move;

public class Randomite extends Alien {

    private static int max = 10;

    @Override
    public void setAbilityPoints(float[] abilities) {
        int r1;
        while (max > 0) {
            if (max == 1) {
                r1 = 1;
            } else {
                r1 = Math.floor(Math.random() * max);
            }
            int r2 = Math.floor(Math.random() * 5);
            abilities[r2] += r1;
            max -= r1;
        }
    }

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

    @Override
    public boolean wantToFight(int[] enemyAbilities) {
        int r3 = Math.floor(Math.random() * 100);
        return r3 > 50;
    }
}

Simulation of random abilities in JavaScript: http://pastebin.com/mmjVpzGU

Spedwards

Posted 2014-07-01T16:17:41.640

Reputation: 159

It is as random as it possibly can be. (claps slowly) – Zaenille – 2014-07-04T12:06:55.500

@MarkGabriel Well nearly every other idea has been done and I thought it would make for an interesting opponent. Granted it could lose straight away. – Spedwards – 2014-07-04T12:18:15.700

Actually the interesting thing about random stuff is that you can expect that you won't be in the extremes. I'm quite interested to see the results of this. Haha. – Zaenille – 2014-07-04T12:43:59.860

@MarkGabriel I ran 10 simulations and they are seriously random. http://pastebin.com/GTkHkVDf

– Spedwards – 2014-07-04T13:41:37.200

1This doesn't compile. Your using variable r1 outside of the block its declared in – rdans – 2014-07-04T21:12:47.877

I declared r1 outside of the if-statement and removed the final modifier from max to get it to run. – CommonGuy – 2014-07-04T21:48:33.977

@Ryan Sorry, haven't worked with Java in quite some time. – Spedwards – 2014-07-05T04:56:14.267

2

HerjanAlien

About my alien breed, he is nothing new, dodging stuff and trying to kill prey if he can. The only thing is that if his vision ability increases he immediately uses the vision he gained. I haven't given him vision levels at the start though, that worked out really bad for his survivability :S. (Just upgrading it by one level will cost him 2 of his strength/life).

My alien can't wait anymore, so enough talk, he makes his entrance:

package alien;

import planet.Move;

public class HerjanAlien extends Alien{

    private final int LIFE = 0, STR = 1;

    private final int UP = 0, LEFT = 1, DOWN = 2, RIGHT = 3, DOWNLEFT = 4, DOWNRIGHT = 5, UPLEFT = 6, UPRIGHT = 7;

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

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

        int middle = getVisionFieldsCount();

        int neededAttacksToWin = 60/((getStrengthLvl()-1)/2+1);
        if(getCurrentHp()-2 > neededAttacksToWin){
            if(fields[middle-1][middle-1] == 'W')
                return Move.NORTHWEST;
            if(fields[middle][middle-1] == 'W')
                return Move.NORTH;
            if(fields[middle+1][middle-1] == 'W')
                return Move.NORTHEAST;
            if(fields[middle+1][middle] == 'W')
                return Move.EAST;
            if(fields[middle+1][middle+1] == 'W')
                return Move.SOUTHEAST;
            if(fields[middle][middle+1] == 'W')
                return Move.SOUTH;
            if(fields[middle-1][middle+1] == 'W')
                return Move.SOUTHWEST;
            if(fields[middle-1][middle] == 'W')
                return Move.EAST;
        }

        if(getCurrentHp() > 5){
            if(fields[middle+1][middle-1] == 'T')
                return Move.STAY;
            if(fields[middle][middle-1] == 'T')
                return Move.WEST;
            if(fields[middle+1][middle] == 'T')
                return Move.SOUTH;

            if(fields[middle-1][middle-1] == 'H')
                return Move.STAY;
            if(fields[middle][middle-1] == 'H')
                return Move.EAST;
            if(fields[middle-1][middle] == 'H')
                return Move.NORTH;
        }

        int[] danger = new int[8];
        for(int i = 0; i < 8; i++){
            danger[i] = 0;
        }

        for(int x = -getVisionFieldsCount(); x <= getVisionFieldsCount(); x++){
            for(int y = -getVisionFieldsCount(); y <= getVisionFieldsCount(); y++){

                if(fields[middle - x][middle - y] == 'A'){
                    int dangerFactor = getVisionFieldsCount();
                    if(x <= 1 && x >= -1 && y <= 1 && y >= -1)
                        dangerFactor = getVisionFieldsCount()*4;

                    if(x<0)
                        danger[LEFT] += dangerFactor;
                    if(x>0)
                        danger[RIGHT] += dangerFactor;
                    if(y<0)
                        danger[UP] += dangerFactor;
                    if(y>0)
                        danger[DOWN] += dangerFactor;

                    if(x<=0 && y<=0)
                        danger[UPLEFT] += dangerFactor;
                    if(x>=0 && y<=0)
                        danger[UPRIGHT] += dangerFactor;
                    if(x<=0 && y>=0)
                        danger[DOWNLEFT] += dangerFactor;
                    if(x>=0 && y>=0)
                        danger[DOWNRIGHT] += dangerFactor;
                }
            }
        }
        boolean safe = true;
        for(int i = 0; i < 4; i++){
            if(danger[i] > 3){
                safe = false;
                break;
            }
        }
        if(safe)
            return Move.STAY;

        int leastDanger = 50;
        int bestWay = 0;
        if(getVisionFieldsCount()>1){
            for(int j = 8; j >= 0; j--){
                if(danger[j] < leastDanger){
                    leastDanger = danger[j];
                    bestWay = j;
                }
            }
        }else{
            for(int j = 4; j >= 0; j--){
                if(danger[j] < leastDanger){
                    leastDanger = danger[j];
                    bestWay = j;
                }
            }
        }

        if(bestWay == LEFT)
            return Move.WEST;
        if(bestWay == UP)
            return Move.NORTH;
        if(bestWay == RIGHT)
            return Move.EAST;
        if(bestWay == DOWN)
            return Move.SOUTH;
        if(bestWay == DOWNLEFT)
            return Move.SOUTHWEST;
        if(bestWay == DOWNRIGHT)
            return Move.SOUTHEAST;
        if(bestWay == UPLEFT)
            return Move.NORTHWEST;
        if(bestWay == UPRIGHT)
            return Move.NORTHEAST;

        return Move.getRandom();
    }

    @Override
    public boolean wantToFight(int[] enemyAbilities) {

        int enemyLifeLvl = enemyAbilities[LIFE];
        int enemyStrengthLvl = enemyAbilities[STR];

        int neededAttacksToWin = (enemyLifeLvl*5+10)/((getStrengthLvl()-1)/2+1);
        int enemyAttacksToLose = (getCurrentHp()/5/((enemyStrengthLvl-1)/2+1));

        if(getCurrentHp() <= enemyStrengthLvl)
            return false;
        if(enemyAttacksToLose-neededAttacksToWin > enemyStrengthLvl/enemyLifeLvl+1)
            return true;
        return false;
    }

    @Override
    public String toString(){ // for some testing
        return "Herjan";
    }
}

Herjan

Posted 2014-07-01T16:17:41.640

Reputation: 1 147

2

The Book of Eli

He just keeps going west guided only by the book of Eli, knowing that a force greater than himself will protect him. He is peaceful and will only fight when attacked.

package alien;

import planet.Move;

public class Eli extends Alien {

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

    public Move move(char[][] fields) {
        //Just keep going west as that is the way to salvation
        return Move.WEST;
    }

    public boolean wantToFight(int[] enemyAbilities) {
        //Will not fight as it's not the moral thing to do
        return false;
    }

}

Rory McPerlroy

Posted 2014-07-01T16:17:41.640

Reputation: 413

1

SecretWeapon3

package alien;

import planet.Move;

/**
 * Created by VJA1075 on 02/07/14.
 */
public class SecretWeapon3 extends Alien {

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

    public void setAbilityPoints(float[] abilities) {
        abilities[LIFE] = 1;
        abilities[STR] = 9;
        abilities[DEF] = 0;
        abilities[VIS] = 0;
        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 ' ': danger++;
                    case 'C': danger++;
                    case 'E': danger++;
                    case 'H': danger++;
                    case 'T': danger++;
                    case 'W': danger++;
                    default: danger++;
                }
            }
            if (danger < leastDanger) {
                bestMove = move;
                leastDanger = danger;
            }
        }
        return bestMove;
    }

    public boolean wantToFight(int[] enemyAbilities)    {
        // LIFE=0, STR=1, DEF=2, VIS=3, CLV=4;
        //abilities[STR]=abilities[STR]*100;
        //((double)this.getCurrentHp() * this.getDefenseLvl()) / (double)enemyAbilities[STR] > (enemyAbilities[LIFE] * enemyAbilities[DEF]) / this.getStrengthLvl()
        return (enemyAbilities[1]+ enemyAbilities[2]  ) < 7;
    }
}

VaibhavJ

Posted 2014-07-01T16:17:41.640

Reputation: 51

1

Geoffrey

package alien;

import planet.Move;

public class Geoffrey extends Alien{
    public void setAbilityPoints(float[] abilities){
        abilities[0] = 5;  
        abilities[1] = 5;  
        abilities[2] = 0; 
        abilities[3] = 0;  
        abilities[4] = 0;  
    }

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

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

Christofer Ohlsson

Posted 2014-07-01T16:17:41.640

Reputation: 1 014

1

CorporateAlien
Tries to maximize value by avoiding other alien and hunt for prey that has good boosts (Whale, Cow, Turtle and Eagle)

package alien;

import planet.Move;

public class CorporateAlien extends Alien {

    float[] abilities = new float[5];

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

    public Move move(char[][] fields) {
        int vision = getVisionFieldsCount();
        char me = fields[vision][vision]; // middle of fields
        int potentialPrey = Integer.MAX_VALUE;
        Move bestMove = Move.getRandom();
        for (Move move : Move.values()) {
            int goodPrey = 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());


                // Try to ignore other aliens
                if (fields[fieldX][fieldY] == 'A') {
                    goodPrey--;
                } else if (fields[fieldX][fieldY] != ' ') { // Look for interesting prey that gives good stat boosts: whale, cow or turtle
                    if(getLifeLvl() > 10){
                        goodPrey++;
                        if (getLifeLvl() < (10 + abilities[0] * 5) * 0.4 && fields[fieldX][fieldY] != 'W') //start prioritizing whales once at 40% health in order to heal
                            goodPrey++;
                    } else goodPrey--; // Always run away when near death
                }

            }
            if (goodPrey > potentialPrey) {
                bestMove = move;
                potentialPrey = goodPrey;
            }
        }
        return bestMove;

    }

    public boolean wantToFight(int[] enemyAbilities) {
        // if it's a whale, always engage when above 10hp
        int combatLvl = enemyAbilities[0] + enemyAbilities[1] + enemyAbilities[2];

        if (getLifeLvl() > 10 && enemyAbilities[0] == 10 && enemyAbilities[1] != 10 && enemyAbilities[2] != 10 && combatLvl == 10){
            return true;
        } else 
            // if it's a cow, always engage when above 15hp
            if(getLifeLvl() > 15 && enemyAbilities[0] != 10 && enemyAbilities[1] == 10 && enemyAbilities[2] != 10 && combatLvl == 10) {
            return true;
        } else 
            // if it's a turtle, always engage when above 10hp
            if(getLifeLvl() > 10 && enemyAbilities[0] != 10 && enemyAbilities[1] != 10 && enemyAbilities[2] == 10 && combatLvl == 10) {
            return true;
        } else 
            //Puny Eagle is weak; CorporateAlien crush puny eagle
            if (combatLvl == 0 && getLifeLvl() > 10) {
                return true;
            } else {
            float dodgeChance = (float) (abilities[2] +1 <= 33 ? 1.333 : 1.5);
            if(getLifeLvl() / ((enemyAbilities[1]/2)+1) > (((enemyAbilities[0]*5)+10) * dodgeChance) / abilities[1]/2 )
                return true;
        }           
        return false;
    }
}

Andreas

Posted 2014-07-01T16:17:41.640

Reputation: 147

2Good idea! But killing humans and eagles is also good, because you get their abilities (which is all that counts at the end of the game). – CommonGuy – 2014-07-04T11:28:52.930

1Yeah, just thought of that. Already modified it. – Andreas – 2014-07-04T11:31:41.327

Nooo. Leave Bender the humans. }:D

– Michael - Where's Clay Shirky – 2014-07-04T22:54:58.710

@Manu Small update - Stole the .5 ability idea from the choose your battles alien (give him/her an upvote as thanks). Currently reworking my avoid and combat algorithms – Andreas – 2014-07-08T11:22:14.510

@Andreas What's the .5 ability idea? o.O – Spedwards – 2014-07-08T11:22:57.293

@Spedwards The abilities are stored as doubles, but returned as ints. A double with a decimal of .5 gets rounded up to the next whole number when converted to an int with Math.round() (i.e. 5.5 becomes 6). – Andreas – 2014-07-08T11:24:49.653

Not to be an attention whore but PredicatClaw actually started the .5f ability idea, as recognized by Choose your battles author James_pic as well. :D – Zaenille – 2014-07-08T11:56:56.880

@MarkGabriel Whoops, upvote for predicatclaw too, then. – Andreas – 2014-07-08T12:18:50.067

1

Stone

Note that code is taken from @TimTech : Bananapeel

public class Stone extends Alien{
    public void setAbilityPoints(float[] abilities){
        abilities[0] = 0;  // Stones are not alive
        abilities[1] = 10;  // Stones are strong
        abilities[2] = 0;  // Stones can't defend themselves
        abilities[3] = 0;  // Stones can't see
        abilities[4] = 0;  // Stones peels can't think
    }

    public Move move(char[][] fields){
        return Move.SOUTH; // Stones just fall down
    }

    public boolean wantToFight(int[] enemyAbilities){
        return enemyAbilities[1] <=2 ; // Stones don't pick fights often.
    }
}

Dennis Jaheruddin

Posted 2014-07-01T16:17:41.640

Reputation: 1 848

1

GentleGiant

The GentleGiant has high life and strength, but chooses not to fight unless the enemy is an eagle. He doesn't like eagles. They can fly up to his head and peck on his tender nose.

package alien;

import planet.Move;

public class GentleGiant extends Alien {

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

    public Move move(char[][] fields) {
        //you are in the middle of the fields, say fields[getVisionFieldsCount()][getVisionFieldsCount()]
        int vision = getVisionFieldsCount(); 
        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] == 'E') {
                    bestMove=move;
                }
            }
         }
        return bestMove;
    }

    public boolean wantToFight(int[] enemyAbilities) {
        if(enemyAbilities[3]==10 && sumAbilities(enemyAbilities)==10){
            return true;
        }
        else return false;
    }

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

}

Kartik_Koro

Posted 2014-07-01T16:17:41.640

Reputation: 111

1

Sped

He's clumsy and a little brain dead.

package alien;

import planet.Move;

public class Sped extends Alien {

    private final int LIF = 0, STR = 1, DEF = 2, VIS = 3, CLV = 4;

    public void setAbilityPoints(float[] abilities) {
        abilities[LIF]  = 8;
        abilities[DEF]  = 2;
    }

    public Move move(char[][] fields) {
        // He's a little clumsy so he doesn't move because he knows he'll fall and trip.
        return Move.STAY;
    }

    public boolean wantToFight(int[] enemyAbilities) {
        // He's a, well, me... a sped. He doesn't know if he wants to fight or not.
        int r = Math.floor(Math.random() * 100);
        return r > 50;
    }

}

Spedwards

Posted 2014-07-01T16:17:41.640

Reputation: 159

1

Assassin

Goes for turtles to gain extra defense, then goes for humans, then he's satisfied and moves randomly. In all this he's open to fighting whales.

package alien;

import planet.Move;

public class Assassin extends Alien {

    public void setAbilityPoints(float[] abilities) {
        abilities[1] = 10; //strength
        abilities[3] = 0; //vision
    }

    public Move move(char[][] fields) {
        // Get yo' priorities sorted!
        int dir = 0;
        if (getDefenseLvl() < 30) {
            if (dir == 0) {
                dir++;
                return Move.WEST;
            } else if (dir == 1) {
                dir--;
                return Move.SOUTH;
            }
        } else if (getClevernessLvl() < 30) {
            if (dir == 0) {
                dir++;
                return Move.EAST;
            } else if (dir == 1) {
                dir--;
                return Move.NORTH;
            }
        } 
        return Move.getRandom();
    }

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

}

Spedwards

Posted 2014-07-01T16:17:41.640

Reputation: 159

You could use return enemyAbilities[2] >= 10;, which would produce the same behaviour as your code but is easier to read ;) – CommonGuy – 2014-07-08T10:50:05.880

@Manu I usually spot those tricks... Surprised I missed it this time. – Spedwards – 2014-07-08T10:51:03.253

what is dir for? – Joshua – 2014-07-08T11:43:25.547

@Joshua Alternate between south and west – Spedwards – 2014-07-08T11:49:27.280

in wantToFight(), enemyAbilities[4] does not exist, because cleverness is not sent. – CommonGuy – 2014-07-09T16:03:57.827

@Manu My bad. I'm always overlooking something it seems. – Spedwards – 2014-07-11T08:51:42.287

1@Spedwards You alien had some compilation errors. I have fixed them on your behalf. Feel free to revert/change the fix if not desired. – Moogie – 2014-07-11T22:02:09.930

-1

My Alien species are so advanced that can alter the reality with their conscience.

At first I wanted to name them 'Q', but then I called them 'Cheater' because I'm gonna be disqualified anyways.

package alien;

import planet.Move;

public class Cheater extends Alien {
    @Override
    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
    }

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

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

    @Override
    public int getStrengthLvl() {
        return Integer.MAX_VALUE;
    }

    @Override
    public int getLifeLvl() {
        return Integer.MAX_VALUE;
    }

    @Override
    public int getDefenseLvl() {
        return Integer.MAX_VALUE;
    }
}

user26862

Posted 2014-07-01T16:17:41.640

Reputation:

1This 'cheat' was already used. – Spedwards – 2014-07-04T11:29:16.087

3actually, you get instakilled if you start of with more than 10 bonus attribute points – Andreas – 2014-07-04T11:34:42.783