# Hunt the Wumpus for the CoCo
# From Gregory Yob, Creative Computing Best 1
# Jerry Stratton astoundingscripts.com

#path of arrow
dim %arrowLegs%(5)
#caves
dim %locations%(20,3)
dim %hazards%(6), %savedHazards%(6)

cls
wrap-center Welcome to
wrap-center \^LHunt\^Q the \^LWumpus\^Q
#IFDEF speech
	#INCLUDE speech.bas

	%speech$ = "Welcome to Hunt the Wumpus"
	gosub speakSpeech
#ENDIFDEF

print
print "Instructions? (Y/N)";
gosub getYesNo
if %answer$="y" then gosub showInstructions

#set up cave
for %cave%=1 to 20
	for %node%=1 to 3
		read %locations%(%cave%, %node%)
	next %node%
next %cave%

#dodecahedron vertices
data
2,5,8,1,3,10,2,4,12,3,5,14,1,4,6
5,7,15,6,8,17,1,7,9,8,10,18,2,9,11
10,12,19,3,11,13,12,14,20,4,13,15,6,14,16
15,17,20,7,16,18,9,17,19,11,18,20,13,16,19
enddata

gosub newSetup

cls
wrap-center \^LHunt\^Q the \^LWumpus\^Q

# game loop
loop
	%arrowCount% = 5
	%playerLocation% = %hazards%(1)
	%finished% = 0

	loop
		gosub displayLocation
		gosub playerAction

		on %action% gosub shoot, movePlayer
	endloop unless (%finished% = 0)

	if (%finished% = 1) then
		%speech$ = "Hee hee hee..."
		gosub gloatAndPrint
		%speech$ = "The Wumpus'll getcha next time!!"
		gosub gloatAndPrint
	else
		%speech$ = "Ha ha ha - you lose!"
		gosub gloatAndPrint
	endif

	print "Same setup?";
	gosub getYesNo
	if (%answer$ = "y") then
		gosub restoreSetup
	else
		gosub newSetup
	endif
endloop

sub restoreSetup
	for %hazard% = 1 to 6
		%hazards%(%hazard%) = %savedHazards%(%hazard%)
	next %hazard%
endsub

# locate hazards
# 1-player
# 2-wumpus
# 3,4-pits
# 5,6-bats
sub newSetup
	for %hazard% = 1 to 6
		loop
			%hazardLocation% = rnd(20)
			%previousHazard% = %hazard%-1
			loop while (%previousHazard% > 0)
				break if (%hazards%(%previousHazard%) = %hazardLocation%)
				%previousHazard%--
			endloop
		endloop unless (%previousHazard% > 0)
		%hazards%(%hazard%) = %hazardLocation%
		%savedHazards%(%hazard%) = %hazards%(%hazard%)
	next %hazard%
endsub

sub displayLocation
	#clear out near hazards
	for %nearHazard% = 1 to 3
		%nearHazards%(%nearHazard%) = 0
	next %nearHazard%

	#collect hazards
	for %hazard% = 2 to 6
		for %node% = 1 to 3
			if (%locations%(%playerLocation%, %node%) = %hazards%(%hazard%)) then
				%nearHazards%((%hazard%+1)/2) = 1
			endif
		next %node%
	next %hazard%

	#hazard warnings
	for %nearHazard% = 1 to 3
		if (%nearHazards%(%nearHazard%) = 1) then
			switch
				case (%nearHazard% = 1)
					%speech$ = "I smell a \^LWumpus\^Q!"
					gosub gloatAndPrint
				case (%nearHazard% = 2)
					%speech$ = "I feel a draft."
					gosub gloatAndPrint
				case (%nearHazard% = 3)
					%speech$ = "I hear bats!"
					gosub gloatAndPrint
			endswitch
		endif
	next %nearHazard%

	print "You are in room ";%playerLocation%
	print "Tunnels lead to ";
	for %node% = 1 to 3
		print %locations%(%playerLocation%, %node%);
	next %node%
	print
endsub

#option is returned in %action%
sub playerAction
	print "\^LShoot or \^LMove?";

	loop
		a$=inkey$
	endloop unless (a$<>"s" and a$<>"m")
	print

	if (a$="s") then
		%action% = 1
	else
		%action% = 2
	endif
endsub

sub shoot
	loop
		input "Number of rooms (1-5)";%legCount%
	endloop unless (%legCount%<1 or %legCount%>5)

	for %leg% = 1 to %legCount%
		loop
			%prompt$ = "Room #" + str$(%leg%)
			gosub getNewRoom
			%arrowLegs%(%leg%) = %newRoom%

			break if (%leg% <=2)
			break if (%newRoom% <> %arrowLegs%(%leg%-2))

			wrap Arrows aren't that crooked. Try another room.
		endloop
	next %leg%

	#shoot arrow
	%arrowLocation% = %playerLocation%
	for %leg% = 1 to %legCount%
		%newLocation% = 0
		for %node% = 1 to 3
			if (%locations%(%arrowLocation%, %node%) = %arrowLegs%(%leg%)) then
				%newLocation% = %arrowLegs%(%leg%)
			endif
		next %node%
		if (%newLocation% = 0) then
			#no tunnel for arrow
			%speech$ = "You hear a ping..."
			gosub gloatAndPrint
			%arrowLocation% = %locations%(%arrowLocation%,rnd(3))
		else
			%arrowLocation% = %newLocation%
		endif

		switch
			case (%arrowLocation% = %playerLocation%)
				%speech$ = "Ouch! Arrow got you!"
				gosub gloatAndPrint
				%finished% = -1
				return
			case (%arrowLocation% = %hazards%(2))
				%speech$ = "Aha! You got the Wumpus!"
				gosub gloatAndPrint
				%finished% = 1
				return
		endswitch
	next %leg%

	print "Missed"

	gosub moveWumpus
	if %finished% < 0 then return

	#reduce arrow count
	%arrowCount%--
	if (%arrowCount% < 1) then
		%finished% = -1
		wrap You are out of arrows. You are defenseless in a dangerous environment.
		pause .5
		wrap-center You are dead.
	endif
endsub

sub movePlayer
	loop
		%prompt$ = "Where to"
		gosub getNewRoom

		#legal move?
		for %node% = 1 to 3
			break if (%locations%(%playerLocation%, %node%) = %newRoom%)
		next %node%
		print "Not possible..."
	endloop
	%playerLocation% = %newRoom%
	gosub roomResults
endsub

sub roomResults
	switch
		case (%playerLocation% = %hazards%(2))
			%speech$ = "... oops! Bumped a wumpus!"
			gosub gloatAndPrint
			gosub moveWumpus
			if %finished% < 0 then return
		case (%playerLocation% = %hazards%(3) or %playerLocation% = %hazards%(4))
			%speech$ = "Yyyiiiieeee . . . fell in pit!"
			gosub gloatAndPrint
			%finished% = -1
			return
		case (%playerLocation% = %hazards%(5) or %playerLocation% = %hazards%(6))
			%speech$ = "Zap--super bat snatch!"
			gosub gloatAndPrint
			%speech$ = "Elsewhereville for you!"
			gosub gloatAndPrint
			%playerLocation% = rnd(20)
			gosub roomResults
	endswitch
endsub

sub moveWumpus
	%wumpusMove% = rnd(4)
	if (%wumpusMove% < 4) then
		%hazards%(2) = %locations%(%hazards%(2), %wumpusMove%)
	endif
	if (%hazards%(2) = %playerLocation%) then
		%speech$ = "Tsk tsk tsk-\^LWumpus\^Q got you!"
		gosub gloatAndPrint
		%finished% = -1
	endif
endsub

sub getYesNo
	loop
		%answer$=inkey$
	endloop unless (%answer$<>"y" and %answer$<>"n")
	print
endsub

sub getNewRoom
	loop
		print %prompt$;
		input %newRoom%
	endloop unless (%newRoom% < 1 or %newRoom% > 20)
endsub

sub showInstructions
	cls
	wrap-center \^LHunt\^Q the \^LWumpus\^Q
	print
	wrap The wumpus lives in a cave of 20 rooms. Each room has 3 tunnels leading to other rooms. (Look at a dodecahedron to see how this works. If you don't know what a dodecahedron is, ask a D&D player.)
	pause
	cls

	wrap Two rooms have bottomless pits in them. If you go there, you fall into the pit & lose!
	print
	wrap Two other rooms have super bats. If you go there, a bat grabs you and takes you to some other room at random, which might be troublesome.
	pause
	cls

	wrap The wumpus is not bothered by the hazards (he has sucker feet and is too big for a bat to lift). Usually he is asleep. Two things wake him up: your entering his room or your shooting an arrow. If the wumpus wakes, he might move one room or he might stay still. After that, if he is where you are, he eats you.
	pause
	cls

	wrap Each turn you may move or shoot a crooked arrow. You have 5 arrows. You lose when you run out. Aim by telling the computer the rooms you want to shoot the arrow into. If the arrow can't go that way it moves at random to a next room.
	pause
	cls
	wrap If the arrow hits the wumpus, you win.
	print
	wrap If the arrow hits you, you lose.

	wrap When you are one room away from something dangerous, you will smell the wumpus, hear bats, or feel a draft from the pit.
	pause
endsub

sub gloatAndPrint
	print %speech$
	#IFDEF speech
		gosub speakSpeech
	#ENDIFDEF
endsub
