Kniffel (Yahtzee) (Kleinprojekte)
Schreibe eine Klasse/Modul
mit der/dem es möglich ist das Spiel Kniffel in
abgespeckter Form abzubilden.
Zur Vereinfachung soll statt 3 nur 1 Mal gewürfelt werden.
Als Ergebnis sollen alle möglichen Gewinnstufen eines Wurfs
sowohl des oberen als auch des unteren Blocks mit der erreichten Punktzahl
ausgegeben werden.
Beispielwurf:
2-2-2-4-4
Oberer Block:
Zweier: 2+2+2 = 6 (nur Summe der 2er zählen)
Vierer: 4+4 = 8 (nur Summe der 4er zählen)
Unterer Block:
Dreierpasch: 2+2+2 und 4+6 = 16 (Summe aller Augen)
Full House: Dreierpasch + Zweierpasch -> Sonderwertung = 25
Chance: 2+2+2+4+6 = 16 (Summe aller Augen)
Als Erweiterung kann auch das dreimalige Würfeln
implementiert werden.
Da die Interaktion mit der Konsole nicht allzu
bedienerfreundlich ist, sollte man vielleicht auf eine grafischen Benutzeroberfläche
ausweichen.
Viel Spaß
0 Kommentare
3 Lösung(en)
/****************************************************\
| Minimalanforderung ..................... [Check!] |
| |
| Den dreifachwurf (mit zurücknahme) halte |
| ich für viel zu verfrüht, bevor die punktzahl |
| für doppelpasch und straßen nicht geklärt sind. |
| |
| Überhaupt liegt hier einiges im argen. |
| Klassischer fall von frühschuss. |
| Aber sei's drum. Ich bin bereit. |
\****************************************************/
let Throw = function() {
this.getDice = function() {
let out = [];
for (let i = 1; i <= 5; i++)
out.push( (Math.floor(Math.random() * 6) +1) );
return out.sort();
}
this.getPattern = function() {
let out = [0,0,0,0,0,0];
for (let i = 0; i < this.dice.length; i++)
out[this.dice[i]-1]++;
return out;
}
this.evalPips = function(pip) {
return this.pattern[pip-1] * pip;
}
this.pipSum = function() {
return eval(this.dice.join('+'));
}
this.getType = function() {
// hier fehlen noch viele ergänzungen
// noch ist alles straßenblind!
let sorted = this.revSortedPattern;
switch(sorted[0]) {
case 5: return 'Kniffe1!';
case 4: return '4er Pasch!';
case 3:
if (sorted[1] == 2) return 'Full House!';
else return '3er Pasch!';
default: return '... hm, mal schauen'
}
}
this.dice = this.getDice();
this.pattern = this.getPattern();
this.revSortedPattern = this.getPattern().sort().reverse();
this.type = this.getType();
}
/************************\
| ausgabe (html-tabelle) |
\************************/
let t = new Throw();
// oberer block
document.write(`
<p>Wurf: <b>${t.dice.join('-')}</b></p>
<p>Sieht aus wie ein ${t.type}</p>
<table>
<tr><th>Typ</th><th>Punkte</th></tr>
<tr><td>1er</td><td>${t.evalPips(1)}</td></tr>
<tr><td>2er</td><td>${t.evalPips(2)}</td></tr>
<tr><td>3er</td><td>${t.evalPips(3)}</td></tr>
<tr><td>4er</td><td>${t.evalPips(4)}</td></tr>
<tr><td>5er</td><td>${t.evalPips(5)}</td></tr>
<tr><td>6er</td><td>${t.evalPips(6)}</td></tr>
`);
// unterer block
if (t.type == 'Full House!') document.write(`
<tr><td>Full House</td><td>25</td></tr>
`);
document.write(`
<tr><td>Chance</td><td>${t.pipSum()}</td></tr>
</table>
`);
Lösung von: Lisa Salander (Heidi-Klum-Gymnasium Bottrop)
// NET Core 3.x; C# 8.x
// Werte für Sonderpunkte (Unterer Block) gem. der verknüpften Seite
// Einfachwurf
/* @ Lisa Salander (javascript): wie immer schöne Arbeit, kann die Polemik aber nicht nachvollziehen!
Es sind doch alle Angaben - wenn auch ein wenig versteckt - vorhanden?!*/
using System;
using System.Collections.Generic;
using System.Linq;
namespace CS_MDL_CORE_Kniffel
{
enum Types // specific point values
{
aces = 1, twos, threes, fours, fives, sixes,
chance, two_of_a_kind, three_of_a_kind, four_of_a_kind,
full_house = 25, small_straight = 30, large_straight = 40, yahtzee = 50,
}
class Program
{
private static List<int> _lstDice;
private static readonly List<string> _lstSmallStraight = new List<string> { "1234", "2345", "3456" };
private static readonly List<string> _lstLargeStraight = new List<string> { "12345", "23456" };
static void Main(string[] args)
{
// dice
_lstDice = Enumerable.Range(0, 5).Select(x => new Random().Next(1, 7)).OrderBy(x => x).ToList();
Console.WriteLine("dice:\n");
Console.WriteLine(string.Join(", ", _lstDice));
// upper section
Console.WriteLine("\nupper section:\n");
_lstDice.GroupBy(x => x).Select(x => new { n = x.Key, c = x.Count(), s = x.Key * x.Count() }).ToList().ForEach(x => Console.WriteLine($"{Enum.GetName(typeof(Types), x.n)}:\t{x.c}x => {x.s} Pkt"));
// lower section
Console.WriteLine("\nlower section:\n");
var sum = _lstDice.Sum();
var lstLowerSection = new List<(Types type, bool won, int points)>
{
(Types.three_of_a_kind, IsXofKind(3), sum),
(Types.four_of_a_kind, IsXofKind(4), sum),
(Types.full_house, IsXofKind(2) && IsXofKind(3), (int)Types.full_house),
(Types.small_straight, IsStraight(_lstSmallStraight), (int)Types.small_straight),
(Types.large_straight, IsStraight(_lstLargeStraight), (int)Types.large_straight),
(Types.yahtzee, IsXofKind(5), (int)Types.yahtzee),
(Types.chance, true, sum)
};
lstLowerSection.Where(x => x.won == true).ToList().ForEach(x => Console.WriteLine($"{x.type}:{new string(' ', 15 - x.type.ToString().Length)} {x.points} Pkt"));
static bool IsXofKind(int p) =>
_lstDice.GroupBy(x => x).Select(x => new { n = x.Key, c = x.Count() }).Any(x => x.c == p);
static bool IsStraight(List<string> comp) =>
comp.Where(x => string.Join("", _lstDice).Contains(x)).ToList().Count() > 0;
}
}
}
Lösung von: Jens Kelm (@JKooP)
// C++ 14 | VS-2022
#include <iostream>
#include <vector>
#include <tuple>
#include <map>
#include <algorithm>
#include <string>
#include <numeric>
const std::vector<std::string> small_straights{ "\x1\x2\x3\x4", "\x2\x3\x4\x5", "\x3\x4\x5\x6" };
const std::vector<std::string> large_straights{ "\x1\x2\x3\x4\x5", "\x2\x3\x4\x5\x6" };
std::map<int, int> get_grouped_vector(const std::vector<int>& v) {
std::map<int, int> m;
for (const auto& i : v)
if (m.count(i)) m[i]++;
else m.emplace(i, 1);
return m;
}
int main() {
// roll dice
srand((int)time(nullptr));
std::vector<int> dice{};
for (size_t i{ 0 }; i < 5; i++) dice.push_back(rand() % 6 + 1);
std::sort(dice.begin(), dice.end());
std::cout << "dice: \n";
for (auto it{ dice.begin() }; it != dice.end() - 1; it++)
std::cout << *it << ", ";
std::cout << dice.back() << "\n";
// upper section
std::cout << "\nupper section: \n";
for (const auto& i : get_grouped_vector(dice))
std::cout << i.second << " x " << i.first << " =>\t" << i.first * i.second << " Pts.\n";
// lower section
const auto is_x_of_kind{ [&dice](int p) {
for (const auto& i : get_grouped_vector(dice))
if (i.second == p)
return true;
return false;
} };
const auto is_straight{ [&dice](std::vector<std::string>v) {
std::string str(dice.begin(), dice.end());
for (const auto& i : v)
if (str.find(i) != std::string::npos) return true;
return false;
} };
const auto sum{ std::accumulate(dice.begin(), dice.end(), 0) };
std::vector<std::tuple<std::string, bool, int>> lower_section {
{"three of a kind", is_x_of_kind(3), sum},
{"four of a kind", is_x_of_kind(4), sum},
{"full house", is_x_of_kind(2) && is_x_of_kind(3), 25},
{"small straight", is_straight(small_straights) , 30},
{"large straight", is_straight(large_straights) , 40},
{"yahtzee", is_x_of_kind(5) , 50},
{"chance", true , sum}
};
std::cout << "\nlower section: \n";
for (const auto& l : lower_section)
if (std::get<1>(l))
std::cout << std::get<0>(l) << " =>\t" << std::get<2>(l) << " Pts\n";
}
Lösung von: Jens Kelm (@JKooP)
Aktionen
Neue Lösung hinzufügen
Bewertung
Durchschnittliche Bewertung: