Rowan University
Rowan University Programming Contest
hosted by the Computer Science Department
our 33rd annual contest was Friday, 3 May 2019
Lessons From the 2018 RUPC
Structural Problems
Repeated Blocks of Code

Many entries had nearly identical methods for marking spots already claimed by X and O, or to check and see whether X or O had won. It was clear that they wrote a method to read in which spaces X had taken, or to see if X had won, and then copied that and changed X to O.

This was a problem for two teams who didn't get all the changes right in the copies, One team marked all claimed hexagons for player X, even those claimed by O. Another team reported "X has won" even if O had won.

Better would be to write a method that takes an additional argument, player or something, and then have the code once.

Problems with Functional Decomposition (or lack thereof)

Two programs were just one big main routine, with one big loop, with all the code in it. This meant lots of repeated code (as above), but also meant that end of the main loop was hundreds of lines, and several pages, after the start of the loop. Such code is hard to read, hard to debug, and hard to get right.

Programs That Didn't Run

One entry included a note that it didn't actually compile or run, but that if a particular method was removed then it would. The method was left in in hopes of getting partial credit for at least understanding how to solve the problem.

We make no changes whatever to the submitted programs. Not a semicolon, not a newline, nothing. By the day of the contest, the judging team has written several versions of the solution. We could make any of the top five programs into the winner in five minutes if we started making edits. The potential for abuse in such a case would be intolerable, which is why making changes is forbidden.

What you submit is what gets evaluated, as it is. If it doesn't compile, or has no output, you get a zero for the output score.

If you have a method that doesn't compile, your smart move is to delete it. If you want us to see it in hopes of getting some partial credit, you can comment it out so the compiler will ignore it.

Methodology Problems
Lack of Flexibility

Some programs just hardcoded values from the sample data into the code, setting the size of the hexagon board grid to 5x5 and marking the spaces from the sample data. Testing such programs on other data is essentially impossible.

Better, but still troublesome, was hardcoding in a filename to read data from. That name can be changed and the program rerun.

If your program is going to read from a file by name, you should ask for the filename as input, which simplifies testing the code.

The problem statement as written assumes that all input will come from the keyboard; during judging, the easiest way for the judges to test is to copy the input data from one window with a mouse and paste it into another window where the program is running. (Unix users can obviously use the shell's input redirection, as can Mac users who work from a Terminal window.) This is likely also the quickest way for competitors to test their code while working.

Long Strings of If/Then/Else

A hexagon where a player has already moved is indicated by a notation such as B3, meaning Column B, Row 3. To store this in an array, where the only valid index values are numbers, the letter has to be converted. In Python, for example, if the string containing the location is spot, this code will return the column number:

            col = ord(spot[0]) - ord('A')
          

You take the ordinal value of the first character, and subtract the ordinal value of A, giving an array index the corresponds to the first column. (Python arrays start at zero.)

Some programs did this same thing, but instead of using a function, subtracted 65, which is the ASCII value for A. That's fine, but should be marked with a comment. A reader who doesn't have the ASCII table committed to memory might see 65 and wonder where that magic number came from.

However, some programs did this:

            if(col == 'A'){
                column = 1;
            }
            else if(col == 'B'){
                column = 2;
            }
            else if(col == 'C'){
                column = 3;
            }
            [ and so on for another two pages ]
          

Worse, some combined this with the Repeated Blocks of Code problem and so had two sets of these. Some didn't have the else keywords, and so instead of stopping after getting a match they continued through all the other tests, even though all the others were going to fail.

And even worse than that, some of them only did this through E, meaning that any grid larger than 5x5 wouldn't be processed correctly at all, even though the problem statement said that grids could be up to 21x21, meaning you had to go all the way to U. (Some programs went all the way to Z, which, while unnecessary, at least meant all valid data would be processed.)

Off-by-One Errors

The problem spec says that rows are numbered starting at one, and columns are lettered starting at A. Many languages start arrays at zero. Which means that if you create an array that's 5x5, its indices are from the set {0, 1, 2, 3, 4}. Several entries mark claimed positions with code that just takes the row number as is, without subtracting one. This means that an input of C5, perfectly valid on a 5x5 board, throws an error because the array doesn't go to 5.

Readability Problems
Uncommented Blocks

One program included this:

            if(count%2==0){
            bo.movecomp(row, column);
            }
            if(count/2==0){
            bo.moveplayer(row, column);
            }
          

We decided that maybe the /2 was a typo, and the second if was supposed to be count%2!=0. But if that's the case, why not just use an else?

In any case, as there were no comments at all, the judges gave up trying to figure it out.

Also, this code has poor use of whitespace. The code inside the blocks isn't indented, and there are no spaces around the operators or variables in the conditions.

Poor Variable and Function Names

One Python program included this:

            list1 = []
            list2 = []
          

Okay, so those are lists, we could tell that from the code. What do they store?

One entry declared variables with names a and b. No explanation of what they were for, and with names so generic it wasn't obvious from the code.

One entry went on to use d, e, f, and g.

Another program declared a 3D array called box. As the game board is two-dimensional, it was unclear what this was for. There were no comments to explain, and the code was no help.

Magic Numbers

One program declared the board this way:

            hexBoard = new String[boardsize+5][boardSize]
          

Why +5? It's never explained.

Incorrect Indentation

Indentation should reflect program structure. In Python, this is required, but in many languages whitespace is ignored. As a result, programs can be indented in ways that are misleading. For example:

    if ( x == 9 )
        if ( y == 7 )
            printf("Zipzap\n");
    else
        printf("Zop\n");
          

This may look like it will print Zop if x is 8, but it won't. It will print nothing if x is 8. The else goes with the closest if, so this only prints Zop if x is 9 and y is not 7. The incorrect indentation is misleading. This makes programs difficult to read, which makes them hard to debug.

Other Mistakes
Mixing Up Rows and Columns

One disastrous mistake made by one team was getting the rows and columns backwards when reading already taken spots. The spot B4, after accounting for arrays starting at zero, should map to the array location [1, 3]. This program would put that at [3, 1]. The code was otherwise pretty good, but by mismarking the already-taken spaces for X and O, it could never get a correct answer.