lenny099: Brauche Hilfe mit Schulprojekt

Hey, ich und ein Freund von mir haben ein Problem mit unserem Schulprojekt und wir finden die Lösung einfach nicht. Wir programmieren in der Schule ein Memory wir sind fast fertig aber uns fehlt die Überprüfung ob zwei Karten gleich sind. Wir wollen das mit den Variablen 'Bild1' und 'Bild2' machen kriegen es aber nicht hin da Bild1 irgendwie wieder glöscht wird. Wir würden uns für jede Hilfe freuen

<html>

<head>
	<title>Erstes Spiel!</title>
</head>

<script>
	var k = 0;
	var bild1;
	var bild2;
  var paar1, paar2;
	var hit = 0;
	var back = "lol.png";
	var r1;
	var r2;
	var temp;
  var timer;
	var i;

	var kartenArray = ["kat.jpg", "kat.jpg", "teemo.jpg", "teemo.jpg", "blitz.jpg", "blitz.jpg", "yi.jpg", "yi.jpg", "garen.jpg", "garen.jpg", "yasuo.jpg", "yasuo.jpg",
		"vel.jpg", "vel.jpg", "annie.jpg", "annie.jpg"];

	for (var s = 0; s < 1010; s = s + 1) {  // Hier wird gemischt
		r1 = parseInt(Math.random() * 8) + 1;
		r2 = parseInt(Math.random() * 8) + 1;
		temp = kartenArray[r1 - 1];
		kartenArray[r1 - 1] = kartenArray[r2 - 1];
		kartenArray[r2 - 1] = temp;
	}

	function choose(i) { // K überprüft wie oft ein Bild angeklickt wurde.i speichert das Bild 				und den Pfad, welches angeklickt wurde.
		if (k < 2) {

			if (k == 0) {
				var bild1 = i;
				var paar1 = kartenArray[i - 1];
        alert('erste Prüfung')
				alert(bild1);
				alert(bild2);
				alert(i);


			} else { //Wenn K nicht 0 ist wird das zweite Bild gespeichert und der Pfad
				var bild2 = i;
				var paar2 = kartenArray[i - 1];
        alert('zweitePrüfung')
        	alert(bild1);
					alert(bild2);
					alert(i);

			}
			k++;


			document.images[i-1].src = kartenArray[i-1];
      prompt(paar1, paar2);


			if (k == 2) { //Wenn K gleich 2 ist dann sollte eigentlich übprüft werden ob die gleichen Karten angeklickt wurden.
        alert('dritte Prüfung')
				alert(bild1);
				alert(bild2);
				alert(i);
				if (kartenArray[bild1] == kartenArray[bild2]){

					alert('jaaaaaaa');
				} else {
					alert('neeeeeeeeeein');


          k = 0;

				}
			}
		}
	}

	function zurueckdrehen(b, c) {  //Hier sollen die karten zurückgedreht werden wenn sie nicht ein Paar sind.
		document.images[b - 1].src = "lol.png";
		document.images[c - 1].src = "lol.png";
		k = 0;
	}
</script>

<body background="hintergrund.jpg">
	<h1 id="1"></h1>
	<br><br>
	<table align=center valign=middle border="3">
		<tr>
			<td> <img src="Lol.png" height="180" width="180" onclick="choose(1)">
			</td>
			<td><img src="Lol.png" height="180" width="180" onclick="choose(2)">
			</td>
			<td><img src="Lol.png" height="180" width="180" onclick="choose(3)">
			</td>
			<td><img src="Lol.png" height="180" width="180" onclick="choose(4)">
			</td>
		</tr>
		<tr>
			<td> <img src="Lol.png" height="180" width="180" onclick="choose(5)">
			</td>
			<td> <img src="Lol.png" height="180" width="180" onclick="choose(6)">
			</td>
			<td><img src="Lol.png" height="180" width="180" onclick="choose(7)">
			</td>
			<td> <img src="Lol.png" height="180" width="180" onclick="choose(8)">
		</tr>
		<tr>
			<td><img src="Lol.png" height="180" width="180" onclick="choose(9)"></td>
			<td><img src="Lol.png" height="180" width="180" onclick="choose(10)"></td>
			<td><img src="Lol.png" height="180" width="180" onclick="choose(11)"></td>
			<td><img src="Lol.png" height="180" width="180" onclick="choose(12)"></td>
		</tr>
		<tr>
			<td><img src="Lol.png" height="180" width="180" onclick="choose(13)"></td>
			<td><img src="Lol.png" height="180" width="180" onclick="choose(14)"></td>
			<td><img src="Lol.png" height="180" width="180" onclick="choose(15)"></td>
			<td><img src="Lol.png" height="180" width="180" onclick="choose(16)"></td>
		</tr>
	</table>

</body>

</html>
  1. @@lenny099

    Wir würden uns für jede Hilfe freuen

    Damit man überhaupt helfen kann: Online-Beispiel, bitte.

    Aus den ersten Blick lässt sich sagen: Da fehlt ein bisschen bei der Grundstruktur.

    <img src="Lol.png" height="180" width="180" onclick="choose()"> funktioniert nicht. Zum einen wegen fehlender Alternativtexte.

    Zum anderen sind img-Elemente allgemein nicht clickbar. Damit die Bilder auch per Tastatur clickbar sind, die img jeweis in einen button tun:

    <td>
    	<button onclick="choose()">
    		<img src="Lol.png" alt="Rückseite">
    	</button>
    </td>
    

    Dem button kannst du mit CSS Rahmen und Hintergrund wegnehmen:

    button
    {
    	padding: 0;
    	background: transparent;
    	border: none;
    }
    

    (Eine andere Möglichkeit wäre, button neben dem img im td und per CSS über die gesamte Fläche des Bilds zu legen – wäre etwas aufwendiger.)

    Eine andere Überlegung wäre, keine Tabelle zu verwenden, sondern eine Liste, und die Bilder mit CSS Grid plazieren.

    LLAP 🖖

    --
    „Wer durch Wissen und Erfahrung der Klügere ist, der sollte nicht nachgeben. Und nicht aufgeben.“ —Kurt Weidemann
    1. Lieber Gunnar,

      Zum anderen sind img-Elemente allgemein nicht clickbar. Damit die Bilder auch per Tastatur clickbar sind, die img jeweis in einen button tun:

      leider habe ich dafür auf die Schnelle keinen Wettgegner gefunden...

      Liebe Grüße,

      Felix Riesterer.

      1. @@Felix Riesterer

        Lieber Gunnar,

        Zum anderen sind img-Elemente allgemein nicht clickbar. Damit die Bilder auch per Tastatur clickbar sind, die img jeweis in einen button tun:

        leider habe ich dafür auf die Schnelle keinen Wettgegner gefunden...

        Hach, ich wünschte, ich könnte dich deine Wetten verlieren lassen und müsste das nicht immer wieder sagen …

        LLAP 🖖

        --
        „Wer durch Wissen und Erfahrung der Klügere ist, der sollte nicht nachgeben. Und nicht aufgeben.“ —Kurt Weidemann
        1. Hallo,

          Hach, ich wünschte, ich könnte dich deine Wetten verlieren lassen und müsste das nicht immer wieder sagen …

          Kann da nicht mal jemand einen Gunnar-Bot schreiben?

          Gruß
          Kalk

          1. Lieber Tabellenkalk,

            Kann da nicht mal jemand einen Gunnar-Bot schreiben?

            den nennen wir dann lieber anders. Wie fändest Du ARIA-Monster?

            Liebe Grüße,

            Felix Riesterer.

          2. Hi,

            Kann da nicht mal jemand einen Gunnar-Bot schreiben?

            Ist Gunnar etwa gar kein Bot?

            cu,
            Andreas a/k/a MudGuard

            1. Hallo,

              Ist Gunnar etwa gar kein Bot?

              Lässt du Subbotnik gelten?

              Gruß
              Kalk

    2. @@Gunnar Bittersmann

      <td>
      	<button onclick="choose()">
      		<img src="Lol.png" alt="Rückseite">
      	</button>
      </td>
      

      An der Stelle habe ich schon mal die width- und height-Attribute weggelassen. Wenn die für alle Bilder gleich sind, kann man das auch mit einer Angabe im CSS für alle Bilder auf einmal haben – wenn man die Bilder denn überhaupt skalieren möchte.

      width- und height-Attribute können helfen, das Seitenlayout gleich initial so zu rendern, dass der Platz für die (noch nicht geladenen) Bilder freigehalten wird. Das ist hier nicht erforderlich, denke ich.

      Im nächsten Schritt wäre auch noch das onclick-Attribut wegzulassen und der Eventhandler im JavaScript zu registrieren (addEventListener, siehe molily). Am besten nicht für jeden Button einzeln, sondern per event delegation.

      LLAP 🖖

      --
      „Wer durch Wissen und Erfahrung der Klügere ist, der sollte nicht nachgeben. Und nicht aufgeben.“ —Kurt Weidemann
  2. Moin lenny099,

    deine Variablen …

    	var bild1;
    	var bild2;
      var paar1, paar2;
    

    … werden hier …

    				var bild1 = i;
    				var paar1 = kartenArray[i - 1];
    

    … und hier lokal „überschrieben“:

    				var bild2 = i;
    				var paar2 = kartenArray[i - 1];
    

    Viele Grüße
    Robert

  3. (Edit: Verflixt, zu langsam 😉)

    Hallo lenny099,

    guckt mal, wo ihr die Variablen bild1 und bild2 überall deklariert. Und hört dabei nicht bei 1 mit Zählen auf...

    JavaScript verwendet immer die nächstliegende Deklaration einer Variablen.

    Rolf

    --
    sumpsi - posui - clusi
  4. Hallo lenny099,

    euer Memory ist als erstes Lernprogramm eine schöne Idee. Ich möchte noch ein paar Tipps beisteuern, wie ihr euren Code verbessern könnt.

    1. Arrayzugriffe. Array-Indexe beginnen in Javascript bei 0. Es ist daher eigentlich ganz sinnvoll, wenn man den Rest des Programms auf dieser Vorgabe aufbaut, und nicht bei jedem Zugriff 1 subtrahiert. Das bedeutet in euerem Spielfeld dann auch, im click-Handler eine um 1 kleinere Zahl an choose zu übergeben.

    2. Mischen der Karten. Einfach tausend mal zwei beliebige Karten vertauschen ist eine Möglichkeit. Bei 64 Karten (Standard-Memory) wird das aber nicht reichen. Eine bessere Idee ist es, wenn ihr Karten aus einer zufälligen Position aus dem Array "zieht"

    var eingabeStapel = [ "kat.jpg", "kat.jpg", "teemo.jpg", "teemo.jpg", "blitz.jpg", "blitz.jpg", "yi.jpg", "yi.jpg", "garen.jpg", "garen.jpg", "yasuo.jpg", "yasuo.jpg",
    		"vel.jpg", "vel.jpg", "annie.jpg", "annie.jpg" ];
    
    // Beginne mit leerem KartenArray
    var kartenArray = [];
    
    // Bei 16 Karten: Schleife von 15 bis 0
    for (var i=eingabeStapel.length-1; i>= 0; i--) {
       // Zufallszahl von 0 bis i
       var p = parseInt(Math.random() * i);
       // Ermittelte Karte ans kartenArray anhängen
       kartenArray.push(eingabeStapel[p]);
       // gezogene Karte durch letzte Karte im eingabeStapel überschreiben
       eingabeStapel[p] = eingabeStapel[i];
    }
    

    Auf diese Weise bekommt ihr auch eine Zufallsverteilung, braucht aber nur so viele Durchläufe wie ihr Karten habt. Der letzte Schritt in der Schleife, wo die wegkopierte Karte durch die letzte Karte des Eingabestapels überschrieben wird, löst das Problem dass es in JavaScript keine Funktion gibt, die mitten in einem Array einen Eintrag entfernt und die folgenden Einträge umnummeriert. Sowas kann man zwar nachbauen, das wäre aber langsam. Das Kopieren des letzten Eintrags füllt die entstandene Lücke ebenfalls, und weil i pro Durchlauf um 1 kleiner wird, wird der letzte Eintrag in den folgenden Durchläufen nicht mehr verwendet.

    1. Zugriff auf die Bilder. document.images ist ungeeignet, weil darin JEDES Bild auf der Seite enthalten ist. Wenn ihr ein nettes Titelbild auf die Seite setzt, müsstet ihr die Zugriffe auf document.images anpassen. Sowas nennt man zerbrechlichen Code, und sowas möchte man vermeiden. Was ihr tun könnt, ist dies: Gebt der table ein id Attribut, damit ihr euer "Spielfeld" im JavaScript eindeutig identifizieren könnt. Nun verwendet die Funktion querySelectorAll, um alle <img> Elemente darin zu finden:
    var spielfeld = document.getElementById("spielfeld");
    var memoryBilder = spielfeld.querySelectorAll("img");
    
    // Man kann das auch zu einer Zeile zusammenfassen:
    var memoryBilder = document.getElementById("spielfeld").querySelectorAll("img");
    

    querySelectorAll ist eine Funktion, die CSS Selektoren verwendet um HTML Elemente zu finden. "img" ist ein Selektor, der img-Elemente findet. Weil querySelectorAll auf dem Spielfeld-Element aufgerufen wird, sucht die Funktion nur die Bilder im Spielfeld.

    Rolf

    --
    sumpsi - posui - clusi
    1. @@Rolf B

      1. Mischen der Karten. Einfach tausend mal zwei beliebige Karten vertauschen ist eine Möglichkeit.

      Eine andere ist ein Einzeiler (von CSS Tricks: Shuffle array):

      kartenArray.sort(function () { return 0.5 - Math.random() });
      

      Mit arrow function sieht’s so aus:

      kartenArray.sort(() => 0.5 - Math.random());
      

      Oder Fisher–Yates Shuffle (s.a. Wikipedia, Stack Overflow)

      Mischt eigentlich beides gleich gut?

      Edit Rolf B, 18.08.2021: Gunnar möchte seinen Vorschlag zurückziehen und findet ihn nicht mehr gut. Diskussion hier.

      querySelectorAll ist eine Funktion, die CSS Selektoren verwendet

      Eben, Selektoren werden nicht nur in CSS verwendet, sondern auch anderswo, bspw. in JavaScript. Deshalb heißen sie besser „Selektoren“ (ohne CSS). Damit hätte sich auch das Problem des Deppenleerzeichens erledigt.

      LLAP 🖖

      --
      „Wer durch Wissen und Erfahrung der Klügere ist, der sollte nicht nachgeben. Und nicht aufgeben.“ —Kurt Weidemann
  5. Lieber lenny099,

    ich und ein Freund von mir

    Stil: Der Esel nennt sich immer zuerst.

    haben ein Problem mit unserem Schulprojekt

    Für ein Schulprojekt seid ihr in einer recht komplexen Sache unterwegs. Gut so!

    Wir programmieren in der Schule ein Memory wir sind fast fertig

    Ich habe für mein Memory-Spiel einen anderen Ansatz gewählt, damit ich das Script so oft einsetzen kann, wie ich will. Ihr müsstet jeweils das JavaScript umschreiben, wenn ihr andere Karten einsetzen wollt. Und mehrere Memory-Spiele auf einer Seite sind mit eurem Ansatz auch nicht möglich. Dazu bräuchte man das ganze Spiel als beliebig oft instantiierbares Objekt.

    Liebe Grüße,

    Felix Riesterer.

  6. @@lenny099

    	var kartenArray = ["kat.jpg", "kat.jpg", "teemo.jpg", "teemo.jpg", "blitz.jpg", "blitz.jpg", "yi.jpg", "yi.jpg", "garen.jpg", "garen.jpg", "yasuo.jpg", "yasuo.jpg",
    		"vel.jpg", "vel.jpg", "annie.jpg", "annie.jpg"];
    

    Nicht die beste Idee, alle Karten doppelt aufzuschreiben. Die Arbeit kann man dem Computer überlassen, der kann das besser und vergisst nicht aus Versehen mal eine.

    var bilderArray = ["kat.jpg", "teemo.jpg", "blitz.jpg", "yi.jpg", "garen.jpg", "yasuo.jpg", "vel.jpg", "annie.jpg"];
    
    var kartenArray = bilderArray.concat(bilderArray);
    

    hängt alle Elemente von bilderArray nochmals an bilderArray an und speichert das (dann doppelt so große) Array als kartenArray. (Man kann natürlich auch dieselbe Variable wiederverwenden, wenn man das ursprüngliche Array nicht mehr braucht.)

    Und in dem Array kann man auch die Alternativtexte für die Bilder mit unterbringen:

    var bilderArray = [
    	{
    		src: "kat.jpg",
    		alt: "Kat"
    	},
    	{
    		src: "teemo.jpg",
    		alt: "Teemo"
    	},];
    

    LLAP 🖖

    --
    „Wer durch Wissen und Erfahrung der Klügere ist, der sollte nicht nachgeben. Und nicht aufgeben.“ —Kurt Weidemann