【问题标题】:Getting text from buttons in an array then concating all the values into a string从数组中的按钮获取文本,然后将所有值连接成一个字符串
【发布时间】:2022-01-17 16:00:50
【问题描述】:

我有一个按钮列表,用作井字游戏的图块,我想制定一种方法来检查平局,该方法基本上可以检查板是否已满并且没有赢家,那么它是领带。

我想从所有按钮中获取文本并将其全部连接成 1 个字符串,当该字符串的长度为 9 并且没有赢家时,那就是平局。

我当前的方法有效,但我想知道是否有任何方法可以通过使用循环或其他方式来提高效率

游戏初始化代码

    @Override
    public void initialize(URL url, ResourceBundle resourceBundle) {
        buttons = new ArrayList<>(Arrays.asList(button1,button2,button3,button4,button5,button6,button7,button8,button9));
        buttons.forEach(button ->{
            setupButton(button);
            button.setFocusTraversable(false);
            button.setText("");
        });
    }

检查平局的代码

line2 = button1.getText() + button2.getText() + button3.getText() + button4.getText() + button5.getText() + button6.getText() + button7.getText() + button8.getText() + button9.getText();

            if ((line2.length()) == 9 && winner == null) {
            ties++;
            tiesText.setText(""+ties);
            disableAllButtons();
            newGame(null);
            }

【问题讨论】:

  • 只是需要考虑:如果每一行都包含 O 和 X,则为平局。这些行是 (1,2,3), (4,5,6), (7,8 ,9), (1,4,7), (2,5,8), (3,6,9), (1,5,9), (3,5,7)。这样,您实际上可以在所有方格都填满之前检测到有保证的平局。
  • 该死的,这很有趣,我从来没有真正想过这样的领带。但这对我的玩家和电脑版的游戏很有用。谢谢詹姆斯。

标签: java button javafx arraylist


【解决方案1】:

您可以使用计数器并在单击按钮时将其递增。如果计数器是 9,则为平局。

如果您想坚持使用按钮文本,您可以使用 foreach 循环,例如:

line2 = "";
foreach (Button button : buttons){
  line2 += button.getText();
}

【讨论】:

    【解决方案2】:

    您可以在串联的字符串绑定上创建一个侦听器,然后使用它来监视所有按钮的串联文本。

    例如:

    StringExpression state = Bindings.concat(
            board.getChildren().stream()
                    .map(node -> ((Button) node).textProperty())
                    .toArray()
    );
    state.addListener((observable, oldState, newState) ->
            handleStateChange(newState)
    );
    

    这可能比必要的要复杂一些。对于基本解决方案,对按钮单击做出反应并在循环中更新状态(如valentin's solution)就可以了,而不是使用绑定。但是绑定确实提供了一种替代解决方案,保留了您原来的连接按钮文本的概念。

    代表newState 的字符串值的示例是一个九字符的字符串:

    "XO  XO  X"
    

    在这个例子中,未玩过的方格是空格,而 X 刚刚以从左上角到右下角的对角线获胜。

    上下文示例

    • 使用 James 的建议,即检查线条以进行平局检测。
    • 使用 Java 17 功能。

    应用代码

    import javafx.application.*;
    import javafx.beans.binding.*;
    import javafx.geometry.Insets;
    import javafx.scene.*;
    import javafx.scene.control.*;
    import javafx.scene.layout.TilePane;
    import javafx.stage.*;
    
    public class NoughtsAndCrosses extends Application {
        private static final int NUM_SQUARES = 9;
    
        private static final String X = "X";
        private static final String O = "O";
        private static final String TIE = "-";
        private static final String NONE = " ";
    
        private String nextPlayer = X;
    
        private Scene scene;
    
        private static final int[][] LINES = {
                {1,2,3}, {4,5,6}, {7,8,9},  // horizontal
                {1,4,7}, {2,5,8}, {3,6,9},  // vertical
                {1,5,9}, {3,5,7}            // diagonal
        };
    
        public void start(Stage stage) {
            scene = new Scene(newGame());
            stage.setScene(scene);
            stage.setTitle("Noughts and Crosses");
            stage.show();
        }
    
        private Parent newGame() {
            TilePane board = createBoard();
            if (scene != null) {
                scene.setRoot(board);
            }
    
            return board;
        }
    
        private TilePane createBoard() {
            TilePane board = new TilePane(10, 10);
            board.setStyle("-fx-base: antiquewhite; -fx-font-size: 30; -fx-font-weight: bold;");
            board.setPadding(new Insets(10));
            board.setPrefColumns(3);
            board.setMinSize(Control.USE_PREF_SIZE, Control.USE_PREF_SIZE);
            board.setMaxSize(Control.USE_PREF_SIZE, Control.USE_PREF_SIZE);
    
            for (int i = 0; i < NUM_SQUARES; i++) {
                board.getChildren().add(createSquare());
            }
    
            StringExpression state = Bindings.concat(
                    board.getChildren().stream()
                            .map(node -> ((Button) node).textProperty())
                            .toArray()
            );
            state.addListener((observable, oldState, newState) ->
                    handleStateChange(newState)
            );
    
            return board;
        }
    
        private Button createSquare() {
            final Button square = new Button(NONE);
            square.setMinSize(Control.USE_PREF_SIZE, Control.USE_PREF_SIZE);
            square.setPrefSize(65, 65);
            square.setMaxSize(Control.USE_PREF_SIZE, Control.USE_PREF_SIZE);
    
            square.setOnAction(e -> takeTurn(square));
    
            return square;
        }
    
        private void takeTurn(Button square) {
            square.setText(nextPlayer);
            nextPlayer = X.equals(nextPlayer) ? O : X;
        }
    
        private void handleStateChange(String state) {
            int nTies = 0;
    
            for (int[] line : LINES) {
                String result = checkResult(line, state);
                switch (result) {
                    case X -> { endGame(X); return; }
                    case O -> { endGame(O); return; }
                    case TIE -> nTies++;
                }
            }
    
            if (nTies == LINES.length) {
                endGame(TIE);
            }
        }
    
        private String checkResult(int[] line, String state) {
            int numX = 0, numO = 0;
    
            for (int j : line) {
                String cellState = state.substring(j - 1, j);
                switch (cellState) {
                    case X -> numX++;
                    case O -> numO++;
                }
            }
    
            if (numX == 3) {
                return X;
            }
    
            if (numO == 3) {
                return O;
            }
    
            if (numX > 0 && numO > 0) {
                return TIE;
            }
    
            return NONE;
        }
    
        private void endGame(String result) {
            String msg = switch (result) {
                case X -> X + " won";
                case O -> O + " won";
                case TIE -> "Tie";
                default -> "unexpected result";
            };
    
            Alert resultDialog = new Alert(
                    Alert.AlertType.CONFIRMATION,
                    """
                    Play again?
                    
                    %s will start first.
                    """.formatted(X.equals(nextPlayer) ? O : X)
            );
            resultDialog.setHeaderText(msg);
            resultDialog.setTitle("Game Over");
    
            resultDialog.initOwner(
                    scene.getWindow()
            );
    
            // we do this in a run later as we want the board state to update for
            // the last interaction before displaying the result dialog.
            Platform.runLater(() ->
                resultDialog.showAndWait()
                        .filter(response -> response == ButtonType.OK)
                        .ifPresentOrElse(
                                response -> newGame(),
                                Platform::exit
                        )
            );
        }
    
        public static void main(String[] args) {
            launch(args);
        }
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-10-05
      • 1970-01-01
      相关资源
      最近更新 更多