Compare commits
10
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
65fb68c233 | ||
|
|
b3237169d6 | ||
|
|
f95cf6e7ef | ||
|
|
90fd825bfe | ||
|
|
1487b6dfac | ||
|
|
2d6b702d37 | ||
|
|
90379fe39b | ||
|
|
d45f55c0ca | ||
|
|
eb81c7ab19 | ||
|
|
3da6673156 |
@@ -0,0 +1,305 @@
|
||||
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());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,42 @@
|
||||
package Client;
|
||||
|
||||
import java.io.DataInputStream;
|
||||
import java.io.IOException;
|
||||
import java.net.Socket;
|
||||
|
||||
public class ClientNetworkReceiver implements Runnable{
|
||||
private Client client;
|
||||
private DataInputStream in;
|
||||
|
||||
public ClientNetworkReceiver(Socket clientSocket, Client client) throws IOException {
|
||||
// initialize client
|
||||
// initialize in
|
||||
}
|
||||
@Override
|
||||
public void run() {
|
||||
while(true) {
|
||||
//TODO: get response
|
||||
String response = "";
|
||||
|
||||
if(false) // TODO: set player number ( 0 or 1)
|
||||
{
|
||||
int number = 0;
|
||||
client.setPlayerNumber(number);
|
||||
}
|
||||
else if(false) // TODO: other player joined the game
|
||||
{
|
||||
client.setOtherPlayerJoined();
|
||||
}
|
||||
else if(false){ // TODO: handle incoming hit
|
||||
int row = 0; //TODO: extract row
|
||||
int col = 0; //TODO: extract col
|
||||
String message = client.getHit(row, col);
|
||||
//TODO: inform server
|
||||
}
|
||||
else if(false) //TODO: handle hit result from opponent
|
||||
{
|
||||
client.setEnemyResult(false, "NONE");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,65 @@
|
||||
package Server;
|
||||
|
||||
import java.io.DataInputStream;
|
||||
import java.io.DataOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.net.Socket;
|
||||
|
||||
public class ClientHandler implements Runnable {
|
||||
private Socket client;
|
||||
private DataInputStream in;
|
||||
private DataOutputStream out;
|
||||
private boolean isFirst;
|
||||
private String username;
|
||||
ClientHandler enemy;
|
||||
|
||||
public void sendData(String request) {
|
||||
//TODO: write to output and flush
|
||||
}
|
||||
|
||||
public void setEnemy(ClientHandler enemy) throws IOException {
|
||||
this.enemy = enemy;
|
||||
}
|
||||
public String getUsername()
|
||||
{
|
||||
return username;
|
||||
}
|
||||
|
||||
public ClientHandler(Socket client, boolean isFirst) throws IOException {
|
||||
//initialize client
|
||||
//initialize in
|
||||
//initialize out
|
||||
//initialize isFirst
|
||||
}
|
||||
|
||||
public void run() {
|
||||
try {
|
||||
while(true) {
|
||||
// TODO: Read a UTF-encoded string from the client
|
||||
String request = "";
|
||||
if (false) { //TODO: Set Username
|
||||
int playerNumber = isFirst?0:1;
|
||||
// TODO: Send player number to client
|
||||
|
||||
username = "";//TODO extract username
|
||||
//TODO: wait till enemy is specified
|
||||
//TODO: tell the clients that the other player joined
|
||||
}
|
||||
else if (false) { //TODO: Handle Attack
|
||||
int row = 0;//TODO: extract row and col
|
||||
int col = 0;//TODO: extract row and col
|
||||
//TODO: inform enemy of the attack
|
||||
}
|
||||
else if (false) { //TODO: Handle Attack Result
|
||||
// TODO: Notify the attacker about the result of their attack (hit or miss)
|
||||
}
|
||||
//TODO(for later): handle winning and losing
|
||||
}
|
||||
} finally
|
||||
{
|
||||
// close in
|
||||
// close out
|
||||
// close client
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,56 @@
|
||||
package Server;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.net.ServerSocket;
|
||||
import java.util.ArrayList;
|
||||
import java.util.concurrent.ExecutorService;
|
||||
import java.util.concurrent.Executors;
|
||||
|
||||
public class Server {
|
||||
private static int PORT = 3737;
|
||||
// TODO: Create a collection to keep track of connected clients
|
||||
private static ArrayList<ClientHandler> clients = new ArrayList();
|
||||
private static ExecutorService pool = Executors.newFixedThreadPool(4);
|
||||
|
||||
static ClientHandler playerOne;
|
||||
static ClientHandler playerTwo;
|
||||
|
||||
|
||||
public static void main(String[] args) {
|
||||
ServerSocket listener = null;
|
||||
|
||||
try {
|
||||
// TODO: Create a ServerSocket to listen for incoming connections
|
||||
//int i = 0;
|
||||
while(true) {
|
||||
|
||||
// TODO: Accept a client connection
|
||||
// TODO: Create a ClientHandler named clientThread for the connected client
|
||||
// TODO: uncomment this code
|
||||
//if(i == 0) {
|
||||
// playerOne = clientThread;
|
||||
//}
|
||||
//if(i == 1) {
|
||||
// playerTwo = clientThread;
|
||||
// playerOne.setEnemy(playerTwo);
|
||||
// playerTwo.setEnemy(playerOne);
|
||||
//}
|
||||
//i++;
|
||||
//TODO add clientThread to clients and executor service
|
||||
|
||||
//TODO(for later): handle the situation where more than two players join at the same time
|
||||
//TODO(for later): handle the situation where more than one game happens
|
||||
}
|
||||
} finally {
|
||||
if (listener != null) {
|
||||
try {
|
||||
listener.close();
|
||||
} catch (IOException ex) {
|
||||
ex.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
pool.shutdown();
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user