HanoiTower.java

/**
* Copyright 2010,2021 Nikolas S Boyd.
Permission is granted to copy this work provided this copyright statement is retained in all copies.

*/
package Hoot.Tests;

import Hoot.Runtime.Functions.*;
import Hoot.Runtime.Faces.*;
import Hoot.Runtime.Values.*;
import Hoot.Runtime.Blocks.*;
import Smalltalk.Core.*;
import Smalltalk.Blocks.*;
import Smalltalk.Magnitudes.*;
import Hoot.Behaviors.*;
import Hoot.Behaviors.Nil;
import Hoot.Behaviors.Object;
import Hoot.Behaviors.True;
import Hoot.Behaviors.False;
import Hoot.Behaviors.Boolean;
import Hoot.Magnitudes.*;
import Hoot.Magnitudes.Integer;
import Hoot.Magnitudes.Character;
import Hoot.Magnitudes.Float;
import Hoot.Magnitudes.Double;
import Hoot.Collections.*;
import Hoot.Collections.String;
import Hoot.Magnitudes.Number;
import Hoot.Magnitudes.Integer;
import Hoot.Runtime.Behaviors.Mirror;
import Hoot.Runtime.Behaviors.Typified;
import Hoot.Runtime.Behaviors.HootRegistry;
import static Hoot.Magnitudes.SmallInteger.*;

public class HanoiTower extends TestableClosure
{

  protected static final String CountReport = String.from("Transfering %s disks");
    protected Number count = HanoiTower.initialCount();
    public Number count() { return this.count; }
    public Object getCount() { return (Object)this.count; }

    public HanoiTower count(Number value) { this.count = value; return this; }
    public void setCount(Object value) { this.count = (Number)value; }

  ;
    protected Boolean usePrimitive = False.literal();
    public Boolean usePrimitive() { return this.usePrimitive; }
    public Object getUsePrimitive() { return (Object)this.usePrimitive; }

    public HanoiTower usePrimitive(Boolean value) { this.usePrimitive = value; return this; }
    public void setUsePrimitive(Object value) { this.usePrimitive = (Boolean)value; }

  ;

  /**
   * @return 
   */
  @Override public   HanoiTower value()
  {
    java.lang.String exitID = "HanoiTower>>value";
    Frame f0 = new Frame(exitID);
    this.reportCount();
    this.reportAfterRun();
    return (HanoiTower)this;
  }

  /**
   * @return 
   */
  @Override public   void runTest()
  {
    java.lang.String exitID = "HanoiTower>>runTest";
    Frame f0 = new Frame(exitID);
    this.move_from_to_via(count, SmallInteger.from(1), SmallInteger.from(2), SmallInteger.from(3));
  }

  /**
   * @return 
   */
  public static   Integer initialCount()
  {
    java.lang.String exitID = "HanoiTower>>$initialCount";
    Frame f0 = new Frame(exitID);
    return (Integer)SmallInteger.from(18);
  }

  /**
   * @return 
   */
  public   HanoiTower reportCount()
  {
    java.lang.String exitID = "HanoiTower>>reportCount";
    Frame f0 = new Frame(exitID);
    this.log().printLine(CountReport.formatWith(HanoiTower.initialCount().printString()));
    return (HanoiTower)this;
  }

  /**
   * @return 
   */
  public static   HanoiTower withFloat()
  {
    java.lang.String exitID = "HanoiTower>>$withFloat";
    Frame f0 = new Frame(exitID);
    return (HanoiTower)new HanoiTower().count(HanoiTower.initialCount().asFloat());
  }

  /**
   * @return 
   */
  public static   HanoiTower withCount(final Number count)
  {
    java.lang.String exitID = "HanoiTower>>$withCount";
    Frame f0 = new Frame(exitID);
    return (HanoiTower)new HanoiTower().count(count);
  }

  /**
   * @return 
   */
  public static   HanoiTower withPrimitive()
  {
    java.lang.String exitID = "HanoiTower>>$withPrimitive";
    Frame f0 = new Frame(exitID);
    return (HanoiTower)new HanoiTower().usePrimitive(True.literal());
  }

  /**
   * @return 
   */
  @Override public   String description()
  {
    java.lang.String exitID = "HanoiTower>>description";
    Frame f0 = new Frame(exitID);
    return (String)(String.from("Tower of Hanoi with ").append(this.typeName()));
  }

  /**
   * @return 
   */
  public   String typeName()
  {
    java.lang.String exitID = "HanoiTower>>typeName";
    Frame f0 = new Frame(exitID);
    return (String)this.usePrimitive().ifFalse_ifTrue(Closure.with(f2 -> {
      return String.from(count.$class().outerClass().getName());
    }, ""), Closure.with(f2 -> {
      return String.from(count.elementaryInteger().getClass().getName());
    }, ""));
  }

  /**
   * @return 
   */
  protected   HanoiTower move_from_to_via(final Number diskCount, final Hoot.Behaviors.Object source, final Hoot.Behaviors.Object target, final Hoot.Behaviors.Object transfer)
  {
    java.lang.String exitID = "HanoiTower>>move_from_to_via";
    Frame f0 = new Frame(exitID);
    if (this.usePrimitive().asPrimitive()) {
      this.move_from_to_via(diskCount.elementaryInteger(), 1, 2, 3);
      return this;
    };
    if (diskCount.isKindOf(SmallInteger.type()).asPrimitive()) {
      this.move_from_to_via(diskCount.asInteger(), source, target, transfer);
    }
    else {
      this.move_from_to_via(diskCount.asFloat(), source, target, transfer);
    };
    return (HanoiTower)this;
  }

  /**
   * @return 
   */
  protected   HanoiTower move_from_to_via(final Integer diskCount, final Hoot.Behaviors.Object source, final Hoot.Behaviors.Object target, final Hoot.Behaviors.Object transfer)
  {
    java.lang.String exitID = "HanoiTower>>move_from_to_via";
    Frame f0 = new Frame(exitID);
    (Unity.lessThan(diskCount)).ifTrue(Closure.with(f2 -> {
      
    Integer disks = (diskCount.minus(Unity));
    {
    HanoiTower prime = this;
    prime.move_from_to_via(disks, source, transfer, target); 

    prime.move_from_to_via(disks, transfer, target, source);
    };
    }, ""));
    return (HanoiTower)this;
  }

  /**
   * @return 
   */
  protected   HanoiTower move_from_to_via(final Float diskCount, final Hoot.Behaviors.Object source, final Hoot.Behaviors.Object target, final Hoot.Behaviors.Object transfer)
  {
    java.lang.String exitID = "HanoiTower>>move_from_to_via";
    Frame f0 = new Frame(exitID);
    (Float.type().unity().lessThan(diskCount)).ifTrue(Closure.with(f2 -> {
      
    Float disks = (diskCount.minus(Float.type().unity()));
    {
    HanoiTower prime = this;
    prime.move_from_to_via(disks, source, transfer, target); 

    prime.move_from_to_via(disks, transfer, target, source);
    };
    }, ""));
    return (HanoiTower)this;
  }

  /**
   * @return 
   */
  protected   void move_from_to_via(final java.lang.Integer diskCount, final int source, final int target, final int transfer)
  {
    java.lang.String exitID = "HanoiTower>>move_from_to_via";
    Frame f0 = new Frame(exitID);
    if ((Unity.asPrimitive() < diskCount)) {
      int disks = (diskCount - Unity.asPrimitive());
      this.move_from_to_via(disks, source, transfer, target);
      this.move_from_to_via(disks, transfer, target, source);
    };
  }
}