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

Added starter code for Lab 8

parent c032e52b
No related branches found
No related tags found
No related merge requests found
# 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