;Jim Piotrowski, Neal, Sarah
;HTW 4/14 3:01 AM
;Stuff to do next:
;RNG (although this might come last) - DONE
;movement wumpus - DONE
;arrows need to be implemented - Still short a counter

;More stuff to do:
;play like crazy, watch for wumpus movements, think there's glitches
;user friendlyify
;clean up duplicate statements
;random arrows?
;multiple wumpuses?







.org  0h
.equ marker, 40h; points to first square in mem
start:
	mov SP, #07h; needed to fix glitch in J51 sim - initializes stack pointer to correct value
	mov   TMOD, #20h ; set timer 1 for auto reload 
	mov   TCON, #41h ; run counter 1 edge trig
	mov   TH1,  #0FDh ; 9600 baud
	mov   SCON,#50h ; 8-bit data mode 1

	mov dptr, #openingscreen
	lcall puts
	lcall outputcr
	lcall getchar

init:
	mov R0, #marker
	mov A, #16
	mov R3, #4 ;R3 is the number of arrows folder
		   ; note R6 holds the random number
	
	

asgnmk:
	mov @r0, #0
	inc r0
	dec a
	jnz asgnmk

setplayer:
	lcall rand8
	anl a, #15
	add a, #marker
	mov R0, a
	mov @r0, #'U'

setwumpus:
	lcall rand8
	anl a, #15
	add a, #marker
	mov R0, a
	mov a, @r0
	cjne a, #0, setwumpus  ;get new position if already taken
	mov @r0, #'W'

setpit:
	lcall rand8
	anl a, #15
	add a, #marker
	mov R0, a
	mov a, @r0
	cjne a, #0, setpit  ;get new position if already taken
	mov @r0, #'P'

setbats:
	lcall rand8
	anl a, #15
	add a, #marker
	mov R0, a
	mov a, @r0
	cjne a, #0, setbats  ;get new position if already taken
	mov @r0, #'B'

	lcall rand8
	anl a, #15
	add a, #marker
	mov R0, a
	mov a, @r0
	cjne a, #0, setbats  ;get new position if already taken
	mov @r0, #'B'

	

actprog:
	lcall showboard
	lcall status
	lcall moveplayer
	lcall movehandler
	cjne a, #2, notbat
	lcall batmove
notbat:
	
	lcall movewumpus
	jz actprog
	
	mov dptr, #nothergame
	lcall outputcr
	lcall puts
	lcall getchar
	sjmp init


	





showboard:
	mov r1, #16
	mov r0, #marker
brdloop:
	mov a, r1
	anl a, #3h; is a mult of 4?  for cr's for drawing board
	jnz putspot
	mov a, #10
	lcall outputa
putspot:
	mov a, #'|'
	lcall outputa
	mov a, @r0
	lcall outputa
	inc r0
	dec r1
	mov a, r1
	jnz brdloop
	mov a, #10
	lcall outputa
	ret
	
	
moveplayer:
	lcall outputcr
	lcall outputcr
	mov dptr, #choosemsg
	lcall puts
	lcall outputcr
getmove:
	lcall charin
	cjne a, #'a', notleft
	lcall moveleft
	mov r0, #0xFFh
	sjmp moved
notleft:
	cjne a, #'d', notright
	lcall moveright
	mov r0, #0xFFh ;mark that movement has been done
	sjmp moved
notright:
	cjne a, #'w', notup
	lcall moveup
	mov r0, #0xFFh ;mark that movement has been done
	sjmp moved
notup:
	cjne a, #'s', notdown
	lcall movedown
	mov r0, #0xFFh ;mark that movement has been done
	sjmp moved
notdown:
	cjne a, #'f', notfire
	lcall firearrow ;function sets r0 to FF if action has occured
notfire:
moved:
	lcall outputcr
	cjne r0, #0xFFh, getmove
	ret
	

firearrow:
	mov a, r3
	jnz hasarrows
	lcall outputcr
	mov dptr, #noarrows
	lcall puts
	lcall outputcr
	mov a, #1
	mov r0, #0xFFh
	ret
hasarrows:
	dec r3
	lcall playerpos
	mov dptr, #firemsg
	lcall puts
	lcall charin
	cjne a, #'d', notfireright
	mov a, r1
	anl a, #3
	subb a, #3
	jz invalidfire
	lcall fireright ;will set r0 to correct marker
	ret
notfireright:
	cjne a, #'a', notfireleft
	mov a, r1
	anl a, #3
	jz invalidfire
	lcall fireleft ;will set r0 to correct marker
	ret
notfireleft:
	cjne a, #'s', notfiredown
	mov a, r1
	clr c
	rrc a
	clr c
	rrc a
	clr c
	subb a, #3
	jz invalidfire
	lcall firedown
	ret
notfiredown:
	cjne a, #'w', notfireup
	mov a, r1
	clr c
	rrc a
	clr c
	rrc a
	clr c
	jz invalidfire
	lcall fireup
	ret
notfireup:
invalidfire:
	lcall missedshot	
	ret	
	
			



fireright:
	mov a, r1
	inc a
	add a, #marker
	mov r0, a
	mov a, @r0
	clr c
	subb a, #'W'
	jz killedright
	mov a, @r0
	clr c
	subb a, #'C'
	jz killedright
	mov a, @r0
	clr c
	subb a, #'Q'
	jnz missedright
killedright:
	lcall killedwumpus
	ret
missedright:
	lcall missedshot
	ret

fireleft:
	mov a, r1
	dec a
	add a, #marker
	mov r0, a
	mov a, @r0
	clr c
	subb a, #'W'
	jz killedleft
	mov a, @r0
	clr c
	subb a, #'C'
	jz killedleft
	mov a, @r0
	clr c
	subb a, #'Q'
	jnz missedleft
killedleft:
	lcall killedwumpus
	ret
missedleft:
	lcall missedshot
	ret



firedown:
	mov a, r1
	add a, #4
	add a, #marker
	mov r0, a
	mov a, @r0
	clr c
	subb a, #'W'
	jz killeddown
	mov a, @r0
	clr c
	subb a, #'C'
	jz killeddown
	mov a, @r0
	clr c
	subb a, #'Q'
	jnz misseddown
killeddown:
	lcall killedwumpus
	ret
misseddown:
	lcall missedshot
	ret

fireup:
	mov a, r1
	subb a, #4
	add a, #marker
	mov r0, a
	mov a, @r0
	clr c
	subb a, #'W'
	jz killedup
	mov a, @r0
	clr c
	subb a, #'C'
	jz killedup
	mov a, @r0
	clr c
	subb a, #'Q'
	jnz missedup
killedup:
	lcall killedwumpus
	ret
missedup:
	lcall missedshot
	ret


killedwumpus:
	mov dptr, #shothit
	lcall outputcr
	lcall puts
	lcall outputcr
	mov r0, #0xFFh
	mov a, #5
	ret

missedshot:
	mov dptr, #shotmissed
	lcall outputcr
	lcall puts
	lcall outputcr
	mov r0, #0xFFh
	mov a, #1
	ret





status:
	mov r0, #marker
	mov r1, #0
statloop:
	clr c
	mov a, @r0
	subb a, #'U'
	jz text; r1 holds position, # 0-15
	inc r1
	inc r0
	sjmp statloop
text:
	mov a, r1
	anl a, #3
	jz afterlookleft
	lcall lookleft
afterlookleft:   ;the next calls use logic of the grid to decide if neighboring spaces are "in bounds"
	subb a, #3  
	jz afterlookright
	lcall lookright
afterlookright:
	mov a, r1
	clr c ;divide by 4
	rrc a
	clr c
	rrc a
	clr c
	jz afterlookup
	lcall lookup
afterlookup:
	subb a, #3
	jz afterlookdown
	lcall lookdown
afterlookdown:
	lcall arrowdisp
	ret



arrowdisp:
	mov r7, a
	mov dptr, #arwbegin
	lcall puts
	mov a, r3
	add a, #'0'
	lcall outputa
	mov dptr, #arwend
	lcall puts
	lcall outputcr
	lcall outputcr
	mov a, r7
	ret



lookleft:
	mov r7, a
	mov a, r1
	add a, #marker
	mov r0,a
	dec r0
	mov a, @r0
	lcall checkresult
	mov a, r7
	ret

lookright:
	mov r7, a
	mov a, r1
	add a, #marker
	mov r0,a
	inc r0
	mov a, @r0
	lcall checkresult
	mov a, r7
	ret

lookup:
	mov r7, a
	mov a, r1
	add a, #marker
	subb a, #4
	mov r0,a
	mov a, @r0
	lcall checkresult
	mov a, r7
	ret

lookdown:
	mov r7, a
	mov a, r1
	add a, #marker
	add a, #4
	mov r0,a
	mov a, @r0
	lcall checkresult
	mov a, r7
	ret

checkresult:
	jz returncheckresult; nothing there, no report
	mov a, @r0
	cjne a, #'W', pitcheck
	lcall nearwumpus
	lcall outputcr
pitcheck:
	cjne a, #'P', batcheck
	lcall nearpit
	lcall outputcr
batcheck:
	cjne a, #'B', wumpusandpitcheck
	lcall nearbats
	lcall outputcr
wumpusandpitcheck:
	cjne a, #'Q', wumpusandbatcheck
	lcall nearwumpus
	lcall outputcr
	lcall nearpit
	lcall outputcr
wumpusandbatcheck:
	cjne a, #'C', returncheckresult ;SHOULD never jump from here
	lcall nearwumpus
	lcall outputcr
	lcall nearbats
	lcall outputcr
returncheckresult:
	ret


outputa:
	clr TI
	mov SBuF, a
charout:
	jnb TI, charout
	ret
	
getchar:
	
charin:
	inc R6
	jnb RI, charin
	clr RI
	mov a, SBUF
	ret


nearwumpus:
	mov dptr, #wummsg
	lcall puts
	ret
nearpit:
	mov dptr, #pitmsg
	lcall puts
	ret
nearbats:
	mov dptr, #batmsg
	lcall puts
	ret

outputcr:
	mov b, a
	mov a,#10
	lcall outputa
	mov a, b
	ret
	
puts:
        clr   a
	movc  a,@a+dptr
	jz    putret
	clr   TI
	mov   SBUF, A
puts1:	jnb   TI,puts1
	inc   dptr
	sjmp  puts
putret:	ret


moveleft:
	lcall playerpos
	mov a, r1  ;check if left is possible by modding r1 by 4
	anl a, #3
	jnz leftexists
	mov a, #1  ;might want to mark error later
	ret
leftexists:
	dec r0
	mov a, @r0
	jnz hazard
	mov @r0, #'U'
	inc r0
	mov @r0, #0
	mov a, #1
	ret

moveright:  
	lcall playerpos
	mov a, r1  ;check if right is possible by modding r1 by 4 and subbing 3
	anl a, #3
	subb a, #3
	jnz rightexists
	mov a, #1 ;might want to mark out of bounds error later
	ret
rightexists:
	inc r0
	mov a, @r0
	jnz hazard
	mov @r0, #'U'
	dec r0
	mov @r0, #0
	mov a, #1 ;might want to mark out of bounds error later
	ret
			
	
moveup:
	lcall playerpos
	mov a, r1  ;check if right is possible by modding r1 by 4 and subbing 3
	clr c ;divide by 4
	rrc a
	clr c
	rrc a
	clr c
	jnz upexists
	mov a, #1 ;might want to mark out of bounds error later
	ret
upexists:
	mov a, r0
	subb a, #4
	mov r0, a
	mov a, @r0
	jnz hazard
	mov @r0, #'U'
	mov a, r0
	add a, #4
	mov r0, a
	mov @r0, #0
	mov a, #1 
	ret



;put in middle for memory jumping range purposes
hazard:
	cjne a, #'B', bathazard
	mov a, #3 ;batted
	ret
bathazard:
	cjne a, #'P', pithazard
	mov a, #2 ;pitted
	ret
pithazard:
	mov a, #4  ;wumpus by elimination
	ret





movedown:
	lcall playerpos
	mov a, r1  ;check if down is possible by dividing by 4 and subbing 3
	clr c ;divide by 4
	rrc a
	clr c
	rrc a
	clr c
	subb a, #3
	jnz downexists
	mov a, #1 ;might want to mark out of bounds error later
	ret
downexists:
	mov a, r0
	add a, #4
	mov r0, a
	mov a, @r0
	jnz hazard
	mov @r0, #'U'
	mov a, r0
	subb a, #4
	mov r0, a
	mov @r0, #0
	mov a, #1 ;might want to mark out of bounds error later
	ret

movehandler:
	cjne a, #1, isterminal
	mov a, #0
	lcall addarrow
	ret
isterminal:
	cjne a, #2, pasthandpit
	mov dptr, #pitdeath
	lcall puts
	lcall outputcr
	mov a, #1
	ret
pasthandpit:               	;past pitdeath
	cjne a, #3, pasthandbat
	mov dptr, #batmovemsg
	lcall puts
	lcall outputcr
	mov a, #2
	ret
pasthandbat:
	cjne a, #4, pastwumpusfood
	mov dptr, #wumpusdeath
	lcall puts
	lcall outputcr
	mov a ,#1
	ret
pastwumpusfood:
	mov a, #1
	ret	
	








playerpos:  ;put player location in r1
	mov r1, #0
	mov r0, #marker
iterateloc: 
	clr c  ;first, is move legal? - find player pos
	mov a, @r0
	subb a, #'U'
	jz doneiterate; r1 holds position, # 0-15
	inc r1
	inc r0
	sjmp iterateloc
doneiterate:
	ret

wumpuspos:  ;put wumpus location in r1
	mov r1, #0
	mov r0, #marker
iteratewloc: 
	clr c  
	mov a, @r0
	subb a, #'W'
	jz donewiterate
	clr c 
	mov a, @r0
	subb a, #'Q'
	jz donewiterate
	clr c 
	mov a, @r0
	subb a, #'C'
	jz donewiterate
	inc r1
	inc r0
	sjmp iteratewloc
donewiterate:
	ret

movewumpus:
	jz isneeded
	ret
isneeded:
	
	mov r7, a
	lcall rand8
	anl a, #3 ;want a 1 in 4 of wumpus staying still
	inc a ;make 3 = 4
	clr c
	rrc a	;shift right twice
	clr c
	rrc a
	clr c
	cjne a, #0, wmoved ;can only equal 1 or 0, jump if 1
invalidwmove:
	lcall wumpuspos
	lcall rand8
	anl a, #7
	clr c
	rrc a
	clr c
	cjne a, #0, skipzero
	lcall movewup
	sjmp wmoved
skipzero:
	cjne a, #1, skipone
	lcall movewdown
	sjmp wmoved
skipone:
	cjne a, #2, skiptwo
	lcall movewright
	sjmp wmoved
skiptwo:
	lcall movewleft
	sjmp wmoved
wmoved:
	jz invalidwmove
	mov a, r7
	ret

movewup:
	mov a, r1
	jz nowspace
	dec a
	jz nowspace
	dec a
	jz nowspace
	dec a
	jz nowspace
	dec a
	add a, #marker
	mov r0, a
	mov a, @r0
	cjne a, #0, wblocked;is pit or bat in wumpus's movement?
	mov @r0, #'W'
	sjmp wcleanup


wblocked:
	cjne a, #'U', notplayer
	mov dptr, #wumpuscaught ;the wumpus moved into the player's spot
	lcall outputcr
	lcall puts	
	mov R7, #1
	mov a, #1
	ret
notplayer:	
	inc a ;since pit and bat's occupied letters are one up, just inc!
	mov @r0, a
	sjmp wcleanup

movewdown:
	mov a, r1
	subb a, #16 ;so that a hits zero and jumps if a > 11
	inc a
	jz nowspace
	inc a
	jz nowspace
	inc a
	jz nowspace
	inc a
	jz nowspace
	add a, #16 ;restore a so that it's a valid location
	add a, #marker
	mov r0, a
	mov a, @r0
	cjne a, #0, wblocked;is pit or bat in wumpus's movement?
	mov @r0, #'W'
	sjmp wcleanup


movewleft:
	mov a, r1
	anl a, #3
	jz nowspace
	mov a, r1
	dec a
	add a, #marker
	mov r0, a
	mov a, @r0
	cjne a, #0, wblocked;is pit or bat in wumpus's movement?
	mov @r0, #'W'
	sjmp wcleanup


movewright:
	mov a, r1
	anl a, #3
	subb a, #3
	jz nowspace
	mov a, r1
	inc a
	add a, #marker
	mov r0, a
	mov a, @r0
	cjne a, #0, wblocked;is pit or bat in wumpus's movement?
	mov @r0, #'W'
	sjmp wcleanup

wcleanup:
	mov a, r1
	add a, #marker
	mov r0, a
	mov a, @r0
	cjne a, #'W', notclear
	mov @r0, #0
	mov a, #1 ;nonzero value so that movewumpus doesn't loop
	ret
notclear:
	dec a
	mov @r0, a
	mov a, #1 ;nonzero value so that movewumpus doesn't loop
	ret

nowspace:
	mov a, #0 ;force movewumpus to loop
	ret
	




batmove:
	lcall playerpos
	mov a, r1
	add a, #marker
	mov r0, a
	mov @r0, #0
moveplr:
	lcall rand8
	anl a, #15
	add a, #marker
	mov r0, a
	mov a, @r0
	jnz moveplr
	mov @r0, #'U'
	ret

addarrow:
	mov r7, a
	mov a, r3
	subb a, #9
	jz nonewarrow
	lcall rand8
	anl a, #7
	cjne a, #5, nonewarrow
	mov dptr, #foundarrow
	lcall puts
	inc r3
nonewarrow:
	mov a, r7
	ret
		

	



rand8:
	mov a, r6
	cjne a, #0, notzero
	inc a
notzero:
	mov b, #221
	mul AB
	add a, #53
	mov r6, a
	ret


batmsg:
	.byte 'Y','o','u',' ','h','e','a','r',' ','b','a','t','s',0
wummsg:
	.byte 'Y','o','u',' ','s','m','e','l','l',' ','a',' ', 'w','u','m','p','u','s',0
pitmsg:
	.byte 'Y','o','u',' ','f','e','e','l',' ','a',' ','d','r','a','f','t',0
choosemsg:
	.byte "Please press w,a,s,or d for a direction or press f to fire."
	.byte 0
pitdeath:
	.byte "You fell into a pit.  Have a nice afterlife."
	.byte 0
batmovemsg:
	.byte "The bats have carried you to a random space!"
	.byte 0
wumpusdeath:
	.byte "Congratulations!  You're wumpus food!"
	.byte 0
firemsg:
	.byte "Please use w,a,s,or d to choose a direction of fire"
	.byte 0
shotmissed:
	.byte "You missed!"
	.byte 0
shothit:
	.byte "You killed the wumpus...nice work!"
	.byte 0
wumpuscaught:
	.byte "The wumpus found you!!  Hope you're full of vitamins and minerals!"
	.byte 0
openingscreen:
	.byte "Welcome to Hunt the Wumpus, where you hunt the most dangerous of\nany animal "
	.byte "that has ever walked the earth!  Your only friend is your trusty\nbow and "
	.byte "arrow.  In the caves are pits that drop you to your death and bats\nthat "
	.byte "pick you up and move you to random places.  Good Hunting!\n"
	.byte "Press a key to continue!\n"
	.byte 0

noarrows:
	.byte "You have no arrows...better try to find one!"
	.byte 0
arwbegin:
	.byte "You have "
	.byte 0
arwend:
	.byte " arrows"
	.byte 0
nothergame:
	.byte "Please press a key to play another game!\n"
	.byte 0
foundarrow:
	.byte "\n\nYou found an arrow!\n\n"
	.byte 0

