La gran caza de Wumpus


22

COMPLETAR

La temporada de Wumpus ha terminado, y con la vida de muchos Wumpus viciosos y valientes Hunter. Además de algunos cazadores cobardes, inmorales y francamente estúpidos. Pero al final del día, NascarHunter del Dr. Heckle salió con el mayor botín y gloria. Te saludamos, oh valiente ... ¿conductor?

Es temporada abierta en Wumpuses, y los cazadores de todo el mundo acuden en masa a las Cuevas de Wumpus para tratar de hacerse rico con las valiosas pieles de Wumpus.

El juego

Basado en el clásico Hunt the Wumpus juego , con algunas variaciones.

El mapa

Un dodecaedro . Hay 20 habitaciones, cada una conectada a otras 3 habitaciones, haciendo básicamente 3 anillos con puentes en el medio.

El wumpus

El Wumpus es una bestia mística. Ninguno está seguro de cómo se ve, pero todos están de acuerdo en que es feroz. El Wumpus vive en las cuevas y le gusta comer cosas muertas. Si hay un cadáver en una cueva al lado del Wumpus, él se moverá allí y se lo comerá. Si el Wumpus se muda a una cueva que contiene cazadores, los matará y se los comerá también. Si el Wumpus oye una flecha cerca de él, entrará en pánico y correrá a una habitación al azar.

Rasgos opcionales : actualmente se incluyen para hacer que el juego sea más interesante, pero se pueden eliminar a pedido popular si agregan demasiada aleatoriedad.

Wumpus enfurecido: si el Wumpus recibe un disparo, tiene un 20% de supervivencia y estragos durante 3 días. Cuando arrasa, se moverá al azar dos veces al día, pero aún se sentirá atraído por los cadáveres. Después de 3 días, morirá. Un segundo disparo de flecha también matará a los Wumpus.

Wumpus errante: cada día, si nada más activa el Wumpus, tiene un 25% de posibilidades de moverse.

Los cazadores

Cuatro cazadores pueden entrar en las cuevas a la vez. Las cuevas son oscuras, por lo que los cazadores no pueden ver, pero pueden usar sus otros sentidos. Los cazadores pueden oler el Wumpus en una habitación adyacente, oler un cadáver en una habitación adyacente, escuchar a otros cazadores moverse en habitaciones adyacentes y escuchar si se dispara una flecha a una habitación adyacente.

Los cazadores tienen dos acciones: disparar o moverse. Un cazador puede disparar una flecha hacia una habitación adyacente o su propia habitación, y moverse de manera similar.

Jugabilidad

En cada ronda, los cazadores primero tomarán nota de su entorno y luego harán un movimiento. El movimiento ocurre antes de las flechas, por lo que si una flecha se dispara a una habitación de la que se está moviendo un cazador, el cazador sobrevivirá. Después de realizar todos los movimientos de cazador, se evalúan las flechas. Si un solo ocupante y una flecha están en la misma habitación, el ocupante recibirá un disparo y morirá. Si dos o más ocupantes comparten una habitación, uno será golpeado y muerto al azar. Nota: los cadáveres son ocupantes, por lo que un cadáver puede servir como un escudo parcial.

Después de que todos los cazadores se muevan, el Wumpus responderá. Si un cazador se ha mudado a la habitación con el Wumpus, el Wumpus se lo comerá. Si el Wumpus se mueve, también se comerá a los ocupantes de la nueva habitación.

Después de 100 días, si los cazadores no han matado al Wumpus, o la víctima caída, morirán de hambre dentro de las cuevas.

El código

Todo el código fuente se puede encontrar aquí . Todos los envíos deben estar en Java, a menos que alguien quiera escribirme un adaptador stdIn / stdOut;)

Los bots deberían extender la clase Hunter. Para nombrar a su cazador, agregue un constructor sin parámetros que establezca el campo de nombre. Para responder, anule la función getResponse. En esta función, en cada turno, se te pasará una serie de 5 booleanos que te informarán sobre tu entorno.

estado 0 = "Hueles un wumpus"

estado 1 = "Escuchas a otro cazador"

estado 2 = "Hueles un cadáver"

status 3 = "Escuchas un ruido de flecha"

status 4 = "Sientes a otro cazador en la misma habitación que tú"

La clase Hunter tiene 2 espacios: nextMove y nextDirection, que usan las enumeraciones Move y Direction respectivamente. Mover puede ser MOVER o DISPARAR, la dirección puede ser IZQUIERDA, DERECHA, ATRÁS o AQUÍ. Las instrucciones son consistentes, lo que significa que regresar siempre lo regresará a la habitación anterior en la que estaba, y si ingresa desde la misma habitación, IZQUIERDA y DERECHA siempre serán las mismas. Sin embargo, si ingresa desde una dirección diferente, IZQUIERDA y DERECHA lo llevarán a diferentes lugares.

Siéntase libre de implementar sus propios métodos también. La memoria es persistente durante todo el torneo, lo que significa que tu cazador solo se construirá una vez. Sin embargo, al comienzo de cada ronda, se llama al método newGame () para que su cazador sepa que ha comenzado un nuevo juego.

Tanteo

Cuatro cazadores compiten a la vez. Si se mata, la piel de Wumpus vale 60 puntos, dividida equitativamente entre todos los cazadores sobrevivientes. Estilo de round robin completo, por lo que cada combinación de 4 cazadores jugarán juntos.

Se incluyen 5 cazadores de muestra: 4 con una funcionalidad muy básica y uno que permite que el usuario ingrese para jugar, con fines de prueba.

Si tiene alguna sugerencia / solicitud, ¡hágamelo saber!

¡El final está a la vista!

La población mundial de Wumpus está siendo cazada a un ritmo alarmante. Se espera que la Ley de Protección de Wumpuses se apruebe el miércoles 17 de junio. Después de esta fecha, no se permitirán más cazadores en las cuevas, y se elegirá un ganador.

Marcador

Nota : Mis disculpas, había un error en el código que podía causar que los Cazadores permanecieran muertos a través de múltiples juegos. Una vez solucionado, no cambia mucho la clasificación general, pero sí cambia en gran medida las estadísticas.

Los puntajes están dentro, ejecutando cada conjunto de cazadores en 1000 juegos cada uno. NascarHunter y FullCoverageHunter lideran la manada, y aunque la adición de AntiHunter les ha dado a los Wumpus un aumento de supervivencia del 2%, todavía están temblando en sus pies con una tasa de supervivencia del 32% de su tipo. Las flechas de otros cazadores son más que nunca la mayor amenaza en las cuevas.

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
¿Puedes golpear a otro cazador con una flecha?
MegaTom

1
Sí señor, o usted mismo si dispara una flecha AQUÍ
Caín

1
En lugar de una matriz para 5 booleanos, ¿por qué no simplemente pasar un intvalor de 0-31? Somos muchachos aquí, podemos hacer operaciones de bit :)
DoctorHeckle

1
@DoctorHeckle Claro que sí, pero aún es más amigable para los desarrolladores tener una matriz en lugar de una única int ^^.
Katenkyo

1
Para flechas y cadáveres, si uno está en la misma habitación que usted, obtiene el mismo estado que si fuera adyacente. Los cazadores son los únicos que puedes distinguir entre estar al lado de la habitación o en la habitación.
Caín

Respuestas:


11

NascarHunter

No hay mucha lógica para eso. Sus reglas son simples: gire a la izquierda, tierra quemada, repita. Y, oye, ¡podría tener suerte!

8 de junio editar:

Se agregó una lógica adicional a Nascar para tener en cuenta la adyacencia a un Wumpus en relación con su último movimiento. Considéralo una parada en boxes, para mantenerte en el tema. Si siente un Wumpus después de derribar un pasillo, entonces debe haber llegado a una de las otras dos habitaciones adyacentes, ya que habría muerto por el disparo que el cazador acaba de tomar. Efectivamente le da a Wumpus 2 turnos para vivir si no se mueve de nuevo, o Nascar 1 turno para vivir si está parado sobre un cadáver. También representa una tercera opción si es el primer turno, pero solo una vez. Llegaré a 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

Sigue el mismo credo del NascarHunter, pero alterna su ruta, que garantiza formar un bucle de 10 habitaciones únicas de largo. Dado que cada habitación es única y disparamos en todas las direcciones por habitación, todas las habitaciones se disparan. Esto es cierto para cualquier sala de inicio (postulado por mi amigo Neal, ¡gracias Neal!). ¡Los dodecaedros son geniales así!

Me gustaría señalar que esto es diferente a nuestro amigo, el MonsterHunter, ya que no intenta ningún truco ni ninguna "táctica" real. La fuerza de esto es el hecho de que cada habitación se dispara, nuevamente: la solución de fuerza bruta. Esto tiene una ventaja teórica sobre el NascarHunter, ya que Nascar solo golpeará 10 de las 20 habitaciones, cubriendo solo la mitad del área.

11 de junio editar:

Agregado en el patrón de lógica de detección Wumpus de NascarHunter. Debería mejorar objetivamente la puntuación.

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;

            }

        }

    }

}

Avíseme si hay algún error, el paquete no funcionó bien con mi IDE :(


1
Estoy bastante seguro de que esto debería llamarse MadMaxHunter, ya que no recuerdo demasiadas carreras de NASCAR que involucren disparos entre vehículos. Parece hacerlo bien!
Ralph Marshall

Tuve que poner corchetes alrededor de la cabeza Izquierda en las declaraciones if para que FullCoverageHunter funcione. A ambos bots les va muy bien: NascarHunter es un poco mejor
euanjt

La variable newGame en FullCoverageHunter parece nunca declararse. Agregué un booleano privado newGame y lo configuré como verdadero en el método newGame (), ¿es eso lo que pretendías?
Caín

@Cain whoops! Sí, gran supervisión mía, lo editaré aquí, mi mal.
DoctorHeckle

7

Tejón

No le gustan los 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. Sé vewy vewy callado, estoy cazando wumpus"

Elmer está obsesionado con la presa e ignora todo excepto los cadáveres y el Wumpus. Intenta encontrar un cadáver, luego retrocede y comienza a disparar. Si huele a Wumpus, retrocederá y si todavía lo huele, disparará.

Mis disculpas a todos los programadores de Java, esto es probablemente extremadamente feo, lleno de errores de sintaxis y probablemente he estropeado mi 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

Este tipo está moralmente en contra de cualquier tipo de deporte sangriento y se pregunta cómo apareció en esta situación. Huirá de cualquier tipo de contacto y nunca disparará.

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
Creo que esto podría funcionar. Todo lo que tienes que hacer en un juego es esperar que alguien reciba el wumpus antes de que te atrape y que obtengas el crédito completo.
Ralph Marshall

1
Esa fue la idea general. Deje que los demás hagan el trabajo duro :-)
MickyT

1
Es por eso que esperé que codificaras esto, aunque lo pensé primero :-)
Mawg

5

Cazador de monstruos

Estamos cazando un monstruo y somos 4 ... ¡Me recuerda a mi juego favorito! Este cazador caminará la mayor parte del mapa moviéndose de izquierda a derecha alternativamente, y si el Wumpus está cerca, lo atraerá yendo hacia atrás para poder determinar con precisión dónde está.

Podría deshacerme de lastDirection, pero mantengo la semántica y la legibilidad :). En realidad, muere bastante, pero el controlador a menudo pone 2/3 cazadores en la misma habitación al comienzo, y a menudo con el Wumpus cerca (también puede estar en la misma habitación) ... así que la muerte instantánea ^^ '.

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

Gracias por señalarlo, el controlador está arreglado para que cada ocupante tenga un comienzo único
Cain

4

PacingHunter

De ida y vuelta, entre las habitaciones. si huele a Wumpus o escucha a un jugador, dispara a la izquierda y luego a la derecha. si un Wumpus está junto a él para comenzar, entonces dispara a la habitación a la que 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

Miedoso

ScaredyCat tiene miedo de todo. Si huele un wumpus o un cadáver o escucha una flecha o un cazador, corre en una dirección aleatoria. De lo contrario, simplemente sigue disparando flechas en direcciones aleatorias.

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

66
Lol, no sé si esto fue intencional, pero se asustará disparando flechas y luego huirá.
Caín

4

Come brotes y hojas

A diferencia del Panda de la fama de los libros de gramática, este cazador en realidad no come nada, pero disparamos si el Wumpus está a punto o nos vamos por un sendero que, con suerte, nos impedirá caminar en 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 es bastante simple: si el Wumpus u otro cazador está cerca, dispara sarrows por todas partes y reza para que la diosa de la caza esté de su lado. Si está cerca de un cadáver, está al acecho del Wumpus. No le gustan los otros cazadores y huirá si comienzan a disparar flechas cerca de él, o si están en la misma habitación que él. Finalmente, si se siente aburrido, camina al azar por los pasillos 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(){}



}

Ten cuidado: según @Cain, puedes dispararte si disparas a tu propia habitación.
DoctorHeckle

3

Emo Wumpus (Cazador)

Emo Wumpuses (relacionado con Emo Wolves que a veces usan pistolas y aviones voladores ) odian todo (especialmente Java). No hacen distinción entre cazadores y wumpus, e intentan dispararles de todos modos. También odian a los conductores de Nascar, y siempre dispararán bien. Si no hay nadie cerca para disparar, se mueven hacia la derecha, pero solo lo harán trece veces seguidas antes de deprimirse aún más por estar solos e intentar dispararse (trece es un número desafortunado). En el turno 99, si todavía están vivos, intentarán dispararse a sí mismos porque morir de hambre es una forma lamentable de morir.

Los wumpuses son más grandes (y más pesados) que los lobos, pero este todavía se ha muerto de hambre a 424 bytes (a diferencia de los 2.72 kb de 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 qué no simplemente suicidarse en primer lugar? Emo Wumpuses cree que el único acto de bien que puede hacer es terminar con el sufrimiento de los demás antes de suicidarse. Por lo tanto, matarán todo lo que puedan antes de que sea hora de morir.

Wumpus? (Anti-Hunter)

¿Qué está haciendo un Wumpus en la lista de cazadores? Este tipo se enojó mucho porque los humanos estaban matando a sus parientes, por lo que decidió vestirse como uno de ellos y unirse a la caza. Su objetivo principal es matar cazadores. Intenta esconderse cerca de los cadáveres, lo que le dará la oportunidad de protegerse de los cazadores. Si no hay cazadores cerca, se moverá en una dirección hasta que los cazadores sean detectados, en cuyo caso intentará matarlos antes de moverse en la otra dirección.

Desafortunadamente, la mayoría de los Wumpus son estúpidos y todavía van a tratar de matarlo. De todos modos, considera que sus sacrificios son necesarios para el bien de Wumpuses en todas partes.

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

}



Lo bueno es que esto no es código golf. Me preguntaba cuánto tiempo pasaría hasta que apareciera un bot Emo, jajaja.
DoctorHeckle

@ Martin Tenga en cuenta que esto no es solo suicida. De los bots disponibles para probar, no ocupó el último lugar.
Michael Brandon Morris

1
¡EmoSolution siempre es divertido!
Mawg

2

Laomedon

Laomedon deambula sin rumbo tratando de encontrar un cadáver. Una vez que encuentra uno y determina dónde está, se queda en el mismo lugar al lado del cadáver. Cuando huele el Wumpus, dispara flechas a la habitación del 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;
    }
}

Desafortunadamente para él, los otros cazadores no aprecian sus habilidades y parecen dispararle mucho ...


2

NealHunter

Después de hablar de esto con mi amigo DoctorHeckle, pensé que sería divertido intentarlo yo mismo. Usó la idea de alternar a izquierda y derecha para cubrir la mayor parte del área, y luego decidió agregar un poco de respuesta a los estados, pero solo 0 y 1, ya sea que haya un Wumpus o un cazador cerca o no. No funciona tan bien como NascarHunter, lo que me sorprendió al principio. Sin embargo, después de pensar un poco, me di cuenta de que disparar una flecha en una dirección aleatoria (como lo hace) después de escuchar a un cazador / oler a un Wumpus no hará nada si se mueven ese turno, ya que las flechas se disparan a las habitaciones, pero se mueven se lleva a cabo antes de que los mate. No es tan efectivo como pensaba ... ¡aunque todavía funciona bien!

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

Éste camina hasta que encuentra el wumpus. Entonces, dispara a la derecha. Si el wumpus todavía está allí, debe estar a la izquierda, así que dispara una vez más. En el camino, no le importan otros cazadores o cadáveres, de ahí su nombre.

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

Permanecer

A Stay no le gusta caminar. Simplemente dispara y recuerda si le disparó a un cazador.

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;
    }
}
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.