Tres Rayas

29
INSTITUTO TECNOLOGICO SUPERIOR DE COATZACOALCOS DIVICION: ING INFORMATICA ASIGNATURA: PROGRAMACION CLIENTE SERVIDOR DOCENTE: I.S.C LIZBETH HERNANDEZ OLAN INTEGRANTES: AVEDAÑO 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

description

faf

Transcript of Tres Rayas

Page 1: Tres Rayas

INSTITUTO TECNOLOGICO SUPERIOR DE

COATZACOALCOS

DIVICION: ING INFORMATICA

ASIGNATURA: PROGRAMACION CLIENTE SERVIDOR

DOCENTE: I.S.C LIZBETH HERNANDEZ OLAN

INTEGRANTES:

AVEDAÑO LOPEZ CARLOSCRUZ FERNANDEZ ALBERTO

IZQUIERDO CRUZ PATRICIA DEL CARMENMARTINEZ ANTONIO IRIDIAN

PEREZ HERNANDEZ MISAEL DE JESUSREYES GARCIA ALAN

TEMA:

AVANCES DE PROYECTO 4

GRADO: 7 GRUPO: B

COATZACOALCOS, VER A 9 DE DICIEMBRE DEL 2015

Page 2: Tres Rayas

// Fig. 24.15: ClienteTresEnRaya.java

// Cliente que permite a un usuario jugar Tres en raya con otro a través 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; // conexión con el servidor

Page 3: Tres Rayas

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 través de las filas en el tablero

for ( int fila = 0; fila < tablero.length; fila++ )

{

// itera a través 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 );

Page 4: Tres Rayas

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 tamaño 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 conexión 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 método iniciarCliente

// subproceso de control que permite la actualización continua de areaPantalla

public void run()

Page 5: Tres Rayas

{

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 método run

} // fin de la clase interna anónima

); // fin de la llamada a SwingUtilities.invokeLater

miTurno = ( miMarca.equals( MARCA_X ) ); // determina si es turno del cliente

// recibe los mensajes que se envían al cliente y los imprime en pantalla

while ( true )

{

if ( entrada.hasNextLine() )

procesarMensaje( entrada.nextLine() );

} // fin de while

} // fin del método run

// procesa los mensajes recibidos por el cliente

private void procesarMensaje( String mensaje )

{

// ocurrió un movimiento válido

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" ) )

Page 6: Tres Rayas

{

mostrarMensaje( mensaje + "\n" ); // muestra el movimiento inválido

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 ubicación del movimiento

entrada.nextLine(); // salta nueva línea después de la ubicación 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 método 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 método run

} // fin de la clase interna

); // fin de la llamada a SwingUtilities.invokeLater

Page 7: Tres Rayas

} // fin del método mostrarMensaje

// método 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 método run

} // fin de la clase interna anónima

); // fin de la llamada a SwingUtilities.invokeLater

} // fin del método establecerMarca

// envía 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 ); // envía la ubicación al servidor

salida.flush();

miTurno = false; // ya no es mi turno

} // fin de if

} // fin del método enviarCuadroClic

// establece el cuadro actual

public void establecerCuadroActual( Cuadro cuadro )

{

cuadroActual = cuadro; // asigna el argumento al cuadro actual

Page 8: Tres Rayas

} // fin del método 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 ubicación de este cuadro

addMouseListener(

new MouseAdapter()

{

public void mouseReleased( MouseEvent e )

{

establecerCuadroActual( Cuadro.this ); // establece el cuadro actual

// envía la ubicación de este cuadro

enviarCuadroClic( obtenerUbicacionCuadro() );

} // fin del método mouseReleased

} // fin de la clase interna anónima

); // fin de la llamada a addMouseListener

} // fin del constructor de Cuadro

// devuelve el tamaño preferido del objeto Cuadro

public Dimension getPreferredSize()

{

return new Dimension( 30, 30 ); // devuelve el tamaño preferido

} // fin del método getPreferredSize

// devuelve el tamaño mínimo del objeto Cuadro

public Dimension getMinimumSize()

{

Page 9: Tres Rayas

return getPreferredSize(); // devuelve el tamaño preferido

} // fin del método 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 método establecerMarca

// devuelve la ubicación del objeto Cuadro

public int obtenerUbicacionCuadro()

{

return ubicacion; // devuelve la ubicación del cuadro

} // fin del método 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 método paintComponent

} // fin de la clase interna Cuadro

} // fin de la clase ClienteTresEnRaya

Page 10: Tres Rayas

// 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 aplicación cliente

// si no hay argumentos de línea 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

Page 11: Tres Rayas

// 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 aplicación cliente

// si no hay argumentos de línea 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

Page 12: Tres Rayas

// 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

Page 13: Tres Rayas

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

public ServidorTresEnRaya()

{

super( "Servidor de Tres en raya" ); // establece el título 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 condición para los dos jugadores conectados

otroJugadorConectado = bloqueoJuego.newCondition();

// variable de condición 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 tamaño de la ventana

setVisible( true ); // muestra la ventana

Page 14: Tres Rayas

} // 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 conexión, 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 ); // continúa el jugador X

otroJugadorConectado.signal(); // despierta el subproceso del jugador X

} // fin de try

finally

{

bloqueoJuego.unlock(); // desbloquea el juego después de avisar al jugador X

} // fin de finally

} // fin del método execute

Page 15: Tres Rayas

// muestra un mensaje en objeto areaSalida

private void mostrarMensaje( final String mensajeAMostrar )

{

// muestra un mensaje del subproceso de ejecución despachador de eventos

SwingUtilities.invokeLater(

new Runnable()

{

public void run() // actualiza el objeto areaSalida

{

areaSalida.append( mensajeAMostrar ); // agrega el mensaje

} // fin del método run

} // fin de la clase interna

); // fin de la llamada a SwingUtilities.invokeLater

} // fin del método mostrarMensaje

// determina si el movimiento es válido

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

Page 16: Tres Rayas

finally

{

bloqueoJuego.unlock(); // desbloquea el juego después de esperar

} // fin de finally

} // fin de while

// si la ubicación 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 válido

} // fin de if

else // el movimiento no fue válido

return false; // notifica al jugador que el movimiento fue inválido

} // fin del método validarYMover

// determina si la ubicación está ocupada

Page 17: Tres Rayas

public boolean estaOcupada( int ubicacion )

{

if ( tablero[ ubicacion ].equals( MARCAS[ JUGADOR_X ] ) ||

tablero [ ubicacion ].equals( MARCAS[ JUGADOR_O ] ) )

return true; // la ubicación está ocupada

else

return false; // la ubicación no está ocupada

} // fin del método estaOcupada

// coloca código en este método para determinar si terminó el juego

public boolean seTerminoJuego()

{

return false; // esto se deja como ejercicio

} // fin del método seTerminoJuego

// la clase interna privada Jugador maneja a cada Jugador como objeto Runnable

private class Jugador implements Runnable

{

private Socket conexion; // conexión con el cliente

private Scanner entrada; // entrada del cliente

private Formatter salida; // salida al cliente

private int numeroJugador; // rastrea cuál 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 número 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

{

Page 18: Tres Rayas

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

// envía 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 ); // envía la ubicación del movimiento

salida.flush(); // vacía la salida

} // fin del método otroJugadorMovio

// controla la ejecución del subproceso

public void run()

{

// envía al cliente su marca (X o O), procesa los mensajes del cliente

try

{

mostrarMensaje( "Jugador " + marca + " conectado\n" );

salida.format( "%s\n", marca ); // envía la marca del jugador

salida.flush(); // vacía 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",

Page 19: Tres Rayas

"Esperando al otro jugador\n" );

salida.flush(); // vacía 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 después del segundojugador

} // fin de finally

// envía un mensaje que indica que el otro jugador se conectó

salida.format( "El otro jugador se conecto. Ahora es su turno.\n" );

salida.flush(); // vacía la salida

} // fin de if

else

{

salida.format( "El jugador O se conecto, por favor espere\n" );

salida.flush(); // vacía la salida

} // fin de else

// mientras el juego no termine

while ( !seTerminoJuego() )

{

Page 20: Tres Rayas

int ubicacion = 0; // inicializa la ubicación del movimiento

if ( entrada.hasNext() )

ubicacion = entrada.nextInt(); // obtiene la ubicación del movimiento

// comprueba si el movimiento es válido

if ( validarYMover( ubicacion, numeroJugador ) )

{

mostrarMensaje( "\nubicacion: " + ubicacion );

salida.format( "Movimiento valido.\n" ); // notifica al cliente

salida.flush(); // vacía la salida

} // fin de if

else // el movimiento fue inválido

{

salida.format( "Movimiento invalido, intente de nuevo\n" );

salida.flush(); // vacía la salida

} // fin de else

} // fin de while

} // fin de try

finally

{

try

{

conexion.close(); // cierra la conexión con el cliente

} // fin de try

catch ( IOException excepcionES )

{

excepcionES.printStackTrace();

System.exit( 1 );

} // fin de catch

} // fin de finally

} // fin del método run

Page 21: Tres Rayas

// establece si se suspende el subproceso o no

public void establecerSuspendido( boolean estado )

{

suspendido = estado; // establece el valor de suspendido

} // fin del método establecerSuspendido

} // fin de la clase Jugador

} // fin de la clase ServidorTresEnRaya

Page 22: Tres Rayas
Page 23: Tres Rayas
Page 24: Tres Rayas
Page 25: Tres Rayas