Recent

Author Topic: Deck of cards question  (Read 1366 times)

Sukuna

  • New Member
  • *
  • Posts: 15
Deck of cards question
« on: April 14, 2025, 01:29:27 pm »
Hello,
I am following this YT tutorial here

https://www.youtube.com/watch?v=F7tiVi0hcZM&list=PLB24C56953A79987A&index=21

and I wonder why the print-out of the array on my screen is vertical and not nice and spaced out horizontally.
I also wonder why in the code there has to be the for-to loop written twice instead of just once writing all together with the writeln command:

for x:= 1 to 4 do
for x:=1 to 13 do
cards[x,y] : = rank[ x ] + suit[y];
writeln(cards[x,y]);

Code: Pascal  [Select][+][-]
  1. program Project1;
  2.  
  3. {$mode objfpc}{$H+}
  4.  
  5. uses
  6.   {$IFDEF UNIX}
  7.   cthreads,
  8.   {$ENDIF}
  9.   Classes
  10.   { you can add units after this };
  11.  
  12.  
  13. var
  14.   suit:array[1..4]of string = ('D','S','H','C');
  15.   rank:array[1..13]of string = ('2','3','4','5','6','7','8','9','10','J','Q','K','A');
  16.   cards:array[1..4,1..13]of string;
  17.  
  18.   x:integer;
  19.   y:integer;
  20.  
  21.   begin
  22.  
  23.   for x:=1 to 4 do
  24.     for y:=1 to 13 do
  25.       cards[x,y] : = suit[x] + rank[y];
  26.  
  27.     for x:=1 to 4 do
  28.     for y:=1 to 13 do
  29.   writeln(cards[x,y],' ');
  30.  
  31.          readln;
  32.  
  33.  
  34.  
  35. end.
  36.  

Zvoni

  • Hero Member
  • *****
  • Posts: 3377
Re: Deck of cards question
« Reply #1 on: April 14, 2025, 01:40:58 pm »
Not tested:
From Line 27
Code: Pascal  [Select][+][-]
  1. for x:=1 to 4 do Begin
  2.     for y:=1 to 13 do begin Write(cards[x,y],#9); End;
  3.     writeln;
  4. End;
  5. readln;

One System to rule them all, One Code to find them,
One IDE to bring them all, and to the Framework bind them,
in the Land of Redmond, where the Windows lie
---------------------------------------------------------------------
Code is like a joke: If you have to explain it, it's bad

paweld

  • Hero Member
  • *****
  • Posts: 1617
Re: Deck of cards question
« Reply #2 on: April 14, 2025, 01:50:48 pm »
https://www.freepascal.org/docs-html/rtl/system/writeln.html
Quote
WriteLn does the same as Write for text files, and emits a Carriage Return - LineFeed character pair after that.
Best regards / Pozdrawiam
paweld

Nimbus

  • Jr. Member
  • **
  • Posts: 88
Re: Deck of cards question
« Reply #3 on: April 14, 2025, 01:52:38 pm »
Hello,

and I wonder why the print-out of the array on my screen is vertical and not nice and spaced out horizontally.

That is because you used WriteLn, which creates a new line for each entry. If you want everything on the same line, you need Write (that is without "Ln").

I also wonder why in the code there has to be the for-to loop written twice instead of just once writing all together with the writeln command:

I assume that demonstrates two separate operations, 1) Initializing the deck of cards; 2) Printing them out. You can combine those if you want to - just don't forget to enclose the inner loop body into a begin..end block, since it has multiple statements now

Code: Pascal  [Select][+][-]
  1. for x := 1 to 4 do
  2.   for y := 1 to 13 do
  3.   begin
  4.     cards[x, y] := suit[x] + rank[y];
  5.     write(cards[x, y], ' ');
  6.   end;
  7.  

Possibly the loop variables deserve better names here than x and y though.
« Last Edit: April 14, 2025, 02:02:51 pm by Nimbus »

Zvoni

  • Hero Member
  • *****
  • Posts: 3377
Re: Deck of cards question
« Reply #4 on: April 14, 2025, 01:53:09 pm »
tested.
The whole thing with a single Loop
Code: Pascal  [Select][+][-]
  1. program Project1;
  2.  
  3. {$mode objfpc}{$H+}
  4.  
  5. uses
  6.   {$IFDEF UNIX}
  7.   cthreads,
  8.   {$ENDIF}
  9.   Classes
  10.   { you can add units after this };
  11. var
  12.   suit:array[0..3]of string = ('D','S','H','C');
  13.   rank:array[0..12]of string = ('2','3','4','5','6','7','8','9','10','J','Q','K','A');
  14.   cards:array[0..3,0..12]of string;
  15.  
  16.   x:integer;
  17.   d,m,l,s,r:Integer;
  18.  
  19. begin
  20.   s:=Length(suit);
  21.   r:=Length(Rank);
  22.   l:=s*r;
  23.   For x:=0 To l-1 do
  24.     Begin
  25.       d:=x Div r;
  26.       m:=x Mod r;
  27.       cards[d,m]:=suit[d]+Rank[m];
  28.     end;
  29.   For x:=0 To l-1 Do
  30.     Begin
  31.       d:=x Div r;
  32.       m:=x Mod r;
  33.       Write(cards[d,m],#9);
  34.       if m=High(Rank) Then Writeln;
  35.     end;
  36.   readln;
  37. end.
One System to rule them all, One Code to find them,
One IDE to bring them all, and to the Framework bind them,
in the Land of Redmond, where the Windows lie
---------------------------------------------------------------------
Code is like a joke: If you have to explain it, it's bad

Sukuna

  • New Member
  • *
  • Posts: 15
Re: Deck of cards question
« Reply #5 on: April 14, 2025, 01:56:57 pm »
Hello,

and I wonder why the print-out of the array on my screen is vertical and not nice and spaced out horizontally.

That is because you used WriteLn, which creates a new line for each entry. If you want everything on the same line, you need Write (that is without "Ln").

I also wonder why in the code there has to be the for-to loop written twice instead of just once writing all together with the writeln command:

I assume that demonstrates two separate operations, 1) Initializing the deck of cards; 2) Printing them out. You can combine those if you want to - just don't forget to enclose the inner loop body into a begin..end block, since it has multiple statements now

Code: Pascal  [Select][+][-]
  1. for x := 1 to 4 do
  2.   for y := 1 to 13 do
  3.   begin
  4.     cards[x, y] : = suit[x] + rank[y];
  5.     write(cards[x, y], ' ');
  6.   end;
  7.  

Possibly the loop variables deserve better names here than x and y though.

Thank you , I know much more now.

Zvoni

  • Hero Member
  • *****
  • Posts: 3377
Re: Deck of cards question
« Reply #6 on: April 14, 2025, 01:59:36 pm »
Nitpicking

This causes a compile-error on my machine
Code: Pascal  [Select][+][-]
  1. cards[x, y] : = suit[x] + rank[y];

Spot the "mistake"
One System to rule them all, One Code to find them,
One IDE to bring them all, and to the Framework bind them,
in the Land of Redmond, where the Windows lie
---------------------------------------------------------------------
Code is like a joke: If you have to explain it, it's bad

Nimbus

  • Jr. Member
  • **
  • Posts: 88
Re: Deck of cards question
« Reply #7 on: April 14, 2025, 02:04:28 pm »
Nitpicking

This causes a compile-error on my machine
Code: Pascal  [Select][+][-]
  1. cards[x, y] : = suit[x] + rank[y];

Spot the "mistake"

Whoops, poor assignment operator, what did I do to it

Zvoni

  • Hero Member
  • *****
  • Posts: 3377
Re: Deck of cards question
« Reply #8 on: April 14, 2025, 04:08:17 pm »
And again condensed down:
Code: Pascal  [Select][+][-]
  1. program Project1;
  2. {$mode objfpc}{$H+}
  3. uses
  4.   {$IFDEF UNIX}cthreads,{$ENDIF}Classes{ you can add units after this };
  5. var
  6.   suit:array[0..3]of string = ('D','S','H','C');
  7.   rank:array[0..12]of string = ('2','3','4','5','6','7','8','9','10','J','Q','K','A');
  8.   cards:array[0..3,0..12]of string;
  9.  
  10.   x:integer;
  11.   d,m,l,s,r,h:Integer;
  12. begin
  13.   s:=Length(suit);
  14.   r:=Length(Rank);
  15.   h:=High(Rank);
  16.   l:=s*r;
  17.   For x:=0 To l-1 do
  18.     Begin
  19.       d:=x Div r;
  20.       m:=x Mod r;
  21.       cards[d,m]:=suit[d]+Rank[m];
  22.       Write(cards[d,m],#9);
  23.       if m=h Then Writeln;
  24.     end;
  25.   readln;
  26. end.

If you want to keep your 1-based Array-Indices.
Line 19+20 have to be changed to
Code: Pascal  [Select][+][-]
  1.       d:=(x Div r)+1;
  2.       m:=(x Mod r)+1;  
« Last Edit: April 14, 2025, 04:14:14 pm by Zvoni »
One System to rule them all, One Code to find them,
One IDE to bring them all, and to the Framework bind them,
in the Land of Redmond, where the Windows lie
---------------------------------------------------------------------
Code is like a joke: If you have to explain it, it's bad

Thaddy

  • Hero Member
  • *****
  • Posts: 19166
  • Glad to be alive.
Re: Deck of cards question
« Reply #9 on: April 14, 2025, 07:14:59 pm »
I have to find something for the TRank enum, but how about:
Code: Pascal  [Select][+][-]
  1. // can be beautified a bit
  2. {$mode objfpc}
  3. type
  4.   TSuit = (D,S,H,C);
  5.   // underscores are necessary
  6.   TRank = (_2,_3,_4,_5,_6,_7,_8,_9,_10,_J,_Q,_K,_A);
  7. var
  8.   cards:array[TSuit,TRank]of string;
  9.   suit:TSuit;  
  10.   rank:TRank;
  11. begin
  12.   // init cards
  13.   for suit in TSuit do
  14.     for rank in TRank do
  15.     begin
  16.       writestr(cards[suit,rank],suit,rank);
  17.       delete(cards[suit,rank],2,1); // delete underscore
  18.     end;
  19.   // print all cards
  20.   for suit in TSuit do
  21.     for rank in TRank do
  22.     begin
  23.       Write(cards[suit,rank]:4);
  24.       if rank=High(TRank) Then Writeln;
  25.     end;
  26. end.
Short...and just three variables.
« Last Edit: April 14, 2025, 07:42:31 pm by Thaddy »
objects are fine constructs. You can even initialize them with constructors.

Nimbus

  • Jr. Member
  • **
  • Posts: 88
Re: Deck of cards question
« Reply #10 on: April 14, 2025, 07:57:49 pm »
So this beginner's thread went out of hand and now it's Nitpicking Olympics  :)

Sukuna, don't worry if this (and some of the above) looks confusing - it is not directly connected to the tutorial you've been following, just a demonstrating some other approaches.

Code: Pascal  [Select][+][-]
  1. program SomeCards;
  2.  
  3. {$mode objfpc}{$H+}
  4. {$ModeSwitch advancedrecords}
  5.  
  6. uses
  7.   SysUtils, Generics.Collections;
  8.  
  9. type
  10.   TSuite = (stHearts, stClubs, stDiamonds, stSpades);
  11.   TRank = (rkTwo, rkThree, rkFour, rkFive, rkSix, rkSeven, rkEight,
  12.            rkNine, rkTen, rkJack, rkQueen, rkKing, rkAce);
  13.  
  14.   { TCard }
  15.  
  16.   TCard = record
  17.     Suite: TSuite;
  18.     Rank: TRank;
  19.     procedure Init(const ASuite: TSuite; const ARank: TRank);
  20.     function ToString: String;
  21.   end;
  22.  
  23.   TDeck = specialize TList<TCard>;
  24.  
  25. function SuiteToStr(const ASuite: TSuite): String;
  26. const
  27.   Names: array[stHearts..stSpades] of String = (
  28.     'Hearts', 'Clubs', 'Diamonds', 'Spades');
  29. begin
  30.   Result := Names[ASuite];
  31. end;
  32.  
  33. function RankToStr(const ARank: TRank): String;
  34. const
  35.   Names: array[rkTwo..rkAce] of String = (
  36.     'Two', 'Three', 'Four', 'Five', 'Six', 'Seven', 'Eight',
  37.     'Nine', 'Ten', 'Jack', 'Queen', 'King', 'Ace');
  38. begin
  39.   Result := Names[ARank];
  40. end;
  41.  
  42. { TCard }
  43.  
  44. procedure TCard.Init(const ASuite: TSuite; const ARank: TRank);
  45. begin
  46.   Suite := ASuite;
  47.   Rank := ARank;
  48. end;
  49.  
  50. function TCard.ToString: String;
  51. begin
  52.   Result := RankToStr(Rank) + ' of ' + SuiteToStr(Suite);
  53. end;
  54.  
  55. var
  56.   Deck: TDeck;
  57.   Card: TCard;
  58.   Suite: TSuite;
  59.   Rank: TRank;
  60.  
  61. begin
  62.   Deck := TDeck.Create;
  63.  
  64.   for Suite in TSuite do
  65.     for Rank in TRank do
  66.     begin
  67.       Card.Init(Suite, Rank);
  68.       Deck.Add(Card);
  69.     end;
  70.  
  71.   for Card in Deck do
  72.     Writeln(Card.ToString);
  73.  
  74.   FreeAndNil(Deck);
  75. end.

 :D
« Last Edit: April 14, 2025, 09:21:12 pm by Nimbus »

TBMan

  • Sr. Member
  • ****
  • Posts: 353
Re: Deck of cards question
« Reply #11 on: April 14, 2025, 08:03:47 pm »
Here's my homemade deck of cards unit. I've used it to write a few card games. There's a display procedure for textmode in there too, but I use sprites for the cards which is another topic. The program you write using this code should include the call to randomize prior to getting any cards.
from the deck.

Code: Pascal  [Select][+][-]
  1. Unit CardDek;
  2. interface
  3. uses ptccrt;
  4.  
  5.  
  6.  
  7. Type
  8. CardSuite = (Clubs, Diamonds, Heart, Spade);
  9.  
  10. CardValue = (Two, Three, Four, Five, Six, Seven, Eight, Nine, Ten, Jack, Queen, King, Ace);
  11.  
  12.  
  13.  
  14. CardRecord = record
  15.   Value : CardValue;
  16.   Suite : CardSuite;
  17.   BlackJackValue:Integer;
  18.   CardSelected:boolean;
  19. end;
  20.  
  21. CardDeck = record
  22.   Card  : CardRecord;
  23.   Dealt : boolean;
  24. end;
  25.  
  26. DeckofCards = array[0..51] of carddeck;
  27. Hand = array[0..9] of cardrecord;
  28.  
  29. var
  30.  
  31.  
  32.  
  33. SuiteCounter : CardSuite;
  34. ValueCounter : CardValue;
  35. Deck         : DeckofCards;
  36. DealerHand,PlayerHand: Hand;
  37.  
  38. Cardname:array[Two..Ace] of string;
  39. CardSuiteName:array[Clubs..Spade] of string;
  40.  
  41. Function GetcardName(Card:CardRecord):String;
  42.  
  43. Procedure InitDeck;
  44.  
  45. Procedure DrawTextCard(Card:CardRecord; Xpos,YPos:Integer);
  46.  
  47. Function GetACard:Integer;
  48.  
  49. Procedure CopyCard(Index:Integer;var ACard:Cardrecord);
  50.  
  51. Function CharLen(Ch:Char;Count:Integer):String;
  52.  
  53. {for building hands for testing}
  54. Function getTheCardvalue(v:cardvalue):integer;
  55. function GetAnotherSuit(suit:Cardsuite):integer;
  56.  
  57.  
  58. implementation
  59.  
  60.  
  61.  
  62.  
  63. {Cardname:array[Two..Ace] of string;
  64. CardSuiteName:array[Clubs..Spade] of string;}
  65.  
  66.  
  67. Function CharLen(Ch:Char;Count:Integer):String;
  68.  
  69. var
  70. s:string;
  71. J:integer;
  72.  
  73. begin
  74. S := '';
  75. For J := 1 to Count do
  76.  S:= s+ch;
  77. CharLen := S;
  78.  
  79. end;
  80.  
  81. Function GetcardName(Card:CardRecord):String;
  82. var
  83. S:String;
  84. begin
  85. S := CardName[Card.Value]+' of '+CardSuiteName[Card.Suite];
  86. GetCardName := S;
  87. end;
  88.  
  89.  
  90.  
  91. Procedure CopyCard(Index:Integer;var ACard:Cardrecord);
  92. Begin
  93. Acard.value := Deck[index].card.value;
  94. Acard.Suite := Deck[index].card.suite;
  95. Acard.BlackJackValue := Deck[index].card.blackjackvalue;
  96. end;
  97.  
  98. Procedure InitDeck;
  99.  
  100. var
  101. a:integer;
  102. begin
  103.  
  104. CardSuiteName[Clubs]    := 'Clubs ';
  105. CardSuiteName[Diamonds] := 'Diamonds';
  106. CardSuiteName[Heart]    := 'Hearts';
  107. CardSuiteName[Spade]    := 'Spades ';
  108. CardName[Two]   := '2';
  109. CardName[Three] := '3';
  110. Cardname[Four]  := '4';
  111. CardName[Five]  := '5';
  112. CardName[Six]   := '6';
  113. CardName[Seven] := '7';
  114. CardName[Eight] := '8';
  115. CardName[Nine]  := '9';
  116. CardName[Ten]   := '10';
  117. CardName[Jack]  := 'Jack';
  118. CardName[Queen] := 'Queen';
  119. CardName[King]  := 'King';
  120. CardName[Ace]   := 'Ace';
  121.  
  122. Fillchar(deck,sizeof(deck),0);
  123. Fillchar(DealerHand,sizeof(dealerhand),0);
  124. Fillchar(PlayerHand,sizeof(Playerhand),0);
  125. a := 0;
  126.  
  127. For SuiteCounter :=Clubs to Spade do
  128.  Begin
  129.  For ValueCounter := Two to Ace do
  130.   Begin
  131.     Deck[a].Card.Suite := SuiteCounter;
  132.     Deck[A].Card.Value := ValueCounter;
  133.     Case ValueCounter of
  134.     Two..Ten:Deck[a].Card.BlackJackValue := ord(ValueCounter)+2;
  135.     Jack..King:Deck[a].Card.BlackjackValue := 10;
  136.     Ace:Deck[a].Card.BlackJackValue := 11;
  137.     end;
  138.     a:=a+1;
  139.   End;
  140.  
  141.  end;
  142.  
  143. end;
  144.  
  145.  
  146.  
  147.  
  148.  
  149. Procedure DrawTextCard(Card:CardRecord; Xpos,YPos:Integer);
  150. var
  151. s:string;
  152. begin
  153.      TextBackground(15);
  154.      Case Card.suite of
  155.           Clubs, Spade:Textcolor(0);
  156.           Heart,Diamonds:TextColor(4);
  157.      End;
  158.  
  159.      GotoXY(Xpos,Ypos);
  160.      S := CharLen('*',17);
  161.      Write('*',s,'*');
  162.  
  163.      GotoXY(Xpos,YPos+1);
  164.      Write(charlen(' ',19));
  165.      GotoXY(XPos,YPos+1);
  166.      Write('³',Cardname[Card.Value]);
  167.  
  168.      Write(CardSuiteName[Card.Suite]);
  169.  
  170.      GotoXY(Xpos+18,Ypos+1);
  171.         Write('*');
  172.  
  173.      GotoXY(Xpos,Ypos+2);
  174.      S := CharLen('*',17);
  175.      Write('*',S,'*');
  176. end;
  177.  
  178. function GetAnotherSuit(suit:Cardsuite):integer;
  179. var
  180.   k,index :integer;
  181.   cardfound:boolean;
  182.   begin
  183.   k := 0;
  184.   cardfound := false;
  185.      for index := 0 to 51 do
  186.        begin
  187.            if not deck[index].dealt and not cardfound then
  188.             begin
  189.                if deck[index].card.suite = suit then
  190.                 begin
  191.                    deck[index].dealt := true;
  192.                    k := index;
  193.                    Cardfound := True;
  194.                 end;
  195.              end;
  196.  
  197.        end;
  198. result := k;
  199. end;
  200. Function getTheCardvalue(v:cardvalue):integer;
  201. var
  202.   k,
  203.   index:integer;
  204.   cardfound:boolean;
  205. begin
  206. k := 0;
  207. cardfound:= false;
  208. for index := 0 to 51 do
  209.   begin
  210.     if not deck[index].dealt then
  211.       if not cardfound then
  212.       if deck[index].card.value = v then
  213.          begin
  214.             k := index;
  215.             deck[index].dealt := true;
  216.             cardfound := true;   {just get the first one}
  217.          end;
  218.   end;
  219. result := k;
  220. end;
  221.  
  222. Function GetACard:Integer;
  223. Var
  224. A:Integer;
  225.  
  226. begin
  227.  
  228.      Repeat
  229.            A:= random(52); {Pick a card index between 0 and 51}
  230.      Until Not Deck[a].dealt; {until not dealt card found}
  231.  
  232.      Deck[a].dealt := true;
  233.  
  234.      GetACard:= a;
  235.  
  236. end;
  237.  
  238. end.
  239.  
  240.  
  241.  
« Last Edit: April 14, 2025, 08:05:49 pm by TBMan »
Barry

Newest game (clone),
Missile Commander:
https://www.youtube.com/watch?v=tgKz0cxog-k

Thaddy

  • Hero Member
  • *****
  • Posts: 19166
  • Glad to be alive.
Re: Deck of cards question
« Reply #12 on: April 15, 2025, 06:07:29 am »
A bit shorter than my last one and understandable:
Code: Pascal  [Select][+][-]
  1. {$mode objfpc}
  2. type
  3.   TSuit = (Diamonds,Spades,Hearts,Clovers);
  4.   TRank = (two,three,four,five,six,seven,eight,nine,ten,jack,Queen,King,Ace);
  5. var
  6.   suit:TSuit;  
  7.   rank:TRank;
  8.   cards:array[TRank,TSuit] of string;// store for game engines
  9. begin
  10.   // 13 x 4 displays better than 4 x 13 in consoles
  11.   for rank in TRank do
  12.     for suit in TSuit do
  13.     begin
  14.       writestr(cards[rank,suit],rank:5,' of ',suit:10);
  15.       write(cards[rank,suit]);
  16.       if suit=high(TSuit) then writeln;
  17.     end;
  18. end.
« Last Edit: April 15, 2025, 06:55:31 am by Thaddy »
objects are fine constructs. You can even initialize them with constructors.

Thaddy

  • Hero Member
  • *****
  • Posts: 19166
  • Glad to be alive.
Re: Deck of cards question
« Reply #13 on: April 15, 2025, 07:22:15 am »
A good set of card game images and sounds is here:
(translating this above code to visual poker game)
https://kenney.nl/assets/boardgame-pack
It is free, donations are appreciated.
objects are fine constructs. You can even initialize them with constructors.

 

TinyPortal © 2005-2018