Towers of Hanoi

By Firstmate on Apr 23, 2009

It's Towers of Hanoi 4 mIRC!
Simple logic game where you have to move all the blocks from the first tower to either of the other two.

Just type /hanoi N to start the game.
Where N is a number between 3-8.
Instructions:
Click and drag a block to the desired tower. You cannot place a block on a block with a lower #. For example, you can't place block 2 on block 1. It must be block 1 on block 2.

Have fun :)

Hope it works.

Screenshot:
Image

;Towers of Hanoi v0.1
;Made by Firstmate
alias hanoi {
  hanoi.load $iif($1 < 9,$1,4)
  window -pdCk0 @hanoi 1 1 700 300
  hanoi.2
}
alias hanoi.2 {
  ;draw lines
  clear @hanoi
  drawfill -r @hanoi $rgb(255,255,255) $rgb(255,255,255) 1 1 599 499
  drawtext -r @hanoi $rgb(0,0,0) Tahoma 22 260 10 Towers of Hanoi
  drawline -r @hanoi $rgb(0,0,0) 3 130 75 130 245 230 245 30 245
  drawline -r @hanoi $rgb(0,0,0) 3 350 75 350 245 450 245 250 245
  drawline -r @hanoi $rgb(0,0,0) 3 570 75 570 245 670 245 470 245

  ;Draw blocks.
  var %x $numtok($hget(hanoi.1,Towers),32), %p, %t
  if (%x != 0) {
    while (%x > 0) { %t = $gettok($hget(hanoi.1,Towers),$+(-,%x),32) | inc %p | drawrect -rf @hanoi $hanoi.getrgb($gettok($hget(hanoi.1,Towers),%x,32)) 1 $calc(130- (16+ (%t * 10))) $calc(245- (20* %p)) $calc(2 *(16+ (%t * 10))) 20 | drawtext -r @hanoi $rgb(0,0,0) Tahoma 14 $calc((130- (16+ (%t * 10))) + (16+ (%t * 10))) $calc(245- (20* %p)) $gettok($hget(hanoi.1,Towers),%p,32) | dec %x }
  }
  %x = $numtok($hget(hanoi.2,Towers),32)
  %p = 0
  if (%x != 0) {
    while (%x > 0) { %t = $gettok($hget(hanoi.2,Towers),$+(-,%x),32) | inc %p | drawrect -rf @hanoi $hanoi.getrgb($gettok($hget(hanoi.2,Towers),%x,32)) 1 $calc(350- (16+ (%t * 10))) $calc(245- (20* %p)) $calc(2 *(16+ (%t * 10))) 20 | drawtext -r @hanoi $rgb(0,0,0) Tahoma 14 $calc((350- (16+ (%t * 10))) + (16+ (%t * 10))) $calc(245- (20* %p)) $gettok($hget(hanoi.2,Towers),%p,32) | dec %x }
  }
  %x = $numtok($hget(hanoi.3,Towers),32)
  %p = 0
  if (%x != 0) {
    while (%x > 0) { %t = $gettok($hget(hanoi.3,Towers),$+(-,%x),32) | inc %p | drawrect -rf @hanoi $hanoi.getrgb($gettok($hget(hanoi.3,Towers),%x,32)) 1 $calc(570- (16+ (%t * 10))) $calc(245- (20* %p)) $calc(2 *(16+ (%t * 10))) 20 | drawtext -r @hanoi $rgb(0,0,0) Tahoma 14 $calc((570 - (16+ (%t * 10))) + (16+ (%t * 10))) $calc(245- (20* %p)) $gettok($hget(hanoi.3,Towers),%p,32) | dec %x }
  }
}
alias hanoi.load {
  if ($hget(hanoi.1)) { hfree hanoi.1 | hfree hanoi.2 | hfree hanoi.3 | hfree hanoi }
  hadd -m hanoi moves 0 | hadd hanoi blocks $1
  hadd -m hanoi.1 Towers
  hadd -m hanoi.2 Towers
  hadd -m hanoi.3 Towers
  var %x $1 
  while (%x > 0) {
    hadd hanoi.1 $+(Block.,%x) %x
    dec %x
  }
  hanoi.towers 1
}
alias hanoi.move {
  ;hanoi.move Tower# Before_Tower After_Tower
  var %h $+(Block.,$1), %b $+(hanoi.,$2), %a $+(hanoi.,$3), %c $iif($gettok($hget(%a,Towers),-1,32),$gettok($hget(%a,Towers),-1,32),$calc($1 + 1)), %d $iif($gettok($hget(%b,Towers),-1,32),$gettok($hget(%b,Towers),-1,32),$1)
  if ($1 < %c && %d == $1) {
    if (%b != %a && $hfind(%b,%h,1) && !$hfind(%a,%h,1)) {
      hadd %a %h $hget(%b,%h)
      hdel %b %h
    }
    hanoi.towers $gettok(%b,2,46)
    hanoi.towers $gettok(%a,2,46)
    hanoi.2
    hinc hanoi moves
    ;show # of moves
    drawrect -fr @hanoi $rgb(255,255,255) 1 600 1 100 49 | drawtext -r @hanoi $rgb(0,0,0) Tahoma 14 600 5 Moves: $hget(hanoi,moves)
  }
  else {
    if (%b != %a) {
      drawrect -fr @hanoi $rgb(255,255,255) 1 500 250 200 50
      drawtext -r @hanoi $rgb(0,0,0) Tahoma 11 500 255 Cannot move there.
    }
  }
  ;Now check if they won. %b = # of starting blocks. %n = Number of moves made so far.
  ;minimum number of moves: y=2^x -1
  var %b = $hget(hanoi,blocks), %n $hget(hanoi,moves)
  if (%n >= $calc((2^ %b) -1)) {
    if ($numtok($hget(hanoi.2,Towers),32) == %b || $numtok($hget(hanoi.3,Towers),32) == %b) { 
      drawrect -fr @hanoi $rgb(255,255,255) 1 500 250 200 50
      drawtext -r @hanoi $rgb(0,0,0) Tahoma 14 500 255 You won!
      .timer 1 5 hanoi $hget(hanoi,blocks)
    }
  }
}
alias hanoi.towers {
  ;Add another field for Towers in table sorted biggest to smallest.
  var %h $+(hanoi.,$1), %x $hfind(%h,Block.*,0,w).item, %p
  if ($hget(%h,Towers)) { hdel %h Towers }
  while (%x > 0) {
    %p = %p $hget(%h,$hfind(%h,Block.*,%x,w).item)
    dec %x
  }
  hadd %h Towers $sorttok(%p,32,nr)
}
alias hanoi.isPos {
  ;Check if it's possible to put Block #(%tn) in tower (%a) coming from tower before (%b) $hanoi.ispos(block #,before tower, after tower)
  var %tn $1, %b $2, %a $3
  return $iif($hget(%b,%tn) < $gettok($hget(%a,Towers),1,32),$false,$true)
}
alias hanoi.getrgb { return $color($calc($1 + 2)) }
alias hanoi.gettower {
  ;Returns tower and block # $hanoi.gettower(x coord,y coord)
  var %x $1, %y $2, %i 15, %t $getdot(@hanoi,$1,$2)
  while (%i > 0) {
    if (%t == $color(%i)) { break }
    dec %i
  }
  if ($inrect(%x,%y,30,75,200,170)) { var %a 1 }
  elseif ($inrect(%x,%y,250,75,200,170)) { var %a 2 }
  else var %a 3
  var %b $gettok($hget($+(Hanoi.,%a),Towers),$floor($calc(((245 - %y) / 20) + 1)),32)
  if (%a != 0) { return %a %b }
}
alias hanoi.unload {
  hfree -w hanoi.*
  unset %hanoi.*
}
menu @hanoi {
  sclick: { 
    var %x = $hanoi.gettower($mouse.x,$mouse.y)
    if ($getdot(@hanoi,$mouse.x,$mouse.y) != 16777215 && $getdot(@hanoi,$mouse.x,$mouse.y) != 0) { 
      ;if they have clicked a block
      set %hanoi.temp 1
      set %hanoi.temp1 %x
      ;draw current block in picwin
    }
  }
  uclick: {
    if (%hanoi.temp == 1) {
      ;If they clicked a block and now want to move it.
      var %x $mouse.x, %y $mouse.y
      if ($inrect(%x,%y,30,75,200,170)) { var %a 1 }
      elseif ($inrect(%x,%y,250,75,200,170)) { var %a 2 }
      else var %a 3
      hanoi.move $gettok(%hanoi.temp1,2,32) $gettok(%hanoi.temp1,1,32) %a
      set %hanoi.temp 0
      set %hanoi.temp1 $null
    }
  }
}
on 1:CLOSE:@hanoi: hanoi.unload

Comments

Sign in to comment.
Firstmate   -  Apr 27, 2009

Yeah I'm trying to get rid of the color problem.

Edit:
Think I fixed it, I tested it a couple times and it wasn't changing color. I'll update.

 Respond  
Lazy   -  Apr 27, 2009

Good job with this. Only thing I see weird is that the blocks change color with every move.

5 blocks in 35 moves.

 Respond  
killwithme   -  Apr 26, 2009

nice one :D

got 5 blocks in 48 moves

 Respond  
Firstmate   -  Apr 25, 2009

lol I'm hindu too XD

 Respond  
Kirby   -  Apr 25, 2009

Lol @ tag 'jesus'. :D

 Respond  
Blitzjager   -  Apr 25, 2009

The numbers really help. (odds and evens)

 Respond  
Aucun50   -  Apr 24, 2009

Very nice, it gets tricky as ^Neptune said.

 Respond  
^Neptune   -  Apr 24, 2009

I did 5 blocks in 51 moves, but damn it was pretty tricky.

 Respond  
Firstmate   -  Apr 24, 2009

Posted screenshot.

 Respond  
FordLawnmower   -  Apr 23, 2009

Wow! Nice Firstmate.

 Respond  
Firstmate   -  Apr 23, 2009

NIGathan seems most persistent in me fixing a weird bug bout the color of the block. So I'll do that in the next 2 days or so if I get time.

 Respond  
Prelude   -  Apr 23, 2009

I give it a 15 FM!

 Respond  
Firstmate   -  Apr 23, 2009

Oh I see. Thank you. Will update.

 Respond  
Kirby   -  Apr 23, 2009

You won!
Cool Firstmate, though it took you quite a long time to finish it. :-P

Though, like I said in IRC, you can change

  hfree hanoi.1
  hfree hanoi.2
  hfree hanoi.3

to

  hfree -w hanoi.*

I would also unset the temporary variables %hanoi.temp and %hanoi.temp1 in the hanoi.unload alias.
Not to mention, you forgot the -m switches in many of the /hadd's.

But I like this picture window! I would give it an 8.0 if you can make the blocks follow the mouse until it is released and perfect the script!

 Respond  
Are you sure you want to unfollow this person?
Are you sure you want to delete this?
Click "Unsubscribe" to stop receiving notices pertaining to this post.
Click "Subscribe" to resume notices pertaining to this post.