:- module(agent, [init/0, look/0, move/1, take/1, shoot/1, hazardAt/1, somethingAt/1]). :- consult('misc.prolog'). :- consult('parser.prolog'). :- consult('map.prolog'). % initialisation init :- retractall(here(_)), retractall(pitAt(_)), retractall(wumpusAt(_)), retractall(goldAt(_)), retractall(batsAt(_)), initPos, initPits, initWumpus, initGold, initBats, roomList(Rooms), filter(Rooms, hazardAt, Walkable), isConnected(Walkable) *-> !; init. initPos :- retractall(moves(_)), asserta(moves(0)), roomList(Rooms), filter(Rooms, somethingAt, Emptyrooms), random_member(X,Emptyrooms), asserta(here(X)). initPits :- insert(4,pitAt). initWumpus :- roomList(Rooms), filter(Rooms, somethingAt, Emptyrooms), random_member(X,Emptyrooms), asserta(wumpusAt(X)). initGold :- retractall(haveGold(_)), insert(3,goldAt), asserta(haveGold(0)). initBats :- insert(2,batsAt). insert(N,Thing) :- N > 0, Nx is N - 1, insert(Nx,Thing), roomList(Rooms), filter(Rooms, somethingAt, Emptyrooms), random_member(X,Emptyrooms), P =.. [Thing,X], asserta(P). insert(0,_) :- true. % command functions look :- here(Location), writeSenses(Location), writeExits(Location). move(Direction) :- here(Location), connects(Location, New, Direction), retract(here(Location)), asserta(here(New)), join(['You move to the ',Direction,'.\n\n'],W), write(W), checkHazards, incrementMoves, look, !. move(_) :- write('Unknown direction.\n\n'). take(gold) :- here(Location), goldAt(Location), retract(goldAt(Location)), haveGold(G), Gx is G + 1, retract(haveGold(G)), asserta(haveGold(Gx)), write('You find some gold. Lucky you.\n\n'), incrementMoves, !. take(_) :- write('You cannot take that.\n\n'). shoot(Direction) :- here(Location), connects(Location, Target, Direction), wumpusAt(Target), write('You hear an unearthly scream.\n\n'), retract(wumpusAt(Target)), incrementMoves, win. shoot(Direction) :- here(Location), connects(Location, Target, Direction), not(wumpusAt(Target)), write('Thunk. Missed.\n\n'), incrementMoves, moveWumpus. shoot(_) :- write('Unknown target.\n\n'). % letting the player know what's going on writeSenses(Location) :- glitter(Location), breeze(Location), bats(Location), stench(Location). glitter(Location) :- current_predicate(goldAt/1), goldAt(Location), write('You see a glitter along the sandy floor of the cave.\n'). glitter(_) :- true. breeze(Location) :- current_predicate(pitAt/1), connects(Location, ConnectedRoom, _), pitAt(ConnectedRoom), write('A cold breeze blows through the room, making you shiver slightly.\n'). breeze(_) :- true. bats(Location) :- current_predicate(batsAt/1), connects(Location, ConnectedRoom, _), batsAt(ConnectedRoom), write('All available surfaces are covered in guano. How unsanitary.\n'). bats(_) :- true. stench(Location) :- current_predicate(wumpusAt/1), connects(Location, ConnectedRoom, _), wumpusAt(ConnectedRoom), write('An overpowering stench fills your nose.\n'). stench(_) :- true. writeExits(Location) :- findall(X, connects(Location,_,X), Exits), intercalate(Exits, ', ', O), join(['There are exits to the ',O,'.\n\n'],W), write(W). % modifying things and checking the ramifications moveWumpus :- wumpusAt(Old), findall(X, connects(Old,X,_), PossibleNews), random_member(New, PossibleNews), retract(wumpusAt(Old)), asserta(wumpusAt(New)), checkWumpus. checkHazards :- checkWumpus, checkBats, checkPit. checkWumpus :- current_predicate(wumpusAt/1), here(Location), wumpusAt(Location), lose(eaten). checkWumpus :- true. checkBats :- current_predicate(batsAt/1), here(Location), batsAt(Location), write('A giant bat swoops down, picks you up, and deposits you elsewhere in the cave.\n\n'), roomList(Rooms), random_member(NewLocation, Rooms), retract(here(Location)), asserta(here(NewLocation)), checkHazards. checkBats :- true. checkPit :- current_predicate(pitAt/1), here(Location), pitAt(Location), lose(pit). checkPit :- true. % winning, losing, and otherwise incrementMoves :- moves(N), retractall(moves(_)), Nx is N + 1, asserta(moves(Nx)). win :- write('*** YOU WIN ***\n'), moves(M), haveGold(G), join(['\nWin accomplished in ',M,' moves with ',G,' gold found\n'],W), write(W), halt(0). lose(eaten) :- write('You have been eaten by the wumpus.\n\n'), write('*** GAME OVER ***\n'), halt(0). lose(pit) :- write('You have fallen into a bottomless pit.\n\n'), write('*** GAME OVER ***\n'), halt(0). % miscellaneous clauses somethingAt(X) :- current_predicate(here/1), here(X). somethingAt(X) :- current_predicate(goldAt/1), goldAt(X). somethingAt(X) :- hazardAt(X). hazardAt(X) :- current_predicate(wumpusAt/1), wumpusAt(X). hazardAt(X) :- current_predicate(pitAt/1), pitAt(X). hazardAt(X) :- current_predicate(batsAt/1), batsAt(X).