Page 1 of 2 12 LastLast
Results 1 to 10 of 15

Thread: Glitch on my game

Hybrid View

Previous Post Previous Post   Next Post Next Post
  1. #1

    Glitch on my game

    Hello, i'm a beginner in the pascal language, knowing only the basics. I don't know any other language. I made this text based game some days ago and i was working on my code until i got a error to it... You can get the code here: http://pastebin.com/A5eQa7Hv . The problem is that the 'Continue or Menu?" phrase appears where it isnt supposed to be... i tried to check all the begin's and end's if they are at they'r place and i couldn't find any error... I just don't know why "Continue or Menu?" appears randomly and why it won't accept the input (small c or small m) due my key2 := upcase(key2) . If anyone doesnt mind compiling it and checking the error i'll be very thankful . Thank You!

    Ps: Don't mind the game for now, it's not finished, i'll fix the other "unfinished" parts of it but for now i need to get this fixed.

  2. #2
    Fixed the indents, it was really difficult to read. Don't know yet what the problem place is.
    Code:
    program project1;
     
    uses crt;
     
    var
      inc, rnd1 ,rnd2,jbc,sec, pris ,stats, bank, turn : integer;
      key,key1,key2,key3:char;
     
    procedure etc;
    begin
      writeln('Daily income: ',inc,' cash.');
      writeln('Bank: ',bank);
      writeln('--------------------------------------');
    end;
     
    procedure etc1;
    begin
      writeln('Starting day number ',turn,'.');
      writeln('Bank: ',bank);
      writeln('Prisoners: ',pris);
      writeln('Daily income: ',inc);
      writeln('Security level: ',sec);
    end;
     
    begin
      repeat
        sec := 0;
        jbc := 7;
        turn := 0;
        bank := 0;
        stats := 0;
        pris := 2;
        inc := 150;
        writeln('Hello and welcome to the JailBreak game made by Sami.');
        readln;
        writeln('Instructions: ');
        writeln('-Feed your prisoners day by day (if possible).');
        writeln('-If the unsatisfied prisoners count gets over 3 your');
        writeln('daily income will start to decrease.');
        writeln('-You can buy a new prisoner from Menu(M) or increase');
        writeln('the security system, thus decreasing canche of jailbreak');
        writeln('If you get -300 cash you will lose the game.');
        writeln('The goal of the game is to have 5 prisoners in less days.');
        readln;
        writeln('Ready to play?[press <ENTER> to start the first day.]');
        readln;
        {-Starting the routine-}
        begin
          repeat
            randomize;
            rnd1 := random(3);
            rnd2 := random(jbc);
    
            if (rnd1 = 1) then begin
              clrscr;
              turn := turn + 1;
              etc1;
              repeat
                write(pris,' prisoners are hungry. Feed them? (Y/N): ');
                readln(key);
                key := upcase(key);
              until (key = 'Y') or (key = 'N');
    
              if (key = 'N') then begin
                stats := stats - 2;
                writeln('--------------------------------------');
                writeln('The prisoners are not satisfied for today!');
                writeln('Unsatisfied prisoners count: ',stats);
              end;
    
              if (key = 'Y') then begin
                stats := stats + 2;
                writeln('--------------------------------------');
                writeln('Good job! the prisoners are fullfiled for today!');
                bank := bank - 150;
                writeln('-150 cash');
                writeln('Satisfied prisoners count: ',stats);
                bank := bank + inc;
                etc;
              end;
            end;
    
            if (rnd1 = 2) then begin
              turn := turn + 1;
              clrscr;
              etc1;
              repeat
                write(pris-1,' prisoner is hungry. Feed him? (Y/N): ');
                readln(key);
                key := upcase(key);
              until (key = 'Y') or (key = 'N');
    
              if (key = 'N') then begin
                stats := stats - 1;
                writeln('--------------------------------------');
                writeln('The prisoner is not satisfied for today!');
                writeln('Unsatisfied prisoners count: ',stats);
              end;
    
              if (key = 'Y') then begin
                stats := stats + 1;
                writeln('--------------------------------------');
                writeln('Good job! the prisoners are fullfiled for today!');
                bank := bank - 100;
                writeln('-100 cash');
                writeln('Satisfied prisoners count: ',stats);
                bank := bank + inc;
                etc;
              end;
            end;
    
            if (rnd1 = 3) then begin
              turn := turn + 1;
              clrscr;
              etc1;
              writeln('--------------------------------------');
              write('No prisoner is hungry today, you are lucky!');
              bank := bank + inc;
              etc;
            end;
            {-Ending the routine-}
    
            {--------------------}
    
            {-Deciding either -inc or staying the same-}
            if (stats < -3) then begin
              writeln('The prisoners are very unsatisfied , income - 25');
              inc := inc - 25;
            end;
    
            if (stats > -3) then begin
              inc := 150;
            end;
            {ending -inc routine}
    
            {-----------------------}
    
            {starting final question before next day}
            begin
              repeat
                key2 := ' ';
                key3 := ' ';
                writeln('Continue(C) or Menu(M)? : ');
                readln(key2);
                key2 := upcase(key2);
              until (key2 = 'C') or (key2 = 'M');
    
              {choice to continue or menu}
    
              if (key2 = 'M') then begin
                repeat
                  writeln('You entered the Menu, what you wish to do?');
                  writeln('--------------------------');
                  writeln('(B)uy new prisoner (-300 cash);');
                  writeln('(I)ncrease security (- 200 cash);');
                  writeln('(C)ontinue ( = cash);');
                  readln(key3);
                  key3 := upcase(key3);
                until (key3 = 'B') or (key3 = 'I') or (key3 = 'C');
              end;
            end;
            {ending menu choice}
    
            {starting custom choice}
            if (key3 = 'B') then begin
              writeln('You have bought a new prisoner!');
              writeln('-300 cash');
              writeln('Income : + 50');
              inc := inc + 50;
              bank := bank - 300;
              readln;
            end;
    
            if (key3 = 'I') then begin
              writeln('Security system upgraded, canche of escape decreased');
              writeln('-200 cash');
              bank := bank - 200;
              jbc := jbc + 2;
              sec := sec + 1;
              readln;
            end;
            {ending custom choice}
            {end day}
    
            {chance of escape at night}
            if (rnd2 = 1) then begin
              writeln('Bad Luck!One of your prisoner escaped!');
              pris := pris - 1;
              inc := inc - 50;
              readln;
            end;
            {end canche}
    
          until (pris = 5) or (bank < -300) or (pris = 0);
    
          if pris = 0 then begin
            writeln('You have no more prisoners, sorry, you lost the game!');
          end;
          if pris = 5 then begin
            writeln('Congratulations! You won the game in ',turn,' days with 5 prisoners!');
          end;
          if bank < -300 then
            writeln('Sorry, you lost the game (< -300 cash)');
    
        end;
    
        repeat
          writeln('Play again? (Y/N): ');
          readln(key1);
          key1 := upcase(key1);
        until (key = 'Y') or (key = 'N');
      until (key = 'N');
    end.
    And.. yes, it compiles with Lazarus

    And small sidenote that you shouldn't name variable "inc". There is a function inc() in system unit that is used to add number (default 1) to integer variable.
    Last edited by User137; 07-04-2012 at 12:34 AM.

  3. #3
    Co-Founder / PGD Elder WILL's Avatar
    Join Date
    Apr 2003
    Location
    Canada
    Posts
    6,107
    Blog Entries
    25
    Yeah, I'd just like to add that it's always best practice to avoid reusing ANY keywords or common language functions or you could end up having some crazy logic issues and errors in your programs. I try to think of nice alternatives myself.

    For example lets say you have a record that stores what "type" of object they are, well what do you call that variable to hold that value? Type would be terrible and would most likely cause an error preventing it from compiling. Instead I would try using "kind" (real life example!) as it does not conflict with the keyword type used to define different variable types.

    Oh and feel free to use the code button to post your code right in your post. It should work as long as it's not too long (long as in reallllllly long) User137's post is a good example of posting code of a decent size length.
    Jason McMillen
    Pascal Game Development
    Co-Founder





  4. #4
    PGDCE Developer Carver413's Avatar
    Join Date
    Jun 2010
    Location
    Spokane,WA,Usa
    Posts
    206
    Quote Originally Posted by WILL View Post
    Oh and feel free to use the code button to post your code right in your post.
    What code button ? I alway's have to type all the bb codes in manually on this forum

  5. #5
    Co-Founder / PGD Elder WILL's Avatar
    Join Date
    Apr 2003
    Location
    Canada
    Posts
    6,107
    Blog Entries
    25
    Quote Originally Posted by Carver413 View Post
    What code button ? I alway's have to type all the bb codes in manually on this forum
    Ah then you never followed the directions for existing members who were migrated to the current vBulletin version of the site.

    Click here and see how you can turn on the WYSIWYG Editor for posting here on PGD! You are interested in what is under "Miscellaneous Options".

    Quote Originally Posted by smexhy View Post
    Thanks User137 and Will for your time , and i knew there was the function inc() but forgot bout it D:
    Not a problem. Starting out can seem a little daunting, but if you stick with it and don't always take the easy route you'll get all the ins and outs eventually. Taking a Computer Science class in your school will help greatly! It should cover most of the basic concepts of programming and should allow you to write code for just about any solution that can be thought up, save for the really advanced stuff.
    Jason McMillen
    Pascal Game Development
    Co-Founder





  6. #6
    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.

  7. #7
    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?

  8. #8
    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!

  9. #9
    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

  10. #10
    Thanks User137 and Will for your time , and i knew there was the function inc() but forgot bout it D:

Page 1 of 2 12 LastLast

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
  •