home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
OS/2 Shareware BBS: 10 Tools
/
10-Tools.zip
/
OL.LZH
/
PROGS.LZH
/
BJ.ICN
< prev
next >
Wrap
Text File
|
1991-09-05
|
11KB
|
342 lines
############################################################################
#
# Names: bj.icn
#
# Title: blackjack game
#
# Author: Chris Tenaglia (modified by Richard L. Goerwitz)
#
# Version: 1.7
#
# Date: June 1, 1991
#
############################################################################
#
# Simple but fun blackjack game. The original version was for an ANSI
# screen. This version has been modified to work with the UNIX termcap
# database file.
#
############################################################################
#
# Links: itlib
#
# Requires: UNIX
#
############################################################################
link itlib
global deck, message, lookup,
user_money, host_money,
user_hand, host_hand
procedure main(param)
user_money := integer(param[1]) | 3 ; host_money := user_money
write(screen("cls"))
# Most terminals don't do oversize characters like this.
# write(screen("cls")," ",screen("top"),screen("hinv"),
# "BLACK JACK",screen("norm"))
# write(" ",screen("bot"),screen("hinv"),
# "BLACK JACK",screen("norm"))
write(screen("high")," ---- BLACK JACK ----",screen("norm"))
bonus := 0
repeat
{
if not any('y',(map(input(at(1,3) || " " || screen("under") ||
"Play a game? y/n :"|| screen("norm") || " " ||
screen("eeol")))[1])) then break
every writes(at(1,3|4),screen("eeos"))
display_score()
deck := shuffle()
message := ""
user_hand := [] ; host_hand := []
put(user_hand,pop(deck)) ; put(host_hand,pop(deck))
put(user_hand,pop(deck)) ; put(host_hand,pop(deck))
user_points := first(host_hand[1])
if user_points > 21 then
{
writes(at(1,13),user_points," points. You went over. You lose.")
user_money -:= 1 ; host_money +:= 1 + bonus ; bonus := 0
display_score()
next
}
display_host(2)
host_points := second(user_points)
if host_points > 21 then
{
writes(at(48,22), right(host_points || " points. " ||
(&host ? tab(find(" ")|0)) || " went over.", 28))
writes(at(1,13),screen("hiblink"),"You win.",screen("norm"))
host_money -:= 1 ; user_money +:= 1 + bonus ; bonus := 0
display_score()
next
}
if host_points = user_points then
{
writes(at(1,22),screen("hiblink"),"It's a draw at ",user_points,
". The ANTY goes to bonus.",screen("norm"))
bonus +:= 2 ; host_money -:= 1 ; user_money -:= 1
display_score()
next
}
writes(at(1,12),user_points," points for user.")
writes(at(1,14),host_points," points for ",&host ? tab(find(" ")|0))
if user_points < host_points then
{
write(at(1,22),screen("hiblink"),&host ? tab(find(" ")|0)," wins.",
screen("norm"),screen("eeol"))
user_money -:= 1 ; host_money +:= 1 + bonus ; bonus := 0
display_score()
next
} else {
writes(at(1,12),screen("hiblink"),"You win.",screen("norm"),
screen("eeol"))
user_money +:= 1 + bonus ; host_money -:= 1 ; bonus := 0
display_score()
next
}
}
write(screen("clear"))
end
#
# THIS PROCEDURE ALLOWS THE USER TO PLAY AND TAKE HITS
#
procedure first(host_card)
display_user()
display_host(1)
points := value(user_hand) # just in case
writes(at(1,9),"(",points,") ")
repeat
if any('hy',map(input(at(1,23) || "Hit ? y/n : " || screen("eeol")))) then
{
put(user_hand,pop(deck))
display_user()
if (points := value(user_hand)) > 21 then return points
writes(at(1,9),"(",points,") ")
} else break
(points > 0) | (points := value(user_hand))
writes(at(1,9),"(",points,") ")
write(at(55,11),right("You stay with "||points,20))
return points
end
#
# THIS SECOND PROCEDURE IS THE HOST PLAYING AGAINST THE USER
#
procedure second(ceiling)
static limits
initial limits := [14,14,15,15,19,16,17,18]
stop_at := ?limits ; points := 0
until (points := value(host_hand)) > stop_at do
{
if points > ceiling then return points
writes(at(1,19),"(",points,") ")
# write(at(1,22),screen("eeol"),&host," will take a hit.",screen("eeol"))
write(at(1,22),screen("eeol"),&host ? tab(find(" ")|0),
" will take a hit.",screen("eeol"))
put(host_hand,pop(deck))
display_host(2)
}
(points > 0) | (points := value(host_hand))
writes(at(1,19),"(",points,") ")
return points
end
#
# THIS ROUTINE DISPLAYS THE CURRENT SCORE
#
procedure display_score()
writes(screen("nocursor"))
writes(screen("dim"),at(1,7),"Credits",screen("norm"))
writes(screen("high"),at(1,8),right(user_money,7),screen("norm"))
writes(screen("dim"),at(1,17),"Credits",screen("norm"))
writes(screen("high"),at(1,18),right(host_money,7),screen("norm"))
end
#
# THIS PROCEDURE EVALUATES THE POINTS OF A HAND. IT TRIES TO MAKE THEM
# AS HIGH AS POSSIBLE WITHOUT GOING OVER 21.
#
procedure value(sample)
hand := copy(sample)
possible := []
repeat
{
sum := 0
every card := !hand do sum +:= lookup[card[1]]
put(possible,sum)
if not ("A" == (!hand)[1]) then break else
every i := 1 to *hand do {
if hand[i][1] == "A" then {
hand[i][1] := "a"
break
}
}
}
best_score := 0
gone_over_score := 100
every score := !possible do {
if score > 21
then gone_over_score >:= score
else best_score <:= score
}
return (0 ~= best_score) | gone_over_score
end
#
# THIS ROUTINE DISPLAYS THE USER HAND AND STATUS
#
procedure display_user()
writes(screen("nocursor"),at(1,6),screen("hinv"),"USER",screen("norm"))
x := 10 ; y := 4
every card := !user_hand do
{
display(card,x,y)
x +:= 7
}
end
#
# THIS ROUTINE DISPLAYS THE HOST HAND AND STATUS
#
procedure display_host(flag)
writes(screen("nocursor"),at(1,16),screen("hinv"),
&host ? tab(find(" ")|0),screen("norm"))
x := 10 ; y := 14 ; /flag := 0
every card := !host_hand do
{
if (flag=1) & (x=10) then card := "XX"
display(card,x,y)
x +:= 7
}
end
#
# THIS ROUTINE DISPLAYS A GIVEN CARD AT A GIVEN X,Y SCREEN LOCATION
#
procedure display(card,x,y)
all := [] ; j := y
if find(card[2],"CS") then card := screen("hinv") || card || screen("norm")
# shape := [at(x,(j+:=1)) || screen("gchar") || "lqqqqqqqk"]
shape := [at(x,(j+:=1)) || screen("inv") || " " || screen("norm")]
put(shape,at(x,(j+:=1)) || screen("inv") || " " || screen("norm") ||
" " || card || " " || screen("inv") || " " || screen("norm"))
put(shape,at(x,(j+:=1)) || screen("inv") || " " || screen("norm") ||
" " || screen("inv") || " " || screen("norm"))
put(shape,at(x,(j+:=1)) || screen("inv") || " " || screen("norm") ||
" " || screen("inv") || " " || screen("norm"))
put(shape,at(x,(j+:=1)) || screen("inv") || " " || screen("norm") ||
" " || screen("inv") || " " || screen("norm"))
# put(shape,at(x,(j+:=1)) || "x x")
# put(shape,at(x,(j+:=1)) || "x x")
put(shape,at(x,(j+:=1)) || screen("inv") || " " || screen("norm") ||
" " || card || " " || screen("inv") || " " || screen("norm"))
# put(shape,at(x,(j+:=1)) || "mqqqqqqqj" || screen("nchar"))
put(shape,at(x,(j+:=1)) || screen("inv") || " " || screen("norm"))
put(all,shape)
x +:= 14
while shape := pop(all) do every writes(!shape)
end
#
# THIS ROUTINE SHUFFLES THE CARD DECK
#
procedure shuffle()
static faces, suits
local cards, i
initial {
&random := map(&clock,":","7") # initial on multiple shuffles
faces := ["2","3","4","5","6","7","8","9","T","J","Q","K","A"]
suits := ["D","H","C","S"]
lookup := table(0)
every i := 2 to 9 do insert(lookup,string(i),i)
insert(lookup,"T",10)
insert(lookup,"J",10)
insert(lookup,"Q",10)
insert(lookup,"K",10)
insert(lookup,"A",11)
insert(lookup,"a",1)
}
cards := []
every put(cards,!faces || !suits)
every i := *cards to 2 by -1 do cards[?i] :=: cards[i]
return cards
end
#
# THIS ROUTINE PARSES A STRING WITH RESPECT TO SOME DELIMITER
#
procedure parse(line,delims)
static chars
chars := &cset -- delims
tokens := []
line ? while tab(upto(chars)) do put(tokens,tab(many(chars)))
return tokens
end
#
# THIS ROUTINE PROMPTS FOR INPUT AND RETURNS A STRING
#
procedure input(prompt)
writes(screen("cursor"),prompt)
return read()
end
#
# THIS ROUTINE SETS THE VIDEO OUTPUT ATTRIBUTES FOR VT102 OR LATER
# COMPATIBLE TERMINALS.
#
procedure screen(attr)
initial if getval("ug"|"mg"|"sg") > 0 then
er("screen","oops, magic cookie terminal!",34)
return {
case attr of
{
"cls" : getval("cl")
"clear": getval("cl")
# HIGH INTENSITY & INVERSE
"hinv" : (getval("md") | "") || getval("so")
"norm" : (getval("se") | "") || (getval("me") | "") || (getval("ue")|"")
# LOW INTENSITY VIDEO
"dim" : getval("mh"|"me"|"se")
"blink": getval("mb"|"md"|"so")
# HIGH INTENSITY BLINKING
"hiblink": (getval("md") | "") || getval("mb") | getval("so")
"under": getval("us"|"md"|"so")
"high" : getval("md"|"so"|"ul")
"inv" : getval("so"|"md"|"ul")
# ERASE TO END OF LINE
"eeol" : getval("ce")
# ERASE TO START OF LINE
"esol" : getval("cb")
# ERASE TO END OF SCREEN
"eeos" : getval("cd")
# MAKE CURSOR INVISIBLE
"cursor": getval("vi"|"CO") | ""
# MAKE CURSOR VISIBLE
"nocursor": getval("ve"|"CF") | ""
# # START ALTERNATE FONT <- very non-portable
# "gchar": getval("as") | ""
# # END ALTERNATE FONT
# "nchar": getval("ae") | ""
# "light": return "\e[?5h" # LIGHT COLORED SCREEN
# "dark" : return "\e[?5l" # DARK COLORED SCREEN
# "80" : return "\e[?3l" # 80 COLUMNS ON SCREEN
# "132" : return "\e[?3h" # 132 COLUMNS ON SCREEN
# "smooth": return "\e[?4h" # SMOOTH SCREEN SCROLLING
# "jump" : return "\e[?4l" # JUMP SCREEN SCROLLING
default : er("screen",attr||" is just too weird for most terminals",34)
} | er("screen","I just can't cope with your terminal.",35)
}
end
#
# THIS ROUTINE SETS THE CURSOR TO A GIVEN X (COL) Y(ROW) SCREEN LOCATION
#
procedure at(x,y)
# return "\e[" || y || ";" || x || "f"
return igoto(getval("cm"),x,y)
end