示例#1
0
    /// <summary>
    /// If there is a signInARow that has the same steepness then it will remove that first then add this
    /// </summary>
    public void AddSignInARow(SignInARow inARow, out SignInARow removed)
    {
        removed = null;
        // We remove the one with the same steepness because they overlap and so the longer one should be added (which we think is the new InARow)
        for (int i = signsInARow.Count - 1; i >= 0; i--)
        {
            // We have a signinarow which has the same steepness so
            if (signsInARow[i].Steepness == inARow.Steepness)
            {
                removed = signsInARow[i];
                signsInARow.RemoveAt(i);
                break;
            }
        }

        signsInARow.Add(inARow);
    }
示例#2
0
    public int[] StartEvaluation()
    {
        // ________________________________________ FIRST POINT __________________________________________________
        // There is only one placed in the game so just randomize it because otherwise it only places where we examine first
        if (pointsInGame.Count < 2)
        {
            System.Random rand = new System.Random();
            IntVector2    random;
            do
            {
                random = new IntVector2(rand.Next(0, 3) - 1, rand.Next(0, 3) - 1);
            } while (random.x == 0 && random.y == 0);

            return(LocalAIToGridPos(pointsInGame[0] + random));
        }

        // _____________________________________ DEFENSE EVAL __________________________________________
        // It' only a defending mechanism so only checks for human pointsinrow
        // try places where we surely have to place
        // it has a smaller chance that it skips that position
        SignInARow humThree = null, humFour = null;
        SignInARow aiThree = null, aiFour = null;

        int   tillI             = pointsInGame.Count;
        float exponentialChance = Mathf.Pow(leaveOutChance, 1.55f);

        for (int i = 0; i < tillI; i++)
        {
            List <SignInARow> list = gameField[pointsInGame[i].x, pointsInGame[i].y].signsInARow;
            for (int k = 0; k < list.Count; k++)
            {
                // skip at random
                if (rand.NextDouble() < exponentialChance)
                {
                    continue;
                }


                int length     = list[k].Length;
                int blockCount = list[k].BlockCount();

                if (length == 3 && blockCount == 0)
                {
                    // Store it so if after this loop we don't find a four (we don't return) place there
                    if (list[k].Type == HumanType)
                    {
                        humThree = list[k];
                    }
                    else
                    {
                        aiThree = list[k];
                    }
                }
                else if (length == 4 && blockCount != 2)
                {
                    // It prioritizes the fours so if it finds one place there
                    if (list[k].Type == HumanType)
                    {
                        humFour = list[k];
                    }
                    else     // There is a 4 length that is AIType so place there
                    {
                        aiFour = list[k];
                    }
                }
            }
        }

        // First if there is a four type ai where we can place win the game
        if (aiFour != null)
        {
            return(LocalAIToGridPos(aiFour.GetUnblockedPos()));
        }
        // If there is a four that is type of human we should really place there
        if (humFour != null)
        {
            return(LocalAIToGridPos(humFour.GetUnblockedPos()));
        }

        // If there is a signinarow with aitype that is length of three decide which is better and return that
        if (aiThree != null)
        {
            return(LocalAIToGridPos(WhichIsBetter(aiThree.GetBlockField1Pos(), aiThree.GetBlockField2Pos(), AIType)));
        }

        // If there is no three with AI type but there is one for the human decide which is better
        if (humThree != null)   // We are going to decide which position is better
        {
            return(LocalAIToGridPos(WhichIsBetter(humThree.GetBlockField1Pos(), humThree.GetBlockField2Pos(), AIType)));
        }

        // Come here is everything else fails
        // ___________________ NORMAL EVAL _____________________________-
        EvaluationResult result = new EvaluationResult();

        try {
            result = EvaluateField(gameField, AIType, 1, pointsInGame, int.MinValue, int.MaxValue);
        } catch (Exception e) {
            UnityEngine.Debug.Log(e.Message + "\n" + e.StackTrace);
        }
        return(LocalAIToGridPos(result.fieldPos));
    }
示例#3
0
 public PlaceData(IntVector2 pos, SignInARow signInARow)
 {
     this.fieldPos   = pos;
     this.signInARow = signInARow;
 }
示例#4
0
    /// <summary>
    /// Adds the new signsInARow and removes the ones which overlap
    /// </summary>
    private void NewSignPlaced(EvaluationField[,] field, IntVector2 where, out List <PlaceData> placed, out List <PlaceData> removed)
    {
        Cell.CellOcc     currentType = field[where.x, where.y].type;
        List <PlaceData> _placed     = new List <PlaceData>();
        List <PlaceData> _removed    = new List <PlaceData>();

        // Check how many signs there are in a row that contains the where sign
        for (int i = 0; i < checkDirections.GetLength(0); i++)
        {
            int        count = 1;
            IntVector2 endOne = new IntVector2(where), endTwo = new IntVector2(where);

            // Go through the checkdirection direction
            for (int j = 1; j < Grid.WIN_CONDITION; j++)
            {
                int examineX = where.x + checkDirections[i, 0] * j;
                int examineY = where.y + checkDirections[i, 1] * j;

                // We are in bounds
                //if (examineX >= 0 && examineX < field.GetLength(0) && examineY >= 0 && examineY < field.GetLength(1)) {
                // It is the same sign
                if (field[examineX, examineY].type == currentType)
                {
                    count++;
                    endOne = new IntVector2(examineX, examineY);
                }
                else
                {
                    break;
                }
            }

            // Go through the opposite of checkdirection direction
            for (int j = 1; j < Grid.WIN_CONDITION; j++)
            {
                int examineX = where.x + -checkDirections[i, 0] * j;
                int examineY = where.y + -checkDirections[i, 1] * j;

                // We are in bounds
                //if (examineX >= 0 && examineX < field.GetLength(0) && examineY >= 0 && examineY < field.GetLength(1)) {
                // It is the same sign
                if (field[examineX, examineY].type == currentType)
                {
                    count++;
                    endTwo = new IntVector2(examineX, examineY);
                }
                else
                {
                    break;
                }
            }

            if (count < 2)
            {
                continue;
            }
            // Now we have the endpoints of this checkdirection in endpoint one and endpoint two
            // We also have if there are blocks at the end if there is not then the block variables are null
            SignInARow signsInARow = new SignInARow(endOne, endTwo, currentType);
            IntVector2 end1 = signsInARow.From - signsInARow.Steepness, end2 = signsInARow.To + signsInARow.Steepness;
            signsInARow.SetEndEvaluationFields(field[end1.x, end1.y], field[end2.x, end2.y]);

            SignInARow removedSignInARow = null;
            field[where.x, where.y].AddSignInARow(signsInARow, out removedSignInARow);

            _placed.Add(new PlaceData(new IntVector2(where), signsInARow));
            if (removedSignInARow != null)
            {
                _removed.Add(new PlaceData(new IntVector2(where), removedSignInARow));
            }
        }

        placed = _placed; removed = _removed;
    }