Download PRACTICA 2 SOPA DE LETRAS

Document related concepts
no text concepts found
Transcript
PRACTICA 2 SOPA DE LETRAS
OBJETIVO:
Desarrollar un programa donde se haga uso de cadenas en Java por medio de
una sopa de letras a la que se le asignen 5 palabras las cuales acomodara
aleatoriamente en la sopa de letras, tomando la palabra mas grande como punto
de inicio colocada en diagonal y que los espacios que queden vacios sean
llenadas con diferentes letras.
MARCO TEÓRICO:
Java posee gran capacidad para el manejo de cadenas dentro de sus clases
String y StringBuffer. Un objeto String representa una cadena alfanumérica de
un valor constante que no puede ser cambiada después de haber sido creada. Un
objeto StringBuffer representa una cadena cuyo tamaño puede variar.
Los Strings son objetos constantes y por lo tanto muy baratos para el sistema. La
mayoría de las funciones relacionadas con cadenas esperan valores String como
argumentos y devuelven valores String.
Hay que tener en cuenta que las funciones estáticas no consumen memoria del
objeto, con lo cual es más conveniente usar Character que char. No obstante, char
se usa, por ejemplo, para leer ficheros que están escritos desde otro lenguaje.
Existen muchos constructores para crear nuevas cadenas:
String();
String( String str );
String( char val[] );
String( char val[],int offset,int count );
String( byte val[],int hibyte );
String( byte val[],int hibyte,int offset,int count );
Tal como uno puede imaginarse, las cadenas pueden ser muy complejas,
existiendo muchas funciones muy útiles para trabajar con ellas y,
afortunadamente, la mayoría están codificadas en la clase String.
Funciones Básicas
La primera devuelve la longitud de la cadena y la segunda devuelve el carácter
que se encuentra en la posición que se indica en indice:
int length();
char charAt( int indice );
Funciones de Comparación de Strings
boolean equals( Object obj );
boolean equalsIgnoreCase( Object obj );
Lo mismo que equals() pero no tiene en cuenta mayúsculas o minúsculas.
int compareTo( String str2 );
Devuelve un entero menor que cero si la cadena es léxicamente menor que str2.
Devuelve cero si las dos cadenas son léxicamente iguales y un entero mayor que
cero si la cadena es léxicamente mayor que str2.
Funciones de Comparación de Subcadenas
boolean regionMatch( int thisoffset,String s2,int s2offset,int len );
boolean regionMatch( boolean ignoreCase,int thisoffset,String s2,
int s2offset,int 1 );
Comprueba si una región de esta cadena es igual a una región de otra cadena.
boolean startsWith( String prefix );
boolean startsWith( String prefix,int offset );
boolean endsWith( String suffix );
Devuelve si esta cadena comienza o termina con un cierto prefijo o sufijo
comenzando en un determinado desplazamiento.
int indexOf( int ch );
int indexOf( int ch,int fromindex );
int lastIndexOf( int ch );
int lastIndexOf( int ch,int fromindex );
int indexOf( String str );
int indexOf( String str,int fromindex );
int lastIndexOf( String str );
int lastIndexOf( String str,int fromindex );
Devuelve el primer/último índice de un carácter/cadena empezando la búsqueda a
partir de un determinado desplazamiento.
String substring( int beginindex );
String substring( int beginindex,int endindex );
String concat( String str );
String replace( char oldchar,char newchar );
String toLowerCase();
String toUpperCase();
String trim();
Ajusta los espacios en blanco al comienzo y al final de la cadena.
void getChars( int srcBegin,int srcEnd,char dst[],int dstBegin );
void getBytes( int srcBegin,int srcEnd,byte dst[],int dstBegin );
String toString();
char toCharArray();
int hashCode();
Funciones ValueOf
La clase String posee numerosas funciones para transformar valores de otros
tipos de datos a su representación como cadena. Todas estas funciones tienen el
nombre de valueOf, estando el método sobrecargado para todos los tipos de datos
básicos.
Veamos un ejemplo de su utilización:
String Uno = new String( "Hola Mundo" );
float f = 3.141592;
String PI = Uno.valueOf( f );
String PI = String.valueOf( f ); // Mucho más correcto
La clase String proporciona cadenas de sólo lectura y soporta operaciones con
ellas. Se pueden crear cadenas implícitamente usando una cadena intrecomillada
o usando + ó += con dos objetos String.
También se pueden crear objetos String explícitamente con el mecanismo new. La
clase String soporta los siguientes constructores.
•
•
public String ():construye un nuevo String con el valor " ".
public String (String value):construye un String que es copia de value.
La forma de llamar a cualquier método de la clase String se realiza de la siguiente
forma:
nombre_de_variable.nombre_del_método( ).
Los métodos básicos de los objetos String son:
•
length ():
devuelve el número de caracteres de la cadena.
•
charAt ():
devuelve el char de la posición especificada.
•
•
•
for (int i = 0; i < str.length(); i++)
count[str.charAt(i)]++;
indexOf (char ch):
devuelve el índice de la primera posición de ch.
•
indexOf (char ch, int start):
devuelve el índice de la primera posición de ch >=start.
•
indexOf (String str):
devuelve el índice de la primera posición de str.
•
indexOf (String str, int start):
devuelve el índice de la primera posición de str >= start.
•
lastIndexOf (char ch):
devuelve el índice de la última posición de ch.
•
lastIndexOf (char ch, int start):
devuelve el índice de la última posición de ch <= start.
•
lastIndexOf (String str):
devuelve el índice de la última posición de str.
•
lastIndexOf (String str, int start):
devuelve el índice de la última posición de str <= start.
Los métodos indexOf (para métodos que buscan hacia delante) y lastIndexOf
(para métodos que buscan hacia atrás) devuelven el índice que han encontrado o
–1 si la búsqueda no ha sido satisfactoria.
DESARROLLO
El programa debera mostrar ua sopa de letras que permita ordenar las palabras
aleatoriamente.Se creara una interfaz grafica atractiva para el usuario. Las
palabras seran almacenadas previamente en un archivo .txt donde el programa las
llamara. Primero se creara una clase principal donde se trate el manejo de la sopa
de letras y una segunda clase que contenga los metodos para el "adorno" de la
misma.
ANALISIS
Análisis de los requisitos:
•
•
•
•
Plataforma java (jdk 6)
Editor de código (Text Pad, Blue J, Neat Beans, etc)
Conocimientos previos de programación O.O
Sistema operativo Windows (XP, Vista, Seven)
Analisis operativo:
1. El usuario visualiza una sopa de letras desordenada.
2. A la derecha se encuentran las palabras a buscar.
3.El usuario puede remarcar las palabras arrastrando el raton sobre ellas.
4. Para reiniciar otra serie de busqueda se oprime el boton Recargar.
Diseño
El programa debera mostrar una ventana similar a :
Par empezar a buscar las palabras se clikea cada una de las letras y se marcan
automaticamente:
Para comenzar otra busqueda se oprime "Recargar" y se limpia la sopa de letras
recargando con palabras nuevas:
CODIGO
Clase Worfind
view source
print?
001 import java.awt.*;
002 import java.applet.*;
003 import java.util.Vector;
004 import java.util.Hashtable;
005
006
public class Wordfind extends Applet implements
java.awt.event.MouseListener,java.awt.event.ActionListener
007 {
008 private Label[] mines = null;
009
010
private final int square = 12;
private final int NUM_LABELS = square * square;
011
012
private final int NUM_WORDS_IN_PUZZLE = 4;
private Button button = null;
013
014
private Panel minepanel = null;
private Vector selectedLabels = new Vector();
015
016
private String[] solution = null;
017
018
private String wordlist = null;
private Hashtable words = null;
019
020
private Hashtable selectedWords = null;
//compass type constants
021
022
private final int NORTH = -square; // eg., if square= 12, then -12
private final int SOUTH = square;
023
024
private final int WEST = -1;
private final int EAST = 1;
025
026
private final int NE = -square + 1;
private final int NW = -square - 1;
027
028
private final int SE = square + 1;
private final int SW = square - 1;
029
030
private Label[] captions = null;
private Adorn a = null;
031
032
033
034
035
036
public void init()
{
037
038
setLayout(new BorderLayout());
039
040
this.setBackground(Color.pink);
//setSize(300,300);
041
042
minepanel = new Panel(new GridLayout(square,square));
043
044
this.setForeground(Color.blue);
this.getLabels();
045
046
this.getWords();
this.placeWords();
047
048
this.addFillers();
049
050
Panel buttonpanel = new Panel(new BorderLayout());
051
052
button = new Button("Recargar");
button.addActionListener(this);
053
054
buttonpanel.add("South",button);
055
056
Panel labelpanel = new Panel(new GridLayout(0,1));
for (int j = 0;j < getCaptions().length; j++){
057
058
059
060
labelpanel.add(getCaptions()[j]);
}
061
062
063
064
buttonpanel.add("North",labelpanel);
065
066
067
068
this.add("Center", minepanel);
069
070
this.add("South", buttonpanel);
071
072
setLayout(new FlowLayout());
073
074
setSize(792,396);
this.showStatus("Ready");
075
076
077
078
079
080
}
081
082
public void mouseClicked(java.awt.event.MouseEvent e){
Component c = (Component)e.getSource();
083
084
if (c instanceof Label){
Label l = (Label)c;
085
086
if (l.getBackground() == Color.lightGray){
l.setBackground(Color.pink);
087
088
}else{
l.setBackground(Color.lightGray);
089
090
}
091
092
this.addSelectedLabel(new Integer(l.getText()));
if (checkWin()){
093
094
showWin();
}
095
096
097
098
}
}
099
100
public void mouseEntered(java.awt.event.MouseEvent e){}
public void mouseExited(java.awt.event.MouseEvent e){}
101
102
public void mousePressed(java.awt.event.MouseEvent e){}
public void mouseReleased(java.awt.event.MouseEvent
e){}
104
public void actionPerformed(java.awt.event.ActionEvent e){
103
105
106
if (e.getSource()==button) {
//probably start button
restart();
}
107
108
109
110
111
112
113
114
}
private boolean checkWin(){
115
116
//TO DO:
return false;
117
118
}
private void showWin(){
119
120
}
121
122
private Label[] getLabels(){
if (mines == null){
123
124
mines = new Label[NUM_LABELS];
for (int i = 0;i <
NUM_LABELS;i++){
126
mines[i] = new Label("",1);
125
127
128
mines[i].addMouseListener(this);
mines[i].setName("" + i);
129
130
minepanel.setBackground(Color.lightGray);
minepanel.add(mines[i]);
131
132
}
//set up adornment for these labels
133
134
135
136
a = new Adorn();
a.setLabels(mines);
137
138
Thread aThread = new Thread(a);
aThread.start();
139
140
141
142
}
143
144
return mines;
}
145
146
147
148
149
150
private Label[] getCaptions(){
if (captions==null){
captions = new Label[NUM_WORDS_IN_PUZZLE];
for (int i = 0;i < captions.length;i++){
151
152
153
154
155
156
captions[i] = new Label("");
captions[i].setAlignment(Label.RIGHT);
}
}
return captions;
}
157
158 //**************************
159
160
private void getWords(){
161
162
int i = 0;
163
164
//words passed in ...or use default
wordlist = this.getParameter("WORDLIST");
1
6
if (wordlist ==null){
5
1
wordlist = "loco,
6 tonto,inteligente,trabajado,rico,romantico,holgazan,memory,queue,rational,stere
6 o,tranquil,weaver,zesty,blister,vanish,idiotic,range,scream,smile,spoof";
167
168
}
169
170
wordlist = wordlist.toUpperCase();
171
172
173
java.util.StringTokenizer st = new java.util.StringTokenizer(wordlist,",");
174
words = new Hashtable(st.countTokens());
175
176
while (st.hasMoreElements()){
177
178
179
180
words.put(new String(String.valueOf(i)), st.nextToken());
i++;
}
}
181
182
183 //*****************************
private void
184
placeWords(){
185
186
//clear solution
solution = new
String[NUM_LABELS];
188 String selectedWord = new String("");
187
189
190
191
192
//prepare selectedWords
selectedWords = new Hashtable(NUM_WORDS_IN_PUZZLE);
193
194
195
196
for (int i = 0; i< NUM_WORDS_IN_PUZZLE;i++){
197
198
boolean flag = false;
199
200
//don't add it to the selection if it's already there!!
while(flag==false){
201
202
//where to start
int pos = (int)(java.lang.Math.random()*words.size());
203
204
selectedWord = (String)words.get(String.valueOf(pos));
205
206
if (selectedWords.contains(selectedWord) == false){
flag = true;
207
208
}
}
209
210
char[] thisword = selectedWord.toCharArray();
211
212
System.out.println(selectedWord + " ************************************");
213
214
int looped = 0;
215
216
//the direction should be randomly selected:
int[] directions = {NORTH,SOUTH,EAST,WEST,SW,SE,NE,NW};
217
218
219
220
while (looped < 50){ //presume unfittable word beyond this...
//try to position the word in the solution array
221
222
int startpos = (int)(java.lang.Math.random()* (square*square));
223
224
int direction = (int)(java.lang.Math.random() * directions.length);
225
226
if (this.tryToFit(directions[direction], thisword, startpos)) {
227
228
//the word was placed!! So announce it
captionPuzzle(selectedWord);
229
230
break; //out of while loop
}
231
232
looped++;
233
234
235
236
}
}
}
237 //******************************
238 private void addFillers(){
239
240
241
242
243
244
245
//add any old filler text to labels with no text
for (int i = 0;i < NUM_LABELS;i++){
if (solution[i]==null){
mines[i].setText(this.getRandomLetter());
246
//mines[i].setText("-"); //TEST
247
248
249
250
}else{
mines[i].setText(solution[i]);
251
252
253
254
255
256
}
}
}
257 // ***********************
258 private void clearLabels(){
259
260
//add any old filler text to labels with no text
for (int i = 0;i < NUM_LABELS;i++){
261
262
mines[i].setText("");
mines[i].setBackground(Color.lightGray);
263
264
}
265
266
//now clear the captions
267
268
for (int j = 0;j< NUM_WORDS_IN_PUZZLE;j++){
getCaptions()[j].setText("");
269
270
}
271
272
}
273
274
private void addSelectedLabel(Integer i){
selectedLabels.addElement(i);
275
276
}
277 //***********************************
private String
278
getRandomLetter(){
279
280
String pick = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
281
int spot = (int)(java.lang.Math.random() * 26);
282
283
284
String ret = pick.substring(spot,spot+1);
285
286
return ret;
}
287
288 //****************************
289
290
private synchronized void restart(){
this.getWords();
this.clearLabels();
this.placeWords()
291
292
293
294
;
this.addFillers();
}
295
296 //***************************
297
298
private boolean tryToFit(int increment, char[] what, int startPos){
int charLength = what.length ;
299
300
int newPos = startPos;
301
302
for (int i = 0; i< charLength; i++){
try{
303
// at this position
if
304
((solution[newPos]==null)||(solution[newPos].equals(String.valueOf(what[i])))){
305
306
//solution matrix must be null or same as the character
307
308
//dont worry about boundary on last char...
if ((!isBoundaryOK(newPos,increment)) || (i== charLength )){
309
310
return false;
}
311
312
313
314
315
316
//check another position in increment direction
newPos = newPos + increment ;
317
318
}
else{
// oh oh, roadblock! try another direction...
319
320
321
322
return false;
}
323
324
}catch (Exception e){
return false; //end of the road!
325
326
}
}
327
328
// if we got this far, we can position the char array in this direction
329
330
int charPos = startPos;
for (int q = 0; q< charLength; q++ ){
331
332
solution[charPos] = String.valueOf(what[q]);
charPos = charPos + increment ;
333
334
335
336
}
return true ;
}
337
338 //***************************************
339
340
341
342
private void captionPuzzle(String what){
if (selectedWords !=null){
343
344
345
346
selectedWords.put(what,what);
}
347
348
//find an empty spot in the captions labels
349
350
for (int i = 0;i< getCaptions().length; i++){
if (getCaptions()[i].getText().length()==0){
351
352
353
getCaptions()[i].setText(what);
return;
}
354
}
355
356
357
358
}
359
360
/* this routine checks to see that a char the boundary of the grid
361
362
doesn't try to write itself in the wrong place
ie, xxxh
tabx
xxxx
363
364
365
366
367
368
*note how the word bath is written if moving EAST
369
370
You can call this routine for all but the LAST char
371
372
373
374
375
376
*/
private boolean isBoundaryOK(int newPos,int direction){
377
378
379
380
381
382
switch (direction){
case NORTH:
383
384
385
386
if (newPos < square){
return false;
387
388
}
return true;
389
390
case SOUTH:
if (newPos + square >(square * square)){
391
392
return false;
}
393
394
return true;
case EAST:
395
396
//System.out.println("East" + newPos + " " + square);
if ( java.lang.Math.IEEEremainder(newPos+1,square)== 0){
397
398
399
400
return false;
}
case WEST:
//System.out.println("West" + newPos + " " + square);
401
402
if ( java.lang.Math.IEEEremainder(newPos,square)== 0){
return false;
403
404
}
return true;
405
406
case NE:
if (newPos < square){//same as north
407
408
return false;
}
409
410
//System.out.println(" NE:" + newPos + " " + square);
if ( java.lang.Math.IEEEremainder(newPos+1,square)== 0){ //same rule
as East
411
412
}
413
414
//System.out.println("true");
return true;
415
416
417
418
return false;
case SE:
if (newPos + square >(square * square)){//same as south
419
420
return false;
}
421
422
//System.out.println("SE:" + newPos + " " + square);
if ( java.lang.Math.IEEEremainder(newPos+1,square)== 0){ //same rule
as East
423
424
return false;
}
425
//System.out.println("true");
426
return true;
427
428
case SW:
if (newPos + square >(square * square)){ //Same as south
429
430
return false;
}
431
432
//System.out.println("SW " + newPos + " " + square);
if ( java.lang.Math.IEEEremainder(newPos,square)== 0){//like west
433
434
return false;
}
435
436
//System.out.println("true");
return true;
437
438
case NW:
if (newPos < square){//same as north
439
440
}
441
442
//System.out.println("NW " + newPos + " " + square);
443
return false;
if ( java.lang.Math.IEEEremainder(newPos,square)== 0){ //like west
rule
444
return false;
445
446
}
//System.out.println("true");
447
448
return true;
449
450
default:
break ;
451
452
}
453
454
return false;
455 }
456 }
Aqui la clase responsable del color de los adornos de las letras
Clase Adorn
view source
print?
01 import java.lang.*;
02 import java.awt.Color;
03
04
05
06
07
08
09
public class Adorn extends Object implements Runnable{
private java.awt.Label[] labelArray = null;
private Color[] foreColors =
{Color.magenta,Color.red,Color.cyan,Color.black};
10
11
12
public void setLabels(java.awt.Label[] l){
13
14
15
16
this.labelArray = l;
}
17
18
19
20
21
22
public void run(){
while (true){
23
24
25
26
27
28
try{
int myColor = (int)(java.lang.Math.random() * foreColors.length );
Color thisColor = foreColors[myColor];
int currentLabel = (int)(java.lang.Math.random() * labelArray.length );
29
30
31
32
labelArray[currentLabel].setForeground(thisColor);
33
34
synchronized(this){ //lock it while doing this..
35
String text = labelArray[currentLabel].getText();
36
labelArray[currentLabel].setText(text);
37
38
}
39
40
Thread.currentThread().sleep(1000);
41
42
43
44
45
46
} catch (Exception e){}
}
}
}
PRUEBA Y DEPURACION
Resultado