Skip to content

Concepts

Philippe Vaillancourt edited this page May 22, 2018 · 4 revisions

At its core, Macao is a general game playing AI for JavaScript games. It is based on the Monte Carlo Tree Search algorithm.

Macao requires almost no configuration to add to your project. To get started you only need to understand its Core Concepts:

This document is intended to give a high-level overview of these concepts, while providing links to detailed concept specific use cases.

When programming your game, you will have to decide upon an object type to store the state of the game. Macao doesn't get in your way when it comes to deciding on the shape of your game state object. The only thing it asks of you is that you store game states in a JavaScript object, and that the object has a property named player. The player property should store a player identification, it could be a string or a number, whatever you prefer. Each game state should have an associated player property that identifies the player having just played... the player responsible for making the game state what it is.

Here are a few examples of game state objects that would be compatible with Macao:

const gameState = {
  board: [0, 1, 0, 0, 1, 0]
  player: 1
}

const otherGameState = {
  myBoard: [
    ['X', 'O', 'X'],
    ['O', 'X', 'O'],
    ['X', 'O', 'X']
  ],
  player: 'X'
}

const yetAnotherGameState = {
  gameBoard: 446 //bitboard
  someCondition: true
  someOtherCondition: false
  somePropertyThatYouNeedToTrack: 67
  player: 2
}

As you can see, the game state object can take pretty much any shape you like, as long as it has a player property.

In programming your game, you will also have to come up with a way to represent player actions. In this, Macao gives you complete free rein. You can represent actions however you please. Player actions will be consumed and produced by some of the functions you will have to write in order to make your game, and Macao work.

One of the functions you will need to write for your game, and that you will need to pass to Macao, is a function that generates all possible legal moves given a certain game State. For instance, let's imagine that we are making a simple tic-tac-toe game and that we are representing the board and the game State like this, where 0 represents an empty square, 1 represents an X square and -1 represents an O square:

const ticTacToeGameState = {
  board: [
    [-1,  0,  1],
    [ 1,  1, -1],
    [-1,  0,  0]
  ],
  player: -1
}

Let's also imagine that we had decided upon a very simple Action object type that only contained the 0 indexed coordinates of the move to be made, something like this:

const action = { row: 0, column: 1}

Now we would need to write a function that takes in the game State as an argument and returns an array of Action objects. For this simple game of Tic-Tac-Toe it could look like this:

const generateActions = (state) => {
  const result = []
  state.board.forEach((rowArray, row) => {
    rowArray.forEach((value, column) => {
      if (value === 0) result.push({ row, column })
    })
  })
  return result
}

Pretty simple, isn't it? All we are doing is looking at each square and pushing the coordinates of the empty squares to our result array. Of course, in more complicated games, this function can get much more complex.

Clone this wiki locally