This commit is contained in:
Ulf Gebhardt 2011-10-18 11:52:59 +02:00
parent f06e000fb1
commit 295ef11163
140 changed files with 15240 additions and 0 deletions

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@ -0,0 +1,11 @@
;; The first three lines of this file were inserted by DrScheme. They record metadata
;; about the language level of this file in a form that our tools can easily process.
#reader(lib "htdp-beginner-reader.ss" "lang")((modname contract) (read-case-sensitive #t) (teachpacks ()) (htdp-settings #(#t constructor repeating-decimal #f #t none #f ())))
;;Contract: NAME: PARAMTYPE1, PARAMTYPE2 >>> RESULTTYPE
;;Purpose: X
;;Example:
;;Definition:
(define ()
)
;;Test

View File

@ -0,0 +1,113 @@
;; The first three lines of this file were inserted by DrScheme. They record metadata
;; about the language level of this file in a form that our tools can easily process.
#reader(lib "htdp-beginner-reader.ss" "lang")((modname circle) (read-case-sensitive #t) (teachpacks ()) (htdp-settings #(#t constructor repeating-decimal #f #t none #f ())))
;; Exercise #01
;; (c) Ulf Gebhardt
;;Contract: make-point: number, number >>> point
;;Purpose: Struct to store two numbers, a x and a y value.
;;Example: (make-point 1 1)
;; (make-point 2 -1)
;;Definition:
(define-struct point(x y))
;;Contract: point_point_distance: point, point >>> number
;;Purpose: Calculates distance between two points with sqrt(sqr(y1 - y2) + sqr(x1 - x2))
;;Example: (point_point_distance (make-point 1 1) (make-point 2 -1))
;; (point_point_distance (make-point 1 5) (make-point -2 1))
;;Definition:
(define (point_point_distance p1 p2)
(sqrt (+ (sqr (- (point-y p1) (point-y p2)))
(sqr (- (point-x p1) (point-x p2)))
)
)
)
;;Test
(check-within (point_point_distance (make-point 1 1) (make-point 2 -1)) 2.23 2.24)
(check-expect (point_point_distance (make-point 1 5) (make-point -2 1)) 5)
;;Contract: make-circle: point, number >>> circle
;;Purpose: Circle Struct, containing a point and a radius value to describe a circle.
;; Please notice that radius has to be >= 0, since there is no circle with radius < 0.
;; If you use radius=0 the struct describes a single point - think of using the point struct.
;;Example: (make-circle (make-point 1 1) 5)
;; (make-circle (make-point 2 -1) 1)
;;Definition:
(define-struct circle(point radius)
)
;;Contract: circle_contains_circle: circle, circle >>> bool
;;Purpose: Calculates if a circle c1 contains the second circle c2 with all points of c2.
;; Uses func point_point_distance. Returns true if c2 is completly within c1; false if not.
;;Example: (circle_contains_circle (make-circle (make-point 1 1) 5) (make-circle (make-point 2 -1) 1))
;; (circle_contains_circle (make-circle (make-point 2 2) 1) (make-circle (make-point -2 -1) 2))
;;Definition:
(define (circle_contains_circle c1 c2)
(if (> (circle-radius c2) (circle-radius c1)) ;;cond
false ;;if
(if (> (+ (point_point_distance (circle-point c1) (circle-point c2)) (circle-radius c2)) (circle-radius c1)) ;; cond
false ;;if
true ;; else
)
)
)
;;Test
(check-expect (circle_contains_circle (make-circle (make-point 1 1) 5) (make-circle (make-point 2 -1) 1)) true)
(check-expect (circle_contains_circle (make-circle (make-point 2 2) 1) (make-circle (make-point -2 -1) 2)) false)
;;Contract: circle_contains_point: circle, point >>> bool
;;Purpose: Calculates if a circle c1 contains the point p1. Uses the func point_point_distance.
;, Returns true if point is within circle; false if not.
;;Example: (circle_contains_point (make-circle (make-point 1 1) 5) (make-point 1 1))
;; (circle_contains_point (make-circle (make-point 2 2) 5) (make-point -5 1))
;;Definition:
(define (circle_contains_point c1 p1)
(if (<= (point_point_distance (circle-point c1) p1) (circle-radius c1)) ;;cond
true ;;if
false ;;else
)
)
;;Test
(check-expect (circle_contains_point (make-circle (make-point 1 1) 5) (make-point 1 1)) true)
(check-expect (circle_contains_point (make-circle (make-point 2 2) 5) (make-point -5 1)) false)
;;Contract: circle-contains-circle: number, number, number, number, number, number, number >>> bool
;;Purpose: Does the same as circle_contains_circle, but constructs needed circle and points first.
;; Therefore there are much more parameters - this func exists to match the exercise-requirements
;; Param-sequence: c1x c1y c1r c2x c2y c2r
;; For more info look at circle_contains_circle
;;Example: (circle-contains-circle 1 1 5 2 -1 1)
;; (circle-contains-circle 2 2 1 -2 -1 2)
;;Definition:
(define (circle-contains-circle c1_x c1_y c1_r c2_x c2_y c2_r)
(circle_contains_circle (make-circle (make-point c1_x c1_y) c1_r)
(make-circle (make-point c2_x c2_y) c2_r)
)
)
;;Test
(check-expect (circle-contains-circle 1 1 5 2 -1 1) true)
(check-expect (circle-contains-circle 2 2 1 -2 -1 2) false)
;;Contract: circle-contains-point: number, number, number, number, number >>> bool
;;Purpose: Does the same as circle_contains_point, but constructs needed circles and points first.
;; Therefore there are much more parameters - this func exists to match the exercise-requirements
;; Param-sequence: c1x c1y c1r p1x p1y.
;; For more info look at circle_contains_point
;;Example: (circle-contains-point 1 1 5 1 1)
;; (circle-contains-point 2 2 5 -5 1)
;;Definition:
(define (circle-contains-point c_x c_y c_r p_x p_y)
(circle_contains_point (make-circle (make-point c_x c_y) c_r)
(make-point p_x p_y)
)
)
;;Test
(check-expect (circle-contains-point 1 1 5 1 1) true)
(check-expect (circle-contains-point 2 2 5 -5 1) false)

View File

@ -0,0 +1,11 @@
;; The first three lines of this file were inserted by DrScheme. They record metadata
;; about the language level of this file in a form that our tools can easily process.
#reader(lib "htdp-beginner-reader.ss" "lang")((modname point) (read-case-sensitive #t) (teachpacks ()) (htdp-settings #(#t constructor repeating-decimal #f #t none #f ())))
;;Contract: point: number, number >>> point
;;Purpose: X
;;Example:
;;Definition:
(define-struct point(x y))
;;Test
(make-point 1 1)

View File

View File

@ -0,0 +1,105 @@
;; The first three lines of this file were inserted by DrScheme. They record metadata
;; about the language level of this file in a form that our tools can easily process.
#reader(lib "htdp-beginner-abbr-reader.ss" "lang")((modname students) (read-case-sensitive #t) (teachpacks ()) (htdp-settings #(#t constructor repeating-decimal #f #t none #f ())))
;;Contract: make-student: number, symbol >>> student
;;Purpose: Represents data of a student;
;; id = student-id, fos = fieldofstudy
;;Example: (make-student 1 'inf)
;; (make-student 2 'winf)
;;Definition:
(define-struct student(id fos))
;;Purpose: A list with some sample-students
(define some-students
(list (make-student 13 'inf)
(make-student 532 'winf)
(make-student 352 'ce)
(make-student 54 'inf)
(make-student 256 'ist)
)
)
;;Purpose: A list with some sample-fos
(define some-dist
(list 'inf 'winf 'ce 'ist)
)
;;Purpose: A second list with some sample-fos
(define some-more-dist
(list 'winf 'ce)
)
;;Conmtract: count-students-for: (listof student) symbol >>> number
;;Purpose: Returns the number of students (provided by the given list of students)
;; who are in the fos given by fos-param.
;; Is recursiv
;;Example: (count-students-for some-students 'inf)
;; (count-students-for some-students 'winf)
;;Definition:
(define (count-students-for slist fos)
(if (and (cons? slist)
(student? (first slist))
(symbol? fos)
) ;;cond
(if (symbol=? (student-fos (first slist)) fos) ;;cond
(+ 1
(count-students-for (rest slist) fos)
) ;;if
(count-students-for (rest slist) fos) ;; else
);;if
0;;else
)
)
;;Test
(check-expect (count-students-for some-students 'inf) 2)
(check-expect (count-students-for some-students 'winf) 1)
;;Contract: count-student-dist: (listof student), (listof symbol) >>> (listof number)
;;Purpose: Returns a list of numbers, representing the numbersof students in fos.
;; Order of the numbers is given by the order of the fos in foslist-parameter.
;; Uses count-students-for; Is recursiv
;;Example: (count-student-dist some-students some-dist)
;; (count-student-dist some-students some-more-dist)
;;Definition:
(define (count-student-dist slist foslist)
(if (cons? foslist) ;;cond ;;Do not check slist - it is checked in count-students-for
(append (list (count-students-for slist (first foslist))) ;;Append listelemnet
(count-student-dist slist (rest foslist))
) ;;if
(list) ;;else (empty list)
)
)
;;Test
(check-expect (count-student-dist some-students some-dist) (list 2 1 1 1))
(check-expect (count-student-dist some-students some-more-dist) (list 1 1))
;;Contract: print-student-list: (listof student), (listof symbol) >>> string
;;Purpose: Constructs a string of the following form:
;; fos: number fos2: number
;; Uses count-students-for; Is recursiv
;;Notice: Could have used count-student-dist instead of count-students-for
;; But I think this is much more simple.
;;Example: (print-student-list some-students some-dist)
;; (print-student-list some-students some-more-dist)
;;Definition:
(define (print-student-list slist symlist)
(if (cons? symlist);;cond ;;Do not check slist - it is checked in count-students-for
(string-append (symbol->string (first symlist))
": "
(number->string (count-students-for slist (first symlist)))
" "
(print-student-list slist (rest symlist))
);;if ("fos: number ")
"" ;;else (empty string)
)
)
;;Test
(check-expect (print-student-list some-students some-dist) "inf: 2 winf: 1 ce: 1 ist: 1 ")
(check-expect (print-student-list some-students some-more-dist) "winf: 1 ce: 1 ")

View File

@ -0,0 +1,24 @@
;; The first three lines of this file were inserted by DrScheme. They record metadata
;; about the language level of this file in a form that our tools can easily process.
#reader(lib "htdp-beginner-abbr-reader.ss" "lang")((modname u02) (read-case-sensitive #t) (teachpacks ()) (htdp-settings #(#t constructor repeating-decimal #f #t none #f ())))
(define A (list (cons 1 empty)(list 7) 9))
(define B (cons (cons 42 empty) (list 'Hello'world'!)))
;;Contract : list-length: list >>> number
;;Purpose : calculates the length of a list. Uses recursion
;;Example : (list-length A)
;; (list-length B)
;;Implementation
(define (list-length l)
(if (empty? l) ;;if
0 ;;if
(+ 1 (list-length (first l)) (list-length (rest l)))
)
)
;;Test
(list-length A)
(list-length B)
;;(check-expect (list-length A) 3)
;;(check-expect (list-length B) 2)

View File

@ -0,0 +1,76 @@
;; The first three lines of this file were inserted by DrScheme. They record metadata
;; about the language level of this file in a form that our tools can easily process.
#reader(lib "htdp-beginner-abbr-reader.ss" "lang")((modname u02) (read-case-sensitive #t) (teachpacks ()) (htdp-settings #(#t constructor repeating-decimal #f #t none #f ())))
(define A (list (cons 1 empty)(list 7) 9))
(define B (cons (cons 42 empty) (list 'Hello'world'!)))
;;Contract : list-length: list >>> number
;;Purpose : calculates the length of a list. Uses recursion
;;Example : (list-length A)
;; (list-length B)
;;Implementation
(define (list-length l)
(if (empty? l) ;;if
0 ;;if
(if (cons? l)
(+ (list-length (first l)) (list-length (rest l)))
1
)
)
)
;;Test
(check-expect (list-length A) 3)
(check-expect (list-length B) 4)
;;Contract : contains?: list, symbol >>> bool
;;Purpose : checks if symbol is in list
;;Example : (contains? A 'Hello)
;; (contains? B 'Hello)
;;Implementation
(define (contains? l s)
(if (cons? l)
(if (contains? (first l) s)
true
(contains? (rest l) s)
)
(if (symbol? l)
(if (symbol=? l s)
true
false
)
false
)
)
)
;;Test
(check-expect (contains? A 'Hello) false)
(check-expect (contains? B 'Hello) true)
(define C (list '(a a b)))
(define D (list '(a a b) (list '(c b) (list '(c d)))))
;;Contract : remove-duplicates: list symbol >>> list
;;Purpose : removes all duplicates in a list
;;Example : (remove-duplicates C)
;; (remove-duplicates D)
;;Implementation
(define (remove-duplicates l s)
(if (= s ' )
(if
(
)
)
(define (remove-duplicate l i)
(
)
;;Test
(check-expect (remove-duplicates C ' ) (list '(a b)))
(check-expect (remove-duplicates D ' ) (list '(a b) (list 'c (list 'd))))

View File

@ -0,0 +1,131 @@
;; The first three lines of this file were inserted by DrScheme. They record metadata
;; about the language level of this file in a form that our tools can easily process.
#reader(lib "htdp-beginner-reader.ss" "lang")((modname trees) (read-case-sensitive #t) (teachpacks ()) (htdp-settings #(#t constructor repeating-decimal #f #t none #f ())))
;;(c) Ulf Gebhardt
;;API-Def
;;
;;
;; a bool-direct represents direct boolean values
;; value: direct-boolean - a boolean value that can be either
;; 1. a boolean value, i.e., something that evaluates to true or false,
;; 2. or a symbol that represents one of the variables 'A...'F
(define-struct bool-direct (value))
;; bool-unary represents unary boolean operators
;; op: symbol - a legal unary operator (e.g., 'not)
;; param: bool-tree - a boolean expression
(define-struct bool-unary (op param))
;; bool-binary represents binary boolean operators
;; op: symbol - a legal binary operator (e.g., 'and, 'or)
;; left: bool-tree - the left (2.) part of the binary boolean expression
;; right: bool-tree - the right (3.) part of the binary boolean expr.
(define-struct bool-binary (op left right))
;; lookup-variable: symbol -> boolean
;; looks up the value of the symbol passed in
;; if undefined, returns an error
;; example: (lookup-variable 'A) is true
(define (lookup-variable variable)
(cond
[(symbol=? variable 'A) true]
[(symbol=? variable 'B) false]
[(symbol=? variable 'C) true]
[(symbol=? variable 'D) false]
[(symbol=? variable 'E) false]
[(symbol=? variable 'F) true]
[else (error 'lookup-variable
(string-append "Variable "
(symbol->string variable)
" unknown"))]
))
;; Tests
(check-expect (lookup-variable 'A) true)
(check-expect (lookup-variable 'B) false)
(check-expect (lookup-variable 'C) true)
(check-expect (lookup-variable 'D) false)
(check-expect (lookup-variable 'E) false)
(check-expect (lookup-variable 'F) true)
(check-error (lookup-variable 'G) "lookup-variable: Variable G unknown")
;;-------------------------------------------------------------------------------------------------------
;;-------------------------------------------CODE--------------------------------------------------------
;;-------------------------------------------------------------------------------------------------------
;; a bool-input is either
;; 1. a boolean value (true,false,an expression evaluated to true/false)
;; 2. a symbol 'A...'F for a boolean variable
;; 3. (list 'not b), where b is a bool-input
;; 4. (list 'and b1 b2), where b1 and b2 have type bool-input
;; 5. (list 'or b1 b2), where b1 and b2 have type bool-input
(define (bool-input value)
(if (or (bool? value)
(symbol? value)
(cons? value))
value ;;return value
error("Get lost, this suxxs") ;;Change that shit
)
)
;; a bool-tree is either
;; 1. a bool-direct (boolean value or boolean variable)
;; 2. a bool-unary (unary operator, i.e., 'not)
;; 3. a bool-binary (binary operator, e.g., 'and, 'or)
(define-struct bool_tree (r a b))
(define (bool-tree r a b)
)
;;
;;
;;
;;(define (input->tree input)
;; (cond [(bool? input)]
;; []
;;)
;; Tests
(check-expect (input->tree (list 'and 'A true))
(make-bool-binary 'and
(make-bool-direct 'A)
(make-bool-direct true)))
(check-expect (input->tree (list 'or (list 'not 'A) 'B))
(make-bool-binary 'or
(make-bool-unary 'not
(make-bool-direct 'A))
(make-bool-direct 'B)))
;;
;;
;;
;;
(define (eval-unary unary-op unary-param) ...)
;; Tests
(check-expect (eval-unary 'not true) false)
;;
;;
;;
;;
(define (eval-binary op left right) ...)
;; Tests
(check-expect (eval-binary 'and true true) true)
(check-expect (eval-binary 'or false true) true)
;;
;;
;;
(define (bool-tree->boolean a-bool-tree) ...)
;; Tests
(check-expect (bool-tree->boolean (input->tree (list 'and 'A true)))
true)
(check-expect (bool-tree->boolean (input->tree (list 'or (list 'not 'A) 'B)))
false)

View File

@ -0,0 +1,314 @@
;; The first three lines of this file were inserted by DrScheme. They record metadata
;; about the language level of this file in a form that our tools can easily process.
#reader(lib "htdp-beginner-reader.ss" "lang")((modname trees) (read-case-sensitive #t) (teachpacks ()) (htdp-settings #(#t constructor repeating-decimal #f #t none #f ())))
;;(c) Ulf Gebhardt
;; Ich benutze in der ganzen Aufgabe kein (local ...)
;; Das mache ich bewusst, denn ich finde es sehr unübersichtlich,
;; wenn alle Funktion in er Prozedur definiert sind.
;; Wie man das Problem der Namensraumverschmutzung auch ohne
;; (local ...) lösen kann finden Sie am Ende der Datei (Aufgabe 5.5)
;; a bool-input is either
;; 1. a boolean value (true,false,an expression evaluated to true/false)
;; 2. a symbol 'A...'F for a boolean variable
;; 3. (list 'not b), where b is a bool-input
;; 4. (list 'and b1 b2), where b1 and b2 have type bool-input
;; 5. (list 'or b1 b2), where b1 and b2 have type bool-input
;; a bool-tree is either
;; 1. a bool-direct (boolean value or boolean variable)
;; 2. a bool-unary (unary operator, i.e., 'not)
;; 3. a bool-binary (binary operator, e.g., 'and, 'or)
;; a bool-direct represents direct boolean values
;; value: direct-boolean - a boolean value that can be either
;; 1. a boolean value, i.e., something that evaluates to true or false,
;; 2. or a symbol that represents one of the variables 'A...'F
(define-struct bool-direct (value))
;; bool-unary represents unary boolean operators
;; op: symbol - a legal unary operator (e.g., 'not)
;; param: bool-tree - a boolean expression
(define-struct bool-unary (op param))
;; bool-binary represents binary boolean operators
;; op: symbol - a legal binary operator (e.g., 'and, 'or)
;; left: bool-tree - the left (2.) part of the binary boolean expression
;; right: bool-tree - the right (3.) part of the binary boolean expr.
(define-struct bool-binary (op left right))
;; lookup-variable: symbol -> boolean
;; looks up the value of the symbol passed in
;; if undefined, returns an error
;; example: (lookup-variable 'A) is true
(define (lookup-variable variable)
(cond
[(symbol=? variable 'A) true]
[(symbol=? variable 'B) false]
[(symbol=? variable 'C) true]
[(symbol=? variable 'D) false]
[(symbol=? variable 'E) false]
[(symbol=? variable 'F) true]
[else (error 'lookup-variable
(string-append "Variable "
(symbol->string variable)
" unknown"))]
))
;; Tests
(check-expect (lookup-variable 'A) true)
(check-expect (lookup-variable 'B) false)
(check-expect (lookup-variable 'C) true)
(check-expect (lookup-variable 'D) false)
(check-expect (lookup-variable 'E) false)
(check-expect (lookup-variable 'F) true)
(check-error (lookup-variable 'G) "lookup-variable: Variable G unknown")
;;-------------------------------------------------------------------------------------------------------
;;-------------------------------------------CODE--------------------------------------------------------
;;-------------------------------------------------------------------------------------------------------
;; bool_not, bool_and, bool_or are constants
;; represtenting the textual-expression of
;; the named boolean operator
;;(define bool_equal 'equal)
(define bool_not 'not)
(define bool_and 'and)
(define bool_or 'or )
;; Contract: sym_is_unary: symbol -> boolean
;; Purpose: Tests if the given symbol sym is a unary operator
;; Examples: (sym_is_unary 'not)
;; (sym_is_unary 'equal)
(define (sym_is_unary sym)
(cond [(symbol=? sym bool_not) true]
;;[(symbol=? sym bool_equal) true]
[else false]
)
)
;;Test
(check-expect (sym_is_unary 'not) true)
(check-expect (sym_is_unary 'equal) false)
;; Contract: sym_is_binary: symbol -> boolean
;; Purpose: Tests if the given symbol sym is a binary operator
;; Examples: (sym_is_binary 'and)
;; (sym_is_binary 'equal)
(define (sym_is_binary sym)
(cond [(symbol=? sym bool_and) true]
[(symbol=? sym bool_or) true]
[else false]
)
)
;;Test
(check-expect (sym_is_binary 'and) true)
(check-expect (sym_is_binary 'equal) false)
;; Contract: input-tree: bool-input -> bool-tree
;; Purpose: Converts a bool-input into a bool-tree
;; Notice bool-input is not a struct, but
;; can be many things!
;; Examples: (input->tree (list 'and 'A true))
;; (input->tree (list 'or (list 'not 'A) 'B))
(define (input->tree input)
(if (cons? input)
(cond [(sym_is_unary (first input)) (make-bool-unary (first input) (input->tree (rest input)))]
[(sym_is_binary (first input)) (make-bool-binary (first input) (input->tree (second input)) (input->tree (third input)))]
[(or (symbol? (first input)) (boolean? (first input))) (make-bool-direct (first input))]
[else empty] ;;empty
)
(if (or (symbol? input) (boolean? input))
(make-bool-direct input)
empty
)
)
)
;; Test
(check-expect (input->tree (list 'and 'A true))
(make-bool-binary 'and
(make-bool-direct 'A)
(make-bool-direct true)))
(check-expect (input->tree (list 'or (list 'not 'A) 'B))
(make-bool-binary 'or
(make-bool-unary 'not
(make-bool-direct 'A))
(make-bool-direct 'B)))
;; Contract: eval_not: bool -> bool
;; Purpose: evaluates not operator on given boolean bool.
;; Errors: "Not a Bool"
;; Examples: (eval_not true)
;; (eval_not false)
(define (eval_not bool)
(if (boolean? bool)
(if bool
false
true
)
(error 'eval_not "Not a Bool")
)
)
;; Test
(check-expect (eval_not true) false)
(check-expect (eval_not false) true)
;; Contract: eval-unary: symbol boolean -> boolean
;; Purpose: evalutes the result of an unary-operation on given unary-param.
;; Errors: "Not supported bool-unary"
;; "Not bool-unary"
;; Examples: (eval-unary 'not true)
;; (eval-unary 'not false)
(define (eval-unary unary-op unary-param)
(if (sym_is_unary unary-op)
(cond [(symbol=? bool_not unary-op) (eval_not unary-param)]
[else (error 'eval-unary "Not supported bool-unary")]
)
(error 'eval-unary "Not a bool-unary")
)
)
;; Test
(check-expect (eval-unary 'not true) false)
(check-expect (eval-unary 'not false) true)
;; Contract: eval_and: boolean boolean -> boolean
;; Purpose: evaluates and operator on given booleans bool1, bool2.
;; Errors: "Not a Bool"
;; Examples: (eval_and true true)
;; (eval_and false false)
(define (eval_and bool1 bool2)
(if (and (boolean? bool1) (boolean? bool2))
(if (and bool1 bool2)
true
false
)
(error 'eval_and "Not a Bool")
)
)
;; Test
(check-expect (eval_and true true) true)
(check-expect (eval_and false false) false)
;; Contract: eval_or: boolean boolean -> boolean
;; Purpose: evaluates or operator on given booleans bool1, bool2.
;; Errors: "Not a Bool"
;; Examples: (eval_or true true)
;; (eval_or false false)
(define (eval_or bool1 bool2)
(if (and (boolean? bool1) (boolean? bool2))
(if (or bool1 bool2)
true
false
)
(error 'eval_or "Not a Bool")
)
)
;; Test
(check-expect (eval_or true true) true)
(check-expect (eval_or false false) false)
;; Contract: eval-binary: symbol boolean boolean -> boolean
;; Purpose: evalutes the result of an binary-operation on given binary-param.
;; Error: "Not supported Binary Operator"
;; "Not a Binary Operator"
;; Examples: (eval-binary 'and true true)
;; (eval-unary 'or false true)
(define (eval-binary op left right)
(if (sym_is_binary op)
(cond [(symbol=? bool_and op) (eval_and left right)]
[(symbol=? bool_or op) (eval_or left right)]
[else (error 'eval-binary "Not supported Binary Operator")]
)
(error 'eval-binary "Not a Binary Operator")
)
)
;; Test
(check-expect (eval-binary 'and true true) true)
(check-expect (eval-binary 'or false true) true)
;; Contract: check_bool_tree: DATA -> boolean
;; Purpose: Tests if given data is of type bool-tree
;; Notice bool-tree can be many things!
;; Examples:
(define (check_bool_tree bt)
(if (or (bool-direct? bt)
(bool-unary? bt)
(bool-binary? bt)
(boolean? bt)
)
true
false
)
)
;; Test
(check-expect (check_bool_tree true) true)
(check-expect (check_bool_tree 'abc) false)
;; Contract: eval-direct: bool-direct -> boolean
;; Purpose: Tests if given value is a bool-direct and returns boolean value.
;; Uses lockup-variable.
;; Error: "Not a bool-direct"
;; Examples: (eval_direct true)
;; (eval_direct 'B)
(define (eval-direct bd)
(cond [(symbol? bd) (lookup-variable bd)]
[(boolean? bd) bd]
[else (error 'eval-direct "Not a bool-direct")]
)
)
;; Test
(check-expect (eval-direct true) true)
(check-expect (eval-direct 'B) false)
;; Contract: bool-tree->boolean: bool-tree -> boolean
;; Purpose: evaluates the value of a bool-tree.
;; Uses eval-direct, eval-unary and eval-binary.
;; Errors: "Not a bool-tree"
;; Example: (bool-tree->boolean (input->tree (list 'and 'A true)))
;; (bool-tree->boolean (input->tree (list 'or (list 'not 'A) 'B)))
(define (bool-tree->boolean a-bool-tree)
(if (check_bool_tree a-bool-tree)
(cond [(bool-direct? a-bool-tree) (eval-direct (bool-direct-value a-bool-tree))]
[(bool-unary? a-bool-tree) (eval-unary (bool-unary-op a-bool-tree)
(bool-tree->boolean (bool-unary-param a-bool-tree)))]
[(bool-binary? a-bool-tree) (eval-binary (bool-binary-op a-bool-tree)
(bool-tree->boolean (bool-binary-left a-bool-tree))
(bool-tree->boolean (bool-binary-right a-bool-tree)))]
[else (error 'bool-tree->boolean "Not a bool-tree")]
)
(error 'bool-tree->boolean "Not a bool-tree")
)
)
;; Tests
(check-expect (bool-tree->boolean (input->tree (list 'and 'A true))) true)
(check-expect (bool-tree->boolean (input->tree (list 'or (list 'not 'A) 'B)))false)
;;-------------------------------------------------------------------------------------------------------
;;-------------------------------------------Aufgabe 5.5-------------------------------------------------
;;-------------------------------------------------------------------------------------------------------
;; Ich sehe zwei sinnvolle Möglichkeiten den globalen Namensraum auf die Prozedur
;; eval-input:bool-input -> boolean zu beschränken:
;;
;; 1: Man stellt allen Prozedur-Namen, ausgenommen die genannte eval-input Prozedur, einen Unterstrich vor.
;; Desweiteren wird in dem Vertrag zu dieser Datei definiert, dass alle Funktionen mit einem
;; vorgestellten Unterstrich private Funktionen sind und nicht benutzt werden dürfen.
;;
;; 2: Ich würde die Prozeduren hirachisch mit local(bzw labda) ineinander Schachteln, so dass auf der jeweiligen
;; Ebene nur die Prozeduren sichtbar sind, die in dieser Ebene benötigt werden. So wird auch der Namensraum
;; Der darunterliegenden Ebenen nicht verschmutzt. So ist für jede Funktion nur das sichtbar was wirklich
;; von ihr benötigt wird.
;;
;; Für die in den Hausübungen gegebenen Prozeduren würde das so aussehen:
;;
;; Schachtelung | Prozeduren
;; --------------------------------------------------------------------------------------
;; 0 | eval-input
;; 1 | input->tree bool-tree->boolean
;; 2 | eval-binary, eval-unary
;;

View File

@ -0,0 +1,3 @@
;; The first three lines of this file were inserted by DrScheme. They record metadata
;; about the language level of this file in a form that our tools can easily process.
#reader(lib "htdp-beginner-abbr-reader.ss" "lang")((modname u03) (read-case-sensitive #t) (teachpacks ()) (htdp-settings #(#t constructor repeating-decimal #f #t none #f ())))

View File

@ -0,0 +1,57 @@
;; The first three lines of this file were inserted by DrScheme. They record metadata
;; about the language level of this file in a form that our tools can easily process.
#reader(lib "htdp-advanced-reader.ss" "lang")((modname u03) (read-case-sensitive #t) (teachpacks ()) (htdp-settings #(#t constructor repeating-decimal #t #t none #f ())))
(define-struct tree (r a b))
(define (tree-insert t n)
(if (and (tree? t)
(number? n)
)
(if (> n (tree-r t)) ;;
(if (tree? (tree-b t))
(make-tree (tree-r t) (tree-a t) (tree-insert (tree-b t) n))
(make-tree (tree-r t) (tree-a t) (make-tree n empty empty))
)
(if (tree? (tree-a t))
(make-tree (tree-r t) (tree-insert (tree-a t) n) (tree-b t))
(make-tree (tree-r t) (make-tree n empty empty) (tree-b t))
)
)
t;;else return tree
)
)
(define some-tree
(make-tree 4
(make-tree 2
empty
(make-tree 3
empty
empty))
(make-tree 6
(make-tree 5
empty
empty)
(make-tree 7
empty
empty)
)
)
)
;;(tree-insert some-tree 1)
;;(tree-insert (tree-insert some-tree 1) 0)
;;(tree-insert (tree-insert (tree-insert some-tree 9) 1) 0)
;;(tree-insert (tree-insert (tree-insert some-tree 7) 1) 0)
(define (tree-insert-list t l)
(if (cons? l)
(tree-insert-list (tree-insert t (first l)) (rest l))
t
)
)
(tree-insert-list some-tree (list 1 0 9 7))
(define sort-list

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,235 @@
;; The first three lines of this file were inserted by DrScheme. They record metadata
;; about the language level of this file in a form that our tools can easily process.
#reader(lib "htdp-advanced-reader.ss" "lang")((modname h04) (read-case-sensitive #t) (teachpacks ((lib "image.ss" "teachpack" "htdp"))) (htdp-settings #(#t constructor repeating-decimal #t #t none #f ((lib "image.ss" "teachpack" "htdp")))))
;;Highway-Image
;;(define highway PICHERE)
;;Purpose: Horizontal Sobel-Operator
(define sobel-we (list 2 0 -2))
;; Contract: brightness: color -> number
;; Purpose: Calculates the brightness of a color-struct.
;; Example: (brightness (make-color 0 0 0))
;; (brightness (make-color 255 0 255))
(define (brightness color)
(/ (+ (color-red color)
(color-green color)
(color-blue color)
)
3
)
)
;; Test
(check-expect (brightness (make-color 0 0 0)) 0)
(check-expect (brightness (make-color 255 0 255)) 170)
;; Contract: append2loc: (listof color) -> (listof color)
;; Purpose: Appends two color-struct(0 0 0) at a given list loc
;; Notice: Its not checked if parameter is listof color!
;; It checks if parameter loc is a list!
;; Example: (append2loc (list (make-color 0 0 0)))
;; (append2loc (list (make-color 0 0 0) (make-color 0 0 0)))
(define (append2loc loc)
(if (cons? loc)
(append loc (list (make-color 0 0 0) (make-color 0 0 0)))
(error 'append2loc "Not a list")
)
)
;; Test
(check-expect (append2loc (list (make-color 0 0 0))) ;;command
(list (make-color 0 0 0) (make-color 0 0 0) (make-color 0 0 0))) ;;expect
(check-expect (append2loc (list (make-color 0 0 0) ;;command
(make-color 0 0 0))) (list (make-color 0 0 0) (make-color 0 0 0) (make-color 0 0 0) (make-color 0 0 0))) ;;expect
;; Contract: apply-for-env3x1: (listof color) ((listof color) -> color) -> (listof color)
;; Purpose: calculates loc2c on every tripel in given color-list loc.
;; returns a listof color.
;; uses append2loc to calculate last element.
;; is recursiv!
;; Example: (apply-for-env3x1 (list (make-color 1 2 3) (make-color 4 5 6) (make-color 7 8 9)) (lambda(loc) (first loc)))
;; (apply-for-env3x1 (list (make-color 255 255 255) (make-color 4 5 6) (make-color 10 10 10)) (lambda(loc) (first loc)))
(define (apply-for-env3x1 loc loc2c)
(if (>= (length loc) 3) ;;check if list is long enaugh
(append (list (loc2c (list (first (append2loc loc)) ;;calc first element
(second (append2loc loc))
(third (append2loc loc))
)
)
)
(apply-for-env3x1 (rest loc) loc2c) ;;calc rest elements recursivly
)
loc ;;ancor
)
)
;; Test
(check-expect (apply-for-env3x1 (list (make-color 1 2 3)
(make-color 4 5 6)
(make-color 7 8 9)
)
(lambda(loc) (first loc))
);;command
(list (make-color 1 2 3) ;;expect
(make-color 4 5 6)
(make-color 7 8 9)
)
)
(check-expect (apply-for-env3x1 (list (make-color 255 255 255)
(make-color 4 5 6)
(make-color 10 10 10)
)
(lambda(loc) (first loc))
);;command
(list (make-color 255 255 255) ;;expect
(make-color 4 5 6)
(make-color 10 10 10)
)
)
;; Contract: numberfitcolor: number -> number
;; Purpose: Checks if number is a valid value
;; for a color struct. If not produces
;; a valid value.
;; Uses min,floor and abs.
;; Example: (numberfitcolor -5)
;; (numberfitcolor 267.3)
(define (numberfitcolor n)
(min 255 ;;define maximum@255
(floor (abs n))) ;; round down
)
;; Test
(check-expect (numberfitcolor -5) ;;command
5 ;;expect
)
(check-expect (numberfitcolor 267.3) ;;command
255 ;;expect
)
;; Contract: vec-multi: (listof number) (listof number) -> number
;; Purpose: Calculates Scalar-product of two vectors
;; Example: (vec-multi '(1 2 3) '(1 2 3))
;; (vec-multi '(1 2 3 4) '(1 2 3 4))
(define (vec-multi v1 v2)
(if (and (cons? v1) ;;is a list?
(cons? v2) ;;is a list?
)
(foldl + ;;add all elements in the generated list
0
(map * ;;multip. every element of a vector
v1
v2
)
);;if
0 ;;else
)
)
;; Test
(check-expect (vec-multi '(1 2 3)
'(1 2 3)
);;command
14;;expect
)
(check-expect (vec-multi '(1 2 3 4)
'(1 2 3 4)
);;comamnd
30;;expect
)
;; Contract: scalarofcolorsobel-we: color -> number
;; Purpose: Calculates scalar-product of a color-struct
;; and sobel-we
;; Makes sure result is a valid color-value.
;; Uses vec-multi, sobel-we
;; Example:
(define (scalarofcolorsobel-we color)
(if (color? color)
(numberfitcolor (vec-multi (list (color-red color) ;;numberfitcolor -> ensures generated number is a valid rbg-value
(color-green color)
(color-blue color)) ;;list representing a color
sobel-we ;;sobel-parameter
)
)
(error 'scalarofcolorsobel-we "Not a color") ;; parameter was not a color
)
)
;; Test
(check-expect (scalarofcolorsobel-we (make-color 0 0 0));;command
0;;expect
)
(check-expect (scalarofcolorsobel-we (make-color 255 255 255));;command
0;;expect
)
;; Contract: scalarofcolorsoel-we-brightness: color color color -> number
;; Purpose: calculates the scalar of the brightness of a color-tripel
;; with the sobel-we vector
;; uses scalarofcolorsobel-we
;; Example: (scalarofcolorsobel-we-brightness (make-color 0 0 0) (make-color 0 0 0) (make-color 0 0 0))
;; (scalarofcolorsobel-we-brightness (make-color 255 255 255) (make-color 1 1 1) (make-color 1 1 1))
(define (scalarofcolorsobel-we-brightness c1 c2 c3)
(scalarofcolorsobel-we (make-color (brightness c1) ;;create color-struct here 2 fit scalarofcolorsobel-we
(brightness c2)
(brightness c3))
)
)
;; Test
(check-expect (scalarofcolorsobel-we-brightness (make-color 0 0 0)
(make-color 0 0 0)
(make-color 0 0 0)
);;command
0;;expect
)
(check-expect (scalarofcolorsobel-we-brightness (make-color 255 255 255)
(make-color 1 1 1)
(make-color 1 1 1)
);;command
255;;expect
)
;; Contract: sobel: (list color color color) -> color
;; Purpose:
;; Example:
(define (sobel lo3c)
(if (and (cons? lo3c) ;;parameter is list
(color? (first lo3c)) ;; list contains colors?
(color? (second lo3c))
(color? (third lo3c))
)
(make-color (scalarofcolorsobel-we-brightness (first lo3c) ;;calculate brightness value
(second lo3c)
(third lo3c))
(scalarofcolorsobel-we-brightness (first lo3c) ;;twice^^
(second lo3c)
(third lo3c))
(scalarofcolorsobel-we-brightness (first lo3c) ;;third time^^ -> i hate scheme
(second lo3c)
(third lo3c))
)
(error 'sobel "Not a listof color") ;;Parametermissmatch
)
)
;; Test
(check-expect (sobel (list (make-color 0 0 60)
(make-color 0 0 0)
(make-color 0 60 0)));;command
(make-color 0 0 0));;expect
(check-expect (sobel (list (make-color 0 0 20)
(make-color 127 0 255)
(make-color 0 30 40)));;command
(make-color 33 33 33));;expect
;; Contract: image-transform-3x1: image ((listof color) -> color) -> image
;; Purpose: Transforms image into gray-value-image
;; Example: Not needed
(define (image-transform-3x1 img loc2c)
(color-list->image (apply-for-env3x1 (image->color-list img) ;;convert image 2 color-list, filter via apply-for-env3x1 and loc2c, convert back 2 image
loc2c)
(image-width img) ;;img width
(image-height img) ;;img height
0 ;;dont care 4 that
0 ;;dont care 4 that
)
)
;; Test
(image-transform-3x1 highway sobel) ;;test here ;-)

View File

@ -0,0 +1,126 @@
;;Highway-Image
(define highway ...)
;;Purpose: Horizontal Sobel-Operator
(define sobel-we (list 2 0 -2))
;; Contract: brightness: color -> number
;; Purpose: Calculates the brightness of a color-struct.
;; Example: (brightness (make-color 0 0 0))
;; (brightness (make-color 255 0 255))
(define (brightness color)
(/ (+ (color-red color)
(color-green color)
(color-blue color)
)
3
)
)
;; Test
(check-expect (brightness (make-color 0 0 0)) 0)
(check-expect (brightness (make-color 255 0 255)) 170)
;; Contract: append2loc: (listof color) -> (listof color)
;; Purpose: Ensures that there are at least 3 color-structs
;; in the list. If not (make-color 0 0 0) are appended.
;; If list is empty, no list is given triggers an error.
;; Example:
(define (append2loc loc)
(if (cons? loc)
(if (color? (second loc))
(if (color? (thrid loc))
loc
(append loc (make-color 0 0 0))
)
(append loc (make-color 0 0 0) (make-color 0 0 0))
)
(error 'append2loc "not a listof color")
)
)
;; Test
;; Contract: apply-for-env3x1: (listof color) ((listof color) -> color) -> (listof color)
;; Purpose:
;; Example:
(define (apply-for-env3x1 loc loc2c)
(list (loc2c (list (first (append2loc loc))
(second (append2loc loc))
(third (append2loc loc))
)
)
(apply-for-env3x1 (rest (append2loc loc)))
)
)
;; Test
;;(check-expect (apply-for-env3x1))
;;(check-expect (apply-for-env3x1))
;; Contract: numberfitcolor: number -> number
;; Purpose: Checks if number is a valid value
;; for a color struct. If not produces
;; a valid value.
;; Uses min and floor.
;; Example: (numberfitcolor -5)
;; (numberfitcolor 267)
(define (numberfircolor n)
(if (< n 0)
0
(floor (min n 255))
)
)
;; Test
(check-expect (numberfitcolor -5) 0)
(check-expect (numberfitcolor 267) 255)
;; Contract: vec-multi: (listof number) (listof number) -> number
;; Purpose: Calculates Scalar-product of two vectors
;; Example: (vec-multi '(1 2 3) '(1 2 3))
;; (vec-multi '(1 2 3 4) '(1 2 3 4))
(define (vec-multi v1 v2)
(if (and (cons? v1)
(cons? v2)
)
(foldl + 0 (map * v1 v2))
0
)
)
;; Test
(check-expect (vec-multi '(1 2 3) '(1 2 3)) 14)
(check-expect (vec-multi '(1 2 3 4) '(1 2 3 4)) 30)
;; Contract: scalarofcolorsobel-we: color -> number
;; Purpose: Calculates scalar-product of a color-struct
;; and sobel-we
;; Makes sure result is a valid color-value.
;; Uses vec-multi, sobel-we
;; Example:
(define (scalarofcolorsobel-we color)
(numberfitcolor (vec-multi color sobel-we))
)
;; Test
;; Contract: sobel: (list color color color) -> color
;; Purpose:
;; Example:
(define (sobel lo3c)
(if (and (cons? lo3c)
(color? (first lo3c))
(color? (second lo3c))
(color? (third lo3c))
)
(make-color (scalarofcolorsobel-we (first lo3c))
(scalarofcolorsobel-we (second lo3c))
(scalarofcolorsobel-we (third lo3c))
)
)
;; Test
(check-expect (sobel (list (make-color 0 0 60)
(make-color 0 0 0)
(make-color 0 60 0)))
(make-color 0 0 0))
(check-expect (sobel (list (make-color 0 0 20)
(make-color 127 0 255)
(make-color 0 30 40)))
(make-color 34 34 34))

Binary file not shown.

After

Width:  |  Height:  |  Size: 32 KiB

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,3 @@
;; The first three lines of this file were inserted by DrScheme. They record metadata
;; about the language level of this file in a form that our tools can easily process.
#reader(lib "htdp-advanced-reader.ss" "lang")((modname u04) (read-case-sensitive #t) (teachpacks ()) (htdp-settings #(#t constructor repeating-decimal #t #t none #f ())))

View File

@ -0,0 +1,148 @@
;; The first three lines of this file were inserted by DrScheme. They record metadata
;; about the language level of this file in a form that our tools can easily process.
#reader(lib "htdp-advanced-reader.ss" "lang")((modname u04) (read-case-sensitive #t) (teachpacks ()) (htdp-settings #(#t constructor repeating-decimal #t #t none #f ())))
;;multiply:number > (number > number)
;;returnsafunctionthattakesanumberasinputand
;;andreturnsthenumbermultipliedbyx
(define (multiply x)
(lambda (y)(* x y))
)
(check-expect ((multiply 3) 2) 6)
(check-expect ((multiply 7) 3) 21)
(define (multiplyl x)
(local [(define (multi y) (* x y))]
multi
)
)
(check-expect ((multiplyl 3) 2) 6)
(check-expect ((multiplyl 7) 3) 21)
;; Aufgabe 4.1
;; Contract: f: number number -> number
;; Aufgabe 4.2
;; Contract: g: number -> (number -> number)
;; Aufgabe 4.3/4.4
(define (addX num x)
(+ num x)
)
(check-expect (addX 1 2) 3)
(check-expect (addX 2 2) 4)
(define (add2 num) (addX num 2))
(check-expect (add2 1) 3)
(check-expect (add2 2) 4)
(define (add3 num) (addX num 3))
(check-expect (add3 1) 4)
(check-expect (add3 2) 5)
(define (add4 num) (addX num 4))
(check-expect (add4 1) 5)
(check-expect (add4 2) 6)
;; Aufgabe 4.5
(define (make-adder x)
(lambda (y) (+ x y))
)
(check-expect ((make-adder 1) 2) 3)
(check-expect ((make-adder 2) 2) 4)
(define (adder2 x) ((make-adder 2) x))
(check-expect (adder2 1) 3)
(check-expect (adder2 2) 4)
(define (adder3 x) ((make-adder 3) x))
(check-expect (adder3 1) 4)
(check-expect (adder3 2) 5)
(define (adder4 x) ((make-adder 4) x))
(check-expect (adder4 1) 5)
(check-expect (adder4 2) 6)
;; Aufgabe 4.6
(define (add x y) ((make-adder x) y))
(check-expect (add 1 2) 3)
(check-expect (add 2 2) 4)
;; Aufgabe 4.7
;;Contract: uncurry: (x -> (y -> z)) -> (x y -> z)
(define (uncurry x)
(lambda (a b) ((x a) b))
)
(check-expect ((uncurry make-adder) 2 2) 4)
(check-expect ((uncurry make-adder) 2 3) 5)
(define (add_ x y) ((uncurry make-adder) x y))
(check-expect (add_ 2 2) 4)
(check-expect (add_ 2 3) 5)
;; Aufgabe 5.1
;;Contract map: (X -> Y) (listof X) (listof X) -> (listof Y)
;;Contract map: (X -> Y) (listof X) -> (listof Y)
(check-expect (map + (list 1 2 3 4) (list 1 2 3 4)) (list 2 4 6 8))
(check-expect (map - (list 1 2 3 4) (list 1 2 3 4)) (list 0 0 0 0))
(check-expect (map (lambda (x) (+ x 2)) (list 1 2 3 4)) (list 3 4 5 6))
;; Aufgabe 5.2
(define (mymap op l)
(if (cons? l)
(append (list (op (first l))) (mymap op (rest l)))
;;(list (op (first list)))
(list)
)
)
(check-expect (mymap (lambda (x) (+ x 2)) (list 1 2 3)) (list 3 4 5))
(check-expect (mymap (lambda (x) (+ x 2)) (list 2 3 4)) (list 4 5 6))
;; Aufgabe 5.3/5.4
(check-expect (foldl + 4 '(1 2 3)) 10)
(check-expect (map + '(1 2 3) '(4 5 6)) '(5 7 9))
;; Aufgabe 5.5
(define (zip l1 l2)
(map (lambda (x y) (list x y)) l1 l2)
)
(check-expect (zip '(a b c) '(1 2 3)) (list '(a 1) '(b 2) '(c 3)))
(check-expect (zip '(c b a) '(1 2 3)) (list '(c 1) '(b 2) '(a 3)))
(define (vec-multi v1 v2)
(if (and (cons? v1)
(cons? v2)
)
(foldl + 0 (map * v1 v2))
0
)
)
(check-expect (vec-multi '(1 2 3) '(1 2 3)) 14)
(check-expect (vec-multi '(1 2 3 4) '(1 2 3 4)) 30)
(define (cartesian-product v1 v2)
(if (and (cons? v1)
(cons? v2)
)
(map (lambda (x y)(foldl * x v2)) v1)
;; (foldl + 0
;; (foldl (lambda (x y)(foldl * y v2)) 0 v1)
;; )
0
)
)
(check-expect (cartesian-product '(1 2) '(1 2)) '(1 2 2 4))
;;(check-expect (cartesian-product '(1 2 3) '(1 2 3 4)) 36)

View File

@ -0,0 +1,543 @@
;; The first three lines of this file were inserted by DrScheme. They record metadata
;; about the language level of this file in a form that our tools can easily process.
#reader(lib "htdp-advanced-reader.ss" "lang")((modname h05) (read-case-sensitive #t) (teachpacks ((lib "draw.ss" "teachpack" "htdp"))) (htdp-settings #(#t constructor repeating-decimal #t #t none #f ((lib "draw.ss" "teachpack" "htdp")))))
;;(c) Ulf Gebhardt
;; Ich benutze in der ganzen Aufgabe kein (local ...)
;; Das mache ich bewusst, denn ich finde es sehr unübersichtlich,
;; wenn alle Funktion in er Prozedur definiert sind.
;; Wie man das Problem der Namensraumverschmutzung auch ohne
;; (local ...) lösen kann finden Sie am Ende der Datei (Aufgabe 5.5)
;; a bool-input is either
;; 1. a boolean value (true,false,an expression evaluated to true/false)
;; 2. a symbol 'A...'F for a boolean variable
;; 3. (list 'not b), where b is a bool-input
;; 4. (list 'and b1 b2), where b1 and b2 have type bool-input
;; 5. (list 'or b1 b2), where b1 and b2 have type bool-input
;; a bool-tree is either
;; 1. a bool-direct (boolean value or boolean variable)
;; 2. a bool-unary (unary operator, i.e., 'not)
;; 3. a bool-binary (binary operator, e.g., 'and, 'or)
;; a bool-direct represents direct boolean values
;; value: direct-boolean - a boolean value that can be either
;; 1. a boolean value, i.e., something that evaluates to true or false,
;; 2. or a symbol that represents one of the variables 'A...'F
(define-struct bool-direct (value))
;; bool-unary represents unary boolean operators
;; op: symbol - a legal unary operator (e.g., 'not)
;; param: bool-tree - a boolean expression
(define-struct bool-unary (op param))
;; bool-binary represents binary boolean operators
;; op: symbol - a legal binary operator (e.g., 'and, 'or)
;; left: bool-tree - the left (2.) part of the binary boolean expression
;; right: bool-tree - the right (3.) part of the binary boolean expr.
(define-struct bool-binary (op left right))
;; lookup-variable: symbol -> boolean
;; looks up the value of the symbol passed in
;; if undefined, returns an error
;; example: (lookup-variable 'A) is true
(define (lookup-variable variable)
(cond
[(symbol=? variable 'A) true]
[(symbol=? variable 'B) false]
[(symbol=? variable 'C) true]
[(symbol=? variable 'D) false]
[(symbol=? variable 'E) false]
[(symbol=? variable 'F) true]
[else (error 'lookup-variable
(string-append "Variable "
(symbol->string variable)
" unknown"))]
))
;; Tests
(check-expect (lookup-variable 'A) true)
(check-expect (lookup-variable 'B) false)
(check-expect (lookup-variable 'C) true)
(check-expect (lookup-variable 'D) false)
(check-expect (lookup-variable 'E) false)
(check-expect (lookup-variable 'F) true)
(check-error (lookup-variable 'G) "lookup-variable: Variable G unknown")
;;-------------------------------------------------------------------------------------------------------
;;-------------------------------------------CODE--------------------------------------------------------
;;-------------------------------------------------------------------------------------------------------
;; bool_not, bool_and, bool_or are constants
;; represtenting the textual-expression of
;; the named boolean operator
;;(define bool_equal 'equal)
(define bool_not 'not)
(define bool_and 'and)
(define bool_or 'or )
;; Contract: sym_is_unary: symbol -> boolean
;; Purpose: Tests if the given symbol sym is a unary operator
;; Examples: (sym_is_unary 'not)
;; (sym_is_unary 'equal)
(define (sym_is_unary sym)
(if (symbol? sym)
(cond [(symbol=? sym bool_not) true]
;;[(symbol=? sym bool_equal) true]
[else false]
)
(error 'sym_is_unary "Not a Symbol")
)
)
;;Test
(check-expect (sym_is_unary 'not) true)
(check-expect (sym_is_unary 'equal) false)
;; Contract: sym_is_binary: symbol -> boolean
;; Purpose: Tests if the given symbol sym is a binary operator
;; Examples: (sym_is_binary 'and)
;; (sym_is_binary 'equal)
(define (sym_is_binary sym)
(cond [(symbol=? sym bool_and) true]
[(symbol=? sym bool_or) true]
[else false]
)
)
;;Test
(check-expect (sym_is_binary 'and) true)
(check-expect (sym_is_binary 'equal) false)
;; Contract: input-tree: bool-input -> bool-tree
;; Purpose: Converts a bool-input into a bool-tree
;; Notice bool-input is not a struct, but
;; can be many things!
;; Examples: (input->tree (list 'and 'A true))
;; (input->tree (list 'or (list 'not 'A) 'B))
(define (input->tree input)
(if (cons? input)
(cond [(sym_is_unary (first input)) (make-bool-unary (first input) (input->tree (second input)))]
[(sym_is_binary (first input)) (make-bool-binary (first input) (input->tree (second input)) (input->tree (third input)))]
[(or (symbol? (first input)) (boolean? (first input))) (make-bool-direct (first input))]
[else empty] ;;empty
)
(if (or (symbol? input) (boolean? input))
(make-bool-direct input)
empty
)
)
)
;; Test
(check-expect (input->tree (list 'and 'A true))
(make-bool-binary 'and
(make-bool-direct 'A)
(make-bool-direct true)))
(check-expect (input->tree (list 'or (list 'not 'A) 'B))
(make-bool-binary 'or
(make-bool-unary 'not
(make-bool-direct 'A))
(make-bool-direct 'B)))
;; Contract: eval_not: bool -> bool
;; Purpose: evaluates not operator on given boolean bool.
;; Errors: "Not a Bool"
;; Examples: (eval_not true)
;; (eval_not false)
(define (eval_not bool)
(if (boolean? bool)
(if bool
false
true
)
(error 'eval_not "Not a Bool")
)
)
;; Test
(check-expect (eval_not true) false)
(check-expect (eval_not false) true)
;; Contract: eval-unary: symbol boolean -> boolean
;; Purpose: evalutes the result of an unary-operation on given unary-param.
;; Errors: "Not supported bool-unary"
;; "Not bool-unary"
;; Examples: (eval-unary 'not true)
;; (eval-unary 'not false)
(define (eval-unary unary-op unary-param)
(if (sym_is_unary unary-op)
(cond [(symbol=? bool_not unary-op) (eval_not unary-param)]
[else (error 'eval-unary "Not supported bool-unary")]
)
(error 'eval-unary "Not a bool-unary")
)
)
;; Test
(check-expect (eval-unary 'not true) false)
(check-expect (eval-unary 'not false) true)
;; Contract: eval_and: boolean boolean -> boolean
;; Purpose: evaluates and operator on given booleans bool1, bool2.
;; Errors: "Not a Bool"
;; Examples: (eval_and true true)
;; (eval_and false false)
(define (eval_and bool1 bool2)
(if (and (boolean? bool1) (boolean? bool2))
(if (and bool1 bool2)
true
false
)
(error 'eval_and "Not a Bool")
)
)
;; Test
(check-expect (eval_and true true) true)
(check-expect (eval_and false false) false)
;; Contract: eval_or: boolean boolean -> boolean
;; Purpose: evaluates or operator on given booleans bool1, bool2.
;; Errors: "Not a Bool"
;; Examples: (eval_or true true)
;; (eval_or false false)
(define (eval_or bool1 bool2)
(if (and (boolean? bool1) (boolean? bool2))
(if (or bool1 bool2)
true
false
)
(error 'eval_or "Not a Bool")
)
)
;; Test
(check-expect (eval_or true true) true)
(check-expect (eval_or false false) false)
;; Contract: eval-binary: symbol boolean boolean -> boolean
;; Purpose: evalutes the result of an binary-operation on given binary-param.
;; Error: "Not supported Binary Operator"
;; "Not a Binary Operator"
;; Examples: (eval-binary 'and true true)
;; (eval-unary 'or false true)
(define (eval-binary op left right)
(if (sym_is_binary op)
(cond [(symbol=? bool_and op) (eval_and left right)]
[(symbol=? bool_or op) (eval_or left right)]
[else (error 'eval-binary "Not supported Binary Operator")]
)
(error 'eval-binary "Not a Binary Operator")
)
)
;; Test
(check-expect (eval-binary 'and true true) true)
(check-expect (eval-binary 'or false true) true)
;; Contract: check_bool_tree: DATA -> boolean
;; Purpose: Tests if given data is of type bool-tree
;; Notice bool-tree can be many things!
;; Examples:
(define (check_bool_tree bt)
(if (or (bool-direct? bt)
(bool-unary? bt)
(bool-binary? bt)
(boolean? bt)
)
true
false
)
)
;; Test
(check-expect (check_bool_tree true) true)
(check-expect (check_bool_tree 'abc) false)
;; Contract: eval-direct: bool-direct -> boolean
;; Purpose: Tests if given value is a bool-direct and returns boolean value.
;; Uses lockup-variable.
;; Error: "Not a bool-direct"
;; Examples: (eval_direct true)
;; (eval_direct 'B)
(define (eval-direct bd)
(cond [(symbol? bd) (lookup-variable bd)]
[(boolean? bd) bd]
[else (error 'eval-direct "Not a bool-direct")]
)
)
;; Test
(check-expect (eval-direct true) true)
(check-expect (eval-direct 'B) false)
;; Contract: bool-tree->boolean: bool-tree -> boolean
;; Purpose: evaluates the value of a bool-tree.
;; Uses eval-direct, eval-unary and eval-binary.
;; Errors: "Not a bool-tree"
;; Example: (bool-tree->boolean (input->tree (list 'and 'A true)))
;; (bool-tree->boolean (input->tree (list 'or (list 'not 'A) 'B)))
(define (bool-tree->boolean a-bool-tree)
(if (check_bool_tree a-bool-tree)
(cond [(bool-direct? a-bool-tree) (eval-direct (bool-direct-value a-bool-tree))]
[(bool-unary? a-bool-tree) (eval-unary (bool-unary-op a-bool-tree)
(bool-tree->boolean (bool-unary-param a-bool-tree)))]
[(bool-binary? a-bool-tree) (eval-binary (bool-binary-op a-bool-tree)
(bool-tree->boolean (bool-binary-left a-bool-tree))
(bool-tree->boolean (bool-binary-right a-bool-tree)))]
[else (error 'bool-tree->boolean "Not a bool-tree")]
)
(error 'bool-tree->boolean "Not a bool-tree")
)
)
;; Tests
(check-expect (bool-tree->boolean (input->tree (list 'and 'A true))) true)
(check-expect (bool-tree->boolean (input->tree (list 'or (list 'not 'A) 'B)))false)
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(define (remove-first rv eqop vl)
(if (cons? vl)
(if (eqop rv
(first vl)
)
(rest vl)
(append (list (first vl)) (remove-first rv eqop (rest vl)))
)
(error 'remove-first "Not a List")
)
)
;; Test:
(check-expect (remove-first 5 = '(12 4 6 5 7 8 9)) '(12 4 6 7 8 9))
(check-expect (remove-first 'c symbol=? (list 'a 'b 'c 'd)) (list 'a 'b 'd))
;;(define (lowoflist vl lowop)
;; (if (cons? vl)
;; (local [(define (lolrecursiv vl lowop d)
;; (if (cons? vl)
;; (lolrecursiv (rest vl) lowop (lowop d (first vl)))
;; d
;; )
;; )]
;; (lolrecursiv (rest vl) lowop (first vl))
;; )
;; (error 'lowoflist "Not a List")
;; )
;;)
(define (lowoflist vl lowop)
(foldl lowop (first vl) (rest vl))
)
;; Test:
(check-expect (lowoflist '(1 2 3 4) (lambda (x y) (if (> x y) y x))) 1)
(check-expect (lowoflist '(5 3 7 4) (lambda (x y) (if (> x y) y x))) 3)
(define (selection-sort vl eqop lowop)
(local [;;(define lol (lowoflist vl lowop))
(define (ssrecursiv vl eqop lowop d)
(if (cons? vl)
(ssrecursiv (remove-first (lowoflist vl lowop) eqop vl) eqop lowop (append d (list (lowoflist vl lowop))))
d
)
)]
(ssrecursiv vl eqop lowop '())
)
)
(check-expect (selection-sort '(1 2 3 4) = (lambda (x y) (if (> x y) y x))) '(1 2 3 4))
(check-expect (selection-sort '(5 3 7 1) = (lambda (x y) (if (> x y) y x))) '(1 3 5 7))
(check-expect (selection-sort (list true false false true) boolean=? (lambda (x y) (if x x y))) (list true true false false))
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Contract: bool-direct->string: bool-direct -> string
;; Purpose: Converts a bool-direct to a string value.
;; Notice possible values of bool-direct
;; Examples: (bool-direct->string (make-bool-direct 'A))
;; (bool-direct->string (make-bool-direct false))
(define (bool-direct->string bd)
(if (bool-direct? bd)
(if (symbol? (bool-direct-value bd))
(symbol->string (bool-direct-value bd))
(if (bool-direct-value bd)
"true"
"false"
)
)
(error 'bool-direct->string "Not a Bool-Direct")
)
)
;; Test
(check-expect (bool-direct->string (make-bool-direct 'A)) "A")
(check-expect (bool-direct->string (make-bool-direct false)) "false")
(define (bool-unary->string bu)
(if (bool-unary? bu)
(symbol->string (bool-unary-op bu))
(error 'bool-unary->string "Not a Bool-Unary")
)
)
(define (bool-binary->string bb)
(if (bool-binary? bb)
(symbol->string (bool-binary-op bb))
(error 'bool-unary->string "Not a Bool-Binary")
)
)
;; Contract: tree-depth: bool-tree -> number
;; Purpose: Calculates the depth of a bool-tree-struct
;; First node is depth 1
;; Examples: (tree-depth (input->tree (list 'and 'A true)))
;; (tree-depth (input->tree (list 'or (list 'not 'A) 'B)))
(define (tree-depth bt)
(if (check_bool_tree bt)
(cond [(bool-direct? bt) 1]
[(bool-unary? bt) (+ 1 (tree-depth (bool-unary-param bt)))]
[(bool-binary? bt)
(if (> (tree-depth (bool-binary-left bt)) (tree-depth (bool-binary-right bt)))
(+ 1 (tree-depth (bool-binary-left bt)))
(+ 1 (tree-depth (bool-binary-right bt)))
)
]
)
(error 'tree-depth "Not a Boo-Tree")
)
)
;; Test:
(check-expect (tree-depth (input->tree (list 'and 'A true))) 2)
(check-expect (tree-depth (input->tree (list 'or (list 'not 'A) 'B))) 3)
;; Contract: render-tree: bool-tree number number number -> void
;; Purpose: Renders a given bool-tree at given position number1 number2
;; with width number3.
;; Examples: None
;;(define (render-tree bt x y d)
;; (local [(define (render-tree-recursiv bt x y d)
;; (cond [(bool-direct? bt)(draw-solid-string (make-posn x y) (bool-direct->string bt))]
;; [(bool-unary? bt) (begin (draw-solid-string (make-posn x y) (bool-unary->string bt))
;; (draw-solid-line (make-posn x y) (make-posn (+ x d) (+ y d)))
;; (render-tree-recursiv (bool-unary-param bt) (+ x d) (+ y d) (/ d 2))
;; )]
;; [(bool-binary? bt) (begin (draw-solid-string (make-posn x y) (bool-binary->string bt))
;; (draw-solid-line (make-posn x y) (make-posn (+ x d) (+ y d)))
;; (render-tree-recursiv (bool-binary-right bt) (+ x d) (+ y d) (/ d 2))
;; (draw-solid-line (make-posn x y) (make-posn (- x d) (+ y d)))
;; (render-tree-recursiv (bool-binary-left bt) (- x d) (+ y d) (/ d 2))
;; )]
;; [else void]
;; )
;; )]
;; (if (and (check_bool_tree bt)
;; (number? x)
;; (number? y)
;; (number? d)
;; )
;; (begin (start (+ (* d 2) x) (+ (* d 2) y))
;; (render-tree-recursiv bt x y d)
;; )
;; (error 'render-tree "Parameter missmatch")
;; )
;; )
;;)
;; Test: NONE
;;(render-tree (input->tree (list 'and 'A true)) 100 100 50)
;;(render-tree (input->tree (list 'or (list 'not 'A) 'B)) 100 100 50)
;;(render-tree (input->tree (list 'or (list 'not 'A) (list 'and 'C 'A))) 100 100 50)
;;(render-tree (input->tree (list 'or (list 'not (list 'not 'A)) (list 'and 'C 'A))) 100 100 50)
;;(render-tree (input->tree (list 'or (list 'not (list 'and (list 'not 'A) (list 'or (list 'and 'A 'B) (list 'not 'B)))) (list 'and 'C 'A))) 500 50 320)
;; Contract: determine-initial-width: bool-tree number -> number
;; Purpose: Determines the width of the first node of the given
;; bool-tree with given width of last node of the tree.
;; Examples: (determine-initial-width (make-bool-direct 'A) 5)
;; (determine-initial-width (make-bool-binary 'or (make-bool-direct 'B) (make-bool-direct 'A)) 5)
(define (determine-initial-width bt d)
(if (and (check_bool_tree bt)
(number? d)
)
(* d
(expt 2
(- (tree-depth bt)
1
)
)
)
(error 'determine-initial-width "Parameter Missmatch")
)
)
;; Test:
(check-expect (determine-initial-width (make-bool-direct 'A) 5) 5)
(check-expect (determine-initial-width (make-bool-binary 'or (make-bool-direct 'B) (make-bool-direct 'A)) 5) 10)
;; Contratc: render-tree-minimal-width: bool-tree number number number -> void
;; Purpose: Renders a given bool-tree at given point x y with last tree-node-width
;; equal to md.
;; Uses determine-initial-width
;; Examples: (render-tree-minimal-width (input->tree (list 'or (list 'not (list 'and (list 'not 'A) (list 'or (list 'and 'A 'B) (list 'not 'B)))) (list 'and 'C 'A))) 500 10 10)
;; (render-tree-minimal-width (input->tree (list 'or (list 'and (list 'and (list 'or (list 'and 'A 'B) (list 'not 'B)) (list 'not 'A)) (list 'and 'C 'A)) (list 'and 'C 'A))) 650 10 10)
(define (render-tree-minimal-width bt x y md)
(local [(define (render-tree-inner bt x y d)
(local [(define (render-tree-recursiv bt x y d)
(cond [(bool-direct? bt)(draw-solid-string (make-posn x y) (bool-direct->string bt))]
[(bool-unary? bt) (begin (draw-solid-string (make-posn x y) (bool-unary->string bt))
(draw-solid-line (make-posn x y) (make-posn (+ x d) (+ y d)))
(render-tree-recursiv (bool-unary-param bt) (+ x d) (+ y d) (/ d 2))
)]
[(bool-binary? bt) (begin (draw-solid-string (make-posn x y) (bool-binary->string bt))
(draw-solid-line (make-posn x y) (make-posn (+ x d) (+ y d)))
(render-tree-recursiv (bool-binary-right bt) (+ x d) (+ y d) (/ d 2))
(draw-solid-line (make-posn x y) (make-posn (- x d) (+ y d)))
(render-tree-recursiv (bool-binary-left bt) (- x d) (+ y d) (/ d 2))
)]
[else void]
)
)]
(if (and (check_bool_tree bt)
(number? x)
(number? y)
(number? d)
)
(begin (start (+ (* d 2) x) (+ (* d 2) y))
(render-tree-recursiv bt x y d)
)
(error 'render-tree "Parameter missmatch")
)
)
)]
(render-tree-inner bt x y (determine-initial-width bt md))
)
)
;; Test: NONE
;;(render-tree-minimal-width (input->tree (list 'or (list 'not (list 'and (list 'not 'A) (list 'or (list 'and 'A 'B) (list 'not 'B)))) (list 'and 'C 'A))) 500 10 10)
;;(render-tree-minimal-width (input->tree (list 'or (list 'and (list 'and (list 'or (list 'and 'A 'B) (list 'not 'B)) (list 'not 'A)) (list 'and 'C 'A)) (list 'and 'C 'A))) 650 10 10)
;; Contract: render-tree-intelligent: bool-tree number -> void
;; Purpose: Renders given bool-tree with given width for last
;; tree-node.
;; Examples: (render-tree-intelligent (input->tree (list 'or (list 'not (list 'and (list 'not 'A) (list 'or (list 'and 'A 'B) (list 'not 'B)))) (list 'and 'C 'A))) 10)
;; (render-tree-intelligent (input->tree (list 'or (list 'and (list 'and (list 'or (list 'and 'A 'B) (list 'not 'B)) (list 'not 'A)) (list 'and 'C 'A)) (list 'and 'C 'A))) 10)
(define (render-tree-intelligent bt md)
(render-tree-minimal-width bt (* (determine-initial-width bt md) 2) 10 md)
)
;; Test: NONE
;;(render-tree-intelligent (input->tree (list 'or (list 'not (list 'and (list 'not 'A) (list 'or (list 'and 'A 'B) (list 'not 'B)))) (list 'and 'C 'A))) 10)
;;(render-tree-intelligent (input->tree (list 'or (list 'and (list 'and (list 'or (list 'and 'A 'B) (list 'not 'B)) (list 'not 'A)) (list 'and 'C 'A)) (list 'and 'C 'A))) 10)
;; Contract: render-tree-moAr-intelligent: bool-tree -> void
;; Purpose: Renders given bool-tree.
;; Examples: (render-tree-moAr-intelligent (input->tree (list 'or (list 'not (list 'and (list 'not 'A) (list 'or (list 'and 'A 'B) (list 'not 'B)))) (list 'and 'C 'A))))
;; (render-tree-moAr-intelligent (input->tree (list 'or (list 'and (list 'and (list 'or (list 'and 'A 'B) (list 'not 'B)) (list 'not 'A)) (list 'and 'C 'A)) (list 'and 'C 'A))))
(define (render-tree-moAr-intelligent bt)
(render-tree-minimal-width bt (* (determine-initial-width bt 10) 2) 10 10)
)
;; Test: NONE
;;(render-tree-moAr-intelligent (input->tree (list 'or (list 'not (list 'and (list 'not 'A) (list 'or (list 'and 'A 'B) (list 'not 'B)))) (list 'and 'C 'A))))
(render-tree-moAr-intelligent (input->tree (list 'or (list 'and (list 'and (list 'or (list 'and 'A 'B) (list 'not 'B)) (list 'not 'A)) (list 'and 'C 'A)) (list 'and 'C 'A))))

View File

@ -0,0 +1,576 @@
;; The first three lines of this file were inserted by DrScheme. They record metadata
;; about the language level of this file in a form that our tools can easily process.
#reader(lib "htdp-advanced-reader.ss" "lang")((modname h05) (read-case-sensitive #t) (teachpacks ((lib "draw.ss" "teachpack" "htdp"))) (htdp-settings #(#t constructor repeating-decimal #t #t none #f ((lib "draw.ss" "teachpack" "htdp")))))
;;(c) Ulf Gebhardt
;; Ich benutze in der ganzen Aufgabe kein (local ...)
;; Das mache ich bewusst, denn ich finde es sehr unübersichtlich,
;; wenn alle Funktion in er Prozedur definiert sind.
;; Wie man das Problem der Namensraumverschmutzung auch ohne
;; (local ...) lösen kann finden Sie am Ende der Datei (Aufgabe 5.5)
;; a bool-input is either
;; 1. a boolean value (true,false,an expression evaluated to true/false)
;; 2. a symbol 'A...'F for a boolean variable
;; 3. (list 'not b), where b is a bool-input
;; 4. (list 'and b1 b2), where b1 and b2 have type bool-input
;; 5. (list 'or b1 b2), where b1 and b2 have type bool-input
;; a bool-tree is either
;; 1. a bool-direct (boolean value or boolean variable)
;; 2. a bool-unary (unary operator, i.e., 'not)
;; 3. a bool-binary (binary operator, e.g., 'and, 'or)
;; a bool-direct represents direct boolean values
;; value: direct-boolean - a boolean value that can be either
;; 1. a boolean value, i.e., something that evaluates to true or false,
;; 2. or a symbol that represents one of the variables 'A...'F
(define-struct bool-direct (value))
;; bool-unary represents unary boolean operators
;; op: symbol - a legal unary operator (e.g., 'not)
;; param: bool-tree - a boolean expression
(define-struct bool-unary (op param))
;; bool-binary represents binary boolean operators
;; op: symbol - a legal binary operator (e.g., 'and, 'or)
;; left: bool-tree - the left (2.) part of the binary boolean expression
;; right: bool-tree - the right (3.) part of the binary boolean expr.
(define-struct bool-binary (op left right))
;; lookup-variable: symbol -> boolean
;; looks up the value of the symbol passed in
;; if undefined, returns an error
;; example: (lookup-variable 'A) is true
(define (lookup-variable variable)
(cond
[(symbol=? variable 'A) true]
[(symbol=? variable 'B) false]
[(symbol=? variable 'C) true]
[(symbol=? variable 'D) false]
[(symbol=? variable 'E) false]
[(symbol=? variable 'F) true]
[else (error 'lookup-variable
(string-append "Variable "
(symbol->string variable)
" unknown"))]
))
;; Tests
(check-expect (lookup-variable 'A) true)
(check-expect (lookup-variable 'B) false)
(check-expect (lookup-variable 'C) true)
(check-expect (lookup-variable 'D) false)
(check-expect (lookup-variable 'E) false)
(check-expect (lookup-variable 'F) true)
(check-error (lookup-variable 'G) "lookup-variable: Variable G unknown")
;;-------------------------------------------------------------------------------------------------------
;;-------------------------------------------CODE--------------------------------------------------------
;;-------------------------------------------------------------------------------------------------------
;; bool_not, bool_and, bool_or are constants
;; represtenting the textual-expression of
;; the named boolean operator
;;(define bool_equal 'equal)
(define bool_not 'not)
(define bool_and 'and)
(define bool_or 'or )
;; Contract: sym_is_unary: symbol -> boolean
;; Purpose: Tests if the given symbol sym is a unary operator
;; Examples: (sym_is_unary 'not)
;; (sym_is_unary 'equal)
(define (sym_is_unary sym)
(if (symbol? sym)
(cond [(symbol=? sym bool_not) true]
;;[(symbol=? sym bool_equal) true]
[else false]
)
(error 'sym_is_unary "Not a Symbol")
)
)
;;Test
(check-expect (sym_is_unary 'not) true)
(check-expect (sym_is_unary 'equal) false)
;; Contract: sym_is_binary: symbol -> boolean
;; Purpose: Tests if the given symbol sym is a binary operator
;; Examples: (sym_is_binary 'and)
;; (sym_is_binary 'equal)
(define (sym_is_binary sym)
(cond [(symbol=? sym bool_and) true]
[(symbol=? sym bool_or) true]
[else false]
)
)
;;Test
(check-expect (sym_is_binary 'and) true)
(check-expect (sym_is_binary 'equal) false)
;; Contract: input-tree: bool-input -> bool-tree
;; Purpose: Converts a bool-input into a bool-tree
;; Notice bool-input is not a struct, but
;; can be many things!
;; Examples: (input->tree (list 'and 'A true))
;; (input->tree (list 'or (list 'not 'A) 'B))
(define (input->tree input)
(if (cons? input)
(cond [(sym_is_unary (first input)) (make-bool-unary (first input) (input->tree (second input)))]
[(sym_is_binary (first input)) (make-bool-binary (first input) (input->tree (second input)) (input->tree (third input)))]
[(or (symbol? (first input)) (boolean? (first input))) (make-bool-direct (first input))]
[else empty] ;;empty
)
(if (or (symbol? input) (boolean? input))
(make-bool-direct input)
empty
)
)
)
;; Test
(check-expect (input->tree (list 'and 'A true))
(make-bool-binary 'and
(make-bool-direct 'A)
(make-bool-direct true)))
(check-expect (input->tree (list 'or (list 'not 'A) 'B))
(make-bool-binary 'or
(make-bool-unary 'not
(make-bool-direct 'A))
(make-bool-direct 'B)))
;; Contract: eval_not: bool -> bool
;; Purpose: evaluates not operator on given boolean bool.
;; Errors: "Not a Bool"
;; Examples: (eval_not true)
;; (eval_not false)
(define (eval_not bool)
(if (boolean? bool)
(if bool
false
true
)
(error 'eval_not "Not a Bool")
)
)
;; Test
(check-expect (eval_not true) false)
(check-expect (eval_not false) true)
;; Contract: eval-unary: symbol boolean -> boolean
;; Purpose: evalutes the result of an unary-operation on given unary-param.
;; Errors: "Not supported bool-unary"
;; "Not bool-unary"
;; Examples: (eval-unary 'not true)
;; (eval-unary 'not false)
(define (eval-unary unary-op unary-param)
(if (sym_is_unary unary-op)
(cond [(symbol=? bool_not unary-op) (eval_not unary-param)]
[else (error 'eval-unary "Not supported bool-unary")]
)
(error 'eval-unary "Not a bool-unary")
)
)
;; Test
(check-expect (eval-unary 'not true) false)
(check-expect (eval-unary 'not false) true)
;; Contract: eval_and: boolean boolean -> boolean
;; Purpose: evaluates and operator on given booleans bool1, bool2.
;; Errors: "Not a Bool"
;; Examples: (eval_and true true)
;; (eval_and false false)
(define (eval_and bool1 bool2)
(if (and (boolean? bool1) (boolean? bool2))
(if (and bool1 bool2)
true
false
)
(error 'eval_and "Not a Bool")
)
)
;; Test
(check-expect (eval_and true true) true)
(check-expect (eval_and false false) false)
;; Contract: eval_or: boolean boolean -> boolean
;; Purpose: evaluates or operator on given booleans bool1, bool2.
;; Errors: "Not a Bool"
;; Examples: (eval_or true true)
;; (eval_or false false)
(define (eval_or bool1 bool2)
(if (and (boolean? bool1) (boolean? bool2))
(if (or bool1 bool2)
true
false
)
(error 'eval_or "Not a Bool")
)
)
;; Test
(check-expect (eval_or true true) true)
(check-expect (eval_or false false) false)
;; Contract: eval-binary: symbol boolean boolean -> boolean
;; Purpose: evalutes the result of an binary-operation on given binary-param.
;; Error: "Not supported Binary Operator"
;; "Not a Binary Operator"
;; Examples: (eval-binary 'and true true)
;; (eval-unary 'or false true)
(define (eval-binary op left right)
(if (sym_is_binary op)
(cond [(symbol=? bool_and op) (eval_and left right)]
[(symbol=? bool_or op) (eval_or left right)]
[else (error 'eval-binary "Not supported Binary Operator")]
)
(error 'eval-binary "Not a Binary Operator")
)
)
;; Test
(check-expect (eval-binary 'and true true) true)
(check-expect (eval-binary 'or false true) true)
;; Contract: check_bool_tree: DATA -> boolean
;; Purpose: Tests if given data is of type bool-tree
;; Notice bool-tree can be many things!
;; Examples:
(define (check_bool_tree bt)
(if (or (bool-direct? bt)
(bool-unary? bt)
(bool-binary? bt)
(boolean? bt)
)
true
false
)
)
;; Test
(check-expect (check_bool_tree true) true)
(check-expect (check_bool_tree 'abc) false)
;; Contract: eval-direct: bool-direct -> boolean
;; Purpose: Tests if given value is a bool-direct and returns boolean value.
;; Uses lockup-variable.
;; Error: "Not a bool-direct"
;; Examples: (eval_direct true)
;; (eval_direct 'B)
(define (eval-direct bd)
(cond [(symbol? bd) (lookup-variable bd)]
[(boolean? bd) bd]
[else (error 'eval-direct "Not a bool-direct")]
)
)
;; Test
(check-expect (eval-direct true) true)
(check-expect (eval-direct 'B) false)
;; Contract: bool-tree->boolean: bool-tree -> boolean
;; Purpose: evaluates the value of a bool-tree.
;; Uses eval-direct, eval-unary and eval-binary.
;; Errors: "Not a bool-tree"
;; Example: (bool-tree->boolean (input->tree (list 'and 'A true)))
;; (bool-tree->boolean (input->tree (list 'or (list 'not 'A) 'B)))
(define (bool-tree->boolean a-bool-tree)
(if (check_bool_tree a-bool-tree)
(cond [(bool-direct? a-bool-tree) (eval-direct (bool-direct-value a-bool-tree))]
[(bool-unary? a-bool-tree) (eval-unary (bool-unary-op a-bool-tree)
(bool-tree->boolean (bool-unary-param a-bool-tree)))]
[(bool-binary? a-bool-tree) (eval-binary (bool-binary-op a-bool-tree)
(bool-tree->boolean (bool-binary-left a-bool-tree))
(bool-tree->boolean (bool-binary-right a-bool-tree)))]
[else (error 'bool-tree->boolean "Not a bool-tree")]
)
(error 'bool-tree->boolean "Not a bool-tree")
)
)
;; Tests
(check-expect (bool-tree->boolean (input->tree (list 'and 'A true))) true)
(check-expect (bool-tree->boolean (input->tree (list 'or (list 'not 'A) 'B)))false)
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Contract: remove-first: X (X X -> boolean) listofX -> listofX
;; Purpose: Removes the first element with value rv from list vl.
;; Uses eqop to determine if two elements are equal.
;; Examples: (remove-first 5 = '(12 4 6 5 7 8 9))
;; (remove-first 'c symbol=? (list 'a 'b 'c 'd))
(define (remove-first rv eqop vl)
(if (cons? vl)
(if (eqop rv
(first vl)
)
(rest vl)
(append (list (first vl)) (remove-first rv eqop (rest vl)))
)
(error 'remove-first "Not a List")
)
)
;; Test:
(check-expect (remove-first 5 = '(12 4 6 5 7 8 9)) '(12 4 6 7 8 9))
(check-expect (remove-first 'c symbol=? (list 'a 'b 'c 'd)) (list 'a 'b 'd))
;; Contract: lowoflist: listofX (X X -> X) -> X
;; Purpose: Returns smalest element of given list,
;; lowop is used to determine which is the
;; lower value.
;; Examples: (lowoflist '(1 2 3 4) (lambda (x y) (if (> x y) y x)))
;; (lowoflist '(5 3 7 4) (lambda (x y) (if (> x y) y x)))
;;(define (lowoflist vl lowop)
;; (if (cons? vl)
;; (local [(define (lolrecursiv vl lowop d)
;; (if (cons? vl)
;; (lolrecursiv (rest vl) lowop (lowop d (first vl)))
;; d
;; )
;; )]
;; (lolrecursiv (rest vl) lowop (first vl))
;; )
;; (error 'lowoflist "Not a List")
;; )
;;)
;; Contract: lowoflist: listofX (X X -> X) -> X
;; Purpose: Returns smalest element of given list,
;; lowop is used to determine which is the
;; lower value.
;; Examples: (lowoflist '(1 2 3 4) (lambda (x y) (if (> x y) y x)))
;; (lowoflist '(5 3 7 4) (lambda (x y) (if (> x y) y x)))
(define (lowoflist vl lowop)
(foldl lowop (first vl) (rest vl))
)
;; Test:
(check-expect (lowoflist '(1 2 3 4) (lambda (x y) (if (> x y) y x))) 1)
(check-expect (lowoflist '(5 3 7 4) (lambda (x y) (if (> x y) y x))) 3)
;; Contract: selection-sort: listofX (X X -> boolean) (X X -> X) -> listofX
;; Purpose: Sorts a list via Selectionsortalgorithm.
;; Examples: (selection-sort '(1 2 3 4) = (lambda (x y) (if (> x y) y x))) '(1 2 3 4))
;; (selection-sort '(5 3 7 1) = (lambda (x y) (if (> x y) y x))) '(1 3 5 7))
(define (selection-sort vl eqop lowop)
(local [;;(define lol (lowoflist vl lowop))
(define (ssrecursiv vl eqop lowop d)
(if (cons? vl)
(ssrecursiv (remove-first (lowoflist vl lowop) eqop vl) eqop lowop (append d (list (lowoflist vl lowop))))
d
)
)]
(ssrecursiv vl eqop lowop '())
)
)
;; Test:
(check-expect (selection-sort '(1 2 3 4) = (lambda (x y) (if (> x y) y x))) '(1 2 3 4))
(check-expect (selection-sort '(5 3 7 1) = (lambda (x y) (if (> x y) y x))) '(1 3 5 7))
(check-expect (selection-sort (list true false false true) boolean=? (lambda (x y) (if x x y))) (list true true false false))
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Contract: bool-direct->string: bool-direct -> string
;; Purpose: Converts a bool-direct to a string value.
;; Notice possible values of bool-direct
;; Examples: (bool-direct->string (make-bool-direct 'A))
;; (bool-direct->string (make-bool-direct false))
(define (bool-direct->string bd)
(if (bool-direct? bd)
(if (symbol? (bool-direct-value bd))
(symbol->string (bool-direct-value bd))
(if (bool-direct-value bd)
"true"
"false"
)
)
(error 'bool-direct->string "Not a Bool-Direct")
)
)
;; Test
(check-expect (bool-direct->string (make-bool-direct 'A)) "A")
(check-expect (bool-direct->string (make-bool-direct false)) "false")
;; Contract: bool-unary->string: bool-unary -> string
;; Purpose: Returns a string with Bool-Unary-Operator-String
;; Examples: (bool-unary->string (make-bool-unary 'not true))
;; (bool-unary->string (make-bool-unary 'not false))
(define (bool-unary->string bu)
(if (bool-unary? bu)
(symbol->string (bool-unary-op bu))
(error 'bool-unary->string "Not a Bool-Unary")
)
)
;; Test:
(check-expect (bool-unary->string (make-bool-unary 'not true)) "not")
(check-expect (bool-unary->string (make-bool-unary 'not false)) "not")
;; Contract: bool-binary->string: bool-binary -> string
;; Purpose: Returns a string with Bool-Binary-Operator-String
;; Examples: (bool-binary->string (make-bool-binary 'and true true))
;; (bool-binary->string (make-bool-binary 'or true true))
(define (bool-binary->string bb)
(if (bool-binary? bb)
(symbol->string (bool-binary-op bb))
(error 'bool-unary->string "Not a Bool-Binary")
)
)
(check-expect (bool-binary->string (make-bool-binary 'and true true)) "and")
(check-expect (bool-binary->string (make-bool-binary 'or true true)) "or")
;; Contract: tree-depth: bool-tree -> number
;; Purpose: Calculates the depth of a bool-tree-struct
;; First node is depth 1
;; Examples: (tree-depth (input->tree (list 'and 'A true)))
;; (tree-depth (input->tree (list 'or (list 'not 'A) 'B)))
(define (tree-depth bt)
(if (check_bool_tree bt)
(cond [(bool-direct? bt) 1]
[(bool-unary? bt) (+ 1 (tree-depth (bool-unary-param bt)))]
[(bool-binary? bt)
(if (> (tree-depth (bool-binary-left bt)) (tree-depth (bool-binary-right bt)))
(+ 1 (tree-depth (bool-binary-left bt)))
(+ 1 (tree-depth (bool-binary-right bt)))
)
]
)
(error 'tree-depth "Not a Boo-Tree")
)
)
;; Test:
(check-expect (tree-depth (input->tree (list 'and 'A true))) 2)
(check-expect (tree-depth (input->tree (list 'or (list 'not 'A) 'B))) 3)
;; Contract: render-tree: bool-tree number number number -> void
;; Purpose: Renders a given bool-tree at given position number1 number2
;; with width number3.
;; Examples: None
;;(define (render-tree bt x y d)
;; (local [(define (render-tree-recursiv bt x y d)
;; (cond [(bool-direct? bt)(draw-solid-string (make-posn x y) (bool-direct->string bt))]
;; [(bool-unary? bt) (begin (draw-solid-string (make-posn x y) (bool-unary->string bt))
;; (draw-solid-line (make-posn x y) (make-posn (+ x d) (+ y d)))
;; (render-tree-recursiv (bool-unary-param bt) (+ x d) (+ y d) (/ d 2))
;; )]
;; [(bool-binary? bt) (begin (draw-solid-string (make-posn x y) (bool-binary->string bt))
;; (draw-solid-line (make-posn x y) (make-posn (+ x d) (+ y d)))
;; (render-tree-recursiv (bool-binary-right bt) (+ x d) (+ y d) (/ d 2))
;; (draw-solid-line (make-posn x y) (make-posn (- x d) (+ y d)))
;; (render-tree-recursiv (bool-binary-left bt) (- x d) (+ y d) (/ d 2))
;; )]
;; [else void]
;; )
;; )]
;; (if (and (check_bool_tree bt)
;; (number? x)
;; (number? y)
;; (number? d)
;; )
;; (begin (start (+ (* d 2) x) (+ (* d 2) y))
;; (render-tree-recursiv bt x y d)
;; )
;; (error 'render-tree "Parameter missmatch")
;; )
;; )
;;)
;; Test: NONE
;;(render-tree (input->tree (list 'and 'A true)) 100 100 50)
;;(render-tree (input->tree (list 'or (list 'not 'A) 'B)) 100 100 50)
;;(render-tree (input->tree (list 'or (list 'not 'A) (list 'and 'C 'A))) 100 100 50)
;;(render-tree (input->tree (list 'or (list 'not (list 'not 'A)) (list 'and 'C 'A))) 100 100 50)
;;(render-tree (input->tree (list 'or (list 'not (list 'and (list 'not 'A) (list 'or (list 'and 'A 'B) (list 'not 'B)))) (list 'and 'C 'A))) 500 50 320)
;; Contract: determine-initial-width: bool-tree number -> number
;; Purpose: Determines the width of the first node of the given
;; bool-tree with given width of last node of the tree.
;; Examples: (determine-initial-width (make-bool-direct 'A) 5)
;; (determine-initial-width (make-bool-binary 'or (make-bool-direct 'B) (make-bool-direct 'A)) 5)
(define (determine-initial-width bt d)
(if (and (check_bool_tree bt)
(number? d)
)
(* d
(expt 2
(- (tree-depth bt)
1
)
)
)
(error 'determine-initial-width "Parameter Missmatch")
)
)
;; Test:
(check-expect (determine-initial-width (make-bool-direct 'A) 5) 5)
(check-expect (determine-initial-width (make-bool-binary 'or (make-bool-direct 'B) (make-bool-direct 'A)) 5) 10)
;; Contratc: render-tree-minimal-width: bool-tree number number number -> void
;; Purpose: Renders a given bool-tree at given point x y with last tree-node-width
;; equal to md.
;; Uses determine-initial-width
;; Examples: (render-tree-minimal-width (input->tree (list 'or (list 'not (list 'and (list 'not 'A) (list 'or (list 'and 'A 'B) (list 'not 'B)))) (list 'and 'C 'A))) 500 10 10)
;; (render-tree-minimal-width (input->tree (list 'or (list 'and (list 'and (list 'or (list 'and 'A 'B) (list 'not 'B)) (list 'not 'A)) (list 'and 'C 'A)) (list 'and 'C 'A))) 650 10 10)
(define (render-tree-minimal-width bt x y md)
(local [(define (render-tree-inner bt x y d)
(local [(define (render-tree-recursiv bt x y d)
(cond [(bool-direct? bt)(draw-solid-string (make-posn x y) (bool-direct->string bt))]
[(bool-unary? bt) (begin (draw-solid-string (make-posn x y) (bool-unary->string bt))
(draw-solid-line (make-posn x y) (make-posn (+ x d) (+ y d)))
(render-tree-recursiv (bool-unary-param bt) (+ x d) (+ y d) (/ d 2))
)]
[(bool-binary? bt) (begin (draw-solid-string (make-posn x y) (bool-binary->string bt))
(draw-solid-line (make-posn x y) (make-posn (+ x d) (+ y d)))
(render-tree-recursiv (bool-binary-right bt) (+ x d) (+ y d) (/ d 2))
(draw-solid-line (make-posn x y) (make-posn (- x d) (+ y d)))
(render-tree-recursiv (bool-binary-left bt) (- x d) (+ y d) (/ d 2))
)]
[else void]
)
)]
(if (and (check_bool_tree bt)
(number? x)
(number? y)
(number? d)
)
(begin (start (+ (* d 2) x) (+ (* d 2) y))
(render-tree-recursiv bt x y d)
)
(error 'render-tree "Parameter missmatch")
)
)
)]
(render-tree-inner bt x y (determine-initial-width bt md))
)
)
;; Test: NONE
;;(render-tree-minimal-width (input->tree (list 'or (list 'not (list 'and (list 'not 'A) (list 'or (list 'and 'A 'B) (list 'not 'B)))) (list 'and 'C 'A))) 500 10 10)
;;(render-tree-minimal-width (input->tree (list 'or (list 'and (list 'and (list 'or (list 'and 'A 'B) (list 'not 'B)) (list 'not 'A)) (list 'and 'C 'A)) (list 'and 'C 'A))) 650 10 10)
;; Contract: render-tree-intelligent: bool-tree number -> void
;; Purpose: Renders given bool-tree with given width for last
;; tree-node.
;; Examples: (render-tree-intelligent (input->tree (list 'or (list 'not (list 'and (list 'not 'A) (list 'or (list 'and 'A 'B) (list 'not 'B)))) (list 'and 'C 'A))) 10)
;; (render-tree-intelligent (input->tree (list 'or (list 'and (list 'and (list 'or (list 'and 'A 'B) (list 'not 'B)) (list 'not 'A)) (list 'and 'C 'A)) (list 'and 'C 'A))) 10)
(define (render-tree-intelligent bt md)
(render-tree-minimal-width bt (* (determine-initial-width bt md) 2) 10 md)
)
;; Test: NONE
;;(render-tree-intelligent (input->tree (list 'or (list 'not (list 'and (list 'not 'A) (list 'or (list 'and 'A 'B) (list 'not 'B)))) (list 'and 'C 'A))) 10)
;;(render-tree-intelligent (input->tree (list 'or (list 'and (list 'and (list 'or (list 'and 'A 'B) (list 'not 'B)) (list 'not 'A)) (list 'and 'C 'A)) (list 'and 'C 'A))) 10)
;; Contract: render-tree-moAr-intelligent: bool-tree -> void
;; Purpose: Renders given bool-tree.
;; Examples: (render-tree-moAr-intelligent (input->tree (list 'or (list 'not (list 'and (list 'not 'A) (list 'or (list 'and 'A 'B) (list 'not 'B)))) (list 'and 'C 'A))))
;; (render-tree-moAr-intelligent (input->tree (list 'or (list 'and (list 'and (list 'or (list 'and 'A 'B) (list 'not 'B)) (list 'not 'A)) (list 'and 'C 'A)) (list 'and 'C 'A))))
(define (render-tree-moAr-intelligent bt)
(render-tree-minimal-width bt (* (determine-initial-width bt 10) 2) 10 10)
)
;; Test: NONE
;;(render-tree-moAr-intelligent (input->tree (list 'or (list 'not (list 'and (list 'not 'A) (list 'or (list 'and 'A 'B) (list 'not 'B)))) (list 'and 'C 'A))))
(render-tree-moAr-intelligent (input->tree (list 'or (list 'and (list 'and (list 'or (list 'and 'A 'B) (list 'not 'B)) (list 'not 'A)) (list 'and 'C 'A)) (list 'and 'C 'A))))
(render-tree-moAr-intelligent (input->tree (list 'or (list 'and (list 'and (list 'or (list 'and 'A 'B) (list 'not 'B)) (list 'not 'A)) (list 'and 'C 'A)) (list 'and (list 'and (list 'or (list 'and 'A (list 'or 'A 'B)) 'C) 'D) 'B) 'A)))

View File

@ -0,0 +1,11 @@
;; The first three lines of this file were inserted by DrScheme. They record metadata
;; about the language level of this file in a form that our tools can easily process.
#reader(lib "htdp-advanced-reader.ss" "lang")((modname u05) (read-case-sensitive #t) (teachpacks ()) (htdp-settings #(#t constructor repeating-decimal #t #t none #f ())))
(define (recursive-fun problem)
( cond [(empty? problem) 0]
[ else (+ (1 (rest problem)))]
)
)
(check-expect (recursive-fun (list 1 2 3)) 3)
(check-expect (recursive-fun (list 1 2 3 4 5 6)) 6)

View File

@ -0,0 +1,375 @@
;; The first three lines of this file were inserted by DrScheme. They record metadata
;; about the language level of this file in a form that our tools can easily process.
#reader(lib "htdp-advanced-reader.ss" "lang")((modname u05) (read-case-sensitive #t) (teachpacks ((lib "draw.ss" "teachpack" "htdp"))) (htdp-settings #(#t constructor repeating-decimal #t #t none #f ((lib "draw.ss" "teachpack" "htdp")))))
;;(c) Ulf Gebhardt
;; Ich benutze in der ganzen Aufgabe kein (local ...)
;; Das mache ich bewusst, denn ich finde es sehr unübersichtlich,
;; wenn alle Funktion in er Prozedur definiert sind.
;; Wie man das Problem der Namensraumverschmutzung auch ohne
;; (local ...) lösen kann finden Sie am Ende der Datei (Aufgabe 5.5)
;; a bool-input is either
;; 1. a boolean value (true,false,an expression evaluated to true/false)
;; 2. a symbol 'A...'F for a boolean variable
;; 3. (list 'not b), where b is a bool-input
;; 4. (list 'and b1 b2), where b1 and b2 have type bool-input
;; 5. (list 'or b1 b2), where b1 and b2 have type bool-input
;; a bool-tree is either
;; 1. a bool-direct (boolean value or boolean variable)
;; 2. a bool-unary (unary operator, i.e., 'not)
;; 3. a bool-binary (binary operator, e.g., 'and, 'or)
;; a bool-direct represents direct boolean values
;; value: direct-boolean - a boolean value that can be either
;; 1. a boolean value, i.e., something that evaluates to true or false,
;; 2. or a symbol that represents one of the variables 'A...'F
(define-struct bool-direct (value))
;; bool-unary represents unary boolean operators
;; op: symbol - a legal unary operator (e.g., 'not)
;; param: bool-tree - a boolean expression
(define-struct bool-unary (op param))
;; bool-binary represents binary boolean operators
;; op: symbol - a legal binary operator (e.g., 'and, 'or)
;; left: bool-tree - the left (2.) part of the binary boolean expression
;; right: bool-tree - the right (3.) part of the binary boolean expr.
(define-struct bool-binary (op left right))
;; lookup-variable: symbol -> boolean
;; looks up the value of the symbol passed in
;; if undefined, returns an error
;; example: (lookup-variable 'A) is true
(define (lookup-variable variable)
(cond
[(symbol=? variable 'A) true]
[(symbol=? variable 'B) false]
[(symbol=? variable 'C) true]
[(symbol=? variable 'D) false]
[(symbol=? variable 'E) false]
[(symbol=? variable 'F) true]
[else (error 'lookup-variable
(string-append "Variable "
(symbol->string variable)
" unknown"))]
))
;; Tests
(check-expect (lookup-variable 'A) true)
(check-expect (lookup-variable 'B) false)
(check-expect (lookup-variable 'C) true)
(check-expect (lookup-variable 'D) false)
(check-expect (lookup-variable 'E) false)
(check-expect (lookup-variable 'F) true)
(check-error (lookup-variable 'G) "lookup-variable: Variable G unknown")
;;-------------------------------------------------------------------------------------------------------
;;-------------------------------------------CODE--------------------------------------------------------
;;-------------------------------------------------------------------------------------------------------
;; bool_not, bool_and, bool_or are constants
;; represtenting the textual-expression of
;; the named boolean operator
;;(define bool_equal 'equal)
(define bool_not 'not)
(define bool_and 'and)
(define bool_or 'or )
;; Contract: sym_is_unary: symbol -> boolean
;; Purpose: Tests if the given symbol sym is a unary operator
;; Examples: (sym_is_unary 'not)
;; (sym_is_unary 'equal)
(define (sym_is_unary sym)
(cond [(symbol=? sym bool_not) true]
;;[(symbol=? sym bool_equal) true]
[else false]
)
)
;;Test
(check-expect (sym_is_unary 'not) true)
(check-expect (sym_is_unary 'equal) false)
;; Contract: sym_is_binary: symbol -> boolean
;; Purpose: Tests if the given symbol sym is a binary operator
;; Examples: (sym_is_binary 'and)
;; (sym_is_binary 'equal)
(define (sym_is_binary sym)
(cond [(symbol=? sym bool_and) true]
[(symbol=? sym bool_or) true]
[else false]
)
)
;;Test
(check-expect (sym_is_binary 'and) true)
(check-expect (sym_is_binary 'equal) false)
;; Contract: input-tree: bool-input -> bool-tree
;; Purpose: Converts a bool-input into a bool-tree
;; Notice bool-input is not a struct, but
;; can be many things!
;; Examples: (input->tree (list 'and 'A true))
;; (input->tree (list 'or (list 'not 'A) 'B))
(define (input->tree input)
(if (cons? input)
(cond [(sym_is_unary (first input)) (make-bool-unary (first input) (input->tree (rest input)))]
[(sym_is_binary (first input)) (make-bool-binary (first input) (input->tree (second input)) (input->tree (third input)))]
[(or (symbol? (first input)) (boolean? (first input))) (make-bool-direct (first input))]
[else empty] ;;empty
)
(if (or (symbol? input) (boolean? input))
(make-bool-direct input)
empty
)
)
)
;; Test
(check-expect (input->tree (list 'and 'A true))
(make-bool-binary 'and
(make-bool-direct 'A)
(make-bool-direct true)))
(check-expect (input->tree (list 'or (list 'not 'A) 'B))
(make-bool-binary 'or
(make-bool-unary 'not
(make-bool-direct 'A))
(make-bool-direct 'B)))
;; Contract: eval_not: bool -> bool
;; Purpose: evaluates not operator on given boolean bool.
;; Errors: "Not a Bool"
;; Examples: (eval_not true)
;; (eval_not false)
(define (eval_not bool)
(if (boolean? bool)
(if bool
false
true
)
(error 'eval_not "Not a Bool")
)
)
;; Test
(check-expect (eval_not true) false)
(check-expect (eval_not false) true)
;; Contract: eval-unary: symbol boolean -> boolean
;; Purpose: evalutes the result of an unary-operation on given unary-param.
;; Errors: "Not supported bool-unary"
;; "Not bool-unary"
;; Examples: (eval-unary 'not true)
;; (eval-unary 'not false)
(define (eval-unary unary-op unary-param)
(if (sym_is_unary unary-op)
(cond [(symbol=? bool_not unary-op) (eval_not unary-param)]
[else (error 'eval-unary "Not supported bool-unary")]
)
(error 'eval-unary "Not a bool-unary")
)
)
;; Test
(check-expect (eval-unary 'not true) false)
(check-expect (eval-unary 'not false) true)
;; Contract: eval_and: boolean boolean -> boolean
;; Purpose: evaluates and operator on given booleans bool1, bool2.
;; Errors: "Not a Bool"
;; Examples: (eval_and true true)
;; (eval_and false false)
(define (eval_and bool1 bool2)
(if (and (boolean? bool1) (boolean? bool2))
(if (and bool1 bool2)
true
false
)
(error 'eval_and "Not a Bool")
)
)
;; Test
(check-expect (eval_and true true) true)
(check-expect (eval_and false false) false)
;; Contract: eval_or: boolean boolean -> boolean
;; Purpose: evaluates or operator on given booleans bool1, bool2.
;; Errors: "Not a Bool"
;; Examples: (eval_or true true)
;; (eval_or false false)
(define (eval_or bool1 bool2)
(if (and (boolean? bool1) (boolean? bool2))
(if (or bool1 bool2)
true
false
)
(error 'eval_or "Not a Bool")
)
)
;; Test
(check-expect (eval_or true true) true)
(check-expect (eval_or false false) false)
;; Contract: eval-binary: symbol boolean boolean -> boolean
;; Purpose: evalutes the result of an binary-operation on given binary-param.
;; Error: "Not supported Binary Operator"
;; "Not a Binary Operator"
;; Examples: (eval-binary 'and true true)
;; (eval-unary 'or false true)
(define (eval-binary op left right)
(if (sym_is_binary op)
(cond [(symbol=? bool_and op) (eval_and left right)]
[(symbol=? bool_or op) (eval_or left right)]
[else (error 'eval-binary "Not supported Binary Operator")]
)
(error 'eval-binary "Not a Binary Operator")
)
)
;; Test
(check-expect (eval-binary 'and true true) true)
(check-expect (eval-binary 'or false true) true)
;; Contract: check_bool_tree: DATA -> boolean
;; Purpose: Tests if given data is of type bool-tree
;; Notice bool-tree can be many things!
;; Examples:
(define (check_bool_tree bt)
(if (or (bool-direct? bt)
(bool-unary? bt)
(bool-binary? bt)
(boolean? bt)
)
true
false
)
)
;; Test
(check-expect (check_bool_tree true) true)
(check-expect (check_bool_tree 'abc) false)
;; Contract: eval-direct: bool-direct -> boolean
;; Purpose: Tests if given value is a bool-direct and returns boolean value.
;; Uses lockup-variable.
;; Error: "Not a bool-direct"
;; Examples: (eval_direct true)
;; (eval_direct 'B)
(define (eval-direct bd)
(cond [(symbol? bd) (lookup-variable bd)]
[(boolean? bd) bd]
[else (error 'eval-direct "Not a bool-direct")]
)
)
;; Test
(check-expect (eval-direct true) true)
(check-expect (eval-direct 'B) false)
;; Contract: bool-tree->boolean: bool-tree -> boolean
;; Purpose: evaluates the value of a bool-tree.
;; Uses eval-direct, eval-unary and eval-binary.
;; Errors: "Not a bool-tree"
;; Example: (bool-tree->boolean (input->tree (list 'and 'A true)))
;; (bool-tree->boolean (input->tree (list 'or (list 'not 'A) 'B)))
(define (bool-tree->boolean a-bool-tree)
(if (check_bool_tree a-bool-tree)
(cond [(bool-direct? a-bool-tree) (eval-direct (bool-direct-value a-bool-tree))]
[(bool-unary? a-bool-tree) (eval-unary (bool-unary-op a-bool-tree)
(bool-tree->boolean (bool-unary-param a-bool-tree)))]
[(bool-binary? a-bool-tree) (eval-binary (bool-binary-op a-bool-tree)
(bool-tree->boolean (bool-binary-left a-bool-tree))
(bool-tree->boolean (bool-binary-right a-bool-tree)))]
[else (error 'bool-tree->boolean "Not a bool-tree")]
)
(error 'bool-tree->boolean "Not a bool-tree")
)
)
;; Tests
(check-expect (bool-tree->boolean (input->tree (list 'and 'A true))) true)
(check-expect (bool-tree->boolean (input->tree (list 'or (list 'not 'A) 'B)))false)
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;(define (recursive-fun problem)
;; ( cond [(empty? problem) 0]
;; [else (+ 1 (recursive-fun (rest problem)))]
;; )
;;)
(define (trivially-solvable? p)
(empty? p)
)
(define (determine-solution p)
0
)
(define (combine-solutions p p2)
(+ 1 p2)
)
(define (generate-problem p)
(rest p)
)
(define (recursive-fun problem)
(cond [(trivially-solvable? problem)
(determine-solution problem)]
[else (combine-solutions problem (recursive-fun (generate-problem problem)))]
)
)
(check-expect (recursive-fun (list 1 2 3)) 3)
(check-expect (recursive-fun (list 1 2 3 4 5 6)) 6)
(define (calc-newton f dfx x)
(if (= (dfx x) 0)
0
(- x (/ (f x) (dfx x)))
)
)
(define (newton-method f dfx x delta)
(if (< (- (abs x)
(abs (calc-newton f dfx x))
)
(abs delta)
)
(calc-newton f dfx x)
(newton-method f dfx (calc-newton f dfx x) delta)
)
)
(check-within (newton-method (lambda (x) (* x x)) (lambda (x) (* 2 x)) -5 0.01) -0.10 0.10)
(check-within (newton-method (lambda (x) (- (* x x) 5)) (lambda (x) (* 2 x)) 1 0.01) 2.20 2.30)
;;(newton-method (lambda (x) (+ (* x x x x) -7 (* x x))) (lambda (x) (+ (* 4 x x x) (* 2 x))) 5 0.01)
;;(define (convert x b)
;; (local [(define (convrecursiv x b c d)
;; (if (> c 0)
;; (if (- x exp(b c)
;; (append d
;; d
;; )]
;; (convrecursiv x b (length-representation x b) '() )
;;)
(define (length-representation x b)
(local [(define (rlrecursiv x b p)
(if (<= x
(expt b p)
)
p;;if
(rlrecursiv x b (+ 1 p));;else
)
)]
(rlrecursiv x b 1)
)
)
;;(length-representation 10 16)

View File

View File

@ -0,0 +1,358 @@
;; The first three lines of this file were inserted by DrScheme. They record metadata
;; about the language level of this file in a form that our tools can easily process.
#reader(lib "htdp-advanced-reader.ss" "lang")((modname h06) (read-case-sensitive #t) (teachpacks ()) (htdp-settings #(#t constructor repeating-decimal #t #t none #f ())))
;; Contract: remove-first: X (X X -> boolean) listofX -> listofX
;; Purpose: Removes the first element with value rv from list vl.
;; Uses eqop to determine if two elements are equal.
;; Examples: (remove-first 5 = '(12 4 6 5 7 8 9))
;; (remove-first 'c symbol=? (list 'a 'b 'c 'd))
(define (remove-first rv eqop vl)
(if (cons? vl)
(if (eqop rv
(first vl)
)
(rest vl)
(append (list (first vl)) (remove-first rv eqop (rest vl)))
)
(error 'remove-first "Not a List")
)
)
;; Test:
(check-expect (remove-first 5 = '(12 4 6 5 7 8 9)) '(12 4 6 7 8 9))
(check-expect (remove-first 'c symbol=? (list 'a 'b 'c 'd)) (list 'a 'b 'd))
;; Contract: lowoflist: listofX (X X -> X) -> X
;; Purpose: Returns smalest element of given list,
;; lowop is used to determine which is the
;; lower value.
;; Examples: (lowoflist '(1 2 3 4) (lambda (x y) (if (> x y) y x)))
;; (lowoflist '(5 3 7 4) (lambda (x y) (if (> x y) y x)))
;;(define (lowoflist vl lowop)
;; (if (cons? vl)
;; (local [(define (lolrecursiv vl lowop d)
;; (if (cons? vl)
;; (lolrecursiv (rest vl) lowop (lowop d (first vl)))
;; d
;; )
;; )]
;; (lolrecursiv (rest vl) lowop (first vl))
;; )
;; (error 'lowoflist "Not a List")
;; )
;;)
;; Contract: lowoflist: listofX (X X -> X) -> X
;; Purpose: Returns smalest element of given list,
;; lowop is used to determine which is the
;; lower value.
;; Examples: (lowoflist '(1 2 3 4) (lambda (x y) (if (> x y) y x)))
;; (lowoflist '(5 3 7 4) (lambda (x y) (if (> x y) y x)))
(define (lowoflist vl lowop)
(foldl lowop (first vl) (rest vl))
)
;; Test:
(check-expect (lowoflist '(1 2 3 4) (lambda (x y) (if (> x y) y x))) 1)
(check-expect (lowoflist '(5 3 7 4) (lambda (x y) (if (> x y) y x))) 3)
;; Contract: selection-sort: listofX (X X -> boolean) (X X -> X) -> listofX
;; Purpose: Sorts a list via Selectionsortalgorithm.
;; Examples: (selection-sort '(1 2 3 4) = (lambda (x y) (if (> x y) y x))) '(1 2 3 4))
;; (selection-sort '(5 3 7 1) = (lambda (x y) (if (> x y) y x))) '(1 3 5 7))
(define (selection-sort vl eqop lowop)
(local [;;(define lol (lowoflist vl lowop))
(define (ssrecursiv vl eqop lowop d)
(if (cons? vl)
(ssrecursiv (remove-first (lowoflist vl lowop) eqop vl) eqop lowop (append d (list (lowoflist vl lowop))))
d
)
)]
(ssrecursiv vl eqop lowop '())
)
)
;; Test:
(check-expect (selection-sort '(1 2 3 4) = (lambda (x y) (if (> x y) y x))) '(1 2 3 4))
(check-expect (selection-sort '(5 3 7 1) = (lambda (x y) (if (> x y) y x))) '(1 3 5 7))
(check-expect (selection-sort (list true false false true) boolean=? (lambda (x y) (if x x y))) (list true true false false))
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(define (palindrome input)
(if (cons? input)
(append input
(rest (foldl cons
empty
input
)
)
)
;;(error 'palindrome "Not a List")
empty
)
)
(check-expect (palindrome '(1 2 3 4 5 6)) '(1 2 3 4 5 6 5 4 3 2 1))
(check-expect (palindrome '(a b c d e f)) '(a b c d e f e d c b a))
(check-expect (palindrome empty) empty)
(check-expect (palindrome (list 'a 'b 'c 'd))
(list 'a 'b 'c 'd 'c 'b 'a))
(check-expect (palindrome empty) empty)
(check-expect (palindrome (list 1 2 3 4)) (list 1 2 3 4 3 2 1))
(define (doubled-palindrome input)
(if (cons? input)
(foldl (lambda (x y)
(append y
(cons x
(cons x
empty
)
)
)
)
(list)
(palindrome input)
)
;;(error 'palindrome-double "Not a List")
empty
)
)
(check-expect (doubled-palindrome '(1 2 3 4 5 6)) '(1 1 2 2 3 3 4 4 5 5 6 6 5 5 4 4 3 3 2 2 1 1))
(check-expect (doubled-palindrome '(a b c d e f)) '(a a b b c c d d e e f f e e d d c c b b a a))
(check-expect (doubled-palindrome (list 'a 'b ))
'(a a b b a a))
(check-expect (doubled-palindrome empty) empty)
(check-expect (doubled-palindrome (list 1 2 3))
(list 1 1 2 2 3 3 2 2 1 1))
(define-struct cargo (name urgency mass))
(define max_weight 7667) ;;in kg
;; some potential cargo items for the upcoming launch
(define chocolate (make-cargo "Chocolate" 40 5))
(define electronics (make-cargo "Entertainment Electronics" 45 100))
(define exp41 (make-cargo "Experiment #41" 50 300))
(define exp42 (make-cargo "Experiment #42" 50 1200))
(define plaques (make-cargo "Info Plaques" 60 6000))
(define potential-cargo
(list chocolate electronics exp41 exp42 plaques))
(define test-cargo-list1
(list chocolate electronics exp42 plaques))
(define test-cargo-list2
(list chocolate exp42 plaques))
(define test-cargo-list3
(list chocolate electronics exp41 exp42 plaques))
(define test_cargo_1 (list (make-cargo 'a 10 10)
(make-cargo 'b 10 50)
(make-cargo 'c 10 100)
(make-cargo 'd 10 150)
(make-cargo 'e 10 200)
(make-cargo 'f 10 300)
(make-cargo 'g 10 400)
(make-cargo 'h 10 500)
(make-cargo 'i 10 1000)
(make-cargo 'j 10 1500)
(make-cargo 'k 10 2000)
(make-cargo 'l 10 3000)
)
)
(define test_cargo_2 (list (make-cargo 'a 10 10)
(make-cargo 'b 20 50)
(make-cargo 'c 30 100)
(make-cargo 'd 40 150)
(make-cargo 'e 50 200)
(make-cargo 'f 100 300)
(make-cargo 'g 200 400)
(make-cargo 'h 300 500)
(make-cargo 'i 400 1000)
(make-cargo 'j 500 1500)
(make-cargo 'k 1000 2000)
(make-cargo 'l 2000 3000)
)
)
(define test_cargo_3 (list (make-cargo 'a 2000 10)
(make-cargo 'b 1000 50)
(make-cargo 'c 500 100)
(make-cargo 'd 400 150)
(make-cargo 'e 300 200)
(make-cargo 'f 200 300)
(make-cargo 'g 100 400)
(make-cargo 'h 50 500)
(make-cargo 'i 40 1000)
(make-cargo 'j 30 1500)
(make-cargo 'k 20 2000)
(make-cargo 'l 10 3000)
)
)
(define (cargo-urgency-sum loc)
(if (cons? loc)
(foldl (lambda (x y)
(if (cargo? x)
(+ y
(cargo-urgency x)
)
(error 'cargo-urgency-sum "List-Element not a Cargo-Struct")
)
)
0
loc
)
(error 'corgo-urgency-sum "Not a List")
)
)
(check-expect (cargo-urgency-sum test_cargo_1) 120)
(check-expect (cargo-urgency-sum test_cargo_2) 4650)
(check-expect (cargo-urgency-sum test-cargo-list1) 195)
(check-expect (cargo-urgency-sum test-cargo-list2) 150)
(check-expect (cargo-urgency-sum test-cargo-list3) 245)
(check-expect (cargo-urgency-sum potential-cargo) 245)
;;(define (cargo-urgency-mass-quotient c)
;; (if (cargo? c)
;; (/ (cargo-urgency c)
;; (cargo-mass c)
;; )
;; (error 'corgo-urgeny-mass-quorient "Not a Cargo-Struct")
;; )
;;)
;;(check-expect (cargo-urgency-mass-quotient chocolate) 8)
;;(check-expect (cargo-urgency-mass-quotient plaques) 0.01)
;;(define (create-cargo-list loc maxw)
;; (local [(define (create-cargo-list-recursiv sloc amaxw)
;; (if (cons? sloc)
;; (if (<= (cargo-mass (first sloc))
;; amaxw
;; )
;; (cons (first sloc)
;; (create-cargo-list-recursiv (rest sloc)
;; (- amaxw (cargo-mass (first sloc)))
;; )
;; )
;; (create-cargo-list-recursiv (rest sloc)
;; amaxw
;; )
;; )
;; empty
;; )
;; )]
;; (create-cargo-list-recursiv (selection-sort loc
;; (lambda (x y)
;; (if (= (cargo-urgency-mass-quotient x)
;; (cargo-urgency-mass-quotient y)
;; )
;; true
;; false
;; )
;; )
;; (lambda (x y)
;; (if (> (cargo-urgency-mass-quotient x)
;; (cargo-urgency-mass-quotient y)
;; )
;; x
;; y
;; )
;; )
;; )
;; maxw
;; )
;; )
;;)
(define (create-list cargo max-mass)
(if (cons? cargo)
(if (<= (cargo-mass (first cargo))
max-mass
)
(cons (first cargo)
(create-list (rest cargo)
(- max-mass (cargo-mass (first cargo)))
)
)
(create-list (rest cargo)
max-mass
)
)
empty
)
)
(define (create-cargo-list-recursiv cargo cargo2 max-mass)
(if (>= (cargo-urgency-sum (create-list cargo max-mass))
(cargo-urgency-sum (create-list cargo2 max-mass))
)
(create-list cargo max-mass)
(create-list cargo2 max-mass)
)
)
(define (create-cargo-list cargo max-mass)
(if (and (cons? cargo)
(number? max-mass)
)
(create-cargo-list-recursiv (selection-sort cargo
(lambda (x y)
(if (= (cargo-mass x)
(cargo-mass y)
)
true
false
)
)
(lambda (x y)
(if (> (cargo-mass x)
(cargo-mass y)
)
x
y
)
)
)
(selection-sort cargo
(lambda (y x)
(if (= (cargo-mass x)
(cargo-mass y)
)
true
false
)
)
(lambda (y x)
(if (> (cargo-mass x)
(cargo-mass y)
)
x
y
)
)
)
max-mass
);;(cargolist cargo max-mass 0)
(error 'create-cargo-list "Parameter Missmatch")
)
)
;;(create-cargo-list test_cargo_2 max_weight)
;;(create-cargo-list test_cargo_3 max_weight)
;;(create-cargo-list potential-cargo 50)
(check-expect (create-cargo-list potential-cargo 50)
(list chocolate))
(check-expect (create-cargo-list test-cargo-list1 100)
(list electronics))
(check-expect (create-cargo-list potential-cargo 350)
(list exp41 chocolate))
(check-expect (create-cargo-list test-cargo-list1 350)
(list electronics chocolate))

View File

@ -0,0 +1,56 @@
;; The first three lines of this file were inserted by DrScheme. They record metadata
;; about the language level of this file in a form that our tools can easily process.
#reader(lib "htdp-intermediate-lambda-reader.ss" "lang")((modname template-atv06) (read-case-sensitive #t) (teachpacks ()) (htdp-settings #(#t constructor repeating-decimal #f #t none #f ())))
;; cargo represents items for transport
;; name: string - the name of the cargo item
;; urgency: number - the urgeny of the delivere,
;; the higher, the more urgend
;; mass: number - the mass of the item in kg
(define-struct cargo (name urgency mass))
;; some potential cargo items for the upcoming launch
(define chocolate (make-cargo "Chocolate" 40 5))
(define electronics (make-cargo "Entertainment Electronics" 45 100))
(define exp41 (make-cargo "Experiment #41" 50 300))
(define exp42 (make-cargo "Experiment #42" 50 1200))
(define plaques (make-cargo "Info Plaques" 60 6000))
(define potential-cargo
(list chocolate electronics exp41 exp42 plaques))
(define test-cargo-list1
(list chocolate electronics exp42 plaques))
(define test-cargo-list2
(list chocolate exp42 plaques))
(define test-cargo-list3
(list chocolate electronics exp41 exp42 plaques))
;;
;;
;;
;;
(define (cargo-urgency-sum cargolist) ... )
;; Tests
(check-expect (cargo-urgency-sum test-cargo-list1) 195)
(check-expect (cargo-urgency-sum test-cargo-list2) 150)
(check-expect (cargo-urgency-sum test-cargo-list3) 245)
(check-expect (cargo-urgency-sum potential-cargo) 245)
;;
;;
;;
;;
(define (create-cargo-list cargo max-mass) ...)
;; Tests
(check-expect (create-cargo-list potential-cargo 50)
(list chocolate))
(check-expect (create-cargo-list test-cargo-list1 100)
(list electronics))
(check-expect (create-cargo-list potential-cargo 350)
(list chocolate exp41))
(check-expect (create-cargo-list test-cargo-list1 350)
(list chocolate electronics))

View File

@ -0,0 +1,187 @@
;; The first three lines of this file were inserted by DrScheme. They record metadata
;; about the language level of this file in a form that our tools can easily process.
#reader(lib "htdp-intermediate-lambda-reader.ss" "lang")((modname template-atv06) (read-case-sensitive #t) (teachpacks ()) (htdp-settings #(#t constructor repeating-decimal #f #t none #f ())))
;; Contract: remove-first: X (X X -> boolean) listofX -> listofX
;; Purpose: Removes the first element with value rv from list vl.
;; Uses eqop to determine if two elements are equal.
;; Examples: (remove-first 5 = '(12 4 6 5 7 8 9))
;; (remove-first 'c symbol=? (list 'a 'b 'c 'd))
(define (remove-first rv eqop vl)
(if (cons? vl)
(if (eqop rv
(first vl)
)
(rest vl)
(append (list (first vl)) (remove-first rv eqop (rest vl)))
)
empty;;(error 'remove-first "Not a List")
)
)
;; Test:
(check-expect (remove-first 5 = '(12 4 6 5 7 8 9)) '(12 4 6 7 8 9))
(check-expect (remove-first 'c symbol=? (list 'a 'b 'c 'd)) (list 'a 'b 'd))
;; cargo represents items for transport
;; name: string - the name of the cargo item
;; urgency: number - the urgeny of the delivere,
;; the higher, the more urgend
;; mass: number - the mass of the item in kg
(define-struct cargo (name urgency mass))
;; some potential cargo items for the upcoming launch
(define chocolate (make-cargo "Chocolate" 40 5))
(define electronics (make-cargo "Entertainment Electronics" 45 100))
(define exp41 (make-cargo "Experiment #41" 50 300))
(define exp42 (make-cargo "Experiment #42" 50 1200))
(define plaques (make-cargo "Info Plaques" 60 6000))
(define potential-cargo
(list chocolate electronics exp41 exp42 plaques))
(define test-cargo-list1
(list chocolate electronics exp42 plaques))
(define test-cargo-list2
(list chocolate exp42 plaques))
(define test-cargo-list3
(list chocolate electronics exp41 exp42 plaques))
;; Contract: cargo-urgency-sum: (listof cargo) -> number
;; Purpose: Returns the sum of the urgency of all
;; Elements in cargolist.
;; Errors: List-Element not a Cargo-Struct
;; Not a List
;; Examples: (cargo-urgency-sum test_cargo_1)
;; (cargo-urgency-sum test_cargo_2)
(define (cargo-urgency-sum cargolist)
(local [(define (add-cargo-urgency-to-number cargo number)
(if (cargo? cargo) ;; check if it is a cargo-struct
(+ number
(cargo-urgency cargo)
)
(error 'cargo-urgency-sum "List-Element not a Cargo-Struct")
)
)]
(if (cons? cargolist) ;; check if list
(foldl add-cargo-urgency-to-number ;;sum-function
0 ;; start with 0
cargolist ;; iterate over whole carglist
)
0 ;;(error 'corgo-urgency-sum "Not a List")
)
)
)
;; Tests
(check-expect (cargo-urgency-sum test-cargo-list1) 195)
(check-expect (cargo-urgency-sum test-cargo-list2) 150)
(check-expect (cargo-urgency-sum test-cargo-list3) 245)
(check-expect (cargo-urgency-sum potential-cargo) 245)
;; Contract: cargo=? cargo cargo -> boolean
;; Purpose: Checks if the name of two cargo-structs are
;; the same. If this is the case true is returned
;; else false is returned
;; Examples: (cargo=? chocolate chocolate)
;; (cargo=? chocolate exp41)
(define (cargo=? c1 c2)
(if (and (cargo? c1)
(cargo? c2)
)
(if (string=? (cargo-name c1)
(cargo-name c2)
)
true
false
)
(error 'cargo=? "Not a cargo-struct")
)
)
;; Tests:
(check-expect (cargo=? chocolate chocolate) true)
(check-expect (cargo=? chocolate exp41) false)
;; Contract: get-cargo-list-with-greater-urgency: (listof cargo) (listof cargo) -> (listof cargo)
;; Purpose: Returns cargo-list which has more urgency.
;; Examples: (get-cargolist-with-greater-urgency (list chocolate) (list exp41))
;; (get-cargolist-with-greater-urgency (list chocolate) (list exp42))
(define (get-cargolist-with-greater-urgency loc1 loc2)
(if (>= (cargo-urgency-sum loc1)
(cargo-urgency-sum loc2)
)
loc1
loc2
)
)
;; Tests:
(check-expect (get-cargolist-with-greater-urgency (list chocolate) (list exp41)) (list exp41))
(check-expect (get-cargolist-with-greater-urgency (list chocolate) (list exp42)) (list exp42))
;; Contract: create-carg-list: (listof cargo) number -> (listof cargo)
;; Purpose: Calculates the optimal cargo-list for given max-mass.
;; Depending on Mass and Urgency of Cargo-Items
;; This function uses a recursion which test every possibility
;; of cargo-list-combinations until there is no mas-left.
;; Notice: This function jumps in its recursion between
;; the two local defined function. This might be
;; bad style, but since it makes the whole thing
;; a little more readable i though it would be
;; a good idea.
;; Example: (create-cargo-list potential-cargo 50)
;; (create-cargo-list test-cargo-list1 100)
(define (create-cargo-list cargo max-mass)
;;Calculates if new-cargo-element still fits in the atv(mass). If it does function calls create-cargo-list-recursiv, to check if even more items fit in.
(local [(define (calculate-new-possible-cargo-lists rest-cargo loaded-cargo new-cargo-element rest-mass create-cargo-list-recursiv-func)
(if (>= rest-mass
0
) ;;mass already calculated -> does new item fit?
(create-cargo-list-recursiv-func rest-cargo
rest-mass
(append (list new-cargo-element)
loaded-cargo
);;append new-item to cargo-list
) ;; check if even more items fit
loaded-cargo ;; New element does not match mass-requirements
)
)
(define (create-cargo-list-recursiv rest-cargo rest-mass loaded-cargo)
(if (cons? rest-cargo) ;;something left to load?
(foldl (lambda (new-cargo-element current-cargo-list) ;;i use fold to itterate over list and store list with greater urgency
(get-cargolist-with-greater-urgency (calculate-new-possible-cargo-lists (remove-first new-cargo-element ;;remove the element
cargo=?
rest-cargo
)
loaded-cargo
new-cargo-element
(- rest-mass ;;calculate new rest-mass
(cargo-mass new-cargo-element)
)
create-cargo-list-recursiv
)
current-cargo-list ;; which one has more urgency - new cargo-list or already calculated?
)
)
(list) ;;start with empty list
rest-cargo ;;fold over all cargo-elements
)
loaded-cargo ;;nothing to load left - return load-list
)
)]
(create-cargo-list-recursiv cargo ;;start recursion
max-mass
(list) ;;nothing loaded yet
)
)
)
;; Tests
(check-expect (create-cargo-list potential-cargo 50)
(list chocolate))
(check-expect (create-cargo-list test-cargo-list1 100)
(list electronics))
(check-expect (create-cargo-list potential-cargo 350)
(list chocolate exp41))
(check-expect (create-cargo-list test-cargo-list1 350)
(list chocolate electronics))

View File

@ -0,0 +1,27 @@
;; The first three lines of this file were inserted by DrScheme. They record metadata
;; about the language level of this file in a form that our tools can easily process.
#reader(lib "htdp-intermediate-lambda-reader.ss" "lang")((modname template-palindrome) (read-case-sensitive #t) (teachpacks ()) (htdp-settings #(#t constructor repeating-decimal #f #t none #f ())))
;;
;;
;;
;;
(define (palindrome alox) ...)
;; Tests
(check-expect (palindrome (list 'a 'b 'c 'd))
(list 'a 'b 'c 'd 'c 'b 'a))
(check-expect (palindrome empty) empty)
(check-expect (palindrome (list 1 2 3 4)) (list 1 2 3 4 3 2 1))
;;
;;
;;
;;
(define (doubled-palindrome alox) ...)
;; Tests
(check-expect (doubled-palindrome (list 'a 'b ))
'(a a b b a a))
(check-expect (doubled-palindrome empty) empty)
(check-expect (doubled-palindrome (list 1 2 3))
(list 1 1 2 2 3 3 2 2 1 1))

View File

@ -0,0 +1,67 @@
;; The first three lines of this file were inserted by DrScheme. They record metadata
;; about the language level of this file in a form that our tools can easily process.
#reader(lib "htdp-intermediate-lambda-reader.ss" "lang")((modname template-palindrome) (read-case-sensitive #t) (teachpacks ()) (htdp-settings #(#t constructor repeating-decimal #f #t none #f ())))
;; Contract: palindrome: (listof X) -> (listof X)
;; Purpose: Generates a Palindrome of a given list
;; alox. Last element of alox is not
;; duplicated.
;; Examples: (palindrome '(1 2 3 4 5 6))
;; (palindrome '(a b c d e f))
(define (palindrome alox)
(if (cons? alox) ;;check if valid
(append alox ;;input
(rest (foldl cons ;;inverted list without last element
empty
alox
)
)
)
empty ;; No cons -> return empty
)
)
;; Tests
(check-expect (palindrome (list 'a 'b 'c 'd))
(list 'a 'b 'c 'd 'c 'b 'a))
(check-expect (palindrome empty) empty)
(check-expect (palindrome (list 1 2 3 4)) (list 1 2 3 4 3 2 1))
(check-expect (palindrome '(1 2 3 4 5 6)) '(1 2 3 4 5 6 5 4 3 2 1))
(check-expect (palindrome '(a b c d e f)) '(a b c d e f e d c b a))
;; Contract: doubled-palindrome: (listof X) -> (listof X)
;; Purpose: Generates a Palindrom of given list
;; alox. All elements will be doubled.
;; So every element is in list 4 times,
;; except last element of alox, which is
;; will be present twice, only.
;; Uses: palindrome
;; Examples: (doubled-palindrome '(1 2 3 4 5 6))
;; (doubled-palindrome '(a b c d e f))
(define (doubled-palindrome alox)
(local [(define (append-double-element-to-list element list)
(append list ;;append to list
(cons element ;; 1x element
(cons element ;; 2x element
empty ;; nothing else
)
)
)
)]
(if (cons? alox)
(foldl append-double-element-to-list
(list) ;;empty list as startparam
(palindrome alox)
)
empty
)
)
)
;; Tests
(check-expect (doubled-palindrome '(1 2 3 4 5 6)) '(1 1 2 2 3 3 4 4 5 5 6 6 5 5 4 4 3 3 2 2 1 1))
(check-expect (doubled-palindrome '(a b c d e f)) '(a a b b c c d d e e f f e e d d c c b b a a))
(check-expect (doubled-palindrome (list 'a 'b ))
'(a a b b a a))
(check-expect (doubled-palindrome empty) empty)
(check-expect (doubled-palindrome (list 1 2 3))
(list 1 1 2 2 3 3 2 2 1 1))

BIN
ws2009/gdi I/java_ws.7z Normal file

Binary file not shown.

View File

@ -0,0 +1,76 @@
package de.tu_darmstadt.gdi1.plumber.tests.adapters;
/**
* This is the test adapter for the first extended stage of completion.
* Implement all method stubs in order for the tests to work.
* <br><br>
* <i>Note:</i> This test adapter inherits from the minimal test adapter.
*
* @see PlumberTestAdapterMinimal
*
* @author Jonas Marczona
* @author Christian Merfels
* @author Fabian Vogt
*/
public class PlumberTestAdapterExtended1 extends PlumberTestAdapterMinimal {
/**
* Add a highscore entry to the highscore with the given playername and
* time.
*
* @param playername the name which shall appear in the highscore
* @param time the time which was needed
*/
public void addHighscoreEntry(String playername, int reached_level, double time) {
// TODO: fill stub.
}
/**
* Return the number of highscore entries in your highscore store.
*
* @return the number of highscore entries
*/
public int getHighscoreCount() {
// TODO: fill stub.
return -1;
}
/**
* Clear the highscore store and delete all entries.
*/
public void resetHighscore() {
// TODO: fill stub.
}
/**
* Get the playername of a highscore entry at a given position.
* <strong>Note:</strong> The position counting starts at zero. The first entry should contain the <i>best</i> result.
* <p>
* See the specification in the task assignment for a definition of 'best' in the highscore.<br>
* </p>
* @param position the position of the highscore entry in the highscore
* store
* @return the playername of the highscore entry at the specified position
* or null if the position is invalid
*/
public String getPlayernameAtHighscorePosition(int position) {
// TODO: fill stub.
return null;
}
/**
* Get the needed time of a highscore entry at a given position.
* <strong>Note:</strong> The position counting starts at zero. The first entry should contain the <i>best</i> result.
* <p>
* See the specification in the task assignment for a definition of 'best' in the highscore.<br>
* </p>
* @param position the position of the highscore entry in the highscore
* store
* @return the time of the highscore entry at the specified position
* or -1 if the position is invalid
*/
public double getTimeAtHighscorePosition(int position) {
// TODO: fill stub.
return -1;
}
}

View File

@ -0,0 +1,86 @@
package de.tu_darmstadt.gdi1.plumber.tests.adapters;
import de.tu_darmstadt.gdi1.plumber.ui.GameWindow;
/**
* This is the test adapter for the second extended stage of completion.
* Implement all method stubs in order for the tests to work.
* <br><br>
* <i>Note:</i> This test adapter inherits from the first extended test adapter
*
* @see PlumberTestAdapterMinimal
* @see PlumberTestAdapterExtended1
*
* @author Jonas Marczona
* @author Christian Merfels
* @author Fabian Vogt
*/
public class PlumberTestAdapterExtended2 extends PlumberTestAdapterExtended1 {
/**
* Undo the last action. The state of the game shall be the same as before
* the last action. Action is here defined as "rotating game elements".
* Do nothing if there is no action to undo.
*/
public void undo() {
// TODO: fill stub.
}
/**
* Redo the last action. The state of the game shall be the same as before
* the last "undo".
* Do nothing if there is no action to redo.
*/
public void redo() {
// TODO: fill stub.
}
/**
* Like {@link GameWindow#keySpacePressed()}
*/
public void handleKeyPressedSpace() {
// TODO: fill stub.
}
/**
* Like {@link GameWindow#keyUndoPressed()}
*/
public void handleKeyPressedUndo() {
// TODO: fill stub.
}
/**
* Like {@link GameWindow#keyRedoPressed()}
*/
public void handleKeyPressedRedo() {
// TODO: fill stub.
}
/**
* Like {@link GameWindow#keyUpPressed()}
*/
public void handleKeyPressedUp() {
// TODO: fill stub.
}
/**
* Like {@link GameWindow#keyDownPressed()}
*/
public void handleKeyPressedDown() {
// TODO: fill stub.
}
/**
* Like {@link GameWindow#keyLeftPressed()}
*/
public void handleKeyPressedLeft() {
// TODO: fill stub.
}
/**
* Like {@link GameWindow#keyRightPressed()}
*/
public void handleKeyPressedRight() {
// TODO: fill stub.
}
}

View File

@ -0,0 +1,45 @@
package de.tu_darmstadt.gdi1.plumber.tests.adapters;
/**
* This is the test adapter for the third extended stage of completion.
* Implement all method stubs in order for the tests to work.
* <br><br>
* <i>Note:</i> This test adapter inherits from the second extended test
* adapter.
*
* @see PlumberTestAdapterMinimal
* @see PlumberTestAdapterExtended1
* @see PlumberTestAdapterExtended2
*
* @author Jonas Marczona
* @author Christian Merfels
* @author Fabian Vogt
*/
public class PlumberTestAdapterExtended3 extends PlumberTestAdapterExtended2 {
/**
* Generate a level with the given width and height.
* The generated level has to be solvable. It should be returned as
* string representation of a valid level as described in the
* documentation.
*
* <br>Counting starts at 1, that means a 3x3 board has a width and
* height of three.
*
* @param x the width of the generated level
* @param y the height of the generated level
*/
public String generateLevel(int width, int height) {
// TODO: fill stub.
return "";
}
/**
* Automatically solve the current level. There shall be a connection
* between the source and the sink in the level, but the water shall
* not start to flow automatically.
*/
public void solveLevel() {
// TODO: fill stub.
}
}

View File

@ -0,0 +1,183 @@
package de.tu_darmstadt.gdi1.plumber.tests.adapters;
/**
* This is the test adapter for the minimal stage of completion. You
* <strong>must</strong> implement the method stubs and match them to your concrete
* implementation.
* <br><strong>Important:</strong> This class should not contain any real game
* logic, you should rather only match the method stubs to your game.
* <br>Example: in {@link #isCorrectLevel()} you may return the value
* <i>myGame.isCorrectlevel()</i>, if you have a variable <i>myGame</i> and a
* level has before been loaded via {@link #loadLevelFromString(String)}.
* <br> You should <strong>not</strong> implement the actual logic of the method in <i>this</i> class.
* <br><br>
* If you have implemented the minimal stage of completion, you should be able
* to implement all method stubs. The public and private JUnit tests for the
* minimal stage of completion will be run on this test adapter. The other test
* adapters will inherit from this class, because they need the basic methods
* (like loading a level), too.
* <br><br>
* The methods of all test adapters need to function without any kind of user
* interaction.
*
* @author Jonas Marczona
* @author Christian Merfels
* @author Fabian Vogt
*/
public class PlumberTestAdapterMinimal {
public PlumberTestAdapterMinimal() {
// TODO: fill stub.
}
/**
* Construct a level from a string. You will be given a string
* representation of a level and you need to load this into your game.
* Line breaks will be delimited by \n. Your game should hold the level
* until a new one is loaded; the other methods will assume that this very
* level is the current one and that the actions (like rotating elements)
* will run on the specified level.
* @param levelstring a string representation of the level to load
* @see #isCorrectLevel()
*/
public void loadLevelFromString(String levelstring) {
// TODO: fill stub.
}
/**
* Return the string representation of the current level.
* A level loaded with the method {@link #loadLevelFromString()}
* should be the same as the result of
* {@link #getStringRepresentationOfLevel()}
* as long as no actions has been performed in the meantime. <br>
* But if there were (valid) actions in the meantime this have to be visible in the level representation.<br>
* The level format is the same
* as the one specified for loading levels.
*
* @return string representation of the current level
* or null if no valid level was loaded
*
* @see #loadLevelFromString(String)
* @see #isCorrectLevel()
*/
public String getStringRepresentationOfLevel() {
// TODO: fill stub.
return null;
}
/**
* Is the loaded level a syntactically correct level?
* See the specification in the task assignment for a definition of
* 'syntactical correct'.<br>
* You don't need to implement a solvability evaluation here.
*
* @return if the currently loaded level is syntactically correct return true,
* otherwise return false
*
* @see #loadLevelFromString(String)
* @see #getStringRepresentationOfLevel()
*/
public boolean isCorrectLevel() {
// TODO: fill stub.
return false;
}
/**
* Has the current level been won? If a level has been loaded, this should
* return false. Even if a source and a sink are connected, but the water
* hasn't flown yet, this should return false. If a level has been loaded
* and the necessary actions have been made (or the source and sink were
* connected from the beginning), and the method {@link #playGame()} was
* called and the level has been won, the return value has to be 'true'.
*
* @return if the current level has been won return true, otherwise return
* false*/
public boolean isWon() {
// TODO: fill stub.
return false;
}
/**
* Has the current level been lost? In accordance to {@link #isWon()},
* you should return 'true' if and only if a level was loaded,
* {@link #playGame()} was called and the source and sink were not
* connected in the end. Before or while a game is running, 'false' shall
* be returned. {@link #isWon()} and {@link #isLost()} may be 'false',
* but never both be 'true' at the same time.
*
* @return if the level has been lost after the water has flown return true,
* otherwise return false
*/
public boolean isLost() {
// TODO: fill stub.
return false;
}
/**
* Rotate an element at a specified position (clockwise).
* <BLOCKQUOTE>
* <b>Notice:<br></b>
* [0,0] is the upper left point on the board.<br>
* if a and b were the maximal coordinates:<br>
* [a,b] is the lower right point on the board,<br>
* [0,b] is the lower left point on the board<br>
* [a,0] is the upper right point on the board <br>
* </BLOCKQUOTE>
* @param x the x coordinate of the element to rotate
* @param y the y coordinate of the element to rotate
*/
public void rotateClockwiseAtPosition(int x, int y) {
// TODO: fill stub.
}
/**
* Is the element at a specified position filled with water?
*
* <BLOCKQUOTE>
* <b>Notice:<br></b>
* [0,0] is the upper left point on the board.<br>
* if a and b were the maximal coordinates:<br>
* [a,b] is the lower right point on the board,<br>
* [0,b] is the lower left point on the board<br>
* [a,0] is the upper right point on the board <br>
* </BLOCKQUOTE>
*
* @param x the x coordinate of the element
* @param y the y coordinate of the element
* @return
*/
public boolean isFilledWithWater(int x, int y) {
// TODO: fill stub.
return false;
}
/**
* Rotate an element at a specified position (counter-clockwise).
*
* @see #isFilledWithWater(int, int)
* @see #rotateClockwiseAtPosition(int, int)
*
* @param x the x coordinate of the element to rotate
* @param y the y coordinate of the element to rotate
*/
public void rotateCounterClockwiseAtPosition(int x, int y) {
// TODO: fill stub.
}
/**
* Like {@link GameWindow#keyNewGamePressed()}.
*/
public void handleKeyPressedNew() {
// TODO: fill stub.
}
/**
* Start and play the game: the water shall start to flow. The flow has to
* be ended at the end of this method, either because it reached the sink
* or a wall.
*/
public void playGame() {
// TODO: fill stub.
}
}

View File

@ -0,0 +1,52 @@
/*============================================================================*/
package de.tu_darmstadt.gdi1.plumber.exceptions;
/*============================================================================*/
/**
* Exception that occurs in the case of internal errors. If a method throws this
* exception, this normally indicates a bug and there is nothing that the caller
* could do.
*
* @author Steven Arzt, Oren Avni, Guido Roessling
* @version 1.0
*/
public class InternalFailureException extends Exception {
/* ======================================================================== */
private static final long serialVersionUID = 0L;
/* ======================================================================== */
/**
* Creates a new instance of the InternalFailureException class based upon
* the reason for creation (treated as an inner exception).
*
* @param cause
* The cause why the internal error has occurred. Pass the
* original exception or a more detailed internal one here.
*/
public InternalFailureException(Throwable cause) {
super(cause);
}
/* ======================================================================== */
/**
* Creates a new instance of the InternalFailureException class based upon a
* textual reason
*
* @param errorMessage
* The reason why this error has occurred
*/
public InternalFailureException(String errorMessage) {
super(errorMessage);
}
/* ======================================================================== */
}
/* ============================================================================ */

View File

@ -0,0 +1,49 @@
package de.tu_darmstadt.gdi1.plumber.exceptions;
/*============================================================================*/
/**
* Exception that is thrown whenever a method's parameter falls out of the scope
* of allowed values
*
* @author Steven Arzt, Oren Avni, Guido Roessling
* @version 1.1
*/
public class InvalidOperationException extends Exception {
/* ======================================================================== */
private static final long serialVersionUID = 1L;
/* ======================================================================== */
/**
* Creates a new instance of the InvalidOperationException class
*
* @param errorMessage
* A string description of the reason why this operation is
* invalid
*/
public InvalidOperationException (String errorMessage) {
super(errorMessage);
}
/* ======================================================================== */
/**
* Creates a new instance of the InvalidOperationException class
*
* @param cause
* The original exception that has lead to the error
*/
public InvalidOperationException (Throwable cause) {
super (cause);
}
/* ======================================================================== */
}
/* ============================================================================ */

View File

@ -0,0 +1,98 @@
package de.tu_darmstadt.gdi1.plumber.exceptions;
/*============================================================================*/
/**
* Exception that is thrown whenever a method's parameter falls out of the scope
* of allowed values
*
* @author Steven Arzt, Oren Avni, Guido Roessling
* @version 1.0
*/
public class ParameterOutOfRangeException extends Exception {
/* ======================================================================== */
private static final long serialVersionUID = 1L;
private String parameterName = "";
private Object value = null;
/* ======================================================================== */
/**
* Creates a new instance of the ParameterOutOfRangeException class
*
* @param paramName
* The name of the parameter that has failed the validity check
*/
public ParameterOutOfRangeException(String paramName) {
this(paramName, null);
}
/* ======================================================================== */
/**
* Creates a new instance of the ParameterOutOfRangeException class with the
* value that has caused the error
*
* @param paramName
* The name of the parameter that has failed the validity check
* @param aValue
* The value that has caused the error
*/
public ParameterOutOfRangeException(String paramName, Object aValue) {
super ("The " + paramName + " parameter got an invalid value");
parameterName = paramName;
value = aValue;
}
/* ======================================================================== */
/**
* Creates a new instance of the ParameterOutOfRangeException class with an
* inner exception for exception chaining
*
* @param paramName
* The name of the parameter that has failed the validity check
* @param innerException
* The inner exception that has led to this one
*/
public ParameterOutOfRangeException(String paramName,
Throwable innerException) {
super(innerException);
parameterName = paramName;
}
/* ======================================================================== */
/**
* Gets the name of the parameter that has failed the validity check
*
* @return The name of the parameter that has failed the validity check
*/
public String getParameterName() {
return parameterName;
}
/* ======================================================================== */
/**
* Gets the value that has caused the error
*
* @return The value that has caused the error
*/
public Object getValue() {
return value;
}
/* ======================================================================== */
}
/* ============================================================================ */

View File

@ -0,0 +1,76 @@
package de.tu_darmstadt.gdi1.plumber.tests.adapters;
/**
* This is the test adapter for the first extended stage of completion.
* Implement all method stubs in order for the tests to work.
* <br><br>
* <i>Note:</i> This test adapter inherits from the minimal test adapter.
*
* @see PlumberTestAdapterMinimal
*
* @author Jonas Marczona
* @author Christian Merfels
* @author Fabian Vogt
*/
public class PlumberTestAdapterExtended1 extends PlumberTestAdapterMinimal {
/**
* Add a highscore entry to the highscore with the given playername and
* time.
*
* @param playername the name which shall appear in the highscore
* @param time the time which was needed
*/
public void addHighscoreEntry(String playername, int reached_level, double time) {
// TODO: fill stub.
}
/**
* Return the number of highscore entries in your highscore store.
*
* @return the number of highscore entries
*/
public int getHighscoreCount() {
// TODO: fill stub.
return -1;
}
/**
* Clear the highscore store and delete all entries.
*/
public void resetHighscore() {
// TODO: fill stub.
}
/**
* Get the playername of a highscore entry at a given position.
* <strong>Note:</strong> The position counting starts at zero. The first entry should contain the <i>best</i> result.
* <p>
* See the specification in the task assignment for a definition of 'best' in the highscore.<br>
* </p>
* @param position the position of the highscore entry in the highscore
* store
* @return the playername of the highscore entry at the specified position
* or null if the position is invalid
*/
public String getPlayernameAtHighscorePosition(int position) {
// TODO: fill stub.
return null;
}
/**
* Get the needed time of a highscore entry at a given position.
* <strong>Note:</strong> The position counting starts at zero. The first entry should contain the <i>best</i> result.
* <p>
* See the specification in the task assignment for a definition of 'best' in the highscore.<br>
* </p>
* @param position the position of the highscore entry in the highscore
* store
* @return the time of the highscore entry at the specified position
* or -1 if the position is invalid
*/
public double getTimeAtHighscorePosition(int position) {
// TODO: fill stub.
return -1;
}
}

View File

@ -0,0 +1,86 @@
package de.tu_darmstadt.gdi1.plumber.tests.adapters;
import de.tu_darmstadt.gdi1.plumber.ui.GameWindow;
/**
* This is the test adapter for the second extended stage of completion.
* Implement all method stubs in order for the tests to work.
* <br><br>
* <i>Note:</i> This test adapter inherits from the first extended test adapter
*
* @see PlumberTestAdapterMinimal
* @see PlumberTestAdapterExtended1
*
* @author Jonas Marczona
* @author Christian Merfels
* @author Fabian Vogt
*/
public class PlumberTestAdapterExtended2 extends PlumberTestAdapterExtended1 {
/**
* Undo the last action. The state of the game shall be the same as before
* the last action. Action is here defined as "rotating game elements".
* Do nothing if there is no action to undo.
*/
public void undo() {
// TODO: fill stub.
}
/**
* Redo the last action. The state of the game shall be the same as before
* the last "undo".
* Do nothing if there is no action to redo.
*/
public void redo() {
// TODO: fill stub.
}
/**
* Like {@link GameWindow#keySpacePressed()}
*/
public void handleKeyPressedSpace() {
// TODO: fill stub.
}
/**
* Like {@link GameWindow#keyUndoPressed()}
*/
public void handleKeyPressedUndo() {
// TODO: fill stub.
}
/**
* Like {@link GameWindow#keyRedoPressed()}
*/
public void handleKeyPressedRedo() {
// TODO: fill stub.
}
/**
* Like {@link GameWindow#keyUpPressed()}
*/
public void handleKeyPressedUp() {
// TODO: fill stub.
}
/**
* Like {@link GameWindow#keyDownPressed()}
*/
public void handleKeyPressedDown() {
// TODO: fill stub.
}
/**
* Like {@link GameWindow#keyLeftPressed()}
*/
public void handleKeyPressedLeft() {
// TODO: fill stub.
}
/**
* Like {@link GameWindow#keyRightPressed()}
*/
public void handleKeyPressedRight() {
// TODO: fill stub.
}
}

View File

@ -0,0 +1,45 @@
package de.tu_darmstadt.gdi1.plumber.tests.adapters;
/**
* This is the test adapter for the third extended stage of completion.
* Implement all method stubs in order for the tests to work.
* <br><br>
* <i>Note:</i> This test adapter inherits from the second extended test
* adapter.
*
* @see PlumberTestAdapterMinimal
* @see PlumberTestAdapterExtended1
* @see PlumberTestAdapterExtended2
*
* @author Jonas Marczona
* @author Christian Merfels
* @author Fabian Vogt
*/
public class PlumberTestAdapterExtended3 extends PlumberTestAdapterExtended2 {
/**
* Generate a level with the given width and height.
* The generated level has to be solvable. It should be returned as
* string representation of a valid level as described in the
* documentation.
*
* <br>Counting starts at 1, that means a 3x3 board has a width and
* height of three.
*
* @param x the width of the generated level
* @param y the height of the generated level
*/
public String generateLevel(int width, int height) {
// TODO: fill stub.
return "";
}
/**
* Automatically solve the current level. There shall be a connection
* between the source and the sink in the level, but the water shall
* not start to flow automatically.
*/
public void solveLevel() {
// TODO: fill stub.
}
}

View File

@ -0,0 +1,183 @@
package de.tu_darmstadt.gdi1.plumber.tests.adapters;
/**
* This is the test adapter for the minimal stage of completion. You
* <strong>must</strong> implement the method stubs and match them to your concrete
* implementation.
* <br><strong>Important:</strong> This class should not contain any real game
* logic, you should rather only match the method stubs to your game.
* <br>Example: in {@link #isCorrectLevel()} you may return the value
* <i>myGame.isCorrectlevel()</i>, if you have a variable <i>myGame</i> and a
* level has before been loaded via {@link #loadLevelFromString(String)}.
* <br> You should <strong>not</strong> implement the actual logic of the method in <i>this</i> class.
* <br><br>
* If you have implemented the minimal stage of completion, you should be able
* to implement all method stubs. The public and private JUnit tests for the
* minimal stage of completion will be run on this test adapter. The other test
* adapters will inherit from this class, because they need the basic methods
* (like loading a level), too.
* <br><br>
* The methods of all test adapters need to function without any kind of user
* interaction.
*
* @author Jonas Marczona
* @author Christian Merfels
* @author Fabian Vogt
*/
public class PlumberTestAdapterMinimal {
public PlumberTestAdapterMinimal() {
// TODO: fill stub.
}
/**
* Construct a level from a string. You will be given a string
* representation of a level and you need to load this into your game.
* Line breaks will be delimited by \n. Your game should hold the level
* until a new one is loaded; the other methods will assume that this very
* level is the current one and that the actions (like rotating elements)
* will run on the specified level.
* @param levelstring a string representation of the level to load
* @see #isCorrectLevel()
*/
public void loadLevelFromString(String levelstring) {
// TODO: fill stub.
}
/**
* Return the string representation of the current level.
* A level loaded with the method {@link #loadLevelFromString()}
* should be the same as the result of
* {@link #getStringRepresentationOfLevel()}
* as long as no actions has been performed in the meantime. <br>
* But if there were (valid) actions in the meantime this have to be visible in the level representation.<br>
* The level format is the same
* as the one specified for loading levels.
*
* @return string representation of the current level
* or null if no valid level was loaded
*
* @see #loadLevelFromString(String)
* @see #isCorrectLevel()
*/
public String getStringRepresentationOfLevel() {
// TODO: fill stub.
return null;
}
/**
* Is the loaded level a syntactically correct level?
* See the specification in the task assignment for a definition of
* 'syntactical correct'.<br>
* You don't need to implement a solvability evaluation here.
*
* @return if the currently loaded level is syntactically correct return true,
* otherwise return false
*
* @see #loadLevelFromString(String)
* @see #getStringRepresentationOfLevel()
*/
public boolean isCorrectLevel() {
// TODO: fill stub.
return false;
}
/**
* Has the current level been won? If a level has been loaded, this should
* return false. Even if a source and a sink are connected, but the water
* hasn't flown yet, this should return false. If a level has been loaded
* and the necessary actions have been made (or the source and sink were
* connected from the beginning), and the method {@link #playGame()} was
* called and the level has been won, the return value has to be 'true'.
*
* @return if the current level has been won return true, otherwise return
* false*/
public boolean isWon() {
// TODO: fill stub.
return false;
}
/**
* Has the current level been lost? In accordance to {@link #isWon()},
* you should return 'true' if and only if a level was loaded,
* {@link #playGame()} was called and the source and sink were not
* connected in the end. Before or while a game is running, 'false' shall
* be returned. {@link #isWon()} and {@link #isLost()} may be 'false',
* but never both be 'true' at the same time.
*
* @return if the level has been lost after the water has flown return true,
* otherwise return false
*/
public boolean isLost() {
// TODO: fill stub.
return false;
}
/**
* Rotate an element at a specified position (clockwise).
* <BLOCKQUOTE>
* <b>Notice:<br></b>
* [0,0] is the upper left point on the board.<br>
* if a and b were the maximal coordinates:<br>
* [a,b] is the lower right point on the board,<br>
* [0,b] is the lower left point on the board<br>
* [a,0] is the upper right point on the board <br>
* </BLOCKQUOTE>
* @param x the x coordinate of the element to rotate
* @param y the y coordinate of the element to rotate
*/
public void rotateClockwiseAtPosition(int x, int y) {
// TODO: fill stub.
}
/**
* Is the element at a specified position filled with water?
*
* <BLOCKQUOTE>
* <b>Notice:<br></b>
* [0,0] is the upper left point on the board.<br>
* if a and b were the maximal coordinates:<br>
* [a,b] is the lower right point on the board,<br>
* [0,b] is the lower left point on the board<br>
* [a,0] is the upper right point on the board <br>
* </BLOCKQUOTE>
*
* @param x the x coordinate of the element
* @param y the y coordinate of the element
* @return
*/
public boolean isFilledWithWater(int x, int y) {
// TODO: fill stub.
return false;
}
/**
* Rotate an element at a specified position (counter-clockwise).
*
* @see #isFilledWithWater(int, int)
* @see #rotateClockwiseAtPosition(int, int)
*
* @param x the x coordinate of the element to rotate
* @param y the y coordinate of the element to rotate
*/
public void rotateCounterClockwiseAtPosition(int x, int y) {
// TODO: fill stub.
}
/**
* Like {@link GameWindow#keyNewGamePressed()}.
*/
public void handleKeyPressedNew() {
// TODO: fill stub.
}
/**
* Start and play the game: the water shall start to flow. The flow has to
* be ended at the end of this method, either because it reached the sink
* or a wall.
*/
public void playGame() {
// TODO: fill stub.
}
}

View File

@ -0,0 +1,19 @@
package de.tu_darmstadt.gdi1.plumber.tests.suites.students;
import junit.framework.Test;
import junit.framework.TestSuite;
public class AllTests {
public static Test suite() {
TestSuite suite = new TestSuite("Student tests for Plumber - All tests");
//$JUnit-BEGIN$
suite.addTest(PlumberTestsuiteMinimal.suite());
suite.addTest(PlumberTestsuiteExtended1.suite());
suite.addTest(PlumberTestsuiteExtended3.suite());
suite.addTest(PlumberTestsuiteExtended2.suite());
//$JUnit-END$
return suite;
}
}

View File

@ -0,0 +1,19 @@
package de.tu_darmstadt.gdi1.plumber.tests.suites.students;
import de.tu_darmstadt.gdi1.plumber.tests.testcases.students.HighscoreTest;
import junit.framework.Test;
import junit.framework.TestSuite;
public class PlumberTestsuiteExtended1 {
public static Test suite() {
TestSuite suite = new TestSuite("Student tests for Plumber - Extended 1");
//$JUnit-BEGIN$
suite.addTestSuite(HighscoreTest.class);
//$JUnit-END$
return suite;
}
}

View File

@ -0,0 +1,21 @@
package de.tu_darmstadt.gdi1.plumber.tests.suites.students;
import de.tu_darmstadt.gdi1.plumber.tests.testcases.students.KeyboardControlTest;
import de.tu_darmstadt.gdi1.plumber.tests.testcases.students.UndoRedoTest;
import junit.framework.Test;
import junit.framework.TestSuite;
public class PlumberTestsuiteExtended2 {
public static Test suite() {
TestSuite suite = new TestSuite("Student tests for Plumber - Extended 2");
//$JUnit-BEGIN$
suite.addTestSuite(KeyboardControlTest.class);
suite.addTestSuite(UndoRedoTest.class);
//$JUnit-END$
return suite;
}
}

View File

@ -0,0 +1,21 @@
package de.tu_darmstadt.gdi1.plumber.tests.suites.students;
import de.tu_darmstadt.gdi1.plumber.tests.testcases.students.GenerateLevelTest;
import de.tu_darmstadt.gdi1.plumber.tests.testcases.students.SolveLevelTest;
import junit.framework.Test;
import junit.framework.TestSuite;
public class PlumberTestsuiteExtended3 {
public static Test suite() {
TestSuite suite = new TestSuite("Student tests for Plumber - Extended 3");
//$JUnit-BEGIN$
suite.addTestSuite(GenerateLevelTest.class);
suite.addTestSuite(SolveLevelTest.class);
//$JUnit-END$
return suite;
}
}

View File

@ -0,0 +1,29 @@
package de.tu_darmstadt.gdi1.plumber.tests.suites.students;
import de.tu_darmstadt.gdi1.plumber.tests.testcases.students.HandleRestartLevelKeystrokeTest;
import de.tu_darmstadt.gdi1.plumber.tests.testcases.students.IsCorrectLevelTest;
import de.tu_darmstadt.gdi1.plumber.tests.testcases.students.IsSolvedIsLostTest;
import de.tu_darmstadt.gdi1.plumber.tests.testcases.students.LoadLevelFromStringTest;
import de.tu_darmstadt.gdi1.plumber.tests.testcases.students.PlayGameTest;
import de.tu_darmstadt.gdi1.plumber.tests.testcases.students.RotateTest;
import junit.framework.Test;
import junit.framework.TestSuite;
public class PlumberTestsuiteMinimal {
public static Test suite() {
TestSuite suite = new TestSuite("Student tests for Plumber - Minimal");
//$JUnit-BEGIN$
suite.addTestSuite(LoadLevelFromStringTest.class);
suite.addTestSuite(IsCorrectLevelTest.class);
suite.addTestSuite(IsSolvedIsLostTest.class);
suite.addTestSuite(RotateTest.class);
suite.addTestSuite(HandleRestartLevelKeystrokeTest.class);
suite.addTestSuite(PlayGameTest.class);
//$JUnit-END$
return suite;
}
}

View File

@ -0,0 +1,48 @@
/**
*
*/
package de.tu_darmstadt.gdi1.plumber.tests.testcases.students;
import junit.framework.TestCase;
import org.junit.Test;
import de.tu_darmstadt.gdi1.plumber.tests.adapters.PlumberTestAdapterExtended3;
/**
* Tests, whether the game implementation can successfully generate level.
*
* @author Christian Merfels
*
*/
public class GenerateLevelTest extends TestCase {
PlumberTestAdapterExtended3 testAdapter;
public GenerateLevelTest() {
testAdapter = new PlumberTestAdapterExtended3();
}
/**
* Test method for {@link de.tu_darmstadt.gdi1.plumber.tests.adapters.PlumberTestAdapterExtended3#generate(int, int)}.
*/
@Test
public final void testGenerateLevel() {
String newLevel;
for(int i=0; i < 25; i++) {
newLevel = testAdapter.generateLevel(randomDimension(15), randomDimension(10));
testAdapter.loadLevelFromString(newLevel);
assertTrue("Level is not a correct level", testAdapter.isCorrectLevel());
}
}
/**
* Helper function. Returns a random integer x with 2 <= x <= pMax.
* @param pMax the biggest possible integer
* @return a random integer
*/
private final int randomDimension(final int pMax) {
return (int) ((Math.random()*(pMax-1))+2);
}
}

View File

@ -0,0 +1,52 @@
package de.tu_darmstadt.gdi1.plumber.tests.testcases.students;
import junit.framework.TestCase;
import org.junit.Before;
import org.junit.Test;
import de.tu_darmstadt.gdi1.plumber.tests.adapters.PlumberTestAdapterMinimal;
/**
*
* Tests, whether the game implements the restart keystroke correct.
*
* @author Jonas Marczona
*
*/
public class HandleRestartLevelKeystrokeTest extends TestCase {
private final String level = "c6m\n364\n421";
/** Initial level, rotated at 1|1 and 2|2. */
private final String level2_2and1_1 = "c6m\n354\n422";
private PlumberTestAdapterMinimal testAdapter;
/**
* @throws java.lang.Exception
*/
@Before
public void setUp() throws Exception {
testAdapter = new PlumberTestAdapterMinimal();
testAdapter.loadLevelFromString(level);
}
/**
* Test method for {@link de.tu_darmstadt.gdi1.plumber.tests.adapters.PlumberTestAdapterMinimal#handleKeystroke(java.lang.String)}.
*/
@Test
public final void testHandleKeystroke() {
assertEquals("The initial level is not correct loaded. May the loadLevelFromString-method is wrong? Or the getStringRepresentationOfLevel-method.", level, testAdapter.getStringRepresentationOfLevel().trim());
testAdapter.handleKeyPressedNew();
assertEquals("New game should be the same as before.", level, testAdapter.getStringRepresentationOfLevel().trim());
testAdapter.rotateClockwiseAtPosition(2, 2);
testAdapter.rotateClockwiseAtPosition(1, 1);
testAdapter.rotateClockwiseAtPosition(0, 0);
assertFalse("Your level representation does not change. Please implement getStringRepresentationOfLevel correct.", level.equals(testAdapter.getStringRepresentationOfLevel().trim()));
assertEquals("Your level representation after two rotates (and one illegal click) is invalid.", level2_2and1_1, testAdapter.getStringRepresentationOfLevel().trim());
testAdapter.handleKeyPressedNew();
assertEquals("New game should be the same initial level.", level, testAdapter.getStringRepresentationOfLevel().trim());
}
}

View File

@ -0,0 +1,141 @@
package de.tu_darmstadt.gdi1.plumber.tests.testcases.students;
import junit.framework.TestCase;
import org.junit.Before;
import org.junit.Test;
import de.tu_darmstadt.gdi1.plumber.tests.adapters.PlumberTestAdapterExtended1;
/**
*
* Tests, whether the highscore is implemented correctly.
*
* @author Jonas Marczona
*
*/
public class HighscoreTest extends TestCase {
private PlumberTestAdapterExtended1 testAdapter;
private final String player1 = "player1";
private final double time1 = (double)50*1000;
private final String player2 = "player2";
private final double time2 = (double)49*1000;
private final String player3 = "player3";
private final double time3 = (double)52*1000;
/**
/**
* @throws java.lang.Exception
*/
@Before
public void setUp() throws Exception {
testAdapter = new PlumberTestAdapterExtended1();
testAdapter.resetHighscore();
assertEquals("HighscoreCount is wrong, should be 0 after reset. ", 0, testAdapter.getHighscoreCount());
}
/**
* Test method for {@link de.tu_darmstadt.gdi1.plumber.tests.adapters.PlumberTestAdapterExtended1#getPlayernameAtHighscorePosition(int)}.
*/
@Test
public final void testGetPlayernameAtHighscorePosition() {
testAdapter.addHighscoreEntry(player1, 1, time1);
assertEquals("Received playername is wrong.", player1, testAdapter.getPlayernameAtHighscorePosition(0));
assertNull("Playername at an invalid index should be null.", testAdapter.getPlayernameAtHighscorePosition(1));
assertNull("Playername at an invalid index should be null.", testAdapter.getPlayernameAtHighscorePosition(-1));
assertNull("Playername at an invalid index should be null.", testAdapter.getPlayernameAtHighscorePosition(Integer.MAX_VALUE));
}
/**
* Test method for {@link de.tu_darmstadt.gdi1.plumber.tests.adapters.PlumberTestAdapterExtended1#getTimeAtHighscorePosition(int)}.
*/
@Test
public final void testGetTimeAtHighscorePosition() {
testAdapter.addHighscoreEntry(player1, 1, time1);
assertEquals("Received time is wrong.", time1, testAdapter.getTimeAtHighscorePosition(0));
assertEquals("Time at an invalid index should be -1.", testAdapter.getTimeAtHighscorePosition(1), (double)-1);
assertEquals("Time at an invalid index should be -1.", testAdapter.getTimeAtHighscorePosition(-1), (double)-1);
assertEquals("Time at an invalid index should be -1.", testAdapter.getTimeAtHighscorePosition(Integer.MAX_VALUE), (double)-1);
}
/**
* Test method for {@link de.tu_darmstadt.gdi1.plumber.tests.adapters.PlumberTestAdapterExtended1#getHighscoreCount()}.
*/
@Test
public final void testGetHighscoreCount() {
testAdapter.addHighscoreEntry(player1, 1, time1);
assertEquals("HighscoreCount is wrong. ", 1, testAdapter.getHighscoreCount());
testAdapter.addHighscoreEntry(player2, 1, time2);
testAdapter.addHighscoreEntry(player3, 1, time3);
assertEquals("HighscoreCount is wrong. ", 3, testAdapter.getHighscoreCount());
}
/**
* Test method for {@link de.tu_darmstadt.gdi1.plumber.tests.adapters.PlumberTestAdapterExtended1#resetHighscore()}.
*/
@Test
public final void testResetHighscore() {
testAdapter.addHighscoreEntry(player1, 1, time1);
assertEquals("HighscoreCount is wrong. ", 1, testAdapter.getHighscoreCount());
assertEquals("Received playername is wrong.", player1, testAdapter.getPlayernameAtHighscorePosition(0));
assertEquals("Received time is wrong.", time1, testAdapter.getTimeAtHighscorePosition(0));
testAdapter.resetHighscore();
assertEquals("HighscoreCount is wrong. ", 0, testAdapter.getHighscoreCount());
assertEquals("Time at an invalid index should be -1.", testAdapter.getTimeAtHighscorePosition(0), (double)-1);
assertNull("Playername at an invalid index should be null.", testAdapter.getPlayernameAtHighscorePosition(0));
assertEquals("Time at an invalid index should be -1.", testAdapter.getTimeAtHighscorePosition(1), (double)-1);
assertNull("Playername at an invalid index should be null.", testAdapter.getPlayernameAtHighscorePosition(1));
testAdapter.addHighscoreEntry(player2, 1, time2);
assertEquals("HighscoreCount is wrong. ", 1, testAdapter.getHighscoreCount());
assertEquals("Received playername is wrong.", player2, testAdapter.getPlayernameAtHighscorePosition(0));
assertEquals("Received time is wrong.", time2, testAdapter.getTimeAtHighscorePosition(0));
testAdapter.resetHighscore();
assertEquals("Time at an invalid index should be -1.", testAdapter.getTimeAtHighscorePosition(2), (double)-1);
assertNull("Playername at an invalid index should be null.", testAdapter.getPlayernameAtHighscorePosition(2));
}
/**
* Test method for {@link de.tu_darmstadt.gdi1.plumber.tests.adapters.PlumberTestAdapterExtended1#addHighscoreEntry(java.lang.String, double)}.
*/
@Test
public final void testAddHighscoreEntry() {
testAdapter.addHighscoreEntry(player1, 1, time1);
assertEquals("HighscoreCount is wrong. ", 1, testAdapter.getHighscoreCount());
assertEquals("Received playername is wrong.", player1, testAdapter.getPlayernameAtHighscorePosition(0));
assertEquals("Received time is wrong.", time1, testAdapter.getTimeAtHighscorePosition(0));
assertEquals("Time at an invalid index should be -1.", testAdapter.getTimeAtHighscorePosition(1), (double)-1);
assertNull("Playername at an invalid index should be null.", testAdapter.getPlayernameAtHighscorePosition(1));
testAdapter.addHighscoreEntry(player2, 1, time2);
assertEquals("HighscoreCount is wrong. ", 2, testAdapter.getHighscoreCount());
assertEquals("Highscore sorts wrong, at position 0 should be the best.", player2, testAdapter.getPlayernameAtHighscorePosition(0));
assertEquals("Highscore sorts wrong, at position 0 should be the best.", time2, testAdapter.getTimeAtHighscorePosition(0));
assertEquals("Highscore sorts wrong.", player1, testAdapter.getPlayernameAtHighscorePosition(1));
assertEquals("Highscore sorts wrong.", time1, testAdapter.getTimeAtHighscorePosition(1));
assertEquals("Time at an invalid index should be -1.", testAdapter.getTimeAtHighscorePosition(2), (double)-1);
assertNull("Playername at an invalid index should be null.", testAdapter.getPlayernameAtHighscorePosition(2));
testAdapter.addHighscoreEntry(player3, 1, time3);
assertEquals("HighscoreCount is wrong. ", 3, testAdapter.getHighscoreCount());
assertEquals("Highscore sorts wrong, at position 0 should be the best.", player2, testAdapter.getPlayernameAtHighscorePosition(0));
assertEquals("Highscore sorts wrong, at position 0 should be the best.", time2, testAdapter.getTimeAtHighscorePosition(0));
assertEquals("Highscore sorts wrong.", player1, testAdapter.getPlayernameAtHighscorePosition(1));
assertEquals("Highscore sorts wrong.", time1, testAdapter.getTimeAtHighscorePosition(1));
assertEquals("Highscore sorts wrong.", player3, testAdapter.getPlayernameAtHighscorePosition(2));
assertEquals("Highscore sorts wrong.", time3, testAdapter.getTimeAtHighscorePosition(2));
assertEquals("Time at an invalid index should be -1.", testAdapter.getTimeAtHighscorePosition(3), (double)-1);
assertNull("Playername at an invalid index should be null.", testAdapter.getPlayernameAtHighscorePosition(3));
}
}

View File

@ -0,0 +1,85 @@
package de.tu_darmstadt.gdi1.plumber.tests.testcases.students;
import java.util.HashMap;
import junit.framework.TestCase;
import org.junit.After;
import org.junit.AfterClass;
import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.Test;
import de.tu_darmstadt.gdi1.plumber.tests.adapters.PlumberTestAdapterMinimal;
/**
*
* Tests, whether the game implements the check
* for syntactical correctness the right way.
*
* @author Fabian Vogt
*
*/
public class IsCorrectLevelTest extends TestCase {
private PlumberTestAdapterMinimal testAdapter = new PlumberTestAdapterMinimal();
private HashMap<String, Boolean> levels = new HashMap<String, Boolean>();
public IsCorrectLevelTest() {
super();
levels.put("a6m\n364\n464", true);
levels.put("16222\n14246\n24a65\n2623k", true);
levels.put("b26234\n12n426\n362146\n366232", true);
levels.put("36624\n5l212\n41634\n3143d", true);
levels.put("66m\n364\n464", false);
levels.put("c6m\n364\n4k4", false);
levels.put("c63\n364\n454", false);
}
/**
* @throws java.lang.Exception
*/
@BeforeClass
public static void setUpBeforeClass() throws Exception {
}
/**
* @throws java.lang.Exception
*/
@AfterClass
public static void tearDownAfterClass() throws Exception {
}
/**
* @throws java.lang.Exception
*/
@Before
public void setUp() throws Exception {
}
/**
* @throws java.lang.Exception
*/
@After
public void tearDown() throws Exception {
}
/**
* Test method for {@link de.tu_darmstadt.gdi1.plumber.tests.adapters.PlumberTestAdapterMinimal#isCorrectLevel()}.
*/
@Test
public final void testIsCorrectLevel() {
int i = 0;
for (String level : levels.keySet()) {
i++;
this.testAdapter.loadLevelFromString(level);
assertEquals("Your implementation identified a correct level as incorrect "
+ "or an incorrect level as correct.\n" + level + "\n",
levels.get(level),
Boolean.valueOf(this.testAdapter.isCorrectLevel()));
}
}
}

View File

@ -0,0 +1,69 @@
package de.tu_darmstadt.gdi1.plumber.tests.testcases.students;
import java.util.LinkedList;
import junit.framework.TestCase;
import org.junit.Before;
import org.junit.Test;
import de.tu_darmstadt.gdi1.plumber.tests.adapters.PlumberTestAdapterMinimal;
/**
* Tests, whether solved/lost level are correctly recognized.
*
* @author Christian Merfels
*
*/
public class IsSolvedIsLostTest extends TestCase {
PlumberTestAdapterMinimal testAdapter;
LinkedList<String> solvedLevels, lostLevels;
/**
* @throws java.lang.Exception
*/
@Before
public void setUp() {
testAdapter = new PlumberTestAdapterMinimal();
solvedLevels = new LinkedList<String>();
solvedLevels.add("c6m\n462\n464");
solvedLevels.add("16231\n14325\n24a65\n2623k");
solvedLevels.add("566314\n313k41\n366662\n5b6142\n466264");
lostLevels = new LinkedList<String>();
lostLevels.add("c6m\n364\n464");
lostLevels.add("16222\n14246\n24a65\n2623k");
lostLevels.add("c26234\n12m426\n362146\n366232");
}
/**
* Test method for {@link de.tu_darmstadt.gdi1.plumber.tests.adapters.PlumberTestAdapterMinimal#isWon()}.
*/
@Test
public final void testIsSolved() {
for(String level : solvedLevels) {
System.out.println(level.toString());
testAdapter.loadLevelFromString(level);
testAdapter.playGame();
System.out.println("lost: " + testAdapter.isLost() + "\tsolved: " + testAdapter.isWon());
assertTrue("Game has not been recognized as solved.", testAdapter.isWon());
}
}
/**
* Test method for {@link de.tu_darmstadt.gdi1.plumber.tests.adapters.PlumberTestAdapterMinimal#isLost()}.
*/
@Test
public final void testIsLost() {
for(String level : lostLevels) {
testAdapter.loadLevelFromString(level);
testAdapter.playGame();
assertTrue("Game has not been recognized as lost.", testAdapter.isLost());
}
}
}

View File

@ -0,0 +1,64 @@
package de.tu_darmstadt.gdi1.plumber.tests.testcases.students;
import junit.framework.TestCase;
import org.junit.Before;
import org.junit.Test;
import de.tu_darmstadt.gdi1.plumber.tests.adapters.PlumberTestAdapterExtended2;
/**
* Tests, whether the keyboard control works as specified.
*
* @author Jonas Marczona
* @author Fabian Vogt
*
*/
public class KeyboardControlTest extends TestCase {
PlumberTestAdapterExtended2 adapter;
String level = "c6m\n364\n464";
String level_0_1 = "c5m\n364\n464";
String level_1_2 = "c6m\n364\n454";
@Before
public void setUp() {
adapter = new PlumberTestAdapterExtended2();
}
@Test
public final void testHandleArrowSpaceKeystrokes() {
adapter.loadLevelFromString(level);
adapter.handleKeyPressedSpace();
assertEquals("You cannot rotate a source!", level, adapter.getStringRepresentationOfLevel().trim());
adapter.handleKeyPressedRight();
adapter.handleKeyPressedSpace();
assertEquals("Either you did not change the focus correctly or you did not handle the rotation correctly!", level_0_1, adapter.getStringRepresentationOfLevel().trim());
adapter.handleKeyPressedSpace();
assertEquals("Either you did not change the focus correctly or you did not handle the rotation correctly!", level, adapter.getStringRepresentationOfLevel().trim());
adapter.handleKeyPressedRight();
adapter.handleKeyPressedDown();
adapter.handleKeyPressedDown();
adapter.handleKeyPressedLeft();
adapter.handleKeyPressedSpace();
assertEquals("Either you did not change the focus correctly or you did not handle the rotation correctly!", level_1_2, adapter.getStringRepresentationOfLevel().trim());
adapter.handleKeyPressedSpace();
adapter.handleKeyPressedSpace();
adapter.handleKeyPressedSpace();
adapter.handleKeyPressedLeft();
adapter.handleKeyPressedUp();
adapter.handleKeyPressedUp();
adapter.handleKeyPressedRight();
assertEquals("Either you did not change the focus correctly or you did not handle the rotation correctly!", level, adapter.getStringRepresentationOfLevel().trim());
adapter.handleKeyPressedSpace();
assertEquals("Either you did not change the focus correctly or you did not handle the rotation correctly!", level_0_1, adapter.getStringRepresentationOfLevel().trim());
}
}

View File

@ -0,0 +1,70 @@
package de.tu_darmstadt.gdi1.plumber.tests.testcases.students;
import java.util.LinkedList;
import java.util.List;
import junit.framework.TestCase;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import de.tu_darmstadt.gdi1.plumber.tests.adapters.PlumberTestAdapterMinimal;
/**
* Tests, whether levels can be loaded from strings.
*
* @author Fabian Vogt
*
*/
public class LoadLevelFromStringTest extends TestCase {
private PlumberTestAdapterMinimal testAdapter = new PlumberTestAdapterMinimal();
private List<String> levels = new LinkedList<String>();
public LoadLevelFromStringTest() {
super();
levels.add("c6m\n364\n464");
levels.add("16222\n14246\n24a65\n2623k");
levels.add("b26234\n12n426\n362146\n366232");
levels.add("36624\n5l212\n41634\n3143d");
}
/**
* @throws java.lang.Exception
*/
@Before
public void setUp() throws Exception {
}
/**
* @throws java.lang.Exception
*/
@After
public void tearDown() throws Exception {
}
/**
* Test method for {@link de.tu_darmstadt.gdi1.plumber.tests.adapters.PlumberTestAdapterMinimal#loadLevelFromString(java.lang.String)}.
*/
@Test
public final void testLoadLevelFromString() {
for (int i = 0; i < this.levels.size(); i++) {
String level = this.levels.get(i);
testAdapter.loadLevelFromString(level);
String representation = testAdapter.getStringRepresentationOfLevel();
representation = representation.replace("\r", "");
representation = representation.replaceAll("[\n][\n]*", "\n");
representation = representation.replaceAll("^#[^\n]*\n", "");
representation = representation.replaceAll("\n\\Z", "");
assertEquals("The string representation of level " + i + " does not match the expected representation.", level, representation);
}
}
}

View File

@ -0,0 +1,132 @@
package de.tu_darmstadt.gdi1.plumber.tests.testcases.students;
import junit.framework.TestCase;
import org.junit.Before;
import org.junit.Test;
import de.tu_darmstadt.gdi1.plumber.tests.adapters.PlumberTestAdapterMinimal;
/**
* Tests, whether the game can be played correctly.
*
* @author Jonas Marczona
* @author Fabian Vogt
*
*/
public class PlayGameTest extends TestCase {
private final String levelCorrect = "16231\n14325\n24a65\n2623k";
private final String levelNotCorrect = "16221\n14325\n24a65\n2623k";
private PlumberTestAdapterMinimal testAdapter;
/**
* @throws java.lang.Exception
*/
@Before
public void setUp() throws Exception {
testAdapter = new PlumberTestAdapterMinimal();
testAdapter.loadLevelFromString(levelCorrect);
assertEquals("The initial level is not correct loaded. May the loadLevelFromString-method is wrong? Or the getStringRepresentationOfLevel-method.", levelCorrect, testAdapter.getStringRepresentationOfLevel().trim());
}
/**
* Test method for {@link de.tu_darmstadt.gdi1.plumber.tests.adapters.PlumberTestAdapterMinimal#playGame()}.
*/
@Test
public final void testPlayGameWon() {
testAdapter.playGame();
assertTrue(testAdapter.isWon());
}
/**
* Test method for {@link de.tu_darmstadt.gdi1.plumber.tests.adapters.PlumberTestAdapterMinimal#playGame()}.
*/
@Test
public final void testPlayGameLost() {
testAdapter.loadLevelFromString(levelNotCorrect);
testAdapter.playGame();
assertTrue(testAdapter.isLost());
}
/**
* Test method for {@link de.tu_darmstadt.gdi1.plumber.tests.adapters.PlumberTestAdapterMinimal#playGame()}.
*/
@Test
public final void testPlayGameWonWater() {
testAdapter.playGame();
assertTrue(testAdapter.isWon());
assertFalse(testAdapter.isFilledWithWater(0, 0));
assertFalse(testAdapter.isFilledWithWater(1, 0));
assertFalse(testAdapter.isFilledWithWater(2, 0));
assertTrue(testAdapter.isFilledWithWater(3, 0));
assertTrue(testAdapter.isFilledWithWater(4, 0));
assertFalse(testAdapter.isFilledWithWater(0, 1));
assertFalse(testAdapter.isFilledWithWater(1, 1));
assertTrue(testAdapter.isFilledWithWater(2, 1));
assertTrue(testAdapter.isFilledWithWater(3, 1));
assertTrue(testAdapter.isFilledWithWater(4, 1));
assertFalse(testAdapter.isFilledWithWater(0, 2));
assertFalse(testAdapter.isFilledWithWater(1, 2));
assertTrue(testAdapter.isFilledWithWater(2, 2));
assertFalse(testAdapter.isFilledWithWater(3, 2));
assertTrue(testAdapter.isFilledWithWater(4, 2));
assertFalse(testAdapter.isFilledWithWater(0, 3));
assertFalse(testAdapter.isFilledWithWater(1, 3));
assertFalse(testAdapter.isFilledWithWater(2, 3));
assertFalse(testAdapter.isFilledWithWater(3, 3));
assertTrue(testAdapter.isFilledWithWater(4, 1));
}
/**
* Test method for {@link de.tu_darmstadt.gdi1.plumber.tests.adapters.PlumberTestAdapterMinimal#playGame()}.
*/
@Test
public final void testPlayGameLostWater() {
testAdapter.loadLevelFromString(levelNotCorrect);
testAdapter.playGame();
assertTrue(testAdapter.isLost());
//Row 1
assertFalse(testAdapter.isFilledWithWater(0, 0));
assertFalse(testAdapter.isFilledWithWater(1, 0));
assertFalse(testAdapter.isFilledWithWater(2, 0));
/*
* at this position the water flowed out of the pipe
* it is not defined if this field is filled with water or not.
* assert??(testAdapter.isFilledWithWater(3, 0));
*/
assertFalse(testAdapter.isFilledWithWater(4, 0));
//Row 2
assertFalse(testAdapter.isFilledWithWater(0, 1));
assertFalse(testAdapter.isFilledWithWater(1, 1));
assertTrue(testAdapter.isFilledWithWater(2, 1));
assertTrue(testAdapter.isFilledWithWater(3, 1));
assertFalse(testAdapter.isFilledWithWater(4, 1));
//Row 3
assertFalse(testAdapter.isFilledWithWater(0, 2));
assertFalse(testAdapter.isFilledWithWater(1, 2));
assertTrue(testAdapter.isFilledWithWater(2, 2));
assertFalse(testAdapter.isFilledWithWater(3, 2));
assertFalse(testAdapter.isFilledWithWater(4, 2));
//Row 4
assertFalse(testAdapter.isFilledWithWater(0, 3));
assertFalse(testAdapter.isFilledWithWater(1, 3));
assertFalse(testAdapter.isFilledWithWater(2, 3));
assertFalse(testAdapter.isFilledWithWater(3, 3));
assertFalse(testAdapter.isFilledWithWater(4, 1));
}
}

View File

@ -0,0 +1,108 @@
package de.tu_darmstadt.gdi1.plumber.tests.testcases.students;
import java.util.HashMap;
import junit.framework.TestCase;
import org.junit.Before;
import org.junit.Test;
import de.tu_darmstadt.gdi1.plumber.tests.adapters.PlumberTestAdapterMinimal;
/**
* Tests a basic feature of the game: the ability of rotating certain game
* elements clockwise and counterclockwise.
*
* @author Christian Merfels
*
*/
public class RotateTest extends TestCase {
PlumberTestAdapterMinimal testAdapter;
String level = "c6m\n364\n421";
HashMap<Integer, String> rotatedLevelClockwise, rotatedLevelCounterClockwise;
/**
* @throws java.lang.Exception
*/
@Before
public void setUp() throws Exception {
testAdapter = new PlumberTestAdapterMinimal();
rotatedLevelClockwise = new HashMap<Integer, String>();
rotatedLevelCounterClockwise = new HashMap<Integer, String>();
rotatedLevelClockwise.put(0, "c6m\n364\n421");
rotatedLevelClockwise.put(1, "c5m\n364\n421");
rotatedLevelClockwise.put(2, "c5m\n364\n421");
rotatedLevelClockwise.put(3, "c5m\n164\n421");
rotatedLevelClockwise.put(4, "c5m\n154\n421");
rotatedLevelClockwise.put(5, "c5m\n153\n421");
rotatedLevelClockwise.put(6, "c5m\n153\n321");
rotatedLevelClockwise.put(7, "c5m\n153\n341");
rotatedLevelClockwise.put(8, "c5m\n153\n342");
rotatedLevelCounterClockwise.put(0, "c6m\n364\n421");
rotatedLevelCounterClockwise.put(1, "c5m\n364\n421");
rotatedLevelCounterClockwise.put(2, "c5m\n364\n421");
rotatedLevelCounterClockwise.put(3, "c5m\n464\n421");
rotatedLevelCounterClockwise.put(4, "c5m\n454\n421");
rotatedLevelCounterClockwise.put(5, "c5m\n452\n421");
rotatedLevelCounterClockwise.put(6, "c5m\n452\n221");
rotatedLevelCounterClockwise.put(7, "c5m\n452\n211");
rotatedLevelCounterClockwise.put(8, "c5m\n452\n213");
}
/**
* Test method for {@link de.tu_darmstadt.gdi1.plumber.tests.adapters.PlumberTestAdapterMinimal#rotateClockwiseAtPosition(int, int)}.
*/
@Test
public final void testRotateClockwiseAtPosition() {
testAdapter.loadLevelFromString(level);
String levelIs, levelShouldBe;
for(int i = 0; i < 3; i++) {
for(int n=0; n < 3; n++) {
testAdapter.rotateClockwiseAtPosition(n, i);
levelIs = normalizeLevel(testAdapter.getStringRepresentationOfLevel());
levelShouldBe = rotatedLevelClockwise.get(i*3+n);
assertEquals("Wrong element in rotation detected.", levelShouldBe, levelIs);
}
}
}
/**
* Test method for {@link de.tu_darmstadt.gdi1.plumber.tests.adapters.PlumberTestAdapterMinimal#rotateCounterClockwiseAtPosition(int, int)}.
*/
@Test
public final void testRotateCounterClockwiseAtPosition() {
testAdapter.loadLevelFromString(level);
String levelIs, levelShouldBe;
for(int i = 0; i < 3; i++) {
for(int n=0; n < 3; n++) {
testAdapter.rotateCounterClockwiseAtPosition(n, i);
levelIs = normalizeLevel(testAdapter.getStringRepresentationOfLevel());
levelShouldBe = rotatedLevelCounterClockwise.get(i*3+n);
assertEquals("Wrong element in rotation detected.", levelShouldBe, levelIs);
}
}
}
/**
* Trim the level and remove line breaks.
* @param level the level to work on
* @return the same level but in somewhat weak normalized form
*/
private final String normalizeLevel(final String level) {
String normalized = level;
normalized.trim();
if(normalized.endsWith("\r\n")) {
normalized = normalized.substring(0, normalized.length() - 3);
}else if(normalized.endsWith("\n") || normalized.endsWith("\r")) {
normalized = normalized.substring(0, normalized.length() - 1);
}
return normalized;
}
}

View File

@ -0,0 +1,60 @@
/**
*
*/
package de.tu_darmstadt.gdi1.plumber.tests.testcases.students;
import java.util.LinkedList;
import junit.framework.TestCase;
import org.junit.Before;
import org.junit.Test;
import de.tu_darmstadt.gdi1.plumber.tests.adapters.PlumberTestAdapterExtended3;
/**
* Tests, whether the solver works correctly.
*
* @author Christian Merfels
*/
public class SolveLevelTest extends TestCase {
PlumberTestAdapterExtended3 testAdapter;
LinkedList<String> level;
String level0 = "c6m\n364\n464";
String level1 = "16222\n14246\n24a65\n2623k";
String level2 = "c26234\n12m426\n362146\n366232";
String unsolvable = "d6l\n364\n464";
/**
* @throws java.lang.Exception
*/
@Before
public void setUp() throws Exception {
testAdapter = new PlumberTestAdapterExtended3();
level = new LinkedList<String>();
level.add(level0);
level.add(level1);
level.add(level2);
}
/**
* Test method for {@link de.tu_darmstadt.gdi1.plumber.tests.adapters.PlumberTestAdapterExtended3#solveLevel()}.
*/
@Test
public final void testSolveLevel() {
for(int i = 0; i < level.size(); i++) {
testAdapter.loadLevelFromString(level.get(i));
testAdapter.solveLevel();
testAdapter.playGame();
assertTrue("Level is not solved", testAdapter.isWon());
}
testAdapter.loadLevelFromString(unsolvable);
testAdapter.solveLevel();
testAdapter.playGame();
assertFalse("Unsolvable level was marked as 'solved'", testAdapter.isWon());
}
}

View File

@ -0,0 +1,115 @@
package de.tu_darmstadt.gdi1.plumber.tests.testcases.students;
import junit.framework.TestCase;
import org.junit.Before;
import org.junit.Test;
import de.tu_darmstadt.gdi1.plumber.tests.adapters.PlumberTestAdapterExtended2;
/**
* Tests, whether the game can handle undo/redo.
*
* @author Jonas Marczona
*/
public class UndoRedoTest extends TestCase {
/** The adapter under test. */
private PlumberTestAdapterExtended2 testAdapter;
/** Initial level. */
private final String level = "c6m\n364\n421";
/** Initial level, rotated at 1|1. */
private final String level1_1 = "c6m\n354\n421";
/** Initial level, rotated at 2|2. */
private final String level2_2 = "c6m\n364\n422";
/** Initial level, rotated at 1|1 and 2|2. */
private final String level2_2and1_1 = "c6m\n354\n422";
/**
* @throws java.lang.Exception
*/
@Before
public void setUp() throws Exception {
testAdapter = new PlumberTestAdapterExtended2();
testAdapter.loadLevelFromString(level);
assertEquals("The initial level is not correct loaded. May the loadLevelFromString-method is wrong? Or the getStringRepresentationOfLevel-method.", level, testAdapter.getStringRepresentationOfLevel().trim());
}
/**
* Test method for {@link de.tu_darmstadt.gdi1.plumber.tests.adapters.PlumberTestAdapterExtended2#undo()}.
*/
@Test
public final void testUndo() {
testAdapter.rotateClockwiseAtPosition(1, 1);
testAdapter.undo();
assertEquals("Position 1|1 was rotated - but also undone. Level should be in initial state.", level, testAdapter.getStringRepresentationOfLevel().trim());
testAdapter.rotateClockwiseAtPosition(1, 1);
testAdapter.rotateClockwiseAtPosition(1, 1);
testAdapter.rotateClockwiseAtPosition(2, 2);
testAdapter.undo();
testAdapter.undo();
assertEquals("Only position 1|1 should be rotated, all other changes are undone.", level1_1, testAdapter.getStringRepresentationOfLevel().trim());
testAdapter.rotateClockwiseAtPosition(0, 0); //illegal clicks should not matter.
testAdapter.undo(); //undoes the click to 1|1 in line 49
assertEquals("No position should be rotated anymore.", level, testAdapter.getStringRepresentationOfLevel().trim());
testAdapter.undo();
assertEquals("More undoes than actions should be the initial level.", level, testAdapter.getStringRepresentationOfLevel().trim());
}
/**
* Test method for {@link de.tu_darmstadt.gdi1.plumber.tests.adapters.PlumberTestAdapterExtended2#redo()}.
*/
@Test
public final void testRedo() {
testAdapter.rotateClockwiseAtPosition(1, 1);
testAdapter.undo();
testAdapter.redo();
assertEquals("Only position 1|1 should be rotated one time.", level1_1, testAdapter.getStringRepresentationOfLevel().trim());
testAdapter.undo();
// here we should have the initial level again.
testAdapter.rotateClockwiseAtPosition(1, 1);
testAdapter.rotateClockwiseAtPosition(1, 1);
testAdapter.rotateClockwiseAtPosition(2, 2);
testAdapter.undo();
testAdapter.undo();
testAdapter.redo();
testAdapter.redo();
assertEquals("Only position 2|2 should be rotated one time.", level2_2, testAdapter.getStringRepresentationOfLevel().trim());
testAdapter.rotateClockwiseAtPosition(0, 0); // illegal "clicks" should be no moves for undo
testAdapter.undo(); // at this point the click to 2|2 should be undone.
assertEquals("No position should be rotated anymore.", level, testAdapter.getStringRepresentationOfLevel().trim());
testAdapter.redo();
testAdapter.rotateClockwiseAtPosition(1, 1);
assertEquals("Position 1|1 and 2|2 should be rotated.", level2_2and1_1, testAdapter.getStringRepresentationOfLevel().trim());
testAdapter.undo();
assertEquals("Only position 2|2 should be rotated one time.", level2_2, testAdapter.getStringRepresentationOfLevel().trim());
}
/**
* Test method for {@link de.tu_darmstadt.gdi1.plumber.tests.adapters.PlumberTestAdapterExtended2#redo()}.
*/
@Test
public final void testRedo_two() {
testAdapter.redo();
assertEquals("Redo without any actions before should be take no effect.", level, testAdapter.getStringRepresentationOfLevel().trim());
testAdapter.rotateCounterClockwiseAtPosition(1, 1);
testAdapter.redo(); //no effect
testAdapter.undo();
testAdapter.redo();
testAdapter.redo(); //no effect
assertEquals("More redoes than undoes should end in a level where only position 1|1 is rotated.", level1_1, testAdapter.getStringRepresentationOfLevel().trim());
}
}

View File

@ -0,0 +1,550 @@
/*============================================================================*/
package de.tu_darmstadt.gdi1.plumber.ui;
/*============================================================================*/
import java.awt.Dimension;
import java.awt.GridLayout;
import java.awt.Image;
import java.awt.Insets;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.io.File;
import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.HashMap;
import java.util.Vector;
import javax.swing.Icon;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
import de.tu_darmstadt.gdi1.plumber.exceptions.InternalFailureException;
import de.tu_darmstadt.gdi1.plumber.exceptions.InvalidOperationException;
import de.tu_darmstadt.gdi1.plumber.exceptions.ParameterOutOfRangeException;
/*============================================================================*/
/**
* Class representing a basic Plumber game field display that you can extend for
* your own solution by deriving from it.
*
* @author Steven Arzt, Oren Avni
* @version 1.2
*/
public abstract class GamePanel extends JPanel implements MouseListener {
/* ======================================================================== */
private static final long serialVersionUID = -1037100806444236904L;
/* ======================================================================== */
// the list of entities
private Vector<JButton> entities = null;
// the loaded images, accessed by name
private HashMap<String, ImageIcon> images = null;
// the parent window
private GameWindow parentWindow = null;
// The current layout width and height based on the level
private int layoutWidth = 0, layoutHeight = 0;
// switch for enabling or disabling automatic sizing
private boolean autosize = false;
/* ======================================================================== */
/**
* Creates a new instance of the GamePanel class
*
* @param theParentWindow
* The parent window on which this panel is placed
*/
public GamePanel(GameWindow theParentWindow) {
super();
// Set the reference
parentWindow = theParentWindow;
// Create the internal objects
entities = new Vector<JButton>();
images = new HashMap<String, ImageIcon>();
}
/* ======================================================================== */
/**
* Enables or disables automatic sizing
* @param Autosize True if automatic sizing shall be enabled, otherwise
* false
*/
public void setAutosize
(boolean Autosize)
{
autosize = Autosize;
resizePanel ();
}
/* ======================================================================== */
/**
* Resizes the game panel to match the current contents
*/
private void resizePanel ()
{
int oldWidth = getWidth (), oldHeight = getHeight ();
int width = 0, height = 0;
for (int i = 0; i < entities.size (); i++)
{
JButton btn = entities.get (i);
int icoWidth = btn.getIcon ().getIconWidth () + 2;
int icoHeight = btn.getIcon ().getIconHeight () + 2;
width = Math.max (width, icoWidth);
height = Math.max (height, icoHeight);
// +2px border size (one pixel per side)
if (autosize)
btn.setPreferredSize (new Dimension (icoWidth, icoHeight));
else
btn.setSize (icoWidth, icoHeight);
}
width = layoutWidth * width;
height = layoutHeight * height;
setSize (width, height);
if (oldWidth != width || oldHeight != height)
{
if (autosize)
parentWindow.pack ();
panelResized ();
}
}
/* ======================================================================== */
/**
* Draws the game field once again and updates its graphical representation
* @throws InternalFailureException
* Thrown if an uncorrectable internal error occurs
*/
public void redraw() throws InternalFailureException {
// The following code contains a few tricks concerning Swing and
// threading. I do not require anyone to understand it - mainly
// workarounds for the mess Sun has done...
if (Thread.currentThread ().getName ().contains ("AWT-EventQueue"))
{
clearFrame();
setGamePanelContents();
resizePanel ();
}
else
try
{
SwingUtilities.invokeAndWait (new Runnable ()
{
//@Override
public void run ()
{
clearFrame();
setGamePanelContents();
resizePanel ();
}
});
}
catch (Exception ex)
{
throw new InternalFailureException (ex);
}
}
/* ======================================================================== */
/**
* Method for setting the game panel's contents. Override this method to
* place your game entities like walls, crates etc. on the game field.
*/
protected abstract void setGamePanelContents();
/* ======================================================================== */
/**
* Clears the game frame by removing all entity buttons and recreating the
* corresponding internal data structures. This method can also be used for
* initialization purposes.
*/
private void clearFrame() {
for (int i = 0; i < entities.size(); i++) {
JButton btn = entities.get(i);
btn.setVisible(false);
remove(btn);
synchronized (entities)
{
entities.remove(btn);
}
clearFrame();
return;
}
}
/* ======================================================================== */
/**
* Notifies the game panel that a new level has been loaded
*
* @param width
* The width of the level just loaded
* @param height
* The height if the level just loaded
* @throws ParameterOutOfRangeException
* Thrown if one of the parameters falls out of the range of
* acceptable values
* @throws InternalFailureException
* Thrown if an uncorrectable internal error occurs
*/
void notifyLevelLoaded(int width, int height)
throws ParameterOutOfRangeException, InternalFailureException {
// Check the parameters
if (width <= 0)
throw new ParameterOutOfRangeException("Game Panel width negative");
if (height <= 0)
throw new ParameterOutOfRangeException("Game Panel height negative");
// Initialize the layout
layoutWidth = width;
layoutHeight = height;
setLayout(new GridLayout(height, width));
redraw();
}
/* ======================================================================== */
/**
* Returns whether there are already entities on this game panel
*
* @return True if there are already entities on this game panel, otherwise
* false
*/
protected boolean hasEntities() {
return entities.size() > 0;
}
/* ======================================================================== */
/**
* Checks whether a specific image has already been registered with the game
* panel
*
* @param identifier
* The unique image identifier
* @throws ParameterOutOfRangeException
* Thrown if one of the parameters falls out of the range of
* acceptable values
*/
protected boolean isImageRegistered(String identifier)
throws ParameterOutOfRangeException {
// Check the parameter
if (identifier == null || identifier.equals(""))
throw new ParameterOutOfRangeException("Identifier invalid");
return images.containsKey(identifier);
}
/* ======================================================================== */
/**
* Registers a new image in this game panel. Please note that the identifier
* must be unique, so the operation will fail if an image with the specified
* identifier has already been registered.
*
* @param identifier
* The new image's unique identifier
* @param fileName
* The file name from which to load the image file
* @throws ParameterOutOfRangeException
* Thrown if one of the parameters falls out of the range of
* acceptable values
* @throws InvalidOperationException
* Thrown if this operation is not permitted due to the object's
* current state
* @throws InternalFailureException
* Thrown if an uncorrectable internal error occurs
*/
protected void registerImage(String identifier, String fileName)
throws ParameterOutOfRangeException,
InvalidOperationException,
InternalFailureException {
try
{
// Check for file existence
File f = new File (fileName);
if (!f.exists ())
throw new InvalidOperationException
("File " + fileName + " not found");
StringBuilder builder = new StringBuilder ();
builder.append ("file:");
builder.append (File.separator);
builder.append (f.getCanonicalPath ());
registerImage(identifier, new URL (builder.toString ()));
}
catch (MalformedURLException ex)
{
throw new ParameterOutOfRangeException ("fileName", ex);
}
catch (IOException ex)
{
throw new InternalFailureException (ex);
}
}
/* ======================================================================== */
/**
* Registers a new image in this game panel. Please note that the identifier
* must be unique, so the operation will fail if an image with the specified
* identifier has already been registered.
*
* @param identifier
* The new image's unique identifier
* @param fileName
* The URL from which to load the image file
* @throws ParameterOutOfRangeException
* Thrown if one of the parameters falls out of the range of
* acceptable values
* @throws InvalidOperationException
* Thrown if this operation is not permitted due to the object's
* current state
*/
protected void registerImage(String identifier, URL fileName)
throws ParameterOutOfRangeException, InvalidOperationException {
// Check the parameters
if (identifier == null || identifier.equals(""))
throw new ParameterOutOfRangeException("Identifier invalid");
if (fileName == null || fileName.equals(""))
throw new ParameterOutOfRangeException("FileName invalid");
if (isImageRegistered(identifier))
throw new InvalidOperationException(
"An image with this identifier "
+ "has already been registered");
images.put(identifier, new ImageIcon(fileName));
}
/* ======================================================================== */
/**
* Unregisters a previously registered image from this game panel. If the
* specified identifier does not exist, an exception is thrown.
* @param identifier
* The image's unique identifier
* @throws ParameterOutOfRangeException
* Thrown if one of the parameters falls out of the range of
* acceptable values
* @throws InvalidOperationException
* Thrown if this operation is not permitted due to the object's
* current state
*/
protected void unregisterImage(String identifier)
throws ParameterOutOfRangeException, InvalidOperationException {
// Check the parameters
if (identifier == null || identifier.equals(""))
throw new ParameterOutOfRangeException("Identifier invalid");
if (!isImageRegistered(identifier))
throw new InvalidOperationException(
"An image with this identifier "
+ "has not been registered");
images.remove (identifier);
}
/* ======================================================================== */
/**
* Places a graphical entity on the game panel.
*
* @param imageIdentifier
* The identifier of a previously registered image that will be
* used for rendering the entity
* @throws ParameterOutOfRangeException
* Thrown if one of the parameters falls out of the range of
* acceptable values
* @return The placed entity (JButton).
*/
protected JButton placeEntity(String imageIdentifier)
throws ParameterOutOfRangeException {
// Check the parameters
if (imageIdentifier == null || imageIdentifier.equals(""))
throw new ParameterOutOfRangeException("ImageIdentifier invalid");
// Get the image icon
ImageIcon img = images.get(imageIdentifier);
if (img == null)
throw new RuntimeException("An image with the identifier "
+ imageIdentifier + " could not be found");
return(
placeEntity(
img
)
);
}
/**
* Places a graphical entity on the game panel.
*
* @param image
* An image which will be used for the entity.
* @return The placed entity (JButton).
*/
protected JButton placeEntity(Image image){
return(
placeEntity(
new ImageIcon(
image
)
)
);
}
/**
* Places a graphical entity on the game panel.
*
* @param icon
* An icon which will be used for the entity.
* @return The placed entity (JButton).
*/
protected JButton placeEntity(Icon icon){
// Create the visual entity
JButton btn = new JButton();
btn.setMargin(
new Insets(
0 , 0 , 0 , 0
)
);
synchronized(entities){
entities.add(btn);
}
btn.addKeyListener(parentWindow);
btn.addMouseListener(this);
btn.setIcon(icon);
// add it
add(btn);
btn.requestFocus();
return( btn );
}
/* ======================================================================== */
/**
* This method is called whenever an entity on the game field is clicked
*
* @param positionX
* The x coordinate of the entity that was clicked
* @param positionY
* The y coordinate of the entity that was clicked
*/
protected abstract void entityClicked(int positionX, int positionY);
/* ======================================================================== */
/**
* This method is called whenever the game panel is resized
*/
protected abstract void panelResized ();
/* ======================================================================== */
// @Override
/**
* This method handles the "mouse clicked" mouse event by converting the
* event into a call to <em>entityClicked(int, int)</em>.
*
* @param evt the mouse event caused by clicking "somewhere" on the screen
* @see #entityClicked(int, int)
*/
public void mouseClicked(MouseEvent evt) {
if (!hasEntities())
return;
// retrieve first button
JButton refBtn = entities.get(0);
// iterate buttons until right one was found
for (int i = 0; i < entities.size(); i++) {
JButton btn = entities.get(i);
if (evt.getSource() == btn) {
// determine x and y position
int posX = evt.getXOnScreen();
posX = posX - (int) this.getLocationOnScreen().getX();
int posY = evt.getYOnScreen();
posY = posY - (int) this.getLocationOnScreen().getY();
// pass message along
entityClicked(posX / refBtn.getWidth(), posY
/ refBtn.getHeight());
// done!
evt.consume();
break;
}
}
}
/* ======================================================================== */
public void mousePressed(MouseEvent arg0) {
// nothing to be done here
}
/* ======================================================================== */
public void mouseReleased(MouseEvent arg0) {
// nothing to be done here
}
/* ======================================================================== */
public void mouseEntered(MouseEvent arg0) {
// nothing to be done here
}
/* ======================================================================== */
public void mouseExited(MouseEvent arg0) {
// nothing to be done here
}
/* ======================================================================== */
/**
* Gets the parent window for this game field
*
* @return This game field's parent window
*/
public GameWindow getParentWindow() {
return parentWindow;
}
/* ======================================================================== */
}
/* ============================================================================ */

View File

@ -0,0 +1,273 @@
/*============================================================================*/
package de.tu_darmstadt.gdi1.plumber.ui;
/*============================================================================*/
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import javax.swing.JFrame;
import de.tu_darmstadt.gdi1.plumber.exceptions.InternalFailureException;
import de.tu_darmstadt.gdi1.plumber.exceptions.ParameterOutOfRangeException;
/*============================================================================*/
/**
* Base class for the main game window. Derive from this class for implementing
* your custom solution.
*
* @author Steven Arzt, Oren Avni, Jonas Marczona
* @version 1.1
*/
public abstract class GameWindow extends JFrame implements KeyListener {
/* ======================================================================== */
private static final long serialVersionUID = -2646785578035515024L;
/* ======================================================================== */
protected GamePanel gamePanel = null;
/* ======================================================================== */
/**
* Creates a new instance of the GameWindow class
*
* @param windowTitle The title of the game window
* @throws InternalFailureException
* Thrown if an uncorrectable internal error occurs
*/
public GameWindow(String windowTitle) {
super(windowTitle);
// We may need to correct the window title
if (windowTitle == null || windowTitle.equals(""))
setTitle("Plumber Student Implementation");
// Create the game panel
gamePanel = createGamePanel ();
if (gamePanel == null)
throw new RuntimeException("The game panel may not be null");
// Configure the frame
addKeyListener( this );
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setResizable(false);
}
/* ======================================================================== */
/**
* Override this method to create your own custom game panel.
*
* @return An instance of the GamePanel you want to use
*/
protected abstract GamePanel createGamePanel ();
/* ======================================================================== */
/**
* Method that is invoked whenever the left arrow key is pressed. Override
* this method to implement your custom solution
*/
protected void keyLeftPressed() {
}
/* ======================================================================== */
/**
* Method that is invoked whenever the right arrow key is pressed. Override
* this method to implement your custom solution
*/
protected void keyRightPressed() {
}
/* ======================================================================== */
/**
* Method that is invoked whenever the up arrow key is pressed. Override
* this method to implement your custom solution
*/
protected void keyUpPressed() {
}
/* ======================================================================== */
/**
* Method that is invoked whenever the down arrow key is pressed. Override
* this method to implement your custom solution
*/
protected void keyDownPressed() {
}
/* ======================================================================== */
/**
* Method that is invoked whenever the "q" key is pressed. Override this
* method to implement your custom solution
*/
protected void keyQuitPressed(){
}
/* ======================================================================== */
/**
* Method that is invoked whenever the "n" key is pressed. Override this
* method to implement your custom solution
*/
protected void keyNewGamePressed() {
}
/* ======================================================================== */
/**
* Method that is invoked whenever the backspace key is pressed. Override
* this method to implement your custom solution
*/
protected void keyUndoPressed() {
}
/* ======================================================================== */
/**
* Method that is invoked whenever the return key is pressed. Override this
* method to implement your custom solution
*/
protected void keyRedoPressed(){
}
/* ======================================================================== */
/**
* Method that is invoked whenever the space key is pressed. Override this
* method to implement your custom solution
*/
protected void keySpacePressed() {
}
/* ======================================================================== */
/**
* Method that is invoked whenever a key that is not explicitly handled has
* been pressed. Override this method to implement your custom solution.
*/
protected void keyOtherPressed (KeyEvent key){
}
/* ======================================================================== */
/**
* This method consumes a KeyEvent caused by the user pressing a key. If the
* key is "known", the appropriate method key*Pressed will be called.
*
* @see #keyUpPressed()
* @see #keyLeftPressed()
* @see #keyRightPressed()
* @see #keyDownPressed()
* @see #keyNewGamePressed()
* @see #keyRedoPressed()
* @see #keyUndoPressed()
*/
public void keyPressed(KeyEvent key) {
// retrieve the key code and call the appropriate method, if any
switch (key.getKeyCode()) {
case KeyEvent.VK_LEFT:
keyLeftPressed();
break;
case KeyEvent.VK_RIGHT:
keyRightPressed();
break;
case KeyEvent.VK_UP:
keyUpPressed();
break;
case KeyEvent.VK_DOWN:
keyDownPressed();
break;
case KeyEvent.VK_Q:
keyQuitPressed();
break;
case KeyEvent.VK_N:
keyNewGamePressed();
break;
case KeyEvent.VK_BACK_SPACE:
keyUndoPressed();
break;
case KeyEvent.VK_ENTER:
keyRedoPressed();
break;
case KeyEvent.VK_SPACE:
keySpacePressed();
break;
default:
keyOtherPressed(key);
break;
}
}
/* ======================================================================== */
public void keyReleased(KeyEvent key) {
// nothing to be done here
}
/* ======================================================================== */
public void keyTyped(KeyEvent key) {
// nothing to be done here
}
/* ======================================================================== */
/**
* Returns the game panel used by this game window
*
* @return The game panel used by this game window
*/
public GamePanel getGamePanel() {
return gamePanel;
}
/* ======================================================================== */
/**
* Notifies the game window that a new level has been loaded
*
* @param width
* The width of the level just loaded
* @param height
* The height of the level just loaded
* @throws ParameterOutOfRangeException
* Thrown if one of the parameters falls out of the range of
* acceptable values
* @throws InternalFailureException
* Thrown if an uncorrectable internal error occurs
*/
public void notifyLevelLoaded(int width, int height)
throws ParameterOutOfRangeException, InternalFailureException {
// Check the parameters
if (width <= 0)
throw new ParameterOutOfRangeException("Game Window width invalid");
if (height <= 0)
throw new ParameterOutOfRangeException("Game Window height invalid");
// Notify the panel
gamePanel.notifyLevelLoaded(width, height);
}
/* ======================================================================== */
}
/* ============================================================================ */

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

Some files were not shown because too many files have changed in this diff Show More