2016-01-08 107 views
9

擴大我以前的職位,我仍然在寫河內塔。在解釋瞭如何在釘上畫環之後,我仍然有一個問題,現在我已經擺弄了很長一段時間了。河內塔:從釘掛環到掛鉤

這裏是我的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("----------------"); 
     } 
    } 
} 

這是我的主要方法。

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); 
     } 
    } 
} 

這是電流輸出:

   |     |     |   
       |     |     |  
       |     |     |  
       |     |     |  
       |     |     -|- 
       |     |     --|-- 
       |     -|-    ---|--- 
       -|-    --|--    ----|---- 
     ---------------- ---------------- ---------------- 

我的問題是,一個人如何在移動「 - 」字符從釘住釘住當被問及對於一個提示。我已經嘗試了幾個小時的調整,仍然無法弄清楚。

謝謝你在前進,youmeoutside

+1

歡迎堆棧溢出!請在下次發佈問題時,能否正確縮進?它不僅可以幫助人們閱讀和理解你的代碼,它還可以讓你閱讀並理解你的代碼。 – Rob

+1

爲了更好地理解您的問題,您是否想要在控制檯的原始輸出上移動掛鉤?或者你想在每次輸入後重新繪製一個新的掛鉤系統? – Ruskin

+1

您必須創建戒指作爲單獨的對象。正如它現在顯示你有三個相同寬度的戒指,這不是河內的塔,這是不同的。所以釘的高度是由多少個環給出的,但你需要將環實例化爲具有寬度的具體物體。 –

回答

3

您已經體現了環統稱爲「多環是如何在這個掛鉤」,但還不夠。

例如,如果你有8個環你將代表一個環具有寬度1,一個具有寬度爲2,一個具有3等,至多一個與8.

在圖像你有3個環帶寬度爲1(每個釘上的最高一個),寬度爲2(兩個釘上有多個環的第二個環),依此類推。這是不正確的,並且你的代碼爲什麼這樣做的原因是它沒有「這個特定環應該多寬」的概念,而是它繪製了寬度爲1的頂環,寬度爲2的頂環,等等。

相反這裏是一個非常簡單的設置對象來表示環和PEG和操作從一個移動到另一個:

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; } 
} 

要創建3個釘和您可以在第一PEG堆疊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); 

畫他們我自由了充實了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; 
} 

輸出:

pegs and rings

+0

這是一個非常好的解決方案。我鼓勵你花時間幫助我理解這一點。但是,如何使這不使用任何IEnumerables?除此之外,沒有其他辦法可以做到嗎? – youmeoutside

+0

如果你總是有3個掛鉤,那麼只需要將掛鉤作爲一個集合的方法具體地採用掛鉤,比如'Peg a,Peg b,Peg c'(儘管可能有更好的名字)。 –