Search code examples
c#undotablelayoutpanelredo

How to add UNDO and REDO buttons to TableLayout panel in C#


I'm making game where you put 8 queens on chess board so no queen attack any other. It is for my homework. enter image description here

I used TableLayoutPanel 8x8 with PictureBox in every cell. They change color or picture on click and show user which one cell is available. But I wanted to implement Undo, so user can go step back if he does not like where he positioned his queen. I googled a lot, but every single undo-redo solution is about integers and strings, and I do not have idea how to use it for my table panel. Do you guys have any idea how to do that? I tried to make another copy-panel and copy original one into it, before changing color happens, and if I want to undo, to actually show copy-panel but for some reason it does not work.

If it is already answered somewhere how to make undo for TableLayoutPanel can you please guide me to that guide?

  private void pictureBox1_Click(object sender, EventArgs e)
    {
        PictureBox picture =  (PictureBox)sender;
        //checking if cell is empty 
        if(picture.BackColor==Color.White)
        { 
            picture.Image = Properties.Resources.kraljica;

            int column = tableLayoutPanel1.GetCellPosition(picture).Column;
            int row = tableLayoutPanel1.GetCellPosition(picture).Row;

            int j = column;
            int i = row;
            //changing color of down right diagonal according to current position of queen
            while (i <= 7 && j <= 7)
            {
                tableLayoutPanel1.GetControlFromPosition(j, i).BackColor = Color.DarkRed;
                i++;
                j++;                  
            }

Solution

  • Welcome to the StackOverFlow.

    Normally, we'd ask you to provide some code to help us out in solving your problem, but I'll try and give you some pointers without.

    You need to keep a history of past moves, in this case this would be a history of cell locations for where a queen started to where it ended up.

    I suspect that you must be using an OnClick event or something similar to determine which queen is selected and where it is moved to - if not then the logic would still be the same.

    You want to use the GetRow and GetColumn methods of the TableLayoutPanel control and store the result in a List control e.g.

    public class Move
        {
          int startRow;
          int startColumn;
          int endRow;
          int endColumn;
        }
    

    then in your code have properties

    public List<Move> ListOfMoves = new List<Move>();
    public SelectedMoveIndex {get;set;}
    

    Everytime a new move is made add a new Move instance with populated values to the List

    e.g.

    ListOfMoves.Add(new Move(){startRow = x1, startColumn=y1, endRow=x2, endColumn=y2};
    SelectedMoveIndex = ListOfMoves.Count -1;
    

    where x1, y1, x2, y2 have values taken from GetRow() & GetColumn() on move start and move end.

    To undo a move use the Move values stored at SelectedMoveIndex and play the backwards e.g endRow and endColumn become the start values then decrement the value of SelectedMoveIndex. Redo would use the values as stored at SelectedMoveIndex and then increment SelectedMoveIndex afterwards.

    If you make a new move that isn't stored then you'll need to remove elements after SelectedMoveIndex before adding a new one.