Overload method error in c# console application - c#

I have a class that creates a Box that have different colors on the border. I get an error on my code that says "No overload for method 'SetCursorPosition' takes 3 arguments. Here is my code:
class TitledBox : ColoredBox
{
private string title;
private ConsoleColor titleColor;
public TitledBox(Point p, int width, int height, ConsoleColor backColor, string title, ConsoleColor titleColor)
: base(p, width, height, backColor)
{
if (title.Length > width)
this.title = title.Substring(0, width);
else
this.title = title;
this.titleColor = titleColor;
}
public override void Draw()
{
for (int j = 0; j < height; j++)
{
Console.SetCursorPosition(p.X, p.Y, + j);
Console.BackgroundColor = backColor;
if ( j == 0)
{
Console.ForegroundColor = titleColor;
Console.Write(title);
for (int i = 0; i < width - title.Length; i++)
{
Console.Write(' ');
}
}
else
{
for (int i = 0; i < width; i++)
Console.Write(' ');
}
}
}
}
Any ideas on what I'm doing wrong?

Your Console.SetCursorPosition should be like below
Console.SetCursorPosition(int Left, int Top);

The Method Console.SetCursorPosition gets only 2 int parameters.
You specified 3 parameters. I think you meant to say:
//the second comma was deleted
Console.SetCursorPosition(p.X, p.Y + j);
source: http://msdn.microsoft.com/en-us/library/system.console.setcursorposition.aspx

Console.SetCursorPosition(p.X, p.Y, + j);
should be
Console.SetCursorPosition(p.X, p.Y + j);

Related

Console not printing fast enough c#

I am writing a small libary to draw "graphics" to a console to make writing console games easier, but whenever a frame is renedered, it is very slow
I am new to c#, however I have been coding for 8 months.
I have optimized it as much as I can but I have had no succsess(keep in mind i'm writing this on an ASUS 2016 laptop)
So here is the code:
Console.Title = "Pyrite";
int winWidth = Console.BufferWidth;
int winHeight = Console.BufferHeight / 190;
char[,] screen = new char[winWidth, winHeight];
ConsoleColor[,] screenColours = new ConsoleColor[winWidth, winHeight];
for(int j = 0; j < screen.GetLength(1); j += 1){
for(int i = 0; i < screen.GetLength(0); i += 1){
screenColours[i, j] = ConsoleColor.Green;
screen[i, j] = '■';
}
}
void drawPixel(int x, int y, char character, ConsoleColor colour){
screenColours[x, y] = colour;
screen[x, y] = character;
}
void drawRect(int x, int y, int width, int height, char character, bool outlineOnly, ConsoleColor colour){
if(!outlineOnly){
for(int j = 0; j < height + 1; j += 1){
for(int i = 0; i < width + 1; i += 1){
drawPixel(i + x, j + y, character, colour);
}
}
}else{
for(int i = 0; i < width + 1; i += 1){
drawPixel(x + i, y, character, colour);
}
for(int i = 0; i < width + 1; i += 1){
drawPixel(x + i, y + height, character, colour);
}
for(int i = 0; i < height + 1; i += 1){
drawPixel(x, y + i, character, colour);
}
for(int i = 0; i < height + 1; i += 1){
drawPixel(x + width, y + i, character, colour);
}
}
}
void draw(){
for(int j = 0; j < screen.GetLength(1); j += 1){
for(int i = 0; i < screen.GetLength(0); i += 1){
Console.ForegroundColor = screenColours[i, j];
Console.Write(screen[i, j]);
}
}
}
while(true){
drawPixel(20, 20, '■', ConsoleColor.Cyan);
drawRect(0, 0, 25, 15, '■', true, ConsoleColor.DarkMagenta);
draw();
Console.Clear();
Console.ResetColor();
}
Console.ReadKey();

How to Correctly Assign values from a text file to a 2d Matrix in C#

I am going through a problem I cannot see the way out though it is simple.
I am reading a file and assigning it to an array:
string[] lines = File.ReadAllLines(#"C:\Users\\Documents\Visual Studio 2017\Projects\TheMaze\TheMaze\Data\" + FileName + ".txt");
map = new MapFile();
int width = lines[0].Replace(" ", "").Length;
int height = lines.Length;
map.Matrix = new byte[width, height];
for (int y = 0; y < height; y++)
{
string line = lines[y].Replace(" ", "");
for (int x = 0; x < line.Length;x++)
{
//
}
Console.ReadKey();
}
}
return map;
}
I just dont get how to assign the values from the file correctly to my matrix object.
To which variable the values should be assigned?
I tried map.Matrix[x,y] = line[x]
but I get an error since I have to convert x to byte.
on my class MapFile I have only this variable: public byte[,] Matrix = null;
If I convert line[x] to byte all the values are printed later as 35.
I am kind of completely lost and appreciate any help.
That is just a text file I manually wrote.
The short version just for fun :]
string text = File.ReadAllText(#"..\..\Data\" + FileName + ".txt");
foreach (char c in text.Replace(" ", ""))
{
Console.BackgroundColor = Console.ForegroundColor = (ConsoleColor)(c & 15);
Console.Write(c);
}
I added the variables height and width to my MapFile Class to make it easier to track the size of the array.
The code was changed only from here:
for (int y = 0; y < map.height; y++)
{
string line = lines[y].Replace(" ", "");
for (int x = 0; x < map.width;x++)
{
map.Matrix[x,y] = Convert.ToByte(line[x]);
if (line[x] == '#')
{
map.Matrix[x, y] = 1;
}
if (line[x] == '.')
{
map.Matrix[x, y] = 2;
}
if (line[x] == 'S')
{
map.Matrix[x, y] = 3;
}
if (line[x] == 'F')
{
map.Matrix[x, y] = 5;
}
}
}
And on my MapDisplay class I have now:
for(int y = 0; y < map.height; y++)
{
Console.WriteLine();
for (int x = 0; x<map.width; x++)
{
Console.Write(map.Matrix[x, y]);
}
}
With the Right output from my matrix:
Now to make the Maze Look a little bit better I changed the Background and Foregound color of the output this way:
for(int y = 0; y < map.height; y++)
{
Console.WriteLine();
for (int x = 0; x<map.width; x++)
{
if (map.Matrix[x, y] == 3)
{
Console.BackgroundColor = ConsoleColor.Green;
Console.ForegroundColor = ConsoleColor.Green;
Console.Write("3");
Console.ResetColor();
}
else if (map.Matrix[x, y] == 2)
{
Console.BackgroundColor = ConsoleColor.Blue;
Console.ForegroundColor = ConsoleColor.Blue;
Console.Write("2");
Console.ResetColor();
}
else if (map.Matrix[x, y] == 5)
{
Console.BackgroundColor = ConsoleColor.Green;
Console.ForegroundColor = ConsoleColor.Green;
Console.Write("5");
Console.ResetColor();
}
else if (map.Matrix[x, y] == 1)
{
Console.BackgroundColor = ConsoleColor.DarkRed;
Console.ForegroundColor = ConsoleColor.DarkRed;
Console.Write("1");
}
}
}
Output with different colours:

Rotating matrices

Objectives
Imagine that, we have matrix like
a11 a12 a13
a21 a22 a23
a31 a32 a33
What I want to do is, from textbox value rotate this matrix so that, for example if I write 2 and press rotate, program must keep both diagonal values of matrix (in this case a11, a22, a33, a13, a31) and rotate 2 times clockwise other values. So result must be like
a11 a32 a13
a23 a22 a21
a31 a12 a33
It must work for all N x N size matrices, and as you see every 4 rotation takes matrix into default state.
What I've done
So idea is like that, I have 2 forms. First takes size of matrix (1 value, for example if it's 5, it generates 5x5 matrix). When I press OK it generates second forms textbox matrix like that
Form 1 code
private void button1_Click(object sender, EventArgs e)
{
int matrixSize;
matrixSize = int.Parse(textBox1.Text);
Form2 form2 = new Form2(matrixSize);
form2.Width = matrixSize * 50 + 100;
form2.Height = matrixSize *60 + 200;
form2.Show();
//this.Hide();
}
Form 2 code generates textbox matrix from given value and puts random values into this fields
public Form2(int matrSize)
{
int counter = 0;
InitializeComponent();
TextBox[] MatrixNodes = new TextBox[matrSize*matrSize];
Random r = new Random();
for (int i = 1; i <= matrSize; i++)
{
for (int j = 1; j <= matrSize; j++)
{
var tb = new TextBox();
int num = r.Next(1, 1000);
MatrixNodes[counter] = tb;
tb.Name = string.Format("Node_{0}{1}", i, j);
Debug.Write(string.Format("Node_{0}{1}", i, j));
tb.Text = num.ToString();
tb.Location = new Point(j * 50, i * 50);
tb.Width = 30;
tb.Visible = true;
this.splitContainer1.Panel2.Controls.Add(tb);
counter++;
}
}
}
Form 2 has 1 textbox for controlling rotation (others are generated on the fly, programmatically). What I want to do is, when I enter rotation count and press Enter on this textbox, I want to rotate textbox matrix as I explained above. Can't figure out how to do it.
Copy both diagonals to separate arrays, then rotate your matrix and replace diagonals. Below code shows each step:
class Program
{
static void Main(string[] args)
{
int matrixSize = 3;
string[,] matrix = new string[matrixSize,matrixSize];
//create square matrix
for (int x = 0; x < matrixSize; x++)
{
for (int y = 0; y < matrixSize; y++)
{
matrix[x, y] = "a" + (x + 1).ToString() + (y + 1).ToString();
}
}
Console.WriteLine(Environment.NewLine + "Base square matrix");
for (int x = 0; x < matrixSize; x++)
{
for (int y = 0; y < matrixSize; y++)
{
Console.Write(matrix[x, y] + " ");
}
Console.Write(Environment.NewLine);
}
Console.ReadKey();
//copy diagonals
string[] leftDiagonal = new string[matrixSize];
string[] rightDiagonal = new string[matrixSize];
for (int x = 0; x < matrixSize; x++)
{
leftDiagonal[x] = matrix[x, x];
rightDiagonal[x] = matrix[matrixSize - 1 - x, x];
}
Console.WriteLine(Environment.NewLine + "Diagonals");
for (int x = 0; x < matrixSize; ++x)
{
Console.Write(leftDiagonal[x] + " " + rightDiagonal[x] + Environment.NewLine);
}
Console.ReadKey();
//rotate matrix
string[,] rotatedMatrix = new string[matrixSize, matrixSize];
for (int x = 0; x < matrixSize; x++)
{
for (int y = 0; y < matrixSize; y++)
{
rotatedMatrix[x, y] = matrix[matrixSize - y - 1, x];
}
}
Console.WriteLine(Environment.NewLine + "Rotated");
for (int x = 0; x < matrixSize; x++)
{
for (int y = 0; y < matrixSize; y++)
{
Console.Write(rotatedMatrix[x, y] + " ");
}
Console.Write(Environment.NewLine);
}
Console.ReadKey();
//rotate matrix again
string[,] rotatedMatrixAgain = new string[matrixSize, matrixSize];
for (int x = 0; x < matrixSize; x++)
{
for (int y = 0; y < matrixSize; y++)
{
rotatedMatrixAgain[x, y] = rotatedMatrix[matrixSize - y - 1, x];
}
}
Console.WriteLine(Environment.NewLine + "Rotated again");
for (int x = 0; x < matrixSize; x++)
{
for (int y = 0; y < matrixSize; y++)
{
Console.Write(rotatedMatrixAgain[x, y] + " ");
}
Console.Write(Environment.NewLine);
}
Console.ReadKey();
//replace diagonals
for (int x = 0; x < matrixSize; x++)
{
rotatedMatrixAgain[x, x] = leftDiagonal[x];
rotatedMatrixAgain[matrixSize - 1 - x, x] = rightDiagonal[x];
}
Console.WriteLine(Environment.NewLine + "Completed" + Environment.NewLine);
for (int x = 0; x < matrixSize; x++)
{
for (int y = 0; y < matrixSize; y++)
{
Console.Write(rotatedMatrixAgain[x, y] + " ");
}
Console.Write(Environment.NewLine);
}
Console.ReadKey();
}
}
I don't know C#, so I can only give a suggestion in pseudocode:
Input: An N by N matrix in
Output: The input matrix rotated as described in the OP out
for i = 1 to N
for j = 1 to N
if N - j != i and i != j // Do not change values on either diagonal
out[j][N-i] = in[i][j]
else
out[i][j] = in[i][j]
Disclaimer: This algorithm is untested. I suggest you use a debugger to check that it works as you want.
This seems like quite an unorthodox UI presentation, but you're not too far off in terms of being able to achieve your functionality. Instead of a linear array, a rectangular array will make your job much easier. The actual rotation could be implemented with a for loop repeating a single rotation (which would be implemented as in the case 1 code), but I've decided to combine them into the four possible cases. This actually allows you to enter a negative number for number of rotations. Which reminds me, you really should do more error checking. At least protect against int.Parse throwing an exception both places it's used (with a try catch block or by switching to int.TryParse) and make sure it returns a meaningful number (greater than 0, possibly set a reasonable maximum other than int.MaxValue) for matrixSize in button1_Click.
namespace RotatingMatrices
{
public class Form2 : Form
{
// note these class fields
private TextBox[,] matrixNodes;
private int matrixSize;
public Form2(int matrSize)
{
InitializeComponent();
// note these inits
matrixSize = matrSize;
matrixNodes = new TextBox[matrixSize, matrixSize];
Random r = new Random();
// note the new loop limits
for (int i = 0; i < matrixSize; i++)
{
for (int j = 0; j < matrixSize; j++)
{
var tb = new TextBox();
int num = r.Next(1, 1000);
// note the change in indexing
matrixNodes[i,j] = tb;
tb.Name = string.Format("Node_{0}_{1}", i, j);
Debug.Write(string.Format("Node_{0}_{1}", i, j));
tb.Text = num.ToString();
tb.Location = new Point(j * 50, i * 50);
tb.Width = 30;
tb.Visible = true;
this.splitContainer1.Panel2.Controls.Add(tb);
}
}
}
private void buttonRotate_Click(object sender, EventArgs e)
{
string[,] matrix = new string[matrixSize, matrixSize];
int rotations = (4 + int.Parse(textBoxRotations.Text)) % 4; // note the addition of and mod by 4
switch(rotations)
{
case 1: // rotate clockwise
for (int i = 0; i < matrixSize; i++)
{
for (int j = 0; j < matrixSize; j++)
{
matrix[j, matrixSize - i - 1] = matrixNodes[i, j].Text;
}
}
break;
case 2: // rotate 180 degrees
for (int i = 0; i < matrixSize; i++)
{
for (int j = 0; j < matrixSize; j++)
{
matrix[i, j] = matrixNodes[matrixSize - i - 1, matrixSize - j - 1].Text;
}
}
break;
case 3: // rotate counter-clockwise
for (int i = 0; i < matrixSize; i++)
{
for (int j = 0; j < matrixSize; j++)
{
matrix[i, j] = matrixNodes[j, matrixSize - i - 1].Text;
}
}
break;
default: // do nothing
return;
}
// restore diagonals
for(int i = 0; i < matrixSize; i++)
{
matrix[i, i] = matrixNodes[i, i].Text;
matrix[i, matrixSize - i - 1] = matrixNodes[i, matrixSize - i - 1].Text;
}
// write strings back to text boxes
for (int i = 0; i < matrixSize; i++)
{
for (int j = 0; j < matrixSize; j++)
{
matrixNodes[i, j].Text = matrix[i, j];
}
}
}
}
}
I decided to tackle the issue using a listView instead of a text box, which makes the logic easier for me. Using this method, I was able to think of the matrix as successive boxes. I start on the outside and move in toward the middle, changing the size of my box each time.
Also, rather than using two forms, I use one. At the top I have a textbox where the user enters the size they want the array to be, and a button labeled "Fill" (button2). And at the bottom I have a textbox where the user enters the degree of rotation. When they click "Rotate," it kicks off a process of adding values to linked lists, combining and shifting the list, and then writing back out to the matrix. I'm sure I made it more convoluted than it has to be, but it was a great learning exercise.
After looking over jerry's code above, I think I'm going to look into rectangular arrays. :)
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
namespace Recycle
{
public partial class Form1 : Form
{
public int size;
public LinkedList<string> topRight = new LinkedList<string>();
public LinkedList<string> bottomLeft = new LinkedList<string>();
public LinkedList<string> myMatrix = new LinkedList<string>();
public LinkedList<string> shiftMatrix = new LinkedList<string>();
public Form1()
{
InitializeComponent();
}
private void button2_Click(object sender, EventArgs e)
{
listView1.Clear();
size = int.Parse(textBox2.Text);
int c = 0;
int q = 0;
int w = 0;
string[] content = new string[size];
Random rnd = new Random();
for (c = 0; c < size; c++)
{
listView1.Columns.Add("", 25);
}
for (q = 0; q < size; q++)
{
for (w = 0; w < size; w++)
{
content[w] = rnd.Next(9,100).ToString();
}
ListViewItem lvi = new ListViewItem(content);
listView1.Items.Add(lvi);
}
}
public bool iseven(int size)
{
if (size % 2 == 0)
{
return true;
}
else
{
return false;
}
}
public void button1_Click(object sender, EventArgs e)
{
if (listView1.Items.Count < 3)
{
MessageBox.Show("Matrix cannot be rotated.");
return;
}
bool even = false;
int shift = int.Parse(textBox1.Text); //amount to shift by
int box = listView1.Items.Count - 1; //size of box
int half = Convert.ToInt32(listView1.Items.Count / 2);
int corner = 0; //inside corner of box
if (shift > listView1.Items.Count)
{
shift = shift % ((listView1.Items.Count - 2) * 4);
}
do
{
eachPass(shift, box, corner);
++corner;
--box;
} while (box >= half + 1);
}
public void eachPass(int shift, int box, int corner)
{
int x;
int i;
//Read each non-diagonal value into one of two lists
for (x = corner + 1; x < box; x++)
{
topRight.AddLast(listView1.Items[corner].SubItems[x].Text);
}
x = box;
for (i = corner + 1; i < box; i++)
{
topRight.AddLast(listView1.Items[i].SubItems[x].Text);
}
for (x = box - 1; x > corner; x--)
{
bottomLeft.AddLast(listView1.Items[box].SubItems[x].Text);
}
x = corner;
for (i = box - 1; i > corner; i--)
{
bottomLeft.AddLast(listView1.Items[i].SubItems[x].Text);
}
string myTest = "";
//join the two lists, so they can be shifted
foreach (string tR in topRight)
{
myMatrix.AddLast(tR);
}
foreach (string bL in bottomLeft)
{
myMatrix.AddLast(bL);
}
int sh;
//shift the list using another list
for (sh = shift; sh < myMatrix.Count; sh++)
{
shiftMatrix.AddLast(myMatrix.ElementAt(sh));
}
for (sh = 0; sh < shift; sh++)
{
shiftMatrix.AddLast(myMatrix.ElementAt(sh));
}
//we need the sizes of the current lists
int trCnt = topRight.Count;
int blCnt = bottomLeft.Count;
//clear them for reuse
topRight.Clear();
bottomLeft.Clear();
int s;
//put the shifted values back
for (s = 0; s < trCnt; s++)
{
topRight.AddLast(shiftMatrix.ElementAt(s));
}
for (s = blCnt; s < shiftMatrix.Count; s++)
{
bottomLeft.AddLast(shiftMatrix.ElementAt(s));
}
int tRn = 0;
int bLn = 0;
//write each non-diagonal value from one of two lists
for (x = corner + 1; x < box; x++)
{
listView1.Items[corner].SubItems[x].Text = topRight.ElementAt(tRn);
++tRn;
}
x = box;
for (i = corner + 1; i < box; i++)
{
listView1.Items[i].SubItems[x].Text = topRight.ElementAt(tRn);
++tRn;
}
for (x = box - 1; x > corner; x--)
{
listView1.Items[box].SubItems[x].Text = bottomLeft.ElementAt(bLn);
++bLn;
}
x = corner;
for (i = box - 1; i > corner; i--)
{
listView1.Items[i].SubItems[x].Text = bottomLeft.ElementAt(bLn);
++bLn;
}
myMatrix.Clear();
shiftMatrix.Clear();
topRight.Clear();
bottomLeft.Clear();
}
}
}

Writing stars with specific shape

i want to write a shape with " * " and " | " the shape is below.
The program must take height and width from user.Width is column number without ' | '.I tried to write but confused.My code sometimes works great and sometimes being stupid.For example when i enter height : 13, width : 4 it writes one more,if witdh is 1 it enters infinite loop.While trying to solve it became too conflicted.Must i fix it or rewrite ? Here is the code : height =10, width = 5
|*____|
|_*___|
|__*__|
|___*_|
|____*|
|___*_|
|__*__|
|_*___|
|*____|
|_*___|
private static void Function()
{
int height, width;
if (width == 2)
while (height > 0)
{
FirstPart(width, height);
height -= width;
}
else
while (height > 0)
{
if (height > 1)
{
FirstPart(width, height);
height -= width;
}
if (height > 0)
{
SecondPart(width, height);
height -= width - 2;
}
}
}
private static void FirstPart(int width,int height)
{
if(height > width)
for (int i = 0; i < width; i++)
{
for (int j = 0; j < width+2; j++)
{
if (j == 0 || j == width + 1)
Console.Write("|");
else
if (i + 1 == j)
Console.Write("*");
else
Console.Write(" ");
}
Console.WriteLine();
}
else
for (int i = 0; i < height; i++)
{
for (int j = 0; j < width + 2; j++)
{
if (j == 0 || j == width + 1)
Console.Write("|");
else
if (i + 1 == j)
Console.Write("*");
else
Console.Write(" ");
}
Console.WriteLine();
}
}
private static void SecondPart(int width,int height)
{
if(height > width)
for (int i = 0; i < width-2; i++)
{
for (int j = 0; j < width+2; j++)
{
if (j == 0 || j == width + 1)
Console.Write("|");
else
if (i + j == width-1)
Console.Write("*");
else
Console.Write(" ");
}
Console.WriteLine();
}
else
for (int i = 0; i < height; i++)
{
for (int j = 0; j < width + 2; j++)
{
if (j == 0 || j == width + 1)
Console.Write("|");
else
if (i + j == width - 1)
Console.Write("*");
else
Console.Write(" ");
}
Console.WriteLine();
}
}
private static void WriteStars(int width, int height)
{
int j = 0;
for (int i = 0; i < height; i++)
{
Console.Write("|");
for (int f = 0; f < width; f++)
{
if (f == Math.Abs(j))
{
Console.Write("*");
}
else
{
Console.Write(" ");
}
}
j++;
if (Math.Abs(j) == width - 1)
{
j *= -1;
}
Console.WriteLine("|");
}
}
Probably going to get downvoted for giving you a complete answer, but maybe it'll show you one correct approach and you can learn something from it...
I see a
while (Height > 0)
so your infinite loop is coming from Height never getting less or equal to 0.
It's better to rewrite. When you do, decouple the code into several functions so that one function draws a single line, and another one calls the former to draw all the lines.
void WriteStars(int Width,int Height)
{
int _sp=1; //Star Pos
bool _left = false;
for(int i =0;i<Height;i++)
{
Console.Write("|");
int j;
for(j=1;j<Width-1;j++)
{
if(j==_sp)
{
Console.Write("*");
if(_left)
{
_sp--;
}
else
{
_sp++;
}
j++;
break;
}
else
{
Console.Write("_");
}
}
for(;j<Width-1;j++)
{
Console.Write("_");
}
Console.WriteLine("|");
if(_sp==0)
{
_left = false;
}
else if(_sp==Width)
{
_left = true;
}
}
}
Try if it works, wrote it right here.
even shorter:
static void Variante_2(int height, int width)
{
byte[][] arr = new byte[height][];
int pos = 0;
int mov = 1;
for (int line = 0; line < height; line++)
{
arr[line] = new byte[width];
for (int col = 0; col < width; col++) { arr[line][col] = 45; }
arr[line][pos] = 42;
pos += mov;
if (pos == 0 || pos == (width - 1)) { mov *= -1; }
Console.WriteLine("|" + ASCIIEncoding.ASCII.GetString(arr[line]) + "|");
}
string temp = Console.ReadLine();
}
and it is possible to do it with less code:
static void Variante_3(int height, int width)
{
int pos = 1;
int mov = 1;
for (int line = 0; line < height; line++)
{
Console.WriteLine("|" + "*".PadLeft(pos, '_') + "|".PadLeft(width - pos, '_'));
pos += mov;
if (pos == 1 || pos == (width - 1)) { mov *= -1; }
}
string temp = Console.ReadLine();
}
Sorry to all not doing others homework, but I couldn´t sleep without showing this g

How to draw a rectangle in console application?

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.
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();
}
}
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
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("└─┘");
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.
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);

Categories