1

I am using a 2D array to display Sudoku grids in command line and I want to change the colour of a number which is selected by the user through arrow keys. I have everything except the highlighting part.

Is there a way to change the colour of a selected number in a 2d array? Or would there be some other, more efficient way of doing that?

Lee Taylor
  • 7,761
  • 16
  • 33
  • 49
Dano
  • 11
  • 5
  • What console/stdout/terminal API are you using? If you're using only `System.Console` then your options are limited - how have you implemented that cursor functionality? – Dai Apr 18 '22 at 13:05
  • If you are using SystemConsole, this can help you: https://stackoverflow.com/questions/54218692/multi-colored-characters-in-a-single-line-c-sharp-console – J.Salas Apr 18 '22 at 13:09
  • Maybe you can use [ConsoleColor](https://learn.microsoft.com/en-us/dotnet/api/system.consolecolor?view=net-6.0), but only when you have a console application... – Luuk Apr 18 '22 at 13:09
  • I am building with VSC2022 for Windows cmd. Yes, the value in 0,0 coordinates is copied and based off of that position, arrow clicks increase the counter, updating the position and displaying the selected number. Then the position is saved and when the user chooses another number, it gets updated that way. – Dano Apr 18 '22 at 13:12
  • I suppose maybe I could call the display loop every time the user presses an arrow and add an exception to the coordinates, which would highlight that one given location. I'm going to give it a go now – Dano Apr 18 '22 at 13:14
  • It seems to be half-working, but it highlights the correct selected text(almost). Is there a way to speed up a while loop? I need to press an arrow a couple times until it picks it up – Dano Apr 18 '22 at 13:34
  • Show us the code that draws on the console. You cannot read (easily) what is already written, so you need to redraw by setting the colors each time. – JAlex Apr 18 '22 at 13:40

2 Answers2

0

Thank you all for your input, I have found the solution:

  • Get position of the item to be highlighted
  • Call the Display function again
  • Add an if statement in the 2D array's for loop and pass it the coordinates
  • Change the color in the if statement and change it right back again outside of it

Its not efficient and looks ugly but it works well.

Sorry I couldn't share the code.

Dano
  • 11
  • 5
0

If you want an effect like this

scr1

then you have to handle it in the drawing routine.

The example above is done with

public class Matrix
{
    int[,] data;

    public Matrix(int rows, int columns)
    {
        Rows = rows;
        Columns = columns;
        data = new int[rows, columns];
    }

    internal int[,] Data => data;

    public int Rows { get; }
    public int Columns { get; }

    public ref int this[int row, int col]
        => ref data[row, col];

    public void DrawConsole(int rowCurrent, int colCurrent)
    {
        var fg = Console.ForegroundColor;
        var bk = Console.BackgroundColor;
        var curX = Console.CursorLeft;
        var curY = Console.CursorTop;

        const int width = 7;

        for (int i = 0; i < Rows; i++)
        {
            for (int j = 0; j < Columns; j++)
            {
                Console.SetCursorPosition(width * j + 3, i * 2 + 2);
                Console.ForegroundColor = ConsoleColor.Gray;
                Console.BackgroundColor = ConsoleColor.Black;
                Console.Write(" ");
                if (i == rowCurrent && j == colCurrent)
                {
                    Console.ForegroundColor = ConsoleColor.Black;
                    Console.BackgroundColor = ConsoleColor.DarkCyan;
                }
                else
                {
                    Console.ForegroundColor = ConsoleColor.DarkBlue;
                    Console.BackgroundColor = ConsoleColor.Gray;
                }
                Console.Write(CenteredText(this[i, j].ToString(), width-1));
            }
        }

        Console.SetCursorPosition(curX, curY);
        Console.ForegroundColor = fg;
        Console.BackgroundColor = bk;
    }

    public static string CenteredText(string text, int width)
    {
        if (text.Length >= width) return text;
        int spaces = width- text.Length;
        return text.PadRight(spaces / 2 + text.Length).PadLeft(width);
    }
}
class Program
{
    static void Main(string[] args)
    {
        var grid = new Matrix(9, 9);
        int index = 0;
        for (int i = 0; i < grid.Rows; i++)
        {
            for (int j = 0; j < grid.Columns; j++)
            {
                grid[i, j] = ++index;
            }
        }

        grid.DrawConsole(3, 6);
    }
}

The if (i == rowCurrent && j == colCurrent) line branches off for the highlighted cell changing the display colors before writing the text out.

JAlex
  • 1,486
  • 8
  • 19