C# :: Aufgabe #67

3 Lösungen Lösungen öffentlich

Quiz mittels LINQ in einer Xml-Datei

Fortgeschrittener - C# von Miako - 17.09.2014 um 21:13 Uhr
Schreibe ein Quiz-Programm, welches seine Fragen und Antworten durch LINQ (XmlReader-Klasse ist tabu) aus einer Xml-Datei bezieht.
Die Xml-Datei soll frei erweiterbar sein, sofern ein vorgegebenes Schema eingehalten wird.


Das Programm soll die Xml-Datei auslesen und dem Benutzer die Fragen in eine zufällige Reinfolge ausgeben. Bereits verwendete Fragen sollen kein zweites mal an die Reihe kommen. Die Anzahl der möglichen Antworten bleibt euch überlassen. Natürlich soll geprüft werden, ob die Antwort des Benutzers korrekt ist. Zu guter Schluss soll die korrekte Antwort in der Xml-Datei angegeben werden können.

Zitat:

Tipps und Hinweise
Am besten benutzt ihr für das Einlesen der Fragen und Antworten, sowie das Entfernen beantworteter Fragen ein Array, oder eine Liste.
Zum bestimmen der korrekten Antwort eignet sich ein Attribut für die jeweiligen Antwort in der Xml-Datei.



Viel Spaß beim Planen und schreiben. Ich freue mich auf eure Fragen und Lösungen!

Lösungen:

vote_ok
von pocki (4190 Punkte) - 21.09.2014 um 20:40 Uhr
Hier meine Lösung:
Meine XML-Datei sieht so aus:
Quellcode ausblenden XML-Code
<?xml version='1.0' encoding='UTF-8'?> 
<quiz>
	<frage wortlaut="Hier ist die 1. Frage?">
		<antwort wortlaut="richtige Antwort" istrue="true" />
		<antwort wortlaut="falsche Antwort 1" istrue="false" />
		<antwort wortlaut="falsche Antwort 2" istrue="false" />
	</frage>
	<frage wortlaut="Hier ist die 2. Frage?">
		<antwort wortlaut="richtige Antwort" istrue="true" />
		<antwort wortlaut="falsche Antwort 1" istrue="false" />
		<antwort wortlaut="falsche Antwort 2" istrue="false" />
		<antwort wortlaut="falsche Antwort 3" istrue="false" />
	</frage>
</quiz>

Mit dem Attribut "istrue" gibt man an, ob diese Antwort die richtige ist.
Quellcode ausblenden C#-Code
void Main()
{
	string xmlFile = "quiz.xml";
	var xmlDoc = XDocument.Load(xmlFile);
	
	var fragen = xmlDoc.Descendants("frage").Select(f=> new Frage
		{
			Wortlaut = f.Attribute("wortlaut").Value,
			Antworten = f.Descendants("antwort").Select(a => new Antwort() { Wortlaut = a.Attribute("wortlaut").Value, isTrue = a.Attribute("istrue").Value.ToLower() == "true"}).ToArray()
		});

	//Fragen in zufällige Reihenfolge bringen
	var randomFragen = fragen.ToList().ShuffleSimple();
	//Antworten der Fragen in zufällige Reihenfolge bringen
	randomFragen.ForEach(x=>x.Antworten = x.Antworten.ShuffleSimple().ToArray());
	
	for (int i = 0; i < randomFragen.Count; i++)
	{
		//Frage ausgeben
		Console.WriteLine(string.Format("Frage {0}: {1}", (i+1), randomFragen[i].Wortlaut));
		//Antworten dazu ausgeben
		for (int j = 0; j < randomFragen[i].Antworten.Count(); j++)
		{
			Console.WriteLine(string.Format("\t{0}) {1}", (j+1), randomFragen[i].Antworten[j].Wortlaut));
		}
		Console.Write("Deine Antwort: ");
		string antw = Console.ReadLine();
		if (randomFragen[i].Antworten[int.Parse(antw)-1].isTrue)
		{
			Console.WriteLine("richtig\n");
		}
		else
		{
			Console.WriteLine("falsch\n");
		}
	}
}

public class Frage
{
	public string Wortlaut { get; set; }
	public Antwort[] Antworten { get; set; }
}
public class Antwort
{
	public string Wortlaut { get; set; }
	public bool isTrue { get; set; }
}

die darin enthaltenen Extension-Methods:
Quellcode ausblenden C#-Code
public static IList<T> ShuffleSimple<T>(this IList<T> list)  
{  
	Random rng = new Random();  
	int n = list.Count;  
	while (n > 1) 
	{  
			n--;  
			int k = rng.Next(n+1);  
			T value = list[k];  
			list[k] = list[n];  
			list[n] = value;  
	}
	return list;
}
public static void ForEach<T>(this IEnumerable<T> collection, Action<T> action)
{
	foreach (T v in collection)
	action(v);
}
vote_ok
von daniel59 (4260 Punkte) - 08.04.2016 um 11:46 Uhr
XML:
<?xml version="1.0" encoding="utf-8"?>
<Quiz>
<Frage Id="0" Richtig="A" Text="Welche Farbe hat der Himmel?" A="Blau" B="Grün" C="Braun" D="Rosa"/>
<Frage Id="1" Richtig="C" Text="Wie viel Räder hat ein Dreirad?" A="1" B="2" C="3" D="4"/>
</Quiz>


Quellcode ausblenden C#-Code
using System;
using System.Collections.Generic;
using System.Linq;
using System.Windows;
using System.Windows.Controls;
using System.Xml.Linq;

namespace WPFQuiz
{
    /// <summary>
    /// Interaktionslogik für MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        static Random rnd = new Random();

        XDocument doc;
        List<Question> questions;
        Question currentQuestion;
        public MainWindow()
        {
            InitializeComponent();
            doc = XDocument.Load(@"Dateipfad");
            questions = (from q in doc.Descendants("Frage") select new Question() { Id = Convert.ToInt32(q.Attribute("Id").Value), CorrectAnswer = q.Attribute("Richtig").Value, Text = q.Attribute("Text").Value, AnswerA = q.Attribute("A").Value, AnswerB = q.Attribute("B").Value, AnswerC = q.Attribute("C").Value, AnswerD = q.Attribute("D").Value }).ToList();
            NextQuestion();
        }

        private void NextQuestion()
        {
            int index = rnd.Next(0, questions.Count);
            currentQuestion = questions[index];
            textBlockCount.Text = currentQuestion.Id.ToString();
            textBlockFrage.Text = currentQuestion.Text;
            buttonA.Content = currentQuestion.AnswerA;
            buttonB.Content = currentQuestion.AnswerB;
            buttonC.Content = currentQuestion.AnswerC;
            buttonD.Content = currentQuestion.AnswerD;
        }

        private void EnableAll(bool enabled)
        {
            buttonA.IsEnabled = enabled;
            buttonB.IsEnabled = enabled;
            buttonC.IsEnabled = enabled;
            buttonD.IsEnabled = enabled;
        }

        private void button_Click(object sender, RoutedEventArgs e)
        {
            EnableAll(false);
            string button = ((Button)sender).Name.Substring(6, 1);
            if (button == currentQuestion.CorrectAnswer)
            {
                MessageBox.Show("Richtig");
            }
            else
            { MessageBox.Show("Falsch! Richtig ist: " + currentQuestion.CorrectAnswer); }
        }

        private void buttonNext_Click(object sender, RoutedEventArgs e)
        {
            EnableAll(true);
            NextQuestion();
        }
    }

    class Question
    {
        public int Id { get; set; }
        public string CorrectAnswer { get; set; }
        public string Text { get; set; }
        public string AnswerA { get; set; }
        public string AnswerB { get; set; }
        public string AnswerC { get; set; }
        public string AnswerD { get; set; }
    }
}
vote_ok
von stcalvin (970 Punkte) - 18.05.2018 um 10:30 Uhr
XML:
Quellcode ausblenden XML-Code
<?xml version="1.0" encoding="utf-8" ?>
<Quiz>
  <Fragen>
    <Frage>
      <Fragestellung>Wie schwer werden Elefanten? (in KG)</Fragestellung>
      <Antworten>
        <Antwort>6000</Antwort>
        <Antwort>schwer</Antwort>
      </Antworten>
    </Frage>
    <Frage>
      <Fragestellung>Welche Farbe hat eine Käse?</Fragestellung>
      <Antworten>
        <Antwort>Gelb</Antwort>
        <Antwort>manchmal auch braun</Antwort>
      </Antworten>
    </Frage>
    <Frage>
      <Fragestellung>Wie groß werden Bäume?</Fragestellung>
      <Antworten>
        <Antwort>groß</Antwort>
        <Antwort>ein paar Meter</Antwort>
      </Antworten>
    </Frage>
    <Frage>
      <Fragestellung>Wieviele Fliegen fliegen wenn Fliegen fliegen?</Fragestellung>
      <Antworten>
        <Antwort>10</Antwort>
        <Antwort>10000</Antwort>
        <Antowrt>237537853582</Antowrt>
      </Antworten>
    </Frage>
    <Frage>
      <Fragestellung>Was machen Sachen?</Fragestellung>
      <Antworten>
        <Antwort>Sachen</Antwort>
      </Antworten>
    </Frage>
    <Frage>
      <Fragestellung>Wie geht es dir?</Fragestellung>
      <Antworten>
        <Antwort>Gut</Antwort>
      </Antworten>
    </Frage>
    <Frage>
      <Fragestellung>Wieviele Würste braucht man um glücklich zu sein?</Fragestellung>
      <Antworten>
        <Antwort>17</Antwort>
      </Antworten>
    </Frage>
    <Frage>
      <Fragestellung>Wasabi</Fragestellung>
      <Antworten>
        <Antwort>Ja</Antwort>
      </Antworten>
    </Frage>
  </Fragen>
</Quiz>


Code:
Quellcode ausblenden C#-Code
        static void XML_Auslesen_LINQ()
        {
            string path = @"C:\Users\cklein\source\repos\TrainYourProgrammer\TrainYourProgrammer\XMLFile1.xml", answer;
            Random rnd = new Random();
            int random;
            List<string> listQuestions = new List<string>(), listAnswers = new List<string>();
            XDocument xDoc = XDocument.Load(path);

            var queryQuestions = from qst in xDoc.Descendants("Fragestellung")
                                 select qst.Value;

            listQuestions = queryQuestions.ToList();

            while (listQuestions.Count > 0)
            {
                random = rnd.Next(0, listQuestions.Count);
                Console.Write(listQuestions[random] + " ");
                answer = Console.ReadLine();

                var queryAnswers = from answ in xDoc.Descendants("Antworten").Descendants()
                                   where answ.Parent.Parent.Element("Fragestellung").Value == listQuestions[random]
                                   select answ.Value;
                                   
                listAnswers = queryAnswers.ToList();

                if (listAnswers.Contains(answer, StringComparer.OrdinalIgnoreCase))
                {
                    Console.WriteLine("Die Antwort ist korrekt.");
                }
                else
                {
                    Console.WriteLine("Die Antwort war.. falsch!");
                }

                Console.WriteLine("Korrekte Antwortmöglichkeiten: " + String.Join(", ", listAnswers.ToArray()));
                Console.WriteLine();

                listQuestions.Remove(listQuestions[random]);
            } 
        }