Universidad de Costa Rica
|
|
Implemente el
método estático
convierte()
para completar el programa
ToqueFama.java
que sirve para jugar el juego de "Toques y famas" jalando las
adinanzas del teclado. Demuestre que su método funciona
corriendo la prueba
testConvierte()
en el programa de prueba de la
tarea programada anterior.
Para esta tarea programada usted debe enviarme estos archivos:
En el documento CARNET.docx
deben describir su
experiencia de aprendizaje para completar esta tarea. Explique
qué hizo, cómo lo hizo y por qué lo hizo. En
especial, es importante que explique cómo funciona su
programa, indicando cuál es el trabajo que realiza cada uno
de los
módulos que conforman su solución.
Construya su solución en 2 pasos. Primero, complete la
implementación de la rutina
convierte()
de manera que produzca los resultados definidos en su
especificación. No olvide determinar si su rutina
convierte()
funciona correctamente, probándola
con
testConvierte()
,
que es el bloque de código que usted debe agregarle al
programa testEncajados.java
que usó en la
tarea programada anterior.
Después de comprobar que su rutina convierte()
funciona correctamente, úsela para completar el programa
ToqueFama.java
, agregando en el bloque que
está marcado con la indicación
"{ ***
RELLENE CON SU ALGORITMO
*** }
"
todas las instrucciones para leer adivinanzas y cotejarlas con el
número secreto almacenado en el vector
SECRETO[]
. Es aquí adonde debe invocar
convierte()
para almacenar la siguiente adivinanza en
el vector ADIVINA[]
, pues la rutina
estanEncajados()
trabaja con valores almacenados en vectores. ¡No modifique
ninguna otra parte del programa!
ToqueFama.java
porque para un SECRETO[]
de "n
" dígitos, siempre genera el mismo
secreto:
n==4, SECRETO[] == {2,1,3,0}
n==5, SECRETO[] == {2,0,3,4,1}
n==6, SECRETO[] == {3,1,5,4,2,0}
ToqueFama.java
está
declarada la variable "semilla
" así:
long semilla = 123456789;
- http://www.web-games-online.com/mastermind/
¿Cuántos dígitos quiere en SECRETO? 5 Adivina> 00000 4 toques 1 famas Adivina> 11111 4 toques 1 famas Adivina> 22222 4 toques 1 famas Adivina> 33333 4 toques 1 famas Adivina> 44444 4 toques 1 famas Adivina> 55555 0 toques 0 famas Adivina> 01234 5 toques 0 famas Adivina> 12340 3 toques 2 famas Adivina> 23401 3 toques 2 famas Adivina> 34012 5 toques 0 famas Adivina> 40123 4 toques 1 famas Adivina> 20341 Duraste solo 12 tiros
Entregue su tarea por correo electrónico, como lo hizo anteriormente.
/***********************************************************\ * Incluya este bloque de código en el módulo Encajados.java * \***********************************************************/ /* Almacena los últimos {@code n} dígitos de {@code adivina} en el vector {@code ADIVINA[]}. * Si hay más digitos al principio de {@code adivina}, simplemente los ignora. * En caso de que falten dígitos, los rellena con el valor cero {@code 0}. * Solo modifica sus argumentos cuando el valor de {@code n} está en el rango {@code [1..9]}. * Solo modifica sus argumentos si ya ocurre que {@code ADIVINA.length == n}. */ public static void convierte( int n, int adivina, int ADIVINA[] ) { { /******************************\ * * * RELLENE CON SU ALGORITMO * * * \******************************/ /* VEC[] +---+---+---+---+---+---+---+---+---+---+ | C | A | L | A | M | B | R | I | N | A | +---+---+---+---+---+---+---+---+---+---+ 0 1 2 3 4 5 6 7 8 9 10 i -> <- j assertTrue( VEC[0] == 'C' ); // ... assertTrue( VEC[4] == 'M' ); // ... assertTrue( VEC[9] == 'A' ); assertTrue( VEC.length == 10 ); Rango para el ciclo: - [ 0..9 ] - [ 0 .. VEC.length-1 ] - VEC[0] es el primero - VEC[ VEC.length-1 ] es el último - VEC[ VEC.length ] es incorrecto - El índice [ VEC.length ] está fuera de rango - Si N == VEC.length ==> N-1 == (VEC.length-1) ... - Si N == VEC.length ==> N-3 == (VEC.length-1) - 2 */ } } |
/***************************************************************\ * Incluya este bloque de código en el módulo TestEncajados.java * \***************************************************************/ /** Verifica que los vectores {@code L[]} y {@code R[]} tengan exactamente los mismos valores */ public static boolean isEqual( int L[] , int R[] ) { if ( L.length != R.length ) { return false; } for ( int i=0; i<L.length; ++i ) { if ( L[i] != R[i] ) { return false; } } return true; } /** test -> {@code Encajados.convierte()}. */ public void testConvierte() { int V[] = { 0 , 1 , 2 , 3 }; // vector de pruebas Encajados.convierte( 0, 1234567, V ); // n == 0 assertTrue( isEqual( V , A0123 ) ); // no cambia V[] assertTrue( A1111.length == 4 ); assertTrue( V.length != 2 ); Encajados.convierte( 4, 1111, V ); assertTrue( isEqual( V, A1111 ) ); Encajados.convierte( 4, 990123, V ); assertTrue( isEqual( V, A0123 ) ); Encajados.convierte( 4, 123, V ); assertTrue( isEqual( V, A0123 ) ); V = new int[1]; Encajados.convierte( 1, 139, V ); assertTrue( V[0] == 9 && V.length == 1 ); V = new int[2]; Encajados.convierte( 2, 01, V ); assertTrue( isEqual( V, A01 ) ); V = new int[6]; Encajados.convierte( 6, 990123, V ); assertTrue( isEqual( V, A990123 ) ); { int R[] = { 5,1 }; Encajados.convierte( 2, 01, R ); assertFalse( R[0]==5 && R[1]==1 ); assertTrue( isEqual( R, A01 ) ); assertTrue( R[0]==0 && R[1]==1 ); } { int R[] = { 3 }; Encajados.convierte( 2, 11, R ); assertTrue( R[0]==3 && R.length != 2 ); Encajados.convierte( 1, 0, R ); assertTrue( R[0]==0 ); Encajados.convierte( 1, 9, R ); assertTrue( R[0]==9 ); Encajados.convierte( 1, 90, R ); assertTrue( R[0]==0 ); } { int R[] = new int[33]; Encajados.convierte( R.length, 1, R ); assertTrue( R[0]!=1 && R.length>9 ); } } |
/** @(#)ToqueFama.java 2009 Juego de Toques y Famas (<em>Master Mind</em>). @author Adolfo Di Mare <adolfo@di-mare.com> */ import java.io.*; // Clases para leer desde el teclado import java.util.Random; // Clases para números aleatorios import java.lang.Character; // isDigit() /** Clase que contiene el programa principal {@code main()}. */ public class ToqueFama { /** Lee un número de {@code CIN}. * Se salta los caracteres no númericos antes del número. */ public static int leeInt( BufferedReader CIN ) { int num = 0; char ch; try { do { // se salta la basura antes del número ch = (char)CIN.read(); } while ( ! Character.isDigit(ch) ); while ( Character.isDigit(ch) ) { num = num*10 + (ch-'0'); ch = (char)CIN.read(); } return num; } catch (IOException e) { return 0; } } /** Genera el vector {@code SECRETO[]} de longitud "{@code n}" de adivinanzas. * <ul><li> {@code (n == SECRETO.length)}. </li> * <li> Los valores del vector {@code SECRETO[]} siempre están en el rango el * {@code [0..n-1]}.</li> * <li> Ningún valor del vector está repetido.</li> * <li> El generador de valores aleatorios se incializa con {@code semilla}.</li> * <li> Para el juego de Toques y Famas resulta mejor que el nœmero secreto * siempre tenga dígitos diferentes. </li> * <li> Por ejemplo, para {@code n==7}, esta rutina usa el vector * {@code {0,1,2,3,4,5,6}} para luego revolverle los nœmeros de manera * aleatoria, de forma resulte algo como {@code {3,1,5,6,0,2,4}}, en donde * aparecen todos los dígitos en el rango {@code [0..7-1]} pero sin * repeticiones. </li> * </ul> */ public static void generaSecreto( long semilla, int SECRETO[] ) { Random rand = new Random( semilla ); final int n = SECRETO.length; // Rellena SECRETO[] con los primeros nœmeros for ( int i=0; i<n; ++i ) { SECRETO[i] = i; } // Reacomoda los valores de SECRETO[] usando nœmeros aleatorios for ( int i=0; i<n; ++i ) { int j = rand.nextInt(n); // "j" nunca está fuera de rango if ( i != j ) { // intercambia int temp = SECRETO[i]; SECRETO[i] = SECRETO[j]; SECRETO[j] = temp; } } } /** Nombre el índice de "exactos" en el vector {@code res[]} */ static final int EXACTO = Encajados.EXACTO; /** Nombre el índice de "corridos" en el vector {@code res[]} */ static final int CORRIDO = Encajados.CORRIDO; /** {@code n*DUREZA} es la cantidad máxima de adivinanzas del juego */ static final int DUREZA = 7; /** Programa principal. * OJO: tira la excepción <code>IOException</code> cuando {@code CIN} no funciona. */ public static void main( String args[] ) throws IOException { // CIN es el lector de la consola (teclado) BufferedReader CIN = new BufferedReader( new InputStreamReader(System.in) ); System.out.print( "¿Cuántos dígitos quiere en SECRETO? " ); int n = leeInt(CIN) % 9; // lee el nuevo valor if ( n <= 0 ) { // control de datos de entrada n = 4; } long semilla = 123456789; int SECRETO[] = new int[n]; // este es el que hay que adivinar int ADIVINA[] = new int[n]; // siguiente adivinanza int res[] = { -1 , -1 }; // res[] tiene dimensión 2 generaSecreto( semilla, SECRETO ); // ciclo para procesar cada adivinanza int tiros = 0; System.out.print( "\nAdivina> " ); while ( tiros != n*DUREZA ) { tiros++; int adivina = leeInt(CIN); // jala la adivinanza { /******************************\ * * * RELLENE CON SU ALGORITMO * * * \******************************/ } } if ( tiros == n*DUREZA ) { System.out.print( "\n¡¡¡ CHAPA !!!\n" ); } else { System.out.print( "\nDuraste solo " + (tiros) + " tiros\n" ); } CIN.close(); // Cierra la consola de lectura return; } // main() } // ToqueFama /* EOF: ToqueFama.java */ |
Adolfo Di Mare <adolfo@di-mare.com>.
|