2

所以这就是问题所在。我正在为基于 AI 的游戏开发战斗模拟器。当敌人对每一个动作都做出最佳动作时,人工智能应该为他计算出最佳动作。

我的团队有 X 个单位,有 5 个可能的移动,我的对手有 Y 个单位,有 5 个可能的移动。X 和 Y > 0 使用 alpha-beta 剪枝,我们希望生成每个可能的结果并最终取出最好的结果。问题是我们将每个结果保存到一个情境中,这种情境存储列表,但列表包含对所存储对象的引用,这使得它们将它们的移动保存到相同的情境中(1 个单元的所有 5 个移动)

想象一下我们的 2 个单位和他们的一个单位。我们创建一个情境并添加一个具有 5 个方向中的 1 个的单元。然后为我们的第二个单位添加一个方向,然后为敌方单位添加一个方向。现在我们得到了我们想要保存的最终情况。然后根据我们第二个单位的情况(所以没有敌方单位),我们想为敌人添加一个不同的动作到情况中,如果它更好的话,保存新的情况。但是由于 C# 使用列表的引用,这种情况也包括其他敌人移动的情况。

代码有点大,但我真的被困在这里,所以我希望如果有人有空闲时间来帮助我解决这个问题。

    public Situation RecursiveMaxTree(List<SimAnt> undone, int index, bool[,] positions, Situation situation)
    {
        SimAnt front = undone[index];
        int max = situation.Max;
        List<SimAnt> bestmoves = new List<SimAnt>();

        int frontY = front.position.Y;
        int frontX = front.position.X;

        if (!front.isEnemy() && undone[index + 1].isEnemy())//cutoff activated----------------------------------------------------------------------------
        {
            foreach (Direction direction in directions)
            {
                int newX = GameState.WrapHorizonal(frontX + direction.toVector().X);
                int newY = GameState.WrapVertical(frontY + direction.toVector().Y);
                if (!positions[newX, newY] && map.isNotWater(newX, newY))
                {
                    //add the updated ant to the new allAnts list
                    positions[newX, newY] = true;
                    List<SimAnt> newallAnts = situation.GetList;
                    Friend newant = new Friend(newX, newY);
                    newant.direction = direction;
                    newallAnts.Add(newant);

                    Situation current = RecursiveMinTree(undone, index + 1, positions, new Situation(newallAnts, max));//geeft min van alle enemy options
                    positions[newX, newY] = false;
                    if (current.Max > max)
                    {
                        max = current.Max;
                        bestmoves = current.GetList;
                    }
                }
            }
        }
        else //max-------------------------------------------------------------------------------------------------------------------------------------
        {
            foreach (Direction direction in directions)
            {
                int newX = GameState.WrapHorizonal(frontX + direction.toVector().X);
                int newY = GameState.WrapVertical(frontY + direction.toVector().Y);
                if (!positions[newX, newY] && map.isNotWater(newX, newY))
                {
                    //add the updated ant to the new allAnts list
                    positions[newX, newY] = true;
                    List<SimAnt> newallAnts = situation.GetList.Clone();
                    Friend newant = new Friend(newX, newY);
                    newant.direction = direction;
                    newallAnts.Add(newant);

                    Situation current = RecursiveMaxTree(undone, index + 1, positions, new Situation(newallAnts, max));//geeft min van alle enemy options
                    positions[newX, newY] = false;
                    if (current.Max > max)
                    {
                        max = current.Max;
                        bestmoves = current.GetList;
                    }
                }
            }
        }
        return new Situation(bestmoves, max);
    }

    Situation RecursiveMinTree(List<SimAnt> undone, int index, bool[,] positions, Situation situation)
    {
        SimAnt front = undone[index];
        int max = situation.Max;

        int frontY = front.position.Y;
        int frontX = front.position.X;

        int currentmin = 100;

        foreach (Direction direction in directions)
        {
            int newX = GameState.WrapHorizonal(frontX + direction.toVector().X);
            int newY = GameState.WrapVertical(frontY + direction.toVector().Y);
            if (!positions[newX, newY] && map.isNotWater(newX, newY))
            {
                //add the updated ant to the new allAnts list                    
                List<SimAnt> newallAnts = situation.GetList;
                Foe newant = new Foe(newX, newY);
                newallAnts.Add(newant);
                if (index >= undone.Count - 1)
                {
                    return new Situation(situation.GetList, CalculateBattleValue(situation.GetList));
                }
                else
                {
                    positions[newX, newY] = true;
                    Situation current = RecursiveMinTree(undone, index + 1, positions, new Situation(newallAnts, max));//geeft min van alle enemy options
                    positions[newX, newY] = false;
                    if (current.Max < max)
                        return current;
                    else if (current.Max < currentmin)
                    {
                        currentmin = current.Max;
                    }
                }
            }
        }
        return new Situation(situation.GetList, currentmin);
    }

class Situation
{
    public Situation(List<SimAnt> ants, int max)
    {
        this.max = max;
        this.ants = ants;
    }
    List<SimAnt> ants;
    int max;

    public List<SimAnt> GetList
    { get { return ants; } }

    public int Max
    { get { return max; } }
}

亲切的问候,我

4

0 回答 0