diff options
author | Frederick Yin <fkfd@fkfd.me> | 2022-08-16 11:54:23 +0800 |
---|---|---|
committer | Frederick Yin <fkfd@fkfd.me> | 2022-08-16 11:54:23 +0800 |
commit | 9542deeb483a00b6fabed7574720926ce97d7511 (patch) | |
tree | 0f2c1f72c03dd4693fd59df67544d2a4dddc5494 /projects/09 | |
parent | 9c0cb1d1c32724fc95ac9548e4f8d873d3adaccc (diff) |
Projects, 01-06 completed
Diffstat (limited to 'projects/09')
-rw-r--r-- | projects/09/Average/Main.jack | 27 | ||||
-rw-r--r-- | projects/09/BitmapEditor/BitmapEditor.html | 200 | ||||
-rw-r--r-- | projects/09/BitmapEditor/BitmapEditor.iml | 10 | ||||
-rw-r--r-- | projects/09/Fraction/Fraction.jack | 65 | ||||
-rw-r--r-- | projects/09/Fraction/Main.jack | 16 | ||||
-rw-r--r-- | projects/09/HelloWorld/Main.jack | 14 | ||||
-rw-r--r-- | projects/09/List/List.jack | 46 | ||||
-rw-r--r-- | projects/09/List/Main.jack | 17 | ||||
-rw-r--r-- | projects/09/Square/Main.jack | 15 | ||||
-rw-r--r-- | projects/09/Square/Square.jack | 108 | ||||
-rw-r--r-- | projects/09/Square/SquareGame.jack | 79 |
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;
+ }
+}
+
+
+
|