/* This class is a basic extension of the Applet class. It would generally be used as the main class with a Java browser or the AppletViewer. But an instance can be added to a subclass of Container. To use this applet with a browser or the AppletViewer, create an html file with the following code: Treasure window You can add controls to Simple with Cafe Studio. (Menus can be added only to subclasses of Frame.) */ import java.awt.*; import java.util.*; public class Treasure extends java.applet.Applet { boolean [] [] [] bConnected = new boolean [100] [4] [2]; boolean bDirectionFound; boolean [] [] [] bDirectionUsed = new boolean [256] [4] [2]; boolean bEuclidean; boolean bPathFound; boolean [] bRoomUsed = new boolean [100]; boolean bTreasureCarried; boolean [] bVisited = new boolean [100]; boolean bWeaponRoomFound; boolean bWidthsFound; FontMetrics fmTreasure; int nAddIndex; int [] [] [] [] nCell = new int [15] [15] [15] [15]; int [] nCoordinate = new int [4]; int [] nCoordinateNext = new int [4]; int nDimensions; int nDimension1; int nDimension2; int nDirection1; int nDirection2; int nDirectionsPossible; int [] nDirectionsUsed = new int [256]; long nGame; int [] nGuardRoom = new int [15]; int nMaxWidth; int nMoves; int nPreviousRandomNumber; int nReplaceIndex; int [] nRN = new int [8]; int nRNPartialSum; int nRoom1; int nRoom2; int nRooms; int nScore; int nTCoordinate; int [] nTreasureRoom = new int [15]; int nTreasures; int nTreasuresCarried; int nTreasuresRecovered; int nTreasure1; int nTreasure2; int nTrial; int nVisited; int nVolume; int [] nWayOutDimension = new int [256]; int [] nWayOutDirection = new int [256]; int nWayOutHead; int nWayOutPtr; int [] nWeaponRoom = new int [15]; int [] nWidth = new int [4]; int nXCoordinate; int nYCoordinate; int nZCoordinate; String strDescription [] = { "the entrance to a large network of caverns.", "a spherical room.", "the hall of bones. Dinosaur bones are everywhere.", "a subway tunnel. Don't touch that third rail!", "a railroad tunnel. A whistle wails in the distance.", "an elfin quiche factory. The elves are out mowing spinach.", "an abandoned Plymouth plant. Beware of Road Runners and Barracudas.", "an abandoned Dodge plant. There is a Dart embedded in the North wall.", "a mouse's nest. You'd best exhale; this is a small room.", "a giant crayfish hole. An immense chicken neck is hanging from a rope.", "an abandoned coal mine. Beware of methane.", "the hall of winds. Presently, the wind is from the south.", "a stove pipe!", "a totally darkened room. Although you can see nothing, the sound of dripping water echos from the walls.", "an industrial waste site. Hold your breath and don't touch anything.", "the warehouse for an extremely popular brand of home computer. Tacky plastic enclosures abound.", "a hobbit's bedroom. The hobbit does not look pleased!", "a troll sewerage processing plant. The air quality is not good.", "a rabbit hole. There is a jar of marmalade on a shelf in the wall.", "the giant's oven. Fortunately, it hasn't been used for years.", "a hobbit's drying room. Tobacco leaves abound.", "a large circular room. It is dark in here.", "the Crystal Palace. Quartz crystals cover the walls.", "the Emerald Room. Green crystals cover the ceiling.", "a curtained room.", "an air conditioning duct!", "a giant kiln. Smoke stains the walls.", "the Hall of Mists. Wisps of white vapor rise from the floor.", "an Aztec pyramid. A mummy lies in the northwest corner.", "the Room of the Eternal Flame. A large natural gas flame burns in the center of the room. Coming from the west wall you can barely hear the words, 'Fee Fye Foe Fum'.", "the Giant's store room. You are surrounded by old rugs, books, chairs, etc.", "the Leprechaun's Treasure Room. Unfortunately, the leprechaun's treasure was stolen years ago.", "a large tiled room. A girl is inquiring after a rabbit. Feel free to ignore her.", "a former nuclear test site. There is a large pile of rubble in the center of the floor. The walls are streaked with a multitude of colors.", "a drainage system holding tank. Either it is no longer used, or it hasn't rained in a long time; the room is dry.", "Mayor Schiro's bomb shelter.", "a room with a waterfall. It is not very impressive; it looks like someone left a water faucet running.", "an abandoned Neanderthal home.", "a volcanic chimney. The air is getting warmer.", "a pit full of snakes. Let's get out of here!!!!", "a salt dome.", "Eleanor Roosevelt's privy. Wendall Wilkie buttons cover the wall.", "Napoleon's wine cellar. German wines line the shelves.", "the space behind the giant's bathroom wall. Large razor blades litter the floor. Step lightly.", "the room where all old toe nail clipping come to rest. Used corn pads litter the floor.", "the Den of the Horta. The walls are covered with a sticky fluid. Don't touch it; it is extremely corrosive.", "a damp room. A small creek runs into a crack in the West wall.", "what appears to be a NOPSI manhole.", "the cafeteria of Mammoth Cave. The aroma of rancid corned beef assails your nostrils.", "a small room with a large table. On the table is a bottle that says, 'Drink me.'", "a Confederate States of America bank vault. Once worthless currency papers the walls.", "an abandoned subway station.", "a mine shaft. In the distance you can hear seven high pitched voices singing, 'Hi Ho, Hi Ho, ...'", "a Minuteman missile silo.", "the giant's mouse trap. Fortunately, you are small enough to escape.", "Adolph Hitler's summer bunker.", "a dwarf work site. A sign says, 'Under construction. Enter at your own risk.'", "the giant's refrigerator. Dwarf bodies hang from hooks.", "the Dragon's Lair. Slightly melted suits of armor litter the floor.", "a nuclear waste depository. The walls glow faintly.", "Millard Filmore's tomb. It is dull.", "an abandoned corridor of the Strategic Air Command Headquarters. A graffito reads, 'Beware of Bat Guano.'", "a gnome's workshop. Half-completed whoopee cushions line the tables.", "the Mummy's Tomb. You've triggered some mechanism and the ceiling is slowly descending.", "the Underground Gourmet's retreat. Twinky and King Don wrappers are piled knee deep.", "a Hoola Hoop warehouse. The words 'Shoop Shoop' echo from the walls.", "the first circle of hell. The living are not allowed here.", "the hall of the pixies. The furniture appears to have been made from cradles.", "a sulfur mine. Molten sulfur churns in a nearby pit. It is becoming difficult to breath.", "a fairy mushroom farm. Brilliantly colored mushrooms cover the floor.", "an ice cave. Along the western wall, a brontosaurus is defrosting.", "the giant's stove. Fortunately, the giant now owns a microwave oven.", "the rib cage of a long deceased whale.", "a room with six walls. The walls appear to be made of wax. A loud buzzing noise can be heard.", "the tomb of a Pharoah. It has obviously been visited by others; the tomb is in a state of total disarray.", "a coal bin. There is a fossilized fern stump here.", "a diamond mine. It is uncomfortably hot here.", "the bottom of an oil well. The walls are slick.", "the lowest level of Project Mohole. The funding bubble burst before the earth did.", "the giant's cesspool. Fortunately, the giant was connected to the city sewerage system years ago.", "an eighteenth century sewer. The walls are crumbling brick. Small alligators snap at your feet.", "the lair of a giant trapdoor spider.", "a giant gopher tunnel.", "a shell -- the sole remains of a prehistoric turtle.", "a small chamber. The walls are made of earth. The air smells of formic acid. A strange squeaking noise can be heard in the distance.", "a chamber of columns. The stalagmites and stalactites join here.", "a service tunnel. Ducts, pipes, and cables are everywhere.", "a gas tank below an abandoned service station. No smoking!", "a huge dark chamber. To one side, a dark, muddy river moves sluggishly. A sign written in ancient Greek says, 'Ferry out of order.'", "a small chamber. It is brightly lit by a peculiar lichen growing on the walls and ceiling. The floor is rocky and steeply sloping. Nearby, a cold, clear creek boils into the floor and out of sight.", "the nest of a very large pack rat. There are discarded aluminum Christmas trees, broken steel utility poles, and other shiny, worthless items here.", "a dungeon. An iron maiden, a rack, a piano, and other machines of torture can be seen.", "the hall of bats. Thousands of bats hang from the ceiling. Watch your step; the droppings are quite deep in places.", "a hobgoblin's hideaway.", "an electrical substation. A transformer is humming loudly. Nearby, cables crackle with high voltage.", "the 'gold' room. The walls are covered with iron pyrite.", "a room with one of Dracula's emergency coffins. The Count is out.", "a saltpeter mine. To one side there is a huge wooden evaporation vat. Small crystals of saltpeter cause the walls to sparkle.", "the basement cafeteria of a local hospital. Some say that there has been nothing edible here for years.", "a troll arsenal. Kegs of gun powder surround you." }; String strGameNumber; String strGuard [] = { "giant", "ferocious lion", "grizzly bear", "Tasmanian devil", "crocodile", "giant crayfish", "troll", "boa constrictor", "harpy", "cobra", "singularly large leech", "rabid Doberman pinscher", "colossal cockroach", "giant rat", "titanic toad" }; String strTreasure [] = { "a complete set of superman comic books", "a bag full of gold coins", "a large blue-white diamond", "a four ounce emerald", "a platinum crucifix", "a string of pearls", "a ming vase", "an oriental rug", "a pile of rubies", "a previously undiscovered Rembrandt painting", "a Faberge egg", "a stack of silver bars", "a set of ivory tusks", "an ancient Greek statue", "a small amount of radium in a lead container" }; String strWeapon [] = { "dagger", "axe", "mace", "sword", "staff", "silver bullet", "hand of glory", "trident", "sling shot", "blow gun", "pike", "cutlass", "spear", "stileto", "magic wand" }; StringBuffer sbInventory; StringBuffer sbLine; StringBuffer sbLocation; StringBuffer sbPendingMsg; StringBuffer sbTreasures; StringBuffer sbWayOut; TreasureAbout treasureAbout; public void init() { TreasureFrame treasureFrame; //{{INIT_CONTROLS setLayout(null); addNotify(); buttonWest=new Button("West"); add(buttonWest); buttonWest.reshape(insets().left + 279,insets().top + 200,99,16); buttonSouth=new Button("South"); add(buttonSouth); buttonSouth.reshape(insets().left + 387,insets().top + 216,90,16); buttonNorth=new Button("North"); add(buttonNorth); buttonNorth.reshape(insets().left + 387,insets().top + 184,90,16); buttonEast=new Button("East"); add(buttonEast); buttonEast.reshape(insets().left + 486,insets().top + 200,99,16); buttonUp=new Button("Up"); add(buttonUp); buttonUp.reshape(insets().left + 486,insets().top + 168,99,16); buttonDown=new Button("Down"); add(buttonDown); buttonDown.reshape(insets().left + 279,insets().top + 232,99,16); editLocation=new TextArea(6,22); add(editLocation); editLocation.reshape(insets().left + 9,insets().top + 56,225,136); buttonForward=new Button("Forward"); add(buttonForward); buttonForward.reshape(insets().left + 279,insets().top + 168,99,16); buttonBackward=new Button("Backward"); add(buttonBackward); buttonBackward.reshape(insets().left + 486,insets().top + 232,99,16); buttonCarry=new Button("Carry"); add(buttonCarry); buttonCarry.reshape(insets().left + 252,insets().top + 272,117,16); buttonDropTreasures=new Button("Drop Treasures"); add(buttonDropTreasures); buttonDropTreasures.reshape(insets().left + 495,insets().top + 272,117,16); buttonWayOut=new Button("Way Out"); add(buttonWayOut); buttonWayOut.reshape(insets().left + 387,insets().top + 280,90,16); lableTitle=new Label("Visit all of the rooms and return all of the treasures to the entrance."); add(lableTitle); lableTitle.reshape(insets().left + 9,insets().top + 8,495,16); lavelMoves=new Label("Moves", Label.RIGHT); add(lavelMoves); lavelMoves.reshape(insets().left + 315,insets().top + 40,90,16); labelRoomsVisited=new Label("Rooms visited", Label.RIGHT); add(labelRoomsVisited); labelRoomsVisited.reshape(insets().left + 288,insets().top + 72,117,16); labelScore=new Label("Score", Label.RIGHT); add(labelScore); labelScore.reshape(insets().left + 315,insets().top + 136,90,16); labelTreasuresRecovered=new Label("Treasures recovered", Label.RIGHT); add(labelTreasuresRecovered); labelTreasuresRecovered.reshape(insets().left + 243,insets().top + 104,162,16); editRoomsVisited=new TextField(8); add(editRoomsVisited); editRoomsVisited.reshape(insets().left + 414,insets().top + 64,81,24); editTreasuresRecovered=new TextField(8); add(editTreasuresRecovered); editTreasuresRecovered.reshape(insets().left + 414,insets().top + 96,81,24); editScore=new TextField(8); add(editScore); editScore.reshape(insets().left + 414,insets().top + 128,81,24); editMoves=new TextField(8); add(editMoves); editMoves.reshape(insets().left + 414,insets().top + 32,81,24); labelLocation=new Label("Location"); add(labelLocation); labelLocation.reshape(insets().left + 9,insets().top + 32,90,16); labelInventory=new Label("Inventory"); add(labelInventory); labelInventory.reshape(insets().left + 9,insets().top + 200,90,16); editInventory=new TextArea(4,22); add(editInventory); editInventory.reshape(insets().left + 9,insets().top + 224,225,80); labelNumRooms=new Label("of"); add(labelNumRooms); labelNumRooms.reshape(insets().left + 504,insets().top + 72,36,16); editNumRooms=new TextField(8); add(editNumRooms); editNumRooms.reshape(insets().left + 549,insets().top + 64,81,24); labelNumTreasures=new Label("of"); add(labelNumTreasures); labelNumTreasures.reshape(insets().left + 504,insets().top + 104,36,16); editNumTreasures=new TextField(8); add(editNumTreasures); editNumTreasures.reshape(insets().left + 549,insets().top + 96,81,24); labelMaxScore=new Label("of"); add(labelMaxScore); labelMaxScore.reshape(insets().left + 504,insets().top + 136,36,16); editMaxScore=new TextField(8); add(editMaxScore); editMaxScore.reshape(insets().left + 549,insets().top + 128,81,24); buttonAbout=new Button("About"); add(buttonAbout); buttonAbout.reshape(insets().left + 531,insets().top + 24,90,16); //}} resize(insets().left + insets().right + 632, insets().top + insets().bottom + 305); editLocation.setEditable(false); fmTreasure=getFontMetrics(editLocation.getFont()); editInventory.setEditable(false); editRoomsVisited.setEditable(false); editTreasuresRecovered.setEditable(false); editScore.setEditable(false); editMoves.setEditable(false); editNumRooms.setEditable(false); editNumTreasures.setEditable(false); editMaxScore.setEditable(false); super.init(); treasureAbout=new TreasureAbout(); sbWayOut=new StringBuffer(256); sbPendingMsg=new StringBuffer(256); sbTreasures=new StringBuffer(1024); sbInventory=new StringBuffer(1024); sbLocation=new StringBuffer(3072); nGame=1; nDimensions=4; bEuclidean=true; nRooms=100; nRoom1=0; while (nRoom1 < nRooms) { bVisited[nRoom1]=false; nDimension1=0; while (nDimension1 < nDimensions) { nDirection1=0; while (nDirection1 < 2) { bConnected[nRoom1][nDimension1][nDirection1]=false; ++nDirection1; } ++nDimension1; } ++nRoom1; } nTreasures=15; add("Center",treasureFrame=new TreasureFrame(this)); treasureFrame.show(); disable(); } public synchronized void startGame( String strGameNumber, boolean bEuclidean, int nDimensions) { int nKeyEnd; int nKeyIndex; int nKeyStart; int nKeyLength; String strTem; this.nDimensions=nDimensions; this.bEuclidean=bEuclidean; nKeyLength=strGameNumber.length(); nKeyStart=0; while ((nKeyStart < nKeyLength) && (strGameNumber.charAt(nKeyStart) == ' ')) ++nKeyStart; nKeyEnd=nKeyLength-1; while ((nKeyEnd >= 0) && (strGameNumber.charAt(nKeyEnd) == ' ')) --nKeyEnd; nKeyIndex=0; while ((nKeyStart <= nKeyEnd) && (nKeyIndex < 8)) nRN[nKeyIndex++]=1+(int) (strGameNumber.charAt(nKeyStart++)); while (nKeyIndex < 8) nRN[nKeyIndex++]=16411; nRNPartialSum=0; for (nKeyIndex=7; nKeyIndex > 0; --nKeyIndex) { nRNPartialSum+=nRN[nKeyIndex]; if (nRNPartialSum >= 32771) nRNPartialSum-=32771; } nReplaceIndex=1; nAddIndex=0; nMaxWidth=1+(int) Math.exp( Math.log(((double) (2*nRooms)))/((double) nDimensions)); bWidthsFound=false; while (! bWidthsFound) { nDimension1=0; nVolume=1; while (nDimension1 < nDimensions) { nWidth[nDimension1]=nMaxWidth-nRandomNumber()%2; nVolume=nVolume*nWidth[nDimension1++]; } if (nVolume > nRooms) bWidthsFound=true; } nDimension1=nDimensions; while (nDimension1 < 4) nWidth[nDimension1++]=1; nRoom1=1; while (nRoom1 < nRooms) { nRoom2=1+nRandomNumber()%(nRooms-1); strTem=strDescription[nRoom1]; strDescription[nRoom1++]=strDescription[nRoom2]; strDescription[nRoom2]=strTem; } nXCoordinate=0; while (nXCoordinate < nWidth[0]) { nYCoordinate=0; while (nYCoordinate < nWidth[1]) { nZCoordinate=0; while (nZCoordinate < nWidth[2]) { nTCoordinate=0; while (nTCoordinate < nWidth[3]) nCell[nXCoordinate][nYCoordinate][nZCoordinate][ nTCoordinate++]=-1; ++nZCoordinate; } ++nYCoordinate; } ++nXCoordinate; } nCoordinate[0]=0; nCoordinate[1]=0; nCoordinate[2]=0; nCoordinate[3]=0; nRoom1=0; nRoom2=0; nCell[0][0][0][0]=0; while (nRoom1 < (nRooms-1)) { bDirectionFound=false; while (! bDirectionFound) { nDirection1=nRandomNumber()%2; nDimension1=nRandomNumber()%nDimensions; if (bEuclidean) { if ((nCoordinate[nDimension1]+2*nDirection1-1 >= 0) && (nCoordinate[nDimension1]+2*nDirection1-1 < nWidth[nDimension1])) bDirectionFound=true; } else bDirectionFound=true; } bConnected[nRoom2][nDimension1][nDirection1]=true; nCoordinateNext[0]=nCoordinate[0]; nCoordinateNext[1]=nCoordinate[1]; nCoordinateNext[2]=nCoordinate[2]; nCoordinateNext[3]=nCoordinate[3]; nCoordinateNext[nDimension1] =nCoordinate[nDimension1]+2*nDirection1-1; if (! bEuclidean) { if (nCoordinateNext[nDimension1] < 0) { nDimension2=0; while (nDimension2 < nDimensions) { nCoordinateNext[nDimension2]=nWidth[nDimension2] -nCoordinateNext[nDimension2]-1; ++nDimension2; } nCoordinateNext[nDimension1]=nWidth[nDimension1]-1; } else { if (nCoordinateNext[nDimension1] >= nWidth[nDimension1]) { nDimension2=0; while (nDimension2 < nDimensions) { nCoordinateNext[nDimension2]=nWidth[nDimension2] -nCoordinateNext[nDimension2]-1; ++nDimension2; } nCoordinateNext[nDimension1]=0; } } } if (nCell[nCoordinateNext[0]][nCoordinateNext[1]][ nCoordinateNext[2]][nCoordinateNext[3]] < 0) nCell[nCoordinateNext[0]][nCoordinateNext[1]][ nCoordinateNext[2]][nCoordinateNext[3]]=++nRoom1; nRoom2=nCell[nCoordinateNext[0]][nCoordinateNext[1]][ nCoordinateNext[2]][nCoordinateNext[3]]; bConnected[nRoom2][nDimension1][1-nDirection1]=true; nCoordinate[0]=nCoordinateNext[0]; nCoordinate[1]=nCoordinateNext[1]; nCoordinate[2]=nCoordinateNext[2]; nCoordinate[3]=nCoordinateNext[3]; } nTreasure1=0; while (nTreasure1 < nTreasures) { nTreasureRoom[nTreasure1] =1+nRandomNumber()%(nRooms-1); nGuardRoom[nTreasure1]=nTreasureRoom[nTreasure1]; bWeaponRoomFound=false; while (! bWeaponRoomFound) { nWeaponRoom[nTreasure1] =1+nRandomNumber()%(nRooms-1); if (nWeaponRoom[nTreasure1] != nTreasureRoom[nTreasure1]) bWeaponRoomFound=true; } ++nTreasure1; } nMoves=0; nVisited=0; nXCoordinate=0; nYCoordinate=0; nZCoordinate=0; nTCoordinate=0; sbWayOut.setLength(0); sbPendingMsg.setLength(0); updateScreen(); enable(); requestFocus(); } public boolean handleEvent(Event event) { if (event.id == Event.ACTION_EVENT && event.target == buttonAbout) { clickedButtonAbout(); return true; } else if (event.id == Event.ACTION_EVENT && event.target == buttonWayOut) { clickedButtonWayOut(); return true; } else if (event.id == Event.ACTION_EVENT && event.target == buttonDropTreasures) { clickedButtonDropTreasures(); return true; } else if (event.id == Event.ACTION_EVENT && event.target == buttonCarry) { clickedButtonCarry(); return true; } else if (event.id == Event.ACTION_EVENT && event.target == buttonBackward) { clickedButtonBackward(); return true; } else if (event.id == Event.ACTION_EVENT && event.target == buttonDown) { clickedButtonDown(); return true; } else if (event.id == Event.ACTION_EVENT && event.target == buttonSouth) { clickedButtonSouth(); return true; } else if (event.id == Event.ACTION_EVENT && event.target == buttonEast) { clickedButtonEast(); return true; } else if (event.id == Event.ACTION_EVENT && event.target == buttonWest) { clickedButtonWest(); return true; } else if (event.id == Event.ACTION_EVENT && event.target == buttonNorth) { clickedButtonNorth(); return true; } else if (event.id == Event.ACTION_EVENT && event.target == buttonForward) { clickedButtonForward(); return true; } else if (event.id == Event.ACTION_EVENT && event.target == buttonUp) { clickedButtonUp(); return true; } else if (event.id == Event.KEY_PRESS && event.target == this) { keyPressThis(event); return true; } return super.handleEvent(event); } //{{DECLARE_CONTROLS Button buttonWest; Button buttonSouth; Button buttonNorth; Button buttonEast; Button buttonUp; Button buttonDown; TextArea editLocation; Button buttonForward; Button buttonBackward; Button buttonCarry; Button buttonDropTreasures; Button buttonWayOut; Label lableTitle; Label lavelMoves; Label labelRoomsVisited; Label labelScore; Label labelTreasuresRecovered; TextField editRoomsVisited; TextField editTreasuresRecovered; TextField editScore; TextField editMoves; Label labelLocation; Label labelInventory; TextArea editInventory; Label labelNumRooms; TextField editNumRooms; Label labelNumTreasures; TextField editNumTreasures; Label labelMaxScore; TextField editMaxScore; Button buttonAbout; //}} public void keyPressThis(Event ev) { // to do: put event handler code here. } public void clickedButtonUp() { // to do: put event handler code here. ++nMoves; --nZCoordinate; sbPendingMsg.setLength(0); updateScreen(); } public void clickedButtonForward() { // to do: put event handler code here. ++nMoves; --nTCoordinate; sbPendingMsg.setLength(0); updateScreen(); } public void clickedButtonNorth() { // to do: put event handler code here. ++nMoves; --nXCoordinate; sbPendingMsg.setLength(0); updateScreen(); } public void clickedButtonWest() { // to do: put event handler code here. ++nMoves; ++nYCoordinate; sbPendingMsg.setLength(0); updateScreen(); } public void clickedButtonEast() { // to do: put event handler code here. ++nMoves; --nYCoordinate; sbPendingMsg.setLength(0); updateScreen(); } public void clickedButtonSouth() { // to do: put event handler code here. ++nMoves; ++nXCoordinate; sbPendingMsg.setLength(0); updateScreen(); } public void clickedButtonDown() { // to do: put event handler code here. ++nMoves; ++nZCoordinate; sbPendingMsg.setLength(0); updateScreen(); } public void clickedButtonBackward() { // to do: put event handler code here. ++nMoves; ++nTCoordinate; sbPendingMsg.setLength(0); updateScreen(); } public void clickedButtonCarry() { String msg; // to do: put event handler code here. sbPendingMsg.setLength(0); nTreasure1=0; while (nTreasure1 < nTreasures) { if (nWeaponRoom[nTreasure1] == nRoom1) nWeaponRoom[nTreasure1]=-1; ++nTreasure1; } nTreasure1=0; while (nTreasure1 < nTreasures) { if (nTreasureRoom[nTreasure1] == nRoom1) { if (nWeaponRoom[nTreasure1] < 0) { nTreasureRoom[nTreasure1]=-1; ++nTreasuresRecovered; if (nGuardRoom[nTreasure1] == nRoom1) { nGuardRoom[nTreasure1]=-1; nWeaponRoom[nTreasure1]=-2; sbPendingMsg.append("You're "); sbPendingMsg.append(strWeapon[nTreasure1]); sbPendingMsg.append(" overcomes the "); sbPendingMsg.append(strGuard[nTreasure1]); sbPendingMsg.append(".\n"); } } else { sbPendingMsg.append("You carry nothing to overcome the "); sbPendingMsg.append(strGuard[nTreasure1]); sbPendingMsg.append(".\n"); } } if (nWeaponRoom[nTreasure1] == nRoom1) nWeaponRoom[nTreasure1]=-1; ++nTreasure1; } updateScreen(); } public void clickedButtonDropTreasures() { // to do: put event handler code here. sbPendingMsg.setLength(0); nTreasure1=0; while (nTreasure1 < nTreasures) { if (nTreasureRoom[nTreasure1] == -1) nTreasureRoom[nTreasure1]=0; ++nTreasure1; } updateScreen(); } public void clickedButtonWayOut() { // to do: put event handler code here. sbPendingMsg.setLength(0); bPathFound=false; if ((bTreasureCarried) && (nRoom1 != 0)) { nCoordinate[0]=nXCoordinate; nCoordinate[1]=nYCoordinate; nCoordinate[2]=nZCoordinate; nCoordinate[3]=nTCoordinate; nWayOutHead=0; nRoom2=0; while (nRoom2 < nRooms) bRoomUsed[nRoom2++]=false; bRoomUsed[nRoom1]=true; nDirectionsUsed[nWayOutHead]=0; nDirectionsPossible=2*nDimensions; nDimension1=0; while (nDimension1 < nDimensions) { nDirection1=0; while (nDirection1 < 2) bDirectionUsed[nWayOutHead][nDimension1][nDirection1++]=false; ++nDimension1; } sbWayOut.setLength(0); nRoom2=nRoom1; nTrial=0; while ((nTrial < 500) && (nRoom2 != 0) && (nWayOutHead < 255)) { ++nTrial; bDirectionFound=false; while ((! bDirectionFound) && (nDirectionsUsed[nWayOutHead] < nDirectionsPossible)) { nDirection1=nRandomNumber()%2; nDimension1=nRandomNumber()%nDimensions; if (! bDirectionUsed[nWayOutHead][nDimension1][nDirection1]) { bDirectionUsed[nWayOutHead][nDimension1][nDirection1] =true; nDirectionsUsed[nWayOutHead] =nDirectionsUsed[nWayOutHead]+1; if (bConnected[nRoom2][nDimension1][nDirection1]) { nCoordinateNext[0]=nCoordinate[0]; nCoordinateNext[1]=nCoordinate[1]; nCoordinateNext[2]=nCoordinate[2]; nCoordinateNext[3]=nCoordinate[3]; nCoordinateNext[nDimension1]=nCoordinate[nDimension1] +2*nDirection1-1; if (! bEuclidean) { if (nCoordinateNext[nDimension1] < 0) { nDimension2=0; while (nDimension2 < nDimensions) { nCoordinateNext[nDimension2] =nWidth[nDimension2] -nCoordinateNext[nDimension2]-1; ++nDimension2; } nCoordinateNext[nDimension1] =nWidth[nDimension1]-1; } else { if (nCoordinateNext[nDimension1] >= nWidth[nDimension1]) { nDimension2=0; while (nDimension2 < nDimensions) { nCoordinateNext[nDimension2] =nWidth[nDimension2] -nCoordinateNext[nDimension2]-1; ++nDimension2; } nCoordinateNext[nDimension1]=0; } } } if (! bRoomUsed[nCell[nCoordinateNext[0]][ nCoordinateNext[1]][nCoordinateNext[2]][ nCoordinateNext[3]]]) bDirectionFound=true; } } } if (bDirectionFound) { nRoom2=nCell[nCoordinateNext[0]][nCoordinateNext[1]][ nCoordinateNext[2]][nCoordinateNext[3]]; bRoomUsed[nRoom2]=true; nDirectionsUsed[++nWayOutHead]=0; nDimension2=0; while (nDimension2 < nDimensions) { nDirection2=0; while (nDirection2 < 2) bDirectionUsed[nWayOutHead][nDimension2][nDirection2++] =false; ++nDimension2; } nWayOutDimension[nWayOutHead]=nDimension1; nWayOutDirection[nWayOutHead]=1-nDirection1; switch (nDimension1) { case 0: if (nDirection1 == 0) sbWayOut.append("N"); else sbWayOut.append("S"); break; case 1: if (nDirection1 == 0) sbWayOut.append("E"); else sbWayOut.append("W"); break; case 2: if (nDirection1 == 0) sbWayOut.append("U"); else sbWayOut.append("D"); break; default: if (nDirection1 == 0) sbWayOut.append("F"); else sbWayOut.append("B"); break; } } else { nDirection1=nWayOutDirection[nWayOutHead]; nDimension1=nWayOutDimension[nWayOutHead]; nCoordinateNext[0]=nCoordinate[0]; nCoordinateNext[1]=nCoordinate[1]; nCoordinateNext[2]=nCoordinate[2]; nCoordinateNext[3]=nCoordinate[3]; nCoordinateNext[nDimension1] =nCoordinateNext[nDimension1]+2*nDirection1-1; if (! bEuclidean) { if (nCoordinateNext[nDimension1] < 0) { nDimension2=0; while (nDimension2 < nDimensions) { nCoordinateNext[nDimension2] =nWidth[nDimension2]-nCoordinateNext[nDimension2] -1; ++nDimension2; } nCoordinateNext[nDimension1]=nWidth[nDimension1]-1; } else { if (nCoordinateNext[nDimension1] >= nWidth[nDimension1]) { nDimension2=0; while (nDimension2 < nDimensions) { nCoordinateNext[nDimension2] =nWidth[nDimension2] -nCoordinateNext[nDimension2]-1; ++nDimension2; } nCoordinateNext[nDimension1]=0; } } } nRoom2=nCell[nCoordinateNext[0]][nCoordinateNext[1]][ nCoordinateNext[2]][nCoordinateNext[3]]; --nWayOutHead; sbWayOut.setLength(sbWayOut.length()-1); } nCoordinate[0]=nCoordinateNext[0]; nCoordinate[1]=nCoordinateNext[1]; nCoordinate[2]=nCoordinateNext[2]; nCoordinate[3]=nCoordinateNext[3]; } if (nRoom2 == 0) bPathFound=true; } if (bPathFound) { nTreasure1=0; nRoom2=0; while ((nTreasure1 < nTreasures) && (nRoom2 >= 0)) { nRoom2=nTreasureRoom[nTreasure1]; if (nRoom2 >= 0) ++nTreasure1; } nRoom2=nRoom1; while (nRoom1 == nRoom2) nRoom2=1+nRandomNumber()%(nRooms-1); nTreasureRoom[nTreasure1]=nRoom2; sbPendingMsg.append( "The pirate takes one of your treasures. "); sbPendingMsg.append( "As he leaves, he shouts the letters, \""); sbPendingMsg.append(sbWayOut); sbPendingMsg.append("\".\n"); } else sbPendingMsg.append("Nothing happens. Try again later.\n"); updateScreen(); } public synchronized void updateScreen() { char firstChar; Integer intValue; intValue=new Integer(nMoves); editMoves.setText(intValue.toString()); if (! bEuclidean) { if (nXCoordinate < 0) { nYCoordinate=nWidth[1]-1-nYCoordinate; nZCoordinate=nWidth[2]-1-nZCoordinate; nTCoordinate=nWidth[3]-1-nTCoordinate; nXCoordinate=nWidth[0]-1; } else { if (nXCoordinate >= nWidth[0]) { nYCoordinate=nWidth[1]-1-nYCoordinate; nZCoordinate=nWidth[2]-1-nZCoordinate; nTCoordinate=nWidth[3]-1-nTCoordinate; nXCoordinate=0; } } if (nYCoordinate < 0) { nXCoordinate=nWidth[0]-1-nXCoordinate; nZCoordinate=nWidth[2]-1-nZCoordinate; nTCoordinate=nWidth[3]-1-nTCoordinate; nYCoordinate=nWidth[1]-1; } else { if (nYCoordinate >= nWidth[1]) { nXCoordinate=nWidth[0]-1-nXCoordinate; nZCoordinate=nWidth[2]-1-nZCoordinate; nTCoordinate=nWidth[3]-1-nTCoordinate; nYCoordinate=0; } } if (nZCoordinate < 0) { nXCoordinate=nWidth[0]-1-nXCoordinate; nYCoordinate=nWidth[1]-1-nYCoordinate; nTCoordinate=nWidth[3]-1-nTCoordinate; nZCoordinate=nWidth[2]-1; } else { if (nZCoordinate >= nWidth[2]) { nXCoordinate=nWidth[0]-1-nXCoordinate; nYCoordinate=nWidth[1]-1-nYCoordinate; nTCoordinate=nWidth[3]-1-nTCoordinate; nZCoordinate=0; } } if (nTCoordinate < 0) { nXCoordinate=nWidth[0]-1-nXCoordinate; nYCoordinate=nWidth[1]-1-nYCoordinate; nZCoordinate=nWidth[2]-1-nZCoordinate; nTCoordinate=nWidth[3]-1; } else { if (nTCoordinate >= nWidth[3]) { nXCoordinate=nWidth[0]-1-nXCoordinate; nYCoordinate=nWidth[1]-1-nYCoordinate; nZCoordinate=nWidth[2]-1-nZCoordinate; nTCoordinate=0; } } } nRoom1=nCell[nXCoordinate][nYCoordinate][nZCoordinate][nTCoordinate]; if ((nRoom1 != 0) && (sbWayOut.length() == 0) && (nRandomNumber()%100 == 0)) { nRoom2=0; while (nRoom2 <= 0) { nXCoordinate=nRandomNumber()%nWidth[0]; nYCoordinate=nRandomNumber()%nWidth[1]; nZCoordinate=nRandomNumber()%nWidth[2]; nTCoordinate=nRandomNumber()%nWidth[3]; nRoom2=nCell[nXCoordinate][nYCoordinate][nZCoordinate][nTCoordinate]; } if (nRoom2 != nRoom1) { nRoom1=nRoom2; sbPendingMsg.append("Yeow!!!! A flock of bats grabs you, flies you through the caverns, and drops you.\n"); } } sbWayOut.setLength(0); nTreasuresRecovered=0; nTreasure1=0; bTreasureCarried=false; while ((nTreasure1 < nTreasures) && (! bTreasureCarried)) if (nTreasureRoom[nTreasure1] < 0 ) bTreasureCarried=true; else ++nTreasure1; if (bTreasureCarried) { if (nRandomNumber()%(2*nRooms) == 0) { nRoom2=0; while (nRoom2 <= 0) { nDimension1=0; while (nDimension1 < nDimensions) { nCoordinate[nDimension1] =nRandomNumber()%nWidth[nDimension1]; ++nDimension1; } nRoom2=nCell[nCoordinate[0]][nCoordinate[1]][nCoordinate[2]][nCoordinate[3]]; if (nRoom1 == nRoom2) nRoom2=-1; } nTreasure1=0; while (nTreasure1 < nTreasures) { if (nTreasureRoom[nTreasure1] < 0 ) nTreasureRoom[nTreasure1]=nRoom2; ++nTreasure1; } bTreasureCarried=false; sbPendingMsg.append("A pirate jumps out of the shadows and takes your treasure."); sbPendingMsg.append("As he leaves, he says, \"Arggh! I'll hide me booty better this time.\"\n"); } } nTreasure1=0; nTreasure2=0; sbTreasures.setLength(0); sbInventory.setLength(0); nTreasuresCarried=0; while (nTreasure1 < nTreasures) { if (nTreasureRoom[nTreasure1] == 0) { ++nTreasuresRecovered; if (nRoom1 == 0) { sbTreasures.append("There's "); sbTreasures.append(strTreasure[nTreasure1]); sbTreasures.append(" here.\n"); } } else if (nTreasureRoom[nTreasure1] == nRoom1) { sbTreasures.append("There's "); sbTreasures.append(strTreasure[nTreasure1]); sbTreasures.append(" here. "); if (nGuardRoom[nTreasure1] == nRoom1) { firstChar=strGuard[nTreasure1].charAt(0); if ((firstChar == 'a') || (firstChar == 'e') || (firstChar == 'i') || (firstChar == 'o') || (firstChar == 'u')) sbTreasures.append("It's guarded by an "); else sbTreasures.append("It's guarded by a "); sbTreasures.append(strGuard[nTreasure1]); sbTreasures.append(".\n"); } } else { if (nTreasureRoom[nTreasure1] == -1) { bTreasureCarried=true; ++nTreasuresCarried; ++nTreasure2; sbInventory.append(strTreasure[nTreasure1]); sbInventory.append("\n"); } } if (nWeaponRoom[nTreasure1] == nRoom1) { firstChar=strWeapon[nTreasure1].charAt(0); if ((firstChar == 'a') || (firstChar == 'e') || (firstChar == 'i') || (firstChar == 'o') || (firstChar == 'u')) sbTreasures.append("There's an "); else sbTreasures.append("There's a "); sbTreasures.append(strWeapon[nTreasure1]); sbTreasures.append(" here.\n"); } else { if (nWeaponRoom[nTreasure1] == -1) { ++nTreasure2; sbInventory.append(strWeapon[nTreasure1]); sbInventory.append("\n"); } } ++nTreasure1; } intValue=new Integer(nTreasuresRecovered); editTreasuresRecovered.setText(intValue.toString()); intValue=new Integer(nTreasures); editNumTreasures.setText(intValue.toString()); if ((! bVisited[nRoom1])) { ++nVisited; bVisited[nRoom1]=true; } intValue=new Integer(nVisited); editRoomsVisited.setText(intValue.toString()); intValue=new Integer(nRooms); editNumRooms.setText(intValue.toString()); nScore=25*nVisited/nRooms+75*nTreasuresRecovered/nTreasures+45*nTreasuresCarried/nTreasures; if (nVisited > 5*nRooms) { nScore=nScore-nVisited/(5*nRooms); if (nScore < 0) nScore=0; } intValue=new Integer(nScore); editScore.setText(intValue.toString()); editMaxScore.setText("100"); sbLocation.setLength(0); sbLocation.append(sbPendingMsg); sbLocation.append("You're in "); sbLocation.append(strDescription[nRoom1]); sbLocation.append("\n"); sbLocation.append(sbTreasures); displayFormattedLocation(sbLocation,editLocation.getColumns()); editInventory.setText(sbInventory.toString()); if (sbTreasures.length() == 0) buttonCarry.disable(); else buttonCarry.enable(); if ((nRoom1 == 0) && (bTreasureCarried)) buttonDropTreasures.enable(); else buttonDropTreasures.disable(); if (bConnected[nRoom1][0][0]) buttonNorth.enable(); else buttonNorth.disable(); if (bConnected[nRoom1][0][1]) buttonSouth.enable(); else buttonSouth.disable(); if (bConnected[nRoom1][1][0]) buttonEast.enable(); else buttonEast.disable(); if (bConnected[nRoom1][1][1]) buttonWest.enable(); else buttonWest.disable(); if (bConnected[nRoom1][2][0]) buttonUp.enable(); else buttonUp.disable(); if (bConnected[nRoom1][2][1]) buttonDown.enable(); else buttonDown.disable(); if (bConnected[nRoom1][3][0]) buttonForward.enable(); else buttonForward.disable(); if (bConnected[nRoom1][3][1]) buttonBackward.enable(); else buttonBackward.disable(); } public void displayFormattedLocation( StringBuffer sbRaw, int nColumns) { boolean bEndOfParagraph; boolean bParagraphPending; int nRawIndex; int nRawLength; int nTokenIndex; int nTokenLength; char cCurrent; StringBuffer sbFormatted = new StringBuffer(3072); StringBuffer sbLine = new StringBuffer(50); StringBuffer sbTem = new StringBuffer(256); StringBuffer sbToken = new StringBuffer(256); sbFormatted.setLength(0); sbFormatted.append(" "); nRawIndex=0; nRawLength=sbRaw.length(); sbLine.setLength(0); sbLine.append(" "); bParagraphPending=false; while (nRawIndex < nRawLength) { while ((nRawIndex < nRawLength) && (sbRaw.charAt(nRawIndex) == ' ')) ++nRawIndex; sbToken.setLength(0); bEndOfParagraph=false; while ((nRawIndex < nRawLength) && (! bEndOfParagraph) && ((cCurrent=sbRaw.charAt(nRawIndex)) != ' ')) { sbToken.append(cCurrent); bEndOfParagraph=(cCurrent == '\n'); ++nRawIndex; } if (sbToken.length() > 0) { if (bParagraphPending) { if (sbLine.length() == 0) sbFormatted.append(" "); else sbFormatted.append("\n "); sbLine.setLength(0); sbLine.append(" "); bParagraphPending=false; } if (bEndOfParagraph) { bParagraphPending=true; sbToken.setLength(sbToken.length()-1); } } nTokenLength=sbToken.length(); if (nTokenLength > 0) { if (sbToken.charAt(sbToken.length()-1) == '.') { sbTem.setLength(0); sbTem.append(sbLine); sbTem.append(sbToken); sbTem.append(" "); if (fmTreasure.stringWidth(sbTem.toString()) <= editLocation.preferredSize().width-36) { sbFormatted.append(sbToken).append(" "); sbLine.append(sbToken).append(" "); } else { sbTem.setLength(sbTem.length()-2); if (fmTreasure.stringWidth(sbTem.toString()) <= editLocation.preferredSize().width-36) { sbFormatted.append(sbToken).append('\n'); sbLine.setLength(0); } else { sbFormatted.append('\n'); while (sbToken.length() > 0) { if (fmTreasure.stringWidth(sbToken.toString()) > editLocation.preferredSize().width-36) { sbTem.setLength(0); nTokenIndex=0; while (fmTreasure.stringWidth( sbTem.toString()) <= editLocation.preferredSize().width-36) sbTem.append(sbToken.charAt(nTokenIndex++)); --nTokenIndex; sbFormatted.append( sbToken.toString().substring(0,nTokenIndex)); sbFormatted.append('\n'); sbTem.setLength(0); sbTem.append( sbToken.toString().substring(nTokenIndex)); sbToken.setLength(0); sbToken.append(sbTem); } else { sbFormatted.append(sbToken); sbLine.setLength(0); sbLine.append(sbToken); sbTem.setLength(0); sbTem.append(sbLine); sbTem.append(" "); if (fmTreasure.stringWidth(sbTem.toString()) <= editLocation.preferredSize().width-36) { sbFormatted.append(" "); sbLine.append(" "); } else { sbFormatted.append('\n'); sbLine.setLength(0); } sbToken.setLength(0); } } } } } else { sbTem.setLength(0); sbTem.append(sbLine); sbTem.append(sbToken); sbTem.append(' '); if (fmTreasure.stringWidth(sbTem.toString()) <= editLocation.preferredSize().width-36) { sbFormatted.append(sbToken).append(' '); sbLine.append(sbToken).append(' '); } else { sbTem.setLength(sbTem.length()-2); if (fmTreasure.stringWidth(sbTem.toString()) <= editLocation.preferredSize().width-36) { sbFormatted.append(sbToken).append('\n'); sbLine.setLength(0); } else { sbFormatted.append('\n'); while (sbToken.length() > 0) { if (sbToken.length() > nColumns) { sbTem.setLength(0); nTokenIndex=0; while (fmTreasure.stringWidth( sbTem.toString()) <= editLocation.preferredSize().width-36) sbTem.append(sbToken.charAt(nTokenIndex++)); --nTokenIndex; sbFormatted.append( sbToken.toString().substring(0,nTokenIndex)); sbFormatted.append('\n'); sbTem.setLength(0); sbTem.append( sbToken.toString().substring(nTokenIndex)); sbToken.setLength(0); sbToken.append(sbTem); } else { sbFormatted.append(sbToken); sbLine.setLength(0); sbLine.append(sbToken); sbTem.setLength(0); sbTem.append(sbLine); sbTem.append(' '); if (fmTreasure.stringWidth(sbTem.toString()) <= editLocation.preferredSize().width-36) { sbFormatted.append(' '); sbLine.append(' '); } else { sbFormatted.append('\n'); sbLine.setLength(0); } sbToken.setLength(0); } } } } } } } editLocation.setText(sbFormatted.toString()); } public int nRandomNumber() { int nResult; /* Each pseudo-random number is the modulo sum of the previous eight pseudo-random numbers. A prime modulus makes it likely that the pseudo-random numbers will be uniformly distributed. To speed computation, a partial sum of 7 of the 8 previous pseudo-random numbers is maintained. For a given set of initial values nRN[i], i=0,1,2,...,7, this random number generator should produce the same sequence of random numbers, no matter what Java interpreter it is run under. */ do { nResult=nRNPartialSum+nRN[nAddIndex]; if (nResult >= 32771) nResult-=32771; nRNPartialSum=nResult-nRN[nReplaceIndex]; if (nRNPartialSum < 0) nRNPartialSum+=32771; nRN[nReplaceIndex]=nResult; nAddIndex=nReplaceIndex; if (++nReplaceIndex >= 8) nReplaceIndex=0; } while (nResult > 32767); return(nResult); } public void clickedButtonAbout() { treasureAbout.show(); // to do: put event handler code here. } }