HTML Game: Fragespiel - noch nicht gestellte Fragen

  • HTML Game: Fragespiel - noch nicht gestellte Fragen

    Hi zusammen,

    Ich habe mir als Übung überlegt ein Frage-Antwort Spiel mit PHP und MySQL zu realisieren.

    Ich habe soweit alles geschafft. Nur hakt es derzeit daran:

    Wenn ein User eine Frage beantwortet hat bekommt er wenn Sie richtig beantwortet wurde Punkte (MySQL UPADTE) ... so, nun soll aber wenn er die Mainsite (wo die derzeitigen Spiele gezeigt werden) anklickt bereits erfolgreich gelöste Fragen nicht mehr auftauchen. Wie stelle ich das am besten an?

    Meine Idee:

    Wenn ich die MySQL auslese (Questions) soll er in der table solvedquestions abfragen ob die aktuelle gameid dort bereits mit dem Usernamen vorhanden ist, wenn ja, soll diese Question nicht mehr angezeigt werden.

    Ist alles bisserl blöd zu erklären. Hier mal bisserl Code:

    Quellcode

    1. $get_gameslist = mysql_query("SELECT gameid, question from games_questions WHERE active = '1'");
    2. while($row = mysql_fetch_object($get_gameslist))
    3. {
    4. $gameid = $row->gameid;
    5. if($countsolved == 0){echo "<input type=\"radio\" name=\"gameid\" value=\"".$row->gameid."\">";
    6. echo $row->gameid." ".$row->question."<br>";


    So, diese Abfrage müsste umgebaut werden denke ich, und zwar so das zusätzlich eben verglichen wird ob in der table solvedquestion (in welcher die columns gameid und username sind) die gameid und der Username enthalten sind, wenn ja, dann quest nicht anzeigen.

    Merci vorab für's reinschaun,
    Matthias
    Das Leben ist binär - du bist eine 1, oder eine 0
  • Re: HTML Game

    "RealFairPlayer" schrieb:

    Wenn ich die MySQL auslese (Questions) soll er in der table solvedquestions abfragen ob die aktuelle gameid dort bereits mit dem Usernamen vorhanden ist


    Ohne dein Datenbankdesign zu kennen würde ich das jetzt einfach mal so formulieren:

    Quellcode

    1. SELECT gq.gameid, question from games_questions gq NATURAL LEFT OUTER JOIN solvedquestions sq
    2. WHERE active = '1' AND user_id = '2' AND q.gameid = NULL;


    Bei Unklarheiten einfach nochmal nachfragen und uns eventuell dein Design verraten.
  • Hi,

    Also irgendwie komm ich damit nicht ganz klar, hier nochmal bisserl genauer:

    1 Tabelle (games_questions)
    enhält die Felder: gameid, question, active

    2 Tabelle (games_solved)
    enthält die Felder: gameid, username

    Username ist eine Sessionvariable.

    Wenn ein User eine Frage richtig beantwortet wird folgender Syntax ausgeführt:

    Quellcode

    1. $solved_insert = mysql_query("INSERT INTO games_solved (gameid, username) VALUES ('$gameid', '$username')");


    Somit habe ich dann also in der games_solved die jeweilige ID der Quest und den Usernamen. Wenn nun der User erneut die Seite aufruft wo alle Quests gelistet sind und er eine aussuchen kann sollte bei der Erstellung der Liste diejenigen die in der games_solved stehen nicht mehr auftauchen.

    Merci vorab,
    Matthias
    Das Leben ist binär - du bist eine 1, oder eine 0
  • Hast du meinen SELECT ausprobiert?
    Du musst eigentlich nur user_id durch username und solvedquestions durch games_solved zu ersetzen.

    NATURAL JOIN sorgt für die Verknüpfung der gameids.
    OUTER JOIN sorgt dafür dass auch leere Attribute verknüpft werden
    und die Selektion AND q.gameid = NULL sorgt eben dafür, dass nur die ausgewählt sind die nicht befüllt sind.

    Getestet habe ich es jedoch nicht.
  • Hi,

    warum setzt du nicht ein boolschen wert (z.b. 0 und 1), der dir in deiner abfrage hilft, ob die frage angezeigt werden soll oder eben nicht? Vlt musst du in die tabelle games_solved noch die "fragenID" einfügen.

    also "SELECT * FROM games_solved WHERE fragenID != 1"

    würde prüfen ob eine frage beantworted wurde und die als ergebniss zurückliefern, die noch nicht beantwortet sind.

    ka wie dein design aussieht, deshalb müsstest du das wohl vorher anpassen...

    mfg da BendIt
    .:Reden Ist Schweigen und Silber Ist Gold:.

    real programmers don't comment their code: if it was hard to write, it should be hard to read!
  • HI DoNut,

    Danke für deine Antwort, das habe ich auch getan, also Username und tablename angepasst, jedoch bekam ich dann gar keine Ausgabe mehr (obwohl games_solved keine Einträge enthielt).

    Ich find meinen Fehler einfach ned :(

    @Bendit - Danke für deinen Denkanstoß ... jedoch würde ich der Einfachheit halber und um mich selbst (und euch) nicht noch mehr zu verwirren durch umgeschreibe gern die Lösung (wenn möglich) für mein jetziges Design erarbeiten ... danach kann man immer noch über "bessere" Wege nachdenken :) Erst mal muss es laufen - Nun wirst du sagen, dann mach es gleich gescheit - doch ich bin halt Schüler, ned Lehrer :)
    Das Leben ist binär - du bist eine 1, oder eine 0
  • Hi!

    Okay, ich versuche einmal den Weg durchzuspielen.

    dologin.php

    Quellcode

    1. <?php
    2. $username = $_POST[username];
    3. $password = $_POST[password];
    4. $_SESSION["username"] = $username;
    5. $sql = mysql_query("SELECT username, password FROM games_userdata WHERE username = '$username' AND password = '$password'");
    6. $clogin = mysql_num_rows($sql);
    7. if($clogin == 0){ echo "<center>Falsche Zugangsdaten</center>";}
    8. else
    9. {echo "Login Erfolgreich";echo "<center><a href=\"list_games.php\">Weiter</a></center>";}
    10. ?>
    Alles anzeigen


    list_games.php

    Quellcode

    1. <form name="form1" method="post" action="games_index.php">
    2. <?php
    3. // $get_gameslist = mysql_query("SELECT gameid, question from games_questions WHERE active = '1'");
    4. $get_gameslist = mysql_query("SELECT gameid, question FROM games_questions NATURAL LEFT OUTER JOIN games_solved
    5. WHERE active = '1' AND username = $username AND games_solved.gameid = NULL");
    6. while($row = mysql_fetch_object($get_gameslist))
    7. {
    8. $gameid = $row->gameid;
    9. if($countsolved == 0){echo "<input type=\"radio\" name=\"gameid\" value=\"".$row->gameid."\">";
    10. echo $row->gameid." ".$row->question."<br>";
    11. // echo "<input type=\"submit\" name=\"Submit\" value=\"Senden\">";}
    12. }
    13. }
    14. ?>
    15. <input type="submit" name="Submit" value="Senden">
    16. </form>
    Alles anzeigen


    games.summary.php

    Quellcode

    1. <? include("init.php"); ?>
    2. <?php echo $username.$gameid.$gamename;?>
    3. <?php
    4. $abfrage = mysql_fetch_object(mysql_query("SELECT answer FROM games_answers WHERE active = '1' AND gameid = '$gameid' "));
    5. if($selection == $abfrage->answer)
    6. {echo "richtige Antwort";
    7. $getpoints = mysql_query("SELECT points FROM games_userdata WHERE username = '$username'");
    8. $newpoints = mysql_result($getpoints,0) + 5;
    9. $putpoints = mysql_query("UPDATE games_userdata Set points = $newpoints WHERE username = '$username'");
    10. $solved_insert = mysql_query("INSERT INTO games_solved (gameid, username) VALUES ('$gameid', '$username')");
    11. }
    12. else
    13. {echo "schade, falsche Antwort";}
    14. $getattempts = mysql_query("SELECT attempts FROM games_userdata");
    15. $newattempts = mysql_result($getattempts,0) - 1;
    16. $putattempts = mysql_query("UPDATE games_userdata Set attempts = $newattempts WHERE username = '$username'");
    17. ?>
    18. <a href="highscore.php"><img src="img/highscore.jpg" border="0"></a><br><a href="list_games.php">Spieleauswahl</a> "
    Alles anzeigen


    games_index.php

    Quellcode

    1. <?php
    2. if($countsolved > 0){echo "Quest bereits gelöst";echo "<center><a href=\"list_games.php\">Zurück</a></center>";exit();}
    3. if($userattempts > 0){
    4. $abfrage = mysql_query("SELECT question FROM games_questions WHERE gameid = $gameid");
    5. if(mysql_num_rows($abfrage) < 0)
    6. {echo "Derzeit gibt es keine Quests - Schau doch in ein paar Minuten nochmal rein.";exit();}
    7. else
    8. {
    9. $row = mysql_fetch_object($abfrage);
    10. echo $row->question;
    11. }
    12. }
    13. else
    14. {
    15. echo "Heute keine Versuche mehr möglich";
    16. echo "<center><a href=\"list_games.php\">Zurück</a></center>";
    17. exit();
    18. }
    19. ?></center>
    20. </span></td>
    21. </tr>
    22. <tr>
    23. <td>&nbsp;</td>
    24. </tr>
    25. <tr>
    26. <td>&nbsp;</td>
    27. </tr>
    28. <tr>
    29. <td> <form name="form1" method="post" action="games_summary.php">
    30. <?
    31. $get_answers = mysql_query("SELECT answer from games_answers WHERE gameid = $gameid LIMIT 10");
    32. while($row = mysql_fetch_object($get_answers))
    33. {
    34. echo "<input type=\"radio\" name=\"selection\" value=\"".$row->answer."\">";
    35. echo $row->answer."<br>";
    36. }
    37. if($userattempts > 0){echo "<input name=\"Mein Tipp\" type=\"submit\" value=\"Mein Tipp\">";}
    38. ?>
    39. </form></td>
    40. </tr>
    41. </table>
    Alles anzeigen


    und zu guter letzt die init.php

    Quellcode

    1. <?php include("dbconnect.php");
    2. //Hiermit wird der Highscore abgefragt zur späteren Verwendung.
    3. $gethighscore = mysql_query("SELECT * FROM games_userdata ORDER BY points DESC");
    4. //Hier wird abgefragt ob ein User noch Versuche zur Verfügung hat.
    5. $getattempts = mysql_query("SELECT attempts FROM games_userdata");
    6. $userattempts = mysql_result($getattempts, 0);
    7. //Hier wird abgefragt ob der User den Quest bereits erfolgreich gelöst hat.
    8. $getsolved = mysql_query("SELECT * from games_solved WHERE gameid = '$gameid' AND username = '$username' ");
    9. $countsolved = mysql_num_rows($getsolved);
    10. $_SESSION["countsolved"] = §countsolved;
    11. $getdata = "SELECT * FROM games_settings";
    12. $summary = mysql_query($getdata);
    13. while($row = mysql_fetch_object($summary))
    14. {
    15. // $_SESSION["gameid"] = $row->gameid;
    16. // $_SESSION["gamename"] = $row->gamename;
    17. $_SESSION["bgcolor"] = $row->bgcolor;
    18. $_SESSION["adminemail"] = $row->adminemail;
    19. $_SESSION["index"] = $row->index;
    20. }
    21. ?>
    Alles anzeigen


    So, nun sind die Hosen unten. DB Design ist ja in meinem letzten Beitrag zu sehen.
    Kann sein das des ein oder andere noch durcheinander ist - bin halt wie gesagt Schüler :)
    Das Leben ist binär - du bist eine 1, oder eine 0
  • Hallo,

    ich verstehe die Problematik nicht. Du brauchst doch nur eine Tabelle mit zwei Spalten: UserId und QuestionId.

    Wenn ein User eine Frage gelöst hat, wird ein Eintrag in der Tabelle gemacht.

    Logged sich ein User ein, machst Du eine Abfrage auf die Tabelle und zeigst nur noch die Fragen an, die nicht in der Tabelle stehen..

    70abc
    We raise hopes, here ... until they're old enough to fend for themselves.
    - Mike Callahan
  • "d0nUt" schrieb:



    Quellcode

    1. SELECT * from games_questions
    2. WHERE gameid NOT IN (SELECT gameid FROM games_solved WHERE username="usera");


    Sorry, Off Topic:

    Hoffentlich ist es keine Oracle Datenbank und der User hat nicht mehr als 1000 Fragen gelöst:

    In Orcale darf man nämlich maximall 1000 "Objekte" in ein "IN" Statement stecken.
    Ist aber laut Orcale kein Bug, sondern ein Feature ;)

    Mit der Problematik durfte ich mich diese Woche schon mal rumschlagen...

    Zurück zum Thema:

    Je nach Größe der Datenbank geht es mit einem Slecet nicht unbedingt schneller als mit zwei einzelnen.
    Ich arbeite sehr oft mit sehr großen Datensätzen und je nach DB Desing und Abfrage ist es oft schneller zwei getrennte Select-Anweisungen zu machen als ein Subselect.

    Aber wie gesagt, das hängt extrem vom DB Desing un der Größe ab...

    70abc
    We raise hopes, here ... until they're old enough to fend for themselves.
    - Mike Callahan
  • hi du kannst das natürlich auch anders machen in dem du dir zwei tabellen machst eine in der die fragen sind und eine für die ganzen user...

    in die usertabelle schreibst du einen trennwert rein für die fragen nehmen wir an du hasst 50 fragen dann schreibst du bei einer neuregistrierung in eine userspalte eine zeichenfolge rein z.b. so eine "0|0|0|0" so sollte der user jetzt eine frage beantwortet haben schreibt die db jetz z.B. bei frage 2 "1"
    du liest also die zeichenfolge aus "0|0|0|0" und machst bei der zweiten jetzt eine "1" rein also "0|1|0|0" ... währe zumindest eine idee um deine datenbank zu strukturieren....
    nützliche funktionen um das ganze zu zerlegen auszulesen etc.. sind explode und implode.
    z.B.

    Quellcode

    1. $datenbankabruf=explode("|",$datenbankabruf);
    2. $meineausgabe = $datenbankabruf[$fragenID];


    dazu müsste natürlich die fragen id mit der stelle des wertes stimmen ^^

    dann könnteste das ganze mitn implode wieder eintragen und via UPDATE an die db senden schon passt das

    so nun soll er die gelösten fragen nicht mehr anzeigen machste normale if abfrage

    Quellcode

    1. // deine While schleife ausgabe begin
    2. $datenbankabruf=explode("|",$datenbankabruf);
    3. $meineausgabe = $datenbankabruf[$fragenID];
    4. if (!($meineausgabe)=="1")
    5. {
    6. // frage anzeigen wenn nicht 1
    7. };
    8. // deine While schleife ausgabe ende

    wie gesagt währe eine möglichkeit !!!
    mfg: marcel
    Beste Grüße,
    M4rc3L-XCN
  • "marcel" schrieb:

    hi du kannst das natürlich auch anders machen in dem du dir zwei tabellen machst eine in der die fragen sind und eine für die ganzen user...

    in die usertabelle schreibst du einen trennwert rein für die fragen nehmen wir an du hasst 50 fragen dann schreibst du bei einer neuregistrierung in eine userspalte eine zeichenfolge rein z.b. so eine "0|0|0|0" so sollte der user jetzt eine frage beantwortet haben schreibt die db jetz z.B. bei frage 2 "1"
    du liest also die zeichenfolge aus "0|0|0|0" und machst bei der zweiten jetzt eine "1" rein also "0|1|0|0" ... währe zumindest eine idee um deine datenbank zu strukturieren....
    nützliche funktionen um das ganze zu zerlegen auszulesen etc.. sind explode und implode.
    z.B.

    Quellcode

    1. $datenbankabruf=explode("|",$datenbankabruf);
    2. $meineausgabe = $datenbankabruf[$fragenID];


    dazu müsste natürlich die fragen id mit der stelle des wertes stimmen ^^

    dann könnteste das ganze mitn implode wieder eintragen und via UPDATE an die db senden schon passt das

    so nun soll er die gelösten fragen nicht mehr anzeigen machste normale if abfrage

    Quellcode

    1. // deine While schleife ausgabe begin
    2. $datenbankabruf=explode("|",$datenbankabruf);
    3. $meineausgabe = $datenbankabruf[$fragenID];
    4. if (!($meineausgabe)=="1")
    5. {
    6. // frage anzeigen wenn nicht 1
    7. };
    8. // deine While schleife ausgabe ende

    wie gesagt währe eine möglichkeit !!!
    mfg: marcel


    Würde ich nicht empfehlen, sowas ist weder Konsistent, noch in irgendeiner Normalform (noch nicht mal die erste) Oo
  • "marcel" schrieb:

    @ benny
    was soll das denn bitteschön heisen dann schlag doch was besseres vor anstatt nur zu kritisieren -.-


    Du solltest dich dadurch jetzt nicht angegriffen fühlen... Aber Datentechnisch is sone Lösung mit nem Sperator und ner Datenbank unsinn, bzw. ein schlechtes Datenbank-Design

    de.wikipedia.org/wiki/Normalis…rste_Normalform_.281NF.29

    Eine Normalisierung ist notwendig, um Redundanzen der Daten zu vermeiden, die einen erhöhten Speicherplatz benötigen, das Durchsuchen und Analysieren der Daten verlängern und bei der Änderung von Daten zu Inkonsistenzen führen können.


    der Relation muss einen atomaren Wertebereich haben. Das heißt, zusammengesetzte, mengenwertige oder geschachtelte Wertebereiche (relationenwertige Attributwertebereiche) sind nicht erlaubt. Kurz: Kein Attributwertebereich kann in weitere (sinnvolle) aufgespalten werden (z. B.: Adresse darf nicht als Attribut verwendet werden, sondern muss in PLZ, Ort, Straße, Hausnummer zerlegt werden).


    Dein Vorschlag würde also im Gegensatz zur ersten Normalform stehen. Technisch gesehn ist das natürlich möglich, aber konzeptionell bedenklich.