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