मैं अधिकतम मूल्य से अधिक के बिना किसी चर को कैसे बढ़ा सकता हूं?


89

मैं स्कूल के लिए एक सरल वीडियो गेम कार्यक्रम पर काम कर रहा हूं और मैंने एक विधि बनाई है जहां खिलाड़ी को 15 स्वास्थ्य अंक मिलते हैं यदि वह विधि कहलाती है। मुझे स्वास्थ्य को अधिकतम 100 पर रखना है और अपनी सीमित प्रोग्रामिंग क्षमता के साथ इस बिंदु पर मैं कुछ ऐसा कर रहा हूं।

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

मैं समझता हूं कि मेरा सिंटैक्स सही नहीं है, लेकिन मेरा सवाल यह है कि ऐसा करने का एक बेहतर तरीका क्या हो सकता है, क्योंकि मुझे नुकसान बिंदुओं के साथ भी एक समान काम करना है और 0 से नीचे नहीं जाना चाहिए।

इसे संतृप्ति अंकगणित कहा जाता है


7
एक साइड नोट के रूप में, मैं इस पद्धति के लिए एक अलग नाम चुनूंगा। प्रति जावा मानक (और सबसे अधिक अन्य भाषाएँ जो मुझे पता है), एक विधि जिसका नाम "get" से शुरू होता है, को एक मूल्य वापस करना चाहिए, और कुछ भी नहीं बदलना चाहिए। इसी तरह "सेट" से शुरू होने वाले विधि के नाम को एक मूल्य बदलना चाहिए और आमतौर पर कुछ भी वापस नहीं करना चाहिए।
डारेल हॉफमैन

जवाबों:


225

मैं बस यही करूंगा। यह मूल रूप से 100 (अधिकतम स्वास्थ्य) के बीच न्यूनतम लेता है और 15 अतिरिक्त बिंदुओं के साथ स्वास्थ्य क्या होगा। यह सुनिश्चित करता है कि उपयोगकर्ता का स्वास्थ्य 100 से अधिक न हो।

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

यह सुनिश्चित करने के लिए कि हिट पॉइंट्स शून्य से नीचे नहीं जाते हैं, आप एक समान फ़ंक्शन का उपयोग कर सकते हैं Math.max:।

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

71

स्वास्थ्य के लिए सिर्फ 15 जोड़ें, ताकि:

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

हालाँकि, जैसा कि ब्लैंड ने नोट किया है, कभी-कभी मल्टी-थ्रेडिंग (एक ही बार में कोड निष्पादित करने वाले कई ब्लॉक) के साथ स्वास्थ्य किसी भी बिंदु पर 100 से अधिक हो जाता है, जिससे समस्याएं हो सकती हैं, और कई बार स्वास्थ्य संपत्ति को बदलना भी खराब हो सकता है। उस स्थिति में, आप ऐसा कर सकते हैं, जैसा कि अन्य उत्तरों में बताया गया है।

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

9
इसे कभी भी खत्म नहीं होने देना चाहिए, इससे दौड़ की स्थिति जैसी नई समस्याएं सामने आ सकती हैं जहां चरित्र स्वास्थ्य को सबसे अधिक परिभाषित स्वास्थ्य अधिकतम (100) माना जाता है। इस स्तर की परियोजना के लिए पूरी तरह से मैं अनुमान लगाऊंगा, लेकिन अच्छी प्रथाओं को जल्द लागू करना चाहिए।
नरम

6
@ यदि कोई इस दृष्टिकोण का उपयोग करता है, तो इस तरह की दौड़ की स्थिति से बचने का एक तरीका नए स्वास्थ्य मूल्य को संग्रहीत करने के लिए एक अस्थायी चर का उपयोग करना होगा, और यदि आवश्यक हो तो सिंक्रनाइज़ेशन के साथ स्वास्थ्य को इस नए स्वास्थ्य मूल्य में एक स्थान पर सेट करना होगा।
बॉब

13
@ ग्लैंड: मल्टी थ्रेडिंग के समय रेस की स्थितियां केवल प्रासंगिक होती हैं। और अगर वह मल्टी-थ्रेडिंग (जो मुझे अत्यधिक संदेह है) कर रहा है , तो समाधान सभी एक्सेस पर लॉक करना होगा health, या यह सुनिश्चित करने के लिए कि healthकेवल एक थ्रेड से एक्सेस किया जाता है। बाधा "100 से अधिक जाने के लिए स्वास्थ्य को कभी भी अनुमति नहीं देनी चाहिए" एक यथार्थवादी नहीं है।
ब्लूराजा - डैनी पफ्लुगुफ्ट

@ BlueRaja-DannyPflughoeft मैंने कहा कि यह इस परियोजना के लिए संभावना नहीं थी। सामान्य तालों में हमेशा उपयोग नहीं किया जा सकता है और यदि आपके पास अधिकतम मूल्य है, तो इसे कड़ाई से, गेमिंग या अन्यथा पालन किया जाना चाहिए। उदाहरण: यदि कोई घटना किसी संपत्ति के परिवर्तन से जुड़ी हुई है, और प्रतिशत का उपयोग करता है तो आपने अब उस प्रसंस्करण को बहुत कम कर दिया है, साथ ही इसे दो बार लागू किया है। मैं यहां सामान्य रहने की कोशिश कर रहा हूं और ओपी सीख को सुनिश्चित करता हूं - मुझे यह जवाब लगता है, जबकि यह काम करता है, एक छात्र के लिए बहुत संकीर्ण और विशिष्ट है क्योंकि यह उसे लागू करेगा बड़ी तस्वीर के बारे में न सोचने के लिए।
ब्लैंड

@ मुझे लगता है कि यह आसान कुछ के लिए अनावश्यक है।
मैथ चिलर

45

आप intऊपर प्रत्येक के लिए एक अलग मामले की जरूरत नहीं है 85। बस एक है else, ताकि अगर स्वास्थ्य पहले से 86या अधिक है, तो बस इसे सीधे सेट करें 100

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

25
मेरे लिए थोड़ा बहुत मैजिक नंबर (यहां तक ​​कि 100 की अनुमति पर भी विचार करना) - 15 से 16 बदलते समय 85 को समायोजित करने की आवश्यकता होगी। 85 को कम से कम 100 - 15(या 100 -HEALED_HEALTH) सुधार नहीं होगा?
मैक्सीज पीचोटका

37

मुझे लगता है कि ऐसा करने का एक मुहावरेदार, वस्तु उन्मुख तरह से एक है setHealthपर Characterवर्ग। उस पद्धति का कार्यान्वयन इस तरह दिखेगा:

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

यह स्वास्थ्य को 0 या 100 से नीचे जाने से रोकता है, भले ही आप इसे निर्धारित करें।


आपका getHealed()कार्यान्वयन बस यही हो सकता है:

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

क्या यह समझ में आता है कि Characterएक getHealed()विधि पाठक के लिए छोड़ दिया गया एक अभ्यास है :)


5
+1: ऑब्जेक्ट-ओरिएंटेड तरीके से ऐसा करने का यह एक शानदार तरीका है! केवल एक चीज जो मैं सुझा सकता हूं (और यह शायद पाठक के लिए छोड़ दिया जाएगा) संभवतः दो तरीके हैं ( heal(int hp)और damage(int hp)) जो प्रत्येक आपके setHealth(int newValue)तरीके को कहते हैं ।
क्रिस फॉरेन्स

18
पुस्तकालय कार्यों को कॉल करने में क्या गलत है? नामित कार्यों के रूप में, वे सशर्त तर्क के एक समूह की तुलना में अधिक स्पष्ट रूप से इरादे व्यक्त करते हैं।
इरिकसन

2
कई लाइब्रेरी फ़ंक्शंस (और बहुत संभावना है कि ये वाले) वास्तव में बिल्ट-इन हैं और बिल्कुल भी कॉल नहीं करेंगे।
kriss

2
@ मट्टो गलत जवाब - सबसे अधिक संभावना है कि लाइब्रेरी फ़ंक्शन आंतरिक रूप से बिल्कुल वही काम करता है, इसलिए अपने आप को दोहराएं और अपने कोड को प्रदूषित करें? पुस्तकालय कार्यों का उपयोग नहीं करना DRY के मूल सिद्धांतों का पालन नहीं करता है।
NickG

2
@Matteo यह एक से बचने के लिए नहीं है if। यह खुद को पैर में खुद को गोली मारने से रोकने के लिए है। यदि यह बहुत अधिक क्रियाशील है, तो बस स्थैतिक आयात का उपयोग करें। तब यह इस तरह दिखता है: health = max(0, min(100, newValue)) यदि यह अभी भी आपके लिए अपठनीय है, तो इसे एक विधि नाम से निकालें, clampताकि रेखा इस तरह health = clamp(0, 100, newValue)
दिखे

14

मैं कोड की एक और पुन: प्रयोज्य टुकड़ा की पेशकश करने जा रहा हूं, यह सबसे छोटा नहीं है, लेकिन आप इसे किसी भी राशि के साथ उपयोग कर सकते हैं, इसलिए इसके योग्य अभी भी कहा जा सकता है

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

यदि आप खेल को अपने बनाने के लिए आँकड़े जोड़ना चाहते हैं, तो आप 100 को अधिकतमस्वर्गीय चर में बदल सकते हैं, इसलिए पूरी विधि कुछ इस तरह से हो सकती है

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

संपादित करें

अतिरिक्त जानकारी के लिए

जब खिलाड़ी खराब हो जाता है, तो आप ऐसा कर सकते हैं, लेकिन आपको किसी भी तरह की मिनिस्ट्री की आवश्यकता नहीं होगी क्योंकि यह 0 भी होगा। इसे इस तरह से करने से आप एक ही कोड के साथ किसी भी मात्रा को नुकसान और चंगा कर पाएंगे।


1
minHealthनकारात्मक हो सकता है, उदाहरण के लिए, डी एंड डी में कहें ... :)
JYelton

1
अब तक का सबसे अच्छा जवाब यहाँ।
ग्लिच इच्छा

@ येल्टन, हाँ, यदि आप इस कथन में सिर्फ (स्वास्थ्य <= 0) कहेंगे। आप इसे संभाल सकते हैं, लेकिन अगर आप चाहते हैं, अगर आप चाहते हैं कि वे आपको जीवनकाल से केवल 1 ऋण कम कर दें या बस अगर वे बाहर फ्लैट खो देते हैं तो यह संभाल सकता है। यदि आप चाहते हैं कि आप भी अपने नए जीवन की शुरुआत कर सकते हैं -HP की राशि के साथ जो उनके पास थी। आप इस कोड को कहीं भी पेस्ट कर सकते हैं और यह ठीक काम करेगा, यह इस उत्तर की बात थी।
5tar-Kaster


4

मैं एक सहायक कक्षा में एक स्थिर विधि बनाऊंगा। इस तरह, हर मूल्य के लिए कोड को दोहराने के बजाय जो कुछ सीमाओं के भीतर फिट होने की आवश्यकता है, आपके पास एक सभी उद्देश्य विधि हो सकती है। यह मान और अधिकतम को परिभाषित करने वाले दो मूल्यों को स्वीकार करेगा, और उस सीमा के भीतर क्लैंप किए जाने के लिए एक तीसरा मान होगा।

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

आपके मामले के लिए, आप कहीं न कहीं अपने न्यूनतम और अधिकतम स्वास्थ्य की घोषणा करेंगे।

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

फिर अपने न्यूनतम, अधिकतम और समायोजित स्वास्थ्य में गुजरने वाले फ़ंक्शन को कॉल करें।

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

3

मुझे पता है कि यह एक स्कूल परियोजना है, लेकिन अगर आप बाद में अपने खेल का विस्तार करना चाहते हैं और अपनी उपचार शक्ति को अपग्रेड करने में सक्षम हैं, तो इस तरह से फ़ंक्शन लिखें:

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

और फ़ंक्शन को कॉल करें:

getHealed(15);
getHealed(25);

...आदि...

इसके अलावा आप अपने अधिकतम एचपी को एक चर बना सकते हैं जो फ़ंक्शन के लिए स्थानीय नहीं है। चूंकि मुझे नहीं पता कि आप किस भाषा का उपयोग कर रहे हैं, इसलिए मैं एक उदाहरण नहीं दिखाऊंगा क्योंकि इसमें गलत सिंटैक्स हो सकता है।


2

शायद यह?

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

2

यदि आप चुटीले होना चाहते हैं और अपने कोड को एक पंक्ति में फिट करना चाहते हैं, तो आप एक टर्नरी ऑपरेटर का उपयोग कर सकते हैं :

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

ध्यान दें कि कुछ लोग खराब पठनीयता (यकीनन) की वजह से इस सिंटैक्स पर डूब जाएँगे!


4
मुझे health = (health <= 85)?(health+15):100और अधिक पठनीय लगता है (यदि आप वास्तव में एक टर्नरी ऑपरेटर का उपयोग करना चाहते हैं)
मैट्टो

1

मुझे विश्वास है कि यह करेगा

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

स्पष्टीकरण:

  • यदि उपचार के लिए अंतराल 15 या उससे कम है, तो स्वास्थ्य 100 हो जाएगा।

  • अन्यथा यदि अंतराल 15 से बड़ा है, तो यह स्वास्थ्य में 15 जोड़ देगा।

इसलिए उदाहरण के लिए: यदि स्वास्थ्य 83 है, तो यह 98 नहीं बल्कि 100 हो जाएगा।


क्या आप इस बात का विस्तार कर सकते हैं कि यह कैसे अनुरोधकर्ता के प्रश्न को हल करने के लिए काम करेगा?
Ro Yo Mi

यदि उपचार के लिए अंतराल 15 है या कम स्वास्थ्य 100 और हो जाएगा यदि अंतराल 15 से बड़ा है तो यह स्वास्थ्य में 15 जोड़ देगा। इसलिए उदाहरण के लिए स्वास्थ्य 83 है, लेकिन 98 नहीं बल्कि 100 हो जाएगा। यदि कोई विशेष चिंता है तो कृपया मुझे बताएं, टिप्पणी के लिए धन्यवाद।
MarmiK

&& health < 100हालत अनावश्यक है। यदि यह 100 है, तो इसे 100 पर सेट किया जाएगा, कोई परिवर्तन नहीं। एकमात्र कारण जो आपको चाहिए होगा वह यह है कि यह किसी भी तरह से संभव है> 100 किसी भी तरह से और हम नहीं चाहते कि उपचार आपको 100 से कम कर दे।
डारेल हॉफमैन

@DarrelHoffman मुझे लगता है कि आप सही हैं यदि खेल अतिरिक्त स्वास्थ्य प्रदान नहीं करता है 100+ तो आप सही हैं, मैंने अपना उत्तर सही कर लिया है :) धन्यवाद
MarmiK

1

अगर मैं थ्रेड सुरक्षित होना चाहता था, तो मैं एक ब्लॉक किए गए ब्लॉक का उपयोग करने के बजाय इसे इस तरह से करूंगा।

परमाणु तुलना एसेटसेट ओवरहेड के बिना सिंक्रनाइज़ किए गए समान परिणाम प्राप्त करता है।

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

1

मापांक ऑपरेटर का उपयोग करते हुए सबसे सरल तरीका।

health = (स्वास्थ्य + 50)% 100;

स्वास्थ्य कभी भी बराबर या 100 से अधिक नहीं होगा।


लेकिन अगर आप उस ऑपरेशन healthको 100 साल की उम्र में करते हैं , तो आप 50 स्वास्थ्य के साथ समाप्त हो जाएंगे।
परज़िफ़ल

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

यदि आप कार्य करने जा रहे हैं, तो आपको कम से कम 15 को एक पैरामीटर बनाना चाहिए :)
जॉर्डन

@ जोर्डन: यह उस संदर्भ पर निर्भर करता है जो मैं कोड लिख रहा हूं। :-)
मेरी बगल चुंबन
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.