R·ex / Zeng


音游狗、安全狗、攻城狮、业余设计师、段子手、苦学日语的少年。 MUGer, hacker, developer, amateur UI designer, punster, Japanese learner.

My Adventure 全部代码

注意:本文发布于 2561 天前,文章中的一些内容可能已经过时。

Updated: 2013-06-09

突然发现地下一层有个小 BUG,还有些地方描述不是很科学,于是就改掉了。


My Adventure 的灵感来源是 Emacs 里面那个 Adventure,一个纯文字的冒险游戏。游戏的地图是一个 884 的世界,有点类似“密室逃脱”,只是范围大了点而已。还有就是傻瓜式的 tips,估计只要会敲键盘、读得懂英文,应该就能顺利地玩下来吧。

大家就不要吐槽我的英文水平了……

某天晚上灵光一现就想出了这个游戏的思路,于是寒假的任务之一就是把它写完。由于用的是Ruby语言,这份代码可以直接运行。里面有一些小细节,算是体现了我的个人幽默吧。

复制修改发布随意,这玩意是用来练习Ruby的,不存在版权问题。

附:商店第三层我不打算做了……

#--------------------------------------------------
# Initialize constants
#--------------------------------------------------
ACCOUNTS = [["RexSkz", "my_Adventure"], ["founder", "5eysg5a"]]
ALL_DIRECTIONS = ["east", "west", "north", "south", "in", "out", "up", "down"]
COMMANDS = [
  "where", "help", "look", "scan", "take", "get", "pick", "drop",
  "throw", "go", "put", "enter", "save", "load", "exit", "halt", "quit"
]
DELTA_POS = {
  'e' => [1, 0, 0], 'w' => [-1, 0, 0], 'n' => [0, 1, 0], 's' => [0, -1, 0],
  'i' => [0, 1, 0], 'o' => [0, -1, 0], 'u' => [0, 0, 1], 'd' => [0, 0, -1]
}
FULL_NAME = {
  'e' => "east", 'w' => "west", 'n' => "north", 's' => "south",
  'i' => "in", 'o' => "out", 'u' => "up", 'd' => "down"
}
HELP_ON_UNIX = [
  "---------------------------------------------------------------------------",
  "Attention: Upcase and downcase is different in unix.",
  "---------------------------------------------------------------------------",
  "Possible commands are:",
  "  1. cat",
  "    Usage: 'cat TARGET'",
  "    Display the contents of file TARGET on screen.",
  "  2. cd",
  "    Usage: 'cd [PATH]'",
  "    Consider the path PATH as current work path.",
  "    If PATH is nil, unix will do nothing.",
  "  3. clear",
  "    Usage: 'clear'",
  "    Clear all the content displayed on screen.",
  "  4. exit",
  "    Usage: 'exit'",
  "    Quit unix and return to your world.",
  "  5. help",
  "    Usage: 'help'",
  "    Display this help file.",
  "  6. ls",
  "    Usage: 'ls [TARGET]'",
  "    Display the contents of the folder TARGET.",
  "    If TARGET is nil, unix will display the contents of current work path.",
  "  7. rm",
  "    Usage: rm TARGET",
  "    Remove the file TARGET by this command.",
  "    ATTENTION: DO NOT TRY TO DELETE ANY FILE ON THIS COMPUTER!",
  "  8. send",
  "    Usage: 'send TARGET'",
  "    Send TARGET to server and wait for reply.",
  "---------------------------------------------------------------------------",
]
HELP_OF_THE_GAME = [
  "---------------------------------------------------------------------------",
  "                                MY ADVENTURE",
  "---------------------------------------------------------------------------",
  "Welcome to this game! Hope you enjoy it.",
  "If you wonder how to play this game, just turn to following tips.",
  "(What you could do now: Press ANYKEY to continue, or type \"q\" to quit.)",
  "      ------------------------------------------------------------",
  "This is a game run in batch mode. (It SHOULD be run in batch mode!) The",
  "game will show you a story about a strange world, you're trapped in it and",
  "you must use some strange methods to escape this world.",
  "      ------------------------------------------------------------",
  "There're lots of items, but you don't need to memorize how to use them",
  "because of the following reasons.",
  "  1. If you get a GPS, it's always work, telling you where you are.",
  "  2. You needn't know how to use a pen to write, or use a rock to attack.",
  "  3. If you have a lamp, it's always on.",
  "  4. Maybe you'll meet some computers, just type \"help\" to get help.",
  "  5. You can take many items, and you needn't think about their weight.",
  "So just enjoy it.",
  "      ------------------------------------------------------------",
  "I think the game is convenient to point your position. Though it doesn't",
  "contain a visual map, you could draw a map on a paper so that you couldn't",
  "lose yourself when you're at a MAZE.",
  "If you first visit a place, the game will show you some details about the",
  "place you current are, but the next time you visit this place, you could",
  "only get a name of it. You can type \"where\" for details.",
  "      ------------------------------------------------------------",
  "The game doesn't need lots of commands, for the world is simple. (or you",
  "can consider that the writer is too lazy to program so much ^_^) You don't",
  "need to care about whether to upcase or downcase.",
  "Some commands need arguments, if you just type the command but ignore the",
  "arguments, don't worry, the game will show you all available arguments.",
  "Possible commands are: (arguments are in \"[ ]\")",
  "  1. HELP",
  "    If you forget or don't know the rule of this game, just turn to it.",
  "  2. WHERE",
  "    If you wonder some details about the place you current are, just type",
  "    it for help.",
  "  3. LOOK | SCAN [ item ]",
  "    It will show you some details about the item.",
  "    If you type this command, you should add an argument ITEM, or the game",
  "    will show you all possible items you have.",
  "  4. TAKE | GET | PICK [ item ]",
  "    You can get item by those commands.",
  "    You should also add an argument about the item you'd like to take.",
  "  5. DROP | THROW [ item ]",
  "    Typing this command means you'll drop an item on the ground.",
  "    Items can be got later, so don't worry about whether you'll lose it.",
  "  6. GO [ argument ]",
  "    You can go somewhere by typing this command.",
  "    The argument about this command is a bit complex:",
  "      E | EAST | W | WEST | N | NORTH | S | SOUTH |",
  "      I |  IN  | O | OUT  | U |  UP   | D | DOWN",
  "    Be sure to draw a map! Or you'll lose the way.",
  "  7. PUT [ item ] ON | IN | ONTO | INTO [ target ]",
  "    Put an item you have on a target, for example \"PUT UDISK ON COMPUTER\".",
  "  8. ENTER",
  "    If you have a computer, just use this command to login.",
  "  9. SAVE",
  "    You can save your trip by this command.",
  "    The game'll require you to enter a direction to save or QUIT to cancel.",
  "    ATTENTION: The command will modify your file, so DO BE CAUTIOUS.",
  "  10. LOAD",
  "    Similar to SAVE, you can load your trip by this command and it needs a",
  "    direction or QUIT.",
  "  11. EXIT | QUIT | HALT",
  "    You can exit the game by this command, it doesn't need arguments.",
  "      ------------------------------------------------------------",
  "        And hope you can enjoy MY ADVENTURE. Thanks for reading.\n",
  "                                                            Rex Skywalker",
  "                                   From Shandong Experimental High School",
  "---------------------------------------------------------------------------",
]
ENDINGS = [
  "",
  "---------------------------------------------------------------------------",
  "Thank you for letting me crack the system.", "",
  "I forcefully crack it, and I find a file 'world_core.dat'.", "",
  "And, I finally understand the way which server uses to controll the world.", "",
  "I try to make connections with my soul in real world, and I succeed.", "",
  "............\n............\n", "", "", "", "", "", "", "", "", "", "", "", "",
  "I don't know why I was so worried, but the whole event has gone.", "",
  "After I made connection, I woke up from bed, finding myself lying in a lab.", "",
  "There was also a server similar to the virtual world.", "",
  "To my surprise, the flashdisk was brought to real word as well!", "",
  "So I cracked this server, and realized the two server is one.", "",
  "At first, I was shot, lose myself, and my brain was under control.", "",
  "But now who cares? The scientists were sentenced, and I'm free now!", "",
  "The trip in virtual world really widened my eyesight, from now on I know",
  "it's possible to create a world using computer.", "",
  "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", ""
]
PLACES = {
  # Caves
  "Cave With Lift" => [
    "This is the entrance and the exit of the cave.",
    ['n', 'u'], nil, ["elevator"]
  ],
  "E-W Cave" => [
    "It's dark here, I can only recognize the direction.",
    ['e', 'w'],
  ],
  "N-S Cave" => [
    "It's cold, I must go quickly.",
    ['n', 's'],
  ],
  "East Dead End of Cave" => [
    "I can't go any easter.",
    ['w'],
  ],
  "West Dead End of Cave" => [
    "I can't go any wester.",
    ['e'],
  ],
  "North Dead End of Cave" => [
    "I can't go any norther.",
    ['s'],
  ],
  "South Dead End of Cave" => [
    "I can't go any souther.",
    ['n'],
  ],
  "X Cross of Cave" => [
    "Similar to Bridge, there's also an X Cross.",
    ['e', 'w', 'n', 's'],
  ],
  "East T Cross of Cave" => [
    "It's a T cross, I can't go any easter.",
    ['w', 'n', 's'],
  ],
  "West T Cross of Cave" => [
    "It's a T cross, I can't go any wester.",
    ['e', 'n', 's'],
  ],
  "North T Cross of Cave" => [
    "It's a T cross, I can't go any norther.",
    ['e', 'w', 's'],
  ],
  "South T Cross of Cave" => [
    "It's a T cross, I can't go any souther.",
    ['e', 'w', 'n'],
  ],
  # Departments
  "Department 1A" => [
    "Here's an elevator, I could go up or down.",
    ['e', 'n', 's', 'u'], nil, ["elevator"]
  ],
  "Department 1B" => [
    "Here are some food.",
    ['e', 'n', 's'], ["food"], ["chair", "table", "fridge"]
  ],
  "Department 1C" => [
    "Here're some cloths.",
    ['w', 'n'], ["shirt"], ["table"]
  ],
  "Department 1D" => [
    "Here are some toys.",
    ['e', 'w', 'n', 's'], ["toy"],
  ],
  "Department 1E" => [
    "There is a tiny bar.",
    ['e', 'w', 's'], ["wine", "bottle"], ["chair", "table"]
  ],
  "Department 1F" => [
    "There is a net bar, but no one is here.",
    ['e', 's'], ["flashdisk", "laptop"],
  ],
  "Department 1G" => [
    "Here's an elevator, I could go up or down.",
    ['w', 's', 'u', 'd'], nil, ["elevator"]
  ],
  "Department 1H" => [
    "There seems to sell overcoat.",
    ['w', 'n', 's'], nil, ["overcoat"]
  ],
  "Department 1I" => [
    "Here are some drinks.",
    ['n', 's'], ["cola", "bill"], ["fridge"]
  ],
  "Department 2A" => [
    "Here's an elevator, I could go up or down.",
    ['n', 'u', 'd'], nil, ["elevator"]
  ],
  "Department 2B" => [
    "Here're empty? I can't believe it.",
    ['e', 's'],
  ],
  "Department 2C" => [
    "Seems like there's being decorated.",
    ['e'],
  ],
  "Department 2D" => [
    "A tiny place for kids, I'm not interested in it.",
    ['e', 'w', 'n'],
  ],
  "Department 2E" => [
    "I'm sure the world is computed by server, seems this place is not in server?",
    ['e', 'w'],
  ],
  "Department 2F" => [
    "An empty place.",
    ['e', 'w', 's'],
  ],
  "Department 2G" => [
    "Here's an elevator, I could go up or down.",
    ['w', 'n', 's', 'u', 'd'], nil, ["elevator"]
  ],
  "Department 2H" => [
    "I could only find ways by myself.",
    ['w', 'n', 's'],
  ],
  "Department 2I" => [
    "An empty place.",
    ['w', 'n'],
  ],
  "Department 3A" => [
    "Here's an elevator, I could go down.",
    ['e', 'n', 's', 'd'], nil, ["elevator"]
  ],
  "Department 3B" => [
    "Here are some food.",
    ['n', 's'],
  ],
  "Department 3C" => [
    "Here are some food.",
    ['e', 'w'],
  ],
  "Department 3D" => [
    "Here are some food.",
    ['n'],
  ],
  "Department 3E" => [
    "Here's an elevator, I could go up.",
    ['e', 's', 'u'],
  ],
  "Department 3F" => [
    "Here are some food.",
    ['e', 'w', 's'],
  ],
  "Department 3G" => [
    "Here's an elevator, I could go down.",
    ['w', 's', 'd'], nil, ["elevator"]
  ],
  "Department 3H" => [
    "Here are some food.",
    ['n', 's'],
  ],
  "Department 3I" => [
    "Here are some food.",
    ['w', 'n'],
  ],
  # 0 above sea level
  "Main Road" => [
    "This is Main Road located at southwest of the city.\nThere're lots of trees.",
    ['e'], ["gps"], ["tree"]
  ],
  "E-W Main Road" => [
    "This is E-W Main Road, east to Main Road.\nThe ground here is not smooth at all.",
    ['w', 'n'],
  ],
  "North Sub Road" => [
    "As the name suggests, this road is a sub from Main Road.\nThere's a forest at the north.",
    ['e', 'n', 's'], ["axe"], nil
  ],
  "North East Sub Road" => [
    "I'm at North East Sub Road, it's not as wide as North Sub Road.",
    ['e', 'w'],
  ],
  "East Sub Road" => [
    "It's a bit cold there.",
    ['e', 'w', 's'],
  ],
  "East Sub Road 2" => [
    "It's a bit cold there.",
    ['e', 'w', 'n', 's'],
  ],
  "Entrance of the Forest" => [
    "Lots of trees! I'm at the Entrance of the Forest.\nIt's a bit cold, but I think I can get over it.",
    ['e', 'w', 'n', 's'], nil, ["tree"]
  ],
  "Forest" => [
    "I'm now in the forest, it's fog all around, I hope I won't\n get lost.",
    ['e', 'w', 'n', 's'], nil, ["tree"]
  ],
  "Northeast Corner of the Forest" => [
    "It seems that I can't go any norther or easter.",
    ['w', 's'], nil, ["tree"]
  ],
  "Southeast Corner of the Forest" => [
    "It seems that I can't go any souther or easter.",
    ['w', 'n'], nil, ["tree"]
  ],
  "Northwest Corner of the Forest" => [
    "It seems that I can't go any norther or wester.",
    ['e', 's'], nil, ["tree"]
  ],
  "Southwest Corner of the Forest" => [
    "It seems that I can't go any souther or wester.",
    ['e', 'n'], nil, ["tree"]
  ],
  "North Border of the Forest" => [
    "It seems that I can't go any norther.",
    ['e', 'w', 's'], nil, ["tree"]
  ],
  "South Border of the Forest" => [
    "It seems that I can't go any souther.",
    ['e', 'w', 'n'], nil, ["tree"]
  ],
  "East Border of the Forest" => [
    "It seems that I can't go any easter.",
    ['w', 'n', 's'], nil, ["tree"]
  ],
  "West Border of the Forest" => [
    "It seems that I can't go any wester.",
    ['e', 'n', 's'], nil, ["tree"]
  ],
  "Strange Road" => [
    "The road is quite strange.\nThere's a house at the north of the road, maybe I could go in.",
    ['e', 'w', 's', 'i'], ["udisk"], nil
  ],
  "Strange Road 1" => [
    "The continue, similar to Strange Road.",
    ['e', 'w'],
  ],
  "Dead End of Strange Road" => [
    "This is the dead end, I can't go any easter.",
    ['w'],
  ],
  "String Road" => [
    "The road is more like a string, it's not wide at all.",
    ['e', 'w', 'n', 'u'], nil, ["elevator"]
  ],
  "Dead End of String Road" => [
    "This is the dead end, I can't go any wester.",
    ['e'],
  ],
  "Tiny House" => [
    "The house is tiny and full of mess, there's a table in it.\nI find a computer, but don't know how to power on.\I must find ways to open it.\nMaybe the udisk? Try to use \"PUT\" command!",
    ['o'], ["paper"], ["computer"]
  ],
  "Tiny House With Computer" => [ # New Tiny House
    "The house is tiny and full of mess, there's a computer on the table.\nI could use the computer, just type command \"ENTER\".",
    ['o'], nil, ["unix"]
  ],
  "Near Sea" => [
    "I'm so closed to the sea!",
    ['w', 'n', 's'], ["shell"], nil
  ],
  "Sea Road 00" => [
    "The sign says I'm at Sea Road.\nI can feel the wind from the sea.\nThere's an elevator here.",
    ['e', 'n', 'u'], nil, ["beach", "elevator"]
  ],
  "Sea Road 01" => [
    "Continue of Sea Road.",
    ['e', 'w'], nil, ["beach"]
  ],
  "Sea Road 02" => [
    "Southeast corner of Sea Road.",
    ['w', 'n'], nil, ["beach"]
  ],
  "Sea Road 03" => [
    "Dead end of Sea Road.",
    ['s'], nil, ["beach"]
  ],
  # 1 above sea level
  "String Bridge" => [
    "This is the second floor of String. (String Road is the first floor)",
    ['e', 's', 'd'],
  ],
  "East T Cross" => [
    "This is East T Cross, I can't go any easter.",
    ['w', 'n', 's'],
  ],
  "West T Cross" => [
    "This is West T Cross, I can't go any wester.",
    ['e', 'n', 's'],
  ],
  "North T Cross" => [
    "This is North T Cross, I can't go any norther.",
    ['e', 'w', 's'],
  ],
  "South T Cross" => [
    "This is South T Cross, I can't go any souther.",
    ['e', 'w', 'n'],
  ],
  "X Cross" => [
    "The road here is just like X.",
    ['e', 'w', 'n', 's'],
  ],
  "N-S Bridge" => [
    "As the name suggest, I can go whether north or south.",
    ['n', 's'],
  ],
  "E-W Bridge" => [
    "As the name suggest, I can go whether east or west.",
    ['e', 'w'],
  ],
  "Northeast Corner of Bridge" => [
    "This is the northeast corner of String Bridge.",
    ['w', 's'],
  ],
  "Northwest Corner of Bridge" => [
    "This is the northwest corner of String Bridge.",
    ['e', 's'],
  ],
  "Southeast Corner of Bridge" => [
    "This is the southeast corner of String Bridge.",
    ['w', 'n'],
  ],
  "Southwest Corner of Bridge" => [
    "This is the southwest corner of String Bridge.",
    ['e', 'n'],
  ],
  "East Dead End of Bridge" => [
    "This is the east dead end, I can't go any easter.",
    ['w'],
  ],
  "West Dead End of Bridge" => [
    "This is the west dead end, I can't go any wester.",
    ['e'],
  ],
  "North Dead End of Bridge" => [
    "This is the north dead end, I can't go any norther.",
    ['s'],
  ],
  "South Dead End of Bridge" => [
    "This is the south dead end, I can't go any souther.",
    ['n'],
  ],
  "Transport" => [
    "There is an elevator which can take me up or down.",
    ['e', 'w', 'u', 'd'], nil, ["elevator"]
  ],
  # 2 above sea level
  "Entrance of Sky Park" => [
    "It's amazing! A park built in sky!\nIt should be safe, and I'd like to explore it.",
    ['n', 's'], nil, ["girl"]
  ],
  "Sky Park" => [
    "The ground is made of glass, I could see the ground below!\nThere's lots of fun games, but I don't have any interest.",
    ['e', 'w', 'n', 's'],
  ],
  "East Border of Sky Park" => [
    "I'm at East Border of Sky Park and I can't go any easter.",
    ['w', 'n', 's'],
  ],
  "West Border of Sky Park" => [
    "I'm at West Border of Sky Park and I can't go any wester.",
    ['e', 'n', 's'],
  ],
  "North Border of Sky Park" => [
    "I'm at North Border of Sky Park and I can't go any norther.",
    ['e', 'w', 's'],
  ],
  "South Border of Sky Park" => [
    "I'm at South Border of Sky Park and I can't go any souther.",
    ['e', 'w', 'n'],
  ],
  "Northeast Corner of Sky Park" => [
    "I'm at Northeast Corner of Sky Park and I can't go north or east.",
    ['w', 's'],
  ],
  "Northwest Corner of Sky Park" => [
    "I'm at Northwest Corner of Sky Park and I can't go north or west.",
    ['e', 's'],
  ],
  "Southeast Corner of Sky Park" => [
    "I'm at Southeast Corner of Sky Park and I can't go south or east.",
    ['w', 'n'],
  ],
  "Southwest Corner of Sky Park" => [
    "I'm at Southwest Corner of Sky Park and I can't go south or west.",
    ['e', 'n'],
  ],
  "Top of Transport" => [
    "I can only go down at here.",
    ['e', 'n'], nil, ["elevator"]
  ],
  # Final Place
  "Final P-L" => [
    "It's a secret in the cave. ^_^",
    ['w'], ["permission"],
  ],
  "Net Core" => [
    "Seems it's the place where server lies. Could I enter it?",
    ['d'], nil, ["server"]
  ],
}
TXT_PLACES = [
  "                                  South<----------> North",
  "Places in 0 above sea level:\n",
  "  0      1      2      3      4      5      6      7",
  "0 MainR         Frst---Frst---Frst---Frst---Frst   StrngR",
  "  |             |      |      |      |      |      |",
  "1 MainR--SubR---Frst---Frst---Frst---Frst---Frst   STRNGR",
  "         |      |      |      |      |      |      |",
  "2        SubR---Frst---Frst---Frst---Frst---Frst---StangR",
  "         |      |      |      |      |      |      | ",
  "3 SEAR---SubR   Frst---Frst---Frst---Frst---Frst   StangR",
  "  |      |                                         | ",
  "4 SeaR---SubR---DEP1A--Dep1B--Dep1F                StangR",
  "  |      |      |      |      |                    | ",
  "5 SeaR---SubR   Dep1C--Dep1D--Dep1E                StangR",
  "  |      |             |      |",
  "6 SeaR---NerSea-Dep1I--Dep1H--DEP1G",
  "  |",
  "7 SeaR---SeaR",
  "", "", "", "", "", "", "",
  "Places in 1 above sea level:\n",
  "  0      1      2      3      4      5      6      7",
  "0 Brdg   Brdg   Brdg          Brdg",
  "  |      |      |             |",
  "1 Brdg---Brdg---Brdg---Brdg---Brdg---Brdg---Brdg---BRDG",
  "  |      |      |             |                    |",
  "2 Brdg   Brdg   Brdg          Brdg                 Brdg",
  "  |      |      |             |                    | ",
  "3 TRANS  Brdg   Brdg          Brdg          Brdg   Brdg",
  "  |      |                    |             |      | ",
  "4 Brdg   Brdg   DEP2A--Dep2B  Dep2E         Brdg   Brdg",
  "  |      |             |      |             |      | ",
  "5 Brdg   Brdg   Dep2C  Dep2D--Dep2F         Brdg   Brdg",
  "         |      |      |      |             |",
  "6        Brdg   Dep2I--Dep2H--DEP2G--Brdg---Brdg",
  "         |",
  "7        Brdg---Brdg",
  "", "", "", "", "", "", "",
  "Places in 2 above sea level:\n",
  "  0      1      2      3      4      5      6      7",
  "0 Brdg---Park---Park---Park---Park---Park---Brdg",
  "  |      |      |      |      |      |",
  "1 Brdg   Park---Park---Park---Park   Park---Brdg---Brdg",
  "  |             |      |",
  "2 Brdg---Brdg   Park---Park---Park---Park   Park---Park",
  "  |      |      |      |      |      |      |      |",
  "3 TRANS  Brdg   Park---Park---Park---Park---Park---Park",
  "  |      |                           |      |      |",
  "4 Brdg---Brdg---DEP3A--Dep3B--DEP3E  Park---Park---Park",
  "         |      |             |      |      |      |",
  "5        Brdg   Dep3C  Dep3D--Dep3F  Park---Park---Park",
  "         |      |             |",
  "6        Brdg   Dep3I--Dep3H--DEP3G",
  "         |",
  "7        Brdg---Brdg---Brdg---Brdg---Brdg",
  "", "", "", "", "", "", "",
  "Places in 1 below sea level:\n",
  "  0      1      2      3      4      5      6      7",
  "0        Cave          Cave---Cave---Cave---Cave",
  "         |                    |",
  "1 LIFT---Cave---Cave---Cave---Cave",
  "                |             |",
  "2        Cave   Cave---Cave   Cave   Cave",
  "         |      |                    |",
  "3        Cave---Cave          Cave---Cave---Cave---Cave",
  "         |      |                           |",
  "4 Cave---Cave   Cave   Cave                 Cave---Cave",
  "         |             |                    |",
  "5        Cave---Cave---Cave---Cave---Cave   Cave",
  "         |             |                    |",
  "6        Cave   Cave---Cave---Cave---Cave---Cave",
  "                       |                    |",
  "7                      Cave                 F-PL",
  "", "", "", "", "", "", ""
]
START = [
  "Life could be amazing sometime, it can drive you mad in a way.",
  "I'm Rex Skywalker, somehow I entered this world, and I need your help.",
  "The world looks a bit strange...",
]
MESSAGE_ON_UNIX = [
  "Secret: This is a clone to the world.",
  "Hard to find something? All places are placed at ~/places",
  "BUT! Do you have permission to open it?",
  "You could use 'send' command to send this file to server.",
]
NEW_MESSAGE_ON_UNIX = [
  "I hope you can find the new item on Sea Road.",
  "As you may think, the world is controlled by server and displayed by this",
  "computer. You don't have permission to modify the file by your own ability.",
  "If you wan't to escape from this virtual world, the only thing to do is: to",
  "find message in this computer and the world, send some file to server",
  "at proper time, and wait for reply like this.",
  "ATTENTION: DO NOT TRY TO MODIFY OR DELETE ANY FILE ON THIS COMPUTER!",
]
RUBY_SAYS = [
  "I'm Ruby, the world is created by my own.",
  "Maybe you think you'll be trapped forever, but do remember the world",
  "is a virtual, it can be displayed on computers only.",
  "Try your best to find the message, and when you leave the world, you",
  "will find something astonishing.",
  "Do you know the server is also in the world? Try to find it!",
]
ITEMS = {
  "axe" => "A sharp axe with a sign REX on its helve.",
  "gps" => "A gps, it can help me ensure my position.",
  "pen" => "A normal pen with full of ink.",
  "toy" => "It looks like designed for kids.",
  "bill" => "They add up to 100 Yuan.",
  "cola" => "It tasets good.",
  "food" => "I'm not hungry, but it might have other uses.",
  "note" => "It says, \"There's a permission at (7, 6, -1).\"",
  "rock" => "A hard rock with a text 'Account: founder 5eysg5a'.",
  "wine" => "A bottle of wine.",
  "paper" => "A white paper saying 'Account: RexSkz my_Adventure'.",
  "shell" => "A tiny sea shell which has colorful picture.",
  "shirt" => "I can either wear it or take it.",
  "udisk" => "A tiny udisk which might contains important messages.",
  "bottle" => "An empty bottle which could contains liquid.",
  "laptop" => "It can login the system at Tiny House by Internet.",
  "flashdisk" => "It contains some tools to do hacking.",
  "permission" => "I couldn't take the elevator on Department 3G without this item.",
}
EXTRAS = {
  "sea" => "There's not much sea wave and the wind here is soft.",
  "girl" => "She has something to tell you.\n#{RUBY_SAYS}",
  "tree" => "It's tall and with lots of leaves.",
  "unix" => "An old operating system.",
  "beach" => "The sand here is quite smooth and warm.",
  "chair" => "When I'm tired I can sit on it.",
  "table" => "It has lots of uses.",
  "fridge" => "It can save food or make ice-cream!",
  "server" => "It should be the server which computes this world.",
  "computer" => "It can't be launched at all.",
  "elevator" => "It enables me to go up and down.",
  "overcoat" => "A warm coat, but I don't need it.",
}

#--------------------------------------------------
# Define all places
#--------------------------------------------------
class Place
  attr_accessor :name
  attr_accessor :note
  attr_accessor :passable
  attr_accessor :item
  attr_accessor :extra
  def initialize(name)
    @name = name
    @note, @passable, @item, @extra = PLACES[name]
    @item = [] if @item.nil?
    @extra = [] if @extra.nil?
  end
  def display(is_where = false)
    position = $item.include?("gps") ? " (x = #{$posx}, y = #{$posy}, z = #{$posz})" : ''
    if $foot_print.include?(@name) and !is_where; print @name, position, "\n"
    else
      $foot_print.push(@name)
      print @name, position, "\n" if !is_where
      print @note, "\n"
      print "Where I can go from here:"
      @passable.each{ |p| print " #{FULL_NAME[p].capitalize}(#{p})" }
      print "\n"
      if @item.empty?; print "There's no special item.\n"
      else
        print "There are some items:"
        print_item(@item + @extra)
      end
      if @name == "Net Core" and $item.include?("flashdisk")
        print "I have flashdisk! I can't wait to crack in this system!\n"
        print "I order you to type \"crack\", NOW!\n"
      end
    end
  end
  def try_go(place)
    place.downcase!
    1.times do
      break if place.length > 1 and !ALL_DIRECTIONS.include?(place)
      place = place[0]
      break if DELTA_POS[place].nil? or [email protected]?(place)
      $posx += DELTA_POS[place][0]
      $posy += DELTA_POS[place][1]
      $posz += DELTA_POS[place][2]
      return
    end
    print "I can't go there.\n"
    return
  end
  def print_possible_direction
    print "Where I can go:"
    @passable.each{ |s| print " #{FULL_NAME[s].capitalize}(#{s})" }
    print "\n"
  end
  def try_put(item, target)
    if item == "udisk" and target == "computer"
      $item.delete("udisk")
      $place[0][2][8] = r("Tiny House With Computer")
      print "I put the udisk on this computer and try to power on.\n"
      print "It start suddenly. I could type command \"ENTER\" to use it.\n"
      increase_process
    else; print "I can't put #{item} on #{target}.\n"
    end
  end
end

#--------------------------------------------------
# Computers
#--------------------------------------------------
class Computer
  attr_accessor :user_name
  attr_accessor :password
  def enter
    clear_screen
    print "Welcome to UNIX! You need an account to log in.\n"
    print "Attention: Upcase and downcase is different in unix.\n\n"
    print "Login name: "
    login_name = gets.chomp!
    print "Password: "
    password = gets.chomp!
    if ACCOUNTS.include?([login_name, password])
      if !$item.include?("shell")
        print "Error: 'shell' not found.\n"
        return
      end
      print "\nLogin time: #{Time.new.strftime("%Y-%m-%d %H:%M:%S")}\n"
      @user_name = login_name
      @password = password
      explore("~")
    else
      print "Login name or password is incorrect.\n"
      return
    end
  end
  def display_path(content)
    width = 20
    content.each{ |i| width = 40 if i.length > 20 }
    for i in 0..content.length - 1
      print content[i], ' ' * (width - content[i].length)
      print "\n" if (i - 1) * width == 80 and i < content.length - 1
    end
    print "\n" if content.length % (80 / width) != 0
  end
  def explore(cur_path)
    loop do
      print "-" * (77 - cur_path.length), "(#{cur_path})", "\n"
      print "[email protected]#{@user_name}$ "
      command, target = gets.chomp.split(' ')
      case command
      when "", nil
      when "clear"; clear_screen
      when "exit"; return "do_exit"
      when "ls"
        target = "." if target.nil?
        target = target.split('/').first
        if target == "."; display_path($file_list[cur_path])
        elsif $file_list[cur_path].include?("#{target}/"); display_path($file_list[target])
        else; print "No matches found: '#{target}'\n"
        end
      when "cd"
        target = "." if target.nil?
        target = target.split('/').first
        if target == "."
        elsif target == ".."; (cur_path == "~") ? (print "You are lack of permission.\n") : (return)
        elsif $file_list[target].nil?; print "No matches found: '#{target}'\n"
        else
          temp = explore(target)
          (clear_screen; return temp) if temp == "do_exit"
        end
      when "help"; show_text(HELP_ON_UNIX)
      when "rm"
        if target.nil?; print "Usage: 'rm target'\nATTENTION: DO NOT TRY TO DELETE ANY FILE ON THIS COMPUTER!"
        elsif $file_list[cur_path].include?(target)
          print "The world starts to change, what fulfilled my eyes are all zeros and ones.\n"
          print "I feel so weak, it's this my ending? ...\n"
          announce_death
        else; print "No matches found: '#{target}'\n"
        end
      when "cat"
        if $file_list[cur_path].include?(target)
          case target
          when nil; print "Usage: 'cat target'\n"
          when "account"; print "Login name: #{@user_name}\nPassword: #{@password}\n"
          when "ask"; print "You can send this file to server if you have permission.\n"
          when "position"; $np.display
          when "README"; show_text(HELP_OF_THE_GAME)
          when "USAGE"; show_text(HELP_ON_UNIX)
          when "message"; show_text(MESSAGE_ON_UNIX)
          when "new_message"; show_text(NEW_MESSAGE_ON_UNIX)
          when "place"
            if @user_name == "RexSkz"; print "You are lack of permission.\n"
            else; show_text(TXT_PLACES)
            end
          end
        else; print "No matches found: '#{target}'\n"
        end
      when "send"
        if target.nil?; print "Usage: 'send filename'\n"
        elsif [cur_path, target] == ["secret", "message"]
          $place[0][7][1].item.push("rock")
          $file_list["secret"].delete(target)
          $file_list["secret"].push("new_message")
          print "Successful, the server sends you 'new_message' for reply.\n"
          print "Change has taken place on (7, 1, 0) Near Sea, have a look. ^_^\n"
          print "And... also the file 'ask' is pushed into path '~/'.\n"
          increase_process
          $file_list["~"].push("ask")
          $file_list["~"].sort!{ |a, b| a.downcase <=> b.downcase }
        elsif [cur_path, target] == ["~", "ask"]
          if @user_name == "RexSkz"; print "You are lack of permission.\n"
          elsif !$place[0][1][0].passable.include?('d')
            $place[0][1][0].passable = ['w', 'n', 'd']
            $place[3][3][7].item.push("note")
            print "Successful.\nYou can now go down at (1, 0, 0) Main Road.\n"
            print "Notice the item at (3, 7, -1).\n"
            increase_process
          else; print "Server refuse to accept this file now.\n"
          end
        elsif $file_list[cur_path].include?(target); print "The file can't be accepted by server.\n"
        else; print "No matches found: '#{target}'\n"
        end
      else; print "Unknown command: '#{command}'\n"
      end
    end
  end
end

#--------------------------------------------------
# Define kernel methods
#--------------------------------------------------
def clear_screen
  system "cls"
end
def show_text(text)
  count = 0
  for i in text
    count += 1
    if count % 24 == 0
      cmd = gets.chomp!
      return if cmd == "q"
    end
    print i, ' '
    print "\n" if (count + 1) % 24 > 0
  end
end
def print_item(list)
  list.sort.each{ |item| print ' ', item }
  print "\n"
end
def increase_process
  $process += 1
  print "I've gained #{$process} of all 4 points.\n"
end
def announce_death
  print "\nYou dead.\nYou have gained #{$process} of all 5 points.\n"
  print "Thanks for playing. Press anykey to exit."
  gets; exit
end
def do_save
  print "Input a direction to save(such as E:/ma/sav01) or QUIT to cancel:", "\n"
  path = gets.downcase.chomp!
  return if path == "quit"
  begin
    file = File.open(path, "wb")
    Marshal.dump($item, file)
    Marshal.dump($posx, file)
    Marshal.dump($posy, file)
    Marshal.dump($posz, file)
    Marshal.dump($place, file)
    Marshal.dump($process, file)
    Marshal.dump($np, file)
    Marshal.dump($file_list, file)
    Marshal.dump($foot_print, file)
    file.close
    print "Save successfully.\n"
  rescue; print "Path doesn't exist.\n"
  end
end
def do_load
  print "Input a direction to load(such as E:/ma/sav01) or QUIT to cancel:", "\n"
  path = gets.downcase.chomp!
  return if path == "quit" 
  begin
    file = File.open(path, "rb")
    $item       = Marshal.load(file)
    $posx       = Marshal.load(file)
    $posy       = Marshal.load(file)
    $posz       = Marshal.load(file)
    $place      = Marshal.load(file)
    $process    = Marshal.load(file)
    $np   = Marshal.load(file)
    $file_list  = Marshal.load(file)
    $foot_print = Marshal.load(file)
    file.close
    print "Load successfully.\n"
  rescue; print "Save file doesn't exist.\n"
  end
end
def do_exit
  print "Are you sure to exit the game (y/N): "
  temp = gets.downcase.chomp!
  if temp == "y" or temp.nil?
    print "Thanks for playing. Press anykey to exit."
    gets; exit
  end
end
def match(b)
  m = b.length
  b = ' ' + b
  max, str = 0, ""
  COMMANDS.each do |a|
    n = a.length
    a = ' ' + a
    f = [0] * (m * n + m)
    for i in 1..n
      for j in 1..m
        f[m * i + j] = (a[i] == b[j]) ? (f[m * (i - 1) + j - 1] + 1) : ([f[m * (i - 1) + j], f[m * i + j - 1]].max)
      end
    end
    max, str = f[m * n + m], a if (f[m * n + m] > max) or (f[m * n + m] == max and a[1] == b[1])
  end
  return "you tap the keyboard by random" if max < m / 2
  return "'#{str.delete(' ')}'"
end

#--------------------------------------------------
# Initialize global variables
#--------------------------------------------------
def r(place); return Place.new(place); end # Only for simplify
$place = [
  [
    [r("Main Road"), nil, r("Southwest Corner of the Forest"), r("West Border of the Forest"), r("West Border of the Forest"), r("West Border of the Forest"), r("Northwest Corner of the Forest"), r("Dead End of String Road")],
    [r("E-W Main Road"), r("North Sub Road"), r("Entrance of the Forest"), r("Forest"), r("Forest"), r("Forest"), r("North Border of the Forest"), r("String Road")],
    [nil, r("North East Sub Road"), r("South Border of the Forest"), r("Forest"), r("Forest"), r("Forest"), r("Entrance of the Forest"), r("Strange Road"), r("Tiny House")],
    [r("Sea Road 00"), r("East Sub Road"), r("Southeast Corner of the Forest"), r("East Border of the Forest"), r("East Border of the Forest"), r("East Border of the Forest"), r("Northeast Corner of the Forest"), r("Strange Road 1")],
    [r("Sea Road 01"), r("East Sub Road 2"), r("Department 1A"), r("Department 1B"), r("Department 1F"), nil, nil, r("Strange Road 1")],
    [r("Sea Road 01"), r("East Sub Road"), r("Department 1C"), r("Department 1D"), r("Department 1E"), nil, nil, r("Dead End of Strange Road")],
    [r("Sea Road 01"), r("Near Sea"), r("Department 1I"), r("Department 1H"), r("Department 1G")],
    [r("Sea Road 02"), r("Sea Road 03")]
  ], [
    [r("West Dead End of Bridge"), r("West Dead End of Bridge"), r("West Dead End of Bridge"), nil, r("West Dead End of Bridge")],
    [r("South T Cross"), r("X Cross"), r("X Cross"), r("N-S Bridge"), r("X Cross"), r("N-S Bridge"), r("N-S Bridge"), r("String Bridge")],
    [r("E-W Bridge"), r("E-W Bridge"), r("E-W Bridge"), nil, r("E-W Bridge"), nil, nil, r("E-W Bridge")],
    [r("Transport"), r("E-W Bridge"), r("East Dead End of Bridge"), nil, r("E-W Bridge"), nil, r("West Dead End of Bridge"), r("E-W Bridge")],
    [r("E-W Bridge"), r("E-W Bridge"), r("Department 2A"), r("Department 2B"), r("Department 2E"), nil, r("E-W Bridge"), r("E-W Bridge")],
    [r("East Dead End of Bridge"), r("E-W Bridge"), r("Department 2C"), r("Department 2D"), r("Department 2F"), nil, r("E-W Bridge"), r("East Dead End of Bridge")],
    [nil, r("E-W Bridge"), r("Department 2I"), r("Department 2H"), r("Department 2G"), r("String Bridge"), r("North East Corner of Bridge")],
    [nil, r("Southeast Corner of Bridge"), r("North Dead End of Bridge")]
  ], [
    [r("Southwest Corner of Bridge"), r("Entrance of Sky Park"), r("West Border of Sky Park"), r("West Border of Sky Park"), r("West Border of Sky Park"), r("Entrance of Sky Park"), r("North Dead End of Bridge")],
    [r("E-W Bridge"), r("Southeast Corner of Sky Park"), r("Sky Park"), r("Sky Park"), r("Northeast Corner of Sky Park"), r("Southeast Corner of Sky Park"), r("N-S Bridge"), r("North Dead End of Bridge")],
    [r("South T Cross"), r("X Cross"), r("South Border of Sky Park"), r("Sky Park"), r("West Border of Sky Park"), r("Northwest Corner of Sky Park"), r("Southwest Corner of Sky Park"), r("Northwest Corner of Sky Park")],
    [r("Top of Transport"), r("E-W Bridge"), r("Southeast Corner of Sky Park"), r("East Border of Sky Park"), r("East Border of Sky Park"), r("Sky Park"), r("Sky Park"), r("North Border of Sky Park")],
    [r("Southeast Corner of Bridge"), r("X Cross"), r("Department 3A"), r("Department 3B"), r("Department 3E"), r("South Border of Sky Park"), r("Sky Park"), r("North Border of Sky Park")],
    [nil, r("E-W Bridge"), r("Department 3C"), r("Department 3D"), r("Department 3F"), r("Southeast Corner of Sky Park"), r("East Border of Sky Park"), r("Northeast Corner of Sky Park")],
    [nil, r("E-W Bridge"), r("Department 3I"), r("Department 3H"), r("Department 3G")],
    [nil, r("Southeast Corner of Bridge"), r("N-S Bridge"), r("N-S Bridge"), r("N-S Bridge"), r("North Dead End of Bridge")],
  ], [
    [nil, r("West Dead End of Cave"), nil, r("South Dead End of Cave"), r("West T Cross of Cave"), r("N-S Cave"), r("North Dead End of Cave")],
    [r("Cave With Lift"), r("East T Cross of Cave"), r("West T Cross of Cave"), r("N-S Cave"), r("North T Cross of Cave")],
    [nil, r("West Dead End of Cave"), r("South T Cross of Cave"), r("North Dead End of Cave"), r("East Dead End of Cave"), r("West Dead End of Cave")],
    [nil, r("South T Cross of Cave"), r("North T Cross of Cave"), nil, r("South Dead End of Cave"), r("East T Cross of Cave"), r("West T Cross of Cave"), r("North Dead End of Cave")],
    [r("South Dead End of Cave"), r("North T Cross of Cave"), r("East Dead End of Cave"), r("West Dead End of Cave"), r("Net Core"), nil, r("South T Cross of Cave"), r("North Dead End of Cave")],
    [nil, r("South T Cross of Cave"), r("N-S Cave"), r("X Cross of Cave"), r("N-S Cave"), r("North Dead End of Cave"), r("E-W Cave")],
    [nil, r("East Dead End of Cave"), r("South Dead End of Cave"), r("X Cross of Cave"), r("N-S Cave"), r("N-S Cave"), r("North T Cross of Cave")],
    [nil, nil, nil, r("East Dead End of Cave"), nil, nil, r("Final P-L")],
  ],
]
$item = []
$process = 0
$foot_print = []
$posx = $posy = $posz = 0
$unix = Computer.new
$file_list = {
  "~" => ["Document/", "Music/", "Photo/", "place", "Video/"],
  "Document" => ["account", "position", "README", "secret/", "USAGE"],
  "Music" => ["Moonlight Winter.mp3", "Septette For The Dead Princess.mp3", "U.N. Owen Was Her?.mp3"],
  "Photo" => ["A Dreamy Word.jpg", "Lizlu.7z", "Star Wars Galaxy.png"],
  "secret" => ["message"],
  "Video" => ["RPG Maker VX.mpg"],
}

#--------------------------------------------------
# Main Loop
#--------------------------------------------------
show_text(START)
loop do
  print "\n"
  $np = $place[$posz][$posx][$posy]
  $np.display
  print "What should I do: "
  command, target, a3, a4 = gets.downcase.split(' ')
  if $np.name == "Net Core" and $item.include?("flashdisk")
    if command == "crack"
      show_text(ENDINGS)
      clear_screen
      print "\n"
      increase_process
      print "\n\n\n\nThanks for playing.\n\n"
      print "Author: Rex Skywalker or Skywalker_Z or RexSkz\n\n"
      print "From Shandong Experimental High School\n\n\n\n"
      print "Press anykey to exit."
      gets; exit
    else
      print "I have flashdisk! I can't wait to crack in this system!\n"
      print "I order you to type \"crack\", NOW!\n"
    end
    next
  end
  case command
  when nil; print "Have you said something?\n"
  when "where"; $np.display(true)
  when "help"; show_text(HELP_OF_THE_GAME)
  when "look", "scan"
    if target.nil?
      if ($item + $np.item + $np.extra).empty?; print "There's no item yet.\n"
      else
        print "There're some items:"
        print_item($item + $np.item + $np.extra)
      end
    elsif ($item + $np.item).include?(target); print target.capitalize, " - ", ITEMS[target], "\n"
    elsif $np.extra.include?(target); print target.capitalize, " - ", EXTRAS[target], "\n"
    else; print "There's no such item.\n"
    end
  when "take", "get", "pick"
    if target.nil?
      if $np.item.empty?; print "No item in this place.\n"
      else
        print "The items I could get:"
        print_item($np.item)
      end
    elsif $np.item.include?(target)
      $np.item.delete(target)
      $item.push(target)
      print "I have got #{target}.\n"
    elsif $np.extra.include?(target); print "I can't get it.\n"
    else; print "There is no such item.\n"
    end
  when "drop", "throw"
    if target.nil?
      if $item.empty?; print "I don't have items to drop.\n"
      else
        print "The items I could drop:"
        print_item($item)
      end
    elsif $item.include?(target)
      $item.delete(target)
      $np.item.push(target)
      print "#{target.capitalize} has been dropped at #{$np.name}.\n"
    else; print "I don't have such item.\n"
    end
  when "go"; target.nil? ? $np.print_possible_direction : $np.try_go(target)
  when "put"
    if target.nil?
      if $item.empty?; print "I don't have items to put.\n"
      else
        print "The items I could put:"
        print_item($item)
      end
    elsif $item.include?(target)
      if !a4.nil?
        if $np.extra.include?(a4); $np.try_put(target, a4)
        else; print "There's no #{a4} at all.\n"
        end
      else
        if $np.extra.empty?; print "I can't put #{target} on anywhere.\n"
        else
          print "The place I could put #{target} on:"
          print_item($np.extra)
        end
      end
    else; print "I don't have such item.\n"
    end
  when "enter"
    if $np.name.include?("Computer"); $unix.enter
    elsif $item.include?("laptop"); $unix.enter
    else; print "There's no computer.\n"
    end
  when "save"; do_save
  when "load"; do_load
  when "exit", "halt", "quit"; do_exit
  when "ignore_all_stories"
    $item.push("flashdisk", "permission") if !$item.include?("flashdisk") and !$item.include?("permission")
    $posx, $posy, $posz = 4, 4, 3
    $process = 3
  else; print "I don't know what you said, maybe #{match(command)}?\nType 'help' to get help.\n"
  end
end
版权声明:除文章开头有特殊声明的情况外,所有文章均可在遵从 CC BY 4.0 协议的情况下转载。
上一篇: 胡思乱想
下一篇: 高考前夕

这是我们共同度过的

第 1553 天