2016-07-12 18 views
0

Ich mache einige Chemie-Spiel als ein Telegram-Bot in JavaScript, wo Sie ein Inventar haben und Sie müssen die richtigen Chemikalien mischen. Ich habe das Inventar in einem Array, und um zu verhindern, dass Sie Ihren Weg auf ein Level durch einfaches Einfügen Ihres Inventars erzwingen, muss ich überprüfen, ob die Benutzereingaben ausschließlich die benötigten Chemikalien enthalten und keine der anderen in der Array.Wie überprüft man, ob eine Zeichenfolge ein bestimmtes Element aus einem Array enthält, aber nicht die anderen Elemente?

Zum Beispiel:

users[id].inventory = ["Beaker", "Water", "Baking soda", "Heating plate", "Hydrochloric acid"]; 

if (users[id].level === 1 && 
    msg.text.toLowerCase().indexOf('baking soda') !== -1 && 
    msg.text.toLowerCase().indexOf('hydrochloric acid') !== -1 && 
    msg.text.toLowerCase().indexOf('beaker') === -1 && 
    msg.text.toLowerCase().indexOf('water') === -1 && 
    msg.text.toLowerCase().indexOf('heating plate') === -1) { 

    msg.answer("You mix some baking soda with hydrochloric acid.\nSome fun fizzing happens and you produce useless CO2 gas."); 
} 

Auf higer Ebenen werden Sie ein viel größeres Inventar erhalten und dies zu sehr große if-Aussagen auf diese Weise führen wird. Das sieht schlecht aus und es muss einen besseren Weg geben. Gibt es so etwas wie eine exklusive indexOf() oder eine andere Lösung? Ich habe zum Beispiel arr.filter() ausgecheckt, aber ich kann keinen guten Weg finden, dies zu implementieren.

+1

Haben Sie versucht, mit einer Schleife über das Array zu durchlaufen? – nnnnnn

Antwort

1

Die manuelle Überprüfung auf jede Zutat ist keine gute Idee, da Sie darauf hinweisen, dass es sehr langwierig wird, wenn die Anforderungen für ein Rezept lang sind und das Inventar auch lang ist.

Ich empfehle das Erstellen einer Funktion rightIngredients, die zwei Arrays benötigt: die Anforderungen und die verwendeten Elemente.

In Anbetracht der Tatsache, dass nur die Elemente im Rezept verwendet werden sollten, ist das erste, was ich in der Funktion tun würde, die Länge der beiden Arrays zu überprüfen. Wenn sie anders sind, sollte es falsch zurückgeben und nichts anderes muss überprüft werden.

Wenn die Länge der Arrays gleich ist, dann überprüfen wir jedes der Elemente, um festzustellen, ob sie in den Anforderungen enthalten sind. Wenn einer von ihnen nicht ist, dann kehren wir auch falsch zurück.

requirements = ["baking soda", "hydrochloric acid"]; 

function rightIngredients(req, uses) { 
    if (uses.length != req.length) { 
    console.log(uses.join(', ')+' are not even the right amount of ingredients'); 
    missing = true; 
    } else { 
    var i = 0; 
    var missing = false; 
    while (i<uses.length && !missing) { 
     if (req.indexOf(uses[i].toLowerCase())===-1) missing = true; 
     ++i; 
    } 
    if (missing) console.log(uses.join(', ')+' are not the right ingredients'); 
    else console.log(uses.join(', ')+' are the right ingredients'); 
    } 
    return !missing; 
} 
rightIngredients(requirements, ["Beaker", "Baking Soda", "Hydrochloric Acid"]); 
// Beaker, Baking Soda, Hydrochloric Acid are not even the right amount of ingredients 
rightIngredients(requirements, ["Beaker", "Baking Soda"]); 
// Beaker, Baking Soda are not the right ingredients 
rightIngredients(requirements, ["Baking Soda", "Hydrochloric Acid"]); 
// Baking Soda, Hydrochloric Acid are the right ingredients 
+0

Dies ist eine wirklich elegante Lösung und es funktioniert für mich. Das war, was ich suchte. Ich hoffe, dass ich die Fähigkeiten entwickeln kann, um das selbst zu machen. – bdbdbd

1

Sie können ein Array aller unzulässigen Chemikalien erstellen und Array.every dann diese Bedingung, wenn alle Elemente zu überprüfen, verwenden erfüllen. Außerdem werden Sie unterschiedliche Kombinationen basierend auf dem Level haben, also würde ich vorschlagen, eine Karte von Level und verbotenen Chemikalien zu erstellen und die Funktion generisch zu machen.

Es folgt ein Beispiel:

// Map object of Level and Chemicals 
var map = [{ 
    level: 1, 
    disallowed_chemicals: ['baking soda', 'hydrochloric acid', 'beaker', 'water', 'heating plate'] 
}]; 

// getter function to get map object for current level. 
// If this returns undefined you can assume, incorrect level is entered 
function getLevelMap(u_level) { 
    return map.find(function(o) { 
    return o.level === u_level; 
    }); 
} 

var m_level = getLevelMap(users[id].level); 
if (m_level && 
    m_level.every(function(ch) { 
    return msg.toLowerCase().indexOf(ch) < 0; 
    })) { 

    msg.answer("You mix some baking soda with hydrochloric acid.\nSome fun fizzing happens and you produce useless CO2 gas."); 
} 
+0

Es gibt mehrere Schritte in einem Level, deshalb ist die Antwort von Marc Copte mein Favorit, da es kürzer ist, benötigte Chemikalien anstelle von verbotenen Chemikalien für jeden Schritt zu schreiben. +1 für die Mühe. – bdbdbd

Verwandte Themen