Wer wird Millionär in C++

04/10/2019 11:04 Semikоlоn#1
Hallo,


ich muss für ein Schulprojekt das Spiel "Wer wird Millionär" programmieren. Da ich aber absoluter Anfänger in C++ bin, bekomme ich das im Moment nicht hin.


Ich bekomme aktuell die Ausgaben der Fragen nicht hin. Diese Fragen sollen später random ausgegeben werden. Ich habs vorher mit einem struct versucht, doch mir wurde geraten, das in Arrays zu packen.


Code:
[Only registered and activated users can see links. Click Here To Register...]
04/10/2019 13:03 warfley#2
Versuchen wir doch erstmal strukturiert ran zu gehen.

Für ein Quiz spiel benötigst du einen Container an Fragen, eine Frage besteht aus dem Fragetext, mehreren Antworten, von der natürlich eine richtig sein muss.

In C++ terms bedeutet das du willst eine art von Objekt haben das die Information der Fragen beinhaltet, sowie eine art Container um die fragen zu halten. Aktuell machst du beides mit einem zweidimensionalen Array. Das ist zum einen unleserlich und aufwendig. Mein Tipp ist, erstelle einen eigenen Typen für Fragen (Stuct/Class), und benutz einen Container (std::set, std::vector) für den Fragenkatalog.

Wenn du eine frage stellst, printest du die Fragestellung sowie die möglichen antworten aus, und liest vom user dann eine zahl ein. Wenn die Zahl = index der richtigen antwort (auf dem screen) ist, bekommt der Spieler die nächste frage, wenn nicht hat er das spiel verloren.

Die fragen solle ja zufällig auftreten, da gibt es verschiedene Optionen, z.B. kannst du die Fragen einfach in einem vector speichern, und die nächste frage mit rand() auswählen, und diese dann löschen. Persönlich finde ich das aber recht ugly da Vector elemt löschen langsam ist (O(n)).
Die etwas kompliziertere lösung die ich machen würde, ich würde den Fragen eine Zufallszahl zuordnen, und sie dann nach dieser sortiert in einem std::set lagern (indem man std::less für den Fragen typen spezialisiert) und dann immer das erste element entfernen. gibt bestimmt noch effizientere Methoden (std::set basiert auf nem RBT in den meisten implementationen, was hohe statische kosten hat), aber dir würde ich eh das mit dem vector empfehlen, da ich glaube das es für dich völlig ausreicht.

Also mal als pseudo code:
Code:
Frage {
-- Daten
  Text;
  Antworten;
-- Methoden
  FrageStellen {
    Print (Text);
    Print (Antworten);
    Read (UserAntwort);
    if (UserAntwort == RichtigeAntwort) return true;
    return false;
  }
}

Liste<Frage> Fragen = {
  Frage(Frage1, A1, A2, A3, A4),
  Frage(Frage2, A1, A2, A3, A4),
  ...
  Frage(FrageN, A1, A2, A3, A4),
}

Main {
  While (Fragen not empty) {
    AktuelleFrage = Fragen[Random]
    Fragen.delete(AktuelleFrage);
    if (AktuelleFrage.FrageStellen ist Falsch) Veloren;
  }
  Gewonnen
}
04/10/2019 13:14 Semikоlоn#3
Quote:
Originally Posted by warfley View Post
Versuchen wir doch erstmal strukturiert ran zu gehen.

Für ein Quiz spiel benötigst du einen Container an Fragen, eine Frage besteht aus dem Fragetext, mehreren Antworten, von der natürlich eine richtig sein muss.

In C++ terms bedeutet das du willst eine art von Objekt haben das die Information der Fragen beinhaltet, sowie eine art Container um die fragen zu halten. Aktuell machst du beides mit einem zweidimensionalen Array. Das ist zum einen unleserlich und aufwendig. Mein Tipp ist, erstelle einen eigenen Typen für Fragen (Stuct/Class), und benutz einen Container (std::set, std::vector) für den Fragenkatalog.

Wenn du eine frage stellst, printest du die Fragestellung sowie die möglichen antworten aus, und liest vom user dann eine zahl ein. Wenn die Zahl = index der richtigen antwort (auf dem screen) ist, bekommt der Spieler die nächste frage, wenn nicht hat er das spiel verloren.

Die fragen solle ja zufällig auftreten, da gibt es verschiedene Optionen, z.B. kannst du die Fragen einfach in einem vector speichern, und die nächste frage mit rand() auswählen, und diese dann löschen. Persönlich finde ich das aber recht ugly da Vector elemt löschen langsam ist (O(n)).
Die etwas kompliziertere lösung die ich machen würde, ich würde den Fragen eine Zufallszahl zuordnen, und sie dann nach dieser sortiert in einem std::set lagern (indem man std::less für den Fragen typen spezialisiert) und dann immer das erste element entfernen. gibt bestimmt noch effizientere Methoden (std::set basiert auf nem RBT in den meisten implementationen, was hohe statische kosten hat), aber dir würde ich eh das mit dem vector empfehlen, da ich glaube das es für dich völlig ausreicht.

Also mal als pseudo code:
Code:
Frage {
-- Daten
  Text;
  Antworten;
-- Methoden
  FrageStellen {
    Print (Text);
    Print (Antworten);
    Read (UserAntwort);
    if (UserAntwort == RichtigeAntwort) return true;
    return false;
  }
}

Liste<Frage> Fragen = {
  Frage(Frage1, A1, A2, A3, A4),
  Frage(Frage2, A1, A2, A3, A4),
  ...
  Frage(FrageN, A1, A2, A3, A4),
}

Main {
  While (Fragen not empty) {
    AktuelleFrage = Fragen[Random]
    Fragen.delete(AktuelleFrage);
    if (AktuelleFrage.FrageStellen ist Falsch) Veloren;
  }
  Gewonnen
}

Danke erstmal für die Hilfe!

Das Problem ist, wir sind halt noch ganz am Anfang und hatten bis auf paar Basics nichts gemacht. Sprich bis jetzt eig. Nur Datentypen, Strings, Pointer, arrays und Listen.
Deswegen sagen mir die meisten Sachen nichts. Und wir dürfen halt nur das benutzen was wir gelernt haben.
Ich hatte das halt mit einem struct versucht: [Only registered and activated users can see links. Click Here To Register...]
04/10/2019 13:35 warfley#4
Quote:
Originally Posted by Semikоlоn View Post
Danke erstmal für die Hilfe!

Das Problem ist, wir sind halt noch ganz am Anfang und hatten bis auf paar Basics nichts gemacht. Sprich bis jetzt eig. Nur Datentypen, Strings, Pointer, arrays und Listen.
Deswegen sagen mir die meisten Sachen nichts. Und wir dürfen halt nur das benutzen was wir gelernt haben.
Ich hatte das halt mit einem struct versucht: [Only registered and activated users can see links. Click Here To Register...]
Das ist schon fast richtig, du hast nur den fehler gemacht alle daten in eine Struct zu setzen. Du solltest eine Struct für die Fragen haben und dann eine liste dieser Struct als katalog

So würde ich das machen:
Code:
struct Challange {
  std::string question;
  std::string answers[4];
  int correctAnswer;

  bool askQuestion() {
  ...
  }
}

std::vector<Challange> challanges = {
  {
    .question = "Frage 1",
    .answers = {
      "Antwort1",
      "Antwort2",
      "Antwort3",
      "Antwort4"
    },
    .correctAnswer = 2
  },
  {
    .question = "Frage 2",
    .answers = {
      "Antwort1",
      "Antwort2",
      "Antwort3",
      "Antwort4"
    },
    .correctAnswer = 2
  },
  ...
};
04/10/2019 14:33 Semikоlоn#5
Quote:
Originally Posted by warfley View Post
Das ist schon fast richtig, du hast nur den fehler gemacht alle daten in eine Struct zu setzen. Du solltest eine Struct für die Fragen haben und dann eine liste dieser Struct als katalog

So würde ich das machen:
Code:
struct Challange {
  std::string question;
  std::string answers[4];
  int correctAnswer;

  bool askQuestion() {
  ...
  }
}

std::vector<Challange> challanges = {
  {
    .question = "Frage 1",
    .answers = {
      "Antwort1",
      "Antwort2",
      "Antwort3",
      "Antwort4"
    },
    .correctAnswer = 2
  },
  {
    .question = "Frage 2",
    .answers = {
      "Antwort1",
      "Antwort2",
      "Antwort3",
      "Antwort4"
    },
    .correctAnswer = 2
  },
  ...
};

Wir dürfen halt keine Vektoren benutzen, wenn ich das nicht falsch verstanden habe.
04/10/2019 22:16 florian0#6
Quote:
Originally Posted by Semikоlоn View Post
Wir dürfen halt keine Vektoren benutzen, wenn ich das nicht falsch verstanden habe.
Statt vector geht auch einfach nur ein Array. Die Fragen sind ja eh fix, du musst dir nur merken welche Frage schon gestellt wurde. Statt die Frage aus dem Array zu entfernen (das geht mit Array natürlich nicht so schön wie mit std::vector) kannst du z.B. in der Challange-Struktur eine weitere Variable anlegen, die signalisiert ob die Frage schon gestellt wurde.

Statt
Code:
std::vector<Challanges> challanges = { ... };
kannst du auch einfach
Code:
Challanges challanges[] = { ... };
machen.

PS: Challenge schreibt man mit e ... ;D
06/15/2019 07:27 BosniaWarlord#7
Pn me hab ein fertiges Produkt