How to add a time limit to find object in prolog game? - prolog

I am coding an adventure game in swi-prolog and I am fairly new to it, but I understand the basics. I am trying to figure out how to set a time limit to give the user around 5 minutes to find objects before they disappear. For example, there is a secret key that takes you right to the enemy and if you dont find it in 5 minutes it disappears.
This is what I have so far...
/*
--> Diamond Cookie -- an adventure game
--> You must find the diamond cookie in order to save your sweet land
from being taken over by the healthy enemies.
--> Type start. to begin the story/game
*/
:- dynamic at/2, i_am_at/1, alive/1. /* Needed by SWI-Prolog. */
:- retractall(at(_, _)), retractall(i_am_at(_)), retractall(alive(_)).
/* defines the starting location. */
i_am_at(village).
/* shows how each of the rooms/areas are connected. */
path(snake, d, cave).
path(village, e, box).
path(box, w, village).
path(village, w, secret).
path(secret, e, village).
path(cave, u, snake).
path(cave, w, cave_entrance).
path(cave_entrance, e, cave).
path(cave_entrance, s, village).
path(ghouse, n, village).
path(ghouse, w, fridge).
path(fridge, e, ghouse).
path(room1, w, ghouse).
path(room1, e, room2).
path(secret, n, tree1).
path(tree1, s, secret).
path(secret, w, tree2).
path(tree2, e, secret).
path(secret, s, tree3).
path(tree3, n, secret).
path(village, n, cave_entrance) :- at(popsiclelight, in_hand).
path(village, n, cave_entrance) :-
write('You can''t go into that dark, fudgey cave without the popsiclelight and gumdrop batteries! Are you insane!?'), nl,
!, fail.
path(village, s, ghouse) :- at(gumdrop, in_hand).
path(village, s, ghouse) :-
write('Find the gumdrops to come inside!'), nl,
!, fail.
path(ghouse, e, room1) :- at(lolipopkey, in_hand).
path(ghouse, e, room1) :-
write('The unfrosted door is locked. A lolipop key is needed...'), nl,
fail.
/* where the various objects in the game are located. */
at(diamondcookie, snake).
at(lolipopkey, cave_entrance).
at(popsiclelight, ghouse).
at(candycane, room1).
at(gumdrop, box).
at(key, tree2).
/* snake is alive. */
alive(snake).
/* picking up objects. */
take(X) :-
at(X, in_hand),
write('You are already holding it!'),
nl, !.
take(X) :-
i_am_at(Place),
at(X, Place),
retract(at(X, Place)),
assert(at(X, in_hand)),
write('done.'),
nl, !.
take(_) :-
write('I don''t see that item here.'),
nl.
/* dropping unwanted object. */
drop(X) :-
at(X, in_hand),
i_am_at(Place),
retract(at(X, in_hand)),
assert(at(X, Place)),
write('done.'),
nl, !.
drop(_) :-
write('You are not holding it!'),
nl.
/* the six direction letters to move around */
n :- go(n).
s :- go(s).
e :- go(e).
w :- go(w).
u :- go(u).
d :- go(d).
/* how to move in a given direction. */
go(Direction) :-
i_am_at(Here),
path(Here, Direction, There),
retract(i_am_at(Here)),
assert(i_am_at(There)),
look, !.
go(_) :-
write('You cannot go that way...'), nl.
/* how to look around the area. */
look :-
i_am_at(Place),
describe(Place),
nl,
notice_objects_at(Place),
nl.
/* mention all the objects in the vicinity. */
notice_objects_at(Place) :-
at(X, Place),
write('There is a '), write(X), write(' here.'), nl,
fail.
notice_objects_at(_).
/* inventory to list all possesions */
inventory :-
write(' Inventory: '),nl,
list_items.
list_items :-
at(X, in_hand),
write(X), tab(10),
fail.
list_items.
/* getting killed and killing the celery and the snake. */
kill :-
i_am_at(fridge),
write('Horrible idea! You have just been turned into a vegetable by the celery...'), nl,
!, die.
kill :-
i_am_at(cave),
write('This is not working. The snake is very heavy and'), nl,
write('sticky, how does it even slither...').
kill :-
i_am_at(snake),
at(candycane, in_hand),
retract(alive(snake)),
write('You stab the snake repeatedly. Slimy juices'), nl,
write('ooze out of the spider''s back, and get all over you.'), nl,
write('You have killed it!!'),
nl, !.
kill :-
i_am_at(snake),
write('Punching the snake with your fists does no'), nl,
write('damage to it. '), nl, !.
kill :-
write('I do not see anything dangerous here.'), nl.
/* when you die. */
die :-
!, finish.
/* requests the user to perform the final halt after the game is over. */
finish :-
nl,
write('The game is over. Please enter the halt. command.'),
nl, !.
/* game instructions. */
instructions :-
nl,
write('Enter commands using standard Prolog syntax.'), nl,
write('Available commands are:'), nl,
write('start. -- to start the game.'), nl,
write('n. s. e. w. u. d. -- to go in that direction.'), nl,
write('take(Object). -- to pick up an object.'), nl,
write('drop(Object). -- to put down an object.'), nl,
write('inventory. -- to check your inventory.'), nl,
write('kill. -- to attack an enemy.'), nl,
write('look. -- to look around you again.'), nl,
write('instructions. -- to see this message again.'), nl,
write('halt. -- to end the game and quit.'), nl,
nl.
/* prints out instructions and tells where you are starting. */
start :-
instructions,
look.
/* describe the various rooms. Depending on
circumstances, a room may have more than one description. */
describe(village) :-
at(diamondcookie, in_hand),
write('Congratulations! You have recovered the diamond cookie'), nl,
write('and saved the land! You won.'), nl,
finish, !.
describe(village) :-
write('You are in the Sour Patch Village. To the north is the chocolate'), nl,
write('lava cave enterence; to the south is a small gingerbread house.'), nl,
write('To the east there is a small box that may have something in it.'),nl,
write('Your mission, if you accept, is to recover the diamond cookie'), nl,
write('and return it to this village to save the land from the healthy enemies!.'), nl,
write('There is also a secret in the map that if found in time, .'), nl.
describe(secret) :-
write('WOW... a gummy worm jungle! There are three trees. One tree is to the north and is pink/blue'), nl,
write('gummy worms. To the west there is a yellow/pink gummy worm tree. To the south there is an orange/green'), nl,
write('gummy worm tree. Maybe there is something important here...'), nl.
describe(tree1) :-
write('...just a tree.'), nl.
describe(tree2) :-
write('There is a hole in this tree with seems to be a chocoloate key.'), nl,
write('It must open something in a chocolatey place...'), nl.
describe(tree3) :-
write('Just a bunch of gummy frogs...'), nl.
describe(box) :-
write('Inside the box there are gumdrops, the kind that would go perfect in'), nl,
write('a popsiclelight to emit bright light.'), nl.
describe(ghouse) :-
write('You are in a small gingerbread house. The exit is to the north.'), nl,
write('There is a frosted door to the west, and it cracked opened.'), nl,
write('It smells a bit weird over there. There is an unfrosted door to the east.'), nl.
describe(fridge) :-
write('You are in the angry celery stick''s fridge! The celery sticks are'), nl,
write('angry and want to turn you to a vegetable. Get out while you can!'), nl.
describe(room1) :-
write('This minty smelling room has a sharp candycane, this would make a great weapon!'), nl.
describe(cave_entrance) :-
write('You are in the opening of a fudgey cave. The exit is to'), nl,
write('the south; there is a dark, round sprinkle-covered passage to'), nl,
write('the east.'), nl.
describe(cave) :-
alive(snake),
at(diamondcookie, in_hand),
write('The twizzler snake sees you with the diamond cookie and poisons you with ranch!!'), nl,
write(' ...you die within seconds....'), nl,
die.
describe(cave) :-
alive(snake),
write('There is a huge twizzler snake here! He poisons with ranch dressing,'), nl,
write('and it is directly in front of you!'), nl,
write('You should leave quietly, ASAP!'), nl, !.
describe(cave) :-
write('eghhh! There is a huge twizzler snake here, spewing ranch.'), nl,
write('It is going in circles around something sparkly.'), nl.
describe(snake) :-
alive(snake),
write('You are on top of a huge twizzler snake, standing on its sticky'), nl,
write('red skin. The smell of its poisonous ranch is awful.'), nl.
describe(snake) :-
write('YUCK! You''re on top of a giant dead snake!'), nl.
How would I add a time limit for the user to find an object within a five-minute time limit. Additionally, if they don't, how would I make it so that the object disappears after the five minutes and the user would need to find the objects the long way?

Related

I am new to Prolog. I have tried to develop a major selection simple expert system, but I am stuck

I want to be able to let users choose a few options and not all to get the hypothesis to show. Example: The user is interested in computers, programming, and technology but not apps, i still want the system to show that user can major in Information Technology.
This code is able to run in swi-prolog.
go:-
hypothesis(Major),
write('I believe that the student can major in '),
write(Major), nl,
write('GOOD LUCK '),
undo.
/*Hypothesis that should be tested*/
hypothesis(informationTechnology) :-
informationTechnology, !.
hypothesis(informationTechnology_or_medicine) :-
informationTechnology_or_medicine, !.
hypothesis(medicine) :- medicine, !.
hypothesis(hospitality) :- hospitality, !.
hypothesis(business) :- business, !.
hypothesis(law) :- law, !.
hypothesis(unknown). /* no diagnosis*/
/*Hypothesis Identification Rules*/
informationTechnology :-
verify(computers),
verify(apps),
verify(technology),
verify(programming),
write('Courses to choose from:'), nl,
write('1: Computer Science'), nl,
write('2: Information Systems'), nl,
write('3: Security Technology'), nl,
write('Please wear warm cloths Because'), nl.
informationTechnology_or_medicine :-
verify(computers),
verify(science),
verify(communication),
verify(problem_solving),
verify(research),
verify(technology),
write('Courses to choose from:'), nl,
write('1: Computer Science'), nl,
write('2: Information Systems'), nl,
write('3: Security Technology'), nl,
write('These are the available courses.'), nl.
medicine :-
verify(science),
verify(health),
verify(research),
verify(helping_people),
write('Courses to choose from:'), nl,
write('1: Nursing'), nl,
write('2: Medicine'), nl,
write('3: Physiotherapy'), nl,
write('These are the available courses.'), nl.
hospitality :-
verify(helping_people),
verify(management),
verify(communication),
verify(planning),
write('Courses to choose from:'), nl,
write('1: Hotel Management'), nl,
write('2: Culinary arts'), nl,
write('3: Human Resources Management'), nl,
write('4: Public Relations'), nl,
write('These are the available courses.'), nl.
business :-
verify(money_making),
verify(apps),
verify(economy),
verify(communication),
write('Courses to choose from:'), nl,
write('1: Business Administration'), nl,
write('2: Accounting and Finance'), nl,
write('3: Marketing and E-commerce'), nl,
write('4: International Business'), nl,
write('These are the available courses.'), nl.
law :-
verify(law),
verify(justice),
verify(government),
verify(politics),
verify(reading),
write('Courses to choose from:'), nl,
write('1: Criminology'), nl,
write('2: Political Science'), nl,
write('3: Psychology'), nl,
write('4: Forensics'), nl,
write('These are the available courses.'), nl.
/* how to ask questions */
ask(Question) :-
write('Do you have interest in:'),
write(Question),
write('? '),
read(Response), nl,
( (Response == yes ; Response == y)
->
assert(yes(Question)) ;
assert(no(Question)), fail).
:- dynamic yes/1,no/1.
/*How to verify something */
verify(S) :-
(yes(S)
->
true ;
(no(S)
->
fail ;
ask(S))).
/* undo all yes/no assertions*/
undo :- retract(yes(_)),fail.
undo :- retract(no(_)),fail.
undo.
Just add another hypothesis like this:
hypothesis(informationTechnology_without_apps) :-
informationTechnology_without_apps, !.
and a new hypothesis identification rule:
informationTechnology_without_apps :-
verify(computers),
verify(technology),
verify(programming),
write('Courses to choose from:'), nl,
write('1: Computer Science'), nl,
write('2: Information Systems'), nl,
write('3: Security Technology'), nl,
write('Please wear warm cloths Because'), nl.

How can i use the prompt or terminal to verify the animal identification

/* animal.pro
animal identification game.
start with ?- go. */
go :-
hypothesize(Animal),
write('I guess that the animal is: '),
write(Animal),
nl,
undo.
/* hypotheses to be tested */
hypothesize(cheetah) :- cheetah, !.
hypothesize(tiger) :- tiger, !.
hypothesize(giraffe) :- giraffe, !.
hypothesize(zebra) :- zebra, !.
hypothesize(ostrich) :- ostrich, !.
hypothesize(penguin) :- penguin, !.
hypothesize(albatross) :- albatross, !.
hypothesize(unknown). /* no diagnosis */
/* animal identification rules */
cheetah :- mammal,
carnivore,
verify(has_tawny_color),
verify(has_dark_spots).
tiger :- mammal,
carnivore,
verify(has_tawny_color),
verify(has_black_stripes).
giraffe :- ungulate,
verify(has_long_neck),
verify(has_long_legs).
zebra :- ungulate,
verify(has_black_stripes).
ostrich :- bird,
verify(does_not_fly),
verify(has_long_neck).
penguin :- bird,
verify(does_not_fly),
verify(swims),
verify(is_black_and_white).
albatross :- bird,
verify(appears_in_story_Ancient_Mariner),
verify(flys_well).
/* classification rules */
mammal :- verify(has_hair), !.
mammal :- verify(gives_milk).
bird :- verify(has_feathers), !.
bird :- verify(flys),
verify(lays_eggs).
carnivore :- verify(eats_meat), !.
carnivore :- verify(has_pointed_teeth),
verify(has_claws),
verify(has_forward_eyes).
ungulate :- mammal,
verify(has_hooves), !.
ungulate :- mammal,
verify(chews_cud).
/* how to ask questions */
ask(Question) :-
write('Does the animal have the following attribute: '),
write(Question),
write('? '),
read(Response),
nl,
( (Response == yes ; Response == y)
->
assert(yes(Question)) ;
assert(no(Question)), fail).
:- dynamic yes/1,no/1.
/* How to verify something */
verify(S) :-
(yes(S)
->
true ;
(no(S)
->
fail ;
ask(S))).
/* undo all yes/no assertions */
undo :- retract(yes(_)),fail.
undo :- retract(no(_)),fail.
undo.
Can someone help. I have been trying to use prompt/terminal to output me the result of an animal identification gprolog code above, but it is giving me errors. used this command tiger(X), its giving me this error
| ?- tiger(X).
uncaught exception: error(existence_error(procedure,tiger/1),top_level/0)
can you please help me with other commands to verify if my code is perfect.

truthtable for nested equation

I am trying to create a prolog program to print out the truthtable of a statement. It works fine for the example truthtable(A,B,and(A,B)),
but if I try truthable(A,B,or(A,and(A,B))) it doesn't work and shows everything as false.
and(true,true):- true.
and(false,true):-false.
and(true,false):-false.
and(false,false):-false.
or(true,true):-true.
or(false,true):-true.
or(true,false):-true.
or(false,false):-false.
non(true):-false.
non(false):-true.
evaluate(E, true) :- E, !.
evaluate(E, false).
bool(true).
bool(false).
truthtable(A,B,E):-
bool(A),
bool(B),
write(A),
write(' \t '),
write(B),
write(' \t '),
evaluate(E, R),
write(R),
nl,
fail.
Also what can I do if I want the user to add any number of inputs for example A,B and C not only A and B.

SICStus Prolog - Avoid Redo

I'm trying to do a modified version of checkers in prolog. My main cycle is:
run(Board, Player) :- write('RUNNING BOARD 1'),nl,
canStillPlay(Board, Player),
% printBoard(Board),
printPlayerTurn(Player),
getStartPositions(Player, Board, StartPositions),
write('Starting Positions'), nl,
write(StartPositions), nl,
write('Select Start Position'), nl, nl,
read(StartX-StartY),
checkValidStartPosition(StartX-StartY, StartPositions),
% getEndingPositions(Player, Board, EndingPositions).
% write('Ending Positions'), nl,
% write('Select Move Position'), nl,
% read(EndX-EndY),
% checkValidEndingPosition(EndX-EndY, EndingPositions)
% movePawn(Board, NewBoard, StartPosition, MovePosition, MovementType, Player),
nextTurn(Player, NewPlayer), nl,
run(Board, NewPlayer).
run(Board, Player) :- write('RUNNING BOARD 2'), nl,
canStillPlay(Board, Player),
write('Reselect a pawn'), nl,
run(Board, Player).
run(Board,Player) :- write('RUNNING BOARD 3'), nl,
Player, !,
printBoard(Board),
write('White WON').
run(Board,_Player) :- write('RUNNING BOARD 4'), nl,
printBoard(Board),
write('Black WON').
When I select an invalid position, it redoes getStartPositions, instead of just moving on to the next run(Board, Player). I read in another question here that it is "a compiler optimization that a given compiler/version combination might or might not have."
How can I avoid the redo? If I try to cut it, it just ends the program with a no.

creating a menu in prolog?

menu :-
repeat,
write(' '),nl,
write(' 1.the number of hello '),nl,
write(' '),nl,
write('enter your choice:'),nl,
read(Choice), Choice>0, Choice =<6,
doit(Choice),Choice=6.
doit(1):- numberofhello(N).
doit(6):- abort.
my_list([hello,hello,hello]).
counthowmany(_, [], 0) :- !.
counthowmany(X, [X|Q], N) :- !, counthowmany(X, Q, N1), N is N1+1.
counthowmany(X, [_|Q], N) :- counthowmany(X, Q, N).
numberofhello(N) :- my_list(L),counthowmany(hello,L,N).
now in the code above after compile buffer when I ask Prolog for a menu the menu appears
with one choice and when i enter 1 for number of hello in the list(my_list) i don't get any answer and i get a singleton variable warning while compiling .....
can anyone help me please........
A "singleton" variable is very similar, in other languages, to the warning, "Variable was assigned a value that is never used" or "A variable has been declared but never used". So your clause must do something with N in your first doit clause. You can also avoid the doit(6) :- abort. clause by allowing your menu to succeed without any choice points using a cut (!).
So, try:
menu :- repeat,
write(' '),nl,
write(' 1.the number of hello '),nl,
write(' '),nl,
write('enter your choice:'),nl,
read(Choice), Choice>0, Choice =<6,
doit(Choice), Choice=6, !.
doit(1):-
numberofhello(N),
write('Number of hello is = '), write(N), nl.
% Removed doit(6)...
...

Resources