Robot Game-Playing in MATLAB – Part 2
Last week we showed how to use a Monte Carlo approach to write a program capable of playing Tic Tac Toe. But that was just our warm-up exercise. Now let’s build another game that can take advantage of our game-playing harness.
The first game I thought of was Connect Four, since it’s a straightforward extension of Tic Tac Toe. And sure enough, it’s not to hard to convert our Tic Tac Toe engine into a Connect Four engine.
CONNECT FOUR
In Connect Four, your board is a 6-by-7 grid, and your goal is to be the first to put four pieces in a line. The game board is oriented vertically, so gravity causes your pieces to drop to the bottom of the grid. This means that you have at most seven legal moves. This is good for us, since it constrains the number of possible moves, which in turn makes it quicker for us to play hundreds of games.
The game harness botMoves doesn’t change at all. We just make a new class, ConnectFour, that knows the rules and can draw the Connect Four game board. And when I say “knows the rules”, I mean exactly two things.
- What legal moves can I make right now?
- If the game is over, who won?
That’s it.
Finding legal moves is easy. We just look for any column that has zeroes left in it. But how do you determine if someone has won the game? We need to scan the board for four-in-a-row of either color in any of four directions: vertical, horizontal, and two diagonals. This seemed like it was going to call for some careful thinking, until I remembered that there was a Cody problem about this very topic! See Problem 90. Connect Four Win Checker.
I shopped around in the answers to Problem 90 and found a nice piece of code authored by long time Cody champ @bmtran: Solution 2314.
I wired everything together, and it plays a pretty mean game. Here’s an animation of my Connect Four bot playing itself.
CONNECT FOUR VARIANTS
The Monte Carlo approach means that we haven’t had to put a lot of special game-specific smarts into the code. This gives us great freedom to explore variants on our basic Connect Four game. Suppose, instead of racing to get four in a row, players were trying to be the first to make an “L” shape. In order to make this work, I just had to change a few lines in the isGameOver method. And rather than clone and modify the entire ConnectFour class, I built a FourGameBase class from which I could quickly subclass variants. This base class knows how to draw the board and pick legal moves. The winning conditions are handled by the subclasses.
Here’s my ConnectEl game bot playing itself.
We can imagine a whole family of Connect Tetris variants: be the first to make a square, or a T-shape, or an S-shape. Not all of these variants are interesting as games. I built square and T-shape versions of the game, and in both cases defensive play was so easy that, as with Tic Tac Toe, all the games ended in ties. But this ability to rapidly create and play games leads to another observation. We can use our Monte Carlo code to mutate games in search of interesting variants. An interesting game is one in which either side has a reasonable chance of winning. An uninteresting game consistently ends in a tie or victory for a particular side. So we can effectively use bots to do our play-testing for us. The optimal strategies simply emerge from the Monte Carlo soup.
I want to mention one last Connect Four variant before I move on: Four Corners. In Four Corners, you try to force your opponent to be the first to put his pieces into the four corners of a rectangle.
In this case, I used code from a Cody answer by Alfonso Nieto-Castanon to test for the victory condition: Spot the rectangle.
Here is my bot slugging it out with itself in Four Corners.
This is a fun game to play against the bot. It’s surprisingly tricky to spot all the potential rectangles on the board.
REVERSI
For my last example, I wrote a program that does a passable job of playing Reversi. As before, I used Cody to diminish the coding effort by posting two problems.
- Problem 2538. Find the Next Legal Move in Reversi (thanks Tim!)
- Problem 2565. Determine the Result of a Move in Reversi (thanks Jan!)
Here’s the animation of the game in action.
WHAT NEXT?
If you, like me, are intrigued with the possibilities of Monte Carlo gaming, I encourage you to take a look at my code on GitHub. Maybe you can add some new games to the list that I’ve already created. There are plenty of games that would work with this harness. Or you can improve the code that’s already there, making it speedier or more efficient. Because of the brute force nature of the Monte Carlo technique, it would be an ideal place to experiment with parallel programming. Or you might make it more interactive, with a click-to-move interface.
I’ll stop here, but this is clearly a rich space to explore. It’s a powerful reminder that computers are very different from brains. Sometimes you can make up for not being clever by being stupid very fast.
Comments
To leave a comment, please click here to sign in to your MathWorks Account or create a new one.