Commit 0cce2a25 authored by jcechace's avatar jcechace
Browse files

Initial version of hw03 assignment

parents
# Created by .ignore support plugin (hsz.mobi)
### Java template
*.class
# Mobile Tools for Java (J2ME)
.mtj.tmp/
# Package Files #
*.jar
*.war
*.ear
# virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml
hs_err_pid*
### JetBrains template
# Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio
*.iml
## Directory-based project format:
.idea/
# if you remove the above rule, at least ignore the following:
# User-specific stuff:
# .idea/workspace.xml
# .idea/tasks.xml
# .idea/dictionaries
# Sensitive or high-churn files:
# .idea/dataSources.ids
# .idea/dataSources.xml
# .idea/sqlDataSources.xml
# .idea/dynamic.xml
# .idea/uiDesigner.xml
# Gradle:
# .idea/gradle.xml
# .idea/libraries
# Mongo Explorer plugin:
# .idea/mongoSettings.xml
## File-based project format:
*.ipr
*.iws
## Plugin-specific files:
# IntelliJ
/out/
# mpeltonen/sbt-idea plugin
.idea_modules/
# JIRA plugin
atlassian-ide-plugin.xml
# Crashlytics plugin (for Android Studio and IntelliJ)
com_crashlytics_export_strings.xml
crashlytics.properties
crashlytics-build.properties
### Maven template
target/
pom.xml.tag
pom.xml.releaseBackup
pom.xml.versionsBackup
pom.xml.next
release.properties
dependency-reduced-pom.xml
buildNumber.properties
.mvn/timing.properties
### Eclipse template
*.pydevproject
.metadata
.gradle
bin/
tmp/
*.tmp
*.bak
*.swp
*~.nib
local.properties
.settings/
.loadpath
# Eclipse Core
.project
# External tool builders
.externalToolBuilders/
# Locally stored "Eclipse launch configurations"
*.launch
# CDT-specific
.cproject
# JDT-specific (Eclipse Java Development Tools)
.classpath
# Java annotation processor (APT)
.factorypath
# PDT-specific
.buildpath
# sbteclipse plugin
.target
# TeXlipse plugin
.texlipse
### NetBeans template
nbproject/private/
build/
nbbuild/
dist/
nbdist/
nbactions.xml
nb-configuration.xml
.nb-gradle/
# Vim
*.un~
# VSCode
.vscode/
.classpath
# OS X .DS_Store
.DS_Store
*.txt
image: maven:3-jdk-10
build:
script:
- mvn clean install -B -Dcheckstyle.fail=true
tags:
- shared-fi
Homework assignment no. 2, RPG Character generator
====================================
**Publication date:** 15th May
**Submission deadline:** 5th June 23:59
General information
-------------------
In this assignment you will create a command line application which can be used to generate an HTML overview of a character for a very simple tabletop RPG system.
First and foremost... "What the hell is a tabletop RPG?"
It's a role playing game in which participants describe their character and act as them through speech, writings, and drawings. The entire game is usually driven by another participant (called Dungeon Master -- DM) who acts as a storyteller.
You might have encountered the most famous tabletop RPG game system [DnD (Dungeons & Dragons)](https://dnd.wizards.com/basics-play) or its czech counterpart [Dračí Doupě (DrD)](https://www.drdplus.info/)
### Game System Information
Our game system will be much simpler than those of DnD or DrD. We wont have any classes or leveling system. There will be just characters with predetermined set of skills and attributes.
Each character has some basic information such as name**name**, age, occupation.
In addition character also has a set of attributes (e.g. strength, dexterity) and set of skills (e.g. leadership, intimidation) -- each of these has a rank between 0 and 5.
As you play the game you will encounter many situations. Lets say your group captured certain street thug and needs to know what he did last night.
Since your character has the interrogation you decide to press on the thug and extract the information. The dungeon master determines that you need at least 3 success points to get the information you need.
At this point, since you character has 4 points in the interrogation skill, you roll with four 10-sided dice. If you get a result higher than 4 on at least 3 ouf them, you will succeed in interrogating the thug.
It's a very simple, yet versatile and fast-paced system.
### Application Usage and Overview
As already mentioned, the goal is to implement a command line utility which will produce a character sheet for our tabletop RPG. The program will recognize the following command line options
| Name | Default Value | restriction |Description |
|------|---------------|-------------|------------|
| --name | - | - | Character's name |
| --age | - | positive integer |Character's age |
| --occupation | Citizen |- | Character's occupation |
| --health | - | 1-10 |Character's health |
| --sanity | - |1-10 | Character's sanity |
| --inventory | 42 | positive, x % 3 = 0 | Character's inventory size |
| --attrs | attributes.txt | - | Attribute file descriptor |
| --skills | skills.txt | - | Skills file descriptor |
| --out | character.html | - | output file name |
| --encoding | UTF-8 | - | Encoding of input files |
| --help |false | - | when present displays program help|
Parameters without default value are mandatory and the program could be called for example as follows...
```bash
java -jar rpg-gen.jar --name "Stephen Mercer" --age 32 --occupation "Investigative Journalist" --health 5 --sanity 5 --inventory=45 \
--attrs "stephen_attrs.txt" --skills "stephen_skills.txt"
```
An example of file descriptors can be found in ```src/test/resources```. A generic format is
```text
AbilityOrSkill 5
AbilityOrSkill R
```
Each ability or sill is placed on single line defined as combination of name and level.
Level can be specified either as a number between 0 and 5 or as "R". When "R" is used as level, then the actual value is computed as a random within mentioned range.
### External Libraries
In this assignment you will encounter two useful java libraries
#### JCommander
JCommander is a small library for parsing command line arguments. The documentation and examples can be found [here](https://jcommander.org/).
In this homework you will learn just the basic by replicating what is already present in the skeleton of ```Application``` class.
### Thymeleaf
Thymeleaf is a very complex templating library which allows for templating of various documents from simple text, through html, to javascript files.
In this homework you will be required to fill in a small part of a template. Other than that you are encouraged to have a look at how to use this library.
The documentation can be found [here](https://www.thymeleaf.org/doc/tutorials/3.0/usingthymeleaf.html#introducing-thymeleaf).
## Evaluation
Beside functional correctness this assignment is focused on clean implementation and your understanding of Java's collection framework.
The maximum number of points for this assignment is **11**.
- **5 points** for passing tests (attached tests do not guarantee a 100% correctness).
- **6 points** for clean implementation and creativity.
Note that all this is at your seminar teacher's discretion.
### Preconditions
To successfully implement this assignment you need to learn the following
1. Working with files (java.nio package)
2. Understand more complex code provided by 3rd party
3. Working with external libraries
### Project structure
The structure of project provided as a base for your implementation should meet the following criteria.
1. Package ```cz.muni.fi.pb162.hw03``` contains classes and interfaces provided as part of the assignment.
- **Do not modify or add any classes or subpackages into this package.**
2. Package ```cz.muni.fi.pb162.hw03.impl``` should contain your implementation.
- **Anything outside this package will be ignored during evaluation.**
### Names in this document
Unless fully classified name is provided, all class names are relative to package ```cz.muni.fi.pb162.hw03``` or ```cz.muni.fi.pb162.hw03.impl``` for classes implemented as part of your solution.
### Compiling the project
The project can be compiled and packaged in the same way you already know
```bash
$ mvn clean compile
```
The only difference is, that unlike with seminar project, this time checks for missing documentation and style violation will produce an error.
You can temporarily disable this behavior when running this command.
```bash
$ mvn clean compile -Dcheckstyle.fail=false
```
You can consult your seminar teacher to help you set the ```checkstyle.fail``` property in your IDE (or just google it).
### Submitting the assignment
The procedure to submit your solution may differ based on your seminar group. However generally it should be ok to submit ```target/homework01-2020-1.0-SNAPSHOT-sources.jar``` to the homework vault.
### Step 1: Implementing Character class
Implement the ```Character``` class with the following attributes. In order to help you a bit there is already a very sparse skeleton in place.
| Name | Type | Description |
| -----|------|-------------|
| name | String | character's name |
| age | int | characters age |
| occupation | String | character's occupation |
| health | int | character's health |
| sanity | int | character's sanity |
| attributes | List<SkillOrAttribute> | character's attributes |
| skills | List<SkillOrAttribute> | character's skills |
Since the class has quite a few attributes, you should provide ```Builder``` class -- a builder implementation which will be used to construct instances of ``Character`` class.
This builder should implement ```Buildable``` interface as well as ```read.AttributeReader``` and ```read.SkillReader```;
### Step 2: Implementing the command line interface
Extend the implementation of ``Application`` class in order for it to recognise all of the command line parameters described above.
In order to validate some of the value, you will need to read section *4.1. Individual parameter validation* in JCommander's documentation.
Program usage info should be displayed when ``--help`` is specified as command line parameter.
### Character to HTML file
Running the ``main`` method of ``Application`` class should produce a HTML file with character information.
To achieve this you should use the Thymeleaf library already mentioned in this assignment.
To have easier time working with this library, you can use the class ```impl.AbstractHtmlWriter``` and prepared template located in ```src/main/resources```.
However this template is not complete and you will have to fill in few things.
Also notice that ``AbstractHtmlWriter`` is located inside the ```impl``` package, which means that you can modify it to suit your needs.
\ No newline at end of file
<?xml version="1.0"?>
<!DOCTYPE module PUBLIC
"-//Puppy Crawl//DTD Check Configuration 1.3//EN"
"http://www.puppycrawl.com/dtds/configuration_1_3.dtd">
<module name="Checker">
<!--<property name="fileExtensions" value="java, xml, properties"/>-->
<!-- Checks for whitespace -->
<!-- See http://checkstyle.sf.net/config_whitespace.html -->
<module name="FileTabCharacter"/>
<module name="TreeWalker">
<!-- Checks for Javadoc comments. -->
<!-- See http://checkstyle.sf.net/config_javadoc.html -->
<module name="JavadocMethod">
<property name="scope" value="public"/>
<property name="allowMissingPropertyJavadoc" value="true"/>
<property name="ignoreMethodNamesRegex" value="^(get|set)+[A-Z]+.*$"/>
</module>
<module name="JavadocType">
<property name="scope" value="public"/>
</module>
<module name="JavadocStyle">
<property name="scope" value="public"/>
<property name="checkFirstSentence" value="false"/>
</module>
<!-- Checks for Naming Conventions. -->
<!-- See http://checkstyle.sf.net/config_naming.html -->
<module name="ConstantName"/>
<module name="LocalFinalVariableName"/>
<module name="LocalVariableName"/>
<module name="MemberName"/>
<module name="MethodName"/>
<module name="PackageName"/>
<module name="ParameterName"/>
<module name="StaticVariableName"/>
<module name="TypeName"/>
<!-- Checks for imports -->
<!-- See http://checkstyle.sf.net/config_import.html -->
<module name="AvoidStarImport"/>
<module name="IllegalImport"/> <!-- defaults to sun.* packages -->
<module name="RedundantImport"/>
<module name="UnusedImports"/>
<!-- Checks for Size Violations. -->
<!-- See http://checkstyle.sf.net/config_sizes.html -->
<module name="LineLength">
<property name="max" value="120"/>
</module>
<module name="MethodLength">
<property name="max" value="50"/>
<property name="countEmpty" value="false"/>
</module>
<!-- Modifier Checks -->
<!-- See http://checkstyle.sf.net/config_modifier.html -->
<module name="ModifierOrder"/>
<module name="RedundantModifier"/>
<!-- Checks for blocks. You know, those {}'s -->
<!-- See http://checkstyle.sf.net/config_blocks.html -->
<module name="AvoidNestedBlocks"/>
<module name="LeftCurly">
<property name="option" value="eol"/>
</module>
<module name="NeedBraces">
<property name="allowSingleLineStatement" value="false"/>
</module>
<module name="RightCurly"/>
<!-- Checks for common coding problems -->
<!-- See http://checkstyle.sf.net/config_coding.html -->
<module name="EmptyStatement"/>
<module name="EqualsHashCode"/>
<module name="MissingSwitchDefault"/>
<module name="SimplifyBooleanExpression"/>
<module name="SimplifyBooleanReturn"/>
<!-- Checks for class design -->
<!-- See http://checkstyle.sf.net/config_design.html -->
<module name="InterfaceIsType"/>
<module name="VisibilityModifier">
<property name="protectedAllowed" value="true"/>
</module>
<!-- Miscellaneous other checks. -->
<!-- See http://checkstyle.sf.net/config_misc.html -->
<module name="ArrayTypeStyle"/>
</module>
</module>
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://maven.apache.org/POM/4.0.0"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>cz.muni.fi.pb162</groupId>
<artifactId>homework03-2020</artifactId>
<version>1.0-SNAPSHOT</version>
<properties>
<maven.compiler.source>10</maven.compiler.source>
<maven.compiler.target>10</maven.compiler.target>
<version.plugin.checkstyle>3.1.0</version.plugin.checkstyle>
<version.plugin.source>2.4</version.plugin.source>
<version.junit>4.12</version.junit>
<version.assertj>3.13.2</version.assertj>
<version.commons-lang3>3.4</version.commons-lang3>
<checkstyle.fail>true</checkstyle.fail>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<dependencies>
<dependency>
<groupId>com.beust</groupId>
<artifactId>jcommander</artifactId>
<version>1.78</version>
</dependency>
<dependency>
<groupId>org.thymeleaf</groupId>
<artifactId>thymeleaf</artifactId>
<version>3.0.11.RELEASE</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>${version.junit}</version>
</dependency>
<dependency>
<groupId>org.assertj</groupId>
<artifactId>assertj-core</artifactId>
<version>${version.assertj}</version>
</dependency>
</dependencies>
<build>
<plugins>
<!-- Include sources into JAR -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-source-plugin</artifactId>
<version>${version.plugin.source}</version>
<executions>
<execution>
<id>attach-sources</id>
<goals>
<goal>jar</goal>
</goals>
</execution>
</executions>
</plugin>
<!-- Executable bar -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<version>3.2.2</version>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>shade</goal>
</goals>
<configuration>
<finalName>rpg-gen</finalName>
<shadedArtifactAttached>true</shadedArtifactAttached>
<transformers>
<transformer implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
<mainClass>cz.muni.fi.pb162.hw03.impl.Application</mainClass>
</transformer>
</transformers>
</configuration>
</execution>
</executions>
</plugin>
<!-- surefire Config -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.22.1</version>
<configuration>
<useSystemClassLoader>false</useSystemClassLoader>
</configuration>
</plugin>
<!-- Check code style -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-checkstyle-plugin</artifactId>
<version>${version.plugin.checkstyle}</version>
<executions>
<execution>
<id>validate</id>
<phase>validate</phase>
<configuration>
<configLocation>pb162_codestyle.xml</configLocation>
<encoding>UTF-8</encoding>
<consoleOutput>true</consoleOutput>
<failOnViolation>${checkstyle.fail}</failOnViolation>
<violationSeverity>warning</violationSeverity>
<includeTestSourceDirectory>false</includeTestSourceDirectory>
<excludes>*/**/Demo</excludes>
</configuration>
<goals>
<goal>check</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>
package cz.muni.fi.pb162.hw03;
/**
* A base interface for builder implementations
* @author Jakub Cechacek
* @param <T> type of built object
*/
public interface Buildable<T> {
/**
* Build an instance of {@link T}
* @return instance of {@link T}
*/
T build();
}
package cz.muni.fi.pb162.hw03;
/**
* Representation of either Skill or Attribute
* @author Jakub Cechacek
*/
public class SkillOrAttribute {
private String name;
private int level;
/**
* Constructor for this class
* @param name name of the skill/attribute
* @param level level of the skill/attribute
*/
public SkillOrAttribute(String name, int level) {
this.name = name;
this.level = level;
}
public String getName() {
return name;
}
public int getLevel() {
return level;
}
}
package cz.muni.fi.pb162.hw03.impl;
import cz.muni.fi.pb162.hw03.write.CharacerSerializer;
import cz.muni.fi.pb162.hw03.write.CharacterFileWriter;
import org.thymeleaf.TemplateEngine;
import org.thymeleaf.context.Context;
import org.thymeleaf.templateresolver.ClassLoaderTemplateResolver;
/**
* Base class capable of serialising character into HTML string
* @author Jakub Cechacek
*/
public abstract class AbstractHtmlWriter implements CharacerSerializer<String>, CharacterFileWriter {
public static final String TEMPLATE = "/templates/character.html";
@Override
public String serialize(Character character) {
ClassLoaderTemplateResolver tr = new ClassLoaderTemplateResolver();
TemplateEngine templates = new TemplateEngine();
templates.setTemplateResolver(tr);
Context context = new Context();
context.setVariable("character", character);
return templates.process(TEMPLATE, context);
}
}
package cz.muni.fi.pb162.hw03.impl;
import com.beust.jcommander.JCommander;
import com.beust.jcommander.Parameter;
/**
* Character Generator application
* @author Jakub Cechacek
*/
public class Application {
@Parameter(names = "--help", help = true)
private boolean help = false;
@Parameter(names = {"--encoding"})
private String encoding = "UTF-8";
@Parameter(names = {"--name"}, required = true)
private String name;
@Parameter(names = {"--occupation"})
private String occupation = "Citizen";
// TODO: Fill in the missing command line parameters
/**
* Program entry point.
* You should parse the command line arguments and produce output html file according to them.
* @param args raw command line arguments
*/
public static void main(String[] args) {
Application app = new Application();
JCommander commander = JCommander.newBuilder().addObject(app).build();
commander.setProgramName("char-gen");
commander.parse(args);
// TODO: finish the code
// HINT: Attributes in the app object are populated with parsed command line values
}
}
package cz.muni.fi.pb162.hw03.impl;
/**
* Representation of game character
* @author Jakub Cechacek
*/
public class Character {
/**
* Builder class fro {@link Character}
*/
public static class Builder {
// TODO: implement the builder
}