Version 14 of WebMaze

Updated 2013-02-26 12:28:04 by HJG

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 quite 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=start.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 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 'real' homepage, e.g. /start.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 etc.).

 # http://wiki.tcl.tk/37725
 # webmaze06.tcl - HaJo Gurt - 2013-02-13

 #: Generate a set of webpages that form an text-adventure-type maze.
 # Contains a trap for webcrawlers.
 # Simple, static version

 # Todo: 
 # * Generate a maze, like [maze generator] or [maze generator2], or import such a maze-description.
 # * simpler way to generate the set of trap-pages
 # * tweak page-layout, meta-entries etc.

 set Hdr "WebMaze v0.6"

 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=start.html
  9: Trap (can be reached from rooms 2,4,6,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 }

 ####+####1####+####2####+####3####+####4####+####5####+####6####+####7####+###

 # Hardcoded maze-layout:

   set Loc1  1        ;# First room
   set LocL  8        ;# Last room
   set LocX  X        ;# Exit - no room generated for the exit / see RoomName()
   set LocT  9        ;# Trap

  #             Pg Tx  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 "start.html" }

     return $Name
   }

 ####+####1####+####2####+####3####+####4####+####5####+####6####+####7####+###

   proc RoomText {Tx} { 
                        set Msg "The floor is solid stone."
     if {$Tx == "R1"} { set Msg "You entered the maze here." }
     if {$Tx == "RL"} { set Msg "You can leave the maze from here." }
     if {$Tx == "X" } { set Msg "You have reached the exit." }
     if {$Tx == "DE"} { set Msg "This is a dead end." }
     if {$Tx == "T" } { set Msg "You fell into this trap for webcrawlers and spammers." }
     if {$Tx == "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]"
     put1 "  <LI> <A href=\"[RoomName $N]\">$Dir</A> [LinkText $N]"
   }

   proc TrapLink {Dir N} { 
     put1 "  <LI> <A href=\"[RoomName $N]\">$Dir</A> "
   }

 ####+####1####+####2####+####3####+####4####+####5####+####6####+####7####+###

   proc Header {} { 
     put1 "<html>"
     put1 "<head>"
   # put1 "<title>WebMaze</title>"
     put1 "<title>$::Hdr</title>"
     put1 "</head>\n"
   }

   proc Body1 {Pg Tx} { 
     put1 "<body>"
     put1 "<h1>Maze</h1><hr>"
     put1 "<p>"
     put1 "You are in a maze of twisty little passages, all alike.<p>"
     put1 "[RoomText $Tx]<p>"
     put1 "Exits:"
     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 "&copy; 2012-12-22 -"
     put1 "Contact: <A href=mailto:[email protected]>Webmaster</A>"
     put1 "</body>"
   }

   proc Footer {} { 
     put1 "</html>\n"
   }


   proc put1 {s} { 
     global fp 
   # puts $s
     puts $fp $s
   }

 ####+####1####+####2####+####3####+####4####+####5####+####6####+####7####+###

   puts "# $Hdr :"

   foreach {Pg Tx N E S W} $Links {

   # set pgFile "maze$Pg.html"
     set pgFile [RoomName $Pg]

     puts "# Page $Pg : $N $E $S $W - $pgFile"

     set fp [open $pgFile w]

     Header
     Body1 $Pg $Tx
     if {$Tx=="T" || $Tx=="t"} {
       TrapLinks $N $E $S $W
     } else {
       RoomLinks $N $E $S $W
     }
     Body2
     Footer

     close $fp
   }
   
   puts "# done."

 #.

See also: