diff --git a/src/DrawIcosian.jack b/src/DrawIcosian.jack new file mode 100644 index 0000000..072d7f3 --- /dev/null +++ b/src/DrawIcosian.jack @@ -0,0 +1,146 @@ +class DrawIcosian { + field PointVector points; + + constructor DrawIcosian new() { + let points = PointVector.new(20); + + do points.set(0,65,31,1,7,4,8,1); // A + do points.set(1,192,31,0,2,9,24,1); // B + do points.set(2,231,152,3,1,11,30,13); // C + do points.set(3,128,227,2,4,13,16,21); // D + do points.set(4,25,152,0,5,3,2,13); // E + do points.set(5,60,141,4,14,6,9,12); // F + do points.set(6,80,103,5,7,16,8,9); // G + do points.set(7,86,60,6,8,0,11,6); // H + do points.set(8,128,68,7,9,17,16,5); // I + do points.set(9,171,60,1,8,10,20,6); // J + do points.set(10,177,103,9,11,18,23,9); // K + do points.set(11,197,141,10,12,2,23,12); // L + do points.set(12,158,160,11,13,19,20,15); // M + do points.set(13,128,191,12,14,3,16,16); // N + do points.set(14,98,160,13,5,15,12,15); // O + do points.set(15,109,144,14,16,19,14,12); // P + do points.set(16,98,109,15,17,6,13,10); // Q + do points.set(17,128,81,16,18,8,16,8); // R + do points.set(18,159,109,17,19,10,18,10); // S + do points.set(19,147,144,15,18,12,17,12); // T + return this; + } + + method void plotPoints(boolean dc) { + var int i; + var Array pos, charPos; + let i = 0; + while(i < 20) { + let pos = points.getPoint(i); + do Screen.drawCircle(pos[0],pos[1],3); + if(dc){ + let charPos = points.getCharPos(i); + do Output.moveCursor(charPos[1],charPos[0]); + do Output.printChar(65 + i); + } + let i = i + 1; + } + return; + } + + method void plotLine(int pointa, int pointb) { + var Array aa; + var Array bb; + let aa = points.getPoint(pointa); + let bb = points.getPoint(pointb); + do Screen.drawLine(aa[0],aa[1],bb[0],bb[1]); + return; + } + + + method void drawDashedLine(int pointa, int pointb) { + var Array aa, bb; + let aa = points.getPoint(pointa); + let bb = points.getPoint(pointb); + do drawMid(aa[0],aa[1],bb[0],bb[1]); + return; + } + + method void draw() { + var int j; + do plotPoints(true); + let j = 0; + while(j < 19) { + do drawDashedLine(j, j+1); + let j = j + 1; + } + do drawDashedLine(0,4); + do drawDashedLine(0,7); + do drawDashedLine(1,9); + do drawDashedLine(2,11); + do drawDashedLine(3,13); + do drawDashedLine(8,17); + do drawDashedLine(5,14); + do drawDashedLine(12,19); + do drawDashedLine(10,18); + do drawDashedLine(6,16); + do drawDashedLine(15,19); + return; + } + + method boolean isNeighbour(int p1, int p2) { + var Array check; + let check = points.getNeighbours(p1); + if(check[0] = p2) { + return true; + }else { + if(check[1] = p2) { + return true; + }else { + if(check[2] = p2) { + return true; + }else { + return false; + } + } + } + } + + method void drawMid(int x1, int y1, int x2, int y2) { + var int midx; + var int midy; + var int len; + let len = length(x1,y1,x2,y2); + if(len < 10){ + return; + } + + let midx = (x1 + x2)/2; + let midy = (y1 + y2)/2; + do Screen.drawPixel(midx ,midy); + do drawMid(x1,y1,midx,midy); + do drawMid(midx,midy,x2,y2); + return; + } + + method int length(int x1, int y1, int x2, int y2) { + var int dx, dy; + var int len; + if(x1 > x2) { + let dx = x1 - x2; + }else { + let dx = x2 - x1; + } + + if(y1 > y2) { + let dy = y1 - y2; + }else { + let dy = y2 - y1; + } + + let len = Math.sqrt((dx*dx)+(dy*dy)); + return len; + } + + method void dispose(){ + do points.dispose(); + do Memory.deAlloc(this); + return; + } +} \ No newline at end of file diff --git a/src/IcosianGame.jack b/src/IcosianGame.jack new file mode 100644 index 0000000..90fdd68 --- /dev/null +++ b/src/IcosianGame.jack @@ -0,0 +1,190 @@ +class IcosianGame { + field DrawIcosian icosian; + field int seed; + field boolean won,quit; + + constructor IcosianGame new(int sed) { + let icosian = DrawIcosian.new(); + let seed = sed; + let won = false; + return this; + } + + method void run() { + var int key; + var int last; + var boolean isn; + var boolean plk; + var int move; + var String path; + var boolean clk; + let quit = false; + let move = 15; + let path = drawInitial(seed); + let last = path.charAt(4)-65; + do drawPartition(); + do icosian.draw(); + while(~quit) { + do printInfo(move,path); + while(key = 0) { + let key = Keyboard.keyPressed(); + } + let plk = playKey(key); + if(plk){ + let clk = keyCheck(path,key,move); + let key = key - 65; + let isn = icosian.isNeighbour(last,key); + if(isn & ~clk){ + do icosian.plotLine(last,key); + let last = key; + let move = move - 1; + let path = path.appendChar(key+65); + }else { + if(~clk){ + do Output.moveCursor(19,32); + do Output.printString(" Not reachable point maybe! "); + } + } + }else { + let quit = true; + } + while(~(key = 0)){ + let key = Keyboard.keyPressed(); + } + } + return; + } + + method String drawInitial(int seed) { + var int s; + var String initial; + let initial = String.new(21); + let s = 0; + let initial = initial.appendChar(65+seed); + while(s < 4){ + do icosian.plotLine(seed+s,seed+s+1); + let initial = initial.appendChar(65+seed+s+1); + let s = s+1; + } + return initial; + } + + method boolean keyCheck(String pathe, char key, int move){ + var int len,k; + var boolean check; + let len = pathe.length(); + let k = 0; + do Output.moveCursor(19,32); + while((k < len) & ~check){ + if(pathe.charAt(k)=key){ + let check = true; + if(pathe.charAt(k)=pathe.charAt(0)){ + if(move=0){ + do Output.printString(" You Won, Yayyy ;) "); + let pathe = pathe.appendChar(pathe.charAt(0)); + do SplashScreen.winScreen(pathe); + let won = true; + let quit = true; + }else{ + do Output.printString(" You lost :( "); + do SplashScreen.lossScreen(); + let won =false; + let quit = true; + } + return check; + } + }else{ + let check = false; + } + let k = k+1; + } + if(check){ + do Output.printString(" Already visited the point :| "); + }else{ + do Output.printString(" Playing Nice, Yayyyy :) "); + } + return check; + } + + method void printInfo(int moves, String path){ + do Output.moveCursor(14,49); + do Output.printString(" "); + do Output.moveCursor(14,50); + do Output.printInt(moves); + do Output.moveCursor(17,32); + do Output.printString(path); + return; + } + + method void drawPartition() { + var int j; + let j = 0; + while( j < 64){ + do Output.moveCursor(0,j); + do Output.printChar(35); + do Output.moveCursor(22,j); + do Output.printChar(35); + let j = j + 1; + } + let j = 1; + while(j < 22) { + do Output.moveCursor(j,0); + do Output.printChar(35); + do Output.moveCursor(j,31); + do Output.printChar(35); + do Output.moveCursor(j,63); + do Output.printChar(35); + let j = j + 1; + } + do Output.moveCursor(2,32); + do Output.printString("THE _"); + do Output.moveCursor(3,32); + do Output.printString("| | (_)"); + do Output.moveCursor(4,32); + do Output.printString("| | __ __ __ _ ___ ____"); + do Output.moveCursor(5,32); + do Output.printString("| |/ _)/ \\ /__)| |(__ | _ \\"); + do Output.moveCursor(6,32); + do Output.printString("| ( (_| || |__ || |/ _ | | | |"); + do Output.moveCursor(7,32); + do Output.printString("|_|\\__)\\__/(__/ |_|\\___|_| |_|"); + do Output.moveCursor(10,37); + do Output.printString("Press key A-T to play!"); + do Output.moveCursor(11,34); + do Output.printString("Press any other key to quit!"); + do Output.moveCursor(13,32); + do Output.printString("+++++++++++++++++++++++++++++++"); + do Output.moveCursor(14,32); + do Output.printString(" Moves remaining:"); + do Output.moveCursor(15,32); + do Output.printString("+++++++++++++++++++++++++++++++"); + do Output.moveCursor(16,32); + do Output.printString(" Hamiltonian Cycle:-"); + do Output.moveCursor(18,32); + do Output.printString("+++++++++++++++++++++++++++++++"); + do Output.moveCursor(8,57); + do Output.printString("GAME"); + do Output.moveCursor(21,47); + do Output.printString("(c) 2020 Avinal"); + return; + } + + method boolean playKey(int key) { + if(key > 64){ + if(key < 85) { + return true; + }else { + return false; + } + }else { + return false; + } + } + + method void dispose(){ + do Screen.clearScreen(); + do icosian.dispose(); + do Memory.deAlloc(this); + return; + } +} \ No newline at end of file diff --git a/src/Main.jack b/src/Main.jack new file mode 100644 index 0000000..ba9aa48 --- /dev/null +++ b/src/Main.jack @@ -0,0 +1,25 @@ +class Main { + function void main() { + var IcosianGame game; + var int key,key2; + do SplashScreen.entryScreen(); + while(key=0){ + let key = Keyboard.keyPressed(); + } + let key2 = key; + do Screen.clearScreen(); + let key = key/14; + let key = key2 - (key*14); + let key2 = 0; + do SplashScreen.ruleScreen(); + while(key2=0){ + let key2 = Keyboard.keyPressed(); + } + do Screen.clearScreen(); + let game = IcosianGame.new(key); + do game.run(); + do game.dispose(); + return; + } + +} \ No newline at end of file diff --git a/src/PointVector.jack b/src/PointVector.jack new file mode 100644 index 0000000..1ebfc64 --- /dev/null +++ b/src/PointVector.jack @@ -0,0 +1,62 @@ +class PointVector { + field Array linearVector; + field Array neighbours; + field Array charPos; + field int height; + + constructor PointVector new(int hgt) { + var int i, elements; + let i = 0; + let height = hgt; + let elements = 2 * hgt; + let linearVector = Array.new(elements); + let charPos = Array.new(elements); + let elements = 3 * hgt; + let neighbours = Array.new(elements); + return this; + } + + method void set(int point, int x, int y, int n1, int n2, int n3, int c1, int c2) { + let linearVector[point * 2] = x; + let linearVector[point * 2 + 1] = y; + let charPos[point * 2] = c1; + let charPos[point * 2 + 1] = c2; + let neighbours[point * 3] = n1; + let neighbours[point * 3 + 1] = n2; + let neighbours[point * 3 + 2] = n3; + return; + } + + method Array getPoint(int point) { + var Array ret; + let ret = Array.new(2); + let ret[0] = linearVector[point * 2]; + let ret[1] = linearVector[point * 2 + 1]; + return ret; + } + + method Array getCharPos(int point) { + var Array ret; + let ret = Array.new(2); + let ret[0] = charPos[point * 2]; + let ret[1] = charPos[point * 2 + 1]; + return ret; + } + + method Array getNeighbours(int point) { + var Array ret; + let ret = Array.new(3); + let ret[0] = neighbours[point * 3]; + let ret[1] = neighbours[point * 3 + 1]; + let ret[2] = neighbours[point * 3 + 2]; + return ret; + } + + method void dispose(){ + do linearVector.dispose(); + do neighbours.dispose(); + do charPos.dispose(); + do Memory.deAlloc(this); + return; + } +} \ No newline at end of file diff --git a/src/SplashScreen.jack b/src/SplashScreen.jack new file mode 100644 index 0000000..ce6790a --- /dev/null +++ b/src/SplashScreen.jack @@ -0,0 +1,102 @@ +class SplashScreen { + function void entryScreen(){ + do Output.printString(" ___"); + do Output.println(); + do Output.printString(" | |_ _"); + do Output.println(); + do Output.printString(" | | |(/_"); + do Output.println(); + do Output.printString(" __. _____. _____. _____. __. __. __ __."); + do Output.println(); + do Output.printString(" | | / | / __ \\ / || | / \\ | \\ | |"); + do Output.println(); + do Output.printString(" | | | ,---'| | | | | (---`| | / ^ \\ | \\| |"); + do Output.println(); + do Output.printString(" | | | | | | | | \\ \\ | | / /_\\ \\ | . ` |"); + do Output.println(); + do Output.printString(" | | | `---.| `--' |.----) | | | / _____ \\ | |\\ |"); + do Output.println(); + do Output.printString(" |__| \\_____| \\______/ |______/ |__|/__/ \\__\\ |__| \\__|"); + do Output.moveCursor(9,45); + do Output.printString(" __"); + do Output.moveCursor(10,45); + do Output.printString(" /__ _.._ _ _ "); + do Output.moveCursor(11,45); + do Output.printString(" \\_|(_|| | |(/_"); + do Output.println(); + do Output.println(); + do Output.printString(" The Icosian Game v1.0"); + do Output.println(); + do Output.printString(" Peer-Graded Assignment for Nand2Tetris Part-II Project-09"); + do Output.println(); + do Output.printString(" (c) 2020 Avinal"); + do Output.println(); + do Output.println(); + do Output.printString(" Source Code is available at:-"); + do Output.println(); + do Output.printString(""); + do Output.println(); + do Output.printString(" Press any Key to Start ! "); + return; + } + + function void ruleScreen(){ + do Output.moveCursor(0,0); + do Output.println(); + do Output.printString("What is \" The Icosian Game\" ?"); + do Output.println(); + do Output.printString("The icosian game is a mathematical game invented in 1857 by William Rowan Hamilton. The game's objective is finding a Hamiltonian cycle along the edges of a dodecahedron such that every vertex is visited a single time, and the ending point is the same as the starting point."); + do Output.println(); + do Output.println(); + do Output.printString("How to play The Icosian Game ?"); + do Output.println(); + do Output.printString("The probable paths are shown by dotted lines between two points.Five consecutive initial points are given. Your goal is to coverall the points of the figure with three rules."); + do Output.println(); + do Output.printString("1. Starting from last point shown in the Hamiltonian Cycle box "); + do Output.printString("you can go to any adjacent uncovered point by pressing that key."); + do Output.println(); + do Output.printString("2. Your goal is to cover all points and reach to the initial point."); + do Output.println(); + do Output.printString("3. You cannot undo any path covered and can't use same points again."); + do Output.println(); + do Output.println(); + do Output.printString(" Press any Key to Start ! "); + return; + } + + function void lossScreen(){ + do Screen.clearScreen(); + do Output.moveCursor(10,17); + do Output.printString(" \\_/ _ | _ _ _|_"); + do Output.moveCursor(11,17); + do Output.printString(" | (_) |_| |_ (_) _> |_"); + do Sys.wait(5000); + return; + } + + function void winScreen(String path){ + var DrawIcosian icon; + var int i; + var char p,q; + do Screen.clearScreen(); + let icon = DrawIcosian.new(); + let i = 0; + while( i < 20){ + let p = path.charAt(i); + let q = path.charAt(i+1); + let p = p-65; + let q = q-65; + do icon.plotLine(p,q); + let i = i+1; + } + do Output.moveCursor(8,33); + do Output.printString(" \\_/ _ \\ / _ ._"); + do Output.moveCursor(9,33); + do Output.printString(" | (_) |_| \\/\\/ (_) | |"); + do Output.moveCursor(11,32); + do Output.printString("Here is your Hamiltonian Reward "); + do Sys.wait(10000); + do icon.dispose(); + return; + } +} \ No newline at end of file