mirror of
https://github.com/tu-darmstadt-informatik/Grundlagen-der-Informatik-1.git
synced 2025-12-13 01:35:51 +00:00
gdi1 2009 WiSe
This commit is contained in:
parent
9b8e2b1b78
commit
4a92ed35cc
BIN
exam/gdi1-exam-2008-A-WiSe.pdf
Normal file
BIN
exam/gdi1-exam-2008-A-WiSe.pdf
Normal file
Binary file not shown.
BIN
exam/gdi1-exam-2008-B-WiSe-solution.pdf
Normal file
BIN
exam/gdi1-exam-2008-B-WiSe-solution.pdf
Normal file
Binary file not shown.
BIN
exam/gdi1-exam-2008-B-WiSe.pdf
Normal file
BIN
exam/gdi1-exam-2008-B-WiSe.pdf
Normal file
Binary file not shown.
BIN
exam/gdi1-exam-2009-SoSe-solution.pdf
Normal file
BIN
exam/gdi1-exam-2009-SoSe-solution.pdf
Normal file
Binary file not shown.
BIN
exam/gdi1-exam-2009-SoSe.pdf
Normal file
BIN
exam/gdi1-exam-2009-SoSe.pdf
Normal file
Binary file not shown.
BIN
exam/gdi1-exam-2009-Z-SoSe.pdf
Normal file
BIN
exam/gdi1-exam-2009-Z-SoSe.pdf
Normal file
Binary file not shown.
BIN
exercise/gdi1-exercise-01-2009-WiSe-solution.pdf
Normal file
BIN
exercise/gdi1-exercise-01-2009-WiSe-solution.pdf
Normal file
Binary file not shown.
113
exercise/gdi1-exercise-01-2009-WiSe-solution/circle.ss
Normal file
113
exercise/gdi1-exercise-01-2009-WiSe-solution/circle.ss
Normal 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)
|
||||
11
exercise/gdi1-exercise-01-2009-WiSe-solution/point.ss
Normal file
11
exercise/gdi1-exercise-01-2009-WiSe-solution/point.ss
Normal 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)
|
||||
105
exercise/gdi1-exercise-02-2009-WiSe-solution/students.ss
Normal file
105
exercise/gdi1-exercise-02-2009-WiSe-solution/students.ss
Normal 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 ")
|
||||
76
exercise/gdi1-exercise-02-2009-WiSe-solution/u02.ss
Normal file
76
exercise/gdi1-exercise-02-2009-WiSe-solution/u02.ss
Normal 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))))
|
||||
BIN
exercise/gdi1-exercise-02-2009-WiSe.pdf
Normal file
BIN
exercise/gdi1-exercise-02-2009-WiSe.pdf
Normal file
Binary file not shown.
314
exercise/gdi1-exercise-03-2009-WiSe-solution/trees.ss
Normal file
314
exercise/gdi1-exercise-03-2009-WiSe-solution/trees.ss
Normal 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
|
||||
;;
|
||||
57
exercise/gdi1-exercise-03-2009-WiSe-solution/u03.ss
Normal file
57
exercise/gdi1-exercise-03-2009-WiSe-solution/u03.ss
Normal 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
|
||||
BIN
exercise/gdi1-exercise-03-2009-WiSe.pdf
Normal file
BIN
exercise/gdi1-exercise-03-2009-WiSe.pdf
Normal file
Binary file not shown.
235
exercise/gdi1-exercise-04-2009-WiSe-solution/h04.ss
Normal file
235
exercise/gdi1-exercise-04-2009-WiSe-solution/h04.ss
Normal 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 ;-)
|
||||
126
exercise/gdi1-exercise-04-2009-WiSe-solution/h04.txt
Normal file
126
exercise/gdi1-exercise-04-2009-WiSe-solution/h04.txt
Normal 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))
|
||||
BIN
exercise/gdi1-exercise-04-2009-WiSe-solution/highway.png
Normal file
BIN
exercise/gdi1-exercise-04-2009-WiSe-solution/highway.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 32 KiB |
2938
exercise/gdi1-exercise-04-2009-WiSe-solution/templates04.ss
Normal file
2938
exercise/gdi1-exercise-04-2009-WiSe-solution/templates04.ss
Normal file
File diff suppressed because it is too large
Load Diff
148
exercise/gdi1-exercise-04-2009-WiSe-solution/u04.ss
Normal file
148
exercise/gdi1-exercise-04-2009-WiSe-solution/u04.ss
Normal 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)
|
||||
BIN
exercise/gdi1-exercise-04-2009-WiSe.pdf
Normal file
BIN
exercise/gdi1-exercise-04-2009-WiSe.pdf
Normal file
Binary file not shown.
576
exercise/gdi1-exercise-05-2009-WiSe-solution/h05.ss
Normal file
576
exercise/gdi1-exercise-05-2009-WiSe-solution/h05.ss
Normal 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)))
|
||||
375
exercise/gdi1-exercise-05-2009-WiSe-solution/u05.ss
Normal file
375
exercise/gdi1-exercise-05-2009-WiSe-solution/u05.ss
Normal 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)
|
||||
BIN
exercise/gdi1-exercise-05-2009-WiSe.pdf
Normal file
BIN
exercise/gdi1-exercise-05-2009-WiSe.pdf
Normal file
Binary file not shown.
358
exercise/gdi1-exercise-06-2009-WiSe-solution/h06.ss
Normal file
358
exercise/gdi1-exercise-06-2009-WiSe-solution/h06.ss
Normal 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))
|
||||
187
exercise/gdi1-exercise-06-2009-WiSe-solution/template-atv06.ss
Normal file
187
exercise/gdi1-exercise-06-2009-WiSe-solution/template-atv06.ss
Normal 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))
|
||||
@ -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
exercise/gdi1-exercise-06-2009-WiSe.pdf
Normal file
BIN
exercise/gdi1-exercise-06-2009-WiSe.pdf
Normal file
Binary file not shown.
7
exercise/gdi1-exercise-08-2009-WiSe-solution/.classpath
Normal file
7
exercise/gdi1-exercise-08-2009-WiSe-solution/.classpath
Normal file
@ -0,0 +1,7 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<classpath>
|
||||
<classpathentry kind="src" path="src"/>
|
||||
<classpathentry kind="con" path="org.eclipse.jdt.junit.JUNIT_CONTAINER/4"/>
|
||||
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/>
|
||||
<classpathentry kind="output" path="bin"/>
|
||||
</classpath>
|
||||
17
exercise/gdi1-exercise-08-2009-WiSe-solution/.project
Normal file
17
exercise/gdi1-exercise-08-2009-WiSe-solution/.project
Normal file
@ -0,0 +1,17 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<projectDescription>
|
||||
<name>GDI Calendar</name>
|
||||
<comment></comment>
|
||||
<projects>
|
||||
</projects>
|
||||
<buildSpec>
|
||||
<buildCommand>
|
||||
<name>org.eclipse.jdt.core.javabuilder</name>
|
||||
<arguments>
|
||||
</arguments>
|
||||
</buildCommand>
|
||||
</buildSpec>
|
||||
<natures>
|
||||
<nature>org.eclipse.jdt.core.javanature</nature>
|
||||
</natures>
|
||||
</projectDescription>
|
||||
@ -0,0 +1,12 @@
|
||||
#Fri Dec 18 08:14:28 CET 2009
|
||||
eclipse.preferences.version=1
|
||||
org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
|
||||
org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.6
|
||||
org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve
|
||||
org.eclipse.jdt.core.compiler.compliance=1.6
|
||||
org.eclipse.jdt.core.compiler.debug.lineNumber=generate
|
||||
org.eclipse.jdt.core.compiler.debug.localVariable=generate
|
||||
org.eclipse.jdt.core.compiler.debug.sourceFile=generate
|
||||
org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
|
||||
org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
|
||||
org.eclipse.jdt.core.compiler.source=1.6
|
||||
@ -0,0 +1,106 @@
|
||||
package GdICalendarTemplate;
|
||||
|
||||
/**
|
||||
* Import TimeClasses
|
||||
*/
|
||||
import java.util.GregorianCalendar;
|
||||
|
||||
/**
|
||||
* Instances of the Calendar class contain CalendarEntries.
|
||||
*
|
||||
* @author Ulf Gebhardt
|
||||
* @version 1.0
|
||||
*/
|
||||
public class Calendar {
|
||||
|
||||
/**
|
||||
* Array of CalendarEntry. Startsize is 0.
|
||||
*/
|
||||
private CalendarEntry[] calendarEntries = new CalendarEntry[0];
|
||||
|
||||
/**
|
||||
* Constructor -> Not used, Std Constructor
|
||||
*/
|
||||
public Calendar()
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a CalendarEntry to the array in Calendar.
|
||||
* @param calEntry
|
||||
*/
|
||||
public void addCalendarEntry(CalendarEntry calEntry)
|
||||
{
|
||||
CalendarEntry[] ce = calendarEntries;
|
||||
calendarEntries = new CalendarEntry[ce.length+1];
|
||||
System.arraycopy(ce, 0, calendarEntries, 0, ce.length);
|
||||
calendarEntries[calendarEntries.length-1] = calEntry;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns String containing Entry.tostring values
|
||||
* separated by linebreak.
|
||||
* Does not include Private Elements from foreign
|
||||
* People.
|
||||
*
|
||||
* @param user
|
||||
* @return String
|
||||
*/
|
||||
public String listEntries(User user)
|
||||
{
|
||||
StringBuffer s = new StringBuffer();
|
||||
for (int i = 0; i < calendarEntries.length; i++)
|
||||
{
|
||||
if(!calendarEntries[i].isPrivate() || calendarEntries[i].getOwner() == user)
|
||||
{
|
||||
s.append(calendarEntries[i].toString());
|
||||
s.append("\n");
|
||||
}
|
||||
}
|
||||
|
||||
return s.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* Start the Programm,
|
||||
*
|
||||
* Add some Users, Entries, Print content.
|
||||
* @param args
|
||||
*/
|
||||
public static void main(String[] args) {
|
||||
// please leave this method alone for now...
|
||||
// create a new calendar
|
||||
Calendar cal = new Calendar();
|
||||
|
||||
// create some users
|
||||
User paul = new User("Paul", "Anderson");
|
||||
User mary = new User("Mary", "Bobkins");
|
||||
User bob = new User("Adam", "Johanson");
|
||||
|
||||
// create some entries
|
||||
CalendarEntry plants = new CalendarEntry(
|
||||
new GregorianCalendar(2010, 3, 12, 14, 30),
|
||||
"Water the plants", paul);
|
||||
plants.setPrivate(true);
|
||||
cal.addCalendarEntry(plants);
|
||||
|
||||
CalendarEntry cinema = new CalendarEntry(
|
||||
new GregorianCalendar(2010, 3, 12, 18, 30),
|
||||
"Meet Mary for cinema", paul);
|
||||
cal.addCalendarEntry(cinema);
|
||||
|
||||
CalendarEntry call = new CalendarEntry(
|
||||
new GregorianCalendar(2010, 3, 13, 9, 30),
|
||||
"Call Susi for an appointment with Ron", mary);
|
||||
cal.addCalendarEntry(call);
|
||||
|
||||
CalendarEntry lunch = new CalendarEntry(
|
||||
new GregorianCalendar(2010, 3, 13, 12, 00),
|
||||
"Lunch with Paul", bob);
|
||||
lunch.setPrivate(true);
|
||||
cal.addCalendarEntry(lunch);
|
||||
|
||||
// print out the list of entries
|
||||
System.out.println(cal.listEntries(bob));
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,151 @@
|
||||
package GdICalendarTemplate;
|
||||
|
||||
/**
|
||||
* Import Time/Date/Converter Functionality
|
||||
*/
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.GregorianCalendar;
|
||||
import java.util.Locale;
|
||||
|
||||
/**
|
||||
* All entries in the Calendar are instances of the class CalendarEntry.
|
||||
*
|
||||
* @author Ulf Gebhardt
|
||||
* @version 1.0
|
||||
*/
|
||||
public class CalendarEntry {
|
||||
|
||||
/**
|
||||
* DateTime Stamp
|
||||
*/
|
||||
private GregorianCalendar time;
|
||||
/**
|
||||
* Description what to do/remind
|
||||
*/
|
||||
private String description;
|
||||
/**
|
||||
* Owner of Entry
|
||||
*/
|
||||
private User owner;
|
||||
/**
|
||||
* Determines if Entry is visible for all.
|
||||
*/
|
||||
private boolean priv;
|
||||
|
||||
/**
|
||||
* Constructor of CalendarEntry
|
||||
*
|
||||
* @param time Timestamp (GregorianCalendar)
|
||||
* @param description Description(String)
|
||||
* @param owner (User)
|
||||
*/
|
||||
public CalendarEntry(GregorianCalendar time, String description, User owner)
|
||||
{
|
||||
setTime(time);
|
||||
setDescription(description);
|
||||
setOwner(owner);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the string-representation of
|
||||
* a CalendarEntry of the following form:
|
||||
*
|
||||
* DAYSTRING, DAY MONTH YEAR - HOUR:MIN:SEC by USERFIRSTNAME USERLASTNAME | DESCRIPTION
|
||||
*
|
||||
* @return String
|
||||
*/
|
||||
@Override public String toString()
|
||||
{
|
||||
StringBuffer temp = new StringBuffer();
|
||||
|
||||
SimpleDateFormat sdf = new SimpleDateFormat("E, dd MMMM yyyy - HH:mm:ss", Locale.GERMAN);
|
||||
|
||||
temp.append(sdf.format(time.getTime()));
|
||||
temp.append(" by ");
|
||||
temp.append(owner.toString());
|
||||
temp.append(" | ");
|
||||
temp.append(description);
|
||||
|
||||
return temp.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* Set Timestamp
|
||||
*
|
||||
* @param newtime GregorianCalendar
|
||||
*/
|
||||
public void setTime(GregorianCalendar newtime)
|
||||
{
|
||||
time = newtime;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set Timestamp
|
||||
*
|
||||
* @return GregorianCalendar
|
||||
*/
|
||||
public GregorianCalendar getTime()
|
||||
{
|
||||
return time;
|
||||
}
|
||||
|
||||
/**
|
||||
* set new Description
|
||||
*
|
||||
* @param newdesc String
|
||||
*/
|
||||
public void setDescription(String newdesc)
|
||||
{
|
||||
description = newdesc;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns Description
|
||||
*
|
||||
* @return String
|
||||
*/
|
||||
public String getDescription()
|
||||
{
|
||||
return description;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set new Owner
|
||||
*
|
||||
* @param newowner User
|
||||
*/
|
||||
public void setOwner(User newowner)
|
||||
{
|
||||
owner = newowner;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns current Owner
|
||||
*
|
||||
* @return User
|
||||
*/
|
||||
public User getOwner()
|
||||
{
|
||||
return owner;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set Private-Flag
|
||||
*
|
||||
* @param newpriv boolean
|
||||
*/
|
||||
public void setPrivate(boolean newpriv)
|
||||
{
|
||||
priv = newpriv;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if Entry is Private.
|
||||
*
|
||||
* @return boolean
|
||||
*/
|
||||
public boolean isPrivate()
|
||||
{
|
||||
return priv;
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,78 @@
|
||||
package GdICalendarTemplate;
|
||||
|
||||
/**
|
||||
* User Class Definition
|
||||
* used by: CalendarEntries
|
||||
*
|
||||
* @author Ulf Gebhardt
|
||||
* @version 1.0
|
||||
*/
|
||||
public class User {
|
||||
|
||||
/**
|
||||
* FirstName of the User
|
||||
*/
|
||||
private String givenName;
|
||||
|
||||
/**
|
||||
* FamilyName of the User
|
||||
*/
|
||||
private String familyName;
|
||||
|
||||
/**
|
||||
* The constructor for User objects
|
||||
*
|
||||
* @param givenName FirstName
|
||||
* @param familyName LastName
|
||||
*/
|
||||
public User(String givenName, String familyName)
|
||||
{
|
||||
setGivenName(givenName);
|
||||
setFamilyName(familyName);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets givenName.
|
||||
* @param newname
|
||||
*/
|
||||
public void setGivenName(String newname)
|
||||
{
|
||||
givenName = newname;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns givenName
|
||||
* @return String
|
||||
*/
|
||||
public String getGivenName()
|
||||
{
|
||||
return givenName;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns familyName
|
||||
* @return String
|
||||
*/
|
||||
public String getFamilyName()
|
||||
{
|
||||
return familyName;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets familyName
|
||||
* @param newname
|
||||
*/
|
||||
public void setFamilyName(String newname)
|
||||
{
|
||||
familyName = newname;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns String representing a User
|
||||
* @return String UserName + Lastname
|
||||
*/
|
||||
@Override public String toString()
|
||||
{
|
||||
return givenName + " " + familyName;
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,54 @@
|
||||
|
||||
|
||||
|
||||
|
||||
import GdICalendarTemplate.Calendar;
|
||||
import GdICalendarTemplate.Calendar;
|
||||
import GdICalendarTemplate.CalendarEntry;
|
||||
import GdICalendarTemplate.CalendarEntry;
|
||||
import GdICalendarTemplate.User;
|
||||
import GdICalendarTemplate.User;
|
||||
import java.util.GregorianCalendar;
|
||||
|
||||
import junit.framework.Assert;
|
||||
import org.junit.Test;
|
||||
|
||||
|
||||
/**
|
||||
* Test the various calendar functionality.
|
||||
*/
|
||||
public class CalendarTest{
|
||||
@Test
|
||||
public void testUserCreation() {
|
||||
User sasha = new User("Sasha", "Dole");
|
||||
Assert.assertEquals(sasha.getGivenName(), "Sasha");
|
||||
Assert.assertEquals(sasha.getFamilyName(), "Dole");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCalendarEntryCreation() {
|
||||
CalendarEntry meeting = new CalendarEntry(new GregorianCalendar(2010,
|
||||
3, 12, 18, 30), "Meeting with Alex and Joseph", new User(
|
||||
"Sasha", "Dole"));
|
||||
Assert.assertFalse(meeting.isPrivate());
|
||||
Assert.assertEquals(meeting.getDescription(), "Meeting with Alex and Joseph");
|
||||
Assert.assertEquals(meeting.getOwner().getGivenName(), "Sasha");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCalendarCreation() {
|
||||
Calendar cal = new Calendar();
|
||||
User bob = new User("Bob", "Smith");
|
||||
CalendarEntry meeting = new CalendarEntry(new GregorianCalendar(2010,
|
||||
3, 12, 18, 30), "Meeting with Alex and Joseph", new User(
|
||||
"Sasha", "Dole"));
|
||||
cal.addCalendarEntry(meeting);
|
||||
Assert.assertTrue(cal.listEntries(bob).length() > 0);
|
||||
Assert.assertTrue(cal.listEntries(bob).contains("Sasha"));
|
||||
Assert.assertTrue(cal.listEntries(bob).contains("Meeting with Alex and Joseph"));
|
||||
Assert.assertTrue(cal.listEntries(bob).contains("2010"));
|
||||
Assert.assertTrue(cal.listEntries(bob).contains("April"));
|
||||
Assert.assertTrue(cal.listEntries(bob).contains("Mo"));
|
||||
}
|
||||
|
||||
}
|
||||
BIN
exercise/gdi1-exercise-08-2009-WiSe.pdf
Normal file
BIN
exercise/gdi1-exercise-08-2009-WiSe.pdf
Normal file
Binary file not shown.
7
exercise/gdi1-exercise-09-2009-WiSe-solution/.classpath
Normal file
7
exercise/gdi1-exercise-09-2009-WiSe-solution/.classpath
Normal file
@ -0,0 +1,7 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<classpath>
|
||||
<classpathentry kind="src" path="src"/>
|
||||
<classpathentry kind="con" path="org.eclipse.jdt.junit.JUNIT_CONTAINER/4"/>
|
||||
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/>
|
||||
<classpathentry kind="output" path="bin"/>
|
||||
</classpath>
|
||||
17
exercise/gdi1-exercise-09-2009-WiSe-solution/.project
Normal file
17
exercise/gdi1-exercise-09-2009-WiSe-solution/.project
Normal file
@ -0,0 +1,17 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<projectDescription>
|
||||
<name>GDI Calendar2</name>
|
||||
<comment></comment>
|
||||
<projects>
|
||||
</projects>
|
||||
<buildSpec>
|
||||
<buildCommand>
|
||||
<name>org.eclipse.jdt.core.javabuilder</name>
|
||||
<arguments>
|
||||
</arguments>
|
||||
</buildCommand>
|
||||
</buildSpec>
|
||||
<natures>
|
||||
<nature>org.eclipse.jdt.core.javanature</nature>
|
||||
</natures>
|
||||
</projectDescription>
|
||||
@ -0,0 +1,12 @@
|
||||
#Sat Dec 19 17:46:19 CET 2009
|
||||
eclipse.preferences.version=1
|
||||
org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
|
||||
org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.6
|
||||
org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve
|
||||
org.eclipse.jdt.core.compiler.compliance=1.6
|
||||
org.eclipse.jdt.core.compiler.debug.lineNumber=generate
|
||||
org.eclipse.jdt.core.compiler.debug.localVariable=generate
|
||||
org.eclipse.jdt.core.compiler.debug.sourceFile=generate
|
||||
org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
|
||||
org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
|
||||
org.eclipse.jdt.core.compiler.source=1.6
|
||||
190
exercise/gdi1-exercise-09-2009-WiSe-solution/src/Calendar.java
Normal file
190
exercise/gdi1-exercise-09-2009-WiSe-solution/src/Calendar.java
Normal file
@ -0,0 +1,190 @@
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.GregorianCalendar;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Instances of the Calendar class contain CalendarEntries.
|
||||
*
|
||||
* @author Stefan Radomski, Guido Roessling
|
||||
* @version 1.0
|
||||
*/
|
||||
public class Calendar {
|
||||
|
||||
/**
|
||||
* the internal storage for calendar entries
|
||||
*/
|
||||
private List<CalendarEntry> calendarEntries;
|
||||
|
||||
/**
|
||||
* Construct a new calendar object.
|
||||
*/
|
||||
public Calendar()
|
||||
{
|
||||
calendarEntries = new ArrayList<CalendarEntry>();
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a CalendarEntry to this calendar instance.
|
||||
*
|
||||
* @param calEntry
|
||||
* The entry to add.
|
||||
*/
|
||||
public void addCalendarEntry(CalendarEntry calEntry)
|
||||
{
|
||||
if(!hasCalendarEntry(calEntry))
|
||||
{
|
||||
calendarEntries.add(calEntry);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes a CalendarEntry of this calendar instance.
|
||||
*
|
||||
* @param calEntry Entry to be removed
|
||||
*/
|
||||
public void removeCalendarEntry(CalendarEntry calEntry)
|
||||
{
|
||||
calendarEntries.remove(calEntry);
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if a CalendarEntry is part of this Calendar.
|
||||
*
|
||||
* @param calEntry CalendarEntry to be checked
|
||||
* @return boolean True if Entry is part of Calendar else false.
|
||||
*/
|
||||
public boolean hasCalendarEntry(CalendarEntry calEntry)
|
||||
{
|
||||
return calendarEntries.contains(calEntry);
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes all CalendarEntries from Calendar and replace them
|
||||
* with given Array of CalendarEntries.
|
||||
*
|
||||
* No checks are performed if Entries are valid!
|
||||
*
|
||||
* @param calEntries Array of CalendarEntry
|
||||
*/
|
||||
public void setCalendarEntries(CalendarEntry[] calEntries)
|
||||
{
|
||||
calendarEntries = Arrays.asList(calEntries);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns all CalendarEntries in this Calendar.
|
||||
*
|
||||
* @return CalendarEntry[] Array of CalendarEntries of Calendar.
|
||||
*/
|
||||
public CalendarEntry[] getCalendarEntries()
|
||||
{
|
||||
CalendarEntry[] temparray = new CalendarEntry[calendarEntries.size()];
|
||||
calendarEntries.toArray(temparray);
|
||||
return temparray;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a textual representation of all CalendarEntries visible for the
|
||||
* given user.
|
||||
*
|
||||
* @param user
|
||||
* The user object for whom to display the CalendarEntries.
|
||||
* @return A String representing all the CalendarEntries.
|
||||
*/
|
||||
public String listEntries(User user)
|
||||
{
|
||||
StringBuffer sb = new StringBuffer();
|
||||
|
||||
Iterator<CalendarEntry> it = calendarEntries.iterator();
|
||||
|
||||
while(it.hasNext())
|
||||
{
|
||||
CalendarEntry ce = it.next();
|
||||
if(ce.isVisible(user))
|
||||
{
|
||||
sb.append(ce.toString());
|
||||
sb.append("\n");
|
||||
}
|
||||
}
|
||||
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns new Calendar-Instance which contains only the Entries of
|
||||
* this Calendar with are between start- and end-Time.
|
||||
*
|
||||
* @param start GregorianCalendar
|
||||
* @param end GregorianCalendar
|
||||
* @return Calendar
|
||||
*/
|
||||
public Calendar getBetween(GregorianCalendar start, GregorianCalendar end)
|
||||
{
|
||||
Calendar tempcal = new Calendar();
|
||||
|
||||
Iterator<CalendarEntry> it = calendarEntries.iterator();
|
||||
|
||||
while(it.hasNext())
|
||||
{
|
||||
CalendarEntry ce = it.next();
|
||||
|
||||
if(ce.isBetween(start,end))
|
||||
{
|
||||
tempcal.addCalendarEntry(ce);
|
||||
}
|
||||
}
|
||||
|
||||
return tempcal;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new calendar, three users and add some appointments to the
|
||||
* calendar.
|
||||
*
|
||||
* @param args
|
||||
* command-line arguments (ignored in this application)
|
||||
*/
|
||||
public static void main(String[] args) {
|
||||
Calendar cal = new Calendar();
|
||||
|
||||
Developer paul = new Developer("Paul", "Anderson");
|
||||
Developer mary = new Developer("Mary", "Bobkins");
|
||||
Secretary bob = new Secretary("Adam", "Johanson");
|
||||
|
||||
Reminder plants = new Reminder(
|
||||
new GregorianCalendar(2010, 3, 12, 14, 30),
|
||||
new GregorianCalendar(2010, 3, 12, 14, 20),
|
||||
"Water the plants", paul);
|
||||
plants.setPrivate(true);
|
||||
cal.addCalendarEntry(plants);
|
||||
|
||||
Meeting dailyScrum = new Meeting(
|
||||
new GregorianCalendar(2010, 3, 12, 10, 30),
|
||||
new GregorianCalendar(2010, 3, 12, 11, 30),
|
||||
"Discuss yesterdays work", paul);
|
||||
dailyScrum.addParticipant(mary);
|
||||
cal.addCalendarEntry(dailyScrum);
|
||||
|
||||
Vacation spain = new Vacation(
|
||||
new GregorianCalendar(2010, 2, 3),
|
||||
new GregorianCalendar(2010, 2, 13),
|
||||
"Enjoying the beach in spain", mary);
|
||||
spain.setDelegate(bob);
|
||||
cal.addCalendarEntry(spain);
|
||||
|
||||
Illness cold = new Illness(
|
||||
new GregorianCalendar(2010, 3, 3),
|
||||
new GregorianCalendar(2010, 3, 4),
|
||||
"Caught a cold, will be back tomorrow", bob);
|
||||
cold.setDelegate(mary);
|
||||
cal.addCalendarEntry(cold);
|
||||
|
||||
Calendar earlyApril = cal.getBetween(new GregorianCalendar(2010, 3, 3),
|
||||
new GregorianCalendar(2010, 3, 10));
|
||||
|
||||
System.out.println(cal.listEntries(bob));
|
||||
System.out.println(earlyApril.listEntries(bob));
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,168 @@
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.GregorianCalendar;
|
||||
|
||||
/**
|
||||
* This class represents an entry in our calendar. All entries in the Calendar
|
||||
* are instances of the class CalendarEntry.
|
||||
*
|
||||
* @author Stefan Radomski, Guido Roessling
|
||||
* @version 1.0
|
||||
*/
|
||||
public abstract class CalendarEntry {
|
||||
|
||||
/**
|
||||
* the description of this calendar entry
|
||||
*/
|
||||
private String description;
|
||||
|
||||
/**
|
||||
* the owner of this calendar entry
|
||||
*/
|
||||
private User owner;
|
||||
|
||||
/**
|
||||
* mark if this entry is private (only visible to the user)
|
||||
*/
|
||||
private boolean priv;
|
||||
|
||||
/**
|
||||
* the date and time for this entry
|
||||
*/
|
||||
protected GregorianCalendar time;
|
||||
|
||||
/**
|
||||
* Construct a new CalendarEntry object.
|
||||
*
|
||||
* @param time the GregorianCalendar representing the date and time of the
|
||||
* entry.
|
||||
* @param description a String describing the nature of the entry.
|
||||
* @param owner the User object who owns this entry.
|
||||
*/
|
||||
public CalendarEntry(GregorianCalendar time, String description, User owner)
|
||||
{
|
||||
this.time = time;
|
||||
this.description = description;
|
||||
this.owner = owner;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check whether this entry is visible for the given user.
|
||||
*
|
||||
* @param user The user who wants to see calendar entries.
|
||||
* @return A boolean value, indicating the visibility.
|
||||
*/
|
||||
public boolean isVisible(User user) {
|
||||
return (user.equals(owner) || !priv);
|
||||
}
|
||||
|
||||
/**
|
||||
* returns the description of this entry
|
||||
*
|
||||
* @return the description of this entry
|
||||
*/
|
||||
public String getDescription() {
|
||||
return description;
|
||||
}
|
||||
|
||||
/**
|
||||
* assigns a new description for this entry
|
||||
*
|
||||
* @param description
|
||||
* the new description for this entry
|
||||
*/
|
||||
public void setDescription(String description) {
|
||||
this.description = description;
|
||||
}
|
||||
|
||||
/**
|
||||
* returns the owner of this entry
|
||||
*
|
||||
* @return the ower of this entry
|
||||
*/
|
||||
public User getOwner() {
|
||||
return owner;
|
||||
}
|
||||
|
||||
/**
|
||||
* assigns a new owner for this entry
|
||||
*
|
||||
* @param time the new owner for this entry
|
||||
*/
|
||||
public void setOwner(User owner) {
|
||||
this.owner = owner;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check whether this is a private entry.
|
||||
*
|
||||
* @return The privacy flag of the entry.
|
||||
*/
|
||||
public boolean isPrivate() {
|
||||
return priv;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the privacy of this entry.
|
||||
*
|
||||
* @param priv set to true for private or false for public (default).
|
||||
*/
|
||||
public void setPrivate(boolean priv) {
|
||||
this.priv = priv;
|
||||
}
|
||||
|
||||
/**
|
||||
* returns the date and time of this entry
|
||||
*
|
||||
* @return the date and time of this entry
|
||||
*/
|
||||
public GregorianCalendar getTime() {
|
||||
return time;
|
||||
}
|
||||
|
||||
/**
|
||||
* assigns a new date and time for this entry
|
||||
*
|
||||
* @param time the new date and time for this entry
|
||||
*/
|
||||
public void setTime(GregorianCalendar time)
|
||||
{
|
||||
this.time = time;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if CalendarEntry is between start- and end-Time else false.
|
||||
*
|
||||
* @param start
|
||||
* @param end
|
||||
* @return boolean
|
||||
*/
|
||||
public boolean isBetween(GregorianCalendar start, GregorianCalendar end)
|
||||
{
|
||||
if( time.getTime().getTime() >= start.getTime().getTime() &&
|
||||
time.getTime().getTime() <= end.getTime().getTime() )
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* returns a String representation of this CalendarEntry.
|
||||
*
|
||||
* @return a String representing this object
|
||||
*/
|
||||
@Override
|
||||
public String toString()
|
||||
{
|
||||
StringBuilder sb = new StringBuilder();
|
||||
SimpleDateFormat sdf = new SimpleDateFormat("E, dd MMMM yyyy - kk:mm:ss");
|
||||
|
||||
sb.append(sdf.format(time.getTime()));
|
||||
sb.append(" von ").append(owner.getGivenName()).append(" ");
|
||||
sb.append(owner.getFamilyName());
|
||||
sb.append(" | ").append(description);
|
||||
|
||||
return sb.toString();
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,199 @@
|
||||
import java.util.GregorianCalendar;
|
||||
|
||||
/**
|
||||
* This Class represents a CalendarEntry with a duration.
|
||||
*
|
||||
* @author Ulf Gebhardt
|
||||
* @version 1.0
|
||||
*/
|
||||
|
||||
public class CalendarEntryDuration extends CalendarEntry
|
||||
{
|
||||
/**
|
||||
* Start-Time of the Duration
|
||||
*/
|
||||
private GregorianCalendar startTime;
|
||||
|
||||
/**
|
||||
* End-Time of the Duration
|
||||
*/
|
||||
private GregorianCalendar endTime;
|
||||
|
||||
/**
|
||||
* Delegate which replaces absent Person
|
||||
*/
|
||||
private User delegate;
|
||||
|
||||
/**
|
||||
* Constructor of CalendarEntryDuration.
|
||||
*
|
||||
* You have to pass a aditional start- and end-Time.
|
||||
*
|
||||
* @param startTime
|
||||
* @param endTime
|
||||
* @param description
|
||||
* @param owner
|
||||
*/
|
||||
public CalendarEntryDuration( GregorianCalendar startTime,
|
||||
GregorianCalendar endTime,
|
||||
String description,
|
||||
User owner)
|
||||
{
|
||||
super(startTime,description,owner);
|
||||
setStartTime(startTime);
|
||||
setEndTime(endTime);
|
||||
}
|
||||
|
||||
public GregorianCalendar getStartTime() {
|
||||
return startTime;
|
||||
}
|
||||
|
||||
public void setStartTime(GregorianCalendar startTime) {
|
||||
this.startTime = startTime;
|
||||
}
|
||||
|
||||
public GregorianCalendar getEndTime() {
|
||||
return endTime;
|
||||
}
|
||||
|
||||
public void setEndTime(GregorianCalendar endTime) {
|
||||
this.endTime = endTime;
|
||||
}
|
||||
|
||||
public User getDelegate() {
|
||||
return delegate;
|
||||
}
|
||||
|
||||
public void setDelegate(User delegate) {
|
||||
this.delegate = delegate;
|
||||
}
|
||||
|
||||
/**
|
||||
* returns Duration of CalendarEntry on given field.
|
||||
*
|
||||
* @param field
|
||||
* @return integer
|
||||
*/
|
||||
public int getDuration(int field)
|
||||
{
|
||||
double timedif = endTime.getTimeInMillis() - startTime.getTimeInMillis();
|
||||
|
||||
switch(field)
|
||||
{
|
||||
case GregorianCalendar.DATE:
|
||||
{
|
||||
return (int) Math.floor(timedif / (1000*60*60*24));
|
||||
}
|
||||
case GregorianCalendar.HOUR:
|
||||
{
|
||||
return (int) Math.floor(timedif / (1000*60*60));
|
||||
}
|
||||
case GregorianCalendar.MINUTE:
|
||||
{
|
||||
return (int) Math.floor(timedif / (1000*60));
|
||||
}
|
||||
case GregorianCalendar.SECOND:
|
||||
{
|
||||
return (int) Math.floor(timedif / (1000));
|
||||
}
|
||||
default:
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param date
|
||||
* @return
|
||||
*/
|
||||
public boolean spans(GregorianCalendar date)
|
||||
{
|
||||
if( (date.getTime().getTime() - startTime.getTime().getTime()) >= 0 &&
|
||||
(date.getTime().getTime() - endTime.getTime().getTime()) <= 0 )
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if CalendarEntry is between start- and end-Time else false.
|
||||
*
|
||||
* @param start
|
||||
* @param end
|
||||
* @return boolean
|
||||
*/
|
||||
@Override
|
||||
public boolean isBetween(GregorianCalendar start, GregorianCalendar end)
|
||||
{
|
||||
if( (startTime.getTime().getTime() >= start.getTime().getTime() &&
|
||||
startTime.getTime().getTime() <= end.getTime().getTime() ) ||
|
||||
(endTime.getTime().getTime() >= start.getTime().getTime() &&
|
||||
endTime.getTime().getTime() <= end.getTime().getTime() ))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if given User is allowed to view this CalendarEntry.
|
||||
*
|
||||
* @param user
|
||||
* @return boolean
|
||||
*/
|
||||
@Override
|
||||
public boolean isVisible(User user)
|
||||
{
|
||||
if(user == this.getOwner() || !isPrivate() || user == delegate)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* returns a String representation of this CalendarEntry.
|
||||
*
|
||||
* Warning, do not count months and years!!!
|
||||
*
|
||||
* @return a String representing this object
|
||||
*/
|
||||
@Override
|
||||
public String toString()
|
||||
{
|
||||
String result = super.toString() + " - about ";
|
||||
|
||||
if(getDuration(GregorianCalendar.DATE) > 0)
|
||||
{
|
||||
if(Math.floor((double)getDuration(GregorianCalendar.DATE) / 365) > 0)
|
||||
{
|
||||
return result + (int)Math.floor((double)getDuration(GregorianCalendar.DATE) / 365) + " year(s)";
|
||||
}
|
||||
|
||||
return result + getDuration(GregorianCalendar.DATE) + " day(s)";
|
||||
}
|
||||
|
||||
if(getDuration(GregorianCalendar.HOUR) > 0)
|
||||
{
|
||||
return result + getDuration(GregorianCalendar.HOUR) + " hour(s)";
|
||||
}
|
||||
|
||||
if(getDuration(GregorianCalendar.MINUTE) > 0)
|
||||
{
|
||||
return result + getDuration(GregorianCalendar.MINUTE) + " minute(s)";
|
||||
}
|
||||
|
||||
if(getDuration(GregorianCalendar.SECOND) > 0)
|
||||
{
|
||||
return result + getDuration(GregorianCalendar.SECOND) + " second(s)";
|
||||
}
|
||||
|
||||
return super.toString();
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,20 @@
|
||||
/**
|
||||
* A Developer is a special type of user
|
||||
*
|
||||
*
|
||||
* @author Stefan Radomski, Guido Rößling
|
||||
* @version 1.0 2009-12-03
|
||||
*/
|
||||
public class Developer extends User{
|
||||
|
||||
/**
|
||||
* Create a new Developer.
|
||||
*
|
||||
* @param givenName The developers first name.
|
||||
* @param familyName The developers last name.
|
||||
*/
|
||||
public Developer(String givenName, String familyName)
|
||||
{
|
||||
super(givenName, familyName);
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,27 @@
|
||||
import java.util.GregorianCalendar;
|
||||
|
||||
/**
|
||||
* Illness is a type of CalendarEntry that has a start and end time
|
||||
*
|
||||
* @author Stefan Radomski, Guido Rößling
|
||||
* @version 1.0 2009-12-03
|
||||
*/
|
||||
public class Illness extends CalendarEntryDuration {
|
||||
|
||||
/**
|
||||
* Create a new period of illness as it might be reported by a user.
|
||||
*
|
||||
* @param startTime The day the user went absent due to her illness.
|
||||
* @param endTime The day the user plans to return.
|
||||
* @param description Some additional information.
|
||||
* @param owner The user being ill.
|
||||
*/
|
||||
public Illness( GregorianCalendar startTime,
|
||||
GregorianCalendar endTime,
|
||||
String description,
|
||||
User owner)
|
||||
{
|
||||
super(startTime,endTime,description,owner);
|
||||
}
|
||||
|
||||
}
|
||||
112
exercise/gdi1-exercise-09-2009-WiSe-solution/src/Meeting.java
Normal file
112
exercise/gdi1-exercise-09-2009-WiSe-solution/src/Meeting.java
Normal file
@ -0,0 +1,112 @@
|
||||
import java.util.GregorianCalendar;
|
||||
import java.util.List;
|
||||
import java.util.ArrayList;
|
||||
|
||||
/**
|
||||
* A Meeting is a calendar entry with participants and a start and
|
||||
* end time.
|
||||
*
|
||||
* @author Stefan Radomski, Guido Rößling
|
||||
* @version 1.0 2009-12-03
|
||||
*/
|
||||
public class Meeting extends CalendarEntryDuration
|
||||
{
|
||||
/**
|
||||
* Variable which stores participants of the meeting
|
||||
*/
|
||||
private List<User> participants;
|
||||
|
||||
/**
|
||||
* Create a new Meeting.
|
||||
*
|
||||
* @param startTime The time the meeting will start.
|
||||
* @param endTime The end time of the meeting.
|
||||
* @param description Additional information regarding the meetin.
|
||||
* @param owner The organizer of the meeting.
|
||||
*/
|
||||
public Meeting( GregorianCalendar startTime,
|
||||
GregorianCalendar endTime,
|
||||
String description,
|
||||
User owner)
|
||||
{
|
||||
super(startTime,endTime,description,owner);
|
||||
participants = new ArrayList<User>();
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if user is Allowed to this Meeting
|
||||
*
|
||||
* @param user
|
||||
* @return boolean
|
||||
*/
|
||||
private boolean isUserAllowed(User user)
|
||||
{
|
||||
return user.getClass() == Developer.class ? true : false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds User to Participant-List if user is allowed.
|
||||
*
|
||||
* @param newUser
|
||||
*/
|
||||
public void addParticipant(User newUser)
|
||||
{
|
||||
if(isUserAllowed(newUser) && !hasParticipant(newUser))
|
||||
{
|
||||
participants.add(newUser);
|
||||
}
|
||||
|
||||
//error here
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes given User from Participant-List
|
||||
*
|
||||
* Do not invoke error if User is not in List!
|
||||
*
|
||||
* @param user
|
||||
*/
|
||||
public void removeParticipant(User user)
|
||||
{
|
||||
participants.remove(user);
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if User is in Participant-List.
|
||||
*
|
||||
* @param user
|
||||
* @return boolean
|
||||
*/
|
||||
public boolean hasParticipant(User user)
|
||||
{
|
||||
return participants.contains(user);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets Participant-List.
|
||||
* Users who are not allowed are removed from List.
|
||||
*
|
||||
* @param users
|
||||
*/
|
||||
public void setParticipants(User[] users)
|
||||
{
|
||||
participants.clear();
|
||||
|
||||
for(int i = 0; i < users.length; i++)
|
||||
{
|
||||
addParticipant(users[i]);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns Participant-List.
|
||||
*
|
||||
* @return User[]
|
||||
*/
|
||||
public User[] getParticipants()
|
||||
{
|
||||
User[] temparray = new User[participants.size()];
|
||||
participants.toArray(temparray);
|
||||
return temparray;
|
||||
}
|
||||
}
|
||||
35
exercise/gdi1-exercise-09-2009-WiSe-solution/src/Note.java
Normal file
35
exercise/gdi1-exercise-09-2009-WiSe-solution/src/Note.java
Normal file
@ -0,0 +1,35 @@
|
||||
import java.util.GregorianCalendar;
|
||||
|
||||
/**
|
||||
* A note is a calendar entry that stores details
|
||||
*
|
||||
* @author Stefan Radomski, Guido Rößling
|
||||
* @version 1.0 2009-12-03
|
||||
*/
|
||||
public class Note extends CalendarEntry
|
||||
{
|
||||
/**
|
||||
* Variable to store Details of the Note.
|
||||
*/
|
||||
private String details;
|
||||
|
||||
/**
|
||||
* Create a new note to be added to a calendar.
|
||||
*
|
||||
* @param time The time this note will become relevant.
|
||||
* @param description Additinal information.
|
||||
* @param owner The owner of the note.
|
||||
*/
|
||||
public Note(GregorianCalendar time, String description, User owner)
|
||||
{
|
||||
super(time, description, owner);
|
||||
}
|
||||
|
||||
public String getDetails() {
|
||||
return details;
|
||||
}
|
||||
|
||||
public void setDetails(String details) {
|
||||
this.details = details;
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,44 @@
|
||||
import java.util.GregorianCalendar;
|
||||
|
||||
/**
|
||||
* A reminder is a calendar entry that appears at a defined
|
||||
* point in time but has no duration.
|
||||
*
|
||||
* @author Stefan Radomski, Guido Rößling
|
||||
* @version 1.0 2009-12-03
|
||||
*/
|
||||
public class Reminder extends CalendarEntry
|
||||
{
|
||||
/**
|
||||
* The time when to remind the owner about this entry.
|
||||
*/
|
||||
private GregorianCalendar alarmTime;
|
||||
|
||||
/**
|
||||
* Create a new reminder to be added in a calendar.
|
||||
*
|
||||
* @param time The time this reminder references.
|
||||
* @param alarmTime When to alert the owner about this reminder.
|
||||
* @param description Some descriptive information.
|
||||
* @param owner The user owning this entry.
|
||||
*/
|
||||
public Reminder(GregorianCalendar time,
|
||||
GregorianCalendar alarmTime,
|
||||
String description,
|
||||
User owner)
|
||||
{
|
||||
super(time,description,owner);
|
||||
setAlarmTime(alarmTime);
|
||||
}
|
||||
|
||||
public GregorianCalendar getAlarmTime() {
|
||||
return alarmTime;
|
||||
}
|
||||
|
||||
public void setAlarmTime(GregorianCalendar alarmTime) {
|
||||
if(alarmTime.before(time))
|
||||
{
|
||||
this.alarmTime = alarmTime;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,19 @@
|
||||
/**
|
||||
* A secretary is a special user for calendars.
|
||||
*
|
||||
* @author Stefan Radomski, Guido Rößling
|
||||
* @version 1.0 2009-12-03
|
||||
*/
|
||||
public class Secretary extends User{
|
||||
|
||||
/**
|
||||
* Creates a new secretary
|
||||
*
|
||||
* @param givenName The first name.
|
||||
* @param familyName The last name.
|
||||
*/
|
||||
public Secretary(String givenName, String familyName)
|
||||
{
|
||||
super(givenName,familyName);
|
||||
}
|
||||
}
|
||||
80
exercise/gdi1-exercise-09-2009-WiSe-solution/src/User.java
Normal file
80
exercise/gdi1-exercise-09-2009-WiSe-solution/src/User.java
Normal file
@ -0,0 +1,80 @@
|
||||
/**
|
||||
* Instances of the user class own CalendarEntries
|
||||
*
|
||||
* @author Stefan Radomski, Guido Roessling
|
||||
* @version 1.0 2009-12-03
|
||||
*/
|
||||
public abstract class User {
|
||||
|
||||
/**
|
||||
* the given name of this user
|
||||
*/
|
||||
private String givenName;
|
||||
|
||||
/**
|
||||
* the family name of this user
|
||||
*/
|
||||
private String familyName;
|
||||
|
||||
/**
|
||||
* The constructor for User objects
|
||||
*
|
||||
* @param givenName the first name.
|
||||
* @param familyName the last name.
|
||||
*/
|
||||
public User(String givenName, String familyName) {
|
||||
this.givenName = givenName;
|
||||
this.familyName = familyName;
|
||||
}
|
||||
|
||||
/**
|
||||
* returns a textual representation of this user as a String
|
||||
*
|
||||
* @return the user in a String representation
|
||||
*/
|
||||
public String toString() {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
sb.append(givenName);
|
||||
if (givenName.length() > 0) {
|
||||
sb.append(" ");
|
||||
}
|
||||
sb.append(familyName);
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* returns the given name of this user
|
||||
*
|
||||
* @return the given name of this user
|
||||
*/
|
||||
public String getGivenName() {
|
||||
return givenName;
|
||||
}
|
||||
|
||||
/**
|
||||
* sets the given name of this user
|
||||
*
|
||||
* @param givenName the new given name of the user
|
||||
*/
|
||||
public void setGivenName(String givenName) {
|
||||
this.givenName = givenName;
|
||||
}
|
||||
|
||||
/**
|
||||
* returns the family name of this user
|
||||
*
|
||||
* @return the family name of this user
|
||||
*/
|
||||
public String getFamilyName() {
|
||||
return familyName;
|
||||
}
|
||||
|
||||
/**
|
||||
* sets the family name of this user
|
||||
*
|
||||
* @param familyName the new family name of the user
|
||||
*/
|
||||
public void setFamilyName(String familyName) {
|
||||
this.familyName = familyName;
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,27 @@
|
||||
import java.util.GregorianCalendar;
|
||||
|
||||
/**
|
||||
* Vacation represents an absence of a person due to a vacation
|
||||
*
|
||||
* @author Stefan Radomski, Guido Rößling
|
||||
* @version 1.0 2009-12-03
|
||||
*/
|
||||
public class Vacation extends CalendarEntryDuration
|
||||
{
|
||||
|
||||
/**
|
||||
* Create a new entry of a person's vacation.
|
||||
*
|
||||
* @param startTime When the vacation will start.
|
||||
* @param endTime When the person will be come back.
|
||||
* @param description Some additional information about the vacation.
|
||||
* @param owner The person going on vacation.
|
||||
*/
|
||||
public Vacation(GregorianCalendar startTime,
|
||||
GregorianCalendar endTime,
|
||||
String description,
|
||||
User owner)
|
||||
{
|
||||
super(startTime,endTime,description,owner);
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,453 @@
|
||||
import java.util.GregorianCalendar;
|
||||
|
||||
import junit.framework.Assert;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
|
||||
|
||||
/**
|
||||
* Test the various calendar functionality.
|
||||
*/
|
||||
public class CalendarTest {
|
||||
|
||||
/**
|
||||
* @author felix
|
||||
*/
|
||||
|
||||
private Calendar testCal;
|
||||
private Developer paul;
|
||||
private Developer mary;
|
||||
private Secretary bob;
|
||||
|
||||
private Note note;
|
||||
private Illness illness;
|
||||
private Reminder reminder;
|
||||
private Meeting meeting;
|
||||
private Vacation vacation;
|
||||
|
||||
@Before
|
||||
public void Init() {
|
||||
// test calendar object
|
||||
testCal = new Calendar();
|
||||
|
||||
// users init
|
||||
paul = new Developer("Paul", "Anderson");
|
||||
mary = new Developer("Mary", "Bobkins");
|
||||
bob = new Secretary("Adam", "Johanson");
|
||||
|
||||
// note init
|
||||
note = new Note(new GregorianCalendar(2009, 1, 0, 16, 0), "my note", paul);
|
||||
note.setDetails("test");
|
||||
testCal.addCalendarEntry(note);
|
||||
|
||||
// reminder init
|
||||
reminder = new Reminder(new GregorianCalendar(2010, 3, 12, 14, 30), new GregorianCalendar(2010, 3, 12, 14, 20), "Water the plants", mary);
|
||||
reminder.setPrivate(true);
|
||||
testCal.addCalendarEntry(reminder);
|
||||
|
||||
// meeting init
|
||||
meeting = new Meeting(new GregorianCalendar(2010, 1, 1, 16, 30), new GregorianCalendar(2010, 1, 1, 17, 0), "test meeting", bob);
|
||||
meeting.addParticipant(paul);
|
||||
meeting.addParticipant(mary);
|
||||
// meeting.addParticipant(bob); --> not possible - bob isn't a developer!
|
||||
|
||||
// illness init
|
||||
illness = new Illness(new GregorianCalendar(2010, 0, 1), new GregorianCalendar(2010, 0, 2), "bobs illness", bob);
|
||||
illness.setPrivate(true);
|
||||
testCal.addCalendarEntry(illness);
|
||||
|
||||
// vacation init
|
||||
vacation = new Vacation(new GregorianCalendar(2020, 0, 0, 0, 0), new GregorianCalendar(2020, 0, 0, 0, 1), "short vacation", paul);
|
||||
testCal.addCalendarEntry(vacation);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void noteTest() {
|
||||
// has note the additional field details?
|
||||
Assert.assertEquals(note.getDetails(), "test");
|
||||
Assert.assertEquals(note.getDescription(), "my note");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void reminderTest() {
|
||||
// check current alarm time (should be set)
|
||||
Assert.assertEquals(reminder.getAlarmTime(), new GregorianCalendar(2010, 3, 12, 14, 20));
|
||||
|
||||
// set new alarm time after the actual time - this should not work
|
||||
// -> old alarm time should be set
|
||||
try {
|
||||
reminder.setAlarmTime(new GregorianCalendar(2010, 3, 12, 14, 40));
|
||||
} catch (Exception e) {
|
||||
}
|
||||
Assert.assertEquals(reminder.getAlarmTime(), new GregorianCalendar(2010, 3, 12, 14, 20));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void meetingTest() {
|
||||
// test method getParticipants
|
||||
String[] names = {"Paul", "Mary"};
|
||||
User[] participants = meeting.getParticipants();
|
||||
|
||||
for (int i=0; i<participants.length; i++) {
|
||||
Assert.assertEquals(names[i], participants[i].getGivenName());
|
||||
}
|
||||
|
||||
// test method setParticipants
|
||||
names[0] = "Mary";
|
||||
names[1] = "Paul";
|
||||
meeting.setParticipants(new Developer[] {mary, paul});
|
||||
participants = meeting.getParticipants();
|
||||
|
||||
for (int i=0; i<participants.length; i++)
|
||||
{
|
||||
Assert.assertEquals(names[i], participants[i].getGivenName());
|
||||
}
|
||||
|
||||
// test removeParticipant()
|
||||
meeting.removeParticipant(mary);
|
||||
Assert.assertEquals(1, meeting.getParticipants().length);
|
||||
Assert.assertEquals("Paul", meeting.getParticipants()[0].getGivenName());
|
||||
|
||||
// test addParticipant and hasParticipant
|
||||
meeting.addParticipant(mary);
|
||||
Assert.assertTrue(meeting.hasParticipant(mary));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void userClassesTest() {
|
||||
// check given name of a developer and a secretary
|
||||
Assert.assertEquals("Paul", paul.getGivenName());
|
||||
Assert.assertEquals("Adam", bob.getGivenName());
|
||||
|
||||
// check family name (of a developer and..)
|
||||
Assert.assertEquals("Anderson", paul.getFamilyName());
|
||||
Assert.assertEquals("Johanson", bob.getFamilyName());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void delegateTest() {
|
||||
// check delegate for illness - paul is bobs delegate
|
||||
illness.setDelegate(paul);
|
||||
Assert.assertEquals(paul, illness.getDelegate());
|
||||
|
||||
// although bobs illness is private paul should see it, because he's his delegate
|
||||
Assert.assertTrue(illness.isPrivate());
|
||||
Assert.assertTrue(testCal.listEntries(paul).contains("bobs illness"));
|
||||
|
||||
// mary shouldn't see bobs illness (she isn't his delegate and his illness isn't public)
|
||||
Assert.assertFalse(testCal.listEntries(mary).contains("bobs illness"));
|
||||
|
||||
// test delegate for vacation
|
||||
vacation.setDelegate(bob);
|
||||
Assert.assertEquals("Adam", vacation.getDelegate().getGivenName());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void durationTest() {
|
||||
// the meeting should be from 16:30 until 17:00 -> 30min
|
||||
|
||||
// check getDuration
|
||||
Assert.assertEquals(0, meeting.getDuration(GregorianCalendar.DATE));
|
||||
Assert.assertEquals(0, meeting.getDuration(GregorianCalendar.HOUR));
|
||||
Assert.assertEquals(30, meeting.getDuration(GregorianCalendar.MINUTE));
|
||||
Assert.assertEquals(1800, meeting.getDuration(GregorianCalendar.SECOND));
|
||||
|
||||
// check spans
|
||||
// 16:40 is within 16:30 - 17:00
|
||||
Assert.assertTrue(meeting.spans(new GregorianCalendar(2010, 1, 1, 16, 40)));
|
||||
// 16:00 is not within 16:30 - 17:00
|
||||
Assert.assertFalse(meeting.spans(new GregorianCalendar(2010, 1, 1, 16, 0)));
|
||||
|
||||
// check new toString()
|
||||
Assert.assertEquals("Mo, 01 Februar 2010 - 16:30:00 von Adam Johanson | test meeting - about 30 minute(s)", meeting.toString());
|
||||
meeting.setEndTime(new GregorianCalendar(2011, 1, 1, 18, 0));
|
||||
Assert.assertEquals("Mo, 01 Februar 2010 - 16:30:00 von Adam Johanson | test meeting - about 1 year(s)", meeting.toString());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void calendarTest() {
|
||||
// test getBetween
|
||||
Calendar newCalendar = testCal.getBetween(new GregorianCalendar(2009, 0, 0, 0, 0), new GregorianCalendar(2010, 0, 0, 0, 0));
|
||||
|
||||
// pauls note is the only entry that's in 2009
|
||||
Assert.assertEquals("Sa, 31 Januar 2009 - 16:00:00 von Paul Anderson | my note\n", newCalendar.listEntries(paul));
|
||||
Assert.assertEquals(1, newCalendar.getCalendarEntries().length); // getCalendarEntries should work also for this test
|
||||
|
||||
// test addCalendarEntry and hasCalendarEntry
|
||||
Assert.assertTrue(newCalendar.hasCalendarEntry(note));
|
||||
newCalendar.addCalendarEntry(reminder);
|
||||
Assert.assertTrue(newCalendar.hasCalendarEntry(reminder));
|
||||
|
||||
// test removeCalendarEntry
|
||||
newCalendar.removeCalendarEntry(reminder);
|
||||
Assert.assertFalse(newCalendar.hasCalendarEntry(reminder));
|
||||
|
||||
// test getCalendarEntries and setCalendarEntries
|
||||
CalendarEntry[] testEntries = {meeting, illness};
|
||||
newCalendar.setCalendarEntries(testEntries);
|
||||
CalendarEntry[] actualEntries = newCalendar.getCalendarEntries();
|
||||
for (int i=0; i<testEntries.length; i++) {
|
||||
Assert.assertEquals(testEntries[i], actualEntries[i]);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @author Ulf
|
||||
*/
|
||||
@Test
|
||||
public void testDeveloperCreation() {
|
||||
Developer sasha = new Developer("Sasha", "Dole");
|
||||
Assert.assertEquals(sasha.getGivenName(), "Sasha");
|
||||
Assert.assertEquals(sasha.getFamilyName(), "Dole");
|
||||
|
||||
//You can delete this stuff if you dont need this,
|
||||
//4 example if u use some fancy boolean or stuff to
|
||||
//determine if its a Secretary or a Developer
|
||||
Assert.assertEquals(sasha.getClass(), Developer.class);
|
||||
Assert.assertEquals(sasha.getClass().getSuperclass(), User.class);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSecretaryCreation() {
|
||||
Secretary sasha = new Secretary("Haris", "Pilton");
|
||||
Assert.assertEquals(sasha.getGivenName(), "Haris");
|
||||
Assert.assertEquals(sasha.getFamilyName(), "Pilton");
|
||||
|
||||
//You can delete this stuff if you dont need this,
|
||||
//4 example if u use some fancy boolean or stuff to
|
||||
//determine if its a Secretary or a Developer
|
||||
Assert.assertEquals(sasha.getClass(), Secretary.class);
|
||||
Assert.assertEquals(sasha.getClass().getSuperclass(), User.class);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testMeetingCreation() {
|
||||
Meeting meeting = new Meeting( new GregorianCalendar(2010,4, 3, 18, 30),
|
||||
new GregorianCalendar(2010,4, 4, 18, 30),
|
||||
"Meeting some Dudes",
|
||||
new Developer("Sasha", "Dole"));
|
||||
Assert.assertFalse (meeting.isPrivate());
|
||||
Assert.assertEquals(meeting.getDescription(), "Meeting some Dudes");
|
||||
Assert.assertEquals(meeting.getOwner().getGivenName(), "Sasha");
|
||||
|
||||
Developer mrt = new Developer("Mr.","T.");
|
||||
meeting.addParticipant(mrt);
|
||||
|
||||
Assert.assertTrue(meeting.hasParticipant(mrt));
|
||||
|
||||
Secretary hp = new Secretary("Haris","Pilton");
|
||||
meeting.addParticipant(hp);
|
||||
|
||||
Assert.assertFalse(meeting.hasParticipant(hp));
|
||||
|
||||
meeting.removeParticipant(mrt);
|
||||
|
||||
Assert.assertFalse(meeting.hasParticipant(mrt));
|
||||
|
||||
Assert.assertEquals(meeting.toString(),"Mo, 03 Mai 2010 - 18:30:00 von Sasha Dole | Meeting some Dudes - about 1 day(s)" );
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testVacationCreation() {
|
||||
Vacation vacation = new Vacation( new GregorianCalendar(2010,4, 3, 18, 30),
|
||||
new GregorianCalendar(2011,5, 5, 18, 00),
|
||||
"PARTEY",
|
||||
new Developer("Mr.", "T."));
|
||||
vacation.setPrivate(true);
|
||||
|
||||
Assert.assertTrue(vacation.isPrivate());
|
||||
Assert.assertEquals(vacation.getDescription(), "PARTEY");
|
||||
Assert.assertEquals(vacation.getOwner().getGivenName(), "Mr.");
|
||||
|
||||
Assert.assertEquals(vacation.toString(),"Mo, 03 Mai 2010 - 18:30:00 von Mr. T. | PARTEY - about 1 year(s)" );
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testIllnessCreation() {
|
||||
Illness illness = new Illness( new GregorianCalendar(2010,4, 4, 18, 30),
|
||||
new GregorianCalendar(2010,4, 4, 18, 30, 5),
|
||||
"-17CC outa here - where is the greenhouse effect???",
|
||||
new Developer("Gott", "hat kein Nachnamen"));
|
||||
Assert.assertFalse (illness.isPrivate());
|
||||
Assert.assertEquals(illness.getDescription(), "-17CC outa here - where is the greenhouse effect???");
|
||||
Assert.assertEquals(illness.getOwner().getFamilyName(), "hat kein Nachnamen");
|
||||
|
||||
Assert.assertEquals(illness.toString(),"Di, 04 Mai 2010 - 18:30:00 von Gott hat kein Nachnamen | -17CC outa here - where is the greenhouse effect??? - about 5 second(s)" ); }
|
||||
|
||||
@Test
|
||||
public void testNoteCreation() {
|
||||
Note note = new Note( new GregorianCalendar(2010,1, 1, 1, 1),
|
||||
"download some illegal Stuff",
|
||||
new Developer("Anon", "Anonymous"));
|
||||
note.setPrivate(true);
|
||||
Assert.assertTrue (note.isPrivate());
|
||||
Assert.assertEquals(note.getDescription(), "download some illegal Stuff");
|
||||
Assert.assertEquals(note.getOwner().getFamilyName(), "Anonymous");
|
||||
Assert.assertEquals(note.getDetails(), null);
|
||||
|
||||
note.setDetails("/b/tards always provide something... nvm");
|
||||
|
||||
Assert.assertEquals(note.getDetails(), "/b/tards always provide something... nvm");
|
||||
Assert.assertEquals(note.toString(),"Mo, 01 Februar 2010 - 01:01:00 von Anon Anonymous | download some illegal Stuff" );
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testReminderCreation() {
|
||||
Reminder rem = new Reminder( new GregorianCalendar(2010,2, 1, 1, 1),
|
||||
new GregorianCalendar(2010,1, 1, 10, 0),
|
||||
"Call Mr. T",
|
||||
new Developer("Anon", "Anonymous"));
|
||||
rem.setPrivate(true);
|
||||
Assert.assertTrue (rem.isPrivate());
|
||||
Assert.assertEquals(rem.getDescription(), "Call Mr. T");
|
||||
Assert.assertEquals(rem.getOwner().getGivenName(), "Anon");
|
||||
Assert.assertEquals(rem.getAlarmTime(), new GregorianCalendar(2010,1, 1, 10, 0));
|
||||
|
||||
Assert.assertEquals(rem.toString(),"Mo, 01 März 2010 - 01:01:00 von Anon Anonymous | Call Mr. T" );
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void testCalendarCreation()
|
||||
{
|
||||
Calendar cal = new Calendar();
|
||||
Developer bob = new Developer("Bob", "Smith");
|
||||
Meeting meeting = new Meeting( new GregorianCalendar(2010, 3, 12, 18, 30),
|
||||
new GregorianCalendar(2010, 4, 12, 18, 30),
|
||||
"Meeting with Alex and Joseph",
|
||||
new Secretary("Nailin'", "Palin"));
|
||||
cal.addCalendarEntry(meeting);
|
||||
Assert.assertTrue(cal.listEntries(bob).length() > 0);
|
||||
Assert.assertTrue(cal.listEntries(bob).contains("Nailin'"));
|
||||
Assert.assertTrue(cal.listEntries(bob).contains("Meeting with Alex and Joseph"));
|
||||
Assert.assertTrue(cal.listEntries(bob).contains("2010"));
|
||||
Assert.assertTrue(cal.listEntries(bob).contains("April"));
|
||||
Assert.assertTrue(cal.listEntries(bob).contains("Mo"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCalendarCreationAgain()
|
||||
{
|
||||
Calendar cal = new Calendar();
|
||||
|
||||
Developer mrt = new Developer("Mr.", "T.");
|
||||
Assert.assertEquals(mrt.getGivenName(), "Mr.");
|
||||
Assert.assertEquals(mrt.getFamilyName(), "T.");
|
||||
|
||||
Developer god = new Developer("Gott", "braucht keinen Nachnamen");
|
||||
Assert.assertEquals(god.getGivenName(), "Gott");
|
||||
Assert.assertEquals(god.getFamilyName(), "braucht keinen Nachnamen");
|
||||
|
||||
Secretary hp = new Secretary("Haris", "Pilton");
|
||||
Assert.assertEquals(hp.getGivenName(), "Haris");
|
||||
Assert.assertEquals(hp.getFamilyName(), "Pilton");
|
||||
|
||||
Developer cn = new Developer("chuck", "norris");
|
||||
Assert.assertEquals(cn.getGivenName(), "chuck");
|
||||
Assert.assertEquals(cn.getFamilyName(), "norris");
|
||||
|
||||
Note note = new Note( new GregorianCalendar(2010, 3, 12, 14, 30),
|
||||
"Perform Roundhousekick",
|
||||
cn);
|
||||
|
||||
Assert.assertEquals(note.getDescription(), "Perform Roundhousekick");
|
||||
Assert.assertEquals(note.getDetails(),null);
|
||||
Assert.assertFalse(note.isPrivate());
|
||||
Assert.assertTrue(note.isVisible(mrt));
|
||||
Assert.assertTrue(note.isVisible(god));
|
||||
Assert.assertTrue(note.isVisible(hp));
|
||||
Assert.assertTrue(note.isVisible(cn));
|
||||
|
||||
note.setDetails("In Ya Face");
|
||||
|
||||
Assert.assertEquals(note.getDetails(),"In Ya Face");
|
||||
|
||||
note.setPrivate(true);
|
||||
|
||||
Assert.assertFalse(note.isVisible(mrt));
|
||||
Assert.assertFalse(note.isVisible(god));
|
||||
Assert.assertFalse(note.isVisible(hp));
|
||||
Assert.assertTrue(note.isVisible(cn));
|
||||
|
||||
note.setPrivate(false);
|
||||
|
||||
Reminder rem = new Reminder( new GregorianCalendar(2010, 3, 12, 14, 30),
|
||||
new GregorianCalendar(2010, 3, 12, 14, 20),
|
||||
"Tell some Chuck Norris Jokes",
|
||||
god);
|
||||
rem.setPrivate(true);
|
||||
|
||||
Assert.assertEquals(rem.getDescription(), "Tell some Chuck Norris Jokes");
|
||||
Assert.assertTrue(rem.isPrivate());
|
||||
Assert.assertFalse(rem.isVisible(mrt));
|
||||
Assert.assertTrue(rem.isVisible(god));
|
||||
Assert.assertFalse(rem.isVisible(hp));
|
||||
Assert.assertFalse(rem.isVisible(cn));
|
||||
|
||||
Meeting meet = new Meeting( new GregorianCalendar(2010, 3, 12, 10, 30),
|
||||
new GregorianCalendar(2010, 3, 12, 11, 30),
|
||||
"Meeting about ... wow shiny new shoes",
|
||||
hp);
|
||||
Assert.assertFalse(meet.hasParticipant(god));
|
||||
meet.addParticipant(god);
|
||||
Assert.assertTrue(meet.hasParticipant(god));
|
||||
|
||||
Assert.assertEquals(meet.getDescription(), "Meeting about ... wow shiny new shoes");
|
||||
Assert.assertFalse(meet.isPrivate());
|
||||
Assert.assertTrue(meet.isVisible(mrt));
|
||||
Assert.assertTrue(meet.isVisible(god));
|
||||
Assert.assertTrue(meet.isVisible(hp));
|
||||
Assert.assertTrue(meet.isVisible(cn));
|
||||
|
||||
Vacation vac = new Vacation( new GregorianCalendar(2010, 2, 3),
|
||||
new GregorianCalendar(2010, 2, 13),
|
||||
"Create Nightelf",
|
||||
mrt);
|
||||
|
||||
Assert.assertEquals(vac.getDelegate(),null);
|
||||
|
||||
vac.setDelegate(cn);
|
||||
|
||||
Assert.assertEquals(vac.getDelegate(),cn);
|
||||
|
||||
Assert.assertEquals(vac.getDescription(), "Create Nightelf");
|
||||
Assert.assertFalse(vac.isPrivate());
|
||||
Assert.assertTrue(vac.isVisible(mrt));
|
||||
Assert.assertTrue(vac.isVisible(god));
|
||||
Assert.assertTrue(vac.isVisible(hp));
|
||||
Assert.assertTrue(vac.isVisible(cn));
|
||||
|
||||
Illness ill = new Illness( new GregorianCalendar(2010, 3, 3),
|
||||
new GregorianCalendar(2010, 3, 4),
|
||||
"Chuck Norris f<>ngt sich keine Erk<72>ltung ein, eine Erk<72>ltung f<>ngt sich Eine von Chuck Norris ein",
|
||||
cn);
|
||||
|
||||
Assert.assertEquals(ill.getDelegate(),null);
|
||||
|
||||
ill.setDelegate(god);
|
||||
|
||||
Assert.assertEquals(ill.getDelegate(),god);
|
||||
|
||||
Assert.assertEquals(ill.getDescription(), "Chuck Norris f<>ngt sich keine Erk<72>ltung ein, eine Erk<72>ltung f<>ngt sich Eine von Chuck Norris ein");
|
||||
Assert.assertFalse(ill.isPrivate());
|
||||
Assert.assertTrue(ill.isVisible(mrt));
|
||||
Assert.assertTrue(ill.isVisible(god));
|
||||
Assert.assertTrue(ill.isVisible(hp));
|
||||
Assert.assertTrue(ill.isVisible(cn));
|
||||
|
||||
Calendar earlyApril = cal.getBetween( new GregorianCalendar(2010, 3, 3),
|
||||
new GregorianCalendar(2010, 3, 10));
|
||||
|
||||
cal.listEntries(mrt);
|
||||
cal.listEntries(god);
|
||||
cal.listEntries(hp);
|
||||
cal.listEntries(cn);
|
||||
|
||||
earlyApril.listEntries(mrt);
|
||||
earlyApril.listEntries(god);
|
||||
earlyApril.listEntries(hp);
|
||||
earlyApril.listEntries(cn);
|
||||
}
|
||||
|
||||
}
|
||||
BIN
exercise/gdi1-exercise-09-2009-WiSe.pdf
Normal file
BIN
exercise/gdi1-exercise-09-2009-WiSe.pdf
Normal file
Binary file not shown.
8
exercise/gdi1-exercise-10-2009-WiSe-solution/.classpath
Normal file
8
exercise/gdi1-exercise-10-2009-WiSe-solution/.classpath
Normal file
@ -0,0 +1,8 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<classpath>
|
||||
<classpathentry kind="src" path="src"/>
|
||||
<classpathentry kind="con" path="org.eclipse.jdt.junit.JUNIT_CONTAINER/4"/>
|
||||
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/>
|
||||
<classpathentry kind="con" path="org.eclipse.jdt.USER_LIBRARY/acm"/>
|
||||
<classpathentry kind="output" path="bin"/>
|
||||
</classpath>
|
||||
17
exercise/gdi1-exercise-10-2009-WiSe-solution/.project
Normal file
17
exercise/gdi1-exercise-10-2009-WiSe-solution/.project
Normal file
@ -0,0 +1,17 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<projectDescription>
|
||||
<name>Sudoku</name>
|
||||
<comment></comment>
|
||||
<projects>
|
||||
</projects>
|
||||
<buildSpec>
|
||||
<buildCommand>
|
||||
<name>org.eclipse.jdt.core.javabuilder</name>
|
||||
<arguments>
|
||||
</arguments>
|
||||
</buildCommand>
|
||||
</buildSpec>
|
||||
<natures>
|
||||
<nature>org.eclipse.jdt.core.javanature</nature>
|
||||
</natures>
|
||||
</projectDescription>
|
||||
@ -0,0 +1,12 @@
|
||||
#Tue Jan 19 13:27:34 CET 2010
|
||||
eclipse.preferences.version=1
|
||||
org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
|
||||
org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.6
|
||||
org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve
|
||||
org.eclipse.jdt.core.compiler.compliance=1.6
|
||||
org.eclipse.jdt.core.compiler.debug.lineNumber=generate
|
||||
org.eclipse.jdt.core.compiler.debug.localVariable=generate
|
||||
org.eclipse.jdt.core.compiler.debug.sourceFile=generate
|
||||
org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
|
||||
org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
|
||||
org.eclipse.jdt.core.compiler.source=1.6
|
||||
467
exercise/gdi1-exercise-10-2009-WiSe-solution/src/Sudoku.java
Normal file
467
exercise/gdi1-exercise-10-2009-WiSe-solution/src/Sudoku.java
Normal file
@ -0,0 +1,467 @@
|
||||
import java.awt.Color;
|
||||
import java.awt.event.ActionEvent;
|
||||
import java.awt.event.KeyEvent;
|
||||
import java.awt.event.KeyListener;
|
||||
|
||||
import java.util.Arrays;
|
||||
|
||||
import javax.swing.BorderFactory;
|
||||
import javax.swing.JButton;
|
||||
|
||||
import acm.gui.IntField;
|
||||
import acm.gui.TableLayout;
|
||||
import acm.gui.TablePanel;
|
||||
import acm.program.Program;
|
||||
|
||||
public class Sudoku extends Program {
|
||||
|
||||
/**
|
||||
* Fixed boardsize - alter this if you want to make smaller/bigger boards
|
||||
* Not tested! (is this possible?^^)
|
||||
*/
|
||||
public static int boardsize = 9;
|
||||
|
||||
/**
|
||||
* Simple avoiding some warnings
|
||||
*/
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
|
||||
// the model of the game board
|
||||
IntField[][] board;
|
||||
|
||||
/**
|
||||
* Construct a new game of Sudoku.
|
||||
*
|
||||
* Initializes the game board with all zeroes.
|
||||
*/
|
||||
public Sudoku() {
|
||||
super();
|
||||
board = new IntField[9][9];
|
||||
for (int i = 0; i < 9; i++) {
|
||||
for (int j = 0; j < 9; j++) {
|
||||
board[i][j] = new IntField(0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialize a new game of Sudoku with a given configuration.
|
||||
*
|
||||
* @param values
|
||||
* The configuration of the game board.
|
||||
*/
|
||||
public Sudoku(int[][] values) {
|
||||
this();
|
||||
setConfiguration(values);
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialize the view component.
|
||||
*/
|
||||
@Override
|
||||
public void init() {
|
||||
setTitle("Sudoku");
|
||||
setLayout(new TableLayout(4, 3));
|
||||
for (int i = 0; i < 9; i++) {
|
||||
add(assembleInnerTable(i));
|
||||
}
|
||||
add(new JButton("Solve"));
|
||||
addActionListeners();
|
||||
}
|
||||
|
||||
/**
|
||||
* Assemble a single 3x3 field.
|
||||
*
|
||||
* @param n
|
||||
* The number of the 3x3 field to assemble a table component for.
|
||||
* @return The TablePanel containing a 3x3 field.
|
||||
*/
|
||||
private TablePanel assembleInnerTable(int n) {
|
||||
TablePanel tp = new TablePanel(3, 3);
|
||||
for (int i = 0; i < 9; i++) {
|
||||
// we assemble 3x3 field-wise and have to adjust array indices
|
||||
// accordingly
|
||||
int row = 3 * (n / 3) + i / 3;
|
||||
int col = 3 * (n % 3) + i % 3;
|
||||
|
||||
// The constructor made sure these are instantiated IntFields
|
||||
IntField intField = board[row][col];
|
||||
|
||||
// Register a KeyListener to suppress non-digit entries
|
||||
intField.addKeyListener(new KeyListener() {
|
||||
@Override
|
||||
public void keyPressed(KeyEvent e) {
|
||||
// don't care
|
||||
}
|
||||
|
||||
@Override
|
||||
public void keyReleased(KeyEvent e) {
|
||||
// don't care
|
||||
}
|
||||
|
||||
@Override
|
||||
public void keyTyped(KeyEvent e) {
|
||||
try {
|
||||
// try to parse the pressed keys value into an Integer
|
||||
Integer.parseInt(String.valueOf(e.getKeyChar()));
|
||||
} catch (NumberFormatException nfe) {
|
||||
// consume the event and stop it from propagating
|
||||
e.consume();
|
||||
}
|
||||
}
|
||||
});
|
||||
tp.add(intField);
|
||||
}
|
||||
// draw a solid black border around every 3x3 field
|
||||
tp.setBorder(BorderFactory.createLineBorder(Color.black));
|
||||
return tp;
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialize the game board with the given arrays of ints.
|
||||
*
|
||||
* @param init The 9x9 two-dimensional array with int values from 0..9
|
||||
*/
|
||||
public void setConfiguration(int[][] init) {
|
||||
for (int i = 0; i < 9; i++) {
|
||||
for (int j = 0; j < 9; j++) {
|
||||
if (init[i][j] > 0 && init[i][j] <= 9) {
|
||||
board[i][j].setValue(init[i][j]);
|
||||
} else {
|
||||
board[i][j].setValue(0);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the current configuration of the game board.
|
||||
*
|
||||
* @return The current configuration.
|
||||
*/
|
||||
public int[][] getConfiguration() {
|
||||
int[][] tmp = new int[9][9];
|
||||
for (int i = 0; i < 9; i++) {
|
||||
for (int j = 0; j < 9; j++) {
|
||||
tmp[i][j] = board[i][j].getValue();
|
||||
}
|
||||
}
|
||||
return tmp;
|
||||
}
|
||||
|
||||
// if no solution was found, color every field red
|
||||
public void colorForFailure() {
|
||||
for (int i = 0; i < 9; i++) {
|
||||
for (int j = 0; j < 9; j++) {
|
||||
board[i][j].setBackground(new Color(255, 0, 0));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// if there was a solution, color the new values fields green
|
||||
public void colorForSuccess(int[][] solution) {
|
||||
int[][] actual = getConfiguration();
|
||||
for (int i = 0; i < 9; i++) {
|
||||
for (int j = 0; j < 9; j++) {
|
||||
if (solution[i][j] != actual[i][j]) {
|
||||
board[i][j].setBackground(new Color(0, 255, 0));
|
||||
board[i][j].setValue(solution[i][j]);
|
||||
} else {
|
||||
board[i][j].setBackground(new Color(255, 255, 255));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* The ActionListeners method to process pressed buttons.
|
||||
*
|
||||
* @param e ActionEvent
|
||||
*/
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
if (e.getActionCommand().equals("Solve")) {
|
||||
// The solve button was pressed, find a solution
|
||||
int[][] solution = solve(getConfiguration());
|
||||
if (solution != null) {
|
||||
colorForSuccess(solution);
|
||||
} else {
|
||||
colorForFailure();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if board is valid. Returns false if it is valid, else true.
|
||||
*
|
||||
* public because requested
|
||||
*
|
||||
* @param board Sudoku Configuration
|
||||
* @return false if valid, true if not.
|
||||
*/
|
||||
public boolean reject(int[][] board)
|
||||
{
|
||||
//Check input
|
||||
if(board == null)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
{ //Check if 1-9 is max 1x in every row & line
|
||||
|
||||
//Helper-Vars - Start with false
|
||||
boolean[] row = new boolean[boardsize];
|
||||
boolean[] line = new boolean[boardsize];
|
||||
|
||||
for(int i=0; i < boardsize;i++) //rows
|
||||
{
|
||||
for(int j=0; j < boardsize; j++) //lines
|
||||
{
|
||||
{ //row
|
||||
int t = board[i][j]; //value @ act pos //row
|
||||
|
||||
if( t > 0 && //skip 0 and wrong input!
|
||||
t <= boardsize)
|
||||
{
|
||||
if(row[t-1]) //already seen?
|
||||
{
|
||||
//Number already found in row
|
||||
return true;
|
||||
} else
|
||||
{
|
||||
//Set to true - do not accept this number a second time.
|
||||
row[t-1] = true;
|
||||
}
|
||||
}
|
||||
} //row
|
||||
|
||||
{ //line
|
||||
int t = board[j][i]; //value @ act pos //line
|
||||
|
||||
if( t > 0 && //skip 0 and wrong input!
|
||||
t <= boardsize)
|
||||
{
|
||||
if(line[t-1]) //already seen?
|
||||
{
|
||||
//Number already found in line
|
||||
return true;
|
||||
} else
|
||||
{
|
||||
//Set to true - do not accept this number a second time.
|
||||
line[t-1] = true;
|
||||
}
|
||||
}
|
||||
} //line
|
||||
}
|
||||
|
||||
//Reset helper-vars, new line/row
|
||||
Arrays.fill(row, false);
|
||||
Arrays.fill(line, false);
|
||||
}
|
||||
} //Check if 1-9 is max 1x in every row&line
|
||||
|
||||
{ //Check board-3x3-blocks
|
||||
|
||||
//Helper-Var - Starts with false
|
||||
boolean[] block = new boolean[boardsize];
|
||||
|
||||
for(int n=0; n < 3; n++) //Count block-lines
|
||||
{
|
||||
for(int m=0; m < 3; m++) //Count block-rows
|
||||
{
|
||||
for(int i=0; i < (boardsize/3); i++) //Count line within block
|
||||
{
|
||||
for(int j=0; j < (boardsize/3); j++) //Count row within block
|
||||
{
|
||||
int t = board[n*3+i][m*3+j]; //Value @ act pos
|
||||
|
||||
if( t > 0 && //skip 0 and wrong input!
|
||||
t <= boardsize)
|
||||
{
|
||||
if(block[t-1]) //Number already seen?
|
||||
{
|
||||
//Number already found in Block
|
||||
return true;
|
||||
} else
|
||||
{
|
||||
//Set to true - do not accept this number a second time.
|
||||
block[t-1] = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//Reset - new block
|
||||
Arrays.fill(block, false);
|
||||
}
|
||||
}
|
||||
} //Check board-3x3-blocks
|
||||
|
||||
|
||||
//All Checked & OK
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns position of the next field which is 0 (free field).
|
||||
*
|
||||
* Position-Encoding: row*boardsize + line
|
||||
* row and line starting by 0.
|
||||
* first item is 0,
|
||||
* last item is boardsize*boardsize -1
|
||||
*
|
||||
* public because assumed it is requested
|
||||
*
|
||||
* @param board
|
||||
* @return Position of next free field or -1 if no free field was found.
|
||||
*/
|
||||
public int getNextFreeField(int[][] board)
|
||||
{
|
||||
//Just Checking - should never happen, but method is public... you know...
|
||||
if(board == null)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
//Search
|
||||
for(int i=0; i < boardsize; i++) //row
|
||||
{
|
||||
for(int j=0; j < boardsize; j++) //line
|
||||
{
|
||||
if(board[i][j] == 0) //Is act pos 0 ?
|
||||
{
|
||||
return i*boardsize + j; //Position Calculation
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//Field has no empty fields
|
||||
return -1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns new Sudoku configuration with altered (incremented by 1)
|
||||
* value at given position pos.
|
||||
*
|
||||
* public because assumed it is requested
|
||||
*
|
||||
* @param board Given Sudoku configuration
|
||||
* @param pos position to be altered
|
||||
* @return Sudoku configuration or null
|
||||
*/
|
||||
public int[][] getNextExtension(int[][] board, int pos)
|
||||
{
|
||||
//Decrypt 1-dim-pos to 2-dim-pos
|
||||
int i = pos/boardsize;
|
||||
int j = pos-i*boardsize;
|
||||
|
||||
if( board != null && //Board ok?
|
||||
i < boardsize && //row ok?
|
||||
j < boardsize && //line ok?
|
||||
board[i][j] < boardsize) //value @ pos < boardsize?
|
||||
{
|
||||
int[][] newboard = new int[boardsize][boardsize];
|
||||
|
||||
{ //clone board -> newboard
|
||||
for(int k = 0; k < boardsize; k++)
|
||||
{
|
||||
System.arraycopy(board[k], 0, newboard[k], 0, board[k].length);
|
||||
}
|
||||
} //clone board -> newboard
|
||||
|
||||
newboard[i][j] += 1; // inc value @ pos -> +1
|
||||
return newboard; //return the new board
|
||||
}
|
||||
|
||||
return null; //Something was wrong - see if clause
|
||||
}
|
||||
|
||||
/**
|
||||
* Solve the given Sudoku configuration and return the result.
|
||||
*
|
||||
* @param configuration A 9x9 two-dimensional array, columns first.
|
||||
* @return The solution for this game of Sudoku or null if not solvable.
|
||||
*/
|
||||
public int[][] solve(int[][] configuration)
|
||||
{
|
||||
return solve(configuration,getNextFreeField(configuration));
|
||||
}
|
||||
/**
|
||||
* Solve the given Sudoku configuration and return the result.
|
||||
*
|
||||
* @param configuration A 9x9 two-dimensional array, columns first.
|
||||
* @param pos position to be altered (start with getNextFreeField(configuration))
|
||||
* @return The solution for this game of Sudoku or null if not solvable.
|
||||
*/
|
||||
public int[][] solve(int[][] configuration, int pos)
|
||||
{
|
||||
//Recursion-anchor
|
||||
if(pos == -1) //all fields are done, or startcall was wrong
|
||||
{
|
||||
return configuration;
|
||||
}
|
||||
|
||||
//Recursion
|
||||
while(true) //Always do^^
|
||||
{
|
||||
configuration = getNextExtension(configuration,pos); //getNextExt checks if pos/config is valid!
|
||||
|
||||
if(configuration == null)
|
||||
{
|
||||
return null; //Could not alter act pos any further, not solvable, try alter fields before filled in
|
||||
}
|
||||
|
||||
if(!reject(configuration)) //is generated config ok?
|
||||
{
|
||||
int[][] tboard = solve(configuration,getNextFreeField(configuration)); //Fill in empty fields recursivly.
|
||||
|
||||
if(tboard != null) // was solvable
|
||||
{
|
||||
return tboard;
|
||||
} //else config was not solvable - alter fields filled in before.
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Main-Method
|
||||
*
|
||||
* some start-soduko-defs
|
||||
*
|
||||
* @param args
|
||||
*/
|
||||
public static void main(final String[] args) {
|
||||
@SuppressWarnings("unused")
|
||||
final int[][] emptyField = new int[][] { { 0, 0, 0, 0, 0, 0, 0, 0, 0 },
|
||||
{ 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0, 0, 0, 0, 0 },
|
||||
{ 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0, 0, 0, 0, 0 },
|
||||
{ 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0, 0, 0, 0, 0 },
|
||||
{ 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0, 0, 0, 0, 0 } };
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
final int[][] fullField = new int[][] { { 5, 3, 4, 6, 7, 8, 9, 1, 2 },
|
||||
{ 6, 7, 2, 1, 9, 5, 3, 4, 8 }, { 1, 9, 8, 3, 4, 2, 5, 6, 7 },
|
||||
{ 8, 5, 9, 7, 6, 1, 4, 2, 3 }, { 4, 2, 6, 8, 5, 3, 7, 9, 1 },
|
||||
{ 7, 1, 3, 9, 2, 4, 8, 5, 6 }, { 9, 6, 1, 5, 3, 7, 2, 8, 4 },
|
||||
{ 2, 8, 7, 4, 1, 9, 6, 3, 5 }, { 3, 4, 5, 2, 8, 6, 1, 7, 9 } };
|
||||
|
||||
final int[][] actualField1 = new int[][] {
|
||||
{ 5, 3, 0, 0, 7, 0, 0, 0, 0 }, { 6, 0, 0, 1, 9, 5, 0, 0, 0 },
|
||||
{ 0, 9, 8, 0, 0, 0, 0, 6, 0 }, { 8, 0, 0, 0, 6, 0, 0, 0, 3 },
|
||||
{ 4, 0, 0, 8, 0, 3, 0, 0, 1 }, { 7, 0, 0, 0, 2, 0, 0, 0, 6 },
|
||||
{ 0, 6, 0, 0, 0, 0, 2, 8, 0 }, { 0, 0, 0, 4, 1, 9, 0, 0, 5 },
|
||||
{ 0, 0, 0, 0, 8, 0, 0, 7, 9 } };
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
final int[][] actualField2 = new int[][] {
|
||||
{ 1, 0, 2, 0, 0, 0, 0, 0, 0 }, { 0, 0, 3, 0, 0, 0, 0, 0, 0 },
|
||||
{ 0, 0, 0, 0, 0, 0, 0, 0, 4 }, { 0, 4, 0, 0, 5, 0, 0, 0, 0 },
|
||||
{ 0, 6, 0, 0, 7, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0, 0, 0, 2, 0 },
|
||||
{ 0, 8, 0, 0, 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0, 0, 0, 0, 0 },
|
||||
{ 0, 0, 0, 0, 0, 0, 8, 0, 0 } };
|
||||
|
||||
new Sudoku(actualField1).start();
|
||||
}
|
||||
|
||||
}
|
||||
BIN
exercise/gdi1-exercise-10-2009-WiSe.pdf
Normal file
BIN
exercise/gdi1-exercise-10-2009-WiSe.pdf
Normal file
Binary file not shown.
8
exercise/gdi1-exercise-11-2009-WiSe-solution/.classpath
Normal file
8
exercise/gdi1-exercise-11-2009-WiSe-solution/.classpath
Normal file
@ -0,0 +1,8 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<classpath>
|
||||
<classpathentry kind="src" path="src"/>
|
||||
<classpathentry kind="con" path="org.eclipse.jdt.junit.JUNIT_CONTAINER/4"/>
|
||||
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/>
|
||||
<classpathentry kind="con" path="org.eclipse.jdt.USER_LIBRARY/acm"/>
|
||||
<classpathentry kind="output" path="bin"/>
|
||||
</classpath>
|
||||
17
exercise/gdi1-exercise-11-2009-WiSe-solution/.project
Normal file
17
exercise/gdi1-exercise-11-2009-WiSe-solution/.project
Normal file
@ -0,0 +1,17 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<projectDescription>
|
||||
<name>StockTicker</name>
|
||||
<comment></comment>
|
||||
<projects>
|
||||
</projects>
|
||||
<buildSpec>
|
||||
<buildCommand>
|
||||
<name>org.eclipse.jdt.core.javabuilder</name>
|
||||
<arguments>
|
||||
</arguments>
|
||||
</buildCommand>
|
||||
</buildSpec>
|
||||
<natures>
|
||||
<nature>org.eclipse.jdt.core.javanature</nature>
|
||||
</natures>
|
||||
</projectDescription>
|
||||
@ -0,0 +1,12 @@
|
||||
#Tue Jan 26 10:12:01 CET 2010
|
||||
eclipse.preferences.version=1
|
||||
org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
|
||||
org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.6
|
||||
org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve
|
||||
org.eclipse.jdt.core.compiler.compliance=1.6
|
||||
org.eclipse.jdt.core.compiler.debug.lineNumber=generate
|
||||
org.eclipse.jdt.core.compiler.debug.localVariable=generate
|
||||
org.eclipse.jdt.core.compiler.debug.sourceFile=generate
|
||||
org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
|
||||
org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
|
||||
org.eclipse.jdt.core.compiler.source=1.6
|
||||
File diff suppressed because one or more lines are too long
@ -0,0 +1,261 @@
|
||||
import java.awt.Color;
|
||||
import java.awt.event.ActionEvent;
|
||||
import java.awt.event.ActionListener;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Vector;
|
||||
|
||||
import javax.swing.Timer;
|
||||
|
||||
import acm.graphics.GLabel;
|
||||
import acm.graphics.GLine;
|
||||
import acm.graphics.GPoint;
|
||||
import acm.graphics.GRect;
|
||||
import acm.program.GraphicsProgram;
|
||||
|
||||
public class StockTicker extends GraphicsProgram {
|
||||
|
||||
/**
|
||||
* Solves a warning; not realy needed
|
||||
*/
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
// maximum delay for timers to call updateTicker
|
||||
private static final int MAX_DURATION = 5000;
|
||||
|
||||
// the maximum value to expect
|
||||
private static final int MAX_VALUE = 1000;
|
||||
|
||||
// the number of calls to updateTicker
|
||||
private static final int NR_TIMERS = 3000;
|
||||
|
||||
// the maximum difference of old and new value
|
||||
private static final int MAX_FLUCTUATION = 15;
|
||||
|
||||
// the ticker symbols traded
|
||||
private static final String[] SYMBOLS = new String[] { "SNC", "EKDD",
|
||||
"ATD", "AGN", "HEDM" };
|
||||
|
||||
private Map<String, acm.graphics.GPoint> oldPos;
|
||||
|
||||
// we keep the timers in this collection to start them after init()
|
||||
private Vector<Timer> timers;
|
||||
|
||||
// the appr. time when the timers were startes
|
||||
private long startedAt;
|
||||
|
||||
// the mapping of ticker symbols to colors
|
||||
protected Map<String, Color> colors;
|
||||
|
||||
/**
|
||||
* Create a new StockTicker.
|
||||
*
|
||||
* This will instantiate all timers with their calls to updateTicker and put
|
||||
* them into the timers collection.
|
||||
*/
|
||||
public StockTicker()
|
||||
{
|
||||
timers = new Vector<Timer>(NR_TIMERS);
|
||||
|
||||
final Map<String, Double> oldWorth = new HashMap<String, Double>();
|
||||
for (String symbol : SYMBOLS)
|
||||
{
|
||||
// start somewhere near MAX_VALUE/2
|
||||
oldWorth.put(symbol, MAX_VALUE * Math.random() / 2 + (MAX_VALUE / 4));
|
||||
}
|
||||
for (int i = 0; i < NR_TIMERS; i++)
|
||||
{
|
||||
// instantiate a timer with a random delay within 0..MAX_DURATION
|
||||
Timer timer = new Timer((int) (Math.random() * MAX_DURATION),
|
||||
new ActionListener() {
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
// get a random ticker symbol
|
||||
String symbol = SYMBOLS[(int) (Math.random() * SYMBOLS.length)];
|
||||
|
||||
// calculate the new worth
|
||||
double newWorth = oldWorth.get(symbol)
|
||||
+ MAX_FLUCTUATION * 2
|
||||
* (Math.random() - 0.5);
|
||||
|
||||
// do not increase beyond MAX_VALUE
|
||||
if (newWorth > MAX_VALUE) {
|
||||
newWorth -= MAX_FLUCTUATION;
|
||||
}
|
||||
// save the new value for next time
|
||||
oldWorth.put(symbol, newWorth);
|
||||
|
||||
updateTicker(symbol, newWorth);
|
||||
}
|
||||
});
|
||||
// only fire once
|
||||
timer.setRepeats(false);
|
||||
timers.add(timer);
|
||||
}
|
||||
|
||||
// pre-allocate the color mappings
|
||||
colors = new HashMap<String, Color>();
|
||||
colors.put("SNC", Color.BLUE);
|
||||
colors.put("EKDD", Color.ORANGE);
|
||||
colors.put("ATD", Color.MAGENTA);
|
||||
colors.put("AGN", Color.GRAY);
|
||||
colors.put("HEDM", Color.RED);
|
||||
|
||||
//initialize oldPos HashMap
|
||||
oldPos = new HashMap<String, acm.graphics.GPoint>();
|
||||
}
|
||||
|
||||
/**
|
||||
* Start the timers and set the startTime.
|
||||
*/
|
||||
public void startTicking() {
|
||||
startedAt = System.currentTimeMillis();
|
||||
for (Timer timer : timers) {
|
||||
timer.start();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Correct Height
|
||||
* Delete this when acm is fixed
|
||||
*/
|
||||
@Override
|
||||
public int getHeight()
|
||||
{
|
||||
return super.getHeight() - 30;
|
||||
}
|
||||
|
||||
/**
|
||||
* Draw Interface: - Y-Axis
|
||||
* - X-Lines every 50 pixel
|
||||
* - Value of every line
|
||||
* - White Rect
|
||||
* - Names of TickerSymbols in right Color
|
||||
*/
|
||||
@Override
|
||||
public void init()
|
||||
{
|
||||
{ //draw horizontal line
|
||||
GLine hline = new GLine(0,0,0,getHeight());
|
||||
add(hline); //draw it
|
||||
}
|
||||
|
||||
final int distance = 50; //50px distance between vlines
|
||||
|
||||
{ //draw vertical lines
|
||||
for(int i=0; i <= (getHeight()/distance);i++) //lines
|
||||
{
|
||||
for(int j=0; j < (getWidth()/10);j++) //small lines every 10px with leght 5
|
||||
{
|
||||
//many small lines per "line"
|
||||
GLine vline = new GLine( j*10+1, //+1 to not override the x-achsis
|
||||
getHeight()-i*distance,
|
||||
j*10+5+1,
|
||||
getHeight()-i*distance);
|
||||
vline.setColor(Color.LIGHT_GRAY); //light-gray!!!
|
||||
add(vline); //draw it
|
||||
}
|
||||
|
||||
//once per line
|
||||
GLabel label = new GLabel( String.valueOf((int)(((double)MAX_VALUE/(double)getHeight())*i*distance)),
|
||||
3,
|
||||
getHeight()-i*distance-2);
|
||||
add(label); //draw it
|
||||
}
|
||||
}
|
||||
|
||||
{ //Draw white Rect
|
||||
GRect rect = new GRect(getWidth()-120,0,120,120);
|
||||
rect.setColor(Color.WHITE); //color
|
||||
rect.setFilled(true); //do fill
|
||||
add(rect); //draw it
|
||||
}
|
||||
|
||||
{ //Draw Labels in Rect
|
||||
for(int i=0;i < SYMBOLS.length; i++)
|
||||
{
|
||||
//new label with symbol
|
||||
GLabel label = new GLabel(SYMBOLS[i],getWidth()-100,i*20+20);
|
||||
//set the right color
|
||||
label.setColor(colors.get(SYMBOLS[i])); //load color here
|
||||
//draw it
|
||||
add(label);
|
||||
}
|
||||
}
|
||||
|
||||
// uncomment this line when you have implemented 6.3 - i have
|
||||
startTicking();
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts a X-Value relative to startedAt to an Pixel-Value
|
||||
* relative to MAX_DURATION and Window-Width
|
||||
*
|
||||
* @param x X-Value relative to startedAT
|
||||
* @return Pixel-Value which represents given X-Value
|
||||
*/
|
||||
public double XVal2XPix(double x)
|
||||
{
|
||||
//pixel_per_timepassed
|
||||
return ((double)getWidth()/(double)MAX_DURATION)*x;
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts a Y-Value(worth) to an Pixel-Value
|
||||
* relative to MAX_VALUE and Window-Height
|
||||
*
|
||||
* @param y Y-Value(worth)
|
||||
* @return Pixel-Value which represents given Y-Value
|
||||
*/
|
||||
public double YVal2YPix(double y)
|
||||
{
|
||||
//pixel_per_valuepoint
|
||||
return ((double)getHeight()/(double)MAX_VALUE)*y;
|
||||
}
|
||||
|
||||
/**
|
||||
* Update the graph of a single ticker symbol.
|
||||
*
|
||||
* @param symbol A textual representation of the ticker symbol.
|
||||
* @param worth The new worth of the company.
|
||||
*/
|
||||
public void updateTicker(String symbol, double worth)
|
||||
{
|
||||
//Calculate new Coordinates with time passed since start(x) and worth(y)
|
||||
double x_val = XVal2XPix(System.currentTimeMillis() - startedAt);
|
||||
double y_val = YVal2YPix(worth);
|
||||
|
||||
//Get last Value of given ticker-symbol
|
||||
GPoint oldgp = oldPos.get(symbol);
|
||||
|
||||
//No old value stored at first call for every ticker-symbol
|
||||
if(oldgp == null)
|
||||
{
|
||||
//create new Point with actual values instead
|
||||
oldgp = new GPoint(x_val/*1*/,y_val);//x_val,y_val);
|
||||
}
|
||||
|
||||
//line from oldpos to newpos
|
||||
GLine line = new GLine( oldgp.getX(), //oldpos
|
||||
oldgp.getY(),
|
||||
x_val, //newpos
|
||||
y_val);
|
||||
|
||||
//set the right color for every ticker-symbol
|
||||
line.setColor(colors.get(symbol));
|
||||
|
||||
//paint it
|
||||
add(line);
|
||||
|
||||
//store new pos as oldpos for next call.
|
||||
oldPos.put(symbol, new GPoint(x_val,y_val));
|
||||
}
|
||||
|
||||
/**
|
||||
* Instantiate a new StockTicker and start it.
|
||||
*/
|
||||
public static void main(String[] args) {
|
||||
new StockTicker().start(args);
|
||||
}
|
||||
|
||||
}
|
||||
@ -0,0 +1,206 @@
|
||||
import java.awt.Color;
|
||||
import java.awt.event.ActionEvent;
|
||||
import java.awt.event.ActionListener;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Vector;
|
||||
|
||||
import javax.swing.Timer;
|
||||
|
||||
import acm.graphics.GLabel;
|
||||
import acm.graphics.GLine;
|
||||
import acm.graphics.GPoint;
|
||||
import acm.graphics.GRect;
|
||||
import acm.program.GraphicsProgram;
|
||||
|
||||
public class StockTicker_Solution extends GraphicsProgram {
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
private static final long serialVersionUID = 1866080068453559421L;
|
||||
|
||||
// maximum delay for timers to call updateTicker
|
||||
private static final int MAX_DURATION = 5000;
|
||||
|
||||
// the maximum value to expect
|
||||
private static final int MAX_VALUE = 1000;
|
||||
|
||||
// the number of calls to updateTicker
|
||||
private static final int NR_TIMERS = 3000;
|
||||
|
||||
// the maximum difference of old and new value
|
||||
private static final int MAX_FLUCTUATION = 15;
|
||||
|
||||
// the ticker symbols traded
|
||||
private static final String[] SYMBOLS = new String[] { "SNC", "EKDD",
|
||||
"ATD", "AGN", "HEDM" };
|
||||
|
||||
// we keep the timers in this collection to start them after init()
|
||||
private Vector<Timer> timers;
|
||||
|
||||
// the appr. time when the timers were startes
|
||||
private long startedAt;
|
||||
|
||||
// the mapping of ticker symbols to colors
|
||||
protected Map<String, Color> colors;
|
||||
|
||||
//
|
||||
protected Map<String, GPoint> oldPos;
|
||||
|
||||
/**
|
||||
* Create a new StockTicker.
|
||||
*
|
||||
* This will instantiate all timers with their calls to updateTicker and put
|
||||
* them into the timers collection.
|
||||
*/
|
||||
public StockTicker_Solution() {
|
||||
timers = new Vector<Timer>(NR_TIMERS);
|
||||
|
||||
final Map<String, Double> oldWorth = new HashMap<String, Double>();
|
||||
for (String symbol : SYMBOLS) {
|
||||
// start somewhere near MAX_VALUE/2
|
||||
oldWorth.put(symbol, MAX_VALUE * Math.random() / 2 + (MAX_VALUE / 4));
|
||||
}
|
||||
for (int i = 0; i < NR_TIMERS; i++) {
|
||||
// instantiate a timer with a random delay within 0..MAX_DURATION
|
||||
Timer timer = new Timer((int) (Math.random() * MAX_DURATION),
|
||||
new ActionListener() {
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
// get a random ticker symbol
|
||||
String symbol = SYMBOLS[(int) (Math.random() * SYMBOLS.length)];
|
||||
|
||||
// calculate the new worth
|
||||
double newWorth = oldWorth.get(symbol)
|
||||
+ MAX_FLUCTUATION * 2
|
||||
* (Math.random() - 0.5);
|
||||
|
||||
// do not increase beyond MAX_VALUE
|
||||
if (newWorth > MAX_VALUE) {
|
||||
newWorth -= MAX_FLUCTUATION;
|
||||
}
|
||||
// save the new value for next time
|
||||
oldWorth.put(symbol, newWorth);
|
||||
|
||||
updateTicker(symbol, newWorth);
|
||||
}
|
||||
});
|
||||
// only fire once
|
||||
timer.setRepeats(false);
|
||||
timers.add(timer);
|
||||
}
|
||||
|
||||
// pre-allocate the color mappings
|
||||
colors = new HashMap<String, Color>();
|
||||
colors.put("SNC", Color.BLUE);
|
||||
colors.put("EKDD", Color.ORANGE);
|
||||
colors.put("ATD", Color.MAGENTA);
|
||||
colors.put("AGN", Color.GRAY);
|
||||
colors.put("HEDM", Color.RED);
|
||||
|
||||
oldPos = new HashMap<String, GPoint>();
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Start the timers and set the startTime.
|
||||
*/
|
||||
public void startTicking() {
|
||||
startedAt = System.currentTimeMillis();
|
||||
for (Timer timer : timers) {
|
||||
timer.start();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void init() {
|
||||
// add your call to the methods from 6.2 here
|
||||
GLine line_y = new GLine (0 , 0 , 0 , getHeight() );
|
||||
line_y.setColor(Color.black);
|
||||
add(line_y);
|
||||
|
||||
for (int i = 0; i < (getHeight() / 50) ; i++)
|
||||
{
|
||||
GLabel label = new GLabel (Integer.toString(MAX_VALUE - 100*(10-i)), 5 , getHeight() - (50*i + 5) ) ;
|
||||
add(label);
|
||||
for (int j = 0; j < (getWidth() / 8) ; j++)
|
||||
{
|
||||
GLine line_x = new GLine ( j * 8, getHeight() - (50 * i), j * 8 + 5, getHeight() - (50 * i));
|
||||
line_x.setColor(Color.gray);
|
||||
add(line_x);
|
||||
}
|
||||
}
|
||||
|
||||
GRect names = new GRect(getWidth()- 70,0,70,80);
|
||||
names.setFillColor(Color.white);
|
||||
names.setColor(Color.white);
|
||||
names.setFilled(true);
|
||||
add(names);
|
||||
|
||||
|
||||
for (int i = 0 ; i < SYMBOLS.length ; i++)
|
||||
{
|
||||
GLabel symbols = new GLabel (SYMBOLS[i], getWidth() - 50 , 5 + ((i+1) * 10));
|
||||
symbols.setColor(colors.get(SYMBOLS[i]));
|
||||
add(symbols);
|
||||
}
|
||||
|
||||
// uncomment this line when you have implemented 6.3
|
||||
startTicking();
|
||||
}
|
||||
|
||||
/**
|
||||
* Update the graph of a single ticker symbol.
|
||||
*
|
||||
* @param symbol A textual representation of the ticker symbol.
|
||||
* @param worth The new worth of the company.
|
||||
*/
|
||||
public void updateTicker(String symbol, double worth) {
|
||||
|
||||
|
||||
|
||||
|
||||
if (oldPos.containsKey(symbol)) {
|
||||
|
||||
GLine stock = new GLine (
|
||||
oldPos.get(symbol).getX(), //old x
|
||||
oldPos.get(symbol).getY(), //old y
|
||||
(System.currentTimeMillis() - startedAt) * getWidth() / MAX_DURATION, //new x
|
||||
getHeight () - (worth / 2));//new y
|
||||
stock.setColor(colors.get(symbol));
|
||||
add(stock);
|
||||
|
||||
oldPos.put(symbol, new GPoint (
|
||||
(System.currentTimeMillis() - startedAt) * getWidth()/ MAX_DURATION ,
|
||||
getHeight() - (worth / 2)));
|
||||
} else
|
||||
|
||||
{
|
||||
GLine stock = new GLine(0,
|
||||
getHeight() - (worth / 2),
|
||||
(System.currentTimeMillis() - startedAt) * getWidth() / MAX_DURATION,
|
||||
getHeight() - (worth / 2));
|
||||
stock.setColor(colors.get(symbol));
|
||||
add(stock);
|
||||
|
||||
oldPos.put(symbol, new GPoint (
|
||||
(System.currentTimeMillis() - startedAt) * getWidth() / MAX_DURATION,
|
||||
getHeight()- (worth / 2)));
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Instantiate a new StockTicker and start it.
|
||||
* @param args
|
||||
*/
|
||||
public static void main(String[] args) {
|
||||
new StockTicker_Solution().start(args);
|
||||
}
|
||||
|
||||
}
|
||||
@ -0,0 +1,228 @@
|
||||
import java.util.Arrays;
|
||||
|
||||
import junit.framework.Assert;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
|
||||
public class SudokuTest {
|
||||
|
||||
/**
|
||||
* Test cases for the solver. Public, because you can also use them to use
|
||||
* them for game initialization!
|
||||
*/
|
||||
public final static int[][] testCase1 = new int[][] {
|
||||
{ 5, 3, 0, 0, 7, 0, 0, 0, 0 }, { 6, 0, 0, 1, 9, 5, 0, 0, 0 },
|
||||
{ 0, 9, 8, 0, 0, 0, 0, 6, 0 }, { 8, 0, 0, 0, 6, 0, 0, 0, 3 },
|
||||
{ 4, 0, 0, 8, 0, 3, 0, 0, 1 }, { 7, 0, 0, 0, 2, 0, 0, 0, 6 },
|
||||
{ 0, 6, 0, 0, 0, 0, 2, 8, 0 }, { 0, 0, 0, 4, 1, 9, 0, 0, 5 },
|
||||
{ 0, 0, 0, 0, 8, 0, 0, 7, 9 } };
|
||||
|
||||
public final static int[][] testCase1Result = new int[][] {
|
||||
{ 5, 3, 4, 6, 7, 8, 9, 1, 2 }, { 6, 7, 2, 1, 9, 5, 3, 4, 8 },
|
||||
{ 1, 9, 8, 3, 4, 2, 5, 6, 7 }, { 8, 5, 9, 7, 6, 1, 4, 2, 3 },
|
||||
{ 4, 2, 6, 8, 5, 3, 7, 9, 1 }, { 7, 1, 3, 9, 2, 4, 8, 5, 6 },
|
||||
{ 9, 6, 1, 5, 3, 7, 2, 8, 4 }, { 2, 8, 7, 4, 1, 9, 6, 3, 5 },
|
||||
{ 3, 4, 5, 2, 8, 6, 1, 7, 9 } };
|
||||
|
||||
public final static int[][] testCase2 = new int[][] {
|
||||
{ 1, 0, 2, 0, 0, 0, 0, 0, 0 }, { 0, 0, 3, 0, 0, 0, 0, 0, 0 },
|
||||
{ 0, 0, 0, 0, 0, 0, 0, 0, 4 }, { 0, 4, 0, 0, 5, 0, 0, 0, 0 },
|
||||
{ 0, 6, 0, 0, 7, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0, 0, 0, 2, 0 },
|
||||
{ 0, 8, 0, 0, 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0, 0, 0, 0, 0 },
|
||||
{ 0, 0, 0, 0, 0, 0, 8, 0, 0 } };
|
||||
|
||||
public final static int[][] testCase2Result = new int[][] {
|
||||
{ 1, 5, 2, 3, 4, 6, 7, 8, 9 }, { 4, 7, 3, 1, 8, 9, 2, 5, 6 },
|
||||
{ 6, 9, 8, 5, 2, 7, 1, 3, 4 }, { 2, 4, 1, 6, 5, 3, 9, 7, 8 },
|
||||
{ 5, 6, 9, 2, 7, 8, 3, 4, 1 }, { 8, 3, 7, 4, 9, 1, 6, 2, 5 },
|
||||
{ 3, 8, 4, 9, 1, 2, 5, 6, 7 }, { 7, 1, 6, 8, 3, 5, 4, 9, 2 },
|
||||
{ 9, 2, 5, 7, 6, 4, 8, 1, 3 } };
|
||||
|
||||
final int[][] testField3 = new int[][] { { 0, 0, 0, 0, 0, 0, 0, 0, 0 },
|
||||
{ 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0, 0, 1, 2, 0, 4, 5, 6, 7 },
|
||||
{ 0, 0, 2, 0, 0, 0, 4, 0, 0 }, { 0, 0, 0, 0, 0, 0, 0, 0, 0 },
|
||||
{ 0, 0, 4, 0, 0, 0, 2, 0, 0 }, { 0, 0, 5, 4, 0, 2, 1, 0, 0 },
|
||||
{ 0, 0, 6, 0, 0, 0, 0, 0, 0 }, { 0, 0, 7, 0, 0, 0, 0, 0, 0 } };
|
||||
|
||||
//From template
|
||||
public final int[][] fullField = new int[][] { { 5, 3, 4, 6, 7, 8, 9, 1, 2 },
|
||||
{ 6, 7, 2, 1, 9, 5, 3, 4, 8 }, { 1, 9, 8, 3, 4, 2, 5, 6, 7 },
|
||||
{ 8, 5, 9, 7, 6, 1, 4, 2, 3 }, { 4, 2, 6, 8, 5, 3, 7, 9, 1 },
|
||||
{ 7, 1, 3, 9, 2, 4, 8, 5, 6 }, { 9, 6, 1, 5, 3, 7, 2, 8, 4 },
|
||||
{ 2, 8, 7, 4, 1, 9, 6, 3, 5 }, { 3, 4, 5, 2, 8, 6, 1, 7, 9 } };
|
||||
|
||||
final int[][] sudoku17_1 = new int[][] {
|
||||
{0, 0, 0, 0, 0, 0, 0, 1, 0}, { 0, 6, 0, 3, 0, 0, 0, 0, 0},
|
||||
{9, 0, 0, 0, 0, 0, 0, 7, 0}, { 1, 0, 0, 0, 0, 0, 0, 0, 0},
|
||||
{0, 0, 0, 4, 0, 0, 6, 0, 0}, { 0, 0, 6, 0, 0, 0, 5, 0, 3},
|
||||
{0, 0, 0, 0, 9, 0, 0, 0, 0}, { 0, 2, 0, 0, 0, 0, 4, 0, 0},
|
||||
{0, 0, 8, 0, 1, 7, 0, 0, 0}
|
||||
};
|
||||
|
||||
/**
|
||||
* The test instance.
|
||||
*/
|
||||
private Sudoku sudoku;
|
||||
|
||||
/**
|
||||
* Sets up the test environment.
|
||||
*/
|
||||
@Before
|
||||
public void setUp() {
|
||||
sudoku = new Sudoku();
|
||||
}
|
||||
|
||||
/**
|
||||
* Timing check
|
||||
*/
|
||||
/*
|
||||
//This one is quite nasty
|
||||
@Test
|
||||
public void testTimingField17()
|
||||
{
|
||||
Assert.assertNull(sudoku.solve(sudoku17_1));
|
||||
}*/
|
||||
|
||||
/**
|
||||
* Timing check2
|
||||
*/
|
||||
@Test
|
||||
public void testTimingField3()
|
||||
{
|
||||
Assert.assertNull(sudoku.solve(testField3));
|
||||
}
|
||||
|
||||
/**
|
||||
* Test if predefined fullfield is ok.
|
||||
*/
|
||||
@Test
|
||||
public void testFullField()
|
||||
{
|
||||
//Question was raised - so i do the test
|
||||
Assert.assertFalse(sudoku.reject(fullField));
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests the {@link Sudoku#reject(int[][])} method.
|
||||
*/
|
||||
@Test
|
||||
public void testReject() {
|
||||
int[][] config = new int[9][9];
|
||||
|
||||
// Empty field is always valid!
|
||||
Assert.assertFalse("reject false negative: rejected empty field!",
|
||||
sudoku.reject(config));
|
||||
|
||||
// Check rows
|
||||
config = new int[9][9];
|
||||
config[5][1] = 9;
|
||||
config[5][7] = 9;
|
||||
Assert.assertTrue("reject false negative: row check failed!", sudoku
|
||||
.reject(config));
|
||||
|
||||
config[5][7] = 6;
|
||||
Assert.assertFalse("reject false positive: row check failed!", sudoku
|
||||
.reject(config));
|
||||
|
||||
// Check columns
|
||||
config = new int[9][9];
|
||||
config[5][1] = 9;
|
||||
config[8][1] = 9;
|
||||
Assert.assertTrue("reject false negative: column check failed!", sudoku
|
||||
.reject(config));
|
||||
|
||||
config[8][1] = 3;
|
||||
Assert.assertFalse("reject false positive: column check failed!",
|
||||
sudoku.reject(config));
|
||||
|
||||
// Check 3x3 fields
|
||||
config = new int[9][9];
|
||||
config[0][0] = 7;
|
||||
config[2][2] = 7;
|
||||
Assert.assertTrue("reject false negative: 3x3 field check failed!",
|
||||
sudoku.reject(config));
|
||||
|
||||
config[2][2] = 4;
|
||||
Assert.assertFalse("reject false positive: 3x3 field check failed!",
|
||||
sudoku.reject(config));
|
||||
|
||||
config[2][3] = 7; // out of top-left field
|
||||
Assert.assertFalse("reject false positive: 3x3 field check failed!",
|
||||
sudoku.reject(config));
|
||||
|
||||
// Check with real-world example
|
||||
Assert.assertFalse("reject false positive: real world example", sudoku
|
||||
.reject(testCase1Result));
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests the {@link Sudoku#getNextFreeField(int[][])} method.
|
||||
*/
|
||||
@Test
|
||||
public void testNextFreeField() {
|
||||
int[][] config = new int[9][9];
|
||||
|
||||
// Full & empty field
|
||||
Assert.assertEquals(
|
||||
"getNextFreeField failed: should return 0 if field is empty!",
|
||||
0, sudoku.getNextFreeField(config));
|
||||
Assert.assertEquals(
|
||||
"getNextFreeField failed: should return -1 if field is full!",
|
||||
-1, sudoku.getNextFreeField(testCase1Result));
|
||||
|
||||
// Normal fields
|
||||
config[0][0] = 5;
|
||||
Assert.assertEquals("getNextFreeField failed!", 1, sudoku
|
||||
.getNextFreeField(config));
|
||||
config[0][1] = 5;
|
||||
Assert.assertEquals("getNextFreeField failed!", 2, sudoku
|
||||
.getNextFreeField(config));
|
||||
config[0] = new int[] { 1, 2, 3, 4, 5, 6, 7, 8, 9 };
|
||||
Assert.assertEquals("getNextFreeField failed for second row!", 9,
|
||||
sudoku.getNextFreeField(config));
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests the {@link Sudoku#getNextExtension(int[][], int)} method.
|
||||
*/
|
||||
@Test
|
||||
public void testNextExtension() {
|
||||
int[][] config = new int[9][9];
|
||||
config[4][6] = 8; // Field 42
|
||||
|
||||
int[][] newConfig = sudoku.getNextExtension(config, 42);
|
||||
Assert.assertEquals(
|
||||
"getNextExtension failed: did not increment (correct) field!",
|
||||
9, newConfig[4][6]);
|
||||
Assert.assertNotSame(
|
||||
"getNextExtension failed: did not create a new array!", config,
|
||||
newConfig);
|
||||
Assert.assertNotSame(
|
||||
"getNextExtension failed: did not clone sub-arrays!",
|
||||
config[0], newConfig[0]);
|
||||
|
||||
newConfig = sudoku.getNextExtension(newConfig, 42);
|
||||
Assert
|
||||
.assertEquals(
|
||||
"getNextExtension failed: did not return null if field already is 9",
|
||||
null, newConfig);
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests the {@link Sudoku#solve(int[][])} method.
|
||||
*/
|
||||
@Test
|
||||
public void testSolve() {
|
||||
// Test cases
|
||||
Assert.assertTrue("solve failed for test case 1", Arrays.deepEquals(
|
||||
sudoku.solve(testCase1), testCase1Result));
|
||||
|
||||
Assert.assertTrue("solve failed for test case 2", Arrays.deepEquals(
|
||||
sudoku.solve(testCase2), testCase2Result));
|
||||
|
||||
// Finished field should not be modified
|
||||
Assert.assertTrue("solve failed for finished field", Arrays.deepEquals(
|
||||
sudoku.solve(testCase1Result), testCase1Result));
|
||||
}
|
||||
}
|
||||
BIN
exercise/gdi1-exercise-11-2009-WiSe.pdf
Normal file
BIN
exercise/gdi1-exercise-11-2009-WiSe.pdf
Normal file
Binary file not shown.
7
exercise/gdi1-exercise-12-2009-WiSe-solution/.classpath
Normal file
7
exercise/gdi1-exercise-12-2009-WiSe-solution/.classpath
Normal file
@ -0,0 +1,7 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<classpath>
|
||||
<classpathentry kind="src" path="src"/>
|
||||
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/>
|
||||
<classpathentry kind="con" path="org.eclipse.jdt.USER_LIBRARY/acm"/>
|
||||
<classpathentry kind="output" path="bin"/>
|
||||
</classpath>
|
||||
19
exercise/gdi1-exercise-12-2009-WiSe-solution/.project
Normal file
19
exercise/gdi1-exercise-12-2009-WiSe-solution/.project
Normal file
@ -0,0 +1,19 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<projectDescription>
|
||||
<name>TrainSimulation</name>
|
||||
<comment></comment>
|
||||
<projects>
|
||||
</projects>
|
||||
<buildSpec>
|
||||
<buildCommand>
|
||||
<name>org.eclipse.jdt.core.javabuilder</name>
|
||||
<arguments>
|
||||
</arguments>
|
||||
</buildCommand>
|
||||
</buildSpec>
|
||||
<natures>
|
||||
<nature>org.eclipse.jem.workbench.JavaEMFNature</nature>
|
||||
<nature>org.eclipse.jdt.core.javanature</nature>
|
||||
<nature>org.eclipse.jem.beaninfo.BeanInfoNature</nature>
|
||||
</natures>
|
||||
</projectDescription>
|
||||
@ -0,0 +1,72 @@
|
||||
package TrainSimulation;
|
||||
|
||||
/**
|
||||
* Class to store Int or Char in one variable.
|
||||
*/
|
||||
public class IntChar {
|
||||
|
||||
private int i = -1; //intvar
|
||||
private char c = 0; //charvar
|
||||
/**
|
||||
* Char or int switch
|
||||
*
|
||||
* false = char
|
||||
* true = int
|
||||
*/
|
||||
private boolean ci = false; //false = char; true = int
|
||||
|
||||
public int getInt() {
|
||||
return i;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets ci to true.
|
||||
*/
|
||||
public void setInt(int i) {
|
||||
this.i = i;
|
||||
setToInt();
|
||||
}
|
||||
public char getChar() {
|
||||
return c;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets ci to false.
|
||||
*/
|
||||
public void setChar(char c) {
|
||||
this.c = c;
|
||||
setToChar();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if ci is set to false!
|
||||
*/
|
||||
public boolean isChar()
|
||||
{
|
||||
return !ci;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if ci is true
|
||||
* @return
|
||||
*/
|
||||
public boolean isInt()
|
||||
{
|
||||
return ci;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets ci to false
|
||||
*/
|
||||
public void setToChar() {
|
||||
this.ci = false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets ci to true
|
||||
*/
|
||||
public void setToInt() {
|
||||
this.ci = true;
|
||||
}
|
||||
|
||||
}
|
||||
@ -0,0 +1,122 @@
|
||||
package TrainSimulation;
|
||||
|
||||
import exceptions.InvalidAreaException;
|
||||
import exceptions.InvalidCoordinatesException;
|
||||
import acm.program.DialogProgram;
|
||||
|
||||
public class TrainDialog extends DialogProgram{
|
||||
|
||||
/**
|
||||
* serialVersionUID
|
||||
*/
|
||||
private static final long serialVersionUID = -2064310234134016114L;
|
||||
|
||||
/**
|
||||
* Instance of the Train-Simulation
|
||||
*/
|
||||
private TrainSimulation sim;
|
||||
|
||||
private static String terminate = new String("Program will terminate now");
|
||||
|
||||
/**
|
||||
* Loads a map and interacts with the user
|
||||
*/
|
||||
public void run() {
|
||||
//Example-Array
|
||||
//Attention: This is columnwise
|
||||
char arr[][] = { { '0', '0', '#', '0' }, { '0', '~', '0', '^' }, { '0', '~', '0', '#' },
|
||||
{ '0', '^', '0', '0' }, { '0', '0', '#', '~' } };
|
||||
|
||||
//initiate new TrainSimulation object with the given area
|
||||
//catch correct exceptions
|
||||
try
|
||||
{
|
||||
sim = new TrainSimulation(arr);
|
||||
}catch(InvalidAreaException e)
|
||||
{
|
||||
//show-errortype and terminate
|
||||
println(e.getMessage());
|
||||
println(terminate);
|
||||
return;
|
||||
}
|
||||
|
||||
//print Area as String to help user to decide which coordinate is correct
|
||||
println(sim.toString());
|
||||
|
||||
//ask the user for x- and y-coordinates, calculate reachable areas and show the result
|
||||
while(true)
|
||||
{
|
||||
//ask for x-Coordinate -> -1 = exit
|
||||
int x = this.readInt("X-Coordinate of a City");
|
||||
if(x == -1)
|
||||
{
|
||||
println(terminate);
|
||||
return;
|
||||
}
|
||||
|
||||
//ask for y-Coordinate -> -1 = exit
|
||||
int y = this.readInt("Y-Coordinate of a City");
|
||||
if(y == -1)
|
||||
{
|
||||
println(terminate);
|
||||
return;
|
||||
}
|
||||
|
||||
boolean exit = true;
|
||||
|
||||
try
|
||||
{
|
||||
//Test Costs -> Not needed
|
||||
/*int[][] costs = sim.analyzeCosts(x, y);
|
||||
|
||||
String result = "";
|
||||
|
||||
if(costs.length > 0)
|
||||
{
|
||||
for(int i=0; i<costs[0].length; i++) //count lines
|
||||
{
|
||||
for(int j=0;j<costs.length;j++) //count within lines
|
||||
{
|
||||
result += Integer.toString(costs[j][i])+" ";
|
||||
}
|
||||
|
||||
result += "\n";
|
||||
}
|
||||
}
|
||||
|
||||
println(result);*/
|
||||
|
||||
//calculate reachable areas
|
||||
sim.reachable(x, y);
|
||||
|
||||
} catch (InvalidCoordinatesException e)
|
||||
{
|
||||
//Invalid Coordinates, ask again
|
||||
println("Coordinates are invalid, try again");
|
||||
exit = false;
|
||||
}
|
||||
|
||||
//print area -> overview for the user if coordinates were wrong,
|
||||
//else show result of reachable-calculation
|
||||
println(sim.toString());
|
||||
|
||||
if(exit)
|
||||
{
|
||||
//exit if calculation was successfull
|
||||
println(terminate);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Main method. This is automatically called by the environment when your
|
||||
* program starts.
|
||||
*
|
||||
* @param args
|
||||
*/
|
||||
public static void main(String[] args) {
|
||||
new TrainDialog().start();
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,400 @@
|
||||
package TrainSimulation;
|
||||
|
||||
import exceptions.InvalidAreaException;
|
||||
import exceptions.InvalidCoordinatesException;
|
||||
import exceptions.NoObstacleException;
|
||||
import exceptions.NoPlainsException;
|
||||
import exceptions.NotACityException;
|
||||
import exceptions.NotEnoughCitiesException;
|
||||
|
||||
public class TrainSimulation {
|
||||
|
||||
//Constants for the Map
|
||||
public final char map_city = '#';
|
||||
public final char map_plain = '0';
|
||||
public final char map_swamp = '~';
|
||||
public final char map_mountain = '^';
|
||||
public final char map_train = '=';
|
||||
|
||||
/**
|
||||
* Variable to store Map-Char-Representation
|
||||
*/
|
||||
private char[][] area;
|
||||
|
||||
/**
|
||||
* Constructor sets Map-Char-Representation and throws Exceptions
|
||||
* if its not valid.
|
||||
*
|
||||
* @param area Map-Char-Representation
|
||||
* @throws InvalidAreaException
|
||||
*/
|
||||
public TrainSimulation(char[][] area) throws InvalidAreaException
|
||||
{
|
||||
setArea(area); //use setter-method to check given area
|
||||
}
|
||||
|
||||
/**
|
||||
* Flood-Algorithm to replace all Positions which are reachable
|
||||
* from pos (x/y) with map_train.
|
||||
*
|
||||
* A Position is reachable when (x/y) == map_plain || (x/y) == map_city.
|
||||
*
|
||||
* Cities are not replaced.
|
||||
*
|
||||
* Modifies this.area
|
||||
*
|
||||
* @param x X-Coordinate
|
||||
* @param y >-Coordinate
|
||||
*/
|
||||
private void floodArrayWithTrain(int x, int y)
|
||||
{
|
||||
//check if position is valid
|
||||
if(areCoordinatesValid(x, y))
|
||||
{
|
||||
//skip/anchor -> area not reachable
|
||||
if(area[x][y] != map_plain && area[x][y] != map_city)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
//replace only map_plain not map_city
|
||||
if(area[x][y] == map_plain)
|
||||
{
|
||||
area[x][y] = map_train;
|
||||
}
|
||||
|
||||
//flood-algorithm-recursive call
|
||||
floodArrayWithTrain(x,y+1);
|
||||
floodArrayWithTrain(x,y-1);
|
||||
floodArrayWithTrain(x+1,y);
|
||||
floodArrayWithTrain(x-1,y);
|
||||
}
|
||||
}
|
||||
|
||||
private boolean areCoordinatesValid(IntChar[][] array, int x, int y)
|
||||
{
|
||||
if( x < 0 ||
|
||||
y < 0 ||
|
||||
array.length <= x ||
|
||||
array[x].length <= y)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private boolean areCoordinatesValid(char[][] array, int x, int y)
|
||||
{
|
||||
if( x < 0 ||
|
||||
y < 0 ||
|
||||
array.length <= x ||
|
||||
array[x].length <= y)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private boolean areCoordinatesValid(int x, int y)
|
||||
{
|
||||
return areCoordinatesValid(area, x, y);
|
||||
}
|
||||
|
||||
/**
|
||||
* Replaces all map_plain in this.area
|
||||
* if field is reachable
|
||||
*
|
||||
* Coordinate have to point to a city.
|
||||
*
|
||||
* @param x X-Coordinate
|
||||
* @param y Y-Coordinate
|
||||
* @throws InvalidCoordinatesException
|
||||
*/
|
||||
public void reachable(int x, int y) throws InvalidCoordinatesException
|
||||
{
|
||||
//check if coordinates are valid
|
||||
if(!areCoordinatesValid(x, y))
|
||||
{
|
||||
throw new InvalidCoordinatesException("Error: Coordinates are not valid");
|
||||
}
|
||||
|
||||
//check if position is a city
|
||||
if(area[x][y] != map_city)
|
||||
{
|
||||
throw new NotACityException();
|
||||
}
|
||||
|
||||
//flood-algorithm
|
||||
floodArrayWithTrain(x,y);
|
||||
}
|
||||
|
||||
/**
|
||||
* Floods given are with Costs-parameters; only replaces
|
||||
* reachable fields.
|
||||
*
|
||||
* @param array Array with chars/costs-values
|
||||
* @param x X-Coordinate
|
||||
* @param y Y-Coordinate
|
||||
* @param value Current costs for the field, if its reachable
|
||||
* @return new Array
|
||||
*/
|
||||
private IntChar[][] floodArrayWithCosts(IntChar[][] array, int x, int y, int value)
|
||||
{
|
||||
//check Coordinates are valid
|
||||
if(areCoordinatesValid(array,x, y)) //recursion-anchor
|
||||
{
|
||||
//is Coordinate an integer and value of the field is > current costs
|
||||
// -> replace with current costs
|
||||
if(array[x][y].isInt() && array[x][y].getInt() > value)
|
||||
{
|
||||
array[x][y].setInt(value);
|
||||
} else
|
||||
{
|
||||
//is Coordinate a char and value of the field is map_plain or map_city
|
||||
// -> set current costs @ current field
|
||||
if( array[x][y].isChar() &&
|
||||
(array[x][y].getChar() == map_plain ||
|
||||
array[x][y].getChar() == map_city)
|
||||
)
|
||||
{
|
||||
array[x][y].setInt(value);
|
||||
} else
|
||||
{
|
||||
return array; //recursion-anchor
|
||||
}
|
||||
}
|
||||
|
||||
//Flood-Algorithm
|
||||
array = floodArrayWithCosts(array,x,y+1,value+1);
|
||||
array = floodArrayWithCosts(array,x,y-1,value+1);
|
||||
array = floodArrayWithCosts(array,x+1,y,value+1);
|
||||
array = floodArrayWithCosts(array,x-1,y,value+1);
|
||||
}
|
||||
|
||||
return array;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a integer-field(2-dim) with "costs" of the
|
||||
* all reachable fields from pos (x/y)
|
||||
*
|
||||
* @param x X-Coordinate
|
||||
* @param y Y-Coordinate
|
||||
* @return integer-field(2-dim)
|
||||
* @throws InvalidCoordinatesException
|
||||
*/
|
||||
public int[][] analyzeCosts(int x, int y) throws InvalidCoordinatesException
|
||||
{
|
||||
//Check if array is ok
|
||||
if(!isAreaSizeOk())
|
||||
{
|
||||
//should not happen, but to be sure
|
||||
throw new InvalidCoordinatesException("Error: Area-Array was not ok");
|
||||
}
|
||||
|
||||
//Check Coordinates
|
||||
if(!areCoordinatesValid(x, y))
|
||||
{
|
||||
throw new InvalidCoordinatesException("Error: Coordinates are not valid");
|
||||
}
|
||||
|
||||
//check if position is a city
|
||||
if(area[x][y] != map_city)
|
||||
{
|
||||
throw new NotACityException();
|
||||
}
|
||||
|
||||
//New array to operate on
|
||||
IntChar[][] tarea = new IntChar[area.length][area[0].length];
|
||||
for(int i=0; i<area.length;i++)
|
||||
{
|
||||
for(int j=0; j<area[i].length;j++)
|
||||
{
|
||||
tarea[i][j] = new IntChar(); //create element
|
||||
tarea[i][j].setChar(area[i][j]); //set to value from this.area
|
||||
}
|
||||
}
|
||||
|
||||
//flood Area with Costs-Values
|
||||
tarea = floodArrayWithCosts(tarea,x,y,0);
|
||||
|
||||
//size is ok! -> created object locally
|
||||
int[][] result = new int[tarea.length][tarea[0].length];
|
||||
|
||||
//Convert IntChar[][] -> int[][]
|
||||
for(int i=0;i<tarea.length;i++)
|
||||
{
|
||||
for(int j=0;j<tarea[i].length;j++)
|
||||
{
|
||||
if(tarea[i][j].isInt()) //Calculated Costs in this field?
|
||||
{
|
||||
//set calculated Costs to result-array
|
||||
result[i][j] = tarea[i][j].getInt();
|
||||
} else
|
||||
{
|
||||
//if value is still a char -> set to -1
|
||||
result[i][j] = -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//return int[][]
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return String Returns a String-Representation of the current this.area property.
|
||||
*/
|
||||
public String toString()
|
||||
{
|
||||
//result variable
|
||||
String result = "";
|
||||
|
||||
//check if area has a length
|
||||
if(area.length > 0)
|
||||
{
|
||||
for(int i=0; i<area[0].length; i++) //count lines
|
||||
{
|
||||
for(int j=0;j<area.length;j++) //count within lines(columns)
|
||||
{
|
||||
//add char to result
|
||||
result += area[j][i];
|
||||
}
|
||||
|
||||
//end of line -> add return
|
||||
result += "\n";
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if element is at least count-times present in this.area. else false
|
||||
*
|
||||
* @param element Element to look for
|
||||
* @param count How many times should the Element appear before returning true
|
||||
* @return All required Elements found ? true : false
|
||||
*/
|
||||
private boolean hasElement(char element, int count)
|
||||
{
|
||||
for(int i=0; i<area.length;i++)
|
||||
{
|
||||
for(int j=0; j<area[i].length;j++)
|
||||
{
|
||||
if(area[i][j] == element) //pos = element?
|
||||
{
|
||||
count--; //count down
|
||||
|
||||
if(count <= 0) //no more elements required
|
||||
{
|
||||
return true; //all found -> true
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false; //not all found -> false
|
||||
}
|
||||
|
||||
/**
|
||||
* @return returns true if this.area has two or more cities else false
|
||||
*/
|
||||
private boolean hasTwoCities()
|
||||
{
|
||||
return hasElement(map_city,2);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return returns true if this.area has one or more plains else false
|
||||
*/
|
||||
private boolean hasPlainsElement()
|
||||
{
|
||||
return hasElement(map_plain,1);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return returns true if this.area has one or more terrainObstacle else false
|
||||
*
|
||||
* TerrainObstacle = map_mountain, map_swamp
|
||||
*/
|
||||
private boolean hasTerrainObstacle()
|
||||
{
|
||||
if(hasElement(map_swamp,1))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
return hasElement(map_mountain,1);
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks size of the area, returns true if its ok, else false
|
||||
*/
|
||||
private boolean isAreaSizeOk()
|
||||
{
|
||||
if(area.length == 0)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
int length = area[0].length;
|
||||
|
||||
for(int i=1; i<area.length;i++)
|
||||
{
|
||||
if(area[i].length != length)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if this.area is valid
|
||||
*
|
||||
* @return
|
||||
* @throws InvalidAreaException
|
||||
*/
|
||||
private boolean isAreaValid() throws InvalidAreaException
|
||||
{
|
||||
if(!isAreaSizeOk())
|
||||
{
|
||||
throw new InvalidAreaException("Error: Area-Size(lines/cloumns) was not ok");
|
||||
}
|
||||
|
||||
//Two-Cities
|
||||
if(!hasTwoCities())
|
||||
{
|
||||
throw new NotEnoughCitiesException();
|
||||
}
|
||||
|
||||
//One-Plain
|
||||
if(!hasPlainsElement())
|
||||
{
|
||||
throw new NoPlainsException();
|
||||
}
|
||||
|
||||
//One-TerrainObstacle
|
||||
if(!hasTerrainObstacle())
|
||||
{
|
||||
throw new NoObstacleException();
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public char[][] getArea() {
|
||||
return area;
|
||||
}
|
||||
public void setArea(char[][] area) throws InvalidAreaException {
|
||||
|
||||
this.area = area;
|
||||
|
||||
isAreaValid();
|
||||
}
|
||||
|
||||
}
|
||||
@ -0,0 +1,15 @@
|
||||
package exceptions;
|
||||
|
||||
public class InvalidAreaException extends Exception{
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
private static final long serialVersionUID = 4135649595011391220L;
|
||||
|
||||
public InvalidAreaException(String s)
|
||||
{
|
||||
super(s);
|
||||
}
|
||||
|
||||
}
|
||||
@ -0,0 +1,15 @@
|
||||
package exceptions;
|
||||
|
||||
public class InvalidCoordinatesException extends Exception{
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
private static final long serialVersionUID = 2231800557216094558L;
|
||||
|
||||
public InvalidCoordinatesException(String s)
|
||||
{
|
||||
super(s);
|
||||
}
|
||||
|
||||
}
|
||||
@ -0,0 +1,15 @@
|
||||
package exceptions;
|
||||
|
||||
public class NoObstacleException extends InvalidAreaException{
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
private static final long serialVersionUID = 325818858775514458L;
|
||||
|
||||
public NoObstacleException()
|
||||
{
|
||||
super("Error: No Obstacle on current Map");
|
||||
}
|
||||
|
||||
}
|
||||
@ -0,0 +1,15 @@
|
||||
package exceptions;
|
||||
|
||||
public class NoPlainsException extends InvalidAreaException{
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
private static final long serialVersionUID = -3307803035507617881L;
|
||||
|
||||
|
||||
public NoPlainsException()
|
||||
{
|
||||
super("Error: No Plain on current Map");
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,13 @@
|
||||
package exceptions;
|
||||
|
||||
public class NotACityException extends InvalidCoordinatesException{
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
private static final long serialVersionUID = 6574511033482201479L;
|
||||
|
||||
public NotACityException() {
|
||||
super("Error: Coordinates are not a City");
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,14 @@
|
||||
package exceptions;
|
||||
|
||||
public class NotEnoughCitiesException extends InvalidAreaException{
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
private static final long serialVersionUID = 8352668740319857030L;
|
||||
|
||||
public NotEnoughCitiesException()
|
||||
{
|
||||
super("Error: Not enough Cities on current Map");
|
||||
}
|
||||
}
|
||||
BIN
exercise/gdi1-exercise-12-2009-WiSe.pdf
Normal file
BIN
exercise/gdi1-exercise-12-2009-WiSe.pdf
Normal file
Binary file not shown.
@ -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;
|
||||
}
|
||||
}
|
||||
@ -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.
|
||||
}
|
||||
}
|
||||
@ -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.
|
||||
}
|
||||
}
|
||||
@ -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.
|
||||
}
|
||||
}
|
||||
@ -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);
|
||||
}
|
||||
|
||||
/* ======================================================================== */
|
||||
|
||||
}
|
||||
|
||||
/* ============================================================================ */
|
||||
@ -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);
|
||||
}
|
||||
|
||||
/* ======================================================================== */
|
||||
|
||||
}
|
||||
|
||||
/* ============================================================================ */
|
||||
@ -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;
|
||||
}
|
||||
|
||||
/* ======================================================================== */
|
||||
|
||||
}
|
||||
|
||||
/* ============================================================================ */
|
||||
@ -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;
|
||||
}
|
||||
}
|
||||
@ -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.
|
||||
}
|
||||
}
|
||||
@ -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.
|
||||
}
|
||||
}
|
||||
@ -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.
|
||||
}
|
||||
}
|
||||
@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
@ -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());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -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));
|
||||
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@ -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()));
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@ -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());
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@ -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());
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user