summaryrefslogtreecommitdiff
path: root/src/agent.prolog
diff options
context:
space:
mode:
Diffstat (limited to 'src/agent.prolog')
-rw-r--r--src/agent.prolog278
1 files changed, 278 insertions, 0 deletions
diff --git a/src/agent.prolog b/src/agent.prolog
new file mode 100644
index 0000000..4085bf9
--- /dev/null
+++ b/src/agent.prolog
@@ -0,0 +1,278 @@
+
+:- module(agent, [init, look/0, move/1, take/1, shoot/1, hazardAt/1, somethingAt/1]).
+
+
+:- consult('misc.prolog').
+:- consult('parser.prolog').
+:- consult('map.prolog').
+
+
+
+
+% initialisation
+
+init :-
+ initPos,
+ initPits,
+ initWumpus,
+ initGold,
+ initBats,
+ roomList(Rooms),
+ filter(Rooms, hazardAt, Walkable),
+ isConnected(Walkable) *-> !; init.
+
+
+initPos :-
+ retractall(moves(_)),
+ asserta(moves(0)),
+ retractall(here(_)),
+ roomList(Rooms),
+ filter(Rooms, somethingAt, Emptyrooms),
+ random_member(X,Emptyrooms),
+ asserta(here(X)).
+
+
+initPits :-
+ retractall(pitAt(_)),
+ insert(5,pitAt).
+
+
+initWumpus :-
+ retractall(wumpusAt(_)),
+ roomList(Rooms),
+ filter(Rooms, somethingAt, Emptyrooms),
+ random_member(X,Emptyrooms),
+ asserta(wumpusAt(X)).
+
+
+initGold :-
+ retractall(goldAt(_)),
+ retractall(haveGold(_)),
+ insert(3,goldAt),
+ asserta(haveGold(0)).
+
+
+initBats :-
+ retractall(batsAt(_)),
+ 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'],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'),
+ write('*** GAME OVER ***\n'),
+ halt(0).
+
+
+lose(pit) :-
+ write('You have fallen into a bottomless pit.\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).
+