Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .idea/gradle.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

5 changes: 4 additions & 1 deletion .idea/misc.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

103 changes: 90 additions & 13 deletions src/main/java/Client/Client.java
Original file line number Diff line number Diff line change
Expand Up @@ -27,14 +27,15 @@ public class Client {
volatile boolean otherPlayerJoined = false;
DataOutputStream out;

boolean won = false;
boolean lost = false;

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
new Thread(new ClientNetworkReceiver(new DataInputStream(clientSocket.getInputStream()), this)).start();

System.out.println("Enter Username: ");
Scanner usernameScanner = new Scanner(System.in);
Expand All @@ -50,11 +51,14 @@ public Client(Socket clientSocket) {
}

printBoards();
while(true)
mainLoop : while(!won && !lost)
{
while(!isTurn)
{
Thread.onSpinWait();
if (won || lost) {
break mainLoop;
}
}

System.out.println("Your Turn Now!");
Expand Down Expand Up @@ -95,12 +99,24 @@ public Client(Socket clientSocket) {

//Actions
private void attack() {
//TODO: send attack message to server
String message = "attack|" + lastEnemyRow + "," + lastEnemyCol;
try {
out.writeUTF(message);
} catch (Exception e) {
System.out.println("Could not send message to the server!\n\n");
}

isTurn = false;
}
private void sendUsername(String username) throws IOException {
//TODO: send username to server
String message = "set-username|" + username;
try {
out.writeUTF(message);
} catch (IOException e) {
System.out.println("Could not send message to the server!\n\n");
}
}

public void setEnemyResult(boolean hit, String shipName) {
enemyBoard[lastEnemyRow][lastEnemyCol].setEnemyShip(hit);
enemyBoard[lastEnemyRow][lastEnemyCol].setMarked(true);
Expand All @@ -115,9 +131,8 @@ public void setOtherPlayerJoined() {
otherPlayerJoined = true;
}
public void finishGame(boolean won){
//TODO:
}
public String getHit(int row, int col){
public void getHit(int row, int col){
String message = "";
playerBoard[row][col].setMarked(true);
String sankBattleShipName = "NONE";
Expand All @@ -133,8 +148,35 @@ public String getHit(int row, int col){
} catch (InterruptedException e) {

}
isTurn = true;
return message;

try {
out.writeUTF("attack-result|" + message);
out.flush();
} catch (IOException e) {
throw new RuntimeException(e);
}

// checking game status
boolean lost = true;
for (int i = 0; i < SIZE; i++) {
for (int j = 0; j < SIZE; j++) {
if (playerBoard[i][j].isShip() && !playerBoard[i][j].isMarked()) {
lost = false;
}
}
}

if (lost) {
try {
out.writeUTF("enemy-won");
out.flush();
lose();
} catch (IOException e) {
throw new RuntimeException(e);
}
} else {
isTurn = true;
}
}
private static void playSound(String soundFileName) {
try {
Expand Down Expand Up @@ -284,13 +326,48 @@ private static boolean tryPlace(BattleShipCell[][] board, int row, int col, bool
return false;
}

public void win() {
try {
out.writeUTF("gameover"); //to terminate ClientHandler and ClientNetworkReceiver
out.flush();
} catch (IOException e) {
throw new RuntimeException(e);
}

for (int i = 0; i < 20; i++) {
System.out.println();
}
System.out.println(AnsiColor.CYAN + "Congratulations! You won the game! wait for the next round..." + AnsiColor.RESET + "\n\n");
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}

won = true;
}
public void lose() {
for (int i = 0; i < 20; i++) {
System.out.println();
}
System.out.println(AnsiColor.RED + "What a shame! You lost! wait fot the next round..." + AnsiColor.RESET + "\n\n");
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}

lost = true;
}

public static void main(String[] args) throws IOException {
Socket clientSocket = null;
//TODO: get IP_Address

try {
//initialize clientSocket
//initialize Client
while (true) {
clientSocket = new Socket("localhost", PORT_NUMBER);
new Client(clientSocket);
}
} finally {
try {
if (clientSocket != null) {
Expand Down
51 changes: 36 additions & 15 deletions src/main/java/Client/ClientNetworkReceiver.java
Original file line number Diff line number Diff line change
Expand Up @@ -3,39 +3,60 @@
import java.io.DataInputStream;
import java.io.IOException;
import java.net.Socket;
import java.util.Objects;

public class ClientNetworkReceiver implements Runnable{
private Client client;
private DataInputStream in;

public ClientNetworkReceiver(Socket clientSocket, Client client) throws IOException {
// initialize client
// initialize in
public ClientNetworkReceiver(DataInputStream clientSocket, Client client) throws IOException {
this.client = client;
this.in = clientSocket;
}
@Override
public void run() {
while(true) {
//TODO: get response
String response = "";

if(false) // TODO: set player number ( 0 or 1)
String response;
try {
response = in.readUTF();
} catch (IOException e) {
throw new RuntimeException(e);
}

if(response.startsWith("set-player-number|"))
{
int number = 0;
int number = Integer.parseInt(response.replace("set-player-number|", ""));
client.setPlayerNumber(number);
}
else if(false) // TODO: other player joined the game
else if(response.startsWith("enemy-joined"))
{
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(response.startsWith("incoming-attack|")){
int row = 0;
int col = 0;
//incoming-attack|row,col
response = response.replace("incoming-attack|", "");
row = Integer.parseInt(response.split(",")[0]);
col = Integer.parseInt(response.split(",")[1]);
client.getHit(row, col);
}
else if(response.startsWith("enemy-result|"))
{
response = response.replace("enemy-result|", "");
//enemy-result|HIT,SHIPNAME
//enemy-result|HIT,NONE
//enemy-result|MISS,NINE
client.setEnemyResult(Objects.equals(response.split(",")[0], "HIT"), response.split(",")[1]);
}
else if(response.equals("win"))
{
client.win();
}
else if(false) //TODO: handle hit result from opponent
else if (response.equals("gameover"))
{
client.setEnemyResult(false, "NONE");
return;
}
}
}
Expand Down
87 changes: 65 additions & 22 deletions src/main/java/Server/ClientHandler.java
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,17 @@ public class ClientHandler implements Runnable {
private DataInputStream in;
private DataOutputStream out;
private boolean isFirst;
private boolean usernameSet;
private String username;
ClientHandler enemy;

public void sendData(String request) {
//TODO: write to output and flush
try {
out.writeUTF(request);
out.flush();
} catch (IOException e) {
System.out.println(e.getMessage());
}
}

public void setEnemy(ClientHandler enemy) throws IOException {
Expand All @@ -26,40 +32,77 @@ public String getUsername()
}

public ClientHandler(Socket client, boolean isFirst) throws IOException {
//initialize client
//initialize in
//initialize out
//initialize isFirst
this.client = client;
this.isFirst = isFirst;
this.usernameSet = false;
in = new DataInputStream(client.getInputStream());
out = new DataOutputStream(client.getOutputStream());
}

public void run() {
try {
while(true) {
// TODO: Read a UTF-encoded string from the client
String request = "";
if (false) { //TODO: Set Username
String request = in.readUTF();
if (request.startsWith("set-username")) {

int playerNumber = isFirst?0:1;
// TODO: Send player number to client
username = request.replace("set-username|", "");
out.writeUTF("set-player-number|" + playerNumber);
out.flush();
this.usernameSet = true;

while (enemy == null) {
Thread.onSpinWait();
}
while (!enemy.isUsernameSet()) {
Thread.onSpinWait();
}

out.writeUTF("enemy-joined");
out.flush();
}
else if (request.startsWith("attack") && !request.startsWith("attack-result")) {
int row = 0;
int col = 0;

username = "";//TODO extract username
//TODO: wait till enemy is specified
//TODO: tell the clients that the other player joined
//attack|row,col
request = request.replace("attack|", "");
row = Integer.parseInt(request.split(",")[0]);
col = Integer.parseInt(request.split(",")[1]);

enemy.out.writeUTF("incoming-attack|" + row + "," + col);
}
else if (request.startsWith("attack-result")) {

request = request.replace("attack-result|", "");
enemy.out.writeUTF("enemy-result|" + request);
enemy.out.flush();
}
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 (request.equals("enemy-won")) {
enemy.out.writeUTF("win");
enemy.out.flush();
}
else if (false) { //TODO: Handle Attack Result
// TODO: Notify the attacker about the result of their attack (hit or miss)
else if (request.equals("gameover")) {
out.writeUTF("gameover"); //to terminate ClientNetworkReceiver
out.flush();
return;
}
//TODO(for later): handle winning and losing
}
} catch (IOException e) {
throw new RuntimeException(e);
} finally
{
// close in
// close out
// close client
try {
in.close();
out.close();
client.close();
} catch (IOException e) {
throw new RuntimeException(e);
}
}
}

public boolean isUsernameSet() {
return usernameSet;
}
}
Loading