コード例 #1
0
ファイル: Board.cs プロジェクト: miskosz/BacteriaBattle
    public IntPair GetAIMove()
    {
        // strategy 1: try all moves and choose the one with best AIscore

        List <IntPair> possibleMoves = GetPossibleMoves();

        // self-explanatory
        if (possibleMoves.Count == 0)
        {
            throw new Exception("No moves for AI.");
        }
        else if (possibleMoves.Count == 1)
        {
            return(possibleMoves[0]);
        }

        List <AIMinimax> scoredMoves = new List <AIMinimax>();

        // The score of the simulated move is calculated for the opponent.
        // Therefore we want to minimize it.
        // Randomize equal scores a bit.
        foreach (IntPair move in possibleMoves)
        {
            Board sim = SimulateMove(move.i, move.j);
            scoredMoves.Add(new AIMinimax {
                pos = move, score = sim.AIScore(), rand = UnityEngine.Random.Range(0, 100)
            });
        }

        // sort moves
        scoredMoves.Sort((x, y) => (10000 * x.score + x.rand).CompareTo(10000 * y.score + y.rand));

        // normalize
        // this is just plain heuristics

        // keep cBest best options
        // the worst option gets score 1, better gets more
        // just weigh best cBest options w.r.t. normalized weighths
        int baseScore = scoredMoves[scoredMoves.Count - 1].score + 1;
        int cBest     = Math.Min(3, scoredMoves.Count);

        scoredMoves = scoredMoves.GetRange(0, cBest);
        int randPool = 0;

        foreach (AIMinimax move in scoredMoves)
        {
            move.score = baseScore - move.score;
            move.score = move.score * move.score;           // square
            randPool  += move.score;
        }

        int rand = UnityEngine.Random.Range(0, randPool);
        int m    = 0;

        while (scoredMoves[m].score < rand)
        {
            rand -= scoredMoves[m].score;
            m++;
        }

        // TODO
        string dbg = "";

        foreach (AIMinimax move in scoredMoves)
        {
            dbg += " " + move.score;
        }
        Debug.Log("Normalized AIScores: " + dbg + "    Chosen: " + scoredMoves[m].score);

        return(scoredMoves[m].pos);

//		int r = UnityEngine.Random.Range(0, possibleMoves.Count);
//		return new IntPair(possibleMoves[r].i, possibleMoves[r].j);
    }