package aima.gui.fx.views;
import aima.core.environment.eightpuzzle.EightPuzzleBoard;
import aima.core.util.datastructure.XYLocation;
import javafx.beans.binding.Bindings;
import javafx.event.ActionEvent;
import javafx.geometry.Pos;
import javafx.scene.control.Button;
import javafx.scene.layout.ColumnConstraints;
import javafx.scene.layout.GridPane;
import javafx.scene.layout.RowConstraints;
import javafx.scene.layout.StackPane;
import javafx.scene.text.Font;
/**
* Controller class which provides functionality for using a stack pane as a
* state view for the Eight Puzzle problem.
*
* @author Ruediger Lunde
*/
public class EightPuzzleViewCtrl {
private Button[] tileBtns = new Button[9];
private EightPuzzleBoard board;
/**
* Adds a grid pane to the provided pane and creates a controller class
* instance which is responsible for Eight Puzzle tile positioning on the grid.
*/
public EightPuzzleViewCtrl(StackPane viewRoot) {
GridPane gridPane = new GridPane();
viewRoot.getChildren().add(gridPane);
viewRoot.setAlignment(Pos.CENTER);
gridPane.maxWidthProperty().bind(Bindings.min(viewRoot.widthProperty(), viewRoot.heightProperty()).subtract(20));
gridPane.maxHeightProperty().bind(Bindings.min(viewRoot.widthProperty(), viewRoot.heightProperty()).subtract(10));
RowConstraints c1 = new RowConstraints();
c1.setPercentHeight(100.0 / 3);
ColumnConstraints c2 = new ColumnConstraints();
c2.setPercentWidth(100.0 / 3);
gridPane.setHgap(10);
gridPane.setVgap(10);
for (int i = 0; i < 3; i++) {
gridPane.getRowConstraints().add(c1);
gridPane.getColumnConstraints().add(c2);
}
Font font = Font.font(40);
for (int i = 0; i < 9; i++) {
Button btn = new Button();
btn.setOnAction(this::handleButtonEvent);
btn.setFont(font);
btn.setMaxSize(Double.MAX_VALUE, Double.MAX_VALUE);
tileBtns[i] = btn;
gridPane.add(btn, i % 3, i / 3);
}
}
public void initialize(EightPuzzleBoard board) {
this.board = board;
update();
}
/** Updates the view. */
public void update() {
for (int i = 0; i < 9; i++ ) {
int tileNo = board.getValueAt(new XYLocation(i / 3, i % 3));
tileBtns[i].setText(tileNo == 0 ? "" : Integer.toString(tileNo));
tileBtns[i].setDisable(tileNo == 0);
}
}
public void handleButtonEvent(ActionEvent ae) {
for (int i = 0; i < 9; i++) {
if (ae.getSource() == tileBtns[i]) {
XYLocation locGap = board.getLocationOf(0);
if (locGap.getXCoOrdinate() == i / 3) {
if (locGap.getYCoOrdinate() == i % 3 - 1)
board.moveGapRight();
else if (locGap.getYCoOrdinate() == i % 3 + 1)
board.moveGapLeft();
} else if (locGap.getYCoOrdinate() == i % 3) {
if (locGap.getXCoOrdinate() == i / 3 - 1)
board.moveGapDown();
else if (locGap.getXCoOrdinate() == i / 3 + 1)
board.moveGapUp();
}
}
}
update();
}
}