13
\$\begingroup\$

There's never really been a definitive ASCII-cards challenge AFAIK. So, using the following deck of ASCII cards:

.------..------..------..------..------..------..------..------..------..------..------..------..------.
|2.--. ||3.--. ||4.--. ||5.--. ||6.--. ||7.--. ||8.--. ||9.--. ||T.--. ||J.--. ||Q.--. ||K.--. ||A.--. |
| (\/) || (\/) || (\/) || (\/) || (\/) || (\/) || (\/) || (\/) || (\/) || (\/) || (\/) || (\/) || (\/) |
| :\/: || :\/: || :\/: || :\/: || :\/: || :\/: || :\/: || :\/: || :\/: || :\/: || :\/: || :\/: || :\/: |
| '--'2|| '--'3|| '--'4|| '--'5|| '--'6|| '--'7|| '--'8|| '--'9|| '--'T|| '--'J|| '--'Q|| '--'K|| '--'A|
'------''------''------''------''------''------''------''------''------''------''------''------''------'
.------..------..------..------..------..------..------..------..------..------..------..------..------.
|2.--. ||3.--. ||4.--. ||5.--. ||6.--. ||7.--. ||8.--. ||9.--. ||T.--. ||J.--. ||Q.--. ||K.--. ||A.--. |
| :/\: || :/\: || :/\: || :/\: || :/\: || :/\: || :/\: || :/\: || :/\: || :/\: || :/\: || :/\: || :/\: |
| :\/: || :\/: || :\/: || :\/: || :\/: || :\/: || :\/: || :\/: || :\/: || :\/: || :\/: || :\/: || :\/: |
| '--'2|| '--'3|| '--'4|| '--'5|| '--'6|| '--'7|| '--'8|| '--'9|| '--'T|| '--'J|| '--'Q|| '--'K|| '--'A|
'------''------''------''------''------''------''------''------''------''------''------''------'
.------..------..------..------..------..------..------..------..------..------..------..------..------.
|2.--. ||3.--. ||4.--. ||5.--. ||6.--. ||7.--. ||8.--. ||9.--. ||T.--. ||J.--. ||Q.--. ||K.--. ||A.--. |
| :/\: || :/\: || :/\: || :/\: || :/\: || :/\: || :/\: || :/\: || :/\: || :/\: || :/\: || :/\: || :/\: |
| (__) || (__) || (__) || (__) || (__) || (__) || (__) || (__) || (__) || (__) || (__) || (__) || (__) |
| '--'2|| '--'3|| '--'4|| '--'5|| '--'6|| '--'7|| '--'8|| '--'9|| '--'T|| '--'J|| '--'Q|| '--'K|| '--'A|
'------''------''------''------''------''------''------''------''------''------''------''------''------'
.------..------..------..------..------..------..------..------..------..------..------..------..------.
|2.--. ||3.--. ||4.--. ||5.--. ||6.--. ||7.--. ||8.--. ||9.--. ||T.--. ||J.--. ||Q.--. ||K.--. ||A.--. |
| :(): || :(): || :(): || :(): || :(): || :(): || :(): || :(): || :(): || :(): || :(): || :(): || :(): |
| ()() || ()() || ()() || ()() || ()() || ()() || ()() || ()() || ()() || ()() || ()() || ()() || ()() |
| '--'2|| '--'3|| '--'4|| '--'5|| '--'6|| '--'7|| '--'8|| '--'9|| '--'T|| '--'J|| '--'Q|| '--'K|| '--'A|
'------''------''------''------''------''------''------''------''------''------''------''------''------'

Take two integers, p and q as input; where p is the number of players and q is the number of cards each player gets.

  • Randomly shuffle the deck of cards (this is ambiguous, but means that all cards must be equally likely to appear anywhere once).
  • Deal 1 round of cards per player, outputting q rows of p cards each row.

Rules:

  • The results should be uniformly random, each card should be equally likely to appear anywhere.
  • It is guaranteed that 0 < p*q <= 52 and p < 10, you may have undefined behavior for scenarios where this is not met.
  • You should output q rows of cards with p cards per row.
  • Each column should be separated by | (a pipe char surrounded by spaces); if you choose a different char than this, explain why. Surrounding spaces here are NOT optional.
  • Each row must have 1 or more newlines inbetween them, more than one is acceptable, 0 is not (1 newline meaning the newline there by default).
  • Each row should be labeled with the player who owns it in the format "Player N" (0 or 1-indexed is fine).
  • No one card may appear more than once.
  • T is for Ten.

Examples:

Function(p=1,q=1):

Player 1 # Can also be 0.
.------.
|2.--. |
| (\/) |
| :\/: |
| '--'2|
'------'

Function(p=2,q=1):

Player 1 | Player 2 # Can also be "Player 0 | Player 1"
.------. | .------.
|2.--. | | |T.--. |
| (\/) | | | (\/) |
| :\/: | | | :\/: |
| '--'2| | | '--'T|
'------' | '------'

Function(p=2,q=2):

Player 1 | Player 2 # Can also be "Player 0 | Player 1"
.------. | .------.
|J.--. | | |3.--. |
| (\/) | | | :/\: |
| :\/: | | | :\/: |
| '--'J| | | '--'3|
'------' | '------'
.------. | .------.
|8.--. | | |6.--. |
| :(): | | | :/\: |
| ()() | | | (__) |
| '--'8| | | '--'6|
'------' | '------'

Artistic credit to a font on: http://patorjk.com/software/taag

\$\endgroup\$
  • 5
    \$\begingroup\$ Are you going to post many card-challenges from the cards you found at patorjk.com/software/taag? \$\endgroup\$ – user72269 Oct 25 '17 at 22:29
  • 1
    \$\begingroup\$ Soooo...Can we "use" this site to output the result??? \$\endgroup\$ – J42161217 Oct 25 '17 at 22:37
  • 1
    \$\begingroup\$ I mean: Can I make a program that outputs patorjk.com/software/taag/… this for your last test case? \$\endgroup\$ – J42161217 Oct 25 '17 at 22:49
  • 5
    \$\begingroup\$ Also, Each row must have 1 or more newlines inbetween them, more than one is acceptable, 0 is not. ...But your test cases don't have newlines between cards..? \$\endgroup\$ – totallyhuman Oct 25 '17 at 23:09
  • 1
    \$\begingroup\$ There was almost one challenge on ASCII cards: Play time posted by me. \$\endgroup\$ – sergiol Oct 25 '17 at 23:55

10 Answers 10

6
\$\begingroup\$

Charcoal, 142 133 125 bytes

NθFN«F¬¬ι«→↑×⁶θ| »Player IιFθ«↙↓.↓⁴←'←⁶↑'↑⁴.P⁶↓≔‽⁵²εW№υε≔‽⁵²ε⊞υε≔§”w↘τ[⁵PkxτG”εδδ.--.¶✂”{➙aETê;s∨Hμ⁼⎚↑Z~SÀd~⌀Tê”﹪ε⁴φ⁴'--'δ↘

Try it online! Link is to verbose version of code. Edit: Saved 9 bytes by improving my random sampling code. Saved a further 8 bytes by improving my suit printing code. Explanation:

Nθ

Read the number of cards into q.

FN«

Loop over each player.

F¬¬ι«→↑×⁶θ| »

If this is not the first player, print the vertical line between the previous and this player.

Player Iι

Print the player number.

Fθ«

Loop over each card.

↙↓.↓⁴←'←⁶↑'↑⁴.P⁶↓

Print the card's edge.

≔‽⁵²εW№υε≔‽⁵²ε⊞υε

Pick a card index that hasn't already been picked, and add it to the list of picked card indices.

≔§”w↘τ[⁵PkxτG”εδδ

Choose and print the card's rank by cyclically indexing into a string of valid card ranks (2-9, T, J, Q, K, A).

.--.¶

Print the top of the suit.

✂”{➙aETê;s∨Hμ⁼⎚↑Z~SÀd~⌀Tê”﹪ε⁴φ⁴

Print the middle of the suit by slicing into a string. The slice begins at the card index modulo 4 and takes every 4th character until the string runs out (or the f=1000th character is reached). Since 4 and 13 are coprime this ensures that all 52 cards are possible.

'--'δ↘

Print the bottom of the suit and a copy of the rank, and then move to a point that conveniently is not too far away from either the copy of the rank, the start of the next card, or the start of the dividing line for the next player.

\$\endgroup\$
  • \$\begingroup\$ When I saw this in the sandbox it was a k-c challenge to print the deck, which took me 102 bytes: Try it online! Link is to verbose version of code. \$\endgroup\$ – Neil Dec 19 '17 at 0:49
3
\$\begingroup\$

Python 2, 357 bytes

from random import*
p,q=input()
A,V=':/\:',':\/:'
c=sample([(""".------.
|%s.--. |
| %s |
| %s |
| '--'%s|
'------'"""%(n,s,t,n)).split('\n')for s,t in('(\/)',V),(A,V),(A,'(__)'),(':():','()()')for n in'123456789TJQKA'],p*q)
print' | '.join('Player '+`i`for i in range(p))
for i in range(0,p*q,p):print'\n'.join(map(' | '.join,zip(c[i:i+p][0],c[i:i+p][1])))

Try it online!

I have no friggin' idea.

\$\endgroup\$
3
\$\begingroup\$

Jelly, 126 bytes

³‘Ḷj“×ṁẹHY»;⁶¤ṫ5W;
2r9;“TJQKA”
“¡ẏ%TZ=ẹaɦAY’ṃ“(\/)_:”s4s2
“E¬ƭḊHẈḢ“ðİ“|e*Ḳ?BḤ’ṃ“. -|1¶'”żÐ€¢FỴ$€p2£j/€Ẋ
¢ssḢµṣ€”1Zj€“ | ”Yµ€ÑY

Try it online!

\$\endgroup\$
3
\$\begingroup\$

JavaScript (ES6), 328 ... 312 bytes

Takes input in currying syntax (p)(q). Players are 0-indexed.

p=>g=(q,i=p*q*6,d=[...Array(52).keys(a=`:\\/:,(__),()(),(\\/),:/\\:,:():, | ,
,.3.,|0.--. |,| 1 |,| 2 |,| '--'0|,'3',Player 4`.split`,`)].sort(_=>Math.random()-.5))=>i--+p?g(q,i,d)+a[i%p?6:7]+a[i<0?14:i/p%6|8].replace(/\d/,c=>['TJQKA'[j=x>>2]||j-3,a['3454'[x&=3]],a[x%3],'------',p+i][c],x=d[i%p+p*(i/p/6|0)]):''

Demo

let f =

p=>g=(q,i=p*q*6,d=[...Array(52).keys(a=`:\\/:,(__),()(),(\\/),:/\\:,:():, | ,
,.3.,|0.--. |,| 1 |,| 2 |,| '--'0|,'3',Player 4`.split`,`)].sort(_=>Math.random()-.5))=>i--+p?g(q,i,d)+a[i%p?6:7]+a[i<0?14:i/p%6|8].replace(/\d/,c=>['TJQKA'[j=x>>2]||j-3,a['3454'[x&=3]],a[x%3],'------',p+i][c],x=d[i%p+p*(i/p/6|0)]):''

;(update = _ => O.innerText = f(+P.value)(+Q.value))()
<label>Players <input id=P type=number value=1 onchange="update()"/></label> <label>Cards <input id=Q type=number value=1 onchange="update()"/></label> <button onclick="update()">Deal</button><pre id=O style="font-size:10px"></pre>

How?

This is a recursive function, building the output from bottom to top. During the main part in which the cards are drawn, i is initialized to p*q*6 and decremented until it reaches 0. We then draw the header by further decrementing i until it reaches -p.

The ASCII art is split into small pieces stored into the array a[]. The table below describes the content of a[], which makes the rest of the code easier to understand.

 Index | Content    | Description
-------+------------+------------------------------------------------
    0  | ":\\/:"    | bottom of 'diamonds' and 'hearts'
    1  | "(__)"     | bottom of 'spades'
    2  | "()()"     | bottom of 'clubs'
    3  | "(\\/)"    | top of 'hearts'
    4  | ":/\\:"    | top of 'diamonds' and 'spades'
    5  | ":():"     | top of 'clubs'
    6  | " | "      | player separator
    7  | "\n"       | line-feed
    8  | ".3."      | card row #1, "3" --> "------"
    9  | "|0.--. |" | card row #2, "0" --> symbol of card value
   10  | "| 1 |"    | card row #3, "1" --> top of color ASCII art
   11  | "| 2 |"    | card row #4, "2" --> bottom of color ASCII art
   12  | "| '--'0|" | card row #5, "0" --> symbol of card value
   13  | "'3'"      | card row #6, "3" --> "------"
   14  | "Player 4" | header, "4" --> player ID

Formatted and commented

p => g = (                                // p = number of players
  q,                                      // q = number of cards
  i = p * q * 6,                          // i = counter
  d = [...Array(52).keys(                 // d = deck
    a = `:\\/:,(__),...`.split`,`         // a = ASCII art pieces (truncated, see above)
  )].sort(_ => Math.random() - .5)        // shuffle the deck
) =>                                      //
  i-- + p ?                               // if i is greater than -p:
    g(q, i, d) +                          //   do a recursive call and append ...
    a[i % p ? 6 : 7] +                    //   separator or line-feed
    a[i < 0 ? 14 : i / p % 6 | 8]         //   header or card row
    .replace(/\d/, c => [                 //   where digits are replaced with:
        'TJQKA'[j = x >> 2] || j - 3,     //     0: symbol of card value
        a['3454'[x &= 3]],                //     1: top of color ASCII art
        a[x % 3],                         //     2: bottom of color ASCII art
        '------',                         //     3: horizontal border
        p + i                             //     4: player ID
      ][c],                               //
      x = d[i % p + p * (i / p / 6 | 0)]  //   x = current card with: bits 0-1 = color
    )                                     //                          bits 2-5 = value
  :                                       // else:
    ''                                    //   stop recursion
\$\endgroup\$
2
\$\begingroup\$

Python 2, 382 358 346 338 332 bytes

from random import*
p,n=input()
d=zip([0,1,2,3]*13,'23456789TJQKA'*4)
shuffle(d)
C=""".------.
|%s.--. |
| %s |
| %s |
| '--'%s|
'------'"""
print' | '.join('Player '+`i`for i in range(p))
exec"for l in zip(*[(C%(v,'(:::\/(//\)\):::'[s::4],':((:\_)\/_(/:)):'[s::4],v)).split('\\n')for s,v in d[:p]]):print' | '.join(l)\nd=d[p:]\n"*n

Try it online!

\$\endgroup\$
2
\$\begingroup\$

SOGL V0.12, 106 bytes

E⁽⁰⅜║(Ηe─t¦4»\$²‘8n{"1<ω⅛┘‘4n╬¡;4n33žASUjk"TJQKA”+{a;22žF75ž}}'#δ№{ψ⌡≤οc+C}c_.∫:"▓⅛▲ŗ‘Κ⁽e{≤+};H?;lƧ |Γ∙┼;┼

Try it Here!

Card generating:

...‘                     push "(\/):\/::/\::\/::/\:(__):():()()" - the suits
    8n                   split to line lengths of 8 - individual suits
      {                  for each suit
       "...‘               push ".---| .-|   " - a quarter of a suit
            4n             split to line lengths of 4 - [".---", "| .-", "|   "]
              έ           quad palindromize - empty card
                ;          get the suit on top
                 4n        split to line lengths of 4
                   33ž     insert in the card at [3; 3]
                      A    save on variable A - card template
SU                         push "1234567890"
  jk                       remove the first and last digits
    "TJQKA”+               append "TJQKA"
            {         }    for each number - "23456789TJQKA"
             a               load the template
              ;22ž           at [2; 2] insert the current number
                  F75ž       at [7; 5] insert the current number

Shuffling:

'#             push 52
  δ            lower range - [0, 1, ..., 50, 51]
   №           reverse - [51, 50, ..., 1, 0]
    {       }  for each, pushing the current item
     ψ           get a random number from 0 to ToS (inclusive)
      ⌡          that many times
       ≤           put the first item of the stack on the top
        οc+C     prepend that to the variable C, predefined with an empty array

Dealing:

c_              push Cs contents on the stack - the stack is now a mess of cards
  .∫            repeat input times - each player - pushing the current player number
    :             duplicate the number
     "..‘         push "player "
         Κ        prepend "player " to the number
          ⁽       uppercase the 1st letter
           e{  }  repeat 2nd input times
             ≤      put the first stack item on the top
              +     append it to "Player X" vertically (making an array)
;                 get the other copy of the player number
 H?               if POP-1 (aka if it's not 1)
   ;                swap the top 2 items - the current collumn and all the previous ones (by then they've been joined together)
    l               get its (vertical) length
     Ƨ |            push " |"
        Γ           palindromize - [" | "]
         ∙          multiply " | " vertically that length times
          ┼         append it horizontally (to the previous collumns)
           ;┼       append the current collumn
\$\endgroup\$
2
\$\begingroup\$

Ruby, 262 bytes

->p,q{a=[*0..51].shuffle
puts ["Player %d"]*p*(d=" | ")%[*1..p],(1..q*6).map{|i|(["'------'
.------.
|%X.--. |
| %s |
| %s |
| '--'%X|".split($/)[i%6]]*p*d%a[i/6*p,p].map{|j|["(\\/):()::/\\:"[u=j%4*4-4,4],":\\/:()():\\/:(__)"[u,4],j/4][i%3]}).tr("01BC","TJQK")}}

Harder to follow, but shorter!

Ruby, 279 bytes

->p,q{puts [*1..p].map{|k|"Player #{k}"}*" | "
a=[*0..51].shuffle
(q*6).times{|i|puts [".------.
|%s.--. |
| %s |
| %s |
| '--'%s|
'------'".split($/)[i%6]]*p*" | "%a[i/6*p,p].map{|j|[":\\/:()():\\/:(__)"[u=j%4*4-4,4],("%X"%(j/4)).tr("01BC","TJQK"),"(\\/):()::/\\:"[u,4]][i%3]}}}

Builds a format for each row, then uses the % operator like sprintf to populate it.

The fact that the card value appears on every 3rd row is handy. Card values are presented in hexadecimal with the digits 01BC substituted to TJQK.

Saved 4 bytes from the suit symbols by considering that the top of diamonds and spades are the same but added 2 back on for the -4 at the end of j%4*4-4 Suit codes are -4 0 4 or 8 where [-4,4] means 4 characters starting the 4th last character in the string.

Could probably save a few more bytes. Having to repeat code for the player identifications is ugly.

\$\endgroup\$
2
\$\begingroup\$

PHP, 509 bytes

<?$hu='(\/}';$hv=$dv=':\/:';$du=$su=':/\:';$sv='(__)';$cu=':():';$cv='()()';$q="------";$t=$argv[1];foreach([h,d,s,c]as$a)foreach([2,3,4,5,6,7,8,9,T,J,Q,K,A]as$b)$c[]=[$b,$a];shuffle($c);$h=$a=0;for(;$a<$t;$a++)$e[]="Player $a";$f[]=join(" | ",$e);for($g=$argv[2];$g--;){$p=$i=$k=$l=$m=$r=[];$j=$h+$t;for(;$h<$j;$h++){$n=$c[$h][0];$o=$c[$h][1];$p[]=".$q.";$i[]="|$n.--. |";$k[]="| ${$o.u} |";$l[]="| ${$o.v} |";$m[]="| '--'$n|";$r[]="'$q'";}foreach([p,i,k,l,m,r]as$b)$f[]=join(" | ",${$b});}echo join('
',$f);

Try it online!

This is my first attempt at code golf, so it can probably be improved a lot. I figured I had to start somewhere. :)

\$\endgroup\$
1
\$\begingroup\$

Java (OpenJDK 8), 784 835 843 826 815 781 775 bytes

String k(String s){return s.replaceAll("...$","\n");}
p->q->{int c=0,l=0,s[]=new int[p*q],i=0,j,t,b;java.util.List e=new java.util.Stack();String v="TJQK",o="",n[]=new String[p*q],x=o;for(;i<p;o+="Player "+i+++" | ",x+=v);o=k(o);for(i=0;i<q;i++){o=k(o+x.replace(v,".------. | "));for(j=0;j<p;j++){do{t=(int)(Math.random()*13)+1;b=(int)(Math.random()*4);}while(e.contains(t+""+v.charAt(b)));e.add(t+""+v.charAt(b));s[c]=b;n[c]=t<2?"A":t<10?""+t:""+v.charAt(t-10);o+="|2.--. | | ".replace("2",n[c++]);}o=k(o);for(j=0;j<p;j++,l++)o+="| "+(s[l]<1?"(\\/)":s[l]<3?":/\\:":":():")+" | | ";o=k(o);for(j=0;j<p;j++)o+="| "+(s[i*p+j]<2?":\\/:":s[i*p+j]<3?"(__)":"()()")+" | | ";o=k(o);for(j=0;j<p;)o+="| '--'2| | ".replace("2",n[i*p+j++]);o=k(k(o)+x.replace(v,"'------' | "));}return o;}

Try it online!

Why the downvote, it complies with the spec

\$\endgroup\$
  • \$\begingroup\$ Also, you should create alternate methods instead of creating Function<String,String>: the latter is very, very costly. Both at creation and when used. \$\endgroup\$ – Olivier Grégoire Oct 26 '17 at 11:42
  • \$\begingroup\$ I'm assuming the downvote was for the original bugged answer, but the current seems correct, so I've upvoted to neutralize it. Some small things to golf: parenthesis can be removed at n[c]=t<2?"A":t<10?""+t:""+"TJQK".charAt(t-10); for(j=0;j<p;j++){o+=...;l++;} can be for(j=0;j<p;l++,j++)o+=...;; you can return o; instead of System.out.print(o); by using a second Function instead of Consumer; ,y=p*q can be removed and you can use p*q two times directly instead of y. There is without doubt a lot more to golf, but I don't have time to look into that right now.. \$\endgroup\$ – Kevin Cruijssen Oct 26 '17 at 13:48
  • 1
    \$\begingroup\$ @KevinCruijssen Actually, no. I downvoted after the first edit for "no effort in golfing" beyond removing spaces and using 1-char variable names. My guess is that Roberto Graham should entirely re-read Tips for golfing in Java. The point is that it indeed complies to the spec of the challenge, but not to the spec of the code-golf tag. \$\endgroup\$ – Olivier Grégoire Oct 26 '17 at 14:50
  • \$\begingroup\$ How I know it can be golfed further? I was around 400 bytes when I gave up after seeing this answer, and I estimated around 50 more bytes the rest to finish it. 450 bytes vs. 850, there's barely any golf involved. \$\endgroup\$ – Olivier Grégoire Oct 26 '17 at 14:55
  • \$\begingroup\$ s[l]<2?":/\\:":s[l]<3?":/\\:" can be s[l]<3?":/\\:" and s[i*p+j]<1?":\\/:":s[i*p+j]<2?":\\/:" can be s[i*p+j]<2?":\\/:". @OlivierGrégoire And I'm aware it can most likely be almost halved, so I understand the downvote. But this is mostly a lack of experience, and indeed not reading all the tips multiple times. Some of the things in the answer I've done in the past as well, and this isn't a particular easy challenge for Java. Btw, if you have a 400-450 byte answer, why don't you post it as a separated answer then (if significantly different enough)? You'd have my upvote. ;) \$\endgroup\$ – Kevin Cruijssen Oct 26 '17 at 15:13
1
\$\begingroup\$

Python 3, 332 Bytes

from random import*
P=lambda x:print(*x,sep=' | ')
R=range
def f(p,c):
 P(f"Player {i}"for i in R(p))
 d=[f".------.,|{n}.--. |,| {a[:4]} |,| {a[4:]} |,| '--'{n}|,'------'".split(",")for a,n in sample([*zip(r':/\:(__) (\/):\/: :/\::\/: :():()()'.split()*13,'A23456789TJQK'*4)],p*c)]
 for i in R(c):
  for t in zip(*d[i::c]):
   P(t)
\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.