summaryrefslogtreecommitdiff
path: root/projects/09
diff options
context:
space:
mode:
authorFrederick Yin <fkfd@fkfd.me>2022-08-16 11:54:23 +0800
committerFrederick Yin <fkfd@fkfd.me>2022-08-16 11:54:23 +0800
commit9542deeb483a00b6fabed7574720926ce97d7511 (patch)
tree0f2c1f72c03dd4693fd59df67544d2a4dddc5494 /projects/09
parent9c0cb1d1c32724fc95ac9548e4f8d873d3adaccc (diff)
Projects, 01-06 completed
Diffstat (limited to 'projects/09')
-rw-r--r--projects/09/Average/Main.jack27
-rw-r--r--projects/09/BitmapEditor/BitmapEditor.html200
-rw-r--r--projects/09/BitmapEditor/BitmapEditor.iml10
-rw-r--r--projects/09/Fraction/Fraction.jack65
-rw-r--r--projects/09/Fraction/Main.jack16
-rw-r--r--projects/09/HelloWorld/Main.jack14
-rw-r--r--projects/09/List/List.jack46
-rw-r--r--projects/09/List/Main.jack17
-rw-r--r--projects/09/Square/Main.jack15
-rw-r--r--projects/09/Square/Square.jack108
-rw-r--r--projects/09/Square/SquareGame.jack79
11 files changed, 597 insertions, 0 deletions
diff --git a/projects/09/Average/Main.jack b/projects/09/Average/Main.jack
new file mode 100644
index 0000000..a359602
--- /dev/null
+++ b/projects/09/Average/Main.jack
@@ -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/09/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;
+ }
+}
diff --git a/projects/09/BitmapEditor/BitmapEditor.html b/projects/09/BitmapEditor/BitmapEditor.html
new file mode 100644
index 0000000..fdb9e0b
--- /dev/null
+++ b/projects/09/BitmapEditor/BitmapEditor.html
@@ -0,0 +1,200 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
+ "http://www.w3.org/TR/html4/loose.dtd">
+<html>
+<head>
+ <title>Sokoban Bitmap Editor</title>
+ <script type="text/javascript">
+ var grid = new Array(0);
+
+ function Init() {
+ grid = InitGrid();
+ DisplayGrid();
+ }
+
+ function InitGrid() {
+ var _grid = new Array(16);
+ for (i=0; i<16; i++) {
+ _grid[i] = new Array(16);
+ for (j=0; j<16; j++) {
+ _grid[i][j]=false;
+ }
+ }
+ return _grid;
+ }
+
+ function RotateBitmapRight() {
+ var _grid = InitGrid();
+
+ for (i=0; i<16; i++) {
+ for (j=0; j<16; j++) {
+ _grid[j][15-i]=grid[i][j];
+ }
+ }
+
+ grid = _grid;
+ DisplayGrid();
+ }
+
+ function MirrorBitmap() {
+ var _grid = InitGrid();
+
+ for (i=0; i<16; i++) {
+ for (j=0; j<16; j++) {
+ _grid[i][15-j]=grid[i][j];
+ }
+ }
+
+ grid = _grid;
+ DisplayGrid();
+ }
+
+ function DisplayGrid() {
+ var str = "<table border=1 cellspacing=0>";
+ var i,j, backgroundColor;
+ for (i=-1; i<16; i++) {
+ str=str+"<tr>";
+ for (j=-1; j<16; j++) {
+ if (i == -1 && j != -1) {
+ str=str+"<td>" + (j+1) + "</td>";
+ } else if (i != -1 && j == -1) {
+ str=str+"<td>" + (i+1) + "</td>";
+ } else if (i ==-1 && j == -1) {
+ str=str+"<td/>";
+ } else {
+
+ if (grid[i][j] == true)
+ backgroundColor = "black";
+ else
+ backgroundColor = "white";
+
+ str=str+"<td onclick=\"OnCellClicked(this)\" id="; str=str+(i*16+j); str=str+" width=16 height=16 bgcolor=" + backgroundColor + "></td>";
+ }
+ }
+ str=str+"</tr>";
+ }
+ str=str+"</table>"
+
+ gridElement = document.getElementById('grid');
+ gridElement.innerHTML = str;
+ GenerateBitMap() ;
+ }
+
+ function OnCellClicked(cell) {
+ var i = cell.id / 16 |0;
+ var j = cell.id - i*16;
+ grid[i][j] = !grid[i][j];
+ if (grid[i][j])
+ cell.style.backgroundColor = "black";
+ else
+ cell.style.backgroundColor = "white";
+ GenerateBitMap();
+ }
+
+ function GenerateBitMap() {
+ var i, j;
+ var value;
+
+ var functionTypeSelect = document.getElementById('functionType');
+ methodType = functionTypeSelect.options[functionTypeSelect.selectedIndex].value;
+
+ generateCode = document.getElementById('generatedCode');
+ generateCode.value = methodType + " void " +
+ document.getElementById('functionName').value +
+ "(int location) {\n\tlet memAddress = 16384+location;\n";
+
+ for (i=0; i<16; i++) {
+ //get grid binary representation
+ binary = "";
+ for (j=0; j<16; j++) {
+ if (grid[i][j])
+ binary = "1" + binary;
+ else
+ binary = "0" + binary;
+ }
+
+ isNegative = false;
+ //if number is negative, get its one's complement
+ if (binary[0] == "1") {
+ isNegative = true;
+ oneComplement = "";
+ for (k=0; k<16; k++) {
+ if (binary[k] == "1")
+ oneComplement = oneComplement + "0";
+ else
+ oneComplement = oneComplement + "1";
+ }
+ binary = oneComplement;
+ }
+
+ //calculate one's complement decimal value
+ value = 0;
+ for (k=0; k<16; k++) {
+ value = value * 2;
+ if (binary[k] == "1")
+ value=value+1;
+ }
+
+ //two's complement value if it is a negative value
+ if (isNegative == true)
+ value = -(value + 1)
+
+ generateCode.value = generateCode.value + GenerateCodeLine(i, value);
+ }
+
+ generateCode.value = generateCode.value + "\treturn;\n}";
+ }
+
+ function GenerateCodeLine(row, value) {
+ str = "\tdo Memory.poke(memAddress+" + row*32 + ", " + value + ");\n";
+ return str;
+ }
+ </script>
+</head>
+<body onload="Init();">
+ <h4><i>IDC Herzliya / Efi Arazi School of Computer Science / Digital Systems Construction, Spring 2011 / Project 09 / Golan Parashi</i></h4>
+ <h1>Sokoban Bitmap Editor</h1>
+ <p>This javascript applicaiton is used to generate highly optimized jack code for drawing a 16x16 bitmap to the screen.</p>
+ <p>Using the mouse, click the desired cell to mark/unmark it. You may use 90 degrees rotation and vertical mirroring by<br>
+ clicking the appropriate buttons.</p>
+ <p>When you are finished drawing, you may select function type and enter function's name.</p>
+ <p>
+ <table>
+ <thead>
+ <tr>
+ <th align="left">Bitmap</th>
+ <th align="left"></th>
+ <th align="left">Generated Jack Code</th>
+ </tr>
+ </thead>
+ <tr>
+ <td><div id="grid"/></td>
+ <td>
+ <form action="javascript:GenerateBitMap();">
+ <table>
+ <tr><td align="left">Function Type:</td></tr>
+ <tr><td align="center">
+ <select id="functionType" onChange="GenerateBitMap()">
+ <option value="function" selected="selected">function</option>
+ <option value="method">method</option>
+ </select>
+ </td></tr>
+ <tr><td align="left">Function Name:</td></tr>
+ <tr><td align="left"><input type="text" value="draw" id="functionName" onkeyup="GenerateBitMap()"/></td></tr>
+ <tr><td></td></tr>
+ <tr><td align="center"><input type="button" value="Generate Code >>" onclick="GenerateBitMap()"/></td></tr>
+ </table>
+ </form>
+ </td>
+ <td><textarea id="generatedCode" cols="50" rows="20" readonly="read-only"></textarea></td>
+ </tr>
+ <tr>
+ <table>
+ <tr>
+ <td align="center"><input type="button" value="Rotate right" onclick="RotateBitmapRight()"/></td>
+ <td align="center"><input type="button" value="Vertical Mirror" onclick="MirrorBitmap()"/></td>
+ </tr>
+ </table>
+ </tr>
+ </table>
+</body>
+</html> \ No newline at end of file
diff --git a/projects/09/BitmapEditor/BitmapEditor.iml b/projects/09/BitmapEditor/BitmapEditor.iml
new file mode 100644
index 0000000..ef582b1
--- /dev/null
+++ b/projects/09/BitmapEditor/BitmapEditor.iml
@@ -0,0 +1,10 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<module type="JAVA_MODULE" version="4">
+ <component name="NewModuleRootManager" inherit-compiler-output="true">
+ <exclude-output />
+ <content url="file://$MODULE_DIR$" />
+ <orderEntry type="inheritedJdk" />
+ <orderEntry type="sourceFolder" forTests="false" />
+ </component>
+</module>
+
diff --git a/projects/09/Fraction/Fraction.jack b/projects/09/Fraction/Fraction.jack
new file mode 100644
index 0000000..c86f0a5
--- /dev/null
+++ b/projects/09/Fraction/Fraction.jack
@@ -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/09/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, 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;
+ }
+}
diff --git a/projects/09/Fraction/Main.jack b/projects/09/Fraction/Main.jack
new file mode 100644
index 0000000..43ddece
--- /dev/null
+++ b/projects/09/Fraction/Main.jack
@@ -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/09/Fraction/Main.jack
+
+// Computes 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;
+ }
+}
diff --git a/projects/09/HelloWorld/Main.jack b/projects/09/HelloWorld/Main.jack
new file mode 100644
index 0000000..446b21b
--- /dev/null
+++ b/projects/09/HelloWorld/Main.jack
@@ -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/09/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;
+ }
+}
diff --git a/projects/09/List/List.jack b/projects/09/List/List.jack
new file mode 100644
index 0000000..c62fe28
--- /dev/null
+++ b/projects/09/List/List.jack
@@ -0,0 +1,46 @@
+// 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/List/List.jack
+
+/** Represents a linked list of integers. */
+class List {
+ field int data; // a list consists of a data field,
+ field List next; // followed by a list
+
+ /* 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() {
+ var List current; // initializes current to the first item
+ let current = this; // of this list
+ 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();
+ }
+ // Uses an OS routine to recycle this object.
+ do Memory.deAlloc(this);
+ return;
+ }
+
+ // More list processing methods can come here.
+
+}
diff --git a/projects/09/List/Main.jack b/projects/09/List/Main.jack
new file mode 100644
index 0000000..824eb6f
--- /dev/null
+++ b/projects/09/List/Main.jack
@@ -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/09/List/Main.jack
+
+/** Demonstrates the use of the List abstraction. */
+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;
+ }
+}
diff --git a/projects/09/Square/Main.jack b/projects/09/Square/Main.jack
new file mode 100644
index 0000000..8311cc2
--- /dev/null
+++ b/projects/09/Square/Main.jack
@@ -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/09/Square/Main.jack
+
+/** Initializes a new Square Dance game and starts running it. */
+class Main {
+ function void main() {
+ var SquareGame game;
+ let game = SquareGame.new();
+ do game.run();
+ do game.dispose();
+ return;
+ }
+}
diff --git a/projects/09/Square/Square.jack b/projects/09/Square/Square.jack
new file mode 100644
index 0000000..38066e5
--- /dev/null
+++ b/projects/09/Square/Square.jack
@@ -0,0 +1,108 @@
+// 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/Square.jack
+
+/** Implements a graphical square. */
+class Square {
+
+ field int x, y; // screen location of the square's top-left corner
+ field int size; // length of this square, in pixels
+
+ /** Constructs 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 the square on the screen. */
+ method void draw() {
+ do Screen.setColor(true);
+ do Screen.drawRectangle(x, y, x + size, y + size);
+ return;
+ }
+
+ /** Erases the square from the screen. */
+ method void erase() {
+ do Screen.setColor(false);
+ do Screen.drawRectangle(x, y, x + size, y + size);
+ return;
+ }
+
+ /** Increments the square size by 2 pixels. */
+ 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. */
+ method void decSize() {
+ if (size > 2) {
+ do erase();
+ let size = size - 2;
+ do draw();
+ }
+ return;
+ }
+
+ /** Moves the square up by 2 pixels. */
+ method void moveUp() {
+ if (y > 1) {
+ do Screen.setColor(false);
+ do Screen.drawRectangle(x, (y + size) - 1, x + size, y + size);
+ let y = y - 2;
+ do Screen.setColor(true);
+ do Screen.drawRectangle(x, y, x + size, y + 1);
+ }
+ return;
+ }
+
+ /** Moves the square down by 2 pixels. */
+ 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. */
+ 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. */
+ 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;
+ }
+}
diff --git a/projects/09/Square/SquareGame.jack b/projects/09/Square/SquareGame.jack
new file mode 100644
index 0000000..02393e2
--- /dev/null
+++ b/projects/09/Square/SquareGame.jack
@@ -0,0 +1,79 @@
+// 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 Dance 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() {
+ // Creates a 30 by 30 pixels square and positions it at the top-left
+ // of the screen.
+ let square = Square.new(0, 0, 30);
+ let direction = 0; // initial state is no movement
+ 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;
+ }
+}
+
+
+