|
@ -1,6 +1,224 @@ |
|
|
package BattleShip; |
|
|
package BattleShip; |
|
|
|
|
|
|
|
|
import javax.swing.*; |
|
|
import javax.swing.*; |
|
|
|
|
|
import javax.swing.border.Border; |
|
|
|
|
|
import java.awt.*; |
|
|
|
|
|
import java.util.ArrayList; |
|
|
|
|
|
import java.util.*; |
|
|
|
|
|
|
|
|
public class AIGridGUI extends JPanel { |
|
|
public class AIGridGUI extends JPanel { |
|
|
|
|
|
ArrayList<BSButton> buttons = new ArrayList<BSButton>(); |
|
|
|
|
|
ArrayList<Ship> allShips = new ArrayList<Ship>(); |
|
|
|
|
|
// public ArrayList<SetShipsListener> listeners = new ArrayList<SetShipsListener>(); |
|
|
|
|
|
|
|
|
|
|
|
int[] testLocations; |
|
|
|
|
|
int numOfGuesses = 0; |
|
|
|
|
|
public String text; |
|
|
|
|
|
int rows; |
|
|
|
|
|
int columns; |
|
|
|
|
|
boolean endGame = false; |
|
|
|
|
|
boolean[] cellsGuessed; |
|
|
|
|
|
boolean[] cellsHit; |
|
|
|
|
|
boolean[] cellsKilled; |
|
|
|
|
|
boolean randomGuess = true; |
|
|
|
|
|
int f; // it is the first |
|
|
|
|
|
Color Red = new Color(100, 0, 0); // |
|
|
|
|
|
Border loweredBevel = BorderFactory.createLoweredBevelBorder(); |
|
|
|
|
|
Border defaultBorder; |
|
|
|
|
|
Ship shipToPlace; |
|
|
|
|
|
boolean vertical = false; |
|
|
|
|
|
boolean clear; |
|
|
|
|
|
boolean shipsPlaced = false; |
|
|
|
|
|
Ship destroyer = new Ship(2, "destroyer"); |
|
|
|
|
|
Ship cruiser = new Ship(3, "cruiser"); |
|
|
|
|
|
Ship submarine = new Ship(3, "submarine"); |
|
|
|
|
|
Ship battleship = new Ship(4, "battleship"); |
|
|
|
|
|
Ship aircraftCarrier = new Ship(5, "aircraft carrier"); |
|
|
|
|
|
ArrayList<Direction> directions = new ArrayList<Direction>(); |
|
|
|
|
|
Direction up = new Direction(); |
|
|
|
|
|
Direction down = new Direction(); |
|
|
|
|
|
Direction right = new Direction(); |
|
|
|
|
|
Direction left = new Direction(); |
|
|
|
|
|
|
|
|
|
|
|
public AIGridGUI(int r, int c) { |
|
|
|
|
|
|
|
|
|
|
|
rows = r; |
|
|
|
|
|
columns = c; |
|
|
|
|
|
|
|
|
|
|
|
//Create arrays to keep track of which cells have been guessed, hit, and killed/sunk. |
|
|
|
|
|
|
|
|
|
|
|
cellsGuessed = new boolean[(rows * columns)]; |
|
|
|
|
|
cellsHit = new boolean[(rows * columns)]; |
|
|
|
|
|
cellsKilled = new boolean[(rows * columns)]; |
|
|
|
|
|
for(int i = 0; i < (rows * columns); i++) { |
|
|
|
|
|
cellsGuessed[i] = false; |
|
|
|
|
|
cellsHit[i] = false; |
|
|
|
|
|
cellsKilled[i] = false; |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
//Add all ships to an ArrayList to allow for cycling through all ships. |
|
|
|
|
|
|
|
|
|
|
|
allShips.add(destroyer); |
|
|
|
|
|
allShips.add(cruiser); |
|
|
|
|
|
allShips.add(submarine); |
|
|
|
|
|
allShips.add(battleship); |
|
|
|
|
|
allShips.add(aircraftCarrier); |
|
|
|
|
|
|
|
|
|
|
|
//Add all directions to an ArrayList to allow for comparing and sorting directions. |
|
|
|
|
|
|
|
|
|
|
|
directions.add(up); |
|
|
|
|
|
directions.add(down); |
|
|
|
|
|
directions.add(right); |
|
|
|
|
|
directions.add(left); |
|
|
|
|
|
|
|
|
|
|
|
//Make grid that consists of r rows and c columns of buttons. |
|
|
|
|
|
|
|
|
|
|
|
GridLayout g = new GridLayout(rows,columns); |
|
|
|
|
|
this.setLayout(g); |
|
|
|
|
|
|
|
|
|
|
|
for(int i = 0; i < (rows * columns); i++) { |
|
|
|
|
|
BSButton b = new BSButton(); |
|
|
|
|
|
b.setGridLocation(i); |
|
|
|
|
|
buttons.add(b); |
|
|
|
|
|
this.add(b); |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
defaultBorder = buttons.get(0).getBorder(); |
|
|
|
|
|
} |
|
|
|
|
|
public void autoPlaceShips() { |
|
|
|
|
|
|
|
|
|
|
|
//If ships are to be placed automatically, randomly place each ship. |
|
|
|
|
|
|
|
|
|
|
|
for(Ship s : allShips) { |
|
|
|
|
|
int shipLength = s.getLength(); |
|
|
|
|
|
int clearSpace = 0; |
|
|
|
|
|
testLocations = new int[shipLength]; |
|
|
|
|
|
|
|
|
|
|
|
//Randomly select starting position to place ship and check if sufficient space to place ship. |
|
|
|
|
|
|
|
|
|
|
|
while(clearSpace < shipLength) { |
|
|
|
|
|
|
|
|
|
|
|
//Randomly choose whether to place ship vertically or horizontally and choose location of ship. |
|
|
|
|
|
|
|
|
|
|
|
boolean vert = new Random().nextBoolean(); |
|
|
|
|
|
int x; |
|
|
|
|
|
int y; |
|
|
|
|
|
|
|
|
|
|
|
if(vert) { |
|
|
|
|
|
|
|
|
|
|
|
x = (int) (Math.random() * (columns)); |
|
|
|
|
|
y = (int) (Math.random() * (rows - shipLength)); |
|
|
|
|
|
for(int i = 0; i < shipLength; i++) { |
|
|
|
|
|
testLocations[i] = x + (columns*(y+i)); |
|
|
|
|
|
} |
|
|
|
|
|
} else { |
|
|
|
|
|
x = (int) (Math.random() * (columns - shipLength)); |
|
|
|
|
|
y = (int) (Math.random() * (rows)); |
|
|
|
|
|
for(int i = 0; i < shipLength; i++) { |
|
|
|
|
|
testLocations[i] = x + i + (columns*y); |
|
|
|
|
|
} |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
//Check if the location is clear. |
|
|
|
|
|
|
|
|
|
|
|
clearSpace = 0; |
|
|
|
|
|
for(int i = 0; i < shipLength; i++) { |
|
|
|
|
|
if(buttons.get(testLocations[i]).getCellContents() == null) { |
|
|
|
|
|
clearSpace++; |
|
|
|
|
|
} |
|
|
|
|
|
} |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
//Set the contents of the chosen cells to contain the ship. |
|
|
|
|
|
|
|
|
|
|
|
for(int i = 0; i < shipLength; i++) { |
|
|
|
|
|
buttons.get(testLocations[i]).setCellContents(s); |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
testLocations = null; |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
//Mark all cells containing a ship and disable all cells in the grid. |
|
|
|
|
|
|
|
|
|
|
|
for (BSButton bsb : buttons) { |
|
|
|
|
|
if(bsb.getCellContents() != null) { |
|
|
|
|
|
bsb.setBackground(Color.blue); |
|
|
|
|
|
bsb.setBorder(loweredBevel); |
|
|
|
|
|
} |
|
|
|
|
|
bsb.setEnabled(false); |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
text = "Ready to start the game."; |
|
|
|
|
|
shipsPlaced = true; |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
public boolean getEndGame() { |
|
|
|
|
|
|
|
|
|
|
|
return endGame; |
|
|
|
|
|
} |
|
|
|
|
|
public void go() { |
|
|
|
|
|
//Play a turn by making a guess at a cell. |
|
|
|
|
|
|
|
|
|
|
|
int guessLocation = 0; |
|
|
|
|
|
boolean gameOver = true; |
|
|
|
|
|
numOfGuesses++; |
|
|
|
|
|
BSButton b = null; |
|
|
|
|
|
Ship s = null; |
|
|
|
|
|
boolean killed = false; |
|
|
|
|
|
boolean isClear = false; |
|
|
|
|
|
|
|
|
|
|
|
if(randomGuess) { |
|
|
|
|
|
//Find out the maximum ship length of the surviving ships. |
|
|
|
|
|
int minClearSpace = 0; |
|
|
|
|
|
for(Ship sh : allShips) { |
|
|
|
|
|
if(!sh.isKilled() && sh.getLength() > minClearSpace) { |
|
|
|
|
|
minClearSpace = sh.getLength(); |
|
|
|
|
|
} |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
//Create an array of all possible cells and shuffle the order of the cells. Potential guesses are drawn from this array. |
|
|
|
|
|
|
|
|
|
|
|
int[] guesses = new int[(rows * columns)]; |
|
|
|
|
|
for(int i = 0; i < rows * columns; i++) { |
|
|
|
|
|
guesses[i] = i; |
|
|
|
|
|
} |
|
|
|
|
|
Random rand = new Random(); |
|
|
|
|
|
for(int i = 0; i < guesses.length; i++) { |
|
|
|
|
|
int randInt = rand.nextInt(guesses.length); |
|
|
|
|
|
int randGuess = guesses[randInt]; |
|
|
|
|
|
guesses[randInt] = guesses[i]; |
|
|
|
|
|
guesses[i] = randGuess; |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
int numCellsTried = 0; |
|
|
|
|
|
|
|
|
|
|
|
//Test potential guesses and mark clear if criteria met. |
|
|
|
|
|
while(!isClear && numCellsTried < guesses.length) { |
|
|
|
|
|
guessLocation = guesses[numCellsTried]; |
|
|
|
|
|
numCellsTried++; |
|
|
|
|
|
|
|
|
|
|
|
//If the cell has not already been guessed, test whether there are enough clear spaces in at least one direction. |
|
|
|
|
|
if(!cellsGuessed[guessLocation]) { |
|
|
|
|
|
|
|
|
|
|
|
int u = guessLocation; |
|
|
|
|
|
int upCount = -1; |
|
|
|
|
|
while(u >= 0 && !cellsHit[u]) { |
|
|
|
|
|
u = moveUp(u); |
|
|
|
|
|
upCount++; |
|
|
|
|
|
} |
|
|
|
|
|
} |
|
|
|
|
|
} |
|
|
|
|
|
} |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
//Return the location of a cell one space in the given direction, or return -1 if out of bounds. |
|
|
|
|
|
|
|
|
|
|
|
public int moveUp(int u) { |
|
|
|
|
|
int dirUp = u - columns; |
|
|
|
|
|
if(dirUp < 0) { |
|
|
|
|
|
return -1; |
|
|
|
|
|
} else { |
|
|
|
|
|
return dirUp; |
|
|
|
|
|
} |
|
|
|
|
|
} |
|
|
} |
|
|
} |