4 en línea
-
Upload
jose-rene-white-enciso -
Category
Documents
-
view
220 -
download
0
Transcript of 4 en línea
-
8/4/2019 4 en lnea
1/23
Integrantes:
- Josimar Reyes Campos A00394790
- Miguel ngel Serrano Chvez A00396682
- Jos Ren White Enciso A00397389
4 EN LNEA3ER PARCIAL: MANEJO DE SOCKETS
-
8/4/2019 4 en lnea
2/23
4 EN LNEA3ER PARCIAL: MANEJO DE SOCKETS
CONCLUSIONES
El proyecto realizado en el programa Conecta Cuatro nos ha permitidoaprender el manejo de los sockets a fin de comunicar a las aplicacionesentre si, ya sea mediante protocolo tcp/ip o mediante llamadas internasdentro del mismo sistema.
Sin embargo, el poderlo aplicar a un juego ha resultado ser un gran reto,debido a la cantidad de variables en juego.
Durante la realizacin del proyecto, se encontraron diversos problemas deconectividad, as como problemas en el diseo de la lgica del juego.
Sin embargo, esta se pudo adaptar para cumplir sus reglasindependientemente del tamao del tablero de juego. (En una posiblesegunda versin se podra elegir la dificultad a partir del tamao)
No se agreg la inteligencia artificial al juego final, debido a que estaentorpeca el juego entre 2 jugadores.
Se logr comunicar a los 2 clientes, adems de inicializar un servidorautomtico, dependiendo de la eleccin del jugador de ser host o de ser
invitado.
La clase de servidor y cliente son diferentes, pero comparten la misma GUI.
En resumen se cumplieron, casi todas las expectativas; excepto la delreinicio por fallas y el tiempo de juego por descuido.
OBJETIVOS
Alternar el tirar la ficha
Usar tablero de 8
columnas por 10 filas.
Mostrar en el tablero el tiro
del jugador.
Enviar el mensaje al otro
jugador para que tire.
Determinar si se ha
terminado la partida.
Volver a iniciar el juego.
Competir contra la
mquina.
Mostrar el tiempo de la
partida.
El nmero de partidas
ganadas vs perdidas.
-
8/4/2019 4 en lnea
3/23
CAPTURAS Y RESULTADOS
-
8/4/2019 4 en lnea
4/23
-
8/4/2019 4 en lnea
5/23
ELEMENTOS UTILIZADOS EN LA INTERFAZ GRFICA
Para la interfaz grfica, se utilizaron los siguientes componentes:
JTextArea JLabel JButton JPanel
JScrollPane
Siendo utilizados para crear tanto el tablero, como el display con la informacin de las jugadas.
-
8/4/2019 4 en lnea
6/23
ANEXOS
ANEXO 1
ConectaCuatro _Juego
packageJuego_Conecta4;
importjava.awt.*;importjava.awt.event.*;importjavax.swing.*;importjavax.swing.border.*;importjava.util.InputMismatchException;
publicclassConectaCuatro_Juego{
intPV1;
intPV2;intopcion;Stringhost;
publicvoidConectaCuatro_Juego(intV1,intV2,intop,Stringh){PV1=V1;PV2=V2;opcion=op;host=h;
// if no command line argsif(opcion==0){
ConectaCuatro_Serverserver=newConectaCuatro_Server();
CC_GUIgui=newCC_GUI
(host
);// localhostgui.setVisible(true);
gui.Op=opcion;
ConectaCuatrogame=newConectaCuatro();ConectaCuatroListenerlistener=
newConectaCuatroListener(game,gui);}elseif(opcion==1){
ConectaCuatro_Serverserver=newConectaCuatro_Server();CC_GUIgui=newCC_GUI(host);// localhostgui.setVisible(true);gui.Op=opcion;
ConectaCuatrogame=newConectaCuatro();ConectaCuatroListenerlistener=
newConectaCuatroListener(game,gui);}else{
CC_GUIgui;Stringip=JOptionPane.showInputDialog
("Ingrese la direccin ip del servidor");gui=newCC_GUI(host);// localhostgui.setVisible(true);gui.Op=opcion;
}}
publicstaticvoidmain(Stringargs[]){
-
8/4/2019 4 en lnea
7/23
java.awt.EventQueue.invokeLater(newRunnable(){publicvoidrun(){
//Agrea un option pane al inicio para saber si el juego//es local o como va a ser
intopcion;
try{opcion=Integer.parseInt(JOptionPane.showInputDialog
("0=Partida local ||"+" 1 partida en lnea como anfitrion ||"+" 2 o ms para partida como huesped"));
}catch(InputMismatchExceptione){
opcion=Integer.parseInt(JOptionPane.showInputDialog("Elige 0 para jugar localmente\no elige cualquier "+"numero para jugar en lnea..."));
}
// if no command line argsif(opcion==0){
ConectaCuatro_Serverserver=newConectaCuatro_Server();CC_GUIgui=newCC_GUI("127.0.0.1");// localhostgui.setVisible(true);ConectaCuatrogame=newConectaCuatro();ConectaCuatroListenerlistener=
newConectaCuatroListener(game,gui);}elseif(opcion==1){
ConectaCuatro_Serverserver=newConectaCuatro_Server();CC_GUIgui=newCC_GUI("127.0.0.1");// localhostgui.setVisible(true);
ConectaCuatrogame=newConectaCuatro();ConectaCuatroListenerlistener=
newConectaCuatroListener(game,gui);}else{
CC_GUIgui;Stringip=JOptionPane.showInputDialog
("Ingrese la direccin ip del servidor");gui=newCC_GUI(ip);// localhostgui.setVisible(true);
}}
});}
}
-
8/4/2019 4 en lnea
8/23
ConectaCuatro _Listener
packageJuego_Conecta4;
importjavax.swing.*;importjava.awt.event.*;
publicclassConectaCuatroListenerimplementsMouseListener{
CC_GUIgui;ConectaCuatrogame;
publicConectaCuatroListener(ConectaCuatrogame,CC_GUIgui){
this.game=game;this.gui=gui;
gui.AgregaListener(this);}
publicvoidmouseClicked(MouseEventevent){JLabellabel=(JLabel)event.getComponent();intcolumna=gui.ObtenerColumna(label);intfila=game.caer(columna);
gui.InfoArea.setText(game.toString()+"\n"+gui.msg);if(fila!=-1){
gui.set(columna,fila);if(game.GameOver()){
gui.Ganador(game.GameOver(),gui.JugadorEnTurno);if(gui.Restart){
game.Limpiar();gui.Restart=false;
}
}}
}
publicvoidmousePressed(MouseEventevent){}publicvoidmouseReleased(MouseEventevent){}publicvoidmouseEntered(MouseEventevent){}publicvoidmouseExited(MouseEventevent){}
}
-
8/4/2019 4 en lnea
9/23
ConectaCuatro
packageJuego_Conecta4;
//Clase con la lgica del juego.
publicclassConectaCuatro{
// La red usada para almacenar el entorno del juego.int[][]Tablero;// Indica el turno para cada jugador.
intJugadorEnTurno;intcolumnas=8;intfilas=10;
/*** El constructor del juego.** Crea e inicializa el tablero del juego*/publicConectaCuatro(){
// create the gridTablero=newint[columnas][filas];// initialize the gridfor(intfila=0;fila
-
8/4/2019 4 en lnea
10/23
// Therefore, return false to indicate that this// drop operation failed.if(fila==filas){return-1;}
returnfila;}
publicStringtoString(){StringreturnString="";for(intfila=(filas-1);fila>=0;fila--){
for(intcolumna=0;columna
-
8/4/2019 4 en lnea
11/23
for(intfila=3;fila
-
8/4/2019 4 en lnea
12/23
ConectaCuatro_Server
packageJuego_Conecta4;
importjava.awt.BorderLayout;importjava.net.ServerSocket;importjava.net.Socket;
importjava.io.IOException;importjava.util.Formatter;importjava.util.Scanner;importjava.util.concurrent.ExecutorService;importjava.util.concurrent.Executors;importjava.util.concurrent.locks.Lock;importjava.util.concurrent.locks.ReentrantLock;importjava.util.concurrent.locks.Condition;importjavax.swing.JFrame;importjavax.swing.JTextArea;importjavax.swing.SwingUtilities;
publicclassConectaCuatro_Server{
CC_GUIgui;ConectaCuatrogame;
privateStringoutputArea;// for outputting movesprivatePlayer[]players;// array of PlayersprivateServerSocketserver;// server socket to connect with clientsprivateintJugadorEnTurno;// keeps track of player with current moveprivatefinalstaticintP1=0;// constant for first playerprivatefinalstaticString[]Jugadores={"Jugador 1","Jugador 2"};//
array of marksprivateExecutorServicerunGame;// will run playersprivateLockgameLock;// to lock game for synchronization
privateConditionotherPlayerConnected;// to wait for other playerprivateConditionotherPlayerTurn;// to wait for other player's turn
// set up tic-tac-toe server and GUI that displays messagespublicConectaCuatro_Server(){
// create ExecutorService with a thread for each playerrunGame=Executors.newFixedThreadPool(2);gameLock=newReentrantLock();// create lock for game
// condition variable for both players being connectedotherPlayerConnected=gameLock.newCondition();
// condition variable for the other player's turnotherPlayerTurn=gameLock.newCondition();
players=newPlayer[2];// create array of playersJugadorEnTurno=P1;// set current player to first player
// set up ServerSockettry{server=newServerSocket(12345,2);}catch(IOExceptionioException){
ioException.printStackTrace();System.exit(1);
}// end catch
}
// wait for two connections so game can be played
-
8/4/2019 4 en lnea
13/23
publicvoidexecute(){// wait for each client to connectfor(inti=0;i-2){
game.caer(col);JugadorEnTurno=(JugadorEnTurno+1)%2;// change player
// let new current player know that move occurred
players[JugadorEnTurno].otherPlayerMoved(col);
gameLock.lock();// lock game to signal other player to go
-
8/4/2019 4 en lnea
14/23
try{otherPlayerTurn.signal();// signal other player to continue
}finally{
gameLock.unlock();// unlock game after signaling}
returntrue;// notify player that move was valid}// end ifelse// move was not valid
returnfalse;// notify player that move was invalid}
// place code in this method to determine whether game overpublicbooleanisGameOver(){
returngame.GameOver();}
// private inner class Player manages each Player as a runnableprivateclassPlayerimplementsRunnable{
privateSocketconnection;// connection to clientprivateScannerinput;// input from clientprivateFormatteroutput;// output to clientprivateintNumeroJugador;// tracks which player this isprivateStringNombre;// mark for this playerprivatebooleansuspended=true;// whether thread is suspended
// set up Player threadpublicPlayer(Socketsocket,intnumber){
NumeroJugador=number;// store this player's numberNombre=Jugadores[NumeroJugador];// specify player's markconnection=socket;// store socket for client
try// obtain streams from Socket{
input=newScanner(connection.getInputStream());output=newFormatter(connection.getOutputStream());
}// end trycatch(IOExceptionioException){
ioException.printStackTrace();System.exit(1);
}// end catch}// end Player constructor
// send message that other player movedpublicvoidotherPlayerMoved(intcol){
output.format("Opponent moved\n");output.format("%d\n",game.Fila(col));// send location of moveoutput.format("%d\n",col);// send location of moveoutput.flush();// flush output
}// end method otherPlayerMoved
// control thread's executionpublicvoidrun(){
// send client its mark (X or O), process messages from client
try{
displayMessage(Nombre+" connected\n");output.format("%s\n",Nombre);// send player's mark
-
8/4/2019 4 en lnea
15/23
output.flush();// flush output
// if player X, wait for another player to arriveif(NumeroJugador==P1){
output.format("%s\n%s",(Nombre+" connected\n"),"Waiting for another player\n");
output.flush();// flush output
gameLock.lock();// lock game to wait for second player
try{while(suspended){
otherPlayerConnected.await();// wait for player O}
}catch(InterruptedExceptionexception){
exception.printStackTrace();}finally{
gameLock.unlock();// unlock game after second player}
// send message that other player connectedoutput.format("Other player connected. Your move.\n");output.flush();// flush output
}else{
output.format("Player O connected, please wait\n");output.flush();// flush output
}
// while game not overwhile(!isGameOver()){
intcolumna=-1;// initialize move location
if(input.hasNext())columna=input.nextInt();// get move location
// check for valid moveif(validateAndMove(columna,NumeroJugador)){
displayMessage("\nColumna seleccionada: "+columna);output.format("Movimiento valido.\n");// notify clientoutput.flush();// flush output
}// move was invalidelse{
output.format("Movimiento invalido, intenta de nuevo\n");output.flush();// flush output
}}
}finally {
// close connection to clienttry
{connection.close();}catch(IOExceptionioException){
ioException.printStackTrace();System.exit(1);
}
}}
// set whether or not thread is suspended
-
8/4/2019 4 en lnea
16/23
publicvoidsetSuspended(booleanstatus){suspended=status;// set value of suspended
}}// Fin de la clase Player
}
-
8/4/2019 4 en lnea
17/23
CC_GUI
/** CC_GUI.java** Created on 15/04/2011, 05:06:19 PM*/
packageJuego_Conecta4;
importjava.awt.*;importjava.awt.event.*;importjavax.swing.*;importjavax.swing.border.*;
//Imports clienteimportjava.net.Socket;importjava.net.InetAddress;importjava.io.IOException;
importjava.util.Formatter;importjava.util.Scanner;importjava.util.concurrent.Executors;importjava.util.concurrent.ExecutorService;importjava.util.InputMismatchException;
publicclassCC_GUIextendsjavax.swing.JFrameimplementsRunnable {
ConectaCuatro_Juegoplay=newConectaCuatro_Juego();
privateJLabel[][]casillas;privateintcolumnas=8;
privateintfilas=10;intJugadorEnTurno;intPV1=play.PV1;intPV2=play.PV2;intOp=play.opcion;Stringmsg="";
//Variables para el clienteprivateSocketconnection;// connection to serverprivateScannerinput;// input from serverprivateFormatteroutput;// output to serverprivatebooleanmyTurn;// determines which client's turn it isbooleanRestart=false;// determines which client's turn it is
privateStringNombre;// this client's markStringHostCC;// host name for server
privatefinalStringPlayer1="Jugador 1";// mark for first client
/** Creates new form CC_GUI */publicCC_GUI(Stringhost){
HostCC=host;// set name of server
initComponents();Panel.setLayout(newGridLayout(filas,columnas));casillas=newJLabel[columnas][filas];for(intfila=(filas-1);fila>=0;fila--){
for(intcolumna=0;columna
-
8/4/2019 4 en lnea
18/23
//La linea de arriba es solo para darle un formato msagradable visualmente
casillas[columna][fila].setHorizontalAlignment(SwingConstants.CENTER);casillas[columna][fila].setBorder(new
LineBorder(Color.DARK_GRAY));Panel.add(casillas[columna][fila]);
}}Panel.setSize((50*columnas),(50*filas));
JugadorEnTurno=1;if(!host.isEmpty()){startClient();}
}
/** This method is called from within the constructor to* initialize the form.* WARNING: Do NOT modify this code. The content of this method is* always regenerated by the Form Editor.*/
@SuppressWarnings("unchecked")// //GEN-
BEGIN:initComponentsprivatevoidinitComponents(){
Panel=newjavax.swing.JPanel();jPanel1=newjavax.swing.JPanel();P1N=newjavax.swing.JLabel();P2N=newjavax.swing.JLabel();P1V=newjavax.swing.JLabel();P2V=newjavax.swing.JLabel();Reiniciar=newjavax.swing.JButton();jScrollPane1=newjavax.swing.JScrollPane();InfoArea=newjavax.swing.JTextArea();
setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);setResizable(false);
Panel.setBorder(javax.swing.BorderFactory.createEtchedBorder());Panel.setPreferredSize(newjava.awt.Dimension(400,500));
javax.swing.GroupLayoutPanelLayout=newjavax.swing.GroupLayout(Panel);Panel.setLayout(PanelLayout);PanelLayout.setHorizontalGroup(
PanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING).addGap(0,396,Short.MAX_VALUE)
);PanelLayout.setVerticalGroup(
PanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING).addGap(0,496,Short.MAX_VALUE)
);
jPanel1.setBorder(javax.swing.BorderFactory.createTitledBorder("Jugadores"));
P1N.setIcon(newjavax.swing.ImageIcon(getClass().getResource("/Graficos/User2.png")));// NOI18N
P1N.setText("Jugador 1");
P2N.setHorizontalAlignment(javax.swing.SwingConstants.LEFT);P2N.setIcon(new
javax.swing.ImageIcon(getClass().getResource("/Graficos/User4.png")));// NOI18N
-
8/4/2019 4 en lnea
19/23
P2N.setText("Jugador 2");
P1V.setText("...");
P2V.setText("...");
javax.swing.GroupLayoutjPanel1Layout=newjavax.swing.GroupLayout(jPanel1);
jPanel1.setLayout(jPanel1Layout);jPanel1Layout.setHorizontalGroup(
jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING).addGroup(jPanel1Layout.createSequentialGroup()
.addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING,false)
.addComponent(P2N,javax.swing.GroupLayout.Alignment.LEADING,javax.swing.GroupLayout.DEFAULT_SIZE,javax.swing.GroupLayout.DEFAULT_SIZE,Short.MAX_VALUE)
.addComponent(P1N,javax.swing.GroupLayout.Alignment.LEADING,javax.swing.GroupLayout.DEFAULT_SIZE,javax.swing.GroupLayout.DEFAULT_SIZE,Short.MAX_VALUE))
.addGap(39,39,39)
.addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING)
.addComponent(P1V,javax.swing.GroupLayout.PREFERRED_SIZE,44,javax.swing.GroupLayout.PREFERRED_SIZE)
.addComponent(P2V,javax.swing.GroupLayout.PREFERRED_SIZE,44,javax.swing.GroupLayout.PREFERRED_SIZE))
.addContainerGap()));jPanel1Layout.setVerticalGroup(
jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING).addGroup(jPanel1Layout.createSequentialGroup()
.addContainerGap()
.addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
.addComponent(P1N)
.addComponent(P1V,javax.swing.GroupLayout.DEFAULT_SIZE,50,Short.MAX_VALUE))
.addGap(33,33,33)
.addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
.addComponent(P2N)
.addComponent(P2V,javax.swing.GroupLayout.DEFAULT_SIZE,50,Short.MAX_VALUE))
.addGap(30,30,30)));
Reiniciar.setText("Reiniciar");Reiniciar.setEnabled(false);Reiniciar.addMouseListener(newjava.awt.event.MouseAdapter(){
publicvoidmouseClicked(java.awt.event.MouseEventevt){ReiniciarMouseClicked(evt);
}});
jScrollPane1.setEnabled(false);jScrollPane1.setOpaque(false);
-
8/4/2019 4 en lnea
20/23
InfoArea.setColumns(20);InfoArea.setRows(5);jScrollPane1.setViewportView(InfoArea);
javax.swing.GroupLayoutlayout=newjavax.swing.GroupLayout(getContentPane());
getContentPane().setLayout(layout);layout.setHorizontalGroup(
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING).addGroup(layout.createSequentialGroup()
.addContainerGap()
.addComponent(Panel,javax.swing.GroupLayout.PREFERRED_SIZE,javax.swing.GroupLayout.DEFAULT_SIZE,javax.swing.GroupLayout.PREFERRED_SIZE)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING).addComponent(jScrollPane1,
javax.swing.GroupLayout.DEFAULT_SIZE,262,Short.MAX_VALUE).addComponent(jPanel1,javax.swing.GroupLayout.DEFAULT_SIZE,
262,Short.MAX_VALUE).addComponent(Reiniciar,
javax.swing.GroupLayout.DEFAULT_SIZE,262,Short.MAX_VALUE)).addContainerGap())
);layout.setVerticalGroup(
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING).addGroup(layout.createSequentialGroup()
.addContainerGap()
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING,false)
.addGroup(javax.swing.GroupLayout.Alignment.TRAILING,layout.createSequentialGroup()
.addComponent(jPanel1,javax.swing.GroupLayout.PREFERRED_SIZE,javax.swing.GroupLayout.DEFAULT_SIZE,javax.swing.GroupLayout.PREFERRED_SIZE)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED).addComponent(jScrollPane1)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED).addComponent(Reiniciar))
.addComponent(Panel,javax.swing.GroupLayout.PREFERRED_SIZE,javax.swing.GroupLayout.DEFAULT_SIZE,javax.swing.GroupLayout.PREFERRED_SIZE))
.addContainerGap(28,Short.MAX_VALUE)));
pack();}// //GEN-END:initComponents
privatevoidReiniciarMouseClicked(java.awt.event.MouseEventevt){//GEN-FIRST:event_ReiniciarMouseClicked
// TODO add your handling code here:InfoArea.setText("Reiniciando...\n Aun no del todo implementado");for(intfila=0;fila
-
8/4/2019 4 en lnea
21/23
/*** @param args the command line arguments*/
publicvoidAgregaListener(ConectaCuatroListenerlistener){for(intfila=0;fila
-
8/4/2019 4 en lnea
22/23
worker.execute(this);// execute client}
// control thread that allows continuous update of displayAreapublicvoidrun(){
Nombre=input.nextLine();
SwingUtilities.invokeLater(newRunnable(){
publicvoidrun(){
// display player's markInfoArea.setText("You are player \""+Nombre+"\"");
}// end method run}// end anonymous inner class
);// end call to SwingUtilities.invokeLater
myTurn=(Nombre.equals(Player1));// determine if client's turn
// receive messages sent to client and output themwhile(true){
if(input.hasNextLine())processMessage(input.nextLine());
}// end while}// end method run
// process messages received by clientprivatevoidprocessMessage(Stringmessage){
msg=message;// valid move occurred
if(message.equals("Movimiento valido.")){
displayMessage("Movimiento valido, espere por favor...\n");}// end ifelseif(message.equals("Movimiento invalido, intenta de nuevo")){
displayMessage(message+"\n");// display invalid movemyTurn=true;// still this client's turn
}// end else ifelseif(message.equals("Opponent moved")){
intfila=input.nextInt();// get move locationinput.nextLine();// skip newline after int location
intcolumna=input.nextInt();// get move locationinput.nextLine();// skip newline after int location
set(columna,fila);displayMessage("Opponent moved. Your turn.\n");myTurn=true;// now this client's turn
}// end else ifelse
displayMessage(message+"\n");// display the message}// end method processMessage
// manipulate outputArea in event-dispatch threadprivatevoiddisplayMessage(StringmessageToDisplay){
InfoArea.append(messageToDisplay);// updates output}
// send message to server indicating clicked square
-
8/4/2019 4 en lnea
23/23
publicvoidsendClickedSquare(intcolumna){// if it is my turnif(myTurn){
output.format("%d\n",columna);// send location to serveroutput.flush();myTurn=false;// not my turn anymore
}}
// Variables declaration - do not modify//GEN-BEGIN:variablespublicjavax.swing.JTextAreaInfoArea;privatejavax.swing.JLabelP1N;privatejavax.swing.JLabelP1V;privatejavax.swing.JLabelP2N;privatejavax.swing.JLabelP2V;privatejavax.swing.JPanelPanel;privatejavax.swing.JButtonReiniciar;privatejavax.swing.JPaneljPanel1;privatejavax.swing.JScrollPanejScrollPane1;// End of variables declaration//GEN-END:variables
}