04 - RMI-Aula - Pratica - N - 2 - Resolucao

Você também pode gostar

Você está na página 1de 6

Laboratório Nº4 (2ª Parte): RMI (Resolução)

1. Descrição
Para este exercício foi necessário a criação de uma interface TTTService que estende a Classe
Remota que disponibiliza a assinatura de todos os métodos implementados pelo objeto TTT que
representa o jogo, de forma que possa ser manipulado remotamente por um cliente, mesmo
que a Classe TTT e o objeto concreto se encontrem instanciados apenas no lado do servidor.
Para isso, o TTTServer ao ser executado, cria uma instância concreta de um objeto ttt e faz o seu
registro no diretório Java Names, no nosso caso, na porta 8080 do localhost.

Depois disso, o programa TTTClient tenta ler o nome do diretório, um objeto remoto que
responde à assinatura presente na interface TTTService, assim que a geração de um proxy
permite a interação com o objeto remoto ignorando detalhes da sua implementação.

Foi adicionado um método int lastPlay (int player), implementado na classe concreta TTT como
uma função que, obtendo o jogador retorna o último movimento feito por ele (para cada um
dos jogadores 2) ou retornando -1 se nenhum movimento foi feito pelo respetivo jogador. Este
método remoto é invocado quando o jogador escreve 10 como um lance, tendo para sua
validação alterado o leque de movimentos possíveis na lógica do jogo.

A solução também implementa um método restart () que permite reinicializar o tabuleiro logo
assim que um jogo termine.

2. Classes
As classes que foram implementadas para o acesso remoto ao jogo TTT são as seguintes:

• Game.java implementa a lógica do jogo, com invocações a métodos de objetos


remotos registrados no diretório de nomes, acedidos via proxy (TTTService);
• TTT.java implementa uma classe concreta associada a um jogo do objeto remoto;
• TTTServer.java executa o programa do servidor e registra o objeto no diretório do
Java Names para que possa estar acessível a ligações remotas;
• TTTService.java é usado quer pela interface do servidor do jogo para a declaração
do jogo como um objeto remoto, quer pelo cliente para a geração do proxy capaz
de responder aos métodos do jogo;
• TTTCliente.java executa o programa do cliente, consulta o diretório de nomes e
faz a ligação com o servidor do jogo.

O código que implementa estas classes encontra-se listado na secção Nº 5.

3. Compilação do código fonte:


Na pasta onde se encontram os ficheiros de código executar o seguinte comando (num
terminal): javac *.java

4. Execução do Servidor e Cliente


Num terminal execute o Servidor com o comando: java TTTServer

Noutro terminal execute o Cliente com o comando: java TTTClient

1
5. Listagem do Código
O programa do jogo é composto pelos seguintes ficheiros:

Game.java
import java.util.Scanner;
import java.rmi.RemoteException;

public class Game {


private TTTService ttt;
private Scanner keyboardSc;
private int winner = 0;
private int player = 1;

public Game(TTTService _ttt) throws RemoteException {


ttt = _ttt;
keyboardSc = new Scanner(System.in);
}

public int readPlay() throws RemoteException{


int play;
do {
System.out.printf("\nPlayer %d, please enter the number of the square "
+ "where you want to place your %c (or
0 to refresh the board): \n",
player, (player == 1) ? 'X' : 'O');
play = keyboardSc.nextInt();
System.out.println(play);
if(play == 11){
System.out.println("foi um 11");
ttt.removeLastPlay();
play = 0;

}
} while (play > 9 || play < 0);
return play;
}

public void playGame() throws RemoteException{


int play;
boolean playAccepted;

do {
player = ++player % 2;
do {
System.out.println(ttt.currentBoard());
play = readPlay();
if (play != 0) {
playAccepted = ttt.play( --play / 3, play % 3, player);
if (!playAccepted)
System.out.println("Invalid play! Try again.");
} else
playAccepted = false;
} while (!playAccepted);
winner = ttt.checkWinner();
} while (winner == -1);
}

2
public void congratulate() throws RemoteException{
if (winner == 2)
System.out.printf("\nHow boring, it is a draw\n");
else
System.out.printf(
"\nCongratulations, player %d, YOU ARE THE
WINNER!\n",
winner);
ttt.restart();
}
}

TTT.java
import java.rmi.*;
import java.rmi.server.UnicastRemoteObject;
import java.util.*;
import java.util.LinkedList;

public class TTT extends UnicastRemoteObject implements TTTService {


private LinkedList<TTT.play> Plays = new LinkedList<TTT.play>();

private static final long serialVersionUID = 1L;

protected TTT() throws RemoteException{


//TODO
}

private char board[][] = {


{'1','2','3'}, /* Initial values are reference numbers */
{'4','5','6'}, /* used to select a vacant square for */
{'7','8','9'} /* a turn. */
};

private char boardRestart[][] = {


{'1','2','3'}, /* Initial values are reference numbers */
{'4','5','6'}, /* used to select a vacant square for */
{'7','8','9'} /* a turn. */
};

private int nextPlayer = 0;


private int numPlays = 0;

public class play {


public int row;
public int column;
public int player;

public play(int _row, int _column, int _player){


row = _row;
column = _column;
player = _player;
}

public int getRow(){


return row;
}

3
public int getColumn(){
return column;
}
public int getPlayer(){
return player;
}
}

public String currentBoard() {


String s = "\n\n " +
board[0][0]+" | " +
board[0][1]+" | " +
board[0][2]+" " +
"\n---+---+---\n " +
board[1][0]+" | " +
board[1][1]+" | " +
board[1][2]+" " +
"\n---+---+---\n " +
board[2][0]+" | " +
board[2][1]+" | " +
board[2][2] + " \n";
return s;
}

public boolean play(int row, int column, int player) {


if (!(row >=0 && row <3 && column >= 0 && column < 3))
return false;
if (board[row][column] > '9')
return false;
if (player != nextPlayer)
return false;

if (numPlays == 9)
return false;

Plays.add(new TTT.play(row, column, player));

board[row][column] = (player == 1) ? 'X' : 'O'; /* Insert player symbol */


nextPlayer = (nextPlayer + 1) % 2;
numPlays ++;
return true;
}

public int checkWinner() {


int i;
/* Check for a winning line - diagonals first */
if((board[0][0] == board[1][1] && board[0][0] == board[2][2]) ||
(board[0][2] == board[1][1] && board[0][2] == board[2][0])) {
if (board[1][1]=='X')
return 1;
else
return 0;
}
else
/* Check rows and columns for a winning line */
for(i = 0; i <= 2; i ++){

4
if((board[i][0] == board[i][1] && board[i][0] == board[i][2])) {
if (board[i][0]=='X')
return 1;
else
return 0;
}

if ((board[0][i] == board[1][i] && board[0][i] == board[2][i])) {


if (board[0][i]=='X')
return 1;
else
return 0;
}
}
if (numPlays == 9)
return 2; /* A draw! */
else
return -1; /* Game is not over yet */
}

public void restart() {


board = boardRestart;
nextPlayer = 0;
numPlays = 0;
}

public void removeLastPlay(){


int _column, _row;

for(int k=2; k>0; k--){


if(Plays.size() > 0){
_row = Plays.getLast().getRow();
_column = Plays.getLast().getColumn();

board[_row][_column] = (char) (48 + (( (3*_row) + (1+_column))));

numPlays--;
Plays.removeLast();
}
}
}
}

TTTServer.java
import java.io.IOException;
import java.rmi.registry.LocateRegistry;
import java.rmi.registry.Registry;

public class TTTServer {


public static void main(String args[]) throws IOException {

int registryPort = 8080;

System.out.println("Main OK");

5
try {
TTTService tttGame = new TTT();

System.out.println("After create");

Registry reg = LocateRegistry.createRegistry(registryPort);

System.out.println("Local Registry OK");

reg.rebind("TTTService", tttGame);

System.out.println("Rebind OK");

System.out.println("TTT server ready");

} catch(Exception e) {
System.out.println("TTT server main " + e.getMessage());
}

System.out.println("Please start the client...");

}
}

TTTService.java
import java.rmi.*;

public interface TTTService extends Remote {

String currentBoard() throws RemoteException;


boolean play(int row, int column, int player) throws RemoteException;
int checkWinner() throws RemoteException;
void restart() throws RemoteException;
void removeLastPlay() throws RemoteException;

TTTClient.java
import java.rmi.*;

public class TTTClient {


public static void main(String args[]) throws Exception {
TTTService tttService = null;
try{
tttService = (TTTService) Naming.lookup("rmi://" + "localhost" +":"+8080+"/TTTService");
System.out.println("Found server");
Game g = new Game(tttService);
g.playGame();
g.congratulate();
}catch(RemoteException e) {System.out.println("[REMOTE]:" + e.getMessage());
}catch(Exception e) {System.out.println("[Exception]:" + e.getMessage());}
}
}

Você também pode gostar