public List <nurikabePoint> getSosedeOdOtoka(nurikabePoint n, Island isl) { var ret = new List <nurikabePoint>(); var pt1 = isl.Points.Find(a => (a.x == n.x - 1 && a.y == n.y)); var pt2 = isl.Points.Find(a => (a.x == n.x + 1 && a.y == n.y)); var pt3 = isl.Points.Find(a => (a.x == n.x && a.y == n.y + 1)); var pt4 = isl.Points.Find(a => (a.x == n.x && a.y == n.y - 1)); if (pt1 != null) { ret.Add(pt1); } if (pt2 != null) { ret.Add(pt2); } if (pt3 != null) { ret.Add(pt3); } if (pt4 != null) { ret.Add(pt4); } return(ret); }
nurikabePoint[][] krizaj(nurikabePoint[] a, nurikabePoint[] b) { var froca = new nurikabePoint[2][]; Random ran = new Random(69); int x1 = ran.Next(arr.dim[0] - 2); int x2 = ran.Next(arr.dim[0] - x1) + x1; int y1 = ran.Next(arr.dim[1] - 2); int y2 = ran.Next(arr.dim[1] - y1) + y1; nurikabePoint[] froc1 = new nurikabePoint[a.Length]; nurikabePoint[] froc2 = new nurikabePoint[a.Length]; for (int i = 0; i < a.Length; i++) { if (a[i].x >= x1 && a[i].x <= x2 && a[i].y >= y1 && a[i].y <= y2) { froc1[i] = a[i]; } else { froc2[i] = a[i]; } if (b[i].x >= x1 && b[i].x <= x2 && b[i].y >= y1 && b[i].y <= y2) { froc2[i] = b[i]; } else { froc1[i] = b[i]; } } froca[0] = froc1; froca[1] = froc2; return(froca); }
private nurikabePoint[] generirajEnega() { int kolkoBelihImamo = 0; int kolkoBelihRabimo = 0; Random rad = new Random(69); foreach (var belIsl in arr.beliIsland) { kolkoBelihRabimo += belIsl.Value.maxSize; kolkoBelihImamo += belIsl.Value.size; } double moznostDaJePointBeli = (double)kolkoBelihImamo / (double)kolkoBelihRabimo; var en = new nurikabePoint[velikostEnega]; for (int j = 0; j < velikostEnega; j++) { nurikabePoint pt; double rand = rad.NextDouble(); if (rand <= moznostDaJePointBeli) { pt = new nurikabePoint(val: int.MaxValue, id: int.MaxValue, x: tockeZKaterimiDelam[j].x, y: tockeZKaterimiDelam[j].y); en[j] = pt; } else { pt = new nurikabePoint(val: int.MinValue, id: int.MinValue, x: tockeZKaterimiDelam[j].x, y: tockeZKaterimiDelam[j].y); en[j] = pt; } } return(en); }
public (bool, nurikabePoint) aliMamEnIzhod(Island isl) { //preveri ce ma neki island samo en izhod int c = 0; nurikabePoint outNp = new nurikabePoint(); for (int i = 0; i < isl.Points.Count; i++) { var tempPf = isl.Points[i]; if (tempPf.x + 1 < dim[0]) { if (this[tempPf.x + 1, tempPf.y] == 0) { c++; outNp = this.getPoint(tempPf.x + 1, tempPf.y); } } if (tempPf.x - 1 > -1) { if (this[tempPf.x - 1, tempPf.y] == 0) { c++; outNp = this.getPoint(tempPf.x - 1, tempPf.y); } } if (tempPf.y + 1 < dim[1]) { if (this[tempPf.x, tempPf.y + 1] == 0) { c++; outNp = this.getPoint(tempPf.x, tempPf.y + 1); } } if (tempPf.y - 1 > -1) { if (this[tempPf.x, tempPf.y - 1] == 0) { c++; outNp = this.getPoint(tempPf.x, tempPf.y - 1); } } if (c > 1) { return(false, outNp); } } if (c == 1) { return(true, outNp); } return(false, outNp); }
public void removeFrom(ref List <List <nurikabePoint> > arr, nurikabePoint pt) { for (int i = 0; i < arr[pt.y].Count; i++) { if (arr[pt.y][i] == pt) { arr[pt.y].RemoveAt(i); break; } } }
public Island(nurikabePoint n) { anchor = n; Points = new List <nurikabePoint>(); Points.Add(n); maxSize = n.val; size = 1; amFull = false; if (maxSize == size) { amFull = true; } this.id = n.id; }
private bool seDrzimIslanda(nurikabePoint pt) { var sos = getSosede(pt); foreach (var sosed in sos) { if (sosed.val > 0 && sosed.id > 0 && sosed.seDrzimMasterja) { return(true); } } return(false); }
private int razdaljaMedKvadratoma(nurikabePoint a, nurikabePoint b) { int dis = 0; int y = a.y - b.y; int x = a.x - b.x; x = Math.Abs(x); y = Math.Abs(y); if (x != 0 || y != 0) { x--; } return(x + y); }
//konstruktor za novi island public Island(int x, int y, int val = Int32.MaxValue, int id = 0) { nurikabePoint n = new nurikabePoint(x, y, val: val, id: id); anchor = n; Points = new List <nurikabePoint>(); Points.Add(n); maxSize = val; size = 1; amFull = false; if (maxSize == size) { amFull = true; } this.id = id; }
// to sem vzel iz gen alg private int dobiSteviloCrnihKvadratov(ref int[,] arrT, nurikabePoint np) { int steviloKvadratov = 0; if (np.val > -1) { return(-1); } //levi zgornji if (np.x - 1 > -1 && np.y - 1 > -1) { if (arrT[np.x - 1, np.y - 1] < 0 && arrT[np.x - 1, np.y] < 0 && arrT[np.x, np.y - 1] < 0) { steviloKvadratov++; } } //desnji zgornji if (np.x + 1 < arr.GetLength(0) && np.y - 1 > -1) { if (arrT[np.x + 1, np.y - 1] < 0 && arrT[np.x + 1, np.y] < 0 && arrT[np.x, np.y - 1] < 0) { steviloKvadratov++; } } //levi spodnji if (np.x - 1 > -1 && np.y + 1 < arr.GetLength(1)) { if (arrT[np.x - 1, np.y + 1] < 0 && arrT[np.x - 1, np.y] < 0 && arrT[np.x, np.y + 1] < 0) { steviloKvadratov++; } } //desnji spodni if (np.x + 1 < arr.GetLength(0) && np.y + 1 < arr.GetLength(1)) { if (arrT[np.x + 1, np.y + 1] < 0 && arrT[np.x + 1, np.y] < 0 && arrT[np.x, np.y + 1] < 0) { steviloKvadratov++; } } return(steviloKvadratov); }
public void dodajIslanduTutCeSeNeDrzim(int islId, nurikabePoint pt) { bool seDrzim = seDrzimIslanda(pt); if (seDrzim) { this[pt.x, pt.y] = beliIsland[islId].maxSize; } else { pt.val = beliIsland[islId].maxSize; pt.id = beliIsland[islId].id; pt.seDrzimMasterja = false; beliIsland[islId].addPoint(pt); beliIsland[islId].semPovezan = false; this.arr[pt.x, pt.y] = pt.val; this.arrNull[pt.y].Remove(pt); this.arrBeli[pt.y].Add(pt); } }
public bool lahkoPlacamSemBlock(nurikabePoint pt, int ignoriraj = 0) { if (pt.val != 0) { return(false); } bool ig = true; if (ignoriraj == 0) { ig = false; } var sos = getSosede(pt); foreach (var s in sos) { if (s.val == 0) { continue; } if (s.id > 0) { if (ig) { if (s.id == ignoriraj) { continue; } else { return(false); } } else { return(false); } } } return(true); }
//add point to island public void addPoint(nurikabePoint p) { if (amFull) { throw new InvalidOperationException("Island is full"); } if (this.Points.Contains(p)) { return; } //preverimo ce se dotikam osamele tocke p.id = id; Points.Add(p); size = Points.Count; if (size == maxSize) { amFull = true; } }
//metoda ki previri ce so pozicije ki morajo biti zapolnjene private bool semOgrajen(nurikabePoint orPt) { if (orPt.val != 0) { return(false); } if (orPt.y - 1 > 0 && orPt.x + 1 < this.dim[0]) { if ((this[orPt.x, orPt.y - 1] + this[orPt.x + 1, orPt.y - 1] + this[orPt.x + 1, orPt.y]) == -3) { return(true); } } if (orPt.y - 1 >= 0 && orPt.x - 1 >= 0) { if ((this[orPt.x, orPt.y - 1] + this[orPt.x - 1, orPt.y - 1] + this[orPt.x - 1, orPt.y]) == -3) { return(true); } } if (orPt.y + 1 < this.dim[1] && orPt.x - 1 >= 0) { if ((this[orPt.x, orPt.y + 1] + this[orPt.x - 1, orPt.y + 1] + this[orPt.x - 1, orPt.y]) == -3) { return(true); } } if (orPt.y + 1 < this.dim[1] && orPt.x + 1 < this.dim[0]) { if ((this[orPt.x + 1, orPt.y] + this[orPt.x, orPt.y + 1] + this[orPt.x + 1, orPt.y + 1]) == -3) { return(true); } } return(false); }
public Nurikabe(string strPath) { //nalozimo datoteko in inicializiramo zadevo this.strPath = strPath; var text = File.ReadAllLines(strPath); var first = true; foreach (var str in text) { if (first) { first = false; var words = str.Split(' '); var xy = Array.ConvertAll(words, int.Parse); xSize = xy[0]; ySize = xy[1]; nurikabeArr = new betterArray(xSize, ySize); } else { if (str == "") { continue; } var words = str.Split(' ').ToList(); words.Remove(""); var xy = Array.ConvertAll(words.ToArray(), int.Parse); var p = new nurikabePoint(xy[0], xy[1], xy[2]); if (xy[2] != 1) { var wh = new Island(xy[0], xy[1], xy[2]); islandList.Add(wh); } nurikabeArrIndx.Add(p); nurikabeArr[xy[0], xy[1]] = xy[2]; } } }
private void generirajPop() { popArray = new nurikabePoint[pop][]; //pametno zgenerirajmo szacetno pop tak da vzamemo v postev kolko crnih & belih se rabimo //prvo prestejemo kolko belih imamo in koliko jih se potrebujemo int kolkoBelihImamo = 0; int kolkoBelihRabimo = 0; Random rad = new Random(69); foreach (var belIsl in arr.beliIsland) { kolkoBelihRabimo += belIsl.Value.maxSize; kolkoBelihImamo += belIsl.Value.size; } double moznostDaJePointBeli = (double)kolkoBelihImamo / (double)kolkoBelihRabimo; //zgenerirajmo pop for (int i = 0; i < pop; i++) { popArray[i] = new nurikabePoint[velikostEnega]; for (int j = 0; j < velikostEnega; j++) { nurikabePoint pt; double rand = rad.NextDouble(); if (rand <= moznostDaJePointBeli) { pt = new nurikabePoint(val: int.MaxValue, id: int.MaxValue, x: tockeZKaterimiDelam[j].x, y: tockeZKaterimiDelam[j].y); popArray[i][j] = pt; } else { pt = new nurikabePoint(val: int.MinValue, id: int.MinValue, x: tockeZKaterimiDelam[j].x, y: tockeZKaterimiDelam[j].y); popArray[i][j] = pt; } } } }
List <nurikabePoint> dobiSosede(ref int[,] arrT, nurikabePoint n) { var ret = new List <nurikabePoint>(); if (n.x - 1 > -1) { ret.Add(getPoint(n.x - 1, n.y, ref arrT)); } if (n.x + 1 < arr.GetLength(0)) { ret.Add(getPoint(n.x + 1, n.y, ref arrT)); } if (n.y - 1 > -1) { ret.Add(getPoint(n.x, n.y - 1, ref arrT)); } if (n.y + 1 < arr.GetLength(1)) { ret.Add(getPoint(n.x, n.y + 1, ref arrT)); } return(ret); }
public List <nurikabePoint> getSosede(nurikabePoint n) { var ret = new List <nurikabePoint>(); if (n.x - 1 > -1) { ret.Add(getPoint(n.x - 1, n.y)); } if (n.x + 1 < dim[0]) { ret.Add(getPoint(n.x + 1, n.y)); } if (n.y - 1 > -1) { ret.Add(getPoint(n.x, n.y - 1)); } if (n.y + 1 < dim[1]) { ret.Add(getPoint(n.x, n.y + 1)); } return(ret); }
public bool seMeDrzi(nurikabePoint pt) { foreach (var innerPt in Points) { if (pt.x == innerPt.x + 1 && pt.y == innerPt.y) { return(true); } if (pt.x == innerPt.x - 1 && pt.y == innerPt.y) { return(true); } if (pt.x == innerPt.x && pt.y == innerPt.y - 1) { return(true); } if (pt.x == innerPt.x && pt.y == innerPt.y + 1) { return(true); } } return(false); }
public void doTheEvolution(bool debug = false) { generirajPop(); int maxfit = int.MaxValue; Random rand = new Random(69); while (maxfit > 0) { double fitOcena = 0; //ocenimo pop List <Tuple <nurikabePoint[], int> > fitnessList = new List <Tuple <nurikabePoint[], int> >(); for (int pop = 0; pop < popArray.Length; pop++) { fitOcena += (double)this.fitness(popArray[pop]); fitnessList.Add(Tuple.Create(popArray[pop], this.fitness(popArray[pop]))); } fitnessList.Sort((x, y) => x.Item2.CompareTo(y.Item2)); int najslabsi = fitnessList[fitnessList.Count - 1].Item2; if (debug) { Console.WriteLine("najboljsi:"); izrisiEnega(fitnessList[0].Item1); Console.WriteLine("Ocenapopulacije: " + fitOcena / (double)fitnessList.Count); } //naredimo ruleto double[] moznostPrezivetja = new double[popArray.Length]; for (int i = 0; i < fitnessList.Count; i++) { //moznostPrezivetja[i] = ((double)najslabsi - (double)fitnessList[i].Item2)/(double)najslabsi; moznostPrezivetja[i] = (double)(fitnessList.Count - i) / (double)fitnessList.Count; } //krizam sranje List <nurikabePoint[]> krizani = new List <nurikabePoint[]>(); bool mamEnegaZaKrizaf = false; nurikabePoint[] kogaKrizam = new nurikabePoint[fitnessList[0].Item1.Length]; double moznost; for (int i = 0; i < fitnessList.Count; i++) { moznost = rand.NextDouble(); if (moznost <= moznostKrizanja) { if (mamEnegaZaKrizaf == false) { kogaKrizam = fitnessList[i].Item1; mamEnegaZaKrizaf = true; } else { var froc = krizaj(kogaKrizam, fitnessList[i].Item1); krizani.Add(froc[0]); krizani.Add(froc[1]); mamEnegaZaKrizaf = false; } } } //pobijem sranje int indx = 0; int randVal; for (int i = 0; i < fitnessList.Count; i++) { if (i < elita) { popArray[i] = fitnessList[i].Item1; continue; } if (i - randomFolk <= 0) { popArray[i] = generirajEnega(); } if (rand.NextDouble() > moznostPrezivetja[i]) { //preverim ce mam dovolj frocov if (krizani.Count > 0) { randVal = rand.Next(krizani.Count); popArray[i] = krizani[randVal]; krizani.RemoveAt(randVal); } else { popArray[i] = generirajEnega(); } } else { popArray[i] = fitnessList[i].Item1; } } double mutacija; //zdaj pa se mutiram sranje for (int i = elita; i < popArray.Length; i++) { for (int j = 0; j < popArray[i].Length; j++) { mutacija = rand.NextDouble(); if (mutacija <= this.moznostMutacije) { if (popArray[i][j].val < 0) { popArray[i][j] = new nurikabePoint(val: int.MaxValue, id: int.MaxValue, x: popArray[i][j].x, y: popArray[i][j].y); } else { popArray[i][j] = new nurikabePoint(val: int.MinValue, id: int.MinValue, x: popArray[i][j].x, y: popArray[i][j].y); } } } } var tt = 0; } }
public int this[int i, int j] { get { return(arr[i, j]); } set { arr[i, j] = value; if (value == -1) { //spreminjaj vrednosti za tabelo belih in crnih var mamZe = false; var np = new nurikabePoint(i, j, id: crniIslandId); var npWhite = new nurikabePoint(i, j, 0); mamZe = arrCrni[j].Any(p => (p.x == i && p.y == j)); //mamZe= arrCrni[j].Contains(np); rabim boljsi contains if (mamZe == false) { //preverim idje sosedov, in ce se dotikam kakega soseda idje zdruzim List <int> sosednjiIdji = new List <int>(); nurikabePoint npTemp; if (i + 1 < dim[0]) { npTemp = getPoint(i + 1, j); sosednjiIdji.Add(npTemp.id); } if (i - 1 >= 0) { npTemp = getPoint(i - 1, j); sosednjiIdji.Add(npTemp.id); } if (j + 1 < dim[1]) { npTemp = getPoint(i, j + 1); sosednjiIdji.Add(npTemp.id); } if (j - 1 >= 0) { npTemp = getPoint(i, j - 1); sosednjiIdji.Add(npTemp.id); } List <int> crniIdji = new List <int>(); foreach (var idj in sosednjiIdji) { if (idj < 0) { if (crniIdji.Contains(idj)) { continue; } crniIdji.Add(idj); } } //ustvarimo nov otok, povecamo otok ali zdruzimo otoke if (crniIdji.Count == 0) { Island newCrniIsland = new Island(i, j, crniIslandId, id: crniIslandId); crniIsland[crniIslandId] = newCrniIsland; np.id = crniIslandId; np.val = crniIslandId; arrCrni[j].Add(np); crniIslandId--; } else if (crniIdji.Count == 1) { //todo pofiksaj id za island classo var point = new nurikabePoint(i, j, id: crniIdji[0], val: crniIdji[0]); crniIsland[crniIdji[0]].addPoint(point); arrCrni[j].Add(point); removeFrom(ref this.arrNull, point); } else { for (int g = 1; g < crniIdji.Count; g++) { crniIsland[crniIdji[0]] = this.combineIslands(crniIsland[crniIdji[0]], crniIsland[crniIdji[g]]); crniIsland.Remove(crniIdji[g]); } var point = new nurikabePoint(i, j, id: crniIdji[0], val: crniIdji[0]); crniIsland[crniIdji[0]].addPoint(point); arrCrni[j].Add(point); } } arrNull[j].Remove(new nurikabePoint(i, j)); } //copy paste od crnih otokov na bele if (value > 0) { //spreminjaj vrednosti za tabelo belih in crnih var mamZe = false; var np = new nurikabePoint(i, j, value); mamZe = arrBeli[j].Any(p => (p.x == i && p.y == j)); //mamZe= arrCrni[j].Contains(np); rabim boljsi contains if (mamZe == false) { bool dodalKIslandu = false; foreach (var KeyPair in beliIsland) { if (KeyPair.Value.amFull || (KeyPair.Value.maxSize != value)) { continue; } if (KeyPair.Value.seMeDrzi(np)) { //ce se drzim islanda dodam temu islandi in popravim svoj id da je enak beliIsland[KeyPair.Key].addPoint(np); np.id = beliIsland[KeyPair.Key].id; arrBeli[j].Add(np); removeFrom(ref arrNull, np); dodalKIslandu = true; //preverit se moramo ce smo povezali kaki isl var sos = getSosede(np); foreach (var s in sos) { if (s.seDrzimMasterja == false) { s.seDrzimMasterja = true; //todo spodnji linq ne spremeni sranja beliIsland[KeyPair.Key].Points.Remove(s); beliIsland[KeyPair.Key].Points.Add(s); var debugTemp = 0; } } break; } } if (!dodalKIslandu) { //ce se ne drzim islanda ustvarim island in prilagodim id var isl = new Island(i, j, val: value, id: beliIslandId); beliIsland[beliIslandId] = isl; np.id = beliIsland[beliIslandId].id; beliIslandId++; arrBeli[j].Add(np); removeFrom(ref arrNull, np); } } arrNull[j].Remove(new nurikabePoint(i, j)); } } }
//zrihtamo tiste kjer imajo robe z 2 moznostma private bool zrihtajTisteZEnostavnoMoznostjoZaprtja() { var ch = false; //grem skozi vse islande foreach (var isl in nurikabeArr.beliIsland.Values) { if (isl.amFull || isl.maxSize - isl.size != 1) { continue; } var nullCount = 0; var edgePoint = new nurikabePoint(); var naso = false; //grem skozi vse tocke v islandu in preverim ce obstaja ene z 2 izhodoma foreach (var pt in isl.Points) { var sosedi = nurikabeArr.getSosede(pt); foreach (var sos in sosedi) { if (sos.id == 0) { nullCount++; } } if (nullCount == 2) { edgePoint = pt; naso = true; } else if (nullCount != 0) { naso = false; break; } } if (naso) { var nullSos = new List <nurikabePoint>(); var sos = nurikabeArr.getSosede(edgePoint); foreach (var s in sos) { if (s.id == 0) { nullSos.Add(s); } } if (nullSos[0].x != nullSos[1].x && nullSos[0].y != nullSos[1].y) { if (nurikabeArr[nullSos[0].x, nullSos[1].y] == 0) { nurikabeArr[nullSos[0].x, nullSos[1].y] = -1; ch = true; } else if (nurikabeArr[nullSos[1].x, nullSos[0].y] == 0) { nurikabeArr[nullSos[1].x, nullSos[0].y] = -1; ch = true; } } } } return(ch); }
nurikabePoint getPoint(int x, int y, ref int[,] arrT) { nurikabePoint np = new nurikabePoint(x, y, val: arrT[x, y]); return(np); }
public (bool, List <List <nurikabePoint> >) aliLahkoPridemIzAvB(Island A, nurikabePoint B, bool vsePoti = false) { (var tru, var poti) = doTheA(A, B, vsePoti: vsePoti); return(tru, poti); }
public (bool, List <List <nurikabePoint> >) aliLahkoPridemIzAvBVsePoti(Island A, nurikabePoint B) { (var tru, var poti) = doTheA2(A, B); return(tru, poti); }
private (bool, List <List <nurikabePoint> >) doTheA2(Island isl, nurikabePoint B, int ubijSeNa = Int32.MaxValue) { var output = new List <List <nurikabePoint> >(); //ustvarimo open var open = new List <List <nurikabePoint> >(); for (int i = 0; i < isl.Points.Count; i++) { var openList = new List <nurikabePoint>(); openList.Add(isl.Points[i]); open.Add(openList); } while (open.Count > 0) { if (open.Count > 1000) { return(false, null); } //predelamo tocke //vzamemo en open in zadnjo tocko, ter preverimo ce je ok var odprtaTocka = open[0].Last(); if (odprtaTocka == B) { output.Add(open[0]); open.RemoveAt(0); continue; } //vzamemo potencialne mozne razsiritve var potencialniNovi = this.getSosede(odprtaTocka); for (int i = 0; i < potencialniNovi.Count; i++) { bool splohDosezem = false; //ce je ze ta tocka v tej poti jo ignoriramo if (open[0].Contains(potencialniNovi[i])) { continue; } //ce je primerna za razsiritev jo dodamo if (lahkoPlacamSemBlock(potencialniNovi[i], open[0].Last().id)) { //preverimo ce sploh lahko dosezemo cilj //todo se zadeva brejka ko je prevec osamelih tock? int dist = razdaljaMedKvadratoma(open[0].Last(), B); int availableDist = isl.maxSize - isl.size - open[0].Count + 1; if (dist < availableDist) { splohDosezem = true; } if (splohDosezem) { //todo se sranje kopira sploh? al se samo ptr premakne var varTmp = open[0].ToArray(); var newOpen = new List <nurikabePoint>(varTmp); newOpen.Add(potencialniNovi[i]); open.Add(newOpen); } } } //ko preverim sosede odstranim iz open open.RemoveAt(0); } return(output.Count > 0, output); }
public (List <nurikabePoint>, List <nurikabePoint>) getChainOfRougeWhitesFromSeed(nurikabePoint np) { //najdem vse povezane tocke rogu so ++ none rouge so 03 ipd var rougeOut = new List <nurikabePoint>(); var normalOut = new List <nurikabePoint>(); var closed = new List <nurikabePoint>(); var opn = dobiSosede(ref arr, posibilities[0]); while (opn.Count > 0) { var obdelujem = opn[0]; if ((obdelujem.val > 0) == false || closed.Contains(obdelujem)) { opn.RemoveAt(0); closed.Add(obdelujem); continue; } if (obdelujem.val > 100) { rougeOut.Add(obdelujem); } else { normalOut.Add(obdelujem); } closed.Add(obdelujem); var sosTmp = dobiSosede(ref arr, obdelujem); foreach (var s in sosTmp) { if (closed.Contains(s) == false && s.val > 0) { opn.Add(s); } } opn.RemoveAt(0); } return(rougeOut, normalOut); }
public void razvijFroca(int id) { var cpyEleLsArr = posibilities.ToArray(); var cpyEleLs = new List <nurikabePoint>(cpyEleLsArr); //to ne kopira vredu sranja? var cpyEleLs2 = copyIslList(activeIslands); var froc = new ListElement(cpyEleLs, arr.Clone() as int[, ], cpyEleLs2, id); int vrednost = 0; if (kolkoOtrokSemObdelal == 0) { vrednost = -1; //preverim za sosede ce so 2*2 crni var np = new nurikabePoint(posibilities[0].x, posibilities[0].y); var pointi = dobiSteviloCrnihKvadratov(ref arr, np); if (pointi != 0) { froc.deadEnd = true; if (misc.debug) { Console.WriteLine("2*2 otok"); } } else { //preverim ce sem zadelal kakega belega foreach (var isl in activeIslands) { if (isl.amFull) { continue; } var izhodi = izhodiIsl(isl); if (izhodi.Count == 1 && izhodi.Contains(np)) { froc.deadEnd = true; if (misc.debug) { Console.WriteLine("Zadelal belega"); } } } } //preveri ce sem sebe dal na zadelano mesto todo ? if (!froc.deadEnd) { } froc.arr = arr.Clone() as int[, ]; froc.arr[np.x, np.y] = vrednost; froc.posibilities.RemoveAt(0); froc.father = this; //narisiMe(froc.arr); var tt = 0; } else if (kolkoOtrokSemObdelal == 1) { var sos = dobiSosede(ref arr, posibilities[0]); int stSosIsl = 0; int trenutniIslId = 0; int stNull = 0; vrednost = int.MaxValue; int islId = -1; int islPt = -1; //preverimo ce razsirimo kaki isl foreach (var s in sos) { if (froc.deadEnd) { break; } if (s.val > 0) { foreach (var i in activeIslands) { if (i.Points.Contains(s)) { // ce smo polek polnega isl. je to dead end if (i.amFull) { froc.deadEnd = true; if (misc.debug) { Console.WriteLine("Polek polnega islanda"); } break; } //ce ne dodamo islandu zadevo (razn ce stikam 2 isl) else { //ce stikam 2 islanda if (stSosIsl == 1) { if (islId == i.id) { continue; } froc.deadEnd = true; if (misc.debug) { Console.WriteLine("Dva islanda sestikata"); } break; } // ce ne else { //ker sem lazy in se mi ne da linq-ja checkupat for (int i2 = 0; i2 < froc.activeIslands.Count; i2++) { //najdemo otok in dodamo point if (froc.activeIslands[i2].id == i.id) { if (froc.activeIslands[i2].Points.Contains(posibilities[0]) == false) { //v bistvu predem dodamo point preverimo če se dotikamo kake verige roge islandov (var RougeOnes, var noneRougeOnes) = getChainOfRougeWhitesFromSeed(posibilities[0]); //ce smo prevelik otok ustvarili se ubijemo int newIslSize = noneRougeOnes.Count + RougeOnes.Count + 1; if (newIslSize > froc.activeIslands[i2].maxSize) { froc.deadEnd = true; if (misc.debug) { Console.WriteLine("Prevelik otok"); } break; } //ce rouge otoki povzrocajo da se dotikam z drugim otokom se ubijem bool seDotikam = false; for (int j = 0; j < noneRougeOnes.Count; j++) { if (noneRougeOnes[j].val != noneRougeOnes[0].val) { seDotikam = true; break; } } if (seDotikam) { froc.deadEnd = true; if (misc.debug) { Console.WriteLine("Rouge se dotika drugega otoka"); } break; } else { foreach (var nr in noneRougeOnes) { if (froc.activeIslands[i2].Points.Contains(nr) == false) { if (!froc.activeIslands[i2].amFull) { froc.activeIslands[i2].addPoint(nr); } else { froc.deadEnd = true; break; } } } foreach (var nr in RougeOnes) { if (froc.activeIslands[i2].Points.Contains(nr) == false) { if (!froc.activeIslands[i2].amFull) { froc.activeIslands[i2].addPoint(nr); } else { froc.deadEnd = true; break; } } } if (!froc.deadEnd && !froc.activeIslands[i2].amFull) { froc.activeIslands[i2].addPoint(posibilities[0]); islId = froc.activeIslands[i2].id; islPt = i2; //to dela vredi? stSosIsl++; } } break; } //ce se dotikam istega isl breakam else { break; } } } } } } if (froc.deadEnd) { break; } } } else if (s.val == 0) { stNull++; } } // preverim ce sem se zapr ki med crne if (stNull == 0 && stSosIsl == 0) { froc.deadEnd = true; } // preverim ce sem se zapr ki med crne in nimam izhoda? else if (islPt != -1 && froc.activeIslands[islPt].amFull == false) { var izh = izhodiIsl(froc.activeIslands[islPt]); if (izh.Count == 0) { froc.deadEnd = true; } if (misc.debug && izh.Count == 0) { Console.WriteLine("Zapr sem se med crne"); } } //preverim ce sem zapr kaksen crni otok (samo ce nisem poln) if (posibilities.Count > 0) { //SOS ARAYU DODAM SEBE!!! sos.Add(posibilities[0]); bool semZadelal = semZadelalCrneOtoke(sos, ref arr); if (semZadelal) { froc.deadEnd = true; if (misc.debug) { Console.WriteLine("Zadelan crni"); } } } froc.arr = arr.Clone() as int[, ]; froc.arr[posibilities[0].x, posibilities[0].y] = vrednost; froc.posibilities.RemoveAt(0); froc.father = this; //narisiMe(froc.arr); var tt = 0; } this.children[kolkoOtrokSemObdelal] = froc; kolkoOtrokSemObdelal++; }
private (bool, List <List <nurikabePoint> >) doTheA(Island isl, nurikabePoint B, bool vsePoti = false) { var output = new List <List <nurikabePoint> >(); bool outBool = false; if (isl.amFull) { return(outBool, output); } var odprtePoti = new List <nurikabePoint>(); var zaprtePoti = new List <nurikabePoint>(); //vzamem tocke iz islanda in jih dodadm v odprte poti var splohDosezem = false; foreach (var ptr in isl.Points) { /* * if (ptr.seDrzimMasterja == false) * { * continue; * } */ int dist = razdaljaMedKvadratoma(ptr, B); int availableDist = isl.maxSize - isl.size; if (dist < availableDist) { splohDosezem = true; } else { continue; } var ptCp = ptr.copy(); ptCp.val = isl.maxSize - isl.size; odprtePoti.Add(ptCp); //debug //Console.WriteLine("dodam root node: "+ptCp.x+","+ptCp.y); } if (!splohDosezem) { return(outBool, output); } while (odprtePoti.Count > 0) { //todo problem je ker nena poti hranijo svojega historyja in zberemo tukaj prvega ki smo ga dali v arr var Obdelujem = odprtePoti[0]; //Console.WriteLine("Obdelujem Node: "+Obdelujem.x+","+Obdelujem.y); //ce sem naso pot jo izpisem if (Obdelujem == B) { var Pot = new List <nurikabePoint>(); //Console.WriteLine("Nasel pot: "); var tt = Obdelujem; //Console.WriteLine(tt.x+","+tt.y); Pot.Add(tt); while (tt.kogaSeDrzim[0] != -1 && tt.kogaSeDrzim[1] != -1) { //Console.WriteLine(tt.kogaSeDrzim[0]+","+tt.kogaSeDrzim[1]); var temp1 = new nurikabePoint(tt.kogaSeDrzim[0], tt.kogaSeDrzim[1]); Pot.Add(temp1); var temp = from s in zaprtePoti where s.x == tt.kogaSeDrzim[0] && s.y == tt.kogaSeDrzim[1] select s; tt = temp.ToList()[0]; } output.Add(Pot); odprtePoti.RemoveAt(0); outBool = true; if (!vsePoti) { break; } continue; } var potencialniNovi = getSosede(Obdelujem); //preverim vse potencialne nove kandidate foreach (var pocNov in potencialniNovi) { //preverim ce so sploh prazni if (pocNov.val != 0 && !(pocNov.id == isl.id)) { continue; } //Console.WriteLine("Potencialni novi node: "+pocNov.x+","+pocNov.y); //preverim ce sem ga ze obdelal //todo preveri ce dela contains zdaj if (!vsePoti) { //Console.WriteLine("Ze obstaja: "+pocNov.x+","+pocNov.y); if (zaprtePoti.Contains(pocNov)) { continue; } if (odprtePoti.Contains(pocNov)) { continue; } } //preverim ce se drzim kakih belih bool seDrzimBelih = false; var tempSos = getSosede(pocNov); foreach (var sosPocNov in tempSos) { if (sosPocNov.val > 0 && sosPocNov.id != isl.id) { //ce se drzim ateja je to ok if (sosPocNov.x == Obdelujem.x && sosPocNov.y == Obdelujem.y) { continue; } seDrzimBelih = true; //Console.WriteLine("Node ni primeren: "+sosPocNov.x+","+sosPocNov.y); break; } } if (seDrzimBelih) { continue; } //naredim kopijo in preverim ce sploh dosezem cilj var copPocNov = pocNov.copy(); copPocNov.val = Obdelujem.val - 1; var razMedPocNov = razdaljaMedKvadratoma(copPocNov, B); if (copPocNov.x != B.x && copPocNov.y != B.y) { razMedPocNov++; } if (razMedPocNov > (copPocNov.val)) { //Console.WriteLine("Prevelika razdalja: "+copPocNov.x+","+copPocNov.y); continue; } //ce grem mimo vse pogoje ga dodam v odprte poti copPocNov.kogaSeDrzim[0] = Obdelujem.x; copPocNov.kogaSeDrzim[1] = Obdelujem.y; odprtePoti.Add(copPocNov); //Console.WriteLine("grem proti: " + copPocNov.x+","+copPocNov.y + " val: "+copPocNov.val); var tt = 0; } zaprtePoti.Add(odprtePoti[0]); //Console.WriteLine("Dodam: "+odprtePoti[0].x+","+odprtePoti[0].y); odprtePoti.RemoveAt(0); } return(outBool, output); }