печатать символы строки или массива в C Fast - PullRequest
0 голосов
/ 29 июня 2019

Я кодирую игровую приставку и сохраняю карту игры в массиве персонажей, и мне нужно распечатать их в цвете (разными цветами) в CMD, поэтому я пишу print_map функцию, которую я прикрепляю здесь, яprintf использовал для печати и SetConsoleTextAttribute для того, чтобы сделать их цветными орехами, печать была слишком медленной. Мне нужно быстро напечатать эти символы карты, поэтому помогите мне напечатать их цветными и быстрыми, пожалуйста.

void print_mapp(){
  clear();//clear screen
  int width,height,i,x,y;
  HANDLE hConsole = GetStdHandle(STD_OUTPUT_HANDLE);

  width = map_width;
  height = map_height;
  SetConsoleTextAttribute(hConsole,background_color);

  x=4;
  y=2;

  for(i=0;i<width*(height+1);i++){
    SetPosition(x,y);// set cursor to (x,y)
    if(map[i] == ' '){
        SetConsoleTextAttribute(hConsole,background_color);
        printf("%c",map[i]);
    }
    else if(map[i] == wall){
        SetConsoleTextAttribute(hConsole,wall_color);
        printf("%c",map[i]);
    }
    else if(map[i] == solidblock){
        SetConsoleTextAttribute(hConsole,solidblock_color);
        printf("%c",map[i]);

    }
    else if(map[i] == moveblock){
        SetConsoleTextAttribute(hConsole,moveblock_color);
        printf("%c",map[i]);

    }
    else if(map[i] == deathblock){
        SetConsoleTextAttribute(hConsole,death_blk_color);
        printf("%c",map[i]);

    }
    else if(map[i] == character){
        SetConsoleTextAttribute(hConsole,character_color);
        printf("%c",map[i]);

    }
    else if(map[i] == rpoint){
        SetConsoleTextAttribute(hConsole,rpoint_color);
        printf("%c",map[i]);

    }
    else if(map[i] == target){
        SetConsoleTextAttribute(hConsole,target_color);
        printf("%c",map[i]);

    }
    else if(map[i] == object){
        SetConsoleTextAttribute(hConsole,object_color);
        printf("%c",map[i]);

    }
    else if(map[i] == opp){
        SetConsoleTextAttribute(hConsole,opp_color);
        printf("%c",map[i]);

    }

    else if(map[i] == bullet){
        SetConsoleTextAttribute(hConsole,bullet_color);
        printf("%c",map[i]);

    }
    else if(map[i] == '\n'){
      SetConsoleTextAttribute(hConsole,background_color);
      printf("%c",map[i]);
      x = 3;
      y++;
    }
    else{
      SetConsoleTextAttribute(hConsole,wall_color);
      printf("%c",map[i]);

    }

    x++;
  }

}```

1 Ответ

0 голосов
/ 30 июня 2019

Я бы предположил, что каждый вызов SetPosition() и SetConsoleTextAttribute() приводит к сбросу stdout. Это приводит к сбросу на каждый напечатанный вами char.

Поэтому вы должны пытаться вызывать их только тогда, когда атрибут позиции или символа отличается от того, что вы ожидаете от них.

Использование fputc () вместо printf("%c", ..) также может дать теоретическое ускорение, но не настолько, чтобы это имело значение на практике. Но некоторые, в том числе и я, считают, что код выглядит чище ...

Итак, вот предлагаемое улучшение:

void
set_attrib(HANDLE h, WORD attr, WORD *old_attr)
{
  if (attr != *old_attr)
    {
      SetConsoleTextAttribute(h, attr);
      *old_attr = attr;
    }
}

void print_mapp()
{
  clear();//clear screen
  int width,height,i,x,y;
  HANDLE hConsole = GetStdHandle(STD_OUTPUT_HANDLE);

  width = map_width;
  height = map_height;

  WORD old_attr;

  SetConsoleTextAttribute(hConsole,background_color);
  old_attr = background_color;

  x=4;
  y=2;

  SetPosition(x,y);// set cursor to (x,y)


  for(i=0;i<width*(height+1);i++)
    {
      if(map[i] == ' '){
        set_attr(hConsole, background_color, &old_attr);
        fputc(map[i], stdout);
      }
      else if(map[i] == wall){
        set_attr(hConsole, wall_color, &old_attr);
        fputc(map[i], stdout);
      }
      ....  
      else if(map[i] == '\n'){
        set_attr(hConsole, background_color, &old_attr);
        fputc(map[i], stdout);
        x = 3;
        y++;
        SetPosition(x+1,y);// set cursor to (x,y)

      }
      else{
        set_attr(hConsole, wall_color, &old_attr);
        fputc(map[i], stdout);
      }

    x++;
  }

}

Другие предложения по ускорению:

  1. Вы можете напечатать цветной код ANSI вместо вызова SetConsoleTextAttribute()
  2. Вы можете ограничиться печатью только тех строк, которые изменились после последнего вызова на print_mmap()

Некоторые рекомендации по очистке (не окажут существенного влияния на скорость):

  1. Перемещение fputc() за пределы if и if else
  2. Скорее, в map[i] есть печатные символы, просто enums, описывающие игровые объекты, и ищите печатные символы и атрибуты в отдельном массиве поиска.
...