Trumpf Spiel

Wenn du dir nicht sicher bist, in welchem der anderen Foren du die Frage stellen sollst, dann bist du hier im Forum für allgemeine Fragen sicher richtig.
Antworten
Princess92
User
Beiträge: 1
Registriert: Dienstag 23. Mai 2017, 13:21

Hallo, ich habe eine Übungsaufgabe bekommen die mich zur Verzweiflung bringt. Ich hab nicht mal einen Ansatz mit dem ich diese Aufgabe beginnen kann.
Es wäre sehr lieb wenn mir jemand wenigstens einen Denkanstoß oder Tipp geben könnte.
PS : Aufgabe ist freiwillig und wird nicht bewertet ;)

Es gibt 32 Karten mit den Werten 1 bis 32.
Es gibt 2 Spieler, jeder Spieler erhält die Hälfte der gemischten Karten.
Pro Zug spielen beide Spieler die oberste Karte ihres Stapels aus.
Der Spieler mit dem höheren Wert macht einen Stich.
Nach 16 Zügen gewinnt der Spieler mit mehr Stichen oder das Spiel endet unentschieden.
Schreiben Sie ein Programm, das
1. die Karten von Spieler 1 anzeigt,
2. gefolgt von den 16 Zügen mit Ergebnis des Zugs und Zwischenstand, sowie
3. anzeigt, welcher Spieler mit wie vielen Stichen gewonnen hat.

Mit freundlichen Grüßen. R.
Benutzeravatar
/me
User
Beiträge: 3554
Registriert: Donnerstag 25. Juni 2009, 14:40
Wohnort: Bonn

Du brauchst erst einmal die Karten. Die lassen sich durch einfache Integer-Werte von 1 bis 32 repräsentieren und damit leicht erstellen (range). Die Karten sammelst du in einem logischen Kartenstapel (z.B. list). Dann mischt du die Karten (random.shuffle).

Jetzt kannst du die Karten gleichmäßig auf beide Spieler aufteilen und das Spiel durchführen.
BlackJack

@Princess92: Ansonsten gilt ganz generell was beim Programmieren immer hilfreich ist: Teile das Problem in kleinere Teilprobleme auf, und die gegebenfalls wieder in Teilprobleme, solange bis die einzelnen Teilprobleme so klein sind, das man sie mit einer Funktion in ein paar Zeilen Code lösen kann. Diese Teillösung testet man dann, und wenn sie funktoniert wie sie soll, kann man zur nächsten Funktion weitergehen. Die Teillösungen werden zu grösseren Teillösungen zusammengesetzt, bis irgendwann das Gesamtproblem gelöst ist.

Das Testen der Teillösungen/Funktionen ist wichtig. Beliebter Anfängerfehler ist das runterschreiben des gesamten Programms und erst am Ende zu versuchen ob das überhaupt läuft und alle Fehler suchen. Das kann eine sehr frustrierende Erfahrung sein. Noch schlimmer wird es wenn man beim schreiben falsche Annahmen gemacht hat, und deshalb etwas gar nicht repariert bekommt, sondern es neu schreiben muss.

Das Programm wäre zwar noch von der reinen Länge her vertretbar in *einer* Funktion lösbar (ich habe so ungefähr 35 Zeilen gebraucht), aber diese Funktion macht mehr als eine Sache, ja buchstäblich *alles*, und als Anfänger kann man sicher davon profitieren über einzelne, in sich geschlossene Teile nachzudenken, und die auch separat testen zu können. Das Programm lässt sich beispielsweise sinnvoll grob in Vorbereitung, Spieldurchführung, und Auswertung aufteilen.

Ein weiterer, üblicher Punkt an dem man Code aufteilen kann, sind Wiederholungen. In diesem Fall könnte man beispielsweise sagen, dass das Spiel aus einer Anzahl von Runden besteht, und versuchen eine Runde als Funktion zu schreiben, und die Spieldurchführung dann als Funktion die die Rundenfunktion für jede Runde aufruft.
BlackJack

Spasseshalber mal eine Lösung in Rust:
[codebox=text file=Unbenannt.txt]use std::cmp::Ordering;
use std::fmt;

extern crate rand;
use rand::{thread_rng, Rng};

#[derive(Debug,PartialEq,Eq,PartialOrd,Ord)]
struct Card(u32);

type Deck = Vec<Card>;

#[derive(Debug)]
enum Player { A, B }

type Winner = Option<Player>;

#[derive(Clone,Copy,Debug,Default)]
struct Scores(u32, u32);


impl fmt::Display for Scores {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
let Scores(a, b) = *self;
write!(f, "{}:{}", a, b)
}
}


fn create_shuffled_deck(card_count: u32) -> Deck {
let mut deck: Deck = (1..card_count + 1).map(Card).collect();
thread_rng().shuffle(&mut deck);
deck
}


fn split_deck(deck: Deck) -> (Deck, Deck) {
let split_index = deck.len() / 2;
let mut hand_a = deck;
let hand_b = hand_a.split_off(split_index);
(hand_a, hand_b)
}


fn do_round(card_pair: (&Card, &Card)) -> Winner {
let (a, b) = card_pair;
match a.cmp(b) {
Ordering::Less => Some(Player::B),
Ordering::Equal => None,
Ordering::Greater => Some(Player::A),
}
}


fn update_round_result(scores: &mut Scores, winner: Winner)
-> Option<(Player, Scores)>
{
let winner = winner.expect("there must be a winner");
let &mut Scores(score_a, score_b) = scores;
*scores = match winner {
Player::A => Scores(score_a + 1, score_b),
Player::B => Scores(score_a, score_b + 1),
};
Some((winner, *scores))
}


fn print_round_result(result: &(Player, Scores)) {
let &(ref winner, scores) = result;
println!("Player {:?} wins. Scores: {}", winner, scores);
}


fn play_game(hand_a: Deck, hand_b: Deck) -> Scores {
let card_pairs = hand_a.iter().zip(hand_b.iter());
let round_winners = card_pairs.map(do_round);
let round_scores = round_winners.scan(Scores(0, 0), update_round_result);
let last_scores = round_scores.inspect(print_round_result).last();
match last_scores {
Some((_, scores)) => scores,
None => Scores(0, 0),
}
}


fn print_game_result(scores: Scores) {
let Scores(a, b) = scores;
if a == b {
println!("It's a tie.");
} else {
let (winner, score) = if a > b {(Player::A, a)} else {(Player::B, b)};
println!("Player {:?} wins with {} points.", winner, score);
}
}


fn main() {
let (hand_a, hand_b) = split_deck(create_shuffled_deck(32));
println!("Hand of player {:?}: {:?}", Player::A, hand_a);
print_game_result(play_game(hand_a, hand_b));
}[/code]
Antworten