La grande chasse aux wumpus

22

ACHEVÉE

La saison de Wumpus est terminée, et avec, la vie de nombreux Wumpus vicieux et courageux Hunter. Ainsi que certains chasseurs lâches, immoraux et carrément stupides. Mais à la fin de la journée, NascarHunter du Dr Heckle est reparti avec le plus de butin et de gloire. Nous vous saluons, oh brave ... chauffeur?

C'est la saison ouverte sur Wumpus, et les chasseurs du monde entier affluent vers les grottes de Wumpus pour essayer de s'enrichir de peaux de Wumpus précieuses.

Le jeu

Basé sur le jeu classique Hunt the Wumpus , avec quelques variantes.

La carte

Un dodécaèdre . Il y a 20 chambres, chacune reliée à 3 autres pièces, ce qui fait essentiellement 3 anneaux avec des ponts entre les deux.

Le Wumpus

Le Wumpus est une bête mystique. Aucun ne sait à quoi il ressemble, mais tous conviennent qu'il est féroce. Le Wumpus vit dans les grottes et aime manger des choses mortes. S'il y a un cadavre dans une grotte à côté du Wumpus, il va s'y déplacer et le manger. Si le Wumpus arrive dans une grotte contenant des chasseurs, il les tuera et les mangera également. Si le Wumpus entend une flèche près de lui, il paniquera et courra dans une pièce au hasard.

Traits facultatifs : ils sont actuellement inclus pour rendre le jeu plus intéressant, mais peuvent être supprimés à la demande générale s'ils ajoutent trop de caractère aléatoire.

Wumpus enragé: si le Wumpus est abattu, il a 20% de survie et de déchaînement pendant 3 jours. Lorsqu'il saccage, il se déplacera au hasard deux fois par jour, mais sera toujours attiré par les cadavres. Après 3 jours, il mourra. Un deuxième coup de flèche tuera également les Wumpus.

Wumpus errant: Chaque jour, si rien d'autre ne déclenche le Wumpus, il a 25% de chances de bouger.

Les chasseurs

Quatre chasseurs peuvent entrer dans les grottes à la fois. Les grottes sont sombres, donc les chasseurs ne peuvent pas voir, mais ils peuvent utiliser leurs autres sens. Les chasseurs peuvent sentir le Wumpus dans une pièce adjacente, sentir un cadavre dans une pièce adjacente, entendre d'autres chasseurs se déplacer dans des pièces adjacentes et entendre si une flèche est tirée dans une pièce adjacente.

Les chasseurs ont deux actions: tirer ou se déplacer. Un chasseur peut tirer une flèche dans une pièce adjacente ou dans sa propre pièce et se déplacer de la même manière.

Gameplay

À chaque tour, les chasseurs prendront d'abord note de leur environnement, puis feront un mouvement. Le mouvement se produit avant les flèches, donc si une flèche est tirée dans une pièce où le chasseur sort, le chasseur survivra. Une fois tous les mouvements de chasseurs effectués, les flèches sont évaluées. Si un seul occupant et une flèche se trouvent dans la même pièce, l'occupant sera tué par balle. Si deux occupants ou plus partagent une pièce, un sera frappé au hasard et mourra. Remarque: Les cadavres sont des occupants, donc un cadavre peut servir de bouclier partiel.

Après tous les mouvements du chasseur, le Wumpus répondra. Si un chasseur a emménagé dans la pièce avec les Wumpus, les Wumpus le mangeront. Si le Wumpus bouge, il mangera également les occupants de la nouvelle pièce.

Après 100 jours, si les chasseurs n'ont pas tué les Wumpus, ou la victime tombée, ils mourront de faim dans les grottes.

Le code

Tout le code source peut être trouvé ici . Toutes les soumissions doivent être en Java, sauf si quelqu'un veut m'écrire un adaptateur stdIn / stdOut;)

Les bots devraient étendre la classe Hunter. Pour nommer votre Hunter, ajoutez un constructeur sans paramètres qui définit le champ de nom. Pour répondre, remplacez la fonction getResponse. Dans cette fonction, à chaque tour, vous passerez un tableau de 5 booléens qui vous parlera de votre environnement.

status 0 = "Vous sentez un wumpus"

status 1 = "Vous entendez un autre chasseur"

statut 2 = "Vous sentez un cadavre"

status 3 = "Vous entendez un cliquetis de flèche"

status 4 = "Vous vous sentez un autre chasseur dans la même pièce que vous"

La classe Hunter a 2 emplacements: nextMove et nextDirection, qui utilisent respectivement les enums Move et Direction. Le mouvement peut être MOVE ou SHOOT, la direction peut être LEFT, RIGHT, BACK ou ICI. Les directions sont cohérentes, ce qui signifie que le retour vous ramènera toujours à la pièce précédente dans laquelle vous étiez, et si vous entrez de la même pièce, GAUCHE et DROITE seront toujours les mêmes. Cependant, si vous entrez dans une direction différente, GAUCHE et DROITE vous amèneront à des endroits différents.

N'hésitez pas à mettre également en œuvre vos propres méthodes. La mémoire est persistante tout au long du tournoi, ce qui signifie que votre chasseur ne sera construit qu'une seule fois. Cependant, au début de chaque manche, la méthode newGame () est appelée pour informer votre chasseur qu'un nouveau jeu a commencé.

Notation

Quatre chasseurs s'affrontent à la fois. S'il est tué, la peau de Wumpus vaut 60 points, répartis également entre tous les chasseurs survivants. Style de tournoi à la ronde complet, de sorte que chaque combinaison de 4 chasseurs jouera ensemble.

5 exemples de chasseurs sont inclus: 4 avec des fonctionnalités très basiques et un qui permet à l'utilisateur de jouer, à des fins de test.

Si vous avez des suggestions / demandes, faites-le moi savoir!

La fin est en vue!

La population mondiale de Wumpus est chassée à un rythme alarmant. La loi Protect Our Wumpuses devrait être adoptée le mercredi 17 juin. Après cette date, plus aucun chasseur ne sera autorisé dans les grottes et un gagnant sera choisi.

Tableau d'affichage

Remarque: Mes excuses, il y avait un bogue dans le code qui pourrait faire en sorte que les chasseurs restent morts pendant plusieurs jeux. Après l'avoir corrigé, cela ne change pas beaucoup le classement général, mais change largement les statistiques.

Les scores sont là, exécutant chaque groupe de chasseurs dans 1000 parties chacun. NascarHunter et FullCoverageHunter mènent le peloton, et bien que l'ajout d'AntiHunter ait donné aux Wumpus un boost de survie de 2%, ils tremblent toujours dans leurs pieds sucés au taux de survie de 32% de leur genre. Les flèches des autres chasseurs sont plus que jamais la plus grande menace dans les grottes.

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)
Caïn
la source
1
Pouvez-vous frapper un autre chasseur avec une flèche?
MegaTom
1
Yessir, ou vous-même si vous tirez une flèche ICI
Cain
1
Au lieu d'un tableau pour 5 booléens, pourquoi ne pas simplement passer une intvaleur de 0 à 31? Nous sommes de grands garçons ici, nous pouvons faire des opérations peu :)
DoctorHeckle
1
@DoctorHeckle Bien sûr que nous le sommes, mais c'est toujours plus convivial pour les développeurs d'avoir un tableau plutôt qu'un seul int ^^.
Katenkyo
1
Pour les flèches et les cadavres, si l'on est dans la même pièce que vous, vous obtenez le même statut que s'il est adjacent. Les chasseurs sont les seuls que vous pouvez distinguer entre être à côté de la pièce ou dans la pièce.
Cain

Réponses:

11

NascarHunter

Pas beaucoup de logique. Ses règles sont simples: tourner à gauche, terre brûlée, répéter. Et, hé, il pourrait avoir de la chance!

Édition du 8 juin:

Ajouté dans une logique supplémentaire à Nascar pour tenir compte de la contiguïté d'un Wumpus par rapport à son dernier mouvement. Considérez-le comme un arrêt au stand, pour rester dans le thème. S'il détecte un Wumpus après avoir abattu un couloir, alors il doit être arrivé dans l'une des deux autres pièces adjacentes, car il serait mort du coup que le chasseur vient de prendre. Cela donne effectivement au Wumpus 2 tours à vivre s'il ne bouge plus, ou au Nascar 1 à vivre s'il est debout sur un cadavre. Représente également une troisième option si c'est le premier tour, mais juste une fois. Je vais finalement faire un portage sur FCH, occupé et occupé.

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

Suit le même credo du NascarHunter, mais alterne son cheminement, qui est garanti pour former une boucle de 10 pièces uniques de long. Étant donné que chaque pièce est unique et que nous tirons dans toutes les directions par pièce, toutes les pièces sont mises à feu. Cela est vrai pour n'importe quelle salle de départ (postulé par mon copain Neal, merci Neal!). Les dodécaèdres sont plutôt cool comme ça!

Je voudrais souligner que c'est différent de notre ami, le MonsterHunter, car il n'essaie aucune supercherie ni aucune véritable "tactique". La force de ceci est le fait que chaque pièce est mise à feu, encore une fois: la solution de force brute. Cela a une longueur d'avance théorique sur le NascarHunter, puisque Nascar ne touchera que 10 des 20 salles, couvrant seulement la moitié de la zone.

Édition du 11 juin:

Ajouté dans le modèle logique de détection Wumpus de NascarHunter. Devrait objectivement améliorer le score.

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;

            }

        }

    }

}

Faites-moi savoir s'il y a des erreurs, le package n'a pas bien fonctionné avec mon IDE :(

DoctorHeckle
la source
1
Je suis presque sûr que cela devrait s'appeler MadMaxHunter, car je ne me souviens pas de trop de courses NASCAR impliquant des coups de feu entre les véhicules. Semble bien faire!
Ralph Marshall
J'ai dû mettre des crochets autour de headLeft dans les instructions if pour que FullCoverageHunter fonctionne. Vos deux robots fonctionnent très bien - NascarHunter est légèrement meilleur
euanjt
La variable newGame dans FullCoverageHunter ne semble jamais être déclarée. J'ai ajouté un booléen newGame privé et je l'ai défini sur true dans la méthode newGame (), c'est ce que vous vouliez?
Cain
@Cain whoops! Ouais gros oubli de ma part, je vais éditer ça ici, ma mauvaise.
DoctorHeckle du
7

Blaireau

Il n'aime pas les visiteurs.

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))];
    }
}
Le numéro un
la source
6

Elmer Fudd

"Chut. Soyez très tranquille, je suis en train de chasser le wumpus"

Elmer est obsédé par la proie et ignore tout sauf les cadavres et les Wumpus. Il essaie de trouver un cadavre puis recule et commence à tirer. S'il sent un Wumpus, il reculera et s'il le sent encore, il tirera.

Mes excuses à tous les programmeurs Java, c'est probablement extrêmement laid, plein d'erreurs de syntaxe et j'ai probablement foiré ma logique.

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

    }
}

Pacifiste

Ce gars est moralement contre toute sorte de sport de sang et se demande comment il s'est retrouvé dans cette situation. Il fuira tout contact et ne tirera jamais.

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;
    }
}
MickyT
la source
1
Je pense que cela pourrait fonctionner. Tout ce que vous avez à faire dans un jeu est d'espérer que quelqu'un obtienne le wumpus avant qu'il ne vous obtienne et que vous obteniez un crédit complet.
Ralph Marshall
1
C'était l'idée générale. Laissez les autres travailler dur :-)
MickyT
1
C'est pourquoi je vous ai attendu pour coder cela, même si j'y ai pensé en premier :-)
Mawg
5

Chasseur de monstre

Nous chassons un monstre et nous sommes 4 ... Cela me rappelle mon jeu préféré! Ce chasseur parcourra la majeure partie de la carte en se déplaçant alternativement de gauche à droite, et si le Wumpus est proche, il l'attirera en reculant pour pouvoir déterminer avec précision où il se trouve.

Je pourrais me débarrasser de lastDirection, mais je garde pour la sémantique et la lisibilité :). En fait, il meurt beaucoup, mais le contrôleur met souvent 2/3 chasseurs dans la même pièce au début, et souvent avec les Wumpus à proximité (peut également être dans la même pièce) ... donc insta death ^^ '.

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];
    }
}
Katenkyo
la source
Merci de l'avoir signalé, le contrôleur est corrigé afin que chaque occupant ait un départ unique
Cain
4

PacingHunter

Dans les deux sens, entre les chambres. s'il sent un Wumpus ou entend un joueur, il tire à gauche puis à droite. si un Wumpus est à côté de lui pour commencer, il tire sur la pièce dans laquelle il se déplacera.

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

}

MegaTom
la source
4

ScaredyCat

ScaredyCat a peur de tout. S'il sent un wumpus ou un cadavre ou entend une flèche ou un chasseur, il court dans une direction aléatoire. Sinon, il continue simplement à tirer des flèches dans des directions aléatoires.

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))];
    }
}
Spikatrix
la source
6
Lol, je ne sais pas si c'était intentionnel, mais il se fera peur en tirant des flèches et puis courra.
Cain
4

Mange des pousses et des feuilles

Contrairement au livre Panda de la grammaire, ce chasseur ne mange rien, mais nous tirons si le Wumpus est sur le point ou nous partons sur une piste qui devrait nous empêcher de marcher en rond.

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];
        }
    }
}
Ralph Marshall
la source
3

Idomeneus

Idomeneus est assez simple - si le Wumpus ou un autre chasseur est à proximité, il fait feu partout et prie pour que la déesse de la chasse soit de son côté. S'il est près d'un cadavre, il attend les Wumpus. Il n'aime pas les autres chasseurs et s'enfuira s'ils commencent à tirer des flèches près de lui, ou s'ils sont dans la même pièce que lui. Enfin s'il s'ennuie, il arpente au hasard les couloirs éternels.

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



}
euanjt
la source
Soyez prudent: selon @Cain, vous pouvez vous tirer dessus si vous tirez dans votre propre pièce.
DoctorHeckle
3

Emo Wumpus (Chasseur)

Emo Wumpuses (lié aux Emo Wolves qui utilisent parfois des fusils et des avions volants ) déteste tout (en particulier Java). Ils ne font aucune distinction entre les Chasseurs et les Wumpus et essaient tout de même de leur tirer dessus. Ils détestent également les pilotes Nascar et tireront toujours à droite. Si personne n'est là pour tirer, ils se déplacent à droite, mais ne le feront que treize fois de suite avant d'être encore plus déprimés d'être seuls et d'essayer de se tirer dessus (treize est un chiffre malchanceux). Au tour 99, s'ils sont encore en vie, ils tenteront de se suicider parce que la famine est une façon si boiteuse de mourir.

Les wumpus sont plus grands (et plus lourds) que les loups, mais celui-ci s'est toujours affamé à 424 octets (par opposition aux lourds 2,72 ko 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++;}}

Pourquoi ne pas simplement se suicider en premier lieu? Emo Wumpus pense que le seul acte de bien qui peut faire est de mettre fin à la souffrance des autres avant de se tuer. Par conséquent, ils tueront tout ce qu'ils peuvent avant qu'il ne soit temps de mourir.

Wumpus? (Anti-chasseur)

Que fait un Wumpus sur la liste des chasseurs? Ce mec s'est énervé que les humains tuent ses proches, alors il a décidé de se déguiser en l'un d'eux et de se joindre à la chasse. Son objectif principal est de simplement tuer des chasseurs. Il essaie de se cacher près des cadavres, ce qui lui donnera une chance de se protéger des chasseurs. Si aucun chasseur n'est à proximité, il se déplacera dans une direction jusqu'à ce que des chasseurs soient détectés, auquel cas il essaiera de les tuer avant de se déplacer dans l'autre direction.

Malheureusement, la plupart des Wumpus sont stupides et vont toujours essayer de le tuer. Quoi qu'il en soit, il considère que ses sacrifices sont nécessaires pour le bien des Wumpus partout dans le monde.

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

}

Michael Brandon Morris
la source
1
Plus drôle.
Martin Ender
Heureusement que ce n'est pas du golf de code. Je me demandais combien de temps il faudrait pour qu'un robot Emo apparaisse, lol.
DoctorHeckle
@Martin Notez que ce n'est pas seulement suicidaire. Sur les bots disponibles pour les tests, il ne s'est pas classé dernier.
Michael Brandon Morris
1
EmoSolution est toujours drôle!
Mawg
2

Laomedon

Laomedon erre sans but en essayant de trouver un cadavre. Une fois qu'il en a trouvé un et qu'il sait où il se trouve, il reste au même endroit à côté du cadavre. Quand il sent le Wumpus, il tire des flèches dans la chambre du cadavre.

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

Malheureusement pour lui, les autres chasseurs n'apprécient pas ses compétences et ils semblent lui tirer beaucoup dessus ...

euanjt
la source
2

NealHunter

Après en avoir parlé avec mon ami DoctorHeckle, j'avais pensé que ce serait amusant de l'essayer moi-même. Utilisé l'idée d'alterner gauche et droite pour couvrir la plus grande partie, puis a décidé d'ajouter un peu de réponse aux états, mais seulement 0 et 1 - qu'un Wumpus ou un chasseur soit à proximité ou non. Ne fonctionne pas aussi bien que NascarHunter, ce qui m'a d'abord surpris. Après réflexion, j'ai réalisé que tirer une flèche dans une direction aléatoire (comme c'est le cas) après avoir entendu un chasseur / sentir un Wumpus ne ferait rien s'ils se déplaçaient ce tour-ci, car les flèches sont tirées dans les pièces, mais le mouvement est effectuée avant de les tuer. Pas tout à fait aussi efficace que je le pensais ... fonctionne toujours bien quand même!

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;
        }
    }
}
Neal
la source
1

WalkingIdiot

Celui-ci marche jusqu'à ce qu'il trouve le wumpus. Puis, il tire à droite. Si le wumpus est toujours là, il doit être à gauche, alors tirez à nouveau. Sur le chemin, il ne se soucie pas des autres chasseurs ou cadavres, d'où le nom.

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

Rester

Rester n'aime pas marcher. Il tourne simplement autour et se souvient s'il a tiré sur un chasseur.

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;
    }
}
CommonGuy
la source