Великая Охота на Вумпуса


22

ПОЛНОЕ

Сезон Wumpus закончился, и с, жизнями многих злобного Wumpus и храброго Охотника. А также некоторые трусливые, аморальные и откровенно глупые охотники. Но в конце дня NascarHunter от доктора Гекла ушел с самой добычей и славой. Мы приветствуем тебя, о храбрый ... водитель?

Это открытый сезон для Wumpus, и охотники со всего мира стекаются в пещеры Wumpus, чтобы попытаться разбогатеть на ценных шкурах Wumpus.

Игра

По мотивам классической игры « Охота на вумпа» , с несколькими вариациями.

Карта

Додекаэдр . Есть 20 комнат, каждая из которых соединена с 3 другими комнатами, образуя в основном 3 кольца с мостами между ними.

Wumpus

Wumpus - мистический зверь. Никто не уверен, как это выглядит, но все согласны с тем, что это свирепо. Вумпус живет в пещерах и любит есть мертвые вещи. Если в пещере рядом с Wumpus есть труп, он переедет туда и съест его. Если случится, что Вумпус войдет в пещеру с охотниками, он также убьет и съест их. Если Вумпус услышит стрелу рядом с ним, он запаникует и побежит в случайную комнату.

Дополнительные черты : они в настоящее время включены, чтобы сделать игру более интересной, но могут быть удалены по популярному запросу, если они добавляют слишком много случайности.

Разъяренный Вумпус: Если Вумпуса застрелят, у него будет 20% выживания и неистовства в течение 3 дней. Во время буйства он будет случайным образом двигаться два раза в день, но все равно будет привлекаться к трупам. Через 3 дня он умрет. Второй выстрел стрелой также убьет Wumpus.

Wandering Wumpus: Каждый день, если ничто другое не вызывает Wumpus, у него есть 25% -ый шанс перемещения.

Охотники

Четыре охотника могут войти в пещеры одновременно. Пещеры темные, поэтому охотники не могут видеть, но они могут использовать свои другие чувства. Охотники могут чувствовать запах Wumpus в соседней комнате, чувствовать запах трупа в соседней комнате, слышать, как другие охотники движутся в соседних комнатах, и слышать, стреляют ли стрелы в соседнюю комнату.

У охотников есть два действия: стрелять или двигаться. Охотник может стрелять в соседнюю комнату или в свою комнату и двигаться аналогичным образом.

Игровой процесс

В каждом раунде охотники сначала отмечают свое окружение, а затем делают один ход. Движение происходит перед стрелами, поэтому, если стрела попадет в комнату, из которой выходит охотник, он выживет. После того, как все ходы охотника сделаны, стрелки оцениваются. Если один человек и стрелка находятся в одной комнате, он будет застрелен. Если двое или более человек живут в одной комнате, один из них будет случайно ранен и погибнет. Примечание: трупы являются обитателями, поэтому мертвое тело может служить частичным щитом.

После всех ходов охотника, Wumpus ответит. Если охотник вошел в комнату с Wumpus, Wumpus съест его / ее. Если Wumpus переместится, он также съест обитателей новой комнаты.

Через 100 дней, если охотники не убили Вумпа или пали жертвами, они умрут от голода в пещерах.

Код

Весь исходный код можно найти здесь . Все материалы должны быть на Java, если кто-то не захочет написать мне адаптер stdIn / stdOut;)

Боты должны расширять класс Hunter. Чтобы назвать своего Охотника, добавьте конструктор без параметров, который устанавливает поле имени. Чтобы ответить, переопределите функцию getResponse. В этой функции каждый ход вам будет передан массив из 5 логических значений, который расскажет вам о вашем окружении.

статус 0 = "Ты чувствуешь запах гумуса"

статус 1 = "Ты слышишь другого охотника"

status 2 = "Ты чувствуешь запах трупа"

status 3 = "Вы слышите грохот стрелы"

status 4 = "Ты чувствуешь другого охотника в той же комнате, что и ты"

Класс Hunter имеет 2 слота: nextMove и nextDirection, которые используют перечисления Move и Direction соответственно. Move может быть MOVE или SHOOT, перенаправление может быть LEFT, RIGHT, BACK или HERE. Направления последовательны, то есть возвращение всегда вернет вас в предыдущую комнату, в которой вы были, и если вы входите из той же комнаты, ВЛЕВО и ВПРАВО всегда будут одинаковыми. Однако, если вы войдете в другом направлении, ВЛЕВО и ВПРАВО перенесут вас в разные места.

Не стесняйтесь применять и свои собственные методы. Память сохраняется на протяжении всего турнира, то есть ваш охотник будет построен только один раз. Однако в начале каждого раунда вызывается метод newGame (), чтобы сообщить вашему охотнику, что началась новая игра.

счет

Четыре охотника соревнуются одновременно. Если его убить, шкура Вумпуса будет стоить 60 очков, равномерно распределенных среди всех выживших охотников. Полный круговой стиль, так что каждая комбинация из 4 охотников будет играть вместе.

В комплект входят 5 образцов охотников: 4 с очень простой функциональностью и один, который позволяет пользователю вводить данные для тестирования.

Если у вас есть какие-либо предложения / пожелания, пожалуйста, дайте мне знать!

Конец в поле зрения!

На население Wumpus в мире охотятся с угрожающей скоростью. Ожидается, что закон «Защити наших грызунов» будет принят в среду, 17 июня. После этой даты в пещерах больше не будет охотников, а победитель будет выбран.

Табло

Примечание: мои извинения, в коде была ошибка, из-за которой Охотники могли оставаться мертвыми в нескольких играх. Исправив это, он не сильно изменит общий рейтинг, но в значительной степени изменит статистику.

Счет идет, запустив каждый набор охотника в 1000 игр каждый. NascarHunter и FullCoverageHunter возглавляют группу, и хотя добавление AntiHunter дало Wumpuses повышение выживаемости на 2%, они все еще трясутся в своих сосущих ногах при уровне выживания 32% в своем роде. Стрелки от других охотников больше, чем когда-либо, представляют самую большую угрозу в пещерах.

1. NascarHunter : 16557175 (17.08)
2. FullCoverageHunter : 15195545 (15.68)
3. Trig : 14459385 (14.92)
4. Idomeneus : 13428570 (13.85)
5. Eats Shoots and Leaves : 12763945 (13.17)
6. WalkingIdiot : 12329610 (12.72)
7. NealHunter : 12287140 (12.68)
8. Unnamed : 11013720 (11.36)
9. MonsterHunter : 10686035 (11.02)
10. Pacer : 9187000 (9.48)
11. Badger : 9042570 (9.33)
12. Stay : 8721210 (9.0)
13. Emo Wumpus : 7831050 (8.08)
14. Paranoid : 7722965 (7.97)
15. Huddle : 7465420 (7.7)
16. ElmerFudd : 7245995 (7.47)
17. Laomedon : 6963845 (7.18)
18. Pacifist : 6944960 (7.16)
19. ScaredyCat : 6937370 (7.15)
20. Wumpus : 114170 (0.11)



Total rounds: 4845000
Humans killed by arrows: 5289674 (1.09)
Humans dead by starvation: 1046024 (0.21)
Humans killed by wumpus: 1887634 (0.38)
Wumpus victories: 1563372 (0.32)

1
Можете ли вы поразить другого охотника стрелой?
MegaTom

1
Да, или вы сами, если стреляете в стрелу ЗДЕСЬ
Каин

1
Вместо массива для 5 логических значений, почему бы просто не передать intзначение 0-31? Мы здесь большие мальчики, мы можем выполнять битовые операции :)
DoctorHeckle

1
@DoctorHeckle Конечно, мы все еще более дружественны к массиву, а не к единственному целому ^^.
Катенкё

1
Для стрел и трупов, если вы находитесь в той же комнате, что и вы, вы получаете такой же статус, как если бы он был рядом. Охотники - единственные, кого вы можете различить, находясь рядом с комнатой или в комнате.
Каин

Ответы:


11

NascarHunter

Не так много логики для этого. Его правила просты: поверните налево, выжженная земля, повторите. И, может, ему повезет!

8 июня редактировать:

Добавлена ​​дополнительная логика в Nascar для учета смежности с Wumpus относительно его последнего хода. Считай это пит-стопом, чтобы оставаться в теме. Если он чувствует Wumpus после стрельбы по коридору, то он, должно быть, прибыл в одну из двух других смежных комнат, поскольку он умер бы от выстрела, который только что сделал охотник. Он эффективно дает либо ход Wumpus 2, если он не двигается снова, либо ход Nascar 1, если он стоит на трупе. Также учитывается третий вариант, если это первый поворот, но только один раз. В конце концов, я буду портировать на FCH, занят занят.

package Hunters;

import Mechanics.*;

public class NascarHunter extends Hunter {

    private int state;
    private boolean shootHall;
    private boolean newGame;

    public NascarHunter(){

        name = "NascarHunter";
        state = 0;
        shootHall = true;
        newGame = true;

    }

    public void newGame(){

        state = 0;
        newGame = true;

    }

    public void getResponse(boolean[] status){

        // Wumpus about - stand and deliver
        if( status[0] ){

            nextMove = Move.SHOOT;

            switch( state ){

            case 0: // Must be in either Right or Back
                if(newGame){

                    // try Left if this is the first turn, just in case
                    nextDirection = Direction.LEFT;
                    newGame = false;

                }
                else if(shootHall) nextDirection = Direction.BACK;
                else               nextDirection = Direction.RIGHT;
                shootHall = !shootHall;
                break;
            case 2: // Must be in either Left or Back
                if(newGame){

                    // try Right if this is the first turn, just in case
                    nextDirection = Direction.RIGHT;
                    newGame = false;

                }
                else if(shootHall) nextDirection = Direction.BACK;
                else               nextDirection = Direction.LEFT;
                shootHall = !shootHall;
                break;
            default: // Must be in either Left or Right
                if(newGame){

                    // try Back if this is the first turn, just in case
                    nextDirection = Direction.BACK;
                    newGame = false;

                }
                else if(shootHall) nextDirection = Direction.RIGHT;
                else               nextDirection = Direction.LEFT;
                shootHall = !shootHall;
                break;

            }

        }else{

            // disregard state, shove out and light 'em up!
            switch( state ){

            case 0: // move out
                nextMove = Move.MOVE;
                nextDirection = Direction.LEFT;
                state++;
                break;
            case 1: // shoot right
                nextMove = Move.SHOOT;
                nextDirection = Direction.RIGHT;
                state++;
                break;
            case 2: // shoot behind
                nextMove = Move.SHOOT;
                nextDirection = Direction.BACK;
                state++;
                break;
            case 3: // shoot left
                nextMove = Move.SHOOT;
                nextDirection = Direction.LEFT;
                state = 0;
                break;

            }

        }

    }

}

FullCoverageHunter

Следует тому же кредо NascarHunter, но чередует его путь, который гарантированно образует цикл длиной 10 уникальных комнат. Так как каждая комната уникальна, и мы стреляем в каждом направлении в каждой комнате, все комнаты обстреляны Это верно для любой стартовой комнаты (постулированной моим приятелем Нилом, спасибо Нилу!). Додекаэдры такие крутые!

Я хотел бы отметить, что это отличается от нашего друга, MonsterHunter, так как он не пытается обмана или какой-либо реальной «тактики». Сила этого в том, что каждая комната снова обстреляна: решение грубой силы. Это имеет теоретическую опору для NascarHunter, поскольку Nascar поразит только 10 из 20 комнат, покрывая только половину площади.

11 июня редактировать:

Добавлен логический шаблон обнаружения Wumpus от NascarHunter. Следует объективно улучшить балл.

package Hunters;

import Mechanics.*;

public class FullCoverageHunter extends Hunter {

    private int state;
    private boolean headLeft;
    private boolean shootHall;
    private boolean newGame;

    public FullCoverageHunter(){

        name = "FullCoverageHunter";
        state = 0;
        headLeft = false;
        shootHall = true;

    }

    public void newGame() {
        state = 0;
        headLeft = false;
        newGame = true;
    }


    public void getResponse(boolean[] status){

        // Wumpus about - stand and deliver
        if( status[0] ){

            nextMove = Move.SHOOT;

            switch( state ){

            case 0: // Must be in either Right or Back
                if(newGame){

                    // try Left if this is the first turn, just in case
                    nextDirection = Direction.LEFT;
                    newGame = false;

                }
                else if(shootHall) nextDirection = Direction.BACK;
                else               nextDirection = Direction.RIGHT;
                shootHall = !shootHall;
                break;
            case 2: // Must be in either Left or Back
                if(newGame){

                    // try Right if this is the first turn, just in case
                    nextDirection = Direction.RIGHT;
                    newGame = false;

                }
                else if(shootHall) nextDirection = Direction.BACK;
                else               nextDirection = Direction.LEFT;
                shootHall = !shootHall;
                break;
            default: // Must be in either Left or Right
                if(newGame){

                    // try Back if this is the first turn, just in case
                    nextDirection = Direction.BACK;
                    newGame = false;

                }
                else if(shootHall) nextDirection = Direction.RIGHT;
                else               nextDirection = Direction.LEFT;
                shootHall = !shootHall;
                break;

            }

        }else{

            // disregard state, shove out (in an alternating fashion!) and light 'em up!
            switch( state ){

            case 0: // move out, change alternation state
                nextMove = Move.MOVE;
                if(headLeft) nextDirection = Direction.LEFT;
                else         nextDirection = Direction.RIGHT;
                state++;
                headLeft = !headLeft;
                break;
            case 1: // shoot into non-exit path
                nextMove = Move.SHOOT;
                if(headLeft) nextDirection = Direction.RIGHT;
                else         nextDirection = Direction.LEFT;
                state++;
                break;
            case 2: // shoot behind
                nextMove = Move.SHOOT;
                nextDirection = Direction.BACK;
                state++;
                break;
            default: // shoot into next room,
                nextMove = Move.SHOOT;
                if(headLeft) nextDirection = Direction.LEFT;
                else         nextDirection = Direction.RIGHT;
                state = 0;
                break;

            }

        }

    }

}

Дайте мне знать, если есть какие-либо ошибки, пакет не играл хорошо с моей IDE :(


1
Я почти уверен, что это должно называться MadMaxHunter, так как я не помню слишком много гонок NASCAR с участием перестрелки между транспортными средствами. Кажется, все хорошо!
Ральф Маршалл

Мне пришлось поставить скобки вокруг headLeft в операторах if, чтобы заставить FullCoverageHunter работать. Оба ваших бота справляются очень хорошо - NascarHunter немного лучше
euanjt

Переменная newGame в FullCoverageHunter, кажется, никогда не объявляется. Я добавил приватный логический newGame и установил для него значение true в методе newGame (), это то, что вы хотели?
Каин

@ Каин ой! Да, большой контроль со стороны меня, я отредактирую это здесь, мой плохой.
DoctorHeckle

7

барсук

Он не любит посетителей.

package Hunters;

import Mechanics.*;

public class Badger extends Hunter {

    public Badger(){
        name = "Badger";
    }

    @Override
    public void getResponse(boolean[] status){
        nextMove = Move.SHOOT;
        nextDirection = Direction.values()[((int) (Math.random() * 3))];
    }
}

6

Элмер Фадд

"Шшшш. Будь осторожен, тихий, я охочусь на глупца"

Элмер зациклен на добыче и игнорирует все, кроме трупов и Wumpus. Он пытается найти труп, затем отступает и начинает стрелять. Если он пахнет Wumpus, он отступит, и если он все еще пахнет им, он будет стрелять.

Приношу свои извинения всем Java-программистам, это, вероятно, чрезвычайно уродливо, полно синтаксических ошибок, и я, вероятно, испортил свою логику.

package Hunters;

import Mechanics.*;

public class ElmerFudd extends Hunter {

    private state int;
    private previousDir int;

    public ElmerFudd(){
        name = "ElmerFudd";
    }

    public void newGame() {
        state=0;
        previousDir = Direction.LEFT;
    }

    public void getResponse(boolean[] status){

        nextMove = Move.MOVE;
        switch (previousDir) {
            case Direction.LEFT:
                nextDirection = Direction.RIGHT;
                break;
            case Direction.RIGHT:
                nextDirection = Direction.LEFT;
                break;
        }   

        if(status[2]&&state==0) {
            state = 1;
            return;
        }

        if(state==1){
            if(status[2]){
                state=2;
            };
            nextDirection = Direction.BACK;
            return;
        }

        if(state==2){
            nextMove = Move.SHOOT;
            nextDirection = Direction.BACK;
            return;
        }

        if(state==3&&status[0])
            nextMove = Move.SHOOT;
            nextDirection = Direction.BACK;
            return;
        }

        if(state==3) {
            state = 0;
        }

        if(status[0]){
            state=3;
            nextDirection = Direction.BACK;
        }

    }
}

пацифист

Этот парень морально против любого вида кровавого спорта и удивляется, как он вообще оказался в этой ситуации. Он убежит от любого контакта и никогда не выстрелит.

package Hunters;

import Mechanics.*;

public class Pacifist extends Hunter {


    public Pacifist(){
        name = "Pacifist";
    }

    public void getResponse(boolean[] status){
        nextMove = Move.MOVE;
        if(status[0]||status[1]||status[2]||status[3]||status[4]){
            nextDirection = Direction.values()[((int) (Math.random() * 3))];
            return;
        }
        nextDirection = Direction.HERE;
    }
}

1
Я думаю, что это может сработать. Все, что вам нужно сделать в игре, - это надеяться, что кто-то получит вуплус, прежде чем он получит вас, и вы получите полный кредит.
Ральф Маршалл

1
Это была общая идея. Пусть другие делают тяжелую работу :-)
MickyT

1
Вот почему я ждал, пока вы
закодируете

5

Охотник на монстров

Мы охотимся на монстра и нам 4 года ... Это напоминает мне мою любимую игру! Этот охотник будет ходить большую часть карты, перемещаясь влево-вправо поочередно, и, если Вумпус рядом, он заманивает его, возвращаясь назад, чтобы иметь возможность точно определить, где он находится.

Я мог бы избавиться от lastDirection, но я придерживаюсь семантики и читабельности :). На самом деле, он умирает довольно часто, но контроллер часто помещает 2/3 охотника в одну и ту же комнату с самого начала, и часто рядом с Вумпусом (также может быть в той же комнате) ... так что до смерти ^^ '.

package Hunters;

import Mechanics.*;

public class MonsterHunter extends Hunter 
{
    private Direction lastDirection=Direction.HERE;
    private boolean[] lastStatus=new boolean[5];
    private int   shooted=0;
    private boolean   walkMode=true;
    private int         turnStayed=0;

    public MonsterHunter(){
        super();
        name = "MonsterHunter";
    }

    @Override
    public void getResponse(boolean[] status)
    {
        if(status[0])
        {
            if(!lastStatus[0]||shooted==0)
            {
                nextDirection=(walkMode)?Direction.RIGHT:Direction.LEFT;;
                nextMove=Move.SHOOT;
            }
            else if(lastStatus[0]&&shooted==1)
            {
                nextDirection=Direction.BACK;
                nextMove=Move.MOVE;
            }
            else
            {
                nextDirection=Direction.BACK;
                nextMove=Move.SHOOT;
            }
        }

        else if(status[2])
        {
            nextMove=Move.MOVE;
            if(Math.random()*6<turnStayed)
            {
                nextDirection=Direction.HERE;
                turnStayed++;
            }
            else
                nextDirection=(walkMode)?Direction.RIGHT:Direction.LEFT;
        }
        else
        {
            nextMove=(!status[1]&&Math.random()<0.5)?Move.MOVE:Move.SHOOT;
            nextDirection=(walkMode)?Direction.RIGHT:Direction.LEFT;
        }

        if(nextMove==Move.MOVE)
        {
            if(shooted>0)
                walkMode=walkMode^(shooted>0);
            if(lastStatus[0]&&shooted==1)
                shooted++;
            else
                shooted=0;
            lastDirection=nextDirection;
        }
        else
            shooted++;
        for(int i=0;i<status.length;i++)
            lastStatus[i]=status[i];
    }
}

Спасибо за указание на то, что контроллер установлен так, чтобы у каждого пассажира был уникальный старт
Cain

4

PacingHunter

Назад и вперед, между комнатами. если он пахнет Wumpus или слышит игрока, он стреляет влево, затем вправо. если Wumpus находится рядом с ним для начала, то он снимает комнату, в которую он переедет.

package Hunters;

import Mechanics.Direction;
import Mechanics.Hunter;
import Mechanics.Move;

public class PacingHunter extends Hunter {

    int state = 0;//Pacing
    int turn = 0;

    public PacingHunter() {
        name = "Pacer";
    }

    public void newGame() {
        turn =  0;
        state = 0;
    }

    public void getResponse(boolean[] status){
        turn += 1;
        if(state == 0 && status[0] && turn == 1){
            nextMove = Move.SHOOT;
            nextDirection = Direction.BACK;
            return;
        }
        if(state == 0 &&(status[0] || status[1])){
            nextMove = Move.SHOOT;
            nextDirection = Direction.LEFT;
            state = 1;
            return;
        }
        if(state == 1 && (status[0] || status[1])){
            nextMove = Move.SHOOT;
            nextDirection = Direction.RIGHT;
            state = 0;
            return;
        }
        if(status[1] && state == 0){
            nextMove = Move.SHOOT;
            nextDirection = Direction.BACK;
            state = 0;
            return;

    }
    nextMove = Move.MOVE;
    nextDirection = Direction.BACK;
}

}


4

Напуганная кошка

ScaredyCat боится всего. Если он пахнет wumpus или трупом или слышит стрелу или охотника, он бежит в случайном направлении. В противном случае он просто продолжает стрелять в случайных направлениях.

package Hunters;

import Mechanics.*;

public class ScaredyCat extends Hunter {

    public ScaredyCat(){
        name = "ScaredyCat";
    }

    @Override
    public void getResponse(boolean[] status){

        for(int i=0; i<status.length; i++)
            if(status[i])
            {
                nextMove = Move.MOVE;
                nextDirection = Direction.values()[((int) (Math.random() * 3))];
                return;
            }

        nextMove = Move.SHOOT;
        nextDirection = Direction.values()[((int) (Math.random() * 3))];
    }
}

6
Lol Я не знаю, было ли это преднамеренным, но он напугает себя, стреляя стрелами, и затем убежит.
Каин

4

Ест побеги и листья

В отличие от «Панды грамматики», этот охотник на самом деле ничего не ест, но мы либо стреляем, если вокруг Вумпус, либо уходим на тропу, которая, как мы надеемся, не позволит нам ходить по кругу.

package Hunters;

import java.util.Random;

import Mechanics.Hunter;
import Mechanics.Move;
import Mechanics.Direction;
import Mechanics.Room;

public class EatsShootsAndLeaves extends Hunter {

    private static Direction [] allDirections = { Direction.LEFT, Direction.RIGHT, Direction.BACK, Direction.HERE };
    private static Direction [] movePath = { Direction.LEFT, Direction.RIGHT, Direction.LEFT, Direction.BACK, Direction.RIGHT, Direction.BACK };

    private static int numGames = 0;
    private static int totalLife = 0;

    private static class RoomInfo  {

        public boolean hasWumpus = false;
        public boolean hasLocalHunter = false;
        public boolean hasNeighborHunter = false;
        public boolean hasCorpse = false;
        public boolean hasArrow = false;
        public RoomInfo(Room r) {
            boolean [] status = r.getInfo();
            hasWumpus = status[0];
            hasNeighborHunter = status[1];
            hasCorpse = status[2];
            hasArrow = status[3];
            hasLocalHunter = status[4];
        }

        public String toString() {
            return new String("Status: "
                              + (hasWumpus ? "Wumpus " : "")
                              + (hasNeighborHunter ? "Close Hunter " : "")
                              + (hasCorpse ? "Corpse " : "")
                              + (hasArrow ? "Arrow " : "")
                              + (hasLocalHunter ? "Local Hunter " : ""));
        }
    }

    int turnsAlive = 0;
    int shots = 0, moves = 0;

    public EatsShootsAndLeaves(){
        name = "Eats Shoots and Leaves";
    }

    public void newGame() {

        totalLife += turnsAlive;
        numGames++;

        turnsAlive = shots = moves = 0;
    }

    public void getResponse(boolean[] status){

        turnsAlive++;

        RoomInfo info = new RoomInfo(this.getRoom());
        if (info.hasNeighborHunter || info.hasWumpus) {
            nextMove = Move.SHOOT;
            nextDirection = allDirections[shots++ % 3];
        } else {
            nextMove = Move.MOVE;
            nextDirection = movePath[moves++ % movePath.length];
        }
    }
}

3

Идоменей

Идоменей довольно прост - если поблизости находится Вумпус или другой охотник, он везде стреляет в сарроу и молится, чтобы богиня охоты была на его стороне. Если он рядом с трупом, он подстерегает Wumpus. Он не любит других охотников и убежит, если они начнут стрелять рядом с ним, или если они находятся в той же комнате, что и он. Наконец, если ему скучно, он случайно зашагает по вечным коридорам.

package Hunters;
import Mechanics.Direction;
import Mechanics.Hunter;
import Mechanics.Move;
import java.util.Random;



public class Idomeneus extends Hunter
{
    int direction;
    Random r;
    public Idomeneus()
    {
        super();
        name = "Idomeneus";
        direction = 0;
        r = new Random();
    }

    @Override
    public void getResponse(boolean[] status){
        boolean wumpusNear = status[0];
        boolean hunterNear = status[1];
        boolean corpseNear = status[2];
        boolean arrowNear = status[3];
        boolean hunterHere = status[4];
        direction++;

        if(wumpusNear)
        {
            //ATTACK!!!
            nextMove = Move.SHOOT;
            nextDirection = Direction.values()[direction%3];
        }
        else if(hunterHere || arrowNear)
        {
            //Run away
            nextMove = Move.MOVE;
            nextDirection = Direction.values()[r.nextInt(3)];
        }
        else if(hunterNear)
        {
            //ATTACK!!!
            nextMove = Move.SHOOT;
            nextDirection = Direction.values()[direction%3];
        }
        else if(corpseNear)
        {
            //Stay and wait...
            nextMove = Move.MOVE;
            nextDirection = Direction.HERE;
        }
        else
        {
            //wander around
            nextMove = Move.MOVE;
            nextDirection = Direction.values()[r.nextInt(3)];
        }

    }

    public void newGame(){}



}

Будьте осторожны: согласно @Cain, вы можете застрелить себя, если будете стрелять в свою комнату.
DoctorHeckle

3

Эмо Вумпус (Охотник)

Эмо Вумпусы (связанные с Эмо Волками, которые иногда используют оружие и летают самолеты ) ненавидят все (особенно Java). Они не делают различий между Охотниками и Вумпусами и все равно пытаются их застрелить. Они также ненавидят водителей Nascar и всегда будут стрелять правильно. Если никого нет рядом, чтобы стрелять, они двигаются вправо, но будут делать это тринадцать раз подряд, прежде чем они будут еще более подавлены одиночеством и попытаться застрелиться (тринадцать - неудачное число). На 99-м ходу, если они все еще живы, они попытаются застрелиться, потому что голод - такой неудачный способ умереть.

Вумпусы крупнее (и тяжелее) волков, но этот по-прежнему голодает до 424 байт (в отличие от здоровенных 2,72 кб NascarHunter).

package Hunters;import Mechanics.*;public class EmoWumpus extends Hunter{private int c, t;public EmoWumpus(){name="Emo Wumpus";this.c=0;this.t=0;}public void newGame(){this.c=0;this.t=0;}public void getResponse(boolean[] status){nextMove=Move.SHOOT;if(c<13 && t<100){if(status[0]||status[1]){nextDirection=Direction.RIGHT;}else{nextMove=Move.MOVE;nextDirection=Direction.RIGHT;c++;}}else{nextDirection=Direction.HERE;}t++;}}

Почему бы просто не покончить жизнь самоубийством? Эмо Вумпусы верят, что единственный поступок добра, который может сделать, - это положить конец страданиям других, прежде чем убить себя. Поэтому они убьют все, что могут, прежде чем наступит их время умирать.

Wumpus? (Анти-Хантер)

Хм, что делает Вумпус в списке охотников? Этот парень очень разозлился, что люди убивают его родственников, поэтому он решил одеться как один из них и присоединиться к охоте. Его главная цель - просто убивать охотников. Он пытается спрятаться возле трупов, что даст ему шанс защитить щит от охотников. Если поблизости нет охотников, он будет двигаться в направлении, пока охотники не будут обнаружены, и в этом случае он попытается убить их, прежде чем двигаться в другом направлении.

К сожалению, большинство Wumpus глупы, и все еще собираются попытаться убить его. Несмотря на это, он считает свои жертвы необходимыми во благо Вумпусов повсюду.

package Hunters;

import Mechanics.*;

public class AntiHunter extends Hunter {

private boolean left;

public AntiHunter() {
    name = "Wumpus";
    this.left = true;
}

public void newGame() {
    this.left = true;
}

public void getResponse(boolean[] status) {
    if(status[4]) {
        nextMove = Move.SHOOT;
        nextDirection = Direction.HERE;
    }
    else if(status[2] || status[1]) {
        nextMove = Move.SHOOT;
        if(this.left) {
            this.left = false;
            nextDirection = Direction.LEFT;
        }
        else {
            this.left = true;
            nextDirection = Direction.RIGHT;
        }
    }
    else {
        nextMove = Move.MOVE;
        if(this.left)
            nextDirection = Direction.LEFT;
        else
            nextDirection = Direction.RIGHT;
    }
}

}



Хорошо, что это не код гольф. Интересно, сколько времени пройдет, пока не появится бот Emo, лол.
Доктор Хекл

@ Мартин Обратите внимание, что это не просто самоубийство. Из ботов, доступных для тестирования, он не занял последнее место.
Майкл Брэндон Моррис

1
EmoSolution - это всегда весело!
Мауг

2

Laomedon

Лаомедон бесцельно бродит, пытаясь найти труп. Как только он нашел его и выяснил, где он, он остался в том же месте рядом с трупом. Когда он чувствует запах Wumpus, он стреляет стрелами в комнату Трупа.

package Hunters;
import Mechanics.Direction;
import Mechanics.Hunter;
import Mechanics.Move;
public class Laomedon extends Hunter {
    private enum status
    {
        START,
        SEARCHED_LEFT,
        SEARCHED_RIGHT,
        INITIAL_CORPSE_LEFT,
        INITIAL_CORPSE_RIGHT,
        SMELT_CORPSE,
        CORPSE_BEHIND,
        CORPSE_LEFT
    }

    status myState;
    public Laomedon() {
        this.name = "Laomedon";
    }
    @Override
    public void getResponse(boolean[] status) {
        boolean wumpusNear = status[0];
        boolean hunterNear = status[1];
        boolean corpseNear = status[2];
        boolean arrowNear = status[3];
        boolean hunterHere = status[4];
        switch (myState) {
        case CORPSE_BEHIND:
            if(wumpusNear)
            {
                this.nextDirection = Direction.BACK;
                this.nextMove = Move.SHOOT;
            }
            else
            {
                this.nextDirection = Direction.HERE;
                this.nextMove = Move.MOVE;
            }
            break;
        case CORPSE_LEFT:
            if(wumpusNear)
            {
                this.nextDirection = Direction.LEFT;
                this.nextMove = Move.SHOOT;
            }
            else
            {
                this.nextDirection = Direction.HERE;
                this.nextMove = Move.MOVE;
            }
            break;
        case INITIAL_CORPSE_LEFT:
            if(corpseNear)
            {
                this.nextDirection = Direction.RIGHT;
                this.nextMove = Move.MOVE;
                this.myState = Laomedon.status.INITIAL_CORPSE_RIGHT;
            }
            else
            {
                this.nextDirection = Direction.BACK;
                this.nextMove = Move.MOVE;
                this.myState = Laomedon.status.SEARCHED_LEFT;
            }
            break;
        case INITIAL_CORPSE_RIGHT:
            if(corpseNear)
            {
                this.nextDirection = Direction.LEFT;
                this.nextMove = Move.MOVE;
                myState = Laomedon.status.INITIAL_CORPSE_LEFT;
            }
            else
            {
                this.nextDirection = Direction.BACK;
                this.nextMove = Move.MOVE;
                this.myState = Laomedon.status.SEARCHED_LEFT;
            }
            break;
        case SEARCHED_LEFT:
            if(corpseNear)
            {
                this.nextDirection = Direction.LEFT;
                this.nextMove = Move.MOVE;
                this.myState = Laomedon.status.SMELT_CORPSE;
            }
            else
            {
                this.nextDirection = Direction.RIGHT;
                this.nextMove = Move.MOVE;
                this.myState = Laomedon.status.SEARCHED_RIGHT;
            }
            break;
        case SEARCHED_RIGHT:
            if(corpseNear)
            {
                this.nextDirection = Direction.LEFT;
                this.nextMove = Move.MOVE;
                this.myState = Laomedon.status.SMELT_CORPSE;
            }
            else
            {
                this.nextDirection = Direction.LEFT;
                this.nextMove = Move.MOVE;
                this.myState = Laomedon.status.SEARCHED_LEFT;
            }
            break;
        case SMELT_CORPSE:
            if(corpseNear)
            {
                this.nextDirection = Direction.BACK;
                this.nextMove = Move.MOVE;
                this.myState = Laomedon.status.CORPSE_BEHIND;
            }
            else
            {
                this.nextDirection = Direction.BACK;
                this.nextMove = Move.MOVE;
                this.myState = Laomedon.status.CORPSE_LEFT;
            }
            break;
        case START:
            if(corpseNear)
            {
                this.nextDirection = Direction.LEFT;
                this.nextMove = Move.MOVE;
                this.myState = Laomedon.status.INITIAL_CORPSE_LEFT;
            }
            else
            {
                this.nextDirection = Direction.LEFT;
                this.nextMove = Move.MOVE;
                this.myState = Laomedon.status.SEARCHED_LEFT;
            }
            break;
        }
    }

    @Override
    public void newGame() {

        super.newGame();
        myState = status.START;
    }
}

К сожалению для него, другие охотники не ценят его навыки, и они, кажется, стреляют в него много ...


2

NealHunter

Поговорив об этом с моим другом Доктором Хеклом, я подумал, что было бы весело попробовать самому. Использовал идею чередования влево и вправо, чтобы охватить большую часть области, а затем решил добавить немного отклика на состояния, но только 0 и 1 - независимо от того, находятся ли Wumpus или охотник поблизости. Не так хорошо, как NascarHunter, что меня сначала удивило. Поразмыслив, я понял, что стрелка в случайном направлении (как это делает), услышав, как охотник / пахнет вумпусом, ничего не сделает, если он движется в этом повороте, поскольку стрелы попадают в комнаты, но движение проводится, прежде чем он убивает их. Не так эффективно, как я думал ... но все же хорошо работает!

package Hunters;

import Mechanics.*;
import java.util.Random;

public class NealHunter extends Hunter {

    private boolean goLeft;

    public NealHunter(){
        name = "NealHunter";
        goLeft = false;
    }

    public void newGame() {
        goLeft = false;
    }

    public void getResponse(boolean[] status){

        Random rand = new Random();

        if(status[0] || status[1]){
            nextMove = Move.SHOOT;

            switch ( rand.nextInt(3) ){
                case 0:
                    nextDirection = Direction.LEFT;
                    break;
                case 1:
                    nextDirection = Direction.BACK;
                    break;
                case 2:
                    nextDirection = Direction.RIGHT;
                    break;
            }
        } else {
            nextMove = Move.MOVE;
            if (goLeft) {
                nextDirection = Direction.LEFT;
            } else {
                nextDirection = Direction.RIGHT;
            }

            goLeft = !goLeft;
        }
    }
}

1

WalkingIdiot

Этот ходит, пока он не найдет Wumpus. Затем он стреляет прямо. Если wumpus все еще там, он должен быть слева, поэтому стреляйте еще раз. По дороге ему нет дела до других охотников или трупов, отсюда и название.

package Hunters;

import Mechanics.*;

public class WalkingIdiot extends Hunter {
    private boolean wumpusNear = false;

    @Override
    public void newGame() {
        wumpusNear = false;
    }

    public WalkingIdiot(){
        name = "WalkingIdiot";
    }

    @Override
    public void getResponse(boolean[] status){
        boolean wumpusWasNear = wumpusNear;
        wumpusNear = status[0];
        if (status[0]) {
            nextMove = Move.SHOOT;
            if (wumpusWasNear) {
                nextDirection = Direction.LEFT;
            } else {
                nextDirection = Direction.RIGHT;
            }
            return;
        }
        nextMove = Move.MOVE;
        nextDirection = Math.random() < 0.5 ? Direction.LEFT : Direction.RIGHT;
    }
}

Остаться

Пребывание не любит гулять. Он просто стреляет и вспоминает, стрелял ли он в охотника.

package Hunters;

import Mechanics.*;

public class Stay extends Hunter {
    private Direction lastShot = Direction.LEFT;
    private Direction corpse = null;
    private boolean hunterNear = false;

    public Stay(){
        name = "Stay";
    }

    @Override
    public void newGame() {
        corpse = null;
        hunterNear = false;
        lastShot = Direction.LEFT;
    }

    @Override
    public void getResponse(boolean[] status){
        nextMove = Move.SHOOT;//always
        boolean hunterWasNear = hunterNear;
        hunterNear = status[1];

        if (hunterWasNear && status[2] && !status[1]) {
            corpse = lastShot;
        }

        if (status[0]) {
            if (corpse != null) {
                nextDirection = corpse;
                return;
            }
        }
        if ((status[1] && !status[4]) || status[0]) {
            switch (lastShot) {
                case LEFT: lastShot = nextDirection = Direction.RIGHT; break;
                case RIGHT: lastShot = nextDirection = Direction.BACK; break;
                case BACK: lastShot = nextDirection = Direction.LEFT; break;
            }
            return;
        }

        //default
        lastShot = nextDirection = Direction.LEFT;
    }
}
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.