2016-01-08 14 views
9

Önceki yazımda genişlediğim için hala Hanoi Kuleleri yazıyorum. Halkalar üzerindeki halkaların nasıl çizileceğine dair harika bir çözüme kavuştuktan sonra, hala bir süredir bir süredir uğraştığım bir sorum var.Hanoi Kuleleri: Peg'den Peg'e Taşınan Halkalar

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

Ve burada benim ana yöntemdir:

İşte benim PegClass olduğunu.

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

Bu akım çıkışı:

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

Sorum biri hareket eder, nasıl kalır - Bir istemi için sorulduğunda pimlenmesinin peg karakterleri ''. Saatlerce değiştirmeyi denedim ve hala anlayamadım.

Sadece "Birçok halkalar bu çiviye nasıl" ama bu yeterli olmayacak gibi halkaları tezahür etmiş

+1

Hoşgeldin taşması yığın! Lütfen, bir dahaki sefere bir soru gönderdiğinizde, uygun şekilde girebilir misiniz? Bu sadece insanların kodunuzu okumasına ve anlamasına yardımcı olmaz, aynı zamanda sizin için okumanızı ve başkalarını okumanızı sağlar. – Rob

+1

Sorunuzu biraz daha iyi anlamak için, mandalları Konsolun orijinal çıktısına taşımak ister misiniz? Ya da her girişten sonra yeni bir peg sistemini yeniden çizmek ister misiniz? – Ruskin

+1

Halkaları ayrı nesneler olarak oluşturmanız gerekir. Şimdi göründüğü gibi aynı genişlikte 3 yüzük var, bu hanoi kuleleri değil, bu farklı bir şey. Bir pegin "yüksekliği", üzerinde kaç tane yüzük bulunduğuna göre verilir, ancak halkaları genişliğe sahip beton nesneler olarak örneklendirmeniz gerekir. –

cevap

3

youmeoutside, şimdiden teşekkürler. Eğer 8 halkaları varsa

Örneğin, resminizin 8.

ile birine kadar, genişlik 2 ile genişlik 1, bir ile 3, vb ile bir tek yüzüğü temsil edecek Eğer 3 halkaları ile yapmış 1 genişliği (her bir peg üzerindeki üstteki), 2 genişlik 2 (birden fazla zile sahip iki mandal üzerindeki ikinci halka), vb. Bu yanlıştır ve kodunuzun bunu neden yapmasının nedeni, "bu özel halkanın ne kadar geniş olması gerektiği" kavramına sahip olmamasıdır, bunun yerine genişlik 1 ile üstteki halkayı, genişlik 2 ile üstteki yüzeyi çizer.

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 mandal oluşturmak ve yapabildin ilk çiviye 8 halkaları yığını: yerine burada

birinden diğerine geçmek için yüzük ve mandal ve çalışmasını temsil etmek nesnelerin çok basit bir kümesidir Bu kodu kullanın:

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

Onları çizmek için ben özgürlüğü aldım Onları göstermek için ancak kolayca Şimdi sahip konsol koduna bu uyum olabilir çeken bir LINQPad programı ortaya koymasıyla ait:

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

çıkışı:

pegs and rings

+0

Bu çok iyi bir çözümdür. Bunu anlamama yardımcı olmak için zaman ayırdığınız için sizi alkışlıyorum. Ama bunu IEnumerables'ın herhangi birini kullanmadan nasıl yapar? Bunu yapmanın başka yolu yok mu? – youmeoutside

+0

Eğer her zaman 3 mandal olacaksa, sadece bir mandal almak için mandalları almak, özellikle de "Peg a, Peg b, Peg c" (muhtemelen daha iyi isimlerle) gibi mandalları alın. –

İlgili konular