Search code examples
c#winformsmazereplay

I want to implement the replay function while making the maze game


RED SQUARE : PlayerPictureBox;

BLUE SQUARE : End Point;

BLACK SQUARE : WALL;

I have a maze organized in a PictureBox.

If the player arrives at the arrival point,

I want to implement a replay function that shows the path they found again, what should I do?

enter image description here

  public void CreateNewMaze()
    {
        mazeTiles = new PictureBox[XTILES, YTILES];
        for (int i = 0; i < XTILES; i++)
        {
            for (int j = 0; j < YTILES; j++)
            {
                mazeTiles[i, j] = new PictureBox();
                int xPosition = (i * TILESIZE) + 25;
                int yPosition = (j * TILESIZE) + 10;
                mazeTiles[i, j].SetBounds(xPosition, yPosition, TILESIZE, TILESIZE);

                this.Controls.Add(mazeTiles[i, j]);
            }
        }
    }


 protected override bool ProcessCmdKey(ref Message msg, Keys keyData)
    {
        int directionX = 0;
        int directionY = 0;
        switch (keyData)
        {
            case Keys.Left: directionX = -1;
                EndGame();
                break;

            case Keys.Right: directionX = 1;
                EndGame();
                break;

            case Keys.Up: directionY = -1;
                EndGame();
                break;

            case Keys.Down: directionY = 1;
                EndGame();
                break;

            default: return base.ProcessCmdKey(ref msg, keyData);
        }

        int x = directionX + (PlayerPictureBox.Left - 25) / TILESIZE;
        int y = directionY + (PlayerPictureBox.Top - 10) / TILESIZE;

        bool isRoad = mazeTiles[x, y].BackColor != Color.Black;
        if (isRoad)
        {
            PlayerPictureBox.Left += directionX * TILESIZE;
            PlayerPictureBox.Top += directionY * TILESIZE;
        }
        return true;
  
    }

Solution

    • Add each step (or move) to a list of steps.
    • Add Replay method that takes each step from this list, performs it and then waits for a while.
    • Clear the 'steps' list before each game (in CreateNewMaze for example).
    • Start playback when pressing Space, for example.

    So, add this code to you Form:

        class Step
        {
            public int dx;
            public int dy;
        }
    
        List<Step> steps = new List<Step>();
    
        async void Replay(int delay = 50)
        {
            int firstX = 1; // Initial player position, maybe you'll have to change it
            int firstY = 1; 
    
            PlayerPictureBox.Left = 25 + firstX * TILESIZE;
            PlayerPictureBox.Top = 10 + firstY * TILESIZE;
    
            var copy = steps.ToArray(); // Let's make a copy of steps array, to avoid possible conflicts with working array.
            foreach (var step in copy)
            {
                PlayerPictureBox.Left += step.dx * TILESIZE;
                PlayerPictureBox.Top += step.dy * TILESIZE;
    
                await Task.Delay(delay);
            }
        }
    

    Modify CreateNewMaze like this:

        public void CreateNewMaze()
        {
            // Add the following line
            steps.Clear();
    
            maze = new bool[XTILES, YTILES];
            //...
    

    Modify ProcessCmdKey like this:

        protected override bool ProcessCmdKey(ref Message msg, Keys keyData)
        {
            int directionX = 0;
            int directionY = 0;
            switch (keyData)
            {
                // Add the following:
                case Keys.Space:
                    Replay();
                    return true;
                // ...
    

    and below like this:

            // ...
            if (isRoad)
            {
                // Add the following line
                steps.Add(new Step { dx = directionX, dy = directionY });
    
                PlayerPictureBox.Left += directionX * TILESIZE;
                PlayerPictureBox.Top += directionY * TILESIZE;
            }
    

    I would recommend using a different PictureBox instance for playing back the steps, so that the user can continue playing while playback is running. But I'll leave it for you.