Computer Chess Club Archives


Search

Terms

Messages

Subject: Re: Yet Another Null move question...

Author: Dann Corbit

Date: 00:39:59 12/22/00

Go up one level in this thread


On December 22, 2000 at 03:11:32, David Rasmussen wrote:

>On December 21, 2000 at 21:45:52, Robert Hyatt wrote:
>
>>On December 21, 2000 at 21:29:02, Dann Corbit wrote:
>>
>>>Has anyone tried this:
>>>
>>>Exhaustive search (NO Null move pruning) out to some arbitrary ply from the root
>>>{e.g. ply 5} and then increasingly aggressive Null move pruning forward from
>>>there [perhaps with a linear increase in aggressiveness out to some level]
>>>?
>>
>>
>>I do something similar.  In endgames where there is less than a queen, but
>>one side still has pieces, I don't do null move for the first N plies of
>>the search.
>>
>
>I can't see that anywhere in your code. Help! :)

See:
DATA.C (    404): int null_min = 3 * INCPLY;      /* R=2 */
DATA.C (    405): int null_max = 4 * INCPLY;      /* R=3 */

HASH.C (     42):   register int type, draft, avoid_null = 0, val;
HASH.C (     84):             depth - NULL_MOVE_DEPTH - INCPLY <= draft &&
HASH.C (     86):           avoid_null = AVOID_NULL_MOVE;
HASH.C (    137):           depth - NULL_MOVE_DEPTH - INCPLY <= draft &&
HASH.C (    139):         avoid_null = AVOID_NULL_MOVE;
HASH.C (    141):         return (avoid_null);
HASH.C (    161):           return (avoid_null);
HASH.C (    168):           return (avoid_null);
HASH.C (    171):   return (avoid_null);

 OPTION.C (   3821):    |   "selective" command sets the mininum and maximum
 OPTION.C (   3834):           null_min = (atoi (args[1]) + 1) * INCPLY;
 OPTION.C (   3835):           null_max = (atoi (args[2]) + 1) * INCPLY;
 OPTION.C (   3837):       Print (4095, "null depth set to %d/%d (min/max)\n"
 OPTION.C (   3838):              null_min / INCPLY - 1, null_max / INCPLY -
 OUTPUT.C (     31):    check for null_move first
 OUTPUT.C (     35):       strcpy (text, "null");

but especially here in search.c:

/*
   ----------------------------------------------------------
   |                                                          |
   |  first, we try a null move to see if we can get a quick  |
   |  cutoff with only a little work.  this operates as       |
   |  follows.  instead of making a legal move, the side on   |
   |  move 'passes' and does nothing.  the resulting position |
   |  is searched to a shallower depth than normal (usually   |
   |  one ply less but settable by the operator) this should  |
   |  result in a cutoff or at least should set the lower     |
   |  bound better since anything should be better than not   |
   |  doing anything.                                         |
   |                                                          |
   |  this is skipped for any of the following reasons:       |
   |                                                          |
   |  1.  the side on move is in check.  the null move        |
   |      results in an illegal position.                     |
   |  2.  no more than one null move can appear in succession |
   |      or else the search will degenerate into nothing.    |
   |  3.  the side on move has little material left making    |
   |      zugzwang positions more likely.                     |
   |                                                          |
   |  the null-move search is also used to detect certain     |
   |  types of threats.  the original idea of using the value |
   |  returned by the null-move search was reported by C.     |
   |  Donninger, but was modified by Bruce Moreland (Ferret)  |
   |  in the following way:  if the null-move search returns  |
   |  a score that says "mated in N" then this position is a  |
   |  dangerous one, because not moving gets the side to move |
   |  mated.  we extend the search one ply in this case, al-  |
   |  though, as always, no more than one ply of extensions   |
   |  are allowed at any one level in the tree.  note also    |
   |  that this "threat" condition is hashed so that later,   |
   |  if the hash table says "don't try the null move because |
   |  it likely will fail low, we still know that this is a   |
   |  threat position and that it should be extended.         |
   |                                                          |
   ----------------------------------------------------------
 */
#if defined(NULL_MOVE_DEPTH)
  pieces = (wtm) ? TotalWhitePieces : TotalBlackPieces;
  if (do_null && !tree->in_check[ply] && pieces && (pieces > 5 || depth < 421))
    {
      register BITBOARD save_hash_key;
      int null_depth;
      tree->current_move[ply] = 0;
      tree->phase[ply] = NULL_MOVE;
#if defined(TRACE)
      if (ply <= trace_level)
	SearchTrace (tree, ply, depth, wtm, beta - 1, beta, "Search", 0);
#endif
      tree->position[ply + 1] = tree->position[ply];
      Rule50Moves (ply + 1)++;
      save_hash_key = HashKey;
      if (EnPassant (ply))
	{
	  HashEP (EnPassant (ply + 1), HashKey);
	  EnPassant (ply + 1) = 0;
	}
      null_depth = (depth > 6 * INCPLY) ? null_max : null_min;
      if (depth - null_depth >= INCPLY)
	value = -Search (tree, -beta, 1 - beta, ChangeSide (wtm),
			 depth - null_depth, ply + 1, NO_NULL);
      else
	value = -Quiesce (tree, -beta, 1 - beta, ChangeSide (wtm), ply + 1);
      HashKey = save_hash_key;
      if (abort_search || tree->stop)
	return (0);
      if (value >= beta)
	{
	  HashStore (tree, ply, depth, wtm, LOWER, value, threat);
	  return (value);
	}
      if (value == -MATE + ply + 2)
	threat = 1;
    }
#endif



>>I also do a graduated null-move search, where R=3 for positions near the root,
>>and R=2 for positions near the leaf positions.  I think doing the inverse is
>>wrong, as you will hide too much by letting null-move collapse the last few
>>plies into a simple quiescence search...
>
>This I can see.



This page took 0 seconds to execute

Last modified: Thu, 15 Apr 21 08:11:13 -0700

Current Computer Chess Club Forums at Talkchess. This site by Sean Mintz.