Пример #1
0
    private int CalculateValue(ref AIHardDataStruct curDepthData, bool isEndGame)
    {
        int value = 0;

        if (isEndGame)
        {
            if (CheckWinner(ref curDepthData))
            {
                //玩家赢则权值最低
                value += -10000;
            }
            else
            {
                //AI赢则权值最高
                value += 10000;
            }
        }

        if (curDepthData.depth % 2 == 0)
        {
            return(value + CalculateCurValue(ref curDepthData));
        }
        else
        {
            return(-(value + CalculateCurValue(ref curDepthData)));
        }
    }
Пример #2
0
    private void SelectPiece(ref AIHardDataStruct curDepthData, int x, int y)
    {
        Piece[,] curPieces = curDepthData.pieces;
        List <Piece> curNextPieces = curDepthData.nextPieces;

        curPieces[x, y].isValid = false;
        DeletePiece(ref curDepthData, x, y);
        List <Piece> changedPieces = new List <Piece>();//去掉了注释 若不去掉注释会导致碎裂棋子重复计算

        if (x - 1 >= 0 && curPieces[x - 1, y].isValid)
        {
            curPieces[x - 1, y].isDownHasPiece = false;
            if (!changedPieces.Contains(curPieces[x - 1, y]))
            {
                changedPieces.Add(curPieces[x - 1, y]);
            }
        }
        if (x + 1 < GameManager.Instance.gamePlayMode.boardSideLength && curPieces[x + 1, y].isValid)
        {
            curPieces[x + 1, y].isUpHasPiece = false;
            if (!changedPieces.Contains(curPieces[x + 1, y]))
            {
                changedPieces.Add(curPieces[x + 1, y]);
            }
        }
        if (y - 1 >= 0 && curPieces[x, y - 1].isValid)
        {
            curPieces[x, y - 1].isRightHasPiece = false;
            if (!changedPieces.Contains(curPieces[x, y - 1]))
            {
                changedPieces.Add(curPieces[x, y - 1]);
            }
        }
        if (y + 1 < GameManager.Instance.gamePlayMode.boardSideLength && curPieces[x, y + 1].isValid)
        {
            curPieces[x, y + 1].isLeftHasPiece = false;
            if (!changedPieces.Contains(curPieces[x, y + 1]))
            {
                changedPieces.Add(curPieces[x, y + 1]);
            }
        }
        foreach (var v in changedPieces)
        {
            if (curNextPieces.Contains(v) && !CheckIsCanGoUp(curPieces, x, y))
            {
                curNextPieces.Remove(v);
            }
            else if (CheckIsCanGoUp(curPieces, v.x, v.y))
            {
                if (!curNextPieces.Contains(v))
                {
                    curNextPieces.Add(v);
                }
            }
        }
    }
Пример #3
0
    private int ABPruning(ref AIHardDataStruct curDepthData, int alpha, int beta, bool isEndGame)
    {
        if (curDepthData.depth > ABPruningDepth || isEndGame)
        {
            return(CalculateValue(ref curDepthData, isEndGame));
        }

        Dictionary <PieceColor, List <Piece> > piecesByColor = GroupByColor(curDepthData.nextPieces);
        int bestValue = -0x7FFFFFF;

        foreach (var pieces in piecesByColor)
        {
            List <List <Piece> > combinations = new List <List <Piece> >();
            for (int i = 1; i <= pieces.Value.Count; ++i)
            {
                List <Piece[]> tmp;
                tmp = Algorithms.PermutationAndCombination <Piece> .GetCombination(pieces.Value.ToArray(), i);

                foreach (var v in tmp)
                {
                    List <Piece> combination = new List <Piece>();
                    for (int j = 0; j < v.GetLength(0); ++j)
                    {
                        combination.Add(v[j]);
                    }
                    combinations.Add(combination);
                }
            }
            foreach (var combination in combinations)
            {
                AIHardDataStruct nextDepthData = curDepthData.Clone();
                bool             isNextEndGame = SelectCombination(ref nextDepthData, combination);
                nextDepthData.depth++;
                int nextValue = -ABPruning(ref nextDepthData, -beta, -alpha, isNextEndGame);


                if (nextValue > bestValue)
                {
                    bestValue = nextValue;
                    curDepthData.bestCombination = combination;
                }
                if (bestValue > alpha)
                {
                    alpha = bestValue;
                }
                if (bestValue >= beta)
                {
                    return(bestValue);
                }
            }
        }

        return(bestValue);
    }
Пример #4
0
 private void GetScore(ref AIHardDataStruct curDepthData, PieceColor color)
 {
     if (curDepthData.depth % 2 != 0)
     {
         curDepthData.playerRecord.secord[(int)color]++;
     }
     else
     {
         curDepthData.aiRecord.secord[(int)color]++;
     }
 }
Пример #5
0
        public AIHardDataStruct Clone()
        {
            AIHardDataStruct tar = new AIHardDataStruct();

            tar.pieces       = CopyPieces();
            tar.nextPieces   = CopyCurNextPieces();
            tar.playerRecord = playerRecord.Clone();
            tar.aiRecord     = aiRecord.Clone();
            tar.depth        = depth;

            return(tar);
        }
Пример #6
0
    private void DeletePiece(ref AIHardDataStruct curDepthData, int x, int y)
    {
        Piece[,] curPieces = curDepthData.pieces;
        List <Piece> curNextPieces = curDepthData.nextPieces;

        if (!curNextPieces.Contains(curPieces[x, y]))
        {
            Debug.LogError("Not A Valid Piece");
        }
        GetScore(ref curDepthData, curPieces[x, y].pieceColor);
        curNextPieces.Remove(curPieces[x, y]);
        curPieces[x, y].isValid = false;
    }
Пример #7
0
    //true是玩家赢 false是AI赢
    private bool CheckWinner(ref AIHardDataStruct curDepthData)
    {
        GamePlayMode gpm = GameManager.Instance.gamePlayMode;

        //先判断是否获得一种颜色的全部棋子
        foreach (int s in curDepthData.playerRecord.secord)
        {
            if (s >= gpm.boardSideLength)
            {
                return(true);
            }
        }
        foreach (int s in curDepthData.aiRecord.secord)
        {
            if (s >= gpm.boardSideLength)
            {
                return(false);
            }
        }

        int playerControledNum = 0;

        foreach (var v in curDepthData.playerRecord.secord)
        {
            if (v > gpm.boardSideLength / 2)
            {
                ++playerControledNum;
            }
        }

        int aiControledNum = 0;

        foreach (var v in curDepthData.aiRecord.secord)
        {
            if (v > gpm.boardSideLength / 2)
            {
                ++aiControledNum;
            }
        }

        //再判断谁的分数更高
        if (playerControledNum > aiControledNum)
        {
            return(true);
        }
        else
        {
            return(false);
        }
    }
Пример #8
0
    //返回true则继续往下递归 返回false则停止
    private bool SelectCombination(ref AIHardDataStruct curDepthData, List <Piece> combination)
    {
        //选择棋子
        foreach (var piece in combination)
        {
            SelectPiece(ref curDepthData, piece.x, piece.y);

            if (CheckEndGame(ref curDepthData))
            {
                return(true);
            }
        }
        if (EngTurn(ref curDepthData))
        {
            return(true);
        }
        return(false);
    }
Пример #9
0
    private void MoveInHardLevel()
    {
        Debug.Log("MoveInHardLevel");

        BeginCalculate();

        if (GameManager.Instance.boardManager.GetPieceRemainNum() > 20)
        {
            ABPruningDepth = 4;
        }
        else if (GameManager.Instance.boardManager.GetPieceRemainNum() > 10)
        {
            ABPruningDepth = 5;
        }
        else
        {
            ABPruningDepth = 6;
        }

        Piece[,] curPieces = boardManager.GetPieces();
        List <Piece>     curNextPieces = boardManager.GetNextPieces();
        PlayerRecord     playerRecord  = GameManager.Instance.controller.GetScoreValue();
        PlayerRecord     aiRecord      = GameManager.Instance.controller2.GetScoreValue();
        int              curDepth      = 0;
        int              alpha         = -0x7FFFFFFE;
        int              beta          = 0x7FFFFFFE;
        AIHardDataStruct curDepthData  = new AIHardDataStruct(curPieces, curNextPieces, playerRecord, aiRecord, curDepth);

        Debug.Log("ABPruningDepth: " + ABPruningDepth);
        ABPruning(ref curDepthData, alpha, beta, false);
        Debug.Log("curDepthData.bestCombination count: " + curDepthData.bestCombination.Count);
        List <Piece> abRes = curDepthData.bestCombination;

        foreach (var v in abRes)
        {
            result.Add(new AIResult(v.x, v.y));
        }
        Debug.Log("EndCalculate");

        EndCalculate();
    }
Пример #10
0
    private bool EngTurn(ref AIHardDataStruct curDepthData)
    {
        List <Piece> nextPieces = curDepthData.nextPieces;

        Piece[,] pieces = curDepthData.pieces;
        GamePlayMode gpm = GameManager.Instance.gamePlayMode;

        bool isChanged = true;

        while (isChanged)
        {
            isChanged = false;

            if (gpm.doUseCrack)
            {
                List <Piece> crackPieces = new List <Piece>();
                foreach (var p in nextPieces)
                {
                    if (p.isValid && p.isCrackPiece)
                    {
                        crackPieces.Add(p);
                        isChanged = true;
                    }
                }

                if (isChanged)
                {
                    foreach (var p in crackPieces)
                    {
                        SelectPiece(ref curDepthData, p.x, p.y);
                        if (CheckEndGame(ref curDepthData))
                        {
                            return(true);
                        }
                    }
                }
            }
        }
        return(false);
    }
Пример #11
0
    private int CalculateCurValue(ref AIHardDataStruct curDepthData)
    {
        GamePlayMode gpm         = GameManager.Instance.gamePlayMode;
        int          playerValue = 0;
        int          aiValue     = 0;

        for (int i = 0; i < curDepthData.playerRecord.secord.GetLength(0); ++i)
        {
            var v = curDepthData.playerRecord.secord[i];
            if (curDepthData.aiRecord.secord[i] > gpm.boardSideLength / 2)
            {
                playerValue += v > 0 ? 20 : 0;
            }
            else if (v > gpm.boardSideLength / 2)
            {
                playerValue += 1000;
                if (curDepthData.aiRecord.secord[i] > 0)
                {
                    playerValue += (10 + 4 * 10) * 4 / 2;
                }
                else
                {
                    playerValue += (10 + v * 10) * v / 2;
                }
            }
            else
            {
                playerValue += (10 + v * 10) * v / 2;
            }
        }

        for (int i = 0; i < curDepthData.aiRecord.secord.GetLength(0); ++i)
        {
            var v = curDepthData.aiRecord.secord[i];
            if (curDepthData.playerRecord.secord[i] > gpm.boardSideLength / 2)
            {
                aiValue += v > 0 ? 20 : 0;
            }
            else if (v > gpm.boardSideLength / 2)
            {
                aiValue += 1000;
                if (curDepthData.playerRecord.secord[i] > 0)
                {
                    aiValue += (10 + 4 * 10) * 4 / 2;
                }
                else
                {
                    aiValue += (10 + v * 10) * v / 2;
                }
            }
            else
            {
                aiValue += (10 + v * 10) * v / 2;
            }
        }

        int value = aiValue - playerValue;

        if (curDepthData.depth % 2 == 0)
        {
            return(value);
        }
        else
        {
            return(value);
        }
    }
Пример #12
0
    private bool CheckEndGame(ref AIHardDataStruct curDepthData)
    {
        List <Piece> curNextPieces   = curDepthData.nextPieces;
        PlayerRecord curPlayerRecord = curDepthData.playerRecord;
        PlayerRecord curAiRecord     = curDepthData.aiRecord;
        GamePlayMode gpm             = GameManager.Instance.gamePlayMode;

        if (curNextPieces.Count <= 0)
        {
            return(true);
        }

        foreach (int s in curPlayerRecord.secord)
        {
            if (s >= gpm.boardSideLength)
            {
                return(true);
            }
        }

        foreach (int s in curAiRecord.secord)
        {
            if (s >= gpm.boardSideLength)
            {
                return(true);
            }
        }

        int controllNum = 0;
        int takeNum     = 0;

        foreach (int s in curAiRecord.secord)
        {
            if (s > 0)
            {
                takeNum++;
            }
            if (s > gpm.boardSideLength / 2)
            {
                controllNum++;
            }
        }
        if (controllNum > gpm.boardSideLength / 2 && takeNum >= gpm.boardSideLength)
        {
            return(true);
        }

        controllNum = 0;
        takeNum     = 0;
        foreach (int s in curPlayerRecord.secord)
        {
            if (s > 0)
            {
                takeNum++;
            }
            if (s > gpm.boardSideLength / 2)
            {
                controllNum++;
            }
        }
        if (controllNum > gpm.boardSideLength / 2 && takeNum >= gpm.boardSideLength)
        {
            return(true);
        }

        return(false);
    }