Game Programming 101
Tic-Tac-Toe

https://slides.com/artfuldev/gp101-tic-tac-toe/live

Sudarsan Balaji

@artfuldev

Game Programming 101
Tic-Tac-Toe

Game Programming
?

Game Programming

Game Programming

Software development of video games

Game Programming

Software development of video games

Game Programming

Software development of video games

Game Programming

Software development of video games

What qualifies as a game?

Game Programming

Software development of video games

Game Programming

Software development of video games

Game Programming

Software development of video games

Game Programming

Software development of video games

What all is involved?

Game Programming

Game Programming

Simulation

Game Programming

Simulation

Computer Graphics

Game Programming

Simulation

Computer Graphics

Artificial Intelligence

Game Programming

Simulation

Computer Graphics

Artificial Intelligence

Physics

Game Programming

Simulation

Computer Graphics

Artificial Intelligence

Physics

Audio Programming

Game Programming

Simulation

Computer Graphics

Artificial Intelligence

Physics

Audio Programming

Input

Game Programming

Simulation

Computer Graphics

Artificial Intelligence

Physics

Audio Programming

Input

Network Programming

Game Programming

Simulation

Computer Graphics

Artificial Intelligence

Physics

Audio Programming

Input

Network Programming

Database Programming

Game Programming

Simulation

Computer Graphics

Artificial Intelligence

Physics

Audio Programming

Input

Network Programming

Database Programming

Game Programming

Artificial Intelligence

Game Programming

Artificial Intelligence

Game Programming

Artificial Intelligence

Game Programming

Artificial Intelligence

Game Programming

Artificial Intelligence

Artificial Intelligence

Expert System

Game Programming

Artificial Intelligence

Expert System

Game Programming

Artificial Intelligence

Expert System

Game Programming

Game Engine

Artificial Intelligence

Expert System

Game Programming

Game Engine

Artificial Intelligence

Expert System

Game Programming

Game Engine

Artificial Intelligence

Expert System

Game Programming

Game Engine

Game Programming

Game Engine

Game Engine

Game Engine

A program that analyses and provides feedback on the best possible move in a particular state of a game

Game Engine

A program that analyses and provides feedback on the best possible move in a particular state of a game

Game Engine

Example: Chess engines

Game Engine

Example: Chess engines

We can build them easily.

Game Engine

Example: Chess engines

We can build them easily.

Game Engine

Let's start with TicTacToe

Game Engine

Let's start with TicTacToe

Tic-Tac-Toe

Tic-Tac-Toe

As an AI environment

D

S

O

A

K

E

D

Tic-Tac-Toe

As an AI environment

D

S

O

A

K

E

D

D

S

O

A

K

E

D

Deterministicness

D

S

O

A

K

E

D

Deterministicness

Staticness

D

S

O

A

K

E

D

Deterministicness

Staticness

Observability

D

S

O

A

K

E

D

Deterministicness

Staticness

Observability

Agency

D

S

O

A

K

E

D

Deterministicness

Staticness

Observability

Agency

Knowledge

D

S

O

A

K

E

D

Deterministicness

Staticness

Observability

Agency

Knowledge

Episodicness

D

S

O

A

K

E

D

Deterministicness

Staticness

Observability

Agency

Knowledge

Episodicness

Discreteness

D

S

O

A

K

E

D

Deterministicness

Staticness

Observability

Agency

Knowledge

Episodicness

Discreteness

D

S

O

A

K

E

D

Deterministicness

Staticness

Observability

Agency

Knowledge

Episodicness

Discreteness

Deterministic

D

S

O

A

K

E

D

Deterministicness

Staticness

Observability

Agency

Knowledge

Episodicness

Discreteness

Deterministic

Static

D

S

O

A

K

E

D

Deterministicness

Staticness

Observability

Agency

Knowledge

Episodicness

Discreteness

Deterministic

Static

Fully Observable

D

S

O

A

K

E

D

Deterministicness

Staticness

Observability

Agency

Knowledge

Episodicness

Discreteness

Deterministic

Static

Fully Observable

Single-Agency

D

S

O

A

K

E

D

Deterministicness

Staticness

Observability

Agency

Knowledge

Episodicness

Discreteness

Deterministic

Static

Fully Observable

Single-Agency

Known (Expert)

D

S

O

A

K

E

D

Deterministicness

Staticness

Observability

Agency

Knowledge

Episodicness

Discreteness

Deterministic

Static

Fully Observable

Single-Agency

Known (Expert)

Episodic

D

S

O

A

K

E

D

Deterministicness

Staticness

Observability

Agency

Knowledge

Episodicness

Discreteness

Deterministic

Static

Fully Observable

Single-Agency

Known (Expert)

Episodic

Discrete

D

S

O

A

K

E

D

Deterministicness

Staticness

Observability

Agency

Knowledge

Episodicness

Discreteness

Deterministic

Static

Fully Observable

Single-Agency

Known (Expert)

Episodic

Discrete

D

S

O

A

K

E

D

Deterministicness

Staticness

Observability

Agency

Knowledge

Episodicness

Discreteness

Deterministic

Static

Fully Observable

Single-Agency

Known (Expert)

Episodic

Discrete

Simulateable

Solving Tic-Tac-Toe

Solving Tic-Tac-Toe

As a Human

Solving Tic-Tac-Toe

As a Human

How do we think?

Solving Tic-Tac-Toe

As a Computer

Solving Tic-Tac-Toe

As a Computer

function getBestMove(grid, currentPlayer) {
    // ...
    // calculate best move
    // ...
    return bestMove;
}

Solving Tic-Tac-Toe

As a Computer

Occam's Razor

Solving Tic-Tac-Toe

As a Computer

Occam's Razor

"in explaining a thing no more assumptions should be made than are necessary"

Solving Tic-Tac-Toe

As a Computer

Occam's Razor

"in explaining a thing no more assumptions should be made than are necessary"

Solving Tic-Tac-Toe

As a Computer

Occam's Razor

the simplest solution is usually the best

Solving Tic-Tac-Toe

As a Computer

Occam's Razor

the simplest solution is usually the best

Solving Tic-Tac-Toe

As a Computer

Occam's Razor

the simplest solution is usually the best

Solving Tic-Tac-Toe

As a Computer

Occam's Razor

the simplest solution is usually the best

What is the simplest solution?

Solving Tic-Tac-Toe

As a Computer

What is the simplest solution?

Solving Tic-Tac-Toe

As a Computer

What is the simplest solution?

BRUTE FORCE

What is the simplest solution?

BRUTE FORCE

BRUTE FORCE

BRUTE FORCE

Okay, but...

BRUTE FORCE

Okay, but...

HOW?

Okay, but...

HOW?

Okay, but...

HOW?

"Time travel is the solution to all problems."

Okay, but...

HOW?

"Time travel is the solution to all problems."

-Unknown

Okay, but...

HOW?

"Time travel is the solution to all problems."

-Unknown

Okay, but...

HOW?

"Time travel is the solution to all problems."

-Unknown

Okay, but...

HOW?

"Time travel is the solution to all problems."

-Unknown

How?

Okay, but...

HOW?

Get all possible moves.

Okay, but...

HOW?

Get all possible moves.

Play all possible moves until the end of the game.

Okay, but...

HOW?

Get all possible moves.

Play all possible moves until the end of the game.

Pick the best possible move.

Okay, but...

HOW?

Get all possible moves.

Play all possible moves until the end of the game.

Pick the best possible move.

Return the best possible move.

Okay, but...

HOW?

Get all possible moves.

Play all possible moves until the end of the game.

Pick the best possible move.

Return the best possible move.

Okay, but...

HOW?

Get all possible moves.

Play all possible moves until the end of the game.

Pick the best possible move.

Return the best possible move.

Okay, but...

HOW?

Get all possible moves.

Play all possible moves until the end of the game.

Pick the best possible move.

Return the best possible move.

HOW?

Okay, but...

HOW?

Get all possible moves.

Play all possible moves until the end of the game.

See the results of every move.

Return the best possible move.

Okay, but...

HOW?

Get all possible moves.

Play all possible moves until the end of the game.

See the results of every move.

Pick the move which results in least losses.

Return the best possible move.

Okay, but...

HOW?

Get all possible moves.

Play all possible moves until the end of the game.

See the results of every move.

Pick the move which results in least losses.

Return the best possible move.

Okay, but...

IN CODE?

Get all possible moves.

Play all possible moves until the end of the game.

See the results of every move.

Pick the move which results in least losses.

Return the best possible move.

Okay, but...

IN CODE?

Okay, but...

IN CODE?

Okay, but...

IN CODE?

Time to say hi...

Okay, but...

IN CODE?

Time to say hi...

...to

Game Trees

Game Trees

Game Trees

A directive graph whose nodes are positions in a game and whose edges are moves

Game Trees

A directive graph whose nodes are positions in a game and whose edges are moves

By the way,

we just stepped into Game Theory.

Game Trees

A directive graph whose nodes are positions in a game and whose edges are moves

Game Trees

A directive graph whose nodes are positions in a game and whose edges are moves

Game Trees

A directive graph whose nodes are positions in a game and whose edges are moves

Game Trees

A directive graph whose nodes are positions in a game and whose edges are moves

Game Trees

A directive graph whose nodes are positions in a game and whose edges are moves

Game Trees

A directive graph whose nodes are positions in a game and whose edges are moves

Traversal

Game Trees

A directive graph whose nodes are positions in a game and whose edges are moves

Traversal

Evaluation

Game Trees

A directive graph whose nodes are positions in a game and whose edges are moves

Traversal

Evaluation

Let's look at one!

Game Trees

A directive graph whose nodes are positions in a game and whose edges are moves

Traversal

Evaluation

Let's look at one!

And next we have...

Minimax

Minimax

Minimax

A decision rule that minimizes possible loss for a worst case scenario.

Minimax

Depends on the maximin score.

Minimax

Depends on the maximin score.

Minimax

Depends on the maximin score.

The largest value that the player can be sure to get without knowing the actions of the other players

Minimax

Minimax

Let's watch it in action again, in more detail this time!

Minimax

Let's watch it in action again, in more detail this time!

Minimax

function minimax(node, depth, maximizingPlayer) {
  if (depth === 0 || isTerminalNode(node))
    return evaluate(node);
  if (maximizingPlayer)
    return getChildren(node)
      .reduce((best, child) =>
        Math.max(best, minimax(child, depth - 1, false)),
      -Infinity);
  return getChildren(node)
    .reduce((best, child) =>
        Math.min(best, minimax(child, depth - 1, true)),
      Infinity);
}

Minimax

function minimax(node, depth, maximizingPlayer) {
  if (depth === 0 || isTerminalNode(node))
    return evaluate(node);
  if (maximizingPlayer)
    return getChildren(node)
      .reduce((best, child) =>
        Math.max(best, minimax(child, depth - 1, false)),
      -Infinity);
  return getChildren(node)
    .reduce((best, child) =>
        Math.min(best, minimax(child, depth - 1, true)),
      Infinity);
}
function minimax(node, depth, maximizingPlayer) {
  if (depth === 0 || isTerminalNode(node))
    return evaluate(node);
  if (maximizingPlayer)
    return getChildren(node)
      .reduce((best, child) =>
        Math.max(best, minimax(child, depth - 1, false)),
      -Infinity);
  return getChildren(node)
    .reduce((best, child) =>
        Math.min(best, minimax(child, depth - 1, true)),
      Infinity);
}
function minimax(node, depth, maximizingPlayer) {
  if (depth === 0 || isTerminalNode(node))
    return evaluate(node);
  if (maximizingPlayer)
    return getChildren(node)
      .reduce((best, child) =>
        Math.max(best, minimax(child, depth - 1, false)),
      -Infinity);
  return getChildren(node)
    .reduce((best, child) =>
        Math.min(best, minimax(child, depth - 1, true)),
      Infinity);
}

How to find?

function minimax(node, depth, maximizingPlayer) {
  if (depth === 0 || isTerminalNode(node))
    return evaluate(node);
  if (maximizingPlayer)
    return getChildren(node)
      .reduce((best, child) =>
        Math.max(best, minimax(child, depth - 1, false)),
      -Infinity);
  return getChildren(node)
    .reduce((best, child) =>
        Math.min(best, minimax(child, depth - 1, true)),
      Infinity);
}

How to find?

function minimax(node, depth, maximizingPlayer) {
  if (depth === 0 || isTerminalNode(node))
    return evaluate(node);
  if (maximizingPlayer)
    return getChildren(node)
      .reduce((best, child) =>
        Math.max(best, minimax(child, depth - 1, false)),
      -Infinity);
  return getChildren(node)
    .reduce((best, child) =>
        Math.min(best, minimax(child, depth - 1, true)),
      Infinity);
}

How to find?

How?

function minimax(node, depth, maximizingPlayer) {
  if (depth === 0 || isTerminalNode(node))
    return evaluate(node);
  if (maximizingPlayer)
    return getChildren(node)
      .reduce((best, child) =>
        Math.max(best, minimax(child, depth - 1, false)),
      -Infinity);
  return getChildren(node)
    .reduce((best, child) =>
        Math.min(best, minimax(child, depth - 1, true)),
      Infinity);
}

How to find?

How?

function minimax(node, depth, maximizingPlayer) {
  if (depth === 0 || isTerminalNode(node))
    return evaluate(node);
  if (maximizingPlayer)
    return getChildren(node)
      .reduce((best, child) =>
        Math.max(best, minimax(child, depth - 1, false)),
      -Infinity);
  return getChildren(node)
    .reduce((best, child) =>
        Math.min(best, minimax(child, depth - 1, true)),
      Infinity);
}

How to find?

How?

How?

function minimax(node, depth, maximizingPlayer) {
  if (depth === 0 || isTerminalNode(node))
    return evaluate(node);
  if (maximizingPlayer)
    return getChildren(node)
      .reduce((best, child) =>
        Math.max(best, minimax(child, depth - 1, false)),
      -Infinity);
  return getChildren(node)
    .reduce((best, child) =>
        Math.min(best, minimax(child, depth - 1, true)),
      Infinity);
}

How to find?

How?

How?

function minimax(node, depth, maximizingPlayer) {
  if (depth === 0 || isTerminalNode(node))
    return evaluate(node);
  if (maximizingPlayer)
    return getChildren(node)
      .reduce((best, child) =>
        Math.max(best, minimax(child, depth - 1, false)),
      -Infinity);
  return getChildren(node)
    .reduce((best, child) =>
        Math.min(best, minimax(child, depth - 1, true)),
      Infinity);
}

Is game over?

How?

How?

function minimax(node, depth, maximizingPlayer) {
  if (depth === 0 || isTerminalNode(node))
    return evaluate(node);
  if (maximizingPlayer)
    return getChildren(node)
      .reduce((best, child) =>
        Math.max(best, minimax(child, depth - 1, false)),
      -Infinity);
  return getChildren(node)
    .reduce((best, child) =>
        Math.min(best, minimax(child, depth - 1, true)),
      Infinity);
}

Is game over?

How close is X to winning?

How?

function minimax(node, depth, maximizingPlayer) {
  if (depth === 0 || isTerminalNode(node))
    return evaluate(node);
  if (maximizingPlayer)
    return getChildren(node)
      .reduce((best, child) =>
        Math.max(best, minimax(child, depth - 1, false)),
      -Infinity);
  return getChildren(node)
    .reduce((best, child) =>
        Math.min(best, minimax(child, depth - 1, true)),
      Infinity);
}

Is game over?

How close is X to winning?

What are my next possible moves?

function minimax(node, depth, maximizingPlayer) {
  if (depth === 0 || isTerminalNode(node))
    return evaluate(node);
  if (maximizingPlayer)
    return getChildren(node)
      .reduce((best, child) =>
        Math.max(best, minimax(child, depth - 1, false)),
      -Infinity);
  return getChildren(node)
    .reduce((best, child) =>
        Math.min(best, minimax(child, depth - 1, true)),
      Infinity);
}

Is game over?

How close is X to winning?

What are my next possible moves?

function minimax(node, depth, maximizingPlayer) {
  if (depth === 0 || isTerminalNode(node))
    return evaluate(node);
  if (maximizingPlayer)
    return getChildren(node)
      .reduce((best, child) =>
        Math.max(best, minimax(child, depth - 1, false)),
      -Infinity);
  return getChildren(node)
    .reduce((best, child) =>
        Math.min(best, minimax(child, depth - 1, true)),
      Infinity);
}

Minimax

Minimax

Optimizations

Minimax

Optimizations

should we traverse the entire tree?

Minimax

Optimizations

should we traverse the entire tree?
alpha-beta pruning

Minimax

Optimizations

should we traverse the entire tree?
alpha-beta pruning

if(β ≤ α) break;

Minimax

Optimizations

should we traverse the entire tree?
alpha-beta pruning

if(β ≤ α) break;

 

should we calculate min and max?

Minimax

Optimizations

should we traverse the entire tree?
alpha-beta pruning

if(β ≤ α) break;

 

should we calculate min and max?
negamax

Minimax

Optimizations

should we traverse the entire tree?
alpha-beta pruning

if(β ≤ α) break;

 

should we calculate min and max?
negamax

max(a,b) = -min(-a,-b);

Minimax

Optimizations

should we traverse the entire tree?
alpha-beta pruning

if(β ≤ α) break;

 

should we calculate min and max?
negamax

max(a,b) = -min(-a,-b);

 

concurrency

Minimax

Optimizations

should we traverse the entire tree?
alpha-beta pruning

if(β ≤ α) break;

 

should we calculate min and max?
negamax

max(a,b) = -min(-a,-b);

 

concurrency

 

simpler evaluation

Minimax

Optimizations

should we traverse the entire tree?
alpha-beta pruning

if(β ≤ α) break;

 

should we calculate min and max?
negamax

max(a,b) = -min(-a,-b);

 

concurrency

 

simpler evaluation

Minimax

Optimizations

should we traverse the entire tree?
alpha-beta pruning

if(β ≤ α) break;

 

should we calculate min and max?
negamax

max(a,b) = -min(-a,-b);

 

concurrency

 

simpler evaluation

evaluation

evaluation

evaluation

evaluation

evaluation is the process of assigning a value to a node

evaluation

evaluation is the process of assigning a value to a node

it is the heart of any engine, optimal moves can only be found with a sound evaluation function

evaluation

for tic-tac-toe

evaluation

function evaluateCells(cells) {
  const length = cells.length;
  if(length === 0) return 0;
  const initial = { undefined: 0, true: 0, false: 0 };
  const counts = cells.reduce((counts, cell) => increment(counts, cell), initial);
  if (counts.undefined === length) return 0;
  if (counts.true === length) return Infinity;
  if (counts.false === length) return -Infinity;
  if (counts.false === 0) return Math.pow(2, counts.true);
  if (counts.true === 0) return -Math.pow(2, counts.false);
  return 0;
}

function evaluate(grid) {
  return evaluateRows(grid) + evaluateColumns(grid) + evaluateDiagonals(grid);
}

move generation

function getMoves(grid) {
  return grid
          .map((value, index) => value == undefined ? index : undefined)
          .filter(value => value != undefined);
}

move generation

function getMoves(grid) {
  return grid
          .map((value, index) => value == undefined ? index : undefined)
          .filter(value => value != undefined);
}

termination

function hasGameEnded(grid) {
  return hasXWon(grid) || hasOWon(grid) || isFull(grid);
}

Source!

Source!

Source!

Other interesting games

Other interesting games

Chess

Other interesting games

Chess
2048

Other interesting games

Chess
2048

 

Think of your own game to beat!

Other interesting games

Chess
2048

 

Think of your own game to beat!

Other interesting games

Chess
2048

 

Think of your own game to beat!

My favourite!

Other interesting games

Chess
2048

 

Think of your own game to beat!

My favourite!

Chess

Chess

  • Iterative deepening

Chess

  • Iterative deepening
  • Killer moves

Chess

  • Iterative deepening
  • Killer moves
  • Quiescence search

Chess

  • Iterative deepening
  • Killer moves
  • Quiescence search
  • Move ordering

Chess

  • Iterative deepening
  • Killer moves
  • Quiescence search
  • Move ordering
  • Hashtables

Chess

  • Iterative deepening
  • Killer moves
  • Quiescence search
  • Move ordering
  • Hashtables
  • Transposition table

Chess

  • Iterative deepening
  • Killer moves
  • Quiescence search
  • Move ordering
  • Hashtables
  • Transposition table

2048

2048

  • Expectimax

2048

  • Expectimax

2048

  • Expectimax

Experiments

  • github.com/artfuldev/Kenny
  • github.com/artfuldev/KennyClassIQ
  • github.com/artfuldev/KenTacToe
  • github.com/artfuldev/Sharp48
  • github.com/artfuldev/CAESAR
  • github.com/artfuldev/tictactoe-ai

Questions?

Game Progamming 101: Programming Tic Tac Toe

By artfuldev

Game Progamming 101: Programming Tic Tac Toe

  • 1,985