Ok, got a slew of advice for you here...
With your user input checks, it is correct to use else, however on a few of those take a moment to think...
Code:
until (key = 'Y') or (key = 'N');
if (key = 'N') then begin
...
end;
if (key = 'Y') then begin
...
end;
If the until will only ever pass Y or N, and you already checked for N... you don't have to check for Y. When possible, avoid checking unneccessary values!
Code:
until (key = 'Y') or (key = 'N');
if (key = 'N') then begin
...
end else begin
{ isn't N, must be Y! }
...
end;
Also, when checking multiple values of a single variable is needed, you are better off using the CASE statement.
Code:
case key of
'N':begin
...
end;
'Y':begin
...
end;
end;
Executes faster, usually results in cleaner code.
You are storing values that are only really used once in variables... your multiple if statements for rnd1 for example could be removed and simply done as a single case statement.
Code:
case random(3) of
0:begin
{ do your feed 2, 150 }
end;
1:begin
{ do your feed 1, 100 }
end;
2:begin
{ do your no prisoner hungry }
end;
end;
Oh, and random starts at zero and does NOT include the number you declare -- since you didn'add 1 to the random(3), this:
Code:
if (rnd1 = 3) then begin
Would never run. Random(3) returns 0..2, not 1..3
As mentioned your two feed sections both basically do the same thing, just with different values, I'd put those into proceedures passing those different values.
I HIGHLY suggest not using such vague and cryptic variable names, the handful of time you save not typing as much is wasted the moment you try to debug, or ask for help... or come back to this in a year from now when you've forgotten what "jbc" even means. Since you're just starting out, I like to link beginners to an article on IBM's linux developer site:
http://www.ibm.com/developerworks/li.../l-clear-code/
While meant for C programmers, I believe people writing code in any language can come away with meaningful lessons from that... I'm particularly fond of the "Oh, now we're done?" part. It's a good read.
You use hyphen-lines as horizontal rules enough that I'd consider putting them into a constant, so you always have the same number.
Under the hood it's often faster to test for zero, so I'd make the game start at 300 in the bank, then have the lose condition be less than zero. Likewise I'd make the 'menu' not show options they can't afford.
Because you poll the keyboard so often and so many times, I'd suggest making a procedure to handle that. readln is cute, but it would be nicer to handle it as single keypresses and only pass when valid. A routine I've used for years takes a string of valid keypresses, and returns which one is hit, ignoring all others.
Code:
function keyPoll(values:string):char;
var
ch:char;
t:word;
begin
while keypressed do ch:=readkey; { flushes key buffer }
repeat
ch:=upcase(readkey);
for t:=1 to length(values) do begin
if ch=values[t] then begin
keyPoll:=ch;
exit;
end;
end;
until false;
end; { function keyPoll }
I always like to flush the keybuffer first so any extra presses made since the last input check are disposed of... it then just goes down the string comparing until it finds a match, returning that match. If we were to turn your 'feeding' code into it's own procedure using the above function, it ends up thus:
Code:
procedure feed(statAdjust,cost:integer);
begin
write(prisoners,' prisoners are hungry. Feed them? (Y)es or (N)o');
if keyPoll('YN')='Y' then begin
stats:=stats+statAdjust;
writeln(hrule);
writeln('Good job! the prisoners are fullfiled for today!');
dec(bank,cost);
writeln('-',cost,' cash');
writeln('Satisfied prisoners count: ',stats);
end else begin
dec(stats,statAdjust);
writeln(hrule);
writeln('The prisoners are not satisfied for today!');
writeln('Unsatisfied prisoners count: ',stats);
end;
end; { procedure feed }
As I mentioned above, we only need to check for yes, since the routine is only passing yes or no... if it's not yes...
The 'menu' could be similarly optimized. you could build a string 'compare' thus:
compare:='E';
then, you could
Code:
compare:='E';
if bank>=200 then begin
if bank>=300 then begin
writeln(' (B)uy new prisoner -300 cash');
compare:=compare+'B';
end;
writeln(' (I)ncrease security -200 cash');
compare:=compare+'I';
end else begin
writeln('You have insufficient funds to perform any actions!');
end;
writeln(' (E)xit Menu');
ch:=keyPoll(compare);
case ch of
'B':begin
etc, etc...
I took a few moments to do a quick rewrite for you, to show you what I mean.
Code:
program warden;
uses
crt;
var
income,
jailBreakChance,
security,
prisoners,
stats,
bank,
turn:integer;
key:char;
const
hRule=#13+'--------------------------------------';
function keyPoll(values:string):char;
var
ch:char;
t:word;
begin
while keypressed do ch:=readkey; { flushes key buffer }
repeat
ch:=upcase(readkey);
for t:=1 to length(values) do begin
if ch=values[t] then begin
keyPoll:=ch;
exit;
end;
end;
until false;
end; { function keyPoll }
procedure fullStats;
begin
writeln('Day number ',turn,'.');
writeln('Bank: ',bank);
writeln('Prisoners: ',prisoners);
writeln('Daily income: ',income);
writeln('Security level: ',security);
end; { procedure fullStats }
procedure feed(statAdjust,cost:integer);
begin
write(prisoners,' prisoners are hungry. Feed them? (Y)es or (N)o');
if keyPoll('YN')='Y' then begin
stats:=stats+statAdjust;
writeln(hrule);
writeln('Good job! the prisoners are fullfiled for today!');
dec(bank,cost);
writeln('-',cost,' cash');
writeln('Satisfied prisoners count: ',stats);
end else begin
dec(stats,statAdjust);
writeln(hrule);
writeln('The prisoners are not satisfied for today!');
writeln('Unsatisfied prisoners count: ',stats);
end;
end; { procedure feed }
procedure menu;
var
ch:char;
compare:string;
begin
repeat
clrscr;
writeln('Purchasing Menu');
writeln(hrule);
fullStats;
writeln(hrule);
compare:='E';
if bank>=200 then begin
if bank>=300 then begin
writeln(' (B)uy new prisoner -300 cash');
compare:=compare+'B';
end;
writeln(' (I)ncrease security -200 cash');
compare:=compare+'I';
end else begin
writeln('You have insufficient funds to perform any actions!');
end;
writeln(' (E)xit Menu');
ch:=keyPoll(compare);
case ch of
'B':begin
writeln('You have bought a new prisoner!');
writeln('-300 cash');
inc(bank,300);
writeln('+50 Income');
inc(income,50);
end;
'I':begin
writeln('Security system upgraded, chance of escape decreased');
writeln('-200 cash');
inc(bank,200);
dec(jailBreakChance,2);
inc(security);
end;
end;
until ch='E';
end; { procedure menu }
begin
repeat
security:=0;
jailBreakChance:=7;
turn:=0;
bank:=300;
stats:=0;
prisoners:=2;
income:=150;
randomize;
writeln('Hello and welcome to the JailBreak game made by Sami.');
writeln;
writeln('Instructions: ');
writeln(' 1) Feed your prisoners day by day (if possible).');
writeln(' 2) If the unsatisfied prisoners count gets over 3 your');
writeln(' daily income will start to decrease.');
writeln(' 3) You can buy a new prisoner from Menu(M) or increase');
writeln(' the security system, thus decreasing canche of jailbreak');
writeln(' 4) If you get -300 cash you will lose the game.');
writeln(' 5) The goal of the game is to have 5 prisoners in less days.');
writeln;
write('Ready to play? (Y)es or (N)o');
key:=keyPoll('YN');
if key='Y' then begin
repeat
inc(turn);
clrscr;
write('Starting ');
fullStats;
case random(3) of
0:feed(2,150);
1:feed(1,100);
2:begin
writeln(hrule);
write('No prisoner is hungry today, you are lucky!');
end;
end;
inc(bank,income);
if (stats<-3) then begin
writeln('The prisoners are very unsatisfied , income -25');
dec(income,25);
end else begin
income:=150;
end;
if random(jailBreakChance)=0 then begin
writeln('Bad Luck! One of your prisoner escaped!');
dec(prisoners);
inc(income,50);
end;
writeln(hrule);
repeat
write('(M)enu, (C)ontinue or (E)xit?');
key:=keyPoll('MCE');
if key='M' then menu;
until (key='C') or (key='E');
writeln;
until (prisoners>=5) or (prisoners<=0) or (bank<=0) or (key='E');
writeln(hrule);
if prisoners<=0 then begin
writeln('You have no more prisoners, sorry, you lost the game!');
end else if prisoners>=5 then begin
writeln('Congratulations! You won the game in ',turn,' days with 5 prisoners!');
end else if bank<=0 then begin
writeln('Sorry, you went bankrupt!');
end else begin
writeln('Aborting Game');
end;
writeln;
write('Play again? (Y)es or (N)o');
key:=keyPoll('YN');
end;
until key='N';
writeln;
writeln('Exiting game');
end.
I'll also attach it as a download... annoying though that this site's not set up to recognize .pas, .pp or .dpr
Bookmarks