### ### ### ### ### ### ### ### # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # ### ### ### ### ### ### ### # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # ### ### ### ### ### ### ###
In this project we want to implement a clock that displays the time in LCD-format.
We will build up the project in small steps, one function at a time.
Let us number the seven segments from 0 to 6 as follows:
555 4 0 4 0 4 0 666 3 1 3 1 3 1 222
I have made a table which tells us which segment to turn on for each digit:
val digits = Array(Array(true, true, true, true, true, true, false), // 0 Array(true, true, false, false, false, false, false), // 1 Array(true, false, true, true, false, true, true), // 2 Array(true, true, true, false, false, true, true), // 3 Array(true, true, false, false, true, false, true), // 4 Array(false, true, true, false, true, true, true), // 5 Array(false, true, true, true, true, true, true), // 6 Array(true, true, false, false, false, true, false), // 7 Array(true, true, true, true, true, true, true), // 8 Array(true, true, true, false, true, true, true), // 9 Array(false, false, false, false, false, false, false)) // BlankFor example, digits(5) is an array of 7 Boolean's, telling us to switch on segments 1, 2, 4, 5, 6. Note the entry with index 10, which simply displays a blank.
Your first task is to write a function
def lcdDigit(digit: Char, k: Int, c: Char): StringThis function takes a character digit and returns a string that represents this character in LCD-format. k is the size of the LCD-display, c is the character to be used for the LCD-display.
When digit is not a digit, the function should simply return a blank string. You can use the following code to convert digit to an index for the digits table:
val d = if ('0' <= digit && digit <= '9') digit - '0' else 10
Here are some examples for the output:
scala> println(lcdDigit('0', 2, '*')) ** * * * * * * * * ** scala> println(lcdDigit('4', 3, '&')) & & & & & & &&& & & & scala> println(lcdDigit('9', 5, 'M')) MMMMM M M M M M M M M M M MMMMM M M M M M MMMMM scala> println(lcdDigit('a', 3, 'M'))Note that the character 'a' is simply displayed as a blank.
Note that the function does not print the digit itself. It only returns a string. Since this string goes over several lines, it needs to contain the "new-line" character, which you can enter as "\n". There should be no new-line character at the beginning and at the end of the output string.
Next we need a function that combines two digits:
def combine(left: String, sep: String, right: String): String
This function needs to split both left and right into pieces at the new-line characters. It then adds the pieces together, and finally generates a new string.
You can use s.split("\n") to split a string into pieces, and a.mkstring("\n") to compose an array of strings into a single long string.
Here are some examples:
scala> combine("This\nis\nfun", "&", "Hello\nCS109\nStudents!") res7: String = This&Hello is&CS109 fun&Students! scala> combine(lcdDigit('0', 3, '*'), " # ", lcdDigit('9', 3, '@')) res8: String = " *** # @@@ * * # @ @ * * # @ @ * * # @ @ # @@@ * * # @ * * # @ * * # @ *** # @@@ "
Next, we need a function that takes a string and changes it to LCD-format. To save you some typing, here it is:
def lcd(s: String, k: Int, c: Char, sep: String): String = { var result = lcdDigit(s(0), k, c) for (i <- 1 until s.length) result = combine(result, sep, lcdDigit(s(i), k, c)) result }
Test the function and check that it works well:
scala> println(lcd("12:45:99", 4, '@', ":")) : @@@@ : : : @@@@ : : @@@@ : @@@@ @: @: :@ @:@ : :@ @:@ @ @: @: :@ @:@ : :@ @:@ @ @: @: :@ @:@ : :@ @:@ @ @: @: :@ @:@ : :@ @:@ @ : @@@@ : : @@@@ : @@@@ : : @@@@ : @@@@ @:@ : : @: @: : @: @ @:@ : : @: @: : @: @ @:@ : : @: @: : @: @ @:@ : : @: @: : @: @ : @@@@ : : : @@@@ : : @@@@ : @@@@
If you got the lcd-function working, there is nothing to stop us from implementing our clock. Since it's mostly special functions for obtaining and formatting the current time, I wrote it for you:
def clearScreen() { println("\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n") } def clock() { val form = new java.text.SimpleDateFormat("HH mm ss") var current = form.format(java.util.Calendar.getInstance().getTime) clearScreen() println(lcd(current, 4, '#', " ")) while (true) { Thread.sleep(100) val ntime = form.format(java.util.Calendar.getInstance().getTime) if (ntime != current) { current = ntime clearScreen() println(lcd(current, 4, '#', " ")) } } }
Note that it runs forever. You can stop it by typing Ctrl+C.