diff --git a/uebung04/chess/Board.java b/uebung04/chess/Board.java new file mode 100644 index 0000000..44f4cfa --- /dev/null +++ b/uebung04/chess/Board.java @@ -0,0 +1,54 @@ +package chess; + +import java.util.ArrayList; + +public class Board { + private final Piece[][] field = new Piece[8][8]; + private final ArrayList 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.toString()); + 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 : pieces) { + System.out.println(p1.toString()); + for (Piece p2 : pieces) + 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() { + return pieces.toString(); + } +} diff --git a/uebung04/chess/Chess.java b/uebung04/chess/Chess.java new file mode 100644 index 0000000..3a844d0 --- /dev/null +++ b/uebung04/chess/Chess.java @@ -0,0 +1,15 @@ +package chess; + +public class Chess { + public static void main(String[] args) { + final Board board = new Board(); + final Piece p1 = new Queen(Color.black, board, 1, 4); + final Piece p2 = new Queen(Color.white, board, 8, 4); + final Piece p3 = new Knight(Color.white, board, 3, 3); + final Piece p4 = new Knight(Color.black, board, 6, 4); + System.out.println(board); + System.out.println(board.toString()); + board.printBoard(); + board.check(); + } +} diff --git a/uebung04/chess/ChessTest.java b/uebung04/chess/ChessTest.java new file mode 100644 index 0000000..abba355 --- /dev/null +++ b/uebung04/chess/ChessTest.java @@ -0,0 +1,168 @@ +package chess; + +import org.junit.After; +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; + +import java.io.ByteArrayOutputStream; +import java.io.PrintStream; + +import static org.junit.Assert.assertEquals; + +public class ChessTest { + // Das Zeilenende wird auf Windows-Systemen anders codiert als auf Nicht-Windows-Systemen. + // Die folgende Zeile ermittelt die aktuelle Codierung. + // EOL = "End of Line" + private static final String LS = System.lineSeparator(); + private static final String HE = " 1 2 3 4 5 6 7 8" + LS; + private static final String LI = " +---+---+---+---+---+---+---+---+" + LS; + private static final String EMP = " | | | | | | | | |" + LS; + private static final String WK1 = " | n | | | | | | | |" + LS; + private static final String WQ3 = " | | | q | | | | | |" + LS; + private static final String CO1 = " | | | n | | N | Q | | |" + LS; + private static final String INIT_BOARD = board(EMP, EMP, EMP, EMP, EMP, EMP, EMP, EMP); + private static final String WK61_BOARD = board(EMP, EMP, EMP, EMP, EMP, WK1, EMP, EMP); + private static final String APP1_BOARD = board(EMP, EMP, EMP, EMP, WQ3, CO1, EMP, EMP); + private static final String CHECK_TEXT1 = "white queen at (4, 2)" + LS + + " cannot capture black queen at (8, 6)" + LS + + " cannot capture white knight at (6, 4)" + LS + + "black queen at (8, 6)" + LS + + " cannot capture white queen at (4, 2)" + LS + + " can capture white knight at (6, 4)" + LS + + "white knight at (6, 4)" + LS + + " cannot capture white queen at (4, 2)" + LS + + " cannot capture black queen at (8, 6)" + LS; + private static final String CHECK_TEXT2 = "white knight at (6, 3)" + LS + + " cannot capture black knight at (6, 5)" + LS + + " cannot capture black queen at (6, 6)" + LS + + " cannot capture white queen at (5, 3)" + LS + + "black knight at (6, 5)" + LS + + " cannot capture white knight at (6, 3)" + LS + + " cannot capture black queen at (6, 6)" + LS + + " can capture white queen at (5, 3)" + LS + + "black queen at (6, 6)" + LS + + " cannot capture white knight at (6, 3)" + LS + + " cannot capture black knight at (6, 5)" + LS + + " cannot capture white queen at (5, 3)" + LS + + "white queen at (5, 3)" + LS + + " cannot capture white knight at (6, 3)" + LS + + " cannot capture black knight at (6, 5)" + LS + + " cannot capture black queen at (6, 6)" + LS; + + private static String board(String... s) { + if (s.length != 8) + throw new IllegalArgumentException("Expected 8, but got " + s.length + " arguments"); + StringBuilder sb = new StringBuilder(); + sb.append(HE).append(LI); + for (int i = 1; i <= 8; i++) + sb.append(i).append(s[i - 1]).append(LI); + return sb.toString(); + } + + private Board board; + + private final ByteArrayOutputStream printed = new ByteArrayOutputStream(); + private final PrintStream printStream = new PrintStream(printed, true); + + @Before + public void setup() { + board = new Board(); + printed.reset(); + System.setOut(printStream); + } + + @After + public void tearDown() { + printStream.close(); + } + + @Test + public void testEmpty() { + board.printBoard(); + assertEquals(INIT_BOARD, printed.toString()); + } + + @Test(expected = IllegalArgumentException.class) + public void testInvalidPos1() { + new Knight(Color.white, board, 0, 4); + } + + @Test(expected = IllegalArgumentException.class) + public void testInvalidPos2() { + new Queen(Color.white, board, 0, 4); + } + + @Test + public void testWhiteknight() { + final Piece knight = new Knight(Color.white, board, 6, 1); + checkPieces(1); + assertEquals(knight, board.pieceAt(6, 1)); + board.printBoard(); + assertEquals(WK61_BOARD, printed.toString()); + } + + @Test + public void test3Pieces() { + final Piece queen1 = new Queen(Color.white, board, 4, 2); + final Piece queen2 = new Queen(Color.black, board, 8, 6); + final Piece knight = new Knight(Color.white, board, 6, 4); + Assert.assertFalse(queen1.canCapture(queen2)); + Assert.assertFalse(queen1.canCapture(knight)); + Assert.assertFalse(queen2.canCapture(queen1)); + Assert.assertTrue(queen2.canCapture(knight)); + Assert.assertFalse(knight.canCapture(queen1)); + Assert.assertFalse(knight.canCapture(queen2)); + checkPieces(3); + assertEquals(queen1, board.pieceAt(4, 2)); + assertEquals(queen2, board.pieceAt(8, 6)); + assertEquals(knight, board.pieceAt(6, 4)); + board.check(); + assertEquals(CHECK_TEXT1, printed.toString()); + } + + @Test + public void test4Pieces() { + final Piece knight1 = new Knight(Color.white, board, 6, 3); + final Piece knight2 = new Knight(Color.black, board, 6, 5); + final Piece queen1 = new Queen(Color.black, board, 6, 6); + final Piece queen2 = new Queen(Color.white, board, 5, 3); + checkPieces(4); + assertEquals(knight1, board.pieceAt(6, 3)); + assertEquals(knight2, board.pieceAt(6, 5)); + assertEquals(queen1, board.pieceAt(6, 6)); + assertEquals(queen2, board.pieceAt(5, 3)); + board.printBoard(); + assertEquals(APP1_BOARD, printed.toString()); + Assert.assertFalse(knight1.canCapture(knight2)); + Assert.assertFalse(knight1.canCapture(queen1)); + Assert.assertFalse(knight1.canCapture(queen2)); + Assert.assertFalse(knight2.canCapture(knight1)); + Assert.assertFalse(knight2.canCapture(queen1)); + Assert.assertTrue(knight2.canCapture(queen2)); + Assert.assertFalse(queen1.canCapture(knight1)); + Assert.assertFalse(queen1.canCapture(knight2)); + Assert.assertFalse(queen1.canCapture(queen2)); + Assert.assertFalse(queen2.canCapture(knight1)); + Assert.assertFalse(queen2.canCapture(knight2)); + Assert.assertFalse(queen2.canCapture(queen1)); + printed.reset(); + board.check(); + assertEquals(CHECK_TEXT2, printed.toString()); + } + + private void checkPieces(int expectedNumPieces) { + int numPieces = 0; + for (int row = 1; row < 9; row++) + for (int col = 1; col < 9; col++) + if (board.pieceAt(row, col) != null) + numPieces++; + assertEquals(expectedNumPieces, numPieces); + } + + @Test + public void testRunWithErrors() { + final Piece rook = new Rook(Color.white, board, 1, 1); + assertEquals(rook, board.pieceAt(1, 1)); + } +} \ No newline at end of file diff --git a/uebung04/chess/Color.java b/uebung04/chess/Color.java new file mode 100644 index 0000000..cbca86f --- /dev/null +++ b/uebung04/chess/Color.java @@ -0,0 +1,5 @@ +package chess; + +public enum Color { + black, white +} diff --git a/uebung04/chess/Knight.java b/uebung04/chess/Knight.java new file mode 100644 index 0000000..2e8bbff --- /dev/null +++ b/uebung04/chess/Knight.java @@ -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 "" + getColor() + " knight at (" + 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; + } +} diff --git a/uebung04/chess/Piece.java b/uebung04/chess/Piece.java new file mode 100644 index 0000000..8dbd751 --- /dev/null +++ b/uebung04/chess/Piece.java @@ -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); +} diff --git a/uebung04/chess/Queen.java b/uebung04/chess/Queen.java new file mode 100644 index 0000000..e203c73 --- /dev/null +++ b/uebung04/chess/Queen.java @@ -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 "" + getColor() + " queen at (" + 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; + } +} diff --git a/uebung04/tournament/TournamentTest.java b/uebung04/tournament/TournamentTest.java new file mode 100644 index 0000000..8e8a6a3 --- /dev/null +++ b/uebung04/tournament/TournamentTest.java @@ -0,0 +1,134 @@ +package tournament; + +import org.junit.Before; +import org.junit.Test; + +import java.util.Collection; +import java.util.HashSet; +import java.util.Set; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertThrows; + +public class TournamentTest { + + private static final String BORGHOFF = "Prof. Borghoff"; + private static final String HOMMEL = "Prof. Hommel"; + private static final String KOCH = "Prof. Koch"; + private static final String MINAS = "Prof. Minas"; + private static final String BUCHENRIEDER = "Prof. Buchenrieder"; + private static final String DREO = "Prof. Dreo"; + private static final String ROSE = "Prof. Rose"; + private static final String SIEGLE = "Prof. Siegle"; + private static final String TEEGE = "Prof. Teege"; + private static final Set SET1 = Set.of(BORGHOFF, HOMMEL, KOCH, MINAS, BUCHENRIEDER, DREO, ROSE, SIEGLE, TEEGE); + private static final Set SET2 = Set.of(BORGHOFF, MINAS, SIEGLE, HOMMEL, DREO); + private static final Set SET3 = Set.of(BORGHOFF, MINAS, SIEGLE); + private static final Set SET4 = Set.of(MINAS, SIEGLE); + private static final Set SET5 = Set.of(MINAS); + + private Tournament tournament; + private Game r1s1; + private Game r1s2; + private Game r1s3; + private Game r1s4; + private Game r2s1; + private Game r2s2; + private Game r3s1; + private Game r4s1; + + @Before + public void setup() { + r1s1 = new SeededGame(HOMMEL, KOCH); + r1s2 = new SeededGame(MINAS, BUCHENRIEDER); + r1s3 = new SeededGame(DREO, ROSE); + r1s4 = new SeededGame(SIEGLE, TEEGE); + r2s1 = new ByeGame(BORGHOFF, r1s1); + r2s2 = new OrdinaryGame(r1s2, r1s3); + r3s1 = new OrdinaryGame(r2s1, r2s2); + r4s1 = new OrdinaryGame(r3s1, r1s4); + tournament = new Tournament("UniBw Sportschießen", r4s1); + } + + @Test + public void testBeforeFirstRound() { + assertEquals(SET1, asSet(tournament.getAllPlayers())); + assertEquals(SET1, asSet(tournament.getRemainingPlayers())); + } + + @Test + public void testFirstRound() { + r1s1.setWinner(HOMMEL); + r1s2.setWinner(MINAS); + r1s3.setWinner(DREO); + r1s4.setWinner(SIEGLE); + assertEquals(SET1, asSet(tournament.getAllPlayers())); + assertEquals(SET2, asSet(tournament.getRemainingPlayers())); + } + + @Test + public void testSecondRound() { + r1s1.setWinner(HOMMEL); + r1s2.setWinner(MINAS); + r1s3.setWinner(DREO); + r1s4.setWinner(SIEGLE); + r2s1.setWinner(BORGHOFF); + r2s2.setWinner(MINAS); + assertEquals(SET1, asSet(tournament.getAllPlayers())); + assertEquals(SET3, asSet(tournament.getRemainingPlayers())); + } + + @Test + public void testThirdRound() { + r1s1.setWinner(HOMMEL); + r1s2.setWinner(MINAS); + r1s3.setWinner(DREO); + r1s4.setWinner(SIEGLE); + r2s1.setWinner(BORGHOFF); + r2s2.setWinner(MINAS); + r3s1.setWinner(MINAS); + assertEquals(SET1, asSet(tournament.getAllPlayers())); + assertEquals(SET4, asSet(tournament.getRemainingPlayers())); + } + + @Test + public void testCompleteTournament() { + r1s1.setWinner(HOMMEL); + r1s2.setWinner(MINAS); + r1s3.setWinner(DREO); + r1s4.setWinner(SIEGLE); + r2s1.setWinner(BORGHOFF); + r2s2.setWinner(MINAS); + r3s1.setWinner(MINAS); + r4s1.setWinner(MINAS); + assertEquals(SET1, asSet(tournament.getAllPlayers())); + assertEquals(SET5, asSet(tournament.getRemainingPlayers())); + } + + @Test + public void testException() { + r1s1.setWinner(HOMMEL); + r1s2.setWinner(MINAS); + r1s3.setWinner(DREO); + r1s4.setWinner(SIEGLE); + r2s1.setWinner(BORGHOFF); + r2s2.setWinner(MINAS); + r3s1.setWinner(MINAS); + assertThrows(IllegalArgumentException.class, () -> r4s1.setWinner(BUCHENRIEDER)); + } + + @Test(expected = IllegalStateException.class) + public void testException2() { + r4s1.setWinner(MINAS); + } + + @Test + public void testException3() { + r1s1.setWinner(HOMMEL); + assertThrows(IllegalStateException.class, () -> r1s1.setWinner(HOMMEL)); + } + + private static Set asSet(Collection collection) { + return new HashSet<>(collection); + } +}