Add solutions for part 1

This commit is contained in:
2020-11-15 13:57:48 -05:00
parent e4f9fd2682
commit 742db6d102
479 changed files with 202980 additions and 13 deletions

View File

@@ -0,0 +1,178 @@
// 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/12/Screen.jack
/**
* A library of functions for displaying graphics on the screen.
* The Hack physical screen consists of 512 rows (indexed 0..511, top to bottom)
* of 256 pixels each (indexed 0..255, left to right). The top left pixel on
* the screen is indexed (0,0).
*/
class Screen {
static boolean color;
/** Initializes the Screen. */
function void init() {
let color = true;
return;
}
/** Erases the entire screen. */
function void clearScreen() {
var int i;
var Array a;
let i = 0;
let a = 16384;
while (i < 8192) {
let a[i] = 0;
let i = i + 1;
}
return;
}
function int modulo(int a, int b) {
var int d;
let d = a / b;
return a - (d * b);
}
/** Sets the current color, to be used for all subsequent drawXXX commands.
* Black is represented by true, white by false. */
function void setColor(boolean b) {
let color = b;
return;
}
/** Draws the (x,y) pixel, using the current color. */
function void drawPixel(int x, int y) {
var int address;
var int value;
var int i;
var int mask;
var int inverseMask;
var int pixel;
let pixel = Screen.modulo(x, 16);
let i = 0;
let mask = 1;
while (~(i = pixel)) {
let mask = mask + mask;
let i = i + 1;
}
let inverseMask = ~mask;
let address = 16384 + (32 * y) + (x / 16);
let value = Memory.peek(address);
if (color) {
let value = ((value & inverseMask) | ((-1) & mask)); // pixel gets set to 1
} else {
let value = (value & inverseMask); // pixel gets set to 0
}
do Memory.poke(address, value);
return;
}
/** Draws a line from pixel (x1,y1) to pixel (x2,y2), using the current color. */
function void drawLine(int x1, int y1, int x2, int y2) {
var int a, b, diff, dx, dy, xinc, yinc;
var boolean continue;
let a = 0;
let b = 0;
let diff = 0;
let dx = Math.abs(x2 - x1);
let dy = Math.abs(y2 - y1);
let continue = true;
if (x2 > x1) {
let xinc = 1; // going from left to right;
} else {
let xinc = -1; // going from right to left;
}
if (y2 > y1) {
let yinc = 1; // going from top to bottom
} else {
let yinc = -1; // going from bottom to top
}
// vertical line
if (dx = 0) {
while (~(y1 = y2)) {
do Screen.drawPixel(x1, y1);
let y1 = y1 + yinc;
}
return;
}
// horizontal line
if (dy = 0) {
while (~(x1 = x2)) {
do Screen.drawPixel(x1, y1);
let x1 = x1 + xinc;
}
return;
}
while (continue) {
do Screen.drawPixel(x1 + a, y1 + b);
if (diff < 0) {
let a = a + xinc;
let diff = diff + dy;
} else {
let b = b + yinc;
let diff = diff - dx;
}
if ((x1 + a) = x2) {
if ((y1 + b) = y2) {
let continue = false;
}
}
}
return;
}
/** Draws a filled rectangle whose top left corner is (x1, y1)
* and bottom right corner is (x2,y2), using the current color. */
function void drawRectangle(int x1, int y1, int x2, int y2) {
var int yinc;
if (y2 > y1) {
let yinc = 1;
} else {
let yinc = -1;
}
while (~(y1 = y2)) {
do Screen.drawLine(x1, y1, x2, y1);
let y1 = y1 + yinc;
}
return;
}
/** Draws a filled circle of radius r<=181 around (x,y), using the current color. */
function void drawCircle(int x, int y, int r) {
var int dy;
var int halfSegment;
let dy = -r;
if (r > 181) {
return;
}
while (dy < (r + 1)) {
let halfSegment = Math.sqrt((r * r) - (dy * dy));
do Screen.drawLine(x - halfSegment, y + dy, x + halfSegment, y + dy);
let dy = dy + 1;
}
return;
}
}