Too many 'if' statements?

前端 未结 26 1080
天涯浪人
天涯浪人 2020-11-30 16:24

The following code does work how I need it to, but it\'s ugly, excessive or a number of other things. I\'ve looked at formulas and attempted to write a few solutions, but I

26条回答
  •  抹茶落季
    2020-11-30 16:44

    1. Use constants or enums to make the code more readable
    2. Try to split the code into more functions
    3. Try to use the symmetry of the problem

    Here is a suggestion how this could look like, but using an ints here is still kind of ugly:

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

    It would be nicer to use a structured type for the input and the output. The input actually has two fields: the position and the type (block or attack). The output also has two fields: player1Wins and player2Wins. Encoding this into a single integer makes it harder to read the code.

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

    Unfortunately, Java is not very good at expressing those kinds of data-types.

提交回复
热议问题