Skip to content
Snippets Groups Projects
Verified Commit dd44639a authored by Christopher Bohn's avatar Christopher Bohn :thinking:
Browse files

Week 8 assignments

parent 099c1b82
Branches
Tags v1.1.1
No related merge requests found
Showing
with 1439 additions and 0 deletions
# Mac file finder metadata
.DS_Store
# Windows file metadata
._*
# Thumbnail image caches
Thumbs.db
ethumbs.db
# MS Office temporary file
~*
# Emacs backup file
*~
# Common
[Bb]in/
[Bb]uild/
[Oo]bj/
[Oo]ut/
[Tt]mp/
[Xx]86/
[Ii][Aa]32/
[Xx]64/
[Xx]86_64/
[Xx]86-64/
[Aa]rm
[Aa]32
[Tt]32
[Aa]64
*.tmp
*.bak
*.bk
*.swp
# Java files
*.class
javadoc/
# Maven
target/
# JetBrains (IntelliJ IDEA, PyCharm, etc) files
.idea/
cmake-build-*/
*.iml
*.iws
*.ipr
# Eclipse files
.settings/
.project
.classpath
.buildpath
.loadpath
.factorypath
local.properties
# Decomposition and Conditionals Homework
**Collaboration Policy**: No collaboration is permitted on this assignment.
**Notes and References**: This is an open-book, open-note assignment.
## Overview
Proper problem and solution decomposition is an important software engineering
technique for writing readable and maintainable code. In this assignment you
will practice decomposition to solve two small computational problems whose
solutions may not be obvious from their descriptions. You will also practice
writing code that uses an enumerated type, string concatenation, and exception
handlers.
## Learning Goals
By completing this assignment, you should be able to:
1. Decompose a solution to a problem into multiple methods in a Java program,
2. Use an enumerated type to represent values from a limited space,
3. Use string concatenation to format text output, and
4. Use exception handlers to catch and handle input errors.
## Instructions
This assignment is to be completed individually; **no collaboration is
permitted**.
### Clone the Starter Code and Set Up Eclipse
1. In your virtual machine, create a new folder in your `soft160-homework`
folder named `homework5`.
2. Change into the `homework5` directory.
3. Clone
[the starter code](https://git.unl.edu/soft-core/soft-160/decomposition-and-conditionals-homework).
4. Change into the `decomposition-and-conditionals-homework` directory. Verify that you are in
the correct directory by running the command `pwd`.
5. Remove the Git folder that links this code to the instructors' repository by
running the command `chmod -R u+w .git` (which gives you permission to
remove the folder without extra confirmation prompts) and then the command
`rm -rI .git`. Answer `yes` when asked to confirm the deletion.
6. Verify the Git folder has been removed by running `ls -a` and making sure
that you see folders with names like `src` and `documentation`, but that `.git`
is **not** one of the items listed.
7. Start the Eclipse IDE.
8. Import the starter code into Eclipse as a Maven project.
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>edu.unl.cse.soft160.decomposition_and_conditionals</groupId>
<artifactId>decomposition_and_conditionals</artifactId>
<packaging>jar</packaging>
<version>1.0-SNAPSHOT</version>
<name>decomposition_and_conditionals</name>
<url>http://maven.apache.org</url>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<build>
<plugins>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.8.1</version>
<configuration>
<source>8</source>
<target>8</target>
</configuration>
</plugin>
</plugins>
</build>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.13</version>
<scope>test</scope>
</dependency>
</dependencies>
</project>
package edu.unl.cse.soft160.decomposition_and_conditionals;
public class BooleanOperator {
private static enum TruthValue {
TRUE, FALSE, UNKNOWN,
}
public static void main(String... arguments) {
// [write code here]
}
}
package edu.unl.cse.soft160.decomposition_and_conditionals;
public class ProcessInput {
private static enum State {
EMPTY, DECIMAL, NUMERIC,
}
private static enum Classification {
FLOAT, INTEGER, NAN,
}
public static void main(String... arguments) {
// [write code here]
}
}
package edu.unl.cse.soft160.decomposition_and_conditionals;
import static org.junit.Assert.*;
import org.junit.Test;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.InputStream;
import java.io.PrintStream;
public class BooleanOperatorTest {
protected static String assemble(String... lines) {
return String.join("\n", lines) + "\n";
}
protected static String runMain(String... inputs) {
InputStream in = System.in;
PrintStream out = System.out;
System.setIn(new ByteArrayInputStream(assemble(inputs).getBytes()));
ByteArrayOutputStream collector = new ByteArrayOutputStream();
System.setOut(new PrintStream(collector));
BooleanOperator.main();
System.setIn(in);
System.setOut(out);
return collector.toString();
}
@Test
public void testTrueTrue() {
assertEquals(assemble(
"Enter truth value of operand 1: Enter truth value of operand 2: The NOR value of TRUE and TRUE is FALSE."),
runMain("TRUE", "TRUE"));
}
@Test
public void testTrueFalse() {
assertEquals(assemble(
"Enter truth value of operand 1: Enter truth value of operand 2: The NOR value of TRUE and FALSE is FALSE."),
runMain("TRUE", "FALSE"));
}
@Test
public void testFalseTrue() {
assertEquals(assemble(
"Enter truth value of operand 1: Enter truth value of operand 2: The NOR value of FALSE and TRUE is FALSE."),
runMain("FALSE", "TRUE"));
}
@Test
public void testFalseFalse() {
assertEquals(assemble(
"Enter truth value of operand 1: Enter truth value of operand 2: The NOR value of FALSE and FALSE is TRUE."),
runMain("FALSE", "FALSE"));
}
@Test
public void testFalseUnknown() {
assertEquals(assemble(
"Enter truth value of operand 1: Enter truth value of operand 2: The NOR value of FALSE and UNKNOWN is UNKNOWN."),
runMain("FALSE", "UNKNOWN"));
}
@Test
public void testUnknownFalse() {
assertEquals(assemble(
"Enter truth value of operand 1: Enter truth value of operand 2: The NOR value of UNKNOWN and FALSE is UNKNOWN."),
runMain("UNKNOWN", "FALSE"));
}
@Test
public void testUnknownUnknown() {
assertEquals(assemble(
"Enter truth value of operand 1: Enter truth value of operand 2: The NOR value of UNKNOWN and UNKNOWN is UNKNOWN."),
runMain("UNKNOWN", "UNKNOWN"));
}
@Test
public void testTrueUnknown() {
assertEquals(assemble(
"Enter truth value of operand 1: Enter truth value of operand 2: The NOR value of TRUE and UNKNOWN is FALSE."),
runMain("TRUE", "UNKNOWN"));
}
@Test
public void testUnknownTrue() {
assertEquals(assemble(
"Enter truth value of operand 1: Enter truth value of operand 2: The NOR value of UNKNOWN and TRUE is FALSE."),
runMain("UNKNOWN", "TRUE"));
}
@Test
public void testExceptionInOp1() {
assertEquals(assemble(
"Enter truth value of operand 1: Enter truth value of operand 2: Truth value must be one of TRUE, FALSE, or UNKNOWN."),
runMain("FOO", "TRUE"));
}
@Test
public void testExceptionInOp2() {
assertEquals(assemble(
"Enter truth value of operand 1: Enter truth value of operand 2: Truth value must be one of TRUE, FALSE, or UNKNOWN."),
runMain("TRUE", "BAR"));
}
}
package edu.unl.cse.soft160.decomposition_and_conditionals;
import static org.junit.Assert.*;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.InputStream;
import java.io.PrintStream;
import org.junit.Test;
public class ProcessInputTest {
protected static String assemble(String... lines) {
return String.join("\n", lines) + "\n";
}
protected static String runMain(String... inputs) {
InputStream in = System.in;
PrintStream out = System.out;
System.setIn(new ByteArrayInputStream(assemble(inputs).getBytes()));
ByteArrayOutputStream collector = new ByteArrayOutputStream();
System.setOut(new PrintStream(collector));
ProcessInput.main();
System.setIn(in);
System.setOut(out);
return collector.toString();
}
@Test
public void testEmptyL() {
assertEquals(
assemble("Enter the current state: Enter the next character: "
+ "Classification: NAN"),
runMain("empty","L"));
}
@Test
public void testEmpty0() {
assertEquals(
assemble("Enter the current state: Enter the next character: "
+ "Classification: INTEGER"),
runMain("empty","0"));
}
@Test
public void testEmpty1() {
assertEquals(
assemble("Enter the current state: Enter the next character: "
+ "Classification: INTEGER"),
runMain("empty","1"));
}
@Test
public void testEmpty2() {
assertEquals(
assemble("Enter the current state: Enter the next character: "
+ "Classification: INTEGER"),
runMain("empty","2"));
}
@Test
public void testEmpty3() {
assertEquals(
assemble("Enter the current state: Enter the next character: "
+ "Classification: INTEGER"),
runMain("empty","3"));
}
@Test
public void testEmpty4() {
assertEquals(
assemble("Enter the current state: Enter the next character: "
+ "Classification: INTEGER"),
runMain("empty","4"));
}
@Test
public void testEmpty5() {
assertEquals(
assemble("Enter the current state: Enter the next character: "
+ "Classification: INTEGER"),
runMain("empty","5"));
}
@Test
public void testEmpty6() {
assertEquals(
assemble("Enter the current state: Enter the next character: "
+ "Classification: INTEGER"),
runMain("empty","6"));
}
@Test
public void testEmpty7() {
assertEquals(
assemble("Enter the current state: Enter the next character: "
+ "Classification: INTEGER"),
runMain("empty","7"));
}
@Test
public void testEmpty8() {
assertEquals(
assemble("Enter the current state: Enter the next character: "
+ "Classification: INTEGER"),
runMain("empty","8"));
}
@Test
public void testEmpty9() {
assertEquals(
assemble("Enter the current state: Enter the next character: "
+ "Classification: INTEGER"),
runMain("empty","9"));
}
@Test
public void testEmptyPeriod() {
assertEquals(
assemble("Enter the current state: Enter the next character: "
+ "Classification: FLOAT"),
runMain("empty","."));
}
@Test
public void testEmptyF() {
assertEquals(
assemble("Enter the current state: Enter the next character: "
+ "Classification: NAN"),
runMain("empty","f"));
}
@Test
public void testEmptyD() {
assertEquals(
assemble("Enter the current state: Enter the next character: "
+ "Classification: NAN"),
runMain("empty","d"));
}
@Test
public void testDecimalL() {
assertEquals(
assemble("Enter the current state: Enter the next character: "
+ "Classification: NAN"),
runMain("decimal","L"));
}
@Test
public void testDecimal0() {
assertEquals(
assemble("Enter the current state: Enter the next character: "
+ "Classification: FLOAT"),
runMain("decimal","0"));
}
@Test
public void testDecimal1() {
assertEquals(
assemble("Enter the current state: Enter the next character: "
+ "Classification: FLOAT"),
runMain("decimal","1"));
}
@Test
public void testDecimal2() {
assertEquals(
assemble("Enter the current state: Enter the next character: "
+ "Classification: FLOAT"),
runMain("decimal","2"));
}
@Test
public void testDecimal3() {
assertEquals(
assemble("Enter the current state: Enter the next character: "
+ "Classification: FLOAT"),
runMain("decimal","3"));
}
@Test
public void testDecimal4() {
assertEquals(
assemble("Enter the current state: Enter the next character: "
+ "Classification: FLOAT"),
runMain("decimal","4"));
}
@Test
public void testDecimal5() {
assertEquals(
assemble("Enter the current state: Enter the next character: "
+ "Classification: FLOAT"),
runMain("decimal","5"));
}
@Test
public void testDecimal6() {
assertEquals(
assemble("Enter the current state: Enter the next character: "
+ "Classification: FLOAT"),
runMain("decimal","6"));
}
@Test
public void testDecimal7() {
assertEquals(
assemble("Enter the current state: Enter the next character: "
+ "Classification: FLOAT"),
runMain("decimal","7"));
}
@Test
public void testDecimal8() {
assertEquals(
assemble("Enter the current state: Enter the next character: "
+ "Classification: FLOAT"),
runMain("decimal","8"));
}
@Test
public void testDecimal9() {
assertEquals(
assemble("Enter the current state: Enter the next character: "
+ "Classification: FLOAT"),
runMain("decimal","9"));
}
@Test
public void testDecimalPeriod() {
assertEquals(
assemble("Enter the current state: Enter the next character: "
+ "Classification: NAN"),
runMain("decimal","."));
}
@Test
public void testDecimalF() {
assertEquals(
assemble("Enter the current state: Enter the next character: "
+ "Classification: FLOAT"),
runMain("decimal","f"));
}
@Test
public void testDecimalD() {
assertEquals(
assemble("Enter the current state: Enter the next character: "
+ "Classification: FLOAT"),
runMain("decimal","d"));
}
@Test
public void testNumericL() {
assertEquals(
assemble("Enter the current state: Enter the next character: "
+ "Classification: INTEGER"),
runMain("numeric","L"));
}
@Test
public void testNumeric0() {
assertEquals(
assemble("Enter the current state: Enter the next character: "
+ "Classification: INTEGER"),
runMain("numeric","0"));
}
@Test
public void testNumeric1() {
assertEquals(
assemble("Enter the current state: Enter the next character: "
+ "Classification: INTEGER"),
runMain("numeric","1"));
}
@Test
public void testNumeric2() {
assertEquals(
assemble("Enter the current state: Enter the next character: "
+ "Classification: INTEGER"),
runMain("numeric","2"));
}
@Test
public void testNumeric3() {
assertEquals(
assemble("Enter the current state: Enter the next character: "
+ "Classification: INTEGER"),
runMain("numeric","3"));
}
@Test
public void testNumeric4() {
assertEquals(
assemble("Enter the current state: Enter the next character: "
+ "Classification: INTEGER"),
runMain("numeric","4"));
}
@Test
public void testNumeric5() {
assertEquals(
assemble("Enter the current state: Enter the next character: "
+ "Classification: INTEGER"),
runMain("numeric","5"));
}
@Test
public void testNumeric6() {
assertEquals(
assemble("Enter the current state: Enter the next character: "
+ "Classification: INTEGER"),
runMain("numeric","6"));
}
@Test
public void testNumeric7() {
assertEquals(
assemble("Enter the current state: Enter the next character: "
+ "Classification: INTEGER"),
runMain("numeric","7"));
}
@Test
public void testNumeric8() {
assertEquals(
assemble("Enter the current state: Enter the next character: "
+ "Classification: INTEGER"),
runMain("numeric","8"));
}
@Test
public void testNumeric9() {
assertEquals(
assemble("Enter the current state: Enter the next character: "
+ "Classification: INTEGER"),
runMain("numeric","9"));
}
@Test
public void testNumericPeriod() {
assertEquals(
assemble("Enter the current state: Enter the next character: "
+ "Classification: FLOAT"),
runMain("numeric","."));
}
@Test
public void testNumericF() {
assertEquals(
assemble("Enter the current state: Enter the next character: "
+ "Classification: FLOAT"),
runMain("numeric","f"));
}
@Test
public void testNumericD() {
assertEquals(
assemble("Enter the current state: Enter the next character: "
+ "Classification: FLOAT"),
runMain("numeric","d"));
}
}
# Mac file finder metadata
.DS_Store
# Windows file metadata
._*
# Thumbnail image caches
Thumbs.db
ethumbs.db
# MS Office temporary file
~*
# Emacs backup file
*~
# Common
[Bb]in/
[Bb]uild/
[Oo]bj/
[Oo]ut/
[Tt]mp/
[Xx]86/
[Ii][Aa]32/
[Xx]64/
[Xx]86_64/
[Xx]86-64/
[Aa]rm
[Aa]32
[Tt]32
[Aa]64
*.tmp
*.bak
*.bk
*.swp
# Java files
*.class
javadoc/
# Maven
target/
pom.xml.tag
pom.xml.releaseBackup
pom.xml.versionsBackup
pom.xml.next
release.properties
dependency-reduced-pom.xml
buildNumber.properties
.mvn/timing.properties
# JetBrains (IntelliJ IDEA, PyCharm, etc) files
.idea/
cmake-build-*/
*.iml
*.iws
*.ipr
# Eclipse files
.settings/
.project
.classpath
.buildpath
.loadpath
.factorypath
local.properties
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>edu.unl.cse.soft160.sort_three_pairs</groupId>
<artifactId>sort_three_pairs</artifactId>
<packaging>jar</packaging>
<version>1.0-SNAPSHOT</version>
<name>sort_three_pairs</name>
<url>http://maven.apache.org</url>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>8</source>
<target>8</target>
</configuration>
</plugin>
</plugins>
</build>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.13</version>
<scope>test</scope>
</dependency>
</dependencies>
</project>
package edu.unl.cse.soft160.sort_three_pairs;
public class SortThreePairs {
public static double readArgument(int position, String... arguments) {
return Double.parseDouble(arguments[position]);
}
public static String formatPair(double x, double y) {
return "(" + x + ", " + y + ")";
}
public static int getPositionOfMinimum(double x0, double y0, double x1, double y1, double x2, double y2) {
int result = 0;
double xmin = x0;
double ymin = y0;
if (x1 < xmin || x1 == xmin && y1 < ymin) {
result = result + 1;
xmin = x1;
ymin = y1;
}
if (x2 < xmin || x2 == xmin && y2 < ymin) {
result = result + 1;
xmin = x2;
ymin = y2;
}
return result;
}
public static void main(String... arguments) {
if (arguments.length != 6) {
System.err.println("Sorts three points by their x coordinates, breaking ties using y coordinates.");
System.err.println(
"Usage: java edu.unl.cse.soft160.sort_three_pairs.SortThreePairs [X0] [Y0] [X1] [Y1] [X2] [Y2]");
System.exit(1);
}
double x0 = readArgument(0, arguments);
double y0 = readArgument(1, arguments);
double x1 = readArgument(2, arguments);
double y1 = readArgument(3, arguments);
double x2 = readArgument(4, arguments);
double y2 = readArgument(5, arguments);
double x3 = x0;
double y3 = y0;
// move the smallest pair to (x0, y0)
int firstPositionOfMinimum = getPositionOfMinimum(x0, y0, x1, y1, x2, y2);
switch (firstPositionOfMinimum) {
case 2:
x3 = x1;
x1 = x2;
x2 = x3;
y3 = y1;
y1 = y2;
y2 = y3;
case 1:
x3 = x0;
x0 = x1;
x1 = x3;
y3 = y0;
y0 = y1;
y1 = y3;
}
// move the second-smallest pair to (x1, y1)
int secondPositionOfMinimum = getPositionOfMinimum(Double.MAX_VALUE, Double.MAX_VALUE, x1, y1, x2, y2);
switch (secondPositionOfMinimum) {
case 2:
x3 = x1;
x1 = x2;
x2 = x3;
y3 = y1;
y1 = y2;
y2 = y3;
}
System.out.println(formatPair(x1, y1));
System.out.println(formatPair(x2, y2));
System.out.println(formatPair(x3, y3));
}
}
package edu.unl.cse.soft160.sort_three_pairs;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import java.io.InputStream;
import java.io.ByteArrayInputStream;
import java.io.PrintStream;
import java.security.Permission;
import java.io.ByteArrayOutputStream;
import static org.junit.Assert.*;
public class SortThreePairsTest {
protected static String assemble(String... lines) {
return String.join("\n", lines) + "\n";
}
protected static String runMain(String... arguments) {
InputStream in = System.in;
PrintStream out = System.out;
System.setIn(new ByteArrayInputStream("".getBytes()));
ByteArrayOutputStream collector = new ByteArrayOutputStream();
System.setOut(new PrintStream(collector));
SortThreePairs.main(arguments);
System.setIn(in);
System.setOut(out);
return collector.toString();
}
@SuppressWarnings("serial")
protected static class ExitException extends SecurityException {
public final int status;
public ExitException(int status) {
super("Exit with status " + status);
this.status = status;
}
}
private static class TestingSecurityManager extends SecurityManager {
@Override
public void checkPermission(Permission perm) {
}
@Override
public void checkPermission(Permission perm, Object context) {
}
@Override
public void checkExit(int status) {
super.checkExit(status);
throw new ExitException(status);
}
}
@Before
public void setUp() throws SecurityException {
System.setSecurityManager(new TestingSecurityManager());
}
@After
public void tearDown() throws SecurityException {
System.setSecurityManager(null);
}
protected static String runMainForError(int expectedStatus, String... arguments) {
InputStream in = System.in;
PrintStream err = System.err;
System.setIn(new ByteArrayInputStream("".getBytes()));
ByteArrayOutputStream collector = new ByteArrayOutputStream();
System.setErr(new PrintStream(collector));
boolean exited = false;
try {
SortThreePairs.main(arguments);
} catch (ExitException expected) {
assertEquals(expectedStatus, expected.status);
exited = true;
} finally {
System.setIn(in);
System.setErr(err);
}
assertTrue(exited);
return collector.toString();
}
@Test
public void testZeros() {
assertEquals(assemble("(0.0, 0.0)", "(0.0, 0.0)", "(0.0, 0.0)"),
runMain("0", "0", "0", "0", "0", "0"));
}
@Test
public void testAlreadySorted() {
assertEquals(assemble("(0.0, 0.0)", "(1.0, 1.0)", "(2.0, 2.0)"),
runMain("0", "0", "1", "1", "2", "2"));
}
@Test
public void testReversed() {
assertEquals(assemble("(0.0, 0.0)", "(1.0, 1.0)", "(2.0, 2.0)"),
runMain("2", "2", "1", "1", "0", "0"));
}
@Test
public void testJumbled() {
assertEquals(assemble("(0.0, 0.0)", "(1.0, 1.0)", "(2.0, 2.0)"),
runMain("1", "1", "2", "2", "0", "0"));
}
@Test
public void testTieBreaking() {
assertEquals(assemble("(0.0, 1.0)", "(1.0, 2.0)", "(1.0, 3.0)"),
runMain("1", "3", "0", "1", "1", "2"));
}
@Test
public void testMultipleTieBreaking() {
assertEquals(assemble("(0.0, 0.0)", "(0.0, 1.0)", "(0.0, 3.0)"),
runMain("0", "1", "0", "0", "0", "3"));
}
@Test
public void testDuplicates() {
assertEquals(assemble("(1.0, 1.0)", "(1.0, 1.0)", "(1.0, 2.0)"),
runMain("1", "1", "1", "2", "1", "1"));
}
@Test
public void testPermutation1() {
assertEquals(assemble("(0.0, 0.0)", "(1.0, 1.0)", "(2.0, 2.0)"),
runMain("0", "0", "2", "2", "1", "1"));
}
@Test
public void testPermutation2() {
assertEquals(assemble("(0.0, 0.0)", "(1.0, 1.0)", "(2.0, 2.0)"),
runMain("2", "2", "0", "0", "1", "1"));
}
@Test
public void testPermutation3() {
assertEquals(assemble("(0.0, 0.0)", "(1.0, 1.0)", "(2.0, 2.0)"),
runMain("2", "2", "1", "1", "0", "0"));
}
@Test
public void testPermutation16() {
assertEquals(assemble("(0.0, 0.0)", "(1.0, 1.0)", "(2.0, 2.0)"),
runMain("1", "1", "2", "2", "0", "0"));
}
@Test
public void testPermutation20() {
assertEquals(assemble("(0.0, 0.0)", "(1.0, 1.0)", "(2.0, 2.0)"),
runMain("1", "1", "0", "0", "2", "2"));
}
@Test
public void testTooFewArguments() {
assertEquals(
assemble("Sorts three points by their x coordinates, breaking ties using y coordinates.",
"Usage: java edu.unl.cse.soft160.sort_three_pairs.SortThreePairs [X0] [Y0] [X1] [Y1] [X2] [Y2]"),
runMainForError(1, "0", "0", "1", "1", "2", "2", "3"));
}
}
# Mac file finder metadata
.DS_Store
# Windows file metadata
._*
# Thumbnail image caches
Thumbs.db
ethumbs.db
# MS Office temporary file
~*
# Emacs backup file
*~
# Common
[Bb]in/
[Bb]uild/
[Oo]bj/
[Oo]ut/
[Tt]mp/
[Xx]86/
[Ii][Aa]32/
[Xx]64/
[Xx]86_64/
[Xx]86-64/
[Aa]rm
[Aa]32
[Tt]32
[Aa]64
*.tmp
*.bak
*.bk
*.swp
# Java files
*.class
javadoc/
# Maven
target/
pom.xml.tag
pom.xml.releaseBackup
pom.xml.versionsBackup
pom.xml.next
release.properties
dependency-reduced-pom.xml
buildNumber.properties
.mvn/timing.properties
# JetBrains (IntelliJ IDEA, PyCharm, etc) files
.idea/
cmake-build-*/
*.iml
*.iws
*.ipr
# Eclipse files
.settings/
.project
.classpath
.buildpath
.loadpath
.factorypath
local.properties
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>edu.unl.cse.soft160.tetris</groupId>
<artifactId>tetris</artifactId>
<packaging>jar</packaging>
<version>1.0-SNAPSHOT</version>
<name>tetris</name>
<url>http://maven.apache.org</url>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<build>
<plugins>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.8.1</version>
<configuration>
<source>8</source>
<target>8</target>
</configuration>
</plugin>
</plugins>
</build>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.13</version>
<scope>test</scope>
</dependency>
</dependencies>
</project>
package edu.unl.cse.soft160.tetris;
import java.util.Collections;
import java.util.ArrayList;
import java.awt.Font;
import java.awt.Color;
import java.awt.Graphics;
import javax.swing.JFrame;
import javax.swing.JPanel;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.nio.file.StandardOpenOption;
public class Tetris extends JFrame {
private static final long serialVersionUID = -6851893161385783635L;
protected static void log(String message) {
try {
Files.write(Paths.get("logs/tetris.log"), (message + "\n").getBytes(), StandardOpenOption.CREATE,
StandardOpenOption.APPEND);
} catch (IOException exception) {
exception.printStackTrace();
}
}
protected void logFailedMove(String moveName) {
log("Attempted move failed: " + moveName + " on shape " + shape + " (\"" + SHAPE_NAMES[shape] + "\")");
}
protected static int mod(int value, int modulus) {
int result = value % modulus;
return result < 0 ? result + modulus : result;
}
protected static final int DEFAULT_SQUARE_SIZE = 60; // pixels
protected static final Font TEXT_FONT = new Font(Font.SANS_SERIF, Font.BOLD, DEFAULT_SQUARE_SIZE / 2);
protected static final Color TEXT_COLOR = new Color(255, 255, 255, 127);
protected static final String ROWS_CLEARED = "Rows cleared";
protected static final String FINAL_SCORE = "Final score";
protected static final String SCORE_SEPARATOR = ": ";
protected static final int ROTATE_LEFT = KeyEvent.VK_DOWN;
protected static final int ROTATE_RIGHT = KeyEvent.VK_UP;
protected static final int SHIFT_LEFT = KeyEvent.VK_LEFT;
protected static final int SHIFT_RIGHT = KeyEvent.VK_RIGHT;
protected static final int DROP = KeyEvent.VK_SPACE;
protected static final int PAUSE = KeyEvent.VK_P;
protected static final int NEW_GAME = KeyEvent.VK_N;
protected static final int WIDTH = 7; // squares
protected static final int HEIGHT = 11; // squares
protected static final int START_Y = 1; // squares from top
protected static final Color EMPTY = new Color(0, 0, 0);
protected static final Color[] COLORS = { new Color(0, 0, 204), new Color(142, 0, 204), new Color(204, 204, 0),
new Color(204, 0, 204), new Color(0, 204, 204), new Color(0, 204, 0), new Color(204, 0, 0), };
protected static final String[] SHAPE_NAMES = { "O", "L", "J", "S", "Z", "T", "I", };
protected static final int[] SHAPE_WIDTHS = { 2, 3, 3, 3, 3, 3, 4, };
protected static final int[][][][] SHAPES = {
{ // O
{ { 0, 0 }, { 1, 0 }, { 0, 1 }, { 1, 1 } }, },
{ // L
{ { 0, 0 }, { 1, 0 }, { 2, 0 }, { 2, 1 } }, { { 1, -1 }, { 1, 0 }, { 1, 1 }, { 0, 1 } },
{ { 0, -1 }, { 0, 0 }, { 1, 0 }, { 2, 0 } }, { { 1, -1 }, { 2, -1 }, { 1, 0 }, { 1, 1 } }, },
{ // J
{ { 0, 0 }, { 1, 0 }, { 2, 0 }, { 0, 1 } }, { { 0, -1 }, { 1, -1 }, { 1, 0 }, { 1, 1 } },
{ { 2, -1 }, { 0, 0 }, { 1, 0 }, { 2, 0 } }, { { 1, -1 }, { 1, 0 }, { 1, 1 }, { 2, 1 } }, },
{ // S
{ { 0, 0 }, { 1, 0 }, { 1, 1 }, { 2, 1 } }, { { 1, 0 }, { 0, 1 }, { 1, 1 }, { 0, 2 } }, },
{ // Z
{ { 1, 0 }, { 2, 0 }, { 0, 1 }, { 1, 1 } }, { { 0, 0 }, { 0, 1 }, { 1, 1 }, { 1, 2 } }, },
{ // T
{ { 1, 0 }, { 0, 1 }, { 1, 1 }, { 2, 1 } }, { { 1, 0 }, { 1, 1 }, { 2, 1 }, { 1, 2 } },
{ { 0, 1 }, { 1, 1 }, { 2, 1 }, { 1, 2 } }, { { 1, 0 }, { 0, 1 }, { 1, 1 }, { 1, 2 } }, },
{ // I
{ { 0, 0 }, { 1, 0 }, { 2, 0 }, { 3, 0 } }, { { 0, 0 }, { 0, 1 }, { 0, 2 }, { 0, 3 } }, }, };
protected Color[][] board;
protected int score;
protected boolean isOccupied(int x, int y) {
return x < 0 || x >= WIDTH || y < 0 || y >= HEIGHT || board[x][y] != EMPTY;
}
protected void emptyBoard() {
board = new Color[WIDTH][HEIGHT];
for (int x = 0; x < WIDTH; ++x) {
for (int y = 0; y < HEIGHT; ++y) {
board[x][y] = EMPTY;
}
}
}
protected void clearRows() {
int fallTo = HEIGHT - 1;
for (int y = HEIGHT; y-- > 0;) {
boolean full = true;
for (int x = 0; x < WIDTH; ++x) {
if (board[x][y] == EMPTY) {
full = false;
break;
}
}
if (full) {
++score;
} else {
for (int x = 0; x < WIDTH; ++x) {
board[x][fallTo] = board[x][y];
}
--fallTo;
}
}
for (int x = 0; x < WIDTH; ++x) {
for (int y = fallTo; y >= 0; --y) {
board[x][y] = EMPTY;
}
}
}
protected long getDelay() {
return 20000 / (score + 50);
}
protected ArrayList<Integer> currentShuffle = new ArrayList<Integer>();
protected int currentShuffleIndex;
protected int nextShape() {
if (currentShuffleIndex >= currentShuffle.size()) {
currentShuffleIndex = 0;
currentShuffle.clear();
for (int i = 0; i < SHAPES.length; ++i) {
currentShuffle.add(i);
}
Collections.shuffle(currentShuffle);
}
return currentShuffle.get(currentShuffleIndex++);
}
protected int shape;
protected int orientation;
protected int x;
protected int y;
protected void createShape() {
shape = nextShape();
orientation = 0;
x = (WIDTH - SHAPE_WIDTHS[shape]) / 2;
y = START_Y;
}
protected int[][] getFallingSquares() {
int[][] result = { { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 } };
int[][][] entry = SHAPES[shape];
int[][] offsets = entry[mod(orientation, entry.length)];
for (int i = 0; i < 4; ++i) {
for (int j = 0; j < 2; ++j) {
result[i][j] = (j == 0 ? x : y) + offsets[i][j];
}
}
return result;
}
protected boolean shapeCollides() {
for (int[] square : getFallingSquares()) {
if (isOccupied(square[0], square[1])) {
return true;
}
}
return false;
}
protected void drawShape(Color color) {
for (int[] square : getFallingSquares()) {
board[square[0]][square[1]] = color;
}
}
protected void placeShape() {
drawShape(COLORS[shape]);
JPanel panel = (JPanel)getContentPane();
panel.paintImmediately(0, 0, panel.getWidth(), panel.getHeight());
}
protected void unplaceShape() {
drawShape(EMPTY);
}
protected boolean playing = false;
protected boolean paused = false;
protected boolean isPlaying() {
return playing && !paused;
}
protected void togglePause() {
paused = !paused;
}
protected void beginGame() {
emptyBoard();
createShape();
placeShape();
score = 0;
playing = true;
paused = false;
}
protected void endGame() {
playing = false;
}
protected boolean maybeAdjustShape(int rotation, int dx, int dy) {
if (!isPlaying()) {
return true;
}
unplaceShape();
orientation += rotation;
x += dx;
y += dy;
boolean collides = shapeCollides();
if (collides) {
orientation -= rotation;
x -= dx;
y -= dy;
}
placeShape();
return collides;
}
protected boolean sinkShape() {
if (!isPlaying()) {
return true;
}
if (maybeAdjustShape(0, 0, 1)) {
clearRows();
createShape();
if (shapeCollides()) {
endGame();
} else {
placeShape();
}
return true;
}
return false;
}
protected void dropShape() {
while (!sinkShape())
;
}
protected void rotateShapeLeft() {
maybeAdjustShape(-1, 0, 0);
}
protected void rotateShapeRight() {
maybeAdjustShape(1, 0, 0);
}
protected void shiftShapeLeft() {
maybeAdjustShape(0, -1, 0);
}
protected void shiftShapeRight() {
maybeAdjustShape(0, 1, 0);
}
public Tetris(int width, int height) {
super("Tetris");
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setSize(width, height);
setContentPane(new JPanel() {
@Override
public void paint(Graphics graphics) {
super.paint(graphics);
int xScale = getWidth() / Tetris.WIDTH;
int yScale = getHeight() / Tetris.HEIGHT;
for (int x = 0; x < Tetris.WIDTH; ++x) {
for (int y = 0; y < Tetris.HEIGHT; ++y) {
graphics.setColor(board[x][y]);
graphics.fillRect(xScale * x, yScale * y, xScale, yScale);
}
}
String scoreString = (playing ? ROWS_CLEARED : FINAL_SCORE) + SCORE_SEPARATOR + String.valueOf(score);
graphics.setFont(TEXT_FONT);
graphics.setColor(TEXT_COLOR);
graphics.drawString(scoreString, (getWidth() - graphics.getFontMetrics().stringWidth(scoreString)) / 2,
(getHeight() / 2 - graphics.getFontMetrics().getHeight()) / 2);
}
});
addKeyListener(new KeyListener() {
public void keyPressed(KeyEvent event) {
switch (event.getKeyCode()) {
case ROTATE_LEFT:
rotateShapeLeft();
break;
case ROTATE_RIGHT:
rotateShapeRight();
break;
case SHIFT_LEFT:
shiftShapeLeft();
break;
case SHIFT_RIGHT:
shiftShapeRight();
break;
case DROP:
dropShape();
break;
case PAUSE:
togglePause();
break;
case NEW_GAME:
if (playing) {
endGame();
}
beginGame();
break;
}
}
public void keyReleased(KeyEvent e) {
}
public void keyTyped(KeyEvent e) {
}
});
new Thread() {
@Override
public void run() {
while (true) {
try {
Thread.sleep(getDelay());
sinkShape();
} catch (InterruptedException ignored) {
}
}
}
}.start();
}
public static void main(String... arguments) {
Tetris tetris = new Tetris(WIDTH * DEFAULT_SQUARE_SIZE, HEIGHT * DEFAULT_SQUARE_SIZE);
tetris.setVisible(true);
tetris.beginGame();
}
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment