예제 #1
0
 public Area(IndexOfList2D _pos, ConnectedAreas _father)
 {
     Debug.Assert(_father != null);
     pos        = _pos;
     neighbours = new List <Area>(8);
     father     = _father;
 }
예제 #2
0
    public void SearchInit(ConnectedAreas _ca)
    {
        ca            = _ca;
        numberCount   = ca.numbers.Count;
        searchNumbers = new Area[numberCount];
        ca.numbers.CopyTo(searchNumbers);

        areaIndexTable = new Dictionary <Area, int>();
        for (int i = 0; i < numberCount; i++)
        {
            areaIndexTable[searchNumbers[i]] = i;
        }

        pointForEachNumber = new int[numberCount];
        for (int i = 0; i < numberCount; i++)
        {
            pointForEachNumber[i] = Singleton.MainData.mineDatas[searchNumbers[i].pos];
        }

        stackForEachNumber = new List <int> [numberCount];
        for (int i = 0; i < numberCount; i++)
        {
            stackForEachNumber[i] = new List <int>();
        }

        numberIndex    = 0;
        neighbourIndex = 0;

        searchResults = new Dictionary <int, List <List <IndexOfList2D> > >();
        stepResult    = SearchingStepResult.ORIGIN;

        isDead = false;
    }
예제 #3
0
    public Area CreateOutside(IndexOfList2D pos, ConnectedAreas father)
    {
        Area area = new Area(pos, father);

        map[pos] = area;
        father.outsides.Add(area);
        return(area);
    }
예제 #4
0
    public Area CreateNumber(IndexOfList2D pos, ConnectedAreas father)
    {
        Area area = new Area(pos, father);

        map[pos] = area;
        father.numbers.Add(area);
        return(area);
    }
예제 #5
0
 public void Remove(ConnectedAreas ca)
 {
     list.Remove(ca);
     if (removeCaAction != null)
     {
         removeCaAction(ca);
     }
 }
예제 #6
0
 public void SetOutsideResult(ConnectedAreas ca, List<IndexOfList2D> target) {
     List2DInt map = Singleton.CreateNewList2DInt();
     foreach(var pos in target) {
         map[pos] = -1;
     }
     foreach(var area in ca.outsides) {
         result.Add(new SetMap(area.pos,map[area.pos]));
     }
 }
예제 #7
0
 public int CountingMines(ConnectedAreas ca) {
     int count = 0;
     foreach(var area in ca.outsides) {
         if(mineData[area.pos] == -1) {
             count++;
         }
     }
     return count;
 }
예제 #8
0
    public ConnectedAreas CreateCa()
    {
        ConnectedAreas ca = new ConnectedAreas(this);

        list.Add(ca);
        if (addCaAction != null)
        {
            addCaAction(ca);
        }
        return(ca);
    }
예제 #9
0
 public ConnectedAreas MergeCas(ConnectedAreas main, params ConnectedAreas[] args)
 {
     foreach (ConnectedAreas ca in args)
     {
         if (main != ca)
         {
             main.Merge(ca);
             Remove(ca);
         }
     }
     return(main);
 }
예제 #10
0
    public void Calculate() {
        clickArea = tableBase.map.GetArea(clickPos);
        result = new List<SetMap>();
        if(mineData[clickPos] != -1) {
            return;
        }
        int allMinesCount = Singleton.MainData.mineCount;
        if(clickArea != null) {
            ConnectedAreas mainCa = clickArea.father;
            var table = GetMinDifferenceResults(mainCa);
            FindInsideTarget(-1);
            var solution = FindFinalSolution(table, insideCount, allMinesCount, insideTargets.Count);
            if(solution == null) {
                return;
            }
            int nextOutSideMineCount = 0;
            foreach(var ca in solution.Keys) {
                nextOutSideMineCount += solution[ca].Count;
                SetOutsideResult(ca, solution[ca]);
            }
            int nextInsideMineCount = allMinesCount - nextOutSideMineCount;
            int deltaInsideMineCount = nextInsideMineCount - insideTargets.Count;
            if(deltaInsideMineCount > 0) {
                FindInsideTarget(0);
                ReverseRandomInsideTarget(deltaInsideMineCount);
            }else{
                ReverseRandomInsideTarget(-deltaInsideMineCount);
            }
        }else{
            FindInsideTarget(-1);
            if(insideCount != insideTargets.Count) {
                result.Add(new SetMap(clickPos, 0));
                FindInsideTarget(0);
                ReverseRandomInsideTarget(1, null);
            }else{
                var table = GetMinDifferenceResults(null);
                var solution = FindFinalSolution(table, insideCount - 1, allMinesCount, insideCount);
                if(solution == null) {
                    return;
                }
                int nextOutSideMineCount = 0;
                foreach(var ca in solution.Keys) {
                    nextOutSideMineCount += solution[ca].Count;
                    SetOutsideResult(ca, solution[ca]);
                }
                result.Add(new SetMap(clickPos, 0));
                int deltaInsideMineCount = insideCount - allMinesCount + nextOutSideMineCount - 1;
                ReverseRandomInsideTarget(deltaInsideMineCount, clickPos);
            }

        }
    }
예제 #11
0
 public int CalculateDifference(ConnectedAreas ca, List<IndexOfList2D> mines) {
     int result = 0;
     List2DInt map = Singleton.CreateNewList2DInt();
     foreach(var pos in mines) {
         map[pos] = -1;
     }
     foreach(var area in ca.outsides) {
         if((map[area.pos] == -1 && mineData[area.pos] != -1 ) || (map[area.pos] != -1 && mineData[area.pos] == -1)) {
             result++;
         }
     }
     return result;
 }
예제 #12
0
 public void Merge(ConnectedAreas other)
 {
     foreach (var number in other.numbers)
     {
         numbers.Add(number);
         number.father = this;
     }
     foreach (var outside in other.outsides)
     {
         outsides.Add(outside);
         outside.father = this;
     }
 }
예제 #13
0
 public void Flip(List <FlipNode> flipNodes)
 {
     foreach (var node in flipNodes)
     {
         var area = tableBase.map.GetArea(node.pos);
         if (area != null)
         {
             area.father.RemoveOutsides(area);
         }
         ConnectedAreas ca = tableBase.cas.CreateCa();
         area = tableBase.map.CreateNumber(node.pos, ca);
         gamePart.flipBoard.ChangeAround(node.x, node.y,
                                         (int aroundX, int aroundY, int get) => {
             IndexOfList2D pos = new IndexOfList2D(aroundX, aroundY);
             Area neighbour    = tableBase.map.GetArea(pos);
             if (get == 0)
             {
                 if (neighbour == null)
                 {
                     neighbour = tableBase.map.CreateOutside(pos, ca);
                 }
                 else
                 {
                     tableBase.cas.MergeCas(neighbour.father, ca);
                     ca = neighbour.father;
                 }
                 neighbour.neighbours.Add(area);
                 area.neighbours.Add(neighbour);
             }
             return(get);
         }
                                         );
         if (area.neighbours.Count == 0)
         {
             tableBase.map.RemovePos(area.pos);
             tableBase.cas.Remove(ca);
         }
     }
     problemsAndResults = new Dictionary <ConnectedAreas, SearchForCa>();
     foreach (var ca in tableBase.cas.list)
     {
         problemsAndResults[ca] = new SearchForCa(ca);
         problemsAndResults[ca].Process();
     }
     visualizedData();
     if (afterPrecacAction != null)
     {
         afterPrecacAction();
     }
 }
예제 #14
0
 public Dictionary<ConnectedAreas, Dictionary<int, MinesWithDifference>> GetMinDifferenceResults(ConnectedAreas mainCa) {
     var table = new Dictionary<ConnectedAreas, Dictionary<int, MinesWithDifference>>();
     foreach(var ca in sfcas.Keys) {
         table[ca] = new Dictionary<int, MinesWithDifference>();
         foreach(var keyAndValue in sfcas[ca].searchResults) {
             int mineCount = keyAndValue.Key;
             List<IndexOfList2D> minDifference = null;
             int minDifferenceValue = 0;
             foreach(var mines in keyAndValue.Value) {
                 if(ca != mainCa || !CheckContainClickPos(mines)) {
                     int difference = CalculateDifference(ca, mines);
                     if(minDifference == null || difference < minDifferenceValue) {
                         minDifference = mines;
                         minDifferenceValue = difference;
                     }
                 }
             }
             if(minDifference != null) {
                 table[ca][mineCount] = new MinesWithDifference(minDifferenceValue, minDifference);
             }
         }
     }
     return table;
 }
예제 #15
0
 public SearchForCa(ConnectedAreas _ca)
 {
     SearchInit(_ca);
 }
예제 #16
0
 public ConnectedAreas(ConnectedAreas other)
 {
     numbers = new HashSet <Area>(other.numbers);
 }