All pastes #764456 Raw Edit

Boxes by Urza

public text v1 · immutable
·published 2007-11-07 06:33 UTC
rendered paste body
; +--------------------------------------+
; |         Picwin boxes game            |
; | Created by Urza - Urza23@hotmail.com |
; | Created and tested in mIRC 6.31      |
; +--------------------------------------+
alias helpwin {
  ; close the window if it's already open
  if ($window(@Boxes_help)) window - @Boxes_help

  ; re-open the window
  window -adpfk @Boxes_help -1 -1 225 200

  ; Make sure the bg is black
  drawfill -s @Boxes_help 1 $color(background) 1 1

  ; draw the help text
  drawtext @Boxes_help 0 verdana 10 5 10 The rules of Boxes are very simple.
  drawtext @Boxes_help 0 verdana 10 5 30 Players take turns placing a line to
  drawtext @Boxes_help 0 verdana 10 15 42 connect 2 dots on the board.
  drawtext @Boxes_help 0 verdana 10 5 62 The goal is to create full boxes with
  drawtext @Boxes_help 0 verdana 10 15 74 the line you place
  drawtext @Boxes_help 0 verdana 10 5 94 The player with the most Boxes at the
  drawtext @Boxes_help 0 verdana 10 15 106 end of the game i the winner.
  drawtext @Boxes_help 0 verdana 10 5 126 If you successfully create a box you
  drawtext @Boxes_help 0 verdana 10 15 138 get another turn
  drawtext @Boxes_help 0 verdana 10 5 158 You can change the direction of your
  drawtext @Boxes_help 0 verdana 10 15 170 lines by right clicking or by clicking
  drawtext @Boxes_help 0 verdata 10 15 182 the radio boxes
}

; Menu to open boxes game
menu channel,status,query {
  Play Boxes:boxes
}

; Main alias to create the boxes window
alias Boxes {
  ; clear the Boxes hash table if it exists
  if ($hget(Boxes)) hfree Boxes

  ; if the window is open and the new game variable is not set - close it
  if ($window(@Boxes)) && (!%BOXES_NEWGAME) window -c @Boxes

  ; open the window - only if the new game variable is not set
  if (!%BOXES_NEWGAME) window -dpfk +bf @Boxes -1 -1 342 215

  ; Make sure the bg is black
  drawfill -s @Boxes 1 $color(background) 1 1
  drawrect -f @Boxes 1 1 0 0 342 215

  ; Draw seperator lines
  drawline -n @Boxes 0 1 210 0 210 $window(@Boxes).bh
  drawline -n @Boxes 0 1 210 70 342 70

  ; Draw line type text and box
  drawrect -n @Boxes 0 1 235 5 65 14
  drawline -n @Boxes 0 1 235 12 225 12 225 60 325 60 325 12 299 12
  drawtext -n @Boxes 0 verdana 10 240 5 Line Type

  ; Draw line type radio Boxes
  drawdot -n @Boxes 0 6 240 30
  drawdot -n @Boxes 0 6 240 50
  drawdot -n @Boxes 1 4 240 30 
  drawtext -n @Boxes 0 verdana 10 247 22 Vertical
  drawtext -n @Boxes 0 verdana 10 247 42 Horizontal

  ; Draw current player text and create hash table entry
  drawtext -n @Boxes 3 verdana 20 230 75 Player 1
  hadd -m Boxes Player 1

  ; Draw scores text and box
  drawrect -n @Boxes 0 1 235 105 47 14
  drawline -n @Boxes 0 1 235 112 225 112 225 160 325 160 325 112 281 112
  drawtext -n @Boxes 0 verdana 10 240 105 Scores
  drawtext -n @Boxes 3 verdana 10 235 123 Player 1: 0
  drawtext -n @Boxes 4 verdana 10 235 141 Player 2: 0

  ; draw the help button
  drawrect -n @Boxes 0 1 247 190 60 20
  drawtext -n @Boxes 0 verdana 10 263 193 Help

  ; Draw the grid lines
  grid

  ; create hash table to represent which lines in the grid have been drawn
  var %x 1
  while (%x <= 11) {
    hadd -m Boxes H $+ %x $str(0.,11)
    hadd -m Boxes V $+ %x $str(0.,11)
    inc %x
  }

  ; Create hash table entry to track the number of moves remaining
  hadd -m Boxes moves 220
  drawtext -n @boxes 0 verdana 10 215 166 Moves remaining: $hget(boxes,moves)


  ; Update all the drawing
  drawline @Boxes
}

; draw the grid
alias -l grid {
  ; calculate size of the playing grid
  var %h = $window(@Boxes).bh - 5,%w = $window(@Boxes).bw - 135,%x 5,%y 5
  ; loop through rows and columns drawing the dots every 20 pixels
  while (%y <= %h) {
    %x = 5
    while (%x <= %w) {
      drawdot -n @Boxes 14 2 %x %y
      inc %x 20
    }
    inc %y 20
  }
}

; find the current line type
alias -l linetype return $iif($getdot(@Boxes,240,30),Horizontal,Vertical)

; Menu to handle all requred mouse events
menu @Boxes {
  ; mouse movements
  mouse: if ($hget(boxes,moves)) hilightLine

  ; single clicks
  sclick:processClick

  ; right clicks - switch the line type
  rclick: {
    if ($getdot(@Boxes,240,30)) {
      drawdot @Boxes 1 4 240 30
      drawdot @Boxes 0 4 240 50
    }
    else {
      drawdot @Boxes 0 4 240 30
      drawdot @Boxes 1 4 240 50
    }
  }
  ; released clicks - redraw appropriate buttons
  uclick: {
    if ($mouse.x isnum 240-300 && $mouse.y isnum 190-210) {
      drawrect -f @Boxes 1 1 247 190 60 20
      drawrect @Boxes 0 1 247 190 60 20
      drawtext @Boxes 0 verdana 10 263 193 Help
      helpwin
    }
    if ($mouse.x isnum 70-140 && $mouse.y isnum 140-160 && !$hget(boxes,moves)) {
      drawrect -f @boxes 1 1 70 140 70 20 
      drawrect @boxes 0 1 70 140 70 20 
      drawtext @boxes 0 verdana 10 76 143 New Game
      boxes
    }
  }
}

; alias to check whether a new line has created any boxes - and to fill them in with the players olour if so
alias -l boxmade {
  var %box,%player = $hget(Boxes,player),%col = $iif(%player == 1,3,4)
  if (h* iswm $1) {
    ; check if the new line creats the TOP of a finished box
    var %t = $getline(h,$2,$3),%b = $getline(h,$calc($2 + 1),$3),%l = $getline(v,$2,$3),%r = $getline(v,$2,$calc($3 + 1))
    if ($count(%t %b %l %r,1,2) == 4) {
      inc %box
      drawrect -f @Boxes %col 1 $calc($3 * 20 - 17) $calc($2 * 20 - 17) 20 20
    }
    ; check if the new line creates the BOTTOM of a finished box
    var %b = $getline(h,$2,$3),%t = $getline(h,$calc($2 -1),$3),%l = $getline(v,$calc($2 -1),$3),%r = $getline(v,$calc($2 -1),$calc($3 + 1))
    if ($count(%t %b %l %r,1,2) == 4) {
      inc %box
      drawrect -f @Boxes %col 1 $calc($3 * 20 - 17) $calc($({,$2) * 20 - 17) 20 20
    }
  }
  else {
    ; check if the new line creates the LEFT of a finished box
    var %l = $getline(v,$2,$3),%r = $getline(v,$2,$calc($3 + 1)),%t = $getline(h,$2,$3),%b = $getline(h,$calc($2 + 1),$3)
    if ($count(%t %b %l %r,1,2) == 4) {
      inc %box
      drawrect -f @Boxes %col 1 $calc($3 * 20 - 17) $calc($2 * 20 - 17) 20 20
    }
    ; check if the new line creates the RIGHT of a finished box
    var %r = $getline(v,$2,$3),%l = $getline(v,$2,$calc($3 -1)),%t = $getline(h,$2,$calc($3 -1)),%b = $getline(h,$calc($2 +1),$calc($3 - 1))
    if ($count(%t %b %l %r,1,2) == 4) {
      inc %box
      drawrect -f @Boxes %col 1 $calc($({,$3) * 20 - 17) $calc($2 * 20 - 17) 20 20
    }
  }
  ; if any boxes have been made update the players score in the hash table, and the score panel
  if (%box) {
    hinc Boxes score_ $+ %player %box
    if (%player == 1) {
      drawrect -f @Boxes 1 1 290 120 25 18 
      drawtext @Boxes 3 verdana 10 290 123 $hget(Boxes,score_1)
    }
    else {
      drawrect -f @Boxes 1 1 290 140 25 18 
      drawtext @Boxes 4 verdana 10 290 141 $hget(Boxes,score_2)
    }
  }
  return %box
}

; alias to check which player - if any - has filled in a given line based on its direction, x position, and y position in the grid
; $getline([vh],x-pos,y-pos)
alias getline {
  var %type = $left($1,1),%row = $2,%col = $3,%info = $hget(Boxes,%type $+ %row),%token = $token(%info,%col,46)
  return %token
}

; alias to process all mouse clicks
alias -l processClick {
  ; if the mouse is in the game board area and there are moves remaining
  if ($mouse.x isnum 5-215 && $mouse.y isnum 5-215 && $hget(boxes,moves)) {

    ; only proceed if no line has been drawn in this location
    var %entry = $left($linetype,1) $+ $hget(Boxes,line_row)
    if (!$token($hget(Boxes,%entry),$hget(Boxes,line_col),46)) {

      ; draw the players line in bold
      drawline @Boxes $iif($hget(Boxes,player) == 1,3,4) 3 $hget(Boxes,line_coords)

      ; update the hash table
      hadd -m Boxes %entry $puttok($hget(Boxes,%entry),$hget(Boxes,player),$hget(Boxes,line_col),46)

      ; Check if a box has been created since palyers are not changed if a box is made
      if (!$boxmade($linetype,$hget(Boxes,line_row),$hget(Boxes,line_col))) {
        ; Switch the player in the hash table and the panel to the right
        hadd -m Boxes player $iif($hget(Boxes,player) == 1,2,1)
        drawrect -f @Boxes 1 1 230 77 100 25
        drawtext @Boxes $iif($hget(Boxes,player) == 1,3,4) verdana 20 230 75 Player $hget(Boxes,player)
      }

      ; Decrease the number of moves remaining
      hdec boxes moves
      drawrect -f @Boxes 1 1 215 166 150 10
      drawtext @boxes 0 verdana 10 215 166 Moves remaining: $hget(boxes,moves)

      ; If there are no moves remaining end the game
      if (!$hget(boxes,moves)) endgame
    }
  }

  ; process line type changes when radio buttons are clicked
  if ($mouse.x isnum 225-325) {
    if ($mouse.y isnum 20-38) {
      drawdot @Boxes 1 4 240 30
      drawdot @Boxes 0 4 240 50
    }
    elseif ($mouse.y isnum 38-55) {
      drawdot @Boxes 0 4 240 30
      drawdot @Boxes 1 4 240 50
    }
  }

  ; Process help button click
  if ($mouse.x isnum 240-300 && $mouse.y isnum 190-210) {
    ; redraw the help button in clicked state
    drawrect -f @Boxes 14 1 247 190 60 20
    drawrect @Boxes 0 1 247 190 60 20
    drawtext @Boxes 0 verdana 10 263 193 Help
  }

  ; Process New Game button click
  if ($mouse.x isnum 70-140 && $mouse.y isnum 140-160 && !$hget(boxes,moves)) {
    drawrect -f @boxes 14 1 70 140 70 20 
    drawrect @boxes 0 1 70 140 70 20 
    drawtext @boxes 0 verdana 10 76 143 New Game
  }
}

alias -l hilightLine {
  ; if the mouse position is within the play grid
  if ($mouse.x isnum 5-215 && $mouse.y isnum 5-215) {
    ; calculate the x and y positions of start point of the line
    var %x_temp = $int($calc(($mouse.x - 5) / 20)),%y_temp = $int($calc(($mouse.y - 5) / 20))
    var %x = $calc(%x_temp * 20 + 3),%y = $calc(%y_temp * 20 + 3)
    if (%y_temp > 9) && ($linetype == vertical) %y_temp = 9
    if (%x_temp > 9) && ($linetype == horizontal) %x_temp = 9

    ; check the line type and use it to calculate the end position of the line
    if ($linetype == Vertical) var %x_end = %x,%y_end = %y $iif(%y > 200,-,+) 20
    else var %x_end = %x $iif(%x > 200,-,+) 20,%y_end = %y

    ; Update line info in  hash table
    hadd -m Boxes Line_coords %x %y %x_end %y_end
    hadd -m Boxes Line_row $calc(%y_temp + 1)
    hadd -m Boxes line_col $calc(%x_temp + 1)

    ; update grid and draw the current line if there isnt already a locked line in the current position
    if ($hget(boxes,moves)) update
    if (!$token($hget(Boxes,$left($linetype,1) $+ $hget(Boxes,line_row)),$hget(Boxes,line_col),46)) {
      drawline @Boxes $iif($hget(Boxes,player) == 1,3,4) 1 %x %y %x_end %y_end 
    }
  }
}

; alias to update the grid and remove previous position hilight lines
alias -l update {
  var %y 1

  ; loop through each row and column drawing black lines over each part of the grid that has not yet been locked in
  while (%y <= 11) {
    var %x = 1,%h_row = $hget(Boxes,h $+ %y),%v_row = $hget(Boxes,v $+ %y)
    while (%x <= 11) {

      ; check if the current position has been locked in
      var %h_tok = $token(%h_row,%x,46),%v_tok = $token(%v_row,%x,46)
      var %x_start = $calc(20 * %x - 17),%y_start = $calc(20 * %y - 17)

      ; check horizontal line at current position and draw black if required
      if (%h_tok) drawline -n @Boxes $iif($v1 == 1,3,4) 3 %x_start %y_start $calc(%x_start + 20) %y_start
      else drawline -n @Boxes 1 3 %x_start %y_start $calc(%x_start + 20) %y_start

      ; check vertical line at current position and draw black if required
      if (%v_tok) drawline -n @Boxes $iif($v1 == 1,3,4) 3 %x_start %y_start %x_start $calc(%y_start + 20)
      else drawline -n @Boxes 1 3 %x_start %y_start %x_start $calc(%y_start + 20)
      inc %x
    }
    inc %y
  }
  ; redraw the grid positions that were wiped out by the black lines
  grid

  ; redraw the line seperating the grid from the right panel
  drawline -n @Boxes 0 1 210 0 210 $window(@Boxes).bh

  ; update all drawing
  drawdot @Boxes
}

alias endgame {
  ; draw the Game over box and new game button
  drawrect -nf @Boxes 0 1 24 44 160 130
  drawrect -nf @Boxes 14 1 29 49 150 120
  drawrect -nf @Boxes 1 1 34 54 140 110
  drawtext -n @Boxes 0 verdana 20 43 60 GAME OVER
  drawtext -n @boxes 3 verdana 15 53 90 Player 1: $hget(boxes,score_1)
  drawtext -n @boxes 4 verdana 15 53 110 Player 1: $hget(boxes,score_2)
  drawrect -n @boxes 0 1 70 140 70 20 
  drawtext -n @boxes 0 verdana 10 76 143 New Game

  ; Update the drawing
  drawdot @Boxes

  ; set temporary new game variable
  set -u10 %BOXES_NEWGAME 1
}