diff --git a/LICENSE b/LICENSE index 749dcd6..89ed830 100644 --- a/LICENSE +++ b/LICENSE @@ -1,6 +1,6 @@ The MIT License (MIT) -Copyright (c) 2016 Allen Downey +Copyright (c) 2016 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 2e3a6b5..0a68248 100644 --- a/README.md +++ b/README.md @@ -1,2 +1,32 @@ # ThinkJavaCode -Supporting code for Think Java by Allen Downey and Chris Mayfield. +Supporting code for *Think Java* by Allen Downey and Chris Mayfield. + +This is a Git repository that contains the code examples from the book and starter code for some exercises. + +Git is a version control system that allows you to keep track of the files that make up a project. +A collection of files under Git's control is called a repository. + +There are several ways you can work with the code: +* You can edit and run the code on [Codiva online java IDE](https://www.codiva.io/tutorials/thinkjavacode). + +* You can create a copy of this repository on GitHub by pressing the "Fork" button in the upper right. +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. + +* Alternatively, you could clone the 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 back in 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/ThinkJavaCodeZip). + +To clone a repository, you need a Git client installed on your computer. +The URL of this repository is `https://github.com/AllenDowney/ThinkJavaCode.git`. +If you use Git from the command line, you can clone it like this: + + git clone https://github.com/AllenDowney/ThinkJavaCode.git + +After you clone the repository or unzip the zip file, you should have a directory called `ThinkJavaCode` 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. diff --git a/ap01/Series.java b/ap01/Series.java new file mode 100644 index 0000000..2d2d66c --- /dev/null +++ b/ap01/Series.java @@ -0,0 +1,25 @@ +/** + * Example method from Chapter 6. + */ +public class Series { + + public static int fibonacci(int n) { + if (n == 1 || n == 2) { + return 1; + } + return fibonacci(n - 1) + fibonacci(n - 2); + } + + public static void main(String[] args) { + if (fibonacci(1) != 1) { + System.err.println("fibonacci(1) is incorrect"); + } + if (fibonacci(2) != 1) { + System.err.println("fibonacci(2) is incorrect"); + } + if (fibonacci(3) != 2) { + System.err.println("fibonacci(3) is incorrect"); + } + } + +} diff --git a/ap01/SeriesTest.java b/ap01/SeriesTest.java new file mode 100644 index 0000000..6309616 --- /dev/null +++ b/ap01/SeriesTest.java @@ -0,0 +1,14 @@ +import junit.framework.TestCase; + +/** + * Example JUnit test from Appendix A. + */ +public class SeriesTest extends TestCase { + + public void testFibonacci() { + assertEquals(1, Series.fibonacci(1)); + assertEquals(1, Series.fibonacci(2)); + assertEquals(2, Series.fibonacci(3)); + } + +} diff --git a/ap02/Drawing.java b/ap02/Drawing.java new file mode 100644 index 0000000..e82bfca --- /dev/null +++ b/ap02/Drawing.java @@ -0,0 +1,20 @@ +import java.awt.Canvas; +import java.awt.Graphics; +import javax.swing.JFrame; + +public class Drawing extends Canvas { + + public static void main(String[] args) { + JFrame frame = new JFrame("My Drawing"); + Canvas drawing = new Drawing(); + drawing.setSize(400, 400); + frame.add(drawing); + frame.pack(); + frame.setVisible(true); + } + + public void paint(Graphics g) { + g.fillOval(100, 100, 200, 200); + } + +} diff --git a/ap02/Mickey.java b/ap02/Mickey.java new file mode 100644 index 0000000..6dfa3bc --- /dev/null +++ b/ap02/Mickey.java @@ -0,0 +1,42 @@ +import java.awt.Canvas; +import java.awt.Color; +import java.awt.Graphics; +import java.awt.Rectangle; +import javax.swing.JFrame; + +public class Mickey extends Canvas { + + public static void main(String[] args) { + JFrame frame = new JFrame("Mickey Mouse"); + Canvas canvas = new Mickey(); + canvas.setSize(400, 400); + canvas.setBackground(Color.white); + frame.add(canvas); + frame.pack(); + frame.setVisible(true); + } + + public void paint(Graphics g) { + Rectangle bb = new Rectangle(100, 100, 200, 200); + mickey(g, bb); + } + + public void boxOval(Graphics g, Rectangle bb) { + g.fillOval(bb.x, bb.y, bb.width, bb.height); + } + + 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); + + half.translate(-dx / 2, -dy / 2); + boxOval(g, half); + + half.translate(dx * 2, 0); + boxOval(g, half); + } + +} diff --git a/ap02/Moire.java b/ap02/Moire.java new file mode 100644 index 0000000..8e7247f --- /dev/null +++ b/ap02/Moire.java @@ -0,0 +1,26 @@ +import java.awt.Canvas; +import java.awt.Color; +import java.awt.Graphics; +import javax.swing.JFrame; + +public class Moire extends Canvas { + + public static void main(String[] args) { + JFrame frame = new JFrame("Moire Pattern"); + Canvas canvas = new Moire(); + canvas.setSize(400, 400); + canvas.setBackground(Color.white); + frame.add(canvas); + frame.pack(); + frame.setVisible(true); + } + + public void paint(Graphics g) { + int i = 90; + while (i < getWidth()) { + g.drawOval(0, 0, i, i); + i = i + 3; + } + } + +} diff --git a/ch01/Goodbye.java b/ch01/Goodbye.java new file mode 100644 index 0000000..2963e2e --- /dev/null +++ b/ch01/Goodbye.java @@ -0,0 +1,14 @@ +/** + * Example program that demonstrates print vs println. + */ +public class Goodbye { + + /** + * Prints a greeting. + */ + public static void main(String[] args) { + System.out.print("Goodbye, "); // note the space + System.out.println("cruel world"); + } + +} diff --git a/ch01/Hello.java b/ch01/Hello.java new file mode 100644 index 0000000..593557b --- /dev/null +++ b/ch01/Hello.java @@ -0,0 +1,8 @@ +public class Hello { + + public static void main(String[] args) { + // generate some simple output + System.out.println("Hello, World!"); + } + +} diff --git a/ch02/Variables.java b/ch02/Variables.java new file mode 100644 index 0000000..a295abf --- /dev/null +++ b/ch02/Variables.java @@ -0,0 +1,83 @@ +/** + * Examples from Chapter 2. + */ +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 + + System.out.println(17 * 3); + System.out.println(hour * 60 + minute); + + int percentage; + percentage = (minute * 100) / 60; + + hour = minute + 1; // correct + // minute + 1 = hour; // compiler error + } + +} diff --git a/ch03/Convert.java b/ch03/Convert.java new file mode 100644 index 0000000..d31fe77 --- /dev/null +++ b/ch03/Convert.java @@ -0,0 +1,27 @@ +import java.util.Scanner; + +/** + * Converts centimeters to feet and inches. + */ +public class Convert { + + public static void main(String[] args) { + double cm; + int feet, inches, remainder; + final double CM_PER_INCH = 2.54; + final int IN_PER_FOOT = 12; + Scanner in = new Scanner(System.in); + + // prompt the user and get the value + System.out.print("Exactly how many cm? "); + cm = in.nextDouble(); + + // convert and output the result + inches = (int) (cm / CM_PER_INCH); + feet = inches / IN_PER_FOOT; + remainder = inches % IN_PER_FOOT; + System.out.printf("%.2f cm = %d ft, %d in\n", + cm, feet, remainder); + } + +} diff --git a/ch03/Echo.java b/ch03/Echo.java new file mode 100644 index 0000000..500fd9f --- /dev/null +++ b/ch03/Echo.java @@ -0,0 +1,18 @@ +import java.util.Scanner; + +public class Echo { + + public static void main(String[] args) { + String line; + Scanner in = new Scanner(System.in); + + System.out.print("Type something: "); + line = in.nextLine(); + System.out.println("You said: " + line); + + System.out.print("Type something else: "); + line = in.nextLine(); + System.out.println("You also said: " + line); + } + +} diff --git a/ch03/GuessStarter.java b/ch03/GuessStarter.java new file mode 100644 index 0000000..64984df --- /dev/null +++ b/ch03/GuessStarter.java @@ -0,0 +1,15 @@ +import java.util.Random; + +/** + * Starter code for the "Guess My Number" exercise. + */ +public class GuessStarter { + + public static void main(String[] args) { + // pick a random number + Random random = new Random(); + int number = random.nextInt(100) + 1; + System.out.println(number); + } + +} diff --git a/ch03/Input.java b/ch03/Input.java new file mode 100644 index 0000000..de97dc0 --- /dev/null +++ b/ch03/Input.java @@ -0,0 +1,16 @@ +/** + * 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/ScannerBug.java b/ch03/ScannerBug.java new file mode 100644 index 0000000..353affb --- /dev/null +++ b/ch03/ScannerBug.java @@ -0,0 +1,26 @@ +import java.util.Scanner; + +/** + * Demonstrates a common problem using Scanner. + */ +public class ScannerBug { + + public static void main(String[] args) { + String name; + int age; + Scanner in = new Scanner(System.in); + + System.out.print("What is your name? "); + name = in.nextLine(); + System.out.print("What is your age? "); + age = in.nextInt(); + System.out.printf("Hello %s, age %d\n", name, age); + + System.out.print("What is your age? "); + age = in.nextInt(); + System.out.print("What is your name? "); + name = in.nextLine(); + System.out.printf("Hello %s, age %d\n", name, age); + } + +} diff --git a/ch04/Exercise.java b/ch04/Exercise.java new file mode 100644 index 0000000..ba8c2a9 --- /dev/null +++ b/ch04/Exercise.java @@ -0,0 +1,25 @@ +public class Exercise { + + public static void zoop() { + baffle(); + System.out.print("You wugga "); + baffle(); + } + + public static void main(String[] args) { + System.out.print("No, I "); + zoop(); + System.out.print("I "); + baffle(); + } + + public static void baffle() { + System.out.print("wug"); + ping(); + } + + public static void ping() { + System.out.println("."); + } + +} diff --git a/ch04/Methods.java b/ch04/Methods.java new file mode 100644 index 0000000..90c1b7a --- /dev/null +++ b/ch04/Methods.java @@ -0,0 +1,22 @@ +/** + * Examples from Chapter 4. + */ +public class Methods { + + public static void main(String[] args) { + double root = Math.sqrt(17.0); + double angle = 1.5; + double height = Math.sin(angle); + + 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); + + 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/NewLine.java b/ch04/NewLine.java new file mode 100644 index 0000000..a554e40 --- /dev/null +++ b/ch04/NewLine.java @@ -0,0 +1,19 @@ +public class NewLine { + + public static void newLine() { + System.out.println(); + } + + public static void threeLine() { + newLine(); + newLine(); + newLine(); + } + + public static void main(String[] args) { + System.out.println("First line."); + threeLine(); + System.out.println("Second line."); + } + +} diff --git a/ch04/PrintTime.java b/ch04/PrintTime.java new file mode 100644 index 0000000..019d579 --- /dev/null +++ b/ch04/PrintTime.java @@ -0,0 +1,15 @@ +public class PrintTime { + + public static void printTime(int hour, int minute) { + System.out.print(hour); + System.out.print(":"); + System.out.println(minute); + } + + public static void main(String[] args) { + int hour = 11; + int minute = 59; + printTime(hour, minute); + } + +} diff --git a/ch04/PrintTwice.java b/ch04/PrintTwice.java new file mode 100644 index 0000000..7131085 --- /dev/null +++ b/ch04/PrintTwice.java @@ -0,0 +1,12 @@ +public class PrintTwice { + + public static void printTwice(String s) { + System.out.println(s); + System.out.println(s); + } + + public static void main(String[] args) { + printTwice("Don't make me say this twice!"); + } + +} diff --git a/ch05/Buzz.java b/ch05/Buzz.java new file mode 100644 index 0000000..95e1c2a --- /dev/null +++ b/ch05/Buzz.java @@ -0,0 +1,22 @@ +public class Buzz { + + public static void baffle(String blimp) { + System.out.println(blimp); + zippo("ping", -5); + } + + public static void zippo(String quince, int flag) { + if (flag < 0) { + System.out.println(quince + " zoop"); + } else { + System.out.println("ik"); + baffle(quince); + System.out.println("boo-wa-ha-ha"); + } + } + + public static void main(String[] args) { + zippo("rattle", 13); + } + +} diff --git a/ch05/Conditional.java b/ch05/Conditional.java new file mode 100644 index 0000000..f2d6d19 --- /dev/null +++ b/ch05/Conditional.java @@ -0,0 +1,54 @@ +/** + * Examples from Chapter 5. + */ +public class Conditional { + + public static void main(String[] args) { + String fruit1 = "Apple"; + String fruit2 = "Orange"; + System.out.println(fruit1.equals(fruit2)); + + 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 zero"); + } else { + if (x > 0) { + System.out.println("x is positive"); + } else { + System.out.println("x is negative"); + } + } + + 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/Exercise.java b/ch05/Exercise.java new file mode 100644 index 0000000..dbbb6e9 --- /dev/null +++ b/ch05/Exercise.java @@ -0,0 +1,28 @@ +public class Exercise { + + public static void zoop(String fred, int bob) { + System.out.println(fred); + if (bob == 5) { + ping("not "); + } else { + System.out.println("!"); + } + } + + public static void main(String[] args) { + int bizz = 5; + int buzz = 2; + zoop("just for", bizz); + clink(2 * buzz); + } + + public static void clink(int fork) { + System.out.print("It's "); + zoop("breakfast ", fork); + } + + public static void ping(String strangStrung) { + System.out.println("any " + strangStrung + "more "); + } + +} diff --git a/ch05/Logarithm.java b/ch05/Logarithm.java new file mode 100644 index 0000000..5c5986a --- /dev/null +++ b/ch05/Logarithm.java @@ -0,0 +1,44 @@ +import java.util.Scanner; + +public class Logarithm { + + public static void main(String[] args) { + System.out.println("printLogarithm"); + printLogarithm(3.0); + + Scanner in = new Scanner(System.in); + + System.out.println("scandouble"); + scanDouble(in); + + System.out.println("scandouble2"); + scanDouble2(in); + } + + public static void printLogarithm(double x) { + if (x <= 0.0) { + System.err.println("Error: x must be positive."); + return; + } + double result = Math.log(x); + System.out.println("The log of x is " + result); + } + + public static void scanDouble(Scanner in) { + System.out.print("Enter a number: "); + double x = in.nextDouble(); + printLogarithm(x); + } + + public static void scanDouble2(Scanner in) { + System.out.print("Enter a number: "); + if (!in.hasNextDouble()) { + String word = in.next(); + System.err.println(word + " is not a number"); + return; + } + double x = in.nextDouble(); + printLogarithm(x); + } + +} diff --git a/ch05/Recursion.java b/ch05/Recursion.java new file mode 100644 index 0000000..0e772c8 --- /dev/null +++ b/ch05/Recursion.java @@ -0,0 +1,71 @@ +public class Recursion { + + public static void main(String[] args) { + System.out.println("countdown"); + countdown(3); + + System.out.println("countup"); + countup(3); + + System.out.println("newLine"); + newLine(); + + System.out.println("nLines"); + nLines(3); + + System.out.println("threeLine"); + threeLine(); + + System.out.println("displayBinary"); + displayBinary(23); + System.out.println(); + } + + public static void countdown(int n) { + if (n == 0) { + System.out.println("Blastoff!"); + } else { + System.out.println(n); + countdown(n - 1); + } + } + + public static void newLine() { + System.out.println(); + } + + public static void threeLine() { + newLine(); + newLine(); + newLine(); + } + + public static void nLines(int n) { + if (n > 0) { + System.out.println(); + nLines(n - 1); + } + } + + public static void forever(String s) { + System.out.println(s); + forever(s); + } + + public static void countup(int n) { + if (n == 0) { + System.out.println("Blastoff!"); + } else { + countup(n - 1); + System.out.println(n); + } + } + + public static void displayBinary(int value) { + if (value > 0) { + displayBinary(value / 2); + System.out.print(value % 2); + } + } + +} diff --git a/ch06/Exercise.java b/ch06/Exercise.java new file mode 100644 index 0000000..b826b44 --- /dev/null +++ b/ch06/Exercise.java @@ -0,0 +1,36 @@ +public class Exercise { + + public static void main(String[] args) { + boolean flag1 = isHoopy(202); + boolean flag2 = isFrabjuous(202); + System.out.println(flag1); + System.out.println(flag2); + if (flag1 && flag2) { + System.out.println("ping!"); + } + if (flag1 || flag2) { + System.out.println("pong!"); + } + } + + public static boolean isHoopy(int x) { + boolean hoopyFlag; + if (x % 2 == 0) { + hoopyFlag = true; + } else { + hoopyFlag = false; + } + return hoopyFlag; + } + + public static boolean isFrabjuous(int x) { + boolean frabjuousFlag; + if (x > 0) { + frabjuousFlag = true; + } else { + frabjuousFlag = false; + } + return frabjuousFlag; + } + +} diff --git a/ch06/Recursive.java b/ch06/Recursive.java new file mode 100644 index 0000000..f045844 --- /dev/null +++ b/ch06/Recursive.java @@ -0,0 +1,17 @@ +public class Recursive { + + public static void main(String[] args) { + System.out.println(prod(1, 4)); + } + + public static int prod(int m, int n) { + if (m == n) { + return n; + } else { + int recurse = prod(m, n - 1); + int result = n * recurse; + return result; + } + } + +} diff --git a/ch06/Series.java b/ch06/Series.java new file mode 100644 index 0000000..10d2b41 --- /dev/null +++ b/ch06/Series.java @@ -0,0 +1,150 @@ +/** + * Examples from Chapter 6. + */ +public class Series { + + public static void countup(int n) { + if (n == 0) { + System.out.println("Blastoff!"); + } else { + countup(n - 1); + System.out.println(n); + } + } + + 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 absoluteValue(double x) { + if (x < 0) { + return -x; + } else { + return x; + } + } + + 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)); + } + + /** + * Tests whether x is a single digit integer. + * + * @param x the integer to test + * @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 int factorial(int n) { + if (n == 0) { + return 1; + } + int recurse = factorial(n - 1); + int result = n * recurse; + return result; + } + + public static int fibonacci(int n) { + if (n == 1 || n == 2) { + return 1; + } + return fibonacci(n - 1) + fibonacci(n - 2); + } + + public static void main(String[] args) { + countup(3); + System.out.println("Have a nice day."); + + System.out.println("calculateArea"); + System.out.println(calculateArea(3.0)); + + System.out.println("calculateArea2"); + System.out.println(calculateArea2(3.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)); + + System.out.println("absolute value"); + System.out.println(absoluteValue(-2)); + + 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(isSingleDigit(2)); + boolean bigFlag = !isSingleDigit2(17); + + int z = 9; + if (isSingleDigit(z)) { + System.out.println("z is small"); + } else { + System.out.println("z is big"); + } + + System.out.println("factorial"); + System.out.println(factorial(3)); + + System.out.println("fibonacci"); + System.out.println(fibonacci(3)); + } + +} diff --git a/ch07/Exercise.java b/ch07/Exercise.java new file mode 100644 index 0000000..6c7b3df --- /dev/null +++ b/ch07/Exercise.java @@ -0,0 +1,19 @@ +public class Exercise { + + public static void main(String[] args) { + loop(10); + } + + public static void loop(int n) { + int i = n; + while (i > 1) { + System.out.println(i); + if (i % 2 == 0) { + i = i / 2; + } else { + i = i + 1; + } + } + } + +} diff --git a/ch07/Loops.java b/ch07/Loops.java new file mode 100644 index 0000000..dfc03ce --- /dev/null +++ b/ch07/Loops.java @@ -0,0 +1,33 @@ +/** + * Examples from Chapter 7. + */ +public class Loops { + + public static void countdown(int n) { + while (n > 0) { + System.out.println(n); + n = n - 1; + } + System.out.println("Blastoff!"); + } + + public static void sequence(int n) { + while (n != 1) { + System.out.println(n); + if (n % 2 == 0) { // n is even + n = n / 2; + } else { // n is odd + n = n * 3 + 1; + } + } + } + + public static void main(String[] args) { + System.out.println("countdown"); + countdown(3); + + System.out.println("sequence"); + sequence(10); + } + +} diff --git a/ch07/Tables.java b/ch07/Tables.java new file mode 100644 index 0000000..3e33905 --- /dev/null +++ b/ch07/Tables.java @@ -0,0 +1,157 @@ +/** + * Generating tables; encapsulation and generalization. + */ +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 example4() { + int i = 1; + while (i <= 6) { + System.out.printf("%4d", 2 * i); + i = i + 1; + } + System.out.println(); + } + + public static void printRow() { + int i = 1; + while (i <= 6) { + System.out.printf("%4d", 2 * i); + i = i + 1; + } + System.out.println(); + } + + public static void printRow2(int n) { + int i = 1; + while (i <= 6) { + System.out.printf("%4d", n * i); + i = i + 1; + } + System.out.println(); + } + + public static void example5() { + int i = 1; + while (i <= 6) { + printRow2(i); + i = i + 1; + } + } + + public static void printTable() { + int i = 1; + while (i <= 6) { + printRow2(i); + i = i + 1; + } + } + + public static void printTable2(int rows) { + int i = 1; + while (i <= rows) { + printRow2(i); + i = i + 1; + } + } + + public static void printRow3(int n, int cols) { + int i = 1; + while (i <= cols) { + System.out.printf("%4d", n * i); + i = i + 1; + } + System.out.println(); + } + + public static void printTable3(int rows) { + int i = 1; + while (i <= rows) { + printRow3(i, rows); + i = i + 1; + } + } + + public static void printTable4(int rows) { + for (int i = 1; i <= rows; i = i + 1) { + printRow3(i, rows); + } + } + + public static void printRow4(int n, int cols) { + int i; + for (i = 1; i <= cols; i = i + 1) { + System.out.printf("%4d", n * i); + } + System.out.println(i); + } + + public static void main(String[] args) { + System.out.println("example"); + example(); + + System.out.println("example2"); + example2(); + + System.out.println("example3"); + example3(); + + System.out.println("example4"); + example4(); + + System.out.println("example5"); + example5(); + + System.out.println("printRow"); + printRow(); + + System.out.println("printRow2"); + printRow2(6); + + System.out.println("printTable"); + printTable(); + + System.out.println("printTable2"); + printTable2(6); + + System.out.println("printRow3"); + printRow3(6, 6); + + System.out.println("printTable3"); + printTable3(6); + + System.out.println("printRow4"); + printRow4(6, 6); + + System.out.println("printTable4"); + printTable4(6); + } + +} diff --git a/ch07/Validate.java b/ch07/Validate.java new file mode 100644 index 0000000..e825705 --- /dev/null +++ b/ch07/Validate.java @@ -0,0 +1,54 @@ +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/ch08/ArrayExamples.java b/ch08/ArrayExamples.java new file mode 100644 index 0000000..a4cb6c3 --- /dev/null +++ b/ch08/ArrayExamples.java @@ -0,0 +1,100 @@ +import java.util.Arrays; + +/** + * Demonstrates uses of arrays. + */ +public class ArrayExamples { + + /** + * Example code from Chapter 8. + */ + public static void main(String[] args) { + int size = 10; + int[] counts = new int[4]; + double[] values = new double[size]; + + counts[0] = 7; + counts[1] = counts[0] * 2; + counts[2]++; + counts[3] -= 60; + + // traversal with a while loop + int j = 0; + while (j < 4) { + System.out.println(counts[j]); + j++; + } + + // traversal with a for loop + for (int i = 0; i < 4; i++) { + System.out.println(counts[i]); + } + + int[] array = {1, 2, 3, 4}; + printArray(array); + + // printing an array as an object + System.out.println(array); + + // printing with Arrays class + System.out.println(Arrays.toString(array)); + + // copying an array + double[] a = {1.0, 2.0, 3.0}; + double[] b = new double[a.length]; + for (int i = 0; i < a.length; i++) { + b[i] = a[i]; + } + + // copying with Arrays class + double[] c = Arrays.copyOf(a, a.length); + + // traversal + for (int i = 0; i < a.length; i++) { + a[i] = Math.pow(a[i], 2.0); + } + + // search + int index = search(a, 2.0); + System.out.println("index = " + index); + + // reduce + double total = sum(a); + System.out.println("total = " + total); + } + + /** + * 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]); + } + System.out.println("}"); + } + + /** + * 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) { + return i; + } + } + return -1; + } + + /** + * Returns the total of the elements in an array. + */ + public static double sum(double[] a) { + double total = 0.0; + for (int i = 0; i < a.length; i++) { + total += a[i]; + } + return total; + } + +} diff --git a/ch08/Fruit.java b/ch08/Fruit.java new file mode 100644 index 0000000..50428c5 --- /dev/null +++ b/ch08/Fruit.java @@ -0,0 +1,35 @@ +/** + * Fruit exercise. + */ +public class Fruit { + + public static int banana(int[] a) { + int kiwi = 1; + int i = 0; + while (i < a.length) { + kiwi = kiwi * a[i]; + i++; + } + return kiwi; + } + + public static int grapefruit(int[] a, int grape) { + for (int i = 0; i < a.length; i++) { + if (a[i] == grape) { + return i; + } + } + return -1; + } + + public static int pineapple(int[] a, int apple) { + int pear = 0; + for (int pine: a) { + if (pine == apple) { + pear++; + } + } + return pear; + } + +} diff --git a/ch08/Histogram.java b/ch08/Histogram.java new file mode 100644 index 0000000..32b029c --- /dev/null +++ b/ch08/Histogram.java @@ -0,0 +1,59 @@ +import java.util.Random; + +/** + * Example code related to histograms. + */ +public class Histogram { + + /** + * Returns an array of random integers. + */ + public static int[] randomArray(int size) { + Random random = new Random(); + int[] a = new int[size]; + for (int i = 0; i < a.length; i++) { + a[i] = random.nextInt(100); + } + return a; + } + + /** + * Computes the number of array elements in [low, high). + */ + public static int inRange(int[] a, int low, int high) { + int count = 0; + for (int i = 0; i < a.length; i++) { + if (a[i] >= low && a[i] < high) { + count++; + } + } + return count; + } + + public static void main(String[] args) { + int numValues = 8; + int[] array = randomArray(numValues); + ArrayExamples.printArray(array); + + int[] scores = randomArray(30); + int a = inRange(scores, 90, 100); + int b = inRange(scores, 80, 90); + int c = inRange(scores, 70, 80); + int d = inRange(scores, 60, 70); + int f = inRange(scores, 0, 60); + + // making a histogram + int[] counts = new int[100]; + for (int i = 0; i < scores.length; i++) { + int index = scores[i]; + counts[index]++; + } + + // histogram with enhanced for loop + counts = new int[100]; + for (int score : scores) { + counts[score]++; + } + } + +} diff --git a/ch08/MakeDubMus.java b/ch08/MakeDubMus.java new file mode 100644 index 0000000..9c7e193 --- /dev/null +++ b/ch08/MakeDubMus.java @@ -0,0 +1,34 @@ +/** + * Stack diagram exercise. + */ +public class MakeDubMus { + + public static int[] make(int n) { + int[] a = new int[n]; + for (int i = 0; i < n; i++) { + a[i] = i + 1; + } + return a; + } + + public static void dub(int[] jub) { + for (int i = 0; i < jub.length; i++) { + jub[i] *= 2; + } + } + + public static int mus(int[] zoo) { + int fus = 0; + for (int i = 0; i < zoo.length; i++) { + fus += zoo[i]; + } + return fus; + } + + public static void main(String[] args) { + int[] bob = make(5); + dub(bob); + System.out.println(mus(bob)); + } + +} diff --git a/ch09/Exercise.java b/ch09/Exercise.java new file mode 100644 index 0000000..d8a605d --- /dev/null +++ b/ch09/Exercise.java @@ -0,0 +1,22 @@ +/** + * Exercise on encapsulation and generalization. + */ +public class Exercise { + + public static void main(String[] args) { + String s = "((3 + 7) * 2)"; + int count = 0; + + for (int i = 0; i < s.length(); i++) { + char c = s.charAt(i); + if (c == '(') { + count++; + } else if (c == ')') { + count--; + } + } + + System.out.println(count); + } + +} diff --git a/ch09/Format.java b/ch09/Format.java new file mode 100644 index 0000000..7e3ff8a --- /dev/null +++ b/ch09/Format.java @@ -0,0 +1,33 @@ +/** + * Example using the String.format method. + */ +public class Format { + + /** + * Returns a time string in 12-hour format. + * + * @param hour between 0 and 23 + * @param minute between 0 and 59 + */ + public static String timeString(int hour, int minute) { + String ampm; + if (hour < 12) { + ampm = "AM"; + if (hour == 0) { + hour = 12; // midnight + } + } else { + ampm = "PM"; + hour = hour - 12; + } + return String.format("%02d:%02d %s", hour, minute, ampm); + } + + public static void main(String[] args) { + System.out.println(timeString(0, 0)); + System.out.println(timeString(7, 30)); + System.out.println(timeString(12, 5)); + System.out.println(timeString(23, 59)); + } + +} diff --git a/ch09/Max.java b/ch09/Max.java new file mode 100644 index 0000000..2bf923e --- /dev/null +++ b/ch09/Max.java @@ -0,0 +1,24 @@ +import java.util.Arrays; + +/** + * Demonstrates command-line arguments. + */ +public class Max { + + /** + * Converts args to integers and prints the max. + */ + public static void main(String[] args) { + System.out.println(Arrays.toString(args)); + + int max = Integer.MIN_VALUE; + for (String arg : args) { + int value = Integer.parseInt(arg); + if (value > max) { + max = value; + } + } + System.out.println("The max is " + max); + } + +} diff --git a/ch09/Recurse.java b/ch09/Recurse.java new file mode 100644 index 0000000..c4ba2fb --- /dev/null +++ b/ch09/Recurse.java @@ -0,0 +1,34 @@ +/** + * Recursion exercise. + */ +public class Recurse { + + /** + * Returns the first character of the given String. + */ + public static char first(String s) { + return s.charAt(0); + } + + /** + * Returns all but the first letter of the given String. + */ + public static String rest(String s) { + return s.substring(1); + } + + /** + * Returns all but the first and last letter of the String. + */ + public static String middle(String s) { + return s.substring(1, s.length() - 1); + } + + /** + * Returns the length of the given String. + */ + public static int length(String s) { + return s.length(); + } + +} diff --git a/ch09/StringsThings.java b/ch09/StringsThings.java new file mode 100644 index 0000000..8b95e7e --- /dev/null +++ b/ch09/StringsThings.java @@ -0,0 +1,105 @@ +/** + * Demonstates uses of Strings. + */ +public class StringsThings { + + public static void main(String[] args) { + + // Characters + + String fruit = "banana"; + char letter0 = fruit.charAt(0); + + if (letter0 == 'a') { + System.out.println('?'); + } + + System.out.print("Roman alphabet: "); + for (char c = 'A'; c <= 'Z'; c++) { + System.out.print(c); + } + System.out.println(); + + System.out.print("Greek alphabet: "); + for (int i = 913; i <= 937; i++) { + System.out.print((char) i); + } + System.out.println(); + + // Strings are immutable + + String name = "Alan Turing"; + String upperName = name.toUpperCase(); + + String text = "Computer Science is fun!"; + text = text.replace("Computer Science", "CS"); + + // String traversal + + for (int i = 0; i < fruit.length(); i++) { + char letter = fruit.charAt(i); + System.out.println(letter); + } + + for (char letter : fruit.toCharArray()) { + System.out.println(letter); + } + + int length = fruit.length(); + char last = fruit.charAt(length - 1); // correct + + System.out.println(reverse(fruit)); + + // 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)); + + // The indexOf method + + int index = fruit.indexOf('a'); + int index2 = fruit.indexOf('a', 2); + + // String comparison + + String name1 = "Alan Turing"; + String name2 = "Ada Lovelace"; + if (name1.equals(name2)) { + System.out.println("The names are the same."); + } + + int diff = name1.compareTo(name2); + if (diff == 0) { + System.out.println("The names are the same."); + } else if (diff < 0) { + System.out.println("name1 comes before name2."); + } else if (diff > 0) { + System.out.println("name2 comes before name1."); + } + + // Wrapper classes + + String str = "12345"; + int num = Integer.parseInt(str); + + num = 12345; + str = Integer.toString(num); + } + + /** + * Reverses a string, returns a new String. + */ + public static String reverse(String s) { + String r = ""; + for (int i = s.length() - 1; i >= 0; i--) { + r = r + s.charAt(i); + } + return r; + } + +} diff --git a/ch10/PointRect.java b/ch10/PointRect.java new file mode 100644 index 0000000..36801a5 --- /dev/null +++ b/ch10/PointRect.java @@ -0,0 +1,90 @@ +import java.awt.Point; +import java.awt.Rectangle; + +/** + * Demonstates 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; + + Rectangle box = new Rectangle(0, 0, 100, 200); + moveRect(box, 50, 100); + System.out.println(box); + box.translate(50, 100); + + 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); + } + + /** + * Prints the attributes of a Point object. + */ + public static void printPoint(Point p) { + System.out.println("(" + p.x + ", " + p.y + ")"); + } + + /** + * Computes the distance between two points. + */ + public static double distance(Point p1, Point p2) { + int dx = p2.x - p1.x; + int dy = p2.y - p1.y; + return Math.sqrt(dx * dx + dy * dy); + } + + /** + * Finds the center of a Rectangle and returns a new Point. + */ + public static Point findCenter(Rectangle box) { + int x = box.x + box.width / 2; + int y = box.y + box.height / 2; + return new Point(x, y); + } + + /** + * Moves a Rectangle by modifying the x and y attributes. + */ + public static void moveRect(Rectangle box, int dx, int dy) { + box.x = box.x + dx; + box.y = box.y + dy; + } + + /** + * Exercise on returning objects. + */ + public static void exercise2() { + Point blank = new Point(5, 8); + + Rectangle rect = new Rectangle(0, 2, 4, 4); + Point center = findCenter(rect); + + double dist = distance(center, blank); + System.out.println(dist); + } + + /** + * Exercise on aliasing. + */ + public static void exercise3() { + Rectangle box1 = new Rectangle(2, 4, 7, 9); + Point p1 = findCenter(box1); + printPoint(p1); + + box1.grow(1, 1); + Point p2 = findCenter(box1); + printPoint(p2); + } + +} diff --git a/ch10/Pow.java b/ch10/Pow.java new file mode 100644 index 0000000..9ba0952 --- /dev/null +++ b/ch10/Pow.java @@ -0,0 +1,24 @@ +/** + * BigInteger exercise. + */ +public class Pow { + + /** + * Integer exponentiation. + */ + public static int pow(int x, int n) { + if (n == 0) return 1; + + // find x to the n/2 recursively + int t = pow(x, n / 2); + + // if n is even, the result is t squared + // if n is odd, the result is t squared times x + if (n % 2 == 0) { + return t * t; + } else { + return t * t * x; + } + } + +} diff --git a/ch10/Riddle.java b/ch10/Riddle.java new file mode 100644 index 0000000..cd04a16 --- /dev/null +++ b/ch10/Riddle.java @@ -0,0 +1,23 @@ +import java.awt.Point; + +/** + * Exercise on passing objects as parameters. + */ +public class Riddle { + + public static int riddle(int x, Point p) { + x = x + 7; + return x + p.x + p.y; + } + + public static void main(String[] args) { + int x = 5; + Point blank = new Point(1, 2); + + System.out.println(riddle(x, blank)); + System.out.println(x); + System.out.println(blank.x); + System.out.println(blank.y); + } + +} diff --git a/ch11/Time.java b/ch11/Time.java new file mode 100644 index 0000000..53afa0d --- /dev/null +++ b/ch11/Time.java @@ -0,0 +1,102 @@ +/** + * Represents a time of day. + */ +public class Time { + + private int hour; + private int minute; + private double second; + + /** + * Construct a Time object with default values. + */ + public Time() { + this.hour = 0; + this.minute = 0; + this.second = 0.0; + } + + /** + * Construct a Time object with given values. + */ + public Time(int hour, int minute, double second) { + this.hour = hour; + this.minute = minute; + this.second = second; + } + + /** + * Prints the time in a simple format. + */ + public static void printTime(Time t) { + System.out.print(t.hour); + System.out.print(":"); + System.out.println(t.minute); + System.out.print(":"); + System.out.println(t.second); + } + + /** + * Returns a String representation of the time. + */ + public String toString() { + return String.format("%02d:%02d:%04.1f\n", + this.hour, this.minute, this.second); + } + + /** + * Tests whether two times are equivalent. + */ + public boolean equals(Time that) { + return this.hour == that.hour + && this.minute == that.minute + && this.second == that.second; + } + + /** + * Adds two Times and returns a new Time object (static method). + */ + public static Time add(Time t1, Time t2) { + Time sum = new Time(); + sum.hour = t1.hour + t2.hour; + sum.minute = t1.minute + t2.minute; + sum.second = t1.second + t2.second; + return sum; + } + + /** + * Adds two Times and returns a new Time object (instance method). + */ + public Time add(Time t2) { + Time sum = new Time(); + 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; + } + if (sum.minute >= 60) { + 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; + } + } + +} diff --git a/ch11/TimeClient.java b/ch11/TimeClient.java new file mode 100644 index 0000000..aa90401 --- /dev/null +++ b/ch11/TimeClient.java @@ -0,0 +1,33 @@ +/** + * Class that uses Time objects. + */ +public class TimeClient { + + public static void main(String[] args) { + Time time = new Time(11, 59, 59.9); + System.out.println(time); + + // cannot access private variables from another class + // System.out.println(time.hour); + + String s = time.toString(); + System.out.println(s); + + Time time1 = new Time(9, 30, 0.0); + Time time2 = time1; + Time time3 = new Time(9, 30, 0.0); + + System.out.println(time1 == time2); + System.out.println(time1 == time3); + System.out.println(time1.equals(time2)); + System.out.println(time1.equals(time3)); + + Time startTime = new Time(18, 50, 0.0); + Time runningTime = new Time(2, 16, 0.0); + Time endTime = Time.add(startTime, runningTime); + + // using the instance method + endTime = startTime.add(runningTime); + } + +} diff --git a/ch12/Card.java b/ch12/Card.java new file mode 100644 index 0000000..e7a0661 --- /dev/null +++ b/ch12/Card.java @@ -0,0 +1,83 @@ +/** + * A standard playing card. + */ +public class Card { + + public static final String[] RANKS = { + null, "Ace", "2", "3", "4", "5", "6", "7", + "8", "9", "10", "Jack", "Queen", "King"}; + + public static final String[] SUITS = { + "Clubs", "Diamonds", "Hearts", "Spades"}; + + private final int rank; + + private final int suit; + + /** + * Constructs a card of the given rank and suit. + */ + public Card(int rank, int suit) { + this.rank = rank; + this.suit = suit; + } + + /** + * Returns a negative integer if this card comes before + * the given card, zero if the two cards are equal, or + * a positive integer if this card comes after the card. + */ + public int compareTo(Card that) { + if (this.suit < that.suit) { + return -1; + } + if (this.suit > that.suit) { + return 1; + } + if (this.rank < that.rank) { + return -1; + } + if (this.rank > that.rank) { + return 1; + } + return 0; + } + + /** + * Returns true if the given card has the same + * rank AND same suit; otherwise returns false. + */ + public boolean equals(Card that) { + return this.rank == that.rank + && this.suit == that.suit; + } + + /** + * Gets the card's rank. + */ + public int getRank() { + return this.rank; + } + + /** + * Gets the card's suit. + */ + public int getSuit() { + return this.suit; + } + + /** + * Returns the card's index in a sorted deck of 52 cards. + */ + public int position() { + return this.suit * 13 + this.rank - 1; + } + + /** + * Returns a string representation of the card. + */ + public String toString() { + return RANKS[this.rank] + " of " + SUITS[this.suit]; + } + +} diff --git a/ch12/CardTable.java b/ch12/CardTable.java new file mode 100644 index 0000000..727d307 --- /dev/null +++ b/ch12/CardTable.java @@ -0,0 +1,93 @@ +import java.awt.Canvas; +import java.awt.Color; +import java.awt.Graphics; +import java.awt.Image; + +import javax.swing.ImageIcon; +import javax.swing.JFrame; + +public class CardTable extends Canvas { + + private Image[][] images; + private int cardWidth, cardHeight; + + /** + * Creates a CardTable. + * cardset is the name of the folder that contains the card images. + */ + public CardTable(String cardset) { + setBackground(new Color(0x088A4B)); + + // create a 2-D array of card images + images = new Image[14][4]; + String suits = "cdhs"; + + for (int suit = 0; suit <= 3; suit++) { + char c = suits.charAt(suit); + + for (int rank = 1; rank <= 13; rank++) { + String s = String.format("%s/%02d%c.gif", + cardset, rank, c); + images[rank][suit] = new ImageIcon(s).getImage(); + } + } + + // get the width and height of the cards and set the size of + // the frame accordingly + cardWidth = images[1][1].getWidth(null); + cardHeight = images[1][1].getHeight(null); + + // set the size temporarily to get the insets + setTableSize(14, 4); + } + + /** + * Sets the table size. + * x and y are in units of card width/height. + */ + public void setTableSize(double x, double y) { + setSize((int) (x * cardWidth), + (int) (y * cardHeight)); + } + + /** + * Draws a card at the given coordinates. + * x and y are in units of card width/height. + */ + public void drawCard(Graphics g, int rank, int suit, double x, double y) { + Image image = images[rank][suit]; + g.drawImage(image, + (int) (x * cardWidth), + (int) (y * cardHeight), + null); + } + + /** + * Special method invoked when the Frame needs to be drawn. + */ + public void paint(Graphics g) { + for (int rank = 1; rank <= 13; rank++) { + for (int suit = 0; suit <= 3; suit++) { + double x = rank - 1 + suit / 5.0; + double y = suit / 2.0; + drawCard(g, rank, suit, x, y); + } + } + } + + public static void main(String[] args) { + // make the frame + JFrame frame = new JFrame("Card Table"); + frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); + + // add the CardTable + String cardset = "cardset-oxymoron"; + Canvas canvas = new CardTable(cardset); + frame.getContentPane().add(canvas); + + // show the frame + frame.pack(); + frame.setVisible(true); + } + +} diff --git a/ch12/Search.java b/ch12/Search.java new file mode 100644 index 0000000..2f83023 --- /dev/null +++ b/ch12/Search.java @@ -0,0 +1,112 @@ +/** + * Search algorithms for arrays of cards. + */ +public class Search { + + /** + * Make an array of 52 cards. + */ + public static Card[] makeDeck() { + Card[] cards = new Card[52]; + int index = 0; + for (int suit = 0; suit <= 3; suit++) { + for (int rank = 1; rank <= 13; rank++) { + cards[index] = new Card(rank, suit); + index++; + } + } + return cards; + } + + /** + * Displays the given deck of cards. + */ + public static void printDeck(Card[] cards) { + for (int i = 0; i < cards.length; i++) { + System.out.println(cards[i]); + } + } + + /** + * Sequential search. + */ + public static int search(Card[] cards, Card target) { + for (int i = 0; i < cards.length; i++) { + if (cards[i].equals(target)) { + return i; + } + } + return -1; + } + + /** + * Binary search (iterative version). + */ + public static int binarySearch(Card[] cards, Card target) { + int low = 0; + int high = cards.length - 1; + while (low <= high) { + System.out.println(low + ", " + high); + + 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 + low = mid + 1; + } else { // step 4 + high = mid - 1; + } + } + 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. + */ + public static void main(String[] args) { + Card[] cards = makeDeck(); + Card jack = new Card(11, 0); + Card fake = new Card(15, 1); + + System.out.println("Sequential search"); + System.out.println(search(cards, jack)); + System.out.println(); + + System.out.println("Binary search"); + System.out.println(binarySearch(cards, jack)); + System.out.println(); + + 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/ch12/cardset-oxymoron/01c.gif b/ch12/cardset-oxymoron/01c.gif new file mode 100644 index 0000000..cbc57d5 Binary files /dev/null and b/ch12/cardset-oxymoron/01c.gif differ diff --git a/ch12/cardset-oxymoron/01d.gif b/ch12/cardset-oxymoron/01d.gif new file mode 100644 index 0000000..111e36d Binary files /dev/null and b/ch12/cardset-oxymoron/01d.gif differ diff --git a/ch12/cardset-oxymoron/01h.gif b/ch12/cardset-oxymoron/01h.gif new file mode 100644 index 0000000..20810e1 Binary files /dev/null and b/ch12/cardset-oxymoron/01h.gif differ diff --git a/ch12/cardset-oxymoron/01s.gif b/ch12/cardset-oxymoron/01s.gif new file mode 100644 index 0000000..548ee0a Binary files /dev/null and b/ch12/cardset-oxymoron/01s.gif differ diff --git a/ch12/cardset-oxymoron/02c.gif b/ch12/cardset-oxymoron/02c.gif new file mode 100644 index 0000000..121edd0 Binary files /dev/null and b/ch12/cardset-oxymoron/02c.gif differ diff --git a/ch12/cardset-oxymoron/02d.gif b/ch12/cardset-oxymoron/02d.gif new file mode 100644 index 0000000..a014c91 Binary files /dev/null and b/ch12/cardset-oxymoron/02d.gif differ diff --git a/ch12/cardset-oxymoron/02h.gif b/ch12/cardset-oxymoron/02h.gif new file mode 100644 index 0000000..f7b84de Binary files /dev/null and b/ch12/cardset-oxymoron/02h.gif differ diff --git a/ch12/cardset-oxymoron/02s.gif b/ch12/cardset-oxymoron/02s.gif new file mode 100644 index 0000000..946eac0 Binary files /dev/null and b/ch12/cardset-oxymoron/02s.gif differ diff --git a/ch12/cardset-oxymoron/03c.gif b/ch12/cardset-oxymoron/03c.gif new file mode 100644 index 0000000..fdc44b2 Binary files /dev/null and b/ch12/cardset-oxymoron/03c.gif differ diff --git a/ch12/cardset-oxymoron/03d.gif b/ch12/cardset-oxymoron/03d.gif new file mode 100644 index 0000000..38b8cb5 Binary files /dev/null and b/ch12/cardset-oxymoron/03d.gif differ diff --git a/ch12/cardset-oxymoron/03h.gif b/ch12/cardset-oxymoron/03h.gif new file mode 100644 index 0000000..5a9daa2 Binary files /dev/null and b/ch12/cardset-oxymoron/03h.gif differ diff --git a/ch12/cardset-oxymoron/03s.gif b/ch12/cardset-oxymoron/03s.gif new file mode 100644 index 0000000..db0a44e Binary files /dev/null and b/ch12/cardset-oxymoron/03s.gif differ diff --git a/ch12/cardset-oxymoron/04c.gif b/ch12/cardset-oxymoron/04c.gif new file mode 100644 index 0000000..be0f1bf Binary files /dev/null and b/ch12/cardset-oxymoron/04c.gif differ diff --git a/ch12/cardset-oxymoron/04d.gif b/ch12/cardset-oxymoron/04d.gif new file mode 100644 index 0000000..f2b9a2a Binary files /dev/null and b/ch12/cardset-oxymoron/04d.gif differ diff --git a/ch12/cardset-oxymoron/04h.gif b/ch12/cardset-oxymoron/04h.gif new file mode 100644 index 0000000..3dddc1d Binary files /dev/null and b/ch12/cardset-oxymoron/04h.gif differ diff --git a/ch12/cardset-oxymoron/04s.gif b/ch12/cardset-oxymoron/04s.gif new file mode 100644 index 0000000..acddfc8 Binary files /dev/null and b/ch12/cardset-oxymoron/04s.gif differ diff --git a/ch12/cardset-oxymoron/05c.gif b/ch12/cardset-oxymoron/05c.gif new file mode 100644 index 0000000..8848578 Binary files /dev/null and b/ch12/cardset-oxymoron/05c.gif differ diff --git a/ch12/cardset-oxymoron/05d.gif b/ch12/cardset-oxymoron/05d.gif new file mode 100644 index 0000000..4f21e46 Binary files /dev/null and b/ch12/cardset-oxymoron/05d.gif differ diff --git a/ch12/cardset-oxymoron/05h.gif b/ch12/cardset-oxymoron/05h.gif new file mode 100644 index 0000000..c5f2671 Binary files /dev/null and b/ch12/cardset-oxymoron/05h.gif differ diff --git a/ch12/cardset-oxymoron/05s.gif b/ch12/cardset-oxymoron/05s.gif new file mode 100644 index 0000000..bd55b4f Binary files /dev/null and b/ch12/cardset-oxymoron/05s.gif differ diff --git a/ch12/cardset-oxymoron/06c.gif b/ch12/cardset-oxymoron/06c.gif new file mode 100644 index 0000000..d34bac8 Binary files /dev/null and b/ch12/cardset-oxymoron/06c.gif differ diff --git a/ch12/cardset-oxymoron/06d.gif b/ch12/cardset-oxymoron/06d.gif new file mode 100644 index 0000000..82cde58 Binary files /dev/null and b/ch12/cardset-oxymoron/06d.gif differ diff --git a/ch12/cardset-oxymoron/06h.gif b/ch12/cardset-oxymoron/06h.gif new file mode 100644 index 0000000..b578655 Binary files /dev/null and b/ch12/cardset-oxymoron/06h.gif differ diff --git a/ch12/cardset-oxymoron/06s.gif b/ch12/cardset-oxymoron/06s.gif new file mode 100644 index 0000000..146571d Binary files /dev/null and b/ch12/cardset-oxymoron/06s.gif differ diff --git a/ch12/cardset-oxymoron/07c.gif b/ch12/cardset-oxymoron/07c.gif new file mode 100644 index 0000000..248e0b2 Binary files /dev/null and b/ch12/cardset-oxymoron/07c.gif differ diff --git a/ch12/cardset-oxymoron/07d.gif b/ch12/cardset-oxymoron/07d.gif new file mode 100644 index 0000000..920d5f5 Binary files /dev/null and b/ch12/cardset-oxymoron/07d.gif differ diff --git a/ch12/cardset-oxymoron/07h.gif b/ch12/cardset-oxymoron/07h.gif new file mode 100644 index 0000000..c996bd3 Binary files /dev/null and b/ch12/cardset-oxymoron/07h.gif differ diff --git a/ch12/cardset-oxymoron/07s.gif b/ch12/cardset-oxymoron/07s.gif new file mode 100644 index 0000000..5a7842f Binary files /dev/null and b/ch12/cardset-oxymoron/07s.gif differ diff --git a/ch12/cardset-oxymoron/08c.gif b/ch12/cardset-oxymoron/08c.gif new file mode 100644 index 0000000..e267751 Binary files /dev/null and b/ch12/cardset-oxymoron/08c.gif differ diff --git a/ch12/cardset-oxymoron/08d.gif b/ch12/cardset-oxymoron/08d.gif new file mode 100644 index 0000000..c939519 Binary files /dev/null and b/ch12/cardset-oxymoron/08d.gif differ diff --git a/ch12/cardset-oxymoron/08h.gif b/ch12/cardset-oxymoron/08h.gif new file mode 100644 index 0000000..7379dd6 Binary files /dev/null and b/ch12/cardset-oxymoron/08h.gif differ diff --git a/ch12/cardset-oxymoron/08s.gif b/ch12/cardset-oxymoron/08s.gif new file mode 100644 index 0000000..c3ecb02 Binary files /dev/null and b/ch12/cardset-oxymoron/08s.gif differ diff --git a/ch12/cardset-oxymoron/09c.gif b/ch12/cardset-oxymoron/09c.gif new file mode 100644 index 0000000..becbd26 Binary files /dev/null and b/ch12/cardset-oxymoron/09c.gif differ diff --git a/ch12/cardset-oxymoron/09d.gif b/ch12/cardset-oxymoron/09d.gif new file mode 100644 index 0000000..9487da3 Binary files /dev/null and b/ch12/cardset-oxymoron/09d.gif differ diff --git a/ch12/cardset-oxymoron/09h.gif b/ch12/cardset-oxymoron/09h.gif new file mode 100644 index 0000000..1715043 Binary files /dev/null and b/ch12/cardset-oxymoron/09h.gif differ diff --git a/ch12/cardset-oxymoron/09s.gif b/ch12/cardset-oxymoron/09s.gif new file mode 100644 index 0000000..1322a37 Binary files /dev/null and b/ch12/cardset-oxymoron/09s.gif differ diff --git a/ch12/cardset-oxymoron/10c.gif b/ch12/cardset-oxymoron/10c.gif new file mode 100644 index 0000000..2a0ca7a Binary files /dev/null and b/ch12/cardset-oxymoron/10c.gif differ diff --git a/ch12/cardset-oxymoron/10d.gif b/ch12/cardset-oxymoron/10d.gif new file mode 100644 index 0000000..2f4f3e3 Binary files /dev/null and b/ch12/cardset-oxymoron/10d.gif differ diff --git a/ch12/cardset-oxymoron/10h.gif b/ch12/cardset-oxymoron/10h.gif new file mode 100644 index 0000000..5307b74 Binary files /dev/null and b/ch12/cardset-oxymoron/10h.gif differ diff --git a/ch12/cardset-oxymoron/10s.gif b/ch12/cardset-oxymoron/10s.gif new file mode 100644 index 0000000..46fd134 Binary files /dev/null and b/ch12/cardset-oxymoron/10s.gif differ diff --git a/ch12/cardset-oxymoron/11c.gif b/ch12/cardset-oxymoron/11c.gif new file mode 100644 index 0000000..32a07ab Binary files /dev/null and b/ch12/cardset-oxymoron/11c.gif differ diff --git a/ch12/cardset-oxymoron/11d.gif b/ch12/cardset-oxymoron/11d.gif new file mode 100644 index 0000000..ba63b6d Binary files /dev/null and b/ch12/cardset-oxymoron/11d.gif differ diff --git a/ch12/cardset-oxymoron/11h.gif b/ch12/cardset-oxymoron/11h.gif new file mode 100644 index 0000000..2826910 Binary files /dev/null and b/ch12/cardset-oxymoron/11h.gif differ diff --git a/ch12/cardset-oxymoron/11s.gif b/ch12/cardset-oxymoron/11s.gif new file mode 100644 index 0000000..7c4ba71 Binary files /dev/null and b/ch12/cardset-oxymoron/11s.gif differ diff --git a/ch12/cardset-oxymoron/12c.gif b/ch12/cardset-oxymoron/12c.gif new file mode 100644 index 0000000..758898e Binary files /dev/null and b/ch12/cardset-oxymoron/12c.gif differ diff --git a/ch12/cardset-oxymoron/12d.gif b/ch12/cardset-oxymoron/12d.gif new file mode 100644 index 0000000..edcb179 Binary files /dev/null and b/ch12/cardset-oxymoron/12d.gif differ diff --git a/ch12/cardset-oxymoron/12h.gif b/ch12/cardset-oxymoron/12h.gif new file mode 100644 index 0000000..3c7346a Binary files /dev/null and b/ch12/cardset-oxymoron/12h.gif differ diff --git a/ch12/cardset-oxymoron/12s.gif b/ch12/cardset-oxymoron/12s.gif new file mode 100644 index 0000000..228969c Binary files /dev/null and b/ch12/cardset-oxymoron/12s.gif differ diff --git a/ch12/cardset-oxymoron/13c.gif b/ch12/cardset-oxymoron/13c.gif new file mode 100644 index 0000000..f1705b1 Binary files /dev/null and b/ch12/cardset-oxymoron/13c.gif differ diff --git a/ch12/cardset-oxymoron/13d.gif b/ch12/cardset-oxymoron/13d.gif new file mode 100644 index 0000000..aa30454 Binary files /dev/null and b/ch12/cardset-oxymoron/13d.gif differ diff --git a/ch12/cardset-oxymoron/13h.gif b/ch12/cardset-oxymoron/13h.gif new file mode 100644 index 0000000..845a65d Binary files /dev/null and b/ch12/cardset-oxymoron/13h.gif differ diff --git a/ch12/cardset-oxymoron/13s.gif b/ch12/cardset-oxymoron/13s.gif new file mode 100644 index 0000000..b719113 Binary files /dev/null and b/ch12/cardset-oxymoron/13s.gif differ diff --git a/ch12/cardset-oxymoron/COPYRIGHT b/ch12/cardset-oxymoron/COPYRIGHT new file mode 100644 index 0000000..1c81a79 --- /dev/null +++ b/ch12/cardset-oxymoron/COPYRIGHT @@ -0,0 +1,10 @@ +This PySol cardset was adapted from cards-2.0.tar.gz. +http://www.waste.org/~oxymoron/cards/ + +Copyright (C) 1998 Oliver Xymoron +Copyright (C) 1999 Markus F.X.J. Oberhumer + +This cardset is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 of +the License, or (at your option) any later version. diff --git a/ch12/cardset-oxymoron/back001.gif b/ch12/cardset-oxymoron/back001.gif new file mode 100644 index 0000000..463c0b0 Binary files /dev/null and b/ch12/cardset-oxymoron/back001.gif differ diff --git a/ch12/cardset-oxymoron/back101.gif b/ch12/cardset-oxymoron/back101.gif new file mode 100644 index 0000000..4bb2c95 Binary files /dev/null and b/ch12/cardset-oxymoron/back101.gif differ diff --git a/ch12/cardset-oxymoron/back102.gif b/ch12/cardset-oxymoron/back102.gif new file mode 100644 index 0000000..82b25f7 Binary files /dev/null and b/ch12/cardset-oxymoron/back102.gif differ diff --git a/ch12/cardset-oxymoron/back111.gif b/ch12/cardset-oxymoron/back111.gif new file mode 100644 index 0000000..d50079d Binary files /dev/null and b/ch12/cardset-oxymoron/back111.gif differ diff --git a/ch12/cardset-oxymoron/back191.gif b/ch12/cardset-oxymoron/back191.gif new file mode 100644 index 0000000..cbd3a5a Binary files /dev/null and b/ch12/cardset-oxymoron/back191.gif differ diff --git a/ch12/cardset-oxymoron/back192.gif b/ch12/cardset-oxymoron/back192.gif new file mode 100644 index 0000000..e7111b3 Binary files /dev/null and b/ch12/cardset-oxymoron/back192.gif differ diff --git a/ch12/cardset-oxymoron/bottom01.gif b/ch12/cardset-oxymoron/bottom01.gif new file mode 100644 index 0000000..dd9dcf7 Binary files /dev/null and b/ch12/cardset-oxymoron/bottom01.gif differ diff --git a/ch12/cardset-oxymoron/bottom02.gif b/ch12/cardset-oxymoron/bottom02.gif new file mode 100644 index 0000000..cf9c90b Binary files /dev/null and b/ch12/cardset-oxymoron/bottom02.gif differ diff --git a/ch12/cardset-oxymoron/bottom03.gif b/ch12/cardset-oxymoron/bottom03.gif new file mode 100644 index 0000000..5357ddc Binary files /dev/null and b/ch12/cardset-oxymoron/bottom03.gif differ diff --git a/ch12/cardset-oxymoron/bottom04.gif b/ch12/cardset-oxymoron/bottom04.gif new file mode 100644 index 0000000..85eca98 Binary files /dev/null and b/ch12/cardset-oxymoron/bottom04.gif differ diff --git a/ch12/cardset-oxymoron/bottom05.gif b/ch12/cardset-oxymoron/bottom05.gif new file mode 100644 index 0000000..c564d79 Binary files /dev/null and b/ch12/cardset-oxymoron/bottom05.gif differ diff --git a/ch12/cardset-oxymoron/bottom06.gif b/ch12/cardset-oxymoron/bottom06.gif new file mode 100644 index 0000000..fc5b61a Binary files /dev/null and b/ch12/cardset-oxymoron/bottom06.gif differ diff --git a/ch12/cardset-oxymoron/bottom07.gif b/ch12/cardset-oxymoron/bottom07.gif new file mode 100644 index 0000000..8c8f330 Binary files /dev/null and b/ch12/cardset-oxymoron/bottom07.gif differ diff --git a/ch12/cardset-oxymoron/config.txt b/ch12/cardset-oxymoron/config.txt new file mode 100644 index 0000000..cc42839 --- /dev/null +++ b/ch12/cardset-oxymoron/config.txt @@ -0,0 +1,6 @@ +PySol solitaire cardset;4;.gif;1;52;0 +1000_oxymoron_073097;Oxymoron +73 97 8 +18 18 7 7 +back001.gif +back001.gif;back101.gif;back102.gif;back111.gif;back191.gif;back192.gif diff --git a/ch12/cardset-oxymoron/l01.gif b/ch12/cardset-oxymoron/l01.gif new file mode 100644 index 0000000..da0b226 Binary files /dev/null and b/ch12/cardset-oxymoron/l01.gif differ diff --git a/ch12/cardset-oxymoron/l02.gif b/ch12/cardset-oxymoron/l02.gif new file mode 100644 index 0000000..6684d21 Binary files /dev/null and b/ch12/cardset-oxymoron/l02.gif differ diff --git a/ch12/cardset-oxymoron/l03.gif b/ch12/cardset-oxymoron/l03.gif new file mode 100644 index 0000000..c8ec2ad Binary files /dev/null and b/ch12/cardset-oxymoron/l03.gif differ diff --git a/ch12/cardset-oxymoron/l04.gif b/ch12/cardset-oxymoron/l04.gif new file mode 100644 index 0000000..cc88f42 Binary files /dev/null and b/ch12/cardset-oxymoron/l04.gif differ diff --git a/ch12/cardset-oxymoron/shade.gif b/ch12/cardset-oxymoron/shade.gif new file mode 100644 index 0000000..ca96877 Binary files /dev/null and b/ch12/cardset-oxymoron/shade.gif differ diff --git a/ch12/cardset-oxymoron/shadow00.gif b/ch12/cardset-oxymoron/shadow00.gif new file mode 100644 index 0000000..cc0560b Binary files /dev/null and b/ch12/cardset-oxymoron/shadow00.gif differ diff --git a/ch12/cardset-oxymoron/shadow01.gif b/ch12/cardset-oxymoron/shadow01.gif new file mode 100644 index 0000000..21e8cb2 Binary files /dev/null and b/ch12/cardset-oxymoron/shadow01.gif differ diff --git a/ch12/cardset-oxymoron/shadow02.gif b/ch12/cardset-oxymoron/shadow02.gif new file mode 100644 index 0000000..5bbf57b Binary files /dev/null and b/ch12/cardset-oxymoron/shadow02.gif differ diff --git a/ch12/cardset-oxymoron/shadow03.gif b/ch12/cardset-oxymoron/shadow03.gif new file mode 100644 index 0000000..5b58fe5 Binary files /dev/null and b/ch12/cardset-oxymoron/shadow03.gif differ diff --git a/ch12/cardset-oxymoron/shadow04.gif b/ch12/cardset-oxymoron/shadow04.gif new file mode 100644 index 0000000..13ac221 Binary files /dev/null and b/ch12/cardset-oxymoron/shadow04.gif differ diff --git a/ch12/cardset-oxymoron/shadow05.gif b/ch12/cardset-oxymoron/shadow05.gif new file mode 100644 index 0000000..5996b2d Binary files /dev/null and b/ch12/cardset-oxymoron/shadow05.gif differ diff --git a/ch12/cardset-oxymoron/shadow06.gif b/ch12/cardset-oxymoron/shadow06.gif new file mode 100644 index 0000000..df18acb Binary files /dev/null and b/ch12/cardset-oxymoron/shadow06.gif differ diff --git a/ch12/cardset-oxymoron/shadow07.gif b/ch12/cardset-oxymoron/shadow07.gif new file mode 100644 index 0000000..b6cd41d Binary files /dev/null and b/ch12/cardset-oxymoron/shadow07.gif differ diff --git a/ch12/cardset-oxymoron/shadow08.gif b/ch12/cardset-oxymoron/shadow08.gif new file mode 100644 index 0000000..dea6b92 Binary files /dev/null and b/ch12/cardset-oxymoron/shadow08.gif differ diff --git a/ch12/cardset-oxymoron/shadow09.gif b/ch12/cardset-oxymoron/shadow09.gif new file mode 100644 index 0000000..3c85f2d Binary files /dev/null and b/ch12/cardset-oxymoron/shadow09.gif differ diff --git a/ch12/cardset-oxymoron/shadow10.gif b/ch12/cardset-oxymoron/shadow10.gif new file mode 100644 index 0000000..2b47bfa Binary files /dev/null and b/ch12/cardset-oxymoron/shadow10.gif differ diff --git a/ch12/cardset-oxymoron/shadow11.gif b/ch12/cardset-oxymoron/shadow11.gif new file mode 100644 index 0000000..85bedaa Binary files /dev/null and b/ch12/cardset-oxymoron/shadow11.gif differ diff --git a/ch12/cardset-oxymoron/shadow12.gif b/ch12/cardset-oxymoron/shadow12.gif new file mode 100644 index 0000000..0f5ab82 Binary files /dev/null and b/ch12/cardset-oxymoron/shadow12.gif differ diff --git a/ch12/cardset-oxymoron/shadow13.gif b/ch12/cardset-oxymoron/shadow13.gif new file mode 100644 index 0000000..3d17c17 Binary files /dev/null and b/ch12/cardset-oxymoron/shadow13.gif differ diff --git a/ch13/Card.java b/ch13/Card.java new file mode 120000 index 0000000..1c6483e --- /dev/null +++ b/ch13/Card.java @@ -0,0 +1 @@ +../ch12/Card.java \ No newline at end of file diff --git a/ch13/Deck.java b/ch13/Deck.java new file mode 100644 index 0000000..742120e --- /dev/null +++ b/ch13/Deck.java @@ -0,0 +1,119 @@ +import java.util.Arrays; +import java.util.Random; + +/** + * A deck of playing cards (of fixed size). + */ +public class Deck { + + private Card[] cards; + + /** + * Constructs a standard deck of 52 cards. + */ + public Deck() { + this.cards = new Card[52]; + int index = 0; + for (int suit = 0; suit <= 3; suit++) { + for (int rank = 1; rank <= 13; rank++) { + this.cards[index] = new Card(rank, suit); + index++; + } + } + } + + /** + * Constructs a deck of n cards (null). + */ + public Deck(int n) { + this.cards = new Card[n]; + } + + /** + * Gets the internal cards array. + */ + public Card[] getCards() { + return this.cards; + } + + /** + * Displays each of the cards in the deck. + */ + public void print() { + for (int i = 0; i < this.cards.length; i++) { + System.out.println(this.cards[i]); + } + } + + /** + * Returns a string representation of the deck. + */ + public String toString() { + return Arrays.toString(this.cards); + } + + /** + * Chooses a random number between low and high, including both. + */ + public int randomInt(int low, int high) { + return 0; + } + + /** + * Swaps the cards at indexes i and j. + */ + public void swapCards(int i, int j) { + } + + /** + * Randomly permutes the array of cards. + */ + public void shuffle() { + } + + /** + * Finds the index of the lowest card + * between low and high inclusive. + */ + public int indexLowest(int low, int high) { + return 0; + } + + /** + * Sorts the cards (in place) using selection sort. + */ + public void selectionSort() { + } + + /** + * Returns a subset of the cards in the deck. + */ + public Deck subdeck(int low, int high) { + Deck sub = new Deck(high - low + 1); + for (int i = 0; i < sub.cards.length; i++) { + sub.cards[i] = this.cards[low + i]; + } + return sub; + } + + /** + * Combines two previously sorted subdecks. + */ + public static Deck merge(Deck d1, Deck d2) { + return null; + } + + /** + * Returns a sorted copy of the deck using merge sort. + */ + public Deck mergeSort() { + return this; + } + + /** + * Reorders the cards (in place) using insertion sort. + */ + public void insertionSort() { + } + +} diff --git a/ch13/Test.java b/ch13/Test.java new file mode 100644 index 0000000..5f49ef1 --- /dev/null +++ b/ch13/Test.java @@ -0,0 +1,43 @@ +/** + * Test sorting algorithms for decks of cards. + */ +public class Test { + + /** + * Checks that the deck is sorted. + */ + public static void checkSorted(Deck deck) { + Card[] cards = deck.getCards(); + for (int i = 0; i < cards.length - 1; i++) { + if (cards[i].compareTo(cards[i + 1]) >= 0) { + System.out.println("Card #" + i + " not sorted!"); + } + } + } + + /** + * Demonstrates how to call the sorting methods. + */ + public static void main(String[] args) { + Deck deck; + + System.out.println("Testing selection..."); + deck = new Deck(); + deck.shuffle(); + deck.selectionSort(); + checkSorted(deck); + + System.out.println("Testing mergesort..."); + deck = new Deck(); + deck.shuffle(); + deck = deck.mergeSort(); + checkSorted(deck); + + System.out.println("Testing insertion..."); + deck = new Deck(); + deck.shuffle(); + deck.insertionSort(); + checkSorted(deck); + } + +} diff --git a/ch14/Card.java b/ch14/Card.java new file mode 120000 index 0000000..1c6483e --- /dev/null +++ b/ch14/Card.java @@ -0,0 +1 @@ +../ch12/Card.java \ No newline at end of file diff --git a/ch14/CardCollection.java b/ch14/CardCollection.java new file mode 100644 index 0000000..f9c3be2 --- /dev/null +++ b/ch14/CardCollection.java @@ -0,0 +1,123 @@ +import java.util.ArrayList; +import java.util.Random; + +/** + * A collection of playing cards. + */ +public class CardCollection { + + private String label; + private ArrayList cards; + + /** + * Constructs an empty collection. + */ + public CardCollection(String label) { + this.label = label; + this.cards = new ArrayList(); + } + + /** + * Returns the label of the card collection. + */ + public String getLabel() { + return label; + } + + /** + * Adds the given card to the collection. + */ + public void addCard(Card card) { + cards.add(card); + } + + /** + * Removes and returns the card with the given index. + */ + public Card popCard(int i) { + return cards.remove(i); + } + + /** + * Removes and returns the last card. + */ + public Card popCard() { + int i = size() - 1; + 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); + } + } + + /** + * Moves all remaining cards to the given collection. + */ + public void dealAll(CardCollection that) { + int n = size(); + deal(that, n); + } + + /** + * Returns the card with the given index. + */ + public Card getCard(int i) { + return cards.get(i); + } + + /** + * Returns the last card. + */ + public Card last() { + int i = size() - 1; + return cards.get(i); + } + + /** + * Swaps the cards at indexes i and j. + */ + public void swapCards(int i, int j) { + Card temp = cards.get(i); + cards.set(i, cards.get(j)); + cards.set(j, temp); + } + + /** + * Randomly permute the cards. + */ + public void shuffle() { + Random random = new Random(); + for (int i = size() - 1; i > 0; i--) { + int j = random.nextInt(i); + swapCards(i, j); + } + } + + /** + * Returns a string representation of the card collection. + */ + public String toString() { + return label + ": " + cards.toString(); + } + +} diff --git a/ch14/Deck.java b/ch14/Deck.java new file mode 100644 index 0000000..8db1814 --- /dev/null +++ b/ch14/Deck.java @@ -0,0 +1,19 @@ +/** + * A deck of playing cards. + */ +public class Deck extends CardCollection { + + /** + * Constructs a standard deck of 52 cards. + */ + public Deck(String label) { + super(label); + + for (int suit = 0; suit <= 3; suit++) { + for (int rank = 1; rank <= 13; rank++) { + addCard(new Card(rank, suit)); + } + } + } + +} diff --git a/ch14/Eights.java b/ch14/Eights.java new file mode 100644 index 0000000..13b7961 --- /dev/null +++ b/ch14/Eights.java @@ -0,0 +1,145 @@ +import java.util.Scanner; + +/** + * Simulates a game of Crazy Eights. See + * https://en.wikipedia.org/wiki/Crazy_Eights + * for basic play and scoring rules. + */ +public class Eights { + + private Player one; + private Player two; + private Hand drawPile; + private Hand discardPile; + private Scanner in; + + /** + * Initializes the state of the game. + */ + public Eights() { + Deck deck = new Deck("Deck"); + deck.shuffle(); + + // deal cards to each player + int handSize = 5; + one = new Player("Allen"); + deck.deal(one.getHand(), handSize); + + two = new Player("Chris"); + deck.deal(two.getHand(), handSize); + + // turn one card face up + discardPile = new Hand("Discards"); + deck.deal(discardPile, 1); + + // put the rest of the deck face down + drawPile = new Hand("Draw pile"); + deck.dealAll(drawPile); + + // create the scanner we'll use to wait for the user + in = new Scanner(System.in); + } + + /** + * Returns true if either hand is empty. + */ + public boolean isDone() { + return one.getHand().empty() || two.getHand().empty(); + } + + /** + * Moves cards from the discard pile to the draw pile and shuffles. + */ + public void reshuffle() { + // save the top card + Card prev = discardPile.popCard(); + + // move the rest of the cards + discardPile.dealAll(drawPile); + + // put the top card back + discardPile.addCard(prev); + + // shuffle the draw pile + drawPile.shuffle(); + } + + /** + * Returns a card from the draw pile. + */ + public Card draw() { + if (drawPile.empty()) { + reshuffle(); + } + return drawPile.popCard(); + } + + /** + * Switches players. + */ + public Player nextPlayer(Player current) { + if (current == one) { + return two; + } else { + return one; + } + } + + /** + * Displays the state of the game. + */ + public void displayState() { + one.display(); + two.display(); + discardPile.display(); + System.out.print("Draw pile: "); + System.out.println(drawPile.size() + " cards"); + } + + /** + * Waits for the user to press enter. + */ + public void waitForUser() { + in.nextLine(); + } + + /** + * One player takes a turn. + */ + public void takeTurn(Player player) { + Card prev = discardPile.last(); + Card next = player.play(this, prev); + discardPile.addCard(next); + + System.out.println(player.getName() + " plays " + next); + System.out.println(); + } + + /** + * Plays the game. + */ + public void playGame() { + Player player = one; + + // keep playing until there's a winner + while (!isDone()) { + displayState(); + waitForUser(); + takeTurn(player); + player = nextPlayer(player); + } + + // display the final score + one.displayScore(); + two.displayScore(); + } + + /** + * Creates the game and runs it. + */ + public static void main(String[] args) { + Eights game = new Eights(); + game.playGame(); + } + +} diff --git a/ch14/Hand.java b/ch14/Hand.java new file mode 100644 index 0000000..8089a49 --- /dev/null +++ b/ch14/Hand.java @@ -0,0 +1,24 @@ +/** + * A hand of playing cards. + */ +public class Hand extends CardCollection { + + /** + * Constructs an empty hand. + */ + public Hand(String label) { + super(label); + } + + /** + * Prints the label and cards. + */ + public void display() { + System.out.println(getLabel() + ": "); + for (int i = 0; i < size(); i++) { + System.out.println(getCard(i)); + } + System.out.println(); + } + +} diff --git a/ch14/Player.java b/ch14/Player.java new file mode 100644 index 0000000..433ff28 --- /dev/null +++ b/ch14/Player.java @@ -0,0 +1,118 @@ +/** + * A player in a game of crazy eights. + */ +public class Player { + + private String name; + private Hand hand; + + /** + * Constructs a player with an empty hand. + */ + public Player(String name) { + this.name = name; + this.hand = new Hand(name); + } + + /** + * Gets the player's name. + */ + public String getName() { + return name; + } + + /** + * Gets the player's hand. + */ + public Hand getHand() { + return hand; + } + + /** + * Removes and returns a legal card from the player's hand. + */ + public Card play(Eights eights, Card prev) { + Card card = searchForMatch(prev); + if (card == null) { + card = drawForMatch(eights, prev); + } + return card; + } + + /** + * Searches the player's hand for a matching card. + */ + public Card searchForMatch(Card prev) { + for (int i = 0; i < hand.size(); i++) { + Card card = hand.getCard(i); + if (cardMatches(card, prev)) { + return hand.popCard(i); + } + } + return null; + } + + /** + * Draws cards until a match is found. + */ + public Card drawForMatch(Eights eights, Card prev) { + while (true) { + Card card = eights.draw(); + System.out.println(name + " draws " + card); + if (cardMatches(card, prev)) { + return card; + } + hand.addCard(card); + } + } + + /** + * 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; + } + + /** + * Calculates the player's score (penalty points). + */ + public int score() { + int sum = 0; + for (int i = 0; i < hand.size(); i++) { + Card card = hand.getCard(i); + int rank = card.getRank(); + if (rank == 8) { + sum -= 20; + } else if (rank > 10) { + sum -= 10; + } else { + sum -= rank; + } + } + return sum; + } + + /** + * Displays the player's hand. + */ + public void display() { + hand.display(); + } + + /** + * Displays the player's name and score. + */ + public void displayScore() { + System.out.println(name + " has " + score() + " points"); + } + +} diff --git a/ch14/Test.java b/ch14/Test.java new file mode 100644 index 0000000..274710c --- /dev/null +++ b/ch14/Test.java @@ -0,0 +1,20 @@ +/** + * Test code for Deck and Hand. + */ +public class Test { + + public static void main(String[] args) { + Deck deck = new Deck("Deck"); + deck.shuffle(); + + Hand hand = new Hand("Hand"); + deck.deal(hand, 5); + hand.display(); + + Hand drawPile = new Hand("Draw Pile"); + deck.dealAll(drawPile); + System.out.printf("Draw Pile has %d cards.\n", + drawPile.size()); + } + +}