Я пытаюсь играть тик tac палец ноги с помощью повторяющегося сокращения Альфы - беты, у меня есть один второй предел для перемещения, но по некоторым причинам это не работает хорошо.
Я изменил обычный код альфы - беты так вместо того, чтобы возвратить альфу или бету, это возвращает состояние (который является платой со следующим перемещением),
Каждый раз, когда я создаю детей, я обновляю их глубину.
Но снова по некоторым причинам я продолжаю проигрывать, и я вижу, что моя альфа-бета не видит лучшее перемещение для создания.
Вот мой код:
Внешний цикл:
while (watch.get_ElapsedMilliseconds() < 900 && d <= board.length * board[0].length - 1)
{
s = maxiMin(beginSt, d, watch);
if (s.getNextMove().getIsWin() == true)
{
break;
}
d++;
}
return new location(s.getNextMove().getRow(), s.getNextMove().getCol());
Альфа-бета:
public State maxiMin(State s, int depth, Stopwatch timer)
{
if (s.getDepth() == 7)
{
Console.WriteLine();
}
if (timer.get_ElapsedMilliseconds() > 850 || s.getDepth() == depth || goalTest(s.getBoard()) != 0)
{
s.evaluationFunc(line_length, PlayerShape);
s.setAlpha(s.getEvaluation());
s.setBeta(s.getEvaluation());
return s;
}
LinkedList<State> children = createChildren(s, true);
// No winner, the board is full
if (children.get_Count() == 0)
{
s.evaluationFunc(line_length, PlayerShape);
s.setAlpha(s.getEvaluation());
s.setBeta(s.getEvaluation());
return s;
}
while (children.get_Count() > 0)
{
State firstChild = children.get_First().get_Value();
children.RemoveFirst();
State tmp = miniMax(firstChild, depth, timer);
int value = tmp.getBeta();
if (value > s.getAlpha())
{
s.setAlpha(value);
s.setNextMove(tmp);
}
if (s.getAlpha() >= s.getBeta())
{
return s;
}
}
return s;
}
public State miniMax(State s, int depth, Stopwatch timer)
{
if (s.getDepth() == 7)
{
Console.WriteLine();
}
if (timer.get_ElapsedMilliseconds() > 850 || s.getDepth() == depth || goalTest(s.getBoard()) != 0)
{
s.evaluationFunc(line_length, PlayerShape);
s.setAlpha(s.getEvaluation());
s.setBeta(s.getEvaluation());
return s;
}
LinkedList<State> children = createChildren(s, false);
// No winner, the board is full
if (children.get_Count() == 0)
{
s.evaluationFunc(line_length, PlayerShape);
s.setAlpha(s.getEvaluation());
s.setBeta(s.getEvaluation());
return s;
}
while (children.get_Count() > 0)
{
State firstChild = children.get_First().get_Value();
children.RemoveFirst();
State tmp = maxiMin(firstChild, depth, timer);
int value = tmp.getAlpha();
if (value < s.getBeta())
{
s.setBeta(value);
s.setNextMove(tmp);
}
if (s.getAlpha() >= s.getBeta())
{
return s;
}
}
return s;
}
Ценил бы много, если кто-либо может сказать мне, если что-то неправильно. Я подозреваю, возможно, что это что-то делает с этим, я возвращаю "s" вместо регулярной альфа-беты, которая возвращает оценку, но мне не удалось найти ошибку.
Заранее спасибо,
Lena
Во-первых, крестики-нолики - очень простая игра, и я считаю, что это разрешимо с помощью гораздо более простого кода, в основном потому, что мы знаем, что всегда есть опция привязки, а общее количество состояний меньше 3 ^ 9 (включая симметричные и многие невозможные состояния).
Что касается вашего кода, я считаю, что одна из ваших проблем заключается в том, что вы не увеличиваете глубину рекурсивных вызовов.
у вас также есть много проблем с плохим стилем в вашем коде, вы разделили miniMax и MaxiMin на две функции, хотя в основном они одинаковы. вы перебираете коллекцию, удаляя из нее элементы, в отличие от использования for-each или итератора (или даже итератора int).