Code: Select all
/* mate-distance pruning */
alpha = MAX(alpha, -MATE + ply);
beta = MIN(beta, MATE - ply - 1);
if (alpha >= beta)
return alpha;
Moderators: hgm, Rebel, chrisw
Code: Select all
/* mate-distance pruning */
alpha = MAX(alpha, -MATE + ply);
beta = MIN(beta, MATE - ply - 1);
if (alpha >= beta)
return alpha;
Sorry, I don't understand that code, could you please explain it? "alpha -= (alpha < -MATE+100);" means you subtract the value of a boolean expression from alpha, i.e. you subtract either 0 or 1? Is that the intent? I would not think so in the first place.hgm wrote:Code: Select all
#define MATE 10000 Search(alpha, beta, depth) { int bestScore = dept >0 ? -MATE : Evaluate(); alpha -= (alpha < -MATE+100); beta -= (beta <= -MATE+100); if(bestScore >= beta) goto cutoff; // stand pat // rest of alpha-beta search routine ... cutoff: bestScore += (bestScore < -MATE+100); return bestScore; }
That's almost 100% identical to my code. For PV nodes:Zach Wegner wrote:check the second post Here's a recursionified version:
Code: Select all
/* mate-distance pruning */ alpha = MAX(alpha, -MATE + ply); beta = MIN(beta, MATE - ply - 1); if (alpha >= beta) return alpha;
Code: Select all
alpha = Max(value_mated_in(ply), alpha);
beta = Min(value_mate_in(ply+1), beta);
if(alpha >= beta)
return alpha;
Code: Select all
if(value_mated_in(ply) >= beta)
return beta;
if(value_mate_in(ply+1) < beta)
return beta-1;
Indeed, they are semantically identical. Mine of course has the search block pointer (as in the second post in the thread). This is the way that makes most sense to me, Fruit's is rather confusing IMO. I've wanted to add mate_in macros, I might not anymore now that I see you have them.Tord Romstad wrote:That's almost 100% identical to my code. For PV nodes:Zach Wegner wrote:check the second post Here's a recursionified version:
Code: Select all
/* mate-distance pruning */ alpha = MAX(alpha, -MATE + ply); beta = MIN(beta, MATE - ply - 1); if (alpha >= beta) return alpha;
For non-PV nodes:Code: Select all
alpha = Max(value_mated_in(ply), alpha); beta = Min(value_mate_in(ply+1), beta); if(alpha >= beta) return alpha;
TordCode: Select all
if(value_mated_in(ply) >= beta) return beta; if(value_mate_in(ply+1) < beta) return beta-1;
What? Am I so unpopular that something automatically becomes bad programming style just because I use it?Zach Wegner wrote: I've wanted to add mate_in macros, I might not anymore now that I see you have them.
Code: Select all
#ifndef IncludeScore
#define IncludeScore
#define ScoringScale 1000000 // Micropawn units
#define ScoringRangeLen BX(30)
#define MateMarginLen BX(10)
#define MateDistanceLen BX(13)
#define SVBroken ((est) (0 - ScoringRangeLen))
#define SVPosInf ((est) (ScoringRangeLen - 1))
#define SVNegInf ((est) (1 - ScoringRangeLen))
#define SVEven ((est) 0)
#define SVMateIn1 ((est) (SVPosInf - MateMarginLen - 1))
#define SVLoseIn0 ((est) (SVNegInf + MateMarginLen))
#define SVCheckmated SVLoseIn0
#define BrokenScore Score(SVBroken)
#define PosInfScore Score(SVPosInf)
#define NegInfScore Score(SVNegInf)
#define EvenScore Score(SVEven)
#define MateIn1Score Score(SVMateIn1)
#define LoseIn0Score Score(SVLoseIn0)
#define CheckmatedScore LoseIn0Score
#define SVLongMate ((est) (SVMateIn1 - MateDistanceLen + 1))
#define SVLongLose ((est) (SVLoseIn0 + MateDistanceLen))
class Score
{
public:
Score(void) {}
Score(const est es) {sv = es;}
~Score(void) {}
est GetSV(void) const {return sv;}
void PutSV(const est es) {sv = es;}
void SynthMateInN(const ui n) {sv = SVMateIn1 - n + 1;}
void SynthLoseInN(const ui n) {sv = SVLoseIn0 + n;}
bool IsBroken(void) const {return sv == SVBroken;}
bool IsPosInf(void) const {return sv == SVPosInf;}
bool IsNegInf(void) const {return sv == SVNegInf;}
bool IsEven(void) const {return sv == SVEven;}
bool IsInfinite(void) const {return IsPosInf() || IsNegInf();}
bool IsSpecial(void) const {return IsBroken() || IsInfinite();}
bool IsMating(void) const {return !IsBroken() && (sv >= SVLongMate);}
bool IsLosing(void) const {return !IsBroken() && (sv <= SVLongLose);}
bool IsMateOrLose(void) const {return IsMating() || IsLosing();}
bool IsMateIn1(void) const {return sv == SVMateIn1;}
bool IsLoseIn0(void) const {return sv == SVLoseIn0;}
bool IsInRange(void) const {return (sv > SVLongLose) && (sv < SVLongMate);}
bool IsPositive(void) const {return sv > 0;}
bool IsNegative(void) const {return sv < 0;}
ui FullMoveMatingDistance(void) const {return SVMateIn1 - sv + 1;}
ui FullMoveLosingDistance(void) const {return sv - SVLoseIn0;}
void UpShift(void);
void DownShift(void);
std::string FmtScore(void) const;
private:
est sv; // Signed integral score value
};
inline void Score::UpShift(void)
{
if (!IsBroken())
{
if (IsInRange()) sv = -sv;
else
{
if (IsInfinite())
{
if (IsPosInf()) sv = SVNegInf; else sv = SVPosInf;
}
else
{
if (IsMating())
SynthLoseInN(FullMoveMatingDistance());
else
SynthMateInN(FullMoveLosingDistance() + 1);
};
}
};
}
inline void Score::DownShift(void)
{
if (!IsBroken())
{
if (IsInRange()) sv = -sv;
else
{
if (IsInfinite())
{
if (IsPosInf()) sv = SVNegInf; else sv = SVPosInf;
}
else
{
if (IsMating())
SynthLoseInN(FullMoveMatingDistance() - 1);
else
SynthMateInN(FullMoveLosingDistance());
};
}
};
}
class Window
{
public:
Window(void) {}
Window(const Score lowerscore, const Score upperscore) {alfa = lowerscore; beta = upperscore;}
~Window(void) {}
Score GetAlfa(void) const {return alfa;}
void PutAlfa(const Score score) {alfa = score;}
Score GetBeta(void) const {return beta;}
void PutBeta(const Score score) {beta = score;}
void SetFullWidth(void) {alfa.PutSV(SVNegInf); beta.PutSV(SVPosInf);}
void DownShift(void);
bool IsFailLow(const Score score) const {return score.GetSV() <= alfa.GetSV();}
bool IsFailHigh(const Score score) const {return score.GetSV() >= beta.GetSV();}
bool IsInside(const Score score) const {return !IsFailLow(score) && !IsFailHigh(score);}
bool IsCutoff(void) const {return alfa.GetSV() >= beta.GetSV();}
std::string FmtWindow(void) const;
private:
Score alfa; // Lower bound score
Score beta; // Upper bound score
};
#endif
Code: Select all
#include <iomanip>
#include <sstream>
#include <string>
#include "Definitions.h"
#include "Score.h"
std::string Score::FmtScore(void) const
{
std::ostringstream oss;
if (IsSpecial())
{
if (IsBroken()) oss << "Broken";
else
{
if (IsPosInf()) oss << "PosInf"; else oss << "NegInf";
};
}
else
{
if (IsMateOrLose())
{
if (IsMating()) oss << "MateIn" << FullMoveMatingDistance();
else
{
if (IsLoseIn0())
oss << "Checkmated";
else
oss << "LoseIn" << FullMoveLosingDistance();
};
}
else
{
if (IsEven()) oss << "Even";
else
{
est alt;
if (IsPositive()) {alt = sv; oss << '+';} else {alt = -sv; oss << '-';};
oss <<
(alt / ScoringScale) << '.' <<
std::setw(3) << std::setfill('0') << ((alt % ScoringScale) / 1000) << std::setfill(' ');
};
};
};
return oss.str();
}
void Window::DownShift(void)
{
Window aux(*this);
alfa = aux.GetBeta(); alfa.DownShift(); beta = aux.GetAlfa(); beta.DownShift();
}
std::string Window::FmtWindow(void) const
{
std::ostringstream oss;
oss << '[' << alfa.FmtScore() << ':' << beta.FmtScore() << ']';
return oss.str();
}