Notifications

The new correspondence of rating to float is:

5.6 5.06
5.7 5.07
5.8 5.08
5.9 5.09
5.10a 5.10
5.10b 5.101
5.10c 5.102
5.10c 5.103
5.11 5.11



Goals for this homework

  • Gain experience with structs and pointers.

You are expected to complete this assignment individually. If you need help, you are invited to come to office hours and/or ask questions on piazza. Clarification questions about the assignments may be asked publicly. Once you have specific bugs related to your code, make the posts private.

This project has a few functions, some of which are provided for you.

The premise based on rock climbing. In rock climbing, each climb is rated for difficulty. Climbs typically start with difficulty 5.6, which is no harder than climbing a ladder. They increase in difficulty fairly quickly, with a novice unlikely to be able to complete a 5.8. The rating goes: 5.6, 5.7, 5.8, 5.9, 5.10a, 5.10b, 5.10c, 5.10d, 5.11. For the purposes of this assignment, we will consider those 5.06, 5.07, 5.08, 5.09, 5.10, 5.101, 5.102, 5.103, and 5.11.

These ratings are based primarily on three aspects of the climb:
  • The positions of the holds - the farther they are apart, or more awkward a position one needs to be in to climb, the higher the rating.
  • The angle of the rock face - the rock face can be straight up, or it can be an "overhang" - when the rock protrudes more as it goes higher.
  • The size and shape of the holds - some holds have a nice hole for the hand to grab onto, whereas others requiring "pinching" or placing a hand in a crack to hold on.

In this assignment, you will work on a series of functions that will attempt to determine the rating of a climb. We will make a series of simplifying assumptions about the data set in order to more easily evaluate the climb. A hold is defined as follows:

typedef struct { unsigned int xcoor; unsigned int ycoor; unsigned int zcoor; unsigned int hold_shape; } climbing_hold; typedef struct { climbing_hold *right_holds; // array of climbing holds unsigned int num_right_holds; climbing_hold *left_holds; // array of climbing holds unsigned int num_left_holds; } climb;
The data is organized as follows:
  • The holds are separated into holds intended for the left hand/foot and holds intended for the right hand/foot.
  • The holds are given in order from lowest to highest.
The rating is determined by first calculating the rating based on only the distance between holds, shape of the holds, and angle of the rock. The overall rating will be the maximum of those three values.

You should submit four files for this assignment ( hw4.h, hw4.c, hw4_main.c, and Makefile) in your subversion repository as directed below.

Set Up

You need a hw4.c and hw4.h file for this portion.

You need to add the skeleton code so that your program will minimally execute. You must do this in case you do not complete your assignment. Our testing infrastructure needs to compile and execute even if you did not complete the entire assignment. Refer to past assignments on how to make skeleton code.

Problem 1: rating_hold_distances

float rating_hold_distances(climb c, float climber_height);

Write a function that rates a climb based on the hold distances, adjusted for the height of the climber. A short climber will have more difficulty with a "reachy" climb than a tall climber.

The rating will be based on the ratio of the height of the climber to the maximum gap between two holds on the same side. All measurements will be given in cm. The table below shows the relationship. For example, if the height of the climber is 4x the maximum gap on one side, then it is a 5.6. If it is 3x, then it is 5.7.

Rating Ratio
5.6 >= 4
5.7 3
5.8 2.7
5.9 2.4
5.10a 2
5.10b 1.75
5.10c 1.5
5.10d 1.25
5.11 < 1.25

If any of the inputs are NULL, then print an error and return 0.

Don't forget to complete this portion, test it, and commit it before moving on!

Problem 2: rating_hold_shapes

float rating_hold_shapes(climb c);

The hold shape is a number from 0 to 20. 0 means that it is virtually impossible to hold, whereas 20 has a large place to comfortably hold. A shape of 18 will be a rating of 5.8.

Rating Hold shape
5.6 20
5.7 19
5.8 17
5.9 15
5.10a 13
5.10b 10
5.10c 8
5.10d 5
5.11 < 5

Problem 3: rating_rock_angle

float rating_rock_angle(climb c);

The next step is to rate based on the maximum rock angle. The angle does not come into play until 5.8 - both 5.6 and 5.7 have rock angle 0. Therefore, 5.7 is not shown in the table. 5.7 is not a valid return value for this problem. To calculate the rock angle at any particular point, you calculate the difference between the z coordinates of two adjacent holds and divide that by the vertical distance between two holds. If the z coordinates are identical, that means there is no overhang, and the ratio is 0. Looking at the table below, a ratio of 0.15 would result in a 5.8 rating.

Rating Ratio
5.6 0
5.8 0.25
5.9 0.6
5.10a 1
5.10b 1.5
5.10c 4
5.10d 10
5.11 > 10

Problem 4: overall_rating

float overall_rating(climb c, float climber_height);

This function calls the three other functions and returns the max value of the three values.

This is clearly not perfect, however, climbs are often rated by their hardest move. The biggest problem with this algorithm is that we don't know if the hardest move is the same for all three aspects. It is clearly more difficult to have a small hold and long distance while climbing most slanted part of the rock. However, in order to make this problem tractable, we are simplifying the algorithm.

Testing

We have provided some resources for your testing. We wrote code that takes in a file containing holds information. You can see the file format in sample_holds.txt. The format is:
#left holds lhold1_xcoor lhold1_ycoor lhold1_zcoor lhold1_hold_shape lhold2_xcoor lhold2_ycoor lhold2_zcoor lhold2_hold_shape ... num_right_holds rhold1_xcoor rhold1_ycoor rhold1_zcoor rhold1_hold_shape ...

The code to read in this file into a climb struct is in hw4_provided.h and hw4_provided.c. Note that the struct is declared in this .h file, so do not redeclare the struct in your own .h file. Instead, you need to #include before your hw4.h file.

You can start with our sample file, but you are expected to create other files that have different ratings for your own testing.

The way you will test is to create different files with different climbs in them, being careful to vary the resulting ratings for the three sub-ratings (distance, angle, hold shape). Your program will call the provided function to read in the holds from a particular file into the climb struct. Then you will call all of your functions from main.

You will then create a testscript. It will contain a sequence of command lines, each one corresponding to one test.

You will send in command-line arguments with the input file, function being tested, and expected rating. You will read in the command-line arguments, determine which function to test, run that test, then compare the resulting rating with the expected rating. Your message needs to contain: filename, function name, success or failure, and, if failure, the expected rating vs resulting rating

./rate_climb holds.txt 0 5.07 150 ./rate_climb <filename> <functionID> <expected_rating> [climber_height]
rating_hold_distances 0
rating_hold_shapes 1
rating_rock_angle 2
overall_rating 3

Recall that to change a string "3" to the integer 3, use atoi. Likewise, to change "5.9" to 5.9, use atof.

Submit

At this point, you should have done the following:
  • Created four files and filled in the proper information: hw4.h, hw4.c, hw4_main.c, testscript inside your hw4 directory. Make sure that before you execute this command, you have already added your hw4 directory.
  • $ svn add hw4.h hw4.c hw4_main.c testscript
    
  • Implemented all of your functions. If not, you at least need skeletons of your functions so that our automated tests will compile for the functions you did write.
  • Compiled your executable manually and with the Makefile
  • Implemented your test cases
  • Executed your code
  • Debugged your code
  • $ svn commit -m "hw4 complete"