'if'문이 너무 많습니까?


263

다음 코드는 내가 필요한 방식으로 작동하지만 못생긴, 과도한 또는 기타 여러 가지입니다. 나는 공식을 살펴보고 몇 가지 해결책을 쓰려고했지만 비슷한 양의 진술로 끝납니다.

이 경우 나에게 도움이되거나 16 개의 if 문이 허용되는 수학 공식이 있습니까?

코드를 설명하기 위해, 그것은 일종의 동시 턴 기반 게임을위한 것입니다. 이것이 도움이된다면 무엇이든 할당했습니다. 결과는 0 = 승리하지 않음, 1 = p1 승리, 2 = p2 승리, 3 = 두 승리입니다.

public int fightMath(int one, int two) {

    if(one == 0 && two == 0) { result = 0; }
    else if(one == 0 && two == 1) { result = 0; }
    else if(one == 0 && two == 2) { result = 1; }
    else if(one == 0 && two == 3) { result = 2; }
    else if(one == 1 && two == 0) { result = 0; }
    else if(one == 1 && two == 1) { result = 0; }
    else if(one == 1 && two == 2) { result = 2; }
    else if(one == 1 && two == 3) { result = 1; }
    else if(one == 2 && two == 0) { result = 2; }
    else if(one == 2 && two == 1) { result = 1; }
    else if(one == 2 && two == 2) { result = 3; }
    else if(one == 2 && two == 3) { result = 3; }
    else if(one == 3 && two == 0) { result = 1; }
    else if(one == 3 && two == 1) { result = 2; }
    else if(one == 3 && two == 2) { result = 3; }
    else if(one == 3 && two == 3) { result = 3; }

    return result;
}


9
분명히 여기에 무차별적인 것이 아니라 일반화 할 수있는 논리가 있습니까? 분명히 f(a, b)일반적인 경우에 답을 산출하는 기능 이 있습니까? 계산의 논리를 설명하지 않았으므로 모든 답변은 돼지의 립스틱 일뿐입니다. int작업에 플래그를 사용하는 것은 매우 오래된 프로그램 논리를 심각하게 다시 생각하는 것으로 시작합니다 . enums는 논리를 포함 할 수 있고 설명 적이므로보다 현대적인 방식으로 코드를 작성할 수 있습니다.
스파이더 보리스

위의 대체 질문에 제공된 @Steve Benett의 답변을 읽은 후에는 본질적으로 데이터베이스와 동일하기 때문에 이에 대한 공식적인 대답이 없다고 가정 할 수 있습니다. 나는 원래의 질문에서 간단한 게임 (파이터)을 만들고 있었고 사용자는 4 개의 버튼을 선택했습니다 : blockHigh (0), blockLow (1), attackHigh (2) 및 attackLow (3). 이 숫자는 필요할 때까지 배열로 유지됩니다. 나중에 'fightMath ()'함수에 의해 사용되어 playerTwos에 대해 playerOne의 선택을 호출하여 결과를 제공합니다. 실제 충돌 감지가 없습니다.
TomFirth

9
답변이 있으시면 게시하십시오. 주석에 대한 자세한 논의는 특히 코드가 관련된 경우 따르기가 어렵습니다. 이 질문이 코드 검토로 마이그레이션되었는지 여부에 대해 이야기하고 싶다면 메타 토론이 있습니다.
George Stocker

1
"데이터베이스와 동일하다"는 무슨 뜻입니까? 이 값이 데이터베이스에있는 경우 해당 값을 데이터베이스에서 가져 오십시오. 그렇지 않으면 실제로 이것이 복잡한 경우 사람들이 진행중인 상황을 이해하도록 각 줄마다 비즈니스 로직 주석을 추가하고 그대로 둡니다. 길고 명백한 것이 나에게 더 낫습니다. 미래의 누군가가 무슨 일이 일어나고 있는지 이해할 수 있습니다. 지도에 넣거나 8 줄의 코드를 저장하려고하면 거꾸로 된 크기가 작고 크기가 커집니다. 하루 동안 코드를 읽어야하는 사람에게는 점점 더 혼란 스럽습니다.
skaz

답변:


600

수식을 만들 수 없으면 제한된 수의 결과에 표를 사용할 수 있습니다.

final int[][] result = new int[][] {
  { 0, 0, 1, 2 },
  { 0, 0, 2, 1 },
  { 2, 1, 3, 3 },
  { 1, 2, 3, 3 }
};
return result[one][two];

7
내가 전에이 솔루션을 보지 못했기 때문에 이것은 흥미 롭습니다. 나는 반환 결과를 이해하지 못하지만 테스트를 즐길 것입니다.
TomFirth

4
어설 션이 필요하지 않습니다. IndexOutOfBoundsException하나 이상의 인덱스가 범위를 벗어나면 Java는 어쨌든 던집니다 .
JAB

43
@JoeHarper 읽기 쉬운 것을 원한다면, 처음에는 매직 넘버를 사용하지 않을 것이고 매핑을 설명하는 주석이있을 것입니다. 그대로, 나는 원래 버전보다이 버전을 선호하지만, 장기적으로 유지할 수있는 것은 열거 형이나 적어도 명명 된 상수를 포함하는 접근 방식을 사용합니다.
JAB

13
@JoeHarper "이론적으로"는 하나이고 "실제로"는 또 다른 것입니다. 물론 상수 이름을 지정하고 코드를 읽을 수있는 방식으로 배열하는 등의 설명 적 명명 ( 루프 변수에 대한 i/ j/ k규칙 제외)을 사용하려고 하지만 변수 및 함수 이름이 20 자 이상을 차지할 때 내가 찾은 각각은 실제로 읽을 수없는 코드로 이어집니다. 내 일반적인 접근 방식은 여기에 의견 이해하지만 간결한 코드를 시도하고 거기에 설명하는 이유 코드 (어떻게 대)가되는 방법을 구성되어있다. 이름에 이유를 넣으면 모든 것이 복잡해집니다.
JAB

13
결과는 실제로 결과 매트릭스에 의해 결정 되므로이 특정 문제에 대해이 솔루션을 좋아합니다.
시도

201

데이터 세트가 너무 작기 때문에 모든 것을 1 개의 긴 정수로 압축하여 수식으로 변환 할 수 있습니다

public int fightMath(int one,int two)
{
   return (int)(0xF9F66090L >> (2*(one*4 + two)))%4;
}

비트 별 변형 :

이것은 모든 것이 2의 배수라는 사실을 이용합니다.

public int fightMath(int one,int two)
{
   return (0xF9F66090 >> ((one << 3) | (two << 1))) & 0x3;
}

마법 상수의 기원

내가 무엇을 말할 수 있습니까? 세상에는 마술이 필요합니다. 때로는 무언가가 창조를 요구할 수도 있습니다.

OP의 문제를 해결하는 함수의 본질은 2 개의 숫자 (1, 2), 도메인 {0,1,2,3}에서 {0,1,2,3} 범위까지의 맵입니다. 각 답변은 해당지도를 구현하는 방법에 접근했습니다.

또한 많은 답변에서 문제의 상태가 1 2 자리 기본 4 숫자 N (1, 2)의 맵으로 나타납니다. 여기서 1은 숫자 1, 2는 숫자 2, N = 4 * 1입니다. + 2; N = {0,1,2, ..., 15}-16 개의 다른 값이 중요합니다. 함수의 출력은 1 자리의 기본 4 자리 숫자 {0,1,2,3}-4 개의 다른 값이며 중요합니다.

이제 1 자리 4 자리 숫자는 2 자리 2 자리 숫자로 표현할 수 있습니다. {0,1,2,3} = {00,01,10,11}이므로 각 출력은 2 비트로 만 인코딩 될 수 있습니다. 위에서는 16 개의 서로 다른 출력 만 가능하므로 전체 맵을 인코딩하는 데 필요한 것은 16 * 2 = 32 비트입니다. 이것은 모두 1 정수에 맞을 수 있습니다.

상수 M은 m (0)이 비트 M [0 : 1]로 인코딩되고 m (1)이 비트 M [2 : 3]으로 인코딩되고 m (n)이 비트로 인코딩되는 맵 m의 인코딩입니다. M [n * 2 : n * 2 + 1].

남아있는 것은 모두 상수의 오른쪽 부분을 인덱싱하고 반환하는 것입니다.이 경우 M을 2 * N 번 오른쪽으로 시프트하고 2 개의 최상위 비트를 가져갈 수 있습니다 (M >> 2 * N) & 0x3. 식 (하나 << 3)과 (두 << 1)은 2 * x = x << 1 및 8 * x = x << 3임을 지적하면서 여러 가지를 곱하는 것입니다.


79
똑똑하지만 코드를 읽는 사람은 아무도 그것을 이해할 수 없습니다.
Aran Mulholland

106
나는 이것이 매우 나쁜 습관이라고 생각합니다. 저자를 제외하고는 아무도 그것을 이해하지 못할 것입니다. 코드를보고 빠르게 이해하려고합니다. 그러나 이것은 단지 시간 낭비입니다.
Balázs Németh

14
나는 @ BalázsMáriaNémeth에 있습니다. 매우 인상적이지만 폭력적인 정신병자를 코딩해야합니다!
OrhanC1

90
모든 다운 보 터는 이것이 끔찍한 코드 냄새라고 생각합니다. 모든 지지자들은 똑같이 생각하지만 그 뒤에있는 영리함에 감탄합니다. +1 (이 코드를 사용하지 마십시오.)
usr

4
쓰기 전용 코드 의 멋진 예입니다 !
lealand

98

JAB를 제외하고 제시된 솔루션은 마음에 들지 않습니다. 다른 어떤 것도 코드를 쉽게 읽고 계산되고있는 것을 이해하지 못합니다 .

이 코드를 작성하는 방법은 다음과 같습니다. Java가 아닌 C # 만 알고 있지만 그림을 얻습니다.

const bool t = true;
const bool f = false;
static readonly bool[,] attackResult = {
    { f, f, t, f }, 
    { f, f, f, t },
    { f, t, t, t },
    { t, f, t, t }
};
[Flags] enum HitResult 
{ 
    Neither = 0,
    PlayerOne = 1,
    PlayerTwo = 2,
    Both = PlayerOne | PlayerTwo
}
static HitResult ResolveAttack(int one, int two)
{
    return 
        (attackResult[one, two] ? HitResult.PlayerOne : HitResult.Neither) | 
        (attackResult[two, one] ? HitResult.PlayerTwo : HitResult.Neither);
}    

여기서 계산되는 내용이 훨씬 더 명확 해집니다. 이는 누가 우리가 어떤 공격에 타격을 받는지 계산하고 두 결과를 모두 반환한다는 것을 강조합니다.

그러나 이것은 더 나을 수 있습니다. 부울 배열은 다소 불투명합니다. 나는 테이블 룩업 접근법을 좋아하지만 의도 한 게임 의미가 무엇인지 명확히하는 방식으로 작성하는 경향이 있습니다. 즉, "제로의 공격과 하나의 방어는 명중되지 않음"보다는 코드가 "낮은 킥 공격과 낮은 블록 방어는 명중되지 않음"을보다 명확하게 암시하는 방법을 찾으십시오. 코드가 게임의 비즈니스 로직을 반영하도록합니다.


66
무의미한 말. 가장 경험이 많은 프로그램은 여기서 제공되는 조언을 이해하고 코딩 스타일을 자신의 언어에 적용 할 수 있습니다. 문제는 일련의 if를 피하는 방법이었습니다. 이것은 방법을 보여줍니다.
GreenAsJade

6
@ user3414693 : Java 질문이라는 것을 잘 알고 있습니다. 답을주의 깊게 읽으면 분명해집니다. 내 대답이 현명하지 않다고 믿는다면 나 자신이 더 좋아하는 답을 쓰도록 권합니다.
Eric Lippert

1
@EricLippert 저도 JAB의 솔루션을 좋아합니다. IMHO, C #의 열거 형 유형은 많이 필요합니다. 나머지 기능이하는 성공 철학의 구덩이를 따르지 않습니다. 예 : stackoverflow.com/a/847353/92414 c # 팀은 더 나은 방식으로 설계된 새로운 열거 형을 만들 계획이 있습니까 (기존 코드가 손상되지 않도록)?
SolutionYogi

@SolutionYogi : C #의 열거 형을 좋아하지는 않지만 좋은 이유 때문에 그렇습니다. (주로 기존 COM 열거 형과의 호환성을 위해) C # 6에서 열거 형을위한 새로운 장비를 추가 할 계획이 없습니다.
Eric Lippert

3
@SList 아니오, 코멘트가 실행되지 않습니다. OP는해야 할 일을 정확히 수행했습니다. 주석을 명확한 코드로 변환하십시오. 예 : Steve McConnell 코드 완성 stevemcconnell.com/cccntnt.htm
djechlin 12

87

결과가 포함 된 행렬을 만들 수 있습니다

int[][] results = {{0, 0, 1, 2}, {0, 0, 2, 1},{2, 1, 3, 3},{2, 1, 3, 3}};

가치를 얻고 싶을 때

public int fightMath(int one, int two) {
  return this.results[one][two]; 
}

69

다른 사람들은 이미 초기 아이디어 인 행렬 방법을 제안했지만 if 문을 통합하는 것 외에도 제공된 인수가 예상 범위에 있는지 확인하고 내부 반환 (일부 코딩)을 사용하여 일부 내용을 피할 수 있습니다 내가 한 함수에 대해 한 번의 종료 지점을 시행하는 것으로 보았지만 여러 리턴이 화살표 코딩을 피하는 데 매우 유용하며 Java에서 예외가 발생함에 따라 어쨌든 그러한 규칙을 엄격하게 시행하는 데는 아무런 의미가 없습니다. 메소드 내에서 발생하는 잡히지 않은 예외는 어쨌든 가능한 종료점이므로). 중첩 스위치 문은 가능하지만 여기에서 확인하는 작은 값 범위의 경우 문이 더 작고 성능 차이가 많이 발생하지 않는지 확인합니다.

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 예를 들어 주요 열거의 속성으로 추가 열거 형을 사용하는 것보다 더 확장 할 수 있습니다 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;해지지 만 (예 : 앞의 블록에있는 코드가 될 수 있음 ) 읽기 어려운 원 라이너로 이어질 수 있습니다. ' 더 복잡한 분기에 권장하지 않습니다.


나는 확실히이 조사하지만 내 현재 코드 날의 int 값을 사용할 수 있습니다 onetwo내 spritesheet에 시작 지점으로 재사용 할 수 있습니다. 그것을 허용하기 위해 많은 추가 코드가 필요하지는 않지만.
TomFirth 2014 년

2
@ TomFirth84있다 EnumMap당신이 (당신은 또한 예를 들면, 직접 열거 멤버의 서수 값을 사용할 수 있습니다 귀하의 정수 오프셋 (offset)에 열거를 매핑하는 데 사용할 수있는 클래스 Move.ATTACK_HIGH.ordinal()0, Move.ATTACK_LOW.ordinal()1, 등,하지만, 명시 적으로 이상이의 더 깨지기 쉬운 / 덜 유연한 기존 멤버들 사이에 열거 형 값을 추가 할 때 각 멤버를 값과 연관 시키면 카운트가 없어 질 것 EnumMap입니다.
JAB

7
이것은 코드를 읽는 사람에게 의미있는 것으로 코드를 변환하기 때문에 가장 읽기 쉬운 솔루션입니다.
David Stanley

적어도 열거 형을 사용하는 코드가 잘못되었습니다. OP의 if 문에 따르면 성공적으로 차단되면 공격자가 적중합니다. 그러나 완전한 코드를 의미하려면 +1입니다.
Taemyr

2
이동이 성공적인 공격이면 HIT를 반환하고 이동이 차단 된 공격이면 BACKFIRE를, 공격이 아닌 경우 NOTHING을 반환 attack(against)하여 Move열거 형에 메소드를 추가 할 수도 있습니다 . 당신은 (일반적으로 그것을 구현할 수있는이 방법 public boolean attack(Move other) { if this.isAttack() return (other.isAttack() || other.height != this.height) ? HIT : BACKFIRE; return NOTHING; }), 그리고 필요한 경우 특정 이동에 재정의 (모든 블록을 차단할 수 있습니다 약한 이동, 공격 결코 역화 등)
다시

50

왜 배열을 사용하지 않습니까?

처음부터 시작하겠습니다. 패턴이 보이면 값이 0에서 3으로 바뀌고 가능한 모든 값을 잡기를 원합니다. 이것은 당신의 테이블입니다 :

0 & 0 = 0
0 & 1 = 0
0 & 2 = 1
0 & 3 = 2
1 & 0 = 0
1 & 1 = 0
1 & 2 = 2
1 & 3 = 1
2 & 0 = 2
2 & 1 = 1
2 & 2 = 3
2 & 3 = 3
3 & 0 = 2
3 & 1 = 1
3 & 2 = 3
3 & 3 = 3

이 같은 테이블 바이너리를 보면 다음과 같은 결과가 나타납니다.

00 & 00 = 00
00 & 01 = 00
00 & 10 = 01
00 & 11 = 10
01 & 00 = 00
01 & 01 = 00
01 & 10 = 10
01 & 11 = 01
10 & 00 = 10
10 & 01 = 01
10 & 10 = 11
10 & 11 = 11
11 & 00 = 10
11 & 01 = 01
11 & 10 = 11
11 & 11 = 11

아마 당신은 이미 어떤 패턴을 보았지만 1과 2의 값을 결합하면 0000, 0001, 0010, ..... 1110과 1111의 모든 값을 사용하고 있음을 알 수 있습니다. 이제 값 1과 2를 결합하여 단일을 만들어 봅시다. 4 비트 정수

0000 = 00
0001 = 00
0010 = 01
0011 = 10
0100 = 00
0101 = 00
0110 = 10
0111 = 01
1000 = 10
1001 = 01
1010 = 11
1011 = 11
1100 = 10
1101 = 01
1110 = 11
1111 = 11

이것을 10 진수 값으로 다시 변환하면 하나와 두 개의 조합이 색인으로 사용될 수있는 매우 가능한 값 배열이 표시됩니다.

0 = 0
1 = 0
2 = 1
3 = 2
4 = 0
5 = 0
6 = 2
7 = 1
8 = 2
9 = 1
10 = 3
11 = 3
12 = 2
13 = 1
14 = 3
15 = 3

그런 다음 배열은 {0, 0, 1, 2, 0, 0, 2, 1, 2, 1, 3, 3, 2, 1, 3, 3}인덱스이며 단순히 하나와 두 개의 조합입니다.

나는 자바 프로그래머는 아니지만 모든 if 문을 제거하고 다음과 같이 쓸 수 있습니다.

int[] myIntArray = {0, 0, 1, 2, 0, 0, 2, 1, 2, 1, 3, 3, 2, 1, 3, 3};
result = myIntArray[one * 4 + two]; 

비트 시프트가 2만큼 곱셈보다 빠른지 모르겠습니다. 그러나 시도해 볼 가치가 있습니다.


2
2의 비트 시프트는 4의 곱보다 거의 확실히 빠릅니다. 최대 4의 곱셈은 4가 2 ^ 2임을 인식하고 비트 시프트 자체를 수행합니다 (컴파일러에 의해 잠재적으로 변환 됨). 솔직히 말해서, 변화는 더 읽기 쉽습니다.
Cruncher

나는 당신의 접근 방식을 좋아합니다! 기본적으로 4x4 행렬을 16 개의 요소 배열로 평면화합니다.
Cameron Tinker 2014 년

6
요즘 내가 실수하지 않으면 컴파일러는 의심 할 여지없이 2의 거듭 제곱을 곱하고 있음을 인식하고 그에 따라 최적화합니다. 따라서 프로그래머에게는 비트 시프트와 곱셈이 동일한 성능을 가져야합니다.
Tanner Swett

24

이것은 약간의 비트 매직을 사용합니다 (단일 정수로 두 비트의 정보 (낮음 / 높음 및 공격 / 차단)를 유지하여 이미하고 있습니다) :

나는 그것을 실행하지 않고 여기에만 입력했습니다. 다시 확인하십시오. 아이디어는 분명히 작동합니다. 편집 : 이제 모든 입력에 대해 테스트되었으며 정상적으로 작동합니다.

public int fightMath(int one, int two) {
    if(one<2 && two<2){ //both players blocking
        return 0; // nobody hits
    }else if(one>1 && two>1){ //both players attacking
        return 3; // both hit
    }else{ // some of them attack, other one blocks
        int different_height = (one ^ two) & 1; // is 0 if they are both going for the same height - i.e. blocker wins, and 1 if height is different, thus attacker wins
        int attacker = one>1?1:0; // is 1 if one is the attacker, two is the blocker, and 0 if one is the blocker, two is the attacker
        return (attacker ^ different_height) + 1;
    }
}

아니면 두 비트의 정보를 별도의 변수로 분리하도록 제안해야합니까? 위와 같은 비트 연산을 기반으로 한 코드는 일반적으로 유지 관리하기가 어렵습니다.


2
이 솔루션에 동의하며 주요 질문에 대한 의견에서 생각했던 것과 매우 비슷합니다. 나는 그것을 별도의 변수로 나누는 것을 선호합니다. 따라서 나중에 예를 들어 중간 공격을 쉽게 추가 할 수 있습니다.
Yoh

2
테스트 후 위의 코드에서 일부 버그를 수정했습니다. 이제 잘 작동합니다. 비트 매니퓰레이터의 방식에 대해 더 나아가서 나는 다른 솔루션의 비트 마스크만큼 신비적이지는 않지만 여전히 당신의 마음을 망칠 정도로 까다로운 한 줄 솔루션을 생각해 냈습니다.return ((one ^ two) & 2) == 0 ? (one & 2) / 2 * 3 : ((one & 2) / 2 ^ ((one ^ two) & 1)) + 1;
elias

1
이것은 새로운 프로그래머가 읽는 모든 마법 숫자 뒤에 발생하는 마법을 실제로 이해하므로 가장 좋은 대답입니다.
bezmax

20

솔직히 말해서 모든 사람은 자신의 코드 스타일을 가지고 있습니다. 나는 성능이 너무 많이 영향을받을 것이라고 생각하지 않았을 것입니다. 스위치 케이스 버전을 사용하는 것보다 더 잘 이해하면 계속 사용하십시오.

ifs를 중첩 할 수 있으므로 if 문을 많이 거치지 않았으므로 마지막 if 검사의 성능이 약간 향상 될 수 있습니다. 그러나 기본 자바 코스의 맥락에서 아마 도움이되지 않을 것입니다.

else if(one == 3 && two == 3) { result = 3; }

그래서 대신에 ...

if(one == 0 && two == 0) { result = 0; }
else if(one == 0 && two == 1) { result = 0; }
else if(one == 0 && two == 2) { result = 1; }
else if(one == 0 && two == 3) { result = 2; }

넌 ...

if(one == 0) 
{ 
    if(two == 0) { result = 0; }
    else if(two == 1) { result = 0; }
    else if(two == 2) { result = 1; }
    else if(two == 3) { result = 2; }
}

원하는대로 다시 포맷하십시오.

이렇게하면 코드가 더 좋아 보이지 않지만 잠재적으로 코드 속도가 느려질 수 있습니다.


3
이것이 좋은 습관인지는 모르지만이 경우 중첩 스위치 문을 사용합니다. 더 많은 공간이 필요하지만 실제로는 분명합니다.
염료 염료

그것은 또한 효과가 있지만 그것은 선호의 문제라고 생각합니다. 실제로 코드가하는 일을 실제로 말하는 것처럼 if 문을 선호합니다. 물론 당신의 의견을 제시하지 않으면, 당신에게 효과가 있습니다 :). 그래도 대안 제안에 찬성!
Joe Harper

12

우리가 알고있는 것을 보자

1 : 답변은 P1 (플레이어 1) 및 P2 (플레이어 2)에 대해 대칭입니다. 이것은 격투 게임에 적합하지만 논리를 향상시키기 위해 활용할 수있는 것이기도합니다.

2 : 3 비트 0 비트 2 비트 1 비트 3이 경우에 포함되지 않는 유일한 경우는 0 대 1과 2 대 3의 조합입니다. 다른 방식으로 말하자면 고유 한 승리 테이블은 다음과 같습니다. 0 비트 2, 1 비트 3, 2 비트 1, 3 비트 0.

3 : 0/1이 서로 맞 닿으면 무승부 무승부가 있지만 2/3이 서로 맞 닿으면 두 명 모두 맞습니다.

먼저, 우리가 이겼는지 알려주는 단방향 함수를 만들어 보자.

// returns whether we beat our opponent
public boolean doesBeat(int attacker, int defender) {
  int[] beats = {2, 3, 1, 0};
  return defender == beats[attacker];
}

그런 다음이 함수를 사용하여 최종 결과를 구성 할 수 있습니다.

// returns the overall fight result
// bit 0 = one hits
// bit 1 = two hits
public int fightMath(int one, int two)
{
  // Check to see whether either has an outright winning combo
  if (doesBeat(one, two))
    return 1;

  if (doesBeat(two, one))
    return 2;

  // If both have 0/1 then its hitless draw but if both have 2/3 then they both hit.
  // We can check this by seeing whether the second bit is set and we need only check
  // one's value as combinations where they don't both have 0/1 or 2/3 have already
  // been dealt with 
  return (one & 2) ? 3 : 0;
}

이것은 많은 답변에서 제공되는 테이블 조회보다 더 복잡하고 아마도 느리지 만 실제로는 코드의 논리를 캡슐화하고 코드를 읽는 사람에게 설명하기 때문에 우수한 방법이라고 생각합니다. 이것이 더 나은 구현이라고 생각합니다.

(구문이 꺼져 있으면 Java가 사과했기 때문에 오랜 시간이 지났지 만, 약간 틀렸다면 여전히 이해할 수 있습니다.)

그건 그렇고, 0-3은 분명히 무언가를 의미 합니다. 그것들은 임의의 값이 아니므로 이름을 지정하는 데 도움이됩니다.


11

나는 논리를 올바르게 이해하기를 바랍니다. 어때요?

public int fightMath (int one, int two)
{
    int oneHit = ((one == 3 && two != 1) || (one == 2 && two != 0)) ? 1 : 0;
    int twoHit = ((two == 3 && one != 1) || (two == 2 && one != 0)) ? 2 : 0;

    return oneHit+twoHit;
}

한 명중 또는 한 명중을 확인하는 것은 차단되지 않으며 두 번째 선수에 대해서도 동일합니다.

편집 : 알고리즘을 완전히 이해하지 못했습니다, 내가 깨달았을 때 "적중"수여 (Thx elias) :

public int fightMath (int one, int two)
{
    int oneAttack = ((one == 3 && two != 1) || (one == 2 && two != 0)) ? 1 : (one >= 2) ? 2 : 0;
    int twoAttack = ((two == 3 && one != 1) || (two == 2 && one != 0)) ? 2 : (two >= 2) ? 1 : 0;

    return oneAttack | twoAttack;
}

후두둑 좋은 결과를 찾는 방법!
차드

1
접근 방식이 마음에 들지만이 솔루션에는 공격을 차단하여 공격 할 가능성이 완전히 없습니다 (예 : one = 0 및 two = 2 인 경우 0을 반환하지만 사양에 따라 1이 예상 됨). 어쩌면 당신은 그것을 올바르게하기 위해 노력할 수도 있지만 결과 코드가 여전히 우아 할 것이라고 확신하지 못합니다. 이는 라인이 다소 길어질 것임을 의미합니다.
elias

"히트"가 블록으로 수여되었음을 알지 못했습니다. 지적 해 주셔서 감사합니다. 매우 간단한 수정으로 조정되었습니다.
Chris

10

Java에 대한 경험이 없으므로 오타가있을 수 있습니다. 코드를 의사 코드로 고려하십시오.

간단한 스위치를 사용하겠습니다. 이를 위해서는 단일 숫자 평가가 필요합니다. 그러나,이 경우에, 이후 0 <= one < 4 <= 90 <= two < 4 <= 9, 우리는 곱하여 간단한 INT에 모두의 int로 변환 할 수 있습니다 one(10)에 의해 추가 two. 그런 다음 결과 번호의 스위치를 다음과 같이 사용하십시오.

public int fightMath(int one, int two) {
    // Convert one and two to a single variable in base 10
    int evaluate = one * 10 + two;

    switch(evaluate) {
        // I'd consider a comment in each line here and in the original code
        // for clarity
        case 0: result = 0; break;
        case 1: result = 0; break;
        case 1: result = 0; break;
        case 2: result = 1; break;
        case 3: result = 2; break;
        case 10: result = 0; break;
        case 11: result = 0; break;
        case 12: result = 2; break;
        case 13: result = 1; break;
        case 20: result = 2; break;
        case 21: result = 1; break;
        case 22: result = 3; break;
        case 23: result = 3; break;
        case 30: result = 1; break;
        case 31: result = 2; break;
        case 32: result = 3; break;
        case 33: result = 3; break;
    }

    return result;
}

이론적 코드로 지적하고 싶은 또 다른 짧은 방법이 있습니다. 그러나 일반적으로 다루고 싶지 않은 추가 복잡성이 있기 때문에 사용하지 않을 것입니다. 계산이 0, 1, 2, 3, 10, 11, 12, 13, 20, ...이기 때문에 추가 복잡도는 기본 4 에서 나옵니다 .

public int fightMath(int one, int two) {
    // Convert one and two to a single variable in base 4
    int evaluate = one * 4 + two;

    allresults = new int[] { 0, 0, 1, 2, 0, 0, 2, 1, 2, 1, 3, 3, 1, 2, 3, 3 };

    return allresults[evaluate];
}

Java에서 무언가를 놓친 경우를 대비하여 추가 참고 사항입니다. PHP에서는 다음을 수행합니다.

function fightMath($one, $two) {
    // Convert one and two to a single variable in base 4
    $evaluate = $one * 10 + $two;

    $allresults = array(
         0 => 0,  1 => 0,  2 => 1,  3 => 2,
        10 => 0, 11 => 0, 12 => 2, 13 => 1,
        20 => 2, 21 => 1, 22 => 3, 23 => 3,
        30 => 1, 31 => 2, 32 => 3, 33 => 3 );

    return $allresults[$evaluate];
}

Java는 8 번째 버전 이전에 람다가 없습니다
Kirill Gamazkov

1
이. 그런 적은 수의 입력의 경우 복합 값을 가진 스위치를 사용합니다 (100 또는 1000과 같이 10보다 큰 승수로 더 읽을 수는 있지만).
Medinoc

7

중첩 된 if조건부 를 선호하므로 다른 방법이 있습니다. 멤버를
사용 result하지 않으며 상태를 변경하지 않습니다.

public int fightMath(int one, int two) {
    if (one == 0) {
      if (two == 0) { return 0; }
      if (two == 1) { return 0; }
      if (two == 2) { return 1; }
      if (two == 3) { return 2; }
    }   
    if (one == 1) {
      if (two == 0) { return 0; }
      if (two == 1) { return 0; }
      if (two == 2) { return 2; }
      if (two == 3) { return 1; }
    }
    if (one == 2) {
      if (two == 0) { return 2; }
      if (two == 1) { return 1; }
      if (two == 2) { return 3; }
      if (two == 3) { return 3; }
    }
    if (one == 3) {
      if (two == 0) { return 1; }
      if (two == 1) { return 2; }
      if (two == 2) { return 3; }
      if (two == 3) { return 3; }
    }
    return DEFAULT_RESULT;
}

왜 다른 거 없어?
FDinoff

3
@ FDinoff else체인 을 사용할 수 있었지만 아무런 차이가 없었습니다.
Nick Dandoulakis 2014 년

1
나는 그것이 사소한 것임을 알고 있지만 else 체인을 더 빠르게 실행하지 않습니까? 4 건 중 3 건? 나는 단지 몇 번의주기 일지라도 가능한 한 빨리 실행하기 위해 코드를 작성하는 습관을 만듭니다.
Brandon Bearden

2
@BrandonBearden은 아무런 차이가 없습니다 (입력이 항상 0..3 범위에 있다고 가정). 컴파일러는 어쨌든 코드를 미세 최적화합니다. 일련의 else if문장 이 있으면 코드를 사용 switch하거나 테이블을 조회 할 수 있습니다.
Nick Dandoulakis 2014 년

어때요? 경우 one==0는 코드를 실행, 그것은 있는지 확인해야합니다 one==1다음 경우 one==2마지막 경우 one==3- 그것은 첫 경기 후 문을 종료 때문에의 존재를에, 그것은 지난 3 확인을하지 않는다면 다른 사람이 있다면. 그리고 예, 문 대신 switch 문을 if (one...사용하고 one's. 의 경우 다른 스위치 를 사용하여 더 최적화 할 수 있습니다. 그러나 그것은 내 질문이 아닙니다.
Brandon Bearden

6

스위치 케이스로 사용해보십시오 . ..

여기 또는 여기에 그것에 대해 더 많은 정보를 원하시면

switch (expression)
{ 
  case constant:
        statements;
        break;
  [ case constant-2:
        statements;
        break;  ] ...
  [ default:
        statements;
        break;  ] ...
}

여러 조건을 동시에 추가 할 수 있으며 다른 경우가 충족되지 않은 기본 옵션을 사용할 수도 있습니다 .

PS : 하나의 조건이 충족 되어야만합니다 ..

두 가지 조건이 동시에 발생하면 스위치를 사용할 수 없다고 생각합니다. 그러나 여기에서 코드를 줄일 수 있습니다.

자바 스위치 문 여러 경우


6

나에게 일어난 첫 번째 일은 본질적으로 Francisco Presencia와 같은 대답이지만 다소 최적화되었습니다.

public int fightMath(int one, int two)
{
    switch (one*10 + two)
    {
    case  0:
    case  1:
    case 10:
    case 11:
        return 0;
    case  2:
    case 13:
    case 21:
    case 30:
        return 1;
    case  3:
    case 12:
    case 20:
    case 31:
        return 2;
    case 22:
    case 23:
    case 32:
    case 33:
        return 3;
    }
}

마지막 경우 (3의 경우)를 기본 경우로 만들어 더 최적화 할 수 있습니다.

    //case 22:
    //case 23:
    //case 32:
    //case 33:
    default:
        return 3;

이 방법의 장점은 다른 제안 된 방법보다 어떤 값을 반환 one하고 어떤 값을 two반환 하는지 쉽게 알 수 있다는 것입니다 .


이것은 여기 에 또 다른 대답의 변형입니다 .
David R Tribble

6
((two&2)*(1+((one^two)&1))+(one&2)*(2-((one^two)&1)))/2

4
도착하는데 시간이 얼마나 걸렸습니까?
mbatchkarov

2
@mbatchkarov 10 분 동안 다른 답변을 읽은 다음 10 분 동안 연필과 종이로 낙서하십시오.
Dawood ibn Kareem

7
이것을 유지해야한다면 정말 슬플 것입니다.
Meryovi

흠 ... 버그가 있습니다 : 당신이 누락되었습니다; --unicorns
Alberto

나는 간결하지만 APL 코드처럼 끔찍한 소품 인 @Meryovi에 동의합니다
Ed Griebel


3

1/2과 결과 사이에 표를 그리면 하나의 패턴이 보입니다.

if(one<2 && two <2) result=0; return;

위의 내용은 적어도 3 개의 if 문을 줄였습니다. 나는 설정된 패턴을 보지 못하거나 주어진 코드에서 많은 것을 얻을 수 없지만 그러한 논리를 도출 할 수 있다면 많은 if 문을 줄일 수 있습니다.

도움이 되었기를 바랍니다.


3

규칙을 텍스트로 정의하는 것이 좋으며 올바른 수식을 쉽게 도출 할 수 있습니다. 이것은 laalto의 멋진 배열 표현에서 추출되었습니다.

{ 0, 0, 1, 2 },
{ 0, 0, 2, 1 },
{ 2, 1, 3, 3 },
{ 1, 2, 3, 3 }

여기에 일반적인 의견이 있지만 규칙 용어로 설명해야합니다.

if(one<2) // left half
{
    if(two<2) // upper left half
    {
        result = 0; //neither hits
    }
    else // lower left half
    {
        result = 1+(one+two)%2; //p2 hits if sum is even
    }
}
else // right half
{
    if(two<2) // upper right half
    {
        result = 1+(one+two+1)%2; //p1 hits if sum is even
    }
    else // lower right half
    {
        return 3; //both hit
    }
}

물론이 코드를 적은 코드로 처리 할 수는 있지만 일반적으로 간단한 솔루션을 찾는 대신 코딩하는 내용을 이해하는 것이 좋습니다.

if((one<2)&&(two<2)) result = 0; //top left
else if((one>1)&&(two>1)) result = 3; //bottom right
else result = 1+(one+two+((one>1)?1:0))%2; //no idea what that means

복잡한 p1 / p2 적중에 대한 설명은 훌륭 할 것입니다. 흥미로워 보입니다!


3

가장 짧고 읽기 쉬운 솔루션 :

static public int fightMath(int one, int two)
{
    if (one < 2 && two < 2) return 0;
    if (one > 1 && two > 1) return 3;
    int n = (one + two) % 2;
    return one < two ? 1 + n : 2 - n;
}

또는 더 짧게 :

static public int fightMath(int one, int two)
{
    if (one / 2 == two / 2) return (one / 2) * 3;
    return 1 + (one + two + one / 2) % 2;
}

"마법의"숫자를 포함하지 않습니다;) 그것이 도움이 되길 바랍니다.


2
이와 같은 공식을 사용하면 나중에 조합 결과를 변경 (업데이트) 할 수 없습니다. 유일한 방법은 전체 공식을 재 작업하는 것입니다.
SNag

2
@SNag : 동의합니다. 가장 유연한 솔루션은 2D 어레이를 사용하는 것입니다. 그러나이 게시물의 자동 사용자는 수식을 원했고 이것은 간단한 if와 수학으로 얻을 수있는 가장 좋은 것입니다.
PW

2

static int val(int i, int u){ int q = (i & 1) ^ (u & 1); return ((i >> 1) << (1 ^ q))|((u >> 1) << q); }


1

나는 개인적으로 삼항 연산자를 계단식으로 만들고 싶습니다.

int result = condition1
    ? result1
    : condition2
    ? result2
    : condition3
    ? result3
    : resultElse;

그러나 귀하의 경우 다음을 사용할 수 있습니다.

final int[] result = new int[/*16*/] {
    0, 0, 1, 2,
    0, 0, 2, 1,
    2, 1, 3, 3,
    1, 2, 3, 3
};

public int fightMath(int one, int two) {
    return result[one*4 + two];
}

또는 비트 단위로 패턴을 확인할 수 있습니다.

one   two   result

section 1: higher bits are equals =>
both result bits are equals to that higher bits

00    00    00
00    01    00
01    00    00
01    01    00
10    10    11
10    11    11
11    10    11
11    11    11

section 2: higher bits are different =>
lower result bit is inverse of lower bit of 'two'
higher result bit is lower bit of 'two'

00    10    01
00    11    10
01    10    10
01    11    01
10    00    10
10    01    01
11    00    01
11    01    10

그래서 당신은 마술을 사용할 수 있습니다 :

int fightMath(int one, int two) {
    int b1 = one & 2, b2 = two & 2;
    if (b1 == b2)
        return b1 | (b1 >> 1);

    b1 = two & 1;

    return (b1 << 1) | (~b1);
}

1

JAB의 response 와 비슷한 상당히 간결한 버전이 있습니다. 이것은지도를 활용하여 다른 사람들에게 승리를 가져다줍니다.

public enum Result {
  P1Win, P2Win, BothWin, NeitherWin;
}

public enum Move {
  BLOCK_HIGH, BLOCK_LOW, ATTACK_HIGH, ATTACK_LOW;

  static final Map<Move, List<Move>> beats = new EnumMap<Move, List<Move>>(
      Move.class);

  static {
    beats.put(BLOCK_HIGH, new ArrayList<Move>());
    beats.put(BLOCK_LOW, new ArrayList<Move>());
    beats.put(ATTACK_HIGH, Arrays.asList(ATTACK_LOW, BLOCK_LOW));
    beats.put(ATTACK_LOW, Arrays.asList(ATTACK_HIGH, BLOCK_HIGH));
  }

  public static Result compare(Move p1Move, Move p2Move) {
    boolean p1Wins = beats.get(p1Move).contains(p2Move);
    boolean p2Wins = beats.get(p2Move).contains(p1Move);

    if (p1Wins) {
      return (p2Wins) ? Result.BothWin : Result.P1Win;
    }
    if (p2Wins) {
      return (p1Wins) ? Result.BothWin : Result.P2Win;
    }

    return Result.NeitherWin;
  }
} 

예:

System.out.println(Move.compare(Move.ATTACK_HIGH, Move.BLOCK_LOW));

인쇄물:

P1Win

내가 추천 할 것입니다 static final Map<Move, List<Move>> beats = new java.util.EnumMap<>();그것은 조금 더 효율적이어야한다, 대신.
JAB

@JAB 예, 좋습니다. 나는 항상 유형이 존재한다는 것을 잊어 버립니다. 그리고 ... 하나를 만드는 것이 얼마나 어색한가!
Duncan Jones

1

HashMap 또는 TreeMap 맵을 사용합니다.

특히 매개 변수가 양식에없는 경우 0 <= X < N

임의의 양의 정수 세트처럼 ..

암호

public class MyMap
{
    private TreeMap<String,Integer> map;

    public MyMap ()
    {
        map = new TreeMap<String,Integer> ();
    }

    public void put (int key1, int key2, Integer value)
    {
        String key = (key1+":"+key2);

        map.put(key, new Integer(value));
    }

    public Integer get (int key1, int key2)
    {
        String key = (key1+":"+key2);

        return map.get(key);
    }
}

1

@Joe Harper에게 감사의 말을 전합니다. 4 개 당 2 개의 결과가 동일했기 때문에 더 슬림화하기 위해 더 축소했습니다.

나는 어느 시점에서 이것으로 돌아올 수 있지만, 여러 if문장으로 인한 큰 저항이 없다면 지금 이것을 유지할 것입니다. 테이블 매트릭스와 스위치 문 솔루션을 자세히 살펴 보겠습니다.

public int fightMath(int one, int two) {
  if (one === 0) {
    if (two === 2) { return 1; }
    else if(two === 3) { return 2; }
    else { return 0; }
  } else if (one === 1) {
    if (two === 2) { return 2; }
    else if (two === 3) { return 1; }
    else { return 0; }
  } else if (one === 2) {
    if (two === 0) { return 2; }
    else if (two === 1) { return 1; }
    else { return 3; }
  } else if (one === 3) {
    if (two === 0) { return 1; }
    else if (two === 1) { return 2; }
    else { return 3; }
  }
}

13
이것은 실제로 원본보다 읽기
Chad

@Chad 이것의 아이디어는 프로세스 속도를 높이는 것이었고 끔찍해 보이지만 나중에 더 많은 작업을 추가하면 쉽게 업데이트됩니다. 이것을 말하면 나는 이전에 완전히 이해하지 못한 이전 답변을 사용하고 있습니다.
TomFirth

3
@ TomFirth84 if 문에 적절한 코딩 규칙을 따르지 않는 이유가 있습니까?
ylun.ca

@ylun : 가독성이 아니라 스팸 공간을 위해 SO에 붙여 넣기 전에 줄을 줄였습니다. 이 페이지에는 다양한 변형이 있으며 슬프게도 내가 배우고 편안하게 느끼는 방식입니다.
TomFirth

2
@ TomFirth84 이것이 쉽게 업데이트 되지 않는다고 생각합니다. 행 수는 허용되는 값 수의 곱과 같이 커집니다 .
앤드류 나사로

0
  1. 상수 또는 열거 형을 사용하여 코드를 더 읽기 쉽게 만듭니다.
  2. 코드를 더 많은 기능으로 나누십시오
  3. 문제의 대칭을 사용하십시오

여기 이것이 어떻게 보일지에 대한 제안이 있지만 여기에 정수를 사용하는 것은 여전히 ​​추한 것입니다.

static final int BLOCK_HIGH = 0;
static final int BLOCK_LOW = 1;
static final int ATTACK_HIGH = 2;
static final int ATTACK_LOW = 3;

public static int fightMath(int one, int two) {
    boolean player1Wins = handleAttack(one, two);
    boolean player2Wins = handleAttack(two, one);
    return encodeResult(player1Wins, player2Wins); 
}



private static boolean handleAttack(int one, int two) {
     return one == ATTACK_HIGH && two != BLOCK_HIGH
        || one == ATTACK_LOW && two != BLOCK_LOW
        || one == BLOCK_HIGH && two == ATTACK_HIGH
        || one == BLOCK_LOW && two == ATTACK_LOW;

}

private static int encodeResult(boolean player1Wins, boolean player2Wins) {
    return (player1Wins ? 1 : 0) + (player2Wins ? 2 : 0);
}

입력과 출력에 구조화 된 유형을 사용하는 것이 좋습니다. 입력에는 실제로 위치와 유형 (차단 또는 공격)의 두 필드가 있습니다. 출력에는 player1Wins 및 player2Wins의 두 필드도 있습니다. 이것을 단일 정수로 인코딩하면 코드를 읽기가 어렵습니다.

class PlayerMove {
    PlayerMovePosition pos;
    PlayerMoveType type;
}

enum PlayerMovePosition {
    HIGH,LOW
}

enum PlayerMoveType {
    BLOCK,ATTACK
}

class AttackResult {
    boolean player1Wins;
    boolean player2Wins;

    public AttackResult(boolean player1Wins, boolean player2Wins) {
        this.player1Wins = player1Wins;
        this.player2Wins = player2Wins;
    }
}

AttackResult fightMath(PlayerMove a, PlayerMove b) {
    return new AttackResult(isWinningMove(a, b), isWinningMove(b, a));
}

boolean isWinningMove(PlayerMove a, PlayerMove b) {
    return a.type == PlayerMoveType.ATTACK && !successfulBlock(b, a)
            || successfulBlock(a, b);
}

boolean successfulBlock(PlayerMove a, PlayerMove b) {
    return a.type == PlayerMoveType.BLOCK 
            && b.type == PlayerMoveType.ATTACK 
            && a.pos == b.pos;
}

불행히도 Java는 이러한 종류의 데이터 유형을 표현하는 데별로 좋지 않습니다.


-2

대신 이런 식으로

   public int fightMath(int one, int two) {
    return Calculate(one,two)

    }


    private int Calculate(int one,int two){

    if (one==0){
        if(two==0){
     //return value}
    }else if (one==1){
   // return value as per condtiion
    }

    }

4
공용 함수로 랩핑 된 개인 함수를 작성했습니다. 왜 공공 함수에서 이것을 구현하지 않습니까?
Martin Ueding

5
그리고 당신은 if 문의 수를 줄이지 않았습니다.
Chad
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.