├── .gitignore ├── .gitmodules ├── README.md ├── hw0 └── src │ ├── BreakContinue.java │ ├── DrawATriganle.java │ ├── DrawTriganle.java │ └── GetMax.java ├── lab1 ├── CheckLabConfig.java ├── Collatz.java ├── GetEnvironmentVariables.java ├── HelloNumbers.java └── HelloWorld.java ├── lab2 ├── Arithmetic │ ├── Arithmetic.java │ └── ArithmeticTest.java ├── DebugExercise │ ├── DebugExercise1.java │ └── DebugExercise2.java ├── IntList │ ├── AddConstantTest.java │ ├── IntList.java │ ├── IntListExercises.java │ ├── Primes.java │ ├── SetToZeroIfMaxFELTest.java │ └── SquarePrimesTest.java └── pom.xml ├── lab2setup ├── Dog │ ├── Dog.java │ └── DogTest.java └── pom.xml ├── lab3 ├── pom.xml ├── randomizedtest │ ├── AListNoResizing.java │ ├── BuggyAList.java │ └── TestBuggyAList.java └── timingtest │ ├── AList.java │ ├── SLList.java │ ├── StopwatchDemo.java │ ├── TimeAList.java │ └── TimeSLList.java ├── lab4 ├── flik │ ├── Flik.java │ └── HorribleSteve.java └── pom.xml ├── lab5 ├── magic_word.txt └── self_reflection.txt ├── lab6 ├── Makefile ├── capers │ ├── CapersRepository.java │ ├── Dog.java │ ├── Main.java │ ├── Makefile │ └── Utils.java ├── pom.xml └── testing │ ├── Makefile │ ├── our │ ├── test01-basic-story.in │ ├── test02-two-part-story.in │ ├── test03-basic-dog.in │ ├── test04-dog-birthday.in │ ├── test05-two-dogs.in │ ├── test06-two-birthdays.in │ └── test07-one-dog-two-birthdays.in │ ├── runner.py │ └── tester.py ├── lab7 ├── bstmap │ ├── BSTMap.java │ ├── InsertInOrderSpeedTest.java │ ├── InsertRandomSpeedTest.java │ ├── Map61B.java │ ├── StringUtils.java │ ├── TestBSTMap.java │ ├── TestBSTMapExtra.java │ └── ULLMap.java ├── pom.xml └── speedTestResults.txt ├── lab8 ├── hashmap │ ├── Map61B.java │ ├── MyHashMap.java │ ├── MyHashMapALBuckets.java │ ├── MyHashMapHSBuckets.java │ ├── MyHashMapLLBuckets.java │ ├── MyHashMapPQBuckets.java │ ├── MyHashMapTSBuckets.java │ ├── TestMyHashMap.java │ ├── TestMyHashMapBuckets.java │ ├── TestMyHashMapExtra.java │ └── ULLMap.java ├── pom.xml ├── speed │ ├── BucketsSpeedTest.java │ ├── InsertInOrderSpeedTest.java │ ├── InsertRandomSpeedTest.java │ └── StringUtils.java └── speedTestResults.txt ├── proj0 ├── game2048 │ ├── Board.java │ ├── BoardLogger.java │ ├── BoardWidget.java │ ├── GUI.java │ ├── GUISource.java │ ├── Game.java │ ├── InputSource.java │ ├── Main.java │ ├── Model.java │ ├── Side.java │ ├── TestAtLeastOneMoveExists.java │ ├── TestEmptySpace.java │ ├── TestMaxTileExists.java │ ├── TestModel.java │ ├── TestUpOnly.java │ ├── TestUtils.java │ └── Tile.java └── javalib │ ├── hamcrest-core-1.3.jar │ ├── junit-4.12.jar │ └── ucb.jar ├── proj1 ├── deque │ ├── ArrayDeque.java │ ├── ArrayDequeTest.java │ ├── Deque.java │ ├── LinkedListDeque.java │ ├── LinkedListDequeTest.java │ ├── MaxArrayDeque.java │ └── MaxArrayDequeTest.java ├── gh2 │ ├── GuitarHeroLite.java │ ├── GuitarPlayer.java │ ├── GuitarString.java │ ├── TTFAF.java │ ├── TestGuitarString.java │ ├── beatles-hey_jude.mid │ └── beatles-yesterday.mid └── pom.xml ├── proj1ec ├── pom.xml ├── student │ ├── Deque.java │ └── StudentArrayDeque.java └── tester │ ├── ArrayDequeSolution.java │ ├── AssertEqualsStringDemo.java │ ├── StudentArrayDequeLauncher.java │ └── TestArrayDequeEC.java ├── proj2 ├── Makefile ├── gitlet-design.md ├── gitlet │ ├── Blob.java │ ├── Commit.java │ ├── DumpObj.java │ ├── Dumpable.java │ ├── GitletException.java │ ├── Main.java │ ├── Makefile │ ├── MyUtils.java │ ├── Pointer.java │ ├── Remote.java │ ├── Repository.java │ └── Utils.java ├── pom.xml └── testing │ ├── Makefile │ ├── runner.py │ ├── samples │ ├── definitions.inc │ ├── test01-init.in │ ├── test02-basic-checkout.in │ ├── test03-basic-log.in │ └── test04-prev-checkout.in │ ├── src │ ├── a.txt │ ├── b.txt │ ├── c.txt │ ├── conflict1.txt │ ├── conflict2.txt │ ├── d.txt │ ├── e.txt │ ├── f.txt │ ├── g.txt │ ├── nota.txt │ ├── notb.txt │ ├── notf.txt │ ├── notwug.txt │ ├── wug.txt │ ├── wug2.txt │ └── wug3.txt │ ├── staff-runner.py │ ├── student_tests │ └── definitions.inc │ └── tester.py └── proj3 ├── .save └── saveEngine.txt ├── byow ├── Core │ ├── BYOWException.java │ ├── Engine.java │ ├── Main.java │ ├── Menu.java │ ├── MyUtils.java │ ├── RandomUtils.java │ ├── Room.java │ └── WorldGenerator.java ├── InputDemo │ ├── DemoInputSource.java │ ├── InputSource.java │ ├── KeyboardInputSource.java │ ├── RandomInputSource.java │ └── StringInputDevice.java ├── Networking │ ├── BYOWClient.java │ └── BYOWServer.java ├── TileEngine │ ├── TERenderer.java │ ├── TETile.java │ ├── TETileWrapper.java │ └── Tileset.java ├── lab12 │ ├── BoringWorldDemo.java │ ├── HexWorld.java │ ├── Hexagon.java │ ├── RandomWorldDemo.java │ └── project3prep.md └── lab13 │ ├── MemoryGame.java │ └── TestStdDraw.java └── pom.xml /.gitmodules: -------------------------------------------------------------------------------- 1 | [submodule "library-sp21"] 2 | path = library-sp21 3 | url = https://github.com/Berkeley-CS61B/library-sp21 4 | -------------------------------------------------------------------------------- /hw0/src/BreakContinue.java: -------------------------------------------------------------------------------- 1 | public class BreakContinue { 2 | public static void windowPosSum(int[] a, int n) { 3 | /** your code here */ 4 | for (int i = 0; i < a.length; i++){ 5 | if (a[i] < 0){ 6 | continue; 7 | } 8 | int sum = 0; 9 | // note: use "j" as index and count below loop 10 | for (int j = i; j < i + n; j++){ 11 | if (j == a.length){ 12 | break; 13 | } 14 | sum += a[j]; 15 | } 16 | a[i] = sum; 17 | } 18 | } 19 | 20 | public static void main(String[] args) { 21 | int[] a = {1, 2, -3, 4, 5, 4}; 22 | int n = 3; 23 | windowPosSum(a, n); 24 | 25 | // Should print 4, 8, -3, 13, 9, 4 26 | System.out.println(java.util.Arrays.toString(a)); 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /hw0/src/DrawATriganle.java: -------------------------------------------------------------------------------- 1 | public class DrawATriganle { 2 | public static void main(String[] args) { 3 | int row = 0; // form 0 to 4 4 | int column = 1; // form 1 to 5 5 | while (row < 5){ 6 | int temp_column = column; 7 | while(temp_column > 0){ 8 | if (temp_column == 1 && row == 4){ 9 | System.out.print("*"); 10 | }else if (temp_column == 1){ 11 | System.out.println("*"); 12 | }else{ 13 | System.out.print("*"); 14 | } 15 | temp_column -= 1; 16 | } 17 | column += 1; 18 | row += 1; 19 | } 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /hw0/src/DrawTriganle.java: -------------------------------------------------------------------------------- 1 | public class DrawTriganle { 2 | public static void main(String[] args) { 3 | drawTriangle(10); 4 | } 5 | public static void drawTriangle(int N) { 6 | int row = 0; // form 0 to 4 7 | int column = 1; // form 1 to 5 8 | while (row < N) { 9 | int temp_column = column; 10 | while (temp_column > 0) { 11 | if (temp_column == 1 && row == N - 1) { 12 | System.out.print("*"); 13 | } else if (temp_column == 1) { 14 | System.out.println("*"); 15 | } else { 16 | System.out.print("*"); 17 | } 18 | temp_column -= 1; 19 | } 20 | column += 1; 21 | row += 1; 22 | } 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /hw0/src/GetMax.java: -------------------------------------------------------------------------------- 1 | public class GetMax { 2 | // I only write max() with "for" 3 | public static int max(int[] m) { 4 | int max = m[0]; 5 | for(int i = 0; i < m.length; i++){ 6 | if (m[i] > max){ 7 | max = m[i]; 8 | } 9 | } 10 | return max; 11 | } 12 | public static void main(String[] args) { 13 | int[] numbers = new int[]{9, 2, 15, 2, 22, 10, 6}; 14 | System.out.println(max(numbers)); 15 | } 16 | } -------------------------------------------------------------------------------- /lab1/CheckLabConfig.java: -------------------------------------------------------------------------------- 1 | import java.io.File; 2 | 3 | public class CheckLabConfig { 4 | public static void checkConfig(boolean isWindows) { 5 | String repoVariableName = "REPO_DIR"; 6 | String repoDir = System.getenv(repoVariableName); 7 | checkVariableNotNull(repoDir, repoVariableName); 8 | System.out.println("Validating your " + repoVariableName + 9 | " environment variable, which is currently set to: " + 10 | repoDir); 11 | checkIsValidRepo(repoDir, repoVariableName, isWindows, false); 12 | 13 | String snapsVariableName = "SNAPS_DIR"; 14 | String snapsRepoDir = System.getenv(snapsVariableName); 15 | 16 | checkVariableNotNull(snapsRepoDir, snapsVariableName); 17 | System.out.println("Validating your " + snapsVariableName + 18 | " environment variable, which is currently set to: " + 19 | snapsRepoDir); 20 | checkIsValidRepo(snapsRepoDir, snapsVariableName, isWindows, true); 21 | } 22 | 23 | public static void checkVariableNotNull(String value, String name) { 24 | if (value == null) { 25 | System.out.println("ERROR! Environment variable " + name + " is not set."); 26 | System.out.println("If you've already set it using the lab 1 setup directions, " + 27 | "then try restarting your terminal or IntelliJ."); 28 | System.exit(1); 29 | } 30 | } 31 | 32 | public static void checkIsValidRepo(String value, String name, 33 | boolean isWindows, boolean snapsCheck) { 34 | 35 | String splitString = ""; 36 | if (isWindows) { 37 | splitString = "\\\\"; 38 | } else { 39 | splitString = "/"; 40 | } 41 | 42 | String[] tokens = value.split(splitString); 43 | String folderName = tokens[tokens.length - 1]; 44 | 45 | String pattern; 46 | String expected; 47 | 48 | if (!snapsCheck) { 49 | pattern = "sp21-s[\\d]+"; 50 | expected = "sp21-s1234"; 51 | } else { 52 | pattern = "snaps-sp21-s[\\d]+"; 53 | expected = "snaps-sp21-s1234"; 54 | } 55 | 56 | if (!folderName.matches(pattern)) { 57 | System.out.println("ERROR! Your " + name + " environment variable is incorrect."); 58 | System.out.println("The folder name in the end should match this pattern: " + expected); 59 | System.exit(1); 60 | } 61 | 62 | File file = new File(value); 63 | 64 | boolean isDirectory = file.isDirectory(); 65 | if (!isDirectory) { 66 | System.out.println("ERROR! " + value + " is not a valid folder."); 67 | System.out.println("Double check that this variable was set correctly."); 68 | System.exit(1); 69 | } 70 | 71 | } 72 | 73 | public static void main(String[] args) { 74 | System.out.println("Testing configuration. This program only works for the " + 75 | "Spring 2021 edition of this course."); 76 | 77 | String yourOS = System.getProperty("os.name").toLowerCase(); 78 | String yourOSVersion = System.getProperty("os.version"); 79 | 80 | if (yourOS.contains("windows")) { 81 | checkConfig(true); 82 | } else { 83 | checkConfig(false); 84 | } 85 | 86 | /*if (yourOS.contains("mac")) { 87 | if (yourOSVersion.contains("10.15")) { 88 | checkConfig(false); 89 | } else { 90 | checkConfig(false); 91 | } 92 | } // for future reference in case we need to test configurations separately 93 | for Mac OS, Catalina, Linux, etc*/ 94 | 95 | System.out.println("Your system appears to be configured correctly. You've completed lab 1 setup."); 96 | } 97 | } 98 | 99 | 100 | -------------------------------------------------------------------------------- /lab1/Collatz.java: -------------------------------------------------------------------------------- 1 | /** Class that prints the Collatz sequence starting from a given number. 2 | * @author YOUR NAME HERE 3 | */ 4 | public class Collatz { 5 | 6 | /** Nice implementation of nextNumber! */ 7 | public static int nextNumber(int n) { 8 | if (n == 1) { 9 | return 1; 10 | } else if (n % 2 == 0) { 11 | return n / 2; 12 | } else { 13 | return 3 * n + 1; 14 | } 15 | } 16 | 17 | public static void main(String[] args) { 18 | int n = 5; 19 | System.out.print(n + " "); 20 | while (n != 1) { 21 | n = nextNumber(n); 22 | System.out.print(n + " "); 23 | } 24 | System.out.println(); 25 | } 26 | } 27 | 28 | -------------------------------------------------------------------------------- /lab1/GetEnvironmentVariables.java: -------------------------------------------------------------------------------- 1 | import java.util.Properties; 2 | 3 | public class GetEnvironmentVariables { 4 | 5 | // Fill in the path to your sp21-s*** folder between the quotes 6 | public static String REPO_DIR = ""; 7 | 8 | // Fill in the path to your snaps-sp21-s*** folder between the quotes 9 | public static String SNAPS_DIR = ""; 10 | 11 | // Fill in the type of your shell by running 'echo $0` in your terminal. It should be zsh or bash. 12 | public static String SHELL = ""; 13 | 14 | public static void main(String[] args) { 15 | 16 | String catalina = "echo 'export {variable}={value}' >> ~/.zprofile"; 17 | String mac = "echo 'export {variable}={value}' >> ~/.bash_profile"; 18 | String linux = "echo 'export {variable}={value}' >> ~/.bashrc"; 19 | String catalinaSource = "source ~/.zprofile"; 20 | String macSource = "source ~/.bash_profile"; 21 | String linuxSource = "source ~/.bashrc"; 22 | 23 | String yourOS = System.getProperty("os.name").toLowerCase(); 24 | 25 | String repo = null; 26 | String snaps = null; 27 | String source = null; 28 | if (yourOS.contains("mac")) { 29 | String version = System.getProperty("os.version"); 30 | if (SHELL.equals("zsh")) { 31 | repo = catalina.replace("{variable}", "REPO_DIR").replace("{value}", REPO_DIR); 32 | snaps = catalina.replace("{variable}", "SNAPS_DIR").replace("{value}", SNAPS_DIR); 33 | source = catalinaSource; 34 | } else { 35 | repo = mac.replace("{variable}", "REPO_DIR").replace("{value}", REPO_DIR); 36 | snaps = mac.replace("{variable}", "SNAPS_DIR").replace("{value}", SNAPS_DIR); 37 | source = macSource; 38 | } 39 | } else if (yourOS.contains("nux")) { 40 | repo = linux.replace("{variable}", "REPO_DIR").replace("{value}", REPO_DIR); 41 | snaps = linux.replace("{variable}", "SNAPS_DIR").replace("{value}", SNAPS_DIR); 42 | source = linuxSource; 43 | } 44 | 45 | if (repo == null) { 46 | System.out.println(); 47 | System.out.println("Oops! We couldn't detect your OS. Please reach out to a lab TA or post on Ed so we can help you move forward"); 48 | return; 49 | } 50 | 51 | System.out.println(); 52 | System.out.println("Keep reading the spec to know what to do with this output"); 53 | System.out.println("----------------------------------------------------------"); 54 | System.out.println(repo); 55 | System.out.println(snaps); 56 | System.out.println(source); 57 | 58 | } 59 | 60 | } -------------------------------------------------------------------------------- /lab1/HelloNumbers.java: -------------------------------------------------------------------------------- 1 | public class HelloNumbers { 2 | public static void main(String[] args) { 3 | int x = 1; 4 | int total = 0; 5 | while (x <= 10) { 6 | System.out.print(total + " "); 7 | total = total + x; 8 | x = x + 1; 9 | } 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /lab1/HelloWorld.java: -------------------------------------------------------------------------------- 1 | public class HelloWorld { 2 | public static void main(String[] args) { 3 | System.out.println("Hello world!"); 4 | } 5 | } 6 | -------------------------------------------------------------------------------- /lab2/Arithmetic/Arithmetic.java: -------------------------------------------------------------------------------- 1 | package Arithmetic; 2 | 3 | /** Simple Arithmetic Class. 4 | * @author Josh Hug 5 | * */ 6 | public class Arithmetic { 7 | 8 | /** Computes product of two ints. 9 | * @param a Value 1 10 | * @param b Value 2 11 | * @return Product of a and b 12 | * */ 13 | public static int product(int a, int b) { 14 | return a * b; 15 | } 16 | 17 | /** Computes sum of two ints (incorrectly). 18 | * @param a Value 1 19 | * @param b Value 2 20 | * @return Sum of a and b 21 | * */ 22 | public static int sum(int a, int b) { 23 | return a + b; 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /lab2/Arithmetic/ArithmeticTest.java: -------------------------------------------------------------------------------- 1 | package Arithmetic; 2 | 3 | import static org.junit.Assert.*; 4 | import org.junit.Test; 5 | 6 | public class ArithmeticTest { 7 | 8 | /** Performs a few arbitrary tests to see if the product method is 9 | * correct */ 10 | @Test 11 | public void testProduct() { 12 | /* assertEquals for comparison of ints takes two arguments: 13 | assertEquals(expected, actual). 14 | if it is false, then the assertion will be false, 15 | and this test will fail. 16 | */ 17 | 18 | assertEquals(30, Arithmetic.product(5, 6)); 19 | assertEquals(-30, Arithmetic.product(5, -6)); 20 | assertEquals(0, Arithmetic.product(0, -6)); 21 | } 22 | 23 | /** Performs a few arbitrary tests to see if the sum method is correct */ 24 | @Test 25 | public void testSum() { 26 | 27 | assertEquals(11, Arithmetic.sum(5, 6)); 28 | assertEquals(-1, Arithmetic.sum(5, -6)); 29 | assertEquals(-6, Arithmetic.sum(0, -6)); 30 | assertEquals(0, Arithmetic.sum(6, -6)); 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /lab2/DebugExercise/DebugExercise1.java: -------------------------------------------------------------------------------- 1 | package DebugExercise; 2 | 3 | /** 4 | * Exercise for learning how the debug, breakpoint, and step-into 5 | * feature work. 6 | */ 7 | public class DebugExercise1 { 8 | public static int divideThenRound(int top, int bottom) { 9 | int quotient = top / bottom; 10 | int result = Math.round(quotient); 11 | return result; 12 | } 13 | 14 | public static void main(String[] args) { 15 | int t = 10; 16 | int b = 2; 17 | int result = divideThenRound(t, b); 18 | System.out.println("round(" + t + "/" + b + ")=" + result); 19 | 20 | int t2 = 9; 21 | int b2 = 4; 22 | int result2 = divideThenRound(t2, b2); 23 | System.out.println("round(" + t2 + "/" + b2 + ")=" + result2); 24 | 25 | int t3 = 3; 26 | int b3 = 4; 27 | int result3 = divideThenRound(t3, b3); 28 | System.out.println("round(" + t3 + "/" + b3 + ")=" + result3); 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /lab2/DebugExercise/DebugExercise2.java: -------------------------------------------------------------------------------- 1 | package DebugExercise; 2 | 3 | /** 4 | * Exercise to showcase the step over button. 5 | * Code adapted from https://stackoverflow.com/questions/4895173/bitwise-multiply-and-add-in-java and https://stackoverflow.com/questions/1533131/what-useful-bitwise-operator-code-tricks-should-a-developer-know-about 6 | */ 7 | public class DebugExercise2 { 8 | /** Returns the max of a and b. Do not step into this function. */ 9 | // public static int max(int a, int b) { 10 | // int w = (b - a) >> 31; 11 | // /* If you're stepping into this function, click the 12 | // step out button because you're not going to learn anything. */ 13 | // int z = ~(b - a) >> 31; 14 | // 15 | // int max = b & w | a & z; 16 | // return max; 17 | // } 18 | 19 | public static int max(int a, int b) { 20 | return a > b? a : b; 21 | } 22 | 23 | 24 | /** Returns the sum of a and b. Do not step into this function. */ 25 | // public static int add(int a, int b) { 26 | // int x = a, y = b; 27 | // /* If you're stepping into this function, click the 28 | // step out button because you're not going to learn anything. */ 29 | // int xor, and, temp; 30 | // and = x & y; 31 | // xor = x ^ y; 32 | // 33 | // while (and != 0) { 34 | // and <<= 1; 35 | // temp = xor ^ and; 36 | // and &= xor; 37 | // xor = temp; 38 | // } 39 | // return xor; 40 | // } 41 | 42 | /** Returns a new array where entry i is the max of 43 | * a[i] and b[i]. For example, if a = {1, -10, 3} 44 | * and b = {0, 20, 5}, this function will return {1, 20, 5}. 45 | * */ 46 | public static int[] arrayMax(int[] a, int[] b) { 47 | if (a.length != b.length) { 48 | System.out.println("ERROR! Arrays don't match"); 49 | return null; 50 | } 51 | int[] returnArray = new int[a.length]; 52 | for (int i = 0; i < a.length; i += 1) { 53 | int biggerValue = max(a[i], b[i]); 54 | returnArray[i] = biggerValue; 55 | } 56 | 57 | return returnArray; 58 | } 59 | 60 | /** Returns the sum of all elements in x. */ 61 | public static int arraySum(int[] x) { 62 | int i = 0; 63 | int sum = 0; 64 | while (i < x.length) { 65 | sum += x[i]; 66 | i = i + 1; 67 | } 68 | return sum; 69 | } 70 | 71 | /** Returns the sum of the element-wise max of a and b. 72 | * For example if a = {2, 0, 10, 14} and b = {-5, 5, 20, 30}, 73 | * the result should be 57. 74 | * */ 75 | public static int sumOfElementwiseMaxes(int[] a, int[] b) { 76 | int[] maxes = arrayMax(a, b); 77 | int sumofMaxes = arraySum(maxes); 78 | return sumofMaxes; 79 | } 80 | 81 | 82 | public static void main(String[] args) { 83 | int[] a = {1, 11, -1, -11}; 84 | int[] b = {3, -3, 2, -1}; 85 | // int [] a = {2, 0, 10, 14}; 86 | // int [] b = {-5, 5, 20, 30}; 87 | 88 | int sumOfElementwiseMaxes = sumOfElementwiseMaxes(a, b); 89 | System.out.println(sumOfElementwiseMaxes); 90 | } 91 | } 92 | -------------------------------------------------------------------------------- /lab2/IntList/AddConstantTest.java: -------------------------------------------------------------------------------- 1 | package IntList; 2 | 3 | import static org.junit.Assert.*; 4 | import org.junit.Test; 5 | 6 | public class AddConstantTest { 7 | 8 | @Test 9 | public void testAddConstantOne() { 10 | IntList lst = IntList.of(1, 2, 3, 4, 5); 11 | IntListExercises.addConstant(lst, 1); 12 | assertEquals("2 -> 3 -> 4 -> 5 -> 6", lst.toString()); 13 | } 14 | 15 | @Test 16 | public void testAddConstantTwo() { 17 | IntList lst = IntList.of(1, 2, 3, 4, 5); 18 | IntListExercises.addConstant(lst, 2); 19 | assertEquals("3 -> 4 -> 5 -> 6 -> 7", lst.toString()); 20 | } 21 | 22 | @Test 23 | public void testAddToLargeList() { 24 | IntList lst = IntList.of(1, 2, 3, 4, 5, 6, 7, 8, 9); 25 | IntListExercises.addConstant(lst, 10); 26 | assertEquals("11 -> 12 -> 13 -> 14 -> 15 -> 16 -> 17 -> 18 -> 19", lst.toString()); 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /lab2/IntList/IntList.java: -------------------------------------------------------------------------------- 1 | package IntList; 2 | 3 | public class IntList { 4 | public int first; 5 | public IntList rest; 6 | 7 | public IntList(int f, IntList r) { 8 | first = f; 9 | rest = r; 10 | } 11 | 12 | /** Return the size of the list using... recursion! */ 13 | public int size() { 14 | if (rest == null) { 15 | return 1; 16 | } 17 | return 1 + this.rest.size(); 18 | } 19 | 20 | /** Return the size of the list using no recursion! */ 21 | public int iterativeSize() { 22 | IntList p = this; 23 | int totalSize = 0; 24 | while (p != null) { 25 | totalSize += 1; 26 | p = p.rest; 27 | } 28 | return totalSize; 29 | } 30 | 31 | /** Returns the ith item of this IntList. */ 32 | public int get(int i) { 33 | if (i == 0) { 34 | return first; 35 | } 36 | return rest.get(i - 1); 37 | } 38 | 39 | /** Method to return a string representation of an IntList */ 40 | public String toString() { 41 | if (rest == null) { 42 | // Converts an Integer to a String! 43 | return String.valueOf(first); 44 | } else { 45 | return first + " -> " + rest.toString(); 46 | } 47 | } 48 | 49 | /** 50 | * Method to create an IntList from an argument list. 51 | * You don't have to understand this code. We have it here 52 | * because it's convenient with testing. It's used like this: 53 | * 54 | * IntList myList = IntList.of(1, 2, 3, 4, 5); 55 | * will create an IntList 1 -> 2 -> 3 -> 4 -> 5 -> null. 56 | * 57 | * You can pass in any number of arguments to IntList.of and it will work: 58 | * IntList mySmallerList = IntList.of(1, 4, 9); 59 | */ 60 | public static IntList of(int ...argList) { 61 | if (argList.length == 0) 62 | return null; 63 | int[] restList = new int[argList.length - 1]; 64 | System.arraycopy(argList, 1, restList, 0, argList.length - 1); 65 | return new IntList(argList[0], IntList.of(restList)); 66 | } 67 | } 68 | -------------------------------------------------------------------------------- /lab2/IntList/IntListExercises.java: -------------------------------------------------------------------------------- 1 | package IntList; 2 | 3 | public class IntListExercises { 4 | 5 | /** 6 | * Part A: (Buggy) mutative method that adds a constant C to each 7 | * element of an IntList 8 | * 9 | * @param lst IntList from Lecture 10 | */ 11 | public static void addConstant(IntList lst, int c) { 12 | IntList head = lst; 13 | while (head != null) { 14 | head.first += c; 15 | head = head.rest; 16 | } 17 | } 18 | 19 | /** 20 | * Part B: Buggy method that sets node.first to zero if 21 | * the max value in the list starting at node has the same 22 | * first and last digit, for every node in L 23 | * 24 | * @param L IntList from Lecture 25 | */ 26 | public static void setToZeroIfMaxFEL(IntList L) { 27 | IntList p = L; 28 | while (p != null) { 29 | if (firstDigitEqualsLastDigit(max(p))) { 30 | p.first = 0; 31 | } 32 | p = p.rest; 33 | } 34 | } 35 | 36 | /** Returns the max value in the IntList starting at L. */ 37 | public static int max(IntList L) { 38 | int max = L.first; 39 | IntList p = L.rest; 40 | while (p != null) { 41 | if (p.first > max) { 42 | max = p.first; 43 | } 44 | p = p.rest; 45 | } 46 | return max; 47 | } 48 | 49 | /** Returns true if the last digit of x is equal to 50 | * the first digit of x. 51 | */ 52 | public static boolean firstDigitEqualsLastDigit(int x) { 53 | int lastDigit = x % 10; 54 | while (x >= 10) { 55 | x = x / 10; 56 | } 57 | int firstDigit = x % 10; 58 | return firstDigit == lastDigit; 59 | } 60 | 61 | /** 62 | * Part C: (Buggy) mutative method that squares each prime 63 | * element of the IntList. 64 | * 65 | * @param lst IntList from Lecture 66 | * @return True if there was an update to the list 67 | */ 68 | public static boolean squarePrimes(IntList lst) { 69 | return squarePrimes(lst, false); 70 | } 71 | 72 | // I wrapped(using helper func) it, then I could only pass a param of lst 73 | private static boolean squarePrimes(IntList lst, boolean isSquare) { 74 | // Base Case: we have reached the end of the list 75 | if (lst == null) { 76 | return isSquare; 77 | } 78 | 79 | boolean currElemIsPrime = Primes.isPrime(lst.first); 80 | 81 | if (currElemIsPrime) { 82 | lst.first *= lst.first; 83 | isSquare = true; 84 | } 85 | 86 | return squarePrimes(lst.rest, isSquare); 87 | } 88 | } 89 | -------------------------------------------------------------------------------- /lab2/IntList/Primes.java: -------------------------------------------------------------------------------- 1 | package IntList; 2 | 3 | public class Primes { 4 | 5 | /** 6 | * This (complicated) algorithm returns True if its argument is prime, 7 | * otherwise False. When you're debugging, stepping into this function may 8 | * not be the best idea! Consider instead stepping *over* this function, 9 | * and ensuring that its return value makes sense. 10 | * 11 | * If you're curious, this algorithm uses Fermat's Little Theorem as a 12 | * primality test, and returns the correct answer w.h.p. (due to the presence) 13 | * of Carmichael numbers. If this makes no sense to you, good! It shouldn't. 14 | * The goal of this function is to make sure you learn to abstract away the inner 15 | * workings of a function and debug it as a black-box with the "Step Over" feature. 16 | * 17 | * @source: https://www.geeksforgeeks.org/primality-test-set-2-fermet-method/ 18 | * @param n an arbitary integrer 19 | * @return True iff. the integer is prime 20 | */ 21 | public static boolean isPrime(int n) { 22 | // Corner cases 23 | if (n <= 1 || n == 4) return false; 24 | if (n <= 3) return true; 25 | 26 | int k = 3; // Try k = 3 times 27 | while (k > 0) 28 | { 29 | // Pick a random number in [2..n-2] 30 | // Above corner cases make sure that n > 4 31 | int a = 2 + (int)(Math.random() % (n - 4)); 32 | 33 | // Fermat's little theorem 34 | if (power(a, n - 1, n) != 1) 35 | return false; 36 | 37 | k--; 38 | } 39 | 40 | return true; 41 | } 42 | 43 | /** 44 | * This is a helper method to isPrime. You can ignore this method. 45 | * It is an iterative Function to calculate a^n mod p in log time 46 | * 47 | * @source: https://www.geeksforgeeks.org/primality-test-set-2-fermet-method/ 48 | */ 49 | static int power(int a, int n, int p) 50 | { 51 | // Initialize result 52 | int res = 1; 53 | 54 | // Update 'a' if 'a' >= p 55 | a = a % p; 56 | 57 | while (n > 0) 58 | { 59 | // If n is odd, multiply 'a' with result 60 | if ((n & 1) == 1) 61 | res = (res * a) % p; 62 | 63 | // n must be even now 64 | n = n >> 1; // n = n/2 65 | a = (a * a) % p; 66 | } 67 | return res; 68 | } 69 | 70 | /** Driver Code */ 71 | public static void main(String[] args) { 72 | /* Print the first 20 primes */ 73 | int primeCount = 0; 74 | int x = 2; 75 | 76 | while (primeCount < 20) { 77 | if (isPrime(x)) { 78 | System.out.println(x); 79 | primeCount++; 80 | } 81 | x++; 82 | } 83 | } 84 | } 85 | -------------------------------------------------------------------------------- /lab2/IntList/SetToZeroIfMaxFELTest.java: -------------------------------------------------------------------------------- 1 | package IntList; 2 | 3 | import static org.junit.Assert.*; 4 | import org.junit.Test; 5 | 6 | public class SetToZeroIfMaxFELTest { 7 | 8 | @Test 9 | public void testZeroOutFELMaxes1() { 10 | IntList L = IntList.of(1, 22, 15); 11 | IntListExercises.setToZeroIfMaxFEL(L); 12 | assertEquals("0 -> 0 -> 15", L.toString()); 13 | } 14 | 15 | @Test 16 | public void testZeroOutFELMaxes2() { 17 | IntList L = IntList.of(55, 22, 45, 44, 5); 18 | IntListExercises.setToZeroIfMaxFEL(L); 19 | assertEquals("0 -> 22 -> 45 -> 0 -> 0", L.toString()); 20 | } 21 | 22 | @Test 23 | public void testZeroOutFELMaxes3() { 24 | IntList L = IntList.of(5, 535, 35, 11, 10, 0); 25 | IntListExercises.setToZeroIfMaxFEL(L); 26 | assertEquals("0 -> 0 -> 35 -> 0 -> 10 -> 0", L.toString()); 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /lab2/IntList/SquarePrimesTest.java: -------------------------------------------------------------------------------- 1 | package IntList; 2 | 3 | import static org.junit.Assert.*; 4 | import org.junit.Test; 5 | 6 | public class SquarePrimesTest { 7 | 8 | /** 9 | * Here is a test for isPrime method. Try running it. 10 | * It passes, but the starter code implementation of isPrime 11 | * is broken. Write your own JUnit Test to try to uncover the bug! 12 | */ 13 | @Test 14 | public void testSquarePrimesSimple() { 15 | IntList lst = IntList.of(14, 15, 16, 17, 18); 16 | boolean changed = IntListExercises.squarePrimes(lst); 17 | assertEquals("14 -> 15 -> 16 -> 289 -> 18", lst.toString()); 18 | assertTrue(changed); 19 | 20 | // if it is a list of many primes, we should square all primes 21 | IntList lst1 = IntList.of(17,17,17); 22 | boolean changed1 = IntListExercises.squarePrimes(lst1); 23 | assertEquals("289 -> 289 -> 289", lst1.toString()); 24 | assertTrue(changed1); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /lab2/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 4.0.0 6 | 7 | 8 | CS61B 9 | 61BMasterPom 10 | 1.0-SNAPSHOT 11 | ../library-sp21/javalib/masterpom.xml 12 | 13 | 14 | CS61B 15 | lab2 16 | 1.0-SNAPSHOT 17 | 18 | 19 | ${project.basedir} 20 | ${project.basedir} 21 | 22 | 23 | org.apache.maven.plugins 24 | maven-compiler-plugin 25 | 3.1 26 | 27 | 1.9 28 | 1.9 29 | 30 | 31 | 32 | org.apache.maven.plugins 33 | maven-compiler-plugin 34 | 3.8.1 35 | 36 | 37 | -J-XX:+ShowCodeDetailsInExceptionMessages 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | -------------------------------------------------------------------------------- /lab2setup/Dog/Dog.java: -------------------------------------------------------------------------------- 1 | package Dog; 2 | 3 | public class Dog { 4 | private int size; 5 | 6 | public Dog(int s) { 7 | size = s; 8 | } 9 | 10 | /** Makes a noise. */ 11 | public String noise() { 12 | if (size < 10) { 13 | return "yip"; 14 | } 15 | return "bark"; 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /lab2setup/Dog/DogTest.java: -------------------------------------------------------------------------------- 1 | package Dog; 2 | 3 | import static org.junit.Assert.*; 4 | import org.junit.Test; 5 | 6 | public class DogTest { 7 | @Test 8 | public void testSmall() { 9 | Dog d = new Dog(3); 10 | assertEquals("yip", d.noise()); 11 | } 12 | 13 | @Test 14 | public void testLarge() { 15 | Dog d = new Dog(20); 16 | assertEquals("bark", d.noise()); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /lab2setup/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 4.0.0 6 | 7 | 8 | CS61B 9 | 61BMasterPom 10 | 1.0-SNAPSHOT 11 | ../library-sp21/javalib/masterpom.xml 12 | 13 | 14 | CS61B 15 | lab2setup 16 | 1.0-SNAPSHOT 17 | 18 | 19 | ${project.basedir} 20 | ${project.basedir} 21 | 22 | 23 | org.apache.maven.plugins 24 | maven-compiler-plugin 25 | 3.1 26 | 27 | 1.9 28 | 1.9 29 | 30 | 31 | 32 | org.apache.maven.plugins 33 | maven-compiler-plugin 34 | 3.8.1 35 | 36 | 37 | -J-XX:+ShowCodeDetailsInExceptionMessages 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | -------------------------------------------------------------------------------- /lab3/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 4.0.0 6 | 7 | 8 | CS61B 9 | 61BMasterPom 10 | 1.0-SNAPSHOT 11 | ../library-sp21/javalib/masterpom.xml 12 | 13 | 14 | CS61B 15 | lab3 16 | 1.0-SNAPSHOT 17 | 18 | 19 | ${project.basedir} 20 | ${project.basedir} 21 | 22 | 23 | org.apache.maven.plugins 24 | maven-compiler-plugin 25 | 3.1 26 | 27 | 1.14 28 | 1.14 29 | 30 | 31 | 32 | org.apache.maven.plugins 33 | maven-compiler-plugin 34 | 3.8.1 35 | 36 | 37 | -J-XX:+ShowCodeDetailsInExceptionMessages 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | -------------------------------------------------------------------------------- /lab3/randomizedtest/AListNoResizing.java: -------------------------------------------------------------------------------- 1 | package randomizedtest; 2 | 3 | /** Array based list. 4 | * @author Josh Hug 5 | */ 6 | 7 | // 0 1 2 3 4 5 6 7 8 | // items: [6 9 -1 2 0 0 0 0 ...] 9 | // size: 5 10 | 11 | /* Invariants: 12 | addLast: The next item we want to add, will go into position size 13 | getLast: The item we want to return is in position size - 1 14 | size: The number of items in the list should be size. 15 | */ 16 | 17 | public class AListNoResizing { 18 | private Item[] items; 19 | private int size; 20 | 21 | /** Creates an empty list. */ 22 | public AListNoResizing() { 23 | items = (Item[]) new Object[1000]; 24 | size = 0; 25 | } 26 | 27 | /** Inserts X into the back of the list. */ 28 | public void addLast(Item x) { 29 | items[size] = x; 30 | size = size + 1; 31 | } 32 | 33 | /** Returns the item from the back of the list. */ 34 | public Item getLast() { 35 | return items[size - 1]; 36 | } 37 | /** Gets the ith item in the list (0 is the front). */ 38 | public Item get(int i) { 39 | return items[i]; 40 | } 41 | 42 | /** Returns the number of items in the list. */ 43 | public int size() { 44 | return size; 45 | } 46 | 47 | /** Deletes item from back of the list and 48 | * returns deleted item. */ 49 | public Item removeLast() { 50 | Item x = getLast(); 51 | items[size - 1] = null; 52 | size = size - 1; 53 | return x; 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /lab3/randomizedtest/BuggyAList.java: -------------------------------------------------------------------------------- 1 | package randomizedtest; 2 | 3 | /** Array based list. 4 | * @author Josh Hug 5 | */ 6 | 7 | // 0 1 2 3 4 5 6 7 8 | // items: [6 9 -1 2 0 0 0 0 ...] 9 | // size: 5 10 | 11 | /* Invariants: 12 | addLast: The next item we want to add, will go into position size 13 | getLast: The item we want to return is in position size - 1 14 | size: The number of items in the list should be size. 15 | */ 16 | 17 | public class BuggyAList { 18 | private Item[] items; 19 | private int size; 20 | 21 | /** Creates an empty list. */ 22 | public BuggyAList() { 23 | items = (Item[]) new Object[1]; 24 | size = 0; 25 | } 26 | 27 | /** Resizes the underlying array to the target capacity. */ 28 | private void resize(int capacity) { 29 | Item[] a = (Item[]) new Object[capacity]; 30 | for (int i = 0; i < size; i += 1) { 31 | a[i] = items[i]; 32 | } 33 | items = a; 34 | } 35 | 36 | /** Inserts X into the back of the list. */ 37 | public void addLast(Item x) { 38 | if (size == items.length) { 39 | resize(size * 2); 40 | } 41 | items[size] = x; 42 | size = size + 1; 43 | } 44 | 45 | /** Returns the item from the back of the list. */ 46 | public Item getLast() { 47 | return items[size - 1]; 48 | } 49 | /** Gets the ith item in the list (0 is the front). */ 50 | public Item get(int i) { 51 | return items[i]; 52 | } 53 | 54 | /** Returns the number of items in the list. */ 55 | public int size() { 56 | return size; 57 | } 58 | 59 | /** Deletes item from back of the list and 60 | * returns deleted item. */ 61 | public Item removeLast() { 62 | if ((size < items.length / 4) && (size > 4)) { 63 | // you should use "items.length / 4", not "size / 4" 64 | resize(items.length / 4); 65 | } 66 | Item x = getLast(); 67 | items[size - 1] = null; 68 | size = size - 1; 69 | return x; 70 | } 71 | } 72 | -------------------------------------------------------------------------------- /lab3/randomizedtest/TestBuggyAList.java: -------------------------------------------------------------------------------- 1 | package randomizedtest; 2 | 3 | import edu.princeton.cs.algs4.StdRandom; 4 | import org.junit.Test; 5 | import static org.junit.Assert.*; 6 | 7 | /** 8 | * Created by hug. 9 | */ 10 | 11 | // we don't need main() in test of Junit 12 | public class TestBuggyAList { 13 | @Test 14 | public void testThreeAddThreeRemove(){ 15 | BuggyAList buggyAList = new BuggyAList(); 16 | 17 | // three add 18 | for (int i = 4; i < 7; i++){ 19 | buggyAList.addLast(i); 20 | } 21 | // three remove one time 22 | for (int expected = 6 ; expected > 3 ; expected--){ 23 | int actual = buggyAList.removeLast(); 24 | assertEquals(expected, actual); 25 | } 26 | } 27 | // without comparison 28 | // not clean up log 29 | // @Test 30 | // public void randomizedTest(){ 31 | // AListNoResizing L = new AListNoResizing(); 32 | // 33 | // int N = 500; 34 | // for (int i = 0; i < N; i += 1) { 35 | // int operationNumber = StdRandom.uniform(0, 4); 36 | // if (operationNumber == 0) { 37 | // // addLast 38 | // int randVal = StdRandom.uniform(0, 100); 39 | // L.addLast(randVal); 40 | // System.out.println("addLast(" + randVal + ")"); 41 | // } else if (operationNumber == 1) { 42 | // // size 43 | // int size = L.size(); 44 | // System.out.println("size: " + size); 45 | // }else if (operationNumber == 2){ 46 | // // getLast 47 | // if (L.size() == 0){ 48 | // continue; 49 | // } 50 | // int val = L.getLast(); 51 | // System.out.println("getLast(" + val + ")"); 52 | // } else if (operationNumber == 3) { 53 | // // removeLast 54 | // if (L.size() == 0){ 55 | // continue; 56 | // } 57 | // int val = L.removeLast(); 58 | // System.out.println("removeLast(" + val + ")"); 59 | // } 60 | // } 61 | // } 62 | 63 | // without comparison 64 | // clean up log 65 | @Test 66 | public void randomizedTest(){ 67 | AListNoResizing LA = new AListNoResizing(); 68 | BuggyAList LB = new BuggyAList(); 69 | int N = 5000; 70 | 71 | for (int i = 0; i < N; i += 1) { 72 | int operationNumber = StdRandom.uniform(0, 4); 73 | if (operationNumber == 0) { 74 | // addLast 75 | int randVal = StdRandom.uniform(0, 100); 76 | // AListNoResizing 77 | LA.addLast(randVal); 78 | // BuggyAList 79 | LB.addLast(randVal); 80 | } else if (operationNumber == 1) { 81 | // size 82 | // AListNoResizing 83 | LA.size(); 84 | // BuggyAList 85 | LB.size(); 86 | }else if (operationNumber == 2){ 87 | // getLast 88 | if (LA.size() != 0){ 89 | LA.getLast(); 90 | } 91 | if (LB.size() != 0){ 92 | LB.getLast(); 93 | } 94 | } else if (operationNumber == 3) { 95 | // removeLast 96 | if (LA.size() != 0){ 97 | LA.removeLast(); 98 | } 99 | if (LB.size() != 0){ 100 | LB.removeLast(); 101 | } 102 | } 103 | } 104 | } 105 | 106 | // this test from class 107 | // @Test 108 | // public void testThreeAddThreeRemove() { 109 | // AListNoResizing correct = new AListNoResizing(); 110 | // BuggyAList broken = new BuggyAList(); 111 | // 112 | // correct.addLast(5); 113 | // correct.addLast(10); 114 | // correct.addLast(15); 115 | // 116 | // broken.addLast(5); 117 | // broken.addLast(10); 118 | // broken.addLast(15); 119 | // 120 | // assertEquals(correct.size(), broken.size()); 121 | // 122 | // assertEquals(correct.removeLast(), broken.removeLast()); 123 | // assertEquals(correct.removeLast(), broken.removeLast()); 124 | // assertEquals(correct.removeLast(), broken.removeLast()); 125 | // } 126 | } 127 | -------------------------------------------------------------------------------- /lab3/timingtest/AList.java: -------------------------------------------------------------------------------- 1 | package timingtest; 2 | 3 | /** Array based list. 4 | * @author Josh Hug 5 | */ 6 | 7 | // 0 1 2 3 4 5 6 7 8 | // items: [6 9 -1 2 0 0 0 0 ...] 9 | // size: 5 10 | 11 | /* Invariants: 12 | addLast: The next item we want to add, will go into position size 13 | getLast: The item we want to return is in position size - 1 14 | size: The number of items in the list should be size. 15 | */ 16 | 17 | public class AList { 18 | private Item[] items; 19 | private int size; 20 | 21 | /** Creates an empty list. */ 22 | public AList() { 23 | items = (Item[]) new Object[100]; 24 | size = 0; 25 | } 26 | 27 | /** Resizes the underlying array to the target capacity. */ 28 | private void resize(int capacity) { 29 | Item[] a = (Item[]) new Object[capacity]; 30 | System.arraycopy(items, 0, a, 0, size); 31 | items = a; 32 | } 33 | 34 | /** Inserts X into the back of the list. */ 35 | public void addLast(Item x) { 36 | if (size == items.length) { 37 | // resize(size + 1); 38 | resize((int) (size * 1.01)); 39 | } 40 | 41 | items[size] = x; 42 | size = size + 1; 43 | } 44 | 45 | /** Returns the item from the back of the list. */ 46 | public Item getLast() { 47 | return items[size - 1]; 48 | } 49 | /** Gets the ith item in the list (0 is the front). */ 50 | public Item get(int i) { 51 | return items[i]; 52 | } 53 | 54 | /** Returns the number of items in the list. */ 55 | public int size() { 56 | return size; 57 | } 58 | 59 | /** Deletes item from back of the list and 60 | * returns deleted item. */ 61 | public Item removeLast() { 62 | Item x = getLast(); 63 | items[size - 1] = null; 64 | size = size - 1; 65 | return x; 66 | } 67 | } 68 | -------------------------------------------------------------------------------- /lab3/timingtest/SLList.java: -------------------------------------------------------------------------------- 1 | package timingtest; 2 | 3 | /** An SLList is a list of integers, which hides the terrible truth 4 | * of the nakedness within. */ 5 | public class SLList { 6 | private class IntNode { 7 | public Item item; 8 | public IntNode next; 9 | 10 | public IntNode(Item i, IntNode n) { 11 | item = i; 12 | next = n; 13 | } 14 | } 15 | 16 | /* The first item (if it exists) is at sentinel.next. */ 17 | private IntNode sentinel; 18 | private int size; 19 | 20 | /** Creates an empty timingtest.SLList. */ 21 | public SLList() { 22 | sentinel = new IntNode(null, null); 23 | size = 0; 24 | } 25 | 26 | public SLList(Item x) { 27 | sentinel = new IntNode(null, null); 28 | sentinel.next = new IntNode(x, null); 29 | size = 1; 30 | } 31 | 32 | /** Adds x to the front of the list. */ 33 | public void addFirst(Item x) { 34 | sentinel.next = new IntNode(x, sentinel.next); 35 | size = size + 1; 36 | } 37 | 38 | /** Returns the first item in the list. */ 39 | public Item getFirst() { 40 | return sentinel.next.item; 41 | } 42 | 43 | /** Adds x to the end of the list. */ 44 | public void addLast(Item x) { 45 | size = size + 1; 46 | 47 | IntNode p = sentinel; 48 | 49 | /* Advance p to the end of the list. */ 50 | while (p.next != null) { 51 | p = p.next; 52 | } 53 | 54 | p.next = new IntNode(x, null); 55 | } 56 | 57 | /** returns last item in the list */ 58 | public Item getLast() { 59 | IntNode p = sentinel; 60 | 61 | /* Advance p to the end of the list. */ 62 | while (p.next != null) { 63 | p = p.next; 64 | } 65 | 66 | return p.item; 67 | } 68 | 69 | 70 | /** Returns the size of the list. */ 71 | public int size() { 72 | return size; 73 | } 74 | 75 | public static void main(String[] args) { 76 | /* Creates a list of one integer, namely 10 */ 77 | SLList L = new SLList(); 78 | L.addLast(20); 79 | System.out.println(L.size()); 80 | } 81 | } 82 | -------------------------------------------------------------------------------- /lab3/timingtest/StopwatchDemo.java: -------------------------------------------------------------------------------- 1 | package timingtest; 2 | 3 | import edu.princeton.cs.algs4.Stopwatch; 4 | 5 | /** 6 | * Created by hug. 7 | */ 8 | public class StopwatchDemo { 9 | /** Computes the nth Fibonacci number using a slow naive recursive strategy.*/ 10 | private static int fib(int n) { 11 | if (n < 0) { 12 | return 0; 13 | } 14 | if (n == 1) { 15 | return 1; 16 | } 17 | return fib(n - 1) + fib(n - 2); 18 | } 19 | 20 | public static void main(String[] args) { 21 | Stopwatch sw = new Stopwatch(); 22 | int fib41 = fib(41); 23 | double timeInSeconds = sw.elapsedTime(); 24 | System.out.println("The 50th fibonacci number is " + fib41); 25 | System.out.println("Time taken to compute 41st fibonacci number: " + timeInSeconds + " seconds."); 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /lab3/timingtest/TimeAList.java: -------------------------------------------------------------------------------- 1 | package timingtest; 2 | import edu.princeton.cs.algs4.Stopwatch; 3 | 4 | /** 5 | * Created by hug. 6 | */ 7 | public class TimeAList { 8 | private static void printTimingTable(AList Ns, AList times, AList opCounts) { 9 | System.out.printf("%12s %12s %12s %12s\n", "N", "time (s)", "# ops", "microsec/op"); 10 | System.out.printf("------------------------------------------------------------\n"); 11 | for (int i = 0; i < Ns.size(); i += 1) { 12 | int N = Ns.get(i); 13 | double time = times.get(i); 14 | int opCount = opCounts.get(i); 15 | double timePerOp = time / opCount * 1e6; 16 | System.out.printf("%12d %12.2f %12d %12.2f\n", N, time, opCount, timePerOp); 17 | } 18 | } 19 | 20 | public static void main(String[] args) { 21 | timeAListConstruction(); 22 | } 23 | 24 | public static void timeAListConstruction() { 25 | AList testAList = new AList(); 26 | AList Ns = new AList(); 27 | AList times = new AList(); 28 | AList opCounts = new AList(); 29 | for (int i = 1000; i <= 128000; i *= 2 ){ 30 | Ns.addLast(i); 31 | double startTime = System.currentTimeMillis(); 32 | int opCount = 0; 33 | for (int j = 0; j < i; j++){ 34 | testAList.addLast(j); 35 | opCount += 1; 36 | } 37 | double endTime = System.currentTimeMillis(); 38 | double time = (endTime - startTime) / 1000; 39 | opCounts.addLast(opCount); 40 | times.addLast(time); 41 | } 42 | // the time per addLast operation is the same for N = 1000 and N = 2000. 43 | // due to issues like caching, process switching, branch prediction, 44 | // etc. which you’ll learn about if you take 61C 45 | printTimingTable(Ns, times, opCounts); 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /lab3/timingtest/TimeSLList.java: -------------------------------------------------------------------------------- 1 | package timingtest; 2 | import edu.princeton.cs.algs4.Stopwatch; 3 | 4 | /** 5 | * Created by hug. 6 | */ 7 | public class TimeSLList { 8 | private static void printTimingTable(AList Ns, AList times, AList opCounts) { 9 | System.out.printf("%12s %12s %12s %12s\n", "N", "time (s)", "# ops", "microsec/op"); 10 | System.out.printf("------------------------------------------------------------\n"); 11 | for (int i = 0; i < Ns.size(); i += 1) { 12 | int N = Ns.get(i); 13 | double time = times.get(i); 14 | int opCount = opCounts.get(i); 15 | double timePerOp = time / opCount * 1e6; 16 | System.out.printf("%12d %12.2f %12d %12.2f\n", N, time, opCount, timePerOp); 17 | } 18 | } 19 | 20 | public static void main(String[] args) { 21 | timeGetLast(); 22 | } 23 | 24 | public static void timeGetLast() { 25 | AList Ns = new AList(); 26 | AList times = new AList(); 27 | AList opCounts = new AList(); 28 | int M = 10000; 29 | for (int i = 1000; i <= 128000; i *= 2 ){ 30 | Ns.addLast(i); 31 | SLList testSLList = new SLList(); 32 | for (int j = 0; j < i; j++){ 33 | testSLList.addLast(i); 34 | } 35 | double startTime = System.currentTimeMillis(); 36 | int opCount = 0; 37 | for (int j = 0; j < M; j++){ 38 | testSLList.getLast(); 39 | opCount += 1; 40 | } 41 | double endTime = System.currentTimeMillis(); 42 | double time = (endTime - startTime) / 1000; 43 | opCounts.addLast(opCount); 44 | times.addLast(time); 45 | } 46 | // we must travel all node in SLList to get the last node, 47 | // so getlast() is slow in the big SLList 48 | printTimingTable(Ns, times, opCounts); 49 | } 50 | 51 | } 52 | -------------------------------------------------------------------------------- /lab4/flik/Flik.java: -------------------------------------------------------------------------------- 1 | package flik; 2 | 3 | /** An Integer tester created by Flik Enterprises. 4 | * @author Josh Hug 5 | * */ 6 | public class Flik { 7 | /** @param a Value 1 8 | * @param b Value 2 9 | * @return Whether a and b are the same */ 10 | public static boolean isSameNumber(Integer a, Integer b) { 11 | return a.equals(b) ; 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /lab4/flik/HorribleSteve.java: -------------------------------------------------------------------------------- 1 | package flik; 2 | 3 | public class HorribleSteve { 4 | public static void main(String [] args) throws Exception { 5 | int i = 0; 6 | for (int j = 0; i < 500; ++i, ++j) { 7 | if (!Flik.isSameNumber(i, j)) { 8 | throw new Exception( 9 | String.format("i:%d not same as j:%d ??", i, j)); 10 | } 11 | } 12 | System.out.println("i is " + i); 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /lab4/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 4.0.0 6 | 7 | 8 | CS61B 9 | 61BMasterPom 10 | 1.0-SNAPSHOT 11 | ../library-sp21/javalib/masterpom.xml 12 | 13 | 14 | CS61B 15 | lab4 16 | 1.0-SNAPSHOT 17 | 18 | 19 | ${project.basedir} 20 | ${project.basedir} 21 | 22 | 23 | org.apache.maven.plugins 24 | maven-compiler-plugin 25 | 3.1 26 | 27 | 1.14 28 | 1.14 29 | 30 | 31 | 32 | org.apache.maven.plugins 33 | maven-compiler-plugin 34 | 3.8.1 35 | 36 | 37 | -J-XX:+ShowCodeDetailsInExceptionMessages 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | -------------------------------------------------------------------------------- /lab5/magic_word.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/duilec/CS61B-spring2021/83e75670a7d918309695a88e498700e4eafd7d93/lab5/magic_word.txt -------------------------------------------------------------------------------- /lab5/self_reflection.txt: -------------------------------------------------------------------------------- 1 | You must answer at least 4 questions, but the remaining ones are optional. The main goal of this file is to get you thinking critically about your own work, but we will also use these self reflections at the end of the semester when we do our internal review of the course. 2 | 3 | ArrayDeque: 4 | 5 | Q: Give an example of at least one idea from the staff solution that would have made your solution better (if any). 6 | 7 | A: 8 | 9 | Q: What's something you felt proud of in your code, if anything? 10 | 11 | A: 12 | 13 | Q: What's something that was particularly inelegant in your code, if anything? 14 | 15 | A: 16 | 17 | Q: What did you learn by talking to your partner about writing ArrayDeque? 18 | 19 | A: 20 | 21 | Q: What do you wish you would have known before writing ArrayDeque, if anything? 22 | 23 | A: 24 | 25 | Q: If you wrote ArrayDeque again, what would you do differently, if anything? 26 | 27 | A: 28 | 29 | ----- 30 | 31 | LinkedListDeque: 32 | 33 | Q: Give an example of at least one idea from the staff solution that would have made your solution better (if any). 34 | 35 | A: 36 | 37 | Q: What's something you felt proud of in your code, if anything? 38 | 39 | A: 40 | 41 | Q: What's something that was particularly inelegant in your code, if anything? 42 | 43 | A: 44 | 45 | Q: What did you learn by talking to your partner about writing LinkedListDeque? 46 | 47 | A: 48 | 49 | Q: What do you wish you would have known before writing LinkedListDeque, if anything? 50 | 51 | A: 52 | 53 | Q: If you wrote LinkedListDeque again, what would you do differently, if anything? 54 | 55 | A: 56 | 57 | ----- 58 | 59 | Meta: 60 | 61 | Q: Did you like this design review process? Anything we should do differently next time? 62 | 63 | A: 64 | -------------------------------------------------------------------------------- /lab6/Makefile: -------------------------------------------------------------------------------- 1 | # This makefile is defined to give you the following targets: 2 | # 3 | # default: The default target: Compiles the program in package db61b. 4 | # style: Run our style checker on the project source files. Requires that 5 | # the source files compile. 6 | # check: Compiles the db61b package, if needed, and then performs the 7 | # tests described in testing/Makefile. 8 | # clean: Remove regeneratable files (such as .class files) produced by 9 | # other targets and Emacs backup files. 10 | # 11 | # In other words, type 'make' to compile everything; 'make check' to 12 | # compile and test everything, and 'make clean' to clean things up. 13 | # 14 | # You can use this file without understanding most of it, of course, but 15 | # I strongly recommend that you try to figure it out, and where you cannot, 16 | # that you ask questions. The Lab Reader contains documentation. 17 | 18 | # Name of package containing main procedure 19 | PACKAGE = capers 20 | 21 | # The name of the Python 3 program, used in the 'check' target. If your system 22 | # has a different name for this program (such as just "python"), run 23 | # the Makefile with 24 | # make PYTHON=python check 25 | PYTHON = python3 26 | 27 | # Flags to pass to tester.py. 28 | TESTER_FLAGS = 29 | 30 | RMAKE = "$(MAKE)" 31 | 32 | # Targets that don't correspond to files, but are to be treated as commands. 33 | .PHONY: default check clean 34 | 35 | default: 36 | $(RMAKE) -C $(PACKAGE) default 37 | 38 | check: 39 | $(RMAKE) -C testing PYTHON=$(PYTHON) TESTER_FLAGS="$(TESTER_FLAGS)" check 40 | 41 | # 'make clean' will clean up stuff you can reconstruct. 42 | clean: 43 | $(RM) *~ 44 | $(RMAKE) -C $(PACKAGE) clean 45 | $(RMAKE) -C testing clean 46 | 47 | 48 | -------------------------------------------------------------------------------- /lab6/capers/CapersRepository.java: -------------------------------------------------------------------------------- 1 | package capers; 2 | 3 | import java.io.File; 4 | import java.io.IOException; 5 | 6 | import static capers.Dog.DOG_FOLDER; 7 | import static capers.Utils.readContentsAsString; 8 | import static capers.Utils.writeContents; 9 | 10 | /** A repository for Capers 11 | * @author Huang Jinhong 12 | * The structure of a Capers Repository is as follows: 13 | * 14 | * .capers/ -- top level folder for all persistent data in your lab12 folder 15 | * - dogs/ -- folder containing all of the persistent data for dogs 16 | * - story -- file containing the current story 17 | * 18 | * TODO: change the above structure if you do something different. 19 | */ 20 | public class CapersRepository { 21 | /** Current Working Directory. */ 22 | // "CWD" already exists! 23 | static final File CWD = new File(System.getProperty("user.dir")); 24 | 25 | /** Main metadata folder. */ 26 | static final File CAPERS_FOLDER = Utils.join(CWD,".capers"); 27 | // TODO Hint: look at the `join` function in Utils 28 | static final File STORY_FILE = Utils.join(CAPERS_FOLDER, "story"); 29 | 30 | /** 31 | * Does required filesystem operations to allow for persistence. 32 | * (creates any necessary folders or files) 33 | * Remember: recommended structure (you do not have to follow): 34 | * 35 | * .capers/ -- top level folder for all persistent data in your lab12 folder 36 | * - dogs/ -- folder containing all of the persistent data for dogs 37 | * - story -- file containing the current story 38 | */ 39 | public static void setupPersistence() { 40 | // TODO 41 | if (!CAPERS_FOLDER.exists()){ 42 | CAPERS_FOLDER.mkdir(); 43 | } 44 | if (!DOG_FOLDER.exists()){ 45 | DOG_FOLDER.mkdir(); 46 | } 47 | if (!STORY_FILE.exists()){ 48 | try { 49 | STORY_FILE.createNewFile(); 50 | } catch (IOException e) { 51 | throw new RuntimeException(e); 52 | } 53 | } 54 | } 55 | 56 | /** 57 | * Appends the first non-command argument in args 58 | * to a file called `story` in the .capers directory. 59 | * @param text String of the text to be appended to the story 60 | */ 61 | public static void writeStory(String text) { 62 | // TODO 63 | String currentText = readContentsAsString(STORY_FILE); 64 | if (currentText.equals("")) { 65 | currentText = text; 66 | } else { 67 | currentText = currentText.concat("\n" + text); 68 | } 69 | // read guide of lab one by one! 70 | // it is *writeContents()* NOT writeObject()! 71 | writeContents(STORY_FILE, currentText); 72 | System.out.println(currentText); 73 | } 74 | 75 | /** 76 | * Creates and persistently saves a dog using the first 77 | * three non-command arguments of args (name, breed, age). 78 | * Also prints out the dog's information using toString(). 79 | */ 80 | public static void makeDog(String name, String breed, int age) { 81 | // TODO 82 | Dog dog = new Dog(name, breed, age); 83 | dog.saveDog(); 84 | System.out.println(dog); 85 | } 86 | 87 | /** 88 | * Advances a dog's age persistently and prints out a celebratory message. 89 | * Also prints out the dog's information using toString(). 90 | * Chooses dog to advance based on the first non-command argument of args. 91 | * @param name String name of the Dog whose birthday we're celebrating. 92 | */ 93 | public static void celebrateBirthday(String name) { 94 | Dog dog = Dog.fromFile(name); 95 | dog.haveBirthday(); 96 | // you should call saveDog(), after adding 1 to dog.age in haveBirthday() 97 | dog.saveDog(); 98 | } 99 | } 100 | -------------------------------------------------------------------------------- /lab6/capers/Dog.java: -------------------------------------------------------------------------------- 1 | package capers; 2 | 3 | import java.io.File; 4 | import java.io.Serializable; 5 | 6 | import static capers.Utils.*; 7 | 8 | /** Represents a dog that can be serialized. 9 | * @author Huang Jinhong 10 | */ 11 | 12 | // read guide of lab one by one! 13 | // To enable this feature(Serializable) for a given class in Java, 14 | // this simply involves implementing the java.io.Serializable interface 15 | public class Dog implements Serializable{ // TODO 16 | 17 | /** Folder that dogs live in. */ 18 | // TODO Hint: look at the `join` function in Utils 19 | static final File DOG_FOLDER = join(".capers", "dogs");; 20 | 21 | /** Age of dog. */ 22 | private int age; 23 | /** Breed of dog. */ 24 | private String breed; 25 | /** Name of dog. */ 26 | private String name; 27 | 28 | /** 29 | * Creates a dog object with the specified parameters. 30 | * @param name Name of dog 31 | * @param breed Breed of dog 32 | * @param age Age of dog 33 | */ 34 | public Dog(String name, String breed, int age) { 35 | this.age = age; 36 | this.breed = breed; 37 | this.name = name; 38 | } 39 | 40 | /** 41 | * Reads in and deserializes a dog from a file with name NAME in DOG_FOLDER. 42 | * 43 | * @param name Name of dog to load 44 | * @return Dog read from file 45 | */ 46 | public static Dog fromFile(String name) { 47 | // TODO (hint: look at the Utils file) 48 | File DOG_FILE = join(DOG_FOLDER, name); 49 | // or use: File DOG_FILE = join(".capers", "dogs", name); 50 | // class Dog must "implements Serializable" 51 | return readObject(DOG_FILE, Dog.class); 52 | } 53 | 54 | /** 55 | * Increases a dog's age and celebrates! 56 | */ 57 | public void haveBirthday() { 58 | age += 1; 59 | System.out.println(toString()); 60 | System.out.println("Happy birthday! Woof! Woof!"); 61 | } 62 | 63 | /** 64 | * Saves a dog to a file for future use. 65 | */ 66 | public void saveDog() { 67 | // TODO (hint: don't forget dog names are unique) 68 | File DOG_FILE = join(DOG_FOLDER, name); 69 | // class Dog "implements Serializable" in class Dog 70 | writeObject(DOG_FILE, this); 71 | } 72 | 73 | @Override 74 | public String toString() { 75 | return String.format( 76 | "Woof! My name is %s and I am a %s! I am %d years old! Woof!", 77 | name, breed, age); 78 | } 79 | 80 | } 81 | 82 | 83 | -------------------------------------------------------------------------------- /lab6/capers/Main.java: -------------------------------------------------------------------------------- 1 | package capers; 2 | 3 | import static capers.Utils.exitWithError; 4 | 5 | /** Canine Capers: A Gitlet Prelude. 6 | * @author Huang Jinhong 7 | */ 8 | public class Main { 9 | /** 10 | * Runs one of three commands: 11 | * story [text] -- Appends "text" + a newline to a story file in the 12 | * .capers directory. Additionally, prints out the 13 | * current story. 14 | * 15 | * dog [name] [breed] [age] -- Persistently creates a dog with 16 | * the specified parameters; should also print 17 | * the dog's toString(). Assume dog names are 18 | * unique. 19 | * 20 | * birthday [name] -- Advances a dog's age persistently 21 | * and prints out a celebratory message. 22 | * 23 | * All persistent data should be stored in a ".capers" 24 | * directory in the current working directory. 25 | * 26 | * Recommended structure (you do not have to follow): 27 | * 28 | * *YOU SHOULD NOT CREATE THESE MANUALLY, 29 | * YOUR PROGRAM SHOULD CREATE THESE FOLDERS/FILES* 30 | * 31 | * .capers/ -- top level folder for all persistent data in your lab12 folder 32 | * - dogs/ -- folder containing all of the persistent data for dogs 33 | * - story -- file containing the current story 34 | * 35 | * @param args arguments from the command line 36 | */ 37 | public static void main(String[] args) { 38 | if (args.length == 0) { 39 | Utils.exitWithError("Must have at least one argument"); 40 | } 41 | // System.out.println("args: " + Arrays.toString(args)); 42 | 43 | CapersRepository.setupPersistence(); 44 | String text; 45 | switch (args[0]) { 46 | case "story": 47 | /* This call has been handled for you. The rest will be similar. */ 48 | validateNumArgs("story", args, 2); 49 | text = args[1]; 50 | CapersRepository.writeStory(text); 51 | break; 52 | case "dog": 53 | validateNumArgs("dog", args, 4); 54 | // TODO: make a dog 55 | String name = args[1]; 56 | String breed = args[2]; 57 | int age = Integer.parseInt(args[3]); 58 | CapersRepository.makeDog(name, breed, age); 59 | break; 60 | case "birthday": 61 | validateNumArgs("birthday", args, 2); 62 | // TODO: celebrate this dog's birthday 63 | name = args[1]; 64 | CapersRepository.celebrateBirthday(name); 65 | break; 66 | default: 67 | exitWithError(String.format("Unknown command: %s", args[0])); 68 | } 69 | return; 70 | } 71 | 72 | /** 73 | * Checks the number of arguments versus the expected number, 74 | * throws a RuntimeException if they do not match. 75 | * 76 | * @param cmd Name of command you are validating 77 | * @param args Argument array from command line 78 | * @param n Number of expected arguments 79 | */ 80 | public static void validateNumArgs(String cmd, String[] args, int n) { 81 | if (args.length != n) { 82 | throw new RuntimeException( 83 | String.format("Invalid number of arguments for: %s.", cmd)); 84 | } 85 | } 86 | } 87 | -------------------------------------------------------------------------------- /lab6/capers/Makefile: -------------------------------------------------------------------------------- 1 | # This makefile is defined to give you the following targets: 2 | # 3 | # default: The default target: Compiles $(PROG) and whatever it 4 | # depends on. 5 | # style: Run our style checker on the project source files. Requires that 6 | # the source files compile. 7 | # check: Compile $(PROG), if needed, and then for each file, F.in, in 8 | # directory testing, use F.in as input to "java $(MAIN_CLASS)" and 9 | # compare the output to the contents of the file names F.out. 10 | # Report discrepencies. 11 | # clean: Remove all the .class files produced by java compilation, 12 | # all Emacs backup files, and testing output files. 13 | # 14 | # In other words, type 'gmake' to compile everything; 'gmake check' to 15 | # compile and test everything, and 'gmake clean' to clean things up. 16 | # 17 | # You can use this file without understanding most of it, of course, but 18 | # I strongly recommend that you try to figure it out, and where you cannot, 19 | # that you ask questions. The Lab Reader contains documentation. 20 | 21 | STYLEPROG = style61b 22 | 23 | JFLAGS = -g -Xlint:unchecked -Xlint:deprecation 24 | 25 | CLASSDIR = ../classes 26 | 27 | # See comment in ../Makefile 28 | PYTHON = python3 29 | 30 | RMAKE = "$(MAKE)" 31 | 32 | # A CLASSPATH value that (seems) to work on both Windows and Unix systems. 33 | # To Unix, it looks like ..:$(CLASSPATH):JUNK and to Windows like 34 | # JUNK;..;$(CLASSPATH). 35 | CPATH = "..:$(CLASSPATH):;..;$(CLASSPATH)" 36 | 37 | # All .java files in this directory. 38 | SRCS := $(wildcard *.java) 39 | 40 | .PHONY: default check clean style 41 | 42 | # As a convenience, you can compile a single Java file X.java in this directory 43 | # with 'make X.class' 44 | %.class: %.java 45 | javac $(JFLAGS) -cp $(CPATH) $< 46 | 47 | # First, and therefore default, target. 48 | default: sentinel 49 | 50 | style: default 51 | $(STYLEPROG) $(SRCS) 52 | 53 | check: 54 | $(RMAKE) -C .. PYTHON=$(PYTHON) check 55 | 56 | integration: 57 | $(RMAKE) -C .. PYTHON=$(PYTHON) integration 58 | 59 | # 'make clean' will clean up stuff you can reconstruct. 60 | clean: 61 | $(RM) *~ *.class sentinel 62 | 63 | ### DEPENDENCIES ### 64 | 65 | sentinel: $(SRCS) 66 | javac $(JFLAGS) -cp $(CPATH) $(SRCS) 67 | touch sentinel 68 | -------------------------------------------------------------------------------- /lab6/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 4.0.0 6 | 7 | 8 | CS61B 9 | 61BMasterPom 10 | 1.0-SNAPSHOT 11 | ../library-sp21/javalib/masterpom.xml 12 | 13 | 14 | CS61B 15 | lab6 16 | 1.0-SNAPSHOT 17 | 18 | 19 | ${project.basedir} 20 | ${project.basedir} 21 | 22 | 23 | org.apache.maven.plugins 24 | maven-compiler-plugin 25 | 3.1 26 | 27 | 7 28 | 7 29 | 30 | 31 | 32 | org.apache.maven.plugins 33 | maven-compiler-plugin 34 | 3.8.1 35 | 36 | 37 | -J-XX:+ShowCodeDetailsInExceptionMessages 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | -------------------------------------------------------------------------------- /lab6/testing/Makefile: -------------------------------------------------------------------------------- 1 | # This makefile is defined to give you the following targets: 2 | # 3 | # default: Same as check 4 | # check: 5 | # clean: Remove all files and directories generated by testing. 6 | # 7 | 8 | SHELL = /bin/bash 9 | 10 | # Flags to Java interpreter: check assertions 11 | JFLAGS = -ea 12 | 13 | # See comment in ../Makefile 14 | PYTHON = python3 15 | 16 | RMAKE = "$(MAKE)" 17 | 18 | TESTER = $(PYTHON) tester.py 19 | 20 | TESTER_FLAGS = 21 | 22 | SRCDIR = our-src 23 | 24 | TESTS = our/*.in 25 | 26 | .PHONY: default check clean std 27 | 28 | # First, and therefore default, target. 29 | default: 30 | $(RMAKE) -C .. 31 | $(RMAKE) PYTHON=$(PYTHON) check 32 | 33 | check: 34 | @CLASSPATH=..:$(CLASSPATH) java -ea capers.Main >/dev/null 2>&1 || true 35 | @echo "Testing application capers.Main..." 36 | $(TESTER) $(TESTER_FLAGS) --src=$(SRCDIR) $(TESTS) 37 | 38 | # 'make clean' will clean up stuff you can reconstruct. 39 | clean: 40 | $(RM) -r */*~ *~ __pycache__ 41 | -------------------------------------------------------------------------------- /lab6/testing/our/test01-basic-story.in: -------------------------------------------------------------------------------- 1 | # A single use of the `story` command 2 | > story "hello world" 3 | hello world 4 | <<< 5 | -------------------------------------------------------------------------------- /lab6/testing/our/test02-two-part-story.in: -------------------------------------------------------------------------------- 1 | # Two uses of the `story` command 2 | > story "Hello" 3 | Hello 4 | <<< 5 | > story "World" 6 | Hello 7 | World 8 | <<< 9 | -------------------------------------------------------------------------------- /lab6/testing/our/test03-basic-dog.in: -------------------------------------------------------------------------------- 1 | # A single use of the `dog` command 2 | > dog Fido dalmation 3 3 | Woof! My name is Fido and I am a dalmation! I am 3 years old! Woof! 4 | <<< 5 | -------------------------------------------------------------------------------- /lab6/testing/our/test04-dog-birthday.in: -------------------------------------------------------------------------------- 1 | # Uses the `dog` command in coordination with the `birthday` command 2 | > dog Scruffy poodle 1 3 | Woof! My name is Scruffy and I am a poodle! I am 1 years old! Woof! 4 | <<< 5 | > birthday Scruffy 6 | Woof! My name is Scruffy and I am a poodle! I am 2 years old! Woof! 7 | Happy birthday! Woof! Woof! 8 | <<< 9 | -------------------------------------------------------------------------------- /lab6/testing/our/test05-two-dogs.in: -------------------------------------------------------------------------------- 1 | # Uses the `dog` command twice 2 | > dog Sparky labrador 2 3 | Woof! My name is Sparky and I am a labrador! I am 2 years old! Woof! 4 | <<< 5 | > dog Dash labradoodle 1 6 | Woof! My name is Dash and I am a labradoodle! I am 1 years old! Woof! 7 | <<< 8 | -------------------------------------------------------------------------------- /lab6/testing/our/test06-two-birthdays.in: -------------------------------------------------------------------------------- 1 | # Uses the `dog` command twice and also the `birthday` command twice 2 | > dog Sparky labrador 2 3 | Woof! My name is Sparky and I am a labrador! I am 2 years old! Woof! 4 | <<< 5 | > dog Dash labradoodle 1 6 | Woof! My name is Dash and I am a labradoodle! I am 1 years old! Woof! 7 | <<< 8 | > birthday Dash 9 | Woof! My name is Dash and I am a labradoodle! I am 2 years old! Woof! 10 | Happy birthday! Woof! Woof! 11 | <<< 12 | > birthday Sparky 13 | Woof! My name is Sparky and I am a labrador! I am 3 years old! Woof! 14 | Happy birthday! Woof! Woof! 15 | <<< 16 | -------------------------------------------------------------------------------- /lab6/testing/our/test07-one-dog-two-birthdays.in: -------------------------------------------------------------------------------- 1 | # (UNGRADED) Uses the `dog` command once and also the `birthday` command twice 2 | > dog Boofy labradoodle 2 3 | Woof! My name is Boofy and I am a labradoodle! I am 2 years old! Woof! 4 | <<< 5 | > birthday Boofy 6 | Woof! My name is Boofy and I am a labradoodle! I am 3 years old! Woof! 7 | Happy birthday! Woof! Woof! 8 | <<< 9 | > birthday Boofy 10 | Woof! My name is Boofy and I am a labradoodle! I am 4 years old! Woof! 11 | Happy birthday! Woof! Woof! 12 | <<< 13 | -------------------------------------------------------------------------------- /lab7/bstmap/Map61B.java: -------------------------------------------------------------------------------- 1 | package bstmap; 2 | 3 | import java.util.Set; 4 | 5 | /* Your implementation BSTMap should implement this interface. To do so, 6 | * append "implements Map61B" to the end of your "public class..." 7 | * declaration, though you can use other formal type parameters if you'd like. 8 | */ 9 | public interface Map61B extends Iterable { 10 | 11 | /** Removes all of the mappings from this map. */ 12 | void clear(); 13 | 14 | /* Returns true if this map contains a mapping for the specified key. */ 15 | boolean containsKey(K key); 16 | 17 | /* Returns the value to which the specified key is mapped, or null if this 18 | * map contains no mapping for the key. 19 | */ 20 | V get(K key); 21 | 22 | /* Returns the number of key-value mappings in this map. */ 23 | int size(); 24 | 25 | /* Associates the specified value with the specified key in this map. */ 26 | void put(K key, V value); 27 | 28 | /* Returns a Set view of the keys contained in this map. Not required for Lab 7. 29 | * If you don't implement this, throw an UnsupportedOperationException. */ 30 | Set keySet(); 31 | 32 | /* Removes the mapping for the specified key from this map if present. 33 | * Not required for Lab 7. If you don't implement this, throw an 34 | * UnsupportedOperationException. */ 35 | V remove(K key); 36 | 37 | /* Removes the entry for the specified key only if it is currently mapped to 38 | * the specified value. Not required for Lab 7. If you don't implement this, 39 | * throw an UnsupportedOperationException.*/ 40 | V remove(K key, V value); 41 | 42 | } 43 | -------------------------------------------------------------------------------- /lab7/bstmap/StringUtils.java: -------------------------------------------------------------------------------- 1 | package bstmap; 2 | 3 | import java.util.regex.Pattern; 4 | import java.util.Random; 5 | 6 | /** Utility function for Strings. 7 | * @author Josh Hug 8 | */ 9 | public class StringUtils { 10 | /** To get the style checker to be quiet. */ 11 | private static final int ALPHABET_SIZE = 26; 12 | 13 | /** Random number generator for this class. */ 14 | private static Random r = new Random(); 15 | 16 | /** Sets random seed to L so that results of randomString are predictable.*/ 17 | public static void setSeed(long l) { 18 | r = new Random(l); 19 | } 20 | 21 | /** Returns the next random string of length LENGTH. */ 22 | public static String randomString(int length) { 23 | char[] someChars = new char[length]; 24 | for (int i = 0; i < length; i++) { 25 | someChars[i] = (char) (r.nextInt(ALPHABET_SIZE) + 'a'); 26 | } 27 | return new String(someChars); 28 | } 29 | 30 | /** Returns true if string S consists of characters between 31 | * 'a' and 'z' only. No spaces, numbers, upper-case, or any other 32 | * characters are allowed. 33 | */ 34 | public static boolean isLowerCase(String s) { 35 | return Pattern.matches("[a-z]*", s); 36 | } 37 | 38 | /** Returns the string that comes right after S in alphabetical order. 39 | * For example, if s is 'potato', this method will return 'potatp'. If 40 | * the last character is a z, then we add to the next position, and so 41 | * on. 42 | */ 43 | public static String nextString(String s) { 44 | /* Handle all zs as a special case to keep helper method simple. */ 45 | if (isAllzs(s)) { 46 | return allAs(s.length() + 1); 47 | } 48 | char[] charVersion = s.toCharArray(); 49 | incrementCharArray(charVersion, charVersion.length - 1); 50 | return new String(charVersion); 51 | } 52 | 53 | /** Helper function for nextString. Increments the Pth position of X 54 | * by one, wrapping around to 'a' if p == 'z'. If wraparound occurs, 55 | * then we need to carry the one, and we increment position P - 1. 56 | * 57 | * Will fail for a character array containing only zs. 58 | */ 59 | private static void incrementCharArray(char [] x, int p) { 60 | if (x[p] != 'z') { 61 | x[p] += 1; 62 | } else { 63 | x[p] = 'a'; 64 | incrementCharArray(x, p - 1); 65 | } 66 | } 67 | 68 | /** Returns a string of all 'a' of length LEN. */ 69 | private static String allAs(int len) { 70 | StringBuilder sb = new StringBuilder(); 71 | for (int i = 0; i < len; i++) { 72 | sb.append('a'); 73 | } 74 | return sb.toString(); 75 | } 76 | 77 | /** Returns true if S is all 'z'. False for empty strings */ 78 | public static boolean isAllzs(String s) { 79 | return Pattern.matches("[z]+", s); 80 | } 81 | 82 | } 83 | -------------------------------------------------------------------------------- /lab7/bstmap/TestBSTMap.java: -------------------------------------------------------------------------------- 1 | package bstmap; 2 | 3 | import static org.junit.Assert.*; 4 | import org.junit.Test; 5 | 6 | import java.util.Random; 7 | 8 | /** Tests by Brendan Hu, Spring 2015, revised for 2016 by Josh Hug */ 9 | public class TestBSTMap { 10 | 11 | @Test 12 | public void sanityGenericsTest() { 13 | try { 14 | BSTMap a = new BSTMap(); 15 | BSTMap b = new BSTMap(); 16 | BSTMap c = new BSTMap(); 17 | BSTMap e = new BSTMap(); 18 | } catch (Exception e) { 19 | fail(); 20 | } 21 | } 22 | 23 | //assumes put/size/containsKey/get work 24 | @Test 25 | public void sanityClearTest() { 26 | BSTMap b = new BSTMap(); 27 | for (int i = 0; i < 455; i++) { 28 | b.put("hi" + i, 1+i); 29 | //make sure put is working via containsKey and get 30 | assertTrue( null != b.get("hi" + i) && (b.get("hi"+i).equals(1+i)) 31 | && b.containsKey("hi" + i)); 32 | } 33 | assertEquals(455, b.size()); 34 | b.clear(); 35 | assertEquals(0, b.size()); 36 | for (int i = 0; i < 455; i++) { 37 | assertTrue(null == b.get("hi" + i) && !b.containsKey("hi" + i)); 38 | } 39 | } 40 | 41 | // assumes put works 42 | @Test 43 | public void sanityContainsKeyTest() { 44 | BSTMap b = new BSTMap(); 45 | assertFalse(b.containsKey("waterYouDoingHere")); 46 | b.put("waterYouDoingHere", 0); 47 | assertTrue(b.containsKey("waterYouDoingHere")); 48 | } 49 | 50 | // assumes put works 51 | @Test 52 | public void sanityGetTest() { 53 | BSTMap b = new BSTMap(); 54 | assertEquals(null,b.get("starChild")); 55 | assertEquals(0, b.size()); 56 | b.put("starChild", 5); 57 | assertTrue(((Integer) b.get("starChild")).equals(5)); 58 | b.put("KISS", 5); 59 | assertTrue(((Integer) b.get("KISS")).equals(5)); 60 | assertNotEquals(null,b.get("starChild")); 61 | assertEquals(2, b.size()); 62 | } 63 | 64 | // assumes put works 65 | @Test 66 | public void sanitySizeTest() { 67 | BSTMap b = new BSTMap(); 68 | assertEquals(0, b.size()); 69 | b.put("hi", 1); 70 | assertEquals(1, b.size()); 71 | for (int i = 0; i < 455; i++) 72 | b.put("hi" + i, 1); 73 | assertEquals(456, b.size()); 74 | } 75 | 76 | //assumes get/containskey work 77 | @Test 78 | public void sanityPutTest() { 79 | BSTMap b = new BSTMap(); 80 | b.put("hi", 1); 81 | assertTrue(b.containsKey("hi") && b.get("hi") != null); 82 | } 83 | 84 | //assumes put works 85 | @Test 86 | public void containsKeyNullTest() { 87 | BSTMap b = new BSTMap(); 88 | b.put("hi", null); 89 | assertTrue(b.containsKey("hi")); 90 | } 91 | 92 | @Test 93 | public void printTest(){ 94 | BSTMap b = new BSTMap(); 95 | for (int i = 0; i < 455; i++) { 96 | Random rnd = new Random(); 97 | int num = rnd.nextInt(1000); 98 | b.put(num, i); 99 | } 100 | b.printInOrder(); 101 | } 102 | } 103 | -------------------------------------------------------------------------------- /lab7/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 4.0.0 6 | 7 | 8 | CS61B 9 | 61BMasterPom 10 | 1.0-SNAPSHOT 11 | ../library-sp21/javalib/masterpom.xml 12 | 13 | 14 | CS61B 15 | lab7 16 | 1.0-SNAPSHOT 17 | 18 | 19 | ${project.basedir} 20 | ${project.basedir} 21 | 22 | 23 | org.apache.maven.plugins 24 | maven-compiler-plugin 25 | 3.1 26 | 27 | 1.14 28 | 1.14 29 | 30 | 31 | 32 | org.apache.maven.plugins 33 | maven-compiler-plugin 34 | 3.8.1 35 | 36 | 37 | -J-XX:+ShowCodeDetailsInExceptionMessages 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | -------------------------------------------------------------------------------- /lab7/speedTestResults.txt: -------------------------------------------------------------------------------- 1 | /* InOrder */ 2 | This program inserts lexicographically increasing Strings into Maps as pairs. 3 | 4 | Enter # strings to insert into the maps: 1000 5 | class bstmap.ULLMap: 0.02 sec 6 | class bstmap.BSTMap: 0.02 sec 7 | Java's Built-in TreeMap: 0.00 sec 8 | Java's Built-in HashMap: 0.00 sec 9 | Would you like to try more timed-tests? (y/n): y 10 | 11 | Enter # strings to insert into the maps: 10000 12 | class bstmap.ULLMap: 0.92 sec 13 | class bstmap.BSTMap: 1.04 sec 14 | Java's Built-in TreeMap: 0.01 sec 15 | Java's Built-in HashMap: 0.01 sec 16 | Would you like to try more timed-tests? (y/n): y 17 | 18 | Enter # strings to insert into the maps: 100000 19 | --Stack Overflow -- couldn't add 100000 strings. 20 | --Stack Overflow -- couldn't add 100000 strings. 21 | Java's Built-in TreeMap: 0.08 sec 22 | Java's Built-in HashMap: 0.04 sec 23 | Would you like to try more timed-tests? (y/n): n 24 | 25 | Process finished with exit code 0 26 | 27 | /* Random */ 28 | This program inserts random Strings of length L into different types of maps as pairs. 29 | Please enter desired length of each string: 10 30 | 31 | Enter # strings to insert into the maps: 1000 32 | class bstmap.ULLMap: 0.01 sec 33 | class bstmap.BSTMap: 0.00 sec 34 | Java's Built-in TreeMap: 0.00 sec 35 | Java's Built-in HashMap: 0.00 sec 36 | Would you like to try more timed-tests? (y/n)y 37 | 38 | Enter # strings to insert into the maps: 10000 39 | class bstmap.ULLMap: 0.38 sec 40 | class bstmap.BSTMap: 0.01 sec 41 | Java's Built-in TreeMap: 0.01 sec 42 | Java's Built-in HashMap: 0.00 sec 43 | Would you like to try more timed-tests? (y/n)y 44 | 45 | Enter # strings to insert into the maps: 100000 46 | --Stack Overflow -- couldn't add 100000 strings of length 10. 47 | class bstmap.BSTMap: 0.10 sec 48 | Java's Built-in TreeMap: 0.10 sec 49 | Java's Built-in HashMap: 0.03 sec 50 | Would you like to try more timed-tests? (y/n)y 51 | 52 | Enter # strings to insert into the maps: 1000000 53 | --Stack Overflow -- couldn't add 1000000 strings of length 10. 54 | class bstmap.BSTMap: 1.74 sec 55 | Java's Built-in TreeMap: 0.94 sec 56 | Java's Built-in HashMap: 0.44 sec 57 | Would you like to try more timed-tests? (y/n)n 58 | 59 | Process finished with exit code 0 60 | 61 | -------------------------------------------------------------------------------- /lab8/hashmap/Map61B.java: -------------------------------------------------------------------------------- 1 | package hashmap; 2 | 3 | import java.util.Set; 4 | /** 5 | * Your implementation hashmap.MyHashMap should implement this interface. To do so, 6 | * append "implements hashmap.Map61B" to the end of your "public class..." 7 | * declaration, though you can use other formal type parameters if you'd like. 8 | */ 9 | public interface Map61B extends Iterable { 10 | /** Removes all of the mappings from this map. */ 11 | void clear(); 12 | 13 | /** Returns true if this map contains a mapping for the specified key. */ 14 | boolean containsKey(K key); 15 | 16 | /** 17 | * Returns the value to which the specified key is mapped, or null if this 18 | * map contains no mapping for the key. 19 | */ 20 | V get(K key); 21 | 22 | /** Returns the number of key-value mappings in this map. */ 23 | int size(); 24 | 25 | /** 26 | * Associates the specified value with the specified key in this map. 27 | * If the map previously contained a mapping for the key, 28 | * the old value is replaced. 29 | */ 30 | void put(K key, V value); 31 | 32 | /** Returns a Set view of the keys contained in this map. */ 33 | Set keySet(); 34 | 35 | /** 36 | * Removes the mapping for the specified key from this map if present. 37 | * Not required for Lab 8. If you don't implement this, throw an 38 | * UnsupportedOperationException. 39 | */ 40 | V remove(K key); 41 | 42 | /** 43 | * Removes the entry for the specified key only if it is currently mapped to 44 | * the specified value. Not required for Lab 8. If you don't implement this, 45 | * throw an UnsupportedOperationException. 46 | */ 47 | V remove(K key, V value); 48 | } 49 | 50 | -------------------------------------------------------------------------------- /lab8/hashmap/MyHashMapALBuckets.java: -------------------------------------------------------------------------------- 1 | package hashmap; 2 | 3 | import java.util.ArrayList; 4 | import java.util.Collection; 5 | 6 | /** 7 | * Hash Table with Array List buckets 8 | * @author Neil Kulkarni 9 | */ 10 | public class MyHashMapALBuckets extends MyHashMap { 11 | 12 | /** 13 | * Constructor that creates a backing array with default 14 | * initial size and load factor 15 | */ 16 | public MyHashMapALBuckets() { 17 | super(); 18 | } 19 | 20 | /** 21 | * Constructor that creates a backing array of initialSize 22 | * and default load factor 23 | * 24 | * @param initialSize initial size of backing array 25 | */ 26 | public MyHashMapALBuckets(int initialSize) { 27 | super(initialSize); 28 | } 29 | 30 | /** 31 | * Constructor that creates a backing array of initialSize. 32 | * The load factor (# items / # buckets) should always be <= loadFactor 33 | * 34 | * @param initialSize initial size of backing array 35 | * @param maxLoad maximum load factor 36 | */ 37 | public MyHashMapALBuckets(int initialSize, double maxLoad) { 38 | super(initialSize, maxLoad); 39 | } 40 | 41 | @Override 42 | protected Collection createBucket() { 43 | return new ArrayList<>(); 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /lab8/hashmap/MyHashMapHSBuckets.java: -------------------------------------------------------------------------------- 1 | package hashmap; 2 | 3 | import java.util.HashSet; 4 | import java.util.Collection; 5 | 6 | /** 7 | * Hash Table with buckets that are Hash Sets (trippy!) 8 | * @author Neil Kulkarni 9 | */ 10 | public class MyHashMapHSBuckets extends MyHashMap { 11 | 12 | /** 13 | * Constructor that creates a backing array with default 14 | * initial size and load factor 15 | */ 16 | public MyHashMapHSBuckets() { 17 | super(); 18 | } 19 | 20 | /** 21 | * Constructor that creates a backing array of initialSize 22 | * and default load factor 23 | * 24 | * @param initialSize initial size of backing array 25 | */ 26 | public MyHashMapHSBuckets(int initialSize) { 27 | super(initialSize); 28 | } 29 | 30 | /** 31 | * Constructor that creates a backing array of initialSize. 32 | * The load factor (# items / # buckets) should always be <= loadFactor 33 | * 34 | * @param initialSize initial size of backing array 35 | * @param maxLoad maximum load factor 36 | */ 37 | public MyHashMapHSBuckets(int initialSize, double maxLoad) { 38 | super(initialSize, maxLoad); 39 | } 40 | 41 | @Override 42 | protected Collection createBucket() { 43 | return new HashSet<>(); 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /lab8/hashmap/MyHashMapLLBuckets.java: -------------------------------------------------------------------------------- 1 | package hashmap; 2 | 3 | import java.util.LinkedList; 4 | import java.util.Collection; 5 | 6 | /** 7 | * Hash Table with Linked List buckets 8 | * @author Neil Kulkarni 9 | */ 10 | public class MyHashMapLLBuckets extends MyHashMap { 11 | 12 | /** 13 | * Constructor that creates a backing array with default 14 | * initial size and load factor 15 | */ 16 | public MyHashMapLLBuckets() { 17 | super(); 18 | } 19 | 20 | /** 21 | * Constructor that creates a backing array of initialSize 22 | * and default load factor 23 | * 24 | * @param initialSize initial size of backing array 25 | */ 26 | public MyHashMapLLBuckets(int initialSize) { 27 | super(initialSize); 28 | } 29 | 30 | /** 31 | * Constructor that creates a backing array of initialSize. 32 | * The load factor (# items / # buckets) should always be <= loadFactor 33 | * 34 | * @param initialSize initial size of backing array 35 | * @param maxLoad maximum load factor 36 | */ 37 | public MyHashMapLLBuckets(int initialSize, double maxLoad) { 38 | super(initialSize, maxLoad); 39 | } 40 | 41 | @Override 42 | protected Collection createBucket() { 43 | return new LinkedList<>(); 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /lab8/hashmap/MyHashMapPQBuckets.java: -------------------------------------------------------------------------------- 1 | package hashmap; 2 | 3 | import java.util.Collection; 4 | import java.util.Comparator; 5 | import java.util.PriorityQueue; 6 | 7 | /** 8 | * Hash Table with Priority Queue buckets 9 | * Elements of priority queues need to be comparable, so we restrict our map to 10 | * only allow comparable keys 11 | * 12 | * @author Neil Kulkarni 13 | */ 14 | public class MyHashMapPQBuckets, V> extends MyHashMap { 15 | 16 | /** 17 | * Constructor that creates a backing array with default 18 | * initial size and load factor 19 | */ 20 | public MyHashMapPQBuckets() { 21 | super(); 22 | } 23 | 24 | /** 25 | * Constructor that creates a backing array of initialSize 26 | * and default load factor 27 | * 28 | * @param initialSize initial size of backing array 29 | */ 30 | public MyHashMapPQBuckets(int initialSize) { 31 | super(initialSize); 32 | } 33 | 34 | /** 35 | * Constructor that creates a backing array of initialSize. 36 | * The load factor (# items / # buckets) should always be <= loadFactor 37 | * 38 | * @param initialSize initial size of backing array 39 | * @param maxLoad maximum load factor 40 | */ 41 | public MyHashMapPQBuckets(int initialSize, double maxLoad) { 42 | super(initialSize, maxLoad); 43 | } 44 | 45 | @Override 46 | protected Collection createBucket() { 47 | // This is fancy new-fangled Java that says in plain English: 48 | // 49 | // "Build a PriorityQueue of Nodes, and when you compare two Nodes, 50 | // compare their keys by their key's compareTo method" 51 | // 52 | // Remember, we had K extends Comparable in our class header, 53 | // so we know the keys have implemented a compareTo method 54 | return new PriorityQueue<>(Comparator.comparing(a -> a.key)); 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /lab8/hashmap/MyHashMapTSBuckets.java: -------------------------------------------------------------------------------- 1 | package hashmap; 2 | 3 | import java.util.Collection; 4 | import java.util.Comparator; 5 | import java.util.TreeSet; 6 | 7 | /** 8 | * Hash Table with Tree Set buckets 9 | * Elements of tree sets need to be comparable, so we restrict our map to 10 | * only allow comparable keys 11 | * 12 | * @author Neil Kulkarni 13 | */ 14 | public class MyHashMapTSBuckets, V> extends MyHashMap { 15 | 16 | /** 17 | * Constructor that creates a backing array with default 18 | * initial size and load factor 19 | */ 20 | public MyHashMapTSBuckets() { 21 | super(); 22 | } 23 | 24 | /** 25 | * Constructor that creates a backing array of initialSize 26 | * and default load factor 27 | * 28 | * @param initialSize initial size of backing array 29 | */ 30 | public MyHashMapTSBuckets(int initialSize) { 31 | super(initialSize); 32 | } 33 | 34 | /** 35 | * Constructor that creates a backing array of initialSize. 36 | * The load factor (# items / # buckets) should always be <= loadFactor 37 | * 38 | * @param initialSize initial size of backing array 39 | * @param maxLoad maximum load factor 40 | */ 41 | public MyHashMapTSBuckets(int initialSize, double maxLoad) { 42 | super(initialSize, maxLoad); 43 | } 44 | 45 | @Override 46 | protected Collection createBucket() { 47 | // This is fancy new-fangled Java that says in plain English: 48 | // 49 | // "Build a TreeSet of Nodes, and when you compare two Nodes, 50 | // compare their keys by their key's compareTo method" 51 | // 52 | // Remember, we had K extends Comparable in our class header, 53 | // so we know the keys have implemented a compareTo method 54 | return new TreeSet<>(Comparator.comparing(a -> a.key)); 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /lab8/hashmap/TestMyHashMapExtra.java: -------------------------------------------------------------------------------- 1 | package hashmap; 2 | 3 | import static org.junit.Assert.*; 4 | import org.junit.Test; 5 | 6 | /** Tests of optional parts of lab 8. */ 7 | public class TestMyHashMapExtra { 8 | 9 | @Test 10 | public void testRemove() { 11 | MyHashMap q = new MyHashMap<>(); 12 | q.put("c", "a"); 13 | q.put("b", "a"); 14 | q.put("a", "a"); 15 | q.put("d", "a"); 16 | q.put("e", "a"); // a b c d e 17 | assertTrue(null != q.remove("c")); 18 | assertFalse(q.containsKey("c")); 19 | assertTrue(q.containsKey("a")); 20 | assertTrue(q.containsKey("b")); 21 | assertTrue(q.containsKey("d")); 22 | assertTrue(q.containsKey("e")); 23 | } 24 | 25 | /** 26 | * Remove Test 2 27 | * Test the 3 different cases of remove 28 | */ 29 | @Test 30 | public void testRemoveThreeCases() { 31 | MyHashMap q = new MyHashMap<>(); 32 | q.put("c", "a"); 33 | q.put("b", "a"); 34 | q.put("a", "a"); 35 | q.put("d", "a"); 36 | q.put("e", "a"); // a b c d e 37 | assertTrue(null != q.remove("e")); // a b c d 38 | assertTrue(q.containsKey("a")); 39 | assertTrue(q.containsKey("b")); 40 | assertTrue(q.containsKey("c")); 41 | assertTrue(q.containsKey("d")); 42 | assertTrue(null != q.remove("c")); // a b d 43 | assertTrue(q.containsKey("a")); 44 | assertTrue(q.containsKey("b")); 45 | assertTrue(q.containsKey("d")); 46 | q.put("f", "a"); // a b d f 47 | assertTrue(null != q.remove("d")); // a b f 48 | assertTrue(q.containsKey("a")); 49 | assertTrue(q.containsKey("b")); 50 | assertTrue(q.containsKey("f")); 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /lab8/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 4.0.0 6 | 7 | 8 | CS61B 9 | 61BMasterPom 10 | 1.0-SNAPSHOT 11 | ../library-sp21/javalib/masterpom.xml 12 | 13 | 14 | CS61B 15 | lab8 16 | 1.0-SNAPSHOT 17 | 18 | 19 | ${project.basedir} 20 | ${project.basedir} 21 | 22 | 23 | org.apache.maven.plugins 24 | maven-compiler-plugin 25 | 3.1 26 | 27 | 1.14 28 | 1.14 29 | 30 | 31 | 32 | org.apache.maven.plugins 33 | maven-compiler-plugin 34 | 3.8.1 35 | 36 | 37 | -J-XX:+ShowCodeDetailsInExceptionMessages 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | -------------------------------------------------------------------------------- /lab8/speed/BucketsSpeedTest.java: -------------------------------------------------------------------------------- 1 | package speed; 2 | 3 | import edu.princeton.cs.algs4.Stopwatch; 4 | 5 | import java.io.IOException; 6 | import java.util.Scanner; 7 | 8 | import hashmap.Map61B; 9 | import hashmap.MyHashMapALBuckets; 10 | import hashmap.MyHashMapLLBuckets; 11 | import hashmap.MyHashMapTSBuckets; 12 | import hashmap.MyHashMapHSBuckets; 13 | import hashmap.MyHashMapPQBuckets; 14 | 15 | /** Performs a timing test on three different set implementations. 16 | * @author Neil Kulkarni adapted from Josh Hug, Brendan Hu 17 | */ 18 | public class BucketsSpeedTest { 19 | /** 20 | * Requests user input and performs tests of three different set 21 | * implementations. ARGS is unused. 22 | */ 23 | public static void main(String[] args) throws IOException { 24 | int N; 25 | Scanner input = new Scanner(System.in); 26 | 27 | System.out.println("\n This program inserts random " 28 | + "Strings of length L\n" 29 | + " Into different types of maps " 30 | + "as pairs.\n"); 31 | System.out.print("What would you like L to be?: "); 32 | int L = waitForPositiveInt(input); 33 | 34 | String repeat = "y"; 35 | do { 36 | System.out.print("\nEnter # strings to insert into each map: "); 37 | N = waitForPositiveInt(input); 38 | 39 | // Test each of the map implementations 40 | timeRandomMap61B(new MyHashMapALBuckets<>(), N, L); 41 | timeRandomMap61B(new MyHashMapLLBuckets<>(), N, L); 42 | timeRandomMap61B(new MyHashMapTSBuckets<>(), N, L); 43 | timeRandomMap61B(new MyHashMapHSBuckets<>(), N, L); 44 | timeRandomMap61B(new MyHashMapPQBuckets<>(), N, L); 45 | 46 | System.out.print("\nWould you like to try more timed-tests? (y/n)"); 47 | repeat = input.nextLine(); 48 | } while (!repeat.equalsIgnoreCase("n") && !repeat.equalsIgnoreCase("no")); 49 | input.close(); 50 | } 51 | 52 | /** 53 | * Returns time needed to put N random strings of length L into the 54 | * hashmap.Map61B 61bMap. 55 | */ 56 | public static double insertRandom(Map61B map61B, int N, int L) { 57 | Stopwatch sw = new Stopwatch(); 58 | String s = "cat"; 59 | for (int i = 0; i < N; i++) { 60 | s = StringUtils.randomString(L); 61 | map61B.put(s, new Integer(i)); 62 | } 63 | return sw.elapsedTime(); 64 | } 65 | 66 | /** 67 | * Attempts to insert N random strings of length L into map, 68 | * Prints time of the N insert calls, otherwise 69 | * Prints a nice message about the error 70 | */ 71 | public static void timeRandomMap61B(Map61B map, int N, int L) { 72 | try { 73 | double mapTime = insertRandom(map, N, L); 74 | System.out.printf(map.getClass() + ": %.2f sec\n", mapTime); 75 | } catch (StackOverflowError e) { 76 | printInfoOnStackOverflow(N, L); 77 | } catch (RuntimeException e) { 78 | e.printStackTrace(); 79 | } 80 | } 81 | 82 | /** 83 | * Waits for the user on other side of Scanner 84 | * to enter a positive int, 85 | * and outputs that int 86 | */ 87 | public static int waitForPositiveInt(Scanner input) { 88 | int ret = 0; 89 | do { 90 | while (!input.hasNextInt()) { 91 | errorBadIntegerInput(); 92 | input.next(); 93 | } 94 | ret = input.nextInt(); 95 | input.nextLine(); //consume \n not taken by nextInt() 96 | } while (ret <= 0); 97 | return ret; 98 | } 99 | /* ------------------------------- Private methods ------------------------------- */ 100 | /** 101 | * To be called after catching a StackOverflowError 102 | * Prints the error with corresponding N and L 103 | */ 104 | private static void printInfoOnStackOverflow(int N, int L) { 105 | System.out.println("--Stack Overflow -- couldn't add " + N 106 | + " strings of length " + L + "."); 107 | } 108 | 109 | /** 110 | * Prints a nice message for the user on bad input 111 | */ 112 | private static void errorBadIntegerInput() { 113 | System.out.print("Please enter a positive integer: "); 114 | } 115 | } 116 | -------------------------------------------------------------------------------- /lab8/speed/StringUtils.java: -------------------------------------------------------------------------------- 1 | package speed; 2 | 3 | import java.util.regex.Pattern; 4 | import java.util.Random; 5 | 6 | /** Utility function for Strings. 7 | * @author Josh Hug 8 | */ 9 | public class StringUtils { 10 | /** To get the style checker to be quiet. */ 11 | private static final int ALPHABET_SIZE = 26; 12 | 13 | /** Random number generator for this class. */ 14 | private static Random r = new Random(); 15 | 16 | /** Sets random seed to L so that results of randomString are predictable.*/ 17 | public static void setSeed(long l) { 18 | r = new Random(l); 19 | } 20 | 21 | /** Returns the next random string of length LENGTH. */ 22 | public static String randomString(int length) { 23 | char[] someChars = new char[length]; 24 | for (int i = 0; i < length; i++) { 25 | someChars[i] = (char) (r.nextInt(ALPHABET_SIZE) + 'a'); 26 | } 27 | return new String(someChars); 28 | } 29 | 30 | /** 31 | * Returns true if string S consists of characters between 32 | * 'a' and 'z' only. No spaces, numbers, upper-case, or any other 33 | * characters are allowed. 34 | */ 35 | public static boolean isLowerCase(String s) { 36 | return Pattern.matches("[a-z]*", s); 37 | } 38 | 39 | /** 40 | * Returns the string that comes right after S in alphabetical order. 41 | * For example, if s is 'potato', this method will return 'potatp'. If 42 | * the last character is a z, then we add to the next position, and so 43 | * on. 44 | */ 45 | public static String nextString(String s) { 46 | /* Handle all zs as a special case to keep helper method simple. */ 47 | if (isAllzs(s)) { 48 | return allAs(s.length() + 1); 49 | } 50 | char[] charVersion = s.toCharArray(); 51 | incrementCharArray(charVersion, charVersion.length - 1); 52 | return new String(charVersion); 53 | } 54 | 55 | /** 56 | * Helper function for nextString. Increments the Pth position of X 57 | * by one, wrapping around to 'a' if p == 'z'. If wraparound occurs, 58 | * then we need to carry the one, and we increment position P - 1. 59 | * 60 | * Will fail for a character array containing only zs. 61 | */ 62 | private static void incrementCharArray(char [] x, int p) { 63 | if (x[p] != 'z') { 64 | x[p] += 1; 65 | } else { 66 | x[p] = 'a'; 67 | incrementCharArray(x, p - 1); 68 | } 69 | } 70 | 71 | /** Returns a string of all 'a' of length LEN. */ 72 | private static String allAs(int len) { 73 | StringBuilder sb = new StringBuilder(); 74 | for (int i = 0; i < len; i++) { 75 | sb.append('a'); 76 | } 77 | return sb.toString(); 78 | } 79 | 80 | /** Returns true if S is all 'z'. False for empty strings */ 81 | public static boolean isAllzs(String s) { 82 | return Pattern.matches("[z]+", s); 83 | } 84 | 85 | } 86 | 87 | -------------------------------------------------------------------------------- /lab8/speedTestResults.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/duilec/CS61B-spring2021/83e75670a7d918309695a88e498700e4eafd7d93/lab8/speedTestResults.txt -------------------------------------------------------------------------------- /proj0/game2048/BoardLogger.java: -------------------------------------------------------------------------------- 1 | package game2048; 2 | 3 | import java.util.Observer; 4 | import java.util.Observable; 5 | 6 | /** An observer that prints changes to a Model. 7 | * @author P. N. Hilfinger 8 | */ 9 | class BoardLogger implements Observer { 10 | 11 | /** A line to separate each move. */ 12 | private static final String LINE = "---------------------"; 13 | 14 | @Override 15 | /** Prints the board state and how it was changed after each move. */ 16 | public void update(Observable obs, Object arg) { 17 | Model model = (Model) obs; 18 | String direction; 19 | if (arg == null) { 20 | direction = "Randomly generated tiles placed on board"; 21 | } else { 22 | direction = String.format("Board tilted %s", arg); 23 | } 24 | System.out.printf("%n%s%n%s%s", LINE, direction, model); 25 | } 26 | 27 | } 28 | -------------------------------------------------------------------------------- /proj0/game2048/GUI.java: -------------------------------------------------------------------------------- 1 | package game2048; 2 | 3 | import ucb.gui2.TopLevel; 4 | import ucb.gui2.LayoutSpec; 5 | 6 | import java.util.Observable; 7 | import java.util.Observer; 8 | 9 | import java.util.concurrent.ArrayBlockingQueue; 10 | 11 | import java.awt.event.KeyEvent; 12 | 13 | 14 | /** The GUI controller for a 2048 board and buttons. 15 | * @author P. N. Hilfinger 16 | */ 17 | class GUI extends TopLevel implements Observer { 18 | 19 | /** Minimum size of board in pixels. */ 20 | private static final int MIN_SIZE = 500; 21 | 22 | /** A new window with given TITLE providing a view of MODEL. */ 23 | GUI(String title, Model model) { 24 | super(title, true); 25 | addMenuButton("Game->New", this::newGame); 26 | addMenuButton("Game->Quit", this::quit); 27 | 28 | addLabel("", "Score", new LayoutSpec("y", 1)); 29 | 30 | _model = model; 31 | _model.addObserver(this); 32 | 33 | _widget = new BoardWidget(model.size()); 34 | add(_widget, 35 | new LayoutSpec("y", 0, 36 | "height", "REMAINDER", 37 | "width", "REMAINDER")); 38 | 39 | _widget.requestFocusInWindow(); 40 | _widget.setKeyHandler("keypress", this::keyPressed); 41 | setPreferredFocus(_widget); 42 | setScore(0, 0); 43 | } 44 | 45 | /** Response to "Quit" button click. */ 46 | public void quit(String dummy) { 47 | _pendingKeys.offer("Quit"); 48 | _widget.requestFocusInWindow(); 49 | } 50 | 51 | /** Response to "New Game" button click. */ 52 | public void newGame(String dummy) { 53 | _pendingKeys.offer("New Game"); 54 | _widget.requestFocusInWindow(); 55 | } 56 | 57 | /** Respond to the user pressing key E by queuing the key on our 58 | * queue of pending keys.*/ 59 | public void keyPressed(String unused, KeyEvent e) { 60 | _pendingKeys.offer(e.getKeyText(e.getKeyCode())); 61 | } 62 | 63 | /** Return the next pending event, waiting for it as necessary. 64 | * Ordinary key presses are reported as the key codes of the 65 | * character pressed. In addition, menu-button clicks result in 66 | * the messages "Quit" or "New Game". */ 67 | String readKey() { 68 | try { 69 | return _pendingKeys.take(); 70 | } catch (InterruptedException excp) { 71 | throw new Error("unexpected interrupt"); 72 | } 73 | } 74 | 75 | /** Set the current score being displayed to SCORE and the current 76 | * maximum score to MAXSCORE. */ 77 | public void setScore(int score, int maxScore) { 78 | setLabel("Score", String.format("Score: %6d / Max score: %6d", 79 | score, maxScore)); 80 | } 81 | 82 | /** The model notifies me that is has changed when its notifyObservers 83 | * method is called, because my constructor registered me as an 84 | * Observer of the model. */ 85 | @Override 86 | public void update(Observable model, Object arg) { 87 | _widget.update(_model); 88 | setScore(_model.score(), _model.maxScore()); 89 | } 90 | 91 | /** The board widget. */ 92 | private BoardWidget _widget; 93 | /** The game model being viewed. */ 94 | private Model _model; 95 | 96 | /** Queue of pending key presses. */ 97 | private ArrayBlockingQueue _pendingKeys = 98 | new ArrayBlockingQueue<>(5); 99 | 100 | } 101 | -------------------------------------------------------------------------------- /proj0/game2048/GUISource.java: -------------------------------------------------------------------------------- 1 | package game2048; 2 | 3 | import java.io.File; 4 | import java.io.FileWriter; 5 | import java.io.IOException; 6 | import java.util.Random; 7 | 8 | /** A type of InputSource that receives commands from a GUI. 9 | * @author P. N. Hilfinger 10 | */ 11 | class GUISource implements InputSource { 12 | 13 | /** Provides input from SOURCE, logging it iff LOG. Use RANDOMSOURCE to 14 | * select random tiles having value 2 with probability PROBOF2. */ 15 | GUISource(GUI source, Random randomSource, double probOf2, 16 | String logFileName) { 17 | _source = source; 18 | _randomSource = randomSource; 19 | _probOf2 = probOf2; 20 | 21 | if (logFileName != null) { 22 | 23 | File logFile = new File(logFileName); 24 | try { 25 | _logFileWriter = new FileWriter(logFile); 26 | } catch (IOException e) { 27 | System.err.println("Error: no such file " + logFileName); 28 | System.exit(1); 29 | } 30 | } 31 | } 32 | 33 | @Override 34 | /** Return and log which direction arrow was pressed. */ 35 | public String getKey() { 36 | String command = _source.readKey(); 37 | switch (command) { 38 | case "↑" : 39 | command = "Up"; 40 | break; 41 | case "→" : 42 | command = "Right"; 43 | break; 44 | case "↓" : 45 | command = "Down"; 46 | break; 47 | case "←" : 48 | command = "Left"; 49 | break; 50 | default : 51 | break; 52 | } 53 | 54 | String logLine = String.format("K %s%n", command); 55 | 56 | if (_logFileWriter != null) { 57 | System.out.print(logLine); 58 | try { 59 | _logFileWriter.write(logLine); 60 | } catch (IOException e) { 61 | System.err.print("Error: cannot write to log file"); 62 | System.exit(1); 63 | } 64 | } 65 | return command; 66 | } 67 | 68 | @Override 69 | /** Return a randomly positioned tile with either value of 2 with 70 | * probability _probOf2 or a value of 4 with probability 1 - _probOf2 in a 71 | * board with size SIZE. */ 72 | public Tile getNewTile(int size) { 73 | int c = _randomSource.nextInt(size), r = _randomSource.nextInt(size); 74 | int v = _randomSource.nextDouble() <= _probOf2 ? 2 : 4; 75 | if (_logFileWriter != null) { 76 | System.out.printf("T %d %d %d%n", v, c, r); 77 | } 78 | return Tile.create(v, c, r); 79 | } 80 | 81 | /** Input source. */ 82 | private GUI _source; 83 | /** Random source for Tiles. */ 84 | private Random _randomSource; 85 | /** Probabilty that value of new Tile is 2 rather than 4. */ 86 | private double _probOf2; 87 | /** The FileWriter to log inputs to (null if no logging required). */ 88 | private FileWriter _logFileWriter; 89 | 90 | } 91 | -------------------------------------------------------------------------------- /proj0/game2048/Game.java: -------------------------------------------------------------------------------- 1 | package game2048; 2 | 3 | import static game2048.Side.*; 4 | 5 | /** The input/output and GUI controller for play of a game of 2048. 6 | * @author P. N. Hilfinger. */ 7 | public class Game { 8 | 9 | /** Controller for a game represented by MODEL, using SOURCE as the 10 | * the source of key inputs and random Tiles. */ 11 | public Game(Model model, InputSource source) { 12 | _model = model; 13 | _source = source; 14 | _playing = true; 15 | } 16 | 17 | /** Return true iff we have not received a Quit command. */ 18 | boolean playing() { 19 | return _playing; 20 | } 21 | 22 | /** Clear the board and play one game, until receiving a quit or 23 | * new-game request. Update the viewer with each added tile or 24 | * change in the board from tilting. */ 25 | void playGame() { 26 | _model.clear(); 27 | _model.addTile(getValidNewTile()); 28 | while (_playing) { 29 | if (!_model.gameOver()) { 30 | _model.addTile(getValidNewTile()); 31 | _model.notifyObservers(); 32 | } 33 | 34 | boolean moved; 35 | moved = false; 36 | while (!moved) { 37 | String cmnd = _source.getKey(); 38 | switch (cmnd) { 39 | case "Quit": 40 | _playing = false; 41 | return; 42 | case "New Game": 43 | return; 44 | case "Up": case "Down": case "Left": case "Right": 45 | case "\u2190": case "\u2191": case "\u2192": case "\u2193": 46 | if (!_model.gameOver() && _model.tilt(keyToSide(cmnd))) { 47 | _model.notifyObservers(cmnd); 48 | moved = true; 49 | } 50 | break; 51 | default: 52 | break; 53 | } 54 | 55 | } 56 | } 57 | } 58 | 59 | /** Return the side indicated by KEY ("Up", "Down", "Left", 60 | * or "Right"). */ 61 | private Side keyToSide(String key) { 62 | switch (key) { 63 | case "Up": case "\u2191": 64 | return NORTH; 65 | case "Down": case "\u2193": 66 | return SOUTH; 67 | case "Left": case "\u2190": 68 | return WEST; 69 | case "Right": case "\u2192": 70 | return EAST; 71 | default: 72 | throw new IllegalArgumentException("unknown key designation"); 73 | } 74 | } 75 | 76 | /** Return a valid tile, using our source's tile input until finding 77 | * one that fits on the current board. Assumes there is at least one 78 | * empty square on the board. */ 79 | private Tile getValidNewTile() { 80 | while (true) { 81 | Tile tile = _source.getNewTile(_model.size()); 82 | if (_model.tile(tile.col(), tile.row()) == null) { 83 | return tile; 84 | } 85 | } 86 | } 87 | 88 | /** The playing board. */ 89 | private Model _model; 90 | 91 | /** Input source from standard input. */ 92 | private InputSource _source; 93 | 94 | /** True while user is still willing to play. */ 95 | private boolean _playing; 96 | 97 | } 98 | -------------------------------------------------------------------------------- /proj0/game2048/InputSource.java: -------------------------------------------------------------------------------- 1 | package game2048; 2 | 3 | /** Describes a source of input commands. 4 | * @author P. N. Hilfinger 5 | */ 6 | interface InputSource { 7 | 8 | /** Returns one command string. */ 9 | String getKey(); 10 | 11 | /** Returns a candidate Tile whose row and column is in the range 12 | * 0 .. SIZE-1. */ 13 | Tile getNewTile(int size); 14 | 15 | } 16 | 17 | -------------------------------------------------------------------------------- /proj0/game2048/Main.java: -------------------------------------------------------------------------------- 1 | package game2048; 2 | 3 | import java.util.Random; 4 | 5 | import ucb.util.CommandArgs; 6 | 7 | /** The main class for the 2048 game. 8 | * @author P. N. Hilfinger 9 | */ 10 | public class Main { 11 | 12 | /** Number of squares on the side of a board. */ 13 | static final int BOARD_SIZE = 4; 14 | /** Probability of choosing 2 as random tile (as opposed to 4). */ 15 | static final double TILE2_PROBABILITY = 0.9; 16 | 17 | /** The main program. ARGS may contain the options --seed=NUM, 18 | * (random seed); --log (record moves and random tiles 19 | * selected.). */ 20 | public static void main(String... args) { 21 | CommandArgs options = 22 | new CommandArgs("--seed=(\\d+) --log=(.+)", 23 | args); 24 | if (!options.ok()) { 25 | System.err.println("Usage: java game2048.Main [ --seed=NUM ] " 26 | + "[ --log=LOG_FILE ]"); 27 | System.exit(1); 28 | } 29 | 30 | Random gen = new Random(); 31 | if (options.contains("--seed")) { 32 | gen.setSeed(options.getLong("--seed")); 33 | } 34 | 35 | Model model = new Model(BOARD_SIZE); 36 | 37 | GUI gui; 38 | 39 | gui = new GUI("2048 61B", model); 40 | gui.display(true); 41 | 42 | InputSource inp; 43 | 44 | inp = new GUISource(gui, gen, TILE2_PROBABILITY, 45 | options.getFirst("--log")); 46 | 47 | Game game = new Game(model, inp); 48 | 49 | try { 50 | while (game.playing()) { 51 | game.playGame(); 52 | } 53 | } catch (IllegalStateException excp) { 54 | System.err.printf("Internal error: %s%n", excp.getMessage()); 55 | System.exit(1); 56 | } 57 | 58 | System.exit(0); 59 | } 60 | 61 | } 62 | -------------------------------------------------------------------------------- /proj0/game2048/Side.java: -------------------------------------------------------------------------------- 1 | package game2048; 2 | 3 | /** Symbolic names for the four sides of a board. 4 | * @author P. N. Hilfinger */ 5 | public enum Side { 6 | /** The parameters (COL0, ROW0, DCOL, and DROW) for each of the 7 | * symbolic directions, D, below are to be interpreted as follows: 8 | * The board's standard orientation has the top of the board 9 | * as NORTH, and rows and columns (see Model) are numbered 10 | * from its lower-left corner. Consider the board oriented 11 | * so that side D of the board is farthest from you. Then 12 | * * (COL0*s, ROW0*s) are the standard coordinates of the 13 | * lower-left corner of the reoriented board (where s is the 14 | * board size), and 15 | * * If (c, r) are the standard coordinates of a certain 16 | * square on the reoriented board, then (c+DCOL, r+DROW) 17 | * are the standard coordinates of the squares immediately 18 | * above it on the reoriented board. 19 | * The idea behind going to this trouble is that by using the 20 | * col() and row() methods below to translate from reoriented to 21 | * standard coordinates, one can arrange to use exactly the same code 22 | * to compute the result of tilting the board in any particular 23 | * direction. */ 24 | 25 | NORTH(0, 0, 0, 1), EAST(0, 1, 1, 0), SOUTH(1, 1, 0, -1), 26 | WEST(1, 0, -1, 0); 27 | 28 | /** The side that is in the direction (DCOL, DROW) from any square 29 | * of the board. Here, "direction (DCOL, DROW) means that to 30 | * move one space in the direction of this Side increases the row 31 | * by DROW and the colunn by DCOL. (COL0, ROW0) are the row and 32 | * column of the lower-left square when sitting at the board facing 33 | * towards this Side. */ 34 | Side(int col0, int row0, int dcol, int drow) { 35 | this.row0 = row0; 36 | this.col0 = col0; 37 | this.drow = drow; 38 | this.dcol = dcol; 39 | } 40 | 41 | /** Returns the side opposite of side S. */ 42 | static Side opposite(Side s) { 43 | if (s == NORTH) { 44 | return SOUTH; 45 | } else if (s == SOUTH) { 46 | return NORTH; 47 | } else if (s == EAST) { 48 | return WEST; 49 | } else { 50 | return EAST; 51 | } 52 | } 53 | 54 | /** Return the standard column number for square (C, R) on a board 55 | * of size SIZE oriented with this Side on top. */ 56 | public int col(int c, int r, int size) { 57 | return col0 * (size - 1) + c * drow + r * dcol; 58 | } 59 | 60 | /** Return the standard row number for square (C, R) on a board 61 | * of size SIZE oriented with this Side on top. */ 62 | public int row(int c, int r, int size) { 63 | return row0 * (size - 1) - c * dcol + r * drow; 64 | } 65 | 66 | /** Parameters describing this Side, as documented in the comment at the 67 | * start of this class. */ 68 | private int row0, col0, drow, dcol; 69 | 70 | }; 71 | -------------------------------------------------------------------------------- /proj0/game2048/TestEmptySpace.java: -------------------------------------------------------------------------------- 1 | package game2048; 2 | 3 | import org.junit.Test; 4 | 5 | import static org.junit.Assert.*; 6 | 7 | /** Tests the emptySpaceExists() static method of Model. 8 | * 9 | * @author Omar Khan 10 | */ 11 | public class TestEmptySpace { 12 | 13 | /** The Board that we'll be testing on. */ 14 | static Board b; 15 | 16 | @Test 17 | /** Note that this isn't a possible board state. */ 18 | public void testCompletelyEmpty() { 19 | int[][] rawVals = new int[][] { 20 | {0, 0, 0, 0}, 21 | {0, 0, 0, 0}, 22 | {0, 0, 0, 0}, 23 | {0, 0, 0, 0}, 24 | }; 25 | 26 | b = new Board(rawVals, 0); 27 | assertTrue("Board is full of empty space\n" + b, 28 | Model.emptySpaceExists(b)); 29 | } 30 | 31 | @Test 32 | /** Tests a board that is completely full except for the top row. */ 33 | public void testEmptyTopRow() { 34 | int[][] rawVals = new int[][] { 35 | {0, 0, 0, 0}, 36 | {2, 4, 2, 4}, 37 | {4, 2, 4, 2}, 38 | {2, 4, 2, 4}, 39 | }; 40 | 41 | b = new Board(rawVals, 0); 42 | 43 | assertTrue("Top row is empty\n" + b, Model.emptySpaceExists(b)); 44 | } 45 | 46 | @Test 47 | /** Tests a board that is completely full except for the bottom row. */ 48 | public void testEmptyBottomRow() { 49 | int[][] rawVals = new int[][] { 50 | {2, 4, 2, 4}, 51 | {4, 2, 4, 2}, 52 | {2, 4, 2, 4}, 53 | {0, 0, 0, 0}, 54 | }; 55 | 56 | b = new Board(rawVals, 0); 57 | assertTrue("Bottom row is empty\n" + b, 58 | Model.emptySpaceExists(b)); 59 | } 60 | 61 | 62 | @Test 63 | /** Tests a board that is completely full except for the left column. */ 64 | public void testEmptyLeftCol() { 65 | int[][] rawVals = new int[][] { 66 | {0, 4, 2, 4}, 67 | {0, 2, 4, 2}, 68 | {0, 4, 2, 4}, 69 | {0, 2, 4, 2}, 70 | }; 71 | 72 | b = new Board(rawVals, 0); 73 | 74 | assertTrue("Left col is empty\n" + b, 75 | Model.emptySpaceExists(b)); 76 | } 77 | 78 | @Test 79 | /** Tests a board that is completely full except for the right column. */ 80 | public void testEmptyRightCol() { 81 | int[][] rawVals = new int[][] { 82 | {2, 4, 2, 0}, 83 | {4, 2, 4, 0}, 84 | {2, 4, 2, 0}, 85 | {4, 2, 4, 0}, 86 | }; 87 | 88 | b = new Board(rawVals, 0); 89 | 90 | assertTrue("Right col is empty\n" + b, 91 | Model.emptySpaceExists(b)); 92 | } 93 | 94 | @Test 95 | /** Tests a completely full board except one piece. */ 96 | public void testAlmostFullBoard() { 97 | int[][] rawVals = new int[][] { 98 | {2, 4, 2, 4}, 99 | {4, 2, 4, 2}, 100 | {2, 0, 2, 4}, 101 | {4, 2, 4, 2}, 102 | }; 103 | 104 | b = new Board(rawVals, 0); 105 | 106 | assertTrue("Board is not full\n" + b, 107 | Model.emptySpaceExists(b)); 108 | } 109 | 110 | @Test 111 | /** Tests a completely full board. 112 | * The game isn't over since you can merge, but the emptySpaceExists method 113 | * should only look for empty space (and not adjacent values). */ 114 | public void testFullBoard() { 115 | int[][] rawVals = new int[][] { 116 | {2, 2, 2, 2}, 117 | {2, 2, 2, 2}, 118 | {2, 2, 2, 2}, 119 | {2, 2, 2, 2}, 120 | }; 121 | 122 | b = new Board(rawVals, 0); 123 | 124 | assertFalse("Board is full\n" + b, Model.emptySpaceExists(b)); 125 | } 126 | 127 | @Test 128 | /** Tests a completely full board. */ 129 | public void testFullBoardNoMerge() { 130 | int[][] rawVals = new int[][] { 131 | {2, 4, 2, 4}, 132 | {4, 2, 4, 2}, 133 | {2, 4, 2, 4}, 134 | {4, 2, 4, 2}, 135 | }; 136 | 137 | b = new Board(rawVals, 0); 138 | 139 | assertFalse("Board is full\n" + b, Model.emptySpaceExists(b)); 140 | } 141 | } 142 | -------------------------------------------------------------------------------- /proj0/game2048/TestMaxTileExists.java: -------------------------------------------------------------------------------- 1 | package game2048; 2 | 3 | import org.junit.Test; 4 | 5 | import static org.junit.Assert.*; 6 | 7 | /** Tests the maxTileExists() static method of Model. 8 | * 9 | * @author Omar Khan 10 | */ 11 | public class TestMaxTileExists { 12 | /** The board we'll be testing. */ 13 | static Board b; 14 | 15 | @Test 16 | /** Note that this isn't a possible board state. */ 17 | public void testEmptyBoard() { 18 | int[][] rawVals = new int[][] { 19 | {0, 0, 0, 0}, 20 | {0, 0, 0, 0}, 21 | {0, 0, 0, 0}, 22 | {0, 0, 0, 0}, 23 | }; 24 | 25 | b = new Board(rawVals, 0); 26 | 27 | assertFalse("Board is empty\n" + b, Model.maxTileExists(b)); 28 | } 29 | 30 | @Test 31 | /** Tests a full board with no max piece. */ 32 | public void testFullBoardNoMax() { 33 | int[][] rawVals = new int[][] { 34 | {2, 2, 2, 2}, 35 | {2, 2, 2, 2}, 36 | {2, 2, 2, 2}, 37 | {2, 2, 2, 2}, 38 | }; 39 | 40 | b = new Board(rawVals, 0); 41 | 42 | assertFalse("No 2048 tile on board\n" + b, Model.maxTileExists(b)); 43 | } 44 | 45 | @Test 46 | /** Tests a full board with the max piece. */ 47 | public void testFullBoardMax() { 48 | int[][] rawVals = new int[][] { 49 | {2, 2, 2, 2}, 50 | {2, 2, 2, 2}, 51 | {2, 2, 2, 2}, 52 | {2, 2, 2, 2048}, 53 | }; 54 | 55 | b = new Board(rawVals, 0); 56 | 57 | assertTrue("One 2048 tile on board\n" + b, 58 | Model.maxTileExists(b)); 59 | } 60 | 61 | @Test 62 | /** Tests multiple max pieces. */ 63 | public void testMultipleMax() { 64 | int[][] rawVals = new int[][] { 65 | {2, 2, 2, 2}, 66 | {2, 2048, 0, 0}, 67 | {0, 0, 0, 2}, 68 | {0, 0, 2, 2048}, 69 | }; 70 | 71 | b = new Board(rawVals, 0); 72 | 73 | assertTrue("Two 2048 tile on board\n" + b, 74 | Model.maxTileExists(b)); 75 | } 76 | 77 | @Test 78 | /** Tests when the max piece is in the top right corner. */ 79 | public void testTopRightCorner() { 80 | int[][] rawVals = new int[][] { 81 | {0, 0, 0, 2048}, 82 | {0, 0, 0, 0}, 83 | {0, 0, 0, 0}, 84 | {0, 0, 0, 0} 85 | }; 86 | 87 | b = new Board(rawVals, 0); 88 | 89 | assertTrue("One 2048 tile on board\n" + b, 90 | Model.maxTileExists(b)); 91 | } 92 | 93 | @Test 94 | /** Tests when the max piece is in the top left corner. */ 95 | public void testTopLeftCorner() { 96 | int[][] rawVals = new int[][] { 97 | {2048, 0, 0, 0}, 98 | {0, 0, 0, 0}, 99 | {0, 0, 0, 0}, 100 | {0, 0, 0, 0} 101 | }; 102 | 103 | b = new Board(rawVals, 0); 104 | 105 | assertTrue("One 2048 tile on board\n" + b, 106 | Model.maxTileExists(b)); 107 | } 108 | 109 | @Test 110 | /** Tests when the max piece is in the bottom left corner. */ 111 | public void testBottomLeftCorner() { 112 | int[][] rawVals = new int[][] { 113 | {0, 0, 0, 0}, 114 | {0, 0, 0, 0}, 115 | {0, 0, 0, 0}, 116 | {2048, 0, 0, 0} 117 | }; 118 | 119 | b = new Board(rawVals, 0); 120 | 121 | assertTrue("One 2048 tile on board\n" + b, 122 | Model.maxTileExists(b)); 123 | } 124 | 125 | @Test 126 | /** Tests when the max piece is in the bottom right corner. */ 127 | public void testBottomRightCorner() { 128 | int[][] rawVals = new int[][] { 129 | {0, 0, 0, 0}, 130 | {0, 0, 0, 0}, 131 | {0, 0, 0, 0}, 132 | {0, 0, 0, 2048} 133 | }; 134 | 135 | b = new Board(rawVals, 0); 136 | 137 | assertTrue("One 2048 tile on board\n" + b, 138 | Model.maxTileExists(b)); 139 | } 140 | 141 | } 142 | -------------------------------------------------------------------------------- /proj0/game2048/TestUpOnly.java: -------------------------------------------------------------------------------- 1 | package game2048; 2 | 3 | import org.junit.Test; 4 | 5 | import static org.junit.Assert.*; 6 | 7 | /** Tests the tilt() method in the up (Side.NORTH) direction only. 8 | * 9 | * @author Omar Khan 10 | */ 11 | public class TestUpOnly extends TestUtils { 12 | 13 | 14 | @Test 15 | /** Move tiles up (no merging). */ 16 | public void testUpNoMerge() { 17 | int[][] before = new int[][] { 18 | {0, 0, 4, 0}, 19 | {0, 0, 0, 2}, 20 | {0, 0, 0, 0}, 21 | {0, 0, 0, 0}, 22 | }; 23 | int[][] after = new int[][] { 24 | {0, 0, 4, 2}, 25 | {0, 0, 0, 0}, 26 | {0, 0, 0, 0}, 27 | {0, 0, 0, 0}, 28 | }; 29 | 30 | model = new Model(before, 0, 0, false); 31 | String prevBoard = model.toString(); 32 | boolean changed = model.tilt(Side.NORTH); 33 | checkChanged(Side.NORTH, true, changed); 34 | checkModel(after, 0, 0, prevBoard, Side.NORTH); 35 | } 36 | 37 | @Test 38 | /** A basic merge. */ 39 | public void testUpBasicMerge() { 40 | int[][] before = new int[][] { 41 | {0, 0, 0, 0}, 42 | {0, 0, 2, 0}, 43 | {0, 0, 2, 0}, 44 | {0, 0, 0, 0}, 45 | }; 46 | int[][] after = new int[][] { 47 | {0, 0, 4, 0}, 48 | {0, 0, 0, 0}, 49 | {0, 0, 0, 0}, 50 | {0, 0, 0, 0}, 51 | }; 52 | 53 | updateModel(before, 0, 0, false); 54 | String prevBoard = model.toString(); 55 | boolean changed = model.tilt(Side.NORTH); 56 | checkChanged(Side.NORTH, true, changed); 57 | checkModel(after, 4, 0, prevBoard, Side.NORTH); 58 | } 59 | 60 | @Test 61 | /** A triple merge. Only the leading 2 tiles should merge. */ 62 | public void testUpTripleMerge() { 63 | int[][] before = new int[][] { 64 | {0, 0, 2, 0}, 65 | {0, 0, 0, 0}, 66 | {0, 0, 2, 0}, 67 | {0, 0, 2, 0}, 68 | }; 69 | int[][] after = new int[][] { 70 | {0, 0, 4, 0}, 71 | {0, 0, 2, 0}, 72 | {0, 0, 0, 0}, 73 | {0, 0, 0, 0}, 74 | }; 75 | 76 | updateModel(before, 0, 0, false); 77 | String prevBoard = model.toString(); 78 | boolean changed = model.tilt(Side.NORTH); 79 | checkChanged(Side.NORTH, true, changed); 80 | checkModel(after, 4, 0, prevBoard, Side.NORTH); 81 | } 82 | 83 | @Test 84 | /** A tricky merge. 85 | * 86 | * The tricky part here is that the 4 tile on the bottom row shouldn't 87 | * merge with the newly created 4 tile on the top row. If you're failing 88 | * this test, try seeing how you can ensure that the bottom 4 tile doesn't 89 | * merge with the newly created 4 tile on top.*/ 90 | public void testUpTrickyMerge() { 91 | int[][] before = new int[][] { 92 | {0, 0, 2, 0}, 93 | {0, 0, 2, 0}, 94 | {0, 0, 0, 0}, 95 | {0, 0, 4, 0}, 96 | }; 97 | int[][] after = new int[][] { 98 | {0, 0, 4, 0}, 99 | {0, 0, 4, 0}, 100 | {0, 0, 0, 0}, 101 | {0, 0, 0, 0}, 102 | }; 103 | 104 | updateModel(before, 0, 0, false); 105 | String prevBoard = model.toString(); 106 | boolean changed = model.tilt(Side.NORTH); 107 | checkChanged(Side.NORTH, true, changed); 108 | checkModel(after, 4, 0, prevBoard, Side.NORTH); 109 | } 110 | } 111 | -------------------------------------------------------------------------------- /proj0/game2048/TestUtils.java: -------------------------------------------------------------------------------- 1 | package game2048; 2 | 3 | import static org.junit.Assert.*; 4 | 5 | public class TestUtils { 6 | 7 | /** The Model we'll be testing. */ 8 | static Model model; 9 | /** The size of the Board on these tests. */ 10 | public static final int SIZE = 4; 11 | 12 | /** Utility method to generate an error message. */ 13 | public static String boardShouldChange(Side side) { 14 | return "When tilted to the " + side + ", the model should change, but" 15 | + " the call to tilt returned false.\nModel after call:" + model; 16 | } 17 | 18 | /** Utility method to generate an error message. */ 19 | public static String boardShouldNotChange(Side side) { 20 | return "When tilted to the " + side + ", the model should NOT change," 21 | + " but the call to tilt returned true.\nModel after call:" 22 | + model; 23 | } 24 | 25 | /** 26 | * Updates the static variable model to be the Model with board attribute 27 | * as described by VALUES. 28 | */ 29 | public static void updateModel(int[][] values, int score, int maxScore, 30 | boolean gameOver) { 31 | assert values.length == SIZE : "board must have 4x4 dimensions"; 32 | assert values[0].length == SIZE : "board must have 4x4 dimensions"; 33 | model = new Model(values, score, maxScore, gameOver); 34 | } 35 | 36 | /** 37 | * Checks that the static variable model is configured as described by 38 | * VALUES with score attribute SCORE. 39 | * @param values - a 2D array of integers describing the expected board a 40 | * "0" element represents a null Tile. 41 | * @param score - what score the model should have. 42 | * @param maxScore 43 | * @param prevBoard - what the board looked like before this move. 44 | * @param currMove - the Side that we tilted towards. 45 | */ 46 | public static void checkModel(int[][] values, int score, int maxScore, 47 | String prevBoard, Side currMove) { 48 | 49 | Model expected = new Model(values, score, maxScore, false); 50 | String errMsg = String.format("Board incorrect. Before tilting towards" 51 | + " %s, your board looked like:%s%nAfter the call to" 52 | + " tilt, we expected:%s%nBut your board looks like:%s.", 53 | currMove, prevBoard, expected.toString(), model.toString()); 54 | assertEquals(errMsg, expected, model); 55 | } 56 | 57 | /** 58 | * Checks that the returned boolean of a call to the tilt method is correct. 59 | * 60 | * @param s - the side that was tilted (the parameter to tilt). 61 | * @param expected - what the expected return value is. 62 | * @param actual - what the actual return value is. 63 | */ 64 | public static void checkChanged(Side s, boolean expected, boolean actual) { 65 | String changedErrMsg; 66 | if (expected) { 67 | changedErrMsg = boardShouldChange(s); 68 | assertTrue(changedErrMsg, actual); 69 | } else { 70 | changedErrMsg = boardShouldNotChange(s); 71 | assertFalse(changedErrMsg, actual); 72 | } 73 | } 74 | } 75 | -------------------------------------------------------------------------------- /proj0/game2048/Tile.java: -------------------------------------------------------------------------------- 1 | package game2048; 2 | 3 | /** Represents the image of a numbered tile on a 2048 board. 4 | * @author P. N. Hilfinger. 5 | */ 6 | public class Tile { 7 | 8 | /** A new tile with VALUE as its value at (ROW, COL). This 9 | * constructor is private, so all tiles are created by the 10 | * factory methods create, move, and merge. */ 11 | private Tile(int value, int col, int row) { 12 | this.value = value; 13 | this.row = row; 14 | this.col = col; 15 | this.next = null; 16 | } 17 | 18 | /** Return my current row. */ 19 | public int row() { 20 | return row; 21 | } 22 | 23 | /** Return my current column. */ 24 | public int col() { 25 | return col; 26 | } 27 | 28 | /** Return the value supplied to my constructor. */ 29 | public int value() { 30 | return value; 31 | } 32 | 33 | /** Return my next state. Before I am moved or merged, I am my 34 | * own successor. */ 35 | public Tile next() { 36 | return next == null ? this : next; 37 | } 38 | 39 | /** Return a new tile at (ROW, COL) with value VALUE. */ 40 | public static Tile create(int value, int col, int row) { 41 | return new Tile(value, col, row); 42 | } 43 | 44 | /** Return the result of moving me to (COL, ROW). */ 45 | public Tile move(int col, int row) { 46 | Tile result = new Tile(value, col, row); 47 | next = result; 48 | return result; 49 | } 50 | 51 | /** Return the result of merging OTHERTILE with me after moving to 52 | * (COL, ROW). */ 53 | public Tile merge(int col, int row, Tile otherTile) { 54 | assert value == otherTile.value(); 55 | next = otherTile.next = new Tile(2 * value, col, row); 56 | return next; 57 | } 58 | 59 | /** Return the distance in rows or columns between me and my successor 60 | * tile (0 if I have no successor). */ 61 | public int distToNext() { 62 | if (next == null) { 63 | return 0; 64 | } else { 65 | return Math.max(Math.abs(row - next.row()), 66 | Math.abs(col - next.col())); 67 | } 68 | } 69 | 70 | @Override 71 | public String toString() { 72 | return String.format("%d@(%d, %d)", value(), col(), row()); 73 | } 74 | 75 | /** My value. */ 76 | private final int value; 77 | 78 | /** My last position on the board. */ 79 | private final int row, col; 80 | 81 | /** Successor tile: one I am moved to or merged with. */ 82 | private Tile next; 83 | } 84 | -------------------------------------------------------------------------------- /proj0/javalib/hamcrest-core-1.3.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/duilec/CS61B-spring2021/83e75670a7d918309695a88e498700e4eafd7d93/proj0/javalib/hamcrest-core-1.3.jar -------------------------------------------------------------------------------- /proj0/javalib/junit-4.12.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/duilec/CS61B-spring2021/83e75670a7d918309695a88e498700e4eafd7d93/proj0/javalib/junit-4.12.jar -------------------------------------------------------------------------------- /proj0/javalib/ucb.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/duilec/CS61B-spring2021/83e75670a7d918309695a88e498700e4eafd7d93/proj0/javalib/ucb.jar -------------------------------------------------------------------------------- /proj1/deque/Deque.java: -------------------------------------------------------------------------------- 1 | package deque; 2 | 3 | public interface Deque{ 4 | void addFirst(T item); 5 | void addLast(T item); 6 | int size(); 7 | void printDeque(); 8 | T removeFirst(); 9 | T removeLast(); 10 | T get(int index); 11 | 12 | /** Returns true if deque is empty, false otherwise.*/ 13 | default boolean isEmpty(){ 14 | if (size() == 0){ 15 | return true; 16 | } 17 | return false; 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /proj1/deque/MaxArrayDeque.java: -------------------------------------------------------------------------------- 1 | package deque; 2 | import java.util.Comparator; 3 | 4 | /** Max Array Deque. 5 | * @author Huang Jinhong 6 | */ 7 | 8 | // define: additional method and constructor 9 | // public MaxArrayDeque(Comparator c) 10 | // public T max(Comparator c) 11 | // public T max() 12 | 13 | public class MaxArrayDeque extends ArrayDeque { 14 | // store the pass argument of "c" to "comparator" 15 | // when using max(), we can use "comparator" 16 | private Comparator comparator; 17 | 18 | /** creates a MaxArrayDeque with the given Comparator. */ 19 | // store the pass argument of "c" to "comparator" 20 | // when using max(), we can use "comparator" 21 | public MaxArrayDeque(Comparator c) { 22 | comparator = c; 23 | } 24 | 25 | /** returns the maximum element in the deque as governed by the parameter Comparator c. 26 | * If the MaxArrayDeque is empty, simply return null.*/ 27 | // note: we use method of comparator to compare 28 | public T max(Comparator c) { 29 | if(isEmpty()){ 30 | return null; 31 | } 32 | int maxIndex = 0; 33 | for(int i = 1; i < size(); i++){ 34 | if(c.compare(get(maxIndex), get(i)) < 0){ 35 | maxIndex = i; 36 | } 37 | } 38 | return get(maxIndex); 39 | } 40 | 41 | /** returns the maximum element in the deque as governed by the previously given Comparator. 42 | * If the MaxArrayDeque is empty, simply return null.*/ 43 | public T max() { 44 | return max(comparator); 45 | } 46 | } 47 | 48 | -------------------------------------------------------------------------------- /proj1/deque/MaxArrayDequeTest.java: -------------------------------------------------------------------------------- 1 | package deque; 2 | 3 | import org.junit.Test; 4 | import java.util.Comparator; 5 | import static org.junit.Assert.assertEquals; 6 | 7 | // test: date and using method(like function of main()) 8 | // hint: You’ll likely be creating multiple Comparator classes to test your code 9 | // so, we need build different comparator to test in MaxArrayDeque 10 | 11 | public class MaxArrayDequeTest { 12 | @Test 13 | public void maxWithIntComparatorTest() { 14 | // construct an instance of class by using "new ClassName()" 15 | // when the class not pass argument to constructor 16 | IntComparator intComparator = new IntComparator(); 17 | MaxArrayDeque maxArrayDeque= new MaxArrayDeque<>(intComparator); 18 | for (int i = 0; i <= 100000; i++){ 19 | maxArrayDeque.addFirst(i); 20 | } 21 | int actual = maxArrayDeque.max(); 22 | assertEquals(100000, actual); 23 | 24 | int actual1 = maxArrayDeque.max(intComparator); 25 | assertEquals(100000, actual1); 26 | } 27 | 28 | private static class IntComparator implements Comparator{ 29 | @Override 30 | public int compare(Integer i1, Integer i2){ 31 | return i1 - i2; 32 | } 33 | } 34 | 35 | @Test 36 | public void maxWithDoubleComparatorTest() { 37 | DoubleComparator doubleComparator = new DoubleComparator(); 38 | MaxArrayDeque maxArrayDeque= new MaxArrayDeque<>(doubleComparator); 39 | for (double i = 0; i <= 100000; i++){ 40 | maxArrayDeque.addFirst(i); 41 | } 42 | double actual = maxArrayDeque.max(); 43 | // you should pass delta, when using assertEquals() to assert type of double 44 | assertEquals(100000, actual,0.0); 45 | 46 | double actual1 = maxArrayDeque.max(doubleComparator); 47 | assertEquals(100000, actual1,0.0); 48 | } 49 | 50 | private static class DoubleComparator implements Comparator{ 51 | @Override 52 | // we should have same name and signature when overriding 53 | // so, we can't use "public double compare(Double d1, Double d2)" 54 | public int compare(Double d1, Double d2){ 55 | return (int)(d1 - d2); 56 | } 57 | } 58 | 59 | @Test 60 | public void maxWithStringLengthComparatorTest() { 61 | StringLengthComparator stringLengthComparator = new StringLengthComparator(); 62 | MaxArrayDeque maxArrayDeque= new MaxArrayDeque<>(stringLengthComparator); 63 | 64 | maxArrayDeque.addFirst("HelloWorld"); 65 | maxArrayDeque.addFirst("Hello World!"); 66 | 67 | assertEquals("Hello World!", maxArrayDeque.max()); 68 | assertEquals("Hello World!", maxArrayDeque.max(stringLengthComparator)); 69 | } 70 | 71 | private static class StringLengthComparator implements Comparator{ 72 | @Override 73 | public int compare(String d1, String d2){ 74 | return d1.length() - d2.length(); 75 | } 76 | } 77 | } 78 | -------------------------------------------------------------------------------- /proj1/gh2/GuitarHeroLite.java: -------------------------------------------------------------------------------- 1 | package gh2; 2 | import edu.princeton.cs.algs4.StdAudio; 3 | import edu.princeton.cs.algs4.StdDraw; 4 | 5 | /** 6 | * A client that uses the synthesizer package to replicate a plucked guitar string sound 7 | */ 8 | public class GuitarHeroLite { 9 | // CONCERT_Q: 440 * 2 ** ((0-24)/12) = 110.0 in python 10 | public static final double CONCERT_A = 440.0; 11 | // keyboard from "q" to " ", 37 keys 12 | public static final String keyboard = "q2we4r5ty7u8i9op-[=zxdcfvgbnjmk,.;/' "; 13 | 14 | public static void main(String[] args) { 15 | // make sure you working in main() 16 | // when writing code about String, System and so on in java.lang 17 | GuitarString[] strings = new GuitarString[keyboard.length()]; 18 | 19 | // create 37 guitar strings, from "q" to " " 20 | for (int i = 0; i < keyboard.length(); i += 1){ 21 | double Concert = CONCERT_A * Math.pow(2, ((i - 24.0) / 12.0)); 22 | strings[i] = new GuitarString(Concert); 23 | } 24 | 25 | while (true) { 26 | /* check if the user has typed a key; if so, process it */ 27 | if (StdDraw.hasNextKeyTyped()) { 28 | char key = StdDraw.nextKeyTyped(); 29 | for (int i = 0; i < keyboard.length(); i += 1) { 30 | if (i == keyboard.indexOf(key)){ 31 | strings[i].pluck(); 32 | break; 33 | } 34 | } 35 | } 36 | 37 | /* compute the superposition of samples */ 38 | double sample = 0.0; 39 | for (int i = 0; i < keyboard.length(); i += 1) { 40 | sample += strings[i].sample(); 41 | } 42 | 43 | /* play the sample on standard audio */ 44 | StdAudio.play(sample); 45 | 46 | /* advance the simulation of each guitar string by one step */ 47 | for (int i = 0; i < keyboard.length(); i += 1) { 48 | strings[i].tic(); 49 | } 50 | } 51 | } 52 | } 53 | 54 | -------------------------------------------------------------------------------- /proj1/gh2/GuitarString.java: -------------------------------------------------------------------------------- 1 | package gh2; 2 | 3 | // uncomment the following import once you're ready to start this portion 4 | import deque.Deque; 5 | // maybe more imports 6 | // I would like ArrayDeque when using Java Visualizer 7 | import deque.ArrayDeque; 8 | 9 | //Note: This file will not compile until you complete the Deque implementations 10 | public class GuitarString { 11 | /** Constants. Do not change. In case you're curious, the keyword final 12 | * means the values cannot be changed at runtime. We'll discuss this and 13 | * other topics in lecture on Friday. */ 14 | private static final int SR = 44100; // Sampling Rate 15 | private static final double DECAY = .996; // energy decay factor 16 | 17 | /* Buffer for storing sound data. */ 18 | // uncomment the following line once you're ready to start this portion 19 | private Deque buffer; 20 | private double sample; 21 | 22 | /* Create a guitar string of the given frequency. */ 23 | public GuitarString(double frequency) { 24 | // Create a buffer with capacity = SR / frequency. You'll need to 25 | // cast the result of this division operation into an int. For 26 | // better accuracy, use the Math.round() function before casting. 27 | // Your should initially fill your buffer array with zeros. 28 | int capacity = (int)(Math.round(SR / frequency)); 29 | buffer = new ArrayDeque<>(); 30 | while (capacity > 0){ 31 | buffer.addFirst(0.0); 32 | capacity -= 1; 33 | } 34 | } 35 | 36 | 37 | /* Pluck the guitar string by replacing the buffer with white noise. */ 38 | public void pluck() { 39 | // Dequeue everything in buffer, and replace with random numbers 40 | // between -0.5 and 0.5. You can get such a number by using: 41 | // double r = Math.random() - 0.5; 42 | // 43 | // Make sure that your random numbers are different from each 44 | // other. This does not mean that you need to check that the numbers 45 | // are different from each other. It means you should repeatedly call 46 | // Math.random() - 0.5 to generate new random numbers for each array index. 47 | 48 | // note: Math.random() generates double greater than 0.0 and smaller than 1.0 49 | int bufferSize = buffer.size(); 50 | while(bufferSize > 0){ 51 | double r = Math.random() - 0.5; 52 | buffer.removeFirst(); 53 | buffer.addFirst(r); 54 | bufferSize -= 1; 55 | } 56 | } 57 | 58 | /* Advance the simulation one time step by performing one iteration of 59 | * the Karplus-Strong algorithm. 60 | */ 61 | public void tic() { 62 | // Dequeue the front sample and enqueue a new sample that is 63 | // the average of the two multiplied by the DECAY factor. 64 | // **Do not call StdAudio.play().** 65 | 66 | // note: sample() not affect running of tic() 67 | double sample = buffer.removeFirst(); 68 | double newFront = buffer.get(0); 69 | sample = ((sample + newFront) / 2) * DECAY; 70 | buffer.addLast(sample); 71 | } 72 | 73 | /* Return the double at the front of the buffer. */ 74 | public double sample() { 75 | // Return the correct thing. 76 | sample = buffer.get(0); 77 | return sample; 78 | } 79 | } 80 | // Remove all comments that say TODO when you're done. 81 | -------------------------------------------------------------------------------- /proj1/gh2/TestGuitarString.java: -------------------------------------------------------------------------------- 1 | package gh2; 2 | 3 | /* Imports the required audio library from the 4 | * edu.princeton.cs.introcs package. */ 5 | import edu.princeton.cs.introcs.StdAudio; 6 | 7 | import org.junit.Test; 8 | import static org.junit.Assert.*; 9 | 10 | /** Tests the GuitarString class. 11 | * @author Josh Hug 12 | */ 13 | public class TestGuitarString { 14 | 15 | @Test 16 | public void testPluckTheAString() { 17 | GuitarString aString = new GuitarString(GuitarHeroLite.CONCERT_A); 18 | aString.pluck(); 19 | for (int i = 0; i < 50000; i += 1) { 20 | StdAudio.play(aString.sample()); 21 | aString.tic(); 22 | } 23 | } 24 | 25 | @Test 26 | public void testSample() { 27 | GuitarString s = new GuitarString(100); 28 | assertEquals(0.0, s.sample(), 0.0); 29 | assertEquals(0.0, s.sample(), 0.0); 30 | assertEquals(0.0, s.sample(), 0.0); 31 | s.pluck(); 32 | double sample = s.sample(); 33 | assertNotEquals("After plucking, your samples should not be 0.", 0.0, sample); 34 | 35 | assertEquals("Sample should not change the state of your string.", sample, s.sample(), 0.0); 36 | assertEquals("Sample should not change the state of your string.", sample, s.sample(), 0.0); 37 | } 38 | 39 | 40 | @Test 41 | public void testTic() { 42 | GuitarString s = new GuitarString(100); 43 | assertEquals(0.0, s.sample(), 0.0); 44 | assertEquals(0.0, s.sample(), 0.0); 45 | assertEquals(0.0, s.sample(), 0.0); 46 | s.pluck(); 47 | double sample1 = s.sample(); 48 | assertNotEquals("After plucking, your samples should not be 0.", 0.0, sample1); 49 | 50 | s.tic(); 51 | assertNotEquals("After tic(), your samples should not stay the same.", sample1, s.sample()); 52 | } 53 | 54 | 55 | @Test 56 | public void testTicCalculations() { 57 | // Create a GuitarString of frequency 11025, which 58 | // is a Deque of length 4. 59 | GuitarString s = new GuitarString(11025); 60 | s.pluck(); 61 | 62 | // Record the front four values, ticcing as we go. 63 | double s1 = s.sample(); 64 | s.tic(); 65 | double s2 = s.sample(); 66 | s.tic(); 67 | double s3 = s.sample(); 68 | s.tic(); 69 | double s4 = s.sample(); 70 | 71 | // If we tic once more, it should be equal to 0.996*0.5*(s1 + s2) 72 | s.tic(); 73 | 74 | double s5 = s.sample(); 75 | double expected = 0.996 * 0.5 * (s1 + s2); 76 | 77 | // Check that new sample is correct, using tolerance of 0.001. 78 | // See JUnit documentation for a description of how tolerances work 79 | // for assertEquals(double, double) 80 | assertEquals("Wrong tic value. Try running the testTic method.", expected, s5, 0.001); 81 | } 82 | } 83 | 84 | -------------------------------------------------------------------------------- /proj1/gh2/beatles-hey_jude.mid: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/duilec/CS61B-spring2021/83e75670a7d918309695a88e498700e4eafd7d93/proj1/gh2/beatles-hey_jude.mid -------------------------------------------------------------------------------- /proj1/gh2/beatles-yesterday.mid: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/duilec/CS61B-spring2021/83e75670a7d918309695a88e498700e4eafd7d93/proj1/gh2/beatles-yesterday.mid -------------------------------------------------------------------------------- /proj1/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 4.0.0 6 | 7 | 8 | CS61B 9 | 61BMasterPom 10 | 1.0-SNAPSHOT 11 | ../library-sp21/javalib/masterpom.xml 12 | 13 | 14 | CS61B 15 | proj1 16 | 1.0-SNAPSHOT 17 | 18 | 19 | ${project.basedir} 20 | ${project.basedir} 21 | 22 | 23 | org.apache.maven.plugins 24 | maven-compiler-plugin 25 | 3.1 26 | 27 | 1.14 28 | 1.14 29 | 30 | 31 | 32 | org.apache.maven.plugins 33 | maven-compiler-plugin 34 | 3.8.1 35 | 36 | 37 | -J-XX:+ShowCodeDetailsInExceptionMessages 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | -------------------------------------------------------------------------------- /proj1ec/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 4.0.0 6 | 7 | 8 | CS61B 9 | 61BMasterPom 10 | 1.0-SNAPSHOT 11 | ../library-sp21/javalib/masterpom.xml 12 | 13 | 14 | CS61B 15 | proj1ec 16 | 1.0-SNAPSHOT 17 | 18 | 19 | ${project.basedir} 20 | ${project.basedir} 21 | 22 | 23 | org.apache.maven.plugins 24 | maven-compiler-plugin 25 | 3.1 26 | 27 | 1.14 28 | 1.14 29 | 30 | 31 | 32 | org.apache.maven.plugins 33 | maven-compiler-plugin 34 | 3.8.1 35 | 36 | 37 | -J-XX:+ShowCodeDetailsInExceptionMessages 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | -------------------------------------------------------------------------------- /proj1ec/student/Deque.java: -------------------------------------------------------------------------------- 1 | package student; 2 | 3 | /** 4 | * Created by hug on 2/4/2017. 5 | * Added isEmpty() default implementation on 2/3/2019. 6 | */ 7 | public interface Deque { 8 | void addFirst(Item x); 9 | void addLast(Item x); 10 | 11 | default boolean isEmpty() { 12 | return size() == 0; 13 | } 14 | 15 | int size(); 16 | void printDeque(); 17 | Item removeFirst(); 18 | Item removeLast(); 19 | Item get(int index); 20 | } -------------------------------------------------------------------------------- /proj1ec/tester/ArrayDequeSolution.java: -------------------------------------------------------------------------------- 1 | package tester; 2 | 3 | import java.util.LinkedList; 4 | 5 | /** 6 | * Isn't this solution kinda... cheating? Yes. 7 | * The aesthete will be especially alarmed by the fact that this 8 | * supposed ArrayDeque is actually using a LinkedList. SAD! 9 | */ 10 | public class ArrayDequeSolution extends LinkedList { 11 | public void printDeque() { 12 | System.out.println("dummy"); 13 | } 14 | 15 | public Item getRecursive(int i) { 16 | return get(i); 17 | } 18 | 19 | public Item removeFirst() { 20 | try { 21 | return super.removeFirst(); 22 | } catch (NullPointerException e) { 23 | return null; 24 | } 25 | } 26 | 27 | public Item removeLast() { 28 | try { 29 | return super.removeLast(); 30 | } catch (NullPointerException e) { 31 | return null; 32 | } 33 | } 34 | 35 | public void addFirst(Item item){ 36 | super.addFirst(item); 37 | } 38 | 39 | public void addLast(Item item){ 40 | super.addLast(item); 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /proj1ec/tester/AssertEqualsStringDemo.java: -------------------------------------------------------------------------------- 1 | package tester; 2 | 3 | import org.junit.Test; 4 | import static org.junit.Assert.*; 5 | import edu.princeton.cs.introcs.StdRandom; 6 | /** Demos the version of assertEquals with a String message. */ 7 | public class AssertEqualsStringDemo { 8 | @Test 9 | public void test1() { 10 | int expected = 20; 11 | int actual = StdRandom.uniform(4); 12 | assertEquals("Oh noooo!\nThis is bad:\n Random number " + actual 13 | + " not equal to " + expected + "!", 14 | expected, actual); 15 | } 16 | 17 | /** This main method is optional. */ 18 | public static void main(String[] args) { 19 | jh61b.junit.TestRunner.runTests(AssertEqualsStringDemo.class); 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /proj1ec/tester/StudentArrayDequeLauncher.java: -------------------------------------------------------------------------------- 1 | package tester; 2 | 3 | import student.StudentArrayDeque; 4 | import edu.princeton.cs.introcs.StdRandom; 5 | 6 | /** If you project is set up properly, this file should execute. 7 | * One thing you might consider is to try printing out the sequence of 8 | * operations */ 9 | public class StudentArrayDequeLauncher { 10 | public static void main(String[] args) { 11 | StudentArrayDeque sad1 = new StudentArrayDeque<>(); 12 | 13 | for (int i = 0; i < 10; i += 1) { 14 | double numberBetweenZeroAndOne = StdRandom.uniform(); 15 | 16 | if (numberBetweenZeroAndOne < 0.5) { 17 | sad1.addLast(i); 18 | } else { 19 | sad1.addFirst(i); 20 | } 21 | } 22 | 23 | sad1.printDeque(); 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /proj1ec/tester/TestArrayDequeEC.java: -------------------------------------------------------------------------------- 1 | package tester; 2 | 3 | import static org.junit.Assert.*; 4 | 5 | import edu.princeton.cs.introcs.StdRandom; 6 | import org.junit.Test; 7 | import student.StudentArrayDeque; 8 | 9 | public class TestArrayDequeEC { 10 | @Test 11 | public void add10000ThenRemoveFirst10000Test(){ 12 | StudentArrayDeque sad1 = new StudentArrayDeque<>(); 13 | ArrayDequeSolution ads1 = new ArrayDequeSolution<>(); 14 | 15 | String message = ""; 16 | for (int i = 0; i < 100; i += 1) { 17 | Integer number = StdRandom.uniform(1, 100); 18 | if (number < 50){ 19 | sad1.addFirst(number); 20 | ads1.addFirst(number); 21 | message += "addFirst(" + number + ")\n"; 22 | } else { 23 | sad1.addLast(number); 24 | ads1.addLast(number); 25 | message += "addLast(" + number + ")\n"; 26 | } 27 | } 28 | 29 | Integer actual; 30 | Integer expected; 31 | for (int i = 0; i < 100; i += 1) { 32 | Integer numberZeroOrOne = StdRandom.uniform(0, 2); 33 | if (numberZeroOrOne == 1) { 34 | actual = sad1.removeFirst(); 35 | expected = ads1.removeFirst(); 36 | message += "removeFirst()\n"; 37 | } else { 38 | actual = sad1.removeLast(); 39 | expected = ads1.removeLast(); 40 | message += "removeLast()\n"; 41 | } 42 | assertEquals(message, expected, actual); 43 | 44 | } 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /proj2/Makefile: -------------------------------------------------------------------------------- 1 | # This makefile is defined to give you the following targets: 2 | # 3 | # default: The default target: Compiles the program in package db61b. 4 | # check: Compiles the gitlet package, if needed, and then performs the 5 | # tests described in testing/Makefile. 6 | # clean: Remove regeneratable files (such as .class files) produced by 7 | # other targets and Emacs backup files. 8 | # 9 | # In other words, type 'make' to compile everything; 'make check' to 10 | # compile and test everything, and 'make clean' to clean things up. 11 | # 12 | # You can use this file without understanding most of it, of course, but 13 | # I strongly recommend that you try to figure it out, and where you cannot, 14 | # that you ask questions. The Lab Reader contains documentation. 15 | 16 | # Name of package containing main procedure 17 | PACKAGE = gitlet 18 | 19 | # The name of the Python 3 program, used in the 'check' target. If your system 20 | # has a different name for this program (such as just "python"), run 21 | # the Makefile with 22 | # make PYTHON=python check 23 | PYTHON = python3 24 | 25 | # Flags to pass to tester.py. 26 | TESTER_FLAGS = 27 | 28 | RMAKE = "$(MAKE)" 29 | 30 | # Targets that don't correspond to files, but are to be treated as commands. 31 | .PHONY: default check clean 32 | 33 | default: 34 | $(RMAKE) -C $(PACKAGE) default 35 | 36 | check: default 37 | $(RMAKE) -C testing PYTHON=$(PYTHON) TESTER_FLAGS="$(TESTER_FLAGS)" check 38 | 39 | # 'make clean' will clean up stuff you can reconstruct. 40 | clean: 41 | $(RM) *~ 42 | $(RMAKE) -C $(PACKAGE) clean 43 | $(RMAKE) -C testing clean 44 | 45 | -------------------------------------------------------------------------------- /proj2/gitlet/Blob.java: -------------------------------------------------------------------------------- 1 | package gitlet; 2 | 3 | import java.io.File; 4 | import java.io.Serializable; 5 | 6 | import static gitlet.MyUtils.getFileID; 7 | import static gitlet.Utils.*; 8 | 9 | public class Blob implements Serializable { 10 | /** The id(hash code) of blob. */ 11 | private String blobID; 12 | /** The copied file id(hash code) of blob. */ 13 | private String copiedFileID; 14 | /** The copied file content of blob. */ 15 | private String copiedFileContent; 16 | /** The copied file name of blob. */ 17 | private String copiedFileName; 18 | 19 | // each blob has one file 20 | public Blob(File stagingFile) { 21 | // copiedFile just a soft link 22 | this.copiedFileID = getFileID(stagingFile); 23 | this.blobID = sha1(serialize(this)); 24 | this.copiedFileName = stagingFile.getName(); 25 | this.copiedFileContent = readContentsAsString(stagingFile); 26 | } 27 | 28 | /** get variable from blob */ 29 | public String getBlobID() { 30 | return this.blobID; 31 | } 32 | 33 | public String getCopiedFileName() { 34 | return this.copiedFileName; 35 | } 36 | 37 | public String getCopiedFileContent() { 38 | return this.copiedFileContent; 39 | } 40 | 41 | public String getCopiedFileID() { 42 | return this.copiedFileID; 43 | } 44 | } 45 | 46 | -------------------------------------------------------------------------------- /proj2/gitlet/DumpObj.java: -------------------------------------------------------------------------------- 1 | package gitlet; 2 | 3 | import java.io.File; 4 | 5 | /** A debugging class whose main program may be invoked as follows: 6 | * java gitlet.DumpObj FILE... 7 | * where each FILE is a file produced by Utils.writeObject (or any file 8 | * containing a serialized object). This will simply read FILE, 9 | * deserialize it, and call the dump method on the resulting Object. 10 | * The object must implement the gitlet.Dumpable interface for this 11 | * to work. For example, you might define your class like this: 12 | * 13 | * import java.io.Serializable; 14 | * import java.util.TreeMap; 15 | * class MyClass implements Serializeable, Dumpable { 16 | * ... 17 | * @Override 18 | * public void dump() { 19 | * System.out.printf("size: %d%nmapping: %s%n", _size, _mapping); 20 | * } 21 | * ... 22 | * int _size; 23 | * TreeMap _mapping = new TreeMap<>(); 24 | * } 25 | * 26 | * As illustrated, your dump method should print useful information from 27 | * objects of your class. 28 | * @author P. N. Hilfinger 29 | */ 30 | public class DumpObj { 31 | 32 | /** Deserialize and apply dump to the contents of each of the files 33 | * in FILES. */ 34 | public static void main(String... files) { 35 | for (String fileName : files) { 36 | Dumpable obj = Utils.readObject(new File(fileName), 37 | Dumpable.class); 38 | obj.dump(); 39 | System.out.println("---"); 40 | } 41 | } 42 | } 43 | 44 | -------------------------------------------------------------------------------- /proj2/gitlet/Dumpable.java: -------------------------------------------------------------------------------- 1 | package gitlet; 2 | 3 | import java.io.Serializable; 4 | 5 | /** An interface describing dumpable objects. 6 | * @author P. N. Hilfinger 7 | */ 8 | interface Dumpable extends Serializable { 9 | /** Print useful information about this object on System.out. */ 10 | void dump(); 11 | } 12 | -------------------------------------------------------------------------------- /proj2/gitlet/GitletException.java: -------------------------------------------------------------------------------- 1 | package gitlet; 2 | 3 | /** General exception indicating a Gitlet error. For fatal errors, the 4 | * result of .getMessage() is the error message to be printed. 5 | * @author P. N. Hilfinger 6 | */ 7 | class GitletException extends RuntimeException { 8 | 9 | 10 | /** A GitletException with no message. */ 11 | GitletException() { 12 | super(); 13 | } 14 | 15 | /** A GitletException MSG as its message. */ 16 | GitletException(String msg) { 17 | super(msg); 18 | } 19 | 20 | } 21 | -------------------------------------------------------------------------------- /proj2/gitlet/Makefile: -------------------------------------------------------------------------------- 1 | # This makefile is defined to give you the following targets: 2 | # 3 | # default: The default target: Compiles $(PROG) and whatever it 4 | # depends on. 5 | # check: Compile $(PROG), if needed, and then for each file, F.in, in 6 | # directory testing, use F.in as input to "java $(MAIN_CLASS)" and 7 | # compare the output to the contents of the file names F.out. 8 | # Report discrepencies. 9 | # clean: Remove all the .class files produced by java compilation, 10 | # all Emacs backup files, and testing output files. 11 | # 12 | # In other words, type 'make' to compile everything; 'make check' to 13 | # compile and test everything, and 'make clean' to clean things up. 14 | # 15 | # You can use this file without understanding most of it, of course, but 16 | # I strongly recommend that you try to figure it out, and where you cannot, 17 | # that you ask questions. 18 | 19 | JFLAGS = -g -Xlint:unchecked -Xlint:deprecation 20 | 21 | CLASSDIR = ../classes 22 | 23 | # See comment in ../Makefile 24 | PYTHON = python3 25 | 26 | RMAKE = "$(MAKE)" 27 | 28 | # A CLASSPATH value that (seems) to work on both Windows and Unix systems. 29 | # To Unix, it looks like ..:$(CLASSPATH):JUNK and to Windows like 30 | # JUNK;..;$(CLASSPATH). 31 | 32 | LIB = ../../library-sp21/javalib/* 33 | 34 | 35 | CPATH = "$(LIB):..:$(CLASSPATH):;$(LIB);..;$(CLASSPATH)" 36 | 37 | # All .java files in this directory. 38 | SRCS := $(wildcard *.java) 39 | 40 | .PHONY: default check clean 41 | 42 | # As a convenience, you can compile a single Java file X.java in this directory 43 | # with 'make X.class' 44 | %.class: %.java 45 | javac $(JFLAGS) -cp $(CPATH) $< 46 | 47 | # First, and therefore default, target. 48 | default: sentinel 49 | 50 | check: 51 | $(RMAKE) -C .. PYTHON=$(PYTHON) check 52 | 53 | integration: 54 | $(RMAKE) -C .. PYTHON=$(PYTHON) integration 55 | 56 | # 'make clean' will clean up stuff you can reconstruct. 57 | clean: 58 | $(RM) *~ *.class sentinel 59 | 60 | ### DEPENDENCIES ### 61 | 62 | sentinel: $(SRCS) 63 | javac $(JFLAGS) -cp $(CPATH) $(SRCS) 64 | touch sentinel 65 | -------------------------------------------------------------------------------- /proj2/gitlet/MyUtils.java: -------------------------------------------------------------------------------- 1 | package gitlet; 2 | 3 | import java.io.File; 4 | import java.io.Serializable; 5 | import java.util.List; 6 | 7 | import static gitlet.Repository.*; 8 | import static gitlet.Utils.*; 9 | 10 | public class MyUtils { 11 | // in blobs, 12 | // we may use same blob so, we need to compare ID to parent 13 | public static void saveDirAndObjInBlobs(Serializable SerObj, File FOLDER, String ID) { 14 | Commit parentCommit = getCurrentCommit(); 15 | // get blobIDs of parent 16 | List parentBlobIDs = parentCommit.getBlobIDs(); 17 | if (parentBlobIDs.size() != 0) { 18 | for (String parentBlobID : parentBlobIDs) { 19 | // if equaling parentBlobID, directly return, NOT need to create blobFile 20 | if (ID.equals(parentBlobID)) { 21 | return; 22 | } 23 | } 24 | } 25 | // compared substring(2 chars) to determine create subdir or not 26 | List dirIDList = Utils.plainFilenamesIn(FOLDER); 27 | String dirID = getDirID(ID); 28 | if (!dirIDList.contains(dirID)) { 29 | saveDir(FOLDER, dirID); 30 | } 31 | // compared blobID to determine create blob or not 32 | List IDList = Utils.plainFilenamesIn(join(FOLDER, dirID)); 33 | if (IDList != null && !IDList.contains(ID)) { 34 | saveObj(FOLDER, dirID, ID, SerObj); 35 | } 36 | } 37 | 38 | // set the first and second characters of blob id as name of folder of blobs 39 | public static String getDirID(String ID) { 40 | return ID.substring(0, 2); 41 | } 42 | 43 | public static void saveDir(File FOLDER, String dirID) { 44 | File dir = join(FOLDER, dirID); 45 | dir.mkdir(); 46 | } 47 | 48 | // save file by FOLDER, subdirectory ID and current ID 49 | public static void saveObj(File FOLDER, String dirID, String ID, Serializable SerObj) { 50 | File file = join(FOLDER, dirID, ID); 51 | writeObject(file, SerObj); 52 | } 53 | 54 | // in commits, 55 | // each commit is only one, so we don't need to compare ID 56 | // save file by FOLDER 57 | public static void saveObj(File FOLDER, String name, Serializable SerObj) { 58 | File file = join(FOLDER, name); 59 | writeObject(file, SerObj); 60 | } 61 | 62 | // saveObj vs saveContent 63 | // Obj: writeObject(file, SerObj); 64 | // File: writeObject(file, content); 65 | public static void saveContent(File FOLDER, String name, String content) { 66 | File file = join(FOLDER, name); 67 | writeContents(file, content); 68 | } 69 | 70 | // using with CWD/STAGING/REMOVED/blob/commit 71 | // get file id by using filename and file content(as string) 72 | public static String getFileID(File file) { 73 | return sha1(serialize(file.getName()), serialize(readContentsAsString(file))); 74 | } 75 | 76 | // validate filesystem 77 | public static boolean validateDirAndFolder(){ 78 | return GITLET_DIR.exists(); 79 | } 80 | } 81 | -------------------------------------------------------------------------------- /proj2/gitlet/Pointer.java: -------------------------------------------------------------------------------- 1 | package gitlet; 2 | 3 | import java.io.Serializable; 4 | 5 | import static gitlet.Repository.*; 6 | import static gitlet.MyUtils.*; 7 | 8 | public class Pointer implements Serializable { 9 | // HEAD point to active branch 10 | // branch point to a commit 11 | // master 12 | // other branch 13 | private String commitID; 14 | private String branchName; 15 | private String initCommitID; 16 | private String activeBranchName; 17 | 18 | // construct pointer of HEAD/branch 19 | public Pointer(boolean isHead, String Name, String ID) { 20 | if (isHead) { 21 | this.initCommitID = ID; 22 | this.activeBranchName = Name; 23 | } else { 24 | this.commitID = ID; 25 | this.branchName = Name; 26 | } 27 | } 28 | 29 | /** save branch/head */ 30 | // save branch by branchName 31 | public void saveBranchFile() { 32 | saveObj(BRANCH_FOLDER, this.branchName, this); 33 | } 34 | 35 | // save HEAD by headName 36 | public void saveHEADFile() { 37 | saveObj(GITLET_DIR, headName, this); 38 | } 39 | 40 | /** get variable from commit */ 41 | // get ActiveBranchName in HEAD 42 | public String getActiveBranchName() { 43 | return this.activeBranchName; 44 | } 45 | 46 | // get initCommitID in HEAD 47 | public String getInitCommitID() { 48 | return this.initCommitID; 49 | } 50 | 51 | // get CommitID in branch 52 | public String getCommitID() { 53 | return this.commitID; 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /proj2/gitlet/Remote.java: -------------------------------------------------------------------------------- 1 | package gitlet; 2 | 3 | import java.io.File; 4 | import java.io.IOException; 5 | import java.io.Serializable; 6 | import java.nio.file.Paths; 7 | import java.util.List; 8 | 9 | import static gitlet.MyUtils.*; 10 | import static gitlet.Repository.*; 11 | import static gitlet.Utils.*; 12 | 13 | public class Remote implements Serializable { 14 | private String remoteName; 15 | private File remoteDir; 16 | 17 | // we don't hard copy of dir, we just use soft link of dir 18 | public Remote(String remoteName, String dirPathString) { 19 | this.remoteName = remoteName; 20 | // get directory 21 | this.remoteDir = join(dirPathString); 22 | } 23 | 24 | // get branch names 25 | public List getBranchNames() { 26 | return plainFilenamesIn(join(remoteDir, "branch")); 27 | } 28 | 29 | // get remote name 30 | public String getRemoteName() { 31 | return remoteName; 32 | } 33 | 34 | // get remote directory 35 | public File getRemoteDir() { 36 | return remoteDir; 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /proj2/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 4.0.0 6 | 7 | 8 | junit 9 | junit 10 | RELEASE 11 | compile 12 | 13 | 14 | 15 | 16 | CS61B 17 | 61BMasterPom 18 | 1.0-SNAPSHOT 19 | ../library-sp21/javalib/masterpom.xml 20 | 21 | 22 | CS61B 23 | proj2 24 | 1.0-SNAPSHOT 25 | 26 | 27 | ${project.basedir} 28 | ${project.basedir} 29 | 30 | 31 | org.apache.maven.plugins 32 | maven-compiler-plugin 33 | 3.1 34 | 35 | ${java.version} 36 | ${java.version} 37 | 38 | 39 | 40 | org.apache.maven.plugins 41 | maven-compiler-plugin 42 | 3.8.1 43 | 44 | 45 | -J-XX:+ShowCodeDetailsInExceptionMessages 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | -------------------------------------------------------------------------------- /proj2/testing/Makefile: -------------------------------------------------------------------------------- 1 | # This makefile is defined to give you the following targets: 2 | # 3 | # default: Same as check 4 | # check: Run the integration tests. 5 | # clean: Remove all files and directories generated by testing. 6 | # 7 | 8 | SHELL = /bin/bash 9 | 10 | # Flags to Java interpreter: check assertions 11 | JFLAGS = -ea 12 | 13 | # See comment in ../Makefile 14 | PYTHON = python3 15 | 16 | RMAKE = "$(MAKE)" 17 | 18 | TESTER = CLASSPATH="$$(pwd)/..:$(CLASSPATH):;$$(pwd)/..;$(CLASSPATH)" $(PYTHON) tester.py 19 | 20 | TESTER_FLAGS = 21 | 22 | TESTS = samples/*.in student_tests/*.in *.in 23 | 24 | .PHONY: default check clean std 25 | 26 | # First, and therefore default, target. 27 | default: 28 | $(RMAKE) -C .. 29 | $(RMAKE) PYTHON=$(PYTHON) check 30 | 31 | check: 32 | @echo "Testing application gitlet.Main..." 33 | $(TESTER) $(TESTER_FLAGS) $(TESTS) 34 | 35 | # 'make clean' will clean up stuff you can reconstruct. 36 | clean: 37 | $(RM) -r */*~ *~ __pycache__ -------------------------------------------------------------------------------- /proj2/testing/samples/definitions.inc: -------------------------------------------------------------------------------- 1 | # Standard definitions 2 | D DATE "Date: \w\w\w \w\w\w \d+ \d\d:\d\d:\d\d \d\d\d\d [-+]\d\d\d\d" 3 | # A status log header RE. Captures the commit id in its sole group. 4 | D COMMIT_HEAD "commit ([a-f0-9]+)[ \t]*\n(?:Merge:\s+[0-9a-f]{7}\s+[0-9a-f]{7}[ ] *\n)?${DATE}" 5 | # A full log entry. Captures the entry. Assume logs messages don't contain 6 | # "===" 7 | D COMMIT_LOG "(===[ ]*\ncommit [a-f0-9]+[ ]*\n(?:Merge:\s+[0-9a-f]{7}\s+[0-9a-f]{7}[ ]*\n)?${DATE}[ ]*\n(?:.|\n)*?(?=\Z|\n===))" 8 | # An arbitrary line of text (works even with ?s) 9 | D ARBLINE "[^\n]*(?=\n|\Z)" 10 | # Zero or more arbitrary full lines of text. 11 | D ARBLINES "(?:(?:.|\n)*(?:\n|\Z)|\A|\Z)" 12 | -------------------------------------------------------------------------------- /proj2/testing/samples/test01-init.in: -------------------------------------------------------------------------------- 1 | # Basic initialization 2 | > init 3 | <<< 4 | E .gitlet 5 | -------------------------------------------------------------------------------- /proj2/testing/samples/test02-basic-checkout.in: -------------------------------------------------------------------------------- 1 | # A simple test of adding, committing, modifying, and checking out. 2 | > init 3 | <<< 4 | + wug.txt wug.txt 5 | > add wug.txt 6 | <<< 7 | > commit "added wug" 8 | <<< 9 | + wug.txt notwug.txt 10 | # Must change 11 | > checkout -- wug.txt 12 | <<< 13 | = wug.txt wug.txt 14 | -------------------------------------------------------------------------------- /proj2/testing/samples/test03-basic-log.in: -------------------------------------------------------------------------------- 1 | # Set up a simple chain of commits and check their log. 2 | > init 3 | <<< 4 | + wug.txt wug.txt 5 | > add wug.txt 6 | <<< 7 | > commit "added wug" 8 | <<< 9 | D HEADER "commit [a-f0-9]+" 10 | D DATE "Date: \w\w\w \w\w\w \d+ \d\d:\d\d:\d\d \d\d\d\d [-+]\d\d\d\d" 11 | > log 12 | === 13 | ${HEADER} 14 | ${DATE} 15 | added wug 16 | 17 | === 18 | ${HEADER} 19 | ${DATE} 20 | initial commit 21 | 22 | <<<* 23 | -------------------------------------------------------------------------------- /proj2/testing/samples/test04-prev-checkout.in: -------------------------------------------------------------------------------- 1 | # Check that we can check out a previous version. 2 | > init 3 | <<< 4 | + wug.txt wug.txt 5 | > add wug.txt 6 | <<< 7 | > commit "version 1 of wug.txt" 8 | <<< 9 | + wug.txt notwug.txt 10 | > add wug.txt 11 | <<< 12 | > commit "version 2 of wug.txt" 13 | <<< 14 | = wug.txt notwug.txt 15 | # Each ${HEADER} captures its commit UID. 16 | D UID "[a-f0-9]+" 17 | D HEADER "commit (${UID})" 18 | D DATE "Date: \w\w\w \w\w\w \d+ \d\d:\d\d:\d\d \d\d\d\d [-+]\d\d\d\d" 19 | > log 20 | === 21 | ${HEADER} 22 | ${DATE} 23 | version 2 of wug.txt 24 | 25 | === 26 | ${HEADER} 27 | ${DATE} 28 | version 1 of wug.txt 29 | 30 | === 31 | ${HEADER} 32 | ${DATE} 33 | initial commit 34 | 35 | <<<* 36 | # UID of second version 37 | D UID2 "${1}" 38 | # UID of current version 39 | D UID1 "${2}" 40 | > checkout ${UID1} -- wug.txt 41 | <<< 42 | = wug.txt wug.txt 43 | > checkout ${UID2} -- wug.txt 44 | <<< 45 | = wug.txt notwug.txt 46 | -------------------------------------------------------------------------------- /proj2/testing/src/a.txt: -------------------------------------------------------------------------------- 1 | a 2 | -------------------------------------------------------------------------------- /proj2/testing/src/b.txt: -------------------------------------------------------------------------------- 1 | b 2 | -------------------------------------------------------------------------------- /proj2/testing/src/c.txt: -------------------------------------------------------------------------------- 1 | c 2 | -------------------------------------------------------------------------------- /proj2/testing/src/conflict1.txt: -------------------------------------------------------------------------------- 1 | <<<<<<< HEAD 2 | Another wug. 3 | ======= 4 | This is not a wug. 5 | >>>>>>> 6 | -------------------------------------------------------------------------------- /proj2/testing/src/conflict2.txt: -------------------------------------------------------------------------------- 1 | <<<<<<< HEAD 2 | Another wug. 3 | ======= 4 | >>>>>>> 5 | -------------------------------------------------------------------------------- /proj2/testing/src/d.txt: -------------------------------------------------------------------------------- 1 | d 2 | -------------------------------------------------------------------------------- /proj2/testing/src/e.txt: -------------------------------------------------------------------------------- 1 | e 2 | -------------------------------------------------------------------------------- /proj2/testing/src/f.txt: -------------------------------------------------------------------------------- 1 | not f 2 | -------------------------------------------------------------------------------- /proj2/testing/src/g.txt: -------------------------------------------------------------------------------- 1 | is g 2 | -------------------------------------------------------------------------------- /proj2/testing/src/nota.txt: -------------------------------------------------------------------------------- 1 | not a 2 | -------------------------------------------------------------------------------- /proj2/testing/src/notb.txt: -------------------------------------------------------------------------------- 1 | not b 2 | -------------------------------------------------------------------------------- /proj2/testing/src/notf.txt: -------------------------------------------------------------------------------- 1 | not f 2 | -------------------------------------------------------------------------------- /proj2/testing/src/notwug.txt: -------------------------------------------------------------------------------- 1 | This is not a wug. 2 | -------------------------------------------------------------------------------- /proj2/testing/src/wug.txt: -------------------------------------------------------------------------------- 1 | This is a wug. 2 | -------------------------------------------------------------------------------- /proj2/testing/src/wug2.txt: -------------------------------------------------------------------------------- 1 | Another wug. 2 | -------------------------------------------------------------------------------- /proj2/testing/src/wug3.txt: -------------------------------------------------------------------------------- 1 | And yet another wug. 2 | -------------------------------------------------------------------------------- /proj2/testing/student_tests/definitions.inc: -------------------------------------------------------------------------------- 1 | # Standard definitions 2 | D DATE "Date: \w\w\w \w\w\w \d+ \d\d:\d\d:\d\d \d\d\d\d [-+]\d\d\d\d" 3 | # A status log header RE. Captures the commit id in its sole group. 4 | D COMMIT_HEAD "commit ([a-f0-9]+)[ \t]*\n(?:Merge:\s+[0-9a-f]{7}\s+[0-9a-f]{7}[ ]*\n)?${DATE}" 5 | # A full log entry. Captures the entry. Assume logs messages don't contain 6 | # "===" 7 | D COMMIT_LOG "(===[ ]*\ncommit [a-f0-9]+[ ]*\n(?:Merge:\s+[0-9a-f]{7}\s+[0-9a-f]{7}[ ]*\n)?${DATE}[ ]*\n(?:.|\n)*?(?=\Z|\n===))" 8 | # An arbitrary line of text (works even with ?s) 9 | D ARBLINE "[^\n]*(?=\n|\Z)" 10 | # Zero or more arbitrary full lines of text. 11 | D ARBLINES "(?:(?:.|\n)*(?:\n|\Z)|\A|\Z)" 12 | -------------------------------------------------------------------------------- /proj3/.save/saveEngine.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/duilec/CS61B-spring2021/83e75670a7d918309695a88e498700e4eafd7d93/proj3/.save/saveEngine.txt -------------------------------------------------------------------------------- /proj3/byow/Core/BYOWException.java: -------------------------------------------------------------------------------- 1 | package byow.Core; 2 | 3 | public class BYOWException extends RuntimeException { 4 | /** A BYOWException with no message. */ 5 | BYOWException() { 6 | super(); 7 | } 8 | 9 | /** A BYOWException MSG as its message. */ 10 | BYOWException(String msg) { 11 | super(msg); 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /proj3/byow/Core/Main.java: -------------------------------------------------------------------------------- 1 | package byow.Core; 2 | 3 | /** This is the main entry point for the program. This class simply parses 4 | * the command line inputs, and lets the byow.Core.Engine class take over 5 | * in either keyboard or input string mode. 6 | */ 7 | public class Main { 8 | public static void main(String[] args) { 9 | if (args.length > 2) { 10 | System.out.println("Can only have two arguments - the flag and input string"); 11 | System.exit(0); 12 | } else if (args.length == 2 && args[0].equals("-s")) { 13 | Engine engine = new Engine(); 14 | engine.interactWithInputString(args[1]); 15 | System.out.println(engine.toString()); 16 | // DO NOT CHANGE THESE LINES YET ;) 17 | } else if (args.length == 2 && args[0].equals("-p")) { System.out.println("Coming soon."); } 18 | // DO NOT CHANGE THESE LINES YET ;) 19 | else { 20 | Engine engine = new Engine(); 21 | engine.interactWithKeyboard(); 22 | } 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /proj3/byow/Core/Menu.java: -------------------------------------------------------------------------------- 1 | package byow.Core; 2 | 3 | import edu.princeton.cs.introcs.StdDraw; 4 | 5 | import java.awt.*; 6 | import java.io.Serializable; 7 | 8 | public class Menu implements Serializable { 9 | /** The width of the menu of window of this game. */ 10 | private int width; 11 | /** The height of the menu of window of this game. */ 12 | private int height; 13 | 14 | private final String titleContent = "My World"; 15 | private final String[] menuContents = {"New Game (N)", "Load Game (L)", "Quit (Q)", "Primary Features (P)"}; 16 | 17 | public Menu(int width, int height) { 18 | /* Sets up StdDraw so that it has a width by height grid of 16 by 16 squares as its canvas 19 | * Also sets up the scale so the top left is (0,0) and the bottom right is (width, height) 20 | */ 21 | this.width = width; 22 | this.height = height; 23 | StdDraw.setCanvasSize(this.width * 16, this.height * 16); 24 | StdDraw.setXscale(0, this.width); 25 | StdDraw.setYscale(0, this.height); 26 | StdDraw.clear(Color.BLACK); 27 | StdDraw.enableDoubleBuffering(); 28 | } 29 | 30 | public void drawMenu() { 31 | // Take the string and display it in the center of the screen 32 | StdDraw.clear(Color.black); 33 | StdDraw.setPenColor(Color.white); 34 | // title 35 | Font font = new Font("Monaco", Font.BOLD, 50); 36 | StdDraw.setFont(font); 37 | StdDraw.text(this.width / 2.0, this.height * (2.0 / 3.0), titleContent); 38 | // menu 39 | font = new Font("Monaco", Font.BOLD, 20); 40 | StdDraw.setFont(font); 41 | int distance = 0; 42 | for (String menuContent : menuContents) { 43 | StdDraw.text(this.width / 2.0, this.height / 2.0 - distance, menuContent); 44 | // distance bias is 2 45 | distance += 2; 46 | } 47 | StdDraw.show(); 48 | } 49 | 50 | } 51 | -------------------------------------------------------------------------------- /proj3/byow/InputDemo/DemoInputSource.java: -------------------------------------------------------------------------------- 1 | package byow.InputDemo; 2 | 3 | /** 4 | * Created by hug. 5 | * Demonstrates how a single interface can be used to provide input 6 | * from they keyboard, from a random sequence, from a string, or whatever else. 7 | */ 8 | public class DemoInputSource { 9 | private static final int KEYBOARD = 0; 10 | private static final int RANDOM = 1; 11 | private static final int STRING = 2; 12 | 13 | public static void main(String[] args) { 14 | int inputType = KEYBOARD; 15 | 16 | InputSource inputSource; 17 | 18 | if (inputType == KEYBOARD) { 19 | inputSource = new KeyboardInputSource(); 20 | } else if (inputType == RANDOM) { 21 | inputSource = new RandomInputSource(50L); 22 | } else { // inputType == STRING 23 | inputSource = new StringInputDevice("HELLO MY FRIEND. QUACK QUACK"); 24 | } 25 | 26 | int totalCharacters = 0; 27 | 28 | while (inputSource.possibleNextInput()) { 29 | totalCharacters += 1; 30 | char c = inputSource.getNextKey(); 31 | if (c == 'M') { 32 | System.out.println("moo"); 33 | } 34 | if (c == 'Q') { 35 | System.out.println("done."); 36 | break; 37 | } 38 | } 39 | 40 | System.out.println("Processed " + totalCharacters + " characters."); 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /proj3/byow/InputDemo/InputSource.java: -------------------------------------------------------------------------------- 1 | package byow.InputDemo; 2 | 3 | /** 4 | * Created by hug. 5 | */ 6 | public interface InputSource { 7 | public char getNextKey(); 8 | public boolean possibleNextInput(); 9 | } 10 | -------------------------------------------------------------------------------- /proj3/byow/InputDemo/KeyboardInputSource.java: -------------------------------------------------------------------------------- 1 | package byow.InputDemo; 2 | 3 | /** 4 | * Created by hug. 5 | */ 6 | import edu.princeton.cs.introcs.StdDraw; 7 | 8 | public class KeyboardInputSource implements InputSource { 9 | private static final boolean PRINT_TYPED_KEYS = false; 10 | public KeyboardInputSource() { 11 | StdDraw.text(0.3, 0.3, "press m to moo, q to quit"); 12 | } 13 | 14 | public char getNextKey() { 15 | while (true) { 16 | if (StdDraw.hasNextKeyTyped()) { 17 | char c = Character.toUpperCase(StdDraw.nextKeyTyped()); 18 | if (PRINT_TYPED_KEYS) { 19 | System.out.print(c); 20 | } 21 | return c; 22 | } 23 | } 24 | } 25 | 26 | public boolean possibleNextInput() { 27 | return true; 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /proj3/byow/InputDemo/RandomInputSource.java: -------------------------------------------------------------------------------- 1 | package byow.InputDemo; 2 | 3 | import edu.princeton.cs.introcs.StdDraw; 4 | 5 | import java.util.Random; 6 | 7 | /** 8 | * Created by hug. 9 | */ 10 | public class RandomInputSource implements InputSource { 11 | Random r; 12 | 13 | public RandomInputSource(Long seed) { 14 | r = new Random(seed); 15 | } 16 | 17 | /** Returns a random letter between a and z.*/ 18 | public char getNextKey() { 19 | return (char) (r.nextInt(26) + 'A'); 20 | } 21 | 22 | public boolean possibleNextInput() { 23 | return true; 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /proj3/byow/InputDemo/StringInputDevice.java: -------------------------------------------------------------------------------- 1 | package byow.InputDemo; 2 | 3 | /** 4 | * Created by hug. 5 | */ 6 | public class StringInputDevice implements InputSource { 7 | private String input; 8 | private int index; 9 | 10 | public StringInputDevice(String s) { 11 | index = 0; 12 | input = s; 13 | } 14 | 15 | public char getNextKey() { 16 | char returnChar = input.charAt(index); 17 | index += 1; 18 | return returnChar; 19 | } 20 | 21 | public boolean possibleNextInput() { 22 | return index < input.length(); 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /proj3/byow/Networking/BYOWServer.java: -------------------------------------------------------------------------------- 1 | package byow.Networking; 2 | 3 | import edu.princeton.cs.introcs.StdDraw; 4 | 5 | import java.io.*; 6 | import java.net.ServerSocket; 7 | import java.net.Socket; 8 | import java.nio.file.Paths; 9 | 10 | /** 11 | * Created by Arjun Sahai and Boren Tsai. 12 | */ 13 | 14 | public class BYOWServer { 15 | 16 | static private final File CWD = new File(System.getProperty("user.dir")); 17 | static private final String CANVAS_FILE = ".server_canvas.png"; 18 | 19 | private ServerSocket serverSocket; 20 | private Socket clientStringSocket; 21 | private Socket clientWriteSocket; 22 | 23 | private BufferedReader in; 24 | private BufferedWriter out; 25 | private DataOutputStream dos; 26 | 27 | public BYOWServer(int port) throws IOException { 28 | serverSocket = new ServerSocket(port); 29 | System.out.println("Server started. Waiting for client to connect... "); 30 | clientWriteSocket = serverSocket.accept(); // block until client connects 31 | clientStringSocket = serverSocket.accept(); 32 | in = new BufferedReader(new InputStreamReader(clientStringSocket.getInputStream())); 33 | out = new BufferedWriter(new OutputStreamWriter(clientStringSocket.getOutputStream())); 34 | dos = new DataOutputStream(clientWriteSocket.getOutputStream()); 35 | System.out.println("Client connected!"); 36 | } 37 | 38 | public void sendCanvasConfig(int width, int height) { 39 | sendCanvas(width, height, true); 40 | } 41 | 42 | public void sendCanvas() { 43 | sendCanvas(0, 0, false); 44 | } 45 | 46 | /* 47 | This method will check to see if the client is sending a key press to the server 48 | This will not block your code 49 | */ 50 | public boolean clientHasKeyTyped() { 51 | try { 52 | return in.ready(); 53 | } catch (IOException e) { 54 | stopConnection(); 55 | return false; 56 | } 57 | } 58 | 59 | /* 60 | Gives the next character sent from the client. 61 | If the client has not sent anything yet, then this method will block 62 | */ 63 | public char clientNextKeyTyped() { 64 | try { 65 | return (char) in.read(); 66 | } catch (IOException e) { 67 | System.out.println("IO EXCEPTION CAUGHT"); 68 | stopConnection(); 69 | return 'q'; 70 | } 71 | } 72 | 73 | /* 74 | Closes all input/output streams and sockets. 75 | */ 76 | public void stopConnection() { 77 | try { 78 | out.write("QUIT"); 79 | out.flush(); 80 | in.close(); 81 | dos.close(); 82 | clientStringSocket.close(); 83 | clientWriteSocket.close(); 84 | serverSocket.close(); 85 | } catch (IOException e) { 86 | return; 87 | } 88 | } 89 | 90 | /* 91 | Sends world bitmap and, optionally, StdDraw canvas configuration metadata. 92 | */ 93 | private void sendCanvas(int width, int height, boolean sendConfig) { 94 | try { 95 | dos.writeBoolean(sendConfig); 96 | 97 | if (sendConfig) { 98 | dos.writeInt(width); 99 | dos.writeInt(height); 100 | dos.flush(); 101 | } else { 102 | dos.flush(); 103 | } 104 | 105 | 106 | // Save the canvas to a PNG file 107 | StdDraw.save(CANVAS_FILE); 108 | File canvas = join(CWD, CANVAS_FILE); 109 | 110 | // Send file size and unblock client from waiting 111 | dos.writeLong(canvas.length()); 112 | dos.flush(); 113 | 114 | FileInputStream fis = new FileInputStream(canvas); 115 | 116 | // break file into chunks and send to client 117 | int bytes; 118 | byte[] buffer = new byte[4 * 1024]; 119 | while ((bytes = fis.read(buffer)) != -1) { 120 | dos.write(buffer, 0, bytes); 121 | dos.flush(); 122 | } 123 | fis.close(); 124 | } catch (IOException e) { 125 | stopConnection(); 126 | } 127 | } 128 | 129 | private static File join(File first, String... others) { 130 | return Paths.get(first.getPath(), others).toFile(); 131 | } 132 | } 133 | -------------------------------------------------------------------------------- /proj3/byow/TileEngine/TETileWrapper.java: -------------------------------------------------------------------------------- 1 | package byow.TileEngine; 2 | 3 | import java.io.Serializable; 4 | 5 | public class TETileWrapper implements Serializable { 6 | // Tile type 7 | private TETile tile; 8 | // booleanValue 9 | private boolean marked; 10 | private boolean isRoom; 11 | // x, y 12 | private int x; 13 | private int y; 14 | 15 | // number of room 16 | private int roomNum; 17 | 18 | // it is around(i.e. four corners, walls and door) of room? 19 | // the floor is not around in room 20 | private boolean isAround = false; 21 | 22 | public TETileWrapper(TETile tile, int x, int y) { 23 | this.tile = tile; 24 | this.x = x; 25 | this.y = y; 26 | this.marked = false; 27 | this.isRoom = false; 28 | } 29 | 30 | public void setTile(TETile tile) { 31 | this.tile = tile; 32 | } 33 | 34 | public TETile getTile() { 35 | return tile; 36 | } 37 | 38 | // mark a tile 39 | public void markTile(boolean markedValue) { 40 | marked = markedValue; 41 | } 42 | // the tile be marked in world? 43 | public boolean isMarked() { 44 | return marked; 45 | } 46 | 47 | // mark a room 48 | public void markRoom() { 49 | isRoom = true; 50 | } 51 | // the tile is room in world? 52 | public boolean isRoom() { 53 | return isRoom; 54 | } 55 | 56 | // set x 57 | public void setX(Integer x) { 58 | this.x = x; 59 | } 60 | // get x 61 | public int getX() { 62 | return x; 63 | } 64 | 65 | // set y 66 | public void setY(Integer y) { 67 | this.y = y; 68 | } 69 | // get y 70 | public int getY() { 71 | return y; 72 | } 73 | 74 | // set number of room 75 | public void setRoomNum(int roomNum) { 76 | this.roomNum = roomNum; 77 | } 78 | // get number of room 79 | public int getRoomNum() { 80 | return roomNum; 81 | } 82 | 83 | // set isAround 84 | public void setIsAround() { 85 | this.isAround = true; 86 | } 87 | // get isAround 88 | public boolean getIsAround() { 89 | return isAround; 90 | } 91 | } 92 | -------------------------------------------------------------------------------- /proj3/byow/TileEngine/Tileset.java: -------------------------------------------------------------------------------- 1 | package byow.TileEngine; 2 | 3 | import java.awt.Color; 4 | import java.io.Serializable; 5 | 6 | /** 7 | * Contains constant tile objects, to avoid having to remake the same tiles in different parts of 8 | * the code. 9 | * 10 | * You are free to (and encouraged to) create and add your own tiles to this file. This file will 11 | * be turned in with the rest of your code. 12 | * 13 | * Ex: 14 | * world[x][y] = Tileset.FLOOR; 15 | * 16 | * The style checker may crash when you try to style check this file due to use of unicode 17 | * characters. This is OK. 18 | */ 19 | 20 | public class Tileset implements Serializable { 21 | public static final TETile AVATAR = new TETile('@', Color.white, Color.black, "you"); 22 | // public static final TETile WALL = new TETile('#', new Color(216, 128, 128), Color.darkGray, 23 | // "wall"); 24 | public static final TETile FLOOR = new TETile('.', new Color(128, 192, 128), Color.black, 25 | "floor"); 26 | public static final TETile NOTHING = new TETile(' ', Color.black, Color.black, "nothing"); 27 | public static final TETile GRASS = new TETile('"', Color.green, Color.black, "grass"); 28 | public static final TETile WATER = new TETile('≈', Color.blue, Color.black, "water"); 29 | public static final TETile FLOWER = new TETile('❀', Color.magenta, Color.pink, "flower"); 30 | public static final TETile LOCKED_DOOR = new TETile('█', Color.orange, Color.black, 31 | "locked door"); 32 | public static final TETile UNLOCKED_DOOR = new TETile('▢', Color.orange, Color.black, 33 | "unlocked door"); 34 | public static final TETile SAND = new TETile('▒', Color.yellow, Color.black, "sand"); 35 | public static final TETile MOUNTAIN = new TETile('▲', Color.gray, Color.black, "mountain"); 36 | public static final TETile TREE = new TETile('♠', Color.green, Color.black, "tree"); 37 | 38 | //We strongly recommend adding your own tiles as well. 39 | public static final TETile WALL = new TETile(' ', Color.gray, Color.darkGray, 40 | "wall"); 41 | 42 | // the level of deep of color 43 | public static final int levelWithLights = 8; 44 | // the lights 45 | public static TETile[] LIGHTS = new TETile[levelWithLights]; 46 | 47 | public static void generateLightWithBlue() { 48 | int r = 30; 49 | int g = 144; 50 | int b = 255; 51 | Color backgroundColor = new Color(r, g, b); 52 | LIGHTS[0] = new TETile('●', Color.white, backgroundColor, "light"); 53 | for (int i = 1; i < levelWithLights; i += 1) { 54 | backgroundColor = new Color(r -= 4, g -= 20, b -= 30); 55 | LIGHTS[i] = new TETile('.', Color.white, backgroundColor, "light"); 56 | } 57 | } 58 | 59 | public static void generateLightWithYellow() { 60 | int r = 255; 61 | int g = 255; 62 | int b = 100; 63 | Color backgroundColor = new Color(r, g, b); 64 | LIGHTS[0] = new TETile('●', Color.white, backgroundColor, "light"); 65 | for (int i = 1; i < levelWithLights; i += 1) { 66 | backgroundColor = new Color(r -= 20, g -= 20, b += 5); 67 | LIGHTS[i] = new TETile('.', Color.white, backgroundColor, "light"); 68 | } 69 | } 70 | 71 | public static void generateLightWithoutBackground() { 72 | LIGHTS[0] = new TETile('●', Color.white, Color.black, "light"); 73 | for (int i = 1; i < levelWithLights; i += 1) { 74 | LIGHTS[i] = new TETile('.', Color.white, Color.black, "light"); 75 | } 76 | } 77 | } 78 | 79 | 80 | -------------------------------------------------------------------------------- /proj3/byow/lab12/BoringWorldDemo.java: -------------------------------------------------------------------------------- 1 | package byow.lab12; 2 | 3 | import byow.TileEngine.TERenderer; 4 | import byow.TileEngine.TETile; 5 | import byow.TileEngine.Tileset; 6 | 7 | /** 8 | * Draws a world that is mostly empty except for a small region. 9 | */ 10 | public class BoringWorldDemo { 11 | 12 | private static final int WIDTH = 60; 13 | private static final int HEIGHT = 30; 14 | 15 | public static void main(String[] args) { 16 | // initialize the tile rendering engine with a window of size WIDTH x HEIGHT 17 | TERenderer ter = new TERenderer(); 18 | ter.initialize(WIDTH, HEIGHT); 19 | 20 | // initialize tiles 21 | TETile[][] world = new TETile[WIDTH][HEIGHT]; 22 | for (int x = 0; x < WIDTH; x += 1) { 23 | for (int y = 0; y < HEIGHT; y += 1) { 24 | world[x][y] = Tileset.NOTHING; 25 | } 26 | } 27 | 28 | // fills in a block 14 tiles wide by 4 tiles tall 29 | for (int x = 20; x < 35; x += 1) { 30 | for (int y = 5; y < 10; y += 1) { 31 | world[x][y] = Tileset.WALL; 32 | } 33 | } 34 | 35 | // draws the world to the screen 36 | ter.renderFrame(world); 37 | } 38 | 39 | 40 | } 41 | -------------------------------------------------------------------------------- /proj3/byow/lab12/HexWorld.java: -------------------------------------------------------------------------------- 1 | package byow.lab12; 2 | import org.junit.Test; 3 | import static org.junit.Assert.*; 4 | 5 | import byow.TileEngine.TERenderer; 6 | import byow.TileEngine.TETile; 7 | import byow.TileEngine.Tileset; 8 | 9 | import java.util.Random; 10 | 11 | /** 12 | * Draws a world consisting of hexagonal regions. 13 | */ 14 | public class HexWorld { 15 | private static final int WIDTH = 50; 16 | private static final int HEIGHT = 40; 17 | private static final int hexagonNumInTesselation = 19; 18 | 19 | public static void fillWithNOTHING(TETile[][] tiles) { 20 | int height = tiles[0].length; 21 | int width = tiles.length; 22 | for (int x = 0; x < width; x += 1) { 23 | for (int y = 0; y < height; y += 1) { 24 | tiles[x][y] = Tileset.NOTHING; 25 | } 26 | } 27 | } 28 | 29 | public static void main(String[] args) { 30 | TERenderer ter = new TERenderer(); 31 | ter.initialize(WIDTH, HEIGHT); 32 | 33 | TETile[][] tiles = new TETile[WIDTH][HEIGHT]; 34 | fillWithNOTHING(tiles); 35 | makeTesselation(tiles, 3, hexagonNumInTesselation); 36 | 37 | ter.renderFrame(tiles); 38 | } 39 | 40 | public static void makeTesselation(TETile[][] tiles, int size, int hexagonNumInTesselation) { 41 | // left half triangle include middle 42 | makeColumHalfTriangle(tiles, size, hexagonNumInTesselation, true); 43 | // right half triangle exclude middle 44 | makeColumHalfTriangle(tiles, size, hexagonNumInTesselation, false); 45 | } 46 | 47 | public static void makeColumHalfTriangle(TETile[][] tiles, int size, int hexagonNumInTesselation, boolean isLeft) { 48 | int minHexagonNumInYPosition = ((hexagonNumInTesselation + 1) / 5) - 1; 49 | int TilesHeight = tiles[0].length; 50 | int yPositionBias = size * 2; 51 | 52 | // left half triangle include middle 53 | int MaxHexagonNumInYPosition = ((hexagonNumInTesselation + 1) / 5) + 1; 54 | // positive bias at x position 55 | int xPositionBias = size * 2 - 1; 56 | int yPosition = TilesHeight - 1; 57 | int xPosition = tiles.length / 2; 58 | 59 | // right half triangle exclude middle 60 | if (!isLeft) { 61 | MaxHexagonNumInYPosition = ((hexagonNumInTesselation + 1) / 5); 62 | // negative bias at x position 63 | xPositionBias = -(size * 2 - 1); 64 | yPosition = (TilesHeight - 1) - size; 65 | xPosition = (tiles.length / 2) + xPositionBias; 66 | } 67 | 68 | // add hexagons from middle(include/exclude) to left/right 69 | while (MaxHexagonNumInYPosition >= minHexagonNumInYPosition) { 70 | int hexagonNumInYPosition = MaxHexagonNumInYPosition; 71 | int currentYPosition = yPosition; 72 | while (hexagonNumInYPosition > 0) { 73 | Hexagon hexagonWithSize = new Hexagon(size); 74 | hexagonWithSize.addDiffHexagon(tiles, xPosition, currentYPosition); 75 | currentYPosition -= yPositionBias; 76 | hexagonNumInYPosition -= 1; 77 | } 78 | xPosition += xPositionBias; 79 | yPosition -= size; 80 | MaxHexagonNumInYPosition -= 1; 81 | } 82 | } 83 | 84 | public static void makeSameHexagons(TETile[][] tiles) { 85 | int xPosition = 6; 86 | int count = 6; 87 | for (int i = 2; i <= 5; i++) { 88 | Hexagon hexagonWithSize = new Hexagon(i); 89 | hexagonWithSize.addSameHexagon(tiles, xPosition); 90 | xPosition += count + i; 91 | count += 1; 92 | } 93 | } 94 | } 95 | -------------------------------------------------------------------------------- /proj3/byow/lab12/Hexagon.java: -------------------------------------------------------------------------------- 1 | package byow.lab12; 2 | 3 | import byow.TileEngine.TETile; 4 | import byow.TileEngine.Tileset; 5 | 6 | import java.util.Random; 7 | 8 | public class Hexagon { 9 | private int size; 10 | private int height; 11 | private static final long SEED = 2873123; 12 | private static final Random RANDOM = new Random(SEED); 13 | 14 | public Hexagon(int size) { 15 | this.size = size; 16 | this.height = size * 2; 17 | } 18 | 19 | public void addSameHexagon(TETile[][] tiles, int xPosition) { 20 | int startHeight = tiles[0].length; 21 | addHexagon(tiles, xPosition, startHeight, Tileset.WALL); 22 | } 23 | 24 | public void addDiffHexagon(TETile[][] tiles, int xPosition, int startHeight) { 25 | addHexagon(tiles, xPosition, startHeight, randomTile()); 26 | } 27 | 28 | // adds a hexagon of side length xPosition to a given position in the world. 29 | public void addHexagon(TETile[][] tiles, int xPosition, int startHeight, TETile tile) { 30 | int changeSize = size; 31 | // Upper half triangle 32 | for (int y = startHeight - 1; y >= startHeight - size; y -= 1) { 33 | for (int x = xPosition; x < xPosition + changeSize; x += 1) { 34 | tiles[x][y] = tile; 35 | } 36 | changeSize += 2; 37 | xPosition -= 1; 38 | } 39 | // Bottom half triangle 40 | changeSize -= 2; 41 | xPosition += 1; 42 | for (int y = startHeight - 1 - size; y >= startHeight - height; y -= 1) { 43 | for (int x = xPosition; x < xPosition + changeSize; x += 1) { 44 | tiles[x][y] = tile; 45 | } 46 | changeSize -= 2; 47 | xPosition += 1; 48 | } 49 | } 50 | 51 | /** Picks a RANDOM tile with a 33% change of being 52 | * a wall, 33% chance of being a flower, and 33% 53 | * chance of being empty space. 54 | */ 55 | private static TETile randomTile() { 56 | int tileNum = RANDOM.nextInt(5); 57 | switch (tileNum) { 58 | case 0: return Tileset.WALL; 59 | case 1: return Tileset.FLOWER; 60 | case 2: return Tileset.GRASS; 61 | case 3: return Tileset.WATER; 62 | case 4: return Tileset.TREE; 63 | default: return Tileset.NOTHING; 64 | } 65 | } 66 | } 67 | -------------------------------------------------------------------------------- /proj3/byow/lab12/RandomWorldDemo.java: -------------------------------------------------------------------------------- 1 | package byow.lab12; 2 | 3 | import byow.TileEngine.TERenderer; 4 | import byow.TileEngine.TETile; 5 | import byow.TileEngine.Tileset; 6 | 7 | import java.util.Random; 8 | 9 | /** 10 | * Draws a world that contains RANDOM tiles. 11 | */ 12 | public class RandomWorldDemo { 13 | private static final int WIDTH = 50; 14 | private static final int HEIGHT = 50; 15 | 16 | private static final long SEED = 2873123; 17 | private static final Random RANDOM = new Random(SEED); 18 | 19 | /** 20 | * Fills the given 2D array of tiles with RANDOM tiles. 21 | * @param tiles 22 | */ 23 | public static void fillWithRandomTiles(TETile[][] tiles) { 24 | int height = tiles[0].length; 25 | int width = tiles.length; 26 | for (int x = 0; x < width; x += 1) { 27 | for (int y = 0; y < height; y += 1) { 28 | tiles[x][y] = randomTile(); 29 | } 30 | } 31 | } 32 | 33 | /** Picks a RANDOM tile with a 33% change of being 34 | * a wall, 33% chance of being a flower, and 33% 35 | * chance of being empty space. 36 | */ 37 | private static TETile randomTile() { 38 | int tileNum = RANDOM.nextInt(3); 39 | switch (tileNum) { 40 | case 0: return Tileset.WALL; 41 | case 1: return Tileset.FLOWER; 42 | case 2: return Tileset.NOTHING; 43 | default: return Tileset.NOTHING; 44 | } 45 | } 46 | 47 | public static void main(String[] args) { 48 | TERenderer ter = new TERenderer(); 49 | ter.initialize(WIDTH, HEIGHT); 50 | 51 | TETile[][] randomTiles = new TETile[WIDTH][HEIGHT]; 52 | fillWithRandomTiles(randomTiles); 53 | 54 | ter.renderFrame(randomTiles); 55 | } 56 | 57 | 58 | } 59 | -------------------------------------------------------------------------------- /proj3/byow/lab12/project3prep.md: -------------------------------------------------------------------------------- 1 | # Project 3 Prep 2 | 3 | **For tessellating hexagons, one of the hardest parts is figuring out where to place each hexagon/how to easily place hexagons on screen in an algorithmic way. 4 | After looking at your own implementation, consider the implementation provided near the end of the lab. 5 | How did your implementation differ from the given one? What lessons can be learned from it?** 6 | 7 | Answer: where to place hexagon?; you should figure most easiest rule and using hierarchical abstraction 8 | 9 | ----- 10 | 11 | **Can you think of an analogy between the process of tessellating hexagons and randomly generating a world using rooms and hallways? 12 | What is the hexagon and what is the tesselation on the Project 3 side?** 13 | 14 | Answer: 15 | 16 | ----- 17 | **If you were to start working on world generation, what kind of method would you think of writing first? 18 | Think back to the lab and the process used to eventually get to tessellating hexagons.** 19 | 20 | Answer: 21 | 22 | ----- 23 | **What distinguishes a hallway from a room? How are they similar?** 24 | 25 | Answer: 26 | -------------------------------------------------------------------------------- /proj3/byow/lab13/TestStdDraw.java: -------------------------------------------------------------------------------- 1 | package byow.lab13; 2 | import edu.princeton.cs.introcs.StdDraw; 3 | 4 | import java.awt.*; 5 | 6 | public class TestStdDraw { 7 | public static void main(String[] args) { 8 | StdDraw.clear(Color.black); 9 | Font font = new Font("Arial", Font.BOLD, 30); 10 | StdDraw.setFont(font); 11 | StdDraw.setPenColor(Color.white); 12 | StdDraw.text(0.5, 0.5, "Hello, World"); 13 | StdDraw.show(); 14 | } 15 | } -------------------------------------------------------------------------------- /proj3/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 4.0.0 6 | 7 | 8 | CS61B 9 | 61BMasterPom 10 | 1.0-SNAPSHOT 11 | ../library-sp21/javalib/masterpom.xml 12 | 13 | 14 | 15 | CS61B 16 | proj3 17 | 1.0-SNAPSHOT 18 | 19 | 20 | ${project.basedir} 21 | ${project.basedir} 22 | 23 | 24 | org.apache.maven.plugins 25 | maven-compiler-plugin 26 | 3.1 27 | 28 | 1.14 29 | 1.14 30 | 31 | 32 | 33 | org.apache.maven.plugins 34 | maven-compiler-plugin 35 | 3.8.1 36 | 37 | 38 | -J-XX:+ShowCodeDetailsInExceptionMessages 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | --------------------------------------------------------------------------------