Department of Computing Science CS_PAS Course Manual 1999/2000 University of Aberdeen CS_PAS 1999/2000 COURSE MANUAL Introduction Welcome to this course. No matter how much programming you may have done in the past - and that includes none - I hope that you will find the course interesting and instructive. This manual contains the information you will need to get started. Much of the material for the course is available on the World Wide Web: lecture notes, slides used in lectures, solutions to problems, etc. You will be told later in this manual how to access it. At the end of this course you should understand the basic principles of structured program design and be able to apply them in writing a simple Pascal program which makes extensive use of library procedures and functions. It is a pre-requisite for any undergraduate wishing to continue their studies in Computing Science, and it is also suitable if you wish to develop programming skills to support your studies in other subject areas. One of the following books is required for the course: J Bishop, Turbo Pascal Precisely , Addison-Wesley (1992) paperback. or D W Nance, Understanding Turbo Pascal: Programming and Problem Solving, West Publishing Company (1994). Most of you taking this course will be doing so in classrooms belonging to the University Computing Centre. Some may be taking it at a remote Study Centre; in this case the Centre will have provided suitable facilities, and you should consult the staff there. It is possible to use a stand-alone computer at home for working on this course; a Web page will be set up which will describe how to do this. In the rest of this document, the following conventions will apply: a hollow bullet (like this) indicates that you should take some action italics will usually describe the response you should get Copyright: Jim Hunter (September 1998) 2 CS_PAS 1999/2000 COURSE MANUAL KAREL the Robot During the first part of this course, you will be writing programs which control a robot called KAREL. It's too expensive to provide everyone with a real robot, so we have to simulate him on the PC. Getting to Know KAREL and his World Your first objective is to get to know KAREL and his world. To this end we have built a version of the KAREL simulator (we call it a 'manual' version - ManKAREL) which allows you to control KAREL using the mouse. If necessary, start up Windows NT. Open the Science and Engineering folder on the Desktop Open the Computing Science folder. Double click on the Mount CS_PAS icon Note: You should always do this before you start ant work in connection with this course - amongst other things it mounts the L: drive. Double-click on the ManKAREL icon. This will bring up a large window which shows KAREL’s world, and a smaller window (the Control Panel) which will allow you to get KAREL to do things. If necessary, move the Control Panel away from the centre of the screen. KAREL's World KAREL lives in a flat world with the standard north, south, east and west compass points; north is to the top of your screen. He moves around a two-dimensional grid marked by an array of Grid Points (often referred to simply as Points). KAREL is always positioned on a Grid Point facing north, south, east or west; he is represented by a black crescent. Grid Points have co-ordinates - an X co-ordinate (running from left to right) and a Y co-ordinate (running from bottom to top). We'll use the standard convention to indicate the co-ordinates of a given Grid Point e.g. (3,4) means that the X co-ordinate is 3 and the Y co-ordinate is 4. The Origin is the Point (1,1) - not (0,0) which doesn't exist in KAREL's world. We will need to refer to distances in KAREL's world. The basic unit of distance is that between two neighbouring Points. I will refer to this distance as a block - referring to the American way of describing the distance between two parallel streets. KAREL's world is bounded all round by external walls. We can set up different worlds for KAREL to be in, with different internal walls, but they all have the external walls just described. Internal walls can be of any length, and are positioned between adjacent Points, blocking KAREL's path from one Point to the next; walls are represented by blue lines. KAREL can detect walls but can't penetrate them. The other kind of object in KAREL's world is a beeper. Beepers are small plastic balls that emit a quiet beeping noise; one beeper is represented by red concentric circle - more than one by a red number. They are situated on Points and can be picked up, carried or put down by KAREL. The figure on the next page gives one possible world for KAREL. In this world KAREL starts as shown at Point (3,11). Different worlds are stored in separate files. The name of the file is the name of the world. Each file determines where the internal walls are (if any), where KAREL starts from, where any beepers are (if any) and how many beepers he is carrying to begin with (if any). KAREL's Capabilities KAREL can only move in the direction he is facing, one Point at a time. He can also turn, although he only understands the command to turn left. He carries with him a beeper bag and at any time, if he has 3 CS_PAS 1999/2000 COURSE MANUAL beepers in his bag, can take one out and place it where he is. If he is on the same Point as a beeper then he can pick it up and put it in his bag. Finally he can turn himself off. He therefore understands the following commands: move pickbeeper turnoff turnleft putbeeper Note that turnoff should always be the last command given to KAREL. Certain actions are illegal trying to move through a wall, trying to pick up a beeper that isn't there, or trying to put down a beeper when his beeper-bag is empty. You will get a message indicating that the action you have attempted is impossible. The action won't be carried out. It is important to note that when you program KAREL in Pascal, the program will stop (exit) if an illegal command is given. Controlling KAREL Using the Mouse On this occasion, KAREL finds himself in the world shown below; he has five beepers in his bag. Click on the various buttons to get the appropriate actions. Notice that the last action to be performed is given as a Status Message at the bottom left hand corner of the window. If you try to do something illegal, then the Status Message will tell you what has happened. 4 CS_PAS 1999/2000 COURSE MANUAL KAREL's World Window A the very top of KAREL's world window you will see the menu bar which lists a number of commands which are obeyed when the mouse is clicked on them. Some of them will give rise to a drop-down menu from which you can select an option by clicking the mouse; if you don't want to choose any of the options click the mouse outside the drop-down menu. Run Ultimately, this will start executing the instructions in the program you have written to control KAREL. Since you have no program at present, it is 'greyed out' to show that it is not available. Exit Stop running your program at whatever point it's at. World Load World Normally KAREL will appear in whatever world you have specified in your program. In this case I have specified the world which is defined in the file called manual. However you can put him in different worlds and this command allows you to do so. It will open up a file select box - pre-existing worlds are stored in L:\delphi\system\worlds. Create New World If you don't like any of the existing worlds, then you can create a new one. Selecting this command will bring up the World Editor. It’s probably not a good idea to use this yet - instructions will be given later. View Status Window This pops up a window which will keep a record of the commands that you have given. It’s not particularly useful at present, but when you come to write programs, it should help you to understand what’s going on. You may need to move it to a convenient spot. Refresh This redraws the contents of the window, and shouldn’t really be needed. Pause/Resume Again, this isn’t any use at present, but when you start running a program, it is useful to be able to stop it running to see what is going on, and then to resume it again. Speed Defined as 1 (slow) .. 6 (fastest). These are the speeds at which KAREL carries out his actions. Slow speeds are useful when you are running a program and need time to see what is happening. Print Should print out the contents of the window to the printer. Use this fairly sparingly; if everyone in the room were to print every screen, the printer queue would get full up and you'd wait a long time for output. Help At present, this just brings up the Copyright box. What you get KAREL to do in this world is not very important; just familiarise yourself with the various commands. You might like to get him to set out all the beepers (those he has in his bag plus the other two) in a straight horizontal line somewhere. KAREL’s Senses KAREL has a number of sensory inputs. We won’t use them for a bit, but it seems appropriate to mention them now. He has three cameras which tell him if there is a wall immediately ahead of him, to 5 CS_PAS 1999/2000 COURSE MANUAL his right, or to his left - but only for walls that are half the distance between Grid Points away - he is very short sighted. So he knows the answer TRUE or FALSE to the following questions: front_is_clear left_is_clear right_is_clear front_is_blocked left_is_blocked right_is_blocked He can hear if he is next to a beeper, but, because beepers are so quiet (and his hearing isn't that good), only if he and the beeper are on the same Point: next_to_a_beeper He can tell whether he has any beepers in his bag, but not how many: any_beepers_in_beeper_bag He also has a compass which can tell him which way he is facing: facing_north facing_east facing_south facing_west Note that the only way KAREL can find out about the world is through his senses. He doesn't have direct access to any of the information in the world files but must navigate through the world we have set up for him using only the capabilities described above. Finally he can tell which Point he is on. In our programs we can get at these values by using two functions (don't worry what a function is yet) which give (respectively) his X and Y co-ordinates at the time: Karel_X Karel_Y Pascal and Delphi Pascal is the name of the language you will be writing programs in; Delphi is the name of the development environment. Delphi provides state-of-the-art programming facilities. This has the disadvantage that it provides far more power than you need at present, but it does allow us to provide you with a teaching environment which would be difficult to provide in any other way. Running Your First Program You are now ready to run your first Pascal program - one that has been already written. you should already have copied the file L:\delphi\programs\notmuch.dpr into a suitable directory on your H: drive; if you haven’t, do so now. use Windows Explorer and find your copy of notmuch.dpr. double click on it to start Delphi, this may take a little time, especially if you are running on a 486 PC. It is not a good idea to try to run Delphi on any 386 PC. You should see: a menu bar at the top of the screen a window on the left hand side of the screen called the Object Inspector. You will never need the Object Inspector so close it a window with the title NOTMUCH.DPR; this is the window you will use to enter and change your Pascal code - for this reason it is called the Edit Window. Resize it if necessary. It might be a good idea to minimise any other open windows to reduce clutter on your screen. 6 CS_PAS 1999/2000 COURSE MANUAL The Edit Window should contain the following code: PROGRAM notmuch; USES cskarel; BEGIN setworld(’notmuch’); move; move; pickbeeper; move; turnleft; move; move; putbeeper; move; turnoff END. The world notmuch is shown below. KAREL's task is to move the beeper from Point (4,2) to Point (5,4) and to finish at Point (5,5). We will discuss the structure of this program in lectures. For the moment you should note that the command: setworld('notmuch') ensures that when the program is run, KAREL will find himself in the world notmuch. The general form of the command is: setworld('<worldname>') where <worldname> is the name of a particular world. Note that the names of worlds are always enclosed by single quotation marks. You will be working through many problems, and the worldnames to be used are given with each question. setworld sets up the appropriate world and draws it on the screen, and should always be the first command in a KAREL program. Choose Run, Run or click the dark blue arrow on the tool-bar. This is called (no surprise) Running the program. This will bring up KAREL’s world window with KAREL in the world notmuch. In this window, choose Run to execute the sequence of statements in the program. 7 CS_PAS 1999/2000 COURSE MANUAL Run the program several times, using the commands to pause, change speed, look at the status window, etc. When you have finished, choose File, Close All. Exit from Delphi - choose File, Exit. We can note at this point that there are two further commands you can include in your program: speed(1), speed(2) ... speed(6) This determines how fast KAREL moves. You can change this during the simulation by using a command from the menu (see above) but you can also change it from within your program. Pause_KAREL This causes your program to suspend its execution at the point where it is encountered. You resume execution by clicking on Resume in the menu bar. Writing Your First Program Start Delphi by double clicking the Delphi icon in the Computing Science folder. Ignore the windows that appear Choose File, New… and click on the Projects tab. Double click on KAREL A window will appear asking you to Select Directory - this is where your program will be saved. You first need to make sure that the correct drive is selected (drop down menu) and then the correct directory. If you are ever asked to replace the existing file program.dpr, then say YES. The Edit Window will now contain the following code: PROGRAM program; USES cskarel; BEGIN { Save this file with another filename by choosing File, Save Project As... DO NOT change the first line of the file (i.e. PROGRAM ...) Then delete this comment. } END. Save the file by choosing File, Save Project As ... A suitable name might be first. You should save it to the appropriate directory in your H: drive. You can just use the simple filename first - Delphi will save it as first.dpr. All your program files will have the file extension .dpr. Notice that the name of the program has been changed to the name of the file. Now delete the comment (the text between the curly brackets { ... }) using Editing commands (see below) When making changes to the program, the Edit Window must be active. If it isn't, make it active by clicking the mouse inside the window. 8 CS_PAS 1999/2000 COURSE MANUAL To delete text inside a program, move the mouse to the end of it, click, and press Backspace or Delete keys, as required. For deletions of larger sections use the drop-down menu, headed by Edit using the options Cut, Copy and Delete. For these, a section of text must be highlighted in the Edit Window by dragging the mouse over it. This is done by dragging the mouse across the area - move the mouse to the start of the area, press the left button and keep it depressed while moving the mouse to the end of the area. Cut Copy Paste removes the highlighted text, but puts it into a temporary area called the clipboard . leaves the highlighted text in the Edit Window but places a copy of it in the clipboard. copies the contents of the clipboard (created by the last Copy or Cut ) to the area in the Edit Window currently selected by the mouse. Delete removes the highlighted text and does not save it in the clipboard. For example, you could remove the three lines of text between the { … } by highlighting them and choosing Edit, Cut. You are now going to change this program so that KAREL accomplishes a specific task. KAREL starts in the initial situation illustrated below; his task is to get to the beeper, pick it up, and then turn himself off. The following program will accomplish that task: PROGRAM first; USES cskarel; BEGIN setworld('hiding'); move; turnleft; turnleft; turnleft; move; turnleft; move; turnleft; move; pickbeeper; turnoff END. Edit the program to include the text between BEGIN and END. To add text inside the program, move the mouse to the point of entry, click, and type the desired text. Run the program as before You may get some errors before KAREL's world window appears - these are compilation errors; check that you have entered the program exactly as it appears above. Try to figure it out for yourself - mis- 9 CS_PAS 1999/2000 COURSE MANUAL spellings, missing semi-colons, etc., but get help if you are stuck. If you haven't encountered such an error then create one deliberately! Compilation errors are one kind of error. Other errors are run-time errors which are errors which occur as the program runs. Deliberately create a run time error by removing one of the commands (i.e. move or turnleft) Run the program again. KAREL will either run into a wall or will try to pick up a beeper that isn’t there. Alter the program in various ways and run the altered versions; understand what is happening. You will spend a most of your time at the terminal in the Editor Window. It is a very good idea to invest time now in becoming very familiar with it and its capabilities. Your investment will be repaid in the future! Saving Your Program You should make a permanent copy of the correct version of your program; you do this by saving it again: Choose File, Save Note that you have already saved it once before, so it already has a name You might want to get a print-out by choosing File, Print If you use the Windows Explorer to look in the directory where you are saving your files, you will find more than you bargained for - i.e. a number of files with the same name but with different extensions. You can leave these alone, because they are all quite small with the exception of the .exe files. These can get quite large, and if you run short of file quota, you may want to remove them. There is no harm in this as they are recreated every time you compile your program. Important Delphi Commands Here is a summary of the most important Delphi commands. As we’ve already said, Delphi is a very complex system, and there are many more commands than you will need in this course. File New … Open Reopen Save Save As ... Close Print Exit Choose the Project tab. Creates a new program for you to work with. Note that you can only work on one program (or project) at a time. In the dialogue box that appears, you would normally select the KAREL project. Opens an existing project for you to work on Provides a list of projects that you've worked on recently Saves the program you are working on to disk. It is a good idea to do this at frequent intervals. Saves the program under a different name. Stop working on the current program. Get a listing of your program on the printer. Leave Delphi Edit Undo/Redo Undo (or do again) the effect of the last editing command - useful if you make a mistake. Cut, Copy, Paste and Delete Already described 10 CS_PAS 1999/2000 COURSE MANUAL Run Run Program Reset Complies and runs your program. Useful if you really get into trouble and need to stop your program executing. Help Delphi has extensive built-in help facilities; much of what is said will be too complicated, but it’s always worth trying! Structure of a Complete KAREL Program in Pascal This is the way it should look; we'll come to procedures soon: PROGRAM <program_name>; USES cskarel {Compulsory} {Compulsory} PROCEDURE <new_name_1>; BEGIN <statement>; . . <statement> END; {Not Compulsory} . . PROCEDURE <new_name_n>; ... {Not Compulsory} BEGIN {Compulsory} setworld(’worldname’); {Compulsory for using KAREL} <statement>; {This is where KAREL starts executing instructions, either pre-defined, or defined above} <statement> turnoff {The usual way to end a KAREL program} END. {Compulsory} Example Programs All of the programs talked about in the lectures, and all of the solutions to problems (where they are complete programs) are (or will be) available in the directory L:\delphi\programs. You can copy them into your own directory, run them and modify them as you wish. The World Editor KAREL is not restricted to the worlds which have already been defined. You may create your own worlds for KAREL to explore. Run the KAREL World Editor by clicking Weditor in the Computing Science folder or by choosing World, Create New World from the KAREL window. 11 CS_PAS 1999/2000 COURSE MANUAL The World Editor is controlled primarily by using the mouse. Note that if you are using a one-buttoned mouse then clicking with the right mouse button can be simulated by holding down the <CTRL> key while pressing the mouse button. Here is a summary of the functionality of the World Editor. File New World Open World Save Creates a new, blank KAREL world Loads a world from disk Saves the current world to disk under its current filename; note that you can only save your new worlds to a directory on your drive (H:). Save As... Saves the current world to disk under a new filename Exit Exits the World Editor program Update and Return This option only exists if you are running the World Editor from a KAREL program. It will make the KAREL Simulator load the world currently in the Editor, minimise the Editor and return to the KAREL program. View Refresh Refreshes the screen Item Beeper (Single) Places the editor into Single Beeper Mode. In this mode, a left mouse click will place a single beeper on the Point the cursor is over. A right click will delete a single beeper. Subsequent left mouse clicks will add one to the number of beepers on that Point, and subsequent right mouse clicks will subtract one. Beeper (Multiple) Places the editor into Multiple Beeper Mode. In this mode, the mouse cursor may be dragged while pressing either the left mouse button (to place beepers) or the right mouse button (to delete beepers). Beeper (Specified) In this mode, when the left mouse button is clicked over a Point a dialogue box appears for you to enter the number of beepers you wish to be at this Point. Wall Places the editor into Wall Mode. In this mode, you may press the left button and drag the mouse to create a new wall. Releasing the button finalises the operation. Clicking on a wall with the right mouse button allows you to delete that wall. Karel Once this option is selected, you may click with the left mouse button to place KAREL in another position in the world. Right-click in order to rotate KAREL. Beeper Bag Selecting this option brings up a dialogue in which you may enter the number of beepers for KAREL’s beeper bag. World Name This option allows you to enter a name for KAREL’s world (up to 255 characters). This name then appears at the top of the World Editor as well as any program using the KAREL World Simulator. Special FX Flood Beepers This allows you to add a number (positive or negative) of beepers to every Point of the world. Options Colours This option allows you to change the background colour of the World Editor About Brings up information about the World Editor’s author 12 CS_PAS 1999/2000 COURSE MANUAL Interacting with the User As time goes on, your programs will need to write textual messages to the screen and to take in text and numbers that the user types in. In much of the course software, the following procedures and functions will be available. Note that for non-KAREL programs you will have to include IO in your USES statement. procedure DisplayStringToUser(MessageString:STRING) displays the MessageString in a box function GetStringFromUser(Question:STRING): STRING displays the Question string and waits for the user to type a string in reply; the function returns when the user hits Return function GetIntegerFromUser(Question: STRING): INTEGER displays the Question string and waits for the user to type an integer in reply; the function returns when the user hits Return; if a valid integer is not entered, an error message is displayed and the user has a chance to try again. function GetRealFromUser(Question: STRING): REAL as for GetIntegerFromUser but returning a real number. function YesNoQuestion(Question: STRING): BOOLEAN pops up a dialogue box with the text Question in it. It has two buttons - Yes and No. If Yes is clicked, then the function returns TRUE, otherwise FALSE. 13 CS_PAS 1999/2000 COURSE MANUAL Tutorial Problems 1. Start KAREL in the initial situation illustrated on the left below and simulate his execution of the program below. KAREL's task is to get to the beeper, pick it up, and then turn himself off. Say where KAREL ends up and what error occurs (if any). If an error does occur, explain how you would correct the program. This program has no lexical or syntactic errors. PROGRAM getit; USES cskarel; BEGIN setworld('getit'); turnleft; turnleft; move; turnleft; move; move; turnleft; move; turnleft; move; pickbeeper; turnoff END. 2. Every morning KAREL is awakened in bed when his newspaper, represented by a beeper, is thrown onto the front porch of his house. Program KAREL to retrieve his paper and bring it back to bed with him. The initial situation is given in Figure 2-5, and the final situation must have KAREL back in bed (same Point, same direction) with the newspaper. Verify that the program is correct by hand simulating with KAREL in the appropriate initial situation. (If you want to try this out in practicals, the world is paper). 3. The wall sections in Figure 2-6 represent a mountain (north is up). Program KAREL to climb the mountain and then plant a flag, represented by a beeper, on the summit - Point (5,5); KAREL must then descend the other side of the mountain to location (8,1). Assume that he starts with the flag-beeper in his bag. Remember that KAREL is not a super-robot who can leap up and down in a single bound. KAREL must closely follow the mountain's face on his way up and down, i.e. he must be in contact with the internal walls at all times. (If you want to try this out in practicals, the world is mountain). 14 CS_PAS 4. 1999/2000 COURSE MANUAL Write appropriate definitions for the following four new instructions: (i) turnaround, which turns KAREL around 180; (ii) move_mile - a mile is eight blocks; (iii) move_backward, which moves KAREL one block backward but leaves him facing the same direction; (iv) move_kilo_mile, which moves KAREL 1000 miles forward. This last problem is difficult, but a fairly short solution does exist. You may use the move_mile instruction in this problem without redefining it. Also, which of these four instructions might cause an error shutoff when it is executed? Which will certainly do so? 5. (a) KAREL sometimes works as a pin-setter in a bowling alley. He starts this task in bowling at Point (5,1) facing north with ten beepers in his beeper-bag and no beepers set out. Write a program that instructs him to achieve the final situation as shown. (b) Rework your solution to part (a) by defining: PROCEDURE set_out_a_row (n : INTEGER); where n is the number of pins in the row. Use FOR loops to get the simplest program you can. 6. Define face_south, a new procedure that faces KAREL south regardless of the direction he is initially facing. First, do this without using face_north as a known procedure. Experiment with different forms of the IF/THEN and IF/THEN/ELSE statements and with the FOR instruction. Next, write face_south assuming that the procedure face_north has already been defined. Given that face_north is correct, it should be easy to convince anyone of the correctness of face_south. 7. Look at the following statement. Is there a simpler statement which has the same effect when it is executed? If so, write it down; if not, explain why not. IF NOT next_to_a_beeper THEN move ELSE move 8. Assume that KAREL is on a Point with either one or two beepers. Write a new procedure that leaves him facing north if he is started on a Point with one beeper and facing south if he is started on a Point with two beepers. After KAREL has executed this procedure, there must be the same number of beepers on the Point as were there originally. Write another version of the procedure in which no beepers are left on the Point. 9. Write an instruction that turns KAREL off if he is completely surrounded by walls, unable to move in any direction. If he is not completely surrounded, KAREL should execute this instruction by leaving himself turned on, and by remaining on the same Point, facing the same direction in which he started. Hint: To write this instruction correctly, you may need to include a turnoff inside it. This combination is perfectly legal, but it is the first time that you will have used a turnoff instruction outside of the main program compound statement. 15 CS_PAS 10. 1999/2000 COURSE MANUAL Look back at the 'climbing stairs' example discussed in the lectures - Figure 3.1(a). The object is to get KAREL to the top step having picked up all the beepers. Write a solution using a FOR loop. Look at all the previous tutorial and practical examples you have been set, and see where repeated code could be replaced by a FOR loop. 11. Write a new instruction for KAREL named empty_beeper_bag. When KAREL executes this instruction, he should empty his beeperbag on the Point he is standing at. 12. Write a new instruction called go_to_origin that positions KAREL at Point (1,1) facing east, regardless of his initial location or the direction he is initially facing. Assume that there are no internal wall sections present. Hint: Use the south and west external walls as guides. 13. Study the following program fragments separately. What does each do? For each one, is there a simpler program fragment that yields the same result when executed? If so, write it down; if not, explain why not. Hint: The formal properties of REPEAT and WHILE are useful. (i) REPEAT move UNTIL NOT next_to_a_beeper; IF next_to_a_beeper THEN pickbeeper ELSE turnoff (ii) WHILE NOT next_to_a_beeper DO IF next_to_a_beeper THEN pickbeeper ELSE move 14. Write an instruction that faces KAREL east if he is on a Point with an even number of beepers, and faces him west if he is on a Point with an odd number of beepers (zero is considered an even number for this task). KAREL can clear the Point of beepers while he is determining which direction to face 15. Which of the following are invalid Pascal identifiers and why? 16. A1 A1 12A A1* JANE'S scarlet SCARLET YO-YO this_one FunnyOne Why do Pascal and certain other languages insist that variables have a pre-declared type? 16 CS_PAS 17. 1999/2000 COURSE MANUAL What is the value of the variable result at the end of execution of each of the following sequences of assignment statements? Can (ii) be simplified and if so, how? (i) VAR party, doubles, singles, result : INTEGER; BEGIN party := 27; doubles := party div 2; singles := party mod 2; result := singles + doubles END (ii) VAR a, b, result : INTEGER; i, j : BOOLEAN; BEGIN a:= 12; b:= 5; a := a + b; b := a - b; i := a > b; j := a <= b; IF i OR j THEN result := a * b ELSE result := a - b END 18. We want to interchange the values of two variables a and b. Explain why the pair of statements below doesn't do this, and find a way, using just assignment statements, that does. (Hint: use an extra variable temp). a := b; b := a; 19. KAREL finds himself inside a rectangular box, made up of internal walls. Other than that he is in the box, he doesn't know where he is, nor which way he is facing. There are no other internal walls. His task is, by making the appropriate moves, to establish the dimensions of the box. Write a program which will do this. Use the DisplayStringToUser statement to output the dimensions e.g. for the given example: The box is 7 by 5 blocks. If you want to program this, the world is box. 17 CS_PAS 20. 1999/2000 COURSE MANUAL KAREL is at one end of a line of beepers facing along it. Write a procedure which, when it returns, has the number of beepers in the line stored in a variable number (which will be declared in the main program): PROCEDURE count_beepers KAREL should pick up the beepers as he goes. It is up to you to decide where he ends up, but you should be clear where it is. Write two versions - one with a WHILE loop, and one with a REPEAT loop. 21. What are the essential differences between WHILE and REPEAT loops? 22. Look at the following Pascal expressions. With the given variable declarations, some are legal and some are not. Say which is which. For those that are legal state the type of the value of the expression. For those that are not, say why not. VAR a, b, c : INTEGER; i, j : BOOLEAN; (i) (iv) (vii) (x) 23. a b i a <= b AND c = j mod b (ii) (v) (viii) i OR a i * j a < b < c (iii) (vi) (ix) NOT i a c NOT i AND j k, m and n are all integer variables. What are their values after executing the following sections of code? (i) n:=3; m:=n+2; IF n<3 THEN n:=4 ELSE IF m>4 THEN k:=5 ELSE k:=6; (ii) n:=4; k:=0; REPEAT IF n<>2 THEN k:= k + SQR(n); n:=n-1 UNTIL n=1; 24. Why is it advantageous to be able to declare symbolic constants in Pascal programs? 18 CS_PAS 25. 1999/2000 COURSE MANUAL Work out the values of the following expressions, given the initial values for the variables: VAR a, b : INTEGER; a=7; b:=4; (i) (ii) (iii) (vi) (v) 26. SQR(a) + SQR(b) ODD(a-b) OR ODD(a+b) PRED(PRED(PRED(SUCC(SUCC(SUCC(a)))))) ODD(a mod 2) = ODD(a) SQR(b) + 2*b + 1 - SQR(SUCC(b)) Write three sections of code each of which ends up with the integer variable sum assigned to the sum of the fourth powers of the odd integers between 0 and 10: (i) using a FOR loop; (ii) using a REPEAT loop. (iii) using a WHILE loop; You can get the fourth power by taking the square of the square. 27. Write the following expressions in Pascal notation: (i) (iv) 28. sin3 + 3 sin cos xmin x x' xmax (ii) ax2 + bx + c (iii) 1/ (v) a 1/ (vi) r2 3 |b| 2x For each of the following expressions, work out its value when the variables have the values given. If the parentheses were removed, would the resulting expression be legal. If so what would be the value? Are any of the parentheses unnecessary? If the resulting expression is not legal, why not? a:=3; b:=9; c:=5; i:= TRUE; j:= FALSE; k:= FALSE; (i) (a+b)*c (iv) (a*b)/c 29. (ii) (a<6) AND (b>7) (v) ((a*b))+(5*c) Explain why the values of the following expressions may both be different from 13.0. How significant is the difference in each case? (i) (13 div 7)*7.0 30. (iii) NOT((i OR j) AND k) (vi) (15-b)div(c mod 2) (ii) (13.0/7.0)*7.0 If day and month are integer variables, and possibly_leap is a Boolean variable, rewrite the following statement more concisely: IF (day=29) AND (month=2) THEN possibly_leap := TRUE ELSE possibly_leap := FALSE 31. If two rabbits produce a litter of four babies every three months, and if rabbits are capable of reproduction when they are three months old, write a piece of code which will work out how long it will take to generate more than 500 rabbits starting from 2 babies. 19 CS_PAS 32. 1999/2000 COURSE MANUAL Write a program that repeatedly prompts for a string, reads it in, and outputs the string and its length, until the user enters the word end. Enter the string: Hi there The string Hi there has 8 characters Enter the string: What a load of rubbish! The string What a load of rubbish! has 23 characters Enter the string: end Bye bye 33. Write a program that reads in two integers a and b where a < b, calculates the sum of all integers i such that a i b and i is not exactly divisible by 5 or by 7. Enter the lower integer: 20 Enter the upper integer: 30 The sum is: 151 34. Write a program that reads in two temperatures T low and Thigh which are temperatures in degrees Centigrade, and writes out a conversion table at intervals of 0.3 degree Centigrade from Centigrade to Fahrenheit. Temperatures in Centigrade should be given to one decimal place, those in Fahrenheit to two decimal places. To convert a temperature in degrees Centigrade (T c) to one in degrees Fahrenheit (T f ) use the formula: T f = 9 T c /5 + 32 Enter the lower temperature: 45 Enter the higher temperature: 48 35. Centigrade Fahrenheit 45.0 45.3 45.6 45.9 ... 48.0 113.00 113.54 114.08 114.62 118.40 The following are the various procedures than can be called for an external text file used for input. Assuming the declarations: VAR input_data: TEXT; n: INTEGER; what do they accomplish? AssignFile(input_data, 'myfile.txt'); Reset(input_data); READLN(input_data, n); CloseFile(input_data); What are the corresponding procedures for an external text file used for output? What built-in function do you know which takes an input text file as its parameter, and returns a Boolean? Under what circumstances does the function return TRUE? 20 CS_PAS 1999/2000 COURSE MANUAL 36. What is meant by an (n+1/2) times loop? How can it arise in a program with a loop to handle an input data stream where a marker indicates the end of the data? How does the use of the EOF function simplify the loop? 37. Write a program that i) ii) prompts the user for the name of a text file; copies the contents of that file to the screen; every 20 lines it should pause and say to the user: Press <RETURN> to continue and wait until RETURN is pressed before doing so. Note that the procedure READLN without any parameters will complete execution when the RETURN key alone is pressed. 38. Use the squared grid below to show what the output would be from the following code, assuming that the constants have the values as given: CONST a = b = c = d = e = f = -56.2345; 0.000348; -591; 't'; 'Merry Christmas'; ' '; {three spaces} WRITELN('123456789012345678901234567890'); WRITELN(a); WRITE(b, f, c); WRITELN; WRITELN(a:13); WRITELN(b:11); WRITELN(a:10:2, f, b:10:2); WRITELN(c:8); WRITELN; WRITELN(d:3, e:20); 21 CS_PAS 39. 1999/2000 COURSE MANUAL The Delphi system delivered with the PC which you got as a Christmas present is great, except for one thing. The sin function which should be built-in, isn't! However you remember that sin can be expressed as a series: sin = - 3 5 7 + + ... 3! 5! 7! over the range 0 2 Remember that n! = n (n-1) (n-2) ... 2 1. Write a procedure: PROCEDURE get_sin(theta:REAL); which will remedy the situation by working out the value of sin(theta) and assigning it to a variable my_sin. One slight problem is that the series has an infinite number of terms, and your computer (although the latest model) is finite! This means that you can only calculate sin to a given precision. I suggest that 0.000001 is good enough, so you should stop adding terms to the total when you come across a term which is less than this amount. (It can be shown that the terms are always decreasing in value). This problem is more complicated than it looks, and is an example of a calculation in which you do have to take account of the finite size of numbers that can be represented. You can't just calculate the numerator and denominator of a term separately and divide the one by the other, each gets too large. Look at what you have to do to the nth term to get the (n+1)th term. Note that as far as I can see, the series only gives the correct result if 0 <= theta <= 2*pi. You might like to check this out by plotting for values of theta around 40! 40. (i) (ii) (iii) What is the difference between a local and a global variable? Explain how global variables enable procedures to communicate with each other. In the program given below, which variables are local and which global. What would be written to the screen by the program? PROGRAM test; VAR c, d:INTEGER; PROCEDURE first(c:INTEGER); VAR d:INTEGER; BEGIN d := 5; WRITE(c); WRITE(' '); WRITELN(d); c := d+2; d := c-3 END; PROCEDURE second(a:INTEGER); BEGIN WRITE(c); WRITE(' '); WRITELN(a); d := d+9 END; BEGIN c := 13; d := 7; WRITE(c); WRITE(' first(d+2); WRITE(c); WRITE(' second(c); WRITE(c); WRITE(' END. '); WRITELN(d); '); WRITELN(d); '); WRITELN(d) 22 CS_PAS 41. 1999/2000 Look at the following program. I have missed out a number of semi-colons. I've also put in some which should not be there. Finally there are some which, although not illegal are unnecessary. Modify the program so that it is legal, and identify the unnecessary semi-colons. PROGRAM plot_it USES csPlot, IO; CONST x_step = 1.0; x_max = 360.0; y_max = 20.0; VAR x, y_s, y_c : REAL BEGIN DrawAxes(x_max, y_max); x:=0.0 REPEAT y_s:=10*(1.0+SIN(radians(x/57.2958))); y_c:=10*(1.0+COS(radians(x/57.2958))) IF (0.0 <= x) AND (x <= x_max) AND (0.0 <= y) AND (y <= y_max); THEN BEGIN; PlotPoint(x,y_s); PlotPoint(x,y_c) END; ELSE DisplayStringToUser('Out of range'); x := x + x_step; UNTIL x > x_max; REPEAT UNTIL ExitClicked END. 42. COURSE MANUAL What does the following program print out? PROGRAM mystery; VAR ar: ARRAY[1..8] OF INTEGER; k, m, tmp: INTEGER; BEGIN FOR k:= 1 TO 8 DO ar[k] := 3*k; ar[8] := 0; m := 8 div 2; ar[m] := ar[m] + 1; m := m div 2; tmp := ar[m]; ar[m] := ar[m+1]; ar[m+1] := tmp; FOR k := 5 TO 7 DO ar[8] := ar[8] + k; FOR k := 8 DOWNTO 1 DO WRITE(ar[k]:4); WRITELN END. 23 CS_PAS 1999/2000 COURSE MANUAL 43. A list of names is contained in a text file (names.txt), one name (string) per line. Write a program to read them into an array of strings, sort them alphabetically and then output them to the screen in alphabetical order. Look at the Sorting problem in the next section, and use the algorithm given there to do the alphabetical sort. 44. Write a Pascal program to read a sequence of integers from a text file (named integers.txt) and to print them out in two different ways. Each integer should be printed out in a field of width eight. Use an array to hold the integers. (i) Write the main program which reads up to 100 integers (each of which is on a separate line) terminated by end of file. Indicate where the two output procedures of (ii) and (iii) below have to be declared and called in the main program. (ii) Write a procedure row_order which outputs the integers input in (i). Commence the output with the heading ROW ORDER, underlined by a sequence of minus signs, and then output the integers in rows across the page, ten per row. Output the first ten integers in the first row, the next ten integers in the second row, and so on. The final row may be partially filled. (iii ) Write a procedure column_order which outputs the integers input in (i). Commence the output with the heading COLUMN ORDER, underlined by a sequence of minus signs, and then output the integers in columns down the page, ten per column. Arrange the output so that on completion the first ten integers will appear in the first column, the next ten integers in the second column, and so on. In this case you may assume that there are exactly 100 integers input. 45. A string variable str is to be printed out left justified in a field of width 20 characters Assuming that str will always contain strings of 20 characters or less, show how this can be achieved. 46. Look again at the practical Credit Analysis. Write a program that will print out for each customer his name, the total value of unpaid orders and the total value of all his orders. The input file has the same format except that we can detect the end of file (there is no explicit 'end' marker'). Assume that there will be no more than 100 customers. You will need to set up three arrays: name: ARRAY[1..100] OF STRING; { for the names} paid: ARRAY[1..100] OF CHAR; {to show if the order has been paid} value: ARRAY[1..100] OF REAL; {the values of the orders} The output should look like: NAME UNPAID TOTAL smith jones atkinson 185.28 42.75 0.00 414.99 42.75 464.46 47. Write a function which, given a temperature in degrees Centigrade will return the same temperature in degrees Fahrenheit. Assume both temperatures are real numbers. 48. Write a function which returns the length of the hypotenuse (c) of a right angled triangle given the lengths of the two other sides (a and b): c2 = a 2 + b 2 24 CS_PAS 1999/2000 COURSE MANUAL 49. KAREL is seized with a sudden desire to know whether the world he lives in is square. Write a function which will return TRUE if it is, and FALSE otherwise: FUNCTION square : BOOLEAN; You can assume that there are no internal walls. It doesn't matter where he ends up. 50. Look at the program scope11.dpr. What would be the output if n were declared as a variable parameter in: PROCEDURE proc_eleven(VAR n:INTEGER) 51. Find an alternative solution to Practical Problem 8(b) - the Treasure Hunt, using a two-dimensional array of integers to record the number of beepers on each Point; then examine that array to determine which Point contains the maximum number of beepers. 25 CS_PAS 1999/2000 COURSE MANUAL Practical Exercises 1. KAREL Goes Shopping On the way home from the supermarket, KAREL's shopping bag gets ripped slightly at the bottom, leaking a few expensive items. These groceries are represented by beepers. The initial situation, when KAREL discovered the leak, is represented in Figure 2-7(a). Program KAREL to pick up all the dropped items, line them up along the eastern wall of his house, as shown in Figure 2-7(b) and then return to his starting position. The world to use is shopping. 2. Harvesting These problems have all to do with picking up and putting down beepers which are contained within a rectangular area. KAREL always starts off outside this area, facing towards the bottom left hand Point, one block from it. His exact task, and the starting state of the 'field' will vary from problem to problem. Test each program on the sample world given, but note that it should work in any world which conforms with the given specification. 26 CS_PAS 1999/2000 COURSE MANUAL (a) KAREL's initial situation is shown in Figure 3.2 (harvest). His task is to end up with all the beepers in his bag - see Figure 3.2(b). (b) Some of the beepers are missing - as in Figure 4.1 (harvestm). Again, his task is to end up with all the beepers in his bag. (c) The world is the same as for part (b), but his task is to pick up the beepers that are there, and to put down beeper on the Points where there aren't any. You can assume that he starts with a large number of beepers in his bag. (d) There may be zero, one or two beepers on each Point - see Figure 4.3(a) (harveste). KAREL's task is to leave the field with exactly one beeper on each Point (so that it looks like Figure 3.2). (e) On any Point there can be any number (zero, one or more ) of beepers; see Figure 4.10 (harvestu). KAREL's task - as in parts (a) and (b) - is to remove all of the beepers. (f) This task is identical to that of part (e) except that there are internal walls. These may be horizontal or vertical and are guaranteed only to be one block long. In principle they can be between any two adjacent Points, but in fact it is the case that no two internal walls touch each other in any way. Modify your program so that KAREL can still harvest the field. Hint: Given that the walls are only one block long and don't touch, you know that you can always go round them - so write a procedure to do just that. Test your program in harvestw, shown in Figure 4.11. 27 CS_PAS 1999/2000 COURSE MANUAL 3. Diamond Shaped Field Figure 3-4 illustrates an odd-shaped field of beepers. Write a program that harvests all these beepers. The world to use is diamond. Hint: this task is not too different from the harvesting example. If you see the correspondence between these two harvesting tasks, you should be able to develop a program for this task that is similar to the original harvesting program. 4. Say 'HELLO' KAREL wants to send his greetings to the other inhabitants of his universe, so he needs to plant a field of beepers that broadcasts his message to alien astronomers. Program KAREL to plant the message of beepers shown in Figure 3-5. OK ... you have to construct the rest of the HELLO. KAREL's start position is (2,3) facing north; he has 51 beepers in his bag and there are no beepers set out (hello). His final position is up to you. 5. Wall-Hugging and Mazes (a) Write an procedure named follow_wall_right, assuming that whenever KAREL executes this instruction there is a wall directly to his right. Figure 4-5 shows all four of the different position changes that he must be able to make (i.e. from the position in (a) to the position in (b). The effect of repeatedly executing this procedure will be to make KAREL 'hug' (i.e. stay in contact with) the righthand wall of any world he is put in - assuming that there is initially a wall to his right. 28 CS_PAS 1999/2000 COURSE MANUAL (b) Using this procedure write a program to enable KAREL to find a beeper in a maze that contains no islands. This task can be accomplished for this kind of maze by commanding KAREL to move through it with his right side always next to a wall as discussed above. The figure below shows one example of such a maze; it is found in maze1. A different example is in maze2. (c) As an interesting side issue, consider the worlds shown in Figures 5.10 and 5.11 - found in hurdles1 and hurdles2 respectively. The objective is to get to the beeper by 'jumping' the 'hurdles' - which get progressively more complex. You can see the solutions to these as progressive refinements to the 'hurdling' problem discussed in PATTIS in section 4.4 and the problem on page 59. By this I mean that one would write procedures to 'jump up' and 'jump down' with a procedure to 'go along the top' for Figure 5.11. However if you change your point of view, you can look at these as being solved by the 'right wall hugging' algorithm you have just developed. Try your program in these worlds. Does it work? If not, why not. 29 CS_PAS 1999/2000 COURSE MANUAL (d) Not all mazes are easily amenable to 'wall hugging'. The figure below shows one which isn't. The class of mazes of which this is a member can be described as follows: KAREL is in a world in which there are horizontal internal walls. Walls can be of any length up to 29 blocks and may or may not join an external wall. KAREL is placed somewhere in the world. His direction is not specified, nor do we know if he is next to a wall. His task is to get to the Point (30,20) and to turn himself off when he gets there. Test your program on maze3 (which is not the world shown in the figure). 30 CS_PAS 1999/2000 COURSE MANUAL 6. Follow the Path KAREL is put at one "end" of a path of beepers - an example world is shown below in Figure 5.12 contained in path1. The other end is marked by a pile of two beepers. There are no forks in the path i.e. any beeper is adjacent to two and only two beepers (apart from the ends of the path). KAREL's task is to get to the other end. There are no internal walls. You can chose whether or not to leave the beepers behind. A different test world is path2. 7. Escape KAREL is in a room composed of internal walls. The door is one block wide. See, for example, Figure 5.4 above. KAREL's task is to escape. We don't know where he starts (inside the room), nor which way he is facing, nor the size of the room, nor the location of the door. We know that there are no other internal walls. KAREL is carrying a large number of beepers which he can put down if he wants - this may or may not be useful. room1 contains the world shown above. Other suitable worlds are room2, room3 and room4. 31 CS_PAS 1999/2000 COURSE MANUAL 8. Treasure Hunts (a) KAREL is sent on a treasure hunt. He starts on a Point with a number of beepers. He counts them by picking them up and putting them in his beeper bag. The number of beepers picked up, when considered as a two digit integer between 01 and 39, determines where he is to go next. If the first digit is 0 he goes north; if it is 1 he goes east, if 2, south, and if 3, west. The second digit tells him how many blocks to move. Thus if he is on a Point with 25 beepers, he should go south 5 blocks. If he ends up on a Point which has beepers on it, he repeats this process. If the Point has no beepers then he has reached the treasure and should turn himself off (and start digging!). If he encounters any walls, he should turn through 180° and carry on until he has moved the required number of blocks. Consider the example world. In case you can't read it, the numbers of beepers are: Point Number (3,2) (7,2) (7,5) (4,5) 14 25 33 2 KAREL starts on Point (3,2) - although for the sake of clarity I haven't shown him. He finds 14 beepers - this means 'go east (1) 4 blocks'. He ends up on (7,2). Here there are 25 beepers. This means 'go south 5 blocks'. He tries to do this but after one block meets a wall. He turns around and goes north 4 blocks (the 5 he has to go, less the one already gone). He ends up on Point (7,5); the beepers there get him to (4,5) where he finds 2 beepers. The first digit is (implicitly) 0 so he goes north 2 blocks. to Point (4,7). There are no beepers on that Point, so he has found the treasure. Note that in order to solve this problem you need to recognise that if n is a variable containing the number of beepers on a corner, then n div 10 will give the 'tens' part of that number (the first digit); for example 14 div 10 is equal to 1. n mod 10 will give the 'units' part (or second digit); so 14 mod 10 is equal to 4. Write a program to solve this task and test it in treasur1 and treasur2. (b) KAREL goes on a different kind of Treasure Hunt. On some Points (but not all) there are piles of one or more beepers. In part (a) the beepers were signposts to the treasure; this time the beepers are the treasure. KAREL's task is to find the Point with the largest number of beepers on it, and to return to that Point and turn himself off (presumably with a satisfied smile on his face). We are not told where KAREL starts, nor which way he is facing. There are no internal walls. In order to count the beepers he will need to pick up them up, but when he leaves the Point, the pile should be as he found it. By way of example, in the world shown KAREL should turn himself off on Point (7,5). Note that this time, KAREL has no information as to where the beepers are, and will have to search his entire world in a systematic manner. He will need to examine each Point, if there is a pile there to count it, to remember which is the largest pile and where it is, and finally to return to the largest. Try out your program in treasur3 and in treasur4. 32 CS_PAS 1999/2000 COURSE MANUAL 9. Criss-Cross KAREL is put somewhere on a cross. The cross is composed of one vertical line of beepers and one horizontal line. A sample world is given above. His task is to get to the centre of the cross i.e. the point where there are beepers on all four sides of him. He must leave the cross the way he found it - with all beepers in their original positions. There are no internal walls, and you can assume that KAREL will always be far enough away from any external wall that you needn't bother about it. (a) Assume that he is placed at the end of one of the arms (you don't know which) facing towards the centre; try world cross1. (b) Assume that he may be placed anywhere on the cross, facing in any direction; try world cross2. 10. Fair Shares (a) KAREL is presented with a row of piles of beepers. For example in the world shown below, there are four beepers on the first Point of the row, two on the second, five on the third , and one on the fourth. There are internal vertical walls at each end of the row, but no other internal walls. KAREL is on the first Point (i.e. the most westerly) of the row, facing east; he isn't shown for the sake of clarity. His task is to distribute the beepers evenly over the four Points in the row; thus in the example given, he would end up with three beepers on each Point in the row. You can assume that there are exactly enough beepers on the Points to achieve this. KAREL starts with no beepers in his bag. fair1 provides a test world. b) This is the same task as the one above but with the following complication - the internal walls have been removed. However you can assume that there are no gaps in the row i.e. that when KAREL discovers a Point without any beepers, he has come to the end of the row. fair2 provides a test world. 11. Rectangles All of the tasks in this exercise are concerned with rectangles of beepers - this also includes squares. In all cases, KAREL starts facing east at the bottom left-hand corner of the rectangle - as shown in Figure 8.1. We don't know the dimensions of the rectangle. You can make the following assumptions: • KAREL starts with a large number of beepers in his bag; if he needs more beepers than he picks up, he will have them. • his initial position and the size of the rectangles are such that he never risks bumping into an external wall; there are no internal walls. • the length of a side of a rectangle is defined as the number of blocks that it covers - not the number of beepers along it; thus the rectangle in Figure 8.1 is four blocks by three blocks. 33 CS_PAS 1999/2000 COURSE MANUAL (a) KAREL's task is to pick up all the beepers in the rectangle, ending up where he started, facing the same way. (b) The task is to move the rectangle and to set it out again exactly as it was before. The new location will be specified relative to the original location; the relative movement will be specified by the user and KAREL must ask for this information. Thus the following dialogue would lead to KAREL laying out a 4x3 rectangle to the north-east of Point (7,6). How far to move in X? 4 How far to move in Y? 3 KAREL will need to measure and remember the dimensions of the rectangle in appropriate variables. (c) This is almost the same as the previous task, except that in the replaced rectangle, the width should become the height, and vice versa. (d) As before he has to set out a new rectangle. The size and shape of this rectangle should be determined as follows: • If it is possible to plot a square which has the same area as the original rectangle, then he should do so. Hint: use a conditional loop to work out the areas of squares of side length 1, 2, 3, ... and stop when the area is the same as or greater than the area you are looking for. • Otherwise, if it is possible to plot a square with the same perimeter as the original rectangle, then he should do so; • Otherwise he should plot a rectangle with the same perimeter as the original one, but with a different shape. Test your solution on rect1, rect2 and rect3. Complications You can make the problem more complex as follows: (i) Occasionally a unkind programmer plays a trick on KAREL, and puts him in the kind of world shown in Figure 8.1(a) where the beepers form four lines at right angles but the lines don't join up to make a rectangle. However, you can assume that even if the lines don't make a rectangle, 34 CS_PAS 1999/2000 COURSE MANUAL they will be at right angles in an anti-clockwise sense as shown in Figure 8.1(a). If KAREL isn't on a closed rectangle, he should turn himself off. Hint: compare the lengths of opposite sides. Try world rect4. (ii) KAREL starts somewhere along one of the sides of the rectangle - but he doesn't know which one or how far along. The displacement of the rectangle is relative to its south-west corner, so you will have to determine where that is. 12. Sorting KAREL has to sort piles of beepers. He finds himself in a world like that shown in Figure 8.2. His task is to move the piles of beepers around to achieve the situation shown in Figure 8.3 where the piles are in ascending order of height. His starting position is at the base of the rightmost pile facing west, and you can assume that the piles are always at the bottom left hand corner of his world as shown. However he doesn't know how many piles there are, nor how many beepers there are in each. It doesn't matter where he ends up. One possible algorithm to use is a bubble sort. If we refer to a pile by its X co-ordinate and if there are n piles, then the algorithm is: for i := 2 to n do for j := n downto i do if the pile on j is less than the pile on (j-1) then swap the two piles For example, if n=4, we can show the numbers in each pile at the end of each iteration (and the corresponding values of i and j): Position i j 1 2 3 4 2 2 2 3 3 4 4 3 2 4 3 4 7 7 7 2 2 2 2 3 3 2 7 7 3 3 5 2 3 3 3 7 5 2 5 5 5 5 5 7 Start 35 CS_PAS 1999/2000 COURSE MANUAL See how the lower number 'bubbles' down towards the correct end. How would you sort in descending order? If you choose SORTING in the Computing Science folder, you can see this program in operation. Write your own code, and demonstrate its operation on sort1 (as shown overleaf) and sort2. This isn't the only way to sort, but bubble sort is a very popular method. There are more efficient way of doing the sort but this implementation shows clearly what is going on. If you already know about ARRAYS, you might like to modify this solution to store the sizes of the piles in an array, and sort its contents. 13. KAREL Draws a Line A straight line can be defined by the equation y = ax + b. Write a program which will prompt the user to enter the two coefficients (a and b), and then get KAREL to plot the line by putting beepers down on the appropriate Points for all values of x between 1 and 30 inclusive. If any value of y is outside his world, then he should recognise this, and not try to plot the point. We don't know where KAREL starts, nor which way he is facing. He has enough beepers to complete any line we ask him to plot. There are no internal walls. As an example this is the plot of the line: y = 2x - 5. 36 CS_PAS 1999/2000 COURSE MANUAL 14. Find the Top KAREL goes mountain climbing. He starts at Point (1,1) facing east and is faced with a range of mountains. At the far end of the range is a beeper. His task is to climb over the mountains to get the beeper. As he crosses them, he should find the highest point. Once he has collected the beeper, he should climb back to that highest point, plant the beeper there and turn himself off. 15. Plotting In all of these exercises you should use the procedures: procedure DrawAxes(x_max, y_max: REAL) puts X and Y axes on the screen; x_max and y_max specify the maximum x and y values that are to be plotted. procedure PlotPoint(x,y: REAL) plots a single point with the given co-ordinate system. function ExitClicked: BOOLEAN returns FALSE until the user clicks Exit on the menu - at which point it returns TRUE. Note that the parameters to these procedures should be actual values in the real world (meters). DrawAxes works out the necessary transformations from the real world co-ordinates to screen coordinates, and they are remembered within the unit for use when PlotPoint is called. Use ExitClicked in a loop at the end of your program to give you a chance to see the results: REPEAT {do nothing} UNTIL ExitClicked To access these procedures and functions you need: USES csPlot; 37 CS_PAS 1999/2000 COURSE MANUAL Remember the facilities for interacting with the user (which were described earlier): procedure DisplayStringToUser(MessageString:String) function GetStringFromUser(Question:String): String function GetIntegerFromUser(Question:String): Integer function GetRealFromUser(Question:String): Real (a) Sine Waves Draw the function: y =10 (sin + 1) where goes from 0 to 360 degrees (2radians (b) Circles Write a program that prompts the user for the centre and radius of a circle, and then plots a sequence of points to form that circle on the screen in a co-ordinate system in which both x and y go from 0 to 100. If any point falls outside the range 0 to 100 (in either x or y), then don't plot it. If is an angle measured clockwise from the horizontal, the radius of the circle is R, and its centre is the point (x0, y0), then all points with co-ordinates (x0 + R cos y0- R sinlie on the circle. Make up the circle from (say) 1000 points at equi-spaced increments of between 0 and 2 You might also like to try to think of another way of solving the problem using equal increments of x. (c) Modulated Sine Wave Write a program that plots the function: y = 10 (sin + 1) (1 - 1/ e /1000 ) (where is expressed in degrees over the range 0 1000. 16. Golf You will need to include USES csPlot, IO; (a) The objective is to develop a very simple golf-playing program which plots the flight of a golf ball on the screen. Firstly, here's some necessary physics. We'll work in a standard co-ordinate system with the origin (0,0) in the bottom left hand corner. The golf ball is launched from the origin. Assuming that there is no air resistance, the equations of motion are: x = vx t y = vy t - 1/ g 2 t2 vx is the initial X component of the velocity given to the ball vy is the initial Y component of the velocity given to the ball g is the acceleration due to gravity (9.81 m/s2). These initial values of vx and vy are given by: vx = v cos vy = v sin 38 CS_PAS 1999/2000 COURSE MANUAL Where v is the magnitude of the initial velocity, and is the angle that the initial trajectory makes with respect to the horizontal Let us take it that the maximum length of a stroke is 250 m. and that a golf ball never rises above 50 m. - use these as values for x_max and y_max. You are going to read in the values of angle () and velocity (v) from the user, and plot the resulting trajectory by repeated calls to PlotPoint . To simulate the motion of the ball you will need to work out, and plot the position of the ball at equal closely spaced time intervals, t. We'll use a constant for this; 0.01 seconds is a good choice. CONST time_step = 0.01 If the ball is moving with a velocity of vx in the horizontal direction and with a vertical velocity of vy , then the ball's new position at the end of the time step can be calculated from its old position by using the formulae: x = xold + t vx y = yold + t vy Gravity will affect the ball's movement, so you will need to declare a constant g = 9.81 and decrease the vertical velocity of the ball by t g each timestep. Thus: vy = vyold - t g Now, we don't know how far the ball will go, so we simulate until it hits the ground, i.e. y=0 . However, remember that checking that a real number is exactly equal to 0.0 is undesirable, so we check for y going negative. We shouldn't plot this negative value, nor indeed any point which is outside the range, so before plotting any point we need to check that: 0 x xmax and 0 y ymax The algorithm looks like this: plot the axes ask the user to type in the velocity ask the user to type in the angle calculate the initial values of the x and y velocities set the values of x and y to 0 draw the ball at (x,y) repeat copy x to xold (likewise for y) work out the new x and y at the end of the time step if x is in range and y is in range then draw the ball at (x,y) update the y velocity until y < 0 wait until Exit is clicked How do we get the input from the user? Assuming that v and theta have been declared as real variables, you would have something like: v:=GetRealFromUser('Enter the velocity in m/sec’); People think more naturally in degrees rather than radians (well at least I do), so it makes sense to ask for the angle in degrees. However sin and cos need the angle in radians - the program will have to perform the conversion: 1 radian = 57.2958. 39 CS_PAS 1999/2000 COURSE MANUAL Once you've written your program, test it with a range of velocities and angles. Try velocities between 10 and 70 m/s, and angles between 15 and 60. If you think that your program is in an infinite loop, try choosing Exit from the menu bar. Depending on the exact circumstances it may get you out. Otherwise you will have to restart the computer. (b) You could try to modify your program to allow for the effect of air resistance. One way to do this would be to reduce the velocity by a very small percentage every time step. (c) The aim now is to take the previous program and turn it into a little game. Implementing this program in full will take some time. You might try to implement only part of the specification. If you choose GOLF from the Computing Science Menu, you can see the complete program in operation. Suppose that we are playing a round of golf with four clubs in our bag. These are a driver, a four iron, a wedge, and a putter. The choice of club determines: (i) the angle at which the ball is struck; (ii) the range of velocities available, according to the following table (any serious golfers are requested not to be put off at this point by any gross error or simplification!): Club Code Angle in degrees Minimum velocity (m/s) Maximum velocity (m/s) 1 2 3 4 15 40 60 0 44 22 11 - 70 32 24 - Driver Four Iron Wedge Putter When the program starts the length of the hole is set; assuming that length is a real variable: length := 100 + 350 * Random The real function Random returns a real number randomly chosen between 0 and 1. Set x_max to be 1.2*length. Any ball landing beyond x_max is out of bounds. If you land in bounds but beyond x_max, the next shot should be played back towards the hole. The user is then asked what club is to be used and replies with one of the codes 1 to 4 as above. A putter may only be selected if the ball is on the green (i.e. within 10 meters of the hole), and in this situation, this is the only club that may be selected. Any putt made within 2 meters of the hole is regarded as being sunk. It takes two putts to hole out from anywhere else on the green. Any further away and you can't use your putter. A driver may only be selected for the first shot. The user is then asked what velocity is to be given to the ball (unless the club selected is the putter); the result needs to be checked against the ranges given in the table, and the question asked again until a satisfactory reply is received. The first trajectory of the ball is plotted, starting from (0,0) and a record is kept of where it lands. The equation of motion for y is the same as before. For x it is: x(t) = x_start + v cos t The dialogue is repeated, and the second stroke is plotted from the place where the first one landed. A running total is kept of the number of strokes taken. If a putter is chosen then one stroke is added if the hole is less than 2 metres away, and two strokes if less than 10 metres. The aim (as with real golf) is to get the ball in the hole with as few strokes as possible. The algorithm look like this: work out length of hole 40 CS_PAS 1999/2000 COURSE MANUAL plot axes set stroke count to zero set x_start to zero repeat increment stroke count ask user for club and check that it is OK if putter then ball in hole if outside one putt range then increase stroke count by another one else ask user for velocity and check that it is OK get the angle for the chosen club if x_start > length then reverse the direction of the shot plot the trajectory from x_start and get x_final if x_final > xmax then out of bounds else x_start becomes x_final until ball in hole or ball out of bounds if ball in hole then tell the user the number of shots else tell the user that the ball is out of bounds wait until Exit is clicked To tell the user how many strokes (s)he has taken or that s(he) is out of bounds: DisplayStringToUser('Number of strokes is ' + IntToStr(stroke_count); DisplayStringToUser('Sorry - out of bounds'); IntToStr is a built-in function that converts an integer to its representation as a string; remember to include SysUtils in your USES. The ‘+’ in the first DisplayStringToUser joins the two strings together. You can use the following procedure from csPlot: PlaceFlag(x:REAL) This does what it says - plots a flag at the x position given by the parameter x. 41 CS_PAS 1999/2000 COURSE MANUAL 17. Digital and Analogue Clocks This exercise is concerned with producing graphical clock displays, either digital or analogue. The aim is to display the current time (in hours, minutes and seconds) and to the display every second. It will help if you run the programs CLOCKS in the Computing Science folder. You will need to include csClocks and Graphics in your USES. Digital Clock This is based on the standard seven-segment display used in digital watches and clocks to display a digit. Our clock has six digits. Digits one and two display the hour, digits three and four display the minutes and digits five and six show the seconds. So, for example, the time of 02:35 and 18 seconds would be displayed as Digit number: 1 2 3 4 5 6 The individual segments are numbered as follows: 1 2 6 7 5 3 4 On the screen, individual he segments can be lit using the procedure: Light(position, segment:INTEGER) The input parameter position determines which digit on the screen is to be affected and should be in the range 1 to 6. The input parameter segment determines which segment is to be lit up; it must be in the range 1 to 7. There is no way to delete individual segments. Instead, individual digits can be deleted from the screen by using the procedure DeleteDigit(position:INTEGER) where position is a number from 1 to 6. The current time is to be obtained using the functions Hour: INTEGER Minute:INTEGER Second:INTEGER which return the current hour (in 24-hour clock time), minute and second, respectively. 42 CS_PAS 1999/2000 COURSE MANUAL NB: Before the procedures described above may be used, you must call the procedure InitialiseDigital at the beginning of your program. This also draws the dots which appear between the hours and minutes, and between the minutes and seconds. You need to be able to know when it is time to update your display (i.e. when the end of the current second is up). One way to do this is to compare the value of seconds with the last value read; as soon as they are different then update. So assuming you have the last value of the seconds in a variable called sec then you could have the loop: REPEAT {do nothing} UNTIL sec <> Second The whole program should be in a loop which continues until ExitClicked is TRUE One question that you will have to consider in your design, is how often to update the minutes and hours in your display. Analogue Clock The idea here is to create a standard clock-face showing the current hour (in 12-hour clock time), minute and second (updated every second). The procedure InitialiseAnalogue should be used at the beginning of your program rather than InitialiseDigital. This will draw a clock-face without hands (i.e. a circle with surrounding numbers from 1 to 12) in the middle of the screen as well as initialising certain features you will use. The basic approach is the same as for the digital clock, but instead of updating digits on the screen, you need to update the hands of the clock. In order to do this, you will need to use the procedure: DrawHand(length, angle:REAL) The constant ClockRadius, also defined in the csClock, is to be used for the length of the second and minute hands, whilst the hour hand should be a bit shorter - perhaps about two-thirds of that length. The angle to be used with DrawHand should be in radians (remember that 360° is equal to 2*pi radians) measured clockwise (!) from the vertical. To get the angles required to point the hands at the correct numbers on the clock, use the following formulae: hours_angle :=2*pi*hrs/12; minutes_angle:=2*pi*min/60; seconds_angle:=2*pi*sec/60; Each hand should be a separate colour; this is achieved by using the predefined procedure SetColor(color:integer) (note the American spelling) where color is one of the following predefined constants: clBlack clRed clYellow clBlue clSilver clAqua clLime clFuchsia clWhite SetColor should be called each time a different hand is drawn. Deletion of a hand (or hands) at a given angle is achieved by calling: SetColour(black) DrawHand(length, angle) 43 CS_PAS 1999/2000 COURSE MANUAL 18. Credit Analysis Your task is to write a simple credit analysis program for a small company. They keep a file of orders that have been placed; for each order they record: • • • • the name of the customer (as a string); whether the order has been paid (as a single character - y or n); the number of items in the order, assuming that the order is all for the same item (as an integer); the unit cost of each item (as a real number in pounds). Each piece of information is recorded on a separate line. For example, an order from smith for 5 items at £5.67 each which has been paid would look like: smith y 5 5.67 The file consists of a number of orders. The end of the file is marked by the single string end in place of the name. For example: smith y 12 5.60 jones n 3 7.80 atkinson y 23 1.07 smith y 34 2.78 smith n 32 5.79 atkinson y 5 87.97 jones n 43 0.45 smith y 13 5.23 end Your program should do the following: i) Prompt the user for the name of the customer whose credit status we want to analyse, and read in this name. ii) For each order placed by this customer, write out on a single line: • the word paid if the order has been paid and unpaid otherwise; • the number of items in the order; • the unit cost; • the value of the order. iii) Write out • the total value of the unpaid orders for this customer; • what this represents as a percentage of the value of all of his/her orders (both paid and unpaid); • what it represents as a percentage of the value of all unpaid orders from all customers. Here's an example of the interaction for the given data: 44 CS_PAS 1999/2000 COURSE MANUAL Whose account do you want to look at? smith Orders for smith Status Quantity Unit Cost Order Value paid paid unpaid paid 12 34 32 13 5.60 2.78 5.79 5.23 67.20 94.52 185.28 67.99 The total value of unpaid orders from smith is 185.28 This represents 45% of the total orders he has placed. This represents 81% of the total of unpaid orders. Hit <RETURN> to exit You should generate the headings and layout as shown above. The percentages should be rounded to the nearest integer. The last line is needed so that you have time to look at the output. The code is: WRITELN('Hit <RETURN> to exit'); REPEAT UNTIL KeyPressed You will need to include USES WinCrt; Besides making it possible to write to and read from a text window, WinCrt provides one function and one procedure which are useful: function KeyPressed: Boolean procedure DoneWinCrt returns true when <RETURN> is pressed closes down the text window You will also need to chose Projects|Options and click the Linker tab. Then check the box beside Generate console application Initially it is a good idea to write your program so that it takes the input data from the keyboard. This will lead to a somewhat confused presentation on the screen, but will give you more control over what is going on. Then modify your program so that it takes input from a data file. There are two files available, their full path names are: contains the data given above is longer. L:\delphi\data\orders_1.txt L:\delphi\data\orders_2.txt To open a file for reading you need to include, at the start of your program: VAR data : TEXT; ... AssignFile(data, 'L:\delphi\data\orders_1.txt'); Reset(data); Except at the beginning where you read in the name of the customer we are interested in, all subsequent calls to READLN should refer to this file: READLN(data, ...) 45 CS_PAS 1999/2000 COURSE MANUAL If you have time, think carefully about the different kinds of error which could arise and implement ways of trapping and dealing with them. 19. Heights A file L:\delphi\data\heights.txt contains the names of individuals and their heights in meters. There is one data item per line - a name, a height, a name, a height, etc. An example file would be: James 1.79 Freda 1.56 Hugh 1.89 Alison 1.65 Elaine 1.67 Martin 1.90 Lucy 1.45 The program should print out the average height, and the name of everyone who is more than 20 cm away from the average. For the above data this would be: The average is 1.70 Freda Hugh Lucy 20. Birthdays The exercise is concerned with a group of people, their ages and their birthdays. The basic data is contained in a file which contains: • • • the name of the person (as a string) the day and month of their birthday (as a string) the year of their birth (as an integer) Each piece of information is recorded on a separate line. For example the entry for Dave would look like: Dave 13 July 1953 The file consists of this data on a number of individuals; for example: 46 CS_PAS 1999/2000 Dave 13 July 1953 Sarah 24 June 1967 Tom 2 December 1959 COURSE MANUAL Mike 10 March 1966 Anne 24 June 1945 Fred 16 August 1957 (a) Your program should do the following: 1. Read the names, birthdays, and years of birth from the file into separate arrays. 2. Prompt the user for the name of an individual and read in his/her name. 3. If the name isn't in the file then print out an appropriate message, otherwise do the following: Print out the full date of birth (including year) of the individual. If there is anyone in the file who shares the same birthday as the individual (day and month but not necessarily the year) then say so. Print out how many people in the file are younger than that individual; younger means that they were born in a later year - don't try to look at birthdays to see if they were born later in the same year - just say that such a person is not younger. 4. Repeat steps 2 and 3 until the user enters end to the prompt in step 2. Thus given the file above, one might have the following interaction (user input in italics): Enter a name: Dave Dave was born on 13 July 1953 4 people are younger than Dave Enter a name: Jack Jack is not in the file Enter a name: Anne Anne was born on 24 June 1945 Anne has the same birthday as Sarah 0 people are younger than Anne Enter a name: end Here is some outline pseudo-code to help you get started: read the data from the file into three arrays {one for the names, one for the birthday and one for the year} REPEAT get the chosen name IF the name isn't 'end' THEN go through the array of names looking for the chosen name IF you find it THEN write out the birthday go through the array of names build up the total of those that are younger IF you find someone with the same birthday THEN write an appropriate message IF you haven't found the chosen name THEN 47 CS_PAS 1999/2000 COURSE MANUAL write out an appropriate message UNTIL the name is 'end' Test data is available at the start in a file L:\delphi\data\birthday.txt (b) If two people share the same birthday, work out and report the 'probability of this happening. The probability that two people in a group of n have the same birthday is: 365 364 363 365 - n + 1 p(n) = 1 - 365 365 365 365 So you would report: The probability of this happening in a group of 6 people is 0.04 21. Rates of Exchange The file L:\delphi\data\rates.txt contains information which allows the conversion of different currencies to pounds sterling. The file consists of a sequence of pairs of lines. The first line contains the name of the currency as a string of characters, the second contains the amount of that currency that is equivalent to one pound sterling (i.e. the rate) as a real number. Thus the first two lines might be: dollar 1.48 which means that there are 1.48 dollars to the pound. Assume that the file will contain data on no more than 20 currencies (but the number might be less than 20). Write a program which reads in the conversion data and conducts an interactive dialogue to ask the user for the name of a currency and an amount, and prints out the corresponding amount in sterling. The program should continue to prompt for a currency and amount until the user types the string end. 48 CS_PAS 1999/2000 COURSE MANUAL 22. Possible Routes An airline operates flights between pairs of cities as shown in the diagram below. The arrows indicate the directions of the flights - just because there is a flight from Paris to London, does not mean that there is a flight from London to Paris. London Amsterdam Paris Rome Berlin Madrid Cairo Lagos The information on origin/destination pairs is held in a text file (L:\delphi\data\routes.txt) with the name of each city on a separate line. Of each pair, the first is the origin and the second is the destination. The data represented in the above diagram would be coded in the file as follows: Paris London Paris Lagos Lagos Paris Lagos Madrid Lagos Cairo Madrid London Madrid Rome Cairo Lagos Cairo Berlin London Madrid London Amsterdam Amsterdam Rome Amsterdam Berlin Rome Amsterdam Rome Cairo Berlin Cairo Your task is to write a program which will: • • • obtain from the user the name of an initial origin; obtain the name of a final destination; if there is a direct connection between the initial origin and the final destination then inform the user; 49 CS_PAS • • • 1999/2000 COURSE MANUAL otherwise tell the user of all possible ways of getting from the origin to the destination with only one intermediate stop; note that there may be no such routes; if the user types in the names of cities which are not recognised, or if there are no routes, the program is not required to take any action; the program finishes when the user types none as the reply to the first question. Thus a possible dialogue might be: What is the initial origin? Amsterdam What is the final destination? Berlin Direct flight What is the initial origin? Lagos What is the final destination? Rome Connection via Madrid What is the initial origin? Paris What is the final destination? Madrid Connection via London Connection via Lagos What is the initial origin? Amsterdam What is the final destination? London What is the initial origin? none Think how you would extend your program to find routes with any number of intermediate stops - this is not easy! 23. Barkings Bank Barkings Bank has been concerned that it doesn't exercise sufficient control over its staff who trade in shares. It wants to set up a computer system which will monitor their performance on a daily basis. Let us follow the activities of a given trader (let's call him Nick) during a typical day. He starts the day holding different numbers of different shares. The value of these shares is determined by the number he holds and the price per share at the end of the previous day. He also has a certain amount of cash which he can use to buy and sell shares. During the day he trades, buying and selling quantities of shares at the price prevailing at the time; if he buys he uses his cash to pay for them - if he sells, what he gets is added to his cash reserve. At the end of the day he enters the prices quoted on the exchange for each of his shares. Note that this 'end of trading' price will not necessarily be that at which he traded the shares during the day, nor indeed their valuation at the end of the previous day. If the value of his shares at the end of the day plus the cash he holds at that time is greater than the sum of the value and cash at the beginning of the day, then Nick has made a profit. If not, he'd better take the next plane out! The program you are to write works as follows: At the beginning of the trading day, when the program is started, it reads in from a text file the position at the end of the previous days trading. An example of such a file is shown below: Value 7500.00 Cash 2500.00 BT 1000 Thorn 2000 Boots 500 50 CS_PAS 1999/2000 COURSE MANUAL The fist line always consists of the string Value followed on the next line by a real number which is the value of his share holdings as calculated at the end of the previous day's trading. The third line is always the string Cash followed on the next line by his cash holding (a real) also at the end of the previous day. Next are a series of pairs of lines: the first is the name of the share (a string) and the second is the number of those shares held at the close of trading (an integer). Note that he never trades in more than 50 different shares. The program now prompts Nick for a series of transactions which are entered at the keyboard. Firstly he is prompted to enter the type of the transaction, which can have of one of three values. If he enters end this means that trading has finished for the day, and there are no more transactions. If he enters buy or sell then the program should prompt for three more entries: the name of the share (a string), the number of shares bought or sold (an integer), the price at which they were bought or sold. For example the transactions on a (very!) light day might be: Enter transactions: Type of transaction: buy Share: BT Quantity: 200 Price: 2.25 Type of transaction: sell Share: Thorn Quantity: 500 Price: 2.00 Type of transaction: end When trading is over, the program should prompt Nick for the 'end of trading' prices for each of his shares. It then works out the total value of his holdings, and tells him if he has made a profit or loss and of how much. An example of such an interaction is: Enter share prices at the end of trading: BT : 1.25 Thorn : 2.1 Boots : 2.2 You made a loss of 1200.00 Finally the program writes out a new file showing his position at the end of that day - this will be used as the input file the following day, and has exactly the format described above. The file written following the previous example would be: Value 5750.00 Cash 3050.00 BT 1200 Thorn 1500 Boots 500 Your program should read the data for the previous day's trading from a file called: L:\delphi\data\sthold.txt 51 CS_PAS 1999/2000 COURSE MANUAL which refers to a file containing test data (not that used in the example above). Your program should write out the position at the end of trading to a file on your floppy disc. You should call the file endhold.txt, so you will need to use statements like: AssignFile(end_holdings, 'endhold.txt'); Rewrite(end_holdings); Carry out a test run of your program on the data given in sthold.txt. You should enter several transactions before entering the prices at the end of trading. Suitable values for these are: Barclays BT Dixons GEC Granada Guinness ICI Manweb MFI Stagecoach 6.03 3.62 2.09 2.93 4.94 4.21 2.51 5.91 1.25 2.36 You should print out the contents of endhold.txt (as well as your program listing) and hand both in with your floppy disc. You could extend your program to: • • • • allow the user to tell the program that he is dealing in a new share. This will have a transaction type of new (and implies buying); delete any share if the user's holding falls to zero in it; incorporate suitable error checking (e.g. not trading shares that he doesn't have); write out the time of the next flight to Kuala Lumpur if his losses exceed £800 million! 52 CS_PAS 1999/2000 COURSE MANUAL 24. Squash The task is to write a program which plays a simple game of Squash. Everyone should be capable of tackling part (a). It will help if you run the program SQUASH in the Computing Science folder; this implements a solution to part (a). You will be prompted to enter a speed. Try a value of 15 - higher values make the ball move more slowly. A left mouse click releases a ball. You can control the position of the bat by moving the mouse. When you have missed the ball, you can get another with another left mouse click. To exit the game, chose Stop. If you have any problem at all with the Maths/Physics, please consult your tutor. (a) The object of this program is to play a simple game of squash, in which the player controls a bat on the right hand side of the screen using the mouse. The game ends when the player misses the ball. x_left x_right y_top Vy bat ball Vx y_bottom To make the Squash procedures and functions available you will need: USES csSquash The game starts with no ball in play. When the left mouse button is clicked, the ball should appear. You should use the function: function LeftMouseClick:BOOLEAN which will return TRUE if the left mouse button has been clicked and FALSE otherwise. So to wait and do nothing until the left mouse button is clicked you can say: REPEAT {do nothing} UNTIL LeftMouseClick In my version of the program you can move the bat (see later) before clicking, but this isn’t obligatory. 53 CS_PAS 1999/2000 COURSE MANUAL In order to control the bat with the mouse, you should use the following function and procedures: function GetMouse:REAL GetMouse will return the vertical position of the mouse (in the range y_bottom to y_top). To show the bat, you will need: procedure DrawBat(y:REAL) procedure DeleteBat(y:REAL) where y represents the middle of the bat. The mouse has been set up so that the bat will not go beyond the boundaries defined by y_top and y_bottom, and it will always stay at the right-hand side of the court. Once the left mouse button is clicked, you will need to make the ball appear - this can be anywhere you want in the court. In my version it appears at the right-hand side of the court, aligned vertically with the centre of the bat. When it appears the simulation should start. The initial x and y components of the ball's velocity will be provided in the supplied variables initial_x_velocity and initial_y_velocity. These initial velocities are calculated for you - you just need to copy the values into your own variables. To simulate the motion of the ball you will need to work out, and plot the position of the ball at equal time intervals, t. You should use the given constant delta_t for this interval. If the ball is moving with a velocity of vx in the horizontal direction and with a vertical velocity of vy , then the ball's new position can be calculated from its old position by using the formulae: x = xold + t vx y = yold + t vy See the Golf practical for more details. Gravity will affect the ball's movement, so you will need to declare a constant g = 9.81 and decrease the vertical velocity of the ball by t g each timestep. Thus: vy = vyold - t g Note that in the absence of air resistance, vx will not change (other than on collision with the left wall or the bat - see later). The ball may be drawn and removed from the screen using the procedures: procedure DrawSquashBall(no:INTEGER;x,y:REAL) procedure DeleteSquashBall(x,y:REAL) The first parameter in DrawSquashBall requires a ball number from 1 to 3 - you can have 3 balls in play, but in this version just use ball number 1. The x and y refer to the co-ordinates at which you want to draw or delete the ball. The ball will appear (or disappear) with its centre on (x, y). During the course of its motion, three things can happen to the ball: (i) (ii) (iii) it can hit one of the three walls and bounce off; it can hit the bat at the right hand side of the court and bounce off; it can miss the bat at the right hand side of the court. The ball has hit the top wall when yball + r ytop where yball is the y co-ordinate of the ball and r is its radius. You will need to work out the tests for hitting the other walls. The ball is soft and ‘gives’ a bit - this means that you are allowed to plot the ball 54 CS_PAS 1999/2000 COURSE MANUAL when its centre is slightly closer to the wall than the radius of the ball. If the ball is at the right hand side of the court, you will need to determine whether it has hit or missed the bat. The following diagram may help you decide how to do this. bat_y + 1/2*bat_height bat_y ball_y bat_y - 1/2*bat_height There is a predefined constant called ball_radius for you to use, which holds the value of the radius of the ball. What happens to the ball when it hits a wall depends on which wall it hits. Consider the left hand wall. When the ball hits this wall, the y-component of its velocity (vy) will not change. However, before the collision the ball's horizontal velocity (vx) will have been negative (going from right to left) and this will now be reversed i.e. vx := -vx This is also true if the ball bounces off the bat. Similarly, if the ball hits the top or the bottom walls, its horizontal velocity will remain unchanged, but its vertical velocity will be reversed: vy := -vy The game should end when the ball misses the bat at the right hand side of the court. How fast the ball moves will depend on the way your program is written, and on the speed of the computer it runs on. A procedure: SquashDelay(Del:INTEGER) is provided should you need to slow things down. On my version a value in the range 8 to 14 produces reasonable results. You might like to use: GetIntegerFromUser(Question:STRING): INTEGER at the start of the program (as I have done) to prompt the user with a string Question and use the value typed in reply for Del. Remember to include IO in USES. Here is a full list of the constants, variables, functions and procedures provided in csSquash. The ‘constants’ and ‘variables’ are in fact calls to functions (to stop you changing them) but this doesn’t make any difference as far as your program is concerned. 55 CS_PAS 1999/2000 COURSE MANUAL Constants and Variables ball_radius:INTEGER bat_height:INTEGER x_left:REAL x_right:REAL y_top:REAL y_bottom:REAL delta_t:REAL initial_x_velocity:INTEGER initial_x_velocity:INTEGER The radius of the ball The height of the bat The x co-ordinate of the left wall The x co-ordinate of the edge of the bat The y co-ordinate of the top wall They co-ordinate of the bottom wall The increment in time to be used The initial value of the ball's horizontal velocity The initial value of the ball's vertical velocity Procedures Draws the bat with its vertical centre at y, at the right hand side of the court DeleteBat(y:REAL) Deletes the bat with centre at y DrawSquashBall(no:INTEGER; x,y:REAL) Draws ball number no with its centre at the specified position - in part (a) there is only one ball - number 1 DeleteSquashBall(x,y:REAL) Deletes the ball at the specified location SquashDelay(Del:Integer) Introduces a delay to slow the game down. DrawBat(y:REAL) Functions GetMouse:REAL LeftMouseClick:BOOLEAN ExitClicked: BOOLEAN Returns the vertical position of the mouse, i.e. where the centre of the bat should be. Determines whether left mouse button has been clicked As before The two commands in the squash court window have the following properties: Pause will halt the game temporarily until restarted Exit will exit the program Here is some pseudo-code to get you started. My version of the program repeatedly releases a ball every time the left mouse button is clicked. A simple version would just finish when the ball has been missed once. FIRST LEVEL REFINEMENT squash: initialise REPEAT draw the ball at its current position work out next position of ball handle any collision with left wall handle any collisions with roof and floor IF the position of the bat has changed THEN delete the bat and redraw it IF the ball hits the bat THEN handle the collision ELSE the ball has missed delay if necessary delete the ball at its previous position UNTIL the ball has missed the bat 56 CS_PAS 1999/2000 COURSE MANUAL (b) You can make the game more complex by playing with more than one ball. DrawSquashBall allows you to specify which one of three differently coloured balls to draw on the screen. Try to develop your program so that more than one ball can be in play at a time, and so that collisions between the balls occur. (c) You may develop your program so that it becomes a breakout-style game. There are two procedures supplied which enable you to do this: DrawBrick(col:TColor; x, y:REAL) RemoveBrick(x, y:INTEGER) DrawBrick draws a brick with the same dimensions as the bat onto the screen with its centre on (x, y) in colour col where col is one of the following predefined constants: clBlack clRed clYellow clBlue clSilver clAqua clLime clFuchsia clWhite You will need to include Graphics in your USES to make these colours available. RemoveBrick deletes the brick at location (x, y) on the screen. In order to enable collision detection with the bricks, two constants,: brick_width:INTEGER brick_height:INTEGER are provided. When the ball hits a brick, the brick should disappear and the appropriate adjustments made to the velocity of the ball. 57 CS_PAS 1999/2000 COURSE MANUAL 25. Billiards The task is to write a program which plays a simple game of billiards. Everyone should be capable of tackling part (a). It will help if you run the program BILLIARDS in the Computing Science folder; this implements a solution to the first stage. If you have any problem at all with the Maths, please consult your tutor. The meaning of some of the terms used below will be clear if you refer to the following Figure. x_right x_left top y_top direction of travel y right left x bottom y_bottom (a) A ball is placed on a billiard table which has the normal six pockets. The player is prompted to enter an angle which determines the initial trajectory of the ball. This angle is specified in degrees clockwise from the y-axis as shown. The ball is always struck with the same velocity, v; the velocities in the x and y directions will be: vx = v sin( vy = v cos( where is in radians (1 radian = 57.2958 degrees). You should simulate the motion of the billiard ball until it either comes to rest or ends up in a pocket. If it comes to rest without going into a pocket then prompt the user for another angle, and continue to simulate the motion from the place where the ball came to rest. Carry on prompting and simulating until the ball is in a pocket. To simulate the motion, you will need to work out, and plot the position of the ball at equal time intervals, t. You should use the given constant delta_t (see below) for this interval. Thus: xnew = xold + t vx ynew = yold + t vy This means that as long as it does not hit a cushion (see below) the ball will continue in a straight line ( will remain unchanged). 58 CS_PAS 1999/2000 COURSE MANUAL Due to friction, the ball slows down until it eventually comes to a stop. To simulate this you should subtract v from the velocity each time step. You should use the given constant delta_v (see below) for this decrease. Thus, for each time step:: vnew = vold - v In the course of its motion, three things can happen to the ball: (i) (ii) (iii) it can come to a stop (see above); it can hit a wall and bounce off; it can go into a pocket. When the ball hits a wall, what happens depends on which wall it hits. Consider when the ball hits the 'top' wall. In terms of the angle new = - ld This is also true when the ball hits the 'bottom' wall. Likewise, if the ball hits the 'left' or 'right' walls we have: new = 360 - ld (This comes from a consideration of the physics of elastic collisions. In all cases the sign of the component of the velocity perpendicular to the wall is reversed. In the case of the 'top' wall the ydirection is perpendicular, so in this case it is the y-component of the velocity which is reversed.) If the walls were perfectly rigid, the ball would hit the top wall when: yball + r= ytop where yball is the y co-ordinate of the ball and r is its radius. However, as with a real billiards table, the walls have cushions which 'give' a little when the ball comes into contact with them. For the top wall we have a 'hit' when: yball + r ytop You will need to work out the tests for hitting the other three walls. A number of constants, variables, procedures and functions are provided in the csBill unit: Constants radius (INTEGER) The radius of the ball initial_velocity (REAL) The initial velocity given to the ball delta_t (REAL) The increment in time to be used in the simulation delta_v (REAL) The decrease in velocity which takes place every time step 59 CS_PAS 1999/2000 COURSE MANUAL Variables These are assigned values within the unit, and should be treated as 'read-only' -i.e. like constants. x_left: INTEGER x_right: INTEGER y_top: INTEGER y_bottom: INTEGER x_spot: INTEGER y_spot: INTEGER The x co-ordinate of the left wall The x co-ordinate of the right wall The y co-ordinate of the top wall The y co-ordinate of the bottom wall The x co-ordinate of the place where the ball is placed at the start of the game. The corresponding y co-ordinate. Procedures PutBall(ball: INTEGER; x, y: REAL) Draws ball number ball at the specified position. In part (a), there is only one ball - number 1. DeleteBall(x, y: REAL) Delete the drawing of the ball at the specified location. BillDelay(del:INTEGER) Introduces a delay so that the ball doesn’t move too fast; you will have to experiment with the exact value of the number that you pass to it - this will depend on your program, and on the machine it is running on. Functions InPocket (x, y: REAL): BOOLEAN Returns TRUE whenever the position denoted by the parameters lies within any of the six pockets - it doesn't differentiate between the different pockets.. ExitClicked: BOOLEAN As before The Billiard window has two menu items: Pause/Resume (which allow you to do just that) and Exit (which can be used at any time if your program is not doing what you want, and also at the end of the game) If at any time you call PutBall, DeleteBall or InPocket with co-ordinates which place the centre of the ball off the table, you will get an error message and the program will terminate. (b) You should now use your simulation to play a game between two players. The file L:\delphi\data\billiard.txt contains the name of the first player followed by the name of the second player. Then comes a number of angles (expressed as an integer number of degrees) at which the ball is hit for a stroke; in each pair the first corresponds to a stroke from the first player; this is always followed by a stroke from the second. For example: Hendry Higgins 100 35 265 187 45 78 This represents a six stroke match in which Hendry's first stroke is hit at 100 degrees. The rules of the match are simple. The ball is placed on the spot. The first player hits it as specified. If it comes to a halt without going in a pocket, the second player plays it from where it stops. If it goes in a 60 CS_PAS 1999/2000 COURSE MANUAL pocket, then the player who plays the stroke gets a point and the ball is placed on the spot for the other player. The winner is the player who gets the most balls in pockets (i.e. the most points). Your program should read in the data from the file, and output the results to the screen in the following format (assuming that the second, fourth and fifth strokes go in a pocket): Hendry Higgins Hendry Higgins Hendry Higgins 100 35 265 187 45 78 Pocket Pocket Pocket Higgins wins by 2 points to 1 If the match is a draw, the last line should be: A draw: 3 points each Note that the last shot does not necessarily end up in a pocket. You can assume that both players play the same number of strokes in strict alternation. It is a good idea to redraw the table each time a ball goes into a pocket. (c) Develop your program to deal with more than one ball and collisions between balls. PutBall allows you to specify the colour of the ball - three colours are available: 1 = white; 2 = red; 3 = black. 26. Frequency Histogram A given file contains a number of integers, one per line. The integers (apart from the first) are generated randomly over the range given by the first integer. For example, if the file were to contain the following integers: 20 10 11 13 8 12 10 8 9 7 15 then the range of the random numbers would be in the range 1..20; the random numbers would be 10, 11, 13 ... You can assume that the range will not exceed 100. 61 CS_PAS 1999/2000 COURSE MANUAL Your task is to plot a frequency histogram of the random numbers. The histogram for the numbers given above would look like: In general the file will be a lot larger than the example given. Sample files are in: L:\delphi\data\rand?.txt Graphical output should be obtained with the augmented csPlot; you will need the following procedures: DrawAxes(x_max, y_max : REAL) PlotLine(x1, y1, x2, y2 :REAL) DrawAxes puts X and Y axes on the screen; x_max and y_max specify the maximum x and y values that are to be plotted although you can actually use x values a bit larger than x_max (a fact which I've exploited in the example). PlotLine plots a line from (x1, y1) to (x2, y2). The data files will contain distributions of four types: uniform, unimodal, bimodal or none of these. Your program should apply tests to the distributions to identify which type is present, and inform the user with: DisplayStringToUser The tests are: uniform: unimodal: bimodal: all frequencies deviate by less than 10% from the mean frequency. there is a single maximum frequency; the distribution has two maxima separated by a minimum which is less than 50% of either maximum. Start by recognising the uniform distribution. If you have time, try the other two. 62 CS_PAS 1999/2000 COURSE MANUAL 27. Translation A text file L:\delphi\data\convert.txt contains information which allows the conversion of measurements between UK and metric units. The information is coded as triples; each triple consists of three lines. The first line contains a string specifying a UK unit, the second contains a real number and the third line contains a string specifying the corresponding metric unit. The real number says how many metric units are contained in the given UK unit. Each line contains only one word or number. For example, the contents of the file might be: inch 2.54 cm yard 0.91 m mile 1.61 km acre 0.4 hectare gallon 4.55 litre pound 0.45 kg ton 1.02 tonne This states, for example, that 1 inch = 2.54 cm. Your task is to write a program that: • • • • • asks the user to enter a quantity as a real number; asks the user to enter a unit of measurement (UK or metric); converts the quantity to the alternate system and writes out the result (to two places of decimals); if the unit is not recognised, then inform the user that no conversion is possible; the program stops when the user types 0 as the quantity. Thus a possible dialogue might be: Enter a quantity: 3.2 Enter a unit: inch 3.2 inch = 8.13 cm Enter a quantity: 24.5 Enter a unit: litre 24.5 litre = 5.38 gallon Enter a quantity: 19.6 Enter a unit: foot The unit foot is not recognised Enter a quantity: 0 63 CS_PAS 1999/2000 COURSE MANUAL Additional Tasks: A text file L:\delphi\data\words.txt contains pairs of words, the first is an English word and the second is its French equivalent. Each line contains only one word. For example, the contents of the file might be: boy garcon girl fille father pere mother mere son fils Your task is to write a program that: • • • • • asks the user to enter a word; if the word is an English word, then print out its French equivalent; if the word is a French word, then print out its English equivalent; if the word is not in the file, then inform the user that no translation is available; the program stops when the user types the word end (which is not one of the words in the file); Thus a possible dialogue might be: Enter a word: mere The English translation of mere is mother Enter a word: son The French translation of son is fils Enter a word: sun There is no translation for: sun Enter a word: end Suppose that the dictionary file were extended to be multi-lingual; this means that rather than containing pairs of words it contained sets of words; each set contains words of the same meaning in several different languages. Thus an English/French/German dictionary file might be: boy garcon Junger girl fille Madchen father pere Vater mother mere Mutter son fils Sohn dog chien Hund Extend your solution so that the user specifies a word in any of the three languages, and then the language into which that word is to be translated. The program should find the appropriate translation and then write it out. A possible dialogue might be: 64 CS_PAS 1999/2000 COURSE MANUAL Enter a word: mere Translate mere into: German The German for mere is Mutter Enter a word: Hund Translate Hund into: English The English translation of Hund is dog Enter a word: pere Translate pere into: French pere is a French word Enter a word: cat There is no translation for: cat Enter a word: end Consider the problems of extending the program to cope with a larger number of languages. 28. Shapes An engineering firm cuts a number of standard shapes from sheet metal. The standard shapes, their dimensions, and the corresponding areas are: SHAPE square circle triangle DIMENSION(S) side: s1 radius: s1 three sides s1, s2, s3 rectangle 45 degree rhombus two sides s1, s2: side: s1 AREA SQR(s1) pi*SQR(s1) SQRT(s*(s-s1)*(s-s2)*(s-s3)) where: s =(s1+s2+s3)/2 s1*s2 SQR(s1)/SQRT(2.0) Write a program which reads in the names of shapes followed by their dimensions from a text file and writes out the name of each shape and its area. The end of the data is indicated by the 'end of file'. Once all of the data has been handled, the program should print out the total area and the average area. An example of the input data is in L:delphi\data\shapes.txt: SHAPE circle triangle square circle rhombus rectangle square AREA 91.6 30.9 8.4 784.3 10.8 98.0 60.8 The output should be: Total area = Average area = 1084.7 155.0 65 CS_PAS 1999/2000 COURSE MANUAL 29. Intensive Care Unit (ICU) Patient data from an ICU is available in a text file as a sequence of integers, one per line; samples are taken at equi-spaced time intervals. (a) Write a program to plot the data.. A sample data files is L:\delphi\data\icu1.txt (and icu2.txt and icu3.txt) (b) Add low pass filtering: f(t) = c*f(t-1) + (1-c)*r(t) where f(t) is the filtered data at time t and r(t) is the raw data. Plot the filtered data as well as the raw data. (c) Use an average window filter: f(w,t) = average of w raw data points centred on t (d) A third filter is the median filter. This also involves moving a window over the data, but rather than taking the average of the values in the window to represent the filtered value at its mid-point, we look for the value which is the median of those values (i.e. there are as many values greater than the median as there are values less). This involves sorting the values in the window into order, and then taking the one in the middle. For example, suppose the values in the window (w = 7) are: 124 204 46 183 195 156 166 Sorting them gives: 46 124 156 166 183 195 204 and the median value is 166. 30. Retracing Your Steps Look again at Problem 5(b) in which KAREL explores a maze to find a beeper. Modify the solution so that KAREL can carry the beeper back to where he started by the shortest route. This means that he will have to record the Points he visits on the way out, and remove from his record those Points that he visits twice (i.e. when he has been down a 'blind alley'). 66