//********************************************************
//* Program #2 and 6 *
//* Author: Paul Adcock *
//* Last Modified 4/21/10 *
//* Battleship program *
//********************************************************
// This program is supposed to prompt the user to enter an x and y value and
// also to enter a -1 for either if they want to quit and see where the battleship
// is. It returns a M for miss, for a hit, "You sunk my battleship!" and a A and
// "already shot here, try again." message if already shot there. It also should
// stop asking the user for info once either the user enters -1 or if the user hits
// the battleship. It also returns the number of shots fired. It has fixed the old
// problem with it setting it to miss again the third time if it was already shot there
// twice and the shot counter error was fixed. This program checks for exceptions for both
// n, the size of the grid, and the x and y values. It won't let the grid be smaller than 1
// or larger than 50. It also will not abort if the user enters a non-integer value.
// What it does is tell them to enter an integer that is at least 1 or less than 51
// till they get it right. Also, the program now exits when the battleship is hit.
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.JFrame;
import javax.swing.JDialog;
import javax.swing.JPanel;
import java.awt.Graphics;
import javax.swing.ImageIcon;
import java.util.*;
import java.io.*;
import java.awt.Component;
public class battleshipGame7
{ // beginning of program
static Scanner console = new Scanner(System.in);
public static void main( String[] args)
{ // beginning of main method
// TODO Auto-generated method stub
JFrame frame = new JFrame();
int x = 0; // x value inputted by user
int y = 0; // y value inputted by user
int n = 1; // size of array inputted by user
// and if it is in bounds
boolean enteredNegativeOne;
boolean isHit;
boolean thisWorks;
float gamesPlayed = 0;
float percentWon = 0;
float gamesWon = 0;
float gamesLost = 0;
thisWorks = false;
boolean endGame = false;
while (endGame == false)
{
System.out.println("Please enter an positive integer no smaller than"
+ " one and no greater than 50. ");
System.out.println("An integer is not a decimal like 1.234 . ");
System.out.println("When using the program, the first row and first "+
"column, start at 0, so enter 0,0 for column one"
+ " row one. ");
System.out.println("Don't have the comma. Enter 0 for x and 0 for y "
+ "to get column one row one. ");
System.out.println();
thisWorks = false;
while (thisWorks == false)
{ // beginning of while
try
{ // beginning of try
System.out.println ("Enter the size of the grid. ");
n = console.nextInt();
if (n < 1) // combines negative array and out of bounds exceptions
throw new MyOutOfBoundsException() ; // needs to be thrown to be able to catch MyOutOfBoundsException
if (n > 50) // exception that won't let n be greater than 50, though the computer can handle about 5700.
throw new MyTooBigException(); // needs to be thrown to be able to catch MyTooBigException
thisWorks = true; // will set thisWorks to true no exceptions are thrown.
} // end of try
catch ( MyOutOfBoundsException moobe)
{ // beginning of catch
System.out.println("Enter a value that is an integer and"
+ " greater than 0" +"\n " + moobe.toString() );
} // end of catch
catch ( MyTooBigException mtbe)
{ // beginning of catch
System.out.println("Enter a value that is an integer and"
+ " no greater than 50 " +"\n " + mtbe.toString() );
} // end of catch
catch (InputMismatchException imeRef )
{ // beginning of catch
System.out.println( "Enter a value"
+" that is an integer, i.e. not a decimal " +
"\n" + imeRef.toString());
} // end of catch
} // end of while
char[][]arraySize = new char[n][n]; // creates an array of n by n
System.out.println("Enter a x and a y" );
System.out.println("Enter a -1 to show battleship and exit program. ");
int shots; // declares shots
shots = 0; // sets shots initially to 0
enteredNegativeOne = false; // sets enteredNegative initially to false
isHit = false; // sets isHit initially to false;
boolean thisWorks2; //boolean variable to check if x coordinate is an integer within specified range
boolean thisWorks3;// boolean variable to check if y coordinate is an integer within specified range
placeBattleship(arraySize);
while(enteredNegativeOne == false && isHit == false) // executes while user continues to input x and y values.
{ // beginning of while loop
thisWorks2 = false; // keeps resetting thisWorks2 to false so it won't
// only go through the catch once and then be true
// and cause a mysterious infinite loop
thisWorks3 = false; // keeps resetting thisWorks3 to false so it won't
// only go through the catch once and then be true
// and cause a mysterious infinite loop
// while loop will keep asking for x values till an integer within the given
// bounds is entered. After getting the y coordinate, if it isn't a hit, thisWorks2
// will be set to false again after 1 is added to shots. It returns a message telling the
// user to enter an integer if they don't enter the right type of value and also the type of exception.
while (thisWorks2 == false)
{ // beginning of while loop
try
{ // beginning of try
System.out.println("Enter an x value. ");
x = console.nextInt();
thisWorks2 = true;
} // end of try
catch (InputMismatchException imeRef )
{ // beginning of catch
System.out.println( "Enter a value"
+" that is an integer, i.e. not a decimal " +
"\n" + imeRef.toString());
} // end of catch
} // end of while
// while loop will keep asking for y values till an integer within the given
// bounds is entered. If it isn't a hit, thisWorks3 will be set to false again after 1 is added to shots.
// It returns a message telling the user to enter an integer if they don't enter the right type of value and
// also telling them the type of exception.
while(thisWorks3 == false)
{ // beginning of while
try
{ // beginning of try
System.out.println("Enter a y value. ");
y = console.nextInt();
thisWorks3 = true;
} // end of try
catch (InputMismatchException imeRef )
{ // beginning of catch
System.out.println( "Enter a value"
+" that is an integer, i.e. not a decimal " +
"\n" + imeRef.toString());
} // end of catch
} // end of while
shots = shots + 1;
if (x == -1 || y == -1) // if user enters a -1 for either x or y, ends program
// it also shows location of battleship and displays
// number of shots fired.
{ // beginning of if statement
enteredNegativeOne = true;
System.out.println("Game over");
System.out.println("Shots: " + shots);
printArray(arraySize);
gamesPlayed = gamesPlayed + 1;
percentWon = (gamesWon/gamesPlayed) * 100;
gamesLost = gamesPlayed - gamesWon;
System.out.printf( "Games Played: " + "%.0f" , gamesPlayed);
System.out.println();
System.out.printf("Games Won: " + "%.0f", gamesWon);
System.out.println();
System.out.printf("Games Lost: " + "%.0f", gamesLost);
System.out.println();
System.out.printf("Percent Won: " + "%.0f", percentWon);
System.out.println();
Object[] options2 = {"No",
"Yes"};
int m = JOptionPane.showOptionDialog(frame,
"Play again?",
"Do you want to play again?",
JOptionPane.YES_NO_OPTION,
JOptionPane.QUESTION_MESSAGE,
null, options2, options2[0]);
// creates Yes and Continue playing butons buttons.
// if Yee button is clicked, sends output "You quit." as heading and sends a message "Adiós!" and exits when
// user clicks OK on dialog box
if (m == JOptionPane.YES_OPTION)
{ // beginning of if
endGame = true;
isHit = false;
System.exit(0);
} // end of if
// changes the string the standard dialog box for the No button but still uses its predefined return value. If user clicks on
// Continue Playing, sends title "Ok don't quit then." and the message "Whatever." and takes the user back to the grid.
else if ( m == JOptionPane.NO_OPTION)
{ // beginning of else if
endGame = false;
isHit = true;
} // end of else if
} // end of if statement
else if ((x < 0 || x > arraySize.length -1)||
(y < 0 || y > arraySize.length -1)) // this loop executes if user enters value of out bounds
{ // beginning of else if statement // and not equal to -1.
System.out.println("Enter a valid x and y value ");
} //end of else if statement
else // executes if user is in bounds. Adds up shots and updates array.
{ // beginning of else statement
if (Fire(x, y, shots, arraySize) == 'H')
{ // beginning of if statement
gamesPlayed = gamesPlayed + 1;
gamesWon = gamesWon + 1;
percentWon = (gamesWon/gamesPlayed) * 100;
gamesLost = gamesPlayed - gamesWon;
System.out.printf( "Games Played: " + "%.0f" , gamesPlayed);
System.out.println();
System.out.printf("Games Won: " + "%.0f", gamesWon);
System.out.println();
System.out.printf("Games Lost: " + "%.0f", gamesLost);
System.out.println();
System.out.printf("Percent Won: " + "%.0f", percentWon);
System.out.println();
isHit = true;
printArray(arraySize);
Object[] options = {"No",
"Yes"};
int r = JOptionPane.showOptionDialog(frame,
"Play again?",
"Do you want to play again?",
JOptionPane.YES_NO_OPTION,
JOptionPane.QUESTION_MESSAGE,
null, options, options[0]);
// creates Yes and Continue playing butons buttons.
// if Yee button is clicked, sends output "You quit." as heading and sends a message "Adiós!" and exits when
// user clicks OK on dialog box
if (r == JOptionPane.YES_OPTION)
{ // beginning of if
endGame = true;
isHit = true;
System.exit(0);
} // end of if
// changes the string the standard dialog box for the No button but still uses its predefined return value. If user clicks on
// Continue Playing, sends title "Ok don't quit then." and the message "Whatever." and takes the user back to the grid.
else if (r == JOptionPane.NO_OPTION)
{ // beginning of else if
endGame = false;
} // end of else if
} // end of if statement
else
isHit = false;
if (isHit == false)
System.out.println("Enter a x and y value. ");
} // end of else statement
}//ends while loop
} // end of while
}// ends main method
// the method placeBattleship, places the battleship by randomly choosing an
// x and y coordinate and storing a 'B' there. The 'B' is not displayed to
// the user unless the user enters -1. It takes the array as a parameter and
// should return nothing. This method sets the location of the battleship.
private static void placeBattleship(char arraySize[][])
{
int valueOne, valueTwo;
valueOne= (int) ( 1 + (Math.random() * arraySize.length - 1 ));
valueTwo = (int) ( 1 + (Math.random() * arraySize.length - 1));
arraySize[valueOne][valueTwo] = 'B';
} //end of method placeBattleship
//This is method Fire. It returns a char. Either a M for miss, a H for hit
// or an A for already shot there. It takes the array and the user's x and y
// values as parameters.
public static char Fire( int x, int y, int shots,
char arraySize[][])
{ // beginning of method Fire
// IntClass intShotObj = new IntClass(0); this would be necessary if I needed to use IntClass
// to somehow get the value of shots for Miss and Already Shot.
// IntClass intShotObj2 = new IntClass();
if (arraySize[x][y] == 'B') // if battleship is hit return H and end game
{ // beginning of if statement
arraySize[x][y] = 'H';
System.out.println("You've sunk my battleship! ");
System.out.println("Game over! ");
System.out.println("Shots: " + shots);
System.out.println();
return ('H');
} // end of if statement
else if (arraySize[x][y] == 'M') // this is else if
// because it could also
// be just a miss.
{ // beginning of else if statement
System.out.println("Previously selected, try again ");
arraySize[x][y] = 'A';
return ('A');
} // end of else if statement
else if (arraySize[x][y] == 'A') // makes sure it won't set an A to an M again.
{ // beginning of else if
System.out.println("Previously selected, try again ");
arraySize[x][y] = 'A';
// intShotObj.addToNum(1); This would be used to add one to get
// intShotObj to get from its original value and keep adding one to it till
// I hit the battleship. I still don't know how to do that, but I found a better way.
return ('A');
} // end of else if
else
{ // beginning of else statement
arraySize[x][y] = 'M';
System.out.println("Miss"); // this is an else statement because if it
return ('M'); // isn't already shot and it isn't a hit
// then it must be a miss.
} // end of else statement
} // end of method fire
/*this method makes it easier than having to just use a for loop every time to
get it to keep printing the array. This is method printArray. It should just
have a nested for loop. It takes the array as a parameter. */
public static void printArray(char [][]arraySize)
{ // beginning of method printArray
int x;
int y;
for (x = 0; x < arraySize.length; x++)
{ // beginning of for loop
for ( y = 0; y < arraySize[x].length; y++)
System.out.print( arraySize[x][y]);
System.out.println();
} // end of for loop
} //end of method printArray
} // end program