Skip to content

Instantly share code, notes, and snippets.

@heimp
Created January 9, 2014 15:06
Show Gist options
  • Save heimp/8335486 to your computer and use it in GitHub Desktop.
Save heimp/8335486 to your computer and use it in GitHub Desktop.
set game for rosetta code maybe
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