diff --git a/src/net/torvald/terrarum/QNDTreeNode.kt b/src/net/torvald/terrarum/QNDTreeNode.kt index ea81c5b3b..c6958a7f5 100644 --- a/src/net/torvald/terrarum/QNDTreeNode.kt +++ b/src/net/torvald/terrarum/QNDTreeNode.kt @@ -1,6 +1,7 @@ package net.torvald.terrarum -import java.util.ArrayList +import java.util.* +import kotlin.collections.ArrayList class QNDTreeNode(var data: T? = null, var parent: QNDTreeNode? = null) { var children = ArrayList>() @@ -18,11 +19,54 @@ class QNDTreeNode(var data: T? = null, var parent: QNDTreeNode? = null) { action(node, depth) } + /** + * (QNDTreeNode, Int) is Node-depth pair, starting from zero. + */ fun traversePreorder(action: (QNDTreeNode, Int) -> Unit) { this.traverse1(this, action) } + /** + * (QNDTreeNode, Int) is Node-depth pair, starting from zero. + */ fun traversePostorder(action: (QNDTreeNode, Int) -> Unit) { this.traverse2(this, action) } + + /** + * (QNDTreeNode, Int) is Node-depth pair, starting from zero. + */ + fun traverseLevelorder(action: (QNDTreeNode, Int) -> Unit) { + val q = ArrayList, Int>>() // node, depth + q.add(this to 0) + while (q.isNotEmpty()) { + val node = q.removeAt(0) + action(node.first, node.second) + node.first.children.forEach { + q.add(it to node.second + 1) + } + } + } + + /** + * Retrieves data in the node in a specific depth (level). + * Probably only useful for level = 1 + */ + fun getLevelData(level: Int): List { + val list = ArrayList() + + traversePreorder { node, i -> + if (i == level) { + list.add(node.data) + } + } + + return list + } + + override fun toString() = data.toString() + + fun print() { + TODO() + } } \ No newline at end of file diff --git a/src/net/torvald/terrarum/Yaml.kt b/src/net/torvald/terrarum/Yaml.kt index fb41686eb..7cfbe4966 100644 --- a/src/net/torvald/terrarum/Yaml.kt +++ b/src/net/torvald/terrarum/Yaml.kt @@ -44,6 +44,7 @@ import java.util.* * - All lines are indented with one space * - All entries are preceded by '- ' (dash and a space) * - All propery are separated by ' : ' (space colon space) + * - A line that does not start with '- ' are simply ignored, so you can freely make empty lines and/or comments. * * Any deviation to the above rule will cause a parse failure, because it's simple and dumb as that. * @@ -55,39 +56,41 @@ inline class Yaml(val text: String) { val SEPARATOR = Regex(" : ") } - fun parse(): QNDTreeNode { var currentIndentLevel = -1 val root = QNDTreeNode() var currentNode = root val nodesStack = Stack>() + val validLineStartRe = Regex(""" *\- """) nodesStack.push(currentNode) text.split('\n') .forEach { - val indentLevel = it.countSpaces() - val it = it.trimIndent() - if (it.startsWith("- ")) { - val nodeName = it.drop(2) + if (validLineStartRe.containsMatchIn(it)) { // take partial match; do the task if the text's line is valid + val indentLevel = it.countSpaces() + val it = it.trimIndent() + if (it.startsWith("- ")) { // just double check if indent-trimmed line looks valid + val nodeName = it.drop(2) - if (indentLevel == currentIndentLevel) { - val sibling = QNDTreeNode(nodeName, currentNode.parent) - currentNode.parent!!.children.add(sibling) - currentNode = sibling - } - else if (indentLevel > currentIndentLevel) { - val childNode = QNDTreeNode(nodeName, currentNode) - currentNode.children.add(childNode) - nodesStack.push(currentNode) - currentNode = childNode - currentIndentLevel = indentLevel - } - else { - repeat(currentIndentLevel - indentLevel) { currentNode = nodesStack.pop() } - currentIndentLevel = indentLevel - val sibling = QNDTreeNode(nodeName, currentNode.parent) - currentNode.parent!!.children.add(sibling) - currentNode = sibling + if (indentLevel == currentIndentLevel) { + val sibling = QNDTreeNode(nodeName, currentNode.parent) + currentNode.parent!!.children.add(sibling) + currentNode = sibling + } + else if (indentLevel > currentIndentLevel) { + val childNode = QNDTreeNode(nodeName, currentNode) + currentNode.children.add(childNode) + nodesStack.push(currentNode) + currentNode = childNode + currentIndentLevel = indentLevel + } + else { + repeat(currentIndentLevel - indentLevel) { currentNode = nodesStack.pop() } + currentIndentLevel = indentLevel + val sibling = QNDTreeNode(nodeName, currentNode.parent) + currentNode.parent!!.children.add(sibling) + currentNode = sibling + } } } } diff --git a/src/net/torvald/terrarum/tests/QNDTreeTest.kt b/src/net/torvald/terrarum/tests/QNDTreeTest.kt new file mode 100644 index 000000000..ba4bc722d --- /dev/null +++ b/src/net/torvald/terrarum/tests/QNDTreeTest.kt @@ -0,0 +1,78 @@ +package net.torvald.terrarum.tests + +import net.torvald.terrarum.Yaml +import net.torvald.terrarum.modulebasegame.ui.UITitleRemoConYaml + +/** + * Created by minjaesong on 2018-12-08. + */ +class QNDTreeTest { + + val treeStr = """ +- File + - New : Ctrl-N + - Open : Ctrl-O + - Open Recent + - yaml_example.yaml + - Yaml.kt + - Close : Ctrl-W + - Settings + - Line Separators + - CRLF + - CR + - LF +- Edit + - Undo : Ctrl-Z + - Redo : Shift-Ctrl-Z + - Cut : Ctrl-X + - Copy : Ctrl-C + - Paste : Ctrl-V + - Find + - Find : Ctrl-F + - Replace : Shift-Ctrl-F + - Convert Indents + - To Spaces + - Set Project Indentation + - To Tabs +- Refactor + - Refactor This + - Rename : Shift-Ctrl-R + - Extract + - Variable + - Property + - Function +""" + + operator fun invoke() { + val treeYaml = Yaml(treeStr) + val tree = treeYaml.parse() + + println("\nTest traversePreorder()\n") + tree.traversePreorder { qndTreeNode, i -> + print("-".repeat(i)) + print(" ") + println("$qndTreeNode <- ${qndTreeNode.parent}") + } + + println("\nTest traversePostOrder()\n") + tree.traversePostorder { qndTreeNode, i -> + print("-".repeat(i)) + print(" ") + println("$qndTreeNode <- ${qndTreeNode.parent}") + } + + println("\nTest traverseLevelOrder()\n") + tree.traverseLevelorder { qndTreeNode, i -> + print("-".repeat(i)) + print(" ") + println("$qndTreeNode <- ${qndTreeNode.parent}") + } + println("\nLevel 1 nodes:\n") + println(tree.getLevelData(1)) + } + +} + +fun main(args: Array) { + QNDTreeTest().invoke() +} \ No newline at end of file diff --git a/src/net/torvald/terrarum/ui/UIItemNSMenus.kt b/src/net/torvald/terrarum/ui/UIItemNSMenus.kt index d49ab6d09..70daaed14 100644 --- a/src/net/torvald/terrarum/ui/UIItemNSMenus.kt +++ b/src/net/torvald/terrarum/ui/UIItemNSMenus.kt @@ -11,9 +11,10 @@ import net.torvald.terrarum.Yaml override var posX: Int, override var posY: Int, override var width: Int, - val tree: Yaml + val treeRepresentation: Yaml ) : UIItem(parent) { - override val height: Int - get() = TODO("not implemented") + val tree = treeRepresentation.parse() + + override val height = -1 }*/ \ No newline at end of file