예제 #1
0
파일: SjmGame.cs 프로젝트: LiyeXu/SJM
 public SjmGame(Action onCatMove)
 {
     BoardData = new bool[BoardSize, BoardSize];
     int blocks = rand.Next(BoardSize * BoardSize / 5, BoardSize * BoardSize / 4);
     for (int i = 0; i < blocks; i++)
     {
         int r = rand.Next(0, BoardSize);
         int c = rand.Next(0, BoardSize);
         bool skip = false;
         for (int j = 0; j < CatsCount; j++)
         {
             if (r == BoardSize / 2 && c == BoardSize / 2 - CatsCount / 2 + j)
                 skip = true;
         }
         if (skip)
             continue;
         if (!BoardData[r, c])
             BoardData[r, c] = true;
     }
     Cats = new Cat[CatsCount];
     for (int i = 0; i < CatsCount; i++)
     {
         Cats[i] = new Cat()
         {
             ColumnIndex = BoardSize / 2 - CatsCount / 2 + i,
             RowIndex = BoardSize / 2 ,
             EscapeAtRow = -1,
             EscapeAtColumn = -1,
             EscapePath = new HashSet<Tuple<int,int>>()
         };
     }
     Steps = 0;
     OnCatMove = onCatMove;
 }
예제 #2
0
파일: SjmGame.cs 프로젝트: LiyeXu/SJM
 private void ProcessAdjNode(int r, int c, Queue<Tuple<int, int>> queue, int newDistance, Tuple<int, int> pos, Cat cat, List<Tuple<int, int>> nextPos)
 {
     if (r >= 0 && c >= 0 && r < BoardSize && c < BoardSize &&
         !BoardData[r, c] && !visited[r, c] &&
         Cats.Count(cc => cc.RowIndex == r && cc.ColumnIndex == c) == 0)
     {
         var p = new Tuple<int, int>(r, c);
         queue.Enqueue(p);
         visited[r, c] = true;
         distance[r, c] = newDistance;
         prev[r, c] = pos;
         if (pos.Item1 == cat.RowIndex && pos.Item2 == cat.ColumnIndex)
             nextPos.Add(p);
     }
 }
예제 #3
0
파일: SjmGame.cs 프로젝트: LiyeXu/SJM
 private int FindMinimalEscapeDistance(Cat cat)
 {
     int r = cat.RowIndex;
     int c = cat.ColumnIndex;
     if (Escaped(r, c))
         return 1;
     var queue = new Queue<Tuple<int, int>>();
     queue.Enqueue(new Tuple<int, int>(r, c));
     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[r, c] = 0;
     prev[r, c] = null;
     visited[r, c] = 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();
         r = pos.Item1;
         c = pos.Item2;
         if (Escaped(r, c) && ret > distance[r, c])
         {
             ret = distance[r, c];
             cat.EscapeAtRow = r;
             cat.EscapeAtColumn = c;
         }
         int newDistance = distance[r, c] + 1;
         bool isOdd = (r & 1) == 1;
         int c2 = c + (isOdd ? 1 : -1);
         ProcessAdjNode(r - 1, c, queue, newDistance, pos, cat, nextPos);
         ProcessAdjNode(r - 1, c2, queue, newDistance, pos, cat, nextPos);
         ProcessAdjNode(r, c + 1, queue, newDistance, pos, cat, nextPos);
         ProcessAdjNode(r + 1, c, queue, newDistance, pos, cat, nextPos);
         ProcessAdjNode(r + 1, c2, queue, newDistance, pos, cat, nextPos);
         ProcessAdjNode(r, c - 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;
 }