Monday, January 1, 2024

Week 1: Programming Languages and My Experience Recreating Snake

 

    Today, I began my first formal foray into the realm of computer programming with an online educational tool called Scratch. Scratch is a simple drag-and-drop block programming tool used to help build a student’s beginning awareness of programming logic. Through reading the course materials, I learned about the several foundational programming languages, machine language, assembly, and our first higher-level programming language: Python. In this initial post I will be relating my first experience with this website, what I learned through my first exposure to the other programming languages, and how these languages might best be used.

My First Experience using Scratch

      My first experience in using the online educational programming platform, Scratch, was an interesting one. I was dropped into the programming environment with very little explanation or example. It began with a basic example program to animate a sprite of a cat to move and play a simple meowing sound once the green flag button was clicked (Scratch, n.d.). However, once I got to exploring the available options for new block instructions, I remembered that one common task programmers use to help learn a new platform is to recreate the classic arcade game ‘Snake’. Once I had a vision of what I wanted my end product to look like, I set about animating a simple circle sprite with the proper controls. I quickly learned that movement commands are dependent on which way the sprite is currently facing, and so as part of any movement commands, I first needed to instruct the sprite to change direction when the corresponding arrow is pressed before moving. Once I could move the dot around the screen, I needed pellets to collect, so I created a new sprite. With this new sprite, I learned that program instructions are tied to the current sprite, and so I needed to create the behavior of this sprite from scratch. Using my current knowledge of how video games typically handle collectibles, I didn’t waste time trying to individually code each pellet as a separate entity, but instead coding my new dot as a spawner, creating and distributing clones of itself across the playing field at random when the game begins and setting a variable called ‘# of balls’ to 10. I then created instructions for the clones to interact with my avatar. When my avatar comes into contact with one of these spawned entities, it’s supposed to disappear with a popping sound and decrease the ‘# of balls’ variable by 1. Additionally, when I press the button to begin the game, I needed them to reset instead of just creating more balls, so I added an instruction telling all cloned balls to despawn once the spacebar is pressed to begin a new game. Once the balls had functionality, I needed to code a win condition for the game; so, I went back to the player sprite to code a win condition specifying that when the ‘# of balls’ variable reaches zero, the game ends and it needs to spawn a word bubble proclaiming ‘You Win!’. I also created an instruction to reset the player to the lower-left-hand corner of the screen when the spacebar is pressed to start a new game.

      One of the key features of the game ‘Snake’ is the behavior associated with the player character. As more balls are collected, more segments are added to the snake, and touching one of these segments with the foremost segment results in a fail-state. I ran into trouble properly coding behavior needed to properly spawn and offset the positions of additional segments and have them follow the main character. Additionally, limitations associated with coding behavior of cloned entities do not allow them to condition behaviors associated with interacting with separate instances of the same sprite. It occurs to me only now as I write this that I might be able to overcome this limitation by creating a third entity solely for the tail segments, so that they can be coded to trigger a fail state when coming into contact with the main sprite. On top of that, the game would always spawn precisely one collectible with no collision, resulting in it being unable to be collected. My theory is that this entity is the original sprite, which is for some reason ignoring its routine following the spawning of other objects. Attempting to instruct this instance of ‘Ball’ to delete itself after spawning the others didn’t work, likely because the instruction for doing so specifies ‘delete this clone’, and the program doesn’t recognize the original entity as a clone. I overcame this limitation by adding a command to the beginning of the spawn routine to ensure it’s shown when it begins, so the clones it spawns are set to be visible, then to hide itself at the end of the routine to avoid leaving behind one uncollectable sphere.

    One final problem I ran into, but was not able to figure out the cause of, was that when spawning in the collectibles, spawning in only ten would often have less than ten spawn, resulting in me having to settle on spawning 13 in order to guarantee enough balls spawn to allow the game to be won.

    During this exercise, I have gotten used to using entities, using instructions and variables to control those entities, and defining basic conditional statements in Scratch. It’s given me an appreciation for the difficulty of game development and whetted my appetite for more. I find myself constantly mulling over the puzzle of how to get these troublesome problems, and instead of exhausting me, they prove to be invigorating, like trying to come up with the answer to a difficult riddle.

This iteration of the game can be found here: https://scratch.mit.edu/projects/931227421/

Machine Language, Assembly, and Python

    Machine Language, the most barebones of programming languages, is the binary language that computers actually communicate in. It is literally the 0’s and 1’s that determine the sequence of transistor switches that physically execute a program. All other programming languages are simply this language, translated into a form that is more easily understood by humans and for readability and troubleshooting purposes (Vahid and Lysecky, 2019, Ch 2.8).

    One step above Machine Language is Assembly, which is a basic textual representation of the instructions given in Machine Language, which needs to be converted by an Assembler before it can be run. Where Machine Language  uses specific bytes to signal what instruction to perform, followed by the exact address in memory to execute to and from, Assembly translates those bytes to instructions that are easier for humans to read and keep track of, and assigns the memory addresses to shorter variables that humans can more easily work with. When the program is complete and ready to run, it’s passed through and assembler program to convert the human-readable program into an executable written in Machine Language which can be run (Vahid and Lysecky, 2019, Ch. 2.9). Prior to higher-level program languages like Fortran in 1957, programs were most commonly written in Assembly, and even after, depending on the application, Assembly was still the go-to language when the task wasn’t well-suited to a high-level language. One such example of relatively modern usage of Assembly is Super Mario World, which was coded in 65c816 Assembly language, a variation of Assembly used to develop for the Super Nintendo (SFC Dev. Wiki, 2021).

    Finally, our first higher-level programming language covered is Python, which uses more complex and sophisticated instructions, each of which can represent a sequence of multiple instructions in Assembly/Machine Language. These kinds of programming languages make it far easier for humans to create complex and sophisticated programs by grouping together instructions to conduct more complex calculations and transformations of data into single commands, making the code far shorter and more readable than its equivalent in Assembly or Machine Language. Before the code can be read by a computer, it needs to be converted to Machine Language using a program called a Compiler, which translates the functions and variables of the high-level language into the expanded series of functions and memory addresses of Machine Language (Vahid and Lysecky, 2019, Ch. 2.10). Python is commonly used for data-processing due to it having many specialized instructions for conducting higher-level data-processing operations (Vahid and Lysecky, 2019, Ch. 2.11).

Ease of Use

 I found Scratch to be the easiest to use, due to its readability, simplicity, and the ability to easily drag and drop instructions to modify the program. However, once I am more familiar with Python and how to use its more complex array of functions, I suspect that I will find that far easier to use overall due to how it simplifies creating multi-step functions under one command. The most difficult to use, unsurprisingly, was Machine Language. Trying to remember what bytes represent which instructions and what memory addresses to store values to was far more cumbersome, even in the basic exercises in the textbook, than in the equivalent exercises for Assembly. Assembly was sort of a mid-point between Python and Machine Language for ease-of-use.

 Conclusion

 In conclusion, my first experience with coding using Scratch was overwhelmingly positive. I experienced several challenges in just this first attempt, but finding ways to overcome them has left me feeling this profound sense of accomplishment and an eagerness to tackle another. Reading about different programming languages in this week’s assigned chapters has taught me a lot about how programming has come to be what it is, and I am very eager to learn more about using Assembly, Python, and the other high-level programming languages. I intend to iterate on my efforts this week, and hopefully have a fully functional version of ‘Snake’ running in Scratch for people to play soon.


 

References

Scratch. (n.d.). https://scratch.mit.edu/.

SFC Development Wiki. (2021, January 27). ASM Tutorial Part 1. https://wiki.superfamicom.org/asm-tutorial-part-1

Vahid, F., & Lysecky, S. (2019). Computing technology for all. zyBooks

No comments:

Post a Comment

CPT 307: Newbie to Newbie Week 5

Demystifying Algorithmic Design and Data Structures for Beginners When starting your journey in programming, understanding how to effectivel...