Set puzzle: Difference between revisions

Content added Content deleted
m (→‎{{header|REXX}}: added/changed whitespace and comments, split some compound clauses, used a template for the output section.)
Line 2,696: Line 2,696:


Row[{Style[#2, #1], #3, #4}] & @@@ deal[{9, 4}]</lang>
Row[{Style[#2, #1], #3, #4}] & @@@ deal[{9, 4}]</lang>

=={{header|Nim}}==
<lang Nim>import algorithm, math, random, sequtils, strformat, strutils

type

# Card features.
Number {.pure.} = enum One, Two, Three
Color {.pure.} = enum Red, Green, Purple
Symbol {.pure.} = enum Oval, Squiggle, Diamond
Shading {.pure.} = enum Solid, Open, Striped

# Cards and list of cards.
Card = tuple[number: Number; color: Color; symbol: Symbol; shading: Shading]
Triplet = array[3, Card]
Deck = array[81, Card]

# Game level.
Level {.pure.} = enum Basic = "basic", Advanced = "advanced"


proc `$`(card: Card): string =
## Return the string representation of a card.
toLowerAscii(&"{card.number:<5} {card.color:<6} {card.symbol:<8} {card.shading:<7}")


proc initDeck(): Deck =
## Create a new deck.
var i = 0
for num in Number.low..Number.high:
for col in Color.low..Color.high:
for sym in Symbol.low..Symbol.high:
for sh in Shading.low..Shading.high:
result[i] = (number: num, color: col, symbol: sym, shading: sh)
inc i


proc isSet(triplet: Triplet): bool =
## Check if a triplets of cards is a set.
sum(triplet.mapIt(ord(it.number))) mod 3 == 0 and
sum(triplet.mapIt(ord(it.color))) mod 3 == 0 and
sum(triplet.mapIt(ord(it.symbol))) mod 3 == 0 and
sum(triplet.mapIt(ord(it.shading))) mod 3 == 0


proc playGame(level: Level) =
## Play the game at given level.

var deck = initDeck()
let (nCards, nSets) = if level == Basic: (9, 4) else: (12, 6)
var sets: seq[Triplet]
var hand: seq[Card]
echo &"Playing {level} game: {nCards} cards, {nSets} sets."

block searchHand:
while true:
sets.setLen(0)
deck.shuffle()
hand = deck[0..<nCards]
block countSets:
for i in 0..(nCards - 3):
for j in (i + 1)..(nCards - 2):
for k in (j + 1)..(nCards - 1):
let triplet = [hand[i], hand[j], hand[k]]
if triplet.isSet():
sets.add triplet
if sets.len > nSets:
break countSets # Too much sets. Try with a new hand.
if sets.len == nSets:
break searchHand # Found: terminate search.

# Display the hand and the sets.
echo "\nCards:"
for card in sorted(hand): echo " ", card
echo "\nSets:"
for s in sets:
for card in sorted(s): echo " ", card
echo()


randomize()
playGame(Basic)
echo()
playGame(Advanced)</lang>

{{out}}
<pre>Playing basic game: 9 cards, 4 sets.

Cards:
one purple oval solid
one purple diamond open
two red squiggle open
two green diamond open
two green diamond striped
two purple oval open
three red diamond solid
three red diamond open
three purple squiggle open

Sets:
one purple diamond open
two purple oval open
three purple squiggle open

one purple diamond open
two green diamond striped
three red diamond solid

two red squiggle open
two green diamond open
two purple oval open

one purple diamond open
two green diamond open
three red diamond open


Playing advanced game: 12 cards, 6 sets.

Cards:
one green diamond striped
one purple diamond striped
two red oval open
two red diamond open
two green oval solid
two green oval striped
three red squiggle striped
three green oval solid
three green squiggle solid
three green squiggle open
three green squiggle striped
three purple diamond open

Sets:
one green diamond striped
two green oval striped
three green squiggle striped

one purple diamond striped
two green oval striped
three red squiggle striped

one green diamond striped
two green oval solid
three green squiggle open

one purple diamond striped
two red oval open
three green squiggle solid

three green squiggle solid
three green squiggle open
three green squiggle striped

three red squiggle striped
three green oval solid
three purple diamond open</pre>


=={{header|PARI/GP}}==
=={{header|PARI/GP}}==