CJA, on 13 June 2016 - 04:04 PM, said:
I think that the reason that I had a different experience with HRM is that because I played it on my phone, which, yes, okay, it was designed for. I thought that the PC version would have... you know... typing. The challenges don't really get very complicated or push the limits of what the game offers, but the optimization challenges are perfect 15-minute-break sized puzzles that are designed to be solved while my fiancee is in line to get ice cream, and then I can lock your phone and walk away. Also, this was my first experience working with any assembly-level language at all! I think it's a very good introduction to the concept of working with data at such a low level. I also think that if I had taken some sort of formal course about ASM I would find the puzzles akin to tedious homework.
So I have no contest with anything you said and I'm inclined to agree that if this game on PC is anything like it is on iOS, then it would probably be much more annoying to play. But I feel like for someone like me, having no ASM experience and playing it on a phone, all of these things were positive factors or at least didn't affect me.
I do look forward to playing TIS-100, though. I hope the memory cell concept isn't anything like trying to reverse-engineer sliding puzzles.
Not really much like sliding puzzles, it's more that you have to be creative when doing anything involving more than one value at a time.
Let me give you a "simple" example:
>SEQUENCES ARE ZERO-TERMINATED
>READ A SEQUENCE FROM IN
>WRITE THE MIN VALUE TO OUT.I
>WRITE THE MAX VALUE TO OUT.A
>EXAMPLE INPUT: 14 73 58 0 21 87 11 56 0 50 71 60 0 98 60 18 76 0 20 28 98 0 83 34 11 0 50 84 53 58 0 92 52 83 24 88 0 76 0
>EXAMPLE OUT.I: 14 11 50 18 20 11 50 24 76
>EXAMPLE OUT.A: 73 87 71 98 98 83 84 92 76
IN |
+------------------++----------v-------++------------------++------------------+
| ||MOV UP DOWN || || |
| || || || |
| || || || |
| || || || |
| || || || |
| || || || |
| -> -> -> |
| || || || |
| <- <- <- |
| || || || |
| || || || |
| || || || |
| || || || |
| || || || |
| || || || |
+-------^--|-------++-------^--|-------++-------^--|-------++------------------+
+-------|--v-------++-------|--v-------++-------|--v-------++------------------+
| ||MOV UP ACC ||MOV LEFT DOWN ||\ /|
| ||MOV ACC DOWN || || \ / |
| ||MOV ACC RIGHT || || \ / |
| || || || \ / |
| || || || \ / |
| || || || \ / |
| -> -> || \ / |
| || || || >--< |
| <- <- || / \ |
| || || || / \ |
| || || || / \ |
| || || || / \ |
| || || || / \ |
| || || || / \ |
| || || ||/ \|
+-------^--|-------++-------^--|-------++-------^--|-------++------------------+
+-------|--v-------++-------|--v-------++-------|--v-------++------------------+
|S: MOV RIGHT ACC ||MOV UP ACC ||MOV UP ACC ||S: MOV LEFT ACC |
|SUB RIGHT ||JEZ Z ||JEZ Z ||SUB LEFT |
|JLZ R ||SWP ||SWP ||JGZ R |
|MOV 1 RIGHT ||S: MOV UP ACC ||S: MOV UP ACC ||MOV 1 LEFT |
|JMP S ||JEZ O ||JEZ O ||JMP S |
|R: MOV 2 RIGHT ||MOV ACC LEFT ||MOV ACC RIGHT ||R: MOV 2 LEFT |
| ->SWP ->SWP -> |
| ||MOV ACC LEFT ||MOV ACC RIGHT || |
| <-JRO LEFT <-JRO RIGHT <- |
| ||SWP ||SWP || |
| ||JMP S ||JMP S || |
| ||O: SWP ||O: SWP || |
| ||Z: MOV ACC DOWN ||Z: MOV ACC DOWN || |
| || || || |
| || || || |
+------------------++----------|-------++----------|-------++------------------+
OUT.I v OUT.A v
This is a program that tracks min and max values over sequences. The three cells at the top are really just about splitting the input and passing it to two different processing units of very similar form. These take the form of a storage unit (right above each output) and a comparison unit (to the left or right). The main limitation is that while each "processor" can store two values and SWP between them, it can never work with both at the same time. Processors can reason about data being passed on their "ports", but not about comparisons between values "inside" themselves. So we NEED a second processor in order to ask a question about the relationship between two values. The program basically says, accept first input. Zero (empty list) passes through automatically, otherwise we store the first input. For all subsequent input, we check for end of list (output current stored value), and then pass both to the comparitor. The comparitor subtracts and compares less than zero and then returns what is basically an argument to a switch statement (JRO X jumps X instructions forward or back depending on the value read from X). This way, if the subtraction says the original value is less than or equal, the main processing swaps it back to storage. Otherwise, the new value remains in storage and the old one gets overwritten on the next loop. the right side of the program runs very similar steps targeted at determining the largest value instead.
Hopefully that's understandable enough to follow, while demonstrating the complexity of the workarounds you have to invent to get around otherwise simple problems like comparing two values.