/// <summary> /// /// </summary> /// <param name="size"></param> /// <returns></returns> public static IEnumerable<PermutationGroup> Calculate(int size) { var source = GetElements(size); var listPermutation = new List<PermutationGroup>(); listPermutation.Add(new PermutationGroup(new VectorI(Enumerable.Range(0, size).ToArray()), new VectorI[0])); int length = 0; var listElements = new List<VectorI[]>(); while (listPermutation.Count() < size.Factorial()) { length++; listElements.Clear(); for (int i = 0; i < source.Length; i++) { var vector = new VectorI[length]; vector[0] = source[i]; CalculateElements(listElements, source, length, 0, vector); } foreach (var elements in listElements) { var vector = CalculateVector(size, elements); if (!listPermutation.Exists(x => x.Vector.Equals(vector))) { listPermutation.Add(new PermutationGroup(vector, elements)); } } } return listPermutation; }
public static void ForEachCellInLine(VectorI lineBegin, VectorI lineEnd, Action <VectorI> action) { // from https://en.wikipedia.org/wiki/Bresenham%27s_line_algorithm ("All Cases" section) var(x, y) = lineBegin; var dx = Math.Abs(lineEnd.X - x); var sx = x < lineEnd.X ? 1 : -1; var dy = -Math.Abs(lineEnd.Y - y); var sy = y < lineEnd.Y ? 1 : -1; var error = dx + dy; while (true) { action(new VectorI(x, y)); if (x == lineEnd.X && y == lineEnd.Y) { break; } var e2 = error + error; if (e2 >= dy) { error += dy; x += sx; } if (e2 <= dx) { error += dx; y += sy; } } }
private void DrawGlyph(VectorI coords) { if (!_documentControl.Document.IsInRange(coords)) { return; } _hasDrawn = true; ref var element = ref _layerEditAccess.GetElementRef(coords);
public ref DocumentElement GetElementRef(VectorI coords) { if (coords.X < 0 || coords.Y < 0 || coords.X >= _layer.Width || coords.Y >= _layer.Height) { throw new ArgumentOutOfRangeException($"({coords}) are not a valid position in the document."); } var(x, y) = coords; return(ref _layer.Elements[x, y]); }
protected internal override void OnMouseLeftButtonDown(object sender, MouseEventArgs e) { if (_manipulationScope != null) { return; // don't know if this ever happens, but it should just continue the current manipulation. } _previousDrawPosition = _documentControl.GetDocumentCoordsAt(e.MouseState.Position); _manipulationScope = _documentControl.Document.Manipulator.BeginManipulation(); _layerEditAccess = _manipulationScope.GetLayerEditAccess(_documentControl.ActiveLayerId); DrawGlyph(_previousDrawPosition); }
protected internal override void OnMouseMove(object sender, MouseMoveEventArgs e) { if (_manipulationScope == null) { return; } var documentCoords = _documentControl.GetDocumentCoordsAt(e.MouseState.Position); GridGeometry.ForEachCellInLine(_previousDrawPosition, documentCoords, DrawGlyph); _previousDrawPosition = documentCoords; }
private static VectorI CalculateVector(int size, VectorI[] target) { var array = Enumerable.Range(0, size).ToArray(); for (int i = 0; i < target.Length; i++) { var temp = array[target[i][0]]; array[target[i][0]] = array[target[i][1]]; array[target[i][1]] = temp; } return new VectorI(array); }
private static void CalculateElements(List<VectorI[]> list, VectorI[] source, int length, int index, VectorI[] vector) { if (index == length - 1) { var copy = new VectorI[length]; Array.Copy(vector, copy, length); list.Add(copy); } else { index++; for (int i = 0; i < source.Length; i++) { vector[index] = source[i]; CalculateElements(list, source, length, index, vector); } } }
private PermutationGroup(VectorI vector, VectorI[] elements) { this.Vector = vector; this.Elements = elements; }
public static IObservable<PermutationGroup> CalculateEx(int size) { var result = Observable.Create<PermutationGroup>(observer => { PermutationGroup pg = null; var source = GetElements(size); var listPermutation = new List<PermutationGroup>(); pg = new PermutationGroup(new VectorI(Enumerable.Range(0, size).ToArray()), new VectorI[0]); listPermutation.Add(pg); observer.OnNext(pg); int length = 0; int maxSize = size.Factorial(); var listElements = new List<VectorI[]>(); while (listPermutation.Count() < maxSize) { length++; listElements.Clear(); for (int i = 0; i < source.Length; i++) { var vector = new VectorI[length]; vector[0] = source[i]; CalculateElements(listElements, source, length, 0, vector); } foreach (var elements in listElements) { var vector = CalculateVector(size, elements); if (listPermutation.Where(x => x.Vector.Equals(vector)).Count() == 0) { pg = new PermutationGroup(vector, elements); listPermutation.Add(pg); observer.OnNext(pg); if (listPermutation.Count() == maxSize) { break; } } } } observer.OnCompleted(); return () => { }; }); return result; }
public override bool InHitArea(BattleGrid grid, BattleUnit unit, VectorI target, VectorI tile) { return(true); }
public override bool InRange(BattleGrid grid, BattleUnit unit, VectorI target) { return(true); }