Sixteen for mIRCBy: FoF
Last Modified: Mar 22 3:39pm (r14)

I was asked to write this for a channel(and my bot) so with some help I present you the game of Sixteen.
You play by removing pieces from the "board" and the person who removes the last piece is the loser. Have fun and suggestions are welcome.
r1: Arcane gave me bad code.
r2-4: I just don't give idiots enough credit.
r5-8: Implemented things Frads mentioned. Also thanks to secretz.
r9-10: { } <--- sometimes they run away
r11: added checking of errors but didn't halt the action.
r12-13: Added variable size care of secretz. The limit right now is 9 because I believe the board would just to big to enjoy playing after that.
r14: cleaned up a little.
You play by removing pieces from the "board" and the person who removes the last piece is the loser. Have fun and suggestions are welcome.
r1: Arcane gave me bad code.
r2-4: I just don't give idiots enough credit.
r5-8: Implemented things Frads mentioned. Also thanks to secretz.
r9-10: { } <--- sometimes they run away
r11: added checking of errors but didn't halt the action.
r12-13: Added variable size care of secretz. The limit right now is 9 because I believe the board would just to big to enjoy playing after that.
r14: cleaned up a little.

On *:text:!Sixteen:#: {
if ( $hget(game)) {
SEnd
}
msg $chan Now starting a game of sixteen. Who wants to play against $nick $+ ?
set %players $nick
enable #js
}
#js off
on *:text:join*:#: {
msg $chan $nick is going to play against $gettok(%players,1,32)
set %players %players $nick
bs
}
#js end
alias bS {
disable #js
hmake game 10
hadd game 1 1
hadd game 2 3
hadd game 3 5
hadd game 4 7
set %turn 1
enable #st
board
}
alias board {
msg $chan Row 1: $str(X,$hget(game,1))
msg $chan Row 2: $str(X,$hget(game,2))
msg $chan Row 3: $str(X,$hget(game,3))
msg $chan Row 4: $str(X,$hget(game,4))
}
#st on
On *:text:take *:#: {
if ( $2 !isnum ) {
The row must be a number.
halt
}
if ( $3 !isnum ) {
The ammount must be a number.
halt
}
if ( $int($3) > $hget(game,$2) ) {
msg $chan There are not that many X's in that row please chose a differnt row or a different amount.
halt
}
if ( $int($3) <= 0 ) {
msg $chan Please choose a number greater then 0.
halt
}
if ( $2 > 4 ) || ( $2 <= 0 ) {
msg $chan That row does not exist please choose a number 1-4
halt
}
else {
if ( $nick == $gettok(%players,%turn,32) ) {
hdec game $2 $int($3)
if (( $hget(game,1) == 0 ) && ($hget(game,2) == 0 ) && ($hget(game,3) == 0 ) && ($hget(game,4) == 0 )) {
msg $chan $nick has lost.
msg $chan Sixteen has ended. Type !sixteen to start a new game.
SEnd
}
else {
board
if ( %turn == 1 ) {
set %turn 2
}
else {
set %turn 1
}
msg $chan It is now $gettok(%players,%turn,32) $+ 's turn.
}
}
}
}
on *:text:!stend:#: {
if ($istok(%players,$nick,32)) {
msg $chan Ending Sixteen. Type !sixteen to start a new game.
SEnd
}
}
on *:text:!board:#: {
if ($istok(%players,$nick,32)) {
board
}
}
#st end
alias SEnd {
disable #st
hfree game
unset %turn
unset %players
}
on *:text:!sthelp*:#: {
if ( $2 == !sixteen ) {
notice $nick Use this command to start the game.
}
if ( $2 == join ) {
notice $nick Use this to join a game after someone has started with !sixteen.
}
if ( $2 == take ) {
notice $nick Use this to remove pieces from the board in the form of Take #(row #) #(amount to take). E.G. take 4 3
}
if ( $2 == !stend ) {
notice $nick Use this command to end the game if your opponent has left.
}
if ( $2 == !board ) {
notice $nick This commands will display the board to the channel.
}
else {
notice $nick The commands for this game are: !sixteen, join, take, !board, !stend.
}
} |

Comments| Fradam Aug 20 8:57pm | "On *:text:!Sixteen:#: { if ( $hget(game) != : ) { hfree game unset %turn unset %player1 unset %player2" needs a closing bracket |
![]() | |
| Fradam Aug 20 8:59pm | " if ( $hget(game) != : ) { " <-- would it be better to simply use " if ( $hget(game)) {"? I noticed that if the table doesn't exist, mIRC will return an error by trying to test the inequality (as opposed to doing a test for existence) |
![]() | |
| Fradam Aug 20 9:54pm | Some more comments after implementing: - you might want to consider your current data structure for the names - using a single variable holding both names and gettok to retrieve them could save you a lot of code there (since you dont have to repeat all that code, you're simply accessing from what is essentially an array - I changed "On *:text:take *:#: { If ( $nick == %player1 ) && ( %turn == 1 ) {" into: "On *:text:take *:#: { if ($hget(game,$3) > 0) { If ( $nick == %player1 ) && ( %turn == 1 ) {" and added an appropriate else statement at the end -- otherwise, you could continually take fictional sticks from non-existent rows - This might be just me, but I switched the args around on the hdec game lines - it seemed more intuitive to me, when -thinking/saying- it, you say "You take 3 sticks from Row 2", as opposed to "You go to Row 2 and take 3 sticks" (which is moreso functionally correct - to go to a place and do something).. so if thats just me, feel free to ignore. - Might want to consider aliasing the board printing with parameters if neccessary for the various uses - I mean, it's really just the same code being used all over the place.. |
![]() | |
| Fradam Aug 23 4:56pm | Some more points: - you can currently play against yourself (I don't know about you, but I thought this was a little silly ;) - you need to return an error msg on trying to remove zero sticks (currently possible) - It looks a lot simpler and neater when aliasing the common functs and using tokens to store the players :) |
![]() | |
| Fradam Aug 26 7:37pm | Looking good FoF, just in addition to our discussion in #scripting .. for your !take trigger, instead of using : " if ( $nick == %player1 ) && ( %turn == 1 ) {" and the second if one for the second player, use this.. " if ( $nick == $gettok(%players,%turn,32) ) { " This means you check the nick against the token corresponding to the turn -- which wow, is the very nick you want :) Try it, and you'll see how beautifully it works! |
![]() | |
| secretz Aug 27 4:51pm | Think Fradamus mentioned while loops to make your codes shorter in some part. msg $chan Row 1: $str(X,$hget(game,1)) msg $chan Row 2: $str(X,$hget(game,2)) msg $chan Row 3: $str(X,$hget(game,3)) msg $chan Row 4: $str(X,$hget(game,4)) could be: var %i = 1 while ($hget(game,%i)) { msg $chan Row %i $+ : $str(X,$v1) inc %i } This also opens the possibility of a n-rowed game. hadd game 1 1 hadd game 2 3 hadd game 3 5 hadd game 4 7 could be: var %i = 1 while (%i <= $1) { hadd game %i $calc(2 * %i - 1) inc %i } It would also make the starting syntax of the game: !sixteen <numbers of rows>. You might make a if (!$1) there to maintain the default of four. |
![]() | |
| Fradam Oct 25 9:44am | Yey for implementation of the variable size boards :) |
![]() | |
| Franimus Dec 06 11:25pm | I think you still have 4 rows hardcoded there.. if ( $2 > 4 ) || ( $2 <= 0 ) { msg $chan That row does not exist please choose a number 1-4 halt } that's what jumped out at me (in the take trigger)... so you might have it other places |
![]() | |
| secretz Dec 28 3:59pm | Since "send" and "board" are such popular words, it could be wise to use local aliases. alias -l send |
![]() | |
