Code:
LOCAL STHANOI:={"Tower of Hanoi","Wieża Hanoi","Tour de Hanoi"};
LOCAL STG:=" StephenG1CMZ ";
LOCAL CRID:=" ©2016"+STG;
LOCAL VERNUM:="1.0";
LOCAL SL;
LOCAL II;
LOCAL NOTEsc;
LOCAL EN:=1;
LOCAL PL:=2;
LOCAL FR:=3;
LOCAL LANGS:={"English","Polskie","Français"};
//CUSTOMISE
LOCAL LANG_ASK:=1; //1=ASK 0=USE SYSTEM
LOCAL DEFLT_LANG:={EN,PL,FR,EN}; // 1 2 3 REST
LOCAL INTRO_CONFIRM:=1; //1 0
LOCAL INPROGRESS:=0; //1=SHOW 0=NO
LOCAL SHOW_MOVE_LIST:=1;
//
LOCAL TFROM,TTO,TVIA;
LOCAL STVER:={"Version ","Wersja ","Version "}+ VERNUM;
LOCAL THREET:={": 3 Towers",": 3 Wieże",": 3 Tours"};
LOCAL NITEMS:=5; //0..13;
LOCAL STFIRST:={"1st","1-ty","1er"};
LOCAL STDEST:={"DEST","CEL","DEST"};
LOCAL STVIA:={"VIA","PRZEZ","VIA"};
LOCAL NL:=CHAR(10);
LOCAL Z_ESC:=4;
LOCAL IMP_LIMITS_CHOOSE:={1,2047};// 11 ITEMS
LOCAL IMP_LIMIT_LISTS:=10000;// 13 ITEMS
LOCAL MOVES;//REQUIRED
LOCAL NMOVE;
// ENTER TIMEGIVEN TO ESTIMATE MOVETIME
// ENTER MOVETIME TO ESTIMATE REQUIRED TIME
// (ANY UNITS UNSPECIFIED)
LOCAL TIMEGIVEN := 10*60;//FOR CHALLENGE
LOCAL EST_MOVETIME:=1;
LOCAL TTL;
LOCAL STOBJ:={" Objects",""," Objets"};
LOCAL LBL:={
{"# objects","From","To","Via",
"TOTAL TIME","MOVE TIME"},
{"# obiekty","Od","Do","Przez","Czas Caŀkowity","Przesunąć czas"},
{"# objets","De","À","Via","Temps Totale","DéplacerTemps"}};
LOCAL HLP:={
{"Number of objects to move [0..13]",
"Name of From/1st Tower",
"Name of To/Destination Tower",
"Name of Via/Temporary Tower",
"TIME ALLOWED -> EST TIME PER MOVE",
"EST MOVE TIME -> TIME NEEDED"},
{"Liczbe obkiektõw, aby przenieść [0..13]",
"Nazwa Z/1-ty wieży",
"Nazwa Do/Preznacenia wieży",
"Nazwa Poprzez/Tymczasowej wieży",
"Dopuszczalny czas -> przewidywany czas na ruch",
"Szacowany czas ruch -> czas potrzebny"},
{"Nombre d'objets à déplacer [0..13]",
"Nom de De/1er Tour","Nom de À/Tour de destination","Nom de Via/Tour Temporaire",
"Temps imparti -> heure par coup","déplacer le temps -> temps nécessaire estimée"}};
LOCAL STIMPLIMIT:={"IMPLEMENTATION LIMIT:"+NL,"REALIZACJA LIMIT:"+NL,"LIMITE DE MISE EN OEUVRE"+NL};
LOCAL STTOOMANY:={"too many moves to list","zbyt wiele ruchów do listy","trop de coups à la liste"};
LOCAL STNOCHOOSE:={"CHOOSE","CHOOSE","CHOOSE"};
LOCAL STOBJNEEDS:={" objects need "," przedmioty potrzebne "," objets ont besoin de "};
LOCAL STMOVES:={" moves"," porusza"," mouvements"};
LOCAL STPERMOVE:={" per move"," za ruch"," par coup"};
LOCAL STESTDUN:={"Estimated completion in ","Szacuje się zakończenie ","L'estimation d'achèvement "};
LOCAL STANYKEY:={"PRESS ANY KEY","NACIŚNIJ DOWOLNY KLAWISZ","APPUYEZ SUR UNE TOUCHE"}+" !{Esc}";
LOCAL STLIST:={"Listing ","Wymienianie kolejno ","Liste des "};
LOCAL STSEELISTS:={
"{Esc Shift List Edit} to see lists ",
"{Esc Shift List Edit} aby zobaczyć list ",
"{Esc Shift List Editer}pour voir les listes"};
LOCAL INSTR:="";
LOCAL INSTRS:={};
LOCAL CHS,OKC;
LOCAL TM;
OOPS()
BEGIN
LOCAL ST:="*** Esc ***";
MSGBOX(ST);
PRINT(ST);
END;
GOON()
BEGIN
IF NOTEsc THEN
IF GETKEY==Z_ESC THEN
OOPS();
NOTEsc:=0;
//RETURN 0;
END;
RETURN 1;
ELSE
RETURN 0;
END;
END;
LOCAL TOOBIG(MSG)
BEGIN
MSGBOX(STHANOI(SL)+NL+STIMPLIMIT(SL)+MSG);
END;
LOCAL MOVECOUNT(NITEMS)
BEGIN
RETURN 2^(ABS(NITEMS))-1;
END;
LOCAL AMOVE(NITEMS,TFROM,TTO,TVIA)
BEGIN
IF GOON()==1 THEN
IF (NITEMS>0) THEN
IF INPROGRESS THEN
DRAWMENU(MOVES-NMOVE);
END;
//PRINT("GOAL:GET "+NITEMS+" ITEMS FROM "+TFROM+" TO "+TTO);
AMOVE(NITEMS-1,TFROM,TVIA,TTO);//SOLVING
L1(NMOVE):=TFROM;
L2(NMOVE):=TTO;
INSTR:=(MOVES-NMOVE+1)+"↔"+NMOVE+": "+TFROM+" -> "+TTO;
INSTRS(NMOVE):=INSTR;
NMOVE:=NMOVE+1;
AMOVE(NITEMS-1,TVIA,TTO,TFROM);//COMPLETED
END;
END;
END;
LOCAL GET_INPUTS()
BEGIN
OKC:=INPUT({NITEMS,TFROM,TTO,TVIA,TIMEGIVEN,EST_MOVETIME},TTL,LBL(SL),HLP(SL));
END;
INTRO_REPORT()
BEGIN
MOVES:=MOVECOUNT(NITEMS);
PRINT(NITEMS+STOBJNEEDS(SL)+MOVES+STMOVES(SL));
IF TIMEGIVEN AND MOVES THEN
PRINT(TIMEGIVEN+"/"+MOVES+"="+(TIMEGIVEN/MOVES) + STPERMOVE(SL));
END;
IF EST_MOVETIME THEN
PRINT(STESTDUN(SL)+MOVES+"*"+EST_MOVETIME+"="+(MOVES*EST_MOVETIME));
END;
//THOSE ESTIMATES ARE CALCULATED INDEPENDENTLY AND MUTUALLY INCONSISTENT
END;
LOCAL RESULT_REPORT()
BEGIN
IF SHOW_MOVE_LIST AND MOVES≥IMP_LIMITS_CHOOSE(1) THEN //WA.CHOOSE
IF MOVES>IMP_LIMITS_CHOOSE(2) THEN
//TOOBIG(STNOCHOOSE(SL)+NL+MOVES+">"+IMP_LIMITS_CHOOSE(2));
ELSE
TTL:=STHANOI(SL)+STG;
OKC:=CHOOSE(CHS,TTL+NITEMS+STOBJ(SL),INSTRS);
END;
END;
END;
LOCAL PROGRAM_REPORT()
BEGIN
PRINT(IFTE(TM<1000,TM+" ms",ROUND(TM/1000,0)+" s"));
PRINT(STSEELISTS(SL)+"L1&L2");
END;
LOCAL DO_TOWER3(NITEMS)
BEGIN
//MOVING A NEG NUM OF DISKS TO DEST
//PERHAPS EQUATES TO MOVING THE DISKS FROM DEST
IF NITEMS<0 THEN
NITEMS:=ABS(NITEMS);//INGUARD
//SWAP FROM AND TO TOWERS() RETURN TBD
END;
MOVES:=MOVECOUNT(NITEMS);
NMOVE:=1;//MOVES
L1:={}; L2:={}; //LIST L1 FROM L2 TO
INSTRS:={}; //READABLE INSTRUCION
AMOVE(NITEMS,TFROM,TTO,TVIA);//COMPLETED
END;
LOCAL STARTING ()
BEGIN
SL:=DEFLT_LANG(MIN(Language,SIZE(DEFLT_LANG)));
TTL:=STHANOI(SL)+CRID;
PRINT();
PRINT(TTL);
IF LANG_ASK THEN
OKC:=CHOOSE(SL,TTL,LANGS);
SL:=DEFLT_LANG(SL);
END;
TTL:=STHANOI(SL)+CRID;
PRINT();
PRINT(TTL);
PRINT(STVER(SL)+THREET(SL));
TFROM:=STFIRST(SL);
TTO:=STDEST(SL);
TVIA:=STVIA(SL);
NOTEsc:=1;//GOON INIT
TM:=0;
END;
EXPORT TOWER1()
BEGIN
STARTING();
GET_INPUTS();
IF OKC THEN //INPUT READY
//OKC:=1;//MUST NOT =Z_ESC
MOVES:=MOVECOUNT(NITEMS);
IF INTRO_CONFIRM THEN //OPTIONAL INFO
INTRO_REPORT();
PRINT(STANYKEY(SL));
OKC:=WAIT;
END;
IF OKC==Z_ESC THEN
OOPS();
ELSE //REQUEST CONFIRMED
PRINT(STLIST(SL)+MOVES+STMOVES(SL)+"...");
IF MOVES>IMP_LIMIT_LISTS THEN
TOOBIG(STTOOMANY(SL)+NL+MOVES+">"+IMP_LIMIT_LISTS);
ELSE
//DO ACTION
TM:=TICKS;
DO_TOWER3(NITEMS);
TM:=TICKS-TM;
RESULT_REPORT();//SHOWS MOVES
END;
END;
PROGRAM_REPORT();
ELSE
OOPS();//INPUT CANCEL
END;
END;