
// FBFServer.java
// Andrew Davison, April 2005, ad@fivedots.coe.psu.ac.th

/* Vláknový server specializovaný na práci s nejvýše dvěma
   souběžnými spoji od dvou hráčů zapojených do hraní 
   piškvorek.

   Jedná se o tenký server -- veškerá herní logika je umístěna
   na straně klienta.

   Sdílená data tvoří pole odkazů na obslužné objekty a 
   aktuální počet hráčů. Údajů je tedy jen hrstka a tak pro ně není
   nutné vytvářet speciální objekt, který by je spravoval.
*/

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


public class FBFServer
{
  private static final int PORT = 1234;

  private static final int MAX_PLAYERS = 2;   // hra pro dva hráče
  private final static int PLAYER1    = 1;
  private final static int PLAYER2    = 2;   // dříve byl stroj

  // data structures shared by the handlers
  private PlayerServerHandler[] handlers;     // pro zpracování zpráv hráčů
  private int numPlayers;

  
  public FBFServer()
  // souběžně zpracovává hráče
  {
    handlers = new PlayerServerHandler[MAX_PLAYERS];
    handlers[0] = null;
    handlers[1] = null;
    numPlayers = 0;

    try {
      ServerSocket serverSock = new ServerSocket(PORT);
      Socket clientSock;
      while (true) {
        System.out.println("Čekám na klienta...");
        clientSock = serverSock.accept();
        new PlayerServerHandler(clientSock, this).start();
      }
    }
    catch(Exception e)
    {  System.out.println(e);  }
  }  // konec metody: ChatServer()


  // metody pro vlákna poskytující přístup ke sdíleným datovým strukturám

  synchronized public boolean enoughPlayers()
  { return (numPlayers == MAX_PLAYERS); }


  synchronized public int addmlayer(PlayerServerHandler h)
  /* Uloží odkaz na obslužný objekt a vrátí ID hráče, které je indexem
     určující pozici obslužného objektu (+1).
  */
  { for(int i=0; i < MAX_PLAYERS; i++)
      if (handlers[i] == null) {
        handlers[i] = h;
        numPlayers++; 
        return i+1;   // hráč je 1 nebo 2  (index v poli + 1)
      }
    return -1;  // znamená, že již máme dostatek hráčů
  }  // konec metody: addmlayer()


  synchronized public void removePlayer(int playerID)
  { handlers[playerID-1] = null;     // hodnotu hráče nijak nekontrolujeme
    numPlayers--; 
  }  // konec metody: removePlayer()


  synchronized public void tellOther(int playerID, String msg)
  // pošle zprávu druhému hráči
  { int otherID = ((playerID == PLAYER1) ? PLAYER2 : PLAYER1 );
    if (handlers[otherID-1] != null)     // index je ID - 1
      handlers[otherID-1].sendMessage(msg);
  }  // konec metody: tellOther()


  // -----------------------------------

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

} // konec třídy: FBFServer



