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
Idea
Aims
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
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.
(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
Toys
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
Classes
Game store
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[]=
,,,
Entity class hierarchy
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[]:=
Out[]=
In[]:=
Out[]=
In[]:=
Out[]=
In[]:=
edges=Flatten[{#["SuperClass"]->#}&/@Complement[EntityList["Game"],{GameEntity["Game"]}]];Graph[edges,GraphLayout->"LayeredDigraphEmbedding",VertexShapeFunction->(Text[Style[#2,12],#]&),ImageSize150]
Out[]=
Games as types
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[]:=
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[]:=
Out[]=
game
Out[]=
combinatorialGame
Out[]=
mnkGame
Out[]=
tictactoeGame
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
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!
Well, let’s play some Tic-tac-toe!
We instantiate a game by creating an ‘instance’ of it:
In[]:=
ttt=["createInstance"];
The current state of the game contains information about the state of the 33 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}},toMove1
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
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
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
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.
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
Cite This Notebook