Skip to content

Instantly share code, notes, and snippets.

@Joelbyte
Created March 20, 2011 11:25
Show Gist options
  • Save Joelbyte/878277 to your computer and use it in GitHub Desktop.
Save Joelbyte/878277 to your computer and use it in GitHub Desktop.
Bacchus-Bosch - Part 3
:- object(property).
:- info([
version is 1.0,
author is 'Victor Lagerkvist',
date is 2011/03/19,
comment is 'A property constitutes the basic behaviours of the objects in Bacchus-Bosch.']).
:- public(update/2).
:- mode(update(+entity, -entity), zero_or_more).
:- info(update/2, [
comment is 'Update the entity to which the property belong.',
argnames is ['Entity', 'Entity1']]).
:- public(action/6).
:- mode(action(+atom, +list, +entity, +state, -state, -entity), zero_or_more).
:- info(action/6, [
comment is 'Execute the action Name with respects to Args, State and Entity, and store the resulting new state and entity in State1 and Entity1.',
argnames is ['Name', 'Args', 'Entity', 'State', 'Entity1', 'State1']]).
:- public(new/1).
:- mode(new(-term), zero_or_more).
:- info(new/1, [
comment is 'Unify State with the initial state of the property.',
argnames is ['State']]).
%% Basic definition: do nothing!
update(E, E).
%% Basic definition, overloaded in almost every subclass.
new(void).
:- end_object.
:- object(container_property,
extends(property)).
new([]).
update(E0, E) :-
entity::select_property(container_property-Items, E0, E1),
update_children(Items, Items1),
E = [container_property-Items1|E1].
update_children([], []).
update_children([E|Es], [E1|E1s]) :-
entity::update(E, E1),
update_children(Es, E1s).
action(add_item, [E], Owner, Items, Owner, [E|Items]).
action(remove_item, [E], Owner, Items, Owner, Items1) :-
list::select(E, Items, Items1).
action(print_children, Args, Owner, Items, Owner, Items) :-
meta::include([E] >>
(entity::action(print, Args, E, _)),
Items,
_).
:- end_object.
:- object(inventory_property,
extends(container_property)).
valid_item(E) :-
entity::get_property(E, carriable_property-_).
action(add_item, [E], Owner, Items, Owner, [E|Items]) :-
valid_item(E).
action(drop_item, [E], Owner, Items, Owner, Items1) :-
valid_item(E),
list::select(E, Items, Items1).
:- end_object.
:- object(carriable_property,
extends(property)).
%% Perhaps not the most interesting property in the game.
:- end_object.
:- object(health_property,
extends(property)).
new(10).
action(decrease_health, [], Owner, H0, Owner, H) :-
H is H0 - 1.
action(increase_health, [], Owner, H0, Owner, H) :-
H is H0 + 1.
:- end_object.
:- object(key_property,
extends(property)).
%% The default key.
new(key).
:- end_object.
:- object(lock_property,
extends(property)).
%% The (default) key that opens the lock.
new(key).
valid_key(E, Key) :-
entity::get_property(E, key_property-Key).
action(lock, [Entity], Owner, Key, Owner, Key) :-
valid_key(Entity, Key).
action(unlock, [Entity], Owner, Key, Owner, Key) :-
valid_key(Entity, Key).
:- end_object.
:- object(openable_property,
extends(property)).
new(closed-[lock_property- Lock]) :- lock_property::new(Lock).
action(open, Key, Owner, closed-Lock, Owner, open-Lock) :-
entity::action(unlock, Key, Lock, _).
action(close, [], Owner, _-Lock, Owner, closed-Lock).
:- end_object.
:- object(on_fire_property,
extends(property)).
update(E0, E) :-
entity::action(decrease_health, [], E0, E).
:- end_object.
:- object(printable_property,
extends(property)).
new(Description) :-
is_list(Description).
action(print, [], Owner, Description, Owner, Description) :-
format(Description).
:- end_object.
:- object(eat_property,
extends(property)).
action(eat, [E, E1], Owner, void, Owner1, void) :-
entity::action(dissolve, [Owner, Owner1], E, E1).
:- end_object.
:- object(fruit_property,
extends(property)).
action(dissolve, [E, E1], _, void, [], void) :-
entity::action(increase_health, [], E, E1).
:- end_object.
:- object(entity).
:- info([
version is 1.0,
author is 'Victor Lagerkvist',
date is 2011/03/18,
comment is 'The entity operations of Bacchus-Bosch.']).
:- public(update/2).
:- public(action/4).
:- public(get_property/2).
:- public(select_property/3).
update(E0, E) :-
update(E0, E0, E).
update(E, [], E).
update(E0, [P|Ps], E) :-
P = Name - _,
Name::update(E0, E1),
update(E1, Ps, E).
action(A, Args, E0, E) :-
%% Select a property from the list such that the action A can
%% be performed with the arguments Args.
list::select(P, E0, E1),
P = PropertyName - State,
PropertyName::action(A, Args, E1, State, E2, State1),
%% Add the property with the updated state to E2.
P1 = PropertyName - State1,
E = [P1|E2].
get_property(E, P) :-
list::member(P, E).
select_property(P, E, E1) :-
list::select(P, E, E1).
:- end_object.
:- object(game).
:- info([
version is 1.0,
author is 'Victor Lagerkvist',
date is 2011/03/20,
comment is 'The core functionality of Bacchus-Bosch.']).
:- public(init1/0).
room_description("A rather unremarkable room.\n").
door_description("A wooden door with a small and rusty lock.\n").
key_description("A slightly bent key.\n").
build_test_door(Door) :-
Door = [openable_property-State1, printable_property-State2],
openable_property::new(State1),
door_description(State2).
build_test_key(Key) :-
Key = [key_property-State1, printable_property-State2],
key_property::new(State1),
key_description(State2).
build_test_player(Player) :-
Player = [inventory_property-State1, health_property-State2],
inventory_property::new(State1),
health_property::new(State2).
build_test_room(Room) :-
build_test_door(Door),
build_test_player(Player),
build_test_key(Key),
Room0 = [container_property - State1, printable_property - State2],
container_property::new(State1),
room_description(State2),
entity::action(add_item, [Door], Room0, Room1),
entity::action(add_item, [Player], Room1, Room2),
entity::action(add_item, [Key], Room2, Room).
init1 :-
write('Welcome to Bacchus-Bosch!'), nl,
build_test_room(Room),
entity::action(print, [], Room, Room1),
write('You see: '), nl,
entity::action(print_children, [], Room1, _Room).
init2 :-
write('Welcome to Bacchus-Bosch!'), nl,
write('Attempting to create some properties and entities...'), nl,
health_property::new(HP),
on_fire_property::new(FP),
Ps = [health_property-HP, on_fire_property-FP],
Ps1 = [health_property, on_fire_property],
E = Ps,
entity::update(E, E1),
write(E1), nl,
entity::update(E1, E2),
write(E2), nl,
write('Creating a door...'), nl,
Door = [openable_property - NewState],
openable_property::new(NewState),
write(Door), nl,
write('Creating a key...'), nl,
Key = [key_property - KeyState],
key_property::new(KeyState),
write(Key), nl,
write('Opening door...'), nl,
entity::action(open, [Key], Door, Door1),
write(Door1), nl,
write('Closing door...'), nl,
entity::action(close, [], Door1, Door2),
write(Door2), nl.
:- end_object.
:- initialization((
logtalk_load(library(metapredicates_loader)),
logtalk_load(library(types_loader)),
logtalk_load(entity),
logtalk_load(game),
game::init1)).
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment