project09 - template

This commit is contained in:
2025-11-08 21:44:08 -05:00
parent c4852a88b6
commit 35777dcdff
15 changed files with 997 additions and 0 deletions

27
09/Average/Main.jack Normal file
View File

@@ -0,0 +1,27 @@
// This file is part of www.nand2tetris.org
// and the book "The Elements of Computing Systems"
// by Nisan and Schocken, MIT Press.
// File name: projects/9/Average/Main.jack
// Inputs some numbers and computes their average
class Main {
function void main() {
var Array a;
var int length;
var int i, sum;
let length = Keyboard.readInt("How many numbers? ");
let a = Array.new(length); // constructs the array
let i = 0;
while (i < length) {
let a[i] = Keyboard.readInt("Enter a number: ");
let sum = sum + a[i];
let i = i + 1;
}
do Output.printString("The average is ");
do Output.printInt(sum / length);
return;
}
}

View File

@@ -0,0 +1,69 @@
// This file is part of www.nand2tetris.org
// and the book "The Elements of Computing Systems"
// by Nisan and Schocken, MIT Press.
// File name: projects/9/ComplexArrays/Main.jack
/**
* Performs several complex array processing tests.
* For each test, the expected result is printed, along with the
* actual result. In each test, the two results should be equal.
*/
class Main {
function void main() {
var Array a, b, c;
let a = Array.new(10);
let b = Array.new(5);
let c = Array.new(1);
let a[3] = 2;
let a[4] = 8;
let a[5] = 4;
let b[a[3]] = a[3] + 3; // b[2] = 5
let a[b[a[3]]] = a[a[5]] * b[((7 - a[3]) - Main.double(2)) + 1]; // a[5] = 8 * 5 = 40
let c[0] = null;
let c = c[0];
do Output.printString("Test 1: expected result: 5; actual result: ");
do Output.printInt(b[2]);
do Output.println();
do Output.printString("Test 2: expected result: 40; actual result: ");
do Output.printInt(a[5]);
do Output.println();
do Output.printString("Test 3: expected result: 0; actual result: ");
do Output.printInt(c);
do Output.println();
let c = null;
if (c = null) {
do Main.fill(a, 10);
let c = a[3];
let c[1] = 33;
let c = a[7];
let c[1] = 77;
let b = a[3];
let b[1] = b[1] + c[1]; // b[1] = 33 + 77 = 110;
}
do Output.printString("Test 4: expected result: 77; actual result: ");
do Output.printInt(c[1]);
do Output.println();
do Output.printString("Test 5: expected result: 110; actual result: ");
do Output.printInt(b[1]);
do Output.println();
return;
}
function int double(int a) {
return a * 2;
}
function void fill(Array a, int size) {
while (size > 0) {
let size = size - 1;
let a[size] = Array.new(3);
}
return;
}
}

78
09/ConvertToBin/Main.jack Normal file
View File

@@ -0,0 +1,78 @@
// This file is part of www.nand2tetris.org
// and the book "The Elements of Computing Systems"
// by Nisan and Schocken, MIT Press.
// File name: projects/9/ConvertToBin/Main.jack
/**
* Unpacks a 16-bit number into its binary representation:
* Takes the 16-bit number stored in RAM[8000] and stores its individual
* bits in RAM[8001]..RAM[8016] (each location will contain 0 or 1).
* Before the conversion, RAM[8001]..RAM[8016] are initialized to -1.
*
* The program should be tested as follows:
* 1) Load the compiled program into the supplied VM emulator
* 2) Put some value in RAM[8000]
* 3) Switch to "no animation"
* 4) Run the program (give it enough time to run)
* 5) Stop the program
* 6) Check that RAM[8001]..RAM[8016] contains the correct binary result, and
* that none of these memory locations contains -1.
*/
class Main {
/** Initializes RAM[8001]..RAM[8016] to -1,
* and converts the value in RAM[8000] to binary. */
function void main() {
var int value;
do Main.fillMemory(8001, 16, -1); // sets RAM[8001]..RAM[8016] to -1
let value = Memory.peek(8000); // reads a value from RAM[8000]
do Main.convert(value); // performs the conversion
return;
}
/** Converts the given decimal value to binary, and puts
* the resulting bits in RAM[8001]..RAM[8016]. */
function void convert(int value) {
var int mask, position;
var boolean loop;
let loop = true;
while (loop) {
let position = position + 1;
let mask = Main.nextMask(mask);
if (~(position > 16)) {
if (~((value & mask) = 0)) {
do Memory.poke(8000 + position, 1);
}
else {
do Memory.poke(8000 + position, 0);
}
}
else {
let loop = false;
}
}
return;
}
/** Returns the next mask (the mask that should follow the given mask). */
function int nextMask(int mask) {
if (mask = 0) {
return 1;
}
else {
return mask * 2;
}
}
/** Fills 'length' consecutive memory locations with 'value',
* starting at 'startAddress'. */
function void fillMemory(int startAddress, int length, int value) {
while (length > 0) {
do Memory.poke(startAddress, value);
let length = length - 1;
let startAddress = startAddress + 1;
}
return;
}
}

65
09/Fraction/Fraction.jack Normal file
View File

@@ -0,0 +1,65 @@
// This file is part of www.nand2tetris.org
// and the book "The Elements of Computing Systems"
// by Nisan and Schocken, MIT Press.
// File name: projects/9/Fraction/Fraction.jack
/** Represents the Fraction type and related operations. */
class Fraction {
field int numerator, denominator; // field = property = member variable.
/** Constructs a (reduced) fraction from the given numerator and denominator. */
constructor Fraction new(int x, int y) {
let numerator = x;
let denominator = y;
do reduce(); // reduces the fraction
return this; // a constructor is expected to return a reference to the new object
}
// Reduces this fraction.
method void reduce() {
var int g;
let g = Fraction.gcd(numerator, denominator);
if (g > 1) {
let numerator = numerator / g;
let denominator = denominator / g;
}
return;
}
/** Accessors. */
method int getNumerator() { return numerator; }
method int getDenominator() { return denominator; }
/** Returns the sum of this fraction and the other one. */
method Fraction plus(Fraction other) {
var int sum;
let sum = (numerator * other.getDenominator()) + (other.getNumerator() * denominator);
return Fraction.new(sum, denominator * other.getDenominator());
}
// More fraction-related methods (minus, times, div, invert, etc.) can be added here.
/** Disposes this fraction. */
method void dispose() {
do Memory.deAlloc(this); // uses an OS routine to recycle the memory held by the object
return;
}
/** Prints this fraction in the format x/y. */
method void print() {
do Output.printInt(numerator);
do Output.printString("/");
do Output.printInt(denominator);
return;
}
// Computes the greatest common divisor of the given integers.
function int gcd(int a, int b) {
var int r;
while (~(b = 0)) { // applies Euclid's algorithm
let r = a - (b * (a / b)); // r = remainder of the integer division a/b
let a = b; let b = r;
}
return a;
}
}

16
09/Fraction/Main.jack Normal file
View File

@@ -0,0 +1,16 @@
// This file is part of www.nand2tetris.org
// and the book "The Elements of Computing Systems"
// by Nisan and Schocken, MIT Press.
// File name: projects/9/Fraction/Main.jack
// Computes and prints the sum of 2/3 and 1/5.
class Main {
function void main() {
var Fraction a, b, c;
let a = Fraction.new(2,3);
let b = Fraction.new(1,5);
let c = a.plus(b); // Computes c = a + b
do c.print(); // Prints "13/15"
return;
}
}

14
09/HelloWorld/Main.jack Normal file
View File

@@ -0,0 +1,14 @@
// This file is part of www.nand2tetris.org
// and the book "The Elements of Computing Systems"
// by Nisan and Schocken, MIT Press.
// File name: projects/9/HelloWorld/Main.jack
/** Hello World program. */
class Main {
function void main() {
/* Prints some text using the standard library. */
do Output.printString("Hello world!");
do Output.println(); // New line
return;
}
}

48
09/List/List.jack Normal file
View File

@@ -0,0 +1,48 @@
// This file is part of www.nand2tetris.org
// and the book "The Elements of Computing Systems"
// by Nisan and Schocken, MIT Press.
// File name: projects/9/List/List.jack
/** Represents a linked list of integers. */
class List {
field int data; // an int value,
field List next; // followed by a list of int values
/* Creates a List. */
constructor List new(int car, List cdr) {
let data = car; // the identifiers car and cdr are used in
let next = cdr; // memory of the Lisp programming language
return this;
}
/** Accessors. */
method int getData() { return data; }
method int getNext() { return next; }
/** Prints this list. */
method void print() {
// Sets current to the first element of this list
var List current;
let current = this;
while (~(current = null)) {
do Output.printInt(current.getData());
do Output.printChar(32); // prints a space
let current = current.getNext();
}
return;
}
/** Disposes this List. */
// By recursively disposing its tail.
method void dispose() {
if (~(next = null)) {
do next.dispose();
}
// Calls an OS routine to free the memory of this object.
do Memory.deAlloc(this);
return;
}
// More list processing methods can come here.
}

17
09/List/Main.jack Normal file
View File

@@ -0,0 +1,17 @@
// This file is part of www.nand2tetris.org
// and the book "The Elements of Computing Systems"
// by Nisan and Schocken, MIT Press.
// File name: projects/9/List/Main.jack
/** An example of creating and using List objects. */
class Main {
function void main() {
// Creates and uses the list (2,3,5).
var List v;
let v = List.new(5,null);
let v = List.new(2,List.new(3,v));
do v.print(); // prints 2 3 5
do v.dispose(); // disposes the list
return;
}
}

202
09/Pong/Ball.jack Normal file
View File

@@ -0,0 +1,202 @@
// This file is part of www.nand2tetris.org
// and the book "The Elements of Computing Systems"
// by Nisan and Schocken, MIT Press.
// File name: projects/9/Pong/Ball.jack
/**
* A graphical ball in a Pong game. Characterized by a screen location and
* distance of last destination. Has methods for drawing, erasing and moving
* on the screen. The ball is displayed as a filled, 6-by-6 pixles rectangle.
*/
class Ball {
field int x, y; // the ball's screen location (in pixels)
field int lengthx, lengthy; // distance of last destination (in pixels)
field int d, straightD, diagonalD; // used for straight line movement computation
field boolean invert, positivex, positivey; // (same)
field int leftWall, rightWall, topWall, bottomWall; // wall locations
field int wall; // last wall that the ball was bounced off of
/** Constructs a new ball with the given initial location and wall locations. */
constructor Ball new(int Ax, int Ay,
int AleftWall, int ArightWall, int AtopWall, int AbottomWall) {
let x = Ax;
let y = Ay;
let leftWall = AleftWall;
let rightWall = ArightWall - 6; // -6 for ball size
let topWall = AtopWall;
let bottomWall = AbottomWall - 6; // -6 for ball size
let wall = 0;
do show();
return this;
}
/** Deallocates the Ball's memory. */
method void dispose() {
do Memory.deAlloc(this);
return;
}
/** Shows the ball. */
method void show() {
do Screen.setColor(true);
do draw();
return;
}
/** Hides the ball. */
method void hide() {
do Screen.setColor(false);
do draw();
return;
}
/** Draws the ball. */
method void draw() {
do Screen.drawRectangle(x, y, x + 5, y + 5);
return;
}
/** Returns the ball's left edge. */
method int getLeft() {
return x;
}
/** Returns the ball's right edge. */
method int getRight() {
return x + 5;
}
/** Computes and sets the ball's destination. */
method void setDestination(int destx, int desty) {
var int dx, dy, temp;
let lengthx = destx - x;
let lengthy = desty - y;
let dx = Math.abs(lengthx);
let dy = Math.abs(lengthy);
let invert = (dx < dy);
if (invert) {
let temp = dx; // swap dx, dy
let dx = dy;
let dy = temp;
let positivex = (y < desty);
let positivey = (x < destx);
}
else {
let positivex = (x < destx);
let positivey = (y < desty);
}
let d = (2 * dy) - dx;
let straightD = 2 * dy;
let diagonalD = 2 * (dy - dx);
return;
}
/**
* Moves the ball one step towards its destination.
* If the ball has reached a wall, returns 0.
* Else, returns a value according to the wall:
* 1 (left wall), 2 (right wall), 3 (top wall), 4 (bottom wall).
*/
method int move() {
do hide();
if (d < 0) { let d = d + straightD; }
else {
let d = d + diagonalD;
if (positivey) {
if (invert) { let x = x + 4; }
else { let y = y + 4; }
}
else {
if (invert) { let x = x - 4; }
else { let y = y - 4; }
}
}
if (positivex) {
if (invert) { let y = y + 4; }
else { let x = x + 4; }
}
else {
if (invert) { let y = y - 4; }
else { let x = x - 4; }
}
if (~(x > leftWall)) {
let wall = 1;
let x = leftWall;
}
if (~(x < rightWall)) {
let wall = 2;
let x = rightWall;
}
if (~(y > topWall)) {
let wall = 3;
let y = topWall;
}
if (~(y < bottomWall)) {
let wall = 4;
let y = bottomWall;
}
do show();
return wall;
}
/**
* Bounces off the current wall: sets the new destination
* of the ball according to the ball's angle and the given
* bouncing direction (-1/0/1=left/center/right or up/center/down).
*/
method void bounce(int bouncingDirection) {
var int newx, newy, divLengthx, divLengthy, factor;
// Since results are too big, divides by 10
let divLengthx = lengthx / 10;
let divLengthy = lengthy / 10;
if (bouncingDirection = 0) { let factor = 10; }
else {
if (((~(lengthx < 0)) & (bouncingDirection = 1)) | ((lengthx < 0) & (bouncingDirection = (-1)))) {
let factor = 20; // bounce direction is in ball direction
}
else { let factor = 5; } // bounce direction is against ball direction
}
if (wall = 1) {
let newx = 506;
let newy = (divLengthy * (-50)) / divLengthx;
let newy = y + (newy * factor);
}
else {
if (wall = 2) {
let newx = 0;
let newy = (divLengthy * 50) / divLengthx;
let newy = y + (newy * factor);
}
else {
if (wall = 3) {
let newy = 250;
let newx = (divLengthx * (-25)) / divLengthy;
let newx = x + (newx * factor);
}
else { // assumes wall = 4
let newy = 0;
let newx = (divLengthx * 25) / divLengthy;
let newx = x + (newx * factor);
}
}
}
do setDestination(newx, newy);
return;
}
}

103
09/Pong/Bat.jack Normal file
View File

@@ -0,0 +1,103 @@
// This file is part of www.nand2tetris.org
// and the book "The Elements of Computing Systems"
// by Nisan and Schocken, MIT Press.
// File name: projects/9/Pong/Bat.jack
/**
* A graphical bat in a Pong game.
* Displayed as a filled horizontal rectangle that has a screen location,
* a width and a height.
* Has methods for drawing, erasing, moving left and right, and changing
* its width (to make the hitting action more challenging).
* This class should have been called "Paddle", following the
* standard Pong terminology. Unaware of this terminology,
* we called it "bat", and the name stuck.
*/
class Bat {
field int x, y; // the bat's screen location
field int width, height; // the bat's width and height
field int direction; // direction of the bat's movement
// (1 = left, 2 = right)
/** Constructs a new bat with the given location and width. */
constructor Bat new(int Ax, int Ay, int Awidth, int Aheight) {
let x = Ax;
let y = Ay;
let width = Awidth;
let height = Aheight;
let direction = 2;
do show();
return this;
}
/** Deallocates the object's memory. */
method void dispose() {
do Memory.deAlloc(this);
return;
}
/** Shows the bat. */
method void show() {
do Screen.setColor(true);
do draw();
return;
}
/** Hides the bat. */
method void hide() {
do Screen.setColor(false);
do draw();
return;
}
/** Draws the bat. */
method void draw() {
do Screen.drawRectangle(x, y, x + width, y + height);
return;
}
/** Sets the bat's direction (0=stop, 1=left, 2=right). */
method void setDirection(int Adirection) {
let direction = Adirection;
return;
}
/** Returns the bat's left edge. */
method int getLeft() {
return x;
}
/** Returns the bat's right edge. */
method int getRight() {
return x + width;
}
/** Sets the bat's width. */
method void setWidth(int Awidth) {
do hide();
let width = Awidth;
do show();
return;
}
/** Moves the bat one step in the bat's direction. */
method void move() {
if (direction = 1) {
let x = x - 4;
if (x < 0) { let x = 0; }
do Screen.setColor(false);
do Screen.drawRectangle((x + width) + 1, y, (x + width) + 4, y + height);
do Screen.setColor(true);
do Screen.drawRectangle(x, y, x + 3, y + height);
}
else {
let x = x + 4;
if ((x + width) > 511) { let x = 511 - width; }
do Screen.setColor(false);
do Screen.drawRectangle(x - 4, y, x - 1, y + height);
do Screen.setColor(true);
do Screen.drawRectangle((x + width) - 3, y, x + width, y + height);
}
return;
}
}

18
09/Pong/Main.jack Normal file
View File

@@ -0,0 +1,18 @@
// This file is part of www.nand2tetris.org
// and the book "The Elements of Computing Systems"
// by Nisan and Schocken, MIT Press.
// File name: projects/9/Pong/Main.jack
/**
* Main class of the Pong game.
*/
class Main {
/** Initializes a Pong game and starts running it. */
function void main() {
var PongGame game;
do PongGame.newInstance();
let game = PongGame.getInstance();
do game.run();
do game.dispose();
return;
}
}

136
09/Pong/PongGame.jack Normal file
View File

@@ -0,0 +1,136 @@
// This file is part of www.nand2tetris.org
// and the book "The Elements of Computing Systems"
// by Nisan and Schocken, MIT Press.
// File name: projects/9/Pong/PongGame.jack
/**
* Represents a Pong game.
*/
class PongGame {
static PongGame instance; // A Pong game
field Bat bat; // bat
field Ball ball; // ball
field int wall; // current wall that the ball is bouncing off of
field boolean exit; // true when the game is over
field int score; // current score
field int lastWall; // last wall that the ball bounced off of
// The current width of the bat
field int batWidth;
/** Constructs a new Pong game. */
constructor PongGame new() {
do Screen.clearScreen();
let batWidth = 50; // initial bat size
let bat = Bat.new(230, 229, batWidth, 7);
let ball = Ball.new(253, 222, 0, 511, 0, 229);
do ball.setDestination(400,0);
do Screen.drawRectangle(0, 238, 511, 240);
do Output.moveCursor(22,0);
do Output.printString("Score: 0");
let exit = false;
let score = 0;
let wall = 0;
let lastWall = 0;
return this;
}
/** Deallocates the object's memory. */
method void dispose() {
do bat.dispose();
do ball.dispose();
do Memory.deAlloc(this);
return;
}
/** Creates an instance of a Pong game. */
function void newInstance() {
let instance = PongGame.new();
return;
}
/** Returns this Pong game. */
function PongGame getInstance() {
return instance;
}
/** Starts the game, and handles inputs from the user that control
* the bat's movement direction. */
method void run() {
var char key;
while (~exit) {
// waits for a key to be pressed.
while ((key = 0) & (~exit)) {
let key = Keyboard.keyPressed();
do bat.move();
do moveBall();
do Sys.wait(50);
}
if (key = 130) { do bat.setDirection(1); }
else {
if (key = 132) { do bat.setDirection(2); }
else {
if (key = 140) { let exit = true; }
}
}
// Waits for the key to be released.
while ((~(key = 0)) & (~exit)) {
let key = Keyboard.keyPressed();
do bat.move();
do moveBall();
do Sys.wait(50);
}
}
if (exit) {
do Output.moveCursor(10,27);
do Output.printString("Game Over");
}
return;
}
/**
* Handles ball movement, including bouncing.
* If the ball bounces off a wall, finds its new direction.
* If the ball bounces off the bat, increases the score by one
* and shrinks the bat's size, to make the game more challenging.
*/
method void moveBall() {
var int bouncingDirection, batLeft, batRight, ballLeft, ballRight;
let wall = ball.move();
if ((wall > 0) & (~(wall = lastWall))) {
let lastWall = wall;
let bouncingDirection = 0;
let batLeft = bat.getLeft();
let batRight = bat.getRight();
let ballLeft = ball.getLeft();
let ballRight = ball.getRight();
if (wall = 4) {
let exit = (batLeft > ballRight) | (batRight < ballLeft);
if (~exit) {
if (ballRight < (batLeft + 10)) { let bouncingDirection = -1; }
else {
if (ballLeft > (batRight - 10)) { let bouncingDirection = 1; }
}
let batWidth = batWidth - 2;
do bat.setWidth(batWidth);
let score = score + 1;
do Output.moveCursor(22,7);
do Output.printInt(score);
}
}
do ball.bounce(bouncingDirection);
}
return;
}
}

15
09/Square/Main.jack Normal file
View File

@@ -0,0 +1,15 @@
// This file is part of www.nand2tetris.org
// and the book "The Elements of Computing Systems"
// by Nisan and Schocken, MIT Press.
// File name: projects/9/Square/Main.jack
/** Initializes a new Square game and starts running it. */
class Main {
function void main() {
var SquareGame game;
let game = SquareGame.new();
do game.run();
do game.dispose();
return;
}
}

113
09/Square/Square.jack Normal file
View File

@@ -0,0 +1,113 @@
// This file is part of www.nand2tetris.org
// and the book "The Elements of Computing Systems"
// by Nisan and Schocken, MIT Press.
// File name: projects/9/Square/Square.jack
/** Implements a graphical square.
The square has top-left x and y coordinates, and a size. */
class Square {
field int x, y; // screen location of the top-left corner of this square
field int size; // length of this square, in pixels
/** Constructs and draws a new square with a given location and size. */
constructor Square new(int ax, int ay, int asize) {
let x = ax;
let y = ay;
let size = asize;
do draw();
return this;
}
/** Disposes this square. */
method void dispose() {
do Memory.deAlloc(this);
return;
}
/** Draws this square in its current (x,y) location */
method void draw() {
// Draws the square using the color black
do Screen.setColor(true);
do Screen.drawRectangle(x, y, x + size, y + size);
return;
}
/** Erases this square. */
method void erase() {
// Draws the square using the color white (background color)
do Screen.setColor(false);
do Screen.drawRectangle(x, y, x + size, y + size);
return;
}
/** Increments the square size by 2 pixels (if possible). */
method void incSize() {
if (((y + size) < 254) & ((x + size) < 510)) {
do erase();
let size = size + 2;
do draw();
}
return;
}
/** Decrements the square size by 2 pixels (if possible). */
method void decSize() {
if (size > 2) {
do erase();
let size = size - 2;
do draw();
}
return;
}
/** Moves this square up by 2 pixels (if possible). */
method void moveUp() {
if (y > 1) {
// Erases the bottom two rows of this square in its current location
do Screen.setColor(false);
do Screen.drawRectangle(x, (y + size) - 1, x + size, y + size);
let y = y - 2;
// Draws the top two rows of this square in its new location
do Screen.setColor(true);
do Screen.drawRectangle(x, y, x + size, y + 1);
}
return;
}
/** Moves the square down by 2 pixels (if possible). */
method void moveDown() {
if ((y + size) < 254) {
do Screen.setColor(false);
do Screen.drawRectangle(x, y, x + size, y + 1);
let y = y + 2;
do Screen.setColor(true);
do Screen.drawRectangle(x, (y + size) - 1, x + size, y + size);
}
return;
}
/** Moves the square left by 2 pixels (if possible). */
method void moveLeft() {
if (x > 1) {
do Screen.setColor(false);
do Screen.drawRectangle((x + size) - 1, y, x + size, y + size);
let x = x - 2;
do Screen.setColor(true);
do Screen.drawRectangle(x, y, x + 1, y + size);
}
return;
}
/** Moves the square right by 2 pixels (if possible). */
method void moveRight() {
if ((x + size) < 510) {
do Screen.setColor(false);
do Screen.drawRectangle(x, y, x + 1, y + size);
let x = x + 2;
do Screen.setColor(true);
do Screen.drawRectangle((x + size) - 1, y, x + size, y + size);
}
return;
}
}

76
09/Square/SquareGame.jack Normal file
View File

@@ -0,0 +1,76 @@
// This file is part of www.nand2tetris.org
// and the book "The Elements of Computing Systems"
// by Nisan and Schocken, MIT Press.
// File name: projects/09/Square/SquareGame.jack
/**
* Implements the Square game.
* This simple game allows the user to move a black square around
* the screen, and change the square's size during the movement.
* When the game starts, a square of 30 by 30 pixels is shown at the
* top-left corner of the screen. The user controls the square as follows.
* The 4 arrow keys are used to move the square up, down, left, and right.
* The 'z' and 'x' keys are used, respectively, to decrement and increment
* the square's size. The 'q' key is used to quit the game.
*/
class SquareGame {
field Square square; // the square of this game
field int direction; // the square's current direction:
// 0=none, 1=up, 2=down, 3=left, 4=right
/** Constructs a new square game. */
constructor SquareGame new() {
// The initial square is located in (0,0), has size 30, and is not moving.
let square = Square.new(0, 0, 30);
let direction = 0;
return this;
}
/** Disposes this game. */
method void dispose() {
do square.dispose();
do Memory.deAlloc(this);
return;
}
/** Moves the square in the current direction. */
method void moveSquare() {
if (direction = 1) { do square.moveUp(); }
if (direction = 2) { do square.moveDown(); }
if (direction = 3) { do square.moveLeft(); }
if (direction = 4) { do square.moveRight(); }
do Sys.wait(5); // delays the next movement
return;
}
/** Runs the game: handles the user's inputs and moves the square accordingly */
method void run() {
var char key; // the key currently pressed by the user
var boolean exit;
let exit = false;
while (~exit) {
// waits for a key to be pressed
while (key = 0) {
let key = Keyboard.keyPressed();
do moveSquare();
}
if (key = 81) { let exit = true; } // q key
if (key = 90) { do square.decSize(); } // z key
if (key = 88) { do square.incSize(); } // x key
if (key = 131) { let direction = 1; } // up arrow
if (key = 133) { let direction = 2; } // down arrow
if (key = 130) { let direction = 3; } // left arrow
if (key = 132) { let direction = 4; } // right arrow
// waits for the key to be released
while (~(key = 0)) {
let key = Keyboard.keyPressed();
do moveSquare();
}
} // while
return;
}
}