
:-object dogworld : [bcilib].


var url = './dog/dogworld.wrl'.

main :-
	text_area(Browser),
	set_output(Browser),

	format('Load the game ...~n'),
	loadURL(url),
	Clock := new(game_clock),
      _Pulse := new(game_clock_pulse(Clock)),
      Clock <- get_game_time(TimeLeft),
	format('the game will start in 5 seconds,~n'),
	format('the total playing time is ~w seconds,~n', [TimeLeft]),
      sleep(5000),
	format('the game startup,~n'),
	_dog1 := new(dog(dog1, Clock)),
	_dog2 := new(dog(dog2, Clock)),
	_dog3 := new(dog(dog3, Clock)),
	_dog4 := new(dog(dog4, Clock)),
	_dog5 := new(dog(dog5, Clock)),
	_dog6 := new(dog(dog6, Clock)),
	_dog7 := new(dog(dog7, Clock)),
	_dog8 := new(dog(dog8, Clock)),
	_dog9 := new(dog(dog9, Clock)),
	_dog10:= new(dog(dog10, Clock)).


:-end_object dogworld.

:-object game_clock.

	var time_left = 5000.

	get_game_time(Time) :-
		Time := time_left.
	set_game_time(Time) :-
		time_left := Time.

:-end_object game_clock.


:-object game_clock_pulse.

	game_clock_pulse(Clock) :-
		repeat,
			sleep(1000),
			Clock <- get_game_time(Time),

			Left is Time - 1,
			Clock <- set_game_time(Left),
		Left < 1,
		!.

:-end_object game_clock_pulse.




:-object dog : [bcilib].

var sleeptime = 250.
var small_movement = 0.20.
var big_movement = 0.40.
var enlargement = 5.
var max_distance = 40.

dog(Dog, Clock) :-
	setSFInt32(Dog,whichChoice, 0),
	format('~w thread active.~n', [Dog]),
	activity(Dog,Clock).

activity(Dog,Clock) :-
	repeat,
		sleep(500),
		Clock <- get_game_time(TimeLeft),
%		format('player ~w  thread ~w seconds left~n', [Name,TimeLeft]),
		getInformation(Dog, DogPosition, MasterPosition1,MasterRotation1, MasterPosition2, MasterRotation2),
		findHowtoReact(Dog,DogPosition,MasterPosition1, MasterRotation1, MasterPosition2, MasterRotation2, Action),
		nonvar(Action),
		format('player ~w action: ~w~n',[Dog,Action]),
		doAction(Dog,DogPosition,MasterPosition1,MasterRotation1,MasterPosition2, MasterRotation2,Action),
	TimeLeft < 1,
%	quitGame(Dog),
	!.

getInformation(Dog,position(X,Y,Z),position(X1,Y1,Z1),rotation(X2,Y2,Z2,R2),position(X3,Y3,Z3),rotation(X4,Y4,Z4,R4)):-
	getSFVec3f(Dog,position,X,Y,Z),
	getSFVec3f(proxSensor,position,X1,Y1,Z1),
	getSFRotation(proxSensor,orientation,X2,Y2,Z2,R2),
	sleep(sleeptime),
	getSFVec3f(proxSensor,position,X3,Y3,Z3),
	getSFRotation(proxSensor,orientation,X4,Y4,Z4,R4).


findHowtoReact(_,position(X,_Y,Z),_,_,position(X3,_Y3,Z3),_,move_to_master):-
	distance2D(X,Z,X3,Z3,Dist),
	Dist > max_distance,
	!.

	
findHowtoReact(_,_,position(X1,_Y1,Z1),_,position(X3,_Y3,Z3),_,move_to_master):-
	distance2D(X1,Z1,X3,Z3,Dist),
	Dist < small_movement,
	!.

findHowtoReact(_,_,position(X1,_Y1,Z1),_,position(X3,_Y3,Z3),_,move_with_master):-
	distance2D(X1,Z1,X3,Z3, Dist),
	Dist > big_movement,
	!.

findHowtoReact(_,_,position(X1,_Y1,Z1),_,position(X3,_Y3,Z3),_,look_at_master):-
	distance2D(X1,Z1,X3,Z3,Dist),
	Dist < big_movement,
	Dist > small_movement,
	!.





findHowtoReact(_,_,_,_,_,_,look_at_master):-!.



bark(Dog,Time):- 
	setSFBool(Dog, bark, true),
	sleep(Time),
	setSFBool(Dog, bark, false).
		


doAction(Dog, position(X,_Y,Z),position(X1,_Y1,Z1),_,_,_,look_at_master):-
	look_at_position(Dog,X,Z,X1,Z1),
	bark(Dog,500).

doAction(Dog, position(X,Y,Z),position(X1,_Y1,Z1),_,_,_,move_to_master):-
	getSFInt32(Dog,id,ID),
	getFlockCenter(position(X2,_Y2,Z2), master_standing,[]),
	dFunction(ID, Xd,Zd),
	X3 is X2 + Xd,
	Z3 is Z2 + Zd,
	look_at_position(Dog,X,Z,X1,Z1),
	bark(Dog,500),	
	move_to_position(Dog,position(X,Y,Z),position(X3,Y,Z3),5),
	!.

doAction(Dog, position(X,Y,Z),position(X1,_Y1,Z1),_,
    position(X3,Y3,Z3),_,move_with_master):-
	Xdif is X3-X1,
	Zdif is Z3-Z1,
	getFlockCenter(position(X5,_Y5,Z5), master_moving, [position(X3,Y3,Z3),Xdif,Zdif]),
	getSFInt32(Dog,id,ID),
	dFunction(ID, Xd,Zd),
	X6 is X5 + Xd,
	Z6 is Z5 + Zd,
	look_at_position(Dog,X,Z,X6,Z6),	
	move_to_position(Dog,position(X,Y,Z),position(X6,Y,Z6),10),
	!.


look_at_position(O,X,Z,X1,Z1):-
	Xdif is X-X1,
	Zdif is Z1-Z,
	Xdif =\= 0.0,
	R is atan(Zdif/Xdif) - sign(Xdif)*1.57,
	setRotation(O, 0.0, 1.0, 0.0, R).

look_at_position(_,_,_,_,_):-!.

move_to_position(O,_,position(X,Y,Z),0):-
            setSFVec3f(O,position,X,Y,Z).

move_to_position(O, position(X1,Y1,Z1),position(X2,Y2,Z2),C):-
		C > 0,
		C1 is C-1,
		Xdif is X2 -X1,
		Zdif is Z2 -Z1,
		X is X1 + Xdif/C,
		Z is Z1 + Zdif/C,
		setSFVec3f(O,position,X,Y1,Z),
            sleep(500),
		move_to_position(O,position(X,Y1,Z),position(X2,Y2,Z2),C1).

getFlockCenter(position(X,Y,Z),master_standing, []):-
	getSFVec3f(proxSensor,position,X,Y,Z),
	!.

getFlockCenter(position(X,Y,Z),master_moving, [position(X1,Y,Z1), Xdif, Zdif]):-
	X is X1 + Xdif* enlargement,
	Z is Z1 + Zdif* enlargement,
	!.


dFunction(1,0,3):-!.
dFunction(2,-1,-2):-!.
dFunction(3,1,-7):-!.
dFunction(4,-2,3):-!.
dFunction(5,2,2):-!.
dFunction(6,-3,0):-!.
dFunction(7,3,-1):-!.
dFunction(8,-4,4):-!.
dFunction(9,5,-4):-!.
dFunction(10,5,-3):-!.



:-end_object dog.





