if 0 {
MiHa 2015-06-24: One of the example-programs on my HelloWorld-page creates a deck of cards,
so I had the idea to expand that into a simple cardgame, for the tcl-console.
Blackjack is quite simple, and with (debug-)options still in place to show the cards "in the open",
this would nicely double as a tcl-tutorial and a blackjack-trainer.
With ideas and code from the following pages:
}
# Whitejack.tcl - MiHa - 2015-06-25 # http://wiki.tcl.tk/41565 # http://ideone.com/jVxnHV puts "Whitejack:\n" proc help {} { ;# Todo: needs rewording puts "\nWhitejack - a cardgame much like simplified, self-service blackjack." puts {It is played with one or more decks of 52 cards. The object of the game is to beat the dealer: * Get 21 points on the player's first two cards (called a blackjack), without a dealer blackjack; * Reach a final score higher than the dealer without exceeding 21; * orLet the dealer draw additional cards until his or her hand exceeds 21. The player is dealt an initial two-card hand and add together the value of their cards. Face cards (kings, queens, and jacks) count as ten points. An ace is worth 1 point or 11 points, owners choice. All other cards count as the numeric value shown on the card. After their initial two cards, players can get a "hit", i.e. take an additional card. In a given round, the player or the dealer wins by having a score of 21 or by having the highest score that is less than 21. Scoring higher than 21 (called "busting" or "going bust") results in a loss.Commands: --------- h : help q : quit n : new cards: add a fresh pack of 52 cards to the deck. f = fill: move cards from discard-pile to the end of the deck. t = trash: empty both hands and the discard-pile. f : fill: move cards from discard-pile to the end of the deck. t : trash: empty both hands and the discard-pile. 0-9 : move the card from position 0..9 of the deck to the end of the deck. 0 : move the card from the front of the deck to the discard-pile 1 : move the card from the front of the deck to the end of the deck. 2-9 : move the card from position 2..9 of the deck to the end of the deck. % : swap the two cards at the front of the deck (positions 1 and 2). s : shuffle the deck (do a number of "1-9"-actions). d,- : dealer-draw: move first card from deck to dealer's hand b,l : bust: player loses the round w : win : player wins the round x = discard: move cards from player's hand to the discard-pile y = discard: move cards from dealer's hand to the discard-pile x : discard: move cards from player's hand to the discard-pile y : discard: move cards from dealer's hand to the discard-pile } proc showStatus {} { global deck discard playerHand dealerHand cWin cLoss puts "\nStatus:" puts -nonewline "Number of cards in " puts -nonewline "deck: [llength $deck] " puts -nonewline "discard: [llength $discard] " puts -nonewline "playerHand: [llength $playerHand] " puts "dealerHand: [llength $dealerHand] " puts "Wins: $cWin Losses: $cLoss" #puts "card #3 [lindex $::deck 2]" ;# index is zero-based #showList "Deck" $deck 0 19 showFirst "Deck" $deck 18 showLast "Deck" $deck 18 puts "Player: $playerHand Value: [cardValue $playerHand]" puts "Dealer: $dealerHand Value: [cardValue $dealerHand]" puts "Player: $playerHand" puts "Dealer: $dealerHand" proc win {x} { if { $x>0 } { puts -nonewline "Making cards..." set i 0 # For unicode, see also: http://wiki.tcl.tk/26403 : [HTML character entity references] # Spades Hearts Diamonds Clubs foreach {suit sym} { S \u2660 H \u2665 D \u2666 C \u2663 } { foreach rank { A 2 3 4 5 6 7 8 9 10 J Q K } { ;# Ace 2 .. 10 Jack Queen King incr i set card "$rank$sym" #puts -nonewline " $rank$suit=$card " lappend deck $card ;# add card to list } #puts "" } set maxCard $i puts "done.\nPack of $maxCard cards added to the deck." #puts "\ndeck : $deck" ;## puts "done.\nPack of cards with $maxCard cards added to deck." proc c1 {s} { set c [string range $s 0 0] } ;# return first char of string puts "$tx $p1-$p2: [lrange $L $p1 $p2]" } proc showFirst {tx L n} { ;# show the first n elements in list L puts "$tx 0-$n: [lrange $L 0 $n] ..." } proc showLast {tx L n} { ;# show the last n elements in list L set p2 [llength $L] set p1 $p2; incr p1 -$n puts "$tx $p1-$p2: ... [lrange $L $p1 $p2]" } proc deal_p {} { # deal card from deck to player's hand: global deck discard playerHand dealerHand set card [lindex $deck 0] ;# get first card from deck lappend playerHand $card ;# put it in his hand ;# delete it from the deck: set deck [lreplace $deck[set deck {}] 0 0 ] # see also: [lreplace] - "Modifying a List In-Place" ##puts "deck : $deck" ##showList "Deck" $deck 0 18 } proc moveCard {p} { # move card from position p at front of deck to end of deck: global deck discard playerHand dealerHand set card [lindex $deck 0] ;# get first card from deck lappend dealerHand $card ;# put it in his hand ;# delete it from the deck: set deck [lreplace $deck[set deck {}] 0 0 ] } proc deal {to} { # deal card from deck to player- or dealer's hand: #global deck discard playerHand dealerHand set card [lindex $::deck 0] ;# get first card from deck lappend $to $card ;# put it in his hand ;# delete it from the deck: set ::deck [lreplace $::deck[set ::deck {}] 0 0 ] # see also: [lreplace] - "Modifying a List In-Place" ##puts "deck : $::deck" ##showList "Deck" $::deck 0 18 } set deck {} ;# create empty list set discard {} set playerHand {} set dealerHand {} set cWin 0 set cLoss 0 set dealerCash 1000 set playerCash 100 puts "Start with 'n' to get a fresh pack of cards." set cmd "." ;# try: n 1 + - + - + - - w * q while { $cmd ne "q" } { set cmd "." set cmd [gets stdin] puts $cmd if {$cmd=="h"} { help } if {$cmd=="q"} { puts "Bye!"; exit } if {$cmd=="n"} { makeCards } if {$cmd=="0"} { moveCard 0 } if {$cmd=="1"} { moveCard 1 } #if {$cmd=="d"} { deal $dealerHand } #if {$cmd=="p"} { deal $playerHand } if {$cmd=="w"} { win 1 } } #. ---- **Output**
Whitejack:
Start with 'n' to get a fresh pack of cards.
MiHa 2015-06-26: The most basic functionality is done,
This is not-yet the Alpha-version, there will be bugs, so use with caution
... with regard to changing values outside the proc.