diff --git a/.gitignore b/.gitignore index 6143e53..427efdb 100644 --- a/.gitignore +++ b/.gitignore @@ -20,3 +20,7 @@ # virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml hs_err_pid* + +# Eclipse workspace +.metadata +.recommenders diff --git a/Checkstyle.xml b/Checkstyle.xml new file mode 100644 index 0000000..36dbd1f --- /dev/null +++ b/Checkstyle.xml @@ -0,0 +1,155 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Formatter.xml b/Formatter.xml new file mode 100644 index 0000000..ab6e68e --- /dev/null +++ b/Formatter.xml @@ -0,0 +1,390 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/LICENSE b/LICENSE index d3cee1c..c3838e3 100644 --- a/LICENSE +++ b/LICENSE @@ -1,6 +1,6 @@ MIT License -Copyright (c) 2017 Allen Downey and Chris Mayfield +Copyright (c) 2020 Allen Downey and Chris Mayfield Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/README.md b/README.md index 5408ded..a9646f6 100644 --- a/README.md +++ b/README.md @@ -1,12 +1,12 @@ # ThinkJavaCode2 Supporting code for Think Java, 2nd edition. -Copyright (c) 2017 Allen Downey and Chris Mayfield. -**This new edition is a work in progress and won't be completed until May 2019.** +Copyright (c) 2020 Allen B. Downey and Chris Mayfield. +This edition was published in December 2019 by [O'Reilly Media](https://www.oreilly.com/library/view/think-java-2nd/9781492072492/) (ISBN 9781492072508). This repository contains the code examples from the book and starter code for some exercises. There are several ways you can work with the code: -* You can create a copy of this repository on GitHub by pressing the "Fork" button in the upper right. +* You can create a copy of this repository on GitHub by clicking the "Fork" button. If you don't already have a GitHub account, you'll need to create one. After forking, you'll have your own repository on GitHub that you can use to keep track of code you write. Then you can "clone" the repository, which downloads a copy of the files to your computer. @@ -14,7 +14,7 @@ Then you can "clone" the repository, which downloads a copy of the files to your * Alternatively, you could clone the original repository without forking. If you choose this option, you don't need a GitHub account, but you won't be able to save your changes on GitHub. -* If you don't want to use Git at all, you can download the code in a ZIP archive using the "Download ZIP" button on this page, or this link: http://tinyurl.com/ThinkJavaCode2. +* If you don't want to use Git at all, you can download the code in a ZIP archive using the "Clone or download" button, or this link: https://thinkjava.org/code2zip. To clone a repository, you need Git installed on your computer (see https://help.github.com/). If you use Git from the command line, you can clone the original repository like this: @@ -23,6 +23,7 @@ If you use Git from the command line, you can clone the original repository like After you clone the repository or unzip the ZIP file, you should have a directory named `ThinkJavaCode2` with a subdirectory for each chapter in the book. -All examples in this book were developed and tested using Java SE Development Kit 8. -If you are using a more recent version, the examples in this book should still work. -If you are using an older version, some of them may not. +The examples in this book were developed and tested using OpenJDK 11. +If you are using a more recent version, everything should still work. +If you are using an older version, some of the examples might not. + diff --git a/appa/.checkstyle b/appa/.checkstyle new file mode 100644 index 0000000..744b9f9 --- /dev/null +++ b/appa/.checkstyle @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/appa/.classpath b/appa/.classpath new file mode 100644 index 0000000..f37b935 --- /dev/null +++ b/appa/.classpath @@ -0,0 +1,7 @@ + + + + + + + diff --git a/appa/.project b/appa/.project new file mode 100644 index 0000000..89577ab --- /dev/null +++ b/appa/.project @@ -0,0 +1,23 @@ + + + appa + + + + + + org.eclipse.jdt.core.javabuilder + + + + + net.sf.eclipsecs.core.CheckstyleBuilder + + + + + + org.eclipse.jdt.core.javanature + net.sf.eclipsecs.core.CheckstyleNature + + diff --git a/appb/.checkstyle b/appb/.checkstyle new file mode 100644 index 0000000..744b9f9 --- /dev/null +++ b/appb/.checkstyle @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/appb/.classpath b/appb/.classpath new file mode 100644 index 0000000..3f3893a --- /dev/null +++ b/appb/.classpath @@ -0,0 +1,6 @@ + + + + + + diff --git a/appb/.project b/appb/.project new file mode 100644 index 0000000..7658200 --- /dev/null +++ b/appb/.project @@ -0,0 +1,23 @@ + + + appb + + + + + + org.eclipse.jdt.core.javabuilder + + + + + net.sf.eclipsecs.core.CheckstyleBuilder + + + + + + org.eclipse.jdt.core.javanature + net.sf.eclipsecs.core.CheckstyleNature + + diff --git a/appb/Convert.java b/appb/Convert.java index cc25cb0..232abd6 100644 --- a/appb/Convert.java +++ b/appb/Convert.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017 Allen Downey and Chris Mayfield + * Copyright (c) 2019 Allen Downey and Chris Mayfield * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -23,7 +23,7 @@ import java.util.Scanner; /** - * Utility class for converting to/from the metric system. + * Methods for converting to/from the metric system. * * @author Allen Downey * @author Chris Mayfield diff --git a/appb/DigitUtil.java b/appb/DigitUtil.java index 9cd7256..04c55eb 100644 --- a/appb/DigitUtil.java +++ b/appb/DigitUtil.java @@ -13,20 +13,16 @@ public class DigitUtil { * @return true if x has one digit, false otherwise */ public static boolean isSingleDigit(int x) { - if (x > -10 && x < 10) { - return true; - } else { - return false; - } - } - - public static boolean isSingleDigit2(int x) { return x > -10 && x < 10; } public static void main(String[] args) { System.out.println(isSingleDigit(2)); + boolean bigFlag = !isSingleDigit(17); + if (bigFlag) { + System.out.println("not single"); + } int z = 9; if (isSingleDigit(z)) { diff --git a/appc/.checkstyle b/appc/.checkstyle new file mode 100644 index 0000000..744b9f9 --- /dev/null +++ b/appc/.checkstyle @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/appc/.classpath b/appc/.classpath new file mode 100644 index 0000000..3f3893a --- /dev/null +++ b/appc/.classpath @@ -0,0 +1,6 @@ + + + + + + diff --git a/appc/.project b/appc/.project new file mode 100644 index 0000000..0e3c2da --- /dev/null +++ b/appc/.project @@ -0,0 +1,23 @@ + + + appc + + + + + + org.eclipse.jdt.core.javabuilder + + + + + net.sf.eclipsecs.core.CheckstyleBuilder + + + + + + org.eclipse.jdt.core.javanature + net.sf.eclipsecs.core.CheckstyleNature + + diff --git a/appc/Drawing.java b/appc/Drawing.java index e82bfca..ef80672 100644 --- a/appc/Drawing.java +++ b/appc/Drawing.java @@ -6,6 +6,7 @@ public class Drawing extends Canvas { public static void main(String[] args) { JFrame frame = new JFrame("My Drawing"); + frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); Canvas drawing = new Drawing(); drawing.setSize(400, 400); frame.add(drawing); diff --git a/appc/Mickey.java b/appc/Mickey.java index 6dfa3bc..73236d6 100644 --- a/appc/Mickey.java +++ b/appc/Mickey.java @@ -8,9 +8,10 @@ public class Mickey extends Canvas { public static void main(String[] args) { JFrame frame = new JFrame("Mickey Mouse"); + frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); Canvas canvas = new Mickey(); canvas.setSize(400, 400); - canvas.setBackground(Color.white); + canvas.setBackground(Color.WHITE); frame.add(canvas); frame.pack(); frame.setVisible(true); @@ -28,14 +29,14 @@ public void boxOval(Graphics g, Rectangle bb) { public void mickey(Graphics g, Rectangle bb) { boxOval(g, bb); - int dx = bb.width / 2; - int dy = bb.height / 2; - Rectangle half = new Rectangle(bb.x, bb.y, dx, dy); + int hx = bb.width / 2; + int hy = bb.height / 2; + Rectangle half = new Rectangle(bb.x, bb.y, hx, hy); - half.translate(-dx / 2, -dy / 2); + half.translate(-hx / 2, -hy / 2); boxOval(g, half); - half.translate(dx * 2, 0); + half.translate(hx * 2, 0); boxOval(g, half); } diff --git a/appc/Moire.java b/appc/Moire.java index 8e7247f..6c3e78c 100644 --- a/appc/Moire.java +++ b/appc/Moire.java @@ -7,9 +7,10 @@ public class Moire extends Canvas { public static void main(String[] args) { JFrame frame = new JFrame("Moire Pattern"); + frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); Canvas canvas = new Moire(); canvas.setSize(400, 400); - canvas.setBackground(Color.white); + canvas.setBackground(Color.WHITE); frame.add(canvas); frame.pack(); frame.setVisible(true); diff --git a/appd/.checkstyle b/appd/.checkstyle new file mode 100644 index 0000000..744b9f9 --- /dev/null +++ b/appd/.checkstyle @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/appd/.classpath b/appd/.classpath new file mode 100644 index 0000000..3f3893a --- /dev/null +++ b/appd/.classpath @@ -0,0 +1,6 @@ + + + + + + diff --git a/appd/.project b/appd/.project new file mode 100644 index 0000000..7b8a1e5 --- /dev/null +++ b/appd/.project @@ -0,0 +1,23 @@ + + + appd + + + + + + org.eclipse.jdt.core.javabuilder + + + + + net.sf.eclipsecs.core.CheckstyleBuilder + + + + + + org.eclipse.jdt.core.javanature + net.sf.eclipsecs.core.CheckstyleNature + + diff --git a/appd/Complex.java b/appd/Complex.java index ac4c50f..2a86ee6 100644 --- a/appd/Complex.java +++ b/appd/Complex.java @@ -1,10 +1,13 @@ import java.awt.Rectangle; /** - * Example from "My method doesn't return what I expect." + * Examples from Logic Errors section. */ public class Complex { + /** + * My method doesn't return what I expect. + */ public static Rectangle intersection(Rectangle a, Rectangle b) { int x1 = Math.min(a.x, b.x); int y1 = Math.min(a.y, b.y); @@ -14,10 +17,19 @@ public static Rectangle intersection(Rectangle a, Rectangle b) { return rect; } + /** + * I've got a big, hairy expression and it doesn’t do what I expect. + */ public static void main(String[] args) { - Rectangle x = new Rectangle(0, 0, 10, 10); - Rectangle y = new Rectangle(-5, -5, -5, -5); - System.out.println(intersection(x, y)); + Rectangle rect = new Rectangle(0, 0, 10, 10); + Rectangle ngle = new Rectangle(-5, -5, -5, -5); + System.out.println(intersection(rect, ngle)); + + double halfWidth = 0.5 * rect.getWidth(); + double halfHeight = 0.5 * rect.getHeight(); + int dx = (int) Math.round(halfWidth); + int dy = (int) Math.round(halfHeight); + rect.translate(dx, dy); } } diff --git a/appe/Tables.java b/appe/Tables.java deleted file mode 100644 index edade81..0000000 --- a/appe/Tables.java +++ /dev/null @@ -1,45 +0,0 @@ -/** - * Generating tables. - */ -public class Tables { - - public static void example() { - int i = 1; - while (i < 10) { - double x = i; - System.out.println(x + " " + Math.log(x)); - i = i + 1; - } - } - - public static void example2() { - int i = 1; - while (i < 10) { - double x = i; - System.out.println(x + " " + Math.log(x) / Math.log(2)); - i = i + 1; - } - } - - public static void example3() { - final double LOG2 = Math.log(2); - int i = 1; - while (i < 100) { - double x = i; - System.out.println(x + " " + Math.log(x) / LOG2); - i = i * 2; - } - } - - public static void main(String[] args) { - System.out.println("example"); - example(); - - System.out.println("example2"); - example2(); - - System.out.println("example3"); - example3(); - } - -} diff --git a/appe/Unreachable.java b/appe/Unreachable.java deleted file mode 100644 index 7749dd3..0000000 --- a/appe/Unreachable.java +++ /dev/null @@ -1,16 +0,0 @@ -public class Unreachable { - - public static double absoluteValue(double x) { - if (x < 0) { - return -x; - } else { - return x; - } - } - - public static void main(String[] args) { - System.out.println("absolute value"); - System.out.println(absoluteValue(-2)); - } - -} diff --git a/appe/Validate.java b/appe/Validate.java deleted file mode 100644 index e825705..0000000 --- a/appe/Validate.java +++ /dev/null @@ -1,54 +0,0 @@ -import java.util.Scanner; - -/** - * Do-while, break, and continue. - */ -public class Validate { - - public static double scanDouble() { - Scanner in = new Scanner(System.in); - boolean okay; - do { - System.out.print("Enter a number: "); - if (in.hasNextDouble()) { - okay = true; - } else { - okay = false; - String word = in.next(); - System.err.println(word + " is not a number"); - } - } while (!okay); - double x = in.nextDouble(); - return x; - } - - public static double scanDouble2() { - Scanner in = new Scanner(System.in); - while (true) { - System.out.print("Enter a number: "); - if (in.hasNextDouble()) { - break; - } - String word = in.next(); - System.err.println(word + " is not a number"); - } - double x = in.nextDouble(); - return x; - } - - public static double addNumbers() { - Scanner in = new Scanner(System.in); - int x = -1; - int sum = 0; - while (x != 0) { - x = in.nextInt(); - if (x <= 0) { - continue; - } - System.out.println("Adding " + x); - sum += x; - } - return sum; - } - -} diff --git a/appe/Vowels.java b/appe/Vowels.java deleted file mode 100644 index 4b01b58..0000000 --- a/appe/Vowels.java +++ /dev/null @@ -1,46 +0,0 @@ -/** - * Example switch statement with cases that fall through. - */ -public class Vowels { - - public static void main(String[] args) { - String s = "Ahoy!"; - for (int i = 0; i < s.length(); i++) { - - // display the next character - char c = s.charAt(i); - System.out.print(c + " is a "); - - // if capital, convert to lowercase - if (c >= 'A' && c <= 'Z') { - c += 'a' - 'A'; - } - - // check if not a lowercase letter - if (c < 'a' || c > 'z') { - System.out.println("symbol"); - continue; - } - - // output the result of the letter - switch (c) { - case 'a': - case 'e': - case 'i': - case 'o': - case 'u': - System.out.println("vowel"); - break; - - case 'y': - System.out.println("not sure"); - break; - - default: - System.out.println("consonant"); - break; - } - } - } - -} diff --git a/ch01/.checkstyle b/ch01/.checkstyle new file mode 100644 index 0000000..744b9f9 --- /dev/null +++ b/ch01/.checkstyle @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/ch01/.classpath b/ch01/.classpath new file mode 100644 index 0000000..3f3893a --- /dev/null +++ b/ch01/.classpath @@ -0,0 +1,6 @@ + + + + + + diff --git a/ch01/.project b/ch01/.project new file mode 100644 index 0000000..d4e68d5 --- /dev/null +++ b/ch01/.project @@ -0,0 +1,23 @@ + + + ch01 + + + + + + org.eclipse.jdt.core.javabuilder + + + + + net.sf.eclipsecs.core.CheckstyleBuilder + + + + + + org.eclipse.jdt.core.javanature + net.sf.eclipsecs.core.CheckstyleNature + + diff --git a/ch02/.checkstyle b/ch02/.checkstyle new file mode 100644 index 0000000..744b9f9 --- /dev/null +++ b/ch02/.checkstyle @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/ch02/.classpath b/ch02/.classpath new file mode 100644 index 0000000..3f3893a --- /dev/null +++ b/ch02/.classpath @@ -0,0 +1,6 @@ + + + + + + diff --git a/ch02/.project b/ch02/.project new file mode 100644 index 0000000..c7628eb --- /dev/null +++ b/ch02/.project @@ -0,0 +1,23 @@ + + + ch02 + + + + + + org.eclipse.jdt.core.javabuilder + + + + + net.sf.eclipsecs.core.CheckstyleBuilder + + + + + + org.eclipse.jdt.core.javanature + net.sf.eclipsecs.core.CheckstyleNature + + diff --git a/ch02/DeclareAssign.java b/ch02/DeclareAssign.java new file mode 100644 index 0000000..87a8e02 --- /dev/null +++ b/ch02/DeclareAssign.java @@ -0,0 +1,23 @@ +public class DeclareAssign { + + public static void main(String[] args) { + String message; + int x; + + String firstName; + String lastName; + int hour, minute; + + message = "Hello!"; // give message the value "Hello!" + hour = 11; // assign the value 11 to hour + minute = 59; // set minute to 59 + + message = "123"; // legal + // message = 123; // not legal + + String message2 = "Hello!"; + int hour2 = 11; + int minute2 = 59; + } + +} diff --git a/ch02/FloatingPoint.java b/ch02/FloatingPoint.java new file mode 100644 index 0000000..b9afa1c --- /dev/null +++ b/ch02/FloatingPoint.java @@ -0,0 +1,21 @@ +public class FloatingPoint { + + public static void main(String[] args) { + double pi; + pi = 3.14159; + + double minute3 = 59.0; + System.out.print("Fraction of the hour that has passed: "); + System.out.println(minute3 / 60.0); + + double y = 1.0 / 3.0; // correct + + System.out.println(0.1 * 10); + System.out.println(0.1 + 0.1 + 0.1 + 0.1 + 0.1 + + 0.1 + 0.1 + 0.1 + 0.1 + 0.1); + + double balance = 123.45; // potential rounding error + int balance2 = 12345; // total number of cents + } + +} diff --git a/ch02/Hello.java b/ch02/Hello.java new file mode 100644 index 0000000..bbc0349 --- /dev/null +++ b/ch02/Hello.java @@ -0,0 +1,8 @@ +public class Hello { + + public static void main(String[] args) { + System.out.println("Hello, "); + System.out.println("World!"); + } + +} diff --git a/ch02/MemoryDiagram.java b/ch02/MemoryDiagram.java new file mode 100644 index 0000000..1fecfd8 --- /dev/null +++ b/ch02/MemoryDiagram.java @@ -0,0 +1,10 @@ +public class MemoryDiagram { + + public static void main(String[] args) { + int a = 5; + int b = a; // a and b are now equal + a = 3; // a and b are no longer equal + int c = 0; + } + +} diff --git a/ch02/PrintingVars.java b/ch02/PrintingVars.java new file mode 100644 index 0000000..27a0f08 --- /dev/null +++ b/ch02/PrintingVars.java @@ -0,0 +1,28 @@ +public class PrintingVars { + + public static void main(String[] args) { + String firstLine = "Hello, again!"; + System.out.println(firstLine); + + System.out.print("The value of firstLine is "); + System.out.println(firstLine); + + int hour = 11; + int minute = 59; + System.out.print("The current time is "); + System.out.print(hour); + System.out.print(":"); + System.out.print(minute); + System.out.println("."); + + System.out.print("Number of minutes since midnight: "); + System.out.println(hour * 60 + minute); + + System.out.print("Fraction of the hour that has passed: "); + System.out.println(minute / 60); + + System.out.print("Percent of the hour that has passed: "); + System.out.println(minute * 100 / 60); + } + +} diff --git a/ch02/StringConcat.java b/ch02/StringConcat.java new file mode 100644 index 0000000..4ec9902 --- /dev/null +++ b/ch02/StringConcat.java @@ -0,0 +1,12 @@ +public class StringConcat { + + public static void main(String[] args) { + System.out.println(1 + 2 + "Hello"); + // the output is 3Hello + + System.out.println("Hello" + 1 + 2); + // the output is Hello12 + + } + +} diff --git a/ch02/Variables.java b/ch02/Variables.java deleted file mode 100644 index f6ce6ee..0000000 --- a/ch02/Variables.java +++ /dev/null @@ -1,71 +0,0 @@ -public class Variables { - - public static void main(String[] args) { - - String message; - int x; - - String firstName; - String lastName; - int hour, minute; - - message = "Hello!"; // give message the value "Hello!" - hour = 11; // assign the value 11 to hour - minute = 59; // set minute to 59 - - message = "123"; // legal - // message = 123; // not legal - - String message2 = "Hello!"; - int hour2 = 11; - int minute2 = 59; - - int a = 5; - int b = a; // a and b are now equal - a = 3; // a and b are no longer equal - - String firstLine = "Hello, again!"; - System.out.println(firstLine); - - System.out.print("The value of firstLine is "); - System.out.println(firstLine); - - System.out.print("The current time is "); - System.out.print(hour); - System.out.print(":"); - System.out.print(minute); - System.out.println("."); - - System.out.print("Number of minutes since midnight: "); - System.out.println(hour * 60 + minute); - - System.out.print("Fraction of the hour that has passed: "); - System.out.println(minute / 60); - - System.out.print("Percent of the hour that has passed: "); - System.out.println(minute * 100 / 60); - - double pi; - pi = 3.14159; - - double minute3 = 59.0; - System.out.print("Fraction of the hour that has passed: "); - System.out.println(minute3 / 60.0); - - double y = 1.0 / 3.0; // correct - - System.out.println(0.1 * 10); - System.out.println(0.1 + 0.1 + 0.1 + 0.1 + 0.1 - + 0.1 + 0.1 + 0.1 + 0.1 + 0.1); - - double balance = 123.45; // potential rounding error - int balance2 = 12345; // total number of cents - - System.out.println(1 + 2 + "Hello"); - // the output is 3Hello - - System.out.println("Hello" + 1 + 2); - // the output is Hello12 - } - -} diff --git a/ch03/.checkstyle b/ch03/.checkstyle new file mode 100644 index 0000000..744b9f9 --- /dev/null +++ b/ch03/.checkstyle @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/ch03/.classpath b/ch03/.classpath new file mode 100644 index 0000000..3f3893a --- /dev/null +++ b/ch03/.classpath @@ -0,0 +1,6 @@ + + + + + + diff --git a/ch03/.project b/ch03/.project new file mode 100644 index 0000000..13fab09 --- /dev/null +++ b/ch03/.project @@ -0,0 +1,23 @@ + + + ch03 + + + + + + org.eclipse.jdt.core.javabuilder + + + + + net.sf.eclipsecs.core.CheckstyleBuilder + + + + + + org.eclipse.jdt.core.javanature + net.sf.eclipsecs.core.CheckstyleNature + + diff --git a/ch03/Formatting.java b/ch03/Formatting.java new file mode 100644 index 0000000..7beced4 --- /dev/null +++ b/ch03/Formatting.java @@ -0,0 +1,33 @@ +/** + * Examples from the middle of the chapter. + */ +public class Formatting { + + public static void main(String[] args) { + final double CM_PER_INCH = 2.54; + + System.out.println(System.out); + + // formatting output + + System.out.print(4.0 / 3.0); + System.out.printf("Four thirds = %.3f", 4.0 / 3.0); + + int inch = 100; + double cm = inch * CM_PER_INCH; + System.out.printf("%d in = %f cm\n", inch, cm); + + // type cast operators + + double pi = 3.14159; + int xi = (int) pi; + + double x = (int) pi * 20.0; // result is 60.0, not 62.0 + + inch = (int) (cm / CM_PER_INCH); + System.out.printf("%f cm = %d in\n", cm, inch); + + System.out.printf("inches = %d" + inch); // error + } + +} diff --git a/ch03/Input.java b/ch03/Input.java deleted file mode 100644 index de97dc0..0000000 --- a/ch03/Input.java +++ /dev/null @@ -1,16 +0,0 @@ -/** - * Examples from Chapter 3. - */ -public class Input { - - public static void main(String[] args) { - System.out.println(System.out); - - System.out.print(4.0 / 3.0); - System.out.printf("Four thirds = %.3f", 4.0 / 3.0); - - double pi = 3.14159; - double x = (int) pi * 20.0; - } - -} diff --git a/ch03/Literals.java b/ch03/Literals.java new file mode 100644 index 0000000..3741364 --- /dev/null +++ b/ch03/Literals.java @@ -0,0 +1,22 @@ +import java.util.Scanner; + +/** + * Converts inches to centimeters. + */ +public class Literals { + + public static void main(String[] args) { + int inch; + double cm; + Scanner in = new Scanner(System.in); + + System.out.print("How many inches? "); + inch = in.nextInt(); + + final double CM_PER_INCH = 2.54; + cm = inch * CM_PER_INCH; + System.out.print(inch + " in = "); + System.out.println(cm + " cm"); + } + +} diff --git a/ch03/ScannerBug.java b/ch03/ScannerBug.java index 353affb..bef7834 100644 --- a/ch03/ScannerBug.java +++ b/ch03/ScannerBug.java @@ -16,6 +16,9 @@ public static void main(String[] args) { age = in.nextInt(); System.out.printf("Hello %s, age %d\n", name, age); + in.reset(); + System.out.println(); + System.out.print("What is your age? "); age = in.nextInt(); System.out.print("What is your name? "); diff --git a/ch04/.checkstyle b/ch04/.checkstyle new file mode 100644 index 0000000..744b9f9 --- /dev/null +++ b/ch04/.checkstyle @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/ch04/.classpath b/ch04/.classpath new file mode 100644 index 0000000..3f3893a --- /dev/null +++ b/ch04/.classpath @@ -0,0 +1,6 @@ + + + + + + diff --git a/ch04/.project b/ch04/.project new file mode 100644 index 0000000..9834b0d --- /dev/null +++ b/ch04/.project @@ -0,0 +1,23 @@ + + + ch04 + + + + + + org.eclipse.jdt.core.javabuilder + + + + + net.sf.eclipsecs.core.CheckstyleBuilder + + + + + + org.eclipse.jdt.core.javanature + net.sf.eclipsecs.core.CheckstyleNature + + diff --git a/ch04/Baffle.java b/ch04/Baffle.java index 4c0460a..8269fd9 100644 --- a/ch04/Baffle.java +++ b/ch04/Baffle.java @@ -1,5 +1,9 @@ public class Baffle { + public static void main(String[] args) { + zippo("rattle", 13); + } + public static void baffle(String blimp) { System.out.println(blimp); zippo("ping", -5); @@ -15,8 +19,4 @@ public static void zippo(String quince, int flag) { } } - public static void main(String[] args) { - zippo("rattle", 13); - } - } diff --git a/ch04/Circle.java b/ch04/Circle.java index 1e54adf..f79af90 100644 --- a/ch04/Circle.java +++ b/ch04/Circle.java @@ -1,79 +1,13 @@ -/** - * Examples from Chapter 5. - */ public class Circle { public static double calculateArea(double radius) { - double result = Math.PI * radius * radius; - return result; - } - - public static double calculateArea2(double radius) { return Math.PI * radius * radius; } - public static double distance - (double x1, double y1, double x2, double y2) { - double dx = x2 - x1; - double dy = y2 - y1; - System.out.println("dx is " + dx); - System.out.println("dy is " + dy); - return 0.0; - } - - public static double distance2 - (double x1, double y1, double x2, double y2) { - double dx = x2 - x1; - double dy = y2 - y1; - double dsquared = dx * dx + dy * dy; - System.out.println("dsquared is " + dsquared); - return 0.0; - } - - public static double distance3 - (double x1, double y1, double x2, double y2) { - double dx = x2 - x1; - double dy = y2 - y1; - double dsquared = dx * dx + dy * dy; - double result = Math.sqrt(dsquared); - return result; - } - - public static double circleArea - (double xc, double yc, double xp, double yp) { - double radius = distance(xc, yc, xp, yp); - double area = calculateArea(radius); - return area; - } - - public static double calculateArea - (double xc, double yc, double xp, double yp) { - return calculateArea(distance(xc, yc, xp, yp)); - } - public static void main(String[] args) { - - System.out.println("calculateArea"); - System.out.println(calculateArea(3.0)); - - System.out.println("calculateArea2"); - System.out.println(calculateArea2(3.0)); - - System.out.println("distance"); - System.out.println(distance(1.0, 2.0, 4.0, 6.0)); - - System.out.println("distance2"); - System.out.println(distance2(1.0, 2.0, 4.0, 6.0)); - - System.out.println("distance3"); - System.out.println(distance3(1.0, 2.0, 4.0, 6.0)); - - System.out.println("circleArea"); - System.out.println(circleArea(1.0, 2.0, 4.0, 6.0)); - - System.out.println("calculateArea with 4 doubles"); - System.out.println(calculateArea(1.0, 2.0, 4.0, 6.0)); - + double diameter = 10.0; + double area = calculateArea(diameter / 2); + System.out.println(area); } } diff --git a/ch04/Distance.java b/ch04/Distance.java new file mode 100644 index 0000000..5bdb9ad --- /dev/null +++ b/ch04/Distance.java @@ -0,0 +1,45 @@ +public class Distance { + + public static double distance1(double x1, double y1, double x2, double y2) { + return 0.0; // stub + } + + public static double distance2(double x1, double y1, double x2, double y2) { + double dx = x2 - x1; + double dy = y2 - y1; + System.out.println("dx is " + dx); + System.out.println("dy is " + dy); + return 0.0; // stub + } + + public static double distance3(double x1, double y1, double x2, double y2) { + double dx = x2 - x1; + double dy = y2 - y1; + double dsquared = dx * dx + dy * dy; + System.out.println("dsquared is " + dsquared); + return 0.0; // stub + } + + public static double distance4(double x1, double y1, double x2, double y2) { + double dx = x2 - x1; + double dy = y2 - y1; + double dsquared = dx * dx + dy * dy; + double result = Math.sqrt(dsquared); + return result; + } + + public static void main(String[] args) { + System.out.println("\ndistance version 1"); + System.out.println(distance1(1.0, 2.0, 4.0, 6.0)); + + System.out.println("\ndistance version 2"); + System.out.println(distance2(1.0, 2.0, 4.0, 6.0)); + + System.out.println("\ndistance version 3"); + System.out.println(distance3(1.0, 2.0, 4.0, 6.0)); + + System.out.println("\ndistance version 4"); + System.out.println(distance4(1.0, 2.0, 4.0, 6.0)); + } + +} diff --git a/ch05/Methods.java b/ch04/MathMethods.java similarity index 89% rename from ch05/Methods.java rename to ch04/MathMethods.java index 90c1b7a..51ef7dc 100644 --- a/ch05/Methods.java +++ b/ch04/MathMethods.java @@ -1,7 +1,4 @@ -/** - * Examples from Chapter 4. - */ -public class Methods { +public class MathMethods { public static void main(String[] args) { double root = Math.sqrt(17.0); @@ -10,10 +7,14 @@ public static void main(String[] args) { double degrees = 90; double angle2 = degrees / 180.0 * Math.PI; + double radians = Math.toRadians(180.0); double degrees2 = Math.toDegrees(Math.PI); + long x = Math.round(Math.PI * 20.0); + // examples of composition + double x2 = Math.cos(angle + Math.PI / 2.0); double x3 = Math.exp(Math.log(10.0)); double x4 = Math.pow(2.0, 10.0); diff --git a/ch04/PrintTime.java b/ch04/PrintTime.java index 019d579..055781f 100644 --- a/ch04/PrintTime.java +++ b/ch04/PrintTime.java @@ -10,6 +10,9 @@ public static void main(String[] args) { int hour = 11; int minute = 59; printTime(hour, minute); + + // additional example for stack diagram + printTime(hour + 1, 0); } } diff --git a/ch04/PrintTwice.java b/ch04/PrintTwice.java index 7131085..1180417 100644 --- a/ch04/PrintTwice.java +++ b/ch04/PrintTwice.java @@ -7,6 +7,9 @@ public static void printTwice(String s) { public static void main(String[] args) { printTwice("Don't make me say this twice!"); + + String message = "Never say never."; + printTwice(message); } } diff --git a/ch05/.checkstyle b/ch05/.checkstyle new file mode 100644 index 0000000..744b9f9 --- /dev/null +++ b/ch05/.checkstyle @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/ch05/.classpath b/ch05/.classpath new file mode 100644 index 0000000..3f3893a --- /dev/null +++ b/ch05/.classpath @@ -0,0 +1,6 @@ + + + + + + diff --git a/ch05/.project b/ch05/.project new file mode 100644 index 0000000..933b313 --- /dev/null +++ b/ch05/.project @@ -0,0 +1,23 @@ + + + ch05 + + + + + + org.eclipse.jdt.core.javabuilder + + + + + net.sf.eclipsecs.core.CheckstyleBuilder + + + + + + org.eclipse.jdt.core.javanature + net.sf.eclipsecs.core.CheckstyleNature + + diff --git a/ch05/ChainNest.java b/ch05/ChainNest.java new file mode 100644 index 0000000..9d1fd11 --- /dev/null +++ b/ch05/ChainNest.java @@ -0,0 +1,25 @@ +public class ChainNest { + + public static void main(String[] args) { + int x = 0; + + if (x > 0) { + System.out.println("x is positive"); + } else if (x < 0) { + System.out.println("x is negative"); + } else { + System.out.println("x is zero"); + } + + if (x > 0) { + System.out.println("x is positive"); + } else { + if (x < 0) { + System.out.println("x is negative"); + } else { + System.out.println("x is zero"); + } + } + } + +} diff --git a/ch05/Conditional.java b/ch05/Conditional.java deleted file mode 100644 index db9f642..0000000 --- a/ch05/Conditional.java +++ /dev/null @@ -1,50 +0,0 @@ -/** - * Examples from Chapter 4. - */ -public class Conditional { - - public static void main(String[] args) { - int x = 17; - int n = 18; - - if (x > 0) { - System.out.println("x is positive"); - } - - if (x % 2 == 0) { - System.out.println("x is even"); - } else { - System.out.println("x is odd"); - } - - if (x > 0) { - System.out.println("x is positive"); - } else if (x < 0) { - System.out.println("x is negative"); - } else { - System.out.println("x is zero"); - } - - if (x > 0) { - System.out.println("x is positive"); - } else { - if (x < 0) { - System.out.println("x is negative"); - } else { - System.out.println("x is zero"); - } - } - - boolean evenFlag = (n % 2 == 0); // true if n is even - boolean positiveFlag = (x > 0); // true if x is positive - - if (evenFlag) { - System.out.println("n was even when I checked it"); - } - - if (!evenFlag) { - System.out.println("n was odd when I checked it"); - } - } - -} diff --git a/ch05/DigitUtil.java b/ch05/DigitUtil.java new file mode 100644 index 0000000..551e9a9 --- /dev/null +++ b/ch05/DigitUtil.java @@ -0,0 +1,27 @@ +public class DigitUtil { + + public static boolean isSingleDigit(int x) { + if (x > -10 && x < 10) { + return true; + } else { + return false; + } + } + + public static boolean isSingleDigit2(int x) { + return x > -10 && x < 10; + } + + public static void main(String[] args) { + System.out.println(isSingleDigit(2)); + boolean bigFlag = !isSingleDigit(17); + + int z = 9; + if (isSingleDigit(z)) { + System.out.println("z is small"); + } else { + System.out.println("z is big"); + } + } + +} diff --git a/ch04/Hoopy.java b/ch05/Hoopy.java similarity index 100% rename from ch04/Hoopy.java rename to ch05/Hoopy.java diff --git a/ch05/IfElse.java b/ch05/IfElse.java new file mode 100644 index 0000000..83a0e72 --- /dev/null +++ b/ch05/IfElse.java @@ -0,0 +1,32 @@ +public class IfElse { + + public static void main(String[] args) { + int x = 17; + int n = 18; + + if (x > 0) { + System.out.println("x is positive"); + } + + if (x % 2 == 0) { + System.out.println("x is even"); + } else { + System.out.println("x is odd"); + } + + // look, no braces...bad idea! + if (x % 2 == 0) + System.out.println("x is even"); + else + System.out.println("x is odd"); + + if (x > 0) + System.out.println("x is positive"); + System.out.println("x is not zero"); + + if (x % 2 == 0); { // incorrect semicolon + System.out.println("x is even"); + } + } + +} diff --git a/ch05/Logarithm.java b/ch05/Logarithm.java index 4e2fd45..ef9e53a 100644 --- a/ch05/Logarithm.java +++ b/ch05/Logarithm.java @@ -20,7 +20,7 @@ public static void main(String[] args) { // check the range double x = in.nextDouble(); - if (x >= 0) { + if (x > 0) { double y = Math.log(x); System.out.println("The log is " + y); } else { diff --git a/ch05/LogicalOpers.java b/ch05/LogicalOpers.java new file mode 100644 index 0000000..e9dc6dd --- /dev/null +++ b/ch05/LogicalOpers.java @@ -0,0 +1,56 @@ +public class LogicalOpers { + + public static void main(String[] args) { + int x = 0; + int y = 0; + + // nested + if (x == 0) { + if (y == 0) { + System.out.println("Both x and y are zero"); + } + } + + // combined + if (x == 0 && y == 0) { + System.out.println("Both x and y are zero"); + } + + // chained + if (x == 0) { + System.out.println("Either x or y is zero"); + } else if (y == 0) { + System.out.println("Either x or y is zero"); + } + + // combined + if (x == 0 || y == 0) { + System.out.println("Either x or y is zero"); + } + + // De Morgan's + if (!(x == 0 || y == 0)) { + System.out.println("Neither x nor y is zero"); + } + if (x != 0 && y != 0) { + System.out.println("Neither x nor y is zero"); + } + + // boolean variables + boolean flag; + flag = true; + boolean testResult = false; + + boolean evenFlag = (x % 2 == 0); // true if x is even + boolean positiveFlag = (x > 0); // true if x is positive + + if (evenFlag) { + System.out.println("n was even when I checked it"); + } + + if (!evenFlag) { + System.out.println("n was odd when I checked it"); + } + } + +} diff --git a/ch05/Switch.java b/ch05/Switch.java new file mode 100644 index 0000000..70916b7 --- /dev/null +++ b/ch05/Switch.java @@ -0,0 +1,56 @@ +public class Switch { + + public static void main(String[] args) { + int number = 0; + String word; + + // if-else-if + + if (number == 1) { + word = "one"; + } else if (number == 2) { + word = "two"; + } else if (number == 3) { + word = "three"; + } else { + word = "unknown"; + } + + // same result as above + + switch (number) { + case 1: + word = "one"; + break; + case 2: + word = "two"; + break; + case 3: + word = "three"; + break; + default: + word = "unknown"; + break; + } + + System.out.print(number); + System.out.print(word); + + // switch blocks fall through + + String food = "apple"; + switch (food) { + case "apple": + case "banana": + case "cherry": + System.out.println("Fruit!"); + break; + case "asparagus": + case "broccoli": + case "carrot": + System.out.println("Vegetable!"); + break; + } + } + +} diff --git a/ch06/.checkstyle b/ch06/.checkstyle new file mode 100644 index 0000000..744b9f9 --- /dev/null +++ b/ch06/.checkstyle @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/ch06/.classpath b/ch06/.classpath new file mode 100644 index 0000000..3f3893a --- /dev/null +++ b/ch06/.classpath @@ -0,0 +1,6 @@ + + + + + + diff --git a/ch06/.project b/ch06/.project new file mode 100644 index 0000000..50d0c5e --- /dev/null +++ b/ch06/.project @@ -0,0 +1,23 @@ + + + ch06 + + + + + + org.eclipse.jdt.core.javabuilder + + + + + net.sf.eclipsecs.core.CheckstyleBuilder + + + + + + org.eclipse.jdt.core.javanature + net.sf.eclipsecs.core.CheckstyleNature + + diff --git a/ch06/Loops.java b/ch06/Loops.java index f333df9..4f59564 100644 --- a/ch06/Loops.java +++ b/ch06/Loops.java @@ -1,5 +1,5 @@ /** - * Examples from Chapter 6. + * Demonstrates uses of loops. */ public class Loops { @@ -26,7 +26,7 @@ public static void plusplus() { int i = 1; while (i <= 5) { System.out.println(i); - i++; // add 1 to i + i++; // add 1 to i } } @@ -34,7 +34,14 @@ public static void appreciate() { int i = 2; while (i <= 8) { System.out.print(i + ", "); - i += 2; // add 2 to i + i += 2; // add 2 to i + } + System.out.println("Who do we appreciate?"); + } + + public static void appreciate2() { + for (int i = 2; i <= 8; i += 2) { + System.out.print(i + ", "); } System.out.println("Who do we appreciate?"); } @@ -57,22 +64,25 @@ public static void nested() { } public static void main(String[] args) { - System.out.println("countdown"); + System.out.println("\ncountdown"); countdown(3); - System.out.println("sequence"); + System.out.println("\nsequence"); sequence(10); - System.out.println("plusplus"); + System.out.println("\nplusplus"); plusplus(); - System.out.println("appreciate"); + System.out.println("\nappreciate"); appreciate(); - System.out.println("loopvar"); + System.out.println("\nappreciate2"); + appreciate2(); + + System.out.println("\nloopvar"); loopvar(); - System.out.println("nested"); + System.out.println("\nnested"); nested(); } diff --git a/ch06/Strings.java b/ch06/Strings.java index e451db8..f8b40f0 100644 --- a/ch06/Strings.java +++ b/ch06/Strings.java @@ -1,5 +1,7 @@ +import java.util.Scanner; + /** - * Demonstates uses of Strings. + * Demonstrates uses of strings. */ public class Strings { @@ -10,8 +12,8 @@ public static void main(String[] args) { String fruit = "banana"; char letter0 = fruit.charAt(0); - if (letter0 == 'a') { - System.out.println('?'); + if (letter0 == 'A') { + System.out.println("It's an A!"); } System.out.print("Roman alphabet: "); @@ -26,6 +28,18 @@ public static void main(String[] args) { } System.out.println(); + // Which loop to use + + Scanner in = new Scanner(System.in); + System.out.print("Enter a number: "); + while (!in.hasNextDouble()) { + String word = in.next(); + System.err.println(word + " is not a number"); + System.out.print("Enter a number: "); + } + double number = in.nextDouble(); + in.nextLine(); // read the newline + // String iteration for (int i = 0; i < fruit.length(); i++) { @@ -43,8 +57,30 @@ public static void main(String[] args) { int index = fruit.indexOf('a'); int index2 = fruit.indexOf('a', 2); + // Substrings + + System.out.println(fruit.substring(0, 3)); + System.out.println(fruit.substring(2, 5)); + System.out.println(fruit.substring(6, 6)); + + System.out.println(fruit.substring(0)); + System.out.println(fruit.substring(2)); + System.out.println(fruit.substring(6)); + // String comparison + System.out.print("Play again? "); + String answer = in.nextLine(); + if (answer == "yes") { // wrong! + System.out.println("Let's go!"); + } else { + System.out.println("Goodbye!"); + } + + if (answer.equals("yes")) { // correct + System.out.println("Let's go!"); + } + String name1 = "Alan Turing"; String name2 = "Ada Lovelace"; if (name1.equals(name2)) { @@ -52,24 +88,13 @@ public static void main(String[] args) { } int diff = name1.compareTo(name2); - if (diff == 0) { - System.out.println("The names are the same."); - } else if (diff < 0) { + if (diff < 0) { System.out.println("name1 comes before name2."); } else if (diff > 0) { System.out.println("name2 comes before name1."); + } else { + System.out.println("The names are the same."); } - - // Substrings - - System.out.println(fruit.substring(0)); - System.out.println(fruit.substring(2)); - System.out.println(fruit.substring(6)); - - System.out.println(fruit.substring(0, 3)); - System.out.println(fruit.substring(2, 5)); - System.out.println(fruit.substring(6, 6)); - } /** diff --git a/ch07/.checkstyle b/ch07/.checkstyle new file mode 100644 index 0000000..744b9f9 --- /dev/null +++ b/ch07/.checkstyle @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/ch07/.classpath b/ch07/.classpath new file mode 100644 index 0000000..3f3893a --- /dev/null +++ b/ch07/.classpath @@ -0,0 +1,6 @@ + + + + + + diff --git a/ch07/.project b/ch07/.project new file mode 100644 index 0000000..6887963 --- /dev/null +++ b/ch07/.project @@ -0,0 +1,23 @@ + + + ch07 + + + + + + org.eclipse.jdt.core.javabuilder + + + + + net.sf.eclipsecs.core.CheckstyleBuilder + + + + + + org.eclipse.jdt.core.javanature + net.sf.eclipsecs.core.CheckstyleNature + + diff --git a/ch07/ArrayExamples.java b/ch07/ArrayExamples.java index 0ac26f3..9fecdc0 100644 --- a/ch07/ArrayExamples.java +++ b/ch07/ArrayExamples.java @@ -30,6 +30,7 @@ public static void main(String[] args) { System.out.println(counts[i]); } + // displaying arrays int[] array = {1, 2, 3, 4}; printArray(array); @@ -49,9 +50,9 @@ public static void main(String[] args) { // copying with Arrays class double[] c = Arrays.copyOf(a, a.length); - // traversal + // traversing arrays for (int i = 0; i < a.length; i++) { - a[i] = Math.pow(a[i], 2.0); + a[i] *= a[i]; } // search @@ -66,10 +67,10 @@ public static void main(String[] args) { /** * Prints the elements of an array. */ - public static void printArray(int[] array) { - System.out.print("{" + array[0]); - for (int i = 1; i < array.length; i++) { - System.out.print(", " + array[i]); + public static void printArray(int[] a) { + System.out.print("{" + a[0]); + for (int i = 1; i < a.length; i++) { + System.out.print(", " + a[i]); } System.out.println("}"); } @@ -77,22 +78,22 @@ public static void printArray(int[] array) { /** * Returns the index of the target in the array, or -1 if not found. */ - public static int search(double[] a, double target) { - for (int i = 0; i < a.length; i++) { - if (a[i] == target) { + public static int search(double[] array, double target) { + for (int i = 0; i < array.length; i++) { + if (array[i] == target) { return i; } } - return -1; + return -1; // not found } /** * Returns the total of the elements in an array. */ - public static double sum(double[] a) { + public static double sum(double[] array) { double total = 0.0; - for (int i = 0; i < a.length; i++) { - total += a[i]; + for (int i = 0; i < array.length; i++) { + total += array[i]; } return total; } diff --git a/ch07/Doubloon.java b/ch07/Doubloon.java index 61103e0..aba5ed7 100644 --- a/ch07/Doubloon.java +++ b/ch07/Doubloon.java @@ -2,7 +2,7 @@ * Example from the end of Chapter 7. */ public class Doubloon { - + public static boolean isDoubloon(String s) { // count the number of times each letter appears @@ -21,10 +21,9 @@ public static boolean isDoubloon(String s) { } return true; } - + public static void main(String[] args) { - System.out.println(isDoubloon("Mama")); - System.out.println(isDoubloon("Lama")); + System.out.println(isDoubloon("Mama")); // true + System.out.println(isDoubloon("Lama")); // false } - } diff --git a/ch07/Histogram.java b/ch07/Histogram.java index 32b029c..fe9f0b7 100644 --- a/ch07/Histogram.java +++ b/ch07/Histogram.java @@ -31,8 +31,7 @@ public static int inRange(int[] a, int low, int high) { } public static void main(String[] args) { - int numValues = 8; - int[] array = randomArray(numValues); + int[] array = randomArray(8); ArrayExamples.printArray(array); int[] scores = randomArray(30); diff --git a/ch08/.checkstyle b/ch08/.checkstyle new file mode 100644 index 0000000..744b9f9 --- /dev/null +++ b/ch08/.checkstyle @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/ch08/.classpath b/ch08/.classpath new file mode 100644 index 0000000..3f3893a --- /dev/null +++ b/ch08/.classpath @@ -0,0 +1,6 @@ + + + + + + diff --git a/ch08/.project b/ch08/.project new file mode 100644 index 0000000..a78d2dd --- /dev/null +++ b/ch08/.project @@ -0,0 +1,23 @@ + + + ch08 + + + + + + org.eclipse.jdt.core.javabuilder + + + + + net.sf.eclipsecs.core.CheckstyleBuilder + + + + + + org.eclipse.jdt.core.javanature + net.sf.eclipsecs.core.CheckstyleNature + + diff --git a/ch08/CodingBat.java b/ch08/CodingBat.java index c51f2f4..f6ad0d5 100644 --- a/ch08/CodingBat.java +++ b/ch08/CodingBat.java @@ -3,26 +3,35 @@ */ public class CodingBat { - public static String noX(String str) { + /** + * See https://codingbat.com/prob/p118230. + */ + public String noX(String str) { if (str.length() == 0) { return ""; } - char c = str.charAt(0); - if (c == 'x') { - return noX(str.substring(1)); + char first = str.charAt(0); + String rest = str.substring(1); + String recurse = noX(rest); + if (first == 'x') { + return recurse; } else { - return c + noX(str.substring(1)); + return first + recurse; } } + /** + * See https://codingbat.com/prob/p135988. + */ public int array11(int[] nums, int index) { if (index >= nums.length) { return 0; } + int recurse = array11(nums, index + 1); if (nums[index] == 11) { - return 1 + array11(nums, index + 1); + return recurse + 1; } else { - return array11(nums, index + 1); + return recurse; } } diff --git a/ch08/Recursion.java b/ch08/Examples.java similarity index 92% rename from ch08/Recursion.java rename to ch08/Examples.java index 04ac198..39b22dd 100644 --- a/ch08/Recursion.java +++ b/ch08/Examples.java @@ -1,19 +1,4 @@ -public class Recursion { - - public static void main(String[] args) { - System.out.println("countdown"); - countdown(3); - - System.out.println("nLines"); - nLines(3); - - System.out.println("countup"); - countup(3); - - System.out.println("displayBinary"); - displayBinary(23); - System.out.println(); - } +public class Examples { public static void countdown(int n) { if (n == 0) { @@ -24,10 +9,6 @@ public static void countdown(int n) { } } - public static void newLine() { - System.out.println(); - } - public static void nLines(int n) { if (n > 0) { System.out.println(); @@ -56,4 +37,21 @@ public static void displayBinary(int value) { } } + public static void main(String[] args) { + System.out.println("countdown"); + countdown(3); + + System.out.println("nLines"); + nLines(3); + + // forever("Ha!"); + + System.out.println("countup"); + countup(3); + + System.out.println("displayBinary"); + displayBinary(23); + System.out.println(); + } + } diff --git a/ch08/Series.java b/ch08/Series.java index 86e8148..fb1c860 100644 --- a/ch08/Series.java +++ b/ch08/Series.java @@ -1,6 +1,3 @@ -/** - * Examples from Chapter 8. - */ public class Series { public static int factorial(int n) { diff --git a/ch09/.checkstyle b/ch09/.checkstyle new file mode 100644 index 0000000..744b9f9 --- /dev/null +++ b/ch09/.checkstyle @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/ch09/.classpath b/ch09/.classpath new file mode 100644 index 0000000..3f3893a --- /dev/null +++ b/ch09/.classpath @@ -0,0 +1,6 @@ + + + + + + diff --git a/ch09/.project b/ch09/.project new file mode 100644 index 0000000..3dbf792 --- /dev/null +++ b/ch09/.project @@ -0,0 +1,23 @@ + + + ch09 + + + + + + org.eclipse.jdt.core.javabuilder + + + + + net.sf.eclipsecs.core.CheckstyleBuilder + + + + + + org.eclipse.jdt.core.javanature + net.sf.eclipsecs.core.CheckstyleNature + + diff --git a/ch09/ArgValid.java b/ch09/ArgValid.java new file mode 100644 index 0000000..29e4d0a --- /dev/null +++ b/ch09/ArgValid.java @@ -0,0 +1,20 @@ +/** + * Example of argument validation. + */ +public class ArgValid { + + public static boolean isCapitalized(String str) { + if (str == null || str.isEmpty()) { + return false; + } + return Character.isUpperCase(str.charAt(0)); + } + + public static void main(String[] args) { + System.out.println(isCapitalized("Hi!")); + System.out.println(isCapitalized("bye")); + System.out.println(isCapitalized("")); + System.out.println(isCapitalized(null)); + } + +} diff --git a/ch09/BigInt.java b/ch09/BigInt.java new file mode 100644 index 0000000..05b4da5 --- /dev/null +++ b/ch09/BigInt.java @@ -0,0 +1,20 @@ +import java.math.BigInteger; + +/** + * BigInteger examples. + */ +public class BigInt { + + public static void main(String[] args) { + long x = 17; + BigInteger big = BigInteger.valueOf(x); + + String s = "12345678901234567890"; + BigInteger bigger = new BigInteger(s); + + BigInteger a = BigInteger.valueOf(17); + BigInteger b = BigInteger.valueOf(1700000000); + BigInteger c = a.add(b); + } + +} diff --git a/ch09/Objects.java b/ch09/Objects.java index 8bc4cc6..ae7b350 100644 --- a/ch09/Objects.java +++ b/ch09/Objects.java @@ -1,7 +1,5 @@ -import java.math.BigInteger; - /** - * Demonstates uses of objects and wrappers. + * Demonstrates uses of objects and wrappers. */ public class Objects { @@ -14,22 +12,40 @@ public static void main(String[] args) { char[] array = {'c', 'a', 't'}; String word = "dog"; + String word1 = new String("dog"); // creates a string object + String word2 = "dog"; // implicitly creates a string object + + // the null keyword + + String name0 = null; + int[] combo = null; + // System.out.println(name0.length()); // NullPointerException + // System.out.println(combo[0]); // NullPointerException + // Strings are immutable String name = "Alan Turing"; String upperName = name.toUpperCase(); + name.toUpperCase(); // ignores the return value + System.out.println(name); + name = name.toUpperCase(); // references the new string + System.out.println(name); + String text = "Computer Science is fun!"; text = text.replace("Computer Science", "CS"); // Wrapper classes - Integer x = new Integer(123); - Integer y = new Integer(123); - if (x == y) { // false + Integer i = Integer.valueOf(5); + System.out.println(i.equals(5)); // displays true + + Integer x = Integer.valueOf(123); + Integer y = Integer.valueOf(123); + if (x == y) { // false System.out.println("x and y are the same object"); } - if (x.equals(y)) { // true + if (x.equals(y)) { // true System.out.println("x and y have the same value"); } @@ -38,18 +54,6 @@ public static void main(String[] args) { num = 12345; str = Integer.toString(num); - - // BigInteger arithmetic - - long z = 17; - BigInteger big = BigInteger.valueOf(z); - - String s = "12345678901234567890"; - BigInteger bigger = new BigInteger(s); - - BigInteger a = BigInteger.valueOf(17); - BigInteger b = BigInteger.valueOf(1700000000); - BigInteger c = a.add(b); } } diff --git a/ch09/Tables.java b/ch09/Tables.java index f1a5423..1ceaec9 100644 --- a/ch09/Tables.java +++ b/ch09/Tables.java @@ -4,73 +4,61 @@ public class Tables { public static void printRow() { - int i = 1; - while (i <= 6) { + for (int i = 1; i <= 6; i++) { System.out.printf("%4d", 2 * i); - i = i + 1; } System.out.println(); } public static void printRow(int n) { - int i = 1; - while (i <= 6) { + for (int i = 1; i <= 6; i++) { System.out.printf("%4d", n * i); // generalized n - i = i + 1; } System.out.println(); } public static void printTable() { - int i = 1; - while (i <= 6) { + for (int i = 1; i <= 6; i++) { printRow(i); - i = i + 1; } } public static void printTable(int rows) { - int i = 1; - while (i <= rows) { // generalized rows + for (int i = 1; i <= rows; i++) { // generalized rows printRow(i); - i = i + 1; } } public static void printRow(int n, int cols) { - int i = 1; - while (i <= cols) { // generalized cols + for (int i = 1; i <= cols; i++) { // generalized cols System.out.printf("%4d", n * i); - i = i + 1; } System.out.println(); } public static void printTable2(int rows) { - int i = 1; - while (i <= rows) { - printRow(i, rows); // added rows argument - i = i + 1; + for (int i = 1; i <= rows; i++) { + printRow(i, rows); } } public static void main(String[] args) { - System.out.println("printRow()"); + System.out.println("\nprintRow()"); printRow(); - System.out.println("printRow(6)"); + System.out.println("\nprintRow(6)"); printRow(6); - System.out.println("printTable()"); + System.out.println("\nprintTable()"); printTable(); - System.out.println("printTable(6)"); + System.out.println("\nprintTable(6)"); printTable(6); - System.out.println("printRow(6, 6)"); + System.out.println("\nprintRow(6, 6)"); printRow(6, 6); - System.out.println("printTable2(6)"); + System.out.println("\nprintTable2(6)"); printTable2(6); } diff --git a/ch10/.checkstyle b/ch10/.checkstyle new file mode 100644 index 0000000..744b9f9 --- /dev/null +++ b/ch10/.checkstyle @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/ch10/.classpath b/ch10/.classpath new file mode 100644 index 0000000..3f3893a --- /dev/null +++ b/ch10/.classpath @@ -0,0 +1,6 @@ + + + + + + diff --git a/ch10/.project b/ch10/.project new file mode 100644 index 0000000..5b1937d --- /dev/null +++ b/ch10/.project @@ -0,0 +1,23 @@ + + + ch10 + + + + + + org.eclipse.jdt.core.javabuilder + + + + + net.sf.eclipsecs.core.CheckstyleBuilder + + + + + + org.eclipse.jdt.core.javanature + net.sf.eclipsecs.core.CheckstyleNature + + diff --git a/ch10/Append.java b/ch10/Append.java deleted file mode 100644 index 98a9c10..0000000 --- a/ch10/Append.java +++ /dev/null @@ -1,13 +0,0 @@ -import java.util.Scanner; -public class Append { - public static void main(String[] args) { - Scanner in = new Scanner(System.in); - System.out.println("Enter 10 lines:"); - String text = ""; - for (int i = 0; i < 10; i++) { - String line = in.nextLine(); // new string - text = text + line + '\n'; // two more strings - } - System.out.print("You entered:\n" + text); - } -} diff --git a/ch10/Builder.java b/ch10/Builder.java new file mode 100644 index 0000000..8fe955e --- /dev/null +++ b/ch10/Builder.java @@ -0,0 +1,35 @@ +import java.util.Scanner; + +/* + * StringBuilder example. + */ +public class Builder { + + public static void main(String[] args) { + Scanner in = new Scanner(System.in); + + // less efficient + System.out.println("Enter 10 lines:"); + + String slow = ""; + for (int i = 0; i < 10; i++) { + String line = in.nextLine(); // new string + slow = slow + line + '\n'; // two more strings + } + System.out.print("You entered:\n" + slow); + + // more efficient + System.out.println("Enter 10 lines:"); + + StringBuilder text = new StringBuilder(); + for (int i = 0; i < 10; i++) { + String line = in.nextLine(); + text.append(line); + text.append('\n'); + } + System.out.print("You entered:\n" + text); + + String result = text.toString(); + } + +} diff --git a/ch10/PointRect.java b/ch10/PointRect.java index 66f94db..301dd90 100644 --- a/ch10/PointRect.java +++ b/ch10/PointRect.java @@ -2,34 +2,47 @@ import java.awt.Rectangle; /** - * Demonstates use of Point and Rectangle classes. + * Demonstrates use of Point and Rectangle classes. */ public class PointRect { public static void main(String[] args) { Point blank; blank = new Point(3, 4); - System.out.println(blank); int x = blank.x; System.out.println(blank.x + ", " + blank.y); int sum = blank.x * blank.x + blank.y * blank.y; + // objects as parameters + Point p1 = new Point(0, 0); Point p2 = new Point(3, 4); + double temp = distance(p1, p2); double dist = p1.distance(p2); // dist is 5.0 + System.out.println(blank); + + // objects as return values Rectangle box = new Rectangle(0, 0, 100, 200); - moveRect(box, 50, 100); + Point center = findCenter(box); + + // rectangles are mutable + + moveRect(box, 50, 100); // now at (50, 100, 100, 200) System.out.println(box); + + box = new Rectangle(0, 0, 100, 200); box.translate(50, 100); + // aliasing revisited + Rectangle box1 = new Rectangle(0, 0, 100, 200); Rectangle box2 = box1; - System.out.println(box2.width); box1.grow(50, 50); - System.out.println(box2.width); + System.out.println(box1); + System.out.println(box2); } /** diff --git a/ch11/.checkstyle b/ch11/.checkstyle new file mode 100644 index 0000000..744b9f9 --- /dev/null +++ b/ch11/.checkstyle @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/ch11/.classpath b/ch11/.classpath new file mode 100644 index 0000000..3f3893a --- /dev/null +++ b/ch11/.classpath @@ -0,0 +1,6 @@ + + + + + + diff --git a/ch11/.project b/ch11/.project new file mode 100644 index 0000000..dd4d0e0 --- /dev/null +++ b/ch11/.project @@ -0,0 +1,23 @@ + + + ch11 + + + + + + org.eclipse.jdt.core.javabuilder + + + + + net.sf.eclipsecs.core.CheckstyleBuilder + + + + + + org.eclipse.jdt.core.javanature + net.sf.eclipsecs.core.CheckstyleNature + + diff --git a/ch11/Time.java b/ch11/Time.java index 951d5bf..fe5bfd6 100644 --- a/ch11/Time.java +++ b/ch11/Time.java @@ -25,6 +25,30 @@ public Time(int hour, int minute, double second) { this.second = second; } + public int getHour() { + return this.hour; + } + + public int getMinute() { + return this.minute; + } + + public double getSecond() { + return this.second; + } + + public void setHour(int hour) { + this.hour = hour; + } + + public void setMinute(int minute) { + this.minute = minute; + } + + public void setSecond(double second) { + this.second = second; + } + /** * Prints the time in a simple format. */ @@ -48,9 +72,10 @@ public String toString() { * Tests whether two times are equivalent. */ public boolean equals(Time that) { + final double DELTA = 0.001; return this.hour == that.hour && this.minute == that.minute - && this.second == that.second; + && Math.abs(this.second - that.second) < DELTA; } /** @@ -72,6 +97,7 @@ public Time add(Time t2) { sum.hour = this.hour + t2.hour; sum.minute = this.minute + t2.minute; sum.second = this.second + t2.second; + if (sum.second >= 60.0) { sum.second -= 60.0; sum.minute += 1; @@ -80,22 +106,10 @@ public Time add(Time t2) { sum.minute -= 60; sum.hour += 1; } - return sum; - } - - /** - * Adds the given number of seconds to this object (modifier). - */ - public void increment(double seconds) { - this.second += seconds; - while (this.second >= 60.0) { - this.second -= 60.0; - this.minute += 1; - } - while (this.minute >= 60) { - this.minute -= 60; - this.hour += 1; + if (sum.hour >= 24) { + sum.hour -= 24; } + return sum; } } diff --git a/ch12/.checkstyle b/ch12/.checkstyle new file mode 100644 index 0000000..744b9f9 --- /dev/null +++ b/ch12/.checkstyle @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/ch12/.classpath b/ch12/.classpath new file mode 100644 index 0000000..3f3893a --- /dev/null +++ b/ch12/.classpath @@ -0,0 +1,6 @@ + + + + + + diff --git a/ch12/.project b/ch12/.project new file mode 100644 index 0000000..4d575af --- /dev/null +++ b/ch12/.project @@ -0,0 +1,23 @@ + + + ch12 + + + + + + org.eclipse.jdt.core.javabuilder + + + + + net.sf.eclipsecs.core.CheckstyleBuilder + + + + + + org.eclipse.jdt.core.javanature + net.sf.eclipsecs.core.CheckstyleNature + + diff --git a/ch12/CardTable.java b/ch12/CardTable.java index 727d307..5e85686 100644 --- a/ch12/CardTable.java +++ b/ch12/CardTable.java @@ -15,11 +15,13 @@ public class CardTable extends Canvas { * Creates a CardTable. * cardset is the name of the folder that contains the card images. */ - public CardTable(String cardset) { + public CardTable() { setBackground(new Color(0x088A4B)); // create a 2-D array of card images images = new Image[14][4]; + + String cardset = "cardset-oxymoron"; String suits = "cdhs"; for (int suit = 0; suit <= 3; suit++) { @@ -81,8 +83,7 @@ public static void main(String[] args) { frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); // add the CardTable - String cardset = "cardset-oxymoron"; - Canvas canvas = new CardTable(cardset); + Canvas canvas = new CardTable(); frame.getContentPane().add(canvas); // show the frame diff --git a/ch12/Search.java b/ch12/Search.java index 8bd3129..dd81ed0 100644 --- a/ch12/Search.java +++ b/ch12/Search.java @@ -62,28 +62,6 @@ public static int binarySearch(Card[] cards, Card target) { return -1; } - /** - * Binary search (recursive version). - */ - public static int binarySearch(Card[] cards, Card target, - int low, int high) { - System.out.println(low + ", " + high); - - if (high < low) { - return -1; - } - int mid = (low + high) / 2; // step 1 - int comp = cards[mid].compareTo(target); - - if (comp == 0) { // step 2 - return mid; - } else if (comp < 0) { // step 3 - return binarySearch(cards, target, mid + 1, high); - } else { // step 4 - return binarySearch(cards, target, low, mid - 1); - } - } - /** * Demonstrates how to call the search methods. */ @@ -103,10 +81,6 @@ public static void main(String[] args) { System.out.println("Failed binary search"); System.out.println(binarySearch(cards, fake)); System.out.println(); - - System.out.println("Recursive binary search"); - System.out.println(binarySearch(cards, jack, 0, 51)); - System.out.println(); } } diff --git a/ch13/.checkstyle b/ch13/.checkstyle new file mode 100644 index 0000000..744b9f9 --- /dev/null +++ b/ch13/.checkstyle @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/ch13/.classpath b/ch13/.classpath new file mode 100644 index 0000000..3f3893a --- /dev/null +++ b/ch13/.classpath @@ -0,0 +1,6 @@ + + + + + + diff --git a/ch13/.project b/ch13/.project new file mode 100644 index 0000000..5ae6360 --- /dev/null +++ b/ch13/.project @@ -0,0 +1,23 @@ + + + ch13 + + + + + + org.eclipse.jdt.core.javabuilder + + + + + net.sf.eclipsecs.core.CheckstyleBuilder + + + + + + org.eclipse.jdt.core.javanature + net.sf.eclipsecs.core.CheckstyleNature + + diff --git a/ch13/Deck.java b/ch13/Deck.java index 0c32929..25b2912 100644 --- a/ch13/Deck.java +++ b/ch13/Deck.java @@ -1,4 +1,3 @@ -import java.util.Arrays; import java.util.Random; /** @@ -6,6 +5,10 @@ */ public class Deck { + // This is a class variable so we don't have to create + // a new Random object every time we call randomInt. + private static Random random = new Random(); + private Card[] cards; /** @@ -49,7 +52,7 @@ public void print() { * Returns a string representation of the deck. */ public String toString() { - return Arrays.toString(this.cards); + return "TODO"; } /** @@ -122,4 +125,11 @@ public Deck mergeSort() { */ public void insertionSort() { } + + /** + * Helper method for insertion sort. + */ + private void insert(Card card, int i) { + } + } diff --git a/ch13/Pile.java b/ch13/Pile.java index 1b6bdab..1df5cdc 100644 --- a/ch13/Pile.java +++ b/ch13/Pile.java @@ -31,17 +31,17 @@ public void addDeck(Deck deck) { } /** - * Removes a card from the top of the pile. + * Returns true if this pile has no cards. */ - public Card popCard() { - return this.cards.remove(0); + public boolean isEmpty() { + return this.cards.isEmpty(); } /** - * Returns the number of cards in the pile. + * Removes a card from the top of the pile. */ - public int size() { - return this.cards.size(); + public Card popCard() { + return this.cards.remove(0); } } diff --git a/ch13/War.java b/ch13/War.java index 7639f1d..d9e9c04 100644 --- a/ch13/War.java +++ b/ch13/War.java @@ -16,7 +16,7 @@ public static void main(String[] args) { p2.addDeck(deck.subdeck(26, 51)); // while both piles are not empty - while (p1.size() > 0 && p2.size() > 0) { + while (!p1.isEmpty() && !p2.isEmpty()) { Card c1 = p1.popCard(); Card c2 = p2.popCard(); @@ -34,7 +34,7 @@ public static void main(String[] args) { } // display the winner - if (p1.size() > 0) { + if (p2.isEmpty()) { System.out.println("Player 1 wins!"); } else { System.out.println("Player 2 wins!"); diff --git a/ch14/.checkstyle b/ch14/.checkstyle new file mode 100644 index 0000000..744b9f9 --- /dev/null +++ b/ch14/.checkstyle @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/ch14/.classpath b/ch14/.classpath new file mode 100644 index 0000000..3f3893a --- /dev/null +++ b/ch14/.classpath @@ -0,0 +1,6 @@ + + + + + + diff --git a/ch14/.project b/ch14/.project new file mode 100644 index 0000000..4294f38 --- /dev/null +++ b/ch14/.project @@ -0,0 +1,23 @@ + + + ch14 + + + + + + org.eclipse.jdt.core.javabuilder + + + + + net.sf.eclipsecs.core.CheckstyleBuilder + + + + + + org.eclipse.jdt.core.javanature + net.sf.eclipsecs.core.CheckstyleNature + + diff --git a/ch14/CardCollection.java b/ch14/CardCollection.java index 9e65d39..bf00cde 100644 --- a/ch14/CardCollection.java +++ b/ch14/CardCollection.java @@ -24,6 +24,13 @@ public String getLabel() { return label; } + /** + * Returns a string representation of the card collection. + */ + public String toString() { + return label + ": " + cards.toString(); + } + /** * Adds the given card to the collection. */ @@ -42,40 +49,22 @@ public Card popCard(int i) { * Removes and returns the last card. */ public Card popCard() { - int i = size() - 1; + int i = cards.size() - 1; // from the end of the list return popCard(i); } - /** - * Returns the number of cards. - */ - public int size() { - return cards.size(); - } - /** * True if the collection is empty, false otherwise. */ - public boolean empty() { - return cards.size() == 0; - } - - /** - * Moves n cards from this collection to the given collection. - */ - public void deal(CardCollection that, int n) { - for (int i = 0; i < n; i++) { - Card card = popCard(); - that.addCard(card); - } + public boolean isEmpty() { + return cards.isEmpty(); } /** - * Moves all remaining cards to the given collection. + * Returns the number of cards. */ - public void dealAll(CardCollection that) { - int n = size(); - deal(that, n); + public int size() { + return cards.size(); } /** @@ -89,7 +78,7 @@ public Card getCard(int i) { * Returns the last card. */ public Card lastCard() { - int i = size() - 1; + int i = cards.size() - 1; return cards.get(i); } @@ -107,17 +96,28 @@ public void swapCards(int i, int j) { */ public void shuffle() { Random random = new Random(); - for (int i = size() - 1; i > 0; i--) { - int j = random.nextInt(i); + for (int i = cards.size() - 1; i > 0; i--) { + int j = random.nextInt(i + 1); swapCards(i, j); } } /** - * Returns a string representation of the card collection. + * Moves n cards from this collection to the given collection. */ - public String toString() { - return label + ": " + cards.toString(); + public void deal(CardCollection that, int n) { + for (int i = 0; i < n; i++) { + Card card = popCard(); + that.addCard(card); + } + } + + /** + * Moves all remaining cards to the given collection. + */ + public void dealAll(CardCollection that) { + int n = cards.size(); + deal(that, n); } } diff --git a/ch14/Eights.java b/ch14/Eights.java index 9bc0433..c5d5aea 100644 --- a/ch14/Eights.java +++ b/ch14/Eights.java @@ -1,9 +1,8 @@ import java.util.Scanner; /** - * Simulates a game of Crazy Eights. See - * https://en.wikipedia.org/wiki/Crazy_Eights - * for basic play and scoring rules. + * Simulates a game of Crazy Eights. + * See https://en.wikipedia.org/wiki/Crazy_Eights. */ public class Eights { @@ -21,12 +20,10 @@ public Eights() { deck.shuffle(); // deal cards to each player - int handSize = 5; one = new Player("Allen"); - deck.deal(one.getHand(), handSize); - + deck.deal(one.getHand(), 5); two = new Player("Chris"); - deck.deal(two.getHand(), handSize); + deck.deal(two.getHand(), 5); // turn one card face up discardPile = new Hand("Discards"); @@ -44,7 +41,7 @@ public Eights() { * Returns true if either hand is empty. */ public boolean isDone() { - return one.getHand().empty() || two.getHand().empty(); + return one.getHand().isEmpty() || two.getHand().isEmpty(); } /** @@ -68,7 +65,7 @@ public void reshuffle() { * Returns a card from the draw pile. */ public Card drawCard() { - if (drawPile.empty()) { + if (drawPile.isEmpty()) { reshuffle(); } return drawPile.popCard(); diff --git a/ch14/Player.java b/ch14/Player.java index 97870da..aec1394 100644 --- a/ch14/Player.java +++ b/ch14/Player.java @@ -70,16 +70,9 @@ public Card drawForMatch(Eights eights, Card prev) { * Checks whether two cards match. */ public static boolean cardMatches(Card card1, Card card2) { - if (card1.getSuit() == card2.getSuit()) { - return true; - } - if (card1.getRank() == card2.getRank()) { - return true; - } - if (card1.getRank() == 8) { - return true; - } - return false; + return card1.getSuit() == card2.getSuit() + || card1.getRank() == card2.getRank() + || card1.getRank() == 8; } /** diff --git a/ch15/.checkstyle b/ch15/.checkstyle new file mode 100644 index 0000000..744b9f9 --- /dev/null +++ b/ch15/.checkstyle @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/ch15/.classpath b/ch15/.classpath new file mode 100644 index 0000000..3f3893a --- /dev/null +++ b/ch15/.classpath @@ -0,0 +1,6 @@ + + + + + + diff --git a/ch15/.project b/ch15/.project new file mode 100644 index 0000000..77395cb --- /dev/null +++ b/ch15/.project @@ -0,0 +1,23 @@ + + + ch15 + + + + + + org.eclipse.jdt.core.javabuilder + + + + + net.sf.eclipsecs.core.CheckstyleBuilder + + + + + + org.eclipse.jdt.core.javanature + net.sf.eclipsecs.core.CheckstyleNature + + diff --git a/ch15/Cell.java b/ch15/Cell.java new file mode 100644 index 0000000..5b6a0f9 --- /dev/null +++ b/ch15/Cell.java @@ -0,0 +1,77 @@ +import java.awt.Color; +import java.awt.Graphics; + +/** + * A square at a fixed location that changes color. + * + * @author Chris Mayfield + * @version 7.1.0 + */ +public class Cell { + + public static final Color[] COLORS = {Color.WHITE, Color.BLACK}; + + private final int x; + private final int y; + private final int size; + private int state; + + /** + * Constructs a new cell, initially turned off. + * + * @param x the X coordinate + * @param y the Y coordinate + * @param size number of pixels + */ + public Cell(int x, int y, int size) { + this.x = x; + this.y = y; + this.size = size; + this.state = 0; + } + + /** + * Draws the cell on the screen. + * + * @param g graphics context + */ + public void draw(Graphics g) { + g.setColor(COLORS[state]); + g.fillRect(x + 1, y + 1, size - 1, size - 1); + g.setColor(Color.LIGHT_GRAY); + g.drawRect(x, y, size, size); + } + + /** + * Tests whether the cell is off. + * + * @return true if the cell is off + */ + public boolean isOff() { + return state == 0; + } + + /** + * Tests whether the cell is on. + * + * @return true if the cell is on + */ + public boolean isOn() { + return state == 1; + } + + /** + * Sets the cell's state to off. + */ + public void turnOff() { + state = 0; + } + + /** + * Sets the cell's state to on. + */ + public void turnOn() { + state = 1; + } + +} diff --git a/ch15/Conway.java b/ch15/Conway.java new file mode 100644 index 0000000..5ac48c6 --- /dev/null +++ b/ch15/Conway.java @@ -0,0 +1,149 @@ +import javax.swing.JFrame; + +/** + * Conway's Game of Life. + * + * @author Chris Mayfield + * @version 7.1.0 + */ +public class Conway { + + private GridCanvas grid; + + /** + * Creates a grid with two Blinkers. + */ + public Conway() { + grid = new GridCanvas(5, 10, 20); + grid.turnOn(2, 1); + grid.turnOn(2, 2); + grid.turnOn(2, 3); + grid.turnOn(1, 7); + grid.turnOn(2, 7); + grid.turnOn(3, 7); + } + + /** + * Counts the number of live neighbors around a cell. + * + * @param r row index + * @param c column index + * @return number of live neighbors + */ + private int countAlive(int r, int c) { + int count = 0; + count += grid.test(r - 1, c - 1); + count += grid.test(r - 1, c); + count += grid.test(r - 1, c + 1); + count += grid.test(r, c - 1); + count += grid.test(r, c + 1); + count += grid.test(r + 1, c - 1); + count += grid.test(r + 1, c); + count += grid.test(r + 1, c + 1); + return count; + } + + /** + * Apply the update rules of Conway's Game of Life. + * + * @param cell the cell to update + * @param count number of live neighbors + */ + private static void updateCell(Cell cell, int count) { + if (cell.isOn()) { + if (count < 2 || count > 3) { + // Any live cell with fewer than two live neighbors dies, + // as if by underpopulation. + // Any live cell with more than three live neighbors dies, + // as if by overpopulation. + cell.turnOff(); + } + } else { + if (count == 3) { + // Any dead cell with exactly three live neighbors + // becomes a live cell, as if by reproduction. + cell.turnOn(); + } + } + } + + /** + * Counts the neighbors before changing anything. + * + * @return number of neighbors for each cell + */ + private int[][] countNeighbors() { + int rows = grid.numRows(); + int cols = grid.numCols(); + + int[][] counts = new int[rows][cols]; + for (int r = 0; r < rows; r++) { + for (int c = 0; c < cols; c++) { + counts[r][c] = countAlive(r, c); + } + } + return counts; + } + + /** + * Updates each cell based on neighbor counts. + * + * @param counts number of neighbors for each cell + */ + private void updateGrid(int[][] counts) { + int rows = grid.numRows(); + int cols = grid.numCols(); + + for (int r = 0; r < rows; r++) { + for (int c = 0; c < cols; c++) { + Cell cell = grid.getCell(r, c); + updateCell(cell, counts[r][c]); + } + } + } + + /** + * Simulates one round of Conway's Game of Life. + */ + public void update() { + int[][] counts = countNeighbors(); + updateGrid(counts); + } + + /** + * The simulation loop. + */ + private void mainloop() { + while (true) { + + // update the drawing + this.update(); + grid.repaint(); + + // delay the simulation + try { + Thread.sleep(500); + } catch (InterruptedException e) { + // do nothing + } + } + } + + /** + * Creates and runs the simulation. + * + * @param args command-line arguments + */ + public static void main(String[] args) { + String title = "Conway's Game of Life"; + Conway game = new Conway(); + JFrame frame = new JFrame(title); + frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); + frame.setResizable(false); + frame.add(game.grid); + frame.pack(); + frame.setVisible(true); + game.mainloop(); + } + +} diff --git a/ch15/GridCanvas.java b/ch15/GridCanvas.java new file mode 100644 index 0000000..3856a57 --- /dev/null +++ b/ch15/GridCanvas.java @@ -0,0 +1,129 @@ +import java.awt.Canvas; +import java.awt.Graphics; + +/** + * 2D array of cells representing a rectangular grid. + * + * @author Chris Mayfield + * @version 7.1.0 + */ +public class GridCanvas extends Canvas { + + /** Cells stored in row-major order. */ + private Cell[][] array; + + /** + * Constructs a grid of given size. + * + * @param rows number of rows + * @param cols number of columns + * @param size pixels per cell + */ + public GridCanvas(int rows, int cols, int size) { + + // build 2D array of cells + array = new Cell[rows][cols]; + for (int r = 0; r < rows; r++) { + int y = r * size; + for (int c = 0; c < cols; c++) { + int x = c * size; + array[r][c] = new Cell(x, y, size); + } + } + + // set the canvas size + setSize(cols * size, rows * size); + } + + /** + * Gets the number of rows. + * + * @return number of rows + */ + public int numRows() { + return array.length; + } + + /** + * Gets the number of columns. + * + * @return number of columns + */ + public int numCols() { + return array[0].length; + } + + /** + * Gets the cell at index (r, c). + * + * @param r row index + * @param c column index + * @return the cell + */ + public Cell getCell(int r, int c) { + return array[r][c]; + } + + /** + * Convenience method that turns on the cell at (r, c). + * + * @param r row index + * @param c column index + */ + public void turnOn(int r, int c) { + array[r][c].turnOn(); + } + + /** + * Returns 1 if the cell at (r, c) exists and is on. Returns 0 if the cell + * doesn't exist or is off. + * + * @param r row index + * @param c column index + * @return 1 or 0 + */ + public int test(int r, int c) { + try { + if (array[r][c].isOn()) { + return 1; + } + } catch (ArrayIndexOutOfBoundsException e) { + // cell doesn't exist + } + return 0; + } + + /** + * Draws the grid, cell by cell. + * + * @param g graphics context + */ + public void draw(Graphics g) { + for (Cell[] row : array) { + for (Cell cell : row) { + cell.draw(g); + } + } + } + + /** + * Paints the grid on the screen. + * + * @param g graphics context + */ + public void paint(Graphics g) { + draw(g); + } + + /** + * Overriding this method helps the simulation run more smoothly. Normally + * the Canvas is cleared before painting, but there is no need to clear it + * since the paint method draws the entire grid. + * + * @param g graphics context + */ + public void update(Graphics g) { + draw(g); + } + +} diff --git a/ch16/.checkstyle b/ch16/.checkstyle new file mode 100644 index 0000000..744b9f9 --- /dev/null +++ b/ch16/.checkstyle @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/ch16/.classpath b/ch16/.classpath new file mode 100644 index 0000000..3f3893a --- /dev/null +++ b/ch16/.classpath @@ -0,0 +1,6 @@ + + + + + + diff --git a/ch16/.project b/ch16/.project new file mode 100644 index 0000000..ae6ca3f --- /dev/null +++ b/ch16/.project @@ -0,0 +1,23 @@ + + + ch16 + + + + + + org.eclipse.jdt.core.javabuilder + + + + + net.sf.eclipsecs.core.CheckstyleBuilder + + + + + + org.eclipse.jdt.core.javanature + net.sf.eclipsecs.core.CheckstyleNature + + diff --git a/ch16/Automaton.java b/ch16/Automaton.java new file mode 100644 index 0000000..3ca63a6 --- /dev/null +++ b/ch16/Automaton.java @@ -0,0 +1,54 @@ +import javax.swing.JFrame; + +/** + * A cellular automaton consists of a grid of cells and follows a set of rules + * that update the grid over time. + */ +public abstract class Automaton { + + protected GridCanvas grid; + + /** + * Applies rules to update the grid. + */ + public abstract void update(); + + /** + * The simulation loop. + * + * @param rate frames per second + */ + private void mainloop(int rate) { + while (true) { + + // update the drawing + this.update(); + grid.repaint(); + + // delay the simulation + try { + Thread.sleep(1000 / rate); + } catch (InterruptedException e) { + // do nothing + } + } + } + + /** + * Creates a JFrame and runs the automaton. + * + * @param title the frame title + * @param rate frames per second + */ + public void run(String title, int rate) { + // set up the window frame + JFrame frame = new JFrame(title); + frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); + frame.setResizable(false); + frame.add(this.grid); + frame.pack(); + frame.setVisible(true); + this.mainloop(rate); + } + +} diff --git a/ch16/Cell.java b/ch16/Cell.java new file mode 120000 index 0000000..1e0bc1b --- /dev/null +++ b/ch16/Cell.java @@ -0,0 +1 @@ +../ch15/Cell.java \ No newline at end of file diff --git a/ch16/Conway.java b/ch16/Conway.java new file mode 100644 index 0000000..09080c0 --- /dev/null +++ b/ch16/Conway.java @@ -0,0 +1,117 @@ +/** + * Conway's Game of Life. + */ +public class Conway extends Automaton { + + /** + * Creates a grid with two Blinkers. + */ + public Conway() { + grid = new GridCanvas(5, 10, 20); + grid.turnOn(2, 1); + grid.turnOn(2, 2); + grid.turnOn(2, 3); + grid.turnOn(1, 7); + grid.turnOn(2, 7); + grid.turnOn(3, 7); + } + + /** + * Counts the number of live neighbors around a cell. + * + * @param r row index + * @param c column index + * @return number of live neighbors + */ + private int countAlive(int r, int c) { + int count = 0; + count += grid.test(r - 1, c - 1); + count += grid.test(r - 1, c); + count += grid.test(r - 1, c + 1); + count += grid.test(r, c - 1); + count += grid.test(r, c + 1); + count += grid.test(r + 1, c - 1); + count += grid.test(r + 1, c); + count += grid.test(r + 1, c + 1); + return count; + } + + /** + * Apply the update rules of Conway's Game of Life. + * + * @param cell the cell to update + * @param count number of live neighbors + */ + private static void updateCell(Cell cell, int count) { + if (cell.isOn()) { + if (count < 2 || count > 3) { + // Any live cell with fewer than two live neighbors dies, + // as if by underpopulation. + // Any live cell with more than three live neighbors dies, + // as if by overpopulation. + cell.turnOff(); + } + } else { + if (count == 3) { + // Any dead cell with exactly three live neighbors + // becomes a live cell, as if by reproduction. + cell.turnOn(); + } + } + } + + /** + * Counts the neighbors before changing anything. + * + * @return number of neighbors for each cell + */ + private int[][] countNeighbors() { + int rows = grid.numRows(); + int cols = grid.numCols(); + + int[][] counts = new int[rows][cols]; + for (int r = 0; r < rows; r++) { + for (int c = 0; c < cols; c++) { + counts[r][c] = countAlive(r, c); + } + } + return counts; + } + + /** + * Updates each cell based on neighbor counts. + * + * @param counts number of neighbors for each cell + */ + private void updateGrid(int[][] counts) { + int rows = grid.numRows(); + int cols = grid.numCols(); + + for (int r = 0; r < rows; r++) { + for (int c = 0; c < cols; c++) { + Cell cell = grid.getCell(r, c); + updateCell(cell, counts[r][c]); + } + } + } + + /** + * Simulates one round of Conway's Game of Life. + */ + public void update() { + int[][] counts = countNeighbors(); + updateGrid(counts); + } + + /** + * Creates and runs the simulation. + * + * @param args command-line arguments + */ + public static void main(String[] args) { + String title = "Conway's Game of Life"; + Conway game = new Conway(); + game.run(title, 2); + } + +} diff --git a/ch16/GridCanvas.java b/ch16/GridCanvas.java new file mode 120000 index 0000000..6711096 --- /dev/null +++ b/ch16/GridCanvas.java @@ -0,0 +1 @@ +../ch15/GridCanvas.java \ No newline at end of file diff --git a/ch16/Langton.java b/ch16/Langton.java new file mode 100644 index 0000000..a39d7a2 --- /dev/null +++ b/ch16/Langton.java @@ -0,0 +1,103 @@ +import javax.swing.JFrame; + +/** + * Langton's Ant. + */ +public class Langton { + + private GridCanvas grid; + private int xpos; + private int ypos; + private int head; // 0=North, 1=East, 2=South, 3=West + + /** + * Creates a grid with the ant in the center. + * + * @param rows number of rows + * @param cols number of columns + */ + public Langton(int rows, int cols) { + grid = new GridCanvas(rows, cols, 10); + xpos = rows / 2; + ypos = cols / 2; + head = 0; + } + + /** + * Flip the color of the current cell. + */ + private void flipCell() { + Cell cell = grid.getCell(xpos, ypos); + if (cell.isOff()) { + // at a white square; turn right and flip color + head = (head + 1) % 4; + cell.turnOn(); + } else { + // at a black square; turn left and flip color + head = (head + 3) % 4; + cell.turnOff(); + } + } + + /** + * Move the ant forward one unit. + */ + private void moveAnt() { + if (head == 0) { + ypos -= 1; + } else if (head == 1) { + xpos += 1; + } else if (head == 2) { + ypos += 1; + } else { + xpos -= 1; + } + } + + /** + * Simulates one round of Langton's Ant. + */ + public void update() { + flipCell(); + moveAnt(); + } + + /** + * The simulation loop. + * + * @param rate frames per second + */ + private void mainloop() { + while (true) { + + // update the drawing + this.update(); + grid.repaint(); + + // delay the simulation + try { + Thread.sleep(2); + } catch (InterruptedException e) { + // do nothing + } + } + } + + /** + * Creates and runs the simulation. + * + * @param args command-line arguments + */ + public static void main(String[] args) { + String title = "Langton's Ant"; + Langton game = new Langton(61, 61); + JFrame frame = new JFrame(title); + frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); + frame.setResizable(false); + frame.add(game.grid); + frame.pack(); + frame.setVisible(true); + game.mainloop(); + } + +} diff --git a/ch17/.checkstyle b/ch17/.checkstyle new file mode 100644 index 0000000..744b9f9 --- /dev/null +++ b/ch17/.checkstyle @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/ch17/.classpath b/ch17/.classpath new file mode 100644 index 0000000..3f3893a --- /dev/null +++ b/ch17/.classpath @@ -0,0 +1,6 @@ + + + + + + diff --git a/ch17/.project b/ch17/.project new file mode 100644 index 0000000..7010276 --- /dev/null +++ b/ch17/.project @@ -0,0 +1,23 @@ + + + ch17 + + + + + + org.eclipse.jdt.core.javabuilder + + + + + net.sf.eclipsecs.core.CheckstyleBuilder + + + + + + org.eclipse.jdt.core.javanature + net.sf.eclipsecs.core.CheckstyleNature + + diff --git a/ch17/Actor.java b/ch17/Actor.java new file mode 100644 index 0000000..5f99153 --- /dev/null +++ b/ch17/Actor.java @@ -0,0 +1,20 @@ +import java.awt.Graphics; + +/** + * Graphical simulation element. + */ +public interface Actor { + + /** + * Draws the simulation element in the context. + * + * @param g graphics context + */ + void draw(Graphics g); + + /** + * Updates the state of the simulation element. + */ + void step(); + +} diff --git a/ch17/BlinkingPolygon.java b/ch17/BlinkingPolygon.java new file mode 100644 index 0000000..9408309 --- /dev/null +++ b/ch17/BlinkingPolygon.java @@ -0,0 +1,42 @@ +import java.awt.Color; +import java.awt.Graphics; + +/** + * A polygon that periodically changes colors on/off. + */ +public class BlinkingPolygon extends RegularPolygon { + + protected boolean visible; + protected int count; + + /** + * Constructs a blinking polygon. + * + * @param nsides the number of sides + * @param radius from center to vertex + * @param color initial fill color + */ + public BlinkingPolygon(int nsides, int radius, Color color) { + super(nsides, radius, color); + visible = true; + count = 0; + } + + @Override + public void draw(Graphics g) { + if (visible) { + super.draw(g); + } + } + + @Override + public void step() { + // toggle visibility every 10 steps + count++; + if (count == 10) { + visible = !visible; + count = 0; + } + } + +} diff --git a/ch17/DrawablePolygon.java b/ch17/DrawablePolygon.java new file mode 100644 index 0000000..14318f0 --- /dev/null +++ b/ch17/DrawablePolygon.java @@ -0,0 +1,48 @@ +import java.awt.Color; +import java.awt.Graphics; +import java.awt.Polygon; + +/** + * Specialization of Polygon that has a color and the ability to draw itself. + */ +public class DrawablePolygon extends Polygon implements Actor { + + protected Color color; + + /** + * Creates an empty polygon. + */ + public DrawablePolygon() { + super(); + color = Color.GRAY; + } + + /** + * Draws the polygon on the screen. + * + * @param g graphics context + */ + public void draw(Graphics g) { + g.setColor(color); + g.fillPolygon(this); + } + + @Override + public void step() { + // do nothing + } + + /** + * Test code that creates a ColorPolygon. + * + * @param args command-line arguments + */ + public static void main(String[] args) { + DrawablePolygon p = new DrawablePolygon(); + p.addPoint(57, 110); + p.addPoint(100, 35); + p.addPoint(143, 110); + p.color = Color.GREEN; + } + +} diff --git a/ch17/Drawing.bak b/ch17/Drawing.bak new file mode 100644 index 0000000..fef62ef --- /dev/null +++ b/ch17/Drawing.bak @@ -0,0 +1,56 @@ +import java.awt.Canvas; +import java.awt.Color; +import java.awt.Graphics; +import java.util.ArrayList; + +/** + * Draws a collection of DrawablePolygons. + */ +public class Drawing extends Canvas { + + private ArrayList list; + + /** + * Constructs a drawing of given size. + * + * @param width the width in pixels + * @param height the height in pixels + */ + public Drawing(int width, int height) { + setSize(width, height); + setBackground(Color.WHITE); + list = new ArrayList(); + } + + /** + * Adds a new actor to the drawing. + * + * @param dp the object to add + */ + public void add(DrawablePolygon dp) { + list.add(dp); + } + + /** + * Draws all the actors on the canvas. + * + * @param g graphics context + */ + @Override + public void paint(Graphics g) { + for (DrawablePolygon dp : list) { + dp.draw(g); + } + } + + /** + * Calls the step method of each actor and updates the drawing. + */ + public void step() { + for (DrawablePolygon dp : list) { + dp.step(); + } + repaint(); + } + +} diff --git a/ch17/Drawing.java b/ch17/Drawing.java new file mode 100644 index 0000000..6d3792f --- /dev/null +++ b/ch17/Drawing.java @@ -0,0 +1,65 @@ +import java.awt.Canvas; +import java.awt.Color; +import java.awt.Graphics; +import java.util.ArrayList; + +/** + * Draws a collection of actors. + */ +public class Drawing extends Canvas { + + private ArrayList list; + + /** + * Constructs a drawing of given size. + * + * @param width the width in pixels + * @param height the height in pixels + */ + public Drawing(int width, int height) { + setSize(width, height); + setBackground(Color.WHITE); + list = new ArrayList(); + } + + /** + * Adds a new actor to the drawing. + * + * @param actor the object to add + */ + public void add(Actor actor) { + list.add(actor); + } + + /** + * Gets current actors as an array. + * + * @return array of actor objects + */ + public Object[] getActors() { + return list.toArray(); + } + + /** + * Draws all the actors on the canvas. + * + * @param g graphics context + */ + @Override + public void paint(Graphics g) { + for (Actor actor : list) { + actor.draw(g); + } + } + + /** + * Calls the step method of each actor and updates the drawing. + */ + public void step() { + for (Actor actor : list) { + actor.step(); + } + repaint(); + } + +} diff --git a/ch17/Main.java b/ch17/Main.java new file mode 100644 index 0000000..0ab09a0 --- /dev/null +++ b/ch17/Main.java @@ -0,0 +1,40 @@ +import java.awt.Color; +import javax.swing.JFrame; + +/** + * Initial drawing of stationary objects. + */ +public class Main { + + /** + * Test program that draws a few polygons. + * + * @param args command-line arguments + */ + public static void main(String[] args) { + + // create some regular polygons + DrawablePolygon p1 = new RegularPolygon(3, 50, Color.GREEN); + DrawablePolygon p2 = new RegularPolygon(6, 50, Color.ORANGE); + DrawablePolygon p3 = new RegularPolygon(360, 50, Color.BLUE); + + // move them out of the corner + p1.translate(100, 80); + p2.translate(250, 120); + p3.translate(400, 160); + + // create drawing, add polygons + Drawing drawing = new Drawing(500, 250); + drawing.add(p1); + drawing.add(p2); + drawing.add(p3); + + // set up the window frame + JFrame frame = new JFrame("Drawing"); + frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); + frame.add(drawing); + frame.pack(); + frame.setVisible(true); + } + +} diff --git a/ch17/RegularPolygon.java b/ch17/RegularPolygon.java new file mode 100644 index 0000000..4642355 --- /dev/null +++ b/ch17/RegularPolygon.java @@ -0,0 +1,70 @@ +import java.awt.Color; + +/** + * A polygon that is equiangular (all angles are equal in measure) and + * equilateral (all sides have the same length). It also has a color. + */ +public class RegularPolygon extends DrawablePolygon { + + /** + * Constructs a regular polygon, given the number of sides. + * + * @param nsides the number of sides + */ + public RegularPolygon(int nsides) { + this(nsides, 50); + } + + /** + * Constructs a regular polygon, given the number of sides and the radius. + * + * @param nsides the number of sides + * @param radius from center to vertex + */ + public RegularPolygon(int nsides, int radius) { + this(nsides, radius, Color.GRAY); + } + + /** + * Constructs a regular polygon, given the number of sides, the radius, and + * fill color. + * + * @param nsides the number of sides + * @param radius from center to vertex + * @param color initial fill color + */ + public RegularPolygon(int nsides, int radius, Color color) { + + // validate the arguments + if (nsides < 3) { + throw new IllegalArgumentException("invalid nsides"); + } + if (radius <= 0) { + throw new IllegalArgumentException("invalid radius"); + } + if (color == null) { + throw new NullPointerException("invalid color"); + } + + // initialize Polygon attributes + this.npoints = nsides; + this.xpoints = new int[nsides]; + this.ypoints = new int[nsides]; + this.color = color; + + // the amount to rotate for each vertex (in radians) + double theta = 2.0 * Math.PI / nsides; + + // rotation that makes the polygon right-side up + double rotate = Math.PI / nsides + Math.PI / 2.0; + + // compute x and y coordinates, centered at the origin + for (int i = 0; i < nsides; i++) { + double x = radius * Math.cos(i * theta + rotate); + double y = radius * Math.sin(i * theta + rotate); + xpoints[i] = (int) Math.round(x); + ypoints[i] = (int) Math.round(y); + } + } + +} diff --git a/ch17/Sprite.java b/ch17/Sprite.java new file mode 100644 index 0000000..92d013e --- /dev/null +++ b/ch17/Sprite.java @@ -0,0 +1,85 @@ +import java.awt.Graphics; +import java.awt.Image; +import java.awt.event.KeyEvent; +import java.awt.event.KeyListener; +import java.io.File; +import java.io.IOException; +import javax.imageio.ImageIO; + +/** + * A small character that can move around the screen. + */ +public class Sprite implements Actor, KeyListener { + + private int xpos; + private int ypos; + private int dx; + private int dy; + private Image image; + + /** + * Reads a sprite from a png file. + * + * @param path location of image file + * @param xpos initial X coordinate + * @param ypos initial Y coordinate + */ + public Sprite(String path, int xpos, int ypos) { + this.xpos = xpos; + this.ypos = ypos; + try { + this.image = ImageIO.read(new File(path)); + } catch (IOException e) { + e.printStackTrace(); + } + } + + @Override + public void draw(Graphics g) { + g.drawImage(image, xpos, ypos, null); + } + + @Override + public void step() { + xpos += dx; + ypos += dy; + } + + @Override + public void keyPressed(KeyEvent e) { + switch (e.getKeyCode()) { + case KeyEvent.VK_UP: + dy = -5; + break; + case KeyEvent.VK_DOWN: + dy = +5; + break; + case KeyEvent.VK_LEFT: + dx = -5; + break; + case KeyEvent.VK_RIGHT: + dx = +5; + break; + } + } + + @Override + public void keyReleased(KeyEvent e) { + switch (e.getKeyCode()) { + case KeyEvent.VK_UP: + case KeyEvent.VK_DOWN: + dy = 0; + break; + case KeyEvent.VK_LEFT: + case KeyEvent.VK_RIGHT: + dx = 0; + break; + } + } + + @Override + public void keyTyped(KeyEvent e) { + // do nothing + } + +} diff --git a/ch17/VideoGame.java b/ch17/VideoGame.java new file mode 100644 index 0000000..cf06193 --- /dev/null +++ b/ch17/VideoGame.java @@ -0,0 +1,50 @@ +import java.awt.Toolkit; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import javax.swing.JFrame; +import javax.swing.Timer; + +/** + * Example game with a sprite that moves around the screen. + */ +public class VideoGame implements ActionListener { + + private Drawing drawing; + private Toolkit toolkit; + + /** + * Set up the drawing and window frame. + */ + public VideoGame() { + Sprite sprite = new Sprite("face-smile.png", 25, 150); + drawing = new Drawing(800, 600); + drawing.add(sprite); + drawing.addKeyListener(sprite); + drawing.setFocusable(true); + + JFrame frame = new JFrame("Video Game"); + frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); + frame.add(drawing); + frame.pack(); + frame.setVisible(true); + toolkit = frame.getToolkit(); + } + + @Override + public void actionPerformed(ActionEvent e) { + drawing.step(); + toolkit.sync(); + } + + /** + * Create and start the timer. + * + * @param args command-line arguments + */ + public static void main(String[] args) { + VideoGame game = new VideoGame(); + Timer timer = new Timer(33, game); + timer.start(); + } + +} diff --git a/ch17/face-smile.png b/ch17/face-smile.png new file mode 100644 index 0000000..417024e Binary files /dev/null and b/ch17/face-smile.png differ diff --git a/ch17/face-smile.svg b/ch17/face-smile.svg new file mode 100644 index 0000000..362f67e --- /dev/null +++ b/ch17/face-smile.svg @@ -0,0 +1,286 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + Openclipart + + + tango face smile + 2010-03-08T08:40:05 + Smiley icon from Tango Project: http://tango.freedesktop.org/Tango_Desktop_Project \n<br><br> \nTango Project icons are Public Domain. + https://openclipart.org/detail/30217/tango-face-smile-by-warszawianka + + + warszawianka + + + + + emote + happy + icon + smile + smiley + + + + + + + + + + + diff --git a/ch17/face-smile.txt b/ch17/face-smile.txt new file mode 100644 index 0000000..ea6f5b1 --- /dev/null +++ b/ch17/face-smile.txt @@ -0,0 +1,10 @@ +Source: +https://publicdomainvectors.org/en/free-clipart/Smiley-face-icon-vector-image/15374.html + +Description: +Vector illustration of a smiley face icon. Color drawing of a yellow smiling emoticon. + +License: +Public domain + +inkscape -z -e face-smile.png -w 100 -h 100 face-smile.svg diff --git a/user.dict b/user.dict new file mode 100644 index 0000000..11b2406 --- /dev/null +++ b/user.dict @@ -0,0 +1,2 @@ +chris +mayfield