For my pacman project I had the following implementation of the initial state:
defn start-game
“starts a game state”
[]
{:direction ‘left
:pacman { :x 0, :y 0}
})
I got to the point where I had to refactor direction into :pacman. This broke my some of my tests, which I had program against the specific implementation. Below direction-to returned a modified version of the map that start-game creates. With the previous implementation, this worked fine.
(testing “should change direction to direction given, right”
(is (= ‘right (:direction (direction-to ‘right (start-game))))))
Once I changed the implementation, the test broke. The fix was simple, but super ugly and hard to understand.
defn start-game
“starts a game state”
[]
{
:pacman {:direction ‘left :x 0, :y 0}
});; broken
(testing “should change direction to direction given, right”
(is (= ‘right (:direction (direction-to ‘right (start-game))))));; fixed, but awkward and ugly
(testing “should change direction to direction given, right”
(is (= ‘right (:direction (:pacman (direction-to ‘right (start-game)))))))
The solution to this problem was to write a function that would return direction when taking state as an argument.
(defn direction
“gets the direction of pacman”
[state]
(get-in state [:pacman :direction] )
)
Now the test can be written like this:
(testing “should change direction to direction given, right”
(is (= ‘right (direction (direction-to ‘right (start-game))))))
Which is a lot nicer to the eyes. Also, if in the future I must change the implementation of the state map as long as I change the direction function I will be okay since direction is the abstraction.