如何制作河内塔的动画?

时间:2016-03-25 00:22:06

标签: java algorithm swing japplet towers-of-hanoi

所以我试图为河内的常见拼图塔制作动画。我已经编写了算法来在控制台中执行此操作,但我想创建一个弹出的JApplet,并在我询问磁盘数量后激活解决的难题。如果有帮助,这是我的算法代码。只是寻找一些指令,不需要写出整个代码。感谢。

这是我的算法代码。

public class TowerofHanoi extends JFrame{

 static int count= 0;

public void move(int n, String start, String auxiliary, String end) {

       if (n == 1) {
           count++;
           System.out.println(start + " -> " + end);
       } else {
           count++;
           move(n - 1, start, end, auxiliary);
           System.out.println(start + " -> " + end);
           move(n - 1, auxiliary, start, end);
       }
   }

public static void main(String[] args) {
    // TODO Auto-generated method stub
       TowerofHanoi towersOfHanoi = new TowerofHanoi();
       System.out.print("Enter number of discs: ");
       Scanner scanner = new Scanner(System.in);
       int discs = scanner.nextInt();
       towersOfHanoi.move(discs, "A", "B", "C");
       System.out.println("This puzzle took "+count+" moves.");
   }

 public void paint(Graphics g) {
        g.drawRect (10, 10, 200, 200);  

      }
 public TowerofHanoi(){
     setPreferredSize(new Dimension(WIDTH, HEIGHT));
 }
    }

这是我的JApplet代码。

public class Graphics_TOH {

public static void main(String[] args) {
    // TODO Auto-generated method stub
    JFrame frame = new JFrame ("Draw Person");
       frame.setDefaultCloseOperation (JFrame.EXIT_ON_CLOSE);
       TowerofHanoi panel = new TowerofHanoi ();
       frame.getContentPane().add(panel);
       frame.pack();
       frame.setVisible(true);
}

1 个答案:

答案 0 :(得分:1)

这个问题对我来说实际上有点兴趣,因为它与我的一个小小的问题有关 - 大多数编程语言依赖于调用堆栈的方式使得重用那个漂亮的小move()函数变得非常困难你的。

要做这种动画,你需要:

  1. 设置一个计时器,使面板每秒刷新几次(比如说20次);
  2. 记住动画开始时的当前时间;和
  3. 每次面板刷新时,都要获取当前时间并绘制当时的样子。
  4. 当然,对你而言,棘手的部分是第3步。

    让我们说你想每秒画一个动作。刷新发生,您获得当前时间并发现自动画开始以来它已经是4.234秒。你计算到移动4你是0.234秒,所以你想通过移动4画出它应该看起来像23.4%的东西。

    为了做到这一点,你需要知道:什么光盘在移动4期间是哪个光盘是静态的,哪个光盘在移动,它的源钉和它的目标钉。

    修复你的递归移动功能来跟踪所有这些很容易,但是因为它会立刻生成所有动作,所以没有办法告诉你有关移动4的具体信息

    要解决此问题,您基本上有3个选择:

    a)您可以在开始时调用移动功能,并记录所有移动。然后,当你必须绘制时,你可以通过记录的移动前进到正确的移动。这很容易,而且可能很实用。当然,记录大型拼图的所有动作(20张光盘的1M条目)需要大量的记忆,但是它也需要花费大量时间来动画(一周一次/秒),所以你&#39 ;无论如何都不会为大谜题制作动画。

    b)您可以在一个单独的线程中执行递归移动函数,该线程在每次重绘时与呈现线程交换信息。这实际上是在多人游戏中相当常见的等待,其中游戏状态必须在"实时"中跟踪。无论如何。对你来说,这比它的价值更麻烦。

    c)您可以以非递归的方式重写您的hanoi解决方案。然后你可以实现一个迭代器。这可能与解决方案(a)非常相似,但是您可以在必要时推进迭代器以生成新的移动,而不是通过预先记录的移动进行迭代。好处是您不需要提前生成和存储所有动作。

    如果是我,我会做解决方案(c),因为我非常适合将递归解决方案转换为具有单独堆栈的迭代解决方案。如果你对这类事情感到不舒服,那么你可能希望做(a)并将所有动作填充到ArrayList中。

相关问题