Wskazówki do gry w węgiel drzewny

15

Węgiel drzewny to język stworzony przez ASCII i DLosc, który specjalizuje się w wyzwaniach artystycznych ASCII.

Jakie masz wskazówki dotyczące gry w golfa w Charcoal? Oczywiście szukam wskazówek związanych konkretnie z węglem drzewnym, a nie tych, które można zastosować do większości - jeśli nie wszystkich - języków.

Okx
źródło
Chrzanić, spróbuję odpowiedzieć na węgiel drzewny, brb. Może mogę podać drobne wskazówki w tym wątku.
Magic Octopus Urn

Odpowiedzi:

5

Skorzystaj z deverbosifier

Użycie deverbosifier oznacza, że ​​możesz pisać w ASCII ( --dvlub --deverbosifydeverbosify, -vlub --verbosewykonać jako pełny kod). Ponadto kompresuje ciągi dla Ciebie, co może być przydatne w niektórych wyzwaniach ASCII-art, gdy ciąg do skompresowania jest zbyt długi.

@ Neil zaleca używanie -vllub -v --sl. Jest to skrót od --verbose --showlength, co oznacza, że ​​zostanie zinterpretowany jako pełny węgiel drzewny, a długość normalnego kodu węgla drzewnego zostanie pokazana. Ponadto podczas dewerbosyfikacji sprawdź dane wyjściowe, aby upewnić się, że dane wejściowe zostały poprawnie przeanalizowane, ponieważ węgiel drzewny generalnie ignoruje błędy analizy. Jeśli tam jest błąd składni, użycie -a( --astify) lub --oa( --onlyastify), aby pomóc dowiedzieć się problem.

Tylko ASCII
źródło
Ponadto polecam używać -v -sl. Ponadto podczas dewerbosyfikacji sprawdź dane wyjściowe, aby upewnić się, że dane wejściowe zostały poprawnie sparsowane, ponieważ nie zawsze pojawia się błąd analizy.
Neil
3

Użyj przeciążeń

Na przykład wiele poleceń wymaga tylko jednego argumentu:

  • Rectangle, OblongI Boxzrobić kwadrat, jeśli tylko jeden argument podano
  • Reflect polecenia domyślnie odzwierciedlają prawo
  • Rotate polecenia domyślnie wynoszą 90 stopni przeciwnie do ruchu wskazówek zegara
  • Polygoni PolygonHollowmoże przyjmować wielokierunkową i boczną długość. Można tego użyć, jeśli wszystkie boki mają tę samą długość.
Tylko ASCII
źródło
Odkryłem ten fakt PolygonHollowprzypadkiem. Możesz mieć nawet kilku wielokierunkowych, ale muszą oni stawić się przed normalnymi strzałkami (nie wiem, czy to ograniczenie jest zamierzone). Użyłem tego w mojej odpowiedzi na wyzwanie „Draw a cube”.
Neil
Hmm, ograniczenie jest trochę celowe, ale chyba powinienem je zmienić, bo i tak by to nie zaszkodziło
tylko ASCII
Widzę, że ustaliłeś, że Polygon akceptuje strzały i wielokierunkowe w dowolnej kolejności, dzięki! Gdy tu jestem, spodziewałem ReflectButterfly dlssię, że zadzwonię ReflectButterflyw każdym kierunku, ale (jak wiki poprawnie dokumentuje) tak naprawdę woła ReflectOverlap.
Neil
@Neil lol ups, postaram się naprawić ten JAK NAJSZYBCIEJ (myślę, że to zbieg okoliczności zbyt haha)
tylko ASCII
3

Unikaj kolejnych stałych tego samego typu

Na przykład Plus(Times(i, 2), 1)tłumaczy jako ⁺×鲦¹, ale można zapisać bajt, zmieniając parametry: Plus(1, Times(i, 2))tłumaczy jako ⁺¹×ι²i Plus(Times(2, i), 1)jako ⁺ײι¹oba zapisują bajt. Plus(1, Times(2, i))(co tłumaczy się jako ⁺¹×²ι) byłoby jeszcze lepsze, gdyby następowała po nim inna stała liczbowa.

Neil
źródło
3

Użyj predefiniowanych zmiennych

Oto lista wszystkich zmiennych, których można użyć, podając zwięzłą grecką literę i pełną, reprezentującą ją literę.

α/a: The uppercase alphabet
β/b: The lowercase alphabet
γ/g: A string of all the ASCII characters from space to ~
δ/d: The fifth input
ε/e: The fourth input
ζ/z: The third input
η/h: The second input
θ/q: The first input
υ/u: An empty array
φ/f: 1000
χ/c: 10
ψ/y: The null character
ω/w: The empty string

Zmienne reprezentujące dane wejściowe będą puste, jeśli nie będzie wystarczającej ilości danych wejściowych, ale wszystkie inne nie pokazane tutaj zmienne muszą zostać przypisane przed użyciem.

Neil
źródło
Należy je teraz naprawić w TIO, byłoby miło, gdybyś mógł sprawdzić, czy to działa
tylko ASCII
@ Tylko ASCII Czy możesz to potwierdzić yi czy fjest na odwrót od tego, co wkleiłem? (Być może błędnie odczytałem greckie litery, kiedy je pierwotnie napisałem.)
Neil
Tak, są na odwrót
tylko ASCII
3

Naucz się swoich odbić i obrotów

Istnieje wiele odmian podstawowego odbicia i obrotu, więc opłaca się wiedzieć, jakie są subtelne różnice. Klucz do tabel:

  • Polecenie: nazwa polecenia w trybie pełnym.
  • Przekształć: czy węgiel drzewny powinien próbować odwracać lub obracać postacie podczas ich odbicia lub obracania. Na przykład, /może stać się \po obrocie lub odwrocie.
  • Zachowaj oryginalność: czy węgiel drzewny powinien połączyć wynik z oryginalnym płótnem.
  • Nakładanie: (Ma zastosowanie tylko wtedy, gdy Zachowaj oryginał ma wartość Tak.) Określa pozycję osi odbicia / obrotu w pół znakach od granicy. W przypadku odbić, równoważna liczbie wierszy / kolumn, na które nie ma to wpływu i kończy się w środku wyniku. W przypadku rotacji obrócona kopia może zastępować czyste obszary (ale nie spacje) w oryginale.

Refleksje

|         Command         | Transform | Keep Original | Overlap |
|-------------------------|-----------|---------------|---------|
| Reflect                 | No        | No            | n/a     |
| ReflectCopy             | No        | Yes           | 0       |
| ReflectOverlap          | No        | Yes           | 1       |
| ReflectOverlapOverlap   | No        | Yes           | n       |
| ReflectTransform        | Yes       | No            | n/a     |
| ReflectMirror           | Yes       | Yes           | 0       |
| ReflectButterfly        | Yes       | Yes           | 1       |
| ReflectButterflyOverlap | Yes       | Yes           | n       |

Kierunek odbicia jest opcjonalny. Ustawieniem domyślnym jest odbicie raz w prawo. W przypadku odbić, które zachowują oryginał, dozwolony jest wiele kierunków, które po prostu powtarzają polecenie dla każdego kierunku. (Oznacza to, że na przykład ReflectMirror(:¬)faktycznie utworzą w sumie cztery kopie).

Kursor jest przesuwany wraz z odbiciem (nawet gdy oryginał jest zachowany).

Rotacje

|         Command         | Transform | Keep Original | Overlap |
|-------------------------|-----------|---------------|---------|
| Rotate                  | No        | No            | n/a     |
| RotateCopy              | No        | Yes           | 0       |
| RotateOverlap           | No        | Yes           | 1       |
| RotateOverlapOverlap    | No        | Yes           | n       |
| RotateTransform         | Yes       | No            | n/a     |
| RotatePrism             | Yes       | Yes           | 0       |
| RotateShutter           | Yes       | Yes           | 1       |
| RotateShutterOverlap    | Yes       | Yes           | n       |

Dla tych obrotów, które zachowują oryginał, istnieje opcjonalne źródło obrotu. Domyślnie jest to dolny prawy obszar roboczy. Dozwolonymi wartościami są dowolne kierunki po przekątnej.

Wielkość obrotu (w krokach co 45 °) jest opcjonalna. Wartość domyślna to 2, tzn. 90 ° przeciwnie do ruchu wskazówek zegara (przeciwnie do ruchu wskazówek zegara). Dla tych obrotów, które zachowują oryginał, istnieją dwie alternatywne opcje: liczba całkowita dla wielu cyfr określa obrócenie obszaru roboczego raz dla każdej cyfry, a następnie scalenie wyników, podczas gdy lista liczb całkowitych po prostu powtarza polecenie dla każdego obrotu, a wyniki zmiennych zależą od tego, w jaki sposób płótno zmienia się pomiędzy.

Neil
źródło
Pytanie: Co to Transformznaczy?
CalculatorFeline,
@CalculatorFeline Dobre pytanie. Przypadki, w których Transform jest nie, są po prostu kopią znak po znaku. Na przykład standardowe odbicie „4> 2” to tylko znaki w odwrotnej kolejności, tj. „2> 4”. Nie zawsze jest to pożądane, więc Transform próbuje zmienić postać w najbardziej odpowiedni sposób, dlatego odbicie „4> 2” zmieniłoby się na „2 <4”. Transformacja może nie być najlepszym opisem tego, więc sugeruj coś lepszego.
Neil
Nie mogę wymyślić nic lepszego, więc powinieneś po prostu wyjaśnić, jak Transformdziała gdzieś w odpowiedzi.
CalculatorFeline
@CalculatorFeline Dodałem klucz do tabeli, na wypadek gdyby inne kolumny również nie były jasne.
Neil
Błędy powinny zostać teraz naprawione. Dziękuję również za poświęcenie czasu na napisanie tego wyjaśnienia!
Tylko ASCII
2

Używaj poleceń bez znaku polecenia

Wyrażenie, które nie jest częścią polecenia, jest drukowane.
Jeśli poprzedza go kierunek, wyrażenie jest drukowane w określonym kierunku.
Liczby są drukowane jako linia o określonej długości przy użyciu znaku wybranego z \/-|.

Jeśli po kierunku nie następuje wyrażenie, jest ono liczone jako ruch o jedną spację w określonym kierunku.

Uwaga: Czasami można to liczyć jako część poprzedniego polecenia, więc znak polecenia może być faktycznie wymagany. (dzięki Neil za przypomnienie)

Tylko ASCII
źródło
1
Trzeba jednak uważać na niejednoznaczności, ponieważ poprzednie polecenie może zaakceptować parametr opcjonalny.
Neil
2

Używaj wielokierunkowych

Niektóre polecenia mogą przyjąć multidirectionals: +X*|-\/<>^KLTVY7¬⌊⌈. To, do czego się rozwijają, jest tutaj . Ogólnie rzecz biorąc, lista kierunków zaczyna się od góry i kontynuuje zgodnie z ruchem wskazówek zegara.

Tylko ASCII
źródło
Czy jest jakiś konkretny powód, dla którego niektóre polecenia akceptują wielokierunkowe, a inne wymagają listy kierunków? (Może to mieć dobry powód, że przeoczam, ale próbowałem to zrobić ReflectButtterflyOverlap(:¬, Modulo(g, 2));.)
Neil
@Neil Nie sądzę, zmieni się JAK NAJSZYBCIEJ
tylko ASCII
0

Wykorzystaj w pełni Sum

Sum ma wiele przydatnych przeciążeń:

  • Na liście ciągów łączy je razem. Jeśli jednak możliwe jest, że lista może być pusta, dałoby to Brak, więc w takim przypadku użyj Join(..., "")zamiast tego.
  • Na niepustej liście liczb po prostu bierze ich sumę.
  • Na niepustej liście list konkatenuje je razem (spłaszcza do głębokości 1).
  • Na liczbie całkowitej pobiera sumę jej cyfr. (Wartości zmiennoprzecinkowe są obcinane do liczb całkowitych. Jeśli chcesz sumę miejsc dziesiętnych, najpierw rzut na ciąg znaków.)
  • W ciągu zawierającym tylko cyfry i opcjonalnie jeden .znak pobiera sumę cyfr.
  • W ciągu zawierającym liczby i separatory pobiera sumę rzutowanych liczb na int lub float (ale należy pamiętać, że -liczy się jako separator).

Dogodnym efektem ubocznym dwóch ostatnich zasad jest to, że jeśli użyjesz Sumznaku, cyfry 1-9zostaną przypisane do ich wartości, a wszystko inne zwróci zero, w przeciwieństwie do wartości Cast, które zawodzą w przypadku wartości innych niż cyfry.

Neil
źródło
0

Użyj podziału dla tablicy ciągów, podziel i rzutuj dla tablicy liczb

Podział tablicy ciągów to tylko trzy znaki narzutu, a podział i rzut to tylko cztery znaki narzutu. Porównaj to do pisania tablicy dosłownie, co wymagałoby początku i końca tablicy oraz separatora między każdym elementem tablicy.

Jeśli tablica liczb ma tylko liczby mniejsze niż 95, użyj rzutowania (jeśli wszystkie liczby są mniejsze niż 10) lub zindeksuj do jednej ze wstępnie zdefiniowanych zmiennych.

Tylko ASCII
źródło
0

Użyj Filtru, aby wyciąć pierwszy znak z tablicy lub łańcucha

Nawet jeśli masz szczęście, używając Slicedo krojenia pierwszy znak z łańcucha zajmuje 2 bajty: Slice(..., 1). Zajmie to więcej czasu, jeśli wyrażenie, które ma być pocięte, kończy się liczbą wymagającą separatora lub jeśli poniższy kod może być interpretowany jako wyrażenie, ponieważ w takim przypadku Slicebędzie chciał użyć go jako dodatkowego parametru.

Zamiast tego po prostu użyj Filter(..., k), który upuszcza pierwszy element, osiągając w ten sposób pożądany rezultat. (Oczywiście użyj odpowiedniej zmiennej indeksu pętli, jeśli twoje wyrażenie jest zagnieżdżone w innej pętli.) Zawsze są to 2 bajty i otaczający kod nie może na nie wpływać.

Neil
źródło