Пример #1
0
unsigned long long perft(Board *board, int depth) {
    if (is_illegal(board)) {
        return 0L;
    }
    if (depth == 0) {
        return 1L;
    }
    int index = board->hash & MASK;
    Entry *entry = &TABLE[index];
    if (entry->key == board->hash && entry->depth == depth) {
        hits += entry->value;
        return entry->value;
    }
    unsigned long long result = 0;
    Undo undo;
    Move moves[MAX_MOVES];
    int count = gen_moves(board, moves);
    for (int i = 0; i < count; i++) {
        do_move(board, &moves[i], &undo);
        result += perft(board, depth - 1);
        undo_move(board, &moves[i], &undo);
    }
    entry->key = board->hash;
    entry->value = result;
    entry->depth = depth;
    return result;
}
Пример #2
0
command_stream_t
make_command_stream (int (*get_next_byte) (void *),
             void *get_next_byte_argument)
{
  char** commandStrings = (char**)checked_malloc(sizeof(char*));
  commandStrings[0] = NULL;
  char** temp = NULL;
  char c;
  char effective_prev = '\0';
  char prev ='\0';
  int count = 1; // Keeps count of complete commands
  bool sub = false; //To see if we are within a subshell
  int open_par = 0;
  int closed_par = 0;
  int curr_line = 1;
  int* line_nums = (int*)checked_malloc(sizeof(int));
  line_nums[0] = 1;
  
  while((c = get_next_byte(get_next_byte_argument)) != EOF)
  {
    if(is_illegal(c))  // Check for illegal tokens
    {
      error(1,0,"%d: Invalid token '%c'.",curr_line,c);
      return 0;
    }
    if((c == ';') && (!sub))
    {
    if(effective_prev =='\n' || effective_prev =='\0')
      error(1,0, "%d: Can't start line with '%c'", curr_line, c);

    if(effective_prev == ';')
      error(1,0, "%d: Too many '%c' tokens", curr_line, c);

      count++;
      temp = (char**)checked_realloc(commandStrings,sizeof(char*)*count);
      commandStrings = temp;
      commandStrings[count-1] = NULL;
      int* temp_int = (int*)checked_realloc(line_nums,sizeof(int)*count);
      line_nums = temp_int;
      prev = c;
      effective_prev = c;
      continue;
    }
    if(c == '#') // Take care of comments be ignoring everything up to newline
    {
      if((is_special(prev)) || (isblank((unsigned char)prev) != 0)  // changed from unsigned char type to char
        || (prev == '\n') ||(prev == '\0'))
      {
        while((c = get_next_byte(get_next_byte_argument)) != EOF)
          if( c == '\n')
            break;
        if(c == EOF)
          break;
        if((prev == '\0') && (c == '\n')) // Case if script starts with #
        {                             //If I don't include this an empty string is made
          prev = c;
          if(isblank((unsigned char)c) == 0)
            effective_prev = c;
          curr_line++;
          continue;
        }
      }
      else
      {
        error(1,0,"Line %d: Invalid use of '#' token.",curr_line);
        return 0;
      }
    }
    if(c != '\n')
    {
      if((isblank((unsigned char)c) != 0) && (effective_prev == '\0'))
        continue;
      // Check that that only paranthesis are preceded by newline(and words of course)
      if(effective_prev == '\n')
      {
        if((c == '|') || (c == '&') || (c == '>') || (c == '<'))
        {
          error(1,0,"%d: Unexpected newline before '%c' token",curr_line,c);
          return 0;
        }
      }
      if(c == '(')
      {
        sub = true;
        open_par++;
      }
      else if(c == ')')
      {
        closed_par++;
        if(open_par == closed_par)
        {
          sub = false;
          open_par = 0;
          closed_par = 0;
        }
      }
      if(((c == '|') && (effective_prev == '&')) ||
        ((c == '&') && (effective_prev == '|')))
      {
        error(1,0,"%d: Invalid AND-OR.",curr_line);
        return 0;
      }
      if(commandStrings[count-1] == NULL)
      {
        line_nums[count-1] = curr_line;
      }
      add_char(commandStrings,count-1,c);
    }
    else
    {
      if((effective_prev == '|') || (effective_prev == '&') || sub)
      {
        prev = c;
        if(isblank((unsigned char)c) == 0)
          effective_prev = c;
        if(commandStrings[count-1] == NULL)
        {
          line_nums[count-1] = curr_line;
        }
        add_char(commandStrings,count-1,c);        
        curr_line++;
        continue;
      }      
      if(prev == '\n' || effective_prev == '\0')
      {
        prev = c;
        if(isblank((unsigned char)c) == 0)
          effective_prev = c;
        curr_line++;
        continue;
      }
      // Gotta also check for < or > cases
      
      if((effective_prev == '<') || (effective_prev == '>'))
      {
        error(1,0,"%d: Cannot end line in < or >",curr_line);
        return 0;
      }
      if(!sub && (prev != ';'))
      {
        count++;
        temp = (char**)checked_realloc(commandStrings,sizeof(char*)*count);
        commandStrings = temp;
        commandStrings[count-1] = NULL;
        int* temp_int = (int*)checked_realloc(line_nums,sizeof(int)*count);
        line_nums = temp_int;
      }
      curr_line++;
    }
    prev = c;
    if(isblank((unsigned char)c) == 0)
      effective_prev = c;
  }
  if((commandStrings[0] == NULL) && count == 1)
    count = 0;
  if(open_par != closed_par)     // Check to see if paranthesis are all good
  {
    error(1,0,"%d: Missing a paranthesis",curr_line);
    return 0;
  }

  if(prev == '\n' && (commandStrings[count-1] == NULL))
    count--;

  command_stream_t stream = stringsToStream(commandStrings, line_nums, count);

  /* Free Data Allocated Dynamically 
  int j;
  for(j = 0; j < count; j++)
    free(commandStrings[j]);
  free(commandStrings);
  free(line_nums); */

  // BUILD READ/WRITE LISTS (add as a member of command_stream_t)
 
  // BUILD DEPENDENCY LISTS (lists of integer indices of commands that must 
  //  finish before this one does) 
  
  stream->pidList = checked_malloc(count * sizeof(pid_t));

  // 0 out all pid's.  This will give them all integer values of NOT_YET_RUN.
  memset(stream->pidList, 0, count * sizeof(pid_t));
  
  make_dep_lists(stream);

  return stream;
}