0

I have three classes. When the server starts, it creates a randomGame object with a guessCount and random number. When the client starts, it connects to the server and passes the number to server to play the guess method(with console input number) to guess the random number of the randomGame generated.

But the following has problems. The client enter the number each time, the guessCount & the random number are reinitialized(that is, the random number is different and guessCount can't increment). I want the random number to be the same for each client program running and the guessCount will be incremented by 1 each time when the guess method run.

public class Game {
    private int num;
    private int guessCount;
    Game (int num) {
        this.num = num;

        System.out.println("guessCount = " + guessCount);
        System.out.println("num = " + num);
    }

    public int guess (int ran) {
        int result;

        guessCount++;
        if (this.guessCount >= 10) {
            return -2;
        } else if (ran < num) {
            return -1;
        } else if (ran > num) {
            return 1;
        } else {
            return 0;
        }
    }
}

Here's RandomGame

class RandomGame extends Game {
    RandomGame () {        
        super(0 + (int)(Math.random() * ((90 - (0)) + 1)));
    }

    public static void main (String args[]) {
    }
}

Here's the server:

import java.io.*;
import java.net.*;

public class Q4Server {
    public static void main(String arg[]) {
        try {
            ServerSocket ss = new ServerSocket(12345);
            while(true) {
                Socket s = ss.accept();
                ClientHandler ch = new ClientHandler(s);
                ch.start();
            }
        } catch(IOException ioe) {
            ioe.printStackTrace();
        }
    }
}

Here's the client handler:

class  ClientHandler extends Thread {

    Socket socket;
    RandomGame g;

    public ClientHandler(Socket socket) {
        this.socket = socket;
        g = new RandomGame();
    }

    public void run() {
        try {
            DataInputStream dis = new DataInputStream(socket.getInputStream());
            DataOutputStream dos = new DataOutputStream(socket.getOutputStream());

            int x = dis.readInt();     

            int reply = this.g.guess(x);
            System.out.println("reply = " + reply);
            dos.writeInt(reply);

            //System.out.println(reply);
            //System.out.println(reply);

            socket.close();
        } catch(IOException ioe) {
            ioe.printStackTrace();
        }
    }
}
0

4 Answers 4

1

Although @DarkSquirrel42 and @jowierun are correct, I'd like to expand on their answers and provide another alternative.

Right now, the client connects, a new game is created, they provides a guess, and the server replies and disconnects. When the client connects again, they are given a brand new game with a new random number. There is no state holding the same game for the client.

There are 3 possible solutions to the problem:

  1. The client can stay connected to the server between guesses. So the random number would be chosen when the client initially connects and the client and server would stay connected as multiple guesses are made. This is what @jowierun was trying to have you do.

  2. The client can choose the random number and communicate it each time with the server. So the client would write two integers when it connects. But this completely removes the need for the server which is somewhat ridiculous.

  3. The server can hold the state for each client between guesses. You could do this a couple of different ways. The server could store the Game associated with each client's IP in a Map. This would only work if there was 1 client per IP of course. You can get the IP from the Socket.

    One issue would be "timing out" the games. You wouldn't want the server to cache the running games forever. Maybe every time a client connected the server could look through it's Map of games and throw out the ones that are older than some time period. You'd need to add a createdMillis field to the game.

Hope this helps.

Sign up to request clarification or add additional context in comments.

Comments

0

Try using Singleton RandomGame Instance

Comments

0

you wrote

when the server start, it create a randomGame object with a guessCount and random number

you don't do that ... you create that object every time a client connects (a new RandomGame object is created for each client in the client handler constructor)

you should move the creation of that object to Q4server.main(...) and pass it to all client handlers (you will have to change the constructor signature to take it as a parameter)

guessCount should be volatile

Comments

0

Your problem is the ClientHandler.run() method. It should be looping for the 3 (or however many required) guesses before exiting. Your socket client will have to do the same. The way you have it currently, the client is connecting to the server separately for each guess - there is no "conversation" which is what you need:

public void run() {
    try {
        final int guessMax = 3;

        for (int i=0;i<guessMax;i++) {
            DataInputStream dis = new DataInputStream(socket.getInputStream());
            DataOutputStream dos = new DataOutputStream(socket.getOutputStream());

            int x = dis.readInt();     

            int reply = this.g.guess(x);
            System.out.println("reply = " + reply);
            dos.writeInt(reply);
            dos.flush();

            //System.out.println(reply);
            //System.out.println(reply);
        }

        socket.close();

    } catch(IOException ioe) {
        ioe.printStackTrace();
    }
}

Hope that helps.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.