Created
January 9, 2014 15:06
-
-
Save heimp/8335486 to your computer and use it in GitHub Desktop.
set game for rosetta code maybe
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| import 'dart:math'; | |
| import 'dart:collection'; | |
| const NUM_ATTRIBUTES = 4; | |
| const NUM_VALUES_PER_ATTRIBUTE = 3; | |
| const VALID_SET_SIZE = 3; | |
| final COLOURS = ['Red', 'Green', 'Purple']; | |
| final SYMBOLS = ['Diamond', 'Oval', 'Squiggle']; | |
| abstract class Attribute { | |
| final int ordinal; | |
| final String name; | |
| const Attribute(this.ordinal, this.name); | |
| String toString() => name; | |
| } | |
| class Color extends Attribute { | |
| static const RED = const Color._(0, "Red"); | |
| static const GREEN = const Color._(1, "Green"); | |
| static const PURPLE = const Color._(2, "Purple"); | |
| static List<Color> get values => [RED, GREEN, PURPLE]; | |
| const Color._(int ordinal, String name): super(ordinal, name); | |
| } | |
| class CardSymbol extends Attribute { | |
| static const OVAL = const CardSymbol._(0, "Oval"); | |
| static const SQUIGGLE = const CardSymbol._(1, "Squiggle"); | |
| static const DIAMOND = const CardSymbol._(2, "Diamond"); | |
| static List<CardSymbol> get values => [OVAL, SQUIGGLE, DIAMOND]; | |
| const CardSymbol._(int ordinal, String name): super(ordinal, name); | |
| } | |
| class Number extends Attribute { | |
| static const ONE = const Number._(0, "1"); | |
| static const TWO = const Number._(1, "2"); | |
| static const THREE = const Number._(2, "3"); | |
| static List<Number> get values => [ONE, TWO, THREE]; | |
| const Number._(int ordinal, String name): super(ordinal, name); | |
| } | |
| class Fill extends Attribute { | |
| static const SOLID = const Fill._(0, "Solid"); | |
| static const OPEN = const Fill._(1, "Open"); | |
| static const STRIPED = const Fill._(2, "Striped"); | |
| static List<Fill> get values => [SOLID, OPEN, STRIPED]; | |
| const Fill._(int ordinal, String name): super(ordinal, name); | |
| } | |
| class Card { | |
| final Color color; | |
| final CardSymbol symbol; | |
| final Number number; | |
| final Fill fill; | |
| List<Attribute> _attList; | |
| Attribute operator[](int index) => _attList[index]; | |
| Card(this.color, this.symbol, this.number, this.fill) { | |
| _attList = [color, symbol, number, fill]; | |
| } | |
| String toString() => '[$number $fill $color $symbol${number == Number.ONE ? "" : "s"}]'; | |
| } | |
| class Deck extends Object with ListMixin<Card> { | |
| var cards = new List<Card>(); | |
| int get length => cards.length; | |
| Deck() { | |
| for(var color in Color.values) { | |
| for(var symbol in CardSymbol.values) { | |
| for(var number in Number.values) { | |
| for(var fill in Fill.values) { | |
| cards.add(new Card(color, symbol, number, fill)); | |
| } | |
| } | |
| } | |
| } | |
| } | |
| Card operator[](int index) => cards[index]; | |
| void operator[]=(int index, Card value) {cards[index] = value;} | |
| } | |
| bool isAllSame(List<Attribute> atts) { | |
| return atts.every((att) => att == atts.first); | |
| } | |
| bool isAllDifferent(List<Attribute> atts) { | |
| for(var i = 0; i < atts.length; i++) { | |
| for(var j = i + 1; j < atts.length; j++) { | |
| if(atts[i] == atts[j]) { | |
| return false; | |
| } | |
| } | |
| } | |
| return true; | |
| } | |
| List<Attribute> getAttributes(List<Card> cards, int attributeIndex) { | |
| return cards.map((card) => card[attributeIndex]).toList(growable: false); | |
| } | |
| List<List<Attribute>> getAllAttributes(List<Card> cards) { | |
| List<List<Attribute>> atts = new List(); | |
| for(int i = 0; i < NUM_ATTRIBUTES; i++) { | |
| atts.add(getAttributes(cards, i)); | |
| } | |
| return atts; | |
| } | |
| bool isValidSet(List<Card> cards) { | |
| if(cards.length != VALID_SET_SIZE) { | |
| return false; | |
| } | |
| var allAtts = getAllAttributes(cards); | |
| for(var atts in allAtts) { | |
| if(!isAllDifferent(atts) && !isAllSame(atts)) { | |
| return false; | |
| } | |
| } | |
| return true; | |
| } | |
| List<List<Card>> getValidSets(List<Card> cards) { | |
| var sets = new List<List<Card>>(); | |
| for(int i = 0; i < cards.length; i++) { | |
| for(int j = i + 1; j < cards.length; j++) { | |
| for(int k = j + 1; k < cards.length; k++) { | |
| var possibleSet = [cards[i], cards[j], cards[k]]; | |
| if(isValidSet(possibleSet)) { | |
| sets.add(possibleSet); | |
| } | |
| } | |
| } | |
| } | |
| return sets; | |
| } | |
| class Hand { | |
| List<Card> cards; | |
| List<List<Card>> sets; | |
| void prettyPrint() { | |
| print("Dealt ${cards.length} cards"); | |
| cards.forEach((card) => print(" $card")); | |
| print("Containing ${sets.length} sets"); | |
| sets.forEach((set) { | |
| set.forEach((card) => print(" $card")); | |
| print(""); | |
| }); | |
| } | |
| } | |
| Hand getHand(int numCards, int numSets) { | |
| var hand = new Hand(); | |
| var deck = new Deck(); | |
| var rng = new Random(); | |
| while(true) { | |
| deck.shuffle(rng); | |
| hand.cards = deck.take(numCards).toList(growable: false); | |
| hand.sets = getValidSets(hand.cards); | |
| if(hand.sets.length == numSets) { | |
| break; | |
| } | |
| } | |
| return hand; | |
| } | |
| Hand getBasicHand() => getHand(9, 4); | |
| Hand getAdvancedHand() => getHand(12, 6); | |
| void main() { | |
| var basicHand = getBasicHand(); | |
| basicHand.prettyPrint(); | |
| } | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment