Well, it was not unsolvable at all, you just have to cool down and try to write down things progressively.
The solution
The idea I had that evening is that, finding the position of the upper left corner of the ith subgrid in a grid, should be as difficult as finding the position of the ith square in a grid. Make as if the big grid is a small one with subgrids in each square.
So here are the formulas (perhaps it is clearer than my previous "explaining" phrase?):
# returns a square position (x, y) for the upper left corner
# of the "grid_nb"th subgrid in a grid
def get_subgrid grid_nb
square = Grid.new(@width / @sub_width, @height / @sub_height).get_square grid_nb
x = 1 + @sub_width*(square.x_pos - 1)
y = 1 + @sub_height*(square.y_pos - 1)
end
and
# returns a square position (x, y) for the "square_nb"th square in a grid
def get_square square_nb
x = 1 + (square_nb - 1)% @width
y = 1 + (square_nb - 1)/ @width
Square.new x, y
end
OK, and for the crazy ones, the formula that precisely calculates the position of the upper left corner of the "grid_nb" subgrid in a (w * w) grid with (subw*subh) subgrids (for instance, you can have a 6x6 grid with 6 2x3 subgrids):
1 + subw*((1 + (grid_nb - 1)% ((w / subw)) - 1) + w * (1 + subh*((1 + (grid_nb - 1)/ w) - 1))
No wonder why we couldn't get it rigth at once! Indeed, it took me slightly more than one hour to do that with 5 tests and 31 assertions in Ruby.
TDD as an unconscious habit
Thinking about the discussion I had about TDD after the Dojo, I feel that TDD should really become an unconscious skill. You have to train yourself consciously then to master it without thinking about it. You know the classical circle for learning:
- Something I don't know I don't know - unconscious lack of skill
- Something I know I don't know - conscious lack of skill
- Somethind I know I know - conscious knowledge
- Something I don't know I know - unconscious knowledge
- either defining test cases - green bar
- either implementing test cases - green bar
- either implementing code to pass the test cases - red bar
- either refactoring code - green bar
- either refactoring test cases - green bar