306 lines
10 KiB
Java
306 lines
10 KiB
Java
package Client;
|
|
|
|
import javax.sound.sampled.*;
|
|
import java.io.*;
|
|
import java.net.Socket;
|
|
import java.net.URL;
|
|
import java.util.*;
|
|
import Client.utils.AnsiColor;
|
|
|
|
public class Client {
|
|
private static final String SPACING = " ";
|
|
private static final String IP_ADDRESS = "127.0.0.1";
|
|
private static final int PORT_NUMBER = 3737;
|
|
static final int SIZE = 10;
|
|
static final Random rand = new Random();
|
|
|
|
private final Socket clientSocket;
|
|
BattleShipCell[][] playerBoard;
|
|
BattleShipCell[][] enemyBoard;
|
|
|
|
static int lastEnemyRow;
|
|
static int lastEnemyCol;
|
|
|
|
|
|
volatile boolean isBoardSet = false;
|
|
boolean isTurn = false;
|
|
volatile boolean otherPlayerJoined = false;
|
|
DataOutputStream out;
|
|
|
|
public Client(Socket clientSocket) {
|
|
this.clientSocket = clientSocket;
|
|
|
|
try {
|
|
//TODO: initialize out
|
|
this.out = new DataOutputStream(clientSocket.getOutputStream());
|
|
//TODO: create a ClientNetworkReceiver
|
|
//TODO: start it in another thread
|
|
|
|
System.out.println("Enter Username: ");
|
|
Scanner usernameScanner = new Scanner(System.in);
|
|
|
|
String username = usernameScanner.next();
|
|
sendUsername(username);
|
|
initializeBoards();
|
|
|
|
System.out.println("Waiting for the other player to join");
|
|
while(!otherPlayerJoined)
|
|
{
|
|
Thread.onSpinWait();
|
|
}
|
|
|
|
printBoards();
|
|
while(true)
|
|
{
|
|
while(!isTurn)
|
|
{
|
|
Thread.onSpinWait();
|
|
}
|
|
|
|
System.out.println("Your Turn Now!");
|
|
BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
|
|
Scanner scanner = new Scanner(System.in);
|
|
|
|
lastEnemyRow = -1;
|
|
lastEnemyCol = -1;
|
|
|
|
while (lastEnemyRow < 0 || lastEnemyRow >= 10 || lastEnemyCol < 0 || lastEnemyCol >= 10) {
|
|
System.out.println("Type Row and Column (e.g., A1):");
|
|
|
|
String input = scanner.nextLine().trim().toUpperCase();
|
|
|
|
if (input.matches("^[A-J]([1-9]|10)$")) {
|
|
lastEnemyCol = input.charAt(0) - 'A';
|
|
lastEnemyRow = Integer.parseInt(input.substring(1)) - 1;
|
|
|
|
if (lastEnemyRow >= 0 && lastEnemyRow < 10 && lastEnemyCol >= 0 && lastEnemyCol < 10) {
|
|
System.out.println("You selected Row: " + (lastEnemyRow + 1) + ", Column: " + (char)('A' + lastEnemyCol));
|
|
} else {
|
|
System.out.println("Invalid input! Row must be between 1 and 10, and Column must be between A and J.");
|
|
lastEnemyRow = -1;
|
|
lastEnemyCol = -1;
|
|
}
|
|
} else {
|
|
System.out.println("Invalid format! Please enter a valid input like A1, B10, J5.");
|
|
}
|
|
}
|
|
|
|
System.out.println("Move is being sent. Waiting for processing");
|
|
attack();
|
|
}
|
|
} catch (IOException e) {
|
|
System.out.println("Could not connect to the server!\n\n");
|
|
}
|
|
}
|
|
|
|
//Actions
|
|
private void attack() {
|
|
//TODO: send attack message to server
|
|
isTurn = false;
|
|
}
|
|
private void sendUsername(String username) throws IOException {
|
|
//TODO: send username to server
|
|
}
|
|
public void setEnemyResult(boolean hit, String shipName) {
|
|
enemyBoard[lastEnemyRow][lastEnemyCol].setEnemyShip(hit);
|
|
enemyBoard[lastEnemyRow][lastEnemyCol].setMarked(true);
|
|
printBoards();
|
|
playSound((hit?"hit_sound.wav":"miss_sound.wav"));
|
|
System.out.println((hit?"You hit the target!":"You missed!"));
|
|
}
|
|
public void setPlayerNumber(int i) {
|
|
if(i == 0) isTurn = true;
|
|
}
|
|
public void setOtherPlayerJoined() {
|
|
otherPlayerJoined = true;
|
|
}
|
|
public void finishGame(boolean won){
|
|
//TODO:
|
|
}
|
|
public String getHit(int row, int col){
|
|
String message = "";
|
|
playerBoard[row][col].setMarked(true);
|
|
String sankBattleShipName = "NONE";
|
|
if(playerBoard[row][col].isShip() && playerBoard[row][col].getBattleShip().isAllHit()){
|
|
sankBattleShipName = playerBoard[row][col].getBattleShip().getType();
|
|
}
|
|
message = playerBoard[row][col].isShip() ? ("HIT," + sankBattleShipName) : "MISS,NONE";
|
|
printBoards();
|
|
boolean hit = playerBoard[row][col].isShip();
|
|
System.out.println((hit?"They hit a target!":"They missed!"));
|
|
try {
|
|
Thread.sleep(1000);
|
|
} catch (InterruptedException e) {
|
|
|
|
}
|
|
isTurn = true;
|
|
return message;
|
|
}
|
|
private static void playSound(String soundFileName) {
|
|
try {
|
|
// Load the sound file from the resources folder
|
|
URL soundFileURL = Client.class.getClassLoader().getResource( soundFileName);
|
|
|
|
if (soundFileURL == null) {
|
|
System.out.println("Sound file not found: " + soundFileName);
|
|
return;
|
|
}
|
|
|
|
AudioInputStream audioStream = AudioSystem.getAudioInputStream(soundFileURL);
|
|
Clip clip = AudioSystem.getClip();
|
|
clip.open(audioStream);
|
|
clip.start();
|
|
} catch (UnsupportedAudioFileException | IOException | LineUnavailableException e) {
|
|
System.out.println("Error playing sound: " + e.getMessage());
|
|
}
|
|
}
|
|
|
|
//Board
|
|
public void initializeBoards() {
|
|
playerBoard = createBoard();
|
|
enemyBoard = new BattleShipCell[SIZE][SIZE];
|
|
for (int i = 0; i < SIZE; i++) {
|
|
for (int j = 0; j < SIZE; j++){
|
|
enemyBoard[i][j] = new BattleShipCell();
|
|
}
|
|
}
|
|
isBoardSet = true;
|
|
}
|
|
public void printBoards() {
|
|
clearScreen();
|
|
|
|
System.out.printf(" %-40s%s%-40s%n", "PLAYER BOARD", SPACING ," ENEMY BOARD");
|
|
|
|
printColumnHeaders();
|
|
System.out.print(SPACING);
|
|
printColumnHeaders();
|
|
System.out.println();
|
|
|
|
for (int row = 0; row < SIZE; row++) {
|
|
printRowSeparator();
|
|
System.out.print(SPACING);
|
|
printRowSeparator();
|
|
System.out.println();
|
|
|
|
printRowContent(playerBoard[row], row);
|
|
System.out.print(SPACING);
|
|
printRowContent(enemyBoard[row], row);
|
|
System.out.println();
|
|
}
|
|
|
|
printRowSeparator();
|
|
System.out.print(SPACING);
|
|
printRowSeparator();
|
|
System.out.println();
|
|
}
|
|
private void clearScreen() {
|
|
for (int i = 0; i < 20; i++) {
|
|
System.out.println();
|
|
}
|
|
}
|
|
private void printColumnHeaders() {
|
|
System.out.print(" ");
|
|
for (char c : "ABCDEFGHIJ".toCharArray()) {
|
|
System.out.print(AnsiColor.CYAN + " " + c + " " + AnsiColor.RESET);
|
|
}
|
|
}
|
|
private void printRowSeparator() {
|
|
System.out.print(AnsiColor.BORDER + " +" + AnsiColor.RESET);
|
|
for (int i = 0; i < SIZE; i++) {
|
|
System.out.print(AnsiColor.BORDER + "---+" + AnsiColor.RESET);
|
|
}
|
|
}
|
|
private void printRowContent(BattleShipCell[] rowData, int rowNum) {
|
|
System.out.printf(AnsiColor.BORDER +"%2d |" + AnsiColor.RESET, rowNum + 1);
|
|
for (BattleShipCell cell : rowData) {
|
|
System.out.printf( " %s " , cell);
|
|
System.out.print(AnsiColor.BORDER +"|" + AnsiColor.RESET);
|
|
}
|
|
}
|
|
public BattleShipCell[][] createBoard() {
|
|
BattleShipCell[][] board = new BattleShipCell[SIZE][SIZE];
|
|
|
|
// Initialize grids with water
|
|
for (int i = 0; i < SIZE; i++) {
|
|
for (int j = 0; j < SIZE; j++) {
|
|
board[i][j] = new BattleShipCell(); // water
|
|
}
|
|
}
|
|
|
|
for (Map.Entry<String, Integer> entry : BattleShip.ships.entrySet()) {
|
|
BattleShip battleShip = new BattleShip(entry.getKey());
|
|
placeShip(board, battleShip);
|
|
}
|
|
return board;
|
|
}
|
|
public static void placeShip(BattleShipCell[][] board, BattleShip battleShip) {
|
|
boolean placed = false;
|
|
|
|
while(!placed)
|
|
{
|
|
boolean horizontal = rand.nextBoolean();
|
|
int row = rand.nextInt(SIZE);
|
|
int col = rand.nextInt(SIZE);
|
|
placed = tryPlace(board, row, col, horizontal, battleShip);
|
|
}
|
|
|
|
}
|
|
private static boolean tryPlace(BattleShipCell[][] board, int row, int col, boolean horizontal, BattleShip battleShip) {
|
|
|
|
int length = battleShip.getLength();
|
|
if(horizontal && col + length <= SIZE)
|
|
{
|
|
for(int i = 0; i < length; i++)
|
|
{
|
|
if(board[row][col + i].isShip())
|
|
{
|
|
return false;
|
|
}
|
|
}
|
|
for(int i = 0; i < length; i++)
|
|
{
|
|
board[row][col + i].setBattleShip(battleShip);
|
|
}
|
|
return true;
|
|
}
|
|
|
|
if(!horizontal && row + length <= SIZE)
|
|
{
|
|
for(int i = 0; i < length; i++)
|
|
{
|
|
if(board[row + i][col].isShip())
|
|
{
|
|
return false;
|
|
}
|
|
}
|
|
for(int i = 0; i < length; i++)
|
|
{
|
|
board[row + i][col].setBattleShip(battleShip);
|
|
battleShip.addShipCell(board[row + i][col]);
|
|
}
|
|
return true;
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
public static void main(String[] args) throws IOException {
|
|
Socket clientSocket = null;
|
|
//TODO: get IP_Address
|
|
|
|
try {
|
|
//initialize clientSocket
|
|
//initialize Client
|
|
} finally {
|
|
try {
|
|
if (clientSocket != null) {
|
|
clientSocket.close();
|
|
}
|
|
} catch (IOException e) {
|
|
System.out.println("Error closing resources: " + e.getMessage());
|
|
}
|
|
}
|
|
}
|
|
|
|
}
|