capitulo19_extracto

download capitulo19_extracto

of 6

Transcript of capitulo19_extracto

  • Tema 19 El buscaminas

    235

    l da que llevaba esperando toda una semana haba llegado por fin. Estuve toda la maana jugando al buscaminas, tratando de entender su funcionamiento.

    Deberan haberme puesto un examen sobre el buscaminas, lo conoca como la palma de la mano. Ahora, eso s, no tena ni idea de cmo bamos a programarlo.

    Impaciente por aplacar mi curiosidad, no me detuve en detalles de cortesa y la leccin empez.

    Da 19. Creando un juego del buscaminas Un buscaminas en modo texto Nuestra meta no es crear un videojuego, sino explorar en lo que su realizacin puede aportarnos. Por tanto, haremos el buscaminas en modo texto. Visualmente no ser muy vistoso, pero de todos modos la leccin ser sumamente interesante para nosotros.

    El tablero de juego Una de las primeras cosas que hemos de crear para jugar al buscaminas es el tablero de juego. Nosotros usaremos dos tableros de juego del mismo tamao pero diferentes.

    En un tablero jugar el usuario, destapar las casillas, marcaremos los nmeros de bombas limtrofes, y abriremos los caminos. En otro tablero es donde colocaremos las bombas.

    Usamos dos tableros porque as es ms fcil representarlos en pantalla. Si dibujsemos las bombas en el mismo tablero que se muestra en pantalla para el usuario, este vera las bombas desde el primer momento.

    Ejercicio opcional 21 Se puede solucionar el problema con un solo tablero y una lista de posiciones en las que haya bombas. Al acabar esta leccin tratar de crear esta nueva versin del juego con un solo tablero. Convenio de smbolos.

    El asterisco simbolizar una bomba. (*)

    E

  • Tema 19 El buscaminas

    236

    El guin medio simbolizar un hueco sin bombas. (-) La equis simbolizar una casilla que el usuario an no ha

    descubierto. (x) Las casillas descubiertas que quedan vacas sern simbolizadas por

    un espacio en blanco. ( ) Las casillas que deban llevar un nmero que represente el nmero de

    bombas, llevaran dicho nmero. (0-8) Dibujaremos en primer lugar el campo de minas, para ello usaremos una lista de 10 listas de 10 elementos cada una (10x10) y colocaremos en este campo de minas 10 bombas. minas=[ ['-','-','-','-','*','-','-','-','-','-'], ['-','-','-','-','-','-','-','*','-','-'], ['*','-','-','-','-','-','-','-','-','-'], ['-','-','*','-','-','-','-','-','-','-'], ['-','-','-','-','-','-','*','-','-','-'], ['-','-','-','-','-','-','-','-','-','*'], ['-','-','-','*','-','-','-','-','-','-'], ['-','*','-','-','-','-','-','-','-','-'], ['-','-','-','-','-','*','-','-','-','-'], ['-','-','-','-','-','-','-','-','*','-'] ]

    Seguidamente dibujaremos el tablero que el jugador o usuario, podr ver en pantalla inicialmente:

    minasu=[ ['x','x','x','x','x','x','x','x','x','x'], ['x','x','x','x','x','x','x','x','x','x'], ['x','x','x','x','x','x','x','x','x','x'], ['x','x','x','x','x','x','x','x','x','x'], ['x','x','x','x','x','x','x','x','x','x'], ['x','x','x','x','x','x','x','x','x','x'], ['x','x','x','x','x','x','x','x','x','x'], ['x','x','x','x','x','x','x','x','x','x'], ['x','x','x','x','x','x','x','x','x','x'], ['x','x','x','x','x','x','x','x','x','x'] ]

    Hemos llamado a estas dos listas minas y minasu, porque una es el tablero de las minas, y la otra es el tablero de las minas que ve el usuario.

  • Tema 19 El buscaminas

    237

    Ahora hemos de tratar que se vea el tablero del usuario en pantalla. Para lo cual usamos un recorrido de la tabla de minasu y la iremos dibujando en pantalla. En un principio esta lista est totalmente repleta de equis (x), pero poco a poco se irn aadiendo a esta misma lista todos los elementos propios del buscaminas que el usuario deba ver en pantalla. Cada vez que queramos mostrar el tablero del usuario en pantalla usaremos estas mismas lneas de cdigo: for fila in range (10) : for col in range (10) : print minasu[fila][col], print "|",fila print "- - - - - - - - - -"

    print "0 1 2 3 4 5 6 7 8 9"

    El aspecto en pantalla de realizar este proceso es el siguiente: x x x x x x x x x x | 0 x x x x x x x x x x | 1 x x x x x x x x x x | 2 x x x x x x x x x x | 3 x x x x x x x x x x | 4 x x x x x x x x x x | 5 x x x x x x x x x x | 6 x x x x x x x x x x | 7 x x x x x x x x x x | 8 x x x x x x x x x x | 9 - - - - - - - - - -

    0 1 2 3 4 5 6 7 8 9

    Observacin Hemos usado una nueva primitiva range(), esta primitiva crea una lista de nmeros empezando en el 0 y llegando hasta el nmero que hay en el parntesis menos 1. Es este caso range(10) crea la siguiente lista [0,1,2,3,4,5,6,7,8,9], de no existir dicha primitiva habramos tenido que crear la lista nosotros mismos.

    Nuestra siguiente preocupacin es que el usuario pueda elegir qu casilla quiere destapar. Haremos como si jugsemos a los barquitos, dando una fila y

  • Tema 19 El buscaminas

    238

    una columna, definiremos qu casilla destapar. fil = input( "INTRODUCE FILA ... ") col = input( "INTRODUCE COLUMNA ... ")

    Explicacin En esta ocasin tanto la fila como la columna son nmeros, por tanto usamos input en lugar de raw_input que debe ser usado cuando queremos que la entrada del usuario considerada texto.

    Para saber si hemos elegido una bomba hemos de verlo en la tabla de minas y no en la tabla de minasu, que es slo una tabla de presentacin en pantalla. Si en la posicin elegida haba un asterisco, quiere decir que hemos dado de lleno en una bomba. En caso contrario hemos seleccionado una casilla libre y habremos de realizar todas las acciones que hace el buscaminas cuando el usuario selecciona una casilla libre de bombas.

    Contar las bombas de los alrededores Una de las tareas ms importantes que realiza el buscaminas cuando el usuario selecciona una casilla libre es la de contar cuntas bombas hay en los alrededores.

    Supongamos que el usuario ha elegido la casilla central de la tabla. En sus alrededores puede haber un mximo de 8 bombas.

    Bomba 1 Bomba 2 Bomba 3

    Bomba 4 Lugar de la pulsacin Bomba 5

    Bomba 6 Bomba 7 Bomba 8

    Si el lugar de la eleccin lo consideramos el punto: (fila, columna). Podemos plantearnos esta tabla de este otro modo:

    Fila 1, Columna 1 Fila-1, Columna Fila - 1, Columna + 1

    Fila, Columna - 1 Fila, Columna Fila , Columna + 1

    Fila +1, Columna - 1 Fila+1, Columna Fila +1, Columna +1

    Veamos otro ejemplo para acabar de entender lo que pretendemos insinuar. Para la ocasin el usuario supondremos que eligi la Fila 1 y la Columna 1.

  • Tema 19 El buscaminas

    239

    Columna 0 Columna 1 Columna 2

    Fila 0 0,0 0,1 0,2

    Fila 1 1,0 Eleccin del usuario el 1,1 1,2

    Fila 2 2,0 2,1 2,2

    Es decir, que si el usuario hubiese elegido la casilla (1,1) las posibles bombas estaran en los 8 puntos cardinales correspondientes a (0,0) (0,1) (0,2) (1,0) (1,2) (2,0) (2,1) (2,2) Pero nosotros no estamos interesados en resolver un caso particular en el que el usuario puls (1,1) sino que queremos resolver un caso general en el que el usuario eligi la posicin (fila, columna) pudiendo ser tanto la fila como la columna cualquier valor entre 0 y 9. Suponiendo que el usuario determin unos valores al azar de fila y columna, los 8 posibles puntos cardinales que hemos de visitar en busca de bombas para ser contadas son: (fila-1, col-1) (fila-1, col) (fila-1, col+1) (fila-1, col) (fila+1, col) (fila+1, col-1) (fila+1, col) (fila+1, col+1)

    Marcando los lmites Existe un problema respecto al anterior planteamiento. Dicho problema son los lmites de la tabla, o en este caso, los lmites de las listas. Si el usuario selecciona una posicin que est en una esquina, no son ya 8 sino slo 3 las posibles bombas que hemos de localizar, porque los otros puntos cardinales que pudiramos visitar estn fuera del tablero de juego. En tales casos, intentar visitar una posicin que est fuera de los lmites nos provocara un error en el programa y hemos de evitarlo. Para ello hemos de incluir algn tipo de control de lmites en las comprobaciones de bombas limtrofes a la casilla elegida.

    Cdigo Python para contar las bombas de los alrededores de la casilla elegida. Primero establecemos unas variables de mximo y mnimo de fila y columna, que nos servirn de topes. Realmente no son imprescindibles estas variables, se lograra el mismo efecto usando los nmeros 0 y 9 directamente, pero los nmeros no llevan atribuido ningn significado, no sabemos si el 0 pertenece a la fila o a la columna, por poner un ejemplo. Usando variables, incluso para

  • Tema 19 El buscaminas

    240

    valores constantes, ayudamos a que el cdigo sea ms legible y tenga menos errores.

    max_col = 9

    min_col = 0

    max_fil = 9

    min_fil = 0

    numbombas = 0

    Comentaremos la primera condicin y no diremos nada de las otras porque van a ser muy similares todas entre s. Primero se comprueba que la fila est dentro de los lmites. Si no va a causar ningn error podemos mirar a su alrededor sin peligro en busca de bombas. Si encontramos una bomba, lo que hemos de hacer es contarla. Repitiendo esto siete veces ms estamos seguros de haber contado todas las bombas limtrofes a la casilla destapada. if fil > min_fil:

    if minas[fil-1][col]=='*': numbombas = numbombas + 1

    if fil < max_fil:

    if minas[fil+1][col]=='*': numbombas = numbombas + 1

    if col < max_col:

    if minas[fil][col+1]=='*': numbombas = numbombas + 1

    if col > min_col :

    if minas[fil][col-1]=='*': numbombas = numbombas + 1

    if fil < max_fil and col< max_col:

    if minas[fil+1][col+1]=='*': numbombas = numbombas + 1