GitLab steht wegen Wartungsarbeiten am Montag, den 10. Mai, zwischen 17:00 und 19:00 Uhr nicht zur Verfügung.

Commit 76723f50 authored by Dominikus Herzberg's avatar Dominikus Herzberg

Merge branch 'dev-cs' into 'master'

adds two exercises for inheritance and one for enums

See merge request !3
parents a487f13d 9d7ecb6c
...@@ -73,3 +73,148 @@ include::{sourcedir}\Medium.java[] ...@@ -73,3 +73,148 @@ include::{sourcedir}\Medium.java[]
---- ----
include::postDetails.adoc[] include::postDetails.adoc[]
== Typen im Sammelkartenspiel
Sie wollen ein Sammelkartenspiel wie https://playhearthstone.com/de-de/[Heartstone] oder https://www.playgwent.com/en[Gwent] implementieren.
Für Ihr Spiel haben Sie die folgenden Designentscheidungen getroffen:
* Alle Karten haben eine Seltenheit (`COMMON`, `RARE` oder `LEGENDARY`) und einen Namen.
* Es gibt Zauberkarten und Einheitenkarten.
* Einheitenkarten haben zusätzlich eine Stärke zwischen 1 und 100.
* Zauberkarten unterscheiden sich zusätzlich dadurch, ob sie auf freundliche Einheiten, feindliche Einheiten, keine (für globale Effekte) oder beide angewendet werden können.
Erstellen Sie die Klassen `SpellCard` und `UnitCard` für Zauber- und Einheitenkarten, sowie eine gemeinsame Oberklasse `Card`, so dass alle oben genannten Eigenschaften mit geeigneten Datentypen abgebildet werden.
include::preDetailsSolution.adoc[]
----
enum Rarity { COMMON, RARE, LEGENDARY }
abstract class Card {
private String name;
private Rarity rarity;
public Card(String name, Rarity rarity) {
this.name = name;
this.rarity = rarity;
}
public String getName() { return name; }
public Rarity getRarity() { return rarity; }
}
class UnitCard extends Card {
private int strength;
public UnitCard(String name, Rarity rarity, int strength) {
super(name, rarity);
this.strength = strength;
}
public int getStrength() {
return strength;
}
}
class SpellCard extends Card {
private boolean targetsEnemies;
private boolean targetsFriends;
public SpellCard(String name, Rarity rarity, boolean targetsEnemies, boolean targetsFriends) {
super(name, rarity);
this.targetsEnemies = targetsEnemies;
this.targetsFriends = targetsFriends;
}
public boolean targetsFriends() {
return targetsFriends;
return targetsEnemies;
}
}
----
include::postDetails.adoc[]
== SVG Generator
Das https://en.wikipedia.org/wiki/Scalable_Vector_Graphics[Scalable Vector Graphics]-Format beschreibt Vektorgrafiken als XML-basierte Textdatei, wie in dem folgenden Beispiel:
----
<svg width="120" height="120" viewBox="0 0 120 120"
xmlns="http://www.w3.org/2000/svg">
<circle cx="60" cy="60" r="50.5" style="fill:yellow"/>
<line x1="20" y1="100" x2="100" y2="20" style="stroke-width: 2; stroke:black"/>
</svg>
----
Schreiben Sie die Klassen `SVGDocument`, `SVGLine` und `SVGCircle`, so dass das oben gezeigte Dokument (bzw. ein äquivalentes Dokument) mit dem folgenden Code erzeugt werden kann.
Implementieren Sie dazu auch eine gemeinsame Überklasse für `SVGLine` und `SVGCircle` mit dem Namen `SVGElement`.
----
SVGDocument doc = new SVGDocument(120, 120,
new SVGCircle(60,60,50.5f, "fill:yellow"),
new SVGLine(20,100,100,20, "stroke-width: 2; stroke:black")
);
System.out.println(doc);
----
include::preDetailsSolution.adoc[]
----
class SVGDocument {
private float w,h;
private SVGElement[] content;
public SVGDocument(float w, float h, SVGElement ... content) {
this.w = w;
this.h = h;
this.content = content;
}
public String toString() {
String msg = "<svg width=\"%1$.2f\" height=\"%2$.2f\" viewBox=\"0 0 %1$.2f %2$.2f\" "
+ "xmlns=\"http://www.w3.org/2000/svg\">\n%3$s\n</svg>";
String contentString = Arrays.stream(content)
.map(x -> x.toString()).collect(Collectors.joining("\n"));
return String.format(Locale.US, msg, w, h, contentString); // <1>
}
}
abstract class SVGElement {
private String name;
private String style;
public SVGElement(String name, String style) {
this.name = name;
this.style = style;
}
public String toString() {
String attr = additionalAttributes();
return String.format("<%1$s %3$s style=\"%2$s\"/>", name, style, attr);
}
protected abstract String additionalAttributes();
}
class SVGLine extends SVGElement {
private float x1,y1,x2,y2;
public SVGLine(float x1, float y1, float x2, float y2, String style) {
super("line", style);
this.x1 = x1;
this.y1 = y1;
this.x2 = x2;
this.y2 = y2;
}
@Override
protected String additionalAttributes() {
String tmpl = "x1=\"%.2f\" y1=\"%.2f\" x2=\"%.2f\" y2=\"%.2f\"";
return String.format(Locale.US, tmpl, x1, y1, x2, y2); // <1>
}
}
class SVGCircle extends SVGElement {
private float cx,cy,r;
public SVGCircle(float cx, float cy, float r, String style) {
super("circle", style);
this.cx = cx;
this.cy = cy;
this.r = r;
}
@Override
protected String additionalAttributes() {
String tmpl = "cx=\"%.2f\" cy=\"%.2f\" r=\"%.2f\"";
return String.format(Locale.US, tmpl, cx, cy, r); // <1>
}
}
----
<1> Die `Locale` ist hier wichtig, da das SVG-Format vorschreibt, dass Fließkommazahlen in englischer Schreibweise (mit "." statt ",") formatiert werden müssen.
include::postDetails.adoc[]
...@@ -567,6 +567,8 @@ table.CodeRay td.code>pre{padding:0} ...@@ -567,6 +567,8 @@ table.CodeRay td.code>pre{padding:0}
<ul class="sectlevel1"> <ul class="sectlevel1">
<li><a href="#_equals">Equals</a></li> <li><a href="#_equals">Equals</a></li>
<li><a href="#_mediaplayer">Mediaplayer</a></li> <li><a href="#_mediaplayer">Mediaplayer</a></li>
<li><a href="#_typen_im_sammelkartenspiel">Typen im Sammelkartenspiel</a></li>
<li><a href="#_svg_generator">SVG Generator</a></li>
</ul> </ul>
</div> </div>
</div> </div>
...@@ -825,10 +827,188 @@ false</pre> ...@@ -825,10 +827,188 @@ false</pre>
</details> </details>
</div> </div>
</div> </div>
<div class="sect1">
<h2 id="_typen_im_sammelkartenspiel">Typen im Sammelkartenspiel</h2>
<div class="sectionbody">
<div class="paragraph">
<p>Sie wollen ein Sammelkartenspiel wie <a href="https://playhearthstone.com/de-de/">Heartstone</a> oder <a href="https://www.playgwent.com/en">Gwent</a> implementieren.
Für Ihr Spiel haben Sie die folgenden Designentscheidungen getroffen:</p>
</div>
<div class="ulist">
<ul>
<li>
<p>Alle Karten haben eine Seltenheit (<code>COMMON</code>, <code>RARE</code> oder <code>LEGENDARY</code>) und einen Namen.</p>
</li>
<li>
<p>Es gibt Zauberkarten und Einheitenkarten.</p>
</li>
<li>
<p>Einheitenkarten haben zusätzlich eine Stärke zwischen 1 und 100.</p>
</li>
<li>
<p>Zauberkarten unterscheiden sich zusätzlich dadurch, ob sie auf freundliche Einheiten, feindliche Einheiten, keine (für globale Effekte) oder beide angewendet werden können.</p>
</li>
</ul>
</div>
<div class="paragraph">
<p>Erstellen Sie die Klassen <code>SpellCard</code> und <code>UnitCard</code> für Zauber- und Einheitenkarten, sowie eine gemeinsame Oberklasse <code>Card</code>, so dass alle oben genannten Eigenschaften mit geeigneten Datentypen abgebildet werden.</p>
</div>
<details>
<summary>Lösung</summary>
<div class="listingblock">
<div class="content">
<pre>enum Rarity { COMMON, RARE, LEGENDARY }
abstract class Card {
private String name;
private Rarity rarity;
public Card(String name, Rarity rarity) {
this.name = name;
this.rarity = rarity;
}
public String getName() { return name; }
public Rarity getRarity() { return rarity; }
}
class UnitCard extends Card {
private int strength;
public UnitCard(String name, Rarity rarity, int strength) {
super(name, rarity);
this.strength = strength;
}
public int getStrength() {
return strength;
}
}
class SpellCard extends Card {
private boolean targetsEnemies;
private boolean targetsFriends;
public SpellCard(String name, Rarity rarity, boolean targetsEnemies, boolean targetsFriends) {
super(name, rarity);
this.targetsEnemies = targetsEnemies;
this.targetsFriends = targetsFriends;
}
public boolean targetsFriends() {
return targetsFriends;
return targetsEnemies;
}
}</pre>
</div>
</div>
</details>
</div>
</div>
<div class="sect1">
<h2 id="_svg_generator">SVG Generator</h2>
<div class="sectionbody">
<div class="paragraph">
<p>Das <a href="https://en.wikipedia.org/wiki/Scalable_Vector_Graphics">Scalable Vector Graphics</a>-Format beschreibt Vektorgrafiken als XML-basierte Textdatei, wie in dem folgenden Beispiel:</p>
</div>
<div class="listingblock">
<div class="content">
<pre>&lt;svg width="120" height="120" viewBox="0 0 120 120"
xmlns="http://www.w3.org/2000/svg"&gt;
&lt;circle cx="60" cy="60" r="50.5" style="fill:yellow"/&gt;
&lt;line x1="20" y1="100" x2="100" y2="20" style="stroke-width: 2; stroke:black"/&gt;
&lt;/svg&gt;</pre>
</div>
</div>
<div class="paragraph">
<p>Schreiben Sie die Klassen <code>SVGDocument</code>, <code>SVGLine</code> und <code>SVGCircle</code>, so dass das oben gezeigte Dokument (bzw. ein äquivalentes Dokument) mit dem folgenden Code erzeugt werden kann.
Implementieren Sie dazu auch eine gemeinsame Überklasse für <code>SVGLine</code> und <code>SVGCircle</code> mit dem Namen <code>SVGElement</code>.</p>
</div>
<div class="listingblock">
<div class="content">
<pre>SVGDocument doc = new SVGDocument(120, 120,
new SVGCircle(60,60,50.5f, "fill:yellow"),
new SVGLine(20,100,100,20, "stroke-width: 2; stroke:black")
);
System.out.println(doc);</pre>
</div>
</div>
<details>
<summary>Lösung</summary>
<div class="listingblock">
<div class="content">
<pre>class SVGDocument {
private float w,h;
private SVGElement[] content;
public SVGDocument(float w, float h, SVGElement ... content) {
this.w = w;
this.h = h;
this.content = content;
}
public String toString() {
String msg = "&lt;svg width=\"%1$.2f\" height=\"%2$.2f\" viewBox=\"0 0 %1$.2f %2$.2f\" "
+ "xmlns=\"http://www.w3.org/2000/svg\"&gt;\n%3$s\n&lt;/svg&gt;";
String contentString = Arrays.stream(content)
.map(x -&gt; x.toString()).collect(Collectors.joining("\n"));
return String.format(Locale.US, msg, w, h, contentString); <i class="conum" data-value="1"></i><b>(1)</b>
}
}
abstract class SVGElement {
private String name;
private String style;
public SVGElement(String name, String style) {
this.name = name;
this.style = style;
}
public String toString() {
String attr = additionalAttributes();
return String.format("&lt;%1$s %3$s style=\"%2$s\"/&gt;", name, style, attr);
}
protected abstract String additionalAttributes();
}
class SVGLine extends SVGElement {
private float x1,y1,x2,y2;
public SVGLine(float x1, float y1, float x2, float y2, String style) {
super("line", style);
this.x1 = x1;
this.y1 = y1;
this.x2 = x2;
this.y2 = y2;
}
@Override
protected String additionalAttributes() {
String tmpl = "x1=\"%.2f\" y1=\"%.2f\" x2=\"%.2f\" y2=\"%.2f\"";
return String.format(Locale.US, tmpl, x1, y1, x2, y2); <i class="conum" data-value="1"></i><b>(1)</b>
}
}
class SVGCircle extends SVGElement {
private float cx,cy,r;
public SVGCircle(float cx, float cy, float r, String style) {
super("circle", style);
this.cx = cx;
this.cy = cy;
this.r = r;
}
@Override
protected String additionalAttributes() {
String tmpl = "cx=\"%.2f\" cy=\"%.2f\" r=\"%.2f\"";
return String.format(Locale.US, tmpl, cx, cy, r); <i class="conum" data-value="1"></i><b>(1)</b>
}
}</pre>
</div>
</div>
<div class="colist arabic">
<table>
<tr>
<td><i class="conum" data-value="1"></i><b>1</b></td>
<td>Die <code>Locale</code> ist hier wichtig, da das SVG-Format vorschreibt, dass Fließkommazahlen in englischer Schreibweise (mit "." statt ",") formatiert werden müssen.</td>
</tr>
</table>
</div>
</details>
</div>
</div>
</div> </div>
<div id="footer"> <div id="footer">
<div id="footer-text"> <div id="footer-text">
Last updated 2017-11-10 14:49:32 Mitteleuropõische Zeit Last updated 2017-11-14 18:04:58 Mitteleuropõische Zeit
</div> </div>
</div> </div>
</body> </body>
......
...@@ -42,3 +42,44 @@ Ein Unterschied besteht jedoch darin, dass ein Objekt vom Typ `UserInt` prinzipi ...@@ -42,3 +42,44 @@ Ein Unterschied besteht jedoch darin, dass ein Objekt vom Typ `UserInt` prinzipi
Gerade für einen solchen Fall, in dem die Sicherheit des Codes relevant ist, wären also Enumerationstypen zu bevorzugen. Gerade für einen solchen Fall, in dem die Sicherheit des Codes relevant ist, wären also Enumerationstypen zu bevorzugen.
include::postDetails.adoc[] include::postDetails.adoc[]
== Organische Enums
Sie wollen ein Programm für eine Anwendung in der organischen Chemie schreiben. Um die chemischen Elemente möglichst platzsparend zu speichern entscheiden Sie sich, diese als `enum` zu implementieren.
Für ihre Anwendung reicht es, wenn sie die folgenden Elemente darstellen und Name, Symbol und Ordnungszahl auslesen können.
[options="header"]
|====================================
|Name | Symbol | Ordnungszahl
|Wasserstoff | H | 1
|Kohlenstoff | C | 6
|Stickstoff | N | 7
|Sauerstoff | O | 8
|Phosphor | P | 15
|Schwefel | S | 16
|====================================
Implementieren Sie den Datentyp `Element` als `enum`, so dass das Symbol als Bezeichner der Enum-Werte dient. Die natürliche Ordnung von `Element`-Objekten, soll durch die Ordnungszahl bestimmt sein.
(D.h. eine Sortierung z.B. mit `Arrays.sort` muss nach aufsteigender Ordnungszahl erfolgen.)
include::preDetailsSolution.adoc[]
----
public enum Element {
H("Wasserstoff", 1), C("Kohlenstoff", 6), N("Stickstoff", 7),
O("Sauerstoff", 8), P("Phosphor", 15), S("Schwefel", 16);
private final int ord;
private final String name;
Element(String name, int ord) {
this.ord = ord;
this.name = name;
}
public int getOrd() {
return ord;
}
public String getName() {
return name;
}
}
----
include::postDetails.adoc[]
...@@ -566,6 +566,7 @@ table.CodeRay td.code>pre{padding:0} ...@@ -566,6 +566,7 @@ table.CodeRay td.code>pre{padding:0}
<div id="toctitle">Table of Contents</div> <div id="toctitle">Table of Contents</div>
<ul class="sectlevel1"> <ul class="sectlevel1">
<li><a href="#_rechteverwaltung">Rechteverwaltung</a></li> <li><a href="#_rechteverwaltung">Rechteverwaltung</a></li>
<li><a href="#_organische_enums">Organische Enums</a></li>
</ul> </ul>
</div> </div>
</div> </div>
...@@ -638,7 +639,6 @@ summary:after { ...@@ -638,7 +639,6 @@ summary:after {
<details> <details>
<summary>Lösung</summary> <summary>Lösung</summary>
<div class="listingblock"> <div class="listingblock">
<div class="title">Lösung</div>
<div class="content"> <div class="content">
<pre class="CodeRay highlight"><code data-lang="java"><span class="type">enum</span> AccessLevel { <pre class="CodeRay highlight"><code data-lang="java"><span class="type">enum</span> AccessLevel {
GUEST, DEVELOPER, ADMIN; GUEST, DEVELOPER, ADMIN;
...@@ -694,10 +694,94 @@ summary:after { ...@@ -694,10 +694,94 @@ summary:after {
</details> </details>
</div> </div>
</div> </div>
<div class="sect1">
<h2 id="_organische_enums">Organische Enums</h2>
<div class="sectionbody">
<div class="paragraph">
<p>Sie wollen ein Programm für eine Anwendung in der organischen Chemie schreiben. Um die chemischen Elemente möglichst platzsparend zu speichern entscheiden Sie sich, diese als <code>enum</code> zu implementieren.</p>
</div>
<div class="paragraph">
<p>Für ihre Anwendung reicht es, wenn sie die folgenden Elemente darstellen und Name, Symbol und Ordnungszahl auslesen können.</p>
</div>
<table class="tableblock frame-all grid-all spread">
<colgroup>
<col style="width: 33.3333%;">
<col style="width: 33.3333%;">
<col style="width: 33.3334%;">
</colgroup>
<thead>
<tr>
<th class="tableblock halign-left valign-top">Name</th>
<th class="tableblock halign-left valign-top">Symbol</th>
<th class="tableblock halign-left valign-top">Ordnungszahl</th>
</tr>
</thead>
<tbody>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">Wasserstoff</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">H</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">1</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">Kohlenstoff</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">C</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">6</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">Stickstoff</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">N</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">7</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">Sauerstoff</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">O</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">8</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">Phosphor</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">P</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">15</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">Schwefel</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">S</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">16</p></td>
</tr>
</tbody>
</table>
<div class="paragraph">
<p>Implementieren Sie den Datentyp <code>Element</code> als <code>enum</code>, so dass das Symbol als Bezeichner der Enum-Werte dient. Die natürliche Ordnung von <code>Element</code>-Objekten, soll durch die Ordnungszahl bestimmt sein.
(D.h. eine Sortierung z.B. mit <code>Arrays.sort</code> muss nach aufsteigender Ordnungszahl erfolgen.)</p>
</div>
<details>
<summary>Lösung</summary>
<div class="listingblock">
<div class="content">
<pre>public enum Element {
H("Wasserstoff", 1), C("Kohlenstoff", 6), N("Stickstoff", 7),
O("Sauerstoff", 8), P("Phosphor", 15), S("Schwefel", 16);
private final int ord;
private final String name;
Element(String name, int ord) {
this.ord = ord;
this.name = name;
}
public int getOrd() {
return ord;
}
public String getName() {
return name;
}
}</pre>
</div>
</div>
</details>
</div>
</div>
</div> </div>
<div id="footer"> <div id="footer">
<div id="footer-text"> <div id="footer-text">
Last updated 2017-11-10 15:00:34 Mitteleuropõische Zeit Last updated 2017-11-14 17:59:58 Mitteleuropõische Zeit
</div> </div>
</div> </div>
</body> </body>
......
Markdown is supported
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