Велике полювання на Wumpus


22

ЗАВЕРШИТИ

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

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

Гра

Заснований на класичній грі Hunt the Wumpus з кількома варіаціями.

Карта

Додекаедр . Є 20 кімнат, кожна з яких пов'язана з 3 іншими приміщеннями, в основному 3 кільця з мостами між ними.

Вумпус

Wumpus - містичний звір. Ніхто не впевнений, як це виглядає, але всі згодні, що це люто. Wumpus живе в печерах і любить їсти мертві речі. Якщо в печері поруч із Вумпом є труп, він переїде туди і з’їсть його. Якщо Wumpus трапиться в печеру, яка містить мисливців, він також вб'є і з'їсть їх. Якщо Вумп почує стрілу біля себе, він впаде в паніку і вбігає в випадкову кімнату.

Необов’язкові риси : вони зараз включені, щоб зробити гру цікавішою, але їх можна видалити за запитом населення, якщо вони додадуть занадто багато випадковості.

Розлючений Wumpus: Якщо Wumpus застрелений, у нього 20% вижили та вирували протягом 3 днів. Під час скандалу він випадковим чином рухатиметься двічі на день, але все ж буде притягуватися до трупів. Через 3 дні він помре. Другий постріл зі стріли також вб’є Вумпуса.

Блукаючий Wumpus: Кожен день, якщо нічого іншого не викликає Wumpus, у нього є 25% шанс переїхати.

Мисливці

Чотири мисливці можуть зайти одночасно в печери. Печери темні, тому мисливці не бачать, але вони можуть використовувати свої інші почуття. Мисливці можуть понюхати Вумпуса в сусідній кімнаті, понюхати труп у сусідній кімнаті, почути інших мисливців, що рухаються по сусідніх кімнатах, і почути, чи стріляє стріла в сусіднє приміщення.

Мисливці мають дві дії: стріляти або рухатись. Мисливець може стріляти зі стріли у сусідню кімнату чи власну кімнату та рухатися аналогічно.

Ігровий процес

У кожному раунді мисливці спочатку відзначають своє оточення, а потім роблять один хід. Рух відбувається перед стрілами, тож якщо стріла застрелиться в приміщення, з якого мисливець виїжджає, мисливець виживе. Після того, як всі ходи мисливця зроблені, стрілки оцінюються. Якщо один мешканець і стріла знаходяться в одній кімнаті, мешканець буде застрелений і загине. Якщо двоє або більше мешканців розділяють кімнату, один випадковим чином потрапить і помре. Примітка: трупи - це мешканці, тому тіло мертвого може служити частковим щитом.

Після всіх рухів мисливця Wumpus відповість. Якщо мисливець переїхав до кімнати з вовчиками, то Wumpus з'їсть його. Якщо Wumpus переміститься, він також поїсть мешканців нової кімнати.

Через 100 днів, якщо мисливці не вбили Wumpus чи жертву, вони помруть від голоду в печерах.

Кодекс

Весь вихідний код можна знайти тут . Усі матеріали повинні бути на Java, якщо хтось не хоче написати мені адаптер stdIn / stdOut;)

Боти повинні поширити клас Хантера. Щоб назвати свого мисливця, додайте конструктор без параметрів, який встановлює поле імені. Не реагуйте, замініть функцію getResponse. У цій функції кожного кроку вам буде передано масив із 5 булей, який розповість про ваше оточення.

status 0 = "Ви відчуваєте запах вумпу"

status 1 = "Ви чуєте іншого мисливця"

status 2 = "Ви понюхаєте труп"

status 3 = "Ви чуєте клацання стрілки"

status 4 = "Ви відчуваєте іншого мисливця в тій же кімнаті, що і ви"

Клас Hunter має два слоти: nextMove та nextDirection, які використовують перелітки Move та Direction відповідно. Переміщення може бути або ПОВЕРНЕНО, або ЗІГ, перенаправлення може бути Вліво, Вправо, НАЗАД або ТУТ Вказівки послідовні, тобто назад завжди поверне вас до попередньої кімнати, в якій ви були, і якщо ви входите з тієї ж кімнати, ліворуч і праворуч завжди будуть однакові. Однак якщо ви в’їдете з іншого напрямку, ліворуч і праворуч перевезуть вас у різні місця.

Сміливо реалізуйте і свої власні методи. Пам'ять зберігається протягом усього турніру, тобто ваш мисливець буде побудований лише один раз. Однак на початку кожного раунду застосовується метод newGame (), щоб ваш мисливець знав, що почалася нова гра.

Оцінка балів

Чотири мисливці змагаються одночасно. Якщо вбити, шкірка Wumpus коштує 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
Yessir, або ти сам, якщо стріляєш ТУТ
Каїн

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

1
@DoctorHeckle Впевнені, що ми маємо, але все-таки більш приємним для розробників є масив, а не один int ^^.
Katenkyo

1
Що стосується стріл та трупів, якщо ви перебуваєте в одній кімнаті, ви отримуєте такий самий статус, як ніби він суміжний. Мисливці - єдині, яких можна розрізнити, що знаходяться поруч із кімнатою чи в кімнаті.
Каїн

Відповіді:


11

NascarHunter

Не так багато логіки до цього. Його правила прості: поверніть ліворуч, випалену землю, повторіть. І, ей, він може пощастить!

8 червня редагувати:

Додано в Наскара додаткову логіку для обліку примикання до 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, оскільки Наскар потрапить лише на 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, оскільки я не пригадую надто багато перегонів НАСКАР, що включають перестрілки між транспортними засобами. Здається, що добре!
Ральф Маршалл

Мені довелося ставити дужки навколо headLeft у висловлюваннях if, щоб змусити FullCoverageHunter працювати. Обидва ваші боти справляються дуже добре - NascarHunter трохи краще
euanjt

Змінна newGame в FullCoverageHunter, здається, ніколи не декларується. Я додав приватну булеву newGame і встановив її як істинну у методі newGame (), це те, що ви задумали?
Каїн

@Cain whoops! Так, великий нагляд від мене, я відредагую це тут, мій поганий.
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

Елмер Фудд

"Shhh. Будь vewy vewy тихо, я полюю 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

MonsterHunter

Ми полюємо на монстра, і нам 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];
    }
}

Дякуємо за те, що вказали, що контролер закріплений, щоб кожен житель мав унікальний старт
Каїн

4

PacingHunter

Туди-сюди, між кімнатами. якщо він пахне 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

ScaredyCat боїться всього. Якщо він пахне вербою або трупом або чує стрілу чи мисливця, він біжить у випадковий бік. В іншому випадку він просто продовжує стріляти стрілками у випадкових напрямках.

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

Їсть пагони та листя

На відміну від Панди слави з граматики, цей мисливець насправді нічого не їсть, але ми або стріляємо, якщо збирається Wumpus, або залишаємо слід, який, сподіваємось, утримує нас від ходьби по колах.

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 або інший мисливець, він скрізь розпалює воронів і молиться, щоб богиня полювання була на його боці. Якщо він поруч з трупом, він чекає 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

Емо Вумп (мисливець)

Емо Wumpuses (пов'язані з Емо Вовками, які іноді використовують гармати та літають літаки ) ненавидять все (особливо Яву). Вони не роблять різниці між Мисливцями та Вимпусами, і намагаються все одно їх стріляти. Вони також ненавидять водіїв Nascar, і завжди будуть стріляти правильно. Якщо нікого немає навколо, щоб стріляти, вони рухаються праворуч, але робитимуть це лише тринадцять разів поспіль, перш ніж вони ще більше пригнічуватимуться на самоті та спробують стріляти самі (тринадцять - це невдале число). На 99 років, якщо вони ще живі, вони спробують застрелити себе, бо голодування - такий кульгавий спосіб померти.

Wumpuses є більшими (і важчішими), ніж Вовки, але цей все ще голодував до 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 робить на реєстрі мисливців? Цей хлопець дуже розсердився, що люди вбивають його родича, тому він вирішив переодягнутися як один із них і приєднатися до полювання. Його головна мета - просто вбити мисливців. Він намагається сховатися біля трупів, що дасть йому шанс на щиті від мисливців. Якщо поруч немає мисливців, він рухатиметься в напрямку, поки мисливці не будуть виявлені, і в цьому випадку він спробує їх вбити, перш ніж рухатися в інший бік.

На жаль, більшість Wumpuses дурні, і все ще збираються його вбити. Незалежно від того, він вважає свої жертви необхідними для блага Wumpuses скрізь.

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, хаха.
DoctorHeckle

@Martin Зауважте, що це не просто самогубство. Із ботів, доступних для тестування, він не став останнім.
Майкл Брендон Морріс

1
EmoSolution - завжди смішно!
Mawg

2

Лаомедон

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

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, що мене спочатку здивувало. Однак, подумавши, я зрозумів, що стріляючи стрілою у випадковому напрямку (як це робиться) після того, як почути мисливця / нюху Wumpus, нічого не зробить, якщо вони рухатимуться поворотом, оскільки стрілки стріляють у кімнати, а рух проводиться до того, як їх вбиває. Не настільки ефективний, як я думав ... все-таки добре працює!

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

ПрогулянкаІдіот

Цей ходить, поки не знайде вімп. Потім він стріляє прямо. Якщо вим’я все ще є, він повинен знаходитися зліва, тому стріляйте ще раз. До речі, йому не байдуже до інших мисливців чи трупів, звідси і назва.

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.