Compare commits

...

3 Commits

Author SHA1 Message Date
b2eb22a6cc uebung09 small adjustments 2025-06-12 12:10:00 +02:00
57aae3eda6 uebung09 2025-06-12 11:59:41 +02:00
f42c1b23ab angabe ue09 2025-06-10 13:33:42 +02:00
18 changed files with 1037 additions and 0 deletions

View File

@@ -0,0 +1,70 @@
package chess;
import java.util.Iterator;
import iterator.Array2dIterator;
import iterator.SkipNullIterator;
public class Board implements Iterable<Piece> {
private final Piece[][] field = new Piece[8][8];
//private final List<Piece> pieces = new ArrayList<>();
void add(Piece piece) {
if (piece.getBoard() != this)
throw new IllegalArgumentException("wrong board");
final Piece existing = pieceAt(piece.getRow(), piece.getCol());
if (existing != null)
throw new IllegalArgumentException("already occupied by " + existing);
field[piece.getRow() - 1][piece.getCol() - 1] = piece;
//pieces.add(piece);
}
public void printBoard() {
System.out.println(" 1 2 3 4 5 6 7 8");
System.out.println(" +---+---+---+---+---+---+---+---+");
for (int row = 1; row <= 8; row++) {
System.out.print("" + row + " ");
for (int col = 1; col <= 8; col++) {
final Piece p = pieceAt(row, col);
final char c = p == null ? ' ' : p.charRep();
System.out.print("| " + c + " ");
}
System.out.println("|");
System.out.println(" +---+---+---+---+---+---+---+---+");
}
}
public Piece pieceAt(int row, int col) {
return field[row - 1][col - 1];
}
public void check() {
for (Piece p1 : this) {
System.out.println(p1.toString());
for (Piece p2 : this)
if (p1 != p2)
if (p1.canCapture(p2))
System.out.println(" can capture " + p2.toString());
else
System.out.println(" cannot capture " + p2.toString());
}
}
public String toString() {
StringBuilder sb = new StringBuilder("[");
Iterator<Piece> it = iterator();
while (it.hasNext()) {
sb.append(it.next());
if (it.hasNext()) sb.append(", ");
}
sb.append("]");
return sb.toString();
}
@Override
public Iterator<Piece> iterator() {
return new SkipNullIterator<>(new Array2dIterator<>(field));
}
}

View File

@@ -0,0 +1,95 @@
package chess;
import java.io.InputStream;
import java.util.Iterator;
import java.util.NoSuchElementException;
import java.util.Scanner;
public class ChessApp {
private static final String HELP = "h";
private static final String CHECK = "c";
private static final String ABORT = "a";
private static final String WHITE_QUEEN = "q";
private static final String BLACK_QUEEN = "Q";
private static final String WHITE_KNIGHT = "n";
private static final String BLACK_KNIGHT = "N";
private static final String ITERATOR = "i";
private final Scanner scanner;
private final Board board;
public static void main(String[] args) {
new ChessApp(System.in, new Board()).playChess();
}
private ChessApp(InputStream in, Board board) {
scanner = new Scanner(in);
this.board = board;
}
private void playChess() {
board.printBoard();
commandLoop();
System.out.println("Terminated");
}
private void commandLoop() {
while (true) {
System.out.printf("Type in command (%s for help):%n", HELP);
try {
final String command = scanner.next();
if (ABORT.equals(command)) return;
switch (command) {
case HELP -> help();
case CHECK -> board.check();
case BLACK_QUEEN -> addQueen(Color.black);
case WHITE_QUEEN -> addQueen(Color.white);
case BLACK_KNIGHT -> addKnight(Color.black);
case WHITE_KNIGHT -> addKnight(Color.white);
case ITERATOR -> iterate();
default -> System.out.println("Invalid command " + command);
}
}
catch (IllegalArgumentException ex) {
System.out.println(ex.getMessage());
}
catch (NoSuchElementException ex) {
return;
}
}
}
private void addKnight(Color color) {
final int row = scanner.nextInt();
final int col = scanner.nextInt();
new Knight(color, board, row, col);
board.printBoard();
}
private void addQueen(Color color) {
final int row = scanner.nextInt();
final int col = scanner.nextInt();
new Queen(color, board, row, col);
board.printBoard();
}
private void iterate() {
final Iterator<Piece> it = board.iterator();
while (it.hasNext()) {
System.out.println(it.next());
}
}
private void help() {
System.out.println("Commands:");
System.out.println(ABORT + ": terminate the program");
System.out.println(CHECK + ": check the pieces on the board");
System.out.println(WHITE_KNIGHT + " <int> <int>: place a new white knight at specified position");
System.out.println(BLACK_KNIGHT + " <int> <int>: place a new black knight at specified position");
System.out.println(WHITE_QUEEN + " <int> <int>: place a new white queen at specified position");
System.out.println(BLACK_QUEEN + " <int> <int>: place a new black queen at specified position");
System.out.println(ITERATOR + ": iterate over the board and print all pieces to the console");
}
}

View File

@@ -0,0 +1,5 @@
package chess;
public enum Color {
black, white
}

View File

@@ -0,0 +1,28 @@
package chess;
import static java.lang.Math.abs;
public class Knight extends Piece {
public Knight(Color color, Board board, int row, int col) {
super(color, board, row, col);
}
@Override
public char charRep() {
return getColor() == Color.white ? 'n' : 'N';
}
@Override
public String toString() {
return String.format("%s knight at (%d,%d)", getColor(), getRow(), getCol());
}
@Override
public boolean canCapture(Piece other) {
if (getBoard() != other.getBoard() || getColor() == other.getColor())
return false;
final int dr = abs(getRow() - other.getRow());
final int dc = abs(getCol() - other.getCol());
return dr == 2 && dc == 1 || dr == 1 && dc == 2;
}
}

View File

@@ -0,0 +1,38 @@
package chess;
public abstract class Piece {
private Color color;
private Board board;
private int row;
private int col;
protected Piece(Color color, Board board, int row, int col) {
if (row < 1 || row > 8 || col < 1 || col > 8)
throw new IllegalArgumentException("Invalid pos " + row + "/" + col);
this.color = color;
this.board = board;
this.row = row;
this.col = col;
board.add(this);
}
public Color getColor() {
return color;
}
public Board getBoard() {
return board;
}
public int getRow() {
return row;
}
public int getCol() {
return col;
}
public abstract char charRep();
public abstract boolean canCapture(Piece other);
}

View File

@@ -0,0 +1,40 @@
package chess;
import static java.lang.Integer.signum;
import static java.lang.Math.abs;
public class Queen extends Piece {
public Queen(Color color, Board board, int row, int col) {
super(color, board, row, col);
}
@Override
public char charRep() {
return getColor() == Color.white ? 'q' : 'Q';
}
@Override
public String toString() {
return String.format("%s queen at (%d,%d)", getColor(), getRow(), getCol());
}
@Override
public boolean canCapture(Piece other) {
if (getBoard() != other.getBoard() || getColor() == other.getColor())
return false;
if (other.getRow() != getRow() &&
other.getCol() != getCol() &&
abs(other.getRow() - getRow()) != abs(other.getCol() - getCol()))
return false;
final int dr = signum(other.getRow() - getRow());
final int dc = signum(other.getCol() - getCol());
int r = getRow() + dr;
int c = getCol() + dc;
while (r != other.getRow() || c != other.getCol()) {
if (getBoard().pieceAt(r, c) != null) return false;
r += dr;
c += dc;
}
return true;
}
}

View File

@@ -0,0 +1,106 @@
package collection;
import java.util.Iterator;
import java.util.Objects;
class BigSet<E> implements Set<E> {
private final E first;
private final Set<E> rest;
private final int size;
BigSet(E first, Set<E> rest) {
this.first = Objects.requireNonNull(first);
this.rest = Objects.requireNonNull(rest);
size = 1 + rest.size();
}
@Override
public int size() {
return size;
}
@Override
public boolean isEmpty() {
return false;
}
@Override
public boolean contains(Object el) {
return first.equals(el) || rest.contains(el);
}
@Override
public boolean subsetOf(Set<?> other) {
return other.contains(first) && rest.subsetOf(other);
}
@Override
public Set<E> union(Set<E> other) {
return rest.union(other).add(first);
}
@Override
public Set<E> add(E element) {
if (contains(element))
return this;
return new BigSet<>(element, this);
}
@Override
public Set<E> intersection(Set<E> other) {
final Set<E> set = rest.intersection(other);
if (!other.contains(first))
return set;
else if (set.isEmpty())
return SetFactory.create(first);
return new BigSet<>(first, set);
}
@Override
public Iterator<E> iterator() {
return new Iterator<>() {
private int cnt;
private Iterator<E> restIt;
@Override
public boolean hasNext() {
if (cnt == 0) return true;
if (restIt == null) restIt = rest.iterator();
return restIt.hasNext();
}
@Override
public E next() {
if (cnt++ == 0) return first;
if (restIt == null) restIt = rest.iterator();
return restIt.next();
}
};
}
@Override
public String toString() {
final StringBuilder b = new StringBuilder("{");
final Iterator<E> it = iterator();
while (it.hasNext()) {
b.append(it.next());
if (it.hasNext()) b.append(", ");
}
b.append('}');
return b.toString();
}
@Override
public int hashCode() {
return 31 * rest.hashCode() + first.hashCode();
}
@Override
public boolean equals(Object obj) {
if (obj instanceof Set<?>) {
final Set<?> other = (Set<?>) obj;
return this.size() == other.size() && this.subsetOf(other);
}
return false;
}
}

View File

@@ -0,0 +1,76 @@
package collection;
import java.util.Iterator;
import java.util.NoSuchElementException;
class EmptySet<E> implements Set<E> {
@Override
public int size() {
return 0;
}
@Override
public boolean isEmpty() {
return true;
}
@Override
public boolean contains(Object el) {
return false;
}
@Override
public boolean subsetOf(Set<?> other) {
return true;
}
@Override
public Set<E> union(Set<E> other) {
return other;
}
@Override
public Set<E> add(E element) {
return SetFactory.create(element);
}
@Override
public Set<E> intersection(Set<E> other) {
return this;
}
@Override
public Iterator<E> iterator() {
return new Iterator<>() {
@Override
public boolean hasNext() {
return false;
}
@Override
public E next() {
throw new NoSuchElementException();
}
};
}
@Override
public String toString() {
return "{}";
}
@Override
public int hashCode() {
return 31;
}
@Override
public boolean equals(Object obj) {
if (obj instanceof Set<?>) {
@SuppressWarnings("unchecked") final Set<E> other = (Set<E>) obj;
return other.isEmpty();
}
return false;
}
}

View File

@@ -0,0 +1,61 @@
package collection;
/**
* A set of elements that does not contain any element twice.
*
* @param <E> the type of all contained elements.
*/
public interface Set<E> extends Iterable<E> {
/**
* Returns the number of elements stored in this set.
*
* @return the number of elements in this set
*/
int size();
/**
* Returns true if this set contains no elements.
*
* @return true if this set contains no elements
*/
boolean isEmpty();
/**
* Returns true if this set contains the specified element.
*
* @return true if this set contains the specified element.
*/
boolean contains(Object el);
/**
* Returns the union set of this set and the specified set.
*
* @param other a set
* @return the union set of this set and the specified set.
*/
Set<E> union(Set<E> other);
/**
* returns the set resulting from adding the specified element to this set.
*
* @param element an element (must not be null)
* @return the set resulting from adding the specified element to this set.
*/
Set<E> add(E element);
/**
* Returns the intersection of this set and the specified set.
*
* @param other a set
* @return the intersection of this set and the specified set.
*/
Set<E> intersection(Set<E> other);
/**
* Returns true if all elements of this set are contained in the specified set.
*
* @param other a set
* @return true if all elements of this set are contained in the specified set.
*/
boolean subsetOf(Set<?> other);
}

View File

@@ -0,0 +1,29 @@
package collection;
public class SetDemo {
public static void main(String[] args) {
final Set<String> set1 = SetFactory.create();
System.out.println("set1 = " + set1);
final Set<String> set2 = set1.add("foo");
System.out.println("set2 = " + set2);
final Set<String> set3 = set2.add("foo");
System.out.println("set3 = " + set3);
final Set<String> set4 = set3.add("bar");
System.out.println("set4 = " + set4);
final Set<String> set5 = SetFactory.create("foo", "baz", "foo");
System.out.println("set5 = " + set5);
final Set<String> set6 = set4.union(set5);
System.out.println("set6 = " + set6);
final Set<String> set7 = set4.intersection(set5);
System.out.println("set7 = " + set7);
final Set<String> set8 = set5.intersection(set4);
System.out.println("set8 = " + set8);
}
}

View File

@@ -0,0 +1,49 @@
package collection;
public class SetFactory {
// Notwendig um einen korrekten Vergleich von EmptySet zu ermöglichen
private static final EmptySet<Object> EMPTY_SET = new EmptySet<>();
private SetFactory() { /* don't instantiate */ }
/**
* Returns the empty set.
*
* @param <T> the element type of the returned set.
* @return the empty set.
*/
static <T> Set<T> create() {
return (Set<T>) EMPTY_SET;
}
/**
* Returns the singleton set containing the specified element.
*
* @param element an element (must not be null)
* @param <T> the element type of the returned set.
* @return the singleton set containing the specified element.
*/
static <T> Set<T> create(T element) {
return new SingeltonSet<>(element);
}
/**
* Returns a set containing the specified elements. The specified elements may contain equal elements.
*
* @param elems elements of the returned set (may contain equal elements)
* @param <T> the element type of the returned set.
* @return a set containing the specified elements.
*/
static <T> Set<T> create(T... elems) {
if (elems.length == 0) return create();
if (elems.length == 1) return create(elems[0]);
Set<T> result = create();
for (T t : elems) {
result = result.add(t);
}
return result;
}
}

View File

@@ -0,0 +1,89 @@
package collection;
import java.util.Iterator;
import java.util.NoSuchElementException;
import java.util.Objects;
class SingeltonSet<E> implements Set<E> {
private final E element;
SingeltonSet(E element) {
this.element = Objects.requireNonNull(element);
}
@Override
public int size() {
return 1;
}
@Override
public boolean isEmpty() {
return false;
}
@Override
public boolean contains(Object el) {
return element.equals(el);
}
@Override
public boolean subsetOf(Set<?> other) {
return other.contains(element);
}
@Override
public Set<E> union(Set<E> other) {
return other.add(element);
}
@Override
public Set<E> add(E element) {
if (this.element.equals(element))
return this;
return new BigSet<>(element, this);
}
@Override
public Set<E> intersection(Set<E> other) {
return other.contains(element) ? this : SetFactory.create();
}
@Override
public Iterator<E> iterator() {
return new Iterator<>() {
boolean ready = true;
@Override
public boolean hasNext() {
return ready;
}
@Override
public E next() {
if (!ready)
throw new NoSuchElementException();
ready = false;
return element;
}
};
}
@Override
public String toString() {
return "{" + element + "}";
}
@Override
public int hashCode() {
return 47 * element.hashCode();
}
@Override
public boolean equals(Object obj) {
if (obj instanceof Set<?>) {
final Set<?> other = (Set<?>) obj;
return other.size() == 1 && other.contains(element);
}
return false;
}
}

View File

@@ -0,0 +1,38 @@
package iterator;
import java.util.Iterator;
import java.util.NoSuchElementException;
public class Array2dIterator<T> implements Iterator<T> {
private T[][] array;
private int row = 0;
private int col = 0;
public Array2dIterator(T[][] array) {
this.array = array;
}
@Override
public boolean hasNext() {
if (row < array.length) {
if (col >= array[row].length) {
col = 0;
row++;
}
}
if (row < array.length && col < array[row].length) {
return true;
}
return false;
}
@Override
public T next() {
if (!hasNext()) {
throw new NoSuchElementException();
}
return array[row][col++];
}
}

View File

@@ -0,0 +1,97 @@
package iterator;
import java.util.Arrays;
import java.util.Iterator;
import java.util.List;
public class IteratorDemo {
private static void demoArray2dIterator() {
System.out.println("Array2dIterator {{}, {\"foo\", \"bar\"}, {\"baz\"}, {}}");
final String[][] array = {{}, {"foo", "bar"}, {"baz"}, {}};
final Iterator<String> it = new Array2dIterator<>(array);
while (it.hasNext())
System.out.println(it.next());
}
private static void demoArray2dIteratorOnlyEmpty() {
System.out.println("Array2dIterator {{}, {}, {}}");
final String[][] array = {{}, {}, {}};
final Iterator<String> it = new Array2dIterator<>(array);
while (it.hasNext())
System.out.println(it.next());
}
private static void demoArray2dIteratorEmpty() {
System.out.println("Array2dIterator {}");
final String[][] array = {};
final Iterator<String> it = new Array2dIterator<>(array);
while (it.hasNext())
System.out.println(it.next());
}
private static void demoSkipNullIterator() {
System.out.println("SkipNullIterator [\"a\", \"b\", null, \"c\"]");
final Iterator<String> oriIt = Arrays.asList("a", "b", null, "c").iterator();
final Iterator<String> it = new SkipNullIterator<>(oriIt);
while (it.hasNext())
System.out.println(it.next());
}
private static void demoSkipNullIteratorSingleton() {
System.out.println("SkipNullIterator [\"foo\"]");
final Iterator<String> oriIt = List.of("foo").iterator();
final Iterator<String> it = new SkipNullIterator<>(oriIt);
while (it.hasNext())
System.out.println(it.next());
}
private static void demoSkipNullIteratorInfinity() {
System.out.println("SkipNullIterator [\"infinity\", \"infinity\", ...]");
final Iterator<String> oriIt = new Iterator<>() {
@Override
public boolean hasNext() {
return true;
}
@Override
public String next() {
return "infinity";
}
};
final Iterator<String> it = new SkipNullIterator<>(oriIt);
for (int i = 0; i < 10; i++)
System.out.println(i + ": " + it.next());
}
private static void demoPathological() {
System.out.println("SkipNullIterator [null, ..., null, \"infinity\", \"infinity\", ...]");
final Iterator<String> oriIt = new Iterator<>() {
private int ctr;
@Override
public boolean hasNext() {
return true;
}
@Override
public String next() {
return ctr++ > 100000 ? "infinity" : null;
}
};
final SkipNullIterator<String> it = new SkipNullIterator<>(oriIt);
for (int i = 0; i < 10; i++)
System.out.println(i + ": " + it.next());
}
public static void main(String[] args) {
demoArray2dIterator();
demoArray2dIteratorEmpty();
demoArray2dIteratorOnlyEmpty();
demoSkipNullIterator();
demoSkipNullIteratorSingleton();
demoSkipNullIteratorInfinity();
demoPathological();
}
}

View File

@@ -0,0 +1,34 @@
package iterator;
import java.util.Iterator;
import java.util.NoSuchElementException;
public class SkipNullIterator<T> implements Iterator<T> {
private final Iterator<T> iterator;
private T nextObj;
public SkipNullIterator(Iterator<T> iterator) {
this.iterator = iterator;
}
@Override
public boolean hasNext() {
while (nextObj == null && iterator.hasNext()) {
nextObj = iterator.next();
}
return nextObj != null;
}
@Override
public T next() {
if (!hasNext()) {
throw new NoSuchElementException();
}
final T ret = nextObj;
nextObj = null;
return ret;
}
}

View File

@@ -0,0 +1,17 @@
package collection;
import static org.junit.Assert.assertTrue;
import org.junit.Test;
public class SetTest {
@Test
public void testAdd() {
Set<Integer> set = SetFactory.create();
set = set.add(1);
assertTrue(set.contains(1));
set = set.add(3);
assertTrue(set.contains(3));
}
}

View File

@@ -0,0 +1,43 @@
package iterator;
import org.junit.Test;
import java.util.Iterator;
import java.util.NoSuchElementException;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertThrows;
import static org.junit.Assert.assertTrue;
public class Array2dIteratorTest {
@Test
public void testArray2dIterator() {
final String[][] array = {{}, {"foo", "bar"}, {"baz"}, {}};
final Iterator<String> it = new Array2dIterator<>(array);
assertTrue(it.hasNext());
assertEquals("foo", it.next());
assertTrue(it.hasNext());
assertEquals("bar", it.next());
assertTrue(it.hasNext());
assertEquals("baz", it.next());
assertFalse(it.hasNext());
assertThrows(NoSuchElementException.class, it::next);
}
@Test
public void testArray2dIteratorOnlyEmpty() {
final String[][] array = {{}, {}, {}};
final Iterator<String> it = new Array2dIterator<>(array);
assertFalse(it.hasNext());
assertThrows(NoSuchElementException.class, it::next);
}
@Test
public void testArray2dIteratorEmpty() {
final String[][] array = {};
final Iterator<String> it = new Array2dIterator<>(array);
assertFalse(it.hasNext());
assertThrows(NoSuchElementException.class, it::next);
}
}

View File

@@ -0,0 +1,122 @@
package iterator;
import org.junit.Test;
import java.util.Iterator;
import java.util.NoSuchElementException;
import static java.util.Arrays.asList;
import static java.util.Collections.emptyList;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertThrows;
import static org.junit.Assert.assertTrue;
public class SkipNullIteratorTest {
@Test
public void testEmpty() {
final Iterator<Object> it = new SkipNullIterator<>(emptyList().iterator());
assertFalse(it.hasNext());
assertThrows(NoSuchElementException.class, it::next);
}
@Test
public void testNull() {
final Iterator<Object> it = new SkipNullIterator<>(asList(null, null).iterator());
assertFalse(it.hasNext());
assertThrows(NoSuchElementException.class, it::next);
}
@Test
public void testNonNull() {
final Iterator<String> it = new SkipNullIterator<>(asList("foo").iterator());
assertTrue(it.hasNext());
assertEquals("foo", it.next());
assertFalse(it.hasNext());
assertThrows(NoSuchElementException.class, it::next);
}
@Test
public void testMixed() {
final Iterator<String> it = new SkipNullIterator<>(asList(null, "foo", null).iterator());
assertTrue(it.hasNext());
assertEquals("foo", it.next());
assertFalse(it.hasNext());
assertThrows(NoSuchElementException.class, it::next);
}
@Test
public void testMixed2() {
final Iterator<String> oriIt = asList("a", "b", null, "c").iterator();
Iterator<String> it = new SkipNullIterator<>(oriIt);
assertTrue(it.hasNext());
assertEquals("a", it.next());
assertTrue(it.hasNext());
assertEquals("b", it.next());
assertTrue(it.hasNext());
assertEquals("c", it.next());
assertFalse(it.hasNext());
assertThrows(NoSuchElementException.class, it::next);
}
@Test
public void testDontCallInCtor() {
final Iterator<String> dontCallNext = new Iterator<>() {
@Override
public boolean hasNext() {
throw new RuntimeException();
}
@Override
public String next() {
throw new RuntimeException();
}
};
new SkipNullIterator<>(dontCallNext);
}
@Test
public void testSkipNullIteratorInfinity() {
final Iterator<String> oriIt = new Iterator<>() {
@Override
public boolean hasNext() {
return true;
}
@Override
public String next() {
return "infinity";
}
};
final Iterator<String> it = new SkipNullIterator<>(oriIt);
for (int i = 0; i < 1000; i++) {
assertTrue(it.hasNext());
assertEquals("infinity", it.next());
}
}
@Test
public void testPathological() {
final Iterator<String> oriIt = new Iterator<>() {
private int ctr;
@Override
public boolean hasNext() {
return true;
}
@Override
public String next() {
return ctr++ > 100000 ? "infinity" : null;
}
};
final Iterator<String> it = new SkipNullIterator<>(oriIt);
for (int i = 0; i < 1000; i++) {
assertTrue(it.hasNext());
assertEquals("infinity", it.next());
}
}
}