package scotlandyard.server;
import java.util.ArrayList;
import java.util.Queue;
import scotlandyard.shared.BoardState;
import scotlandyard.shared.Player;
import scotlandyard.shared.messaging.Message;
import scotlandyard.shared.messaging.MessageConnect;
import scotlandyard.shared.messaging.MessageDisconnect;
import scotlandyard.shared.messaging.MessageGiveTurn;
import scotlandyard.shared.messaging.MessageMove;
import scotlandyard.shared.messaging.MessageStart;
/**
* @author Felipe Blassioli GameServer handles players and is also responsible
* for receiving and sending messages to and from players.
*
* About receiving messages and sending it to other players: - An
* in-game play (Movement, tip or answer)message is only put to other
* clients's queues if it's the player's turn in the game. - Any other
* type of message such as CONNECT, DISCONNECT are always added to all
* of the queues.
*/
public class GameServer {
public enum GameState {
RUNNING, FINISHED, OPEN
}
public static final int MAX_PLAYERS = 6;
private String gameName;
private ArrayList<Player> players;
private int playersNumber;
// Message Queues
private ArrayList<Queue<Message>> messageQueues;
private boolean[] start;
private int startCount;
private GameManager myManager;
private GameState gameState;
public boolean stopServer = false;
public GameServer(String gameName) {
playersNumber = 0;
players = new ArrayList<Player>();
this.gameName = gameName;
messageQueues = new ArrayList<Queue<Message>>();
start = new boolean[MAX_PLAYERS];
startCount = 0;
myManager = new GameManager(this);
}
// Methods called by GameService
public BoardState getBoardState() {
return myManager.getCurrentBoardState();
}
public void move (Player player, int destination){
myManager.move(player, destination);
/*sendMessage (
new MessageMove(
player.getName(),
String.valueOf(destination),
String.valueOf(src))
);*/
//if destination equals some place door
//send clue to player
//if destinion equals holmes door
//ask answer
//myManager.proximoJogador();
//putMessageOnQueue(players.indexOf(player), new MessageGiveTurn("servidor"));
}
// Methods called by PreGameService
public void joinGame(Player player) {
// GameServer game = MainServer.getMainServerInstance()
// .getGameServerByGameName(gameName);
messageQueues.add(new MessageQueue());
players.add(player);
// notify the other players
this.sendMessage(new MessageConnect(player.getName()));
System.out.println(player.getName() + " has join " + gameName);
}
public void quitGame(Player player) {
messageQueues.remove(players.indexOf(player));
players.remove(player);
// notify the other players
this.sendMessage(new MessageDisconnect(player.getName()));
}
public String[] getPlayerNames() {
String[] names = new String[players.size()];
for (int i = 0; i < players.size(); i++) {
names[i] = players.get(i).getName();
}
return names;
}
public void readyStartGame(Player p) {
if (start[players.indexOf(p)]) {
start[players.indexOf(p)] = false;
--startCount;
} else {
start[players.indexOf(p)] = true;
if (++startCount == players.size()){
MainServer.getMainServerInstance().gameStarted(this);
myManager.startGame();
System.out.println("GAMESERVER: now game has started and is running");
this.setGameState(GameState.RUNNING);
sendMessage(new MessageStart("servidor"));
start = new boolean[MAX_PLAYERS];
startCount = 0;
//myManager.proximoJogador();
}
}
}
/**
* Basically it starts the game (sends message to do it) when all players
* are ready.
*/
// Methods concerning messaging
public Message getMessage(Player player) {
for (int i = 0; i < players.size(); i++) {
if (players.get(i).equals(player)) {
return getMessage(i);
}
}
System.out.println("nulo");
return null;
}
private Message getMessage(int queueIndex) {
return messageQueues.get(queueIndex).poll();
}
private void putMessageOnQueue(int queueIndex, Message message) {
messageQueues.get(queueIndex).add(message);
//System.out.println("\tMensagem colocada na pilha de "
// + players.get(queueIndex).getName());
}
public void sendPrivateMessage(Player p, Message msg) {
System.out.println("\tSending private message");
for (int i = 0; i < players.size(); i++) {
if (players.get(i) == p) {
putMessageOnQueue(i, msg);
System.out
.println("\tPrivate message was sent to " + p.getName()+"\n");
}
}
}
public void sendMessage(Message msg) {
String senderName = msg.getSenderName();
System.out.println("Enviando mensagem... " + msg);
for (int i = 0; i < players.size(); i++) {
putMessageOnQueue(i, msg);
}
}
// Getters and Setters
public String getGameName() {
return gameName;
}
public void setGameName(String gameName) {
this.gameName = gameName;
}
public int getPlayersNumber() {
return playersNumber;
}
public void setPlayersNumber(int playersNumber) {
this.playersNumber = playersNumber;
}
public ArrayList<Player> getPlayers() {
return players;
}
public void setPlayers(ArrayList<Player> players) {
this.players = players;
}
public void switchPlayer (Player p){
for(int i = 0; i < players.size(); i++){
if (players.get(i).getName().equals(p.getName()))
players.add(i, p);
}
}
public void checkAllInterfaceLoaded(Player p) {
if (!start[players.indexOf(p)]) {
start[players.indexOf(p)] = true;
System.out.println("\n\nGAMESERVER: Interfaces prontas: "+startCount+1);
if (++startCount == players.size()){
//myManager.startGame();
//sendMessage(new MessageStart("servidor"));
//myManager.proximoJogador();
System.out.println("GAMESERVER: All interfaces ready! Giving Turn");
myManager.proximoJogador();
}
}else{
System.out.println("N�o entrei no IF!");
}
}
public boolean isRunning() {
if (gameState == GameState.RUNNING)
return true;
return false;
}
public void setGameState(GameState gameState) {
this.gameState = gameState;
}
}