/** * ================================================================================ * SiPro SocketArena™ - Question 2: TCP Even/Odd Game Client * ================================================================================ * COURSE : Distributed Computing & Systems Programming * ASSIGNMENT : Q2 - TCP Client Application for Networked Even/Odd Game * LANGUAGE : Java (SE 11+) * OBJECTIVE : Connect to the concurrent Even/Odd TCP server, send the PLAY registration, * prompt candidate for a chosen number (1-10) and parity guess ("EVEN" or "ODD"), * transmit the GUESS command frame, and parse the server RESULT frame. * PROTOCOL : RFC-SIPRO-EVENODD (ASCII Line-Delimited TCP Protocol) * * STUDENT INSTRUCTIONS: * Complete all 8 fill-in-the-blank sections marked with: * // >>> FILL IN THE BLANK [X]: ... <<< * * COMPILATION & EXECUTION: * javac EvenOddClient.java * java EvenOddClient [YourName] * ================================================================================ */ import java.io.*; import java.net.*; import java.util.Scanner; public class EvenOddClient { public static final String DEFAULT_HOST = "127.0.0.1"; public static final int PORT = 9098; public static void runClient(String host, int port, String playerName) { Socket socket = null; Scanner scanner = new Scanner(System.in); try { // >>> FILL IN THE BLANK [1]: Create a TCP stream client socket <<< // socket = new Socket(); socket = null; // REPLACE THIS LINE // >>> FILL IN THE BLANK [2]: Connect client socket to the server (host, port) <<< // socket.connect(new InetSocketAddress(host, port)); // System.out.println("[CONNECTED] Established TCP connection to " + host + ":" + port); // REPLACE THIS BLOCK if (socket == null) { System.out.println("[SIMULATION] Socket not initialized. Please complete Blank 1 & 2."); return; } // >>> FILL IN THE BLANK [3]: Initialize BufferedReader stream from socket.getInputStream() <<< // BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream())); BufferedReader in = null; // REPLACE THIS LINE // >>> FILL IN THE BLANK [4]: Initialize PrintWriter stream with autoflush enabled <<< // PrintWriter out = new PrintWriter(new OutputStreamWriter(socket.getOutputStream()), true); PrintWriter out = null; // REPLACE THIS LINE if (in == null || out == null) { System.out.println("[SIMULATION] Stream readers/writers not initialized. Complete Blank 3 & 4."); return; } // Read server welcome banner String banner = in.readLine(); System.out.println("[SERVER READY]: " + banner); // >>> FILL IN THE BLANK [5]: Send the initial registration message ("PLAY ") <<< // out.println("PLAY " + playerName); // REPLACE THIS LINE String welcomeMsg = in.readLine(); System.out.println("[SERVER]: " + welcomeMsg); boolean playAgain = true; while (playAgain) { System.out.println("\n-------------------------------------------------------"); System.out.println(" ROUND SELECTION: Pick a number and make your guess!"); System.out.println("-------------------------------------------------------"); int chosenNumber = 0; while (chosenNumber < 1 || chosenNumber > 10) { System.out.print("Enter your chosen number (1 - 10): "); try { String input = scanner.nextLine().trim(); if (input.equalsIgnoreCase("quit")) { out.println("QUIT"); return; } chosenNumber = Integer.parseInt(input); if (chosenNumber < 1 || chosenNumber > 10) { System.out.println("Number must be between 1 and 10."); } } catch (NumberFormatException e) { System.out.println("Invalid input. Please enter an integer."); } } String guessParity = ""; while (!guessParity.equals("EVEN") && !guessParity.equals("ODD")) { System.out.print("Guess whether total sum will be EVEN or ODD: "); String input = scanner.nextLine().trim().toUpperCase(); if (input.equalsIgnoreCase("quit")) { out.println("QUIT"); return; } if (input.equals("EVEN") || input.equals("ODD")) { guessParity = input; } else { System.out.println("Invalid guess. Type 'EVEN' or 'ODD'."); } } // >>> FILL IN THE BLANK [6]: Format and transmit the GUESS command ("GUESS ") <<< // String command = "GUESS " + chosenNumber + " " + guessParity; // out.println(command); // System.out.println("[SENT WIRE FRAME]: " + command); // REPLACE THIS BLOCK // >>> FILL IN THE BLANK [7]: Read the incoming RESULT response frame from the server <<< // String resultLine = in.readLine(); String resultLine = null; // REPLACE THIS LINE if (resultLine == null) { System.out.println("\n[DISCONNECTED] Server closed the connection."); break; } System.out.println("[SERVER RESPONSE]: " + resultLine); // Parse outcome frame: RESULT String[] parts = resultLine.split("\\s+"); if (parts.length >= 6 && parts[0].equalsIgnoreCase("RESULT")) { String outcome = parts[1]; String cNum = parts[2]; String sNum = parts[3]; String totalSum = parts[4]; String actualParity = parts[5]; StringBuilder message = new StringBuilder(); for (int i = 6; i < parts.length; i++) { message.append(parts[i]).append(" "); } System.out.println("\n*******************************************************"); if ("WIN".equalsIgnoreCase(outcome)) { System.out.println("🏆 RESULT: VICTORY!"); } else { System.out.println("💀 RESULT: DEFEAT!"); } System.out.println("Your Number : " + cNum); System.out.println("Server Number : " + sNum); System.out.println("Total Sum : " + totalSum + " (" + actualParity + ")"); System.out.println("Your Guess : " + guessParity); System.out.println("Details : " + message); System.out.println("*******************************************************"); } System.out.print("\nPlay another round? (y/n): "); String again = scanner.nextLine().trim(); if (!again.equalsIgnoreCase("y") && !again.equalsIgnoreCase("yes")) { out.println("QUIT"); playAgain = false; } } String bye = in.readLine(); if (bye != null) System.out.println("[SERVER]: " + bye); } catch (ConnectException e) { System.err.println("[ERROR] Could not connect to Even/Odd Server at " + host + ":" + port); System.err.println("Ensure EvenOddServer is running: java EvenOddServer"); } catch (IOException e) { System.err.println("[CLIENT EXCEPTION] " + e.getMessage()); } finally { // >>> FILL IN THE BLANK [8]: Gracefully close the client socket <<< // if (socket != null && !socket.isClosed()) { // try { socket.close(); } catch (IOException ignored) {} // } System.out.println("[CLIENT] Socket closed. Session terminated."); } } public static void main(String[] args) { String name = (args.length > 0) ? args[0] : "Player_" + (int)(Math.random() * 1000); runClient(DEFAULT_HOST, PORT, name); } }