import java.io.*;
import java.net.*;
import java.util.*;
import java.awt.*;
import javax.swing.*;
public class server extends JFrame{
// Mapping of sockets to output streams
private Hashtable<Socket, DataOutputStream> hTable = new Hashtable<Socket, DataOutputStream>();
JTextArea textArea = new JTextArea(12, 20);
boolean showOPG,singleGame;
Random rand = new Random();
int[] pattern = new int[4];
int[] guess = new int[4];
DataInputStream inputFromClient1;
DataOutputStream outputToClient1;
DataInputStream inputFromClient2;
DataOutputStream outputToClient2;
DataInputStream inputFromClient3;
DataOutputStream outputToClient3;
JScrollPane scrollPane = new JScrollPane(textArea); // Creates a scroll pane to hold text area
ServerSocket serverSocket;
boolean winner = false;
int finalColorMatch, finalBothMatch;
int sessionID = 0, guessCounter = 0;
boolean multiGameOn = false;
int playerID;
public static void main(String[] args) {
new server();
}
public server() {
super("Server");
// creating the container needed by frame
Container container = getContentPane();
textArea.setEditable(false);
getContentPane().add(scrollPane, BorderLayout.CENTER); //Adds the scroll pane to the frame
container.add(textArea);
// designing the frame
setSize(500, 300);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setVisible(true); // It is necessary to show the frame here
// receive info from client
receiveClient();
}// end of constructor
// creating server socket and receive from client to get the specific info about the game
// such as single or multiple players, show feedback or not
public void receiveClient() {
try {
// Create a server socket
serverSocket = new ServerSocket(8000);
textArea.append("MastermindServer started at " + new Date() + "\n");
//create an array of threads
Thread[] threads = new Thread[6];
while(true) {
multiGameOn = false;
winner = false;
// Listen for a connection request
Socket socket1 = serverSocket.accept();
// Socket socket2;
Socket socketMulti;
// create a session to keep track
sessionID = 1;
// Create data input and output streams
inputFromClient1 = new DataInputStream(socket1.getInputStream());
outputToClient1 = new DataOutputStream(socket1.getOutputStream());
// Sends session id to the client
// Notify that the player Player number
outputToClient1.writeInt(sessionID);//Multi(1)send sessionID
outputToClient1.flush();
// Receive the game type from the client and send appropreate
// message to inform them they can start and handle a single
// thread or multiple accordingly
int singleOrMulti = inputFromClient1.readInt();
System.out.println("singleOrMulti(2)" + singleOrMulti);
String message;
if(singleOrMulti == 1) {
// sessionID = 1;
// winner = false;
guessCounter = 1;
//announce this player has joined
textArea.append(new Date() + ": SinglePlayerGame is started now \n");
message = "You can start single player game now"+"\n";
outputToClient1.writeUTF(message);
outputToClient1.flush();
producePattern();
//game untill the player wins or number of guesses reaches 8;
while(!(winner)) {
recNmatch();// compare pattern(chosen by server randomly)with client's guess
sendSingle();// a function for sending to just one client for it's singleplayer game
guessCounter++;
if(guessCounter == 9) {
String looser = "Limit is 8 tries, you lost.";
outputToClient1.writeUTF(looser);
outputToClient1.flush();
textArea.append("The singleplayer lost the game\n");
guessCounter = 0;
winner = true;
sessionID = 0;
break;
}
}
} else {//*********if it's multiplayer game,ensure that there are at least 2 players or more
// Notify that the player Player number
// new DataOutputStream(socket1.getOutputStream()).writeInt(sessionID);//Multi(1)send sessionID
// if (sessionID == 1) {
int showOrNot = inputFromClient1.readInt(); //read from client to decide showOPG!!!
System.out.println("showOrNot(1)" + showOrNot);
/* if(showOrNot == 1)
showOPG = true;
else
showOPG = false;
*/
// }
int sad = inputFromClient1.readInt();
System.out.println(sad);
sessionID++;
Socket socket2 = serverSocket.accept();
inputFromClient2 = new DataInputStream(socket2.getInputStream());
outputToClient2 = new DataOutputStream(socket2.getOutputStream());
// outputToClient2 = new DataOutputStream(socket2.getOutputStream()).writeInt(sessionID);
outputToClient2.writeInt(sessionID);
outputToClient2.flush();
// int show1 = 1, show2 = 2;
outputToClient2.writeInt(showOrNot);
outputToClient2.flush();
/*
if(showOPG){
//to send show or not to client 2
outputToClient2.writeInt(show1);
outputToClient2.flush();
} else {
outputToClient2.writeInt(show2);
outputToClient2.flush();
}
*/
int tempInt;
tempInt = inputFromClient2.readInt(); // input for multiplayer
System.out.println("multi from cl 2(2) = " + tempInt);
// hTable.put(socket2, outputToClient2);//for broad casting later
// int temp = inputFromClient.readInt();
sad = inputFromClient2.readInt();
System.out.println(sad);
//####################################################################################
//problem starts here as message is sent but not received by client
//####################################################################################
try { //makes player waits for 5 seconds
Thread.currentThread().sleep(5000);
} catch (InterruptedException er) {
er.printStackTrace();
}
String startMessage = "Two players now,You can start multiGame!";
System.out.println("Test send message");
outputToClient2.writeUTF(startMessage);
outputToClient2.flush();
outputToClient1.writeUTF(startMessage);
outputToClient1.flush();
System.out.println("message sent");
textArea.append(new Date() + ": MultiPlayerGame is started now \n");
sessionID++;
producePattern();//before starting the game,produce the pattern for clients to guess
multiGameOn = true;
hTable.put(socket1, outputToClient1);
ServerThread player1 = new ServerThread(this,socket1);//create the first thread
hTable.put(socket2, outputToClient2);//for broad casting later
ServerThread player2 = new ServerThread(this,socket2);//create the second thread
player1.start();
player2.start();
while((!(winner)) && sessionID < 6) {
//create connection request
socketMulti = serverSocket.accept();
// Notify that the player Player number
inputFromClient3 = new DataInputStream(socketMulti.getInputStream());
outputToClient3 = new DataOutputStream(socketMulti.getOutputStream());
outputToClient3.writeInt(sessionID);
outputToClient3.flush();
outputToClient3.writeUTF("Game is on alreay,Please enjoy watching...");
outputToClient3.flush();
//increase the session to keep track
sessionID++;
hTable.put(socketMulti, outputToClient3);//for broad casting later
// int playersNoTurn = inputFromClient.readInt();
//*///############################################################
// let the client know game is on. it's for player3 -6;
// if (sessionID > 2)
// new DataOutputStream(socketMulti.getOutputStream()).writeUTF("Game is on alreay,Please enjoy watching...");
// ServerThread player2 = new ServerThread(this,socketMulti);//create the second thread
/* if(sessionID == 2) {//***once there are 2 players, start the multigame!
producePattern();//before starting the game,produce the pattern for clients to guess
multiGameOn = true;
new DataOutputStream(socket1.getOutputStream()).writeUTF("Two players now,You can start multiGame!");
new DataOutputStream(socket2.getOutputStream()).writeUTF("Two players now,You can start multiGame!");
textArea.append(new Date() + ": MultiPlayerGame is started now \n");
}
*/
/*
if(multiGameOn) {
// try {
player1.start();//start the first thread
if(winner)
break;// if guess is right,then the game is over
// player1.sleep(5000);//after the first thread is finished it waits for 5 sec before another guess
player2.start();//start the second thread
if(winner)
break;//if player2 guessed right,then the game is over
// player2.sleep(5000);//second thread waits for 5 sec before taking another guess
// } catch (InterruptedException ex) {
// }
}
if(sessionID == 6) {//when it's 6 players already,stop listening to connection request
// try {
while(true) {
player1.start();//start the first thread
if(winner)
break;// if guess is right,then the game is over
// player1.sleep(5000);//after the first thread is finished it waits for 5 sec before another guess
player2.start();//start the second thread
if(winner)
break;//if player2 guessed right,then the game is over
// player2.sleep(5000);//second thread waits for 5 sec before taking another guess
}
// } catch (InterruptedException ex) {
// }
}
*/
// get info from client whether they wanna continue or not
//************if(continue){ gomeOn = ture;} the while loop should depend on"gameOn"
}
}
}
} catch(IOException ex) {
System.err.println(ex);
}
}//end of receiveClient;
//matching algo for player 1(single and multi player 1)
public void recNmatch() {
try{
finalBothMatch = 0;
finalColorMatch = 0;
// receive the guess from client and put the guesses into an array
for(int i = 0; i < 4; i++){
guess[i] = inputFromClient1.readInt();//input guesses
}
//testing if the guess sent by client is arrived here*****************
System.out.print("User made guess of : ");
for(int i = 0; i < 4; i++)
System.out.print(guess[i]);
System.out.println("");
int[] tempInp = new int[4]; //to hold another copy of the input
for (int i = 0; i < 4; i++) {
tempInp[i] = guess[i];//copy the input
}
for (int i = 0; i < 4; i++) { // black and white matching algorithm
for (int j = 0; j < 4; j++) {
if(tempInp[j] == pattern[i]) {
finalColorMatch++; //increment white
tempInp[j] = -1; //to make sure the same value isn't counted again
j = 4; //to jump out of loop so others wouldn't be taken into account
}
}
}
for (int i = 0; i < 4; i++) {
if (guess[i] == pattern[i]){ //matching color + position
finalBothMatch++;
}
}
finalColorMatch -= finalBothMatch; //matching color & wrong position
if(finalBothMatch == 4) {
winner = true;
sessionID = 0;
}
} catch(IOException ex) {
System.err.println(ex);
}
}// end of recNmatch()
//matching algo for multi player2
public void recNmatch2() {
try{
finalBothMatch = 0;
finalColorMatch = 0;
// receive the guess from client and put the guesses into an array
for(int i = 0; i < 4; i++){
guess[i] = inputFromClient2.readInt();//input guesses
}
//testing if the guess sent by client is arrived here*****************
System.out.print("User made guess of : ");
for(int i = 0; i < 4; i++)
System.out.print(guess[i]);
System.out.println("");
int[] tempInp = new int[4]; //to hold another copy of the input
for (int i = 0; i < 4; i++) {
tempInp[i] = guess[i];//copy the input
}
for (int i = 0; i < 4; i++) { // black and white matching algorithm
for (int j = 0; j < 4; j++) {
if(tempInp[j] == pattern[i]) {
finalColorMatch++; //increment white
tempInp[j] = -1; //to make sure the same value isn't counted again
j = 4; //to jump out of loop so others wouldn't be taken into account
}
}
}
for (int i = 0; i < 4; i++) {
if (guess[i] == pattern[i]){ //matching color + position
finalBothMatch++;
}
}
finalColorMatch -= finalBothMatch; //matching color & wrong position
if(finalBothMatch == 4) {
winner = true;
sessionID = 0;
}
} catch(IOException ex) {
System.err.println(ex);
}
}// end of recNmatch2()
//send these info(colorMatch and bothCnO) to a single client
public void sendSingle() {
try {
outputToClient1.writeInt(finalBothMatch);
outputToClient1.flush();
//first check if the player winning or not
if(winner){
String winnerMsg = "Congratulations! you won with "+guessCounter+" guesses\n";
outputToClient1.writeUTF(winnerMsg);
outputToClient1.flush();
textArea.append("Player won with "+guessCounter+" guesses");
} else{
outputToClient1.writeInt(finalColorMatch);
outputToClient1.flush();
outputToClient1.writeInt(guessCounter);
outputToClient1.flush();
}
} catch(IOException ex) {
System.err.println(ex);
}
}
//send these info(colorMatch and bothCnO) to a single client
public void sendSingle1() {
try {
outputToClient2.writeInt(finalBothMatch);
outputToClient2.flush();
//first check if the player winning or not
if(winner){
String winnerMsg = "Congratulations! you won with "+guessCounter+" guesses\n";
outputToClient2.writeUTF(winnerMsg);
outputToClient2.flush();
textArea.append("Player won with "+guessCounter+" guesses");
} else{
outputToClient2.writeInt(finalColorMatch);
outputToClient2.flush();
outputToClient2.writeInt(guessCounter);
outputToClient2.flush();
}
} catch(IOException ex) {
System.err.println(ex);
}
}
//send the info(color match and both match)to all the clients
public void broadcast(int playID) {
try {
for (Enumeration<DataOutputStream> e = getOutputStreams(); e.hasMoreElements();) {
DataOutputStream out = (DataOutputStream)e.nextElement();
// Write message
out.writeInt(1); //broadcast(1)send
//#############################################################################################################
if(winner) {
String winnerMsg = "Player "+playID+" won! ";
out.writeUTF(winnerMsg);
for (int i = 0; i < 4; i++)
out.writeInt(guess[i]);
out.writeInt(finalBothMatch);
out.writeUTF(winnerMsg);
out.writeInt(finalColorMatch);
} else {
// out.writeInt(1);//let client broadcast listener know server seding game info
if(showOPG) {
String showing = "Player "+playID+" guessed ";
out.writeUTF(showing);
for (int i = 0; i < 4; i++)
out.writeInt(guess[i]);
out.writeInt(finalBothMatch);
out.writeInt(finalColorMatch);
} else {
String notShowing = "Player "+playID+" made a guess";
out.writeUTF(notShowing);
for (int i = 0; i < 4; i++)
out.writeInt(i);
out.writeInt(1);
out.writeInt(1);
}
}
}
} catch(IOException ex) {
System.err.println(ex);
}
}
// this is method to take care of chatting system
private void chat(int plID) {
try {
// receive the message from a client
String string;
if (plID == 1)
string = inputFromClient1.readUTF();
else if (plID == 2)
string = inputFromClient2.readUTF();
else
string = inputFromClient3.readUTF();
// Send text back to all the clients
for (Enumeration<DataOutputStream> e = getOutputStreams(); e.hasMoreElements();) {
DataOutputStream out = (DataOutputStream)e.nextElement();
out.write(2);//inform the client receiver that it's a chat message
// Write message
String str = "Player "+plID+":"+ string;
out.writeUTF(str);
// Add chat to the server jta
textArea.append(str + "\n");
}
} catch(IOException ex) {
System.err.println(ex);
}
}
// Used to get the output streams
Enumeration<DataOutputStream> getOutputStreams() {
return hTable.elements();
}
//=================== server thread class=====================
class ServerThread extends Thread {
private server serv;
private Socket socket;
/** Construct a thread */
public ServerThread(server serv,Socket socket) {
this.socket = socket;
this.serv = serv;
}
//====================run=================================
/** Implement the run() method for the thread */
public void run() {
try {
int chatOrGame = inputFromClient1.readInt();
int playID = inputFromClient1.readInt();
if(chatOrGame == 2) {
chat(playID); //receive string and broadcast it to all
} else {
recNmatch();// find out the color match and both match
broadcast(playID); // broadcast the guesses to all
try { //makes server waits for 5 seconds before new game starts
Thread.currentThread().sleep(5000);
} catch (InterruptedException er) {
er.printStackTrace();
}
}
} catch(IOException ex) {
System.err.println(ex);
}
}
//================== annouce the multigame can be started=====
public void announce(){
try {
// Send text to all the clients
for (Enumeration<DataOutputStream> e = getOutputStreams(); e.hasMoreElements();) {
DataOutputStream out = (DataOutputStream)e.nextElement();
// Write message
String str = sessionID+" Players now, you can start Multigame!";
out.writeUTF(str);
// Add chat to the server jta
textArea.append(str + '\n');
}
} catch(IOException ex) {
System.err.println(ex);
}
}
}//end of class ServerThread;
//============produce pattern ====================================
public void producePattern() {
for(int i=0; i<4; i++) {
pattern[i] = ((rand.nextInt(6))+1);
}
// *****test if the pattern[] is working properly
System.out.print("The secret pattern is : ");
for(int i=0;i<4;i++)
System.out.print(pattern[i]);
System.out.println("");
textArea.append("The secret pattern is "+pattern[0]+pattern[1]+pattern[2]+pattern[3]+"\n");
}
}//end of program;