Skip to content
operational.txt 4.14 KiB
Newer Older
-*- mode: org -*-
ֻݵĵ

* notes
** game design
- buttons are named Button1 to Button15. last empty block is named Button0.
- 
* current
** 
Yuanle Song's avatar
Yuanle Song committed
** 2018-01-15 add step and timer count.
Yuanle Song's avatar
Yuanle Song committed
- add game level selection on GUI.
- After Generate, step and timer resets.
  button becomes "Start".
- when user click "Start", show the game board.
  when game finishes, stop timer. blocks should not response to clicks.

- implementation
  - add game status. use a state machine.

- problems
  - generated game is not resolvable?
    ...
    13 15 14

    print solution on console.
    empty block moving direction.

  - ShowSolution()

    Game board:
    4 6 15 3
    10 2 12 9
    7 5 14 13
    11 1 8

    #+BEGIN_QUOTE
    Solution: 
    UP    UP    RIGHT RIGHT DOWN  RIGHT RIGHT UP    UP    LEFT  
    UP    RIGHT DOWN  DOWN  DOWN  LEFT  LEFT  LEFT  LEFT  UP    
    LEFT  LEFT  DOWN  RIGHT DOWN  RIGHT UP    UP    UP    RIGHT 
    UP    RIGHT DOWN  RIGHT DOWN  DOWN  RIGHT UP    UP    UP    
    RIGHT UP    RIGHT DOWN  LEFT  DOWN  LEFT  DOWN  LEFT  DOWN  
    LEFT  UP    LEFT  DOWN  LEFT  UP    LEFT  DOWN  DOWN  RIGHT 
    #+END_QUOTE

  - ShowSolution()

    Game board:
    6 7 11 9
    4 3 14 2
    5    8 1
    12 10 13 15

    #+BEGIN_QUOTE
    Path: 
    LEFT  LEFT  UP    LEFT  LEFT (!!)  UP    RIGHT RIGHT UP    RIGHT 
    RIGHT DOWN  RIGHT UP    RIGHT UP    LEFT  DOWN  RIGHT UP    
    RIGHT DOWN  LEFT  UP    LEFT  DOWN  DOWN  RIGHT UP    UP    
    LEFT  DOWN  DOWN  RIGHT DOWN  LEFT  LEFT  UP    UP    RIGHT 
    RIGHT UP    RIGHT RIGHT DOWN  LEFT  DOWN  DOWN  LEFT  UP    
    LEFT  UP    LEFT  LEFT  DOWN  DOWN  RIGHT UP    RIGHT RIGHT 

    Solution: 
    LEFT  LEFT  DOWN  LEFT  UP    UP    RIGHT RIGHT DOWN  RIGHT 
    DOWN  RIGHT UP    UP    RIGHT UP    LEFT  LEFT  DOWN  LEFT  
    LEFT  DOWN  DOWN  RIGHT RIGHT UP    LEFT  UP    UP    RIGHT 
    DOWN  DOWN  LEFT  UP    UP    RIGHT DOWN  RIGHT UP    LEFT  
    DOWN  LEFT  UP    RIGHT DOWN  LEFT  DOWN  LEFT  UP    LEFT  
    LEFT  DOWN  LEFT  LEFT  DOWN  RIGHT RIGHT DOWN  RIGHT RIGHT 
    #+END_QUOTE

    algorithm has problem.
    GetEmptyBlockDirections() check is wrong.
    PositionOnBoard is not enough.
    fixed.

Yuanle Song's avatar
Yuanle Song committed
* done
** 2018-01-14 make the basic work
- make blocks move in GUI when I click it.
  when click a non-movable block, do nothing.
- generate a game and reflect it in GUI using buttons.

Yuanle Song's avatar
Yuanle Song committed
  Board board = Board.GenerateBoard();
  // update GUI to show the board
  showBoard(board);

  Just set Content and visibility for each button.

- problems
  - how to write the click event for all buttons?
    decide which button is it.
    decide where is the button, where should it move.

    I decide to change button label and visibility.
    don't change button margin.

    create a model for the current board. then just relfect the board on the
    GUI. when user click a block, send a event to the model, then the model
    should decide which commands to send to the GUI components.

    class Board {
      initState: int[16];
      // block1 to block15 is just 1 to 15.
      // block0 is 0.

      currentState: int[16];
    }

    Button12 click.
    decide the block int id using reflection.

    blockId = getClickButtonId();
    String clickBlockLabel = eventTarget.Content;
    if board.blockCanMove(blockId) {
      String oldBlock0Name = board.getBlock0ButtonName();
      board.moveBlock(blockId);  // change currentState array.
      getButtonByName(board.getBlock0ButtonName()).Visibility = Hidden;
      getButtonByName(oldBlock0Name).Content = clickBlockLabel;
    }

    works on first try.

Yuanle Song's avatar
Yuanle Song committed
  - how to generate a valid game board?

    just move empty block randomly. just don't go backwards.

    easy: move 30 steps
    normal: move 60 steps
    hard: move 90 steps

    path = List<int>{};
    while true:
        directions = board.GetEmptyBlockDirections();
        directions.removeElement(getOppositeDirection(path[-1]));
        if directions is empty:
            Console.WriteLine("should not happen");
            break
        randomDirection = randomChoice(directions);
        board.MoveEmptyBlock(randomDirection);
        path.add(randomDirection);
        if path.length >= difficulty:
            break