Пример #1
0
  private void auto() {
    Step step = null;
    try {
      step = board.auto();
    } catch (Exception e) {
      logger.error("Exception in auto?", e);
      AlertFactory.createError(e).showAndWait();
    }

    // didn't solve anything, don't remember this step
    if (step == null) {
      return;
    }

    steps.push(step);

    Set<Integer> groupIds = new HashSet<Integer>();
    for (CellSnapshot snapshot : step.snapshots) {
      Cell affectedCell = board.getCell(snapshot.row, snapshot.col);
      if (snapshot.isMain()) {
        groupIds.add(affectedCell.getGroupId());
      }
      boardView.updateCellView(affectedCell);
    }

    for (int groupId : groupIds) {
      updateGroupSumView(groupId);
    }

    // after auto, game might be solved
    checkGameIsSolved();
  }
Пример #2
0
  private void removeCellValue(int row, int col) {
    Cell cell = board.getCell(row, col);

    // not allow to clear cell when it is locked
    if (cell.isLocked() || cell.isEmpty()) {
      return;
    }

    Step step = board.removeCellValue(row, col);
    boardView.updateCellView(cell);

    // update other cells which is affected by this cell
    for (CellSnapshot snapshot : step.snapshots) {
      Cell affectedCell = board.getCell(snapshot.row, snapshot.col);
      if (affectedCell.isLocked()) {
        continue;
      }
      boardView.getCellView(affectedCell).becomeValid();
    }

    steps.push(step);

    // current sum of group is changed
    updateGroupSumView(cell.getGroupId());
  }
Пример #3
0
  private void updateEntireView() {

    // upadte board view entirely
    boardView.update(board, remainMode.isSelected());

    // redraw combination view
    Group group = board.getGroup(board.getCurrentCell().getGroupId());
    combinationView.update(group);
  }
Пример #4
0
  private void removeCellHints(int row, int col) {
    Cell cell = board.getCell(row, col);

    // if cell doesn't any hint, don't have to clear it
    if (cell.getHints().isEmpty()) {
      return;
    }

    Step step = board.removeCellHints(row, col);
    steps.push(step);

    boardView.updateCellView(cell);
  }
Пример #5
0
  private void moveFocusTo(int row, int col) {

    // update combination list if new group is selected
    Cell cell = board.getCell(row, col);
    int groupId = cell.getGroupId();
    if (groupId != board.getCurrentCell().getGroupId()) {
      combinationView.update(board.getGroup(groupId));
    }

    // don't update current cell before checking group ID changed
    board.setCurrentCell(row, col);
    boardView.focusOn(row, col);
  }
Пример #6
0
  private void toggleCellHint(int row, int col, int hint) {
    Cell cell = board.getCell(row, col);

    // not allow to toggle hint when cell is holding value
    if (cell.isEmpty() == false) {
      return;
    }

    boolean isAdding = !board.getCell(row, col).getHints().contains(hint);
    Step step = isAdding ? board.addCellHint(row, col, hint) : board.subCellHint(row, col, hint);
    steps.push(step);

    boardView.getCellView(row, col).toggleHint(hint, isAdding);
  }
Пример #7
0
 private void toggleGroupSumMode(boolean remainMode) {
   for (Group group : board.getGroups()) {
     if (group.getTotal() != 0) {
       boardView.updateGroupSum(group, remainMode);
     }
   }
 }
Пример #8
0
 private void updateGroupSumView(int groupId) {
   // if remain mode is not selected, view of group sum is never changed
   if (remainMode.isSelected()) {
     Group group = board.getGroup(groupId);
     boardView.updateGroupSum(group, true);
   }
 }
Пример #9
0
  public void importFrom(InputStream stream) throws IOException {
    // 1. wipe the view
    boardView.reset();

    // 2. instantiate new model and load new data
    board = new Board();
    board.loadFrom(stream);
    board.calculateAllHints();

    // 3. redraw view
    updateEntireView();

    // 4. setup controller
    boardView.setOnKeyPressed(this);
    boardView.requestFocus();

    // 5. reset timer
    timer.reset();
  }
Пример #10
0
  private void undo() {
    if (steps.isEmpty()) {
      logger.warn("There is nothing to undo.");
      return;
    }

    Step step = steps.pop();
    Set<Integer> groupIds = board.undo(step);

    // update all affected group sum view
    for (int groupId : groupIds) {
      updateGroupSumView(groupId);
    }

    // update all cell view
    for (CellSnapshot snapshot : step.snapshots) {
      Cell cell = board.getCell(snapshot.row, snapshot.col);
      boardView.updateCellView(cell);
    }
  }
Пример #11
0
  private void updateCellValue(int row, int col, int value) {
    Cell cell = board.getCell(row, col);

    // not allows to update cell value when cell is locked, or the new value is not changed
    if (cell.isLocked() || cell.getValue() == value) {
      return;
    }

    Step step = board.updateCellValue(row, col, value, autoMode.isSelected());
    boardView.updateCellView(cell);

    for (CellSnapshot snapshot : step.snapshots) {
      Cell affectedCell = board.getCell(snapshot.row, snapshot.col);
      boardView.updateCellView(affectedCell);
    }

    steps.push(step);

    // current sum of group is changed
    updateGroupSumView(cell.getGroupId());

    // check if game is solved
    checkGameIsSolved();
  }
Пример #12
0
  private void checkGameIsSolved() {
    if (board.isSolved() == false) {
      return;
    }

    // clear UNDO stack
    steps.clear();

    // stop the timer
    pauseTimer();

    // stop showing combination list
    combinationView.update(new Group(Group.NON_ID));

    // prevent user input
    boardView.setOnKeyPressed(null);

    // congratulate user
    boardView.congratulate();

    // pop up alert
    AlertFactory.createInfo("SUCCESS", null, "Congratulation! You are genius!").showAndWait();
  }
Пример #13
0
  @Override
  public void handle(KeyEvent event) {
    Cell current = board.getCurrentCell();
    final int row = current.row;
    final int col = current.col;

    int nextRow = row;
    int nextCol = col;

    KeyCode code = event.getCode();
    switch (code) {
        // move using AWSD feature
      case UP:
      case W:
        nextRow = row == Board.MIN_INDEX ? Board.MAX_INDEX : row - 1;
        break;

      case DOWN:
      case S:
        nextRow = row == Board.MAX_INDEX ? Board.MIN_INDEX : row + 1;
        break;

      case LEFT:
      case A:
        nextCol = col == Board.MIN_INDEX ? Board.MAX_INDEX : col - 1;
        break;

      case RIGHT:
      case D:
        nextCol = col == Board.MAX_INDEX ? Board.MIN_INDEX : col + 1;
        break;

        // switch to hint mode feature
      case SHIFT:
        hintMode.setSelected(!hintMode.isSelected());
        break;

        // auto solve
      case SPACE:
        auto();
        break;

        // undo
      case Z:
        if (event.isControlDown()) {
          undo();
        }
        break;

        // delete cell feature
      case DIGIT0:
      case NUMPAD0:
      case DELETE:
      case BACK_SPACE:
        if (hintMode.isSelected()) {
          removeCellHints(row, col);
        } else {
          removeCellValue(row, col);
        }
        break;

        // enter cell value feature
      default:
        if (code.isDigitKey()) {
          String text = event.getText();
          int value = Integer.parseInt(text);

          if (hintMode.isSelected()) {
            toggleCellHint(row, col, value);
          } else {
            updateCellValue(row, col, value);
          }
        }
        break;
    }

    // move to next cell
    event.consume(); // prevent arrow keys automatically change the focus
    if (nextRow != current.row || nextCol != current.col) {
      moveFocusTo(nextRow, nextCol);
    }
  }
Пример #14
-1
  public GameController() {
    logger.debug("Instantiating model");
    board = new Board();

    logger.debug("Instantiating views");
    boardView = new BoardView(Block.COUNT);

    // instantiate click event handler only one time to save instantiation time
    EventHandler<MouseEvent> onCellViewClicked =
        new EventHandler<MouseEvent>() {
          @Override
          public void handle(MouseEvent event) {
            boardView.requestFocus();
            CellView cellView = (CellView) event.getSource();
            moveFocusTo(cellView.row, cellView.col);
          }
        };

    // apply click event handler to all cells
    board.forEach(cell -> boardView.getCellView(cell).setOnMouseClicked(onCellViewClicked));

    // apply key press handler to the board (not each individual cell)
    boardView.setOnKeyPressed(this);

    // instantiate timer
    timer = new TimerWidget();

    // init check box for toggling hint mode
    hintMode = new CheckBox("Pencil (SHIFT)");
    hintMode.setFocusTraversable(false);
    autoMode = new CheckBox("Automation");
    autoMode.setFocusTraversable(false);
    autoMode.setSelected(true);
    remainMode = new CheckBox("Show remaining sum");
    remainMode.setFocusTraversable(false);
    remainMode.setSelected(true);

    // listener for hint mode and remain mode
    hintMode
        .selectedProperty()
        .addListener(
            new ChangeListener<Boolean>() {
              @Override
              public void changed(
                  ObservableValue<? extends Boolean> observable,
                  Boolean oldValue,
                  Boolean newValue) {
                if (newValue) {
                  boardView.setHintsCursor();
                } else {
                  boardView.setValueCursor();
                }
              }
            });

    remainMode
        .selectedProperty()
        .addListener(
            new ChangeListener<Boolean>() {
              @Override
              public void changed(
                  ObservableValue<? extends Boolean> observable,
                  Boolean oldValue,
                  Boolean newValue) {
                toggleGroupSumMode(newValue);
              }
            });

    VBox controlBox = new VBox(hintMode, autoMode, remainMode);
    controlBox.setPadding(new Insets(0, 10, 0, 50));
    controlBox.setSpacing(4);

    // init combination list view
    combinationView = new CombinationView();

    // init combinator view
    combinator = new CombinatorWidget();

    // organize all components in grid style
    view = new GridPane();
    view.setBackground(BackgroundFactory.create(Color.rgb(200, 230, 200)));
    view.add(boardView, 0, 0);
    controlPanel = new VBox(timer, controlBox, combinationView, combinator);
    controlPanel.setAlignment(Pos.TOP_CENTER);
    view.add(controlPanel, 1, 0);
  }