public char this[PointAxial coords] { get { var tup = axial_to_index(coords); return tup == null ? '.' : _grid[tup.Item1][tup.Item2]; } set { var tup = axial_to_index(coords); if (tup != null) _grid[tup.Item1][tup.Item2] = value; } }
private void handleEdges() { if (_grid.Size == 1) { _ips[_activeIp] = new PointAxial(0, 0); return; } var x = coords.Q; var z = coords.R; var y = -x - z; if (Ut.Max(Math.Abs(x), Math.Abs(y), Math.Abs(z)) < _grid.Size) return; var xBigger = Math.Abs(x) >= _grid.Size; var yBigger = Math.Abs(y) >= _grid.Size; var zBigger = Math.Abs(z) >= _grid.Size; // Move the pointer back to the hex near the edge _ips[_activeIp] -= dir.Vector; // If two values are still in range, we are wrapping around an edge (not a corner). if (!xBigger && !yBigger) _ips[_activeIp] = new PointAxial(coords.Q + coords.R, -coords.R); else if (!yBigger && !zBigger) _ips[_activeIp] = new PointAxial(-coords.Q, coords.Q + coords.R); else if (!zBigger && !xBigger) _ips[_activeIp] = new PointAxial(-coords.R, -coords.Q); else { // If two values are out of range, we navigated into a corner. // We teleport to a location that depends on the current memory value. var isPositive = _memory.Get() > 0; if ((!xBigger && !isPositive) || (!yBigger && isPositive)) _ips[_activeIp] = new PointAxial(coords.Q + coords.R, -coords.R); else if ((!yBigger && !isPositive) || (!zBigger && isPositive)) _ips[_activeIp] = new PointAxial(-coords.Q, coords.Q + coords.R); else if ((!zBigger && !isPositive) || (!xBigger && isPositive)) _ips[_activeIp] = new PointAxial(-coords.R, -coords.Q); } }
public void MoveRight() { var index = rightIndex; _mp = index.Item1; _dir = index.Item2; _cw = index.Item3; }
public void MoveLeft() { var index = leftIndex; _mp = index.Item1; _dir = index.Item2; _cw = index.Item3; }
public Bitmap DrawBitmap(HexagonySettings settings, Font defaultValueFont, Font defaultAnnotationFont) { var getX = Ut.Lambda((Direction dir, PointAxial coords) => 4 * coords.Q + 2 * coords.R + (dir is East ? 1 : 0)); var getY = Ut.Lambda((Direction dir, PointAxial coords) => 2 * coords.R + (dir is NorthEast ? 0 : dir is East ? 1 : 2)); int minX = getX(_dir, _mp), maxX = minX; int minY = getY(_dir, _mp), maxY = minY; foreach (var kvp1 in _edges) foreach (var kvp2 in kvp1.Value) { var x = getX(kvp1.Key, kvp2.Key); var y = getY(kvp1.Key, kvp2.Key); minX = Math.Min(minX, x); minY = Math.Min(minY, y); maxX = Math.Max(maxX, x); maxY = Math.Max(maxY, y); } foreach (var kvp1 in _annotations) foreach (var kvp2 in kvp1.Value) { var x = getX(kvp1.Key, kvp2.Key); var y = getY(kvp1.Key, kvp2.Key); minX = Math.Min(minX, x); minY = Math.Min(minY, y); maxX = Math.Max(maxX, x); maxY = Math.Max(maxY, y); } minX -= 3; minY -= 3; maxX += 3; maxY += 3; const int xFactor = 20, yFactor = 34; return GraphicsUtil.DrawBitmap((maxX - minX) * xFactor, (maxY - minY) * yFactor, g => { g.Clear(settings.MemoryBackgroundColor); using (var unusedEdgePen = new Pen(settings.MemoryGridZeroColor)) using (var usedEdgePen = new Pen(settings.MemoryGridNonZeroColor, 2f)) using (var pointerBrush = new SolidBrush(settings.MemoryPointerColor)) using (var valueBrush = new SolidBrush(settings.MemoryValueFont.NullOr(f => f.Color) ?? Color.CornflowerBlue)) using (var annotationBrush = new SolidBrush(settings.MemoryAnnotationFont.NullOr(f => f.Color) ?? Color.ForestGreen)) using (var valueFont = settings.MemoryValueFont.NullOr(f => f.Font)) using (var annotationFont = settings.MemoryAnnotationFont.NullOr(f => f.Font)) { var sfValue = new StringFormat { Alignment = StringAlignment.Center, LineAlignment = StringAlignment.Near }; var sfAnnotation = new StringFormat { Alignment = StringAlignment.Center, LineAlignment = StringAlignment.Far }; for (int y = minY; y <= maxY; y++) for (int x = minX; x <= maxX; x++) { if (!((y % 2 == 0 && x % 2 == 0) || ((y % 4 + 4) % 4 == 1 && (x % 4 + 4) % 4 == 1) || ((y % 4 + 4) % 4 == 3 && (x % 4 + 4) % 4 == 3))) continue; var dir = Direction.East; var mp = new PointAxial(0, 0); if (y % 2 != 0) { dir = Direction.East; mp = new PointAxial((x - y) / 4, (y - 1) / 2); } else if ((x - y) % 4 == 0) { dir = Direction.NorthEast; mp = new PointAxial((x - y) / 4, y / 2); } else { dir = Direction.SouthEast; mp = new PointAxial((x - y + 2) / 4, (y - 2) / 2); } var xx = (x - minX) * xFactor; var yy = (y - minY) * yFactor; var hasValue = _edges.ContainsKeys(dir, mp); using (var tr = new GraphicsTransformer(g).Rotate((dir is NorthEast ? -60 : dir is SouthEast ? 60 : 0) + (_cw ? 180 : 0)).Translate(xx, yy)) { g.DrawLine(hasValue ? usedEdgePen : unusedEdgePen, 0, yFactor * -.68f, 0, yFactor * .68f); if (dir == _dir && mp == _mp) g.FillPolygon(pointerBrush, new[] { new PointF(0, yFactor * -.68f), new PointF(3, yFactor * .68f), new PointF(-3, yFactor * .68f) }); } using (var tr = new GraphicsTransformer(g).Rotate((dir is NorthEast ? 30 : dir is SouthEast ? -30 : -90)).Translate(xx, yy)) { if (hasValue) { var str = _edges[dir][mp].ToString(); // Show printable ISO-8859-1 characters if (_edges[dir][mp] >= 0x20 && _edges[dir][mp] <= 0xff && _edges[dir][mp] != 0x7f) try { str += " '" + char.ConvertFromUtf32((int) _edges[dir][mp]) + "'"; } catch { } g.DrawString(str, valueFont ?? defaultValueFont, valueBrush, 0, 0, sfValue); } var annotation = _annotations.Get(dir, mp, null); if (!string.IsNullOrWhiteSpace(annotation)) g.DrawString(annotation, annotationFont ?? defaultAnnotationFont, annotationBrush, 0, 2, sfAnnotation); } } } }); }
public int GetY(PointAxial p) { return (p.R + Grid.Size - 1) * YTextSpacing + YPadding; }
public int GetX(PointAxial p) { return (2 * (p.Q + Grid.Size - 1) + p.R) * XTextSpacing + XPadding; }
private Tuple<int, int> axial_to_index(PointAxial coords) { var x = coords.Q; var z = coords.R; var y = -x - z; if (Ut.Max(Math.Abs(x), Math.Abs(y), Math.Abs(z)) >= Size) return null; var i = z + Size - 1; var j = x + Math.Min(i, Size - 1); return Tuple.Create(i, j); }
public Position GetPosition(PointAxial coords) { var tup = axial_to_index(coords); return tup == null ? _endPos : _gridPositions[tup.Item1][tup.Item2]; }
private void mouseDown(object sender, MouseEventArgs e) { if (_lastRendering != null) { _lastMouseDown = _file.FromScreen(e.X, e.Y); if (e.Button == MouseButtons.Right) mnuContext.Show(ctImage, e.Location); else DlgMessage.Show("The position you clicked is: " + _lastMouseDown.ToString(), "Axial coordinates", DlgType.Info); } }
private PointAxial? handleEdges(PointAxial ip, Direction dir, bool? isPositive) { if (_file.Grid.Size == 1) return new PointAxial(0, 0); var x = ip.Q; var z = ip.R; var y = -x - z; if (Ut.Max(Math.Abs(x), Math.Abs(y), Math.Abs(z)) < _file.Grid.Size) return ip; var xBigger = Math.Abs(x) >= _file.Grid.Size; var yBigger = Math.Abs(y) >= _file.Grid.Size; var zBigger = Math.Abs(z) >= _file.Grid.Size; // Move the pointer back to the hex near the edge ip -= dir.Vector; // If two values are still in range, we are wrapping around an edge (not a corner). if (!xBigger && !yBigger) return new PointAxial(ip.Q + ip.R, -ip.R); else if (!yBigger && !zBigger) return new PointAxial(-ip.Q, ip.Q + ip.R); else if (!zBigger && !xBigger) return new PointAxial(-ip.R, -ip.Q); // If two values are out of range, we navigated into a corner. if (isPositive == null) return null; // We teleport to a location that depends on the current memory value. if ((!xBigger && !isPositive.Value) || (!yBigger && isPositive.Value)) return new PointAxial(ip.Q + ip.R, -ip.R); else if ((!yBigger && !isPositive.Value) || (!zBigger && isPositive.Value)) return new PointAxial(-ip.Q, ip.Q + ip.R); else if ((!zBigger && !isPositive.Value) || (!xBigger && isPositive.Value)) return new PointAxial(-ip.R, -ip.Q); // This should never be reached throw new InvalidOperationException(); }