diff --git a/Checkstyle.xml b/Checkstyle.xml index 0b55302..36dbd1f 100644 --- a/Checkstyle.xml +++ b/Checkstyle.xml @@ -1,35 +1,40 @@ + "-//Checkstyle//DTD Checkstyle Configuration 1.3//EN" + "https://checkstyle.org/dtds/configuration_1_3.dtd"> + - + - + - + + - + - + + + + @@ -37,58 +42,70 @@ Checkstyle configuration for Think Java, 2nd Edition. - - + + + - - + - + - + - + + + + + - + + + + + + + + + - + + + + - + - + + @@ -101,42 +118,38 @@ Checkstyle configuration for Think Java, 2nd Edition. - + - - + - + + + - - - + + - + diff --git a/Formatter.xml b/Formatter.xml index f97740d..ab6e68e 100644 --- a/Formatter.xml +++ b/Formatter.xml @@ -1,318 +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 84689d7..a9646f6 100644 --- a/README.md +++ b/README.md @@ -1,12 +1,12 @@ # ThinkJavaCode2 Supporting code for Think Java, 2nd edition. -Copyright (c) 2019 Allen Downey and Chris Mayfield. -**This new edition is a work in progress and won't be completed until Fall 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/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/Mickey.java b/appc/Mickey.java index b303b20..73236d6 100644 --- a/appc/Mickey.java +++ b/appc/Mickey.java @@ -11,7 +11,7 @@ public static void main(String[] args) { 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); diff --git a/appc/Moire.java b/appc/Moire.java index b736d97..6c3e78c 100644 --- a/appc/Moire.java +++ b/appc/Moire.java @@ -10,7 +10,7 @@ public static void main(String[] args) { 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/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/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/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/Circle.java b/ch04/Circle.java index a09e594..f79af90 100644 --- a/ch04/Circle.java +++ b/ch04/Circle.java @@ -1,76 +1,13 @@ 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/ch04/Methods.java b/ch04/MathMethods.java similarity index 89% rename from ch04/Methods.java rename to ch04/MathMethods.java index 90c1b7a..51ef7dc 100644 --- a/ch04/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/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 5a5a4ca..0000000 --- a/ch05/Conditional.java +++ /dev/null @@ -1,50 +0,0 @@ -/** - * Examples from Chapter 5. - */ -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/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/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 09b817f..f8b40f0 100644 --- a/ch06/Strings.java +++ b/ch06/Strings.java @@ -1,5 +1,7 @@ +import java.util.Scanner; + /** - * Demonstrates 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/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/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/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 6dde3a0..ae7b350 100644 --- a/ch09/Objects.java +++ b/ch09/Objects.java @@ -1,5 +1,3 @@ -import java.math.BigInteger; - /** * Demonstrates uses of objects and wrappers. */ @@ -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 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 + 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/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 cb0af07..301dd90 100644 --- a/ch10/PointRect.java +++ b/ch10/PointRect.java @@ -9,27 +9,40 @@ 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/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/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/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/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/Cell.java b/ch15/Cell.java index 17e9987..5b6a0f9 100644 --- a/ch15/Cell.java +++ b/ch15/Cell.java @@ -3,6 +3,9 @@ /** * A square at a fixed location that changes color. + * + * @author Chris Mayfield + * @version 7.1.0 */ public class Cell { @@ -40,30 +43,35 @@ public void draw(Graphics g) { } /** - * @return true if the cell is OFF + * Tests whether the cell is off. + * + * @return true if the cell is off */ public boolean isOff() { return state == 0; } /** - * @return true if the cell is ON + * 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. + * Sets the cell's state to off. */ public void turnOff() { state = 0; } /** - * Sets the cell's state to ON. + * Sets the cell's state to on. */ public void turnOn() { state = 1; } + } diff --git a/ch15/Conway.java b/ch15/Conway.java index 572ab78..5ac48c6 100644 --- a/ch15/Conway.java +++ b/ch15/Conway.java @@ -1,80 +1,26 @@ -import java.io.File; -import java.io.FileNotFoundException; -import java.util.ArrayList; -import java.util.Scanner; +import javax.swing.JFrame; /** * Conway's Game of Life. + * + * @author Chris Mayfield + * @version 7.1.0 */ -public class Conway extends Automaton { +public class Conway { + + private GridCanvas grid; /** - * Creates a grid with a Blinker and a Glider. + * Creates a grid with two Blinkers. */ public Conway() { - grid = new GridCanvas(30, 25, SIZE); - grid.turnOn(1, 2); + grid = new GridCanvas(5, 10, 20); + grid.turnOn(2, 1); grid.turnOn(2, 2); - grid.turnOn(3, 2); - grid.turnOn(6, 1); - grid.turnOn(7, 2); - grid.turnOn(7, 3); - grid.turnOn(8, 1); - grid.turnOn(8, 2); - } - - /** - * Creates a grid based on a plain text file. - * http://www.conwaylife.com/wiki/Plaintext - * - * @param path the path to the file - * @param margin how many cells to add - */ - public Conway(String path, int margin) { - - // open the file at the given path - Scanner scan = null; - try { - File file = new File(path); - scan = new Scanner(file); - } catch (FileNotFoundException e) { - e.printStackTrace(); - System.exit(1); - } - - // read file contents into memory - ArrayList data = new ArrayList(); - while (scan.hasNextLine()) { - String line = scan.nextLine(); - // only add non-comment lines - if (!line.startsWith("!")) { - data.add(line); - } - } - - // determine number of rows and columns in the pattern - int rows = data.size(); - int cols = 0; - for (String line : data) { - if (cols < line.length()) { - cols = line.length(); - } - } - if (rows == 0 || cols == 0) { - throw new IllegalArgumentException("no cells found"); - } - - // create the resulting grid with margin of extra cells - grid = new GridCanvas(rows + 2 * margin, cols + 2 * margin, SIZE); - for (int r = 0; r < rows; r++) { - String line = data.get(r); - for (int c = 0; c < line.length(); c++) { - char x = line.charAt(c); - if (x == 'O') { - grid.turnOn(r + margin, c + margin); - } - } - } + grid.turnOn(2, 3); + grid.turnOn(1, 7); + grid.turnOn(2, 7); + grid.turnOn(3, 7); } /** @@ -164,6 +110,25 @@ public void update() { 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. * @@ -171,8 +136,14 @@ public void update() { */ public static void main(String[] args) { String title = "Conway's Game of Life"; - Conway game = new Conway("pulsar.cells", 2); - game.run(title, 2); + 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 index c936135..3856a57 100644 --- a/ch15/GridCanvas.java +++ b/ch15/GridCanvas.java @@ -3,6 +3,9 @@ /** * 2D array of cells representing a rectangular grid. + * + * @author Chris Mayfield + * @version 7.1.0 */ public class GridCanvas extends Canvas { @@ -33,6 +36,8 @@ public GridCanvas(int rows, int cols, int size) { } /** + * Gets the number of rows. + * * @return number of rows */ public int numRows() { @@ -40,6 +45,8 @@ public int numRows() { } /** + * Gets the number of columns. + * * @return number of columns */ public int numCols() { @@ -47,6 +54,8 @@ public int numCols() { } /** + * Gets the cell at index (r, c). + * * @param r row index * @param c column index * @return the cell diff --git a/ch15/empty.cells b/ch15/empty.cells deleted file mode 100644 index add6d90..0000000 --- a/ch15/empty.cells +++ /dev/null @@ -1,11 +0,0 @@ -!An empty 10x10 grid -.......... -.......... -.......... -.......... -.......... -.......... -.......... -.......... -.......... -.......... diff --git a/ch15/pulsar.cells b/ch15/pulsar.cells deleted file mode 100644 index 19eda57..0000000 --- a/ch15/pulsar.cells +++ /dev/null @@ -1,17 +0,0 @@ -!Name: Pulsar -!Author: John Conway -!Despite its size, this is the fourth most common oscillator (and by far the most common of period greater than 2). -!www.conwaylife.com/wiki/index.php?title=Pulsar -..OOO...OOO - -O....O.O....O -O....O.O....O -O....O.O....O -..OOO...OOO - -..OOO...OOO -O....O.O....O -O....O.O....O -O....O.O....O - -..OOO...OOO diff --git a/ch15/Automaton.java b/ch16/Automaton.java similarity index 96% rename from ch15/Automaton.java rename to ch16/Automaton.java index 254bf68..3ca63a6 100644 --- a/ch15/Automaton.java +++ b/ch16/Automaton.java @@ -6,8 +6,6 @@ */ public abstract class Automaton { - public static final int SIZE = 20; - protected GridCanvas grid; /** @@ -15,23 +13,6 @@ public abstract class Automaton { */ public abstract void update(); - /** - * 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); - } - /** * The simulation loop. * @@ -53,4 +34,21 @@ private void mainloop(int rate) { } } + /** + * 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/ch15/Langton.java b/ch16/Langton.java similarity index 67% rename from ch15/Langton.java rename to ch16/Langton.java index 45869a1..a39d7a2 100644 --- a/ch15/Langton.java +++ b/ch16/Langton.java @@ -1,8 +1,11 @@ +import javax.swing.JFrame; + /** * Langton's Ant. */ -public class Langton extends Automaton { +public class Langton { + private GridCanvas grid; private int xpos; private int ypos; private int head; // 0=North, 1=East, 2=South, 3=West @@ -59,6 +62,27 @@ public void update() { 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. * @@ -67,7 +91,13 @@ public void update() { public static void main(String[] args) { String title = "Langton's Ant"; Langton game = new Langton(61, 61); - game.run(title, 750); + 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/ch16/Mole.java b/ch16/Mole.java deleted file mode 100644 index 75d48e0..0000000 --- a/ch16/Mole.java +++ /dev/null @@ -1,43 +0,0 @@ -import java.awt.Color; - -/** - * A polygon that represents a small burrowing mammal. - */ -public class Mole extends BlinkingPolygon { - - public static final Color BROWN = new Color(153, 102, 0); - - private boolean alive; - - /** - * Creates a mole at the given location. - * - * @param x the X coordinate - * @param y the Y coordinate - */ - public Mole(int x, int y) { - super(10, 30, BROWN); - translate(x, y); - alive = true; - } - - @Override - public void step() { - // blink on/off at random times - if (alive && Math.random() < 0.5) { - super.step(); - } - } - - /** - * Updates the state of the mole when clicked. - */ - public void whack() { - // ignore whack when invisible - if (visible) { - color = Color.LIGHT_GRAY; - alive = false; - } - } - -} diff --git a/ch16/MoleHill.java b/ch16/MoleHill.java deleted file mode 100644 index 24978e5..0000000 --- a/ch16/MoleHill.java +++ /dev/null @@ -1,54 +0,0 @@ -import java.awt.event.MouseEvent; -import java.awt.event.MouseListener; - -/** - * Draws a collection of moles and listens for mouse events. - */ -public class MoleHill extends Drawing implements MouseListener { - - /** - * Constructs an interactive drawing of given size. - * - * @param width the width in pixels - * @param height the height in pixels - */ - public MoleHill(int width, int height) { - super(width, height); - addMouseListener(this); - } - - @Override - public void mouseClicked(MouseEvent e) { - int x = e.getX(); - int y = e.getY(); - for (Object obj : getActors()) { - if (obj instanceof Mole) { - Mole mole = (Mole) obj; - if (mole.contains(x, y)) { - mole.whack(); - } - } - } - } - - @Override - public void mouseEntered(MouseEvent e) { - // ignore - } - - @Override - public void mouseExited(MouseEvent e) { - // ignore - } - - @Override - public void mousePressed(MouseEvent e) { - // ignore - } - - @Override - public void mouseReleased(MouseEvent e) { - // ignore - } - -} diff --git a/ch16/MovingPolygon.java b/ch16/MovingPolygon.java deleted file mode 100644 index 7c6c2f5..0000000 --- a/ch16/MovingPolygon.java +++ /dev/null @@ -1,56 +0,0 @@ -/** - * A polygon that bounces off the walls. - */ -public class MovingPolygon extends RegularPolygon { - - private int dx; - private int dy; - - /** - * Constructs a moving polygon. - * - * @param nsides the number of sides - * @param radius from center to vertex - */ - public MovingPolygon(int nsides, int radius) { - super(nsides, radius); - dx = 10; - dy = 5; - } - - /** - * @param dx how many pixels to move left/right - */ - public void setDx(int dx) { - this.dx = dx; - } - - /** - * @param dy how many pixels to move up/down - */ - public void setDy(int dy) { - this.dy = dy; - } - - @Override - public void step() { - - // edge detection - for (int i = 0; i < npoints; i++) { - if (xpoints[i] < 0 || xpoints[i] > 800) { - dx *= -1; - break; - } - } - for (int i = 0; i < npoints; i++) { - if (ypoints[i] < 0 || ypoints[i] > 600) { - dy *= -1; - break; - } - } - - // move one step - translate(dx, dy); - } - -} diff --git a/ch16/RotatingPolygon.java b/ch16/RotatingPolygon.java deleted file mode 100644 index f1a84ed..0000000 --- a/ch16/RotatingPolygon.java +++ /dev/null @@ -1,75 +0,0 @@ -import java.util.Arrays; - -/** - * A polygon that rotates around its center. - */ -public class RotatingPolygon extends RegularPolygon { - - private int xmid; - private int ymid; - - private int angle; // in degrees - - private int[] x0; // original xpoints - private int[] y0; // original ypoints - - /** - * Constructs a rotating polygon. - * - * @param nsides the number of sides - * @param radius from center to vertex - */ - public RotatingPolygon(int nsides, int radius) { - super(nsides, radius); - center(); - } - - /** - * Sets the rotation point to the middle. - */ - public void center() { - - // find the average x and y values - int xsum = 0; - int ysum = 0; - for (int x : xpoints) { - xsum += x; - } - for (int y : ypoints) { - ysum += y; - } - xmid = (int) Math.round(xsum / npoints); - ymid = (int) Math.round(ysum / npoints); - - // reset the rotation direction - angle = 359; - - // save the original x and y points - x0 = Arrays.copyOf(xpoints, npoints); - y0 = Arrays.copyOf(ypoints, npoints); - } - - @Override - public void step() { - // update the rotation angle - angle = (angle + 1) % 360; - final double RAD = Math.toRadians(angle); - final double COS = Math.cos(RAD); - final double SIN = Math.sin(RAD); - - // translate the polygon points - for (int i = 0; i < npoints; i++) { - double t = x0[i] - xmid; - double v = y0[i] - ymid; - xpoints[i] = (int) Math.round(xmid + t * COS - v * SIN); - ypoints[i] = (int) Math.round(ymid + t * SIN + v * COS); - } - } - - @Override - public void translate(int deltaX, int deltaY) { - super.translate(deltaX, deltaY); - center(); - } - -} diff --git a/ch16/Sim2.java b/ch16/Sim2.java deleted file mode 100644 index c1284c2..0000000 --- a/ch16/Sim2.java +++ /dev/null @@ -1,57 +0,0 @@ -import java.awt.Color; -import java.awt.Toolkit; -import javax.swing.JFrame; - -/** - * Example simulation of animated objects. - */ -public class Sim2 { - - /** - * Test program that draws a few polygons. - * - * @param args command-line arguments - */ - public static void main(String[] args) { - - // create some regular polygons - BlinkingPolygon bp = new BlinkingPolygon(3, 20, Color.BLUE); - MovingPolygon mp = new MovingPolygon(8, 30); - RotatingPolygon rp = new RotatingPolygon(5, 40); - - // move them out of the corner - bp.translate(50, 50); - mp.translate(100, 100); - rp.translate(200, 200); - - // create drawing, add polygons - Drawing drawing = new Drawing(800, 600); - drawing.add(bp); - drawing.add(mp); - drawing.add(rp); - - // set up the window frame - JFrame frame = new JFrame("Drawing with Thread.sleep"); - frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); - frame.add(drawing); - frame.pack(); - frame.setVisible(true); - - // main simulation loop - Toolkit toolkit = frame.getToolkit(); - while (true) { - - // update the drawing - toolkit.sync(); - drawing.step(); - - // delay the simulation - try { - Thread.sleep(1000 / 30); - } catch (InterruptedException e) { - // do nothing - } - } - } - -} diff --git a/ch16/Sim3.java b/ch16/Sim3.java deleted file mode 100644 index 2bb42d0..0000000 --- a/ch16/Sim3.java +++ /dev/null @@ -1,62 +0,0 @@ -import java.awt.Color; -import java.awt.Toolkit; -import java.awt.event.ActionEvent; -import java.awt.event.ActionListener; -import javax.swing.JFrame; -import javax.swing.Timer; - -/** - * Smoother version of Sim2 using a timer. - */ -public class Sim3 implements ActionListener { - - private Drawing drawing; - private Toolkit toolkit; - - /** - * Set up the drawing and window frame. - */ - public Sim3() { - // create some regular polygons - BlinkingPolygon bp = new BlinkingPolygon(3, 20, Color.BLUE); - MovingPolygon mp = new MovingPolygon(8, 30); - RotatingPolygon rp = new RotatingPolygon(5, 40); - - // move them out of the corner - bp.translate(50, 50); - mp.translate(100, 100); - rp.translate(200, 200); - - // create drawing, add polygons - drawing = new Drawing(800, 600); - drawing.add(bp); - drawing.add(mp); - drawing.add(rp); - - // set up the window frame - JFrame frame = new JFrame("Drawing with ActionListener"); - frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); - frame.add(drawing); - frame.pack(); - frame.setVisible(true); - toolkit = frame.getToolkit(); - } - - @Override - public void actionPerformed(ActionEvent e) { - toolkit.sync(); - drawing.step(); - } - - /** - * Create and start the timer. - * - * @param args command-line arguments - */ - public static void main(String[] args) { - Sim3 sim = new Sim3(); - Timer timer = new Timer(1000 / 30, sim); - timer.start(); - } - -} diff --git a/ch16/WhackAMole.java b/ch16/WhackAMole.java deleted file mode 100644 index 641d6e3..0000000 --- a/ch16/WhackAMole.java +++ /dev/null @@ -1,57 +0,0 @@ -import java.awt.Toolkit; -import java.awt.event.ActionEvent; -import java.awt.event.ActionListener; -import javax.swing.JFrame; -import javax.swing.Timer; - -/** - * Simulates the arcade game Whack-A-Mole. - * https://en.wikipedia.org/wiki/Whac-A-Mole - */ -public class WhackAMole implements ActionListener { - - private Drawing drawing; - private Toolkit toolkit; - - /** - * Set up the drawing and window frame. - */ - public WhackAMole() { - - // create drawing, add polygons - drawing = new MoleHill(800, 600); - drawing.add(new Mole(150, 200)); - drawing.add(new Mole(350, 200)); - drawing.add(new Mole(550, 200)); - drawing.add(new Mole(150, 400)); - drawing.add(new Mole(350, 400)); - drawing.add(new Mole(550, 400)); - - // set up the window frame - JFrame frame = new JFrame("Whack-A-Mole"); - frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); - frame.setResizable(false); - frame.add(drawing); - frame.pack(); - frame.setVisible(true); - toolkit = frame.getToolkit(); - } - - @Override - public void actionPerformed(ActionEvent e) { - toolkit.sync(); - drawing.step(); - } - - /** - * Create and start the timer. - * - * @param args command-line arguments - */ - public static void main(String[] args) { - WhackAMole sim = new WhackAMole(); - Timer timer = new Timer(1000 / 30, sim); - timer.start(); - } - -} diff --git a/appe/.checkstyle b/ch17/.checkstyle similarity index 100% rename from appe/.checkstyle rename to ch17/.checkstyle diff --git a/appe/.classpath b/ch17/.classpath similarity index 100% rename from appe/.classpath rename to ch17/.classpath diff --git a/appe/.project b/ch17/.project similarity index 96% rename from appe/.project rename to ch17/.project index 0932ca3..7010276 100644 --- a/appe/.project +++ b/ch17/.project @@ -1,6 +1,6 @@ - appe + ch17 diff --git a/ch16/Actor.java b/ch17/Actor.java similarity index 100% rename from ch16/Actor.java rename to ch17/Actor.java diff --git a/ch16/BlinkingPolygon.java b/ch17/BlinkingPolygon.java similarity index 100% rename from ch16/BlinkingPolygon.java rename to ch17/BlinkingPolygon.java diff --git a/ch16/DrawablePolygon.java b/ch17/DrawablePolygon.java similarity index 97% rename from ch16/DrawablePolygon.java rename to ch17/DrawablePolygon.java index 0efc8eb..14318f0 100644 --- a/ch16/DrawablePolygon.java +++ b/ch17/DrawablePolygon.java @@ -7,7 +7,7 @@ */ public class DrawablePolygon extends Polygon implements Actor { - public Color color; + protected Color color; /** * Creates an empty polygon. diff --git a/ch16/Drawing.bak b/ch17/Drawing.bak similarity index 68% rename from ch16/Drawing.bak rename to ch17/Drawing.bak index 63ba8f9..fef62ef 100644 --- a/ch16/Drawing.bak +++ b/ch17/Drawing.bak @@ -4,11 +4,11 @@ import java.awt.Graphics; import java.util.ArrayList; /** - * Draws a collection of actors. + * Draws a collection of DrawablePolygons. */ public class Drawing extends Canvas { - private ArrayList list; + private ArrayList list; /** * Constructs a drawing of given size. @@ -19,7 +19,7 @@ public class Drawing extends Canvas { public Drawing(int width, int height) { setSize(width, height); setBackground(Color.WHITE); - list = new ArrayList(); + list = new ArrayList(); } /** @@ -27,19 +27,10 @@ public class Drawing extends Canvas { * * @param dp the object to add */ - public void add(ColorPolygon dp) { + public void add(DrawablePolygon dp) { list.add(dp); } - /** - * Gets current actors as an array. - * - * @return array of actor objects - */ - public Object[] getActors() { - return list.toArray(); - } - /** * Draws all the actors on the canvas. * @@ -47,7 +38,7 @@ public class Drawing extends Canvas { */ @Override public void paint(Graphics g) { - for (ColorPolygon dp : list) { + for (DrawablePolygon dp : list) { dp.draw(g); } } @@ -56,7 +47,7 @@ public class Drawing extends Canvas { * Calls the step method of each actor and updates the drawing. */ public void step() { - for (ColorPolygon dp : list) { + for (DrawablePolygon dp : list) { dp.step(); } repaint(); diff --git a/ch16/Drawing.java b/ch17/Drawing.java similarity index 100% rename from ch16/Drawing.java rename to ch17/Drawing.java diff --git a/ch16/Sim1.java b/ch17/Main.java similarity index 92% rename from ch16/Sim1.java rename to ch17/Main.java index 019903e..0ab09a0 100644 --- a/ch16/Sim1.java +++ b/ch17/Main.java @@ -4,7 +4,7 @@ /** * Initial drawing of stationary objects. */ -public class Sim1 { +public class Main { /** * Test program that draws a few polygons. @@ -30,7 +30,7 @@ public static void main(String[] args) { drawing.add(p3); // set up the window frame - JFrame frame = new JFrame("Drawing (no animation)"); + JFrame frame = new JFrame("Drawing"); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); frame.add(drawing); frame.pack(); diff --git a/ch16/RegularPolygon.java b/ch17/RegularPolygon.java similarity index 63% rename from ch16/RegularPolygon.java rename to ch17/RegularPolygon.java index 5aef2d3..4642355 100644 --- a/ch16/RegularPolygon.java +++ b/ch17/RegularPolygon.java @@ -6,10 +6,6 @@ */ public class RegularPolygon extends DrawablePolygon { - public static final String[] NAMES = {null, null, null, - "Triangle", "Square", "Pentagon", "Hexagon", - "Heptagon", "Octagon", "Nonagon", "Decagon"}; - /** * Constructs a regular polygon, given the number of sides. * @@ -26,7 +22,7 @@ public RegularPolygon(int nsides) { * @param radius from center to vertex */ public RegularPolygon(int nsides, int radius) { - this(nsides, radius, Color.BLACK); + this(nsides, radius, Color.GRAY); } /** @@ -57,43 +53,18 @@ public RegularPolygon(int nsides, int radius, Color color) { this.color = color; // the amount to rotate for each vertex (in radians) - double angle = 2.0 * Math.PI / nsides; + 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 * angle + rotate); + double x = radius * Math.cos(i * theta + rotate); + double y = radius * Math.sin(i * theta + rotate); xpoints[i] = (int) Math.round(x); - double y = radius * Math.sin(i * angle + rotate); ypoints[i] = (int) Math.round(y); } } - @Override - public String toString() { - StringBuilder str = new StringBuilder(); - if (npoints < NAMES.length) { - str.append(NAMES[npoints]); - } else { - str.append("Polygon"); - } - // append the list of vertexes - str.append('['); - for (int i = 0; i < npoints; i++) { - if (i > 0) { - str.append(", "); - } - // append the next (x, y) point - str.append('('); - str.append(xpoints[i]); - str.append(", "); - str.append(ypoints[i]); - str.append(')'); - } - str.append(']'); - return str.toString(); - } - } diff --git a/ch16/Sprite.java b/ch17/Sprite.java similarity index 100% rename from ch16/Sprite.java rename to ch17/Sprite.java index 515408a..92d013e 100644 --- a/ch16/Sprite.java +++ b/ch17/Sprite.java @@ -11,11 +11,11 @@ */ public class Sprite implements Actor, KeyListener { - private Image image; private int xpos; private int ypos; private int dx; private int dy; + private Image image; /** * Reads a sprite from a png file. @@ -45,11 +45,6 @@ public void step() { ypos += dy; } - @Override - public void keyTyped(KeyEvent e) { - // do nothing - } - @Override public void keyPressed(KeyEvent e) { switch (e.getKeyCode()) { @@ -82,4 +77,9 @@ public void keyReleased(KeyEvent e) { } } + @Override + public void keyTyped(KeyEvent e) { + // do nothing + } + } diff --git a/ch16/VideoGame.java b/ch17/VideoGame.java similarity index 91% rename from ch16/VideoGame.java rename to ch17/VideoGame.java index 3f54c3c..cf06193 100644 --- a/ch16/VideoGame.java +++ b/ch17/VideoGame.java @@ -16,11 +16,12 @@ public class VideoGame implements ActionListener { * Set up the drawing and window frame. */ public VideoGame() { - Sprite sprite = new Sprite("face-smile.png", 50, 50); + 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); @@ -42,7 +43,7 @@ public void actionPerformed(ActionEvent e) { */ public static void main(String[] args) { VideoGame game = new VideoGame(); - Timer timer = new Timer(25, game); + Timer timer = new Timer(33, game); timer.start(); } diff --git a/ch16/face-smile.png b/ch17/face-smile.png similarity index 100% rename from ch16/face-smile.png rename to ch17/face-smile.png diff --git a/ch16/face-smile.svg b/ch17/face-smile.svg similarity index 100% rename from ch16/face-smile.svg rename to ch17/face-smile.svg diff --git a/ch16/face-smile.txt b/ch17/face-smile.txt similarity index 100% rename from ch16/face-smile.txt rename to ch17/face-smile.txt diff --git a/misc/.checkstyle b/misc/.checkstyle deleted file mode 100644 index 744b9f9..0000000 --- a/misc/.checkstyle +++ /dev/null @@ -1,8 +0,0 @@ - - - - - - - - diff --git a/misc/.classpath b/misc/.classpath deleted file mode 100644 index 83091d5..0000000 --- a/misc/.classpath +++ /dev/null @@ -1,7 +0,0 @@ - - - - - - - diff --git a/misc/.project b/misc/.project deleted file mode 100644 index 4ed6818..0000000 --- a/misc/.project +++ /dev/null @@ -1,23 +0,0 @@ - - - misc - - - - - - org.eclipse.jdt.core.javabuilder - - - - - net.sf.eclipsecs.core.CheckstyleBuilder - - - - - - org.eclipse.jdt.core.javanature - net.sf.eclipsecs.core.CheckstyleNature - - diff --git a/misc/Point.java b/misc/Point.java deleted file mode 100644 index 5447d0c..0000000 --- a/misc/Point.java +++ /dev/null @@ -1,69 +0,0 @@ -/** - * An immutable point in two-dimensional space. - */ -public class Point { - - public static final double DELTA = 0.001; - - private final double x; - private final double y; - - /** - * Constructs a point at the given location. - * - * @param x the X coordinate - * @param y the Y coordinate - */ - public Point(double x, double y) { - this.x = x; - this.y = y; - } - - /** - * @return the X coordinate - */ - public double getX() { - return x; - } - - /** - * @return the Y coordinate - */ - public double getY() { - return y; - } - - /** - * Computes the distance between two points. - * - * @param pt the other point - * @return Euclidean distance - */ - public double distance(Point pt) { - double dx = this.x - pt.x; - double dy = this.y - pt.y; - return Math.sqrt(dx * dx + dy * dy); - } - - /** - * Determines whether or not two points are equal. - * - * @param obj the other point - * @return true if this equals obj - */ - public boolean equals(Object obj) { - if (obj instanceof Point) { - Point pt = (Point) obj; - return distance(pt) < DELTA; - } - return super.equals(obj); - } - - /** - * @return string representation of the point - */ - public String toString() { - return String.format("(%.1f, %.1f)", this.x, this.y); - } - -} diff --git a/misc/PointTest.java b/misc/PointTest.java deleted file mode 100644 index fd683dc..0000000 --- a/misc/PointTest.java +++ /dev/null @@ -1,45 +0,0 @@ -import static org.junit.Assert.*; -import org.junit.Test; - -/** - * Tests the Point class. - */ -public class PointTest { - - /** - * Tests the distance method. - */ - @Test - public void testDistance() { - Point p1 = new Point(0, 0); - Point p2 = new Point(3, 4); - assertEquals(0.0, p1.distance(p1), Point.DELTA); - assertEquals(5.0, p1.distance(p2), Point.DELTA); - } - - /** - * Tests the equals method. - */ - @Test - public void testEquals() { - Point p1 = new Point(0, 0); - Point p2 = new Point(0, 0); - Point p3 = new Point(3, 4); - Point p4 = new Point(3, 5); - assertTrue(p1.equals(p2)); - assertFalse(p2.equals(p3)); - assertFalse(p3.equals(p4)); - } - - /** - * Tests the toString method. - */ - @Test - public void testToString() { - Point p1 = new Point(0, 0); - Point p2 = new Point(3, 4); - assertEquals("(0.0, 0.0)", p1.toString()); - assertEquals("(3.0, 4.0)", p2.toString()); - } - -} diff --git a/misc/Pose.java b/misc/Pose.java deleted file mode 100644 index 03fdee4..0000000 --- a/misc/Pose.java +++ /dev/null @@ -1,34 +0,0 @@ -/** - * A point with an associated heading (in degrees). - */ -public class Pose extends Point { - - private final double heading; - - /** - * Constructs a pose at the given location. - * - * @param x the X coordinate - * @param y the Y coordinate - * @param heading the heading - */ - public Pose(double x, double y, double heading) { - super(x, y); - this.heading = heading; - } - - /** - * @return heading the heading - */ - public double getHeading() { - return heading; - } - - /** - * @return string representation of the pose - */ - public String toString() { - return String.format("%s @%.1f", super.toString(), this.heading); - } - -} diff --git a/misc/PoseTest.java b/misc/PoseTest.java deleted file mode 100644 index 00c1b0f..0000000 --- a/misc/PoseTest.java +++ /dev/null @@ -1,34 +0,0 @@ -import static org.junit.Assert.*; -import org.junit.Test; - -/** - * Tests the Pose class. - */ -public class PoseTest { - - /** - * Tests the equals method. - */ - @Test - public void testEquals() { - Pose p1 = new Pose(1, 3, 0); - Pose p2 = new Pose(1, 3, 45); - Pose p3 = new Pose(5, 7, 45); - Point p4 = new Point(5, 7); - assertTrue(p1.equals(p2)); - assertFalse(p2.equals(p3)); - assertTrue(p3.equals(p4)); - } - - /** - * Tests the toString method. - */ - @Test - public void testToString() { - Pose p1 = new Pose(1, 3, 45); - Pose p2 = new Pose(5, 7, 90); - assertEquals("(1.0, 3.0) @45.0", p1.toString()); - assertEquals("(5.0, 7.0) @90.0", p2.toString()); - } - -} diff --git a/misc/Triangle.java b/misc/Triangle.java deleted file mode 100644 index 1b89467..0000000 --- a/misc/Triangle.java +++ /dev/null @@ -1,53 +0,0 @@ -import java.awt.Polygon; - -/** - * A three-sided polygon. - */ -public class Triangle extends Polygon { - - /** - * Constructs a triangle at the given points. - * - * @param ax 1st x-coordinate - * @param ay 1st y-coordinate - * @param bx 2nd x-coordinate - * @param by 2nd y-coordinate - * @param cx 3rd x-coordinate - * @param cy 3rd y-coordinate - */ - public Triangle(int ax, int ay, int bx, int by, int cx, int cy) { - - // check for invalid triangle - int lhs = (cy - by) * (bx - ax); - int rhs = (by - ay) * (cx - bx); - if (lhs == rhs) { - throw new IllegalArgumentException("points are collinear"); - } - - // store points of polygon - xpoints = new int[] {ax, bx, cx}; - ypoints = new int[] {ay, by, cy}; - npoints = 3; - } - - /** - * @return string representation of the triangle - */ - public String toString() { - StringBuilder str = new StringBuilder(); - str.append("Triangle["); - for (int i = 0; i < npoints; i++) { - if (i > 0) { - str.append(", "); - } - // append the next (x, y) point - str.append('('); - str.append(xpoints[i]); - str.append(", "); - str.append(ypoints[i]); - str.append(')'); - } - str.append(']'); - return str.toString(); - } -} diff --git a/misc/TriangleTest.java b/misc/TriangleTest.java deleted file mode 100644 index ff86076..0000000 --- a/misc/TriangleTest.java +++ /dev/null @@ -1,28 +0,0 @@ -import static org.junit.Assert.*; -import org.junit.Test; - -/** - * Tests the Triangle class. - */ -public class TriangleTest { - - /** - * Tests an invalid triangle. - */ - @Test(expected = IllegalArgumentException.class) - public void testCollinear() { - // straight line along the X-axis - new Triangle(0, 0, 1, 0, 2, 0); - } - - /** - * Tests the toString method. - */ - @Test - public void testToString() { - // 3-4-5 right triangle at origin - Triangle t = new Triangle(0, 0, 0, 3, 4, 0); - assertEquals("Triangle[(0, 0), (0, 3), (4, 0)]", t.toString()); - } - -} 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