home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
C!T ROM 2
/
ctrom_ii_b.zip
/
ctrom_ii_b
/
PROGRAM
/
PASCAL
/
30TURUTL
/
CRIBBAGE.PAS
< prev
next >
Wrap
Pascal/Delphi Source File
|
1985-02-16
|
19KB
|
732 lines
PROGRAM Cribbage;
(* TURBO PASCAL 1.0
Morrow Micro Decision MD-2
David C. Oshel, Jan 15, 1984, 1219 Harding Ave, Ames, Iowa 50010
*)
{ TITLE PAGE:
(':::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::');
(':: Adapted from "Cribbage" in APPLE PASCAL GAMES, by Douglas Hergert ::');
(':: and Joseph T. Kalash, pages 301-349. Sybex, 1981. ::');
(':: ::');
(':: January 8, 1984 d.c.o. ::');
(':::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::');
}
Label 1;
Const
decksize = 52;
dealsize = 6;
scribsize = 6;
playsize = 4;
ranksize = 13;
winpoints = 121;
Type
charset = set of char;
str80 = string[80];
suitype = (hearts,diamonds,clubs,spades);
ranktype = 0..ranksize;
card = record
rank: ranktype;
suit: suitype
end;
handtype = array[1..dealsize] of card;
{Typed} Const
alpha:charset = [' '..'}'];
Var
deck: array[1..decksize] of card;
comp,
human,
crib: handtype;
common: card;
i,
hscore,
cscore: integer;
ch: char;
xplayx: integer;
(*
This is the code for simulating an Exit with TURBO Pascal 1.0
--> Include this instead of Exit(Procname) in the procedure which
actually invokes the exit:
inline($2A/save/ { LD HL,(save) ; EXIT PROC }
$F9); { LD SP,HL }
goto procend;
--> Include this as the FIRST instruction in the Procedure you wish
to eventually exit from:
inline($21/0/0/ { LD HL,0000h ; MARK PROC }
$39/ { ADD HL,SP }
$22/save); { LD (save),HL }
David C. Oshel, 15 January 1984, Ames, Iowa
*)
function getchar:char;
var ch,cr,bs: char;
goodset: charset;
bailout: boolean;
begin
cr:=chr(13); bs:=chr(8); goodset:=alpha+[cr,bs];
repeat
read(kbd,ch);
ch:=upcase(ch);
bailout:=(ch=chr(3)) or (ch=chr(27));
if eoln then ch:=cr
until bailout or (ch in goodset);
getchar:=ch;
if bailout then
inline($2A/xplayx/ { LD HL,(xplayx) ;EXIT PROC }
$F9) { LD SP,HL }
end; {getchar}
procedure getln(VAR s:str80);
var ch: char;
done: boolean;
begin
done:=false;
s:='';
repeat
ch:=getchar;
if (* bailout or *) (ch=chr(13)) then
begin
done:=true;
writeln
end
else if ch=chr(8) then
begin
if length(s) > 0 then
begin
write(chr(8),' ',chr(8));
s:=copy(s,1,length(s)-1)
end
else s:=''
end
else
begin
s:=concat(s,ch);
if ch in alpha then write(ch)
end
until done;
end; {getln}
procedure addpoints(who:boolean; amount:integer);
var winner: boolean;
begin
if who then
begin
hscore:=hscore+amount;
writeln('You''ve pegged ',hscore,' points.');
winner := (hscore >= winpoints)
end
else
begin
cscore:=cscore+amount;
writeln('I''ve pegged ',cscore,' points.');
winner := (cscore >= winpoints)
end;
if winner then
inline($2A/xplayx/ { LD HL,(xplayx) ;EXIT PROC }
$F9) { LD SP,HL }
end; {addpoints}
{$I Cribbage.PS2}
function getelement:integer;
label retry;
var irank,isuit: char;
rank: ranktype;
suit: suitype;
which: integer;
index: 1..dealsize;
many: -5..4;
procedure getcard(VAR rankchar:char; VAR suitchar:char);
var ch: char;
s: str80;
i: integer;
begin
repeat
write('__',chr(8),chr(8));
getln(s);
rankchar:=' '; suitchar:=' ';
for i:=1 to length(s) do
begin
ch:=s[i];
if (ch in ['A','2'..'9','T','J','Q','K']) then rankchar:=ch;
if (ch in ['S','H','D','C']) then suitchar:=ch
end;
if (rankchar=' ') or (suitchar=' ') then
begin
writeln(s,'?');
writeln('Suits = S,H,D,C (Spades,Hearts,Diamonds,Clubs)');
writeln('Ranks = A,2,3,4,5,6,7,8,9,T,J,Q,K (Ace is A, 10 is T!)');
writeln('Example: 8D (eight of Diamonds) or TH (ten of Hearts)');
writeln;
write('Try again from the start. Which card? ')
end
until (rankchar<>' ') and (suitchar<>' ');
writeln('{{{ ',rankchar,suitchar,' }}}');
end; {getcard}
begin
retry:
getcard(irank,isuit);
case irank of
'A': rank:=1;
'2','3','4','5','6','7','8','9': rank:=ord(irank)-ord('0');
'T': rank:=10;
'J': rank:=11;
'Q': rank:=12;
'K': rank:=13
end; {case}
case isuit of
'S': suit := spades;
'H': suit := hearts;
'D': suit := diamonds;
'C': suit := clubs
end; {case}
many:=0;
which:=0;
for index:=1 to dealsize do
begin
if human[index].rank = rank then
begin
many:=many+1;
if many>0 then which:=index;
if isuit<>' ' then
if human[index].suit = suit then
many:=-5
end
end;
if many=0 then
begin
writeln('What?! No such card exists.');
write('Which card? ');
goto retry
end;
if many>1 then
begin
writeln('There is more than one ',irank);
write('Please be more specific: ');
goto retry
end;
if (many=1) or (many<0) then getelement:=which;
end; {getelement}
procedure tocrib;
var cardnum: 1..dealsize;
numgone: 0..1;
begin
for numgone:=0 to 1 do
begin
write('Throw which card? [ ');
for cardnum:=1 to (dealsize-numgone) do showcard(human[cardnum]);
write(' ] ');
cardnum:=getelement;
crib[numgone+1]:=human[cardnum];
while cardnum <= (dealsize-1) do
begin
human[cardnum]:=human[cardnum+1];
cardnum:=cardnum+1
end;
human[cardnum].rank:=0
end;
end; {tocrib}
procedure sort(n:integer; var hand:handtype);
var
touched: boolean;
index: 1..dealsize;
tmp: card;
begin
repeat
touched:=false;
for index:=1 to (n-1) do
if hand[index].rank > hand[index+1].rank then
begin
tmp:=hand[index];
hand[index]:=hand[index+1];
hand[index+1]:=tmp;
touched:=true
end
until not touched;
end; {sort}
{$I Cribbage.PS3}
procedure compcrib;
type
bestrec = record
points: integer;
first, second: 1..dealsize
end;
var
tmp: handtype;
best: bestrec;
i,j,points: integer;
function compscore:integer;
var
index,points: integer;
num: 1..dealsize;
begin
num:=1;
for index:=1 to (i-1) do
begin
tmp[num]:=comp[index];
num:=num+1
end;
for index:=(i+1) to (j-1) do
begin
tmp[num]:=comp[index];
num:=num+1
end;
for index:=(j+1) to dealsize do
begin
tmp[num]:=comp[index];
num:=num+1
end;
tmp[5].rank:=0;
compscore:=score(tmp);
end; {function compscore}
begin {compcrib}
best.points:=-1;
sort(6,comp);
for i:=1 to (dealsize-1) do
for j:=i+1 to dealsize do
begin
points:=compscore;
if points > best.points then
begin
best.points:=points;
best.first:=i;
best.second:=j
end
end;
j:=1;
for i:=1 to (best.first-1) do
begin
tmp[j]:=comp[i];
j:=j+1
end;
for i:=(best.first+1) to (best.second-1) do
begin
tmp[j]:=comp[i];
j:=j+1
end;
for i:=(best.second+1) to dealsize do
begin
tmp[j]:=comp[i];
j:=j+1
end;
crib[3]:=comp[best.first];
crib[4]:=comp[best.second];
for i:=1 to playsize do comp[i]:=tmp[i];
end; {compcrib}
procedure count(who: boolean);
var
oldhuman: array[1..4] of card;
curcount: integer;
humcant,
compcant: boolean;
cnthand: array[1..8] of card;
last: 0..2;
cntnum: 1..8;
lastcnt: integer;
humleft,
comleft: 0..playsize;
i: -1..playsize;
points: integer;
function countscore(newcard: card):integer;
var
return: integer;
matched, index: 0..8;
begin
return:=0; matched:=0;
cnthand[cntnum]:=newcard;
if cnthand[cntnum].rank > 10
then curcount:=curcount+10
else curcount:=curcount+cnthand[cntnum].rank;
if cntnum=1 then
begin
cntnum:=cntnum+1;
countscore:=0
end
else
begin
if (curcount=15) or (curcount=31) then return:=2;
index:=cntnum;
while index >= 2 do
begin
if cnthand[index].rank=cnthand[index-1].rank then
matched:=matched+1
else index:=1;
index:=index-1
end;
case matched of
0: ;
1: return:=return+2;
2: return:=return+6;
3: return:=return+12
end; {case}
matched:=0;
index:=cntnum;
while index >= 2 do
begin
if cnthand[index].rank=(cnthand[index-1].rank -1) then
matched:=matched+1
else index:=1;
index:=index-1
end;
cntnum:=cntnum+1;
if matched > 2 then return:=return+matched+1;
countscore:=return
end;
end; {countscore}
function humplay:integer;
var i,j: integer;
begin
if human[1].rank > 10 then i:=10
else i:=human[1].rank;
if (humleft <= 0) or ((i+curcount) > 31) then
begin
humcant:=true;
humplay:=-1
end
else
begin
last:=1;
humcant:=false;
if human[2].rank > 10 then i:=10
else i:=human[2].rank;
if (humleft=1) or ((i+curcount) > 31) then
humplay:=1
else
begin
j:=0;
while j=0 do
begin
write('Play which card? [ ');
for i:=1 to playsize do
if human[i].rank <> 0 then showcard(human[i]);
write(' ] ');
i:=getelement;
if human[i].rank > 10 then j:=10
else j:=human[i].rank;
if (j+curcount) > 31 then
begin
writeln('Sorry, that''s more than 31');
j:=0
end
end;
humplay:=i
end
end
end; {humplay}
function complay:integer;
var
index: 1..playsize;
points, best: integer;
tmp: 0..10;
return: 1..playsize;
begin
best:=-1;
if comp[1].rank > 10 then tmp:=10
else tmp:=comp[1].rank;
if (comleft=0) or ((tmp+curcount) > 31) then
begin
compcant:=true;
complay:=-1
end
else
begin
compcant:=false;
last:=2;
for index:=1 to comleft do
begin
if comp[index].rank>10 then tmp:=10
else tmp:=comp[index].rank;
if (tmp<>0) and ((tmp+curcount) <= 31) then
begin
points:=countscore(comp[index]);
cntnum:=cntnum-1;
curcount:=curcount-tmp;
if points>best then
begin
best:=points;
return:=index
end
end
end;
complay:=return
end;
end; {complay}
begin {count -- at last!}
humleft:=playsize;
comleft:=playsize;
humcant:=false;
compcant:=false;
last:=0;
cntnum:=1;
if common.rank=11 then
begin
if who then
begin
writeln('I get a point for His Nibs!');
addpoints(false,1);
end
else
begin
writeln('YOU get a point for His Nibs!!');
addpoints(true,1);
end
end;
for curcount:=1 to playsize do
oldhuman[curcount]:=human[curcount];
curcount:=0;
while (humleft > 0) or (comleft > 0) do
begin
if who then
begin
who:=false;
i:=humplay;
if i>0 then
begin
write('You played a ');
showcard(human[i]);
writeln('.');
points:=countscore(human[i]);
if points>0 then
begin
writeln('You got ',points,' points');
addpoints(true,points);
end;
while i<=(playsize-1) do
begin
human[i]:=human[i+1];
i:=i+1
end;
human[humleft].rank:=0;
humleft:=humleft-1
end
end;
if not who then
begin
who:=true;
i:=complay;
if i>0 then
begin
write('I play a ');
showcard(comp[i]);
writeln('.');
points:=countscore(comp[i]);
if points>0 then
begin
writeln('I got ',points,' points.');
addpoints(false,points);
end;
while i <= (playsize-1) do
begin
comp[i]:=comp[i+1];
i:=i+1
end;
comp[comleft].rank:=0;
comleft:=comleft-1
end
end;
if lastcnt<>curcount then writeln('Total is ',curcount,'.');
lastcnt:=curcount;
if (humcant and compcant) or ((humleft=0) and (comleft=0)) then
begin
case last of
0: ;
1: begin
writeln('You got a point for last card.');
addpoints(true,1);
who:=false
end;
2: begin
writeln('I got a point for last card.');
addpoints(false,1);
who:=true
end
end; {case}
writeln;
writeln('Total is now 0.');
writeln;
humcant:=false;
compcant:=false;
last:=0;
cntnum:=1;
curcount:=0
end;
end;
for curcount:=1 to playsize do
human[curcount]:=oldhuman[curcount];
end; {count}
procedure play(who: boolean);
var
cpoints,
hpoints,
crbpnts: integer;
user:str80;
usernum,code: integer;
procedure check(num: integer; question: str80);
begin
repeat
write(question);
getln(user);
val(user,usernum,code);
if code<>0
then writeln(user,'??')
else writeln;
until code=0;
if usernum<>num then
begin
writeln('Unless there''s a bug in my program, you should have taken ',num,' points!');
writeln('I get ',abs(num-usernum),', regardless!');
addpoints(false,abs(num-usernum));
if usernum>num then usernum:=num
end;
if (usernum > 0) then addpoints(true,usernum);
writeln;
end; {check}
begin {play}
inline($21/0/0/ { LD HL,0000h ; MARK PROC }
$39/ { ADD HL,SP ; FOR EXIT }
$22/xplayx); { LD (xplayx),HL }
repeat { forever -- we get out by simulating an Exit(Play) }
shuffle;
deal;
if who then writeln('It''s my crib.')
else writeln('It''s your crib.');
sort(6,human);
tocrib;
compcrib;
sort(4,crib);
if who then
begin
repeat
write('Cut which card [1-40] ? ');
getln(user);
val(user,usernum,code);
if code<>0
then writeln(user,'??')
else writeln
until (code=0) and (usernum in [1..40]);
common:=deck[usernum+12]
end
else
begin
common:=deck[13+random(40)]
end;
write('The UPCARD is ');
showcard(common);
writeln;
cpoints:=score(comp);
hpoints:=score(human);
crbpnts:=score(crib);
writeln;
count(who);
writeln;
if who then
begin
write('[ ');
for usernum:=1 to playsize do showcard(human[usernum]);
write(' ] [ ');
showcard(common);
writeln(' ]');
check(hpoints,'How many points you got? ');
writeln('I''ve got ',cpoints,' points in my hand');
addpoints(false,cpoints);
writeln('I have ',crbpnts,' points in my crib');
addpoints(false,crbpnts);
end
else
begin
writeln('I''ve got ',cpoints,' in my hand');
addpoints(false,cpoints);
writeln;
write('[ ');
for usernum := 1 to playsize do showcard(human[usernum]);
write(' ] [ ');
showcard(common);
writeln(' ]');
check(hpoints,'How many points in YOUR hand? ');
writeln;
write('[ ');
for usernum:=1 to playsize do showcard(crib[usernum]);
write(' ] [ ');
showcard(common);
writeln(' ]');
check(crbpnts,'How much in the crib? ');
end;
who:=not who
until false
end; {play}
BEGIN {MAIN}
1:
clrscr;
writeln(':::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::');
writeln(':: W E L C O M E TO K I D D I E K R I B B A G E ! ::');
writeln(':: ::');
writeln(':: Adapted from "Cribbage" in APPLE PASCAL GAMES, by Douglas Hergert ::');
writeln(':: and Joseph T. Kalash, pages 301-349. Sybex, 1981. ::');
writeln(':: ::');
writeln(':: TURBO Pascal 1.0, Copyright 1983 by Borland Intl. 1/17/84 DCO ::');
writeln(':::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::');
writeln;
writeln('It''s you against me, kid! Whoever pegs 121 points first wins!');
writeln;
randomize;
makedeck;
hscore:=0;
cscore:=0;
play(random(2)=0);
writeln;
if cscore>hscore
then writeln('Ho Ho!! I peg out and win this game!')
else writeln('You pegged out and won the game! Congratulations!');
writeln; writeln; writeln;
write('Do you want another game? ');
read(kbd,ch); writeln(ch);
if ch in ['n','N']
then writeln('OK, see you later!')
else goto 1
END.