## Assignment 13

Plot a series of user-specified points onto an abstract board.

Concepts: Objects; constants
Textbook: 3.1, 4.1 - 4.2; 2.2

### Steps

Write a program that lets the user specify a series of points. Each point has an X and Y position, and a single character that will be used to represent that character on the screen. Use this class--BoardToken--to store the details of each point together in a single object. (You simply need to save this .java file in the same directory as your `Username13.java` for this to work.)

The plotting surface--which you can think of as a whiteboard, a game board, or just an abstract coordinate plane--should be 60 characters wide and 20 characters high. Define constants in your program (using the keyword `final`) for these two variables. (I suggest the names `WIDTH` and `HEIGHT` for these.) The default/background character for the board will be user-specified.

Therefore, your program needs to first ask for a background character. It should then continue to ask for another character to plot, including its x and y coordinates. Coordinates should start at 1 and are limited to WIDTH and HEIGHT. As always, ensure the user gives you the correct input. Then put a constructed BoardToken object for each point into a single ArrayList.

If the user enters nothing when you ask for a character to plot, stop looping.

Then, draw the WIDTH x HEIGHT board using the background character, plotting all the points entered by the user as you do so.

### Sample Output

```D:\TA\grading\A13>java ZtomaszeA13
This program plots a series of characters on a 60x20 grid.
Enter the board's background character: ' '
Error: input was not a single character.  Please try again.
Enter the board's background character:
Error: input was not a single character.  Please try again.
Enter the board's background character: *
Enter a character to display (or nothing to stop): one
Error: input was not a single character.  Please try again.
Enter a character to display (or nothing to stop): 1
Enter the x position for this character (1 - 60): 0
Error: input was not between 1 and 60. Please try again.
Enter the x position for this character (1 - 60): 1
Enter the y position for this character (1 - 20): 1
Enter a character to display (or nothing to stop): 2
Enter the x position for this character (1 - 60): 2
Enter the y position for this character (1 - 20): 2
Enter a character to display (or nothing to stop): 3
Enter the x position for this character (1 - 60): 3
Enter the y position for this character (1 - 20): 3
Enter a character to display (or nothing to stop): 4
Enter the x position for this character (1 - 60): 4\
Error: input was not an integer. Please try again.
Enter the x position for this character (1 - 60): 4
Enter the y position for this character (1 - 20): 4
Enter a character to display (or nothing to stop):
1***********************************************************
*2**********************************************************
**3*********************************************************
***4********************************************************
************************************************************
************************************************************
************************************************************
************************************************************
************************************************************
************************************************************
************************************************************
************************************************************
************************************************************
************************************************************
************************************************************
************************************************************
************************************************************
************************************************************
************************************************************
************************************************************

This program plots a series of characters on a 60x20 grid.
Enter the board's background character:
Enter a character to display (or nothing to stop): 0
Enter the x position for this character (1 - 60): 25
Enter the y position for this character (1 - 20): 5
Enter a character to display (or nothing to stop): 0
Enter the x position for this character (1 - 60): 35
Enter the y position for this character (1 - 20): 5
Enter a character to display (or nothing to stop): -
Enter the x position for this character (1 - 60): 29
Enter the y position for this character (1 - 20): 14
Enter a character to display (or nothing to stop): -
Enter the x position for this character (1 - 60): 30
Enter the y position for this character (1 - 20): 14
Enter a character to display (or nothing to stop): -
Enter the x position for this character (1 - 60): 31
Enter the y position for this character (1 - 20): 14
Enter a character to display (or nothing to stop):

0         0

---

```

### Discussion

• This is basically a combination of A11 and A12 with the addition of a simple object. However, the user input checking is a bit more complicated.
• Please construct only one Scanner! This means you don't create the Scanner within a loop or a new instance will be constructed for each input. (Making more than one Scanner will work for you, but it is inefficient and currently messes up Tamarin--though I am working on finding a way around this.)
• However, if you need to use your Scanner in more than one method, you can declare it as a static member variable (sometimes called a "global" variable) by defining it inside the class but outside/before any methods. You may want to declare other variables important to your class here--such as your constants. (Don't start declaring all your variables like this though! Only things you need to reuse in more than one method.)
• Don't forget about clearing the input stream. Remember that whenever you go from reading a number with `nextInt()` to calling `nextLine()`, there's still a `\n` left in the input stream. Therefore, you need an extra call to `nextLine()` to clear this before you can read in the actual data you want. This can also be a problem if you are calling `nextInt()` in a loop but the user enters a string--although an exception is thrown, the bad input is still in the stream and so you need to clear it out before you can successfully call `nextInt()` again.
• Whenever you find yourself cutting-and-pasting code, stop. This is a sign that you could use a method here instead (or a loop, or something that will repeat the code for you). Manually-copied code is a pain to read and a nightmare to maintain. Instead, consider how you could move the code into a method and change the parts that you would have edited after pasting to depend on a parameter or variable instead.

### What to Submit

Upload your `UsernameA13.java` file to Tamarin.
(You do not need to include `BoardToken` because Tamarin will already have a copy of it.)

### Grading [8 points]

1 - Compiles
Your program compiles successfully (no errors)
2.0 - Input
Creates only one Scanner object (0.5). Handles errors when user enters words rather than numbers or numbers out of range and keeps running (1.0). Quits if the user enters nothing for the next character to be plotted (0.5).
1.5 - Constants and object use
Defines `final` constants for the board's width and height (and so the values 60 and 20 occur in only one place in your code) (1.0). Uses BoardToken objects (in an ArrayList) to store the user-entered points (0.5).
3.5 - Board
Prints out a board of the right size (1.0) using the user-specified background character (0.5) with the user-specified points correctly plotted (2.0).

### FAQs

Demo code:
Person.java and Rolodex.java
How do I use `BoardToken.java`?
Just save the file in the same directory as your `UsernameA13.java` file. You don't need to add anything to your code; Java will find the class if it's in the same directory.
How do I print the board?
You'll need a couple nested for loops to print the board of background characters. (Start with this.) Then, inside those two loops, you'll need to loop through the list of BoardTokens each time you want to print a character to see if this is one of the points specified by the user. If it's not (you complete this inner-most loop without finding a match), then you can just print the background character instead.
What do we do if the user enters the same character as the background or multiple characters for the same position?
It's up to you. You can treat it as an error (or just give a warning) if you want to, but it's not required to do so. It's fine to let the user plot a point that's the same as the background character and just print the first BoardToken entered for a certain position on the board. However, do consider this situation because your board must be the right size, so you should only print one character for each place on the board--even if the user entered more than one.
Only the last token the user enters shows up on the board.
I've seen a few people do this now. Remember that a new object only gets created when you see the keyword `new`. This means that you must create a `new BoardToken()` every time you want to add another token to the list. So this should occur within your main loop somewhere. If it does not, then you are just changing the single BoardToken you created at the start of the program, overwriting the old data with the newest user input. Even if you add this single BoardToken to the list multiple times, all you're adding to the list is multiple references/pointers to the single object. Thus, your list `size()` may be 3, but you only have 3 "copies" of one token.

 ~ztomasze Index : TA Details: ICS111: A13 http://www2.hawaii.edu/~ztomasze Last Edited: 23 Oct 2008 ©2008 by Z. Tomaszewski.