TIS-100

TIS-100

61 ratings
TIS-100. Guía para principiantes
By RenfieldCraft
Lenguaje ensamblador, ay que rico. ¿Qué porqué hago esta guía? Es bien sencillo. El manual que viene con el juego (dándole al ESC nos da la opción de abrirlo) es demasiado obtuso para un profano en la materia, y siempre viene bien un poco de ayuda.
3
4
   
Award
Favorite
Favorited
Unfavorite
Introducción
Lo que quiero mostrar con esta guía es una visión muy por encima de lo que trata este título, pues no es nada sencillo hacerse con él. El juego no ofrece una ayuda real y el manual dista mucho de ser una verdadera ayuda, pues son conceptos muy básicos que para un profano en la materia puede parecerle muy difícil.

Antes de continuar, debo decir que no he encontrado una guía en la que basarme que estuviera en español, y es una pena dado el potencial del juego y la de horas de diversión que permite. Añadir también que si he cometido errores (lo cual es más que posible) aquellos lectores que crean y deban corregirlo estaré encantado de debatir eso y otras cuestiones necesarias para ampliar la información que yo aporto. Usaré lenguaje coloquial en la medida de que me sea posible usarlo, y sustituiré nombres básicos de programación a palabras más compensibles para los que no tengan ni idea. Todos hemos empezado desde cero, ¿no?


Gracias, y vamos a por ello.
Conceptos Usados
Una de las buenas cosas que permiten las guías de Steam es que puedo hacer lo que me salga de la caja de Pandora y estructurar la guía como me plazca, y eso es lo que voy a hacer.
En éste capítulo usaremos lenguaje coloquial para denominar a las partes que componen el juego. Aquí no hay lugar para el código, solo son descripciones de lo que visualmente nos vamos a encontrar.

NODOS

Son esas cajas que vemos en cualquier puzzle a resolver. Las hay blancas y rojas. Las rojas las ignoraremos, dado que forman parte del problema, caminos cortados por los que no se puede pasar.
Las blancas es dónde nos centraremos. La parte más amplia (que llamaremos a partir de ahora CUERPO DEL NODO) es dónde pondremos las instrucciones que queremos que haga ese nodo. ¿Qué instrucciones? Dependerá del problema a resolver. Dispondremos tan solo de 15 líneas por cada NODO, lo cual nos complica un poco las cosas (no en los primeros casos, obviamente, pero sí en el futuro)

















Dentro del NODO también podemos encontrar la ACC, que vendría a ser cómo una memoria de lectura y escritura. En ella, cómo si fuera un cajón, podremos almacenar SOLO UN DATO con el que podremos operar si fuera necesario. Cada NODO es capaz de almacenar sólo un dato utilizable, por lo que es imprescindible tener cabeza y saber que si dejamos que otro dato entre en el NODO, perderás la información que tenías almacenada.

También encontramos dentro del nodo la memoria temporal BAK, que básicamente es una memoria a la que sólo se puede acceder usando unos comandos especiales. Es la memoria auxiliar del NODO, lo que nos va a permitir tener una red de seguridad en el caso de congestión. El uso del BAK y de los comandos usados en esta sección estará explicado en el capítulo de Código.

La sección LAST por ahora no le he encontrado utilización, ni ha variado en algún momento, por lo que (y dado que esta guía se irá actualizando dependiendo de las correcciones que se hagan en el futuro) esta sección no siempre estará obviada pero si por ahora.

MODE habla del estado en el que se encuentra el NODO. Dependiendo de qué esté haciendo, estará en modo READ (lectura), WRITE (escritura) o RUN (ejecutando) El estado IDLE (reposo) nos hace ver que ese nodo no está en uso o porque no lo necesitemos o porque hayamos metido la pata en algo.

La sección IDLE nos determina qué porcentaje está usándose del procesamiento de dicho NODO. Es importante más adelante puesto que el NODO solo puede hacer una cosa y hasta que no termine no pasará a la siguiente.

Bordeando al NODO veremos unas flechas que van sin un sentido aparente a veces únicas y otras dobles. Ese es el camino que puede recorrer la información. Si nos fijamos con un poco de calma, los NODOS en rojo (o "No Operativos") solo tienen flechas que les llegan a ellos, pero ellos no emiten flechas. ¿La razón? Al igual que tú puedes llamar a un número de teléfono que no existe (y no obtener respuesta) pero no puedes recibir una llamda de un número inexistente. Pues lo mismo, vaya. En estas flechas veremos el valor que pasa de NODO en NODO, y podemos interpretar dichas flechas cómo cables que conexionan los NODOS entre sí.


INTERFAZ

También podemos ver otras cosas en la interfaz del juego a parte de NODOS. En la esquina inferior izquierda encontraremos la forma de arrancar el programa (RUN), más rápido (FAST), parar (STOP), y lo que os salvará el cu1o en muchos momentos, el paso a paso (STEP) Este último, como digo, nos ayudará a ver dónde la hemos cagado en nuestro sistema y nos permitirá vislumbrar exactamente dónde necesitamos arreglar.

En la esquina superior izquierda tendremos el problema a resolver. Serán problemas de índole matemática o lógica. En el primer ejercicio, por ejemplo, nos manda que "Recojamos la información que llega por ENTRADA.X, la saquemos por SALIDA.X y que cojamos la información que entra por ENTRADA.A y la saquemos por SALIDA.A" En el apartado "Primer Puzzle" explico paso a paso qué hay que hacer para que os sea más llevadero el aprender.
(como dato adicional y antes de continuar con otras secciones, las entradas y salidas nos vienen marcadas en la parte superior o inferior de todos los NODOS. Ahí es dónde empieza y dónde termina el problema)

Justo debajo, esas tablas con unas numeraciones extrañas que a priori no deberían decirnos nada. Si tenemos una entrada de flujo de datos, ahí saldrá (para el modo Debug o, STEP) la información de las entradas y salidas, qué tiene que tener en cada caso y la verificación. Si en las partes "en negro" (información que aún no ha llegado) aparece un dato erróneo, nos saltará un aviso en rojo y la información recibida en la salida. Esto es útil dado que con el modo STEP activado (recordamos, paso a paso) podremos ver dónde va cada información y saber que si ha llegado a la salida algo que no debe, es que has mandado algo que no debías.
Código
En esta sección llamada código vamos a ver si conseguimos construir un caballo de carreras con todas estas piezas de LEGO... No cuela, ¿no?

Sé que esta es la sección más aburrida y tortuosa que os podéis imaginar en vuestras alocadas vidas de solteros, pero intentaré hacerla lo más llevadera humanamente posible. Así que, vamos entrando en materia.



















MOV

Es el comando que más vais a utilizar. Es el que se encarga de mover un dato de un sitio a otro y usaremos la sintaxis MOVE lugar_1, lugar_2. Os pondré unos ejemplos y ya veréis que bien se entiende.


MOV LEFT, ACC
Con esto lo que hacemos es recoger el valor por la izquierda del NODO y almacenarlo en ACC (memoria del NODO, si os acordáis)

MOV 8, DOWN
Esta expresión haría que mandásemos un valor 8 (un ocho como número, vamos) hacia abajo del nodo.

Como veis, MOV es la expresión que más veces usaréis. Tanto que acabaréis hartos de ella.

NOP

Este comando lo usaremos para.... ¿nada? No, en serio. Se usara para hacer que el NODO no haga nada. Es la función de cubo de basura, de "descarte esta carta y robe otra" dado que mandamos al pijo un dato y, si lo tenemos preparado en el NODO, cogemos el siguiente. También podemos usar el comando NIL en vez de NOP para hacer el mismo trabajo. Con un ejemplo lo veréis.

MOV ACC, NOP
Usaremos esto para vaciar la memoria del NODO, porque básicamente le estamos diciendo que mueva la información que hay en la memoria y la mande al pijo. También se podría haber puesto MOV ACC, NIL para el mismo efecto.

ADD
Add nos permite añadir algo a ACC de ese módulo. Es básico, y muy sencillo de usar. La sintaxis a usar es ADD dato_1 y se puede interpretar como ACC+dato_1

ADD 15
Añadirá 15 unidades al ACC (memoria del NODO), por lo que si teníamos 0 ahora tenemos 15, y si teníamos 20 ahora tenemos 35.

ADD ACC
Con esto duplicamos lo que haya en ACC, viene a significar ACC+ACC

ADD UP
A lo que hubiera en ACC le sumamos el dato que entra por arriba.

SUB
Básicamente es lo mismo que ADD pero restando. SUB dato_1 que es lo mismo que ACC-dato_1

SUB ACC
A ACC le restas ACC, básicamente lo dejas a 0

SUB DOWN
A ACC le restas lo que entra por debajo del NODO.

NEG
Invierte a negativo automáticamente el dato que le pongas. Si tenemos ACC con valor 15 y hacemos un NEG ACC, pasará a tener valor -15. Sintaxis es NEG dato_1

SAV

En este caso, se usa SAV para guardar la información de ACC en BAK. Fácil y cómodo.

SWP

En la sección "Conceptos Usados" explicamos qué era el BAK (memoria temporal de un NODO) y comentábamos que los comandos que se usan para el BAK son especiales. Y es cierto, en este caso SWP se usa para intercambiar la información entre el ACC y el BAK. No tiene más.

LABEL

Esto no llega a ser una sentencia ni un operando. Podemos tratarlo como funciones o microprogramitas que harían cosas a parte. La forma de declarar la función A corresponde a A: BLABLABLABLA y cuando el código ejecute A (ya veremos cómo) hará el contenido de BLABLABLABLA. Lo explicaré en la siguiente sección, que se entenderá mejor.

JLZ

El significado es "Jump is Less than Zero" que se viene a traducir "Ir a la función que digas si ACC es inferior a cero". Básicamente, llamaremos a una LABEL si el dato que tenemos en ACC está por debajo de 0. Lo entenderemos en el siguiente caso.

JGZ

Significa "Jump if greater than zero" o "Ir a la función que digas si ACC es superior a cero". Vamos a explicar estos tres últimos casos en código para entenderlo.


MOV UP, ACC Mandar desde arriba a ACC
JLZ A Si ACC es menor que 0, ejecuta la función A.
JGZ B Si ACC es mayor que 0, ejecuta la función B.
A: MOV LEFT, DOWN Crea la función (o label) A, recoge de izq. y para abajo
B: MOV RIGHT, DOWN Crea la función (o label) A, recoge de drch. y para abajo

De esta forma, cogeremos datos de arriba y lo guardamos en ACC. Si ACC es menor que cero, cogerá el dato de la izquierda y lo lanza hacia abajo. Si ACC es mayor que cero, cogerá el dato de la derecha y lo lanza hacia abajo. Esto permite hacer comparadores de forma rápida.

Con JNZ (Jump if not equal to zero - Ir a X función si ACC es distinto de cero) y JEZ (Jump if equal to zero - Ir a X función si ACC es igual a cero) usan el mismo sistema que con JLZ y JGZ.

COMENTARIOS

Esto es, realmente, escribir un comentario en el código. Hará que el programa salte ese texto y se consigue poniendo una almohadilla (#) antes del comentario.

BREAKPOINT

Crear un punto de ruptura o un punto de parada obligada que hará que el programa pare en seco al llegar a ese punto. Es muy útil cuando estás en modo Debug o intentas averiguar porqué tu código no funciona y tienes que ir a un paso en concreto haciendo que los pasos anteriores vayan rápido.Se consigue poniendo un signo de exclamación (!) al principio de la sentencia.

! MOV LEFT, DOWN
El programa se parará justo antes de ejecutar esa sentencia y podrás ir paso a paso para ver qué ocurre cuando recoges el dato desde la izquierda y lo mandas hacia abajo.
Primer puzzle
Antes de empezar la guía, recomendaría echarle un ojo (al menos) al primer caso llamado "SELF-TEST DIAGNOSTIC" dado que me servirá para introducir vuestras mentes en un estado de licuación absoluta. Ensamblador, lenguaje máquina, programación de bajo nivel... Son algunas formas de llamar a este tipo de programación. Se basa en programación más básica, antigua y robusta que existe (si obviamos las tarjetas perforadas o el telar de Jacquard) y con lo único que trabajaremos será con la lógica computacional, las matemáticas y los números. Vamos a ello pues.




















Si ya hemos visto en el capítulo de "Conceptos Básicos" las partes del programa, iremos más rápido. Recomiendo su lectura antes de continuar.

Vale, ¿ya los has leído? ¿Aún no? Venga, que te espero.

¿Ya? ¿Seguuuuuro? Vale, confiaré en ti...

Lo que nos pide el programa es lo siguiente

Read a value from IN.X and write the value to OUT.X
Read a value from IN.A and write the value to OUT.A

Lo que viene siendo que lo que entre por IN.X (ENTRADA.X) salga por OUT.X (SALIDA.X) y lo mismo con IN.A y OUT.A (ENTRADA.A y SALIDA.A)

Es bien sencillo, y tomaremos este puzzle como la mayor ayuda que recibiremos del juego dado que la sección X (IN y OUT) ya la tenemos rellenada y tan solo necesitaremos casi copypastear la información desde la IN.A hasta la OUT.A. Veamos primero el resultado correcto y luego explicaré paso a paso todo.




















Empecemos enumerando los NODOS desde arriba a la izquierda. Ese será el primero. El último de esa fila (por el que debemos empezar en este caso) será el 4º. Como veis, he usado la expresión MOV, lo cual usaremos para mover desde un sitio hasta otro sitio un valor.

En este caso, usamos MOV UP, LEFT para decir que queremos recoger el dato de la parte superior de ese NODO y mandarlo a la izquierda de ese NODO. ¿Fácil, no?

Escribiremos, por tanto, en el NODO 3º (a dónde hemos mandado la información) MOV RIGHT, DOWN porque queremos recoger la información que nos manda el NODO de la derecha y mandarla hacia el NODO de abajo.

Ahora usamos MOV UP, DOWN porque la recogemos de arriba y la mandamos abajo.

MOV UP, RIGHT para recogerla de arriba y mandarla a la derecha

Y para terminar, MOV LEFT, DOWN para recogerla de la izquierda y mandarla abajo.

Ahora, simplemente podemos comprobar paso a paso (con el botón STEP) para ver cómo funciona nuestro programa y aprender más sobre cómo optimizarlo (en el capítulo de Optimización) o simplemente dadle a RUN para que haga las cosas que le habéis mandado hacer y verifique automáticamente la funcionalidad del mismo.

Y este es el primer puzzle, que es lo más parecido a un tutorial que tendréis en el juego.
Ampliación y fin
Por ahora dejo las cosas así. Es una guía rápida para principiantes que les de cosita TIS-100 y su funcionamiento. Con la tontería llevo 5 horas para hacer esta guía, y no es nada del otro mundo.

Esto se puede entender como un organismo vivo, se modificará, he omitido cosas con las que yo aún no he tenido que tratar y se mejorarán con otros ejemplos mejores, explicaciones más entendibles y lo que digáis que necesita mejorar.

El reto del juego TIS-100 a parte de resolver el puzzle es completarlo en la menor cantidad de ciclos, nodos y sentencias posibles. Lo gracioso es que te puedes picar con tus amigos para hacerlo más rápido (o al menos intentarlo y morir en el intento) Esto le da un aliciente interesante para no dejar que el juego muera cuando lo hayas "terminado"

Agradecer a Zachtronics por crear un juego tan divertido y tan alejado de otros títulos tan innecesarios que existen hoy en día, y por darme tantas horas de diversión.

Para cualquier duda, sugerencia o comentario, tenéis la caja de "Habla con el tonto que ha hecho la guía" bajo esta sección, también llamado "Caja de comentarios"

¡Gracias!
12 Comments
kevdelsol Apr 27, 2023 @ 7:48pm 
Muchas gracias por la guia, nuestro profesor de universidad nos mando tu guia para ayudarnos jaja
ARGONITA Feb 18, 2022 @ 2:37pm 
Gracias al empujón inicial que te da este manual, se puede empezar a jugar. Muchas gracias!!!!
dat.hinge Dec 7, 2021 @ 6:23pm 
Muchas gracias por la guía. Muy útil.
txt-capi May 18, 2021 @ 6:55am 
Buen trabajo!! Buen aporte.:steamthumbsup:
tarodwalin Aug 21, 2019 @ 2:10pm 
Gracias¡¡¡¡
|/\|S|\/| Aug 19, 2019 @ 1:07am 
Gracias, tarde mucho en entender el juego prueba y error solo e podido resolver los 3 primeros puzzles pero ahora que leí tu guía ya entiendo mejor las funciones de los códigos aunque sigo sin saber inglés :steamfacepalm: :steamhappy:
Iskander Nov 21, 2018 @ 6:30am 
Hola Trurl, si haces clic en un nodo, dentro del espacio donde ya hay instrucciones escritas, lo podrás utilizar como una consola de comandos y escribir tus instrucciones. Estas se ejecutarán de forma secuencial, una tras otra. Dale duro!
Trurl Feb 4, 2018 @ 5:28pm 
Entiendo los comandos, pero no la forma en la que son ejecutados. Se el destino final de la información, pero me cuesta entender, dónde colocar los comandos para que estos envíen la información..help me
Calabacin Sep 30, 2017 @ 3:56am 
Es una buena guía para empezar. Buen trabajo, RenfieldCraft
Undigon Jul 30, 2017 @ 5:17pm 
Buenas, vi una inexactitud.
MOV ACC, NOP no es ejecutable porque NOP es equivalente a "ADD NIL" o "ADD 0". Por lo tanto, no vaciará ni podrás ejecutar ese nodo en absoluto.
La instrucción que limpia ACC sería cualquiera de estas tres opciones:
MOV NIL, ACC ... MOV 0, ACC ... SUB ACC

Así mismo, NEG no admite argumentos. NEG cambia el signo del contenido de ACC por lo que
MOV -15, ACC
NEG ;Ahora ACC contiene al valor +15!

Por último, me parece que se podría mejorar la explicación de LABELS. Preferiría que lo expliques como puntos de referencia hacia donde puedes realizar los saltos de la secuencia de ejecución (JUMP).

Podrías agregar una sección de "Debugging para principiantes" donde explicás el error más común que tuve, leer o escribir en la dirección equivocada y que el programa espere un dato de un nodo que no se lo proporcionará así como reads o writes simultaneos (¿Colisión?)

¡Saludos!:fdisk: