Hangman game

Problem this snippet solves:

This is an iRule implementation of the popular Hangman Game. The iRule requires a data group definition containing the words, which has been attached as "classwords.txt". The iRule also requires a virtual server with an HTTP profile. If you don't use the attached data group for your words make sure to change the ::hangmanWordSize variable to the appropriate number.

Everything is done in the HTTP_REQUEST event, so interaction with the user is done through redirects, cookies, and HTTP responses from the LTM.

This has been tested to work on 9.4.5 and 10.0.0, but it should work on 9.3 as well.

If the browser does not support session cookies it will cause the iRule to behave unpredictably. It won't work, and there may be some bugs with continuous redirects. This has been tested to work properly with Firefox, IE7-8, and Google Chrome. Other browsers might work fine, although I know Lynx won't work properly.

You will see quite a few comments in the code as this was designed for training purposes to demonstrate the use of cookies, string manipulation, and displaying GIF/PNG using base64 encoding.

This wasn't designed to be used on a production system, but why not give your users something fun to do while waiting for the servers to come back online instead of the boring "This page is under construction" message?

Code :

when RULE_INIT {

#If $::mydebug is set to 1 then the program will do a lot of logging
set ::mydebug 0
#Set this variable to the size of the data group containing the
#hangman words
#This could be converted to a data group to prevent CMP demotion
set ::hangmanWordSize 21497

#These two variables are commented out because scoring is not yet implemented
#
#set ::hangmanHighScore 0
#set ::hangmanHighUser "Nobody has won yet."

#This iRule is designed to be done entirely in the HTTP_REQUEST event
#The client does GET requests, and the iRule interacts with the user through
#cookies and redirects.  The path in the URI is used to determine what
#action to take.
#
#The GIFs are base-64 encoded.  They could have been placed in /var/class
#on the LTM but this would make the code less cut and paste friendly.
#There is an associated data group required for this iRule.  You can create
#your own word list as follows:
# class Hangwords TCL doesnt let me put a brace here but there should be one
# "1 aardvardk"
# "2 aback"
# "3 abacus"
# etc.  The words should only contain lowercase letters a-z, no spaces,
# dashes, or other punctuation are allowed in the words.
#
#This code was written by Tony Torzillo to demonstrate iRule functionality.
#
#TODO:  Implement scoring - thought about using a global associative array
#or just continuing to use cookies.  Wanted to avoid globals, but if we want
#to track the high score for all users we would have to use at least a global
#for that.
#
#Implement cookie encryption - had a lot of cookie debugging to do.  Wanted to
#implement AES encryption for the cookies so that someone can't cheat.
#
#Implement input validation - No input validation currently when someone puts in a
#userID.  This code might be vulnerable to exploits and tampering since a lot of validation
#isn't done.  There was some attempt to protect against forceful browsing, but it isn't
#that robust.
#
#Implement cookie validation - someone could really mess the code up by putting in some
#strange cookie values with something like Fiddler.  Also if cookie encryption is implemented
#you have to make sure to account for the case where the cookies can't be decrypted.  This
#can happen if someone loads the iRule into memory in RULE_INIT and overwrites the existing
#key. I didn't want to implement cookie encryption without cookie validation.
#
#This iRule has been tested to work on 9.4.5 and 10.0.0.  It should work on 9.3 as well
#but I haven't tested it.  It doesn't make use of "values" introduced in 9.4, but I can't
#guarantee it will work.
#
#This code should not be used on a production system as it may have security flaws or
#problems with continuous redirects.
#
#This code has been tested with IE7, IE8, Firefox 1.5.0.4, and Google Chrome 1.0.154.65
#Different browsers handle cookies differently - apparently we all interpret RFC 2109 just
#a little differently, so this may not work with other browsers like Opera and Safari.
}

when HTTP_REQUEST {
  if { $::mydebug} { log local0. "in HTTP_REQUEST" }
  #This iRule will do different things based on the path passed in.
  #Different image names in the path will cause it to display a GIF or PNG
  #It does this by sending a b64encoded GIF or PNG back with an HTTP response
  #when that image is referenced - i.e. /hangman.gif could be referenced within
  #the iRule with   
  #I realize that this could have been put in /var/class to make the code cleaner
  #but I wanted it to be cut and paste friendly.

  switch -glob [string tolower [HTTP::path]] {
/hangman.gif {
HTTP::respond 200 content [b64decode \
"R0lGODlhtgFQAPcAAAAAAIAAAACAAICAAAAAgIAAgACAgICAgMDAwP8AAAD/AP//AAAA//8A/wD/\
/////wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMwAAZgAAmQAAzAAA/wAzAAAzMwAzZgAzmQAzzAAz/wBm\
AABmMwBmZgBmmQBmzABm/wCZAACZMwCZZgCZmQCZzACZ/wDMAADMMwDMZgDMmQDMzADM/wD/AAD/\
MwD/ZgD/mQD/zAD//zMAADMAMzMAZjMAmTMAzDMA/zMzADMzMzMzZjMzmTMzzDMz/zNmADNmMzNm\
ZjNmmTNmzDNm/zOZADOZMzOZZjOZmTOZzDOZ/zPMADPMMzPMZjPMmTPMzDPM/zP/ADP/MzP/ZjP/\
mTP/zDP//2YAAGYAM2YAZmYAmWYAzGYA/2YzAGYzM2YzZmYzmWYzzGYz/2ZmAGZmM2ZmZmZmmWZm\
zGZm/2aZAGaZM2aZZmaZmWaZzGaZ/2bMAGbMM2bMZmbMmWbMzGbM/2b/AGb/M2b/Zmb/mWb/zGb/\
/5kAAJkAM5kAZpkAmZkAzJkA/5kzAJkzM5kzZpkzmZkzzJkz/5lmAJlmM5lmZplmmZlmzJlm/5mZ\
AJmZM5mZZpmZmZmZzJmZ/5nMAJnMM5nMZpnMmZnMzJnM/5n/AJn/M5n/Zpn/mZn/zJn//8wAAMwA\
M8wAZswAmcwAzMwA/8wzAMwzM8wzZswzmcwzzMwz/8xmAMxmM8xmZsxmmcxmzMxm/8yZAMyZM8yZ\
ZsyZmcyZzMyZ/8zMAMzMM8zMZszMmczMzMzM/8z/AMz/M8z/Zsz/mcz/zMz///8AAP8AM/8AZv8A\
mf8AzP8A//8zAP8zM/8zZv8zmf8zzP8z//9mAP9mM/9mZv9mmf9mzP9m//+ZAP+ZM/+ZZv+Zmf+Z\
zP+Z///MAP/MM//MZv/Mmf/MzP/M////AP//M///Zv//mf//zP///ywAAAAAtgFQAAAI/wAfCBxI\
sKDBgwgTKlzIsKHDhxAjSpxIsaLFixgzatzIsaPHjyBDihxJsqTJkyhTqlzJsqXLlzBjypxJs6bN\
mzhz6tzJs6fPn0CDCh1KtKjRo0iTKl3KtKnTp1CjSp1KtarVq1izat3KtavXr2DDih1LtqzZs2jT\
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\
aItUz90Ot7jHTe5ym/vc6E73rAICADs="] "Content-Type" "image-gif"

return ok

}
/hangman0.png {
HTTP::respond 200 content [b64decode \
"iVBORw0KGgoAAAANSUhEUgAAAQAAAAEACAYAAABccqhmAAAABmJLR0QA/wD/AP+gvaeTAAAACXBI\
WXMAAAsSAAALEgHS3X78AAAAB3RJTUUH1QUSFAoGtHRxSwAAAslJREFUeJzt3EEKhDAUBUGVuf+V\
9QgKDnxiV53gbdJkEbJtAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMCdfXoA487pAR+x\
5Fk6pgcAcwQAwgQAwgQAwgQAwgQAwgQAwgQAwgQAwgQAwn7TA1jGkk9dH0g/hXYDgDABgDABgDAB\
gDABgDABgDABgDABgDABgDABgDABgDABgDABgDABgDABgDABgDABgDABgDABgDB/AvLVv/54wA0A\
wgQAwgQAwgQAwgQAwgQAwgQAwgQAwgQAwgQAwgQAwgQAwgQAwgQAwgQAwgQAwgQAwgQAwgQAwgQA\
wgQAwgQAwgQAwgQAwgQAwgQAwgQAwgQAwgQAwgQAwgQAwgQAwgQAwgQAwgQAwgQAwgQAwgQAwgQA\
wgQAwgQAwgQAwgQAwgQAwgQAwgQAwgQAwgQAwgQAwgQAwgQAwgQAwgQAwgQAwgQAwgQAwgQAwgQA\
wgQAwgQAwgQAwgQAwgQAwgQAwgQAwgQAwgQAwgQAwgQAwgQAwgQAwgQAwgQAwgQAwgQAwgQAwgQA\
wgQAwgQAwgQAwgQAwgQAwgQAwgQAwgQAwgQAwgQAwgQAwgQAwgQAwgQAwgQAwgQAwgQAwgQAwgQA\
wgQAwgQAwgQAwgQAwgQAwgQAwgQAwgQAwgQAwgQAwgQAwgQAwgQAwgQAwgQAwgQAwgQAwgQAwgQA\
wgQAwgQAwgQAwgQAwgQAwgQAwgQAwgQAwgQAwgQAwgQAwgQAwgQAwgQAwgQAwgQAwgQAwgQAwgQA\
wgQAwgQAwgQAwgQAwgQAwgQAwgQAwgQAwgQAwgQAwgQAwvbpAfzFOT2AMa/OsBsAhAkAhAkAhAkA\
hAkAhAkAhAkAhAkAhAkAhAkAhAkAhAkAhAkAhAkAhAkAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\
AAAAAAAAANy7AOu/BIYwGzL3AAAAAElFTkSuQmCC"] "Content-Type" "image-png"

return ok

}
/hangman1.png {
HTTP::respond 200 content [b64decode \
"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"] "Content-Type" "image-png"

return ok

}
/hangman2.png {
HTTP::respond 200 content [b64decode \
"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"] "Content-Type" "image-png"

return ok

}
/hangman3.png {
HTTP::respond 200 content [b64decode \
"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"] "Content-Type" "image-png"

return ok

}
/hangman4.png {
HTTP::respond 200 content [b64decode \
"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"] "Content-Type" "image-png"

return ok

}
/hangman5.png {
HTTP::respond 200 content [b64decode \
"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"] "Content-Type" "image-png"

return ok

}
/hangman6.png {
HTTP::respond 200 content [b64decode \
"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"] "Content-Type" "image-png"

return ok

}
/flash.html {
if {[HTTP::cookie exists HangmanCookie]}{
set userID [substr [HTTP::cookie HangmanCookie] 7 ":"]
set hangword [findstr [HTTP::cookie HangmanCookie] "hangword," 9 ":"]
if {$::mydebug} { log local0. "userID=$userID and hangword = $hangword" }
} else {
#If they got in here it was probably by forceful browsing, so send
#them back to the main page.  The cookie needs to be set before moving
#forward.
HTTP::redirect "/index.html"
return ok
}

#Test to see if there are any wrong answers and change that variable to the
#number wrong
if {[HTTP::cookie exists HangmanWrong]} {
set wronganswers [HTTP::cookie HangmanWrong]
} else {
set wronganswers 0
}

#Figure out how long the hangman word is
set lettercount [string length $hangword]

#Iteratively print the letters as dashes - filling in letters if there is a correct
#guess
#create a blank string called letterstring
set letterstring ""
#See if there were any correct guesses first and set a variable to that
#value
if { [HTTP::cookie exists HangmanGuesses] } {
set guesses [HTTP::cookie HangmanGuesses]
} else {
set guesses "_"
}
if {$::mydebug} { log local0. "Guesses = $guesses" }

#create a list of letters from the hangman word
#This is used to determine if a character should be printed on the
#hangman board or not.  This creates a list by making each letter
#into a member of the list - so "abcdef" becomes { a b c d e f }
#You can then reference them with [lindex $hangletterlist 0]
#which in this example would be "a" because it is the 0th letter in
#the list.
set hangletterlist [split $hangword {}]

#OK - iterate through the whole list of letters in the word and determine
#if any of the existing guesses there are correct.  If so then print them
#accordingly
#Assume that there are no right guesses and if there are then display them
#If the user has as many rightguesses as letters then they win
set rightguesses 0

#Wrong guesses isn't used yet - this could be implemented later though
#set wrongguesses 0

for { set i 0 } { $i < $lettercount } { incr i } {
set currentletter [string toupper [lindex $hangletterlist $i]]
if {$::mydebug} { log local0. "Currentletter = $currentletter" }
if { $guesses contains $currentletter } {
set letterstring "$letterstring $currentletter"
incr rightguesses
} else {
set letterstring "$letterstring  _"
#incr wrongguesses
}
}
#If the number of guesses is the same as the letter count they won.
if { $rightguesses >= $lettercount } {
if {$::mydebug} { log local0. "Going to redirect to win.html" }
HTTP::respond 302 Location "/win.html?userID=$userID&hangword=$hangword" 
#Set-Cookie: $cookies
return ok

if {$::mydebug} { log local0. "Should have redirected so I shouldn't be here" }
}
if {$::mydebug} { log local0. "Letterstring = $letterstring" }
#Keystring is the keyboard that is displayed to the user.
#If they already guessed wrong then don't display that key as an HREF.  Bold it.
#

set keystring ""
#Build a keystring so that if the guesses were wrong you don't include an
#HREF.
    if { [HTTP::cookie exists HangmanWrongGuesses] } {
set badguesses "[HTTP::cookie HangmanWrongGuesses]"
}   else {
set badguesses "0"
}
if {$::mydebug} { log local0. "Badguesses = $badguesses" }
#Create a list representing the keyboard and iterate through it to determine
#if each letter should be represented as a link or as a bolded character.
#A bolded character means it has already been pressed, either in a correct guess
#or in a wrong guess.
#
#To add a space into the keyboard, just insert a "-" into the list
#To add a space and a line break, just insert a "_" into the list
foreach keyletter { Q W E R T Y U I O P _ A S D F G H J K L _ - Z X C V B N M} {
if {$::mydebug} { log local0. "Keyletter = $keyletter" }
if { (not ($keyletter eq "_") ) and ( ($badguesses contains $keyletter) or ($guesses contains $keyletter) )} {
set keystring "$keystring\n$keyletter"
} else {
if {$keyletter eq "_"} {
set keystring "$keystring\n  "
} elseif {$keyletter eq "-"} {
set keystring "$keystring\n  "
}
else {
set keystring "$keystring\n$keyletter"
}
}
}



if {$::mydebug} { log local0. "Keystring = $keystring" }

#This code will display a keyboard.  If a user presses a key
#then this will be the path that is called
if { $wronganswers < 7 } {
#All of this is just a bunch of HTML to create keys that the user
#can click on.  Then we can check the path and see what letter they pressed.
#Kind of a cool way to do user input, since we don't use any forms or anything.
#Just good old HTML the way Dr. Berners Lee intended it to be. :)
HTTP::respond 200 content "






$letterstring

$keystring

" return ok } else { #The user lost because wronganswers is not < 7 #so now get rid of the cookies if { $::mydebug } { log local0. "User lost" } set wronganswers 0 HTTP::respond 302 Location "/lost.html?hangword=$hangword&userID=$userID" return ok } } /lost.html* { if {$::mydebug} { log local0. "I'm in your lost section logging your irulez" } #Get the word that they passed in if { [HTTP::query] contains "hangword=" } { set hangword [findstr [HTTP::query] "hangword=" 9 "&"] } else { set hangword "Undefined." } if { [HTTP::query] contains "userID=" } { set userID [findstr [HTTP::query] "userID=" 7 "&"] } else { set userID "Undefined." } HTTP::respond 200 content " You lost

I am so sorry that you lost. Please try again.

The super tricky word that finally did you in was $hangword. Please press here to start over " return ok } /win.html* { if {$::mydebug} { log local0. "I'm in your win section winning your irulez" } if { [HTTP::query] contains "userID=" } { set userID [findstr [HTTP::query] "userID=" 7 "&"] } if { [HTTP::query] contains "hangword=" } { set hangword [findstr [HTTP::query] "hangword=" 9 "&"] } #Before we do any operations on variables we should check to see if they exist first #if userID doesn't exist then we will behave differently. if { [info exists userID] } { HTTP::respond 200 content " You won

You won. You are so awesome $userID.

The winning word was $hangword. Please press here to keep going " return ok } else { HTTP::respond 200 content " Where did you come from

I am not sure how you arrived here but this is the win page.

If you want to play and really win press here. " return ok } } /?.html { #Get the letter that was pressed from the PATH set letter [substr "[HTTP::path]" 1 "."] if {($letter >= "A") and ($letter <= "Z") } { if {$::mydebug} { log local0. "Letter pressed was $letter" } if {[HTTP::cookie exists HangmanCookie]}{ set userID [substr [HTTP::cookie HangmanCookie] 7 ":"] set hangword [findstr [HTTP::cookie HangmanCookie] "hangword," 9 ":"] if {$::mydebug} { log local0. "Letter pressed was $letter userID=$userID and hangword = $hangword" } #Check to see if the word contains the letter pressed if {"[string toupper $hangword]" contains "$letter" } { #If it has the letter you need to display the new #string - for now just redirect back #Getting in here means that the user guessed the letter properly if {$::mydebug} { log local0. "The letter $letter was in $hangword" } if {[HTTP::cookie exists HangmanGuesses]}{ set guesses [HTTP::cookie HangmanGuesses] set guesses "$guesses,$letter" } else { set guesses "$letter" } HTTP::respond 302 Location "/flash.html" "Set-Cookie" \ HangmanGuesses=$guesses return ok } else { #We have to store the letters they guessed wrong as well if {[HTTP::cookie exists HangmanWrongGuesses]}{ set guesses [HTTP::cookie HangmanWrongGuesses] set guesses "$guesses,$letter" } else { set guesses "$letter" } #If there ia a cookie called HangmanWrong, then increment it #if there isn't then create it. if {[HTTP::cookie exists HangmanWrong] } { if {$::mydebug} {log local0. "Had a hangman wrong cookie"} set hangmanWrong "[HTTP::cookie HangmanWrong]" incr hangmanWrong set cookies "HangmanWrong=$hangmanWrong\r\nSet-Cookie: HangmanWrongGuesses=$guesses" HTTP::respond 302 Location "/flash.html" Set-Cookie $cookies return ok } else { set hangmanWrong "1" if {$::mydebug} {log local0. "No hangmanwrong cookie"} set cookies "HangmanWrong=$hangmanWrong\r\nSet-Cookie: HangmanWrongGuesses=$guesses" HTTP::respond 302 Location "/flash.html" Set-Cookie $cookies return ok } } } else { #If they got in here it was probably by forceful browsing, so send #them back to the main page. The cookie needs to be set before moving #forward. HTTP::redirect "/index.html" return ok } } else { #This code should only execute if someone put something manually into the URL #bar to try and mess with the program. HTTP::respond 200 content "You pressed a key You pressed $letter, which is not a valid letter" return ok } } /cookieclear.html { #This code was necessary because cookies weren't clearing properly when done all at once #Tried this to do them manually. Cookies can be a bit difficult to clean up. #This hack will remove the cookies by setting the expire time to an hour #earlier in relative time # #Create a string with all the cookies to send back #This one expires all the cookies #Internet Explorer doesn't process Max-Age - so much for RFC-2109 #Firefox doesn't process expires=-3600 - not sure why #Must do both to support both browsers if { [HTTP::cookie exists HangmanWrong] or [HTTP::cookie exists HangmanGuesses] or \ [HTTP::cookie exists HangmanCookie] or [HTTP::cookie exists HangmanWrongGuesses] } { HTTP::respond 302 Location "/cookieclear.html" Set-Cookie \ "HangmanWrong=null; expires=-3600; max-age=0;\ \r\nSet-Cookie: HangmanGuesses=null; expires=-3600; max-age=0;\ \r\nSet-Cookie: HangmanCookie=null; expires=-3600; max-age=0;\ \r\nSet-Cookie: HangmanWrongGuesses=null; expires=-3600; max-age=0;" return ok } #If they got to here there are no more cookies in the cookie jar. Time to go to the grocery #store and buy some more. #Ok, nice metaphor but we are just going to redirect back to index.hmtl. If they aren't gone it #will come back. Hope we don't get stuck in a loop. #Keep the userID - should be in the Referer header if { [HTTP::header referer] contains "userID=" } { set userID [findstr "[HTTP::header referer]" "userID=" 7 "&"] HTTP::respond 302 Location "/index.html?userID=$userID" return ok } else { HTTP::respond 302 Location "/index.html" return ok } } /index.html - / { #Check to see if any cookies exist. They shouldn't since this is the start of the program. if { [HTTP::cookie exists "HangmanCookie" ] or [HTTP::cookie exists "HangmanWrong"] \ or [HTTP::cookie exists "HangmanGuesses"] or [HTTP::cookie exists "HangmanWrongGuesses"] } { #If there is already a cookie then the user shouldn't be here. #They probably messed with the URL bar manually. HTTP::respond 302 Location "/cookieclear.html" return ok } else { #This is where we need to set the userID if { [HTTP::uri] contains "userID=" } { #Search for userID in query string set userID [findstr "[HTTP::query]" "userID=" 7 "&"] #This is to search through the data group to get the random word #the variable $::hangmanWordSize is a variable that represents #the number of words in the data group, or "class" set randomnumber [expr { int ($::hangmanWordSize * rand()) }] #Since the class is separated by spaces we can just get the one with #that index #The words in the class have the format of "Number Word" #So if you reference "1 aardvark" you can get the word #aardvark using findclass set myword [findclass "$randomnumber" $::Hangmanwords " "] set cookies "HangmanCookie=userID,$userID:hangword,$myword" HTTP::respond 302 Location "/flash.html" Set-Cookie $cookies return ok #This is just the intro page if there was no userID in the URI #Just put the basic page up } else { HTTP::respond 200 content "Hangman
The hangman game is one in which you attempt to guess the letters in a word. The number of letters in the word will be represented by dashes. You have 7 chances to guess the word, and each time you are wrong you will see a new body part created. Please enter a username below and press enter to start the game.

This whole game is done by an iRule with a single event. There are $::hangmanWordSize words available in this game.

Username:
" return ok } } } } if {$::mydebug} { log local0. "The PATH was [HTTP::path]" } } # Data Group Definition

Published Mar 17, 2015
Version 1.0