Наследование: LanguageSettings
Пример #1
0
        public HexagonyEnv(string source, string input, HexagonySettings settings)
        {
            if (source.StartsWith("❢"))
                _linearCode = source.Substring(1);
            else
            {
                _grid = Grid.Parse(source);
                _ips = Ut.NewArray(
                    new PointAxial(0, -_grid.Size + 1),
                    new PointAxial(_grid.Size - 1, -_grid.Size + 1),
                    new PointAxial(_grid.Size - 1, 0),
                    new PointAxial(0, _grid.Size - 1),
                    new PointAxial(-_grid.Size + 1, _grid.Size - 1),
                    new PointAxial(-_grid.Size + 1, 0));
                _ipDirs = Ut.NewArray(
                    Direction.East,
                    Direction.SouthEast,
                    Direction.SouthWest,
                    Direction.West,
                    Direction.NorthWest,
                    Direction.NorthEast);
            }
            switch (_inputMode = settings.InputMode)
            {
                case InputMode.Utf8:
                    _input = input.ToUtf8();
                    break;

                case InputMode.Utf16:
                    _input = input.ToUtf16();
                    break;

                case InputMode.Numbers:
                    var m = Regex.Match(input, @"\A(\s*\d+\s*)*\Z", RegexOptions.Singleline);
                    if (!m.Success)
                        throw new InvalidOperationException("The input provided is not a whitespace-separated list of numbers.");
                    _input = m.Groups[1].Captures.Cast<Capture>().Select(c =>
                    {
                        byte b;
                        if (!byte.TryParse(c.Value.Trim(), out b))
                            throw new InvalidOperationException("The number {0} in the input string does not fit in a byte.".Fmt(c.Value.Trim()));
                        return b;
                    }).ToArray();
                    break;

                default:
                    throw new InvalidOperationException("Please choose an input mode from the “Input semantics” menu.");
            }

            _inputIndex = 0;
            _settings = settings;
            if (!settings.MemoryAnnotations.ContainsKey(settings.LastMemoryAnnotationSet))
                settings.MemoryAnnotations[settings.LastMemoryAnnotationSet] = new Dictionary<Direction, Dictionary<PointAxial, string>>();
            _memory = new Memory(settings.MemoryAnnotations[settings.LastMemoryAnnotationSet]);
        }
Пример #2
0
        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);
                            }
                        }
                }
            });
        }
Пример #3
0
        public HexagonyEnv(string source, string input, HexagonySettings settings)
        {
            if (source.StartsWith("❢"))
            {
                _linearCode = source.Substring(1);
            }
            else
            {
                _grid = Grid.Parse(source);
                _ips  = Ut.NewArray(
                    new PointAxial(0, -_grid.Size + 1),
                    new PointAxial(_grid.Size - 1, -_grid.Size + 1),
                    new PointAxial(_grid.Size - 1, 0),
                    new PointAxial(0, _grid.Size - 1),
                    new PointAxial(-_grid.Size + 1, _grid.Size - 1),
                    new PointAxial(-_grid.Size + 1, 0));
                _ipDirs = Ut.NewArray(
                    Direction.East,
                    Direction.SouthEast,
                    Direction.SouthWest,
                    Direction.West,
                    Direction.NorthWest,
                    Direction.NorthEast);
            }
            switch (_inputMode = settings.InputMode)
            {
            case InputMode.Utf8:
                _input = input.ToUtf8();
                break;

            case InputMode.Utf16:
                _input = input.ToUtf16();
                break;

            case InputMode.Numbers:
                var m = Regex.Match(input, @"\A(\s*\d+\s*)*\Z", RegexOptions.Singleline);
                if (!m.Success)
                {
                    throw new InvalidOperationException("The input provided is not a whitespace-separated list of numbers.");
                }
                _input = m.Groups[1].Captures.Cast <Capture>().Select(c =>
                {
                    byte b;
                    if (!byte.TryParse(c.Value.Trim(), out b))
                    {
                        throw new InvalidOperationException("The number {0} in the input string does not fit in a byte.".Fmt(c.Value.Trim()));
                    }
                    return(b);
                }).ToArray();
                break;

            default:
                throw new InvalidOperationException("Please choose an input mode from the “Input semantics” menu.");
            }

            _inputIndex = 0;
            _settings   = settings;
            if (!settings.MemoryAnnotations.ContainsKey(settings.LastMemoryAnnotationSet))
            {
                settings.MemoryAnnotations[settings.LastMemoryAnnotationSet] = new Dictionary <Direction, Dictionary <PointAxial, string> >();
            }
            _memory = new Memory(settings.MemoryAnnotations[settings.LastMemoryAnnotationSet]);
        }
Пример #4
0
        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);
                                                        }
                                                    }
                                                }
                                            }
                                        }
            }));
        }