Can a game tree be stored in CSS and used to drive a computer AI? Spoiler: yes.
Updated: Check the follow up article which describes how to make the code more DRY.
On the heels of the CSS Counter, I wanted to abuse CSS more.
About two years ago, someone put together a neat JS Fiddle showing CSS as Turing Complete. Someone else put together a version of Tic Tac Toe that uses CSS to compute the winner between two human players.
These are awesome ways to abuse this much maligned web language.
AI in Pure CSS
Here's the demo: A beer drinking game powered only by CSS
But what if you also wanted to encode the opponent with CSS? What types of games could you actually write an artificial intelligence that can play against someone? Here are the rules that I came up with. They may be overly binding, but I think they are sensible:
Way to Encode Computer Moves
Now comes the most vague portion of these standards. In order to write a two player game in CSS, the following needs to be possible:
- The user must be able to register their move. This is best done via form elements, like checkboxes or radio buttons. This also enables the :checked selector to work. So, the user alters form elements on the DOM for their move. (A couple other interactions, like hover and focus could potentially work, too).
- The computer must be able to register its move. By far, this was the trickiest portion of coding the beer game. CSS cannot alter the DOM, and it cannot interact with form elements (that is, it cannot check and uncheck form elements). Because of this, a register of computer moves must be created. In the beer game, it's a series of inputs that are styled with after psuedo elements.
- The computer and human must alternate moves. This is weakly solved in the beer game by having the computer respond immediately to the user.
The opponent must be deterministic. Without a randomizer function in CSS, the game must be played according to strict rules that don't take chance into consideration. Kind of like Newtonian physics.
Unfortunately, although many great games are deterministic (Braid, Myst, Mario, Cut the Rope, Angry Birds), very few good AIs are. The problem with deterministic AIs is that they are either perfect or they have flaws, sometimes intentional, which allow the user a path to win. In the latter case, once the user has found a hole in the AIs gameplay, they can win each time.
Near-perfect Human Play
The former case—the computer playing perfectly—is more interesting. Some games build up large databases in order to be able to perform flawlessly during endgame play. Some of the best boardgame programs use this technique in order to play against the best humans. A notable example is Chinook, a checkers program. Chinook had a massive endgame database, so that the game could play deterministically through any position with 9 or fewer pieces on the board.
A feasible game where determinism could be used is Tic Tac Toe, where nearly everyone can play perfect games after some thought and learning some strategy.
However, due to the nature of CSS, each possibility must be encoded into the stylesheet. This means coding each board layout, without taking symmetries into account. This is practically unfeasible, even for a game as simple as Tic Tac Toe.
For the beer game, there are some advantages when compared to a game like Tic Tac Toe. First of all, each number is reached only once, and the decision where to go from that number is straightforward. The next number can be chosen with only one data point (i.e. the current number) and without regard to previous moves.
Critically, due to the requirement that each move must be encoded in CSS, relatively small spaces are required. Although I think a CSS Tic Tac Toe program could be possible, games like Connect Four, Checkers, and Chess, are straight out. Checkers alone would require multiple petabytes of storage to hold the entire game database in CSS form. Certainly, a modern browser would crash long before parsing this file.
However, philosophically, one could imagine the feasibility of a truly massive computer, many times the size of the universe, computing all the states of Go or Chess with absolute precision. These games are within the theoretical possibilities of a declarative language like CSS.
Programmers who peek at the source code for the beer game will cringe at the repitition in the code. And this is for a simple game! This is not DRY by any stretch of the acronym.
Is it AI?
I've been calling this CSS program AI. Is it? Certainly, CSS AI requires that all the knowledge be hard-coded. There's no provision for it to learn and get better based on prior games. I would hesitate to call this type of program artificially intelligent, since it lacks some of the magic the term seems to engender.
But at the same time, for something as raw as CSS, this level of complexity almost deserves to be called AI. The program is receiving input, looking up what to do with it, and placing output on the screen. Unfortunately, that's precisely what most programs do, and most programs aren't arguably artificially intelligent.