tower of hanoi game

Game development specific discussions.
Post Reply
ron77
Posts: 212
Joined: Feb 21, 2019 19:24

tower of hanoi game

Post by ron77 »

hello...

i need some help with a "hanoi tower" game code...

i'm trying to make the game solve itself with an algorithm i found on the net...

here is the site with the algorithm (it's a recursive one)
https://www.hackerearth.com/blog/develo ... explained/

this is when i'm trying to implement it in the code of the game the program crashes:
here is the code of the game:

Code: Select all

#INCLUDE "fbgfx.bi"
 
type Pole
  bDiscs(8-1) as byte    'disc number on each slot on the pole
  iNumDiscs   as integer 'discs on this pole
end type
 
CONST AS SHORT scr_w = 800, scr_h = 600 ' screen constants
 
static shared as Pole aPoles(2) = {type({7,6,5,4,3,2,1,0},8)}
 
Sub cPrint(row AS INTEGER, s AS STRING)
   LOCATE row ,(LOWORD(width) - LEN(s)) Shr 1 : PRINT s
END SUB
 
sub DrawDisc( iPosX as integer , iPosY as integer , iDisc as integer )
  'color can be on an array
  static as ulong uDiscColor(8-1) = { _
    RGB(255,200,180) , RGB( 0,0,255) , RGB( 30, 0 ,120) , RGB( 0 ,120,120) , _
    RGB( 0 ,255, 0 ) , RGB(50,0,100) , RGB(150,100, 0 ) , RGB(255, 0 , 0 ) _
  }
  dim as integer iPoleWid = 5+iDisc*10 , iPoleHei = iif((iDisc and 3)=0,11,8)
  line ( iPosX-iPoleWid , iPosY-iPoleHei ) - ( iPosX+iPoleWid , iPosY+iPoleHei ) , uDiscColor(iDisc) , bf
end sub
 
sub drawscreen()
  for X as integer = 0 to (3-1)
    'element of this pole
    with aPoles(X)
      for Y as integer = 0 to .iNumDiscs-1
        DrawDisc( 140+X*250 , 400-Y*25 , .bDiscs(Y) )
      next Y
    end with
  next X
end sub

SUB movedisc(sourcePole AS INTEGER, targetPole AS INTEGER)
   aPoles(sourcePole).iNumDiscs -= 1
   aPoles(targetPole).bDiscs(aPoles(targetPole).iNumDiscs) = aPoles(sourcePole).bDiscs(aPoles(sourcePole).iNumDiscs)
   aPoles(targetPole).iNumDiscs += 1
END SUB


function tower(a AS INTEGER ,from AS INTEGER ,aux AS integer,_to AS integer) AS INTEGER
    IF (a=1) THEN
       PRINT "Move disc " & a & " from pole " & from & " to pole " & _to
       RETURN 1
    ELSE
       tower(a-1,from,_to,aux)
       MOVEDISC(from,_to)
       SLEEP(250)
       PRINT "Move disc " & a & " from pole " & from & " to pole " & _to
       tower(a-1,aux,from,_to)
       MOVEDISC(from,_to)
       SLEEP(250)
    ENDIF
END FUNCTION


 
SCREENRES(scr_w,scr_h,32)
WIDTH scr_w \ 8, scr_h \ 16
DIM AS STRING inptS, inptT
DIM result AS INTEGER
do
COLOR(RGB(255,0,0) ,RGB(255,255,255))
CLS
CPRINT(4,"THE TOWER OF HANOI")
DRAWSCREEN()
'INPUT "enter number of start pole to move disc from (0-2): ", inptS
'INPUT "enter number of target pole to move disc from (0-2): ", inptT
'MOVEDISC(VAL(inptS),VAL(inptT))
result = TOWER(8,0,1,2)
LOOP UNTIL result = 1'inptS = "q" OR inptT = "q"
sleep
any help will be appreciated

ron77
ron77
Posts: 212
Joined: Feb 21, 2019 19:24

Re: tower of hanoi game

Post by ron77 »

hello - i got help from @mysoft in IRC channel...

this is his solution to the tower of hanoi game:

Code: Select all

#include "fbgfx.bi"
#include "crt.bi"
 
type Pole
  bDiscs(8-1) as byte    'disc number on each slot on the pole
  iNumDiscs   as integer 'discs on this pole
end type
 
CONST AS SHORT scr_w = 800, scr_h = 600 ' screen constants
 
static shared as Pole aPoles(2) = {type({7,6,5,4,3,2,1,0},8)}
 
Sub cPrint(row AS INTEGER, s AS STRING)
   LOCATE row ,(LOWORD(width) - LEN(s)) Shr 1 : PRINT s
END SUB
 
sub DrawDisc( iPosX as integer , iPosY as integer , iDisc as integer )
  'color can be on an array
  static as ulong uDiscColor(8-1) = { _
    RGB(255,200,180) , RGB( 0,0,255) , RGB( 30, 0 ,120) , RGB( 0 ,120,120) , _
    RGB( 0 ,255, 0 ) , RGB(50,0,100) , RGB(150,100, 0 ) , RGB(255, 0 , 0 ) _
  }
  dim as integer iPoleWid = 5+iDisc*10 , iPoleHei = iif((iDisc and 3)=0,11,8)
  line ( iPosX-iPoleWid , iPosY-iPoleHei ) - ( iPosX+iPoleWid , iPosY+iPoleHei ) , uDiscColor(iDisc) , bf
end sub
 
sub drawscreen()
  
  screenlock
  
  COLOR(RGB(255,0,0) ,RGB(255,255,255))
  CLS
  CPRINT(4,"THE TOWER OF HANOI")
 
  for X as integer = 0 to (3-1)
    'element of this pole
    with aPoles(X)
      for Y as integer = 0 to .iNumDiscs-1
        DrawDisc( 140+X*250 , 400-Y*25 , .bDiscs(Y) )
      next Y
    end with
  next X
  
  screenunlock
  
end sub
 
SUB movedisc(sourcePole AS INTEGER, targetPole AS INTEGER)
   aPoles(sourcePole).iNumDiscs -= 1
   aPoles(targetPole).bDiscs(aPoles(targetPole).iNumDiscs) = aPoles(sourcePole).bDiscs(aPoles(sourcePole).iNumDiscs)
   aPoles(targetPole).iNumDiscs += 1
END SUB
 
function tower(a AS INTEGER ,from AS INTEGER ,aux AS integer,_to AS integer) AS INTEGER
  if multikey(fb.SC_Q) then return 0
  IF (a=1) THEN
    puts("Move disc " & a & " from pole " & from & " to pole " & _to)
    MoveDisc(from,_to):DrawScreen():sleep 250,1
    RETURN 1
  ELSE
    tower(a-1,from,_to,aux)
    puts("Move disc " & a & " from pole " & from & " to pole " & _to)
    MoveDisc(from,_to):DrawScreen():sleep 250,1
    tower(a-1,aux,from,_to)
  END IF
END FUNCTION
 
 
SCREENRES(scr_w,scr_h,32)
WIDTH scr_w \ 8, scr_h \ 16
 
DIM AS STRING inptS, inptT
do
  
  DRAWSCREEN()  
  'INPUT "enter number of start pole to move disc from (0-2): ", inptS
  'INPUT "enter number of start pole to move disc from (0-2): ", inptT
  'MOVEDISC(VAL(inptS),VAL(inptT))
  if tower(8,0,1,2)=0 then exit do
  if tower(8,2,1,0)=0 then exit do
  
LOOP UNTIL inptS = "q" OR inptT = "q"
 
sleep
 
MrSwiss
Posts: 3910
Joined: Jun 02, 2013 9:27
Location: Switzerland

Re: tower of hanoi game

Post by MrSwiss »

@ron77

do you think that you are truely "finished" with this? (rethorical question)
It should be obvious that I think that you're "not yet finished" by far.

For starters a remark from 'SARG' to 'cavelamb' in another thread:
SARG wrote:I guess that you don't completly understand what you are doing. Go forward step by step, try small things before fighting the big boss. ;-)
The point is: unless you really and truely understand (100%) not only "what" you are doing, but also "why" you're doing it, the learning is by far "not finished yet". By cons I'd say that it's just "taking off" from here (to become really interesting).

Some ideas to consider:
  • another Type for the discs perhaps
  • do it without "shared variables" perhaps
  • which .bi file from CRT contains "puts()" statement? (figure it out yourself, no chatting!)
  • (above) referes to the well known "*KISS" principle
*KISS = keep it simple (and) straight(-forward)
IOW, include only what MUST be included (but never MORE than that).

Example code (puts() test):

Code: Select all

' (windows only) compile: -s gui         ' force 'graphics mode'
#Include "crt/stdio.bi"                 ' for puts() forces 'Console Print'

Screen 12, 32                           ' graphics mode (640 x 480)
' conole print: forces a console to open before print(ing) there
puts("Hello World -- from FB's CRT-library")    ' console print (forced)
Sleep
Post Reply