Come posso incrementare una variabile senza superare un valore massimo?

Sto lavorando su un semplice video gioco programma per la scuola e ho creato un metodo in cui il giocatore ottiene 15 punti salute se viene chiamato il metodo. Devo mantenere la salute ad un max di 100 e con la mia limitata capacità di programmazione a questo punto sto facendo qualcosa di simile a questo.

public void getHealed(){
    if(health <= 85)
        health += 15;
    else if(health == 86)
        health += 14;
    else if(health == 87)
    health += 13; 
}//this would continue so that I would never go over 100

Ho capito la mia sintassi circa non è perfetto, ma la mia domanda è, che cosa può essere un modo migliore per farlo, perché devo fare una cosa simile con i punti danno e non andare al di sotto di 0.

Questo è chiamato saturazione aritmetica.

  • Come nota a margine, vorrei scegliere un nome diverso per questo metodo. Per Java standard (e la maggior parte delle altre lingue che conosco), il nome di un metodo che iniziano con “ottenere” dovrebbe restituire un valore, e non cambia nulla. Allo stesso modo il metodo di nomi che iniziano con “set” dovrebbero cambiare un valore e di solito non restituire nulla.
InformationsquelleAutor Steven Eck | 2013-09-05

 

14 Replies
  1. 222

    Vorrei solo fare questo. Fondamentalmente, si prende il minimo tra 100 (il massimo per la salute) e ciò che la salute, sarà con 15 punti extra. Si assicura che la salute non superi i 100.

    public void getHealed() {
        health = Math.min(health + 15, 100);
    }

    Per garantire che i punti ferita non scendere sotto lo zero, è possibile utilizzare una funzione simile: Math.max.

    public void takeDamage(int damage) {
        if(damage > 0) {
            health = Math.max(health - damage, 0);
        }
    }
  2. 71

    basta aggiungere 15 per la salute, in modo da:

    health += 15;
    if(health > 100){
        health = 100;
    }

    Tuttavia, come blando ha notato, a volte con il multi-threading (più blocchi di codice in esecuzione in una sola volta) di avere la salute, andare su 100 a qualsiasi punto può causare problemi, e cambiando la salute proprietà più volte può anche essere un male. In questo caso, si potrebbe fare questo, come già detto in altre risposte.

    if(health + 15 > 100) {
        health = 100;
    } else {
        health += 15;
    }
    • Non dovrebbe mai permettere di andare oltre, questo potrebbe introdurre nuovi problemi come una condizione di competizione in cui il carattere di salute si presume essere più definiti salute max (100). Improbabile per questo progetto a livello immagino, ma deve rispettare le buone pratiche presto.
    • Se uno dovesse usare questo tipo di approccio, un modo di evitare una tale condizione di competizione sarebbe quello di utilizzare una variabile temporanea per memorizzare il nuovo valore della salute, e quindi impostare la salute di questo nuovo valore di salute in un unico luogo, con la sincronizzazione, se necessario.
    • Condizioni di gara sono rilevanti solo quando il multi-threading. E se lui fa il multi-threading (che dubito fortemente), la soluzione sarebbe quella di bloccare tutti gli accessi a health, o per assicurarsi che health è accessibile solo da un thread. Il vincolo di “non Dovrebbe mai permettere di salute per andare su 100” non è realistico.
    • Ho dichiarato che era improbabile per questo progetto. In generale, le serrature non sono andando sempre essere in uso e se si dispone di un valore massimo, quindi dovrebbe essere rigorosamente rispettato, gioco o altro. Esempio: Se un evento è legato al cambiamento di una proprietà e gli usi percentuale quindi ora hai obliqua che il trattamento tantissimo, così come la hanno richiamato due volte. Sto cercando di rimanere qui e di garantire OP impara – mi sento questa risposta, mentre si lavora, è troppo stretto e specifico per uno studente come possa imporre a lui per non pensare che l’immagine grande.
    • penso che è inutile per qualcosa di così semplice.
  3. 45

    Non avete bisogno di un caso separato per ogni int sopra 85. Solo una else, in modo che, se la salute è già 86 o superiore, quindi basta impostare direttamente 100.

    if(health <= 85)
        health += 15;
    else
        health = 100;
    • Un po ‘ troppo di numeri di magia per me (anche considerando 100 ammessi) – quando si modifica il 15 e il 16 85 avrebbe bisogno di essere regolato. Non cambiare 85 per almeno 100 - 15 (o 100 -HEALED_HEALTH) essere un miglioramento?
  4. 37

    Penso che un idiomatiche, object oriented modo di fare questo è quello di avere un setHealth sul Character classe. L’implementazione di tale metodo sarà come questo:

    public void setHealth(int newValue) {
        health = Math.max(0, Math.min(100, newValue))
    }

    Questo impedisce la salute di andare al di sotto di 0 o maggiore di 100, indipendentemente da ciò che si imposta.


    Tuo getHealed() attuazione può essere solo questo:

    public void getHealed() {
        setHealth(getHealth() + 15);
    }

    Se ha senso per il Character avere un getHealed() metodo è un esercizio lasciato al lettore 🙂

    • +1: Questo è un ottimo modo per fare questo in un object-oriented modo! L’unica cosa che potrei suggerire (e questo sarebbe probabilmente essere lasciata al lettore) è, eventualmente, avere due metodi (heal(int hp) e damage(int hp)) che ogni chiamata il setHealth(int newValue) metodo.
    • Questa è una bella soluzione per questo +1
    • La chiamata di due funzioni di libreria (min e max) per evitare che un semplice if è un overkill.
    • Cosa c’è di sbagliato con la chiamata di funzioni di libreria? Come funzioni con nome, hanno l’intento espresso più chiaramente di quanto un mucchio di logica condizionale.
    • Anche molte funzioni di libreria (e molto probabilmente) sono davvero built-in e non effettuare alcuna chiamata.
    • Risposta sbagliata, probabilmente la funzione di libreria che fa esattamente la stessa cosa internamente, quindi perché ripetere a te stesso e inquinare il tuo codice? NON utilizzo di funzioni di libreria non seguire i principi di base del LAVAGGIO.
    • Si preferisce newValue > 100 ? 100 : newValue < 0 ? 0 : newValue? Questo è un MOLTO meno leggibile.
    • Non per le parti interne, ma con entrambi i max e min la dichiarazione non è molto leggibile. Solo la mia opinione, ma se è più leggibile.
    • Non vorrei trovare un se molto più leggibile (ma è solo la mia opinione, non sto dicendo che la soluzione è sbagliata)
    • questo non è quello di evitare un if. Questo per evitare che se stessi da essere in grado di tirarvi la zappa sui piedi. Se è troppo dettagliato, basta usare statico importazioni. Quindi sembra che questo: health = max(0, min(100, newValue)) Se ancora illeggibile a voi, estrarre un metodo denominato clamp in modo che la riga simile a questa: health = clamp(0, 100, newValue)

  5. 14

    Sto solo andando a offrire una più riutilizzabili fetta di codice, non il più piccolo, ma si può utilizzare con qualsiasi importo ancora degno di essere detto

    health += amountToHeal;
    if (health >= 100) 
    { 
        health = 100;
    }

    Si potrebbe anche cambiare il 100 per un maxHealth variabile se si desidera aggiungere le statistiche di gioco rendendo, in modo che il metodo potrebbe essere qualcosa di simile a questo

    private int maxHealth = 100;
    public void heal(int amountToHeal)
    {
        health += amountToHeal;
        if (health >= maxHealth) 
        { 
            health = maxHealth;
        }
    }

    MODIFICA

    Per ulteriori informazioni

    Si potrebbe fare lo stesso per quando il giocatore viene danneggiato, ma non avrebbe bisogno di un minHealth perché sarebbe 0 comunque. Facendo in questo modo si sarebbe in grado di danneggiare e sanare eventuali importi con lo stesso codice.

    • minHealth potrebbe essere negativo, diciamo per esempio, in D&D… 🙂
    • Di gran lunga la migliore risposta qui.
    • sì, devi solo dire (salute <= 0) se la dichiarazione. Si poteva gestire nel modo che si desidera, se si desidera loro di avere la vita, è solo meno 1 dal lifeCount o solo se sono flat out perdere quindi è in grado di gestire. Se si volesse si potrebbe anche iniziare la loro nuova vita con la quantità di HP che avevano. È possibile incollare questo codice praticamente ovunque e si metterà a fare il lavoro bene, che era il punto di questa risposta.
  6. 10
    health = health < 85 ? health + 15 : 100;
    • +1 Questo è come vorrei (e il “migliore” risposta IMHO)
  7. 4

    Vorrei fare un metodo statico in una classe di supporto. In questo modo, anziché ripetere il codice per ogni valore di cui hanno bisogno per adattarsi all’interno di alcuni limiti, si può avere uno scopo tutto il metodo. Si accetta due valori che definiscono il min e max, e un terzo valore di essere bloccato all’interno di tale intervallo.

    class HelperClass
    {
        //Some other methods
    
        public static int clamp( int min, int max, int value )
        {
            if( value > max )
                return max;
            else if( value < min )
                return min;
            else
                return value;
        }
    }

    Per il tuo caso, si dovrebbe dichiarare il minimo e il massimo della salute, da qualche parte.

    final int HealthMin = 0;
    final int HealthMax = 100;

    Quindi chiamare la funzione di passaggio nel vostro min, max, e regolato per la salute.

    health = HelperClass.clamp( HealthMin, HealthMax, health + 15 );
  8. 3

    So che questo è un progetto per la scuola, ma se si voleva espandere il gioco in seguito ed essere in grado di aggiornare il vostro potere di guarigione, scrivere la funzione come:

    public void getHealed(healthPWR) {
        health = Math.min(health + healthPWR, 100);
    }

    e chiamare la funzione:

    getHealed(15);
    getHealed(25);

    …ecc…

    Inoltre è possibile creare il tuo max HP con la creazione di una variabile che non è locale alla funzione. Dato che non so in che linguaggio stai usando, io non mostrare un esempio, perché potrebbe avere la sintassi errata.

  9. 2

    Forse questo?

    public void getHealed()
    {
      if (health <= 85)
      {
        health += 15;
      } else
      {
        health = 100;
      }
    }
  10. 2

    Se vuoi essere sfacciato e adattare il tuo codice su una riga, è possibile utilizzare un operatore ternario:

    health += (health <= 85) ? 15 : (100 - health);

    Nota che alcune persone cipiglio su questa sintassi a causa (probabilmente) la cattiva leggibilità!

    • Trovo health = (health <= 85)?(health+15):100 più leggibile (se vuoi davvero usare un operatore ternario)
    • Troppo complicato.
  11. 1

    Credo che questo farà

    if (health >= 85) health = 100;
    else health += 15;

    Spiegazione:

    • Se il divario per la guarigione è di 15 o meno, la salute diventano 100.

    • Altrimenti, se il divario è più grande di 15, aggiungere 15 per la salute.

    Così, per esempio: se la salute è 83, diventerà 98, ma non 100.

    • Si può espandere su come si lavora per risolvere il richiedente domanda?
    • Se il divario di guarigione è di 15 o meno per la salute diventerà 100 altro se il divario è più grande di 15 aggiungerà 15 per la salute. così, per Esempio, la salute è di 83 diventerà 98, ma non 100. Se qualsiasi interesse specifico per favore fatemi sapere, grazie per il commento.
    • Il && health < 100 condizione è necessaria. Se è 100, sarà impostato a 100, nessun cambiamento. L’unico motivo per cui avrei bisogno è se fosse possibile ottenere > 100, in qualche modo, e noi non vogliamo che la guarigione per ridurre indietro fino a 100.
    • Penso che tu abbia ragione se il gioco non fornire la salute extra 100+ allora hai ragione, ho corretto la mia risposta 🙂 grazie
  12. 1

    Se volevo essere thread-safe mi piacerebbe farlo in questo modo, piuttosto che utilizzando un blocco sincronizzato.

    Atomica compareAndSet ottiene lo stesso risultato sincronizzate, senza il sovraccarico.

    AtomicInteger health = new AtomicInteger();
    
    public void addHealth(int value)
    {
        int original = 0;
        int newValue = 0;
        do
        {
            original = health.get();
            newValue = Math.min(100, original + value);
        }
        while (!health.compareAndSet(original, newValue));
    }
  13. 1

    Più semplice utilizzando l’operatore di modulo.

    salute = (salute + 50) % 100;

    salute non sarà mai uguale o superiore a 100.

    • Ma se si fa l’operazione quando health è 100, si finirebbe con 50 di salute.
  14. 0
       private int health;
        public void Heal()
        {
            if (health > 85)
                health = 100;
            else
                health += 15;
        }
        public void Damage()
        {
            if (health < 15)
                health = 0;
            else
                health -= 15;
        }
    • se avete intenzione di fare funzioni, si dovrebbe fare almeno il 15 essere un parametro 🙂
    • Dipende dal contesto, mi scrive il codice. 🙂

Lascia un commento