'https://en.wikipedia.org/wiki/Tower_of_Hanoi
$ filename "Hanoi.exe"
'uses rtl32
'uses rtl64
uses console
type CONSOLE_CURSOR_INFO ' cci
dword dwSize
bool bVisible
end type
extern lib "KERNEL32.DLL"
! SetConsoleCursorInfo (sys hConsoleOutput, CONSOLE_CURSOR_INFO *lpConsoleCursorInfo) as bool
! SetConsoleWindowInfo (sys hConsoleOutput, bool bAdsolute, SMALL_RECT *lpConsoleWindow)
! Sleep (dword dwMilliseconds)
end extern
extern lib "user32.dll"
! GetSystemMenu (sys hWnd, dword bRevert) as sys
! DeleteMenu (sys hMenu, uint uPosition, uint uFlags)
end extern
sub setcolor(int fg, bg)
SetConsoleTextAttribute (ConsOut, fg+bg*16)
end sub
sub locate (int row,int col, optional int visible=1,int shape=12)
CONSOLE_CURSOR_INFO cci
SetPos(col-1,row-1)
cci.bVisible = visible
cci.dwSize = shape
SetConsoleCursorInfo(ConsOut, cci)
end sub
sub display(int col, row, string txt, optional int visible=1,int shape=12)
locate(row, col, visible)
print txt
end sub
sub AdaptConsole()
'Set size to 80,24
dim ConsoleWindow as SMALL_RECT
ConsoleWindow.Right = 80: ConsoleWindow.Bottom = 24
SetConsoleWindowInfo(GetStdHandle(STD_OUTPUT_HANDLE), 1, ConsoleWindow)
'Fix size
sys hConsMenu=GetSystemMenu(GetConsoleWindow(), 0)
DeleteMenu(hConsMenu, &HF000, 0)
DeleteMenu(hConsMenu, &HF020, 0)
DeleteMenu(hConsMenu, &HF030, 0)
end sub
SetConsoleTitle "Towers of Hanoi Puzzle"
string disk[10] = {
" MMM ",
" MMMMM ",
" MMMMMMM ",
" MMMMMMMMM ",
" MMMMMMMMMMM ",
" MMMMMMMMMMMMM ",
" MMMMMMMMMMMMMMM ",
" MMMMMMMMMMMMMMMMM ",
" MMMMMMMMMMMMMMMMMMM ",
"MMMMMMMMMMMMMMMMMMMMM"
}
string answer
int num, count, seeMoves, countMoves, intervall
int rodCol[3] ={17,41,65} 'x pos of A,B,C
int diskRow[3] 'row position of disks
sub createBoard()
int idx, row
string board=space 75
setcolor 0,6 ' black, yellow
display 4,20, board, 0
for row=9 to 19
for idx=1 to 3
display rodCol[idx],row, " ", 0
next
next
setcolor 7,0 ' white, black
display 17,22,"A",0 : display 41,22,"B",0 : display 65,22,"C",0
end sub
sub pushDisk(string disk, int rod)
setcolor 13,0 ' magenta, black
diskRow(rod)-=1
display rodCol(rod)-10, diskRow(rod), disk,0
end sub
sub popDisk(string disk, int rod)
setcolor 0,0 ' black, black
display rodCol(rod)-10, diskRow(rod), space(21),0
setcolor 0,6 ' black, yellow
display rodCol[rod], diskRow(rod), " ",0
diskRow(rod)+=1
end sub
sub addDisks(int num)
int row
setcolor 13,0 ' magenta, black
for row=num to 1 step -1
pushDisk(disk(row),1)
next
diskRow[1]=20-num
end sub
sub initGame()
setcolor 7,0 ' white, black
display 1,1, "How many disks? (3-10): "
num=val(input)
if num<3 then
num=3
elseif num>10 then
num=10
end if
countMoves=pow(2,num)-1
intervall=(5000\countMoves)
display 25,1, str(num) & " ",0
addDisks(num)
loop1:
setcolor 7,0 ' white, black
display 1,2, "Use Enter for next move? (y/n) "
answer=getkey()
if lcase(chr(answer))="y" then
seeMoves=1
display 1,2, "Press Enter to see next Move "
elseif lcase(chr(answer))="n" then
display 1,2, " ",0
else
goto loop1
end if
end sub
sub movedisk (int n, fromPeg, toPeg, viaPeg)
'recursive method
if n>0 then
movedisk n-1, fromPeg, viaPeg, toPeg
count+=1
if seeMoves then waitkey()
popDisk(disk(n),fromPeg)
pushDisk(disk(n),toPeg)
if seeMoves=0 then Sleep(Intervall)
movedisk n-1, viaPeg, toPeg, fromPeg
end if
end sub
================================================================================
'Prepare console, fix size
AdaptConsole()
'Start the app
start:
diskRow[]={20,20,20} 'row position of disks
setcolor 7,0 ' white, black
cls
count=0 : seeMoves=0 : intervall=0
createBoard()
initGame()
movedisk (num, 1,2,3)
display 1,24, "Solved in " count " moves",0
display 1,25, "Enter to continue ...",0 : waitkey()
loop2:
setcolor 7,0 ' white, black
display 1,25, "Another Try? (y/n) "
answer=getkey() : if lcase(chr(answer))="y" then goto start
if lcase(chr(answer))<>"n" then goto loop2