CS302 -- Lab 5 -- Superball!


Tue Nov 27 16:37:58 EST 2007. Last revision: Fri Jan 21 10:08:31 EST 2022

What you hand in

This is split into two labs on Canvas: They are both due on the same day, and will be graded independently. If you are late with one, but not the other, the late points will only be applied to the late one.

Please do not submit anything other than those programs. The TA's will compile them with the disjoint set implementation described below.


Getting Started

You should start by going to whatever directory you'll be working in (on our lab machines), and doing:
UNIX> sh /home/jplank/cs302/Labs/Lab5/scripts/start_lab.sh
UNIX> git clone https://jimplank@bitbucket.org/jimplank/plank-disjoint-sets.git             # You'll need a bitbucket account for this one.
UNIX> cd plank-disjoint-sets
UNIX> make clean ; make
UNIX> cd ..
UNIX> make
If all is successful, then you'll have three programs in your bin directory:
UNIX> ls bin
sb-analyze	sb-play		sb-read
UNIX> bin/sb-read
usage: sb-read rows cols min-score-size colors
UNIX> bin/sb-analyze
This program doesn't do anything yet.
UNIX> bin/sb-play
This program doesn't do anything yet.
UNIX> 

How you are graded

The gradescript tests sb-analyze. It will be graded as a 50-point lab. For sb-play, we grade it by running sh scripts/run_multiple.sh on it for at least 10 runs. It too is graded as a 50-point lab.

Remember, (and I know I'm repeating myself here), that you are only submitting two programs -- the TA's will compile with their own copy of the disjoint set code.


Also

Every year, someone asks me for the source to sb-player. Sorry, but I can't give it out, because it's too easy to modify it to solve the lab. I can try to make an sb-player binary for your machine, and if you want modifications, I'll listen. Let me know.

There is an sb-player binary for macs in mac-binary/sb-player-mac.

Plus, in 2015, Alex Teepe wrote a multiplatform Superball player to share. I have not tried it, but please do. Thanks, Alex!

https://drive.google.com/file/d/0B4rzPrfwFCsKbUpwd21pMlgtc1E/view?usp=drive_link&resourcekey=0-gAtqjRzaBM5sHYs9nlvb7w

There is a README here, and a brief video to show it in use at: https://drive.google.com/file/d/0B4rzPrfwFCsKel9TOHRTMFR2TUk/view?usp=drive_link&resourcekey=0-rkDUhTWLp1ZgsLpDwEKgrw.

And finally -- a 2023 COSC student, James Shastid, wrote this player, which should play on your browser (you may need to resize your window).


Disjoint Sets

If you've done the command above correctly, in your directory plank-disjoint-sets, there is an implementation of disjoint sets that comes from https://bitbucket.org/jimplank/plank-disjoint-sets. You should have compiled the code in that directory, and then in the makefile, it will:

You are not allowed to modify the disjoint set code -- you should use it as is. The TA's will compile your code with their versions of the disjoint set code, so you can't customize it. Moreover, you shouldn't copy the code into your source files, or copy it from the lecture notes, and then modify it for your lab.

If you don't understand how to compile your program correctly, please ask the TA's or ask on Piazza. DO NOT COPY THE DISJOINT SET CODE FROM LECTURE AND INCLUDE IT WITH YOUR PROGRAM. Instead, use the code from bitbucket, as specified above.


Superball

Superball is a simplistic game that was part of a games CD for my old Windows 95 box. It works as follows. You have a 8x10 grid which is the game board. Each cell of the game board may be empty or hold a color:

The board starts with five random colors set. On your turn, you may do one of two things:

I have a tcl/tk/shell-scripted Superball player at /home/jplank/Superball. Simply copy that directory to your home directory:

UNIX> cp -r /home/jplank/Superball $HOME

Then you can play it with ~/Superball/Superball. The high score probably won't work -- you'll have to change the open command in the file hscore to the name of your web browser.

Let's look at some screen shots. Suppose we fire up Superball:

The "goal" cells are marked with asterisks, and there are five non-empty cells. Our only legal action is to swap two cells -- I'm going to swap cells [3,6] and [5,8]. This will make those two blue cells contiguous. In the game, I do that by clicking on the two cells that I want to swap. Afterwards, five new cells are put on the screen. Here's the screen shot:

I do a bunch more swaps and end up with the following board:

I can score the green cells by clicking on cell [2,1], [3,0], [3,1] or [4,0] and then clicking "Collect". This will score that group of eight green squares, which gets me 48 points (8*6), and three new cells will be added:

There are no cells to score here (the blues ones in the lower right-hand part of the board only compose a group of four). So I revert to swapping. Suppose I keep doing so until I reach:

I'm in trouble. I've got these beautiful groups of red, green and purple cells, but I can't score any of them because they are not connected to a goal call. Dang. I can only score those two groups of blue cells. When I do that, I'm only left with four open squares, and I can't score anything:

Perhaps I should have been a little more thoughtful while playing the game. Regardless, I'm stuck. I simply swap two random squares and end the game:

Oh well -- should have done that swap a little sooner....


For this lab, we are going to deal with a text-based version of the game. Our programs will have the following parameters:

I have written an interactive game player. I'll discuss all the parameters later. Call it as done below:

UNIX> cd /home/jplank/cs302/Labs/Lab5/
UNIX> bin/sb-player
usage: sb-player rows cols min-score-size colors player interactive(y|n) output(y|n) seed
UNIX> bin/sb-player 8 10 5 pbyrg - y y -
Empty Cells: 75     Score: 0

..........
..........
**b....b**
**....b.**
**.g....**
**......**
..........
..g.......

Your Move: 
The format of the board is as follows: When a letter is capitalized, it is on a goal cell. Dots and asterisks stand for empty cells -- asterisks are on the goal cells. If you click on the Print Boards button in the tcl/tk game, it will print out each board on standard output in that format. That's nice for testing.

You can type two commands:

SWAP r1 c1 r2 c2
SCORE r c

In the board above, you can't score anything, so you'll have to swap. We'll swap the blue cell in [2,2] with the green one in [7,2]:

Your Move: SWAP 2 2 7 2

Empty Cells: 70     Score: 0

.r........
..........
**g....b**
**....b.**
**.g....*Y
**......*P
.....rr...
..b.......

Your Move: 

It's incredibly tedious -- play along with me:

Empty Cells: 70     Score: 0

.r........
..........
**g....b**
**....b.**
**.g....*Y
**......*P
.....rr...
..b.......

Your Move: SWAP 0 1 7 2  
Empty Cells: 65     Score: 0

.b........
..........
**g....bB*
**....b.**
P*.g....RY
**......*P
.....rr...
.gry......

Your Move: SWAP 7 3 4 8
Empty Cells: 60     Score: 0

.b.......p
....g.....
**g.p..bB*
**r...b.*R
P*.g....YY
**......*P
.....rr...
.grr......

Your Move: SWAP 3 2 7 1
Empty Cells: 55     Score: 0

.b..r...pp
....g...b.
**g.p..bB*
**g...b.*R
P*.g....YY
**.g....*P
.....rr...
rrrr......

Your Move: SWAP 3 9 0 1
Empty Cells: 50     Score: 0

.r..rgy.pp
....g...b.
**g.p..bB*
**g...b.*B
P*.g....YY
**.g....*P
p...rrr...
rrrr.p....

Your Move: SWAP 6 0 0 1
Empty Cells: 45     Score: 0

.p..rgy.pp
.g..g...b.
**g.p..bB*
**g...b.*B
P*.g..y.YY
**.g..yp*P
r...rrr...
rrrr.py...

Your Move: SWAP 5 9 7 6
Empty Cells: 40     Score: 0

.p..rgy.pp
.g..g...b.
**g.p.pbB*
R*g...by*B
P*.g..y.YY
P*.g..yp*Y
r...rrrb..
rrrr.pp...

Your Move: SWAP 5 0 0 4
Empty Cells: 35     Score: 0

.p..pgy.pp
.g..g.r.b.
G*g.p.pbB*
R*g...by*B
P*.g..y.YY
R*.g..yp*Y
r..grrrb..
rrrrbppy..

Your Move: SWAP 7 4 1 6
Empty Cells: 30     Score: 0

.p..pgy.pp
.g.pg.b.b.
G*g.p.pbB*
R*g.r.by*B
P*pg..y.YY
R*.g.bypBY
r..grrrb..
rrrrrppy..

Your Move: SCORE 5 0
Empty Cells: 37     Score: 50

.p..pgy.pp
.g.pg.b.by
G*g.p.pbB*
R*g.r.byGB
P*pg..y.YY
**.g.bypBY
...g...b..
.p...ppy..

Your Move: 

You'll note, I could have scored cell [5,0] when there were 35 empty cells, but I really wanted to make that patch of red cells bigger.


Program #1: Sb-read

I have written src/sb-read.cpp for you. This program takes the four parameters detailed above, reads in a game board with those parameters and prints out some very basic information. For example, the following board:

May be represented by the following text (in txt/input-1.txt):

...yyryy.p
y.rg.yppyp
**gg.yrpPP
GGgbgybp**
R*bg.yrp*P
G*gygyypY*
yyybpby.pb
.pgg.yp.bb

When we run bin/sb-read on it, we get the following:

UNIX> bin/sb-read 8 10 5 pbyrg < txt/input-1.txt
Empty cells:                    20
Non-Empty cells:                60
Number of pieces in goal cells:  8
Sum of their values:            33
UNIX> 
There are three purple pieces in goal cells, one yellow, three green and one red. That makes a total of 3*2 + 4 + 5 + 3*6 = 33.

You should take a look at src/sb-read.cpp. In particular, look at the Superball class:

class Superball {
  public:
    Superball(int argc, char **argv);
    int r;
    int c;
    int mss;
    int empty;
    vector <int> board;
    vector <int> goals;
    vector <int> colors;
};

Mss is min-score-size. Empty is the number of empty cells in the board. Board is a vector of r * c integers. The element in [i,j] is in entry board[i*c+j], and is either '.', '*' or a lower case letter. goals is another array of r * c integers. It is equal to 0 if the cell is not a goal cell, and 1 if it is a goal cell. Colors is an array of 256 elements, which should be indexed by a letter. Its value is the value of the letter (e.g. in the above example, colors['p'] = 2).

sb-read does all manner of error checking for you. It is a nice program from which to build your other programs.


Program #2: Sb-analyze

You are to write this one.

With bin/sb-analyze, you are to start with sb-read.cpp as a base, and augment it so that it prints out all possible scoring sets. For example, in the above game board (represented by txt/input-1.txt), there are two scoring sets -- the set of 10 purple cells in the upper right-hand corner, and the set of 6 green cells on the left side of the screen. Here is the output to sb_analyze:

UNIX> sb-analyze
usage: sb-analyze rows cols min-score-size colors
UNIX> bin/sb-analyze 8 10 5 pbyrg < txt/input-1.txt
Scoring sets:
  Size: 10  Char: p  Scoring Cell: 2,8
  Size:  6  Char: g  Scoring Cell: 3,0
UNIX> 
Each set must be printed exactly once, but in any order, and with any legal goal cell. Thus, the following output would also be ok:
UNIX> bin/sb-analyze 8 10 5 pbyrg < txt/input-1.txt
Scoring sets:
  Size:  6  Char: g  Scoring Cell: 3,1
  Size: 10  Char: p  Scoring Cell: 2,9
UNIX> 
Think about how you would use the disjoint sets data structure to implement this -- it is a straightforward connected components application. I would recommend augmenting your Superball class with a Disjoint_Set, and then having a method called analyze_superball(), which performs the analysis.

Here's another example:

This is in the file txt/input-2.txt:

yyggyryybp
ggrgpyppyp
RBgggyrpPP
GGgggybpPP
RGygryrpBP
YGyygyypYB
yyybpbyppb
ppggyypbbb

UNIX> bin/sb-analyze 8 10 5 pbyrg < txt/input-2.txt
Scoring sets:
  Size: 14  Char: g  Scoring Cell: 5,1
  Size: 15  Char: p  Scoring Cell: 4,9
  Size:  7  Char: y  Scoring Cell: 5,0
  Size:  5  Char: b  Scoring Cell: 5,9
UNIX> 

Program #3: Sb-play

Your next program takes the same arguments and input as sb-analyze. However, now its job is to print a single move as would be accepted as input for the sb-player program. In other words, it needs to output a SWAP or SCORE line with legal values.

If you have fewer than five pieces and cannot score any, you will lose the game -- you should do that by swapping two legal pieces so that the game can end.

The sb-player program takes as its 5th argument the name of a program that it will use for input. I also have three programs - sb-play, sb-play2 and sb-play3 in that directory. sb-play simply swaps two random cells until there are fewer than five empty, then it scores a set if it can. The other two are smarter, but are by no means the best one can do.

Here's sb-player running on bin/sb-play2 (note, sb-player creates a temporary file, so you must run it from your own directory):

UNIX> /home/jplank/cs302/Labs/Lab5/bin/sb-player 8 10 5 pbyrg /home/jplank/cs302/Labs/Lab5/bin/sb-play2 y y -
Empty Cells: 75     Score: 0

g.........
..........
**......**
*Pr.....**
**......**
**..p...**
........b.
..........

Type Return for the next play
It waits for you to press the return key. When you do so, it will send the game board to /home/jplank/cs302/Labs/Lab5/sp-play2 and perform the output. Here's what happens:
Move is: SWAP 5 4 3 2

Empty Cells: 70     Score: 0

g........g
.......y..
**......**
*Pp.....**
**......G*
**..r...**
..g.....b.
........g.

Type Return for the next play
You can bet that the next move will swap that b with one of the g's:
Move is: SWAP 6 8 0 0

Empty Cells: 65     Score: 0

b........g
.......y..
**..b...**
*Pp.g...**
**.....gG*
**..r...**
..g.....g.
.p...p..g.

Type Return for the next play
And so on. If you run it with n for the 6th argument, it will simply run the program without your input:
UNIX> /home/jplank/cs302/Labs/Lab5/bin/sb-player 8 10 5 pbyrg /home/jplank/cs302/Labs/Lab5/bin/sb-play2 n y -
Empty Cells: 75     Score: 0

..........
..........
**......**
**y..y..**
**......**
*P......**
..........
......p.g.

Move is: SWAP 3 5 3 2

... a bunch of output skipped...

Empty Cells:  1     Score: 505

yyrrgggpyy
grrbppg.yg
GYbgygggPB
GBggpgbpPB
PPgggggrYB
YBbybgpbYR
pprrrggggr
byyrppppgg

Move is: SWAP 0 1 7 5

Game over.  Final score = 505
UNIX> 
Even though there were no good moves at the end, the program did a final SWAP so that the game could finish.

If you run with the 7th argument as n, it will only print out the end result, and the last argument can specify a seed (it uses the current time if that argument is "-"), so that you can compare multiple players on the same game:

UNIX> /home/jplank/cs302/Labs/Lab5/bin/sb-player 8 10 5 pbyrg /home/jplank/cs302/Labs/Lab5/bin/sb-play n n 1
Game over.  Final score = 0
UNIX> /home/jplank/cs302/Labs/Lab5/bin/sb-player 8 10 5 pbyrg /home/jplank/cs302/Labs/Lab5/bin/sb-play2 n n 1
Game over.  Final score = 855
UNIX> /home/jplank/cs302/Labs/Lab5/bin/sb-player 8 10 5 pbyrg /home/jplank/cs302/Labs/Lab5/bin/sb-play3 n n 1
Game over.  Final score = 2572
UNIX> 
It can take a while for these to run -- if it appears to be hanging, send the process a QUIT signal and it will print out what the current score is.

Shell Script to Run Multiple Times

The file scripts/run_multiple.sh is a shell script to run the player on multiple seeds and average the results. Examples:
UNIX> sh scripts/run_multiple.sh 
usage: sh scripts/run_multiple.sh r c mss colors player nruns starting_seed
UNIX> sh scripts/run_multiple.sh 8 10 5 pbyrg bin/sb-play 10 1
Run   1 - Score:     38  - Average     38.000
Run   2 - Score:      0  - Average     19.000
Run   3 - Score:      0  - Average     12.667
Run   4 - Score:     57  - Average     23.750
Run   5 - Score:      0  - Average     19.000
Run   6 - Score:      0  - Average     15.833
Run   7 - Score:     89  - Average     26.286
Run   8 - Score:     15  - Average     24.875
Run   9 - Score:      0  - Average     22.111
Run  10 - Score:     20  - Average     21.900
UNIX> sh scripts/run_multiple.sh 8 10 5 pbyrg bin/sb-play2 10 1
Run   1 - Score:    855  - Average    855.000
Run   2 - Score:    979  - Average    917.000
Run   3 - Score:    650  - Average    828.000
Run   4 - Score:    833  - Average    829.250
Run   5 - Score:    832  - Average    829.800
Run   6 - Score:   3326  - Average   1245.833
Run   7 - Score:   1507  - Average   1283.143
Run   8 - Score:   3643  - Average   1578.125
Run   9 - Score:    610  - Average   1470.556
Run  10 - Score:    862  - Average   1409.700
UNIX> sh scripts/run_multiple.sh 8 10 5 pbyrg bin/sb-play3 10 1
Run   1 - Score:   2572  - Average   2572.000
Run   2 - Score:   2708  - Average   2640.000
Run   3 - Score:    745  - Average   2008.333
Run   4 - Score:    424  - Average   1612.250
Run   5 - Score:   1888  - Average   1667.400
Run   6 - Score:   7140  - Average   2579.500
Run   7 - Score:   3475  - Average   2707.429
Run   8 - Score:   1701  - Average   2581.625
Run   9 - Score:   2699  - Average   2594.667
Run  10 - Score:   2291  - Average   2564.300
UNIX> 
Obviously, to get a meaningful average, many more runs (than 10) will be required.

Oh, and make your programs run in reasonable time. Roughly 5 seconds for every thousand points, and if you are burning all that time, your program better be killing mine....


Hints

Play the game for a bit to try to figure out some strategies. However, one good way to write a game player is to figure out a way to come up with a rating for a game board. Then when you are faced with making a move, you analyze all potential moves by trying them out (in other words, enumerate all potential swap operations) and choosing the one that gives you the resulting board with the highest rating.

Ideas for ratings? How about the total number of disjoint sets on the board (do you want that to bif or small)? Maybe some metric related to the sizes of the disjoint sets? Maybe add a fudge factor for a disjoint set that can be scored?


The Superball Challenge

To get credit, your player needs to average over 100 points on runs of 100 games.

I will run a Superball tournament with all of your players with extra lab points going to the winners:

Dr. Emrich and I have now performed the challenge eleven times: Here's the Superball Challenge Hall Of Fame (scores over 500):

Rank Average Name Semester
1 31814.13 Grant Bruer CS302, Fall, 2015
2 24278.49 Alexander Teepe CS302, Fall, 2015
3 17367.77 Joseph Connor CS302, Fall, 2014
4 17246.98 Caleb Kornegay CS302, Spring, 2023
5 17021.37 Cory Walker CS302, Fall, 2014
6 16963.40 Seth Kitchens CS302, Fall, 2015
7 14555.83 Ben Arnold CS302, Fall, 2012
8 14555.83 Adam Disney CS302, Fall, 2011
9 13657.79 Isaac Sikkema CS302, Fall, 2018
10 12963.47 Jake Davis CS302, Fall, 2014
11 12634.29 Jake Lamberson CS302, Fall, 2014
12 11722.05 Parker Mitchell CS302, Fall, 2014
13 11418.77 James Pickens CS302, Fall, 2014
14 11380.74 Nathan Ziebart CS302, Fall, 2011
15 11291.39 Michael Jugan CS302, Fall, 2010
16 10576.96 Tyler Shields CS302, Fall, 2014
17 10087.23 Maxwell Marcum CS302, Spring, 2022
18 8770.67 Nathan Swartz CS302, Spring, 2019
19 7607.98 Riley Crockett CS302, Spring, 2022
20 7475.07 Jared Smith CS302, Fall, 2014
21 7216.28 Michael Bowie CS302, Fall, 2018
22 7003.56 Andrew LaPrise CS302, Fall, 2011
23 6100.28 Chris Nagy CS302, Fall, 2015
24 5467.56 Tyler Marshall CS302, Fall, 2013
25 5262.80 Harry Channing CS302, Fall, 2018
26 5116.13 Kyle Bashour CS302, Fall, 2014
27 4808.03 Matt Baumgartner CS302, Fall, 2010
28 4586.51 Jeramy Harrison CS302, Fall, 2013
29 4531.96 Philip Hicks CS302, Spring, 2019
30 4057.08 Phillip McKnight CS302, Fall, 2015
31 3882.53 Pranshu Bansal CS302, Fall, 2013
32 3882.28 Kemal Fidan CS302, Fall, 2018
33 3852.87 Yaohung Tsai CS302, Fall, 2015
34 3849.24 Chris Richardson CS302, Fall, 2010
35 3809.41 Arthur Vidineyev CS302, Fall, 2015
36 3588.35 Kevin Dunn CS302, Fall, 2014
37 3545.96 Caleb Fisher CS302, Spring, 2022
38 3464.83 Patrick Slavick CS302, Fall, 2012
39 3460.00 Brandan Roachell CS302, Fall, 2020
40 3436.21 sb-play3 CS140, Fall, 2007
41 3400.50 Kody Bloodworth CS302, Fall, 2018
42 3080.15 Andrew Messing CS302, Fall, 2013
43 3059.06 Stephen Qiu CS302, Spring, 2022
44 2903.38 Adam LaClair CS302, Fall, 2013
45 2736.85 Christopher Canaday CS302, Spring, 2022
46 2728.86 Alexander Yu CS302, Spring, 2022
47 2616.00 Rus Refait CS302, Spring, 2020
48 2555.36 Mohammad Fathi CS302, Fall, 2014
49 2532.89 Trevor Sharpe CS302, Fall, 2015
50 2521.44 Justus Camp CS302, Fall, 2018
51 2487.24 Befikir Bogale CS302, Spring, 2022
52 2473.69 Colin Canonaco CS302, Spring, 2022
53 2354.00 Zach Deguira CS302, Fall, 2020
54 2335.88 Mark Clark CS302, Fall, 2012
55 2307.16 John Burnum CS302, Fall, 2012
56 2205.17 Shawn Cox CS302, Fall, 2011
57 2163.70 Alex Wetherington CS302, Fall, 2011
58 2134.99 Julian Kohann CS302, Fall, 2013
59 2062.54 Gitasuk Jur CS302, Spring, 2022
60 2011.38 Wells Phillip CS302, Fall, 2015
61 1919.72 Ravi Patel CS302, Spring, 2019
62 1854.00 Sam Aba CS302, Spring, 2020
63 1849.73 Andrew Lay CS302, Spring, 2022
64 1828.05 Fatima Bowers CS302, Spring, 2022
65 1778.83 Keith Clinart CS302, Fall, 2011
66 1740.19 Luke Bechtel CS302, Fall, 2014
67 1635.30 Justin Bowers CS302, Spring, 2022
68 1634.49 William Brummette CS302, Fall, 2013
69 1602.83 Forrest Sable CS302, Fall, 2014
70 1498.87 Tom Hills CS302, Spring, 2019
71 1470.84 Christopher Tester CS302, Fall, 2014
72 1446.00 Noah Burgin CS302, Spring, 2020
73 1433.48 Xiao Zhou CS302, Fall, 2015
74 1430.54 Jonathan Burns CS302, Fall, 2018
75 1399.08 Meghan Brandt CS302, Spring, 2022
76 1340.32 John Murray CS302, Fall, 2012
77 1329.34 Benjamin Brock CS302, Fall, 2013
78 1301.00 Henry Brand CS302, Spring, 2022
79 1257.56 Dylan Lee CS302, Fall, 2018
80 1202.06 Bandara CS302, Fall, 2014
81 1149.80 Will Houston CS302, Fall, 2010
82 1148.99 Fort Hunter CS302, Spring, 2022
83 1119.85 Kevin Chiang CS302, Fall, 2014
84 1096.48 Daniel Cash CS302, Fall, 2011
85 1076.30 Abrian Abir CS302, Spring, 2022
86 1059.91 Kaleb McClure CS302, Fall, 2013
87 1058.26 sb-play2 CS140, Fall, 2007
88 1029.63 Lydia San George CS302, Fall, 2018
89 1020.55 Jihun Kim CS302, Spring, 2022
90 1019.72 Justin Langston CS302, Spring, 2019
91 1016.15 Harrison Hoytt CS302, Spring, 2022
92 972.36 Erik Rutledge CS302, Fall, 2013
93 959.79 Daniel Nichols CS302, Fall, 2018
94 917.92 Vasu Kalaria CS302, Fall, 2015
95 916.54 Cody Blankenship CS302, Spring, 2022
96 909.35 Andrew Mueller CS360?, Spring, 2022
97 908.09 Chris Rains CS302, Fall, 2012
98 875.44 Allen McBride CS302, Fall, 2012
99 856.00 Tim Krenz CS302, Spring, 2019
100 852.32 Jonathan Graham CS302, Spring, 2022
101 843.69 Jacob Looney CS302, Spring, 2022
102 840.94 Spencer Howell CS302, Fall, 2018
103 831.74 Ethan Kessinger CS302, Spring, 2022
104 830.79 David Cunningham CS302, Fall, 2014
105 826.00 Kincaid Mcgee CS302, Fall, 2020
106 817.17 Alex Nguyen CS302, Spring, 2022
107 810.17 Collin Bell CS302, Fall, 2012
108 763.58 Jacob Lambert CS302, Fall, 2013
109 707.16 Shivam Mistry CS302, Spring, 2022
110 703.71 Shanna Wallace CS302, Spring, 2022
111 703.67 Scott Marcus CS302, Fall, 2015
112 703.00 Don Lopez CS140, Fall, 2007
113 700.90 Tony Abston CS302, Fall, 2015
114 682.56 Jackson Collier CS302, Fall, 2014
115 681.00 Holland Johnson CS302, Fall, 2020
116 677.83 KC Bentjen CS302, Fall, 2011
117 677.74 Andrew Artates CS302, Spring, 2019
118 665.60 Joshua Clark CS302, Fall, 2012
119 659.96 Warren Dewit CS302, Fall, 2010
120 654.67 Coburn Brandon CS302, Fall, 2015
121 650.98 Joaquin Bujalance CS140, Fall, 2007
122 643.13 John Blackaby CS302, Spring, 2022
123 638.14 Justin Mcknight CS302, Spring, 2022
124 630.73 Dylan Devries CS302, Fall, 2018
125 630.10 Winston Boyd CS302, Fall, 2018
126 626.62 Elliot Greenlee CS302, Fall, 2014
127 616.00 Joseph Wehby CS302, Spring, 2022
128 609.58 Ethan Maness CS302, Spring, 2022
129 603.14 Joseph Eaton CS302, Spring, 2022
130 594.02 James Tucker CS302, Fall, 2015
131 586.71 Jonathan Ting CS302, Spring, 2019
132 586.56 Andrew Berger CS302, Spring, 2019
133 581.29 Mason Stott CS302, Spring, 2022
134 571.02 Rocco Febbo CS302, Fall, 2018
135 558.62 Matthew Bowlby CS302, Spring, 2022
136 557.01 Eli Kell CS302, Spring, 2022
137 555.40 Jovan Yoshioka CS302, Spring, 2022
138 554.94 Jared Burris CS302, Fall, 2015
139 546.52 Andrew Rutter CS302, Spring, 2022
140 539.00 Braden Butler CS302, Fall, 2020
141 534.24 Christian Graham CS302, Spring, 2022
142 524.21 Reagan Austin CS302, Spring, 2022
143 508.04 Victoria Florence CS302, Fall, 2015