0% encontró este documento útil (0 votos)
441 vistas25 páginas

Cliente Tres en Raya en Java

Este documento presenta el avance del proyecto 4 de un grupo de estudiantes de la carrera de Ingeniería en Informática en el Instituto Tecnológico Superior de Coatzacoalcos. Incluye el código Java para un cliente que permite jugar tres en raya de forma remota contra otro usuario a través de una red, estableciendo la interfaz gráfica, el tablero de juego y la comunicación con el servidor.

Cargado por

Patyto Izq Cruz
Derechos de autor
© © All Rights Reserved
Nos tomamos en serio los derechos de los contenidos. Si sospechas que se trata de tu contenido, reclámalo aquí.
Formatos disponibles
Descarga como PDF, TXT o lee en línea desde Scribd
0% encontró este documento útil (0 votos)
441 vistas25 páginas

Cliente Tres en Raya en Java

Este documento presenta el avance del proyecto 4 de un grupo de estudiantes de la carrera de Ingeniería en Informática en el Instituto Tecnológico Superior de Coatzacoalcos. Incluye el código Java para un cliente que permite jugar tres en raya de forma remota contra otro usuario a través de una red, estableciendo la interfaz gráfica, el tablero de juego y la comunicación con el servidor.

Cargado por

Patyto Izq Cruz
Derechos de autor
© © All Rights Reserved
Nos tomamos en serio los derechos de los contenidos. Si sospechas que se trata de tu contenido, reclámalo aquí.
Formatos disponibles
Descarga como PDF, TXT o lee en línea desde Scribd

INSTITUTO TECNOLOGICO SUPERIOR DE

COATZACOALCOS
DIVICION: ING INFORMATICA
ASIGNATURA: PROGRAMACION CLIENTE SERVIDOR
DOCENTE: I.S.C LIZBETH HERNANDEZ OLAN
INTEGRANTES:
AVEDAO LOPEZ CARLOS
CRUZ FERNANDEZ ALBERTO
IZQUIERDO CRUZ PATRICIA DEL CARMEN
MARTINEZ ANTONIO IRIDIAN
PEREZ HERNANDEZ MISAEL DE JESUS
REYES GARCIA ALAN
TEMA:
AVANCES DE PROYECTO 4

GRADO: 7

GRUPO: B

COATZACOALCOS, VER A 9 DE DICIEMBRE DEL 2015

// Fig. 24.15: ClienteTresEnRaya.java


// Cliente que permite a un usuario jugar Tres en raya con otro a travs de una red.
import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.GridLayout;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.net.Socket;
import java.net.InetAddress;
import java.io.IOException;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.JTextField;
import javax.swing.SwingUtilities;
import java.util.Formatter;
import java.util.Scanner;
import java.util.concurrent.Executors;
import java.util.concurrent.ExecutorService;
public class ClienteTresEnRaya extends JFrame implements Runnable
{
private JTextField campoId; // campo de texto para mostrar la marca del jugador
private JTextArea areaPantalla; // objeto JTextArea para mostrar la salida
private JPanel panelTablero; // panel para el tablero de tres en raya
private JPanel panel2; // panel que contiene el tablero
private Cuadro tablero[][]; // tablero de tres en raya
private Cuadro cuadroActual; // el cuadro actual
private Socket conexion; // conexin con el servidor

private Scanner entrada; // entrada del servidor


private Formatter salida; // salida al servidor
private String hostTresEnRaya; // nombre de host para el servidor
private String miMarca; // la marca de este cliente
private boolean miTurno; // determina de qu cliente es el turno
private final String MARCA_X = "X"; // marca para el primer cliente
private final String MARCA_O = "O"; // marca para el segundo cliente
// establece la interfaz de usuario y el tablero
public ClienteTresEnRaya( String host )
{
hostTresEnRaya = host; // establece el nombre del servidor
areaPantalla = new JTextArea( 4, 30 ); // establece objeto JTextArea
areaPantalla.setEditable( false );
add( new JScrollPane( areaPantalla ), BorderLayout.SOUTH );
panelTablero = new JPanel(); // establece panel para los cuadros en el tablero
panelTablero.setLayout( new GridLayout( 3, 3, 0, 0 ) );
tablero = new Cuadro[ 3 ][ 3 ]; // crea el tablero
// itera a travs de las filas en el tablero
for ( int fila = 0; fila < tablero.length; fila++ )
{
// itera a travs de las columnas en el tablero
for ( int columna = 0; columna < tablero[ fila ].length; columna++ )
{
// crea un cuadro
tablero[ fila ][ columna ] = new Cuadro( "",fila * 3 + columna );
panelTablero.add( tablero[ fila ][ columna ] ); // agrega el cuadro
} // fin de for interior
} // fin de for exterior
campoId = new JTextField(); // establece campo de texto
campoId.setEditable( false );

add( campoId, BorderLayout.NORTH );


panel2 = new JPanel(); // establece el panel que contiene a panelTablero
panel2.add( panelTablero, BorderLayout.CENTER ); // agrega el panel deltablero
add( panel2, BorderLayout.CENTER ); // agrega el panel contenedor
setSize( 325, 225 ); // establece el tamao de la ventana
setVisible( true ); // muestra la ventana
iniciarCliente();
} // fin del constructor de ClienteTresEnRaya
// inicia el subproceso cliente
public void iniciarCliente()
{
try // se conecta al servidor, obtiene los flujos e inicia subproceso de salida
{
// realiza conexin con el servidor
conexion = new Socket(
InetAddress.getByName( hostTresEnRaya ), 12345 );
// obtiene flujos para entrada y salida
entrada = new Scanner( conexion.getInputStream() );
salida = new Formatter( conexion.getOutputStream() );
} // fin de try
catch ( IOException excepcionES )
{
excepcionES.printStackTrace();
} // fin de catch
// crea e inicia subproceso trabajador para este cliente
ExecutorService trabajador = Executors.newFixedThreadPool( 1 );
trabajador.execute( this ); // ejecuta el cliente
} // fin del mtodo iniciarCliente
// subproceso de control que permite la actualizacin continua de areaPantalla
public void run()

{
miMarca = entrada.nextLine(); // obtiene la marca del jugador (X o O)
SwingUtilities.invokeLater(
new Runnable()
{
public void run()
{
// muestra la marca del jugador
campoId.setText( "Usted es el jugador \"" + miMarca + "\"" );
} // fin del mtodo run
} // fin de la clase interna annima
); // fin de la llamada a SwingUtilities.invokeLater
miTurno = ( miMarca.equals( MARCA_X ) ); // determina si es turno del cliente
// recibe los mensajes que se envan al cliente y los imprime en pantalla
while ( true )
{
if ( entrada.hasNextLine() )
procesarMensaje( entrada.nextLine() );
} // fin de while
} // fin del mtodo run
// procesa los mensajes recibidos por el cliente
private void procesarMensaje( String mensaje )
{
// ocurri un movimiento vlido
if ( mensaje.equals( "Movimiento valido." ) )
{
mostrarMensaje( "Movimiento valido, por favor espere.\n" );
establecerMarca( cuadroActual, miMarca ); // establece marca en el cuadro
} // fin de if
else if ( mensaje.equals( "Movimiento invalido, intente de nuevo" ) )

{
mostrarMensaje( mensaje + "\n" ); // muestra el movimiento invlido
miTurno = true; // sigue siendo turno de este cliente
} // fin de else if
else if ( mensaje.equals( "El oponente realizo movimiento" ) )
{
int ubicacion = entrada.nextInt(); // obtiene la ubicacin del movimiento
entrada.nextLine(); // salta nueva lnea despus de la ubicacin int
int fila = ubicacion / 3; // calcula la fila
int columna = ubicacion % 3; // calcula la columna
establecerMarca( tablero[ fila ][ columna ],
( miMarca.equals( MARCA_X ) ? MARCA_O : MARCA_X ) ); // marca el movimiento
mostrarMensaje( "El oponente hizo un movimiento. Ahora es su turno.\n" );
miTurno = true; // ahora es turno de este cliente
} // fin de else if
else
mostrarMensaje( mensaje + "\n" ); // muestra el mensaje
} // fin del mtodo procesarMensaje
// manipula el objeto areaSalida en el subproceso despachador de eventos
private void mostrarMensaje( final String mensajeAMostrar )
{
SwingUtilities.invokeLater(
new Runnable()
{
public void run()
{
areaPantalla.append( mensajeAMostrar ); // actualiza la salida
} // fin del mtodo run
} // fin de la clase interna
); // fin de la llamada a SwingUtilities.invokeLater

} // fin del mtodo mostrarMensaje


// mtodo utilitario para establecer una marca en el tablero, en el subprocesodespachador
de eventos
private void establecerMarca( final Cuadro cuadroAMarcar, final String marca )
{
SwingUtilities.invokeLater(
new Runnable()
{
public void run()
{
cuadroAMarcar.establecerMarca( marca ); // establece la marca en elcuadro
} // fin del mtodo run
} // fin de la clase interna annima
); // fin de la llamada a SwingUtilities.invokeLater
} // fin del mtodo establecerMarca
// enva un mensaje al servidor, indicando el cuadro en el que se hizo clic
public void enviarCuadroClic( int ubicacion )
{
// si es mi turno
if ( miTurno )
{
salida.format( "%d\n", ubicacion ); // enva la ubicacin al servidor
salida.flush();
miTurno = false; // ya no es mi turno
} // fin de if
} // fin del mtodo enviarCuadroClic
// establece el cuadro actual
public void establecerCuadroActual( Cuadro cuadro )
{
cuadroActual = cuadro; // asigna el argumento al cuadro actual

} // fin del mtodo establecerCuadroActual


// clase interna privada para los cuadros en el tablero
private class Cuadro extends JPanel
{
private String marca; // marca a dibujar en este cuadro
private int ubicacion; // ubicacion del cuadro
public Cuadro( String marcaCuadro, int ubicacionCuadro )
{
marca = marcaCuadro; // establece la marca para este cuadro
ubicacion = ubicacionCuadro; // establece la ubicacin de este cuadro
addMouseListener(
new MouseAdapter()
{
public void mouseReleased( MouseEvent e )
{
establecerCuadroActual( Cuadro.this ); // establece el cuadro actual
// enva la ubicacin de este cuadro
enviarCuadroClic( obtenerUbicacionCuadro() );
} // fin del mtodo mouseReleased
} // fin de la clase interna annima
); // fin de la llamada a addMouseListener
} // fin del constructor de Cuadro
// devuelve el tamao preferido del objeto Cuadro
public Dimension getPreferredSize()
{
return new Dimension( 30, 30 ); // devuelve el tamao preferido
} // fin del mtodo getPreferredSize
// devuelve el tamao mnimo del objeto Cuadro
public Dimension getMinimumSize()
{

return getPreferredSize(); // devuelve el tamao preferido


} // fin del mtodo getMinimumSize
// establece la marca para el objeto Cuadro
public void establecerMarca( String nuevaMarca )
{
marca = nuevaMarca; // establece la marca del cuadro
repaint(); // vuelve a pintar el cuadro
} // fin del mtodo establecerMarca
// devuelve la ubicacin del objeto Cuadro
public int obtenerUbicacionCuadro()
{
return ubicacion; // devuelve la ubicacin del cuadro
} // fin del mtodo obtenerUbicacionCuadro
// dibuja el objeto Cuadro
public void paintComponent( Graphics g )
{
super.paintComponent( g );
g.drawRect( 0, 0, 29, 29 ); // dibuja el cuadro
g.drawString( marca, 11, 20 ); // dibuja la marca
} // fin del mtodo paintComponent
} // fin de la clase interna Cuadro
} // fin de la clase ClienteTresEnRaya

// Fig. 24.16: PruebaClienteTresEnRaya.java


// Prueba la clase ClienteTresEnRaya.
import javax.swing.JFrame;
public class PruebaClienteTresEnRaya
{
public static void main( String args[] )
{
ClienteTresEnRaya aplicacion; // declara la aplicacin cliente
// si no hay argumentos de lnea de comandos
if ( args.length == 0 )
aplicacion = new ClienteTresEnRaya( "127.0.0.1" ); // localhost
else
aplicacion = new ClienteTresEnRaya( args[ 0 ] ); // usa args
aplicacion.setDefaultCloseOperation( JFrame.EXIT_ON_CLOSE );
} // fin de main
} // fin de la clase PruebaClienteTresEnRaya

// Fig. 24.16: PruebaClienteTresEnRaya.java


// Prueba la clase ClienteTresEnRaya.
import javax.swing.JFrame;
public class PruebaClienteTresEnRaya
{
public static void main( String args[] )
{
ClienteTresEnRaya aplicacion; // declara la aplicacin cliente
// si no hay argumentos de lnea de comandos
if ( args.length == 0 )
aplicacion = new ClienteTresEnRaya( "127.0.0.1" ); // localhost
else
aplicacion = new ClienteTresEnRaya( args[ 0 ] ); // usa args
aplicacion.setDefaultCloseOperation( JFrame.EXIT_ON_CLOSE );
} // fin de main
} // fin de la clase PruebaClienteTresEnRaya

// Fig. 24.13: ServidorTresEnRaya.java


// Esta clase mantiene un juego de Tres en raya para dos clientes.
import java.awt.BorderLayout;
import java.net.ServerSocket;
import java.net.Socket;
import java.io.IOException;
import java.util.Formatter;
import java.util.Scanner;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
import java.util.concurrent.locks.Condition;
import javax.swing.JFrame;
import javax.swing.JTextArea;
import javax.swing.SwingUtilities;
public class ServidorTresEnRaya extends JFrame
{
private String[] tablero = new String[ 9 ]; // tablero de tres en raya
private JTextArea areaSalida; // para imprimir los movimientos en pantalla
private Jugador[] jugadores; // arreglo de objetos Jugador
private ServerSocket servidor; // socket servidor para conectarse con los clientes
private int jugadorActual; // lleva la cuenta del jugador que sigue en turno
private final static int JUGADOR_X = 0; // constante para el primer jugador
private final static int JUGADOR_O = 1; // constante para el segundo jugador
private final static String[] MARCAS = { "X", "O" }; // arreglo de marcas
private ExecutorService ejecutarJuego; // ejecuta a los jugadores
private Lock bloqueoJuego; // para bloquear el juego y estar sincronizado
private Condition otroJugadorConectado; // para esperar al otro jugador
private Condition turnoOtroJugador; // para esperar el turno del otro jugador

// establece servidor de tres en raya y GUI para mostrar mensajes en pantalla


public ServidorTresEnRaya()
{
super( "Servidor de Tres en raya" ); // establece el ttulo de la ventana
// crea objeto ExecutorService con un subproceso para cada jugador
ejecutarJuego = Executors.newFixedThreadPool( 2 );
bloqueoJuego = new ReentrantLock(); // crea bloqueo para el juego

// variable de condicin para los dos jugadores conectados


otroJugadorConectado = bloqueoJuego.newCondition();
// variable de condicin para el turno del otro jugador
turnoOtroJugador = bloqueoJuego.newCondition();
for ( int i = 0; i < 9; i++ )
tablero[ i ] = new String( "" ); // crea tablero de tres en raya
jugadores = new Jugador[ 2 ]; // crea arreglo de jugadores
jugadorActual = JUGADOR_X; // establece el primer jugador como el jugador actual
try
{
servidor = new ServerSocket( 12345, 2 ); // establece objeto ServerSocket
} // fin de try
catch ( IOException excepcionES )
{
excepcionES.printStackTrace();
System.exit( 1 );
} // fin de catch
areaSalida = new JTextArea(); // crea objeto JTextArea para mostrar la salida
add( areaSalida, BorderLayout.CENTER );
areaSalida.setText( "Servidor esperando conexiones\n" );
setSize( 300, 300 ); // establece el tamao de la ventana
setVisible( true ); // muestra la ventana

} // fin del constructor de ServidorTresEnRaya


// espera dos conexiones para poder jugar
public void execute()
{
// espera a que se conecte cada cliente
for ( int i = 0; i < jugadores.length; i++ )
{
try // espera la conexin, crea el objeto Jugador, inicia objeto Runnable
{
jugadores[ i ] = new Jugador( servidor.accept(), i );
ejecutarJuego.execute( jugadores[ i ] ); // ejecuta el objeto Runnable jugador
} // fin de try
catch ( IOException excepcionES )
{
excepcionES.printStackTrace();
System.exit( 1 );
} // fin de catch
} // fin de for
bloqueoJuego.lock(); // bloquea el juego para avisar al subproceso del jugador X
try
{
jugadores[ JUGADOR_X ].establecerSuspendido( false ); // contina el jugador X
otroJugadorConectado.signal(); // despierta el subproceso del jugador X
} // fin de try
finally
{
bloqueoJuego.unlock(); // desbloquea el juego despus de avisar al jugador X
} // fin de finally

} // fin del mtodo execute

// muestra un mensaje en objeto areaSalida


private void mostrarMensaje( final String mensajeAMostrar )
{
// muestra un mensaje del subproceso de ejecucin despachador de eventos
SwingUtilities.invokeLater(
new Runnable()
{
public void run() // actualiza el objeto areaSalida
{
areaSalida.append( mensajeAMostrar ); // agrega el mensaje
} // fin del mtodo run
} // fin de la clase interna
); // fin de la llamada a SwingUtilities.invokeLater
} // fin del mtodo mostrarMensaje
// determina si el movimiento es vlido
public boolean validarYMover( int ubicacion, int jugador )
{
// mientras no sea el jugador actual, debe esperar su turno
while ( jugador != jugadorActual )
{
bloqueoJuego.lock(); // bloquea el juego para esperar a que el otro jugadorhaga su
movmiento
try
{
turnoOtroJugador.await(); // espera el turno de jugador
} // fin de try
catch ( InterruptedException excepcion )
{
excepcion.printStackTrace();
} // fin de catch

finally
{
bloqueoJuego.unlock(); // desbloquea el juego despus de esperar
} // fin de finally
} // fin de while
// si la ubicacin no est ocupada, realiza el movimiento
if ( !estaOcupada( ubicacion ) )
{
tablero[ ubicacion ] = MARCAS[ jugadorActual ]; // establece el movimiento en el tablero
jugadorActual = ( jugadorActual + 1 ) % 2; // cambia el jugador
// deja que el nuevo jugador sepa que se realiz un movimiento
jugadores[ jugadorActual ].otroJugadorMovio( ubicacion );
bloqueoJuego.lock(); // bloquea el juego para indicar al otro jugador querealice su
movimiento
try
{
turnoOtroJugador.signal(); // indica al otro jugador que debe continuar
} // fin de try
finally
{

bloqueoJuego.unlock(); // desbloquea el juego despues de avisar


} // fin de finally
return true; // notifica al jugador que el movimiento fue vlido
} // fin de if
else // el movimiento no fue vlido
return false; // notifica al jugador que el movimiento fue invlido
} // fin del mtodo validarYMover
// determina si la ubicacin est ocupada

public boolean estaOcupada( int ubicacion )


{
if ( tablero[ ubicacion ].equals( MARCAS[ JUGADOR_X ] ) ||
tablero [ ubicacion ].equals( MARCAS[ JUGADOR_O ] ) )
return true; // la ubicacin est ocupada
else
return false; // la ubicacin no est ocupada
} // fin del mtodo estaOcupada
// coloca cdigo en este mtodo para determinar si termin el juego
public boolean seTerminoJuego()
{
return false; // esto se deja como ejercicio
} // fin del mtodo seTerminoJuego
// la clase interna privada Jugador maneja a cada Jugador como objeto Runnable
private class Jugador implements Runnable
{
private Socket conexion; // conexin con el cliente
private Scanner entrada; // entrada del cliente
private Formatter salida; // salida al cliente
private int numeroJugador; // rastrea cul jugador es el actual
private String marca; // marca para este jugador
private boolean suspendido = true; // indica si el subproceso est suspendido
// establece el subproceso Jugador
public Jugador( Socket socket, int numero )
{
numeroJugador = numero; // almacena el nmero de este jugador
marca = MARCAS[ numeroJugador ]; // especifica la marca del jugador
conexion = socket; // almacena socket para el cliente
try // obtiene los flujos del objeto Socket
{

entrada = new Scanner( conexion.getInputStream() );


salida = new Formatter( conexion.getOutputStream() );
} // fin de try
catch ( IOException excepcionES )
{
excepcionES.printStackTrace();
System.exit( 1 );
} // fin de catch
} // fin del constructor de Jugador
// enva mensaje que indica que el otro jugador hizo un movimiento
public void otroJugadorMovio( int ubicacion )
{
salida.format( "El oponente realizo movimiento\n" );
salida.format( "%d\n", ubicacion ); // enva la ubicacin del movimiento

salida.flush(); // vaca la salida


} // fin del mtodo otroJugadorMovio
// controla la ejecucin del subproceso
public void run()
{
// enva al cliente su marca (X o O), procesa los mensajes del cliente
try
{
mostrarMensaje( "Jugador " + marca + " conectado\n" );
salida.format( "%s\n", marca ); // enva la marca del jugador
salida.flush(); // vaca la salida
// si es el jugador X, espera a que llegue el otro jugador
if ( numeroJugador == JUGADOR_X )
{
salida.format( "%s\n%s", "Jugador X conectado",

"Esperando al otro jugador\n" );


salida.flush(); // vaca la salida
bloqueoJuego.lock(); // bloquea el juego para esperar al segundo jugador
try
{
while( suspendido )
{
otroJugadorConectado.await(); // espera al jugador O
} // fin de while
} // fin de try
catch ( InterruptedException excepcion )
{
excepcion.printStackTrace();
} // fin de catch
finally
{
bloqueoJuego.unlock(); // desbloquea el juego despus del segundojugador
} // fin de finally
// enva un mensaje que indica que el otro jugador se conect
salida.format( "El otro jugador se conecto. Ahora es su turno.\n" );
salida.flush(); // vaca la salida
} // fin de if
else
{
salida.format( "El jugador O se conecto, por favor espere\n" );
salida.flush(); // vaca la salida
} // fin de else
// mientras el juego no termine
while ( !seTerminoJuego() )
{

int ubicacion = 0; // inicializa la ubicacin del movimiento


if ( entrada.hasNext() )
ubicacion = entrada.nextInt(); // obtiene la ubicacin del movimiento
// comprueba si el movimiento es vlido
if ( validarYMover( ubicacion, numeroJugador ) )
{
mostrarMensaje( "\nubicacion: " + ubicacion );
salida.format( "Movimiento valido.\n" ); // notifica al cliente
salida.flush(); // vaca la salida
} // fin de if
else // el movimiento fue invlido
{
salida.format( "Movimiento invalido, intente de nuevo\n" );
salida.flush(); // vaca la salida
} // fin de else
} // fin de while
} // fin de try
finally
{
try
{
conexion.close(); // cierra la conexin con el cliente
} // fin de try
catch ( IOException excepcionES )
{
excepcionES.printStackTrace();
System.exit( 1 );
} // fin de catch
} // fin de finally
} // fin del mtodo run

// establece si se suspende el subproceso o no


public void establecerSuspendido( boolean estado )
{
suspendido = estado; // establece el valor de suspendido
} // fin del mtodo establecerSuspendido
} // fin de la clase Jugador
} // fin de la clase ServidorTresEnRaya

También podría gustarte