अन्य लोगों ने पहले से ही मेरे प्रारंभिक विचार, मैट्रिक्स विधि का सुझाव दिया है, लेकिन अगर बयानों को समेकित करने के अलावा, आप कुछ सुनिश्चित करने से बच सकते हैं कि आपूर्ति की गई तर्क अपेक्षित सीमा में हैं और इन-प्लेस रिटर्न का उपयोग करके (कुछ कोडिंग) मानकों को मैंने फ़ंक्शंस के लिए एक-पॉइंट-आउट-आउट लागू करने के लिए देखा है, लेकिन मैंने पाया है कि तीर कोडिंग से बचने के लिए कई रिटर्न बहुत उपयोगी हैं और जावा में अपवादों के प्रसार के साथ वैसे भी इस तरह के नियम को सख्ती से लागू करने के लिए बहुत अधिक बिंदु नहीं हैं। विधि के अंदर फेंका गया कोई भी अनकहा अपवाद वैसे भी बाहर निकलने का एक संभावित बिंदु है)। नेस्टिंग स्विच स्टेटमेंट एक संभावना है, लेकिन आपके द्वारा जांचे जा रहे मानों की छोटी सी श्रेणी के लिए मैं यह पाता हूं कि क्या स्टेटमेंट्स अधिक कॉम्पैक्ट हैं और प्रदर्शन के अंतर के परिणामस्वरूप अधिक होने की संभावना नहीं है,
public int fightMath(int one, int two) {
if (one > 3 || one < 0 || two > 3 || two < 0) {
throw new IllegalArgumentException("Result is undefined for arguments outside the range [0, 3]");
}
if (one <= 1) {
if (two <= 1) return 0;
if (two - one == 2) return 1;
return 2; // two can only be 3 here, no need for an explicit conditional
}
// one >= 2
if (two >= 2) return 3;
if (two == 1) return 1;
return 2; // two can only be 0 here
}
यह अंत में कम पठनीय होता है क्योंकि यह इनपुट-> परिणाम मानचित्रण के कुछ हिस्सों की अनियमितता के कारण हो सकता है। मैं इसकी सरलता के कारण मैट्रिक्स शैली का पक्ष लेता हूं और आप दृष्टिगोचर बनाने के लिए मैट्रिक्स कैसे सेट कर सकते हैं (हालांकि वह कर्णघट मानचित्रों की मेरी यादों से प्रभावित है):
int[][] results = {{0, 0, 1, 2},
{0, 0, 2, 1},
{2, 1, 3, 3},
{2, 1, 3, 3}};
अद्यतन: ब्लॉकिंग / हिटिंग के अपने उल्लेख को देखते हुए, यहाँ फ़ंक्शन के लिए एक अधिक क्रांतिकारी परिवर्तन है जो इनपुट और परिणाम के लिए उचित / विशेषता-धारण किए हुए प्रकारों का उपयोग करता है और अवरुद्ध करने के लिए परिणाम को थोड़ा संशोधित करता है, जिसके परिणामस्वरूप परिणाम अधिक होना चाहिए पठनीय कार्य।
enum MoveType {
ATTACK,
BLOCK;
}
enum MoveHeight {
HIGH,
LOW;
}
enum Move {
// Enum members can have properties/attributes/data members of their own
ATTACK_HIGH(MoveType.ATTACK, MoveHeight.HIGH),
ATTACK_LOW(MoveType.ATTACK, MoveHeight.LOW),
BLOCK_HIGH(MoveType.BLOCK, MoveHeight.HIGH),
BLOCK_LOW(MoveType.BLOCK, MoveHeight.LOW);
public final MoveType type;
public final MoveHeight height;
private Move(MoveType type, MoveHeight height) {
this.type = type;
this.height = height;
}
/** Makes the attack checks later on simpler. */
public boolean isAttack() {
return this.type == MoveType.ATTACK;
}
}
enum LandedHit {
NEITHER,
PLAYER_ONE,
PLAYER_TWO,
BOTH;
}
LandedHit fightMath(Move one, Move two) {
// One is an attack, the other is a block
if (one.type != two.type) {
// attack at some height gets blocked by block at same height
if (one.height == two.height) return LandedHit.NEITHER;
// Either player 1 attacked or player 2 attacked; whoever did
// lands a hit
if (one.isAttack()) return LandedHit.PLAYER_ONE;
return LandedHit.PLAYER_TWO;
}
// both attack
if (one.isAttack()) return LandedHit.BOTH;
// both block
return LandedHit.NEITHER;
}
यदि आप अधिक ऊंचाइयों के ब्लॉक / हमलों को जोड़ना चाहते हैं, तो आपको केवल फ़ंक्शन को बदलना नहीं है; अतिरिक्त प्रकार की चालों को जोड़ने पर संभवतः फ़ंक्शन के संशोधन की आवश्यकता होगी, हालांकि। इसके अलावा, EnumSet
रों अधिक मुख्य enum के गुणों, जैसे के रूप में अतिरिक्त enums का उपयोग करने से एक्स्टेंसिबल हो सकता है EnumSet<Move> attacks = EnumSet.of(Move.ATTACK_HIGH, Move.ATTACK_LOW, ...);
और उसके बाद attacks.contains(move)
के बजाय move.type == MoveType.ATTACK
, हालांकि का उपयोग कर EnumSet
रों शायद प्रत्यक्ष बराबरी चेकों की तुलना में थोड़ा धीमी हो जाएगा।
उस मामले के लिए जहां एक सफल ब्लॉक एक काउंटर में परिणाम देता है, आप के if (one.height == two.height) return LandedHit.NEITHER;
साथ बदल सकते हैं
if (one.height == two.height) {
// Successful block results in a counter against the attacker
if (one.isAttack()) return LandedHit.PLAYER_TWO;
return LandedHit.PLAYER_ONE;
}
इसके अलावा, if
टर्नरी ऑपरेटर के उपयोग के साथ कुछ कथनों को बदलने से ( boolean_expression ? result_if_true : result_if_false
) कोड को अधिक कॉम्पैक्ट बना सकता है (उदाहरण के लिए, पूर्ववर्ती ब्लॉक में कोड बन जाएगा return one.isAttack() ? LandedHit.PLAYER_TWO : LandedHit.PLAYER_ONE;
), लेकिन इससे हार्ड-टू-रीड ओनलिनर्स हो सकते हैं, इसलिए मैं ' टी इसे और अधिक जटिल शाखाओं में बँटाने की सलाह देते हैं।