Solved

# pascal programming question computer game

Posted on 1999-11-17
Medium Priority
245 Views
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
0
Question by:samzman
• 9

LVL 1

Expert Comment

ID: 2216946
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

LVL 1

Expert Comment

ID: 2217005
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

LVL 1

Expert Comment

ID: 2217061
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

LVL 1

Expert Comment

ID: 2217140
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

LVL 1

Accepted Solution

nrico earned 100 total points
ID: 2217150
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

LVL 1

Expert Comment

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

in the PlayGame function.
Sorry :-)
0

LVL 1

Expert Comment

ID: 2229237
?? Are you actually going to evaluate this :-) ??
0

LVL 1

Expert Comment

ID: 2268446
Helllooooooooooooooooooooo???
0

LVL 1

Expert Comment

ID: 2271474
0

## Featured Post

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

This article will show how Aten was able to supply easy management and control for Artear's video walls and wide range display configurations of their newsroom.
Today, unlike web development, the mobile landscape is complex enough for a software engineer and Android is posing more challenging environment thanks to its fragmentation issues on hardware and software fronts.
Viewers will learn how to properly install Eclipse with the necessary JDK, and will take a look at an introductory Java program. Download Eclipse installation zip file: Extract files from zip file: Download and install JDK 8: Open Eclipse and …
Loops Section Overview
###### Suggested Courses
Course of the Month3 days, 9 hours left to enroll