internal override GameState getBestGame(GameState gs) { Random r = new Random(0); List <PointD> allPoints = new List <PointD>(); index = new Dictionary <PointD, int>(); for (int i = 0; i < gs.PortalInfos.Count; i++) { PortalInfo pInfo = gs.PortalInfos[i]; allPoints.Add(pInfo.Pos); index[pInfo.Pos] = i; } List <PointD> remPoints = new List <PointD>(allPoints); List <PointD> hull = ConvexHull.MakeConvexHull(allPoints); foreach (PointD item in hull) { remPoints.Remove(item); } LinkPlan linkPlan = new LinkPlan(gs.PortalInfos.Count); for (int i = 0; i < hull.Count; i++) { //gs.addLink(index[hull[(i - 1 + hull.Count) % hull.Count]], index[hull[i]]); linkPlan.addLink(index[hull[(i - 1 + hull.Count) % hull.Count]], index[hull[i]]); } while (hull.Count > 3) { int mid = r.Next(0, hull.Count); int ind1 = (mid - 1 + hull.Count) % hull.Count; int ind2 = (mid + 1 + hull.Count) % hull.Count; //gs.addLink(index[hull[ind1]], index[hull[ind2]]); linkPlan.addLink(index[hull[ind1]], index[hull[ind2]]); hull.RemoveAt(mid); } List <Triangle> remTriangles = new List <Triangle>(); for (int p1 = 0; p1 < linkPlan.Portals.Length; p1++) { foreach (int p2 in linkPlan.Portals[p1].Links) { foreach (int p3 in linkPlan.Portals[p2].Links) { if (linkPlan.Portals[p3].Links.Contains(p1)) { int[] triangleKey = new int[] { p1, p2, p3 }; Array.Sort(triangleKey); Triangle newTr = new Triangle(triangleKey); if (remTriangles.Contains(newTr)) { continue; } remTriangles.Add(newTr); } } } } while (remTriangles.Count > 0) { Triangle curTriangle = remTriangles[0]; remTriangles.RemoveAt(0); foreach (PointD remPoint in remPoints) { if (geohelper.PointInPolygon(new PointD[] { allPoints[curTriangle.P1], allPoints[curTriangle.P2], allPoints[curTriangle.P3] }, remPoint)) { linkPlan.addLink(curTriangle.P1, index[remPoint]); linkPlan.addLink(curTriangle.P2, index[remPoint]); linkPlan.addLink(curTriangle.P3, index[remPoint]); for (int i = 0; i < 3; i++) { int[] triangleKey = new int[] { curTriangle.P1, curTriangle.P2, curTriangle.P3 }; triangleKey[i] = index[remPoint]; Array.Sort(triangleKey); Triangle newTr = new Triangle(triangleKey); remTriangles.Add(newTr); } remPoints.Remove(remPoint); break; } } } AlgoWayOptimizer wopt = new AlgoWayOptimizer(gs, linkPlan, this); gs = wopt.linkConvex(); this.newBestGame(gs); return(gs); }
internal override GameState getBestGame(GameState gs) { if (gs.Global.AnchorsPortals.Count != 1) { return(gs); } List <PointD> allPoints = new List <PointD>(); Dictionary <PointD, bool> anchors = new Dictionary <PointD, bool>(); if (gs.Global != null) { foreach (PortalInfo item in gs.Global.AnchorsPortals) { anchors[item.Pos] = true; } } foreach (PortalInfo pInfo in gs.PortalInfos) { if (!anchors.ContainsKey(pInfo.Pos)) { allPoints.Add(pInfo.Pos); } } SortedList <double, PointD> anglePoints = new SortedList <double, PointD>(); PointD anchor = anchors.Keys.ToArray()[0]; foreach (PointD p in allPoints) { if (p.Equals(anchor)) { continue; } //gs.addLink(gs.Global.PortalMappingPointD[p], gs.Global.PortalMappingPointD[anchor]); } foreach (PointD p in allPoints) { if (p.Equals(anchor)) { continue; } double angl = geohelper.GetAngle(p, anchor); anglePoints.Add(angl, p); } double biggestAngleKey = 0; double biggestAngleDiff = 0; for (int i = 0; i < anglePoints.Count; i++) { double anglediff = anglePoints.Keys[i] - anglePoints.Keys[(i + 1) % anglePoints.Count]; anglediff = Math.Abs(anglediff); while (anglediff > 180) { anglediff -= 360; } anglediff = Math.Abs(anglediff); //if (anglediff < 0) anglediff += 2 * Math.PI; if (anglediff > biggestAngleDiff) { biggestAngleDiff = anglediff; biggestAngleKey = anglePoints.Keys[(i + 1) % anglePoints.Count]; } } int startInd = anglePoints.IndexOfKey(biggestAngleKey); for (int i = 0; i < anglePoints.Count * 2; i++) { double key = anglePoints.Keys[(i + startInd) % anglePoints.Count]; PointD p = anglePoints[key]; gs.addLink(gs.Global.PortalMappingPointD[p], gs.Global.PortalMappingPointD[anchor]); for (int j = 0; j < i; j++) { double jkey = anglePoints.Keys[(startInd + j) % anglePoints.Count]; double angleDiff = key - jkey; if (angleDiff < 0) { angleDiff += 360; } if (angleDiff > 180) { continue; } gs.addLink(gs.Global.PortalMappingPointD[p], gs.Global.PortalMappingPointD[anglePoints[jkey]]); } } AlgoWayOptimizer wopt = new AlgoWayOptimizer(gs, this); gs = wopt.linkConvex(); this.newBestGame(gs); return(gs); }