10
votes

Comment vérifier une séquence de frappe de frappe

Je fais une partie et je veux implémenter des codes de triche comme le code Konami.

Mais comment vérifier cette séquence de frappe de frappe?

Je veux que cela fonctionne de sorte que si un joueur tape simplement le code, elle déclenchera.

Merci d'avance!


0 commentaires

5 Réponses :


0
votes

Je ne sais pas quels sont vos besoins. Essayez-vous de créer un jeu en utilisant system.in code> et system.out code> ou essayez-vous de créer une interface graphique visuelle complète?

Entre-temps, voir Interface java.awt.event.keylistener code>. ( Documentation Oracle ) aussi , voir tutoriel d'Oracle . P>

et Basé sur une expérience personnelle, le code ci-dessous se rapproche de ce dont vous avez besoin. p> xxx pré>

Lorsque vous utilisez une méthode de course, spécifiez simplement que P>

if (test.cheatEntered()) {
    // do something
}


7 commentaires

Qu'entendez-vous avec la "mise en œuvre à suivre"?


@Ballusc je voulais dire que je vais me chaleter ma réponse. Cela prend du temps.


Comment cela fonctionnerait-il? Un fil / assistant serait-il en marche en arrière-plan? Juste curieux.


@James dans le passé, je viens de le faire en attachant les auditeurs à l'objet (par exemple, les pagaies de pong ou de boutons d'une interface graphique). Je suppose que c'est un fil, mais je ne sais pas assez sur les scripts shell pour être sûr à 100%.


Ah Ok, alors je suppose cela en swing. Il devrait y avoir un moyen de cumuler les clés entrées et réinitialisées s'il y a une erreur. Cela pourrait être fait dans keytyped . Quelque chose comme typedkeys.add (keychar) avec un chèque de comparaison index sur la constante konami_code. Si l'un des caractères ne correspond pas, alors TapeDKeys.clear () déclenche la triche ou définir un drapeau. Il serait intéressant de savoir s'il est possible d'entrer plus d'une clé à la fois au cours de laquelle des contrôles supplémentaires doivent être ajoutés.


@James de la question, il semble que c'est un jeu d'un joueur. Néanmoins, même s'il s'agissait de deux joueurs, la probabilité d'une contribution simultanée de deux joueurs humains s'approche 0.


C'est ce que j'ai compris. C'est juste que je pense en théorie, il est possible d'appuyer sur et / ou de contenir plusieurs touches simultanément sur un clavier PC. Sur les modèles plus anciens, l'ordinateur sera émetteur lorsque plus de trois clés sont pressées. Comment cela est interprété sur le côté de Java, c'est que quelqu'un devine que certains tests soient une bonne idée.



5
votes

edit: Voir mon autre poste pour le code qui fonctionne toujours. Ce qui suit ne détecte pas le code s'il chevauche elle-même (par exemple: «Up, haut, haut, bas, bas, gauche, droite, gauche, droite, B« ne fonctionnerait pas)

Merci à Gevorg pour le pointant de cette sortie.


Si c'est comment identifier la séquence que vous êtes concerné uniquement (je suppose que vous savez comment obtenir l'entrée du clavier) puis Vous pouvez avoir quelque chose comme suit. xxx

Appelez cette fonction chaque fois qu'une touche appuyez sur une touche enregistrée, en passant la touche qui a été enfoncée. Bien sûr modifier les types le cas échéant.


6 commentaires

Up, haut, haut, bas, bas, gauche, droite, gauche, droite, b brise votre algorithme, n'est-ce pas? Le troisième u apporte le courant actuel à 0 et le patt n'est pas reconnu. Notez que si vous supprimez le premier haut, la séquence est valide!


Bien taché! La dernière partie était censée être dans un bloc d'autre.


Fixé. cogne la tête contre le mur


Ouais, ça veut dire! Mais l'algorithme se brise toujours pour ma séquence donnée ci-dessus. Par la 3ème Keystroke, votre algorithme a accepté les deux premiers déjà (Up, Up) et cela s'attendait à «Down», mais après avoir reçu un autre «UP» en courant courante de retour à 0. Néanmoins, ma séquence de Keystrokes est valide et elle devrait être acceptée.


A dû ajouter A = plus dans le premier si, et retirer le -1 en séquence.Length. Mais fonctionne parfaitement maintenant, merci beaucoup


@Gevorg: Désolé n'a pas lu votre premier commentaire correctement et supposé que vous parliez de l'autre problème (manque de bloc d'autre)



0
votes

Il serait peut-être intéressant de regarder le modèle d'état, mais vous pourriez essayer le truc ci-dessous, car il s'agit d'un cas simple:

  1. Placez la séquence à être reconnue dans un fichier secret String
  2. Créer un StringBuilder UserInput qui conserve les touches enfoncées par l'utilisateur
  3. Chaque fois qu'un utilisateur appuie une touche appuyée sur userinput
  4. Après chaque touche ajoutée dans userinput Vérifiez si le code UserInput actualisé contient le code Secret avec le suivant: userinput.indexof ( SecretCode)> - 1

    Vous voudrez peut-être vider le userinput à partir de maintenant, en fonction de l'heure ou une fois qu'une séquence est reconnue par exemple.


0 commentaires

6
votes

ci-dessous est une classe qui vérifie le code konami, y compris des cas tels que " up fort>, haut, haut, bas, etc."

Cela devrait fonctionner pour tout EM> Séquence donnée. P>

import java.util.Map;
import java.util.TreeMap;

public class Konami {

    static private int[] code = 
        {UP, UP, DOWN, DOWN, LEFT, RIGHT, LEFT, RIGHT, B};
    static private Map<Integer, Integer>[] graph;
    static private int currentNode = 0;

    public static void main(String args[]) {
        //Create graph
        graph = generateSequenceMap(code);

        //Call checkKonami(key) whenever a key is pressed
    }


    static public boolean checkKonami(int keyPressed) {
        Integer nextNode = graph[currentNode].get(keyPressed);

        //Set currentNode to nextNode or to 0 if no matching sub-sequence exists
        currentNode = (nextNode==null ? 0 : nextNode);

        return currentNode == code.length-1;
    }


    static private Map<Integer, Integer>[] generateSequenceMap(int[] sequence) {

        //Create map
        Map<Integer, Integer>[] graph = new Map[sequence.length];
        for(int i=0 ; i<sequence.length ; i++) {
            graph[i] = new TreeMap<Integer,Integer>();
        }

        //i is delta
        for(int i=0 ; i<sequence.length ; i++) {
            loop: for(int j=i ; j<sequence.length-1 ; j++) {
            if(sequence[j-i] == sequence[j]) {
                System.out.println("If at Node "+j+" you give me seq["+(j-i+1) 
                        + "] OR " + (sequence[j-i+1]) + " , goto Node " + (j-i+1));

                //Ensure that the longest possible sub-sequence is recognized
                Integer value = graph[j].get(sequence[j-i+1]);
                if(value == null || value < j-i+1)
                    graph[j].put(sequence[j-i+1], j-i+1);
            }
            else
                break loop;
            }
        }
        return graph;
    }
}


1 commentaires

Aussi une solution très gode, et avec une petite modification, me permet maintenant de vérifier une gamme de tricheurs d'attente. :) Un autre merci, vous envoyez votre chemin.



3
votes

Je suis sûr que vous avez passé ce projet maintenant, mais je viens de la mettre en œuvre dans l'une de mes missions et je voulais le laisser pour que d'autres trouvent. Cette solution enregistre les dernières n frappes (définies ici comme 10) dans une matrice circulaire et renvoie true quand ils correspondent à notre code. Vous pouvez simplement passer facilement dans différentes longueurs et codes dans le cadre de la méthode (mais cette implémentation ne l'a pas exigée). J'ai utilisé ^ ^ v v B a.

public class Code {
private static int[] history = new int[10];
private static int front = 0;
private static int size = 0;

// Here is the Code they must enter (ascii vals for konami).
private static int[] code = {38, 38, 40, 40, 37, 39, 37, 39, 66, 65};

// Static class. No constructor.
private Code(){}

// Adds key-press into history buffer. If code is matched, return true.
public static boolean add(int e){

    // Write the value into our key history.
    history[(front + size) % 10] = e;

    // Stop growing at length 10 and overwrite the oldest value instead.
    if (size < 10){
        size++;
    } else {
        front = front + 1 % 10;
    }

    // Compare our history (from the current front) to the code (from 0)
    for(int i = front; i < front + size; i++){
        if (history[i % 10] != code[i-front]){
            // Any 1 mismatch will abort
            return false;
        }
    }
    // Make sure we've logged enough keystrokes so it doesn't fire off
    // if your first key press matches the code.
    if (size < 10){
        return false;
    }
    return true;
}


0 commentaires