söndag 15 mars 2009

Matchgame implementation step #1

Step 1 in implementing the matchstick game described in a previous post was to decide how to represent the game state.
Well, F# seems to work well with lists, so a list it is.
The index in the list represents the row, the value represents the number of matches in the row.

So a representation of the starting state
|||||||
|||||
|||
|

is the list defined as
let startState = [7;5;3;1]


Note that with this representation the game is not limited to just 4 row, but can be any number of rows with any number of matches in them.

The first thing I wanted to do was a basic function which verifies that takes two states and verifies that the second can be reached from the first in one single move.

The function along with some testing code became:

#light

let startState = [7;5;3;1]

let rec ValidStateChange beforeState afterState =
match (beforeState, afterState) with
| ([],[]) -> false
| (bh::bt, ah::at) -> (bh > ah && bt = at) or (bh = ah && ValidStateChange bt at)
| (bh::_,[]) -> false
| ([],ah::_) -> false

let validNewState = [3;5;3;1]
let invalidNewState = [3;3;3;1]

printf "%A to %A : valid=%A\n" startState validNewState (ValidStateChange startState validNewState)
printf "%A to %A : valid=%A\n" startState invalidNewState (ValidStateChange startState invalidNewState)


So I dove right into pattern matching. Seemed neat
The first pattern | ([],[]) -> false

says that it is not a valid move to go from zero matches to zero matches. At least one match needs to be removed, remember?

The second pattern does the major work here. It matches when both states are lists (which they always should be from the start)
It says that
If the number of matches in the first row in the before-state are greater than the number of matches in the first row in the after-state, and all remaining rows being equal, then it is a valid state change.
Either that, OR:
If the number of matches in the first row are equal before and after, and the remaining rows as states themselves are a valid state change, then it is a valid state change.

The compiler now told me that I didn't match all patterns. Eh ok... Yes, of course. What if the states contain different nomber of rows. Then you can't get from on to the other.

As it turned out, this first function had no use in the game implementation in the end. But I got a better feel for F# writing it.

I realize now that a game of matches was not the best choice for explaining things, since the word match takes two meanings in this context... duh.

Inga kommentarer:

Skicka en kommentar