Page 2 of 2 FirstFirst 12
Results 11 to 15 of 15

Thread: Glitch on my game

  1. #11
    PGD Community Manager AthenaOfDelphi's Avatar
    Join Date
    Dec 2004
    Location
    South Wales, UK
    Posts
    1,245
    Blog Entries
    2
    Hi smexhy,

    My first question... are you sure Key is equal to 'F'? (i.e. upper case F). Unless you've got caps lock on or are holding down the shift, key will be equal to 'f' (i.e. lower case F) when you press the F key.

    I'm not sure there is anything else wrong with your code, but without the full context it's a bit difficult to tell.


    Hope this helps
    :: AthenaOfDelphi :: My Blog :: My Software ::

  2. #12
    Uhh... i always do key := upcase(key) so that is not a problem. ill post in some minutes the full code and ill show you what im talking
    PS: is there any other way to backup a program other than saving to another folder?
    Last edited by smexhy; 08-04-2012 at 01:54 PM.

  3. #13
    Well, you used this sort of structure a few times:
    Code:
    repeat
      ...
      readln(key);
      key := upcase(key);
    until (key = 'Y') or (key = 'N');
    if (key = 'N') then begin
      ...
    end;
    if (key = 'Y') then begin
      ...
    end;
    Whereas it should be written:
    Code:
    if (key = 'N') then begin
      ...
    end
    else if (key = 'Y') then begin
      ...
    end;
    Because then it will only check the first IF and ignore the other condition entirely (if 'N' was entered). In the first code it checks both codes which is extra work for CPU, and a possible cause for logic errors in program.

    PS. Tested the WYSIWYG style but had to take it off because i don't know how to use it. If you start writing with code tags, how do you put cursor behind it and continue in normal font?

  4. #14
    Quote Originally Posted by User137 View Post
    Well, you used this sort of structure a few times:
    Code:
    repeat
      ...
      readln(key);
      key := upcase(key);
    until (key = 'Y') or (key = 'N');
    if (key = 'N') then begin
      ...
    end;
    if (key = 'Y') then begin
      ...
    end;
    Whereas it should be written:
    Code:
    if (key = 'N') then begin
      ...
    end
    else if (key = 'Y') then begin
      ...
    end;
    Because then it will only check the first IF and ignore the other condition entirely (if 'N' was entered). In the first code it checks both codes which is extra work for CPU, and a possible cause for logic errors in program.
    Thanks for the tip! I didnt knew about this . Well nevermind... i fixed the whole thing by myself again D: Thank you everyone!

  5. #15
    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
    Attached Files Attached Files
    Last edited by deathshadow; 13-06-2012 at 03:31 PM.
    The accessibility of a website from time to time must be refreshed with the blood of designers and owners. It is its natural manure

Page 2 of 2 FirstFirst 12

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •