Commit b059cffa authored by Markus Klinik's avatar Markus Klinik
Browse files

rule a02_use_stringbuilder

parent 2d66e309
......@@ -12,6 +12,7 @@ import Util;
set[Message] allAssignment02Rules(M3 model)
= a02_all_io_in_view(model)
+ a02_use_stringbuilder(model)
;
// There should be one class that is not the main class and not the Gallows
......@@ -50,4 +51,25 @@ set[Message] a02_all_io_in_view(M3 model)
}
return result;
}
// The gallows class should use StringBuilder
set[Message] a02_use_stringbuilder(M3 model)
{
try
{
loc stringBuilder = |java+class:///java/lang/StringBuilder|;
loc gallows = findClass(model, "Gallows");
set[loc] gallowsMethods = methods(model, gallows);
set[loc] gallowsDependencies = model.typeDependency[gallowsMethods] + model.typeDependency[gallows];
if( !(stringBuilder in gallowsDependencies) )
{
return { error("Gallows should use StringBuilder", gallows) };
}
}
catch error:
{
return { error };
}
return {};
}
\ No newline at end of file
<?xml version="1.0" encoding="UTF-8"?>
<classpath>
<classpathentry kind="src" path="src"/>
<classpathentry kind="src" path="test"/>
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER">
<attributes>
<attribute name="module" value="true"/>
</attributes>
</classpathentry>
<classpathentry kind="con" path="org.eclipse.jdt.junit.JUNIT_CONTAINER/4"/>
<classpathentry kind="output" path="bin"/>
</classpath>
<?xml version="1.0" encoding="UTF-8"?>
<projectDescription>
<name>assignment02-no-use-stringbuilder</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>
<?xml version="1.0" encoding="UTF-8"?>
<!-- You may freely edit this file. See commented blocks below for -->
<!-- some examples of how to customize the build. -->
<!-- (If you delete it and reopen the project it will be recreated.) -->
<!-- By default, only the Clean and Build commands use this build script. -->
<!-- Commands such as Run, Debug, and Test only use this build script if -->
<!-- the Compile on Save feature is turned off for the project. -->
<!-- You can turn off the Compile on Save (or Deploy on Save) setting -->
<!-- in the project's Project Properties dialog box.-->
<project name="assignment02-hangman-example-solution" default="default" basedir=".">
<description>Builds, tests, and runs the project assignment02-hangman-example-solution.</description>
<import file="nbproject/build-impl.xml"/>
<!--
There exist several targets which are by default empty and which can be
used for execution of your tasks. These targets are usually executed
before and after some main targets. They are:
-pre-init: called before initialization of project properties
-post-init: called after initialization of project properties
-pre-compile: called before javac compilation
-post-compile: called after javac compilation
-pre-compile-single: called before javac compilation of single file
-post-compile-single: called after javac compilation of single file
-pre-compile-test: called before javac compilation of JUnit tests
-post-compile-test: called after javac compilation of JUnit tests
-pre-compile-test-single: called before javac compilation of single JUnit test
-post-compile-test-single: called after javac compilation of single JUunit test
-pre-jar: called before JAR building
-post-jar: called after JAR building
-post-clean: called after cleaning build products
(Targets beginning with '-' are not intended to be called on their own.)
Example of inserting an obfuscator after compilation could look like this:
<target name="-post-compile">
<obfuscate>
<fileset dir="${build.classes.dir}"/>
</obfuscate>
</target>
For list of available properties check the imported
nbproject/build-impl.xml file.
Another way to customize the build is by overriding existing main targets.
The targets of interest are:
-init-macrodef-javac: defines macro for javac compilation
-init-macrodef-junit: defines macro for junit execution
-init-macrodef-debug: defines macro for class debugging
-init-macrodef-java: defines macro for class execution
-do-jar: JAR building
run: execution of project
-javadoc-build: Javadoc generation
test-report: JUnit report generation
An example of overriding the target for project execution could look like this:
<target name="run" depends="assignment02-hangman-example-solution-impl.jar">
<exec dir="bin" executable="launcher.exe">
<arg file="${dist.jar}"/>
</exec>
</target>
Notice that the overridden target depends on the jar target and not only on
the compile target as the regular run target does. Again, for a list of available
properties which you can use, check the target you are overriding in the
nbproject/build-impl.xml file.
-->
</project>
Manifest-Version: 1.0
X-COMMENT: Main-Class will be added automatically by build
build.xml.data.CRC32=0571f480
build.xml.script.CRC32=743a03be
build.xml.stylesheet.CRC32=f85dc8f2@1.90.1.48
# This file is used by a NetBeans-based IDE to track changes in generated files such as build-impl.xml.
# Do not edit this file. You may delete it but then the IDE will never regenerate such files for you.
nbproject/build-impl.xml.data.CRC32=0571f480
nbproject/build-impl.xml.script.CRC32=19f2b775
nbproject/build-impl.xml.stylesheet.CRC32=3a2fa800@1.90.1.48
javac.debug=false
user.properties.file=/home/mkl/.netbeans/10.0/build.properties
<?xml version="1.0" encoding="UTF-8"?>
<project-private xmlns="http://www.netbeans.org/ns/project-private/1">
<editor-bookmarks xmlns="http://www.netbeans.org/ns/editor-bookmarks/2" lastBookmarkId="0"/>
<open-files xmlns="http://www.netbeans.org/ns/projectui-open-files/2">
<group>
<file>file:/home/mkl/radboud/teaching/object-orientation/NWI-IPI005-Object-Orientatie/OO-opgaven-18-19/assignment02-hangman/assignment02-hangman-example-solution/test/assignment02/HangmanTest.java</file>
</group>
</open-files>
</project-private>
#Fri Oct 04 10:58:39 CEST 2019
run.classpath=${javac.classpath}\:${build.classes.dir}
javac.test.classpath=${javac.classpath}\:${build.classes.dir}\:\:${libs.junit_4.classpath}\:${libs.hamcrest.classpath}
excludes=
javac.processorpath=${javac.classpath}
dist.javadoc.dir=${dist.dir}/javadoc
test.src.dir=${file.reference.example-solution-test}
run.modulepath=${javac.modulepath}
annotation.processing.enabled=true
build.sysclasspath=ignore
debug.modulepath=${run.modulepath}
file.reference.example-solution-test=test
javac.compilerargs=
javadoc.noindex=false
javadoc.private=false
javadoc.author=false
main.class=assignment02.Main
junit.selected.version=3
source.encoding=UTF-8
auxiliary.org-netbeans-modules-projectimport-eclipse-core.key=src\=src;src\=test;output\=bin;
javac.source=11
includes=**
javadoc.use=true
jar.compress=false
javadoc.nonavbar=false
annotation.processing.enabled.in.editor=false
javadoc.notree=false
annotation.processing.processors.list=
javac.deprecation=false
auxiliary.org-netbeans-modules-projectimport-eclipse-core.project=.
jlink.launcher=true
javadoc.additionalparam=
auxiliary.org-netbeans-modules-projectimport-eclipse-core.timestamp=1570177705244
jlink.launcher.name=assignment02-hangman-example-solution
build.generated.sources.dir=${build.dir}/generated-sources
javadoc.splitindex=true
javac.processormodulepath=
run.jvmargs=
jlink.additionalmodules=
javadoc.encoding=${source.encoding}
javac.classpath=
mkdist.disabled=true
run.test.modulepath=${javac.test.modulepath}
build.classes.excludes=**/*.java,**/*.form
dist.jlink.dir=${dist.dir}/jlink
dist.jar=${dist.dir}/assignment02-hangman-example-solution.jar
build.classes.dir=${build.dir}/classes
debug.test.modulepath=${run.test.modulepath}
build.test.classes.dir=${build.dir}/test/classes
javadoc.windowtitle=
file.reference.example-solution-src=src
build.test.results.dir=${build.dir}/test/results
annotation.processing.processor.options=
dist.dir=dist
build.dir=nbbuild
dist.archive.excludes=
annotation.processing.source.output=${build.generated.sources.dir}/ap-source-output
build.generated.dir=${build.dir}/generated
javadoc.version=false
auxiliary.org-netbeans-modules-projectimport-eclipse-core.workspace=/home/mkl/eclipse-workspaces/java-assignments
javac.test.modulepath=${javac.modulepath}
debug.test.classpath=${run.test.classpath}
javac.external.vm=true
javac.target=11
platform.active=default_platform
manifest.file=manifest.mf
javadoc.html5=false
javac.test.processorpath=${javac.test.classpath}
meta.inf.dir=${src.dir}/META-INF
run.test.classpath=${javac.test.classpath}\:${build.test.classes.dir}
dist.jlink.output=${dist.jlink.dir}/assignment02-hangman-example-solution
annotation.processing.run.all.processors=true
javac.modulepath=
src.dir=${file.reference.example-solution-src}
jlink.additionalparam=
debug.classpath=${run.classpath}
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://www.netbeans.org/ns/project/1">
<type>org.netbeans.modules.java.j2seproject</type>
<configuration>
<data xmlns="http://www.netbeans.org/ns/j2se-project/3">
<name>assignment02-hangman-example-solution</name>
<source-roots>
<root id="src.dir" name="src"/>
</source-roots>
<test-roots>
<root id="test.src.dir" name="test"/>
</test-roots>
</data>
</configuration>
</project>
package assignment02;
import java.util.LinkedList;
import java.util.List;
public class Gallows {
private String wordToGuess;
private List<Character> guessedLetters;
private int guessesLeft;
public int getGuessesLeft() {
return guessesLeft;
}
public String getGuessedLetters() {
String result = "";
for( char l : guessedLetters )
{
result = result + l;
}
return result;
}
public String getWordToGuess() {
return wordToGuess;
}
// When you input your own word.
public Gallows(String s) {
guessedLetters = new LinkedList<>();
this.wordToGuess = s;
guessesLeft = 10;
}
// When you want an automated word.
public Gallows() {
guessedLetters = new LinkedList<>();
WordReader file = new WordReader("words.txt");
this.wordToGuess = file.getWord();
guessesLeft = 10;
}
public boolean isWordGuessed() {
for (int i = 0; i < wordToGuess.length(); ++i) {
if (!guessedLetters.contains(wordToGuess.charAt(i))) {
return false;
}
}
return true;
}
public void guessLetter(char c) {
guessesLeft--;
guessedLetters.add(c);
}
public String getWordSoFar() {
String result = "";
for (int i = 0; i < wordToGuess.length(); ++i) {
char currentLetter = wordToGuess.charAt(i);
if (guessedLetters.contains(currentLetter)) {
result = result + currentLetter;
} else {
result = result + ",";
}
}
return result;
}
}
\ No newline at end of file
package assignment02;
import java.util.*;
public class GallowsUI {
private static Scanner scanner;
private static Gallows gallows;
public GallowsUI() {
scanner = new Scanner(System.in);
welcomeMessage();
chooseWord();
playGallows();
showResult();
}
// Greetings to user
public void welcomeMessage() {
System.out.println("Welcome to Hangman!");
System.out.println("");
System.out.println("");
}
// Choose for an own word or an automated word.
public void chooseWord() {
System.out.println("Please enter a word or press <Enter> to randomly pick one");
System.out.print("> ");
String path = scanner.nextLine();
if (path.isEmpty()) {
gallows = new Gallows();
} else {
gallows = new Gallows(path);
}
}
// Tells if the letter is in the word;
// shows guessed letters; how many attempts left;
// shows where the right guessed letters are in the word.
public void playGallows() {
while (gallows.getGuessesLeft() > 0 && !gallows.isWordGuessed()) {
System.out.println("");
System.out.println("Guessed letters: [" + gallows.getGuessedLetters() + "]");
System.out.println(gallows.getWordSoFar());
System.out.println("Remaining guesses: " + gallows.getGuessesLeft());
System.out.println("Enter a letter you want to guess: ");
System.out.print("> ");
String input = scanner.next();
if (input.length() == 1) {
gallows.guessLetter(input.charAt(0));
} else {
System.out.println("Please enter one letter.");
}
}
}
// Checks if you guessed the word within 10 attempts and shows the word that
// had to be guessed.
public void showResult() {
if (gallows.isWordGuessed()) {
System.out.println("Good job, you got it!!!");
System.out.println("The word was: " + gallows.getWordToGuess());
} else {
System.out.println("Too bad, you did not get the word");
System.out.println("The word was: " + gallows.getWordToGuess());
}
}
}
package assignment02;
public class Main {
public static void main(String[] args) {
new GallowsUI();
}
}
package assignment02;
import java.util.Scanner;
import java.util.Random;
import java.io.FileReader;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
/**
* Reads words from a given file and selects one of those words pseudo randomly
*
* @author Pieter Koopman
*/
public class WordReader {
private final List<String> words;
private final Random rand;
/**
* Saves words from the file in an arrayList IOexceptions while reading the
* file are caught and printed
*
* @param fileName: fileName of the file with the words
*/
public WordReader(String fileName) {
this.rand = new Random();
this.words = new ArrayList<>();
String pattern = "\\S+"; // consisting of at least one non-space
try {
FileReader fileReader = new FileReader(fileName);
Scanner file = new Scanner(fileReader);
while (file.hasNext(pattern)) {
words.add(file.next(pattern).toLowerCase());
}
file.close();
} catch (IOException ioe) {
System.out.println("Error while reading file with name " + fileName
+ ": " + ioe.getMessage());
}
}
/**
* @return the number of read words.
*/
public int getNumberOfWords() {
return words.size();
}
/**
* Gives a pseudo random word from the list of words or returns the empty
* word if the list is empty
*
* @return a pseudo random word
*/
public String getWord() {
if (!words.isEmpty()) {
return words.get(rand.nextInt(getNumberOfWords()));
} else {
return "";
}
}
}
package assignment02;
import static org.junit.Assert.*;
import org.junit.Test;
public class HangmanTest {
@Test
public void test() {
HangmanTester tester = new HangmanTester();
tester.newGallows("baobab");
assertEquals("......", tester.getWordSoFar());
tester.guessLetter('a');
assertEquals(".a..a.", tester.getWordSoFar());
assertEquals("a", tester.getGuessedLetters());
assertFalse(tester.isWordGuessed());
tester.guessLetter('b');
assertEquals("ba.bab", tester.getWordSoFar());
assertEquals("ab", tester.getGuessedLetters());
assertFalse(tester.isWordGuessed());
tester.guessLetter('z');
assertEquals("ba.bab", tester.getWordSoFar());
assertEquals("abz", tester.getGuessedLetters());
assertFalse(tester.isWordGuessed());
tester.guessLetter('o');
assertEquals("baobab", tester.getWordSoFar());
assertEquals("abzo", tester.getGuessedLetters());
assert(tester.isWordGuessed());
}
}
package assignment02;
public class HangmanTester {
Gallows gallows;
public void newGallows(String word) {
gallows = new Gallows(word);
}
public String getWordSoFar() {
return gallows.getWordSoFar();
}
public void guessLetter(char c) {
gallows.guessLetter(c);
}
public String getGuessedLetters() {
return gallows.getGuessedLetters();
}
public boolean isWordGuessed() {
return gallows.isWordGuessed();
}
}
computer interface extend artificial intelligence science bachelor master method class attribute teachingassistant lecture tutorial practical object factory pattern debugger testing abstract collections comparable trees binarytrees quadtrees concurrency multithreading hashing linkedlist array arraylist deadlock synchronize thread input output compile program javadoc project constructor recursion java
......@@ -22,4 +22,10 @@ test bool mainHasIO()
{
errors = allAssignment02Rules(loadTestProject("assignment02-main-has-io"));
return "All I/O should happen in the view class" in { message | error(message, _) <- errors };
}
test bool noUseStringBuilder()
{
errors = allAssignment02Rules(loadTestProject("assignment02-no-use-stringbuilder"));
return "Gallows should use StringBuilder" in { message | error(message, _) <- errors };
}
\ No newline at end of file
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment