*! version 0.1 3 Oct 2023 * by Kerry Du cap program drop hanoitower program define hanoitower version 16 //args num s syntax anything, [FIG] gettoken num anything:anything if "`num'"==""{ di as error "# of Disks should be specified as the first argument." error 198 } else{ confirm integer num `num' if (`num'<1 | `num'>10){ di as error "# of Disks (the first argument) shoud >=1 & <=10." error 198 } } local s `anything' if "`s'"==""{ local s 1000 } else{ if (`s'<0){ di as error "argument for sleep time should not be <0." error 198 } } di "Game Start..." di "#1 denotes the smallest disk, #2 denotes the second smallest disk and so on." _n preserve clear qui set obs 10 forv j=1/10{ gen y`j' = 11-`j' gen x`j' = 2+`j'/3*(_n-5.5)/10*(10/`num') gen xB`j' = 6+`j'/3*(_n-5.5)/10*(10/`num') gen xC`j' = 10+`j'/3*(_n-5.5)/10*(10/`num') } gen x11 = 2+ (_n-5.5)/80 gen xB11 = 6+ (_n-5.5)/80 gen xC11 = 10+ (_n-5.5)/80 gen y11 = 11 gen y12 = 13 gen y0 =0 gen x00 = 0+(_n-1)*13/_n local a A local b B local c C global n = 1 global `b' global `c' global `a' forv j=1/`num'{ global `a' ${`a'} `j' } global aa `a' global bb `b' global cc `c' if "`fig'"!="" plotfig 0 0 ${aa} ${bb} ${cc} hannuota `num' `a' `b' `c' `s' `fig' restore end cap program drop hannuota program define hannuota version 16 args num a b c s fig global `a' ${`a'} global `b' ${`b'} global `c' ${`c'} if `num'==1{ sleep `s' di _n disp "-----------------------------------" display "$n:Move Disk#`num' from `a' to `c'" disfig `a' `c' ${aa} ${bb} ${cc} global n=$n+1 global `c' `num' ${`c'} local aa ${`a'} gettoken j aa:aa global `a' `aa' sleep `s' if "`fig'"!="" plotfig `a' `c' ${aa} ${bb} ${cc} disp "↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓" di "$aa:${$aa}" _n(2) "$bb:${$bb}" _n(2) "$cc:${$cc}" } else{ local num2 = `num' -1 hannuota `num2' `a' `c' `b' `s' `fig' sleep `s' di _n disp "-----------------------------------" display "$n:Move Disk#`num' from `a' to `c'" disfig `a' `c' ${aa} ${bb} ${cc} global `c' `num' ${`c'} local aa ${`a'} gettoken j aa:aa global `a' `aa' global n=$n+1 sleep `s' if "`fig'"!="" plotfig `a' `c' ${aa} ${bb} ${cc} disp "↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓" di "$aa:${$aa}" _n(2) "$bb:${$bb}" _n(2) "$cc:${$cc}" hannuota `num2' `b' `a' `c' `s' `fig' } end ////////////////////////// cap program drop plotfig program define plotfig version 16 args from to A B C local cols gray orange sand navy maroon green purple olive red blue local na: word count $`A' foreach j in $`A'{ tempvar yA`j' yA`=`j'+1' qui gen `yA`j'' = `na' qui gen `yA`=`j'+1''= `na' + 1 local cj: word `j' of `cols' local line1 `line1' (rarea `yA`j'' `yA`=`j'+1'' x`j', color(`cj')) local na = `na' -1 } local nb: word count $`B' foreach j in $`B'{ tempvar yB`j' yB`=`j'+1' qui gen `yB`j'' = `nb' qui gen `yB`=`j'+1''= `nb' + 1 local cj: word `j' of `cols' local line2 `line2' (rarea `yB`j'' `yB`=`j'+1'' xB`j', color(`cj')) local nb = `nb' -1 } local nc: word count $`C' foreach j in $`C'{ tempvar yC`j' yC`=`j'+1' qui gen `yC`j'' = `nc' qui gen `yC`=`j'+1''= `nc' + 1 local cj: word `j' of `cols' local line2 `line2' (rarea `yC`j'' `yC`=`j'+1'' xC`j', color(`cj')) local nc = `nc' -1 } twoway `line1' `line2' `line3' /// (rarea y0 y12 xC11,color(black)) /// (rarea y0 y12 xB11,color(black)) /// (rarea y0 y12 x11,color(black)) /// (rarea y0 y10 x00,color(black)) /// , legend(off) xtitle("") ytitle("") /// xlabel(none) ylabel(none) /// yscale(lstyle(none)) xscale(lstyle(none)) /// text(-0.3 2 "A") text(-0.3 6 "B") text(-0.3 10 "C") end ////////////////////// cap program drop disfig program define disfig version 16 args from to A B C if "`from'"=="`A'" { local line1 `"`A':${`A'}"' if "`to'"=="`B'"{ local line2 `"`B':□ ${`B'}"' local line3 `"`C':${`C'}"' di `"`line1'"' _n `" ↓ "' _n `"`line2'"' _n(2) `"`line3'"' } else{ local line2 `"`B':| ${`B'}"' local line3 `"`C':□ ${`C'}"' di `"`line1'"' _n `" | "' _n `"`line2'"' _n `" ↓ "' _n `"`line3'"' } } if "`from'"=="`B'" { local line2 `"`B':${`B'}"' if "`to'"=="`A'"{ local line1 `"`A':□ ${`A'}"' local line3 `"`C':${`C'}"' di `"`line1'"' _n `" ↑ "' _n `"`line2'"' _n(2) `"`line3'"' } else{ local line1 `"`A':${`A'}"' local line3 `"`C':□ ${`C'}"' di `"`line1'"' _n _n `"`line2'"' _n `" ↓ "' _n `"`line3'"' } } if "`from'"=="`C'" { local line3 `"`C':${`C'}"' if "`to'"=="`A'"{ local line1 `"`A':□ ${`A'}"' local line2 `"`B':| ${`B'}"' di `"`line1'"' _n `" ↑ "' _n `"`line2'"' _n `" | "' _n `"`line3'"' } else{ local line1 `"`A':${`A'}"' local line2 `"`B':□ ${`B'}"' di `"`line1'"' _n _n `"`line2'"' _n `" ↑ "' _n `"`line3'"' } } end