如何在控制台应用程序中绘制矩形?

发布于 2024-11-07 03:39:33 字数 72 浏览 11 评论 0原文

我需要在 C# 控制台应用程序中并使用扩展 ASCII 绘制一个矩形,内部有一个数字。我该怎么办?

这是一个演示。

I need to draw a rectangle, with a number inside, in a C# console app and using extended ASCII. How do I go about it?

This is for a demo.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

深海夜未眠 2024-11-14 03:39:33
public class ConsoleRectangle
{
    private int hWidth;
    private int hHeight;
    private Point hLocation;
    private ConsoleColor hBorderColor;

    public ConsoleRectangle(int width, int height, Point location, ConsoleColor borderColor)
    {
        hWidth = width;
        hHeight = height;
        hLocation = location;
        hBorderColor = borderColor;
    }

    public Point Location
    {
        get { return hLocation; }
        set { hLocation = value; }
    }

    public int Width
    {
        get { return hWidth; }
        set { hWidth = value; }
    }

    public int Height
    {
        get { return hHeight; }
        set { hHeight = value; }
    }

    public ConsoleColor BorderColor
    {
        get { return hBorderColor; }
        set { hBorderColor = value; }
    }

    public void Draw()
    {
        string s = "╔";
        string space = "";
        string temp = "";
        for (int i = 0; i < Width; i++)
        {
            space += " ";
            s += "═";
        }

        for (int j = 0; j < Location.X ; j++)
            temp += " ";

        s += "╗" + "\n";

        for (int i = 0; i < Height; i++)
            s += temp + "║" + space + "║" + "\n";

        s += temp + "╚";
        for (int i = 0; i < Width; i++)
            s += "═";

        s += "╝" + "\n";

        Console.ForegroundColor = BorderColor;
        Console.CursorTop = hLocation.Y;
        Console.CursorLeft = hLocation.X;
        Console.Write(s);
        Console.ResetColor();
    }
}
public class ConsoleRectangle
{
    private int hWidth;
    private int hHeight;
    private Point hLocation;
    private ConsoleColor hBorderColor;

    public ConsoleRectangle(int width, int height, Point location, ConsoleColor borderColor)
    {
        hWidth = width;
        hHeight = height;
        hLocation = location;
        hBorderColor = borderColor;
    }

    public Point Location
    {
        get { return hLocation; }
        set { hLocation = value; }
    }

    public int Width
    {
        get { return hWidth; }
        set { hWidth = value; }
    }

    public int Height
    {
        get { return hHeight; }
        set { hHeight = value; }
    }

    public ConsoleColor BorderColor
    {
        get { return hBorderColor; }
        set { hBorderColor = value; }
    }

    public void Draw()
    {
        string s = "╔";
        string space = "";
        string temp = "";
        for (int i = 0; i < Width; i++)
        {
            space += " ";
            s += "═";
        }

        for (int j = 0; j < Location.X ; j++)
            temp += " ";

        s += "╗" + "\n";

        for (int i = 0; i < Height; i++)
            s += temp + "║" + space + "║" + "\n";

        s += temp + "╚";
        for (int i = 0; i < Width; i++)
            s += "═";

        s += "╝" + "\n";

        Console.ForegroundColor = BorderColor;
        Console.CursorTop = hLocation.Y;
        Console.CursorLeft = hLocation.X;
        Console.Write(s);
        Console.ResetColor();
    }
}
折戟 2024-11-14 03:39:33

这是 String 的扩展方法,它将在给定字符串周围绘制一个控制台框。包括多行支持。

IE
string tmp = "某个值"; Console.Write(tmp.DrawInConsoleBox());

        public static string DrawInConsoleBox(this string s)
        {
            string ulCorner = "╔";
            string llCorner = "╚";
            string urCorner = "╗";
            string lrCorner = "╝";
            string vertical = "║";
            string horizontal = "═";

            string[] lines = s.Split(new char[] { '\r', '\n' }, StringSplitOptions.RemoveEmptyEntries);
            

            int longest = 0;
            foreach(string line in lines)
            {
                if (line.Length > longest)
                    longest = line.Length;
            }
            int width = longest + 2; // 1 space on each side

            
            string h = string.Empty;
            for (int i = 0; i < width; i++)
                h += horizontal;

            // box top
            StringBuilder sb = new StringBuilder();
            sb.AppendLine(ulCorner + h + urCorner);

            // box contents
            foreach (string line in lines)
            {
                double dblSpaces = (((double)width - (double)line.Length) / (double)2);
                int iSpaces = Convert.ToInt32(dblSpaces);

                if (dblSpaces > iSpaces) // not an even amount of chars
                {
                    iSpaces += 1; // round up to next whole number
                }

                string beginSpacing = "";
                string endSpacing = "";
                for (int i = 0; i < iSpaces; i++)
                {
                    beginSpacing += " ";

                    if (! (iSpaces > dblSpaces && i == iSpaces - 1)) // if there is an extra space somewhere, it should be in the beginning
                    {
                        endSpacing += " ";
                    }
                }
                // add the text line to the box
                sb.AppendLine(vertical + beginSpacing + line + endSpacing + vertical);
            }

            // box bottom
            sb.AppendLine(llCorner + h + lrCorner);

            // the finished box
            return sb.ToString();
        }

输出如下
输入图片此处描述

This is an extension method to String, which will draw a console box around a given string. Multi-line support included.

i.e.
string tmp = "some value"; Console.Write(tmp.DrawInConsoleBox());

        public static string DrawInConsoleBox(this string s)
        {
            string ulCorner = "╔";
            string llCorner = "╚";
            string urCorner = "╗";
            string lrCorner = "╝";
            string vertical = "║";
            string horizontal = "═";

            string[] lines = s.Split(new char[] { '\r', '\n' }, StringSplitOptions.RemoveEmptyEntries);
            

            int longest = 0;
            foreach(string line in lines)
            {
                if (line.Length > longest)
                    longest = line.Length;
            }
            int width = longest + 2; // 1 space on each side

            
            string h = string.Empty;
            for (int i = 0; i < width; i++)
                h += horizontal;

            // box top
            StringBuilder sb = new StringBuilder();
            sb.AppendLine(ulCorner + h + urCorner);

            // box contents
            foreach (string line in lines)
            {
                double dblSpaces = (((double)width - (double)line.Length) / (double)2);
                int iSpaces = Convert.ToInt32(dblSpaces);

                if (dblSpaces > iSpaces) // not an even amount of chars
                {
                    iSpaces += 1; // round up to next whole number
                }

                string beginSpacing = "";
                string endSpacing = "";
                for (int i = 0; i < iSpaces; i++)
                {
                    beginSpacing += " ";

                    if (! (iSpaces > dblSpaces && i == iSpaces - 1)) // if there is an extra space somewhere, it should be in the beginning
                    {
                        endSpacing += " ";
                    }
                }
                // add the text line to the box
                sb.AppendLine(vertical + beginSpacing + line + endSpacing + vertical);
            }

            // box bottom
            sb.AppendLine(llCorner + h + lrCorner);

            // the finished box
            return sb.ToString();
        }

Output like this
enter image description here

寻梦旅人 2024-11-14 03:39:33

喜欢这个

这对我有用:

Console.OutputEncoding = Encoding.GetEncoding(866);
Console.WriteLine("┌─┐");
Console.WriteLine("│1│");
Console.WriteLine("└─┘");

[编辑]

回答评论中的子问题:

Console.OutputEncoding = Encoding.GetEncoding(866);
Console.WriteLine("  ┌─┐");
Console.WriteLine("  │1│");
Console.WriteLine("┌─┼─┘");
Console.WriteLine("│1│");
Console.WriteLine("└─┘");

Like this?

This worked for me:

Console.OutputEncoding = Encoding.GetEncoding(866);
Console.WriteLine("┌─┐");
Console.WriteLine("│1│");
Console.WriteLine("└─┘");

[EDIT]

Answer to the sub-question in the comment:

Console.OutputEncoding = Encoding.GetEncoding(866);
Console.WriteLine("  ┌─┐");
Console.WriteLine("  │1│");
Console.WriteLine("┌─┼─┘");
Console.WriteLine("│1│");
Console.WriteLine("└─┘");
慕烟庭风 2024-11-14 03:39:33

您可以使用 CsConsoleFormat† 在控制台中使用 ASCII 边框符号进行绘制。

在具有“双”线的矩形内绘制数字:

ConsoleRenderer.RenderDocument(
    new Document()
        .AddChildren(
            new Border {
                    Stroke = LineThickness.Wide,
                    Align = HorizontalAlignment.Left
                }
                .AddChildren(1337)
        )
);

您可以更改 Stroke = LineThickness.Wide 线来更改线的样式。 LineThickness.Single 将生成细单线,new LineThickness(LineWidth.Single, LineWidth.Wide) 将生成单垂直线和双水平线。

它看起来像这样:

您还可以使用 ConsoleBuffer 类显式绘制线条(参数名称为清楚起见添加):

using static System.ConsoleColor;

var buffer = new ConsoleBuffer(width: 6);
buffer.DrawHorizontalLine(x: 0, y: 0, width: 6, color: White);
buffer.DrawHorizontalLine(x: 0, y: 2, width: 6, color: White);
buffer.DrawVerticalLine(x: 0, y: 0, height: 3, color: White);
buffer.DrawVerticalLine(x: 5, y: 0, height: 3, color: White);
buffer.DrawString(x: 1, y: 1, color: White, text: "1337");
new ConsoleRenderTarget().Render(buffer);

†​​ CsConsoleFormat 是我开发的。

You can use CsConsoleFormat† to draw with ASCII border symbols in console.

Drawing a number within a rectangle with "double" lines:

ConsoleRenderer.RenderDocument(
    new Document()
        .AddChildren(
            new Border {
                    Stroke = LineThickness.Wide,
                    Align = HorizontalAlignment.Left
                }
                .AddChildren(1337)
        )
);

You can change Stroke = LineThickness.Wide line to change the style of lines. LineThickness.Single would produce thin single lines, new LineThickness(LineWidth.Single, LineWidth.Wide) would produce single vertical and double horizontal lines.

Here's what it looks like:

You can also use ConsoleBuffer class to draw lines explicitly (argument names added for clarity):

using static System.ConsoleColor;

var buffer = new ConsoleBuffer(width: 6);
buffer.DrawHorizontalLine(x: 0, y: 0, width: 6, color: White);
buffer.DrawHorizontalLine(x: 0, y: 2, width: 6, color: White);
buffer.DrawVerticalLine(x: 0, y: 0, height: 3, color: White);
buffer.DrawVerticalLine(x: 5, y: 0, height: 3, color: White);
buffer.DrawString(x: 1, y: 1, color: White, text: "1337");
new ConsoleRenderTarget().Render(buffer);

† CsConsoleFormat was developed by me.

愛上了 2024-11-14 03:39:33

上面代码的问题是多余的空格,如果你绘制多个矩形,它会导致混乱。
这是一个递归绘制矩形而没有额外空格的代码。

public class AsciDrawing
{
    public static void TestMain() {
        var w = Console.WindowWidth;
        var h = Console.WindowHeight;
        RecursiveDraw(16, 8, new Point(w/2-8, h/2-4), ConsoleColor.Black);
        Console.CursorTop = h;
        Console.CursorLeft = 0;
    }
    public static void RecursiveDraw(int Width, int Height, Point Location, ConsoleColor BorderColor) { 
        if(Width < 4 || Height < 2) return;
        Draw(Width, Height, Location, BorderColor); //Commnet this draw and and Uncomment Draw bellow to see the difference. 
        Thread.Sleep(500);
        //Comment or Uncomment to see how many recursive calls you want to make
        //The best is to comment all execpt 1 and then uncomment 1 by 1
        RecursiveDraw(Width/2, Height/2, new Point(Location.X-Width/4, Location.Y-Height/4), ConsoleColor.Green); //Left Top
        RecursiveDraw(Width / 2, Height / 2, new Point(Location.X + 3* Width / 4, Location.Y + 3* Height / 4), ConsoleColor.Red); //Right Bottom
        RecursiveDraw(Width / 2, Height / 2, new Point(Location.X + 3* Width / 4, Location.Y - Height / 4), ConsoleColor.Blue); //Right Top
        RecursiveDraw(Width / 2, Height / 2, new Point(Location.X - Width / 4, Location.Y + 3* Height / 4), ConsoleColor.DarkMagenta); // Left Bottom
        
        //Draw(Width, Height, Location, BorderColor);

    }
    public static void Draw(int Width, int Height, Point Location, ConsoleColor BorderColor)
    {
        Console.ForegroundColor = BorderColor;

        string s = "╔";
        string temp = "";
        for (int i = 0; i < Width; i++)
            s += "═";

        s += "╗" + "\n";
        
        Console.CursorTop = Location.Y;
        Console.CursorLeft = Location.X;
        Console.Write(s);



        for (int i = 0; i < Height; i++) {
            Console.CursorTop = Location.Y + 1 + i;
            Console.CursorLeft = Location.X;
            Console.WriteLine("║");
            Console.CursorTop = Location.Y + 1 + i;
            Console.CursorLeft = Location.X + Width+1;
            Console.WriteLine("║");
        }
           

        s = temp + "╚";
        for (int i = 0; i < Width; i++)
            s += "═";

        s += "╝" + "\n";

        
        Console.CursorTop = Location.Y+Height;
        Console.CursorLeft = Location.X;
        Console.Write(s);
        Console.ResetColor();
    }
}

public record Point(int X, int Y);

Problem with above code is extra spaces, if you draw multiple rectangles, it causes mess.
here is a code which draw rectangles recursively without extra spaces.

public class AsciDrawing
{
    public static void TestMain() {
        var w = Console.WindowWidth;
        var h = Console.WindowHeight;
        RecursiveDraw(16, 8, new Point(w/2-8, h/2-4), ConsoleColor.Black);
        Console.CursorTop = h;
        Console.CursorLeft = 0;
    }
    public static void RecursiveDraw(int Width, int Height, Point Location, ConsoleColor BorderColor) { 
        if(Width < 4 || Height < 2) return;
        Draw(Width, Height, Location, BorderColor); //Commnet this draw and and Uncomment Draw bellow to see the difference. 
        Thread.Sleep(500);
        //Comment or Uncomment to see how many recursive calls you want to make
        //The best is to comment all execpt 1 and then uncomment 1 by 1
        RecursiveDraw(Width/2, Height/2, new Point(Location.X-Width/4, Location.Y-Height/4), ConsoleColor.Green); //Left Top
        RecursiveDraw(Width / 2, Height / 2, new Point(Location.X + 3* Width / 4, Location.Y + 3* Height / 4), ConsoleColor.Red); //Right Bottom
        RecursiveDraw(Width / 2, Height / 2, new Point(Location.X + 3* Width / 4, Location.Y - Height / 4), ConsoleColor.Blue); //Right Top
        RecursiveDraw(Width / 2, Height / 2, new Point(Location.X - Width / 4, Location.Y + 3* Height / 4), ConsoleColor.DarkMagenta); // Left Bottom
        
        //Draw(Width, Height, Location, BorderColor);

    }
    public static void Draw(int Width, int Height, Point Location, ConsoleColor BorderColor)
    {
        Console.ForegroundColor = BorderColor;

        string s = "╔";
        string temp = "";
        for (int i = 0; i < Width; i++)
            s += "═";

        s += "╗" + "\n";
        
        Console.CursorTop = Location.Y;
        Console.CursorLeft = Location.X;
        Console.Write(s);



        for (int i = 0; i < Height; i++) {
            Console.CursorTop = Location.Y + 1 + i;
            Console.CursorLeft = Location.X;
            Console.WriteLine("║");
            Console.CursorTop = Location.Y + 1 + i;
            Console.CursorLeft = Location.X + Width+1;
            Console.WriteLine("║");
        }
           

        s = temp + "╚";
        for (int i = 0; i < Width; i++)
            s += "═";

        s += "╝" + "\n";

        
        Console.CursorTop = Location.Y+Height;
        Console.CursorLeft = Location.X;
        Console.Write(s);
        Console.ResetColor();
    }
}

public record Point(int X, int Y);

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文