HJG 2013-02-22 - A WebMaze is a maze of webpages, with links pointing to other pages of the maze.
The userinterface looks like an old-fashioned text-adventure, with commands like "Go north", "Go west" etc. Except, there are no objects, no inventory, no enemies, no actions etc. beside walking around:
Maze You are in a maze of twisty little passages, all alike. The floor is solid stone. Exits: * North another part of the maze * South the entrance * West a trap for webcrawlers and spammers © 2012-12-22 Contact: Webmaster
Each such page is quite simple, but creating/maintaining all the links by hand would be errorprone and boring.
So I wrote a program that creates such a set of webpages. (Does that make me a html-programmer ? :)
This one is really simple, as it uses a hardcoded 3x3 maze:
7 - 6 - 5 ! ! ! X <- 8 - 9 - 4 - ! ! 3 - 2 - 1 <- 0 0: Entry=index.html 1: first room 2,3: dead end 4,5,6,7: correct path 8: last room X: Exit=index2.html 9: Trap (can be reached from rooms 2,4,6,8)
The entry- and exit-pages (here 0 and X) are 'outside', i.e. not part of the maze. The generated files index1- and index2.html are just meant as an example.
The trap is a set of rooms with links that only point to other traps. Anybody that visits more than 3-4 such trap-pages is most likely a bot / webcrawler.
One way to use this, is to 'hide' some part of a website (or all of it :)
E.g. all the maze-pages go into a subdirectory "webmaze", the standard startpage index.html redirects to the first maze-page, and the exit-page of the maze points to the renamed homepage, e.g. /index3.html.
To specify a redirection, just put a line like this at the top of the startpage (after "<head>"):
<meta http-equiv="refresh" content="0; URL=webmaze/maze1.html">
To prevent cheating/guessing, we also need to catch 404-errors (i.e. redirect them to our trap-page :). Such a custom local ErrorDocument is specified with an entry in the file .htaccess, e.g. :
ErrorDocument 404 /webmaze/maze9.html
Before using this script, you might want to customize it a bit (scheme for roomnames, messages, contact-eMail, index1/2/3-files etc.).
# https://wiki.tcl-lang.org/37725 # webmaze08.tcl - HaJo Gurt - 2013-02-18 #: Generate a set of webpages that form an text-adventure-type maze. # Contains a trap for webcrawlers. # Simple, static version # Now also generates example-files index1.html + index2.html. # index1.html is to be moved into the document-root of the webspace, # as a replacement for the default index.html. # All the maze*.html - files go into a subdir "webmaze". # Installation - at your workstation: # * Create subdir "webmaze" # * Copy this script into this directory and run it there --> files are generated. # To run just the maze locally, drag+drop maze1.html into your browser. # # To see the redirection working, move index1.html one level up from webmaze, # then drop it into your browser. # Installation - at the webserver: # * Rename index.html --> index3.html # * Create subdir "webmaze" # * Transfer all files maze* from subdir "webmaze" at the workstation # to the subdir "webmaze" at the webserver. # (Depending on your ftp-client, you might want to zip the files first) # * Transfer the file index1.html from subdir "webmaze" at the workstation # to the webroot "/" at the webserver. # * Rename index1.html --> index.html # # Entering your website, the new index.html should redirect to webmaze/maze1.html. # After running thru the maze, the last mazepage webmaze/maze8.html # leads to the exitpage webmaze/index2.html, and this # webmaze/index2.html redirects to index3.html, which is the old index.html. # # The examplefiles wait 5 seconds before redirecting, so you can see # what is going on, but you can set that time to 0. # Todo: # * Generate a maze, like [maze generator] or [maze generator2], # or import a maze-description in a suitable format. # * Simpler way to generate the set of trap-pages. # * Tweak page-layout, meta-entries etc. # * Options: Switch entry+exit / Disable trap (replace with deadend) set Hdr "WebMaze v0.8" ####+####1####+####2####+####3####+####4####+####5####+####6####+####7####+### ## Console-settings, to allow running in wish as well as in tclsh: catch { console show } catch { wm withdraw . } # catch { console eval { .console config -bg grey -fg blue } } # Resize & put at top-right corner on 1024x768: ##catch { console eval { wm geometry . 56x12+550+0 } } catch { console title "$Hdr" } proc q {} { exit } proc put1 {s} { #: Output to screen or file global fp # puts $s puts $::fp $s } ####+####1####+####2####+####3####+####4####+####5####+####6####+####7####+### if 0 { Simple 3x3 - Maze: N W+E S 7 - 6 - 5 ! ! ! X <- 8 - 9 - 4 - ! ! 3 - 2 - 1 <- 0 0: Entry=index.html 1: first room 2,3: dead end 4,5,6,7: correct path 8: last room X: Exit=index2.html 9: Trap (can be reached from rooms 2,4,6,8) } # Hardcoded maze-layout: set Loc1 1 ;# First room set LocL 8 ;# Last room set LocX X ;# Exit - redirecting examplefile is generated / see RoomName(), ExitPage() set LocT 9 ;# Trap # Pg Ty N E S W set Links " 1 R1 4 - - 2 2 .. 9 1 - 3 3 DE - 2 - - 4 .. 5 - 1 9 5 .. - - 4 6 6 .. - 5 9 7 7 .. - 6 8 - 8 RL 7 9 - X 9 T 9a 9b 9c 9d 9a T 9b 9c 9d 9e 9b T 9c 9d 9e 9f 9c T 9d 9e 9f 9g 9d T 9e 9f 9g 9h 9e t 9f 9g 9h 9i 9f T 9g 9h 9i 9 9g T 9h 9i 9 9 9h T 9i 9 9 9 9i T 9 9 9 9 " proc RoomName {N} { # set Name "http://example.com/maze$N.html" set Name "maze$N.html" if {$N == $::LocX} { set Name "index2.html" } return $Name } ####+####1####+####2####+####3####+####4####+####5####+####6####+####7####+### proc RoomText {Ty} { set Msg "The floor is solid stone." if {$Ty == "R1"} { set Msg "You entered the maze here." } if {$Ty == "RL"} { set Msg "You can leave the maze from here." } if {$Ty == "X" } { set Msg "You have reached the exit." } if {$Ty == "DE"} { set Msg "This is a dead end." } if {$Ty == "D2"} { set Msg "Turn back! The end is here!" } if {$Ty == "T" } { set Msg "You fell into this trap for webcrawlers and spammers." } if {$Ty == "t" } { set Msg "You are still falling down this trap." } return $Msg } proc LinkText {N} { global Loc1 LocL LocX LocT set Msg "another part of the maze" if {$N == $Loc1} { set Msg "the entrance" } if {$N == $LocL} { set Msg "you see light from that part of the maze" } if {$N == $LocX} { set Msg "the exit" } if {$N == $LocT} { set Msg "a trap for webcrawlers and spammers" } return $Msg } proc RoomLink {Dir N} { # put1 " <li> <a href=\"maze$N.html\">$Dir</a> [LinkText $N] </li>" put1 " <li> <a href=\"[RoomName $N]\">$Dir</a> [LinkText $N] </li>" } proc TrapLink {Dir N} { put1 " <li> <a href=\"[RoomName $N]\">$Dir</a> </li>" } ####+####1####+####2####+####3####+####4####+####5####+####6####+####7####+### proc Header {Pg Ty} { put1 "<html>" put1 "<head>" # put1 "<title>$::Hdr</title>" put1 "<title>WebMaze: $Pg</title>" ;# for history & bookmarks put1 "</head>\n" } proc Body1 {Pg Ty} { put1 "<body>" put1 "<h1>Maze</h1><hr>" put1 "<br>" put1 "<p>You are in a maze of twisty little passages, all alike.</p>" put1 "<p>[RoomText $Ty]</p>" put1 "<p><b>Exits:</b>" put1 "<ul>" } proc RoomLinks {N E S W} { if {$N ne "-"} { RoomLink North $N } if {$E ne "-"} { RoomLink East $E } if {$S ne "-"} { RoomLink South $S } if {$W ne "-"} { RoomLink West $W } } proc TrapLinks {N E S W} { if {$N ne "-"} { TrapLink "Down - normal speed" $N } if {$S ne "-"} { TrapLink "Down (slower)" $S } if {$W ne "-"} { TrapLink "Down (faster)" $W } if {$E ne "-"} { TrapLink "Down (extra quick)" $E } } proc Body2 {} { put1 "</ul> </p>" put1 "<hr noshade>" put1 "<!-- Footer: -->" put1 "© 2012-12-23 " put1 "Contact: <a href=mailto:[email protected]>Webmaster</a>" put1 "</body>" } proc Footer {} { put1 "</html>\n" } ####+####1####+####2####+####3####+####4####+####5####+####6####+####7####+### proc StartPage {File Txt To} { # Replacement for index.html, it redirects to the first maze-page. # The original index.html would be placed after the exit-page of the maze. puts "# File $File" set ::fp [open $File w] put1 "<html>" put1 "<head>" put1 "<meta http-equiv=\"refresh\" content=\"5; URL=$To\">" ;# seconds until redirect put1 "<title>$Txt</title>" put1 "</head>\n" put1 "<body bgcolor=cyan>" put1 "<h1>$Txt</h1><hr>" put1 " $Txt: <a href=\"$To\">$To</a>" put1 "</body>" put1 "</html>\n" close $::fp } proc ExitPage {File Txt To} { # Page after the maze is completed, it shows a short message, # and redirects to the old index.html (renamed "index3.html") set ::fp [open $File w] puts "# File $File" put1 "<html>" put1 "<head>" put1 "<meta http-equiv=\"refresh\" content=\"5; URL=$To\">" ;# seconds until redirect put1 "<title>$Txt</title>" put1 "</head>\n" put1 "<body bgcolor=lime>" ;# light green put1 "<h1>$Txt</h1><hr>" put1 "<p>You have reached the exit.</p>" put1 "<p>Congratulations !</p>" put1 "<p>And now, for something completely different: <a href=\"$To\">$To</a></p>" put1 "</body>" put1 "</html>\n" close $::fp } ####+####1####+####2####+####3####+####4####+####5####+####6####+####7####+### puts "# $Hdr :" foreach {Pg Ty N E S W} $Links { set pgFile [RoomName $Pg] puts "# Page $Pg : $N $E $S $W - $pgFile" set fp [open $pgFile w] Header $Pg $Ty Body1 $Pg $Ty if {$Ty=="T" || $Ty=="t"} { TrapLinks $N $E $S $W } else { RoomLinks $N $E $S $W } Body2 Footer close $fp } StartPage index1.html Redirect "webmaze/[RoomName $Loc1]" ExitPage [RoomName $LocX] Done "../index3.html" puts "# done." #.
See also: