Wskazówki dotyczące gry w golfa w SmileBASIC

11

SmileBASIC zasługuje na większą uwagę. Widziałem tu tylko 3 użytkowników (w tym siebie!), Którzy udzielają odpowiedzi SB, i choć to mnie nie dziwi, to mnie rozczarowuje. Jest to płatny język, a także dialekt BASIC z pewnością zniechęca ludzi, ale dla tych, którzy go posiadają, jest dość elastyczny i, co zaskakujące, gra w golfa. Pomyślałem, że otworzę ten wątek z poradami i zobaczę, co się pojawi.

Oczekuję, że 12Me21 będzie często odwiedzać :)

ślimak_
źródło

Odpowiedzi:

11

wymienić string!=""zstring>""

SB pozwala ci dokonywać większych / mniej porównań napisów na podstawie ich współrzędnych kodowych. Jednak pusty ciąg jest uważany za najmniejszy ciąg, jaki istnieje.

Tak więc w sytuacjach, w których to robisz string!="", możesz użyć jednego string>""lub ""<string, ponieważ każdy ciąg jest większy niż ""i ""jest mniejszy niż każdy ciąg. W zależności od tego, czy używasz, <czy >zależy od tego, czy instrukcja wymaga spacji przed, czy po, aby być poprawną składnią, co może również zaoszczędzić bajty.

Na przykład:

WHILE S$!=""

można zamienić

WHILE S$>""

i dalej grał w golfa

WHILE""<S$
ślimak_
źródło
Wszystkie ciągi znaków są zgodne z prawdą. Nawet puste.
snail_
Ah, dobrze. Ma sens.
Rɪᴋᴇʀ
6

Korzystanie ?, ., @, i niezamknięte ciągi

Wiele dialektów obsługi języka BASIC ?dla drukowania, a SB nie jest wyjątkiem. Ogromną zaletą jest możliwość bardzo krótkiego wysyłania tekstu.

W SmileBASIC .jest oceniane na 0.0, więc można go użyć zamiast 0, aby zaoszczędzić miejsce. Na przykład: SPSET 0,21może być SPSET.,21, zapisując 1 bajt. ( SPSET0,21jest niepoprawny, ponieważ SPSET0może to być funkcja zdefiniowana przez użytkownika) EXEC.to bardzo krótki sposób na zrobienie pętli programu na zawsze (ale resetuje wszystkie zmienne, więc nie zawsze jest użyteczna)

Etykiety (stosowane GOTO, GOSUBi czytając DATA) są przedstawione @LABELw SmileBASIC. Użyte w wyrażeniu są traktowane jak ciągi znaków. Na przykład BGMPLAY"@305C"można zapisać jakoBGMPLAY@305C

Ciągi znaków są automatycznie zamykane na końcu wiersza (lub na końcu programu). ?"Hello, World!"można zapisać jako ?"Hello, World!. Można to również wykorzystać do zwiększenia czytelności programów poprzez podzielenie ich na wiele linii bez zmiany długości: ?"Meow"BEEP 69można

?"Meow
BEEP 69
12Me21
źródło
Wow, używanie etykiet do uruchamiania MML jest szalone. Nigdy bym o tym nie pomyślał, choć to ogranicza twój zestaw postaci.
snail_
Innym miejscem, z którego korzystałem, było sprawdzenie, czy cyfra szesnastkowa jest liczbą czy literą: @A<POP(H$)jest krótsza niż "@"<POP(H$)(to Anie ma znaczenia, sprawdza tylko pierwszy znak, ponieważ nigdy nie będzie taki sam)
12Me21
3

Użyj indeksowania ciągów zamiast MID$

Ta MID$funkcja jest powszechną funkcją w wielu językach BASIC, umożliwiającą uzyskanie podciągu gdzieś pośrodku łańcucha. Jeśli jednak potrzebujesz tylko znaku w jakimś indeksie, użycie indeksowania ciągów jest znacznie krótsze. Na przykład:

PRINT MID$("ABC",2,1)
PRINT "ABC"[2]

Oba te elementy drukują C. Ciągi znaków obsługują indeksowanie tablicowe na podstawie znaków, więc jeśli chcesz zaznaczyć tylko jeden znak na raz, jest to najlepszy sposób, aby to zrobić.

ślimak_
źródło
Powinieneś porozmawiać o tym, jak można w ten sposób modyfikować ciągi. A$=@AA:A$[2]="BD":A$[0]="":A$[2]="C"
12Me21
Prawdopodobnie napiszę zestaw odpowiedzi na temat tego, jak ciągi są w zasadzie tablicami znaków, ale nawet lepiej, ponieważ umieszczenie tego w jednym jest dość trudnym zadaniem.
snail_
... lub mógłbyś napisać;)
snail_
Nie znam się na tym, jak to działa w innych językach.
12Me21
2

Kiedy używać :(lub nie)

:Znak jest używany jako oświadczenie wyłącznika w SB. Zasadniczo używasz go do układania instrukcji w jednym wierszu w taki sposób:

PRINT "HELLO!":PRINT "GOODBYE!"

W przeciwnym razie przeciętny wyciąg jest dzielony przez nowy wiersz:

PRINT "HELLO!"
PRINT "GOODBYE!"

W rzeczywistości często nie trzeba wcale używać jelita grubego. Tak długo, jak instrukcje można podzielić na tokeny poprawne pod względem składniowym, parser ma tendencję do określania, kiedy jeden się kończy, a drugi zaczyna. To samo często dotyczy białych znaków.

PRINT"HELLO!"PRINT"GOODBYE!"

Oczywiście to nie zawsze działa. Zawsze występują niejednoznaczne przypadki i niepoprawne składnie, w których trzeba jawnie łamać instrukcje. Weź na przykład:

PRINT "HELLO";END

Średnik oznacza, że PRINToczekuje wydrukowania innego wyrażenia, chyba że instrukcja tam się zepsuje (używamy wiszących średników w celu stłumienia nowego wiersza). Tutaj zakłada, że ENDma być wartością, mimo że jest słowem kluczowym, i próbuje ją wydrukować, w wyniku czego w błędzie. Dlatego musimy wyraźnie złamać to stwierdzenie, czy to dwukropek, czy nowy wiersz.

Ogólnie rzecz biorąc, jeśli coś wydaje się niejednoznaczne, spróbuj, czy działa. Jeśli tak się nie stanie, złam instrukcję. Ponadto wszystko, co mogłoby spowodować niepoprawną składnię, nie jest poprawnie podświetlane, jak wspomniano w 12Me21.

ślimak_
źródło
2

Użyj wyróżnienia składni!

Edytor kodu SmileBASIC ma wbudowany wyróżnik składni, którego można użyć do ustalenia, czy kod będzie działał, czy nie. Na przykład, jeśli spróbujesz to zrobić BEEP0, nie podświetli go, ponieważ między funkcją a cyfrą musi być odstęp. Jednak BEEP.działa, ponieważ. nie jest cyfrą.

Normalnie kod podobny X=7BEEPjest poprawny, ponieważ funkcje nie mogą zaczynać się od cyfry, więc SB przyjmuje to 7i BEEPsą oddzielne. Jednak. X=7ENDNIE jest dozwolone (i nie jest podświetlone), ponieważ próbuje interpretować 7E...jako liczbę, ale ponieważ po E nie ma cyfry, zawodzi, powodując błąd. Zwykle trudno byłoby to rozgryźć, ale dzięki bardzo niezawodnemu rozświetlaczowi składni znacznie łatwiej jest powiedzieć, co możesz, a czego nie możesz zrobić.

Mój wyróżnik składni SmileBASIC został zaprojektowany (mam nadzieję) idealnie pasujący do zachowania SB, więc możesz go użyć do sprawdzenia poprawności kodu.

<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8">
		<script src="https://12Me21.github.io/sbhighlight3/sbhighlight.js"></script>
		<link rel="stylesheet" type="text/css" href="https://12Me21.github.io/sbhighlight3/style.css">
		<link rel="stylesheet" type="text/css" href="https://12Me21.github.io/external/smilebasicfont.css">
		<script>
			function update(event){
				$code.textContent=$input.innerText;
				//must be innerText since contentedible and textContent are too dumb to understand linebreaks
				//contenteditable adds <br>s which textContent ignores
				//whyyyyy
				applySyntaxHighlighting($code,true);
			}
			
			function setCaretPosition(elem,caretPos){
				if(elem){
					if(elem.createTextRange) {
						var range=elem.createTextRange();
						range.move('character',caretPos);
						range.select();
					}else{
						if(elem.selectionStart){
							elem.focus();
							elem.setSelectionRange(caretPos,caretPos);
						}else
							elem.focus();
					}
				}
			}
		</script>
		<style>
			#editcontainer{
				position: absolute;
			}
			#editcontainer>pre{
				position: absolute;
				left: 0;
				top: 0;
				
			}
			pre.csssucks *{
				color:transparent !important;
				background-color:transparent !important;
				caret-color: white;
			}
			pre.csssucks {
				color:transparent !important;
				background-color:transparent !important;
				caret-color: white;
				border-color:transparent;
				padding-right: 50ch;
			}
		</style>
	</head>
	<body>
		Use SB font:<input type="checkbox" autocomplete="off" onchange="$code.dataset.sbfont=$input.dataset.sbfont=this.checked;update()"></input>
		<button onclick="update()">force update</button>
		<hr>
		<div id="editcontainer">
			<pre id="$code">test</pre>
			<pre id="$input" class="csssucks" contenteditable="true" spellcheck="false" onkeydown="setTimeout(function(){update(event)},2);">test</pre>
		</div>
	</body>
</html>

12Me21
źródło
1

Unikaj operatora MOD

Operator modułu jest naprawdę długi i należy go w miarę możliwości unikać.

Jeśli otrzymujesz znaki z ciągu, możesz po prostu powtórzyć ciąg:

"ABC"[X MOD 3]
("ABC"*9)[X] (assuming X will always be less than 27)

Czasem ANDzamiast tego możesz zapisać 1 postać :

X MOD 4
3AND X
12Me21
źródło
0

Pominięcie OUTzwracanych wartości

Funkcja OUTformularza to funkcja z wieloma zwrotami; określasz zmienne, aby akceptować zwracane wartości po OUTsłowie kluczowym. Przykład użycia DTREAD:

DTREAD OUT yearVar,monthVar,dayVar

Ale co, jeśli chcesz tylko jedną z wartości, jak bieżący miesiąc? Możesz „zignorować” pozostałe wartości, po prostu nie wpisując żadnej nazwy zmiennej, aby je zaakceptować! Musisz jednak zostawić przecinki (oprócz sporadycznego opcjonalnego zwrotu).

DTREAD OUT ,monthVar,

Na które można dalej grać w golfa

DTREAD OUT,M,
ślimak_
źródło
0

Posługiwać się LAST()

Teraz, gdy SmileBASIC 4 jest już dostępny w Japonii, możemy sprawdzić niektóre z potencjalnych oszczędności w golfa. Tym, co od razu mi się podoba, jest nowa LAST()funkcja, która zwraca ostatni indeks tablicy lub łańcucha. Możesz zapisać jeden bajt.

LEN(v)-1 'old way
LAST(v)  'new way
ślimak_
źródło