Delphi does not have an ternary operator, but with templates we can do something similar:
TBool<T> = class
public
class function IFF(aCondition: boolean; aTrue, aFalse: T): T; inline;
end;
{ TBool<T> }
class function TBool<T>.IFF(aCondition: boolean; aTrue, aFalse: T): T;
begin
if aCondition then
Exit(aTrue)
else
Exit(aFalse);
end;
I use it in ChessKISS (just for fun) in this way:
//Null moves
mate := False;
if (FUseNullMove and FAllowNullMove) and (CurrentCheck = checkNo) and (CurrentStage <> sPawnEnding) then
begin
R := TBool<integer>.IFF(aDepth > 6, 3, 2);
Switch;
FAllowNullMove := False; //do not use recursive null moves
CurrentScore := -AlphaBeta(-aBeta, -aBeta + 1, aDepth - R);
FAllowNullMove := True;
Switch;
if CurrentScore >= aBeta then
begin
FCache.Add(FBoard.GetBoardHash(FSide), NO_MOVE, aDepth, CurrentScore, htBeta);
Exit(aBeta); //Cutoff!
end else
if (CurrentScore <= -PieceValues[ptKing]) and (FMateExtension) then
mate := True;
end;
The main problem with that is that both expressions are evaluated before the call is make, which it should not be a problem I we know that, but avoid expensive calls like:
TBool<boolean>IFF(i > 3, ExpensiveTrue(), ExpensiveFalse())
Since it will call both functions, both functions will be evaluated. This another example that can even be worse:
TBool<integer>IFF(list <> nil, list.Count, 'null')
If the list is null then Houston we have a problem since it will anyway evaluate List.Count.
No comments:
Post a Comment