Combinatorial games are two-player, perfect-information games where players take actions sequentially. Well-known examples include Tic-tac-toe, Connect-4, and Nim. This project aims to create a suitable representation structure using the Wolfram Language’s ‘Entity’ framework and to demonstrate the framework’s viability. Ensuring compatibility with existing Wolfram Language functions is of particular importance.

Idea

Aims

Wolfram Knowledgebase contains semantic representations of numerous entities from chemical to chords, species to stars. In our (perhaps irredeemably thwarted) perspective, one kind of entity that is conspicuously missing are games. The principal aim for this project was to create a framework that can help fill this lacuna.
Our secondary objective was to demonstrate that the Wolfram Language (WL) supports object-oriented programming (OOP) with relative ease. Harnessing this mode of code organization enabled us to build (what we hope will be) the foundation of an incremental project of introducing a large number of games to WL.

A few words on the question design

The most sassy answer to questions like: “What is good design? What does it mean for something to be well-designed?” is probably akin to what U.S. Supreme Court Justice Potter Stewart said in relation to pornography: “I know it when I see it”.
In[]:=
ColorNegate@EntityValue[Entity["Planet","Mars"],"Image"]
Out[]=
If you think, along with the author of this notebook, that this is good design, and you want to give a less flippant answer to what precisely makes it good, you can try to reason along the following lines.
(Facility) Perhaps what makes the design behind this code good is that it is very easy to read.
(Utility) Perhaps it is the fact that it will be easy to reuse and modify and adjust later.
(Beauty) Perhaps it is shortness and elegance.
(Cogitatio) Perhaps it is the fact that the code moves surreptitiously, along the lines we think.
And, of course, it is nigh impossible to disentangle these factors.
Our aim was to design something similar for games. Something that is easy, useful, pretty and both follows and leads our thinking.

Toys

We will be using the Class paclet written by Nik Murzin. If you don’t have it, get it first:
PacletInstall["Wolfram`Class`"];
After installation, we run:
In[]:=
Needs["Wolfram`Class`"];
Importantly, we define games in separate files. This allows for modularity and compartmentalization. For the purposes of this presentation notebook, however, we bring all the code into a single notebook; we note that this is not the natural habitat of these definitions, however.

Classes

Game store

We define some game classes. The large iconizations below are not accidental: from the perspective of a user of our games framework, the details of our implementations are not really relevant.
In[]:=
GameEntity[x_String]:=Entity["Game",x];​​gameDef=

;​​combinatorialGameDef=

;​​mnkDef=

;​​tictactoeDef=

;
We store everything as entities:
In[]:=
definitions={"gameDef","combinatorialGameDef","mnkDef","tictactoeDef"};​​gameStore=EntityStore[​​"Game"->​​<|​​"Entities"->​​Association@(ToExpression/@definitions)​​|>​​];​​EntityRegister[gameStore];
So what do we have in our gameStore?
In[]:=
EntityList["Game"]
Out[]=

Game
,
Combinatorial game
,
m,n,k-game
,
Tic-tac-toe


Entity class hierarchy

Every Tic-tac-toe game is an m,n,k-game. Every m,n,k-game is a combinatorial game. And every combinatorial game is just a game.
In[]:=
Tic-tac-toe
GAME
["SuperClass"]
Out[]=
m,n,k-game
In[]:=
m,n,k-game
GAME
["SuperClass"]
Out[]=
Combinatorial game
In[]:=
Combinatorial game
GAME
["SuperClass"]
Out[]=
Game
In[]:=
edges=Flatten[{#["SuperClass"]->#}&/@Complement[EntityList["Game"],{GameEntity["Game"]}]];​​​​Graph[edges,GraphLayout->"LayeredDigraphEmbedding",VertexShapeFunction->(Text[Style[#2,12],#]&),ImageSize150]
Out[]=

Games as types

You can think of a game entity as a ‘type’. We saw above that we store information about the SuperClass/Class members of each game type. For each game type, we can have a short description, or a link associated with it, etc.
Each game type contains
In[]:=
Tic-tac-toe
GAME
["Link"]
Out[]=
https://en.wikipedia.org/wiki/Tic-tac-toe
The types also contain information about the rules of the game. To work with these, we have to generate the respective type definitions (once):
In[]:=
Game
GAME
["runTypeDefinition"]​​
Combinatorial game
GAME
["runTypeDefinition"]​​
m,n,k-game
GAME
["runTypeDefinition"]​​
Tic-tac-toe
GAME
["runTypeDefinition"]
Out[]=
game
Class: game
Parent: Class

Out[]=
combinatorialGame
Class: game
Parent: game

Out[]=
mnkGame
Class: game
Parent: combinatorialGame

Out[]=
tictactoeGame
Class: game
Parent: mnkGame

On an average day, we are not interested in games as types. Indeed, on an average day, what makes games interesting is their individuality, peculiarity, winning this. Winning the game one is playing right here, right now.

Play

So how do we bring these abstractions, these ideal-types of games into the ‘here-and-now’?
Well, let’s play some Tic-tac-toe!
We instantiate a game by creating an ‘instance’ of it:
In[]:=
ttt=
Tic-tac-toe
GAME
["createInstance"];
The current state of the game contains information about the state of the 33 Tic-tac-toe board, as well as the player whose turn it is to move.
In[]:=
ttt["currentState"]
Out[]=
board{{0,0,0},{0,0,0},{0,0,0}},toMove1
A picture... and so on
In[]:=
ttt["drawCurrentState"]
Blue can make a move:
Red can make a move:
We can also make several moves one after the other
Has the game ended yet?
We can see the list of all possible moves:
...or the list of possible states to be reached:

Multiplying games

We can easily create multiple instances of the same class of game:
We can also copy a game:
If we make moves in the new instance...
... the original instance (and other instances) are unaffected:
We can create the game graph by calling:

Hope

Ongoing and future work involves ensuring compatibility with functions such as DirectedAcyclicEvaluate and AlphaBetaSearch.
We hope this cursory demonstration is convincing in the viability and benefit of the object-oriented approach to our design problem. I encourage anyone interested in contributing games to this emerging Game entity class to get in touch.

Acknowledgments

Brad Klee’s work was, as always, inspirational, and he generously allowed me to follow my own path on this project.
I am grateful to Nik Murzin for creating the Class paclet, and helping me learn its uses.
Daniel Sanchez and Christopher Wolfram pointed me in the right direction, and were extremely quick in providing support.
Andrea Li’s enthusiasm for games was infectious.

Cite This Notebook

“Introducing combinatorial games in Wolfram Language's Entity framework with object-oriented programming”
by Zsombor Z. Méder​
​https://community.wolfram.com/groups/-/m/t/3210476