Как преобразовать значения из файла .art в ASCII-изображение в Stack Overflow

Работая над проектом, где я должен загрузить файл на основе пользовательского ввода, преобразовать данные в этом файле в координаты в окне, а затем использовать символы ASCII для рисования изображения.

Файлы находятся в .art и начинаются с ширины и высоты необходимого окна, и каждая последующая строка — это ROW, COLUMN, CHARACTER и COUNT, которые необходимо нарисовать. Таким образом, в основном позиция, с которой должен начинаться конкретный персонаж, а затем, сколько раз он должен быть нарисован.
Я борюсь с тем, как импортировать эти данные во что-нибудь пригодное для использования, чтобы я мог нарисовать запрошенное изображение. Моя первоначальная мысль — импортировать данные в виде 4-D массива, но затем я рисую пробел в том, куда мне следует идти оттуда.

Пример строки для файла .art:

  50 x 25
2, 15, *, 9
2, 48, *, 9
3, 6,  *, 15

ОБНОВЛЕНИЕ: Отказался от попытки загрузить файлы, так как я просто не могу обдумать это, поэтому я перешел к рисованию рисунка от руки и вызову строки, но у меня даже есть проблемы с этим. С моим кодом ниже, если я выберу вариант 1, вывод 001FFA80 вместо вывода искусства ASCII, которое находится в строке.

    #include <stdio.h>
#include <cstdlib>
#include <string>
#include <iostream>
using namespace std;

int main ()
{
string shapeCupid[]=
{"                                      ",
"          ..                          ",
"           $. ,o$$$o.                 ",
"           $. $$$$$$$o.   ..          ",
"          .$. $' $$$$$$ ,o''          ",
"         .$'  $  '$$$$$,o'.,'   .oo ' ",
"        .$'   $.   $$$$'  ,,  .o'.    ",
"       .$'    '$o. 'O$ .. ooo''',oo ' ",
"      .$'     .o$'  '$$''     ,,o'    ",
"    .%$,,,,,ooO'      '       ,,o''   ",
"  .$o.           ,o'    $o     ..oo'  ",
"   ''O'''''''''','       $'$. .o'     "};
string shapeFly = "Fly";
string shapeHeart = "Heart";
string shapeImpossible = "Impossible";
string shapeSeuss = "Seuss";
string shapeWorry = "Worry";
int UserInput;
cout << "What do you want to draw?\n";
cout << "1. Cupid\n2. Fly\n3. Heart\n4. Impossible\n5. Seuss\n6. Worry\nNumber: ";
cin >> UserInput;
if (UserInput == 1){
cout << shapeCupid;}
else if (UserInput == 2){
cout << shapeFly;}
else if (UserInput == 3){
cout << shapeHeart;}
else if (UserInput == 4){
cout << shapeImpossible;}
else if (UserInput == 5){
cout << shapeSeuss;}
else if (UserInput == 6){
cout << shapeWorry;}
else if (UserInput != 1 || 2 || 3 || 4 || 5 || 6)
cout << "Please select proper value.\n";

system("pause");
return 0;

}

1

Решение

Вот быстрая и грязная версия, которая может помочь. Я не добавил тонну проверки ошибок, но она работает для 2 примеров, которые я использовал. Если вы планируете встраивать данные в виде строковых литералов, вы обязательно должны избегать любых специальных символов, таких как обратный слеш и двойные кавычки. Пример Boop имеет оба.

Для встроенных строковых литеральных данных первая строка должна быть дополнена до самой длинной строки, поскольку она используется для записи ширины. Улучшение будет заключаться в том, чтобы перебрать все строки, чтобы получить максимальную ширину и использовать ее.

#include <string>
#include <iostream>
#include <vector>
#include <fstream>

using StringVec = std::vector<std::string>;

StringVec shapeCupid =
{
"                                      ",
"          ..                          ",
"           $. ,o$$$o.                 ",
"           $. $$$$$$$o.   ..          ",
"          .$. $' $$$$$$ ,o''          ",
"         .$'  $  '$$$$$,o'.,'   .oo ' ",
"        .$'   $.   $$$$'  ,,  .o'.    ",
"       .$'    '$o. 'O$ .. ooo''',oo ' ",
"      .$'     .o$'  '$$''     ,,o'    ",
"    .%$,,,,,ooO'      '       ,,o''   ",
"  .$o.           ,o'    $o     ..oo'  ",
"   ''O'''''''''','       $'$. .o'     "};

//Borrowed from http://www.chris.com/ascii/index.php?art=cartoons/betty%20boop
StringVec boop =
{
"        _(,__           __),          ",
"    (_,d888888888b,d888888888b",
"     d888888888888/888888888888b_)",
"  (_8888888P'\"\"'`Y8Y`'\"\"'\"Y88888b",
"    Y8888P.-'     `      '-.Y8888b_)",
"   ,_Y88P (_(_(        )_)_) d88Y_,",
"    Y88b,  (o  )      (o  ) d8888P",
"    `Y888   '-'        '-'  `88Y`",
"    ,d/O\\         c         /O\\b,",
"      \\_/'.,______w______,.'\\_/",
"         .-`             `-.",
"        /   , d88b  d88b_   \\",
"       /   / 88888bd88888`\\  \\",
"      /   / \\ Y88888888Y   \\  \\",
"      \\  \\   \\ 88888888    /  /",
"       `\\ `.  \\d8888888b, /\\\\/",
"         `.//.d8888888888b; |",
"           |/d888888888888b/",
"           d8888888888888888b",
"        ,_d88p\"\"q88888p\"\"q888b,",
"        `\"\"'`\\    \"`|    /`'\"\"`",
"              `.    |===/",
"                >   |   |",
"                /   |   |",
"               |    |   |",
"               |    Y  /",
"               \\   /  /",
"         jgs    | /| /",
"               / / / |",
"              /=/  |=/"};

void Write(const std::string& filename, StringVec& data)
{
if(data.empty())
{
return;
}

std::ofstream out(filename);
if(out)
{
out << data[0].size() << " x " << data.size() << "\n";
for(size_t row = 0; row < data.size(); ++row)
{
const std::string& line = data[row];
size_t col_start = 0;
size_t col_end = 0;
char col_char = line[0];
for(size_t col = 0; col < line.size(); ++col)
{
//If we hit a new character write the previous run to the file
if(col_char != line[col])
{
//but only if it wasn't a run of spaces.
if(col_char != ' ')
{
out << row << ", " << col_start << ", " << col_char << ", " << col_end - col_start + 1 << "\n";
}
col_char = line[col];
col_start = col;
col_end = col;
}
col_end = col;
}
//write the last run
if(col_char != ' ')
{
out << row << ", " << col_start << ", " << col_char << ", " << col_end - col_start + 1 << "\n";
}
}
}
}

StringVec Read(const std::string& filename)
{
StringVec data;
std::ifstream in(filename);
if(in)
{
char dummy;

size_t width;
size_t height;
if(in >> width >> dummy >> height)
{
data.resize(height, std::string(width, ' '));
}
if(!data.empty())
{
size_t row;
size_t col;
char ch;
size_t len;
while(in >> row >> dummy >> col >> dummy >> ch >> dummy >> len)
{
for(size_t i = col; i < col + len; ++i)
{
data[row][i] = ch;
}
}
}
}
return data;
}

void Print(const StringVec& data)
{
for(const std::string& s : data)
{
std::cout << s << "\n";
}
std::cout << "\n";
}

int main()
{
Write("cupid.art", shapeCupid);
Print(Read("cupid.art"));
Write("boop.art", boop);
Print(Read("boop.art"));
return 0;
}
1

Другие решения