Пример #1
0
        public void Reset()
        {
            Board = new bool[BoardSize, BoardSize];
            int numOfBlocks = Rand.Next((int)(BoardSize * BoardSize * LowerBoundBlockingRate), (int)(BoardSize * BoardSize * UpperBoundBlockingRate));

            for (int i = 0; i < numOfBlocks; i++)
            {
                int row    = Rand.Next(0, BoardSize);
                int column = Rand.Next(0, BoardSize);
                int j      = 0;
                for (; j < NumOfCats; j++)
                {
                    bool isCatPosition = (row == BoardSize / 2) && (column == BoardSize / 2 - NumOfCats / 2 + j);
                    if (isCatPosition)
                    {
                        break;
                    }
                }
                if (j != NumOfCats)
                {
                    continue;
                }
                Board[row, column] = true;
            }
            Cats = new Octocat[NumOfCats];
            for (int i = 0; i < NumOfCats; i++)
            {
                Cats[i] = new Octocat()
                {
                    ColumnIndex    = BoardSize / 2 - NumOfCats / 2 + i,
                    RowIndex       = BoardSize / 2,
                    EscapeAtRow    = -1,
                    EscapeAtColumn = -1,
                    EscapePath     = new HashSet <Tuple <int, int> >()
                };
            }
            Steps = 0;
        }
Пример #2
0
 private Brush GetCatBrush(Octocat cat)
 {
     return(new SolidColorBrush(cat.IsEnclosed ? Colors.Purple : Colors.Orange));
 }
Пример #3
0
 private void ProcessAdjacentNode(int row, int column, Queue <Tuple <int, int> > queue, int newDistance, Tuple <int, int> pos, Octocat cat, List <Tuple <int, int> > nextPos)
 {
     if (row >= 0 &&
         column >= 0 &&
         row < BoardSize &&
         column < BoardSize &&
         !Board[row, column] &&
         !visited[row, column] &&
         Cats.Count(cc => cc.RowIndex == row && cc.ColumnIndex == column) == 0)
     {
         var p = new Tuple <int, int>(row, column);
         queue.Enqueue(p);
         visited[row, column]  = true;
         distance[row, column] = newDistance;
         prev[row, column]     = pos;
         if (pos.Item1 == cat.RowIndex && pos.Item2 == cat.ColumnIndex)
         {
             nextPos.Add(p);
         }
     }
 }
Пример #4
0
        private int FindMinimalEscapeDistance(Octocat cat)
        {
            int row    = cat.RowIndex;
            int column = cat.ColumnIndex;

            if (IsEscaped(row, column))
            {
                return(1);
            }
            var queue = new Queue <Tuple <int, int> >();

            queue.Enqueue(new Tuple <int, int>(row, column));
            visited  = new bool[BoardSize, BoardSize];
            distance = new int[BoardSize, BoardSize];
            for (int i = 0; i < BoardSize; i++)
            {
                for (int j = 0; j < BoardSize; j++)
                {
                    distance[i, j] = int.MaxValue;
                }
            }
            prev = new Tuple <int, int> [BoardSize, BoardSize];
            distance[row, column] = 0;
            prev[row, column]     = null;
            visited[row, column]  = true;
            int ret = int.MaxValue;

            cat.EscapeAtRow    = -1;
            cat.EscapeAtColumn = -1;
            var nextPos = new List <Tuple <int, int> >();

            while (queue.Count() != 0)
            {
                var pos = queue.Dequeue();
                row    = pos.Item1;
                column = pos.Item2;
                if (IsEscaped(row, column) && ret > distance[row, column])
                {
                    ret                = distance[row, column];
                    cat.EscapeAtRow    = row;
                    cat.EscapeAtColumn = column;
                }
                int  newDistance = distance[row, column] + 1;
                bool isOdd       = (row & 1) == 1;
                int  c2          = column + (isOdd ? 1 : -1);
                ProcessAdjacentNode(row - 1, column, queue, newDistance, pos, cat, nextPos);
                ProcessAdjacentNode(row - 1, c2, queue, newDistance, pos, cat, nextPos);
                ProcessAdjacentNode(row, column + 1, queue, newDistance, pos, cat, nextPos);
                ProcessAdjacentNode(row + 1, column, queue, newDistance, pos, cat, nextPos);
                ProcessAdjacentNode(row + 1, c2, queue, newDistance, pos, cat, nextPos);
                ProcessAdjacentNode(row, column - 1, queue, newDistance, pos, cat, nextPos);
            }
            if (ret == int.MaxValue)
            {
                cat.EscapePath.Clear();
                if (nextPos.Count != 0)
                {
                    int idx = Rand.Next(0, nextPos.Count - 1);
                    cat.RowIndex    = nextPos[idx].Item1;
                    cat.ColumnIndex = nextPos[idx].Item2;
                }
                else
                {
                    return(-1);
                }
            }
            else
            {
                cat.EscapePath.Clear();
                int u    = cat.EscapeAtRow;
                int v    = cat.EscapeAtColumn;
                var next = new Tuple <int, int>(u, v);
                cat.EscapePath.Add(next);
                var back = prev[u, v];
                back = prev[back.Item1, back.Item2];
                while (back != null)
                {
                    back = prev[back.Item1, back.Item2];
                    next = prev[next.Item1, next.Item2];
                    cat.EscapePath.Add(next);
                }
                cat.RowIndex    = next.Item1;
                cat.ColumnIndex = next.Item2;
            }
            return(ret);
        }