ocamllabs / 2048-tutorial

OCaml tutorial based on the 2048 game
49 stars 12 forks source link

More logic #14

Closed yallop closed 10 years ago

yallop commented 10 years ago

Logic to support animation, etc., as previously discussed.

Boards now remember the effects of the previous move, which makes it possible to support scoring and provenance. Only shift_left_helper really needed to change, which is a promising sign for the tutorial structure.

Terminology reverted to say "square" rather than "tile". There are probably a few places where we should still be saying "tile".

Provenance

(I suspect the semantics of a couple of these functions isn't quite what @dbuenzli needs. Just let me know if so; I'll be around this morning.)

val is_new_square : square -> bool
(** [is_new_square t] indicates whether [t] is freshly inserted. *)

val square_shift : square -> int option
(** [square_shift t] indicates how far the current occupant shifted to
    reach its current position. *)

val square_previous : square -> int option
(** [square_previous_value t] indicates the previous value of the
    current occupant of the square. *)

End-of-game

val is_board_winning : board -> bool
(** [is_board_winning board] is [true] iff the [board] is a winning board. *)

Scoring

Scoring is move-based, not board-based: points equal to the sum of the result are awarded for combining two tiles.

val last_move_score : board -> int
(** [last_move_score board] is the score achieved by the last move. *)

Misc

The code needs simplifying a bit to use a minimal set of language features, but let's leave that until last. There are also likely to be more opportunities to simplify the implementation along the lines of 49990e6b.

dbuenzli commented 10 years ago

A few things.

  1. I still need a game over condition. I guess that's when any move returns the same board.
  2. I can do with square_previous but it is really not practical. As when I'm in a position I need to search the board with square_shift to get the value of the tile that moved by square_shift (i.e. do positioning business and introduce something like G2048.square_at : board -> int * int -> tile. If you give me the value of the tile that shifted. I can render with a single fold_squares.
  3. Aren't the things that move tiles ? That should then be tile_shift and (maybe) shifted_tile_value.
dbuenzli commented 10 years ago

Also API wise I think it would be better to expose the provenance type. The reason is that this would make it clear in the interface that given a square t you cannot have is_new_square t = true and square_shift t = Some _ .

dbuenzli commented 10 years ago

And either I understood nothing to Leo's explanation about board games but it should also be is_new_tile rather than is_new_square. But as I said I'd rather have a tile_provenance : square -> provenance option function or even directly square_tile : square -> (int * provenance) option

yallop commented 10 years ago

I still need a game over condition. I guess that's when any move returns the same board.

See 40ed539.

yallop commented 10 years ago

Also API wise I think it would be better to expose the provenance type.

See 62695fa.

(Other changes to follow).

yallop commented 10 years ago

Aren't the things that move tiles ? That should then be tile_shift and (maybe) shifted_tile_value. And either I understood nothing to Leo's explanation about board games but it should also be is_new_tile rather than is_new_square

See 4f8a742.

yallop commented 10 years ago

I can do with square_previous but it is really not practical. As when I'm in a position I need to search the board with square_shiftto get the value of the tile that moved by square_shift (i.e. do positioning business and introduce something like G2048.square_at : board -> int * int -> tile. If you give me the value of the tile that shifted. I can render with a single fold_squares.

I'm not sure I follow here. What API would you rather have?

yallop commented 10 years ago

New approach to provenance in a6fc9a8.

type provenance = { shift : int; value : int }
val square_provenance : square -> provenance list

Subsumes/supersedes tile_shift, shifted_tile_value, is_new_tile.

dbuenzli commented 10 years ago

Sorry I was busy this afternoon with @samoht trying to define an ocamlfindless world. But the interface looks good. Will work on this tomorrow.

yallop commented 10 years ago

Ok -- I'll merge for now, and we can patch if necessary tomorrow.