Clien Server
Jumat, 14 Juni 2013
Membuat Game Domino pada JAVA
Tugas Besar Kuliah CS
Membuat Game Domino pada JAVA
package game;
import game.exceptions.InvalidFaceValueException;
import game.exceptions.InvalidNumberOfPlayersException;
import game.exceptions.InvalidPieceToPlayException;
import game.exceptions.NotPlayersTurnException;
import java.rmi.NotBoundException;
import java.rmi.RemoteException;
import java.rmi.registry.LocateRegistry;
import java.rmi.registry.Registry;
import java.util.ArrayList;
import java.util.List;
import server.Server;
import client.Client;
import client.ClientRemote;
import game.Board;
import game.Domino;
public class Game {
public static final int NUMBER_OF_MESSAGES_PER_GAME = 3;
public static final int NUMBER_OF_PLAYERS = 4; // numero de jogadores total por jogo. deve ser um múltiplo de 2
private static final int CURR_PLAYER_UNDEFINED = -1;
private List<Domino> dominoes;
private List<Player> players; // jogadores do jogo
private Board board; // mesa do jogo (situação atual das peças jogadas
private int currentPlayer = CURR_PLAYER_UNDEFINED; // jogador atual
private Domino firstPiece = null;
private Server server;
// Players can be added to the game all in one time by the Game object constructor
public Game(List<Player> players, Server server) throws InvalidNumberOfPlayersException {
this.server = server;
if (players == null || players.size() != NUMBER_OF_PLAYERS) {
throw new InvalidNumberOfPlayersException();
}
List<Player> tempPlayers = new ArrayList<Player>();
for (Player p: players) {
p.setCurrentGame(this);
tempPlayers.add(p);
}
// sorteando a ordem dos jogadores, o jogador de indice 0 será parceiro do jogador de indice 2, e o 1 do 3
this.players = new ArrayList<Player>();
for (int i = 0; i < NUMBER_OF_PLAYERS; i++) {
this.players.add(tempPlayers.remove((int) (Math.random() * (NUMBER_OF_PLAYERS - i))));
}
this.board = new Board();
}
public void startGame() throws RemoteException {
// Creating game pieces
createDominoPieces();
System.out.println("Existem " + players.size() + " Jogadores no jogo sendo iniciado.");
// ramdom dominoes to decide players pieces
for (int i = 0; i < NUMBER_OF_PLAYERS; i++) {
List<Domino> pieces = new ArrayList<Domino>();
for (int j = 0; j < 6; j++) {
int index = (int) (Math.random() * (28 - (i * 6 + j)));
pieces.add(dominoes.remove(index));
}
players.get(i).setPieces(pieces);
}
// decidindo quem sera o primeiro jogador (encontrar o dozão ou outra carroça)
currentPlayer = CURR_PLAYER_UNDEFINED;
int firstPiece = 6;
this.firstPiece = null;
do {
for (Player p: players) {
for (Domino d: p.getPieces()) {
if (d.getFace1() == firstPiece && d.getFace2() == firstPiece) {
currentPlayer = players.indexOf(p);
this.firstPiece = d;
break;
}
}
if (currentPlayer != CURR_PLAYER_UNDEFINED) break; // já foi encontrado o jogador que ira iniciar
}
firstPiece--; // procurar por uma carroça de menor valor
} while (currentPlayer == CURR_PLAYER_UNDEFINED && firstPiece >= 0);
if (currentPlayer == CURR_PLAYER_UNDEFINED) currentPlayer = 0;
waitForPlayersToBeReady();
// enviar uma mensagem a cada jogador, indicando que um jogo está sendo iniciado
for (Player p: players) {
p.getStub().receiveMessage("Game", "O jogo está sendo iniciado.");
}
// setando os parceiros dos jogadores, e chamando o método remoto em cada jogador para iniciar o jogo
List<String> playersNames = new ArrayList<String>();
for (int i = 0; i < players.size(); i++) {
playersNames.add(players.get((currentPlayer + i) % NUMBER_OF_PLAYERS).getUserName());
}
if (NUMBER_OF_PLAYERS % 2 == 0) {
for (int i = 0; i < NUMBER_OF_PLAYERS / 2; i++) {
Player p = players.get(i);
p.setPartner(players.get(i + NUMBER_OF_PLAYERS / 2).getUserName());
p.getStub().startGame(playersNames, p.getPieces());
p = players.get(i + NUMBER_OF_PLAYERS / 2);
p.setPartner(players.get(i).getUserName());
p.getStub().startGame(playersNames, p.getPieces());
}
}
refreshPlayersTurns();
}
private void createDominoPieces() {
dominoes = new ArrayList<Domino>();
for (int i = 0; i <= 6; i++) {
for (int j = i; j <= 6; j++) {
try {
dominoes.add(new Domino(i, j));
} catch (InvalidFaceValueException e) {
e.printStackTrace();
}
}
}
}
private void waitForPlayersToBeReady() throws RemoteException {
for (Player p: players) {
String service = Client.SERVICE_NAME_PREFIX + p.getUserName();
Registry registry = LocateRegistry.getRegistry();
ClientRemote stub = null;
int i = 0;
do {
try {
stub = (ClientRemote) registry.lookup(service);
System.out.println("O Servico remoto do jogador " + p.getUserName() + " esta pronto.");
} catch (NotBoundException e) {
System.out.println("O Jogador " + p.getUserName() + " ainda não inicializou o serviço remoto");
try {
Thread.sleep(500);
i++;
} catch (InterruptedException e1) {
e1.printStackTrace();
}
}
} while (stub == null || i >= 20);
if (i >= 20) removePlayer(p);
p.setStub(stub);
}
}
public void makeMove(Player p, Domino d, int position) throws NotPlayersTurnException, InvalidPieceToPlayException {
if (players.get(currentPlayer).equals(p)) {
if (d != null) {
if (board.isAValidPieceToPlay(d, position)) {
board.addPiece(d, position);
players.get(currentPlayer).getPieces().remove(d);
currentPlayer = (currentPlayer + 1) % NUMBER_OF_PLAYERS;
} else {
throw new InvalidPieceToPlayException();
}
} else {
currentPlayer = (currentPlayer + 1) % NUMBER_OF_PLAYERS;
}
for (Player player: players) {
if (!player.equals(p)) {
try {
player.getStub().moveMade(d, position);
} catch (RemoteException e) {
removePlayer(player);
return;
}
}
}
// TODO verificar se o jogo terminou
if (p.getPieces().size() == 0) {
// o jogador bateu: finalizar o jogo
playerWon(p);
return;
} else {
boolean finalized = true;
for (Player pTemp: players) {
for (Domino dTemp: pTemp.getPieces()) {
if (board.isAValidPieceToPlay(dTemp, Board.POSITION_START) || board.isAValidPieceToPlay(dTemp, Board.POSITION_END)) {
finalized = false;
break;
}
}
if (!finalized) break;
}
if (finalized) {
countPiecesPoints();
return;
}
}
// iniciando em uma nova Thread para poder retornar sem ficar bloqueado
new Thread() {
public void run() {
refreshPlayersTurns();
}
}.start();
} else {
throw new NotPlayersTurnException();
}
}
private void refreshPlayersTurns() {
// chamando o método para que os jogadores iniciem as jogadas
PlayerThread t = null;
for (int i = 0; i < NUMBER_OF_PLAYERS; i++) {
if (i == currentPlayer) {
// iniciando uma nova thread, para que a atual (do jogo) não fique bloqueada
t = new PlayerThread(players.get(i)) {
public void run() {
try {
p.getStub().myTimeToPlay();
} catch (RemoteException e) {
remoteExceptionThrowed = true;
}
}
};
t.start();
} else {
try {
players.get(i).getStub().waitAnotherPlayersMove();
} catch (RemoteException e) {
removePlayer(players.get(i));
return;
}
}
}
if (t != null) {
if (t.isRemoteExceptionThrowed()) {
removePlayer(players.get(currentPlayer));
return;
} else {
while (t.getState() != Thread.State.TERMINATED) {
try {
Thread.sleep(300);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
}
// retorno o numero de caracteres máximo de uma mensagem, dada a quantidade de mensagens ainda disponíveis
public static int getNumberOfCharsByAvailableMessages(int availableMessages) {
int maximumNumberOfChars = 10;
if (availableMessages <= NUMBER_OF_MESSAGES_PER_GAME && availableMessages >= 0) {
return maximumNumberOfChars - (NUMBER_OF_MESSAGES_PER_GAME - availableMessages) * 2;
}
return 0;
}
public boolean isAValidPieceToPlay(Domino d) {
// verificando se a peça está com o jogador da vez
for (Domino pd: players.get(currentPlayer).getPieces()) {
if (pd.equals(d)) {
// verificando se a peça pode ser jogada
if (board.getDominoes() == null || board.getDominoes().size() == 0) {
if (firstPiece == null) {
return true;
} else {
return firstPiece.equals(d);
}
} else {
boolean valid = board.isAValidPieceToPlay(d, Board.POSITION_START) || board.isAValidPieceToPlay(d, Board.POSITION_END);
if (valid) return true;
else return false;
}
}
}
return false;
}
public void removePlayer(final Player playerToRemove) {
// os outros jogadores devem ser liberados para jogar
for (Player player: players) {
if (playerToRemove != player) {
try {
player.setCurrentGame(null);
player.getStub().receiveMessage("Servidor", "O Jogador " + playerToRemove.getUserName() + " saiu do jogo. O jogo está sendo finalizado.");
player.getStub().receiveMessage("Servidor", "Outro Jogo será iniciado assim que possível");
PlayerThread pt = new PlayerThread(player) {
public void run() {
try {
this.p.getStub().endGame(Client.END_GAME_CAUSE_PLAYER_LOGGED_OUT, "O Jogador " + playerToRemove.getUserName() + " saiu do jogo.\nO jogo está sendo finalizado.");
server.freePlayer(p);
} catch (RemoteException e) {
remoteExceptionThrowed = true;
Game.this.server.removePlayer(p);
}
}
};
pt.start();
} catch (RemoteException e) {
this.server.removePlayer(playerToRemove);
}
}
}
}
private void playerWon(final Player winner) {
for (Player player: players) {
try {
player.setCurrentGame(null);
if (player != winner) {
player.getStub().receiveMessage("Servidor", "O Jogador " + player.getUserName() + " Bateu! Um Novo Jogo Será iniciado.");
} else {
player.getStub().receiveMessage("Servidor", "Você Venceu o Jogo!!! Um Novo Jogo Será iniciado.");
}
PlayerThread pt = new PlayerThread(player) {
public void run() {
try {
if (p != winner) {
this.p.getStub().endGame(Client.END_GAME_CAUSE_PLAYER_WON, "O Jogador " + winner.getUserName() + " Bateu!\nUm novo jogo será iniciado assim que possível.");
} else {
this.p.getStub().endGame(Client.END_GAME_CAUSE_PLAYER_WON, "Você Venceu o Jogo!!!\nUm novo jogo será iniciado assim que possível.");
}
server.freePlayer(p);
} catch (RemoteException e) {
remoteExceptionThrowed = true;
Game.this.server.removePlayer(p);
}
}
};
pt.start();
} catch (RemoteException e) {
this.server.removePlayer(player);
}
}
}
private void countPiecesPoints() {
int less = -1;
final List<Player> winners = new ArrayList<Player>();
// contagem dos pontos
for (Player p: players) {
if (less == -1 || p.getPoints() < less) {
winners.clear();
winners.add(p);
less = p.getPoints();
} else if (p.getPoints() == less) {
winners.add(p);
}
}
String w = "";
for (Player p: winners) {
w += p.getUserName();
if (winners.indexOf(p) < winners.size() - 2) {
w += ", ";
} else if (winners.indexOf(p) == winners.size() - 2) {
w += " e ";
}
}
final String s = w;
for (Player player: players) {
try {
player.setCurrentGame(null);
if (winners.size() == 1) {
if (!winners.contains(player)) {
player.getStub().receiveMessage("Servidor", "O Jogador " + winners.get(0).getUserName() + " Venceu nos pontos! Um Novo Jogo Será iniciado.");
} else {
player.getStub().receiveMessage("Servidor", "Você Venceu o Jogo nos Pontos!!! Um Novo Jogo Será iniciado.");
}
} else {
player.getStub().receiveMessage("Servidor", "Empate entre os jogadores " + w + "! Um Novo Jogo Será iniciado.");
}
PlayerThread pt = new PlayerThread(player) {
public void run() {
try {
if (winners.size() == 1) {
if (!winners.contains(p)) {
this.p.getStub().endGame(Client.END_GAME_CAUSE_GAME_CLOSED, "O Jogador " + winners.get(0).getUserName() + " Venceu nos Pontos!\nUm novo jogo será iniciado assim que possível.");
} else {
this.p.getStub().endGame(Client.END_GAME_CAUSE_GAME_CLOSED, "Você Venceu o Jogo nos Pontos!!!\nUm novo jogo será iniciado assim que possível.");
}
} else {
this.p.getStub().endGame(Client.END_GAME_CAUSE_GAME_CLOSED, "Empate entre os jogadores " + s + "!\nUm novo jogo será iniciado assim que possível.");
}
server.freePlayer(p);
} catch (RemoteException e) {
remoteExceptionThrowed = true;
Game.this.server.removePlayer(p);
}
}
};
pt.start();
} catch (RemoteException e) {
this.server.removePlayer(player);
}
}
}
}
Class Diagram - UML
Class Diagram - UML
Class diagram adalah
diagam yang digunakan untuk menampilkan beberapa kelas serta
paket-paket yang ada dalam sistem/perangkat lunak yang sedang kita
gunakan.
Class diagram memberi kita gambaran (diagram statis) tentang sistem/perangkat lunak dan relas-relasi yang ada didalamnya.
Definisi Class DiagramClass
adalah kumpulan objek-objek dengan dan yang mempunyai struktur umum,
behavior umum, relasi umum, dan semantic/kata yang umum. Class-class
ditentukan/ditemukan dengan cara memeriksa objek-objek dalam sequence
diagram dan collaboration diagram. Sebuah class digambarkan seperti
sebuah bujur sangkar dengan tiga bagian ruangan. Class sebaiknya diberi
nama menggunakan kata benda sesuai dengan domain/bagian/kelompoknya
(Whitten L. Jeffery et al, 2004).
Class Diagram adalah
diagram yang menunjukan class-class yang ada dari sebuah sistem dan
hubungannya secara logika. Class diagram menggambarkan struktur statis
dari sebuah sistem. Karena itu class diagram merupakan tulang punggung
atau kekuatan dasar dari hampir setiap metode berorientasi objek
termasuk UML (Henderi, 2008). Sementara menurut (Whitten L. Jeffery et
al 2004:432) class diagram adalah gambar grafis mengenai struktur objek
statis dari suatu sistem, menunjukan class-class objek yang menyusun
sebuah sistem dan juga hubungan antara class objek tersebut.
Elemen-eleman class diagram dalam
pemodelan UML terdiri dari: Class-class, struktur class, sifat class
(class behavior), perkumpulan/gabungan (association),
pengumpulan/kesatuan (agregation), ketergantungan (dependency),
relasi-relasi turunannya, keberagaman dan indikator navigasi, dan role
name (peranan/tugas nama).
Simbol-simbol class diagram
1.
Class: Class adalah blok - blok pembangun pada pemrograman berorientasi
obyek.Sebuah class digambarkan sebagai sebuah kotak yang terbagi atas 3
bagian. Bagian atas adalah bagian nama dari class. Bagian tengah
mendefinisikan property/atribut class. Bagian akhir mendefinisikan
methodmethod dari sebuah clas.
2.
Association : Sebuah asosiasi merupakan sebuah relationship paling umum
antara 2 class dan dilambangkan oleh sebuah garis yang menghubungkan
antara 2 class. Garis ini bisa melambangkan tipe-tipe relationship dan
juga dapat menampilkan hukum-hukum multiplisitas pada sebuah
relationship.(Contoh: One-to-one, one-to-many,many-to-many).
3.
Composition: Jika sebuah class tidak bisa berdiri sendiri dan harus
merupakan bagian dari class yang lain, maka class tersebut memiliki
relasi Composition terhadap class tempat dia bergantung tersebut. Sebuah
relationship composition digambarkan sebagai garis dengan ujung
berbentuk jajaran genjang berisi/solid.
4.
Dependency : Kadangkala sebuah class menggunakan class yang lain. Hal
ini disebut dependency. Umumnya penggunaan dependency digunakan untuk
menunjukkan operasi pada suatu class yang menggunakan class yang lain.
Sebuah dependency dilambangkan sebagai sebuah panah bertitik-titik.
5. Aggregation : Aggregation mengindikasikan keseluruhan bagian relationship dan biasanya disebut sebagai relasi.

Keterangan:
•
Class / table departemen memiliki ber-Agregasi dengan class / table
pegawai,alasannya karena departemen dapat berdiri sendiri tanpa ada
pegawai tetapi kinerjanya tidak sempurna. Banyak pegawai dapat bekerja
pada satu departemen jadi many to 1.
•
Class/table transaksi tidak dapat berdiri sendiri tanpa adanya
class/table produk. Begitu juga dengan table produk tidak bisa berdiri
sendiri tanpa adanya departemen.
• Banyak pelanggan dapat melakukan banyak tansaksi
• 1 transaksi dapat mencakup banyak produk.
Objek Diagram - UML
Objek Diagram - UML
Object diagram adalah suatu diagram yang berfungsi untuk mengatur atribut,objek dan hubungan antara contoh dalam diagram,object diagram juga dapat menampilkan struktur model system dalam waktu tertentu. Object diagram menggambarkan struktur sistem dari segi penamaan objek dan jalannya objek dalam sistem. Pada object diagram harus dipastikan semua kelas yang sudah didefinisikan pada diagram kelas harus dipakai objeknya, karena jika tidak, pendefinisian kelas itu tidak dapat dipertanggungjawabkan.[1]
Meskipun diagram kelas diperlukan untuk mendokumentasikan struktur kelas, tetapi diagram objek, dapat berguna. Sebuah diagram objek dasarnya Instansiasi semua atau bagian dari diagram kelas. (Instansiasi berarti untuk membuat sebuah instance dari kelas dengan satu set nilai atribut yang sesuai.)
Obyek diagram dapat sangat berguna ketika seseorang mencoba untuk mengungkap rincian dari sebuah kelas. Secara umum lebih mudah untuk berpikir dalam hal objek konkret (contoh) ketimbang abstraksi dari objek (kelas) [6]
A. KOMPONEN OBJECT DIAGRAM
Gambar 2. Komponen Class Diagram dan Object Diagram [6]
B. LANGKAH-LANGKAH PEMBUATAN OBJECT DIAGRAM
Diagram objek adalah instance dari class diagram. Ini menyiratkan bahwa diagram objek terdiri dari contoh hal-hal yang digunakan dalam diagram kelas. Jadi kedua diagram terbuat dari elemen dasar yang sama tetapi dalam bentuk yang berbeda. Dalam elemen diagram kelas dalam bentuk abstrak untuk mewakili cetak biru dan dalam diagram objek unsur-unsur dalam bentuk konkret untuk mewakili objek dunia nyata.
Untuk mengambil sistem tertentu, jumlah diagram kelas yang terbatas. Tetapi jika kita mempertimbangkan diagram objek maka kita dapat memiliki jumlah tak terbatas kasus yang unik di alam. Jadi hanya contoh-contoh yang dianggap mengalami dampak pada sistem. Dari uraian di atas jelaslah bahwa diagram objek tunggal tidak dapat menangkap semua kasus yang diperlukan atau lebih tepatnya tidak dapat menentukan semua objek dari suatu sistem. Jadi solusinya adalah:
- Menganalisis sistem dan memutuskan kasus yang memiliki data penting dan asosiasi.
- Mempertimbangkan hanya contoh-contoh yang akan mencakup fungsi tersebut.
- Membuat optimasi beberapa seperti jumlah contoh yang terbatas.
- Diagram objek yang terdiri dari benda-benda.
- Link dalam diagram objek digunakan untuk menghubungkan obyek.
- Obyek dan link adalah dua elemen yang digunakan untuk membangun sebuah diagram objek.
- Diagram objek harus memiliki nama yang berarti untuk menunjukkan tujuannya.
- Unsur-unsur yang paling penting adalah untuk diidentifikasi.
- Asosiasi antara objek-objek yang harus diklarifikasi.
- Nilai dari elemen yang berbeda harus diambil untuk memasukkan dalam diagram objek.
- Menambahkan catatan yang tepat pada titik-titik di mana kejelasan lebih diperlukan. [7]
C. CONTOH OBJECT DIAGRAM
Gambar 3. Contoh Class Diagram [6]
Gambar 4. Contoh Object Diagram [6]
Langganan:
Postingan (Atom)