简体   繁体   English

永远不会使用更改的值

[英]The value changed is never used

My question is why variables for 'Life' won't work even if I think I did it right?我的问题是为什么即使我认为我做对了,“生活”的变量也不起作用?
I have main method and in it:我有主要方法并在其中:

        int destroyer1Life = 4;
        int destroyer2Life = 4;
        int battleShipLife = 5;
        int gameBoardLenght = 10;
        int shipsLife = destroyer1Life + destroyer2Life + battleShipLife;

        while(shipsLife > 0){  //ships life is warned as always true

            char locationViewUpdate = evaluateGuessAndGetTarget(guessLocation, gameBoard, water, hit, miss, destroyer1, destroyer2, battleShip,battleShipLife, destroyer1Life, destroyer2Life, ship );
            if (shipsLife == 0){  //ships life is warned as always false
                System.out.print("You won");
            }

In another method I have:在另一种方法中,我有:

    private static char evaluateGuessAndGetTarget(int[] guessLocation, char[][] gameBoard, char water, char hit, char miss, char destroyer1, char destroyer2, char battleShip, int battleShipLife, int destroyer1Life, int destroyer2Life,char ship) {

        if (target == destroyer1){
            if (destroyer1Life > 0){
                target = hit;
                message = "Hit!";
                destroyer1Life--; //The value changed at 'destroyer1Life--' is never used 
            }
        }

        if (target == destroyer2){
            if (destroyer2Life > 0){
                target = hit;
                message = "Hit!";
                destroyer2Life--;  //The value changed at 'destroyer2Life--' is never used 
            }
        }

        if (target == battleShip){
            if (battleShipLife > 0){
                target = hit;
                message = "Hit!";
                battleShipLife--;  //The value changed at 'battleShipLife--' is never used 
            }
        }
}

So, even when I get an update on board that ship has been changed into hit, life wont go down.所以,即使我在船上得到更新,那艘船已经变成了命中,生活也不会 go 下降。 Full code: https://github.com/Mertyon/BattleShipsGame/blob/main/src/com/company/BattleShipsGame.java完整代码: https://github.com/Mertyon/BattleShipsGame/blob/main/src/com/company/BattleShipsGame.java

For the context of primitives, like int , Java is pass-by-value.对于基元的上下文,如int , Java 是按值传递的。 This means that when you pass - for example - destroyer1Life to a method, any change is isolated to that method.这意味着当您将 - 例如 - destroyer1Life传递给方法时,任何更改都与该方法隔离。

eg例如

/**
 * loop until someValue isn't 1
 */
public void myThing() {
    int someValue = 1;

    while(someValue == 1)
    {
      decrement(someValue);
    }
}

/**
 * Because of pass-by-value, what happens in decrement, stays in decrement
 */
private void decrement(int someValue) {
    someValue--;
}

If you want to modify a value (keeping it simple), you need to reassign it in scope. For example, to fix the above:如果要修改一个值(keeping it simple),需要在scope中重新赋值。比如修复上面的:

/**
 * loop until someValue isn't 1
 */
public void myThing() {
    int someValue = 1;

    while(someValue == 1)
    {
      // modify the value in scope
      someValue = decrement(someValue);
    }
}

/**
 * Because of pass-by-value, what happens in decrement, stays in decrement
 * BUT, if we return it, it can be reassigned in scope.
 */
private int decrement(int someValue) {
    return --someValue;
}

So you can't act on all those values because they aren't being reassigned.所以你不能对所有这些值采取行动,因为它们没有被重新分配。 It's likely to be simpler to make an object that contains those values, pass that, then modify them on that value.制作一个包含这些值的 object 可能更简单,传递它,然后根据值修改它们。 That is where 'pass-by-value' becomes a little less exact in Java (a little too complex to go into here).这就是 Java 中“按值传递”变得不太精确的地方(对于此处的 go 来说有点太复杂了)。 That object could be a map, a custom POJO, or something else. object 可能是 map、自定义 POJO 或其他。

The Java way of implementing this is to define your very own object to represent the state of the game. Java 的实现方式是定义你自己的 object 来代表游戏的 state。 So you would have something like:所以你会有类似的东西:

// State.java
public class State {

    // constants, initialized only once
    public final char WATER = '~';
    public final char HIT = 'X';
    public final char MISS = '·';
    public final char D1 = '1';
    public final char D2 = '2';
    public final char BB = 'B';
    public final char SHIP = 'O';

    // attributes, can be different for different State objects
    private int destroyer1Life = 4;
    private int destroyer2Life = 4;
    private int battleShipLife = 5;
    private int gameBoardLength = 10;
    private char [][] board;

    // a method to calculate remaining life in this State object
    public int getTotalLife() {
        return destroyer1Life + destroyer2Life + battleShipLife;
    }
     
    // a method to update this State object after a guess
    public char update(int[] guessLocation) {
        char target = board[guessLocation[0]][guessLocation[1]];
        char result = '?';
        if (target == 'WATER') {
           System.out.println("Sploof, miss!");
           result = MISS;   
        } else if (target == D1) {
           System.out.println("Hit!");
           result = HIT;
           destroyer1Life --;
        } // add more else ifs here for other boat types
        // ...

        // write new result to displayed board
        board[guessLocation[0]][guessLocation[1]] = result;
        return result;
    }

    // a method to show the state
    public void show() {
        for (int row=0; row<board.length(); row++) {
          for (int col=0; col<board[0].length(); col++) {
             char c = board[row][col];
             // show '?' for all unknown tiles
             System.out.print(c == HIT || c == MISS ? c : '?');
          }
          System.out.println("");
        }
    }
}

// in Main.java
State state = new State();
while (state.getTotalLife() > 0) {
        int[] guessLocation = askForGuess();
        state.update(guessLocation);
        state.show();
        if (shipsLife == 0){ 
            System.out.print("You won");
        }
}

Instead of passing around lots of integers, and having no way to get their changed values back, you group those values into objects, which have their own methods that can freely change the object's values.不是传递大量整数,也没有办法取回它们更改后的值,而是将这些值分组到对象中,这些对象有自己的方法可以自由更改对象的值。 Much cleaner.干净多了。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM