Проблема с методом обрезки альфа-бета, возвращает бета?может я не понимаю как это работает - PullRequest
2 голосов
/ 03 февраля 2011

Разве это не должно вернуть РИСУ?

def alphabeta(alpha, beta, player)
      best_score = -INFINITY
      if not self.has_available_moves?
        return DRAW
      elsif self.has_this_player_won?(player) == player
        return WIN
      elsif self.has_this_player_won?(1 - player) == 1 - player
        return LOSS
      else
        self.remaining_moves.each do |move|
          if alpha >= beta then return alpha end 

          self.make_move_with_index(move, player)
          move_score = -alphabeta(-beta, -alpha, 1 - player)
          self.undo_move(move)

          if move_score > alpha
            alpha = move_score
            next_move = move
          end
          best_score = alpha
        end
      end
      return best_score
    end

константы:

WIN = 1
LOSS = -1
DRAW = 0
INFINITY = 100

COMPUTER = 0
HUMAN = 1

контрольный пример:

   # computer is 0, human is 1
   # c h c
   # _ h h
   # _ c h -- computer's turn
   test "make sure alpha-beta pruning works (human went first) 1" do
     @board.state = [0,1,0,nil,1,1,nil,0,1]
     score = @board.alphabeta(100, -100, Board::COMPUTER)
     assert_equal(Board::DRAW, score)

   end

соответствующие методы и другие вещи, помогающие прочитать код выше:

self.state = Array.new(9)

    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 make_move_with_index(index, player)
        self.state[index] = player
    end


    def undo_move(index)
        self.state[index] = nil
    end

def has_this_player_won?(player)
      WAYS_TO_WIN.each do |way_to_win|
          return true if self.state.values_at(*way_to_win).uniq.size == 1 and self.state[way_to_win[0]] == player
      end

      return false
    end

    def remaining_moves
        self.state.each_with_index.map{|e,i| (e.nil?) ? i : nil }.compact
    end

    def has_available_moves?
        return self.state.include? nil
    end

1 Ответ

3 голосов
/ 04 февраля 2011

Вы проигнорировали мой комментарий в предыдущем вопросе.has_this_player_won? возвращает логическое значение, которое никогда не может быть равно целому числу player.Кроме того, ваша логика в начале неверна: в игре может быть победитель, даже если больше не осталось ходов.И, наконец, первый вызов рекурсивной функции должен быть сделан с alpha=-inf, beta=+inf.Соответствующие разделы кода:


if self.has_this_player_won?(1 - player)
    return LOSS
elsif not self.has_available_moves?
    return DRAW
else
    ...
score = @board.alphabeta(-INFINITY, INFINITY, Board::COMPUTER)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...