After a bit of hiatus, I’ve resumed a hobby project started many years ago inspired by an online course offered by Stanford University, General Game Playing.
I’ve written the rules to a game, Lines of Action, which I picked because Stanford had a version written in a lispish Prolog dialect called kif at https://games.ggp.org/base/games/linesOfAction/linesOfAction.kif
My SWI-Prolog version is at prolog-ggp-player/linesofaction.pl at f91f6ff304c6fcce4c905eeed4be73e82f6dc130 · roblaing/prolog-ggp-player · GitHub
A web frontend to play the game is at Lines Of Action
I’ve found writing the JavaScript frontend the toughest part of the project, especially since I’ve tried to make it “mobile friendly” by designing for a generic pointer rather than a mouse, and I’ve ended up only using “pointerup” since I’ve no idea what the other dozen pointer events defined by W3C’s standards are supposed to do.
Other thing I’ve learned is translating kif to Prolog is a bit futile. Stanford’s code is incomprehensible to me and my mechanical translation just hangs instead of returning legal moves.
One key difference seems to be kif doesn’t follow Prolog’s “negation as failure” convention. For instance, one of the rules in this game is a piece can’t end it’s turn on a square occupied by a friendly piece, but can capture an enemy piece. In kif, this rule can be written
(not (true (cell ?x ?y white)))
as a query to return all the squares not occupied by white. As I’ve learnt the hard way, mechanically transliterating that to \+true(cell, X, Y, white)
where X and Y haven’t been ground simply returns false. If you know how, the fix is easy:
true(cell(X, Y, Role), Role \= white.
Long story short, writing rules of games by simply hacking away in SWI-Prolog without worrying if the code is imperative, declarative or whatever is fun, whereas trying to decipher kif, for which there doesn’t appear to be any actively developed interpreter that I’m aware of, is just frustrating.
The UI is really the horrible part.