diff --git a/uebung01/Chess.scala b/uebung01/Chess.scala new file mode 100644 index 0000000..2441a60 --- /dev/null +++ b/uebung01/Chess.scala @@ -0,0 +1,161 @@ +package oop.ch01.chess.scala + +import oop.ch01.chess.scala.Color.{black, white} +import oop.ch01.chess.scala.Kind.rook + +import scala.collection.mutable.ArrayBuffer + +enum Color: + case black, white + +enum Kind: + case queen, knight, rook + +class Piece(var kind: Kind, + var color: Color, + var board: Board, + var row: Int, + var col: Int) + +class Board(var pieces: List[Piece]) + +object Chess: + def newPiece(kind: Kind, color: Color, + board: Board, row: Int, col: Int): Piece = + if row < 1 || row > 8 || col < 1 || col > 8 then + throw new IllegalArgumentException("Invalid pos " + row + "/" + col) + val piece = new Piece(kind, color, board, row, col) + add(board, piece) + piece + + def charRep(piece: Piece): Char = piece.kind match + case Kind.queen => queenCharRep(piece) + case Kind.knight => knightCharRep(piece) + case Kind.rook => rookCharRep(piece) + + def toString(piece: Piece): String = piece.kind match + case Kind.queen => queenToString(piece) + case Kind.knight => knightToString(piece) + case Kind.rook => rookToString(piece) + + def canCapture(piece: Piece, other: Piece): Boolean = piece.kind match + case Kind.queen => queenCanCapture(piece, other) + case Kind.knight => knightCanCapture(piece, other) + case Kind.rook => rookCanCapture(piece, other) + + def queenCharRep(piece: Piece): Char = + if piece.color == Color.white then 'q' else 'Q' + + def knightCharRep(piece: Piece): Char = + if piece.color == Color.white then 'n' else 'N' + + def rookCharRep(piece: Piece): Char = + if piece.color == Color.white then 'r' else 'R' + + def queenToString(piece: Piece): String = + "" + piece.color + " queen at (" + piece.row + ", " + piece.col + ")" + + def knightToString(piece: Piece): String = + "" + piece.color + " knight at (" + piece.row + ", " + piece.col + ")" + + def rookToString(piece: Piece): String = + "" + piece.color + " rook at (" + piece.row + ", " + piece.col + ")" + + def queenCanCapture(queen: Piece, other: Piece): Boolean = + if queen.board != other.board || queen.color == other.color then + return false + if other.row != queen.row && + other.col != queen.col && + (other.row - queen.row).abs != + (other.col - queen.col).abs then + return false + val dr: Int = (other.row - queen.row).sign + val dc: Int = (other.col - queen.col).sign + var r: Int = queen.row + dr + var c: Int = queen.col + dc + while r != other.row || c != other.col do + if pieceAt(queen.board, r, c) != null then + return false + r += dr + c += dc + true + + def knightCanCapture(knight: Piece, other: Piece): Boolean = + if knight.board != other.board || + knight.color == other.color then + return false + val dr: Int = (knight.row - other.row).abs + val dc: Int = (knight.col - other.col).abs + dr == 2 && dc == 1 || dr == 1 && dc == 2 + + def rookCanCapture(piece: Piece, other: Piece): Boolean = + if piece.board != other.board || piece.color == other.color then return false + if other.row != piece.row && + other.col != piece.col then + return false + val dr: Int = (other.row - piece.row).sign + val dc: Int = (other.col - piece.col).sign + var r: Int = piece.row + dr + var c: Int = piece.col + dc + while r != other.row || c != other.col do + if pieceAt(piece.board, r, c) != null then + return false + r += dr + c += dc + true + + def newBoard(): Board = + new Board(List()) + + def add(board: Board, piece: Piece): Unit = + if piece.board != board then + throw new IllegalArgumentException("wrong board") + val existing = pieceAt(board, piece.row, piece.col) + if existing != null then + throw new IllegalArgumentException("already occupied by " + + toString(existing)) + piece.board.pieces = piece :: piece.board.pieces + + def toString(board: Board): String = + //"pieces: " + board.pieces + "pieces: " + board.pieces.map(toString) + + def printBoard(board: Board): Unit = + println(" 1 2 3 4 5 6 7 8") + println(" +---+---+---+---+---+---+---+---+") + for row: Int <- 1 to 8 do + print("" + row + " ") + for col: Int <- 1 to 8 do + val p: Piece = pieceAt(board, row, col) + val c: Char = if p == null then ' ' else charRep(p) + print("| " + c + " ") + println("|") + println(" +---+---+---+---+---+---+---+---+") + + def pieceAt(board: Board, row: Int, col: Int): Piece = + for p: Piece <- board.pieces do + if p.row == row && p.col == col then + return p + null + + def check(board: Board): Unit = + for p1: Piece <- board.pieces do + println(toString(p1)) + for p2: Piece <- board.pieces if p1 != p2 do + if canCapture(p1, p2) then + println(" can capture " + toString(p2)) + else + println(" cannot capture " + toString(p2)) + + def main(args: Array[String]): Unit = + val board: Board = newBoard() + val p1: Piece = newPiece(Kind.queen, Color.black, board, 1, 4) + val p2: Piece = newPiece(Kind.queen, Color.white, board, 8, 4) + val p3: Piece = newPiece(Kind.knight, Color.white, board, 3, 3) + val p4: Piece = newPiece(Kind.knight, Color.black, board, 6, 4) + val p5: Piece = newPiece(Kind.rook, white, board, 2,7) + val p6: Piece = newPiece(rook, black, board, 2,1) + println(board) + println(toString(board)) + printBoard(board) + check(board) diff --git a/uebung01/RationalProgram.scala b/uebung01/RationalProgram.scala new file mode 100644 index 0000000..bf3f12b --- /dev/null +++ b/uebung01/RationalProgram.scala @@ -0,0 +1,92 @@ +package oop + +import oop.RationalProgram.Rational + +object RationalProgram: + case class Rational(val numerator: Int, val denominator: Int); + +def newRational(num: Int): Rational = + new Rational(num, 1) + +def newRational(num: Int, denom:Int = 1): Rational = + if (denom == 0) throw new Exception("Nenner darf nicht negativ sein") + reduce(num, denom) + +def reduce(num:Int, denom:Int): Rational = + val newnum = if denom < 0 then -num else num + val newdenom = if denom < 0 then -denom else denom + val g: Int = ggT(newnum.abs , newdenom) + new Rational(newnum / g, newdenom /g) + +def ggT(nom: Int, denom: Int): Int = + if denom == 0 then nom else ggT(denom, nom % denom) + +def getNum(r: Rational): Int = + r.numerator + +def getDenom(r: Rational): Int = + r.denominator + +def add(r1: Rational, r2:Rational): Rational = + newRational(getNum(r1) * getDenom(r2) + getNum(r2) * getDenom(r1), + getDenom(r1) * getDenom(r2)) + +def sub(r1: Rational, r2:Rational): Rational = + newRational(getNum(r1) * getDenom(r2) - getNum(r2) * getDenom(r1), + getDenom(r1) * getDenom(r2)) + +def add(r: Rational, i: Int): Rational = + add(r, newRational(i)) + +def sub(r: Rational, i: Int): Rational = + sub(r, newRational(i)) + +def mult(r1: Rational, r2: Rational): Rational = + newRational(getNum(r1) * getNum(r2), + getDenom(r1) * getDenom(r2)); + +def div(r1: Rational, r2: Rational): Rational = + newRational(getNum(r1) * getDenom(r2), + getDenom(r1) * getNum(r2)); + +def mult(r1: Rational, num: Int): Rational = + mult(r1, newRational(num)) + +def div(r1: Rational, num: Int): Rational = + div(r1, newRational(num)) + +def printRational(r: Rational): Unit = + if (r.denominator == 1) then println(r.numerator) + println(r.numerator + "/" + r.denominator) + +def lessThan(r1: Rational, r2:Rational): Boolean = + val num1 = r1.numerator * r2.denominator + val num2 = r1.denominator * r2.numerator + return num1 < num2 + +def greaterThan(r1: Rational, r2: Rational): Boolean = + val diff = sub(r2, r1) + diff.numerator < 0 + +def greaterThanOrEquals(r1: Rational, r2: Rational): Boolean = + !lessThan(r1,r2) + +def lessThanOrEquals(r1: Rational, r2: Rational): Boolean = + !greaterThan(r1, r2) + +def graterThan(r: Rational, i: Int): Boolean = + greaterThan(r, newRational(i)) + +def isEqual(r1: Rational, r2: Rational): Boolean = + lessThanOrEquals(r1,r2) && greaterThanOrEquals(r1,r2) + +def main(args: Array[String]): Unit = + val one = newRational(1) + val two = newRational(2) + val three = newRational(3) + val four = newRational(4) + + val vierdrittel = div(four, three) + val bruch = div(two, vierdrittel) + val ergebniss = add(one, bruch) + printRational(ergebniss) \ No newline at end of file