河内的塔楼:将钉子从钉子移动到钉子

you*_*ide 9 .net c# windows console

扩大我之前的帖子,我仍然在写河内塔.在解释了如何在钉子上画出环之后,我有一个很好的解决方案,我仍然有一个问题,我现在已经摆弄了很长一段时间.

这是我的PegClass:

namespace Towers_Of_Hanoi
{
    class PegClass
    {
        private int pegheight; 
        private int y = 3;
        int[] rings = new int[0];
        public PegClass()
        { 
            //this is the default constructor 
        }
        public PegClass(int height)
        { 
            pegheight = height; 
        }

        // other user defined functions 
        public void AddRing(int size)
        { 
            Array.Resize (ref rings, rings.Length + 2);
            rings[rings.Length - 1] = size;
        }

        public void DrawPeg(int x, int numberOfRings = 0)
        { 
            for (int i = pegheight; i >= 1; i--) 
            {
                string halfRing = new string (' ', i);
                if (numberOfRings > 0) 
                { 
                    if (i <= numberOfRings)
                        halfRing = new string ('-', numberOfRings - i + 1);

                }
                Console.SetCursorPosition(x - halfRing.Length * 2 + i + (halfRing.Contains("-") ? (-i + halfRing.Length) : 0), y);
                Console.WriteLine(halfRing + "|" + halfRing);
                y++;
            }
            if (x < 7) {
                x = 7;
            }
            Console.SetCursorPosition (x - 7, y); //print the base of the peg
            Console.WriteLine("----------------");
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

这是我的主要方法.

namespace Tower_of_hanoi
{
    class Program
    {
        static void Main(string[] args)
        {
            PegClass myPeg = new PegClass(8);
            PegClass myPeg2 = new PegClass(8);
            PegClass myPeg3 = new PegClass(8);
            DrawBoard(myPeg, myPeg2, myPeg3);
            Console.WriteLine ("\t\t\nWelcome to kTowers!");

            while (true) 
            {
                string input = "\nWhat peg do you want to move to commander?";
                Console.WriteLine (input);
                if (input == "2")
                {
                    myPeg.DrawPeg (2);
                }
                Console.ReadLine ();          
            }
        }

        public static void DrawBoard(PegClass peg1,PegClass peg2,PegClass peg3)
        {
            Console.Clear();
            peg1.DrawPeg(20,1);
            peg2.DrawPeg(40,2);
            peg3.DrawPeg(60,4);
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

这是当前的输出:

                |                   |                   |        
                |                   |                   |       
                |                   |                   |      
                |                   |                   |     
                |                   |                  -|-
                |                   |                 --|--
                |                  -|-               ---|---
               -|-                --|--             ----|----
         ----------------    ----------------    ----------------
Run Code Online (Sandbox Code Playgroud)

我的问题仍然是,当被要求提示时,如何将' - '字符从peg移动到peg.我已经尝试了几个小时调整它仍然无法搞清楚.

提前谢谢你,你在外面

ang*_*son 3

你已经将戒指显化为“这个钉子上有多少个戒指”,但这还不够。

例如,如果您有 8 个环,您将表示一个宽度为 1 的环、一个宽度为 2 的环、一个宽度为 3 的环,等等,最多一个宽度为 8 的环。

在您的图像中,您有 3 个宽度为 1 的环(每个钉子上的顶部一个环),2 个宽度为 2 的环(具有多个环的两个钉子上的第二个环),依此类推。这是不正确的,你的代码这样做的原因是它没有“这个特定环应该有多宽”的概念,而是绘制宽度为 1 的顶部环,宽度为 2 的下面的环,依此类推。

相反,这里有一组非常简单的对象来表示环和钉以及从一个移动到另一个的操作:

public void MoveRing(Peg fromPeg, Peg toPeg)
{
    toPeg.Push(fromPeg.Pop());
}

public class Peg : Stack<Ring>
{
}

public struct Ring
{
    public int Width { get; }
    public Ring(int width) { Width = width; }
}
Run Code Online (Sandbox Code Playgroud)

要创建 3 个钉子并在第一个钉子上堆叠 8 个环,您可以使用以下代码:

const int pegCount = 3;
const int ringCount = 8;

var pegs = Enumerable.Range(1, pegCount).Select(_ => new Peg()).ToList();

foreach (var ring in Enumerable.Range(1, ringCount).Select(width => new Ring(ringCount + 1 - width)))
    pegs[0].Push(ring);
Run Code Online (Sandbox Code Playgroud)

为了绘制它们,我冒昧地充实了一个LINQPad程序,该程序绘制它们进行演示,但您可以轻松地将其调整为您现在拥有的控制台代码:

void Main()
{
    const int pegCount = 3;
    const int ringCount = 8;

    var pegs = Enumerable.Range(1, pegCount).Select(_ => new Peg()).ToList();

    foreach (var ring in Enumerable.Range(1, ringCount).Select(width => new Ring(ringCount + 1 - width)))
        pegs[0].Push(ring);

    DrawPegs(pegs);
    MoveRing(pegs[0], pegs[1]);
    DrawPegs(pegs);
}

public void MoveRing(Peg fromPeg, Peg toPeg)
{
    toPeg.Push(fromPeg.Pop());
}

public class Peg : Stack<Ring>
{
}

public struct Ring
{
    public int Width { get; }
    public Ring(int width) { Width = width; }
}

public void DrawPegs(IEnumerable<Peg> pegs)
{
    var bitmaps = pegs.Select(peg => DrawPeg(peg));
    Util.HorizontalRun(true, bitmaps).Dump();
}

public Bitmap DrawPeg(Peg peg)
{
    const int width = 200;
    const int height = 300;
    const int pegWidth = 6;
    const int ringHeight = 20;
    const int ringWidthFactor = 10;
    const int ringGapHeight = 3;

    var result = new Bitmap(width, height);
    using (var g = Graphics.FromImage(result))
    {
        g.Clear(Color.White);

        g.FillRectangle(Brushes.Black, width / 2 - pegWidth/2, 0, pegWidth, height);
        int y = height;
        foreach (var ring in peg.Reverse())
        {
            y -= ringHeight;
            g.FillRectangle(Brushes.Blue, width / 2 - ring.Width * ringWidthFactor, y, 2 * ring.Width * ringWidthFactor, ringHeight);
            y -= ringGapHeight;
        }
    }
    return result;
}
Run Code Online (Sandbox Code Playgroud)

输出:

钉子和环