fight :-
	dice(3,DiceList),
	setBuffer(DiceList),
	fightStart.


fightStart :- 
	currentPlayer(PlayerID),
	taoist(PlayerID,_,_,_,_,Pos),
	neighbourDirect(Pos,[]),
	broadcastNoGhost.
	
fightStart :-
	currentPlayer(PlayerID),
	taoist(PlayerID,_,_,_,_,Pos),
	neighbourDirect(Pos,FieldList),
	not(FieldList = []),
	playerGhostSelect(FieldList).
	
fight(Pos) :-
	% get ghost to defeat
	fightRange(Pos,Resistance,Action),
	% dice allowed
	not(Action = noDice),
	buffer([WhiteDice|DiceList]),
	setBuffer([WhiteDice,DiceList,Pos]),
	% Subtract PrayerTao from resistance
	addPrayer(Resistance,ResPos),
	% Calculate ghost resistance left over
	vectorSub(ResPos,DiceList,ResList),      
	balance(Pos,WhiteDice,ResList).

fight(Pos) :-
	fightRange(Pos,Resistance,noDice),
	buffer([WhiteDice|DiceList]),
	setBuffer([WhiteDice,DiceList,Pos]),
	addPrayer(Resistance,RestList),
	balance(Pos,0,RestList).

fight(WhiteDiceLeft,TaoMarkersLeft) :-
	% Check if ghost is in range
	buffer([_,DiceList,Pos]),
	fightRange(Pos,Resistance,Action),
	
	% check if user input is valid
	currentPlayer(PlayerID),
	taoist(PlayerID,_,TaoMarkers,_,_,_),
	buffer([WhiteDice,_,_]),
	vectorGE(TaoMarkers,TaoMarkersLeft),
	WhiteDice >= WhiteDiceLeft,
	WhiteDiceLeft >= 0,
	vectorSub(TaoMarkers,TaoMarkersLeft,TaoMarkersUsed),
	WhiteDiceUsed is WhiteDice - WhiteDiceLeft,
	
	% calculate resistance
	fightCalRes(Action,Resistance,DiceList,TaoMarkersUsed,WhiteDiceUsed,NewDice),
	
	% save markers and dice and delete ghost
	setTaoMarkers(TaoMarkersLeft),
	setBuffer([WhiteDiceLeft|NewDice]),
	deleteGhost(Pos),
	fightStart.
		
fightRange(Pos,Resistance,Action) :-
	currentPlayer(PlayerID),
	taoist(PlayerID,_,_,_,_,TaoPos),
	neighbourDirect(TaoPos,FieldList),
	member(Pos,FieldList),
	ghostField(Pos,GhostID,_),
	ghost(GhostID,_,_,Resistance,_,Action,_,_),
	wuFengTest(GhostID).  

fightCalRes(Action,Resistance,DiceList,TaoMarkersUsed,WhiteDiceUsed,NewDice) :-
	not(Action = noDice),
	prayer(Prayer),
	vectorSub(Resistance,Prayer,ResPrayer),
	vectorSub(ResPrayer,DiceList,ResDicePrayer),
	diceLeft(ResDicePrayer,NewDice),
	vectorSub(ResDicePrayer,TaoMarkersUsed,ResTaoDicePrayer),
	sublist(greater0,ResTaoDicePrayer,ResLeft),
	sumlist(ResLeft,ResSum),
	ResSum =< WhiteDiceUsed.

fightCalRes(noDice,Resistance,DiceList,TaoMarkersUsed,WhiteDiceUsed,DiceList) :-
	prayer(Prayer),
	vectorSub(Resistance,Prayer,ResPrayer),
	vectorSub(ResPrayer,TaoMarkersUsed,ResTaoPrayer),
	sublist(greater0,ResTaoPrayer,ResLeft),
	sumlist(ResLeft,ResSum),
	ResSum =< WhiteDiceUsed.

addPrayer(Resistance,ResPos) :-
	prayer(PrayerList),
	addPrayer(Resistance,PrayerList,ResPos).

addPrayer([],[],[]).
addPrayer([0|R1],[_|R2],[0|R3]) :-
	!,
	addPrayer(R1,R2,R3).
addPrayer([A|R1],[P|R2],[C|R3]) :-
	C is A - P,
	addPrayer(R1,R2,R3).

% Defeat ghost without additional ressources
balance(Pos,_,List) :-
	sublist(greater0,List,[]),
	!,
	deleteGhost(Pos),
	diceLeft(List,DiceLeft),
	buffer([WhiteDice,_,_]),
	setBuffer([WhiteDice|DiceLeft]),
	fightStart.

% Can not defeat ghost while tao markers are locked
balance(_,WhiteDice,List) :-
	%get all GhostIDs where special ability is "lockTao"
	findall(GhostID,
		(   ghostField(_,GhostID,_),
		    ghost(GhostID,_,_,_,lockTao,_,_,_)),
		L),
	%if there are not no Ghosts -> there a ghosts with that ability
	not(L = []),
	sublist(greater0,List,ListPos),
	sumlist(ListPos,Sum),
	Sum > WhiteDice,
	broadcastUndefeatable,
	!,
	fightStart.	

% Can not defeat ghost even with additional ressources
balance(_,WhiteDice,List) :- 
	%get the current Players Taomarkers
	currentPlayer(PlayerID),
	taoist(PlayerID,_,TaoMarkers,_,_,_),
	%subtract the TaoMarkerList from the given InputList
	vectorSub(List,TaoMarkers,Result),
	%get all Positions where the resulting taos are greater than 0
	sublist(greater0,Result,ListPos),
	%add all resulting elements to Sum
	sumlist(ListPos,Sum),
	%if the Amount of Sum is greater than the Amount of WhiteDice
	Sum > WhiteDice,
	%broadcast undefeatable
	broadcastUndefeatable,
	!,
	fightStart.

% Defeat ghost with additional ressources
balance(FieldID,WhiteDice,List) :-
	currentPlayer(PlayerID),
	taoist(PlayerID,_,TaoMarkers,_,_,_),
	ghostField(FieldID,GhostID,_),
	normRes(List,Resistance),
	playerChooseMarkers(Resistance,WhiteDice,TaoMarkers,GhostID).

deleteGhost(Pos) :-
	ghostField(Pos,GhostID,_),
	ghost(GhostID,_,_,_,_,haunt,Action,_),	
	ghostDo(GhostID,Action),
	retract(ghostField(Pos,GhostID,Color)),
	assert(ghostField(Pos,0,Color)),
	retract(haunter(Pos,_)),
	broadcastDeleteHaunter(Pos),
	broadcastDeleteGhost(Pos).
deleteGhost(Pos) :-
	ghostField(Pos,GhostID,_),
	ghost(GhostID,_,_,_,_,RoundAction,Action,_),		
	not(RoundAction = haunt),
	ghostDo(GhostID,Action),
	retract(ghostField(Pos,GhostID,Color)),
	assert(ghostField(Pos,0,Color)),
	broadcastDeleteGhost(Pos).

% Wu Feng Howling Nightmare
wuFengTest(56) :-
	ghostField((Start,Add),56,_),
	StartN is Start + Add + Add,
	AddN is -Add,
	ghostField((StartN,AddN),0,_).

% Uncatchable
wuFengTest(57) :-
	uncatchable(catched).

% Everyone else
wuFengTest(GhostID) :-
	not(GhostID = 56),
	not(GhostID = 57).	

diceLeft([],[]).
diceLeft([A|R1],[AN|R2]) :-
	A < 0,
	AN is -A,
	diceLeft(R1,R2).

diceLeft([A|R1],[AN|R2]) :-
	A >= 0,
	AN is 0,
	diceLeft(R1,R2).

normRes([],[]).

normRes([A|R1],[0|R2]) :-
	A < 0,
	!,
        normRes(R1,R2).

normRes([A|R1],[A|R2]) :-
	normRes(R1,R2).	

/**
 @descr Returns true if all elements in both lists are greater or equal 0 and
 each element in list A is greater or equal the element in list B at the same position.
 @form vectorGE(ListA,ListB)
 */
vectorGE([],[]).
vectorGE([A|R1],[B|R2]) :-
	A >= 0,
	B >= 0,
	A >= B,
	vectorGE(R1,R2).
	
vectorSub([],[],[]).
vectorSub([A|R1],[B|R2],[C|R3]) :-
	C is A - B,
	vectorSub(R1,R2,R3).

/**
	@descr Adds two vectors and returns the result.
        @form  vectoradd(Vector1, Vector2, Sum)
*/
vectoradd([],[],[]).
vectoradd([A|R1],[B|R2],[C|R3]):-
	C is A+B,
	vectoradd(R1,R2,R3).

/*
	@descr Returns the inverse vector (addition)
	@form  vectorinvers(Vector,Inverse Vector)
*/
vectorinvers([],[]).
vectorinvers([A|R1],[B|R2]):-
	B is A * (-1),
	vectorinvers(R1,R2).

/**
 @descr Takes a List of same size Vectors and returns the sum as a new vector.
 @form  vectorlistadd(List of vectors, Result).
*/
vectorlistadd([A],A).
vectorlistadd([A|R],D):-
	R=[B|R2],
	vectoradd(A,B,C),
	vectorlistadd([C|R2],D).


/**
   @descr If the Ghost can be defeated without using the white dices and
	  and without taomarkers.
   @form  defeat(Result of the Dices incl. white dices, ID of ghost)
   
*/
defeat([_|Dices], GhostID):-
	ghost(GhostID,_,_,Resistance,_,_,_,_),
	vectorinvers(Dices,InvDices),
	vectoradd(InvDices,Resistance,Dif),
	sublist(greater0,Dif,[]).

/**
	@descr Returns true if the entered number is greater than 0.
        @form(Number)
*/
greater0(X):-X>0.













