Está en la página 1de 22

Instituto Superior de Formación Docente y Técnica

Nº 44

Tecnicatura Superior en Análisis de Sistemas

Espacio de Definición Institucional 3


E.D.I. 3

Trabajo Práctico N° 9:
Análisis de Actividades Scratch

Profesor: Lic. Patricio Meaca

Curso: 3° U

Alumno: Mauricio Codega

Año: 2020
Resolución de Actividades en Scratch
Desde un enfoque sistemático, podríamos resolver la mayoría de las actividades en Scratch utilizando
una cierta cantidad de recursos que son propios de la programación, y en este sentido, comunes a la
resolución de muchos otros problemas que requieren algoritmos o procesos lógicos para la obtención
de resultados.

Según las herramientas que vimos hasta ahora podríamos pensar en los siguientes recursos a utilizar:

Las primitivas, que son los comandos básicos que acepta nuestro autómata. En un procesador
informático, estas instrucciones están clasificadas en RISC (Reduced Instruction Set Computing) y CISC
(Complex Instruction Set Computing). Estas instrucciones básicas después se agruparán en procesos
que van creciendo en complejidad, en el caso de una computadora primero en el núcleo del sistema
operativo, después en las aplicaciones comunes y finalmente en las aplicaciones terminales que utiliza
el usuario. En el caso de Scratch, las rutinas creadas con primitivas no escalan demasiado en
complejidad ya que el usuario es el programador que diseña los algoritmos.
Las sentencias de control, que describen la manera en la que se
suceden las primitivas y permiten formar largas secuencias de
primitivas que forman los algoritmos para resolver los problemas
que se nos plantean. Entre ellas SI (Condición) Entonces… SI
(Condición) Entonces, SI NO…. Mientras (Condición) Hacer…
Hacer Mientras (Condición)… Repetir (N° de Veces) El Algoritmo…

Los eventos, que son como interrupciones globales del sistema


sobre el cual va a funcionar nuestro programa. Son circunstancias
externas al programa que en el caso de verificarse tienen un gran
impacto sobre la ejecución del programa. Algunos ejemplos son
comenzar a ejecutar el programa, detener el programa o hacer
un sondeo de variables
externas al programa como
las teclas que se presionan
en el teclado (polling), por
ejemplo.
Condiciones, que son circunstancias internas al programa que se
pueden medir utilizando diferentes bloques para detectar o sensar
dichas situaciones o condiciones o estados de ejecución del
programa.

Operadores Lógicos, que


actúan sobre las Condiciones
o situaciones que se
encuentran en el programa,
de manera que las suman, las
restan, las multiplican,
dividen, aleatorizan,
comparan… entre otras
operaciones.
Rutinas y subrutinas (También llamadas funciones o métodos o macros o algoritmos o secuencias), son
agrupaciones de comandos primitivos, sentencias de control, y todo lo que vimos hasta ahora de
manera de formar procedimientos que son utilizados por el automatismo de manera recurrente y
desde la perspectiva del programador elevan el lenguaje de programación, facilitando crear
comportamientos complejos mediante la posibilidad de hacer múltiples tareas invocando una única
sentencia (que podría verse como una primitiva, pero en realidad es una secuencia extensa de varias
primitivas). En la imagen inferior encontramos el ejemplo de “El gato en la calle”, que si nos dirigimos
al área de trabajo, en la parte superior derecha, podremos encontrar “el esqueleto” que da sustento al
ejercicio mediante la implementación de subrutinas.
Con los anteriores recursos combinados utilizando programación estructurada, podremos resolver la
mayoría de los ejercicios de Scratch.

Empecemos por “El gato en la calle”. El programa podría ser resuelto, de la forma más sencilla como se
muestra a continuación:

Sin embargo, este tipo de diseño no es óptimo para grandes programas orientados a objetos, ya que
no es fácil de rastrear errores ni modificar el comportamiento de manera modular. Y justamente para
que el programa sea más modular, necesitamos definir fragmentos del programa que sean fácilmente
identificables y nos permitan un control más específico de lo que se le pide al automatismo.

En la siguiente imagen, vemos cómo se implementan las subrutinas de manera que el programa se
divide en dos etapas: IR y VOLVER. En cada una de dichas rutinas se encuentran las subrutinas
necesarias para llevar a cabo el proceso predefinido.
Bueno, pasemos a “No me canso de saltar”. Hay que saltar 30 veces. Una manera de resolverlo sería:
Pero, nuevamente el programa no es fácilmente depurable, ni escalable, ni portable, ni es simple de
comprender a simple vista, ni nada. Hay que empezar a crear procesos. En la siguiente imagen se
resuelve el ejercicio de diferentes maneras.

Primero vemos que si presionamos la bandera verde, damos inicio a un bucle de repetición simple de
30 iteraciones. Es una manera directa de resolver el problema.

En segunda instancia vemos que cuando se presiona la tecla ‘a’, se inicia un bucle infinito de recursión,
en el que se invoca a una función que primero hace saltar al gato y después se vuelve a invocar a si
misma haciendo saltar otra vez al gato… infinitamente. Pero como son 30 piedras y no hay un control
de cantidad (que se podría implementar por ejemplo desde “data”, “nueva variable”), el gato se
termina pasando.

En la tercera entrada (que no están secuencializadas) al proceso de resolución, encontramos que al


presionar “b” hacemos lo mismo que en el primer caso. Hubiera sido mejor llamar a un proceso que se
llame por ejemplo “30 saltos” y que se encargue de hacer justamente eso.
En la siguiente imagen resolvemos “El marciano en el desierto”. El problema consiste en comer una
cantidad de manzanas aleatorias desparramadas por un tablero de 4 columnas por 4 filas. En total son
16 casilleros y bien podríamos ir recorriendo uno por uno y comiendo manzana si hay. Pero en este
caso podemos simplificar las cosas creando por lo menos una rutina “comer fila” (o “Comer Columna”).
Después necesitaríamos que el marciano vuelva, suba y coma otra fila. En el ejemplo elegí utilizar dos
funciones muy similares, una come una fila yendo hacia una dirección y la otra come una fila volviendo
en la dirección contraria. De esta manera, el programa principal consiste en una sucesión de aplicar
una función, subir, aplicar la otra función y volver a subir.

Se podría haber hecho este programa mucho más modular si el programa principal hubiera estado
hecho en una rutina aparte… así como también la toma de decisión de comer manzana o no.

El siguiente ejercicio es “El recolector de Estrellas”. Tenemos que tomar un grupo de estrellas dentro
de un tablero de casillas. Dentro de las subrutinas que vienen predefinidas, tenemos la de volver al
margen izquierdo, así que nos vamos a valer de eso en conjunto con repeticiones simples para resolver
el problema.
Sin embargo podemos aplicar una repetición simple más que nos comprenda las primeras tres
repeticiones simples que son iguales ente sí. Lo vemos en la imagen siguiente:
El siguiente ejercicio se llama “Lightbot en Scratch”. Lo podemos resolver de la siguiente manera:

En la primera repetición simple avanzamos en diagonal hacia arriba y a la derecha mientras vamos
encendiendo. Nos reposicionamos y vamos avanzando en diagonal hacia abajo y a la izquierda
mientras prendemos las luces. Podríamos haber definido varias rutinas auxiliares que comprendan esas
funciones.
“Instalando juegos” es bastante lineal y repite 3 veces el mismo proceso. El programa principal consiste
entonces en una repetición de 3 veces hacer: Ir a la siguiente computadora, instalar el juego.

Continuamos con “la gran aventura bajo el mar”. Primero hay que buscar la llave, después abrir el
cofre, después darle el sombrero al mago, después atacar con la espada y escapar en unicornio. Cada
Rutina creada responde a cada uno de esos pasos. Hubiera estado bueno hacer el juego para que sea
interactivo utilizando eventos y desplazando al personaje en tiempo real.

Seguimos con “María la Come Sandías”. Definimos las rutinas comer fila, comer columna y volver a la
izquierda. Luego las concatenamos de la siguiente manera: repetimos dos veces comer fila, volver a la
izquierda, mover arriba, mover arriba. Por último comemos la fila superior, volvemos a la izquierda y
comemos la columna. No importa si comemos la misma sandía más de una vez.
A continuación, “Reparando la Nave”:

Hay que cargar la nave tres veces con Carbón y tres veces con Hierro. Se definen los Procesos “Hierro”
y “Carbón” que consisten en ir a buscar dichos elementos y depositarlos en la nave y se repiten 3 veces
en el programa principal.
“Alimentando los peces” consiste en ir a buscar comida (como se muestra en el proceso homónimo),
posicionarse para alimentar a los peces en una misma fila y alimentar la fila de peces (ya que se repiten
muchas cosas se crea un proceso “Alimentar Fila Izq”). Luego nos posicionamos nuevamente y
volvemos a alimentar la fila utilizando la función “Alimentar Fila Izq”

A continuación resolvemos “La Elección del Mono”. Este es un programa muy importante dentro de
este análisis. Porque es el primer programa que tiene una rutina principal y única que se llama cuando
arranca el programa. Esto es similar a cuando un programa tiene un menú de entrada, como un
videojuego. El usuario arranca el programa y se encuentra en un lugar común, una especie de lobby de
recepción con ciertas opciones. Algunas opciones que se suelen dar son las de acceder a la
configuración, iniciar un nuevo proyecto, volver a abrir trabajos empezados… También es una instancia
en la que se suele verificar si el usuario tiene la licencia del programa o si se está ejecutando una
versión demo con menos características (que se bloquean intencionadamente llamando a una rutina
de bloqueo de funciones, que es la rutina que los hackers suelen anular para crackear un programa por
ejemplo).

Entonces nuestro programa arranca y se llama a una única función principal que se encarga de todo el
manejo de algoritmos. “Comer Frutas” se encarga de avanzar y luego “Comer Banana Si Hay” y
después “Comer Manzana Si Hay”. En eso consiste toda la resolución del problema.
A continuación veremos “Laberinto Corto”. Consiste en que un personaje avance un único casillero
generado aleatoriamente hacia abajo o hacia la derecha (hay que sensar dónde aparece) y luego hay
que sensar si la casilla en la que nos encontramos es la casilla final y terminar el programa.

Para resolver este problema se crea una única función principal que maneja toda la concatenación de
algoritmos. Primero se ejecuta la rutina “If Derecha” (que mueve el personaje a la derecha, si es que
hay una casilla), después se ejecuta la rutina “If Abajo” (que mueve el personaje abajo, si es que hay
una casilla) y finalmente se ejecuta la rutina “If FIN” (que finaliza el programa si nos encontramos en la
casilla final). Con eso se resuelve el programa. Algunas de estas rutinas se emplearán tal cual, en la
versión extendida de este ejercicio que se analiza a continuación.
En la imagen anterior, resolvimos “Laberinto Largo”, que es una versión extendida del ejercicio
anterior. Fíjense lo importante que es definir bien las rutinas para que sean lo más modulares posibles.
En este caso lo único que varía para recorrer un laberinto de longitud N (desconocida pero finita), es
una única llamada recursiva al final del programa principal que se autoinvoca a sí mismo al final de su
ejecución, por lo que a priori sería un bucle infinito, pero como existe la posibilidad de detectar el final
del recorrido y salir con una sentencia de control “Stop all”, el programa resulta finito. Este tipo de
recursividad ya lo habíamos implementado en Lightbot (en su versión de juego flash standalone).

A continuación tenemos la resolución de “LightBot Recargado”. Hay que prender 10 luces que se
generan aleatoriamente en un camino recto de 10 casillas. Para resolverlo primero invocamos a una
función principal. Esta se encarga de establecer una repetición simple de 10 veces, en la que primero
se invoca a la rutina “If Luz” (que prende luz si la hay, incluso en la primera casilla) y después se avanza.
Con este simple algoritmo se resuelve el ejercicio.

Muchas veces utilizo el comando Say (String) for (float) secs, como un elemento de depuración para
ver cuando el programa ingresa en tal o cual función o subrutina. Con esto logro trazar el
funcionamiento del programa y es más sencillo corregir los defectos o “debuggear” el programa

A continuación resolvemos “Tres Naranjas”. También contiene una función principal que se encarga de
todo y luego de finalizada se procede a detener la ejecución del programa. La función principal se
encarga de repetir 3 veces (avanzar y comer naranja si hay). A su vez, “comer naranja si hay” se
encarga de sensar la existencia de naranja en la casilla y comerla si hubiera. También se informa
cuando se comen las naranjas como elemento de depuración al estilo flag o bandera.
“El detective chaparro” debe identificar al culpable dentro de una serie de personajes inocentes. Para
ello utiliza una función principal que se encarga de toda la lógica. Se avanza hasta el primer sospechoso
y luego se entra a la subrutina “Descubrir culpable”, que consiste en una repetición condicional (hasta
que se encuentre el culpable) haciendo “Identificar inocente” (una subrutina que consiste en pasar al
siguiente personaje si el actual es inocente y luego sacar el disfraz). Eso es todo.

A continuación se resuelve “Laberinto con Queso”, un ejercicio muy similar a otros anteriores pero que
ahora, además de recorrer el laberinto hay que comer el queso. El programa inicia con una única
función encargada de toda la lógica. Esta consiste en un bucle de repetición condicional (hasta que se
toque la casilla final) haciendo “Comer Queso Si Hay” y luego “Elegir Dirección”. La primera función se
encarga de sensar y comer queso si hay. La segunda se encarga de sensar si hay una casilla abajo (en
cuyo caso se avanza abajo) o si no hay (en cuyo caso se avanza a la derecha.)

A continuación resolvemos el ejercicio “Prendiendo las Compus”. Hay que prender todas las
computadoras de los bordes de un tablero de N casillas (número aleatorio), en cuyas esquinas hay una
casilla verde que indica una esquina del tablero (fin de columna y fin de fila). Entonces para resolver
este problema usamos una única función principal encargada de toda la lógica. Dentro de ella podemos
encontrar 4 llamadas a funciones diferentes. “Prender pared de arriba hacia derecha” (que primero
avanza hacia la derecha y luego prende las computadoras de la pared de arriba hacia la derecha hasta
que encuentra una casilla verde o esquina), “Prender pared de derecha hacia abajo” (que primero
avanza hacia abajo y luego prende las computadoras de la pared de la derecha hacia la abajo hasta que
encuentra una casilla verde o esquina), “Prender pared de abajo hacia izquierda” (que primero avanza
hacia la izquierda y luego prende las computadoras de la pared de abajo hacia la izquierda hasta que
encuentra una casilla verde o esquina) y finalmente se invoca a “Prender pared de izquierda hacia
arriba” (que primero avanza hacia arriba y luego prende las computadoras de la pared de la izquierda
hacia arriba hasta que encuentra una casilla verde o esquina). Fin del Programa.

Finalmente, en el ejercicio “Super LightBot”, el personaje debe prender todas las luces ubicadas en
casillas aleatorias de un camino derecho de longitud aleatoria. Para resolver esta tarea también
utilizamos una única función principal que se encarga de toda la lógica. “Encender todas las luces” se
repite hasta que se toque la casilla “FIN” haciendo (Si hay luz encender y avanzar). Dos acciones que
paso a paso detectan si en la casilla actual hay una luz, y si la hay se enciende; y luego se avanza de
casilla para repetir el mismo proceso (hasta la casilla FIN).