Class Crib Notes for CPSC 110                               Brent Dingle

                                    Friday, March 1, 2002

Reminders:

Midterm is next Wednesday (bring a gray/brown scantron – the big full page one).

 

Review:

Still going through procedures

 

New Stuff for today

More procedures.

 

EXAMPLE 1:

The below program shows how procedures can return values.

 
PROGRAM MoreProcs;
VAR
   x, y : real;
 
{ a and b are what type of params ? }
PROCEDURE TimesTheCube(VAR a, b : real);
VAR
   b_cubed : real;    { b_cubed is a LOCAL variable }
 
BEGIN
   b_cubed := b * b * b;
   a := a * b;
END;
 
BEGIN
   x := 10;
   y := 3;
   TimesTheCube(x, y);
END.

 

Notice since we did NOT change the value of b in the above program we could

have made b to be a formal VALUE parameter:

PROCEDURE TimesTheCube(VAR a: real;  b : real);

 

 

 

EXAMPLE 2 A:

Here’s an example to show how you can locally change the value of a parameter

(i.e. you can change the value of the parameter within the context of the procedure,

but NOT change the value of the variable sent)

 

PROGRAM ChangeUp;

VAR 
   x, y : real;
 
PROCEDURE Change(VAR a : real;  b : real);
BEGIN
   a := 10;
   b := 20;
   writeln(a, ‘ ‘, b);   { so 10 20 is output here }
END;
BEGIN
   x := 500;
   y := 1000;
   writeln(x, ‘ ‘, y);   { so 500 1000 is output here }  
 
   Change(x, y);         { x is VARIABLE param and y is VALUE param }
 
   writeln(x, ‘ ‘, y);   { and 10 1000 is written here }

END.

 

 

EXAMPLE 2 B:

Confused?  Okay, let’s look at a ‘bad’ program which uses global and local variables but NO parameters.

 

PROGRAM ChangeUp_BAD_BUT_ILLUSTRATIVE;

VAR 
   x, y : real;
 
PROCEDURE Change;    { no parameters }
VAR
   a, b : real;      { a and b are now local variables }
{ Note since in the last program a was a VARIABLE parameter
  and x was passed in the position of a, anything we do to
  a here must also be done to x.
  Since b was just a VALUE parameter we need not worry about
  the consequences of changing it here
}
 
BEGIN
   a := 10;    { a was a VARIABLE param so we must do the same to x }
   x := 10;
 
   b := 20;    { b was just a VALUE param so don’t worry about conseq }
 
   writeln(a, ‘ ‘, b);   { so 10 20 is output here }
END;
 
BEGIN
   x := 500;
   y := 1000;
   writeln(x, ‘ ‘, y);   { so 500 1000 is output here }  
 
   Change(x, y);         { x is VARIABLE param and y is VALUE param }
 
   writeln(x, ‘ ‘, y);   { and 10 1000 is written here }
                         { now does this output make sense ? }

END.

 

Notice the implication of the above is: Value Parameters are implemented as local variables – you can play with them and not effect anything outside the procedure.

 

 

Now we get to look at some more great and mysterious word definitions (which you might want to commit to at least short term memory =)

 

 

Identifiers:

Any string made up of letters, numbers and the underscore – PROVIDED it starts with a letter or the underscore.

Some examples of identifiers:

 
Block (of code):
A block of code consists of:
·         a parameter list
·         a set of declarations (list of local variables, constants, etc)
·         the body of statements to which they apply  (i.e. the begin, the end and the stuff between them)
 
Scope:
All identifiers (parameters, constants, variables, etc) described at the start of a block are said to be local to that block or rather to have that block as their scope.
 
So the scope of a local variable to a procedure is the procedure.
The scope of a VALUE parameter is the procedure.
The SCOPE of the name (and type) of a variable parameter is the procedure, but the EFFECT of changes to the variable parameter is larger.
 

Some motivation for using procedures:

Say you needed to perform the same action on a set of data that was continually changing.
For example consider the game of tic-tac-toe: The data to be operated on is the game board.
But the status of the game board keeps changing after each turn.
 
Do you want to write a program that accounts for every possible state of the board (29 possibilities)? 
EX: 
IF board state is:   
 X | O | X
---+---+---
 O |   | O
-----------
   |   |
THEN place an X in the center square
ELSE IF board state is:   
 O | O | X
---+---+---
 O | X | O
-----------
   |   |
THEN place an X in the lower left square
 
so that you have 29 IF – ELSE IF statements
 
Or would you prefer to use some general heuristic (common sense) rules to apply to any state of the board?
Such as 
IF I can win then take the winning square 
ELSE IF my opponent can win the block him/her

 

Let’s consider how to do the latter using a procedure:

First let’s break the Main Task of playing TIC-TAC-TOE down into subtasks:

What must we be able to do?

  1. Somehow represent the board
  2. Initialize the board to all blanks (no headstart cheating)
  3. Display the board in its current state
  4. Make a VALID (allowable) move
    1. If possible to win then win 
      (requires subtask to check to see if it is possible to win)
    2. Else if opponent can win then block
      (requires SAME subtask to check to see if it is possible to win, but for the opponent)
    3. Else pick a random(?) square
  5. Determine if somebody won
    1. Check rows
    2. Check columns
    3. Check diagonals
  6. Anything else?

 

Let’s begin:

 

PROGRAM TicTac;

VAR

{ We will use 9 variables to represent the board }

   board1, board2, board3 : char;

   board3, board4, board5 : char;

   board6, board7, board8 : char;

 

{ We may need some vars to represent the winner and whose turn it is }

   turn : char;

   winner : char;

 

{ Here we have a procedure to init the board to all blanks }

PROCEDURE InitBoard(VAR b1, b2, b3, b4, b5, b6, b7, b8, b9 : char);

BEGIN

   b1 := ‘ ‘;

   b2 := ‘ ‘;

   b3 := ‘ ‘;

   b4 := ‘ ‘;

   b5 := ‘ ‘;

   b6 := ‘ ‘;

   b7 := ‘ ‘;

   b8 := ‘ ‘;

   b9 := ‘ ‘;

END;

 

{ Here is a procedure to display the current board status

  notice all the vars are VALUE parameters }

PROCEDURE DisplayBoard(b1, b2, b3, b4, b5, b6, b7, b8, b9 : char);

BEGIN

   writeln(‘ ‘, b1, ‘ | ‘, b2, ‘ | ‘, b3);

   writeln(‘---+---+---‘);

   writeln(‘ ‘, b4, ‘ | ‘, b5, ‘ | ‘, b6);

   writeln(‘---+---+---‘);

   writeln(‘ ‘, b7, ‘ | ‘, b8, ‘ | ‘, b9);

END;

 

 

 

PROCEDURE Move(VAR b1, b2, b3, b4, b5, b6, b7, b8, b9 : char;

               player : char);

BEGIN

   { Here we make the computer dumb }

   if (b1 != ‘ ‘) then

      b1 := player

   else if (b2 != ‘ ‘) then

      b2 := player

   else if (b3 != ‘ ‘) then

      b3 := player

   else if (b4 != ‘ ‘) then

      b4 := player

   else if (b5 != ‘ ‘) then

      b5 := player

   else if (b6 != ‘ ‘) then

      b6 := player

   else if (b7 != ‘ ‘) then

      b7 := player

   else if (b8 != ‘ ‘) then

      b8 := player

   else if (b9 != ‘ ‘) then

      b9 := player

   else

      writeln(‘error – game over but Move Proc called.’);

END;

 

{ CheckForWin determines if anybody won – if all boxes

  are filled it sets winner to C – if nobody has won yet

  it sets winner to ‘ ‘ ( a space ) } 

PROCEDURE CheckForWin(b1, b2, b3, b4, b5, b6, b7, b8, b9 : char;

                      VAR winner : char);

BEGIN

   winner := ‘ ‘;

   Check rows

   Check diagonals

   Check columns

   If no winner found and all boxes are filled

   then set winner to = ‘C’

END;

 

Eventually we can make it smarter by adding:

PROCEDURE CheckIfCanWin(b1, b2, b3, b4, b5, b6, b7, b8, b9 : char;

                        player : char; VAR can : boolean);

BEGIN

    look for 2 consecutive squares followed by a blank

END;

 

 

Next time

Finish TicTacToe More Procedures and  Identifiers?   Maybe a review for the test.