diff --git a/input.txt b/input.txt new file mode 100644 index 0000000..ea7d8af --- /dev/null +++ b/input.txt @@ -0,0 +1,2 @@ +IT Crowd +SoftWriters \ No newline at end of file diff --git a/model.png b/model.png new file mode 100644 index 0000000..07f2485 Binary files /dev/null and b/model.png differ diff --git a/src/Application.java b/src/Application.java new file mode 100644 index 0000000..b9cedd4 --- /dev/null +++ b/src/Application.java @@ -0,0 +1,37 @@ +import parser.VoiceParser; + +import java.io.FileNotFoundException; +import java.util.List; + +/** + * Shows how to combine input and parser module into one application. + * Easily replacable with other parts of system. + */ +public class Application { + + /** + * Run example application for translation + * Supply one argument with the file name to translate + * @param args + */ + public static void main(String[] args) { + + // Get lines to translate + List inputFileLines; + try { + inputFileLines = InputReader.getLinesFromFile(args[0]); + } catch (FileNotFoundException e) { + System.out.println("Could not find that file!"); + return; + } + + VoiceParser parser = new VoiceParser(); + + // Parse/Translate every line + for(String line : inputFileLines) { + String output = parser.parseDirectionsForPhrase(line); + System.out.println(line + ": " + output); + } + } + +} diff --git a/src/InputReader.java b/src/InputReader.java new file mode 100644 index 0000000..326c420 --- /dev/null +++ b/src/InputReader.java @@ -0,0 +1,32 @@ +import java.io.File; +import java.io.FileNotFoundException; +import java.util.ArrayList; +import java.util.List; +import java.util.Scanner; + +/** + * General utility module that allows for reading input from a file + */ +public class InputReader { + + /** + * Read in lines from a file name + * @param fileName + * @return + * @throws FileNotFoundException + */ + public static List getLinesFromFile(String fileName) throws FileNotFoundException { + File file = new File(fileName); + Scanner scanner = new Scanner(file); + + List fileLines = new ArrayList<>(); + + while(scanner.hasNext()) { + fileLines.add(scanner.nextLine()); + } + + scanner.close(); + return fileLines; + } + +} diff --git a/src/parser/VoiceParser.java b/src/parser/VoiceParser.java new file mode 100644 index 0000000..5775d50 --- /dev/null +++ b/src/parser/VoiceParser.java @@ -0,0 +1,47 @@ +package parser; + +import parser.components.Keyboard; + +/** + * A module that can be used to translate phrases into DVR commands + */ +public class VoiceParser { + + /** + * Keyboard to allow for translating text + */ + private Keyboard keyboard; + + public VoiceParser() { + this.keyboard = new Keyboard(); + } + + /** + * Parse directions for a single character + * @param c + * @return + */ + private String getDirectionsForCharacter(char c) { + return keyboard.processCharacter(c); + } + + /** + * Parses directions for an entire line + * @param phrase + * @return + */ + public String parseDirectionsForPhrase(String phrase) { + String outputCommand = ""; + + // Get directions for each character in the phrase + for(char c : phrase.toCharArray()) + outputCommand += getDirectionsForCharacter(c) + ","; + + outputCommand = outputCommand.substring(0, outputCommand.length() - 1); + + // Reset cursor for future phrases + keyboard.resetCursor(); + return outputCommand; + } + +} diff --git a/src/parser/components/Keyboard.java b/src/parser/components/Keyboard.java new file mode 100644 index 0000000..aa34fd3 --- /dev/null +++ b/src/parser/components/Keyboard.java @@ -0,0 +1,149 @@ +package parser.components; + +/** + * Manages keyboard related information. Gives directions on how to + * move between characters via DVR commands. + * + * The keyboard is a 2D Array of characters with a cursor pointed + * at the current character. + * + */ +public class Keyboard { + + private int cursorRow, cursorCol; + private char[][] keyboard; + + public Keyboard() { + initializeKeyboard(); + resetCursor(); + } + + /** + * Initializes keyboard's values + * + */ + private void initializeKeyboard() { + this.keyboard = new char[][] { + {'A', 'B', 'C', 'D', 'E', 'F'}, + {'G', 'H', 'I', 'J', 'K', 'L'}, + {'M', 'N', 'O', 'P', 'Q', 'R'}, + {'S', 'T', 'U', 'V', 'W', 'X'}, + {'Y', 'Z', '1', '2', '3', '4'}, + {'5', '6', '7', '8', '9', '0'}, + }; + } + + /** + * Moves cursor for keyboard + * @param rowOffset + * @param colOffset + */ + private void moveCursor(int rowOffset, int colOffset) { + this.cursorRow += rowOffset; + this.cursorCol += colOffset; + } + + /** + * Used to place 0-9 into our keyboard after Z + * + * To search for a digit, we modify the digit's ASCII value to appear + * after the Z in our keyboard. + * + * @param c + * @return + */ + private char mapDigitToKeyboard(char c) { + if (c == '0') + // '0' Needs to be placed after '9' + c += 10; + + return (char) (c + 42); + } + + /** + * Convert the character to an ASCII format searchable by our keyboard + * @param c + * @return + */ + private char mapCommandToKeyboard(char c) { + return (Character.isDigit(c) ? mapDigitToKeyboard(c) : Character.toUpperCase(c)); + } + + /** + * Gets current character at the cursor. + * + * If it's a digit, map it to our ascii format above to allow + * for searching. + * + * @return + */ + private char getCurrentCharacter() { + char c = this.keyboard[cursorRow][cursorCol]; + if(Character.isDigit(c)) + return mapDigitToKeyboard(c); + return c; + } + + /** + * Sets cursor to row = 0 col = 0 + */ + public void resetCursor() { + this.cursorRow = 0; + this.cursorCol = 0; + } + + /** + * Verify the command is A-Z or 0-9 and in our keyboard + * @param command + * @return + */ + private boolean isValidCharacter(char command) { + return (65 <= command && command <= 101); + } + + /** + * Gets directions for a single character + * + * To search for a letter, we compare the ASCII value of the letter + * with the ASCII values in our keyboard to mathematically determine + * the path. + * + * @param command + * @return + */ + public String processCharacter(char command) { + if(command == ' ') + return "S"; + + command = mapCommandToKeyboard(command); + if(!isValidCharacter(command)) { + System.out.println("Invalid command received. Exiting..."); + System.exit(0); + } + + // Determine left/right + int cursorXPosition = (getCurrentCharacter() - 65) % 6; + int commandXPosition = (command - 65) % 6; + int colDistance = commandXPosition - cursorXPosition; + + String colCharacter = (colDistance > 0) ? "R" : "L"; + moveCursor(0, colDistance); + + // Determine up/down + int rowDistance = (command - getCurrentCharacter()) / 6; + String rowCharacter = (rowDistance > 0) ? "D" : "U"; + moveCursor(rowDistance, 0); + + // Output directions string + String outputCommand = ""; + for (int i = 0; i < Math.abs(rowDistance); i++) + outputCommand += rowCharacter + ","; + for (int i = 0; i < Math.abs(colDistance); i++) + outputCommand += colCharacter + ","; + + outputCommand += "#"; + return outputCommand; + } + + +}