laserpanzerwal
Goto Top

Variable aufrufen, deren Name in einer Variable gespeichert ist.

Ich und ein Kollege haben uns vorgenommen, ein Spiel (in diesem Fall Schiffe versenken) als Batch-Datei umzusetzen. Jeder versucht es gerade für sich umzusetzen, und natürlich sehe ich es als persönliche Herausforderung als erster fertig zu werden;)
Allerdings komme ich bereits jetzt nicht weiter, weil ich versuche, eine Variable aufzurufen, deren Name sich aus Werten von weiteren Variablen ergibt, die wiederum in einer FOR-Schleife festgelegt werden.
Da das ganze jetzt wahrscheinlich recht verwirrend klingt, hier mal der bisherige Quelltext. Leider habe ich ihn noch nicht wirklich mit Kommentaren versehen, es dürfte aber hoffentlich erkennbar sein, was ich versuche. Die Deklaration der 200 Variablen lasse ich der Übersicht halber weg, sie sind anfangs alle mit einer Tilde (~) gefüllt.

@echo off
setlocal ENABLEDELAYEDEXPANSION
set a1=~
set a2=~
::Hier ist im richtigen Quelltext alles von a1 bis a100 und b1 bis b100 deklariert....
set b99=~
set b100=~
set planning=true

:MAINLOOP

echo   THE ENEMY               YOU
echo   1 2 3 4 5 6 7 8 9 10    1 2 3 4 5 6 7 8 9 10
echo 1  %a1% %a2% %a3% %a4% %a5% %a6% %a7% %a8% %a9% %a10%     %b1% %b2% %b3% %b4% %b5% %b6% %b7% %b8% %b9% %b10%
echo 2  %a11% %a12% %a13% %a14% %a15% %a16% %a17% %a18% %a19% %a20%     %b11% %b12% %b13% %b14% %b15% %b16% %b17% %b18% %b19% %b20%
echo 3  %a21% %a22% %a23% %a24% %a25% %a26% %a27% %a28% %a29% %a30%     %b21% %b22% %b23% %b24% %b25% %b26% %b27% %b28% %b29% %b30%
echo 4  %a31% %a32% %a33% %a34% %a35% %a36% %a37% %a38% %a39% %a40%     %b31% %b32% %b33% %b34% %b35% %b36% %b37% %b38% %b39% %b40%
echo 5  %a41% %a42% %a43% %a44% %a45% %a46% %a47% %a48% %a49% %a50%     %b41% %b42% %b43% %b44% %b45% %b46% %b47% %b48% %b49% %b50%
echo 6  %a51% %a52% %a53% %a54% %a55% %a56% %a57% %a58% %a59% %a60%     %b51% %b52% %b53% %b54% %b55% %b56% %b57% %b58% %b59% %b60%
echo 7  %a61% %a62% %a63% %a64% %a65% %a66% %a67% %a68% %a69% %a70%     %b61% %b62% %b63% %b64% %b65% %b66% %b67% %b68% %b69% %b70%
echo 8  %a71% %a72% %a73% %a74% %a75% %a76% %a77% %a78% %a79% %a80%     %b71% %b72% %b73% %b74% %b75% %b76% %b77% %b78% %b79% %b80%
echo 9  %a81% %a82% %a83% %a84% %a85% %a86% %a87% %a88% %a89% %a90%     %b81% %b82% %b83% %b84% %b85% %b86% %b87% %b88% %b89% %b90%
echo 10 %a91% %a92% %a93% %a94% %a95% %a96% %a97% %a98% %a99% %a100%     %b91% %b92% %b93% %b94% %b95% %b96% %b97% %b98% %b99% %b100%

if "%planning%"=="true" (  
	goto PLANNINGLOOP
) else (
	goto BATTLELOOP
)

:PLANNINGLOOP
for /L %%i IN (2 1 5) do (
	:REPEATCOMPUTERPLANNING
	set /a zeile=!random! %%10 + 1
	set /a spalte=!random! %%10 + 1
	set /a richtung=!random! %%2
	set /a laenge=7 - %%i
	set /a var=!zeile! * 10 - 10
	set /a var=!var! + !spalte!
	if "!richtung!"=="1" (  
	::waagerecht
		for /L %%o IN (0 1 !laenge! -1) do (
			set /a temp=!zeile! * 10
			if !var! GTR !temp! (
				goto REPEATCOMPUTERPLANNING
			)
			echo !var!
			echo %%o
			set /a tempvar=!var! + %%o
			if NOT "!a!tempvar!!" == "~" (  
				goto REPEATCOMPUTERPLANNING
			)
		)
		for /L %%o IN (0 1 !laenge! -1) do (
			set tempvar=!var! + %%o
			set a!tempvar!=M
		)
	) else (
	::senkrecht
	
	)
)

In Zeile 50 versuche ich, zu prüfen, ob der Wert der zufällig ausgesuchten Variable eine Tilde ist (also Wasser im Spiel), oder nicht (also ein Schiff, ein beschossenes Feld oder was auch immer).
Das Problem scheint zu sein, dass ich zwar durchaus "echo a!tempvar!" ausgeben oder in einer weiteren variable speichern kann, er mich aber den inhalt dieser variable nicht benutzen lässt, um z.b. die variable a34 aufzurufen (wenn tempvar ==34)
Die Möglichkeiten, das umzusetzen, die ich bisher gefunden habe, mögen ausserhalb der Schleife funktionieren, hier tun sie es aber leider nicht.
Ich hoffe es ist klar was ich hier probiere.
Wer kann mir weiterhelfen?

Content-ID: 175746

Url: https://administrator.de/contentid/175746

Ausgedruckt am: 24.11.2024 um 16:11 Uhr

icsat
icsat 04.11.2011 um 08:16:38 Uhr
Goto Top
Hallo erst mal! (so viel Zeit muss sein)

@echo off
Ist zum finden von Fehlern erst mal eine schlechte Idee!
if NOT "!a!tempvar!!" == "~" (  
Da Dir das entfernen von Echo Off allerdings in diesem Fall (Variablen mit !) keinen Aufschluss über die Auflösung der Variablen in dieser Zeile gibt hat sich bei mir zusätzlich bewährt, vor problematisch zeilen mal ein echo zu setzen und das Ergebnis anzuschauen und zu verstehen was wie aufgelöst wird.
echo if NOT "!a!tempvar!!" == "~" (  
Da die Variable "a" (!a!) nicht definiert ist und "" (!!) auch keinen Sinn ergibt, sollte das Ergebnis in diesem Fall etwa
if NOT "tempvar" == "~" (  
lauten.

Die Lösung für Dein Problem hast Du imho ja schon fast selber geschrieben:
Zitat von @LaserPanzerWal:
...
"echo a!tempvar!" ausgeben oder in einer weiteren variable speichern
...
Speicher Dir den Kram einfach in noch einer Variablen zwischen:
set "nochnetempvar=a!tempvar!  
und verwende diese dann für deine Abfrage:
if NOT "!nochnetempvar!" == "~" (  

Schöne Restwoche

icsAT

(auch dafür war noch Zeit da!)
jeb-the-batcher
jeb-the-batcher 04.11.2011 um 11:12:39 Uhr
Goto Top
Halli Hallo,

und noch eine Technik, nur der Vollständigkeit halber (weil die Methode von icsAT ansich gut funktioniert und übersichtlicher ist).

FOR /F "delims=" %%V in ("!tempvar!") DO (  
  if NOT "!a%%V!"=="~" (  
   goto REPEATCOMPUTERPLANNING
 )
)

Dabei fällt mir noch auf, dass du versuchst innerhalb einer FOR-loop wild mit GOTO's herum zuspringen.
Zum einen verwendet man GOTO mal so gar nicht und nimmer um den Code lesbar und verständlich zu halten(Ok diesen Punkt kann man bei Batch vergessen).

Zum anderen stoppt ein GOTO sofort jede FOR-Loop im aktuellem CALL-Scope,
sprich das ist das Ende deiner Schleife.

Ich denke ein paar elegante Funktionen würden der Lesbarkeit hier ohnehin nicht schaden.

jeb
mathe172
mathe172 04.11.2011, aktualisiert am 18.10.2012 um 18:49:00 Uhr
Goto Top
Hallo,

entweder ich überseh da was, oder bei der Möglichkeit von icsat ist etwas falsch. Man prüft ja, ob der Inhalt von "Nochnetempvar" =="~" ist. Der Inhalt ist aber "a23" oder "a15".

Vielleicht noch eine andere Möglichkeit:
set "a15=~"  
set "tempvar=15"  
call echo %a%tempvar%%

Und was du dir auch noch anschauen solltest sind Pseudo-Arrays in Batch - das würde das ganze erheblich verkürzen. Schau mal #comment-toc15 hier.

MfG,
Mathe172
jeb-the-batcher
jeb-the-batcher 04.11.2011 um 15:29:13 Uhr
Goto Top
Hallo mathe0815,

wobei das mit den Pseudo-Arrays vermutlich am Ende auf die gleiche Problematik hinausläuft face-smile

Kleiner Tippfehler (es fehlt ein %)
call echo %%a%tempvar%%
Aber das übel an der CALL Lösung ist, CALL ist extrem langsam und auch nicht sicher an dieser Stelle.

Dies testen und wundern ...
echo rem /? >echo%~x0
set "a15=~"   
set "tempvar=15"   
call echo %%a%tempvar%%

Das erklärt auch warum CALL so langsam ist face-smile

jeb
mathe172
mathe172 04.11.2011 um 17:11:05 Uhr
Goto Top
@ jeb: Also bei mir funktioniert meine Variante, obwohl ich nicht verstehe, warum es nicht "call echo %%a%tempvar%%%" heissen muss.

Mathe172
icsat
icsat 04.11.2011 um 20:45:40 Uhr
Goto Top
Hallo mathe172,

wenn man auf die Schnelle ungetestete Codezeilen postet darf man sich nicht wundern, wenn am Ende nur Müll dabei rauskommt! Das oben produzierte Ergebnis hat am Ende genau das Problem, welches der TE ja ausführlich beschrieben hat. Es lässt sich so nicht weiterverarbeiten.

Daher ziehe ich meinen unqualifizierten Kommentar von heute Morgen hiermit zurück. Vielen Dank, dass Dir das aufgefallen ist.

Der von Dir angesprochene Call wäre da tatsächlich ein Lösung. Damit müsste meine Definition der zusätzlichen Variable
call set "nochnetempvar=%%a!tempvar!%%"  
lauten, wobei das auch nur dann funktionieren kann, wenn die "a"-Variable außerhalb der Schleife gesetzt wurde. Ich würde hier eindeutig die Variante von jeb-the-batcher vorziehen.

Gruß icsAT
icsat
icsat 04.11.2011 um 21:08:41 Uhr
Goto Top
Hallo,

die erste Variante von mathe172
call echo %a%tempvar%%
funktioniert bei der direkten Eingabe. Im Batch hingegen ist das Ergebnis "tempvar".

Die Variante von jab-the-batcher
call echo %%a%tempvar%%
funktioniert nicht. Bei direkter Eingabe "%~" und im Batch "a15".

die zweite Variante von mathe172
call echo %%a%tempvar%%%
funktioniert im Batch. Bei der direkten Eingabe hingegen ist das Ergebnis "%~%".

Da das eigentliche Problem aber gelöst ist, war dieser Kommentar dann wohl OT. Sorry dafür.


Schönes WE

icsAT
jeb-the-batcher
jeb-the-batcher 05.11.2011 um 10:18:54 Uhr
Goto Top
Hallo icsAt,

Zitat von @icsat:

call set "nochnetempvar=%%a!tempvar!%%"  
lauten, wobei das auch nur dann funktionieren kann, wenn die "a"-Variable außerhalb der Schleife gesetzt wurde.

Die "a"-Variable gibt es ja gar nicht, die Variable heißt ja "a15" und dein Code funktioniert natürlich auch innerhalb der Schleife,
dafür ist ja der CALL Befehl da.

Man kann auch ganz ohne delayed expansion innerhalb der Schleife arbeiten
call call set "contentOfVar=%%%%a%%tempvar%%%%%%"  

Aber scheinbar hat keiner mein zweites "Wunder"-Beispiel ausprobiert face-smile
Da hätte ich nämlich mit Reaktionen gerechnet

jeb
pieh-ejdsch
pieh-ejdsch 05.11.2011 um 22:21:21 Uhr
Goto Top
moin jeb,

wieso denn "Wundern"? - Fragen!
call ruft die Batch echo.cmd mit dem Parameter, welcher aus der %%Pseu%DOvariable%% besteht aus dem Verzeichnis auf.
Nur der Parameter entspricht nicht ganz der erwarteten Variable - warum überhaupt?
erst wird %tempvar% nach 15 aufgelöst (was warscheinlich heist: erst werden Vorhandene Variablen aufgelöst) und die Variable %a die gibt es nicht
  • aber das komischste daran: die Variable "%a15" gibt es nit - warum steht dann etwas da?

[Edit]
ach ja - erst wird das Dopplte Prozent zu einem Prozent und dann %Tempvar% aufgelöst. Das Letzte Prozent ist nur eins und wird im Batch ja gelöscht.
ist geklärt warum doch etwas da steht.
[/Edit]

for /L %%o IN (0 1 !laenge! -1) do ( 
Auch wenn es geht: für was ist -1? Falls das Boot zu kurz ist? laenge ist doch immer definiert.

Gruß Phil
icsat
icsat 07.11.2011 um 15:02:04 Uhr
Goto Top
Hallo,

schönen Start in die Woche.

Zitat von @jeb-the-batcher:
Die "a"-Variable gibt es ja gar nicht, die Variable heißt ja "a15" und dein Code funktioniert
natürlich auch innerhalb der Schleife,
dafür ist ja der CALL Befehl da.

Mit die "a"-Variable war natürlich a1 bis a100 oder in unserem Beispiel a15 gemeint. Ansonsten gebe ich Dir recht.


Gruß icsAT
LaserPanzerWal
LaserPanzerWal 07.11.2011 um 19:58:29 Uhr
Goto Top
Hallo wiedereinmal, und Danke schonmal für die vielen Antworten.

Leider funktioniert das mit der Variable trotzdem nicht so recht. Es klappt zwar mit den beschriebenen Möglichkeiten wunderbar in einer neuen Batch, aber wenn ich es in einer Schleife laufen lassen will weigert er sich strikt, so zu funktionieren wie ich das gerne möchte. Egal wie ich es anstelle, er gibt mir entweder den Variablennamen aus (z.b. a15) oder er meldet mir dass Echo off gesetzt ist, also die angegebene Variable vermutlich leer (und damit nicht richtig) ist. Allerdings will ich auch ungern die Schleife durch ein Pseudo-Schleifen-GOTO-gewurstel ersetzen, nur um das Problem zu umgehen, denn das kann nicht die wirklich sinnvolle Lösung sein.
Mach ich einfach nur irgendetwas falsch, oder klappt das in einer Schleife nicht so einfach?

Grüße,
der Wal =)
mathe172
mathe172 09.11.2011 um 18:02:21 Uhr
Goto Top
Hallo,

wahrscheinlich könnte man dir einfacher Helfen, wenn du uns den Code zeigen würdest.
Schau dir mal "setlocal enabledelayedexpansion" an. Und was die Pseudoschleifen angeht, ich würde eher Pseudo-Call-Subs benutzen

MfG,
Mathe172