- Learn to collaborate on programming tasks and integrate work in git.
- Reinforce good programming practices with respect to functions, pointers, libraries, data structures, input sanitation, and debugging with gdb.
- Gain experience with gnuplot and automatic plotting from C code.
- Have fun programming a game with intermediate results plotted to keep score.
Gnuplot is linux application, and as the name suggest is used for plotting data. It offers several customizable features and is very easy to use. In the first part of this lab, we focus on basic plotting with gnuplot. To start the interactive use of gnuplot, type gnuplot at the terminal. As the first step, we want to set how we want the plots to be generated. For this lab instructions, we use .png as the default output for our plots.
gnuplot> set terminal png gnuplot> set output 'plot.png'
The above command sets the desired output format to .png and the name of our generated plot will be plot.png.
In our first graph we want to plot a sine and a cosine functions. Therefore, we specify our functions and plot them.
gnuplot> a = 1.3 gnuplot> f(x) = a * sin(x) gnuplot> g(x) = a * cos(x) gnuplot> plot [0:10] f(x) title 'sin(x)' with lines linestyle > g(x) notitle w l ls 2
The definitions of functions in gnuplot are straight forward. We want to plot more than one function thats why we have to divide the two commands with a comma. The backslash tells gnuplot that we have a line break at this position. We can also abbreviate commands (“w” for with, etc.). The result of the command is shown in Figure 12.1.
We can also gnuplot in non interactive mode by saving the plotting commands to a file.
For example, to plot the sine and cosine functions, create a new file named simpleplots.gp with the following contents.
a = 0.9 b = 1.3 f(x) = a * sin(x) g(x) = b * cos(x) plot [0:10] f(x) title 'sin(x)' with lines linestyle 1, \ g(x) title 'cos(x)' w l ls 2
Run gnuplot with the above file by calling the below command from the terminal.
Plotting data, e.g., results of calculations or measurements, using gnuplot works the same way as plotting functions. We need a data file and commands to manipulate the data. Let’s start with the basic plotting of simple data. A data file can be a plain text file containing the data points as columns. Create a file with the data below and save it as dataplot.dat
# dataplot.dat # X Y Z 1. 1. 1. 2. 4. 8. 3. 9. 27. 4. 16. 64. 5. 25. 125.
A line starting with ‘#’ is a comment and is ignored by gnuplot. A command to plot the data in the files is
gnuplot> plot 'dataplot.dat' using 1:2 with linespoints, \ > '' u 1:3 w lp
The above command will generate a plot as shown in Figure 12.2.
- gnuplot can print text-based pictures to your terminal - useful for monitoring a running program or development
- The slides linked above have an example of using color maps this will be helpful for the project this week
- By exporting snapshots of the data being plotted, then combining the images, you can make animation of your data!
It is possible to run all linux commands, and other programs from within a C program. For example, we can call ‘ls’ from within a C program to get the contents of the directory from where the C program is running. You can run anything in linux from your C code! In C, the two most popular commands that allows us to make system calls are system() and popen().
Using system(), we can execute any command that can run on terminal if operating system allows. For details and usage of the system() command, refer to the man page for system.
The popen() function is closely related to the system function. It executes the command as a subprocess. However, instead of waiting for the command to complete, it returns a file pointer to the stream containing the output of that command. For details and usage of popen() command, refer to the man page of popen.
The object of the drone surveillance game is to guide a drone to survey the most of a square grid world.
The agents begin in a random location of the grid-world and can see every adjacent square, forming a 3-by-3 “vision” matrix centered around them. Cell’s with a value of 1 contain obstacles and cannot be entered.
On each turn, the agent function is called with a structure containing the current vision matrix and information about the challenge to be solved. If the agent answers the challenge correctly, it is allowed to move.
Moves are indicated by the numbers 1-4 corresponding to the cardinal directions, beginning with north and proceeding clockwise. So to move south, and agent would return ‘3’ and to move west it would return ‘4’. An agent only moves if they correctly answer the challenge and request a valid move (not into an obstacle).
The game engine tracks all cells that have been seen by an agent; the agent that has surveyed the plurality of the gird-world by the end of the final round wins. The number of rounds and size of the world can be altered by command-line arguments.
The main function of the program is included in the compiled libsimulation.a library, you do not need to include one in your code. By modifying the DroneWars.c code and utilizing the DroneWars.h header, you will write:
- Two “agent” functions that take in a header defined structure with game information, place the required data at a location pointed to by the answer pointer, and then return their desired move
- A display function that takes 2 file pointers to the map of the agent’s explored area and uses gnuplot to display a map (either in the console or by producing image files) with obstacle cells colored differently then free cells.
Much of the meat of this exercise comes from determining how to interface with the game from the header file - navigating the structures, unions, enums and pointers that it entails.
You have a partner, the internet, your classmates, textbooks and a TA available as resources
- make good use of these.
Calculation Given a string of a mathematical expression, return the integer value (Hint: Use popen())
Sub-String Given 2 strings, return a pointer to the beginning of the first occurrence of that string (Hint: Use strstr())
Range Given two integers, return the range between them as an integer
Mean Given an array of floats and the number of floats in the array, return the arithmetic mean as a float
Minimum Given an array of floats and the number of floats in the array, return the minimum value as a float
Maximum Given an array of floats and the number of floats in the array, return the maximum value as a float
Reverse Given a string, return a string that is the reverse (Hint: Use strlen())
Find Given a string and a char, return the integer index of the position of the first occurrence (Hint: Use memchr)
Tokenize Given a string, tokenize it by whitespace and return a pointer to a malloced 1-D array of the token strings.
To assist with research into topics not previously covered, the following key-words are provided:
- Void Pointers
- C Unions
When finished, submit a pull-request with your code filled into DroneWars.c and any additional files you need along with a LATEXreport detailing things you learned and difficulties you encountered working through the lab.
There are bonus-points available for groups that use gnuplot to make animations of their agents searches.