A Grande Caça Wumpus


22

COMPLETO

A temporada de Wumpus terminou e com a vida de muitos Wumpus cruéis e corajosos Hunter. Assim como alguns caçadores covardes, imorais e absolutamente estúpidos. Mas no final do dia, o NascarHunter, do Dr. Heckle, saiu com o maior tesouro e glória. Saudamos você, oh corajoso ... motorista?

É temporada aberta em Wumpuses, e caçadores de todo o mundo estão se reunindo nas cavernas de Wumpus para tentar ficar rico com os valiosos Wumpus Pelts.

O jogo

Baseado no clássico jogo Hunt the Wumpus , com algumas variações.

O mapa

Um dodecaedro . Existem 20 quartos, cada um conectado a outros 3 quartos, fazendo basicamente 3 anéis com pontes no meio.

The Wumpus

O Wumpus é um animal místico. Ninguém sabe ao certo o que parece, mas todos concordam que é feroz. O Wumpus vive nas cavernas e gosta de comer coisas mortas. Se houver um cadáver em uma caverna ao lado dos Wumpus, ele se mudará para lá e o comerá. Se o Wumpus se mudar para uma caverna contendo caçadores, ele também os matará e os comerá. Se o Wumpus ouvir uma flecha perto dele, ele entrará em pânico e entrará em uma sala aleatória.

Características opcionais : elas estão atualmente incluídas para tornar o jogo mais interessante, mas podem ser removidas a pedido popular se adicionarem muita aleatoriedade.

Wumpus Enraivecido: Se o Wumpus é baleado, ele tem 20% de sobrevivência e furor por 3 dias. Quando se enfurece, ele se move aleatoriamente duas vezes por dia, mas ainda se sente atraído por cadáveres. Após 3 dias, ele vai morrer. Uma segunda flecha também matará os Wumpus.

Wumpus errante: Todos os dias, se nada mais desencadeia o Wumpus, ele tem 25% de chance de se mover.

Os caçadores

Quatro caçadores podem entrar nas cavernas de cada vez. As cavernas são escuras, então os caçadores não podem ver, mas podem usar seus outros sentidos. Os caçadores podem cheirar os Wumpus em uma sala adjacente, cheirar um cadáver em uma sala adjacente, ouvir outros caçadores se movendo em salas adjacentes e ouvir se uma flecha é disparada para uma sala adjacente.

Os caçadores têm duas ações: Atire ou mova. Um caçador pode atirar uma flecha em uma sala adjacente ou em seu próprio quarto e se mover da mesma forma.

Jogabilidade

Em cada rodada, os caçadores tomam nota do ambiente e, em seguida, fazem um movimento. O movimento ocorre antes das flechas; portanto, se uma flecha for lançada em uma sala da qual um caçador está saindo, o caçador sobreviverá. Após todos os movimentos do caçador, as setas são avaliadas. Se um único ocupante e uma flecha estiverem na mesma sala, o ocupante será baleado e morrerá. Se dois ou mais ocupantes dividirem um quarto, um será aleatoriamente atingido e morto. Nota: Os cadáveres são ocupantes; portanto, um corpo morto pode servir como um escudo parcial.

Depois que todos os caçadores se moverem, o Wumpus responderá. Se um caçador se mudar para a sala com os Wumpus, os Wumpus o comerão. Se o Wumpus se mover, ele também comerá os ocupantes da nova sala.

Depois de 100 dias, se os caçadores não mataram os Wumpus ou foram vítimas, morrerão de fome nas cavernas.

O código

Todo o código fonte pode ser encontrado aqui . Todos os envios devem ser em Java, a menos que alguém queira me escrever um adaptador stdIn / stdOut;)

Bots devem estender a classe Hunter. Para nomear seu Hunter, adicione um construtor sem parâmetros que defina o campo de nome. Para responder, substitua a função getResponse. Nesta função, a cada turno, você recebe uma série de 5 booleanos que informa sobre o ambiente.

status 0 = "Você cheira um wumpus"

status 1 = "Você ouve outro caçador"

status 2 = "Você cheira um cadáver"

status 3 = "Você ouve um som de flecha"

status 4 = "Você sente outro caçador na mesma sala que você"

A classe Hunter possui 2 slots: nextMove e nextDirection, que usam as enumerações Move e Direction, respectivamente. O movimento pode ser Mover ou Atirar, a direção pode ser ESQUERDA, DIREITA, TRÁS ou AQUI. As instruções são consistentes, ou seja, voltar sempre o levará para a sala anterior em que você estava e, se estiver entrando na mesma sala, ESQUERDA e DIREITA serão sempre as mesmas. No entanto, se você entrar de uma direção diferente, ESQUERDA e DIREITA o levarão a lugares diferentes.

Sinta-se à vontade para implementar seus próprios métodos também. A memória é persistente durante todo o torneio, o que significa que o seu caçador será construído apenas uma vez. No entanto, no início de cada rodada, o método newGame () é chamado para informar ao seu caçador que um novo jogo foi iniciado.

Pontuação

Quatro caçadores competem de cada vez. Se morto, a pele de Wumpus vale 60 pontos, dividida igualmente entre todos os caçadores sobreviventes. Estilo robin round completo, para que cada combinação de 4 caçadores jogue juntos.

Estão incluídos 5 caçadores de amostra: 4 com funcionalidade muito básica e um que permite que a entrada do usuário seja reproduzida, para fins de teste.

Se você tiver alguma sugestão / solicitação, entre em contato!

O fim está à vista!

A população mundial de Wumpus está sendo caçada a um ritmo alarmante. A lei Protect Our Wumpuses deve ser aprovada na quarta-feira, 17 de junho. Após essa data, não serão mais permitidos caçadores nas cavernas, e um vencedor será escolhido.

Placar

Nota: Minhas desculpas, houve um erro no código que poderia fazer com que os Hunters permanecessem mortos por vários jogos. Depois de corrigi-lo, ele não altera muito a classificação geral, mas altera muito as estatísticas.

As pontuações estão chegando, executando cada conjunto de caçadores em 1000 jogos cada. O NascarHunter e o FullCoverageHunter lideram o grupo, e embora a adição do AntiHunter tenha dado aos Wumpuses um aumento de 2% na sobrevivência, eles ainda estão tremendo de pés sugados à taxa de sobrevivência de 32% do gênero. Flechas de companheiros caçadores são mais do que nunca a maior ameaça nas cavernas.

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
Você pode acertar outro caçador com uma flecha?
MegaTom 3/15

1
Yessir, ou a si mesmo, se você atirar uma flecha no HERE
Caim

1
Em vez de uma matriz para 5 booleanos, por que não passar apenas um intvalor de 0 a 31? Nós somos garotos grandes aqui, podemos fazer operações de bits :) #
4500

1
@DoctorHeckle Claro que sim, mas ainda é mais amigável ao desenvolvedor ter uma matriz em vez de um único int ^^.
precisa

1
Para flechas e cadáveres, se um estiver na mesma sala que você, obtém o mesmo status como se fosse adjacente. Os caçadores são os únicos que você pode distinguir entre estar próximo à sala ou na sala.
Caim

Respostas:


11

NascarHunter

Não há muita lógica nisso. Suas regras são simples: vire à esquerda, terra arrasada, repita. E, ei, ele pode ter sorte!

8 de junho editar:

Adicionado na lógica adicional da Nascar para considerar a adjacência de um Wumpus em relação à sua última jogada. Considere um pit stop, para manter o tema. Se sentir um Wumpus depois de disparar por um corredor, deve ter chegado a uma das outras duas salas adjacentes, já que teria morrido com o tiro que o caçador acabou de dar. Ele efetivamente dá o Wumpus 2 para viver se ele não se mover novamente, ou o Nascar 1 para viver se ele estiver em pé sobre um cadáver. Também é responsável por uma terceira opção, se for a primeira vez, mas apenas uma vez. Eu irei para FCH eventualmente, ocupado ocupado.

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

Segue o mesmo credo do NascarHunter, mas alterna seu percurso, que garante um loop de 10 quartos únicos. Como cada quarto é único e disparamos em todas as direções por quarto, todos os quartos são queimados. Isso é verdade para qualquer sala de partida (postulada por meu amigo Neal, obrigado Neal!). Dodecaedros são bem legais assim!

Eu gostaria de ressaltar que isso é diferente do nosso amigo MonsterHunter, pois ele não tenta nenhum truque ou "tática" real. A força disso é o fato de que todos os cômodos são incendiados novamente: a solução da força bruta. Isso tem uma vantagem teórica sobre o NascarHunter, já que o Nascar atingirá apenas 10 dos 20 quartos, cobrindo apenas metade da área.

11 de junho editar:

Adicionado no padrão lógico de detecção Wumpus do NascarHunter. Objetivamente deve melhorar a pontuação.

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;

            }

        }

    }

}

Deixe-me saber se houver algum erro, o pacote não foi bom com o meu IDE :(


1
Tenho certeza de que isso deve se chamar MadMaxHunter, pois não me lembro de muitas corridas da NASCAR envolvendo tiros entre veículos. Parece fazer bem!
Ralph Marshall

Eu tive que colocar colchetes em torno do headLeft nas instruções if para fazer o FullCoverageHunter funcionar. Ambos os seus bots fazem muito bem- O NascarHunter é um pouco melhor
euanjt 5/15

A variável newGame no FullCoverageHunter parece nunca ser declarada. Adicionei um newGame booleano privado e o configurei como true no método newGame (). Foi isso que você pretendeu?
Caim

@Cain whoops! Sim, grande supervisão minha, eu vou editar isso aqui, meu mal.
DoctorHeckle

7

Texugo

Ele não gosta de visitantes.

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

Elmer Fudd

"Shhh. Seja vewy vewy quieto, eu estou caçando wumpus"

Elmer é fixado na presa e ignora tudo, exceto cadáveres e os Wumpus. Ele tenta encontrar um cadáver, depois recua e começa a atirar. Se ele cheirar um Wumpus, ele recuará e se ainda o cheirar, atirará.

Minhas desculpas a todos os programadores java, isso é provavelmente extremamente feio, cheio de erros de sintaxe e eu provavelmente baguncei minha lógica.

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

    }
}

Pacifista

Esse cara é moralmente contra qualquer tipo de esporte de sangue e se pergunta como ele apareceu nessa situação. Ele foge de qualquer tipo de contato e nunca tira uma foto.

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
Eu acho que isso pode funcionar. Tudo o que você precisa fazer em um jogo é esperar que alguém receba o wumpus antes que você receba e você receba todo o crédito.
Ralph Marshall

1
Essa foi a ideia geral. Deixe os outros fazer o trabalho duro :-)
MickyT

1
É por isso que eu esperei que você codificasse isso, mesmo que eu pensasse primeiro :-) #
077 Mawg as

5

Caçador de monstros

Estamos caçando um monstro e temos 4 anos ... Isso me lembra o meu jogo favorito! Esse caçador percorrerá a maior parte do mapa movendo-se da esquerda para a direita, alternativamente, e se o Wumpus estiver próximo, ele o atrairá retrocedendo para poder determinar com precisão onde está.

Eu poderia me livrar do lastDirection, mas mantenho a semântica e a legibilidade :). Na verdade, ele morre bastante, mas o controlador geralmente coloca 2/3 de caçador na mesma sala no início, e muitas vezes com os Wumpus próximos (também podem estar na mesma sala) ... então instale a morte ^^ '.

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

Obrigado por apontar isso, o controlador é fixada de modo que cada ocupante tem um começo único
Cain

4

PacingHunter

Para a frente e para trás, entre os quartos. se cheira a um Wumpus ou ouve um jogador, atira para a esquerda e para a direita. se um Wumpus está ao seu lado, ele dispara na sala para a qual ele se mudará.

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 tem medo de tudo. Se cheira a um wumpus ou um cadáver ou ouve uma flecha ou um caçador, corre para uma direção aleatória. Caso contrário, ele simplesmente dispara flechas em direções aleatórias.

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 Não sei se isso foi intencional, mas ele se assustará atirando flechas e depois correndo.
Caim

4

Come brotos e folhas

Ao contrário do Panda da fama dos livros de gramática, esse caçador não come nada, mas nós filmamos se o Wumpus estiver por perto ou deixamos uma trilha que, com sorte, deve nos impedir de andar em círculos.

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

Idomeneus

Idomeneus é bem simples: se o Wumpus ou outro caçador estiver por perto, ele dispara para todos os lados e reza para que a deusa da caça esteja ao seu lado. Se ele está perto de um cadáver, ele fica à espera dos Wumpus. Ele não gosta de outros caçadores e fugirá se eles começarem a disparar flechas perto dele, ou se estiverem na mesma sala que ele. Finalmente, se estiver entediado, percorre aleatoriamente os corredores eternos.

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



}

Cuidado: de acordo com @Cain, você pode atirar em si mesmo se atirar em seu próprio quarto.
precisa

3

Emo Wumpus (Caçador)

Os Emo Wumpuses (relacionados aos Emo Wolves, que às vezes usam armas e aviões ) voam contra tudo (especialmente Java). Eles não fazem distinção entre Caçadores e Wumpuses, e tentam matá-los da mesma forma. Eles também odeiam motoristas da Nascar e sempre disparam bem. Se ninguém está por perto para atirar, eles se movem para a direita, mas só fazem isso treze vezes seguidas antes de ficarem ainda mais deprimidos por estarem sozinhos e tentarem se matar (treze é um número azarado). No turn 99, se ainda estiverem vivos, eles tentarão se matar porque a fome é uma maneira tão idiota de morrer.

Os Wumpuses são maiores (e mais pesados) que os Wolves, mas este ainda passou fome a 424 bytes (em oposição aos pesados ​​2,72 kb do 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++;}}

Por que não cometer suicídio em primeiro lugar? Emo Wumpuses acredita que o único ato de bem que pode fazer é acabar com o sofrimento dos outros antes de se matar. Portanto, eles matarão tudo o que puderem antes que seja a hora de morrer.

Wumpus? (Anti-Hunter)

Hum, o que um Wumpus está fazendo na lista de caçadores? Esse cara ficou super chateado que os humanos estavam matando seus parentes, então ele decidiu se vestir como um deles e participar da caçada. Seu principal objetivo é apenas matar caçadores. Ele tenta se esconder perto de cadáveres, o que lhe dará a chance de um escudo contra os caçadores. Se nenhum caçador estiver por perto, ele se moverá em uma direção até que os caçadores sejam detectados; nesse caso, ele tentará matá-los antes de se mover na outra direção.

Infelizmente, a maioria dos Wumpuses é estúpida e ainda tentará matá-lo. Independentemente disso, ele considera seus sacrifícios necessários para o bem dos Wumpuses em todo lugar.

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

}



Ainda bem que isso não é código de golfe. Estava me perguntando quanto tempo levaria até um robô Emo aparecer, lol.
precisa

@ Martin Note que isso não é apenas suicida. Dos bots disponíveis para teste, ele não ficou em último lugar.
Michael Brandon Morris

1
EmoSolution é sempre engraçado!
MAWG

2

Laomedon

Laomedon vagueia sem rumo, tentando encontrar um cadáver. Depois que ele encontra um e descobre onde está, ele fica no mesmo lugar ao lado do cadáver. Quando ele cheira o Wumpus, ele atira flechas no quarto do cadáver.

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

Infelizmente para ele, os outros caçadores não apreciam suas habilidades e parecem atirar muito nele ...


2

NealHunter

Depois de conversar sobre isso com meu amigo DoctorHeckle, pensei que seria divertido tentar fazer isso sozinho. Usou a ideia de alternar esquerda e direita para cobrir a maior parte da área e, em seguida, decidiu adicionar um pouco de resposta aos estados, mas apenas 0 e 1 - independentemente de um Wumpus ou um caçador estar por perto. Não funciona tão bem quanto o NascarHunter, o que me surpreendeu a princípio. Depois de pensar um pouco, percebi que disparar uma flecha em uma direção aleatória (como esta) depois de ouvir um caçador / cheirar um Wumpus não fará nada se eles estiverem se movendo nesse turno, pois as flechas são disparadas para as salas, mas o movimento é realizado antes de matá-los. Não é tão eficaz quanto eu pensava ... ainda funciona bem!

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

Este caminha até encontrar o wumpus. Então, ele atira certo. Se o wumpus ainda estiver lá, ele deve estar à esquerda, então atire novamente. No caminho, ele não se importa com outros caçadores ou cadáveres, daí o nome.

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

Fique

Ficar não gosta de andar. Ele simplesmente dispara e se lembra se ele atirou em um caçador.

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;
    }
}
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.