Beispiel #1
0
void list_filter(list_t * list, board_t * board, move_test_t test, bool keep) {

   int pos;
   int i, move, value;

   ASSERT(list!=NULL);
   ASSERT(board!=NULL);
   ASSERT(test!=NULL);
   ASSERT(keep==true||keep==false);

   pos = 0;

   for (i = 0; i < LIST_SIZE(list); i++) {

      ASSERT(pos>=0&&pos<=i);

      move = LIST_MOVE(list,i);
      value = LIST_VALUE(list,i);

      if ((*test)(move,board) == keep) {
         list->move[pos] = move;
         list->value[pos] = value;
         pos++;
      }
   }

   ASSERT(pos>=0&&pos<=LIST_SIZE(list));
   list->size = pos;

   // debug

   ASSERT(list_is_ok(list));
}
Beispiel #2
0
int search_full_root(list_t * list, board_t * board, int a, int b, int depth, int search_type, int ThreadId) {

   int value;

   ASSERT(list_is_ok(list));
   ASSERT(board_is_ok(board));
   ASSERT(depth_is_ok(depth));
   ASSERT(search_type==SearchNormal||search_type==SearchShort);

   ASSERT(list==SearchRoot[ThreadId]->list);
   ASSERT(!LIST_IS_EMPTY(list));
   ASSERT(board==SearchCurrent[ThreadId]->board);
   ASSERT(board_is_legal(board));
   ASSERT(depth>=1);

   value = full_root(list,board,a,b,depth,0,search_type, ThreadId);

   ASSERT(value_is_ok(value));
   ASSERT(LIST_VALUE(list,0)==value);

   return value;
}
int search_full_root(list_t * list, board_t * board, int depth, int search_type) {

   int value, a, b;

   ASSERT(list_is_ok(list));
   ASSERT(board_is_ok(board));
   ASSERT(depth_is_ok(depth));
   ASSERT(search_type==SearchNormal||search_type==SearchShort);

   ASSERT(list==SearchRoot->list);
   ASSERT(!LIST_IS_EMPTY(list));
   ASSERT(board==SearchCurrent->board);
   ASSERT(board_is_legal(board));
   ASSERT(depth>=1);

   if (SearchBest[SearchCurrent->multipv].value == 0){
	   a = -ValueInf;
	   b = +ValueInf;
   }
   else{
	   a = SearchBest[SearchCurrent->multipv].value - 40;
	   b = SearchBest[SearchCurrent->multipv].value + 40;
   }

   if (SearchInput->multipv > 0){
	   a = -ValueInf;
       b = +ValueInf;
   }

   value = full_root(list,board,a,b,depth,0,search_type);

   ASSERT(value_is_ok(value));
   ASSERT(LIST_VALUE(list,0)==value);

   return value;
}
Beispiel #4
0
void search() {

   int move;
   int depth;
   int i;
   bool search_ready;

     
   for (i = 0; i < MultiPVMax; i++){
	  save_multipv[SearchCurrent->multipv].mate = 0;
	  save_multipv[SearchCurrent->multipv].depth = 0;
	  save_multipv[SearchCurrent->multipv].max_depth = 0;
	  save_multipv[SearchCurrent->multipv].value = 0;
	  save_multipv[SearchCurrent->multipv].time = 0;
	  save_multipv[SearchCurrent->multipv].node_nb = 0;
	  strcpy(save_multipv[SearchCurrent->multipv].pv_string,""); 
   }
  
   SearchInput->multipv = option_get_int("MultiPV")-1;
   SearchCurrent->multipv = 0;
   
   
   ASSERT(board_is_ok(SearchInput->board));

   // opening book

   if (option_get_bool("OwnBook") && !SearchInput->infinite) {

      move = book_move(SearchInput->board);

      if (move != MoveNone) {

         // play book move

         SearchBest[SearchCurrent->multipv].move = move;
         SearchBest[SearchCurrent->multipv].value = 1;
         SearchBest[SearchCurrent->multipv].flags = SearchExact;
         SearchBest[SearchCurrent->multipv].depth = 1;
         SearchBest[SearchCurrent->multipv].pv[0] = move;
         SearchBest[SearchCurrent->multipv].pv[1] = MoveNone;

         search_update_best();

         return;
      }
   }

   // SearchInput

   gen_legal_moves(SearchInput->list,SearchInput->board);

   if (LIST_SIZE(SearchInput->list) < SearchInput->multipv+1){ 
	  SearchInput->multipv = LIST_SIZE(SearchInput->list)-1;
   }

   if (LIST_SIZE(SearchInput->list) <= 1) {
      SearchInput->depth_is_limited = true;
      SearchInput->depth_limit = 4; // was 1
   }

   // SearchInfo

   if (setjmp(SearchInfo->buf) != 0) {
      ASSERT(SearchInfo->can_stop);
      ASSERT(SearchBest->move!=MoveNone);
      search_update_current();
      return;
   }

   // SearchRoot

   list_copy(SearchRoot->list,SearchInput->list);

   // SearchCurrent

   board_copy(SearchCurrent->board,SearchInput->board);
   my_timer_reset(SearchCurrent->timer);
   my_timer_start(SearchCurrent->timer);

   // init

   trans_inc_date(Trans);

   sort_init();
   search_full_init(SearchRoot->list,SearchCurrent->board);

   // analyze game for evaluation
   
   if (SearchCurrent->board->piece_size[White] < 3 && SearchCurrent->board->piece_size[Black] < 3){
	   trans_endgame = true;
   }
   else{
	   trans_endgame = false;
   }

   
   // iterative deepening

   search_ready = false;

   for (depth = 1; depth < DepthMax; depth++) {
	   for (SearchCurrent->multipv = 0; SearchCurrent->multipv <= SearchInput->multipv; SearchCurrent->multipv++){

		  if (DispDepthStart && SearchCurrent->multipv == 0) send("info depth %d",depth);

		  SearchCurrent->max_extensions = depth * 10;
		  SearchRoot->bad_1 = false;
		  SearchRoot->change = false;

		  board_copy(SearchCurrent->board,SearchInput->board);

		  if (UseShortSearch && depth <= ShortSearchDepth) {
			 search_full_root(SearchRoot->list,SearchCurrent->board,depth,SearchShort);
		  } else {
			 search_full_root(SearchRoot->list,SearchCurrent->board,depth,SearchNormal);
		  }

		  search_update_current();

		  if (DispDepthEnd && SearchCurrent->multipv == SearchInput->multipv) {
			 send("info depth %d seldepth %d time %.0f nodes " S64_FORMAT " nps %.0f",depth,SearchCurrent->max_depth,SearchCurrent->time*1000.0,SearchCurrent->node_nb,SearchCurrent->speed);
		  }

		  // update search info

		  if (depth >= 1) SearchInfo->can_stop = true;

		  if (depth == 1
		   && LIST_SIZE(SearchRoot->list) >= 2
		   && LIST_VALUE(SearchRoot->list,0) >= LIST_VALUE(SearchRoot->list,1) + EasyThreshold) {
			 SearchRoot->easy = true;
		  }

		  if (depth > 1) {
			 SearchRoot->bad_2 = SearchRoot->bad_1;
			 SearchRoot->bad_1 = false;
			 ASSERT(SearchRoot->bad_2==(SearchBest->value<=SearchRoot->last_value-BadThreshold));
		  }

		  SearchRoot->last_value = SearchBest[SearchCurrent->multipv].value;

		  // stop search?

		  if (SearchInput->depth_is_limited && SearchCurrent->multipv >= SearchInput->multipv
		   && depth >= SearchInput->depth_limit) {
			 SearchRoot->flag = true;
		  }

		  if (SearchInput->time_is_limited
		   && SearchCurrent->time * 2 >= SearchInput->time_limit_1
		   && !SearchRoot->bad_2) {
			 SearchRoot->flag = true;
		  }

		  if (SearchInput->time_is_limited
		   && SearchCurrent->time >= SearchInput->time_limit_1 * EasyRatio
		   && SearchRoot->easy) {
			 ASSERT(!SearchRoot->bad_2);
			 ASSERT(!SearchRoot->change);
			 SearchRoot->flag = true;
		  }

		  if (SearchInput->time_is_limited
		   && SearchCurrent->time >= SearchInput->time_limit_1 * EarlyRatio
		   && !SearchRoot->bad_2
		   && !SearchRoot->change) {
			 SearchRoot->flag = true;
		  }

		  if (SearchInfo->can_stop 
		   && (SearchInfo->stop || (SearchRoot->flag && !SearchInput->infinite))) {
			  search_ready = true;
			  break;
		  }
	   }
	   if (search_ready)
		   break;
   }
}
Beispiel #5
0
VOID
ShDestroyShell (
    PSHELL Shell
    )

/*++

Routine Description:

    This routine destroys a new shell object.

Arguments:

    Shell - Supplies a pointer to the shell to destroy.

Return Value:

    None.

--*/

{

    PSHELL_HERE_DOCUMENT HereDocument;

    if (Shell->PostForkCloseDescriptor != -1) {
        close(Shell->PostForkCloseDescriptor);
    }

    if (Shell->Prompt != NULL) {
        free(Shell->Prompt);
        Shell->Prompt = NULL;
    }

    ShRestoreRedirections(Shell, &(Shell->ActiveRedirectList));
    while (LIST_EMPTY(&(Shell->Lexer.HereDocumentList)) == FALSE) {
        HereDocument = LIST_VALUE(Shell->Lexer.HereDocumentList.Next,
                                  SHELL_HERE_DOCUMENT,
                                  ListEntry);

        LIST_REMOVE(&(HereDocument->ListEntry));
        ShDestroyHereDocument(HereDocument);
    }

    ShDestroyVariableList(&(Shell->VariableList));
    ShDestroyFunctionList(Shell);
    ShDestroyAliasList(Shell);
    ShDestroySignalActionList(&(Shell->SignalActionList));
    if (Shell->CommandName != NULL) {
        free(Shell->CommandName);
    }

    ShDestroyArgumentList(&(Shell->ArgumentList));
    ShDestroyLexer(&(Shell->Lexer));

    assert(LIST_EMPTY(&(Shell->ExecutionStack)) != FALSE);
    assert(LIST_EMPTY(&(Shell->ArgumentList)) != FALSE);

    umask(Shell->OriginalUmask);
    if (Shell->NonStandardError != NULL) {
        fclose(Shell->NonStandardError);
        Shell->NonStandardError = NULL;
    }

    free(Shell);
    return;
}
Beispiel #6
0
BOOL
ShFieldSplit (
    PSHELL Shell,
    PSTR *StringBuffer,
    PUINTN StringBufferSize,
    PLIST_ENTRY ExpansionList,
    ULONG MaxFieldCount,
    PSTR **FieldsArray,
    PULONG FieldsArrayCount
    )

/*++

Routine Description:

    This routine performs field splitting on the given string.

Arguments:

    Shell - Supplies a pointer to the shell instance.

    StringBuffer - Supplies a pointer where the address of the fields string
        buffer is on input. On output, this may contain a different buffer that
        all the fields point into.

    StringBufferSize - Supplies a pointer that contains the size of the fields
        string buffer. This value will be updated to reflect the new size.

    ExpansionList - Supplies a pointer to the list of expansions within this
        string.

    MaxFieldCount - Supplies a maximum number of fields to create. When this
        number is reached, the last field contains the rest of the string.
        Supply 0 to indicate no limit.

    FieldsArray - Supplies a pointer where the array of pointers to the fields
        will be returned. This array will contain a NULL entry at the end of it,
        though that entry will not be included in the field count. The caller
        is responsible for freeing this memory.

    FieldsArrayCount - Supplies a pointer where the number of elements in the
        returned field array will be returned on success. This number does not
        include the null terminator entry.

Return Value:

    TRUE on success.

    FALSE on failure.

--*/

{

    CHAR Character;
    UINTN CurrentFieldSize;
    BOOL DeleteField;
    BOOL Delimit;
    PSHELL_EXPANSION_RANGE Expansion;
    PSTR *Field;
    ULONG FieldCapacity;
    ULONG FieldCount;
    ULONG FieldIndex;
    UINTN Index;
    BOOL InEmptyAtExpansion;
    BOOL InsideExpansion;
    PVOID NewBuffer;
    BOOL Quoted;
    BOOL Result;
    UINTN SeparatorCount;
    UINTN SeparatorIndex;
    PSTR Separators;
    BOOL SkipCharacter;
    PSTR String;
    UINTN StringSize;

    String = *StringBuffer;
    StringSize = *StringBufferSize;

    //
    // Allocate an initial array.
    //

    FieldCount = 0;
    FieldIndex = 0;
    FieldCapacity = SHELL_INITIAL_FIELDS_COUNT;
    Field = malloc(FieldCapacity * sizeof(PSTR));
    if (Field == NULL) {
        Result = FALSE;
        goto FieldSplitEnd;
    }

    memset(Field, 0, FieldCapacity * sizeof(PSTR));
    Field[0] = String;

    //
    // Get the field separator variable.
    //

    Result = ShGetVariable(Shell,
                           SHELL_IFS,
                           sizeof(SHELL_IFS),
                           &Separators,
                           &SeparatorCount);

    if (Result == FALSE) {
        Separators = SHELL_IFS_DEFAULT;
        SeparatorCount = sizeof(SHELL_IFS_DEFAULT);
    }

    if (SeparatorCount != 0) {
        SeparatorCount -= 1;
    }

    //
    // Tee up the first expansion.
    //

    Expansion = NULL;
    if (LIST_EMPTY(ExpansionList) == FALSE) {
        Expansion = LIST_VALUE(ExpansionList->Next,
                               SHELL_EXPANSION_RANGE,
                               ListEntry);
    }

    //
    // Loop through every character in the input.
    //

    CurrentFieldSize = 0;
    Delimit = FALSE;
    InEmptyAtExpansion = FALSE;
    InsideExpansion = FALSE;
    SkipCharacter = FALSE;
    Index = 0;
    Quoted = FALSE;
    while (Index < StringSize - 1) {
        Character = String[Index];

        //
        // If at the end of the expansion, move to the next expansion. Being
        // inside an expansion decides whether or not to look for field
        // separators or ordinary whitespace.
        //

        if (Expansion != NULL) {
            if ((Expansion->Type == ShellExpansionSplitOnNull) &&
                (Quoted != FALSE) &&
                (Index >= Expansion->Index)) {

                //
                // If there are no arguments, then an empty at expansion in
                // quotes may collapse to zero arguments.
                //

                if ((Expansion->Length == 0) &&
                    (LIST_EMPTY(ShGetCurrentArgumentList(Shell)) != FALSE)) {

                    InEmptyAtExpansion = TRUE;
                }
            }

            while ((Expansion != NULL) &&
                   (Index == Expansion->Index + Expansion->Length)) {

                InsideExpansion = FALSE;
                if (Expansion->ListEntry.Next != ExpansionList) {
                    Expansion = LIST_VALUE(Expansion->ListEntry.Next,
                                           SHELL_EXPANSION_RANGE,
                                           ListEntry);

                } else {
                    Expansion = NULL;
                }
            }

            //
            // If inside an expansion, look for field separators.
            //

            if ((Expansion != NULL) && (Index >= Expansion->Index)) {
                InsideExpansion = TRUE;
            }
        }

        //
        // If the character is an escape, skip it and the next character.
        //

        if (Character == SHELL_CONTROL_ESCAPE) {
            Index += 2;

            assert(Index <= StringSize - 1);

            CurrentFieldSize += 1;
            continue;

        } else if (Character == SHELL_CONTROL_QUOTE) {
            Quoted = !Quoted;
        }

        //
        // If not inside an expansion, look for quotes or blanks.
        //

        if (InsideExpansion == FALSE) {

            //
            // It's not a quote, and it's not inside an expansion, so look
            // for white space to field split on.
            //

            if ((Quoted == FALSE) && (isspace(Character))) {
                if (CurrentFieldSize != 0) {
                    Delimit = TRUE;

                } else {
                    SkipCharacter = TRUE;
                }
            }

        //
        // This is inside an expansion.
        //

        } else {
            switch (Expansion->Type) {
            case ShellExpansionSplitOnNull:
                if (Character == '\0') {
                    Delimit = TRUE;
                    break;
                }

                //
                // Fall throuth.
                //

            case ShellExpansionFieldSplit:
                if (Quoted != FALSE) {
                    break;
                }

                for (SeparatorIndex = 0;
                     SeparatorIndex < SeparatorCount;
                     SeparatorIndex += 1) {

                    //
                    // Treat carraige returns as equal to newlines. This is
                    // cheating a bit, but the hope is it fixes up CRLFs
                    // seamlessly without causing much other damage.
                    //

                    if ((Character == Separators[SeparatorIndex]) ||
                        ((Separators[SeparatorIndex] == '\n') &&
                         (Character == '\r'))) {

                        Delimit = TRUE;

                        //
                        // Whitespace separators are treated differently than
                        // other characters. Multiple whitespaces in a row are
                        // glossed over.
                        //

                        if ((CurrentFieldSize == 0) &&
                            ((Character == ' ') ||
                             (Character == '\n') || (Character == '\r') ||
                             (Character == '\t'))) {

                            Delimit = FALSE;
                            SkipCharacter = TRUE;
                        }

                        break;
                    }
                }

                break;

            case ShellExpansionNoFieldSplit:
                break;

            default:

                assert(FALSE);

                Result = FALSE;
                goto FieldSplitEnd;
            }
        }

        if (Delimit != FALSE) {
            Delimit = FALSE;
            SkipCharacter = TRUE;

            //
            // Stop if the desired maximum number of fields has been reached.
            //

            if (FieldIndex + 1 == MaxFieldCount) {
                break;
            }

            String[Index] = '\0';
            CurrentFieldSize = 0;

            //
            // Expand the array size if needed. Leave space for an empty field
            // at the end.
            //

            if (FieldIndex + 2 >= FieldCapacity) {
                FieldCapacity *= 2;
                NewBuffer = realloc(Field, FieldCapacity * sizeof(PSTR));
                if (NewBuffer == NULL) {
                    Result = FALSE;
                    goto FieldSplitEnd;
                }

                Field = NewBuffer;
                memset(Field + FieldIndex + 1,
                       0,
                       (FieldCapacity - FieldIndex - 1) * sizeof(PSTR));
            }

            DeleteField = FALSE;
            if (Index + 1 != StringSize) {

                //
                // For $@ expansions, an empty "$@" expands to zero fields, and
                // empty parameters within $@ are not removed.
                //

                if (InEmptyAtExpansion != FALSE) {
                    if (strcmp(Field[FieldIndex], ShEmptyQuotedString) == 0) {
                        DeleteField = TRUE;
                    }

                //
                // Outside of expansions, remove empty fields.
                //

                } else if (InsideExpansion == FALSE) {
                    if (Field[FieldIndex][0] == '\0') {
                        DeleteField = TRUE;
                    }
                }

                if (DeleteField == FALSE) {
                    FieldIndex += 1;
                }

                Field[FieldIndex] = String + Index + 1;
            }

            InEmptyAtExpansion = FALSE;
        }

        //
        // If there were two whitespaces in a row, advance the field to skip
        // over them.
        //

        if (SkipCharacter != FALSE) {
            SkipCharacter = FALSE;

            //
            // If this is the end of the string, the field can't be walked
            // forward anymore. Remove the field.
            //

            if (Index + 2 == StringSize) {

                //
                // If this is the first field it can't be removed. That means
                // the whole string was whitespace. Null out the string and
                // return the 1 empty field.
                //

                if (FieldIndex == 0) {
                    Field[0] = NULL;

                } else {
                    FieldIndex -= 1;
                }

            } else {
                Field[FieldIndex] = String + Index + 1;
            }

        } else {
            CurrentFieldSize += 1;
        }

        Index += 1;
    }

    Result = TRUE;
    FieldCount = FieldIndex;

    //
    // Check the last field.
    //

    DeleteField = FALSE;
    if (Field[FieldIndex] == NULL) {
        DeleteField = TRUE;

    } else if (InEmptyAtExpansion != FALSE) {
        if (strcmp(Field[FieldIndex], ShEmptyQuotedString) == 0) {
            DeleteField = TRUE;
        }

    //
    // Outside of expansions, remove empty fields.
    //

    } else if (InsideExpansion == FALSE) {
        if (Field[FieldIndex][0] == '\0') {
            DeleteField = TRUE;
        }
    }

    if (DeleteField == FALSE) {
        FieldCount += 1;
    }

    //
    // Null terminate the field array.
    //

    assert(FieldCount < FieldCapacity);

    Field[FieldCount] = NULL;

FieldSplitEnd:
    if (Result == FALSE) {
        if (Field != NULL) {
            free(Field);
            Field = NULL;
        }
    }

    *StringBuffer = String;
    *StringBufferSize = StringSize;
    *FieldsArray = Field;
    *FieldsArrayCount = FieldCount;
    return Result;
}