CSCI 1320 - Assignment #8


This is the final assignment of the semester. There is no real theme to what you have to do for it. It will just exercise a fair bit of what you have learned in this class and hopefully be interesting to program.

Text Adventure:

It's time to make your map program into a true text adventure game. It doesn't matter how you do this, but you need to add in a goal to the game and have it inform the player if he/she wins or loses. Most of the original text adventure games had some type of puzzle solving where the items could interact with one another or with rooms in certain ways to make things happen. You probably don't want to go the MUD route and have equipment, combat, and the like though simple combat might be feasible. You must add a help command which prints out the objective of the game and how to play. I suggest that this reads and prints the content of a file so you don't have to type in the full help in printf statements.

Graphics Problem:

This is the assignment I've been waiting for with the graphics path. In this assignment you will use your lighting calculations and your raster to help you make a ray tracer. The general method goes like this. For each point in your raster you will "send out a ray" and see what, if anything it runs into. The closest thing it runs into is what you would see. From the point where it hits you will send out rays towards each light source. If there is something between the light source and the point then it is in shadow and that light doesn't illuminate that part of the surface so the pixel doesn't get any light from that light source. You check all the lights that way and add up the ones that aren't blocked. The way you add it up is similar to what you did in assignment #7/8, but now the point you are using isn't one of the corners, but where your original ray hit the surface.

You will simply use the code from in class or from assignment #3 to do the casting of individual rays to see if they hit something. There is more information on that here. Because the method of finding intersections is best expressed with vector notation, I'm giving you a PDF file that describes that method. I recommend that you write a function that takes as input the ray data as two points, a start point and another point on the ray and the geometry data. It will return the point on the closest surface intersected, the normal at that point, and the color of that surface. You will also want a function that specifically tells you if a given ray intersects one particular triangle (or sphere), the point where it does, and maybe the normal (though you can find that in the calling function). You might find it helpful to have a triangle structure that stores not only the three points and color, but also the normal vector just to speed things up a bit.

Your program should take one command line argument, the name of the geometry file, and should write a file called raster.txt that has the image. The raster format is the same as before and should be viewable with the Java program you have used earlier. For the geometry file, you can take either format, but if your program is executed without a file name it should say what format is expected. If you make your program handle spheres, the number of spheres and data for them should follow the triangles in the format where you give numbers of each. In the other format, lines that begin with an S will be spheres. If you don't handle spheres then just ignore those parts of the input or read them and throw it away.

Keep in mind that you can use a larger raster if you want to make nicer images and certainly try to view your raster with my viewer before turning it in. Your output doesn't have to match mine exactly, but it should look similar. You will be passing around some fairly large amounts of data. Consider using structures to keep track of some of those things.

For extra credit (and a really cool effect) try to add reflection in. If you only have "perfect" reflection, then when your first ray hits a reflective surface, you find the new ray it would be reflected to, and display whatever that would draw. Basically, you will be doing the rendering recursively. You can think about how you might do other things like making surfaces partially transparent or partially reflective as well. You could also add ambient light though I wouldn't worry about diffuse reflection because that can be a bit too much of a pain.

For help with the executable I provide below, just type the executable name and no arguments. My executable does a number of other things that can help you, such as giving you some nice functionality for building geometries. I highly recommend that if you pick this option you download that file and play with it some before beginning and use it to help you make better inputs. Most of the options for building your geometries are straight forward. My tool asks for alpha values and reflectivities for just about everyting. You can ignore these if you don't do that. If you want to do that, I store the values in the top byte of the packed rgb so you should talk to me about how to get those out for your rendering. Three of the options are things you might not understand. Option 4 constructs a very simple fractal "terrain". It does this by doing midpoint displacements on a triangle. You have to give it the bounding triangle and an original offset. The offset should be a fairly small faction of the edge length. You also tell it how many levels to go down. Don't go higher than 5. The sheet option lets you enter four points and a surface is drawn with straight edges for those point. You tell it how many subregions to break it into and if you want it to be checkered. If it is checkered you will give it two colors for the checkering. Lastly, there is an option to add a "cylinder". This is actually a prism that approximates one. You pick the center spots for the top and bottom faces and one point on the top rim then tell it how many points to use around the rims. Using 4 would give you a cube type of shape.

Also, I have put up a new JAR file with a RasterViewer that will let you save the images you make as JPG or PNG files so you can do more with them. The use is the same as for earlier assignments.

geometry file : raster file : executable : geometry file 2 : geometry file 3

Chemistry Problem:

Take the code you did for assignment #9 and make it so you find integer coefficients.

Text Skiing Game:

For this option you will write a text based action game. The game is fairly simple and has appeared in many forms over time. Your player is at the top of the screen and appears as a certain character. Something like a # works well. On either side of your character at certain distances are "walls" that can move around. They are represented by other characters. In fancy implementations they use /, \, and | for the walls depending on what direction they are moving. You see, the walls aren't straight, they shift around. There must always be a certain minimum distance between the walls so that your player can always get through. Generally a minimum of something like 3 characters works well but you might set it higher.

The game advances by having the whole thing scroll up except for your player. The player must simply avoid the walls. Both the walls and the player can either go straight or move one character to the left or right each time step. The game ends when the player runs into a wall. If you want, you could keep a score of how long the player has gone without hitting the wall.

In order to do this you have to use a library that we haven't covered yet, the curses library. You will need to include curses.h and when you compile you need to give the option -lncurses. I have provided links to more information on the curses library below. I've also provided you with sample code that will help you get up and running. The first sample program I have provided simply places a # at a random location once each second and scrolls everything up. This shows you how to use the curses functions and how to use them to print characters at specific locations as well as to scroll. The second example shows you how you could do timing and moving something around based on player input that is non-blocking. For that example the arrow keys change the direction the indicator is moving a hitting 'q' stops the program.

Curses library page

ncurses help - there seem to be some things missing in this, but it helped me get the samples working.

Drawing characters at random places and scrolling

Ski executable - use the arrow keys to move. Don't go through the walls. After downloading you might need to do "chmod a+x Ski" so you can run it.

Showing player movement with curses

Text Tron

Using the information above you could also write a game of tron lightcycles where you and an opponent draw lines and whoever hits a wall first loses. You could make a computer controlled player or have it be two player sharing a keyboard. Tron is one of the few games where you can write a computer controlled player that can be challenging to beat without too much difficulty.

Zooming Mandelbrot or Julia Set

If you implemented the X11 version of the Mandelbrot set for the last assignment this is the option for you. For this one you get to add some event handling to the last program. There are two options here. One is to make it so that the user can click and drag on the Mandelbrot to zoom in. For this to work well you probably have to give the user some way of increasing the number of iterations while it is running. The other option is to read simple clicks by the user and when the user clicks on a point in the Mandelbrot you bring up a new window and show the Julia set that corresponds to that point.

Baby Mathematica with Plotting

If you did baby mathematica in the last assignment this is an option to extend it. All you have to do is add a second plot option called graph that works like plot except that it draws the function you give it in a X11 window instead of outputting the values to file.