Znak & w konsoli z gwiazdek

1

Jak narysować ampersand (&) z gwiazdek w konsoli C++? Wymiary planszy to 40x40.

Kolega dostał znak dolara a jaki taki trudny

Jak to zrobić?

1
  1. Narysuj znak w paintcie, w rozmiarze 40px na 40px czarnym kolorem na białym.
  2. Wyświetl w konsoli w programie kwadrat z samych gwiazdek * w rozmiarze 40 poziomo i 40 pionowo.
  3. Posiłkując się bitmapą w Paint, zamieniaj gwiazdki na spacje, aż do pożądanego wyglądu.

screenshot-20241118134331.png

PS: Ewentualnie możesz po prostu napisać w paint'cie znak &. Możliwe że Paint doda antialiasing (cienie), więc żeby je usunąć możesz podciągnąć janość i kontrast na maxa. Podsyłam literę w bitmapie 40px/40px w formacie BMP w załączniku ampersand.zip.

0

Napisałem znak & w Paincie, zaznaczyłem i przeskalowałem na 40x40, zapisałem najpierw jako bitmapę monochromatyczną, a potem jako 256-kolorową, ponieważ to najprostszy format do odczytu - jeden piksel to jeden bajt. Za pomocą prostego programu w C przerobiłem bitmapę na następującą grafikę ze znaków:

                                        
               ********                 
             ****    ***                
            ****      ***               
            ****      ***               
           *****      ***               
          ******      *****             
          ******      *****             
          ******      *****             
          ******     ****               
          ******   ******               
           ****** ******                
           ****** ******                
           ************  *************  
           **********      ********     
            ******          ******      
          ********          *****       
        ***********         *****       
       ***** ******         ****        
      *****  ********       ****        
      *****  ********       ****        
     *****     ******      ***          
    ****       *******     **           
  ******        *******  ****           
  *****         *******  ***            
 ******          ***********            
 ******           *********             
 ******           *******               
 ******           *******               
 *******           ********             
 *******           *********        *** 
  ********        ***********       *** 
  *********     **************     **** 
    *****************  ***************  
     *************      ************    
      **********           *******      
      **********           *******      
                                        
                                        
                                        
0

Oba te sposoby powyżej są wporzo, ale ciężko powiedzieć, czy spodoba się prowadzącemu (zakładam że to na studia), bo używasz zewnętrznego programu typu Paint. Może to jest ok (i wtedy fajnie), ale jeśli tak, to równie dobrze możesz zrobić cout << "..." i w miejsce kropek wkleić to co @Manna5 wyprodukował, albo wygenerować w necie ascii art.

Bez zewnętrznego programu, to chyba pozostaje próba wyznaczenia wzoru tej krzywej i narysowanie jej w układzie kartezjańskim jako krzyżyki, ale czy to nie przekombinowane - nie wiem.

0

jak coś wygenerować z 40x40.
Najbardziej prymitywnie.

  1. Weź tablice dwu wymiarową 40x40. Wartość 1 to że coś trzeba narysować 0 spacja.
  2. Wypełnij ją odpowiednio
  3. Traktuj każdą komórke jak piksel o koordynatach XY
  4. Printuj odpowiednio tzn. wiersz po wierszu a pixel o wartości 1 w tablicy to znak *
2

Po co komu Paint czy inne okienkowe programy jak można sobie bezpośrednio renderować czcionkę do bitmapy :P

#include <iostream>
#include <ft2build.h>

#include FT_FREETYPE_H  

int main() {
    FT_Library ft;
    if (FT_Init_FreeType(&ft)) {
        std::cout << "ERROR::FREETYPE: Could not init FreeType Library" << std::endl;
        return -1;
    }
    FT_Face face;
    if (FT_New_Face(ft, "arial.ttf", 0, &face)) {
        std::cout << "ERROR::FREETYPE: Failed to load font" << std::endl;  
        return -1;
    }
    FT_Set_Pixel_Sizes(face, 0, 40);
    if (FT_Load_Char(face, '&', FT_LOAD_RENDER)) {
        std::cout << "ERROR::FREETYTPE: Failed to load Glyph" << std::endl;  
        return -1;
    }
    for (int y = 0; y < face->glyph->bitmap.rows; y++) {
        for (int x = 0; x < face->glyph->bitmap.width; x++) {
            std::cout << ((face->glyph->bitmap.buffer[y * face->glyph->bitmap.width + x] > 0) ? '*' : ' ');
        }
        std::cout << "\n";
    }
    std::cout << "\n";
    FT_Done_Face(face);
    FT_Done_FreeType(ft);
}
$ g++ test.cpp -o test -I./freetype-2.10.0/include/ -lfreetype
$ ./test 
       *********         
      ***********        
     *************       
    **************       
    *****    *****       
    *****     *****      
    *****     *****      
    *****     ****       
    ******   *****       
     ****** ******       
     ************        
      **********         
      ********           
     *********           
   ************          
  **************  *****  
 *******  ******* *****  
 *****     ************  
 *****      ***********  
*****        *********   
*****        *********   
*****         *******    
******         *******   
 *****        *********  
 ******     ************ 
  ***********************
  *************** *******
   *************   ***** 
     **********      *** 
0

Gotowego rozwiązania Ci nie dostarczę, ale możesz eksperymentować w rysowaniu tekstowych grafik ASCII
Istnieje możliwość zmiany kolorów, znaków. Przykładowy piktogram.


// test Windows 10 Pro x86 Standard ISO C++17 (/std:c++17)
// g++ --version g++ (x86_64-posix-seh-rev0, Built by MinGW-W64 project) 8.1.0
// cl Microsoft (R) Kompilator optymalizujący C/C++, wersja 19.42.34433 dla architektury x86

#include <iostream>
#include <cstdint>
#include <vector>
#include <Windows.h>
#include <string>

int main()
{
    const std::vector<std::wstring>  pictus =
    {
        L"                                                                 ",
        L"                                                                     ",
        L"  ▄███████████████████████████████████████████████████████████████▄  ",
        L"  █████████████████████████████████████████████████████████████████  ",
        L"  █████████████████████████████████████████████████████████████████  ",
        L"  ███████░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░███████  ",
        L"  ███████░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░███████  ",
        L"  ███████░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░███████  ",
        L"  ███████░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░███████  ",
        L"  ███████░░░░██░░░░░░░░░░░░░░░░██░░░░░██░░░░░░░░░░░░░░░░░░░░███████  ",
        L"  ███████░░░░██░░░░░░░░░░░░░░░░██░░░░░██░░░░░░░░░░░░░░░░░░░░███████  ",
        L"  ███████░░░░██░░░░░░░░░░░░░░░░██░░░░░██░░░░░░░░░░░░░░░░░░░░███████  ",
        L"  ███████░░░░██░░░░░░░░░░░░░░░░██░░░░░██░░░░░░░░░░░░░░░░░░░░███████  ",
        L"  ███████░░░░████████░████████░██░░░░░██░░░░░░██████░░░░░░░░███████  ",
        L"  ███████░░░░██░░░░██░██░░░░██░██░░░░░██░░░░░██░░░░██░░░░░░░███████  ",
        L"  ███████░░░░██░░░░██░████████░██░░░░░██░░░░░██░░░░██░░░░░░░███████  ",
        L"  ███████░░░░██░░░░██░██░░░░░░░██░░░░░██░░░░░██░░░░██░░░░░░░███████  ",
        L"  ███████░░░░██░░░░██░████████░██████░██████░░██████░░██░░░░███████  ",
        L"  ███████░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░███████  ",
        L"  ███████░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░███████  ",
        L"  ███████░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░███████  ",
        L"  █████████████████████████████████████████████████████████████████  ",
        L"  █████████████████████████████████████████████████████████████████  ",
        L"  █████████████████████████████████████████████████████████████████  ",
        L"  █████████████████████████████████████████████████████████████████  ",
        L"  █████████████████████████████████████████████▒▒▒▒▒▒▒▒▒▒▒█████████  ",
        L"  █████████████████████████████████████▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓███████  ",
        L"  █████████████████████████████████████████████▒▒▒▒▒▒▒▒▒▒▒█████████  ",
        L"  █████████████████████████████████████████████████████████████████  ",
        L"  █████████████████████████████████████████████████████████████████  ",
        L"  █████████████████████████████████████████████████████████████████  ",
        L"  █████████████████████████████████████████████████████████████████  ",
        L"  █████████████████████████████████████████████████████████████████  ",
        L"  ▀███████████████████████████████████████████████████████████████▀  ",
        L"   ███████████████████████████████████████████████████████████████   ",
        L"   ▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄   ",
        L" ▄▄▄▄ ▀▀▀ ▄▄ ▀▀▀ ▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄ ▀▀▀ ▄▄ ▀▀▀ ▄▄▄▄ ",
        L" ███████████████████████████████████████████████████████████████████ ",
        L"                                                                     ",
        L"                                                                 ",
    };

    HANDLE hConsole = GetStdHandle(STD_OUTPUT_HANDLE);
    WriteConsoleW(hConsole, L"\n", 1, nullptr, nullptr);
    for (size_t i = 0; i <  pictus.size(); ++i) {
        const wchar_t* padding = (i == 0 || i ==  pictus.size() - 1) ? L"       " : L"     ";
        WriteConsoleW(hConsole, padding, wcslen(padding), nullptr, nullptr);
        SetConsoleTextAttribute(hConsole, BACKGROUND_RED | BACKGROUND_GREEN | BACKGROUND_GREEN | BACKGROUND_INTENSITY | FOREGROUND_GREEN);
        WriteConsoleW(hConsole,  pictus[i].c_str(),  pictus[i].size(), nullptr, nullptr);
        SetConsoleTextAttribute(hConsole, FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE);
        WriteConsoleW(hConsole, L"\n", 1, nullptr, nullptr);
    }
    SetConsoleTextAttribute(hConsole, FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE);
    std::string antrakt;
    std::getline(std::cin, antrakt);
    return 0;
}



// edit.

Aby uzyskać bardziej imponujący efekt wizualny, warto skorzystać z nowoczesnej biblioteki formatowania
{fmt}, zyskasz kontrolę nad każdym znakiem.
https://fmt.dev/11.0/

1

Jako programista power pointa zrobiłbym tak:

a) bierzesz dużego ampersanda i robisz go półprzezroczystym
b) dorzucasz grida w tle
c) robisz przybliżenie kształtu ampersanda na gridzie za pomocą linii
d) w przybliżeniu odczytujesz punkty A-B-...-O

Rysujesz kształt, np. linie algorytmem Bresenhma, a żeby było mniej koślawe, możesz przybliżyć spline'ami. Porfit: nie musisz hardkodować rozmiaru 40x40.

Przykładowy output:

screenshot-20241119093027.png

Koncept ja, wykonanie ChatGPT.

ampersand.PNG
ampersand_code.7z

Zarejestruj się i dołącz do największej społeczności programistów w Polsce.

Otrzymaj wsparcie, dziel się wiedzą i rozwijaj swoje umiejętności z najlepszymi.