Add caching for gameNode.board()

I added caching for gameNode.board().

In my application, I am going through a lot of games in PGN format and simply extracting all positions as EPD, with the supplied moves.

It was very slow, and I found that's because for every position, all boards leading up to that position are being recursively rebuilt.

I added caching so that it remembers the board for subsequent use (in my case, that's for building the board for the next position). It shouldn't impact performance on applications that don't call the function, because it's only computed on first use. For my application, it's now O(n) instead of O(n^2) for a game of length n.

On a test input file with 780 games -
CPython -
Old - 3:37
New - 0:41

Pypy3 -
Old - 1:10
New - 0:30

Thanks!
Matthew