Ruby: implementing alpha-beta pruning for tic-tac-toe

Posted by DerNalia on Game Development See other posts from Game Development or by DerNalia
Published on 2011-02-01T06:54:24Z Indexed on 2011/02/01 7:33 UTC
Read the original article Hit count: 357

Filed under:
|
|
|

So, alpha-beta pruning seems to be the most efficient algorithm out there aside from hard coding (for tic tac toe). However, I'm having problems converting the algorithm from the C++ example given in the link: http://www.webkinesia.com/games/gametree.php

#based off http://www.webkinesia.com/games/gametree.php
# (converted from C++ code from the alpha - beta pruning section)
# returns 0 if draw
LOSS = -1
DRAW = 0
WIN = 1
@next_move = 0
def calculate_ai_next_move
    score = self.get_best_move(COMPUTER, WIN, LOSS)
    return @next_move
end

def get_best_move(player, alpha, beta)
    best_score = nil
    score = nil
    if not self.has_available_moves?
      return false
    elsif self.has_this_player_won?(player)
      return WIN
    elsif self.has_this_player_won?(1 - player)
      return LOSS
    else
      best_score = alpha
      NUM_SQUARES.times do |square| 
        if best_score >= beta
          break
        end

        if self.state[square].nil?
          self.make_move_with_index(square, player)
          # set to negative of opponent's best move; we only need the returned score;
          # the returned move is irrelevant.
          score = -get_best_move(1-player, -beta, -alpha)

          if (score > bestScore)
            @next_move = square
            best_score = score
          end
          undo_move(square)
        end
      end
    end
    return best_score
end

the problem is that this is returning nil.

some support methods that are used above:

    WAYS_TO_WIN = [[0, 1, 2], [3, 4, 5], [6, 7, 8], [0, 3, 6], [1, 4, 7], [2, 5, 8],[0, 4, 8], [2, 4, 6]]


    def has_this_player_won?(player)
      result = false
      WAYS_TO_WIN.each {|solution| result = self.state[solution[0]] if contains_win?(solution) }
      return (result == player)
    end

   def contains_win?(ttt_win_state)
    ttt_win_state.each do |pos|
      return false if self.state[pos] != self.state[ttt_win_state[0]] or self.state[pos].nil?
    end

    return true
  end

   def make_move(x, y, player)
        self.set_square(x,y, player)
    end

© Game Development or respective owner

Related posts about c++

Related posts about algorithm