# pascal programming question computer game

my mum saids that i need to learn programming, so i started an evening course but the teacher is not very good. i cant understand him.i am trying to work out a problem in my exercise book THIS IS NOT HOMEWORK. it involves random numbers please help me with this.
I want to write a computer game called paper, sissors. stone.
the computer picks a random  one of paper, sissors, or stone without telling the user which it has chosen. asks the user one of these by entering a suitable number. The winner is decided as follows

paper beats stone (because paper wraps stone)
Scissors beats paper (because scissors cuts paper)
Stone beats scissors (because stone blunts scissors)
The user has to enter a number that the program puts on the screen for example 1=paper,2 =scissors 3=stone

If both chose the same, it's a draw. After each round the computer declares who has won and why, and offers the user another round. if the user does not want to play again the computer displays the final score of the games played, won, lost and drawn together with a 'goodbye' message.
I WOULD VERY MUCH APPRECIATE YOUR HELP IN SOLVING THIS PROBLEM

SAMZMAN
###### Who is Participating?
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

Commented:
This oughtn't be hard :-). Pascal, eh?
I'm gonna try to use a "TOP-DOWN" programming method. The problem is, I never use a "method". I just sit down and code. Anyway, that's how you SHOULDN'T do it :-)

Let's see:

First, we need to make a loop the program runs in, only stopping at a certain command from the user. That'd obviously be a
Repeat
<Game>
Until <User wants to quit>
or a
While <User not quitting> Do
Begin
<Game>
End;
Since, I guess, the first one is easier, we'll do a Repeat...Until loop.

For reading ease, we'll put the game in a separate function (you have had "Procedures and Functions", haven't you?), which returns "True" if the user wants to quit and "False" if he doesn't.
Since we don't want to make things too complicated, we'll introduce a variable to hold the users response.
The main procedure now looks a bit like this (PlayGame is the function that plays the game):

Var
UserQuit:Boolean;

Begin
Repeat
UserQuit:=PlayGame;
Until UserQuit;
<Display ending message>
End.

| Note that you could also write
| Repeat Until PlayGame;,
| it's the same thing. (It just doesn't
| sound very logical :-).

Now that we've got that settled, I'm gonna submit this block of text and create a new one.
0
Commented:
Back for more? ;-)

We're gonna describe the PlayGame function, but first, we need some extra variables to hold things like:

Var
GamesWon,GamesLost,GamesDrawn,
UserChose,ComputerChose:Integer;

I hope the names of these variables are obvious...

Okay, the computer needs to choose a random number (Scissors, paper or stone). The function Random(X) returns a random number between 0 and X-1, so obviously, if we want a number from 1 to X, we add 1 to it. The code would be something like:
ComputerChose:=Random(3)+1;
Which would net "ComputerChose" a random value from 1 to 3.
Except that it ISN'T RANDOM AT ALL! Every time you run the program, you'll notice the numbers are always the same. That's because a computer CAN'T PRODUCE TRULY RANDOM NUMBERS! It just repeats a series of seemingly random numbers from 0..1 every time you call the procedure, and multiplies that by X.

To counter this problem, we set the "pointer" that points to the first number the computer will return to another value. If we determine this pointer by using the system clock, we'll have other numbers each time we run the program (You can't possibly run two programs at the exact same time... Well, not DOS programs anyway).

We do this using the procedure "Randomize", which only needs to be called once. We put this in our main program, and we get something that looks like this:

Var
UserQuit:Boolean;
GamesWon,GamesLost,GamesDrawn,
UserChose,ComputerChose:Integer;

Begin
Randomize;
Repeat
UserQuit:=PlayGame;
Until UserQuit;
WriteLn('*********************************');
WriteLn(' You have won '+GamesWon+' times');
WriteLn(' You have lost '+GamesLost+' times');
WriteLn(' The game ended in a draw '+GamesDrawn+' times');
WriteLn('*********************************');
WriteLn;
WriteLn('Thank you for playing and see you next time!');
End.

| You'll see that we have added some status messages
| at the end and a "good-bye" phrase.
| The status message is (of course) composed of
| some text and the values of GamesWon, GamesLost and
| GamesDrawn, which will be filled in our game
| function.

Still not a problem? Let's move along!
0
Commented:
Okay, finally we're getting to the "PlayGame" function.

Right now, we have this:

Function PlayGame:Boolean;
Begin
ComputerChose:=Random(3)+1;
End;

Now the user gets to take his pick. We write a line indicating that he may choose something:

WriteLn('1=Scissors  2=Paper  3=Stone');

That's easy. Now, to read the users input. We *could* simply read it in through a ReadLn, but it's often better (and nicer) to simply react to the first character he enters. Reading one character at a time is done by the function "ReadKey", which returns a character. The character type in Pascal is called a "Char", so we need another variable:

Var
Character:Char;
But I most often use
Ch:Char;
'cuz it's less typework ;-)!
Now, we don't want to let the user enter things that are not valid, so we need another loop that only proceeds once the user gives valid input.

Repeat
Until <Ch is in '1','2' or '3'>.

We _could_ combine a lot of "If" conditions there, which would look a terrible lot like this:

(((Ch='1') Or (Ch='2')) Or Ch='3')

It's cleaner to use a set. With a set, we can check if Byte or Char values are within a certain collection. Using a set, we can simply do this:

Repeat
Until Ch In ['1','2','3'];

Looks a lot better, doesn't it?
Well now, we can compare....

Oops! The computer select is a number, the user select is a char. We can't really compare those! Luckily, we now the ASCII code of the character '1' (It's 49). If '1' is 49, and '2' is 50, and '3' is 51... See it? We get the asci code, and simply subtract 48 from it: Presto, we got the value!

UserChose:=Asc(Ch)-48;

(If you don't know what ASCII is, ask your teacher. I can't really explain it :-(. Okay, it's a system where every character also has a number)

What's our code 'till now (yep, you guessed it, another block of code!):

Var
UserQuit:Boolean;
GamesWon,GamesLost,GamesDrawn,
UserChose,ComputerChose:Integer;
Ch:Char

Function PlayGame:Boolean;
Begin
ComputerChose:=Random(3)+1;
WriteLn('1=Scissors  2=Paper  3=Stone');
Repeat
Until Ch In ['1','2','3'];
UserChose:=Asc(Ch)-48;
End;

Begin
Randomize;
Repeat
UserQuit:=PlayGame;
Until UserQuit;
WriteLn('*********************************');
WriteLn(' You have won '+GamesWon+' times');
WriteLn(' You have lost '+GamesLost+' times');
WriteLn(' The game ended in a draw '+GamesDrawn+' times');
WriteLn('*********************************');
WriteLn;
WriteLn('Thank you for playing and see you next time!');
End.
0
Commented:
Now comes the hardest part, comparing the two values. For reading (and typing) ease, we'll introduce another function for that:

Function WhichWins(Val1,Val2):Integer;
Begin
End;

This function will return 1 if "Val1" wins, 2 if "Val2" wins and 0 if neither wins. The first part is easy: If both are the same, the game obviously ends in a draw:

If Val1=Val2 Then WhichWins:=0;

We don't need to check for that anymore.
From this point, it just gets plain old ugly in many, many combined "if" statements. (If I make an error in this, please be forgiving. Normally, I have a compiler handy to correct my mistakes)
So here we go:

If Val1=Val2 Then WhichWins:=0
Else
If Val1=1 Then
Begin { Scissors(1) }
If Val2=2 Then
WhichWins:=1 { Scissors(1) beats Paper(2) }
Else
WhichWins:=2; { Stone(3) beats Scissors(1) }
End Else
If Val1=2 Then
Begin { Paper(2) }
If Val2=1 Then
WhichWins:=2 { Scissors(1) beats Paper(2) }
Else
WhichWins:=1 { Paper(2) beats Stone(3) }
End Else
Begin { Stone(3) }
If Val2=1 Then
WhichWins:=1 { Stone(3) beats Scissors(1) }
Else
WhichWins:=2 { Paper(2) beats Stone(3) }
End;

I hope I got everything right... :-)

| Note that, after the first check inside the
| Begin...End parts, we don't check anymore,
| because if Val2 isn't Val1, and it isn't the one
| we've already checked for, it must be the remaining
| one!

Now that we've got that running, let's get back to our PlayGame function:

For local storing of the result of a round, we introduce
Var
RoundResult:Integer;
0 means draw, 1 means computer wins, 2 means player wins;

RoundResult:=WhichWins(ComputerChose,UserChose);

To let the computer tell what he had, we want a constant array with strings (You could use "if" statements again, but this is more elegant).

Const
Names:Array[1..3] Of String=('Scissors','Paper','Stone');

Now we can report the result:

If RoundResult=0 Then
Begin
WriteLn('It''s a draw!');
Inc(GamesDrawn)
End Else
If RoundResult=1 Then
Begin
WriteLn('I won!');
Inc(GamesLost)
End Else
Begin
WriteLn('You won!');
Inc(GamesWon);
End;

| We use the number the computer chose as an
| index in the array with strings. That's easy!
| And "inc" simply INCreases a number. Duh!

Then, simply ask for play again (we can use Ch again...)

WriteLn('Play again? (Y/N');
Repeat
Until Ch In ['Y','N'];
If Ch='Y' Then PlayGame:=False Else PlayGame:=True;

| Remember that PlayGame needed to return a

Now, I think we have it all covered. So here comes the final code:
0
Commented:
Var
UserQuit:Boolean;
GamesWon,GamesLost,GamesDrawn,
UserChose,ComputerChose:Integer;
Ch:Char

Function WhichWins(Val1,Val2:Integer):Integer;
Begin
If Val1=Val2 Then WhichWins:=0
Else
If Val1=1 Then
Begin { Scissors(1) }
If Val2=2 Then
WhichWins:=1 { Scissors(1) beats Paper(2) }
Else
WhichWins:=2; { Stone(3) beats Scissors(1) }
End Else
If Val1=2 Then
Begin { Paper(2) }
If Val2=1 Then
WhichWins:=2 { Scissors(1) beats Paper(2) }
Else
WhichWins:=1 { Paper(2) beats Stone(3) }
End Else
Begin { Stone(3) }
If Val2=1 Then
WhichWins:=1 { Stone(3) beats Scissors(1) }
Else
WhichWins:=2 { Paper(2) beats Stone(3) }
End;
End;

Function PlayGame:Boolean;
Begin
ComputerChose:=Random(3)+1;
WriteLn('1=Scissors  2=Paper  3=Stone');
Repeat
Until Ch In ['1','2','3'];
UserChose:=Asc(Ch)-48;
WriteLn;
If RoundResult=0 Then
Begin
WriteLn('It''s a draw!');
Inc(GamesDrawn)
End Else
If RoundResult=1 Then
Begin
WriteLn('I won!');
Inc(GamesLost)
End Else
Begin
WriteLn('You won!');
Inc(GamesWon);
End;
WriteLn;
WriteLn('Play again? (Y/N');
Repeat
Until Ch In ['Y','N'];
If Ch='Y' Then PlayGame:=False Else PlayGame:=True;
End;

Begin
Randomize;
Repeat
UserQuit:=PlayGame;
Until UserQuit;
WriteLn('*********************************');
WriteLn(' You have won '+GamesWon+' times');
WriteLn(' You have lost '+GamesLost+' times');
WriteLn(' The game ended in a draw '+GamesDrawn+' times');
WriteLn('*********************************');
WriteLn;
WriteLn('Thank you for playing and see you next time!');
End.

| Good luck with it! If you have any questions, please post them!
0

Experts Exchange Solution brought to you by

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Commented:
Oops!!!
I forgot the line
RoundResult:=WhichWins(ComputerChose,UserChose);

in the PlayGame function.
Sorry :-)
0
Commented:
?? Are you actually going to evaluate this :-) ??
0
Commented:
Helllooooooooooooooooooooo???
0
Commented: