ASCII Battleship v0.2

By Meta on Apr 09, 2012

First release of an ASCII based battleship game. There are a few things I plan on adding (such as a help system) and there may be a few bugs, but the game should work.

-- Example video: http://screencast-o-matic.com/watch/clfqrTpmg

In order to play, you and another person must both have this script loaded. To start a game, type /bship . A request will be sent to that person allowing them to accept or deny your challenge. (Assuming that person has this script loaded.)

If your challenge request is accepted, a window will open in which you can place your ships on the board. To place your ships, click on the mark (rectangle) where you would like your ship to begin, and then click on the mark where you would like your ship to end. (Either in the same column or the same row as the start of the ship)

Once you have placed all your ships, a message will be sent to the other player alerting them that you are ready to begin. When both of you are ready, the game will begin. The person who initiated the challenge goes first.

When a game has started, simply click on the mark you would like to strike, and you will recieve an alert telling you if you've hit or missed one of the other players ships. In order to win, you must sink all of the other players ships.

Notes: As I've mentioned, this script is still in development. Some things I plan on adding are:

  • Visual representation of ships left (when placing and while playing)
  • Help System
  • Whose turn alert
  • Named ships

    And like I also said, there may be a few bugs, so feel free to report any that you find. I do plan on improving and shortening the code too of course.


Made a few small changes. A bug with the ship counting while playing should be fixed. The game should also detect if you change your nick or quit IRC. I'm still working on the features above as well as error messages where needed.

; --- Main Functions

alias bship {
  if ($1 == $me) echo -gaec i * [Battleship] You can't challenge yourself!
  elseif ($window(@Battleship)) noop $input(You have already started a game with %__b.chl,ok5s,@Battleship,Battleship)
  else {
    echo -gaec i * [Battleship] Sending challenge request to $1...
    .ctcp $1 bship_chal
    set %__b.trn $me
  }
}

on ^$*:HOTLINK:/(___|Reset)/Si:@Battleship: {
  if ($mouse.key & 1) {
    if ($regml(1) == Reset) && ($input(Are you sure you want to reset your board?,wyk5s,@Battleship,Battleship)) bwndw -r
    elseif ($regml(1) == ___) {
      var %_b.psx $gettok($hotlinepos,1,32), %_b.psy $gettok($hotlinepos,2,32)
      if ($window($target).title == - Placing Ships...) {
        if (!%_b.rsp) set %_b.rsp - 2 3 3 4 5
        if (!%_b.mrk) {
          set %_b.mrk %_b.psx %_b.psy
          rline $target %_b.psy $puttok($hotline,[O],%_b.psx,32)
        }
        else {
          var %_b.its %_b.psy, %_b.itr %_b.its, %_b.ite $gettok(%_b.mrk,2,32), %_b.mth $calc(($instok($sorttok(%_b.its %_b.ite,32,nr),-,2,32)) / 2 + 1), %_b.tst
          if (%_b.psy == $gettok(%_b.mrk,2,32)) && ($calc($abs($calc(%_b.psx - $gettok(%_b.mrk,1,32))) +1) <= 5) {
            if (!$istok(%_b.rsp,$v1,32)) {
              noop $input(Error: Cannot place ship here... $+ $crlf $crlf Ship already in use,ows,@Battleship,Battleship)
              rline $target $gettok(%_b.mrk,2,32) $puttok($line($target,$gettok(%_b.mrk,2,32)),___,$gettok(%_b.mrk,1,32),32)
            }
            else {
              var %_b.tln $puttok($hotline,[O],%_b.psx,32), %_b.rng $iif(%_b.psx < $gettok(%_b.mrk,1,32),$+($v1,-,$v2),$+($v2,-,$v1)), %_b.tsp $gettok(%_b.tln,%_b.rng,32)
              if ($matchtok(%_b.tsp,[O],0,32) > 2) {
                noop $input(Error: Cannot place ship here... $+ $crlf $crlf Other ships in the way,ows,@Battleship,Battleship)
                rline $target %_b.psy $puttok($hotline,___,$gettok(%_b.mrk,1,32),32)
              }
              else {
                rline $target %_b.psy $puttok($hotline,[O],%_b.rng,32)
                %_b.rsp = $remtok(%_b.rsp,$abs($calc(%_b.rng - 1)),1,32)
                var %_b.tis $iif(%_b.psx < $gettok(%_b.mrk,1,32),$v1,$v2), %_b.tie $iif(%_b.tis == %_b.psx,$gettok(%_b.mrk,1,32),$v2)
                while (%_b.tis <= %_b.tie) {
                  var %_b.xmp $addtok(%_b.xmp,$bspot($v1,%_b.psy),32)
                  inc %_b.tis
                } 
                set %_b.map %_b.map $sorttok(%_b.xmp,32,n) $iif($numtok(%_b.map,44) < 4,$chr(44))
              }
            }
          }
          elseif (%_b.psx == $gettok(%_b.mrk,1,32)) && (%_b.mth <= 5) {
            if (!$istok(%_b.rsp,%_b.mth,32)) {
              noop $input(Error: Cannot place ship here... $+ $crlf $crlf Ship already in use,ows,@Battleship,Battleship)
              rline $target $gettok(%_b.mrk,2,32) $puttok($line($target,$gettok(%_b.mrk,2,32)),___,$gettok(%_b.mrk,1,32),32)
            }
            else {
              var %_b.opr $iif(%_b.its < %_b.ite,<=,>=), %_b.iod $replace(%_b.opr,<=,inc,>=,dec)
              while (%_b.itr %_b.opr %_b.ite) {
                if (!%_b.pas) {
                  var %_b.tst = $gettok($line($target,%_b.itr),%_b.psx,32)
                  if (%_b.tst == [O]) && (%_b.itr != %_b.ite) {
                    noop $input(Error: Cannot place ship here... $+ $crlf $crlf Other ships in the way,ows,@Battleship,Battleship)
                    rline $target $gettok(%_b.mrk,2,32) $puttok($line($target,$gettok(%_b.mrk,2,32)),___,$gettok(%_b.mrk,1,32),32)
                    break
                  }
                  if (%_b.itr == %_b.ite) var %_b.pas $true, %_b.itr %_b.its
                }
                if (%_b.pas) {
                  rline $target %_b.itr $puttok($line($target,%_b.itr),[O],%_b.psx,32)
                  var %_b.xmp $addtok(%_b.xmp,$bspot(%_b.psx,%_b.itr),32)
                }
                %_b.iod %_b.itr 2
              }
              if (%_b.pas) {
                %_b.rsp = $remtok(%_b.rsp,%_b.mth,1,32)
                set %_b.map %_b.map $sorttok(%_b.xmp,32,n) $iif($numtok(%_b.map,44) < 4, $chr(44))
              }
            }
          }
          else {
            noop $input(Error: Cannot place ship here... $+ $crlf $crlf Out of range,ows,@Battleship,Battleship) 
            rline $target $gettok(%_b.mrk,2,32) $puttok($line($target,$gettok(%_b.mrk,2,32)),___,$gettok(%_b.mrk,1,32),32)
          }
          unset %_b.mrk
        }
        if (%_b.rsp == -) {
          .ctcp %__b.chl bship_redy
          bwndw -s
        }
      }
      else {
        if (!%__b.rdy) noop $input(Please wait for %__b.chl to finish placing their ships,ok5s,@Battleship,Battleship)
        elseif (%__b.trn == $me) {
          var -g %_b.tgt $replace($hotlinepos,$chr(32),$chr(44))
          .ctcp %__b.chl $+(bship_,%_b.tgt)
          %__b.trn = %__b.chl
        }
        else noop $input(It is not your turn!,os,@Battleship,Battleship)
      }
    }
  }
}

; --- Background Functions

alias -l bwndw {
  if ($isid) return $window(@Battleship)
  if ($istok(-r -s,$1,32)) window -c $$window(@Battleship)
  if (!$window(@Battleship)) {
    if ($1 != -s) unset %_b.*
    window -aCdk0fB @Battleship -1 -1 526 404 "Courier New" 15 | var %_b.win @Battleship - $iif($1 == -s,$me vs. %__b.chl,Placing Ships...) | Renwin @Battleship %_b.win
    aline @Battleship $str($chr(160),2) $regsubex(A B C D E F G H I J,/(\w)/g,$chr(160)\t$chr(160)) $iif($1 != -s,$str($chr(160),4) Reset)
    aline @Battleship 
    var %i 1 | while (%i <= 10) {
      aline @Battleship $base(%i,10,10,2) ___ ___ ___ ___ ___ ___ ___ ___ ___ ___
      aline @Battleship 
      inc %i
    }
  }
}

alias -l bspot return $+($gettok(A B C D E F G H I J,$calc($1 - 1),32),:,$int($calc($2 / 2)))

on *:CLOSE:@Battleship: {
  .ctcp %__b.chl bship_quit
  unset %__b.* %_b.*
}

on me:*:NICK: {
  if (%__b.chl) .ctcp $v1 bship_nick
}

on me:*:QUIT: {
  if (%__b.chl) {
    .ctcp $v1 bship_quit
    unset %__b.* %_b.*
  }
}

ctcp ^*:bship_*:?: {
  haltdef | var %_b.cmd $gettok($1-,2,95)
  if (%_b.cmd == chal) {
    .timerbc 1 0 .ctcp $nick bship_ $!+ $!replace( $!input( $nick is challenging you to a game of battleship. Do you wish to accept?,yvk30s,@Battleship,Battleship) , $&
      $yes , acpt , $no , deny , $timeout , nrsp )
  }
  if ($istok(acpt strt,%_b.cmd,32)) {
    bwndw
    if (%_b.cmd == acpt) {
      .ctcp $nick bship_strt
    }
    var -g %__b.chl $nick, %__b.trn $iif(%__b.trn,$v1,$nick)
  }
  if (%_b.cmd == deny) {
    echo -gaec i * [Battleship] $nick has declined your challenge request
    unset %__b.trn
  }
  if (%_b.cmd == nrsp) echo -gaec i * [Battleship] No Response
  if (%_b.cmd == quit) {
    window -c @Battleship
    if (!%___b.nqm) echo -gaec i * [Battleship] %__b.chl has stopped playing
    unset %__b.* %_b.* %___b.nqm
  }
  if ($istok(~hit ~mis,%_b.cmd,32)) {
    rline @Battleship $gettok(%_b.tgt,2,44) $puttok($line(@Battleship,$gettok(%_b.tgt,2,44)),$replace(%_b.cmd,~hit,04[X],~mis,[-]),$gettok(%_b.tgt,1,44),32)
    .timerbc 1 0 noop $!input( $!replace( %_b.cmd , ~hit , Hit! , ~mis , Miss ) ,ok5s,@Battleship,Battleship)
    unset %_b.tgt
  }
  if (%_b.cmd == redy) {
    .timerbc 1 0 noop $!input(%__b.chl has finished placing their ships,ok5,Battleship )
    set %__b.rdy $true
  }
  if (, isin %_b.cmd) {
    var %_b.nsp $numtok($remove(%_b.map,$chr(32)),44), %_b.mtg $bspot( [ $v2 ] )
    .ctcp $nick $+(bship_,$iif($istok(%_b.map,%_b.mtg,32),~hit,~mis))
    var -g %__b.trn $me, %_b.map $remtok(%_b.map,%_b.mtg,1,32)
    if ($numtok($remove(%_b.map,$chr(32)),44) < %_b.nsp) {
      .timerbc 1 0 noop $!input( One of your ships has been sunk!,wok5s,@Battleship,Battleship) 
      .ctcp $nick bship_sink
      if (!$v1) .ctcp $nick bship_clos
    }
  }
  if (%_b.cmd == sink) .timerbc 1 0 noop $!input( You have sunk one of $nick $+ 's ships!,ok5s,@Battleship,Battleship)
  if (%_b.cmd == clos) {
    .ctcp $nick bship_cwin
    .timerbc 1 0 noop $!input( You win! All of $nick $+ 's ships have been sunk!,ok5s,@Battleship,Battleship) $(|) set %___b.nqm $true $(|) window -c @Battleship
  }
  if (%_b.cmd == cwin) .timerbc 1 0 noop $!input( You lose. $nick has sunk all of your ships,ok5s,@Battleship,Battleship) $(|) set %___b.nqm $true $(|) window -c @Battleship
  if (%_b.cmd == nick) set %__b.chl $nick
}
Sign in to comment.
Meta   -  Apr 19, 2012

o_O @evilMonkey - What error are you getting?

I've added a video demonstrating this script in action above.

 Respond  
evilMonkey   -  Apr 19, 2012

So this still doesn't work. When I try to place ships, it keeps coming up with errors after I'm trying to place the fourth piece.

 Respond  
Meta   -  Apr 14, 2012

Ok, I've made a few updates to the script.

 Respond  
SunnyD   -  Apr 12, 2012

Looks intriguing, Meta. I may have to dust off mIRC and give it a shot.

I couldn't help but laugh a little bit regarding your comment, Spoof.

.00 = zero .01 = 1 hundredth or 1/100 or 1% .10 = 1 tenth or 1/10 or 10%

 Respond  
KilllerX   -  Apr 11, 2012

lol, ok Meta.

 Respond  
Meta   -  Apr 11, 2012

Meta inconspicuously points at his tags and code description. (KilllerX)

Btw, I have made some improvements over the last couple of days, so expect an update soon. Hopefully some of the major bugs will be completely fixed (if anyone was able to test this and find any) and hopefully the script will be more reliable as a result.

 Respond  
Hawkee   -  Apr 11, 2012

I've seen .1 used before to denote alpha. It just indicates that it's still in the early stages of testing.

 Respond  
KilllerX   -  Apr 11, 2012

But, when counting. Who start's counting at the number Zero. If this wasn't finished, It would be considered a Demo, but since it seems to be finished. It is considered Version 1.0 after that, you can increment the .0 to .1 or .2 or stuff like that.

 Respond  
sunslayer   -  Apr 10, 2012

@Spoof i sincerely hope you are kidding.

 Respond  
Spoof   -  Apr 10, 2012

.00 = tenths .01 = 1 tenth .10 tenths = a whole number called 1 stay in school sunslayer.

 Respond  
sunslayer   -  Apr 09, 2012

Shouldn't it be called " v1.0 " seeing how 1.0 = 1 ? hmmmlol, dyslexic moment?

 Respond  
Meta   -  Apr 09, 2012

Hmm... something might've happened to the code while I was pasting it. I'll look at it and try to fix it when I get home. I should probably mention that this script (currently) relies almost entirely on custom CTCPs. so make sure that the person you are challenging can recieve them. I'll add error alerts for these things as well when I get home. Spoof, this script is still pretty much in the alpha phase, which is why I'm calling it v0.1 rather than v1.0

 Respond  
Spoof   -  Apr 09, 2012

Shouldn't it be called " v1.0 " seeing how 1.0 = 1 ? hmmm

 Respond  
Hawkee   -  Apr 09, 2012

We just tried it and after accepting the challenge nothing happened. No errors were thrown.

 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.