Compare commits
13 Commits
136be17443
...
main
Author | SHA1 | Date | |
---|---|---|---|
b2eb22a6cc | |||
57aae3eda6 | |||
f42c1b23ab | |||
9e5e9eb91a | |||
4b73c1b5e3 | |||
1b07a3b6ab | |||
701e732eb6 | |||
ac9d7fdd39 | |||
8942229d87 | |||
6efe637f23 | |||
cd913d2703 | |||
e7f7a20ea6 | |||
703097ad4d |
@@ -8,7 +8,7 @@ public class ByeGame extends Game{
|
|||||||
private final String player1;
|
private final String player1;
|
||||||
private final Game ref;
|
private final Game ref;
|
||||||
|
|
||||||
ByeGame(String player1, Game ref){
|
ByeGame(String player1, Game ref) {
|
||||||
super();
|
super();
|
||||||
this.ref = ref;
|
this.ref = ref;
|
||||||
this.player1 = player1;
|
this.player1 = player1;
|
||||||
@@ -38,16 +38,22 @@ public class ByeGame extends Game{
|
|||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public List<Game> getAllGames()
|
public List<Game> getAllGames() {
|
||||||
{
|
List<Game> temp = new ArrayList<>();
|
||||||
List<Game> temp = new ArrayList(Arrays.asList(this.getId()));
|
temp.add(this);
|
||||||
temp.addAll(ref.getAllGames());
|
temp.addAll(ref.getAllGames());
|
||||||
return temp;
|
return temp;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public List<String> getRemaningPlayers() {
|
public List<String> getRemaningPlayers() {
|
||||||
// TODO Auto-generated method stub
|
if (winner != null) {
|
||||||
throw new UnsupportedOperationException("Unimplemented method 'getRemaningPlayers'");
|
return Arrays.asList(winner);
|
||||||
|
} else {
|
||||||
|
List<String> players = new ArrayList<>();
|
||||||
|
players.add(player1);
|
||||||
|
players.addAll(ref.getRemaningPlayers());
|
||||||
|
return players;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -3,45 +3,49 @@ package tournament;
|
|||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
public abstract class Game {
|
public abstract class Game {
|
||||||
private static int counter = 0;
|
|
||||||
private final int id;
|
private static int counter = 0;
|
||||||
//null nicht notwendig
|
protected final int id;
|
||||||
private String winner = null;
|
//null nicht notwendig
|
||||||
|
protected String winner = null;
|
||||||
|
|
||||||
|
|
||||||
protected Game() {
|
protected Game() {
|
||||||
this.id = counter++;
|
this.id = counter++;
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getId(){
|
public int getId(){
|
||||||
return this.id;
|
return this.id;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getWinner(){
|
public String getWinner(){
|
||||||
return this.winner;
|
return this.winner;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setWinner(String winner) {
|
public void setWinner(String winner) {
|
||||||
String player1 = getPlayer1();
|
if (this.winner != null)
|
||||||
System.out.println("Player 1: " + player1);
|
throw new IllegalStateException("winner already set");
|
||||||
String player2 = getPlayer2();
|
if (getPlayer1() == null || getPlayer2() == null)
|
||||||
System.out.println("Player 2: " + player2);
|
throw new IllegalStateException("Opponents are not yet known");
|
||||||
this.winner = this.winner == null && player1 != null && player2 != null && (winner == player1 || winner == player2) ? this.winner = winner : this.winner;
|
if (getPlayer1().equals(winner) || getPlayer2().equals(winner))
|
||||||
}
|
this.winner = winner;
|
||||||
|
else
|
||||||
|
throw new IllegalArgumentException("Unknown player " + winner);
|
||||||
|
}
|
||||||
|
|
||||||
public abstract String getPlayer1();
|
|
||||||
|
|
||||||
public abstract String getPlayer2();
|
public abstract String getPlayer1();
|
||||||
|
|
||||||
public abstract List<String> getAllPlayers();
|
public abstract String getPlayer2();
|
||||||
|
|
||||||
|
public abstract List<String> getAllPlayers();
|
||||||
|
|
||||||
public abstract List<String> getRemaningPlayers();
|
public abstract List<String> getRemaningPlayers();
|
||||||
|
|
||||||
public abstract List<Game> getAllGames();
|
public abstract List<Game> getAllGames();
|
||||||
|
|
||||||
public String toString(){
|
public String toString() {
|
||||||
return "Game: " + getId() + " Player: "+ getPlayer1()+ " vs Player: " + getPlayer2() + "Winner is: "+ getWinner();
|
return "Game: " + getId() + " Player: "+ getPlayer1()+ " vs Player: " + getPlayer2() + "Winner is: "+ getWinner();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@@ -5,45 +5,46 @@ import java.util.Arrays;
|
|||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
public class OrdinaryGame extends Game{
|
public class OrdinaryGame extends Game{
|
||||||
|
|
||||||
private Game Player1;
|
private Game Player1;
|
||||||
private Game Player2;
|
private Game Player2;
|
||||||
public OrdinaryGame(Game Player1, Game Player2)
|
|
||||||
{
|
public OrdinaryGame(Game Player1, Game Player2) {
|
||||||
this.Player1 = Player1;
|
this.Player1 = Player1;
|
||||||
this.Player2 = Player2;
|
this.Player2 = Player2;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getPlayer1()
|
public String getPlayer1() {
|
||||||
{
|
|
||||||
return Player1.getWinner();
|
return Player1.getWinner();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getPlayer2()
|
public String getPlayer2() {
|
||||||
{
|
|
||||||
return Player2.getWinner();
|
return Player2.getWinner();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public List<String> getAllPlayers()
|
public List<String> getAllPlayers() {
|
||||||
{
|
List<String> temp = new ArrayList<>();
|
||||||
List<String> temp = new ArrayList();
|
|
||||||
temp.addAll(Player1.getAllPlayers());
|
temp.addAll(Player1.getAllPlayers());
|
||||||
temp.addAll(Player2.getAllPlayers());
|
temp.addAll(Player2.getAllPlayers());
|
||||||
return temp;
|
return temp;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public List<String> getRemaningPlayers()
|
public List<String> getRemaningPlayers() {
|
||||||
{
|
|
||||||
if(this.getWinner() != null)
|
if(this.getWinner() != null)
|
||||||
return new ArrayList<>(Arrays.asList(this.getWinner()));
|
return new ArrayList<>(Arrays.asList(this.getWinner()));
|
||||||
List<String> temp = new ArrayList();
|
List<String> temp = new ArrayList<>();
|
||||||
temp.addAll(Player1.getRemaningPlayers());
|
temp.addAll(Player1.getRemaningPlayers());
|
||||||
temp.addAll(Player2.getRemaningPlayers());
|
temp.addAll(Player2.getRemaningPlayers());
|
||||||
return temp;
|
return temp;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public List<Game> getAllGames()
|
public List<Game> getAllGames() {
|
||||||
{
|
List<Game> temp = new ArrayList<>();
|
||||||
List<Game> temp = new ArrayList(Arrays.asList(this.getId()));
|
|
||||||
temp.addAll(Player1.getAllGames());
|
temp.addAll(Player1.getAllGames());
|
||||||
temp.addAll(Player2.getAllGames());
|
temp.addAll(Player2.getAllGames());
|
||||||
return temp;
|
return temp;
|
||||||
|
@@ -6,6 +6,7 @@ import java.util.Arrays;
|
|||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
public class SeededGame extends Game{
|
public class SeededGame extends Game{
|
||||||
|
|
||||||
private String player1;
|
private String player1;
|
||||||
private String player2;
|
private String player2;
|
||||||
|
|
||||||
@@ -16,35 +17,32 @@ public class SeededGame extends Game{
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getPlayer1()
|
public String getPlayer1() {
|
||||||
{
|
|
||||||
return player1;
|
return player1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getPlayer2()
|
public String getPlayer2() {
|
||||||
{
|
|
||||||
return player2;
|
return player2;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public List<String> getAllPlayers()
|
public List<String> getAllPlayers() {
|
||||||
{
|
|
||||||
//return new ArrayList<String>(Arrays.asList(player1, player2));
|
//return new ArrayList<String>(Arrays.asList(player1, player2));
|
||||||
return List.of(player1, player2);
|
return List.of(player1, player2);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public List<String> getRemaningPlayers()
|
public List<String> getRemaningPlayers() {
|
||||||
{
|
if(this.getWinner() != null) {
|
||||||
if(this.getWinner() != null)
|
|
||||||
return new ArrayList<>(Arrays.asList(this.getWinner()));
|
return new ArrayList<>(Arrays.asList(this.getWinner()));
|
||||||
List<String> temp = new ArrayList(Arrays.asList(player1,player2));
|
}
|
||||||
return temp;
|
|
||||||
|
return List.of(player1, player2);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public List<Game> getAllGames()
|
public List<Game> getAllGames() {
|
||||||
{
|
|
||||||
return List.of(this);
|
return List.of(this);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
43
uebung05/src/logistics/Demo.java
Normal file
43
uebung05/src/logistics/Demo.java
Normal file
@@ -0,0 +1,43 @@
|
|||||||
|
package logistics;
|
||||||
|
|
||||||
|
import logistics.material.BulletBelts;
|
||||||
|
import logistics.material.Grease;
|
||||||
|
import logistics.material.LiterDiesel;
|
||||||
|
import logistics.material.MetGallonsKerosene;
|
||||||
|
import logistics.material.Oil;
|
||||||
|
import logistics.material.RocketPods;
|
||||||
|
import logistics.material.ShellBatches;
|
||||||
|
|
||||||
|
public class Demo {
|
||||||
|
public static void main(String[] args) {
|
||||||
|
final Manager manager = new Manager();
|
||||||
|
manager.addVehicle(new Tank("Leo1", 50, 2, 3));
|
||||||
|
manager.addVehicle(new Tank("Leo2", 60, 3, 4));
|
||||||
|
manager.addVehicle(new Helicopter("Tiger1", 300, 2, 5));
|
||||||
|
manager.addVehicle(new Helicopter("Tiger2", 400, 7, 8));
|
||||||
|
System.out.println();
|
||||||
|
manager.showOverallNeed();
|
||||||
|
System.out.println();
|
||||||
|
manager.fillUpVehicles();
|
||||||
|
manager.showOverallNeed();
|
||||||
|
System.out.println();
|
||||||
|
manager.logTick(1);
|
||||||
|
System.out.println();
|
||||||
|
manager.showNeed(LiterDiesel.INSTANCE);
|
||||||
|
System.out.println();
|
||||||
|
manager.showNeed(MetGallonsKerosene.INSTANCE);
|
||||||
|
System.out.println();
|
||||||
|
manager.showNeed(BulletBelts.INSTANCE);
|
||||||
|
System.out.println();
|
||||||
|
manager.showNeed(RocketPods.INSTANCE);
|
||||||
|
System.out.println();
|
||||||
|
manager.showNeed(ShellBatches.INSTANCE);
|
||||||
|
System.out.println();
|
||||||
|
manager.showNeed(Oil.INSTANCE);
|
||||||
|
System.out.println();
|
||||||
|
manager.showNeed(Grease.INSTANCE);
|
||||||
|
System.out.println();
|
||||||
|
manager.showOverallNeed();
|
||||||
|
System.out.println();
|
||||||
|
}
|
||||||
|
}
|
50
uebung05/src/logistics/Helicopter.java
Normal file
50
uebung05/src/logistics/Helicopter.java
Normal file
@@ -0,0 +1,50 @@
|
|||||||
|
package logistics;
|
||||||
|
|
||||||
|
import logistics.material.BulletBelts;
|
||||||
|
import logistics.material.MetGallonsKerosene;
|
||||||
|
import logistics.material.RocketPods;
|
||||||
|
import logistics.quantities.NeedCollector;
|
||||||
|
import logistics.storage.FloatStorage;
|
||||||
|
import logistics.storage.IntStorage;
|
||||||
|
|
||||||
|
public class Helicopter extends Vehicle {
|
||||||
|
|
||||||
|
public IntStorage bullets;
|
||||||
|
public IntStorage rockets;
|
||||||
|
public FloatStorage tank;
|
||||||
|
|
||||||
|
public Helicopter(String name, float kerosene, int bulletBelts, int rocketPods) {
|
||||||
|
super(name);
|
||||||
|
this.tank = new FloatStorage(kerosene, MetGallonsKerosene.INSTANCE, 500);
|
||||||
|
bullets = new IntStorage(bulletBelts, BulletBelts.INSTANCE, 2);
|
||||||
|
rockets = new IntStorage(rocketPods, RocketPods.INSTANCE, 2);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void reportNeeds(NeedCollector collector) {
|
||||||
|
oil.reportNeed(collector);
|
||||||
|
grease.reportNeed(collector);
|
||||||
|
tank.reportNeed(collector);
|
||||||
|
bullets.reportNeed(collector);
|
||||||
|
rockets.reportNeed(collector);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void fillUpAll() {
|
||||||
|
oil.fillUp();
|
||||||
|
grease.fillUp();
|
||||||
|
tank.fillUp();
|
||||||
|
bullets.fillUp();
|
||||||
|
rockets.fillUp();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void consumeAll(int intensityRate) {
|
||||||
|
tank.consume(intensityRate * 200);
|
||||||
|
bullets.consume(intensityRate);
|
||||||
|
rockets.consume(intensityRate);
|
||||||
|
oil.consume(1);
|
||||||
|
grease.consume(1);
|
||||||
|
}
|
||||||
|
}
|
54
uebung05/src/logistics/Manager.java
Normal file
54
uebung05/src/logistics/Manager.java
Normal file
@@ -0,0 +1,54 @@
|
|||||||
|
package logistics;
|
||||||
|
|
||||||
|
import logistics.quantities.FloatUnit;
|
||||||
|
import logistics.quantities.IntUnit;
|
||||||
|
import logistics.quantities.NeedCollector;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
public class Manager {
|
||||||
|
|
||||||
|
private final List<Vehicle> vehicles = new ArrayList<>();
|
||||||
|
|
||||||
|
|
||||||
|
public void addVehicle(Vehicle vehicle) {
|
||||||
|
vehicles.add(vehicle);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void fillUpVehicles() {
|
||||||
|
for (Vehicle vehicle : vehicles) {
|
||||||
|
vehicle.fillUpAll();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void logTick(int intensityRate) {
|
||||||
|
for (Vehicle vehicle : vehicles) {
|
||||||
|
vehicle.consumeAll(intensityRate);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public NeedCollector collectNeeds() {
|
||||||
|
NeedCollector collector = new NeedCollector();
|
||||||
|
for (Vehicle vehicle : vehicles) {
|
||||||
|
vehicle.reportNeeds(collector);
|
||||||
|
}
|
||||||
|
return collector;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void showOverallNeed() {
|
||||||
|
collectNeeds().show();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void showNeed(IntUnit unit) {
|
||||||
|
NeedCollector collector = collectNeeds();
|
||||||
|
System.out.println(collector.getNeed(unit));
|
||||||
|
}
|
||||||
|
|
||||||
|
public void showNeed(FloatUnit unit) {
|
||||||
|
NeedCollector collector = collectNeeds();
|
||||||
|
System.out.println(collector.getNeed(unit));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
47
uebung05/src/logistics/Tank.java
Normal file
47
uebung05/src/logistics/Tank.java
Normal file
@@ -0,0 +1,47 @@
|
|||||||
|
package logistics;
|
||||||
|
|
||||||
|
|
||||||
|
import logistics.material.BulletBelts;
|
||||||
|
import logistics.material.LiterDiesel;
|
||||||
|
import logistics.material.ShellBatches;
|
||||||
|
import logistics.quantities.NeedCollector;
|
||||||
|
import logistics.storage.FloatStorage;
|
||||||
|
import logistics.storage.IntStorage;
|
||||||
|
|
||||||
|
public class Tank extends Vehicle {
|
||||||
|
public final IntStorage bullets;
|
||||||
|
public final IntStorage shells;
|
||||||
|
public final FloatStorage tank;
|
||||||
|
|
||||||
|
public Tank(String name, float diesel,int bulletBelts, int shellBatches) {
|
||||||
|
super(name);
|
||||||
|
bullets = new IntStorage(bulletBelts, BulletBelts.INSTANCE, 10);
|
||||||
|
shells = new IntStorage(shellBatches, ShellBatches.INSTANCE, 10);
|
||||||
|
tank = new FloatStorage(diesel, LiterDiesel.INSTANCE, 1200);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void reportNeeds(NeedCollector collector) {
|
||||||
|
super.reportNeedsSuper(collector);
|
||||||
|
bullets.reportNeed(collector);
|
||||||
|
shells.reportNeed(collector);
|
||||||
|
tank.reportNeed(collector);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void fillUpAll() {
|
||||||
|
super.fillUpAllSuper();
|
||||||
|
bullets.fillUp();
|
||||||
|
shells.fillUp();
|
||||||
|
tank.fillUp();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void consumeAll(int intesity) {
|
||||||
|
super.consumeAll();
|
||||||
|
bullets.consume(intesity*2);
|
||||||
|
tank.consume(intesity*180f);
|
||||||
|
shells.consume(intesity*2);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
45
uebung05/src/logistics/Truck.java
Normal file
45
uebung05/src/logistics/Truck.java
Normal file
@@ -0,0 +1,45 @@
|
|||||||
|
package logistics;
|
||||||
|
|
||||||
|
import logistics.material.BulletBelts;
|
||||||
|
import logistics.material.LiterDiesel;
|
||||||
|
import logistics.quantities.NeedCollector;
|
||||||
|
import logistics.storage.FloatStorage;
|
||||||
|
import logistics.storage.IntStorage;
|
||||||
|
|
||||||
|
public class Truck extends Vehicle {
|
||||||
|
private final FloatStorage tank;
|
||||||
|
private final IntStorage bullets;
|
||||||
|
|
||||||
|
public Truck(String name, float diesel, int bullets) {
|
||||||
|
super(name);
|
||||||
|
this.tank = new FloatStorage(diesel, LiterDiesel.INSTANCE, 180);
|
||||||
|
this.bullets = new IntStorage(bullets, BulletBelts.INSTANCE, 3);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void consumeAll(int intensity) {
|
||||||
|
oil.consume(1);
|
||||||
|
grease.consume(1);
|
||||||
|
tank.consume(intensity * 25);
|
||||||
|
bullets.consume(intensity * 2);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void reportNeeds(NeedCollector collector) {
|
||||||
|
oil.reportNeed(collector);
|
||||||
|
grease.reportNeed(collector);
|
||||||
|
tank.reportNeed(collector);
|
||||||
|
bullets.reportNeed(collector);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void fillUpAll() {
|
||||||
|
oil.fillUp();
|
||||||
|
grease.fillUp();
|
||||||
|
tank.fillUp();
|
||||||
|
bullets.fillUp();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
43
uebung05/src/logistics/Vehicle.java
Normal file
43
uebung05/src/logistics/Vehicle.java
Normal file
@@ -0,0 +1,43 @@
|
|||||||
|
package logistics;
|
||||||
|
|
||||||
|
import logistics.material.Grease;
|
||||||
|
import logistics.material.Oil;
|
||||||
|
import logistics.quantities.NeedCollector;
|
||||||
|
import logistics.storage.IntStorage;
|
||||||
|
|
||||||
|
public abstract class Vehicle {
|
||||||
|
public String name;
|
||||||
|
public IntStorage oil;
|
||||||
|
public IntStorage grease;
|
||||||
|
|
||||||
|
public Vehicle(String name) {
|
||||||
|
this.name = name;
|
||||||
|
this.oil = new IntStorage(0, Oil.INSTANCE, 3);
|
||||||
|
this.grease = new IntStorage(0, Grease.INSTANCE, 3);
|
||||||
|
}
|
||||||
|
|
||||||
|
public abstract void reportNeeds(NeedCollector collector);
|
||||||
|
|
||||||
|
public abstract void fillUpAll();
|
||||||
|
|
||||||
|
public abstract void consumeAll(int intensity);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
public void consumeAll(){
|
||||||
|
oil.consume(1);
|
||||||
|
grease.consume(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void fillUpAllSuper(){
|
||||||
|
oil.fillUp();
|
||||||
|
grease.fillUp();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void reportNeedsSuper(NeedCollector collector){
|
||||||
|
oil.reportNeed(collector);
|
||||||
|
grease.reportNeed(collector);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
14
uebung05/src/logistics/material/BulletBelts.java
Normal file
14
uebung05/src/logistics/material/BulletBelts.java
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
package logistics.material;
|
||||||
|
|
||||||
|
import logistics.quantities.IntUnit;
|
||||||
|
|
||||||
|
public class BulletBelts implements IntUnit{
|
||||||
|
public static BulletBelts INSTANCE = new BulletBelts();
|
||||||
|
|
||||||
|
private BulletBelts() {}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return "belts of 7.62 bullets";
|
||||||
|
}
|
||||||
|
}
|
15
uebung05/src/logistics/material/Grease.java
Normal file
15
uebung05/src/logistics/material/Grease.java
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
package logistics.material;
|
||||||
|
|
||||||
|
import logistics.quantities.IntUnit;
|
||||||
|
|
||||||
|
public class Grease implements IntUnit{
|
||||||
|
public static Grease INSTANCE = new Grease();
|
||||||
|
|
||||||
|
private Grease() {}
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return "units of grease";
|
||||||
|
}
|
||||||
|
}
|
14
uebung05/src/logistics/material/LiterDiesel.java
Normal file
14
uebung05/src/logistics/material/LiterDiesel.java
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
package logistics.material;
|
||||||
|
|
||||||
|
import logistics.quantities.FloatUnit;
|
||||||
|
|
||||||
|
public class LiterDiesel implements FloatUnit{
|
||||||
|
public static LiterDiesel INSTANCE = new LiterDiesel();
|
||||||
|
|
||||||
|
private LiterDiesel() {}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return "liters of diesel";
|
||||||
|
}
|
||||||
|
}
|
14
uebung05/src/logistics/material/MetGallonsKerosene.java
Normal file
14
uebung05/src/logistics/material/MetGallonsKerosene.java
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
package logistics.material;
|
||||||
|
|
||||||
|
import logistics.quantities.FloatUnit;
|
||||||
|
|
||||||
|
public class MetGallonsKerosene implements FloatUnit{
|
||||||
|
public static MetGallonsKerosene INSTANCE = new MetGallonsKerosene();
|
||||||
|
|
||||||
|
private MetGallonsKerosene() {}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return "met gallons of kerosene";
|
||||||
|
}
|
||||||
|
}
|
14
uebung05/src/logistics/material/Oil.java
Normal file
14
uebung05/src/logistics/material/Oil.java
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
package logistics.material;
|
||||||
|
|
||||||
|
import logistics.quantities.IntUnit;
|
||||||
|
|
||||||
|
public class Oil implements IntUnit{
|
||||||
|
public static Oil INSTANCE = new Oil();
|
||||||
|
|
||||||
|
private Oil() {}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return "units of oil";
|
||||||
|
}
|
||||||
|
}
|
14
uebung05/src/logistics/material/RocketPods.java
Normal file
14
uebung05/src/logistics/material/RocketPods.java
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
package logistics.material;
|
||||||
|
|
||||||
|
import logistics.quantities.IntUnit;
|
||||||
|
|
||||||
|
public class RocketPods implements IntUnit{
|
||||||
|
public static RocketPods INSTANCE = new RocketPods();
|
||||||
|
|
||||||
|
private RocketPods() {}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return "pods of 70mm rockets";
|
||||||
|
}
|
||||||
|
}
|
14
uebung05/src/logistics/material/ShellBatches.java
Normal file
14
uebung05/src/logistics/material/ShellBatches.java
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
package logistics.material;
|
||||||
|
|
||||||
|
import logistics.quantities.IntUnit;
|
||||||
|
|
||||||
|
public class ShellBatches implements IntUnit{
|
||||||
|
public static ShellBatches INSTANCE = new ShellBatches();
|
||||||
|
|
||||||
|
private ShellBatches() {}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return "batches of 120mm shells";
|
||||||
|
}
|
||||||
|
}
|
5
uebung05/src/logistics/quantities/FloatUnit.java
Normal file
5
uebung05/src/logistics/quantities/FloatUnit.java
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
package logistics.quantities;
|
||||||
|
|
||||||
|
public interface FloatUnit {
|
||||||
|
|
||||||
|
}
|
5
uebung05/src/logistics/quantities/IntUnit.java
Normal file
5
uebung05/src/logistics/quantities/IntUnit.java
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
package logistics.quantities;
|
||||||
|
|
||||||
|
public interface IntUnit {
|
||||||
|
|
||||||
|
}
|
43
uebung05/src/logistics/quantities/NeedCollector.java
Normal file
43
uebung05/src/logistics/quantities/NeedCollector.java
Normal file
@@ -0,0 +1,43 @@
|
|||||||
|
package logistics.quantities;
|
||||||
|
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
public class NeedCollector {
|
||||||
|
private Map<IntUnit, Integer> intNeeded = new HashMap<>();
|
||||||
|
private Map<FloatUnit, Float> floatNeeded;
|
||||||
|
|
||||||
|
public NeedCollector() {
|
||||||
|
// wird bei Deklaration initialisiert
|
||||||
|
//intNeeded = new HashMap<>();
|
||||||
|
floatNeeded = new HashMap<>();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void add(int amount, IntUnit unit) {
|
||||||
|
if (intNeeded.containsKey(unit)) {
|
||||||
|
intNeeded.put(unit, intNeeded.get(unit) + amount);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
intNeeded.put(unit, amount);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void add(float amount, FloatUnit unit) {
|
||||||
|
if (floatNeeded.containsKey(unit))
|
||||||
|
floatNeeded.put(unit, floatNeeded.get(unit) + amount);
|
||||||
|
else
|
||||||
|
floatNeeded.put(unit, amount);
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getNeed(IntUnit unit) {
|
||||||
|
return intNeeded.get(unit);
|
||||||
|
}
|
||||||
|
|
||||||
|
public float getNeed(FloatUnit unit) {
|
||||||
|
return floatNeeded.get(unit);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void show() {
|
||||||
|
System.out.println(intNeeded);
|
||||||
|
System.out.println(floatNeeded);
|
||||||
|
}
|
||||||
|
}
|
59
uebung05/src/logistics/storage/FloatStorage.java
Normal file
59
uebung05/src/logistics/storage/FloatStorage.java
Normal file
@@ -0,0 +1,59 @@
|
|||||||
|
package logistics.storage;
|
||||||
|
|
||||||
|
import logistics.quantities.FloatUnit;
|
||||||
|
import logistics.quantities.NeedCollector;
|
||||||
|
|
||||||
|
public class FloatStorage {
|
||||||
|
|
||||||
|
private float stored;
|
||||||
|
private final FloatUnit unit;
|
||||||
|
private final float max;
|
||||||
|
|
||||||
|
public FloatStorage(float stored, FloatUnit unit, float max) {
|
||||||
|
if (stored < 0 || max < 0)
|
||||||
|
throw new IllegalArgumentException("negative");
|
||||||
|
this.stored = stored;
|
||||||
|
this.unit = unit;
|
||||||
|
this.max = max;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public float consume(float amount) {
|
||||||
|
if (amount < 0)
|
||||||
|
throw new IllegalArgumentException("negative");
|
||||||
|
amount = Math.min(amount, stored);
|
||||||
|
stored -= amount;
|
||||||
|
return amount;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void fill(float amount) {
|
||||||
|
stored = Math.min(stored + amount, max);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void fillUp() {
|
||||||
|
stored = max;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void reportNeed(NeedCollector collector) {
|
||||||
|
collector.add(max - stored, unit);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public float getStored() {
|
||||||
|
return stored;
|
||||||
|
}
|
||||||
|
|
||||||
|
public FloatUnit getUnit() {
|
||||||
|
return unit;
|
||||||
|
}
|
||||||
|
|
||||||
|
public float getMax() {
|
||||||
|
return max;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return "storage with " + stored + " of " + max + " " + unit;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
60
uebung05/src/logistics/storage/IntStorage.java
Normal file
60
uebung05/src/logistics/storage/IntStorage.java
Normal file
@@ -0,0 +1,60 @@
|
|||||||
|
package logistics.storage;
|
||||||
|
|
||||||
|
import logistics.quantities.IntUnit;
|
||||||
|
import logistics.quantities.NeedCollector;
|
||||||
|
|
||||||
|
public class IntStorage {
|
||||||
|
private int stored;
|
||||||
|
private final IntUnit unit;
|
||||||
|
private final int max;
|
||||||
|
|
||||||
|
public IntStorage(int stored, IntUnit unit, int max) {
|
||||||
|
if (stored < 0 || max < 0)
|
||||||
|
throw new IllegalArgumentException("negative");
|
||||||
|
this.stored = Math.min(stored, max);
|
||||||
|
this.unit = unit;
|
||||||
|
this.max = max;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public int consume(int amount) {
|
||||||
|
if (amount < 0)
|
||||||
|
throw new IllegalArgumentException("negative");
|
||||||
|
|
||||||
|
int result = Math.min(amount, stored);
|
||||||
|
stored -= result;
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void fill(int amount) {
|
||||||
|
if (amount < 0) throw new IllegalArgumentException("negative");
|
||||||
|
stored = Math.min(stored + amount, max);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void fillUp() {
|
||||||
|
stored = max;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void reportNeed(NeedCollector collector) {
|
||||||
|
collector.add(max - stored, unit);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public int getStored() {
|
||||||
|
return stored;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getMax() {
|
||||||
|
return max;
|
||||||
|
}
|
||||||
|
|
||||||
|
public IntUnit getUnit() {
|
||||||
|
return unit;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return "storage with " + stored + " of " + max + " " + unit;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
67
uebung05/test/logistics/ManagerTest.java
Normal file
67
uebung05/test/logistics/ManagerTest.java
Normal file
@@ -0,0 +1,67 @@
|
|||||||
|
package logistics;
|
||||||
|
|
||||||
|
import logistics.material.BulletBelts;
|
||||||
|
import logistics.material.Grease;
|
||||||
|
import logistics.material.LiterDiesel;
|
||||||
|
import logistics.material.MetGallonsKerosene;
|
||||||
|
import logistics.material.Oil;
|
||||||
|
import logistics.material.RocketPods;
|
||||||
|
import logistics.material.ShellBatches;
|
||||||
|
import logistics.quantities.NeedCollector;
|
||||||
|
import org.junit.Before;
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
import static org.junit.Assert.assertEquals;
|
||||||
|
|
||||||
|
public class ManagerTest {
|
||||||
|
private static final float EPS = 1e-5f;
|
||||||
|
private Manager manager;
|
||||||
|
|
||||||
|
@Before
|
||||||
|
public void setup() {
|
||||||
|
manager = new Manager();
|
||||||
|
manager.addVehicle(new Tank("Leo1", 50, 2, 3));
|
||||||
|
manager.addVehicle(new Tank("Leo2", 60, 3, 4));
|
||||||
|
manager.addVehicle(new Helicopter("Tiger1", 300, 2, 5));
|
||||||
|
manager.addVehicle(new Helicopter("Tiger2", 400, 7, 8));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testInitialNeed() {
|
||||||
|
final NeedCollector collector = manager.collectNeeds();
|
||||||
|
assertEquals(4, collector.getNeed(RocketPods.INSTANCE));
|
||||||
|
assertEquals(12, collector.getNeed(Oil.INSTANCE));
|
||||||
|
assertEquals(24, collector.getNeed(BulletBelts.INSTANCE));
|
||||||
|
assertEquals(20, collector.getNeed(ShellBatches.INSTANCE));
|
||||||
|
assertEquals(12, collector.getNeed(Grease.INSTANCE));
|
||||||
|
assertEquals(1000f, collector.getNeed(MetGallonsKerosene.INSTANCE), EPS);
|
||||||
|
assertEquals(2400f, collector.getNeed(LiterDiesel.INSTANCE), EPS);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testNeedAfterFillUp() {
|
||||||
|
manager.fillUpVehicles();
|
||||||
|
final NeedCollector collector = manager.collectNeeds();
|
||||||
|
assertEquals(0, collector.getNeed(RocketPods.INSTANCE));
|
||||||
|
assertEquals(0, collector.getNeed(Oil.INSTANCE));
|
||||||
|
assertEquals(0, collector.getNeed(BulletBelts.INSTANCE));
|
||||||
|
assertEquals(0, collector.getNeed(ShellBatches.INSTANCE));
|
||||||
|
assertEquals(0, collector.getNeed(Grease.INSTANCE));
|
||||||
|
assertEquals(0f, collector.getNeed(MetGallonsKerosene.INSTANCE), EPS);
|
||||||
|
assertEquals(0f, collector.getNeed(LiterDiesel.INSTANCE), EPS);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testNeedAfterLogTick() {
|
||||||
|
manager.fillUpVehicles();
|
||||||
|
manager.logTick(1);
|
||||||
|
final NeedCollector collector = manager.collectNeeds();
|
||||||
|
assertEquals(2, collector.getNeed(RocketPods.INSTANCE));
|
||||||
|
assertEquals(4, collector.getNeed(Oil.INSTANCE));
|
||||||
|
assertEquals(6, collector.getNeed(BulletBelts.INSTANCE));
|
||||||
|
assertEquals(4, collector.getNeed(ShellBatches.INSTANCE));
|
||||||
|
assertEquals(4, collector.getNeed(Grease.INSTANCE));
|
||||||
|
assertEquals(400f, collector.getNeed(MetGallonsKerosene.INSTANCE), EPS);
|
||||||
|
assertEquals(360f, collector.getNeed(LiterDiesel.INSTANCE), EPS);
|
||||||
|
}
|
||||||
|
}
|
80
uebung05/test/logistics/storage/IntStorageTest.java
Normal file
80
uebung05/test/logistics/storage/IntStorageTest.java
Normal file
@@ -0,0 +1,80 @@
|
|||||||
|
package logistics.storage;
|
||||||
|
|
||||||
|
import logistics.material.Oil;
|
||||||
|
import org.junit.Before;
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
import static org.junit.Assert.assertEquals;
|
||||||
|
|
||||||
|
public class IntStorageTest {
|
||||||
|
private static final int MAX = 3;
|
||||||
|
|
||||||
|
private IntStorage intStorage;
|
||||||
|
|
||||||
|
@Before
|
||||||
|
public void setup() {
|
||||||
|
intStorage = new IntStorage(0, Oil.INSTANCE, MAX);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testEmptyStorage() {
|
||||||
|
assertEquals(0, intStorage.getStored());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testGetStorage() {
|
||||||
|
intStorage.fill(1);
|
||||||
|
assertEquals(1, intStorage.getStored());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testGetMax() {
|
||||||
|
assertEquals(MAX, intStorage.getMax());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testFillUp() {
|
||||||
|
intStorage.fillUp();
|
||||||
|
assertEquals(MAX, intStorage.getStored());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testUpperBound() {
|
||||||
|
intStorage.fill(MAX + 1);
|
||||||
|
assertEquals(MAX, intStorage.getStored());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testConsume() {
|
||||||
|
intStorage.fillUp();
|
||||||
|
assertEquals(MAX, intStorage.getStored());
|
||||||
|
assertEquals(MAX, intStorage.consume(MAX));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testLowerBound() {
|
||||||
|
intStorage.consume(1);
|
||||||
|
assertEquals(0, intStorage.getStored());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test(expected = IllegalArgumentException.class)
|
||||||
|
public void testIllegalFill() {
|
||||||
|
intStorage.fill(-1);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test(expected = IllegalArgumentException.class)
|
||||||
|
public void testIllegalConsume() {
|
||||||
|
intStorage.consume(-1);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test(expected = IllegalArgumentException.class)
|
||||||
|
public void testIllegalLowerBoundConstructor() {
|
||||||
|
new IntStorage(-1, Oil.INSTANCE, MAX);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testUpperBoundConstructor() {
|
||||||
|
final IntStorage storage = new IntStorage(MAX + 1, Oil.INSTANCE, MAX);
|
||||||
|
assertEquals(MAX, storage.getStored());
|
||||||
|
}
|
||||||
|
}
|
123
uebung06/src/sudoku/Field.java
Normal file
123
uebung06/src/sudoku/Field.java
Normal file
@@ -0,0 +1,123 @@
|
|||||||
|
package sudoku;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.EnumSet;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
import static java.util.Collections.emptySet;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A field of a Sudoku board.
|
||||||
|
*/
|
||||||
|
public class Field {
|
||||||
|
private static final int DEP_LENGTH = 2 * Sudoku.SIZE + 2;
|
||||||
|
public final Sudoku sudoku;
|
||||||
|
public final int x;
|
||||||
|
public final int y;
|
||||||
|
private Value value;
|
||||||
|
private List<Field> dependents;
|
||||||
|
private final Set<Value> domain = EnumSet.allOf(Value.class);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a field of the specified Sudoku board at the specified coordinates.
|
||||||
|
*
|
||||||
|
* @param sudoku the Sudoku board
|
||||||
|
* @param x x coordinate (0 <= x < 9)
|
||||||
|
* @param y y coordinate (0 <= y < 9)
|
||||||
|
*/
|
||||||
|
public Field(Sudoku sudoku, int x, int y) {
|
||||||
|
if (x < 0 || x >= Sudoku.SIZE || y < 0 || y >= Sudoku.SIZE)
|
||||||
|
throw new IllegalArgumentException("Illegal coordinates " + x + ", " + y);
|
||||||
|
this.sudoku = sudoku;
|
||||||
|
this.x = x;
|
||||||
|
this.y = y;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the value of this field, or null if it is empty.
|
||||||
|
*
|
||||||
|
* @return the value of this field, or null if it is empty.
|
||||||
|
*/
|
||||||
|
public Value getValue() {
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the value of this field
|
||||||
|
*
|
||||||
|
* @param v the value, or null if this field shall be empty.
|
||||||
|
*/
|
||||||
|
public void setValue(Value v) {
|
||||||
|
value = v;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Removes the value of this field so that it is empty.
|
||||||
|
*/
|
||||||
|
public void clearValue() {
|
||||||
|
setValue(null);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Checks whether this field is empty.
|
||||||
|
*
|
||||||
|
* @return true iff this field is empty.
|
||||||
|
*/
|
||||||
|
public boolean isEmpty() {
|
||||||
|
return value == null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns a string representation of this field. As a matter of fact,
|
||||||
|
* its value is returned, or "." if it is empty.
|
||||||
|
*
|
||||||
|
* @return a string representation of this field.
|
||||||
|
*/
|
||||||
|
public String toString() {
|
||||||
|
return isEmpty() ? "." : value.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the set of all values possible for this field that do not violate the Sudoku constraints,
|
||||||
|
* if the field is empty. Otherwise, it returns the empty set. The returned set may be modified if
|
||||||
|
* the field is empty.
|
||||||
|
*
|
||||||
|
* @return the domain of this field.
|
||||||
|
*/
|
||||||
|
public Set<Value> getDomain() {
|
||||||
|
return isEmpty() ? domain : emptySet();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the list of all other fields of this Sudoku field whose values are constrained by the
|
||||||
|
* value of this field.
|
||||||
|
*
|
||||||
|
* @return the list of all dependent fields.
|
||||||
|
*/
|
||||||
|
List<Field> getDependents() {
|
||||||
|
if (dependents == null) {
|
||||||
|
dependents = new ArrayList<>(DEP_LENGTH);
|
||||||
|
|
||||||
|
// fill the list with all fields in the given row and column
|
||||||
|
for (int i = 0; i < Sudoku.SIZE; i++) {
|
||||||
|
if (i != x)
|
||||||
|
dependents.add(sudoku.field(i, y));
|
||||||
|
if (i != y)
|
||||||
|
dependents.add(sudoku.field(x, i));
|
||||||
|
}
|
||||||
|
|
||||||
|
// determine the coordinates of the upper left corner of this field's block
|
||||||
|
final int x0 = 3 * (x / 3);
|
||||||
|
final int y0 = 3 * (y / 3);
|
||||||
|
|
||||||
|
// fill the list with the whole block
|
||||||
|
for (int x1 = x0; x1 < x0 + 3; x1++)
|
||||||
|
if (x1 != x)
|
||||||
|
for (int y1 = y0; y1 < y0 + 3; y1++)
|
||||||
|
if (y1 != y)
|
||||||
|
dependents.add(sudoku.field(x1, y1));
|
||||||
|
}
|
||||||
|
return dependents;
|
||||||
|
}
|
||||||
|
}
|
206
uebung06/src/sudoku/Sudoku.java
Normal file
206
uebung06/src/sudoku/Sudoku.java
Normal file
@@ -0,0 +1,206 @@
|
|||||||
|
package sudoku;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A Sudoku board as a matrix of {@linkplain sudoku.Field} instances.
|
||||||
|
* <p>
|
||||||
|
* Call {@linkplain #solve()} to solve it.
|
||||||
|
*/
|
||||||
|
public class Sudoku {
|
||||||
|
/**
|
||||||
|
* Edge size of the Sudoku board.
|
||||||
|
*/
|
||||||
|
public static final int SIZE = 9;
|
||||||
|
private static final String LS = System.lineSeparator();
|
||||||
|
private final Field[] board = new Field[SIZE * SIZE];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a Sudoku board with all of its fields being empty.
|
||||||
|
*/
|
||||||
|
public Sudoku() {
|
||||||
|
for (int x = 0; x < SIZE; x++)
|
||||||
|
for (int y = 0; y < SIZE; y++)
|
||||||
|
board[SIZE * y + x] = new Field(this, x, y);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the field at the specified coordinates
|
||||||
|
*
|
||||||
|
* @param x x coordinate (0 <= x < 9)
|
||||||
|
* @param y y coordinate (0 <= x < 9)
|
||||||
|
* @return the field at the specified coordinates
|
||||||
|
*/
|
||||||
|
public Field field(int x, int y) {
|
||||||
|
return board[SIZE * y + x];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Bulk operation to set values of the fields.
|
||||||
|
*
|
||||||
|
* @param values a sequence of integers where 0 means empty
|
||||||
|
*/
|
||||||
|
public void initialize(int... values) {
|
||||||
|
if (values.length != board.length)
|
||||||
|
throw new IllegalArgumentException("Wrong Sudoku board with " + values.length + " values");
|
||||||
|
for (int i = 0; i < values.length; i++)
|
||||||
|
if (values[i] != 0)
|
||||||
|
setValue(board[i], Value.of(values[i]));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the specified value of the specified empty field
|
||||||
|
*
|
||||||
|
* @param field the empty field whose value is set
|
||||||
|
* @param value the value of the field
|
||||||
|
* @throws IllegalStateException if the field is not empty
|
||||||
|
* @throws IllegalArgumentException if setting this value would violate the Sudoku constraints
|
||||||
|
* @throws NullPointerException if the value is null
|
||||||
|
*/
|
||||||
|
public void setValue(Field field, Value value) {
|
||||||
|
if (value == null)
|
||||||
|
throw new NullPointerException("value is null");
|
||||||
|
if (!field.isEmpty())
|
||||||
|
throw new IllegalStateException("Value already set: " + field);
|
||||||
|
if (!field.getDomain().contains(value))
|
||||||
|
throw new IllegalArgumentException(value + " is not permitted");
|
||||||
|
for (Field dependent : field.getDependents())
|
||||||
|
dependent.getDomain().remove(value);
|
||||||
|
field.setValue(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns a string representation of this board.
|
||||||
|
*
|
||||||
|
* @return a string representation of this board
|
||||||
|
*/
|
||||||
|
public String toString() {
|
||||||
|
StringBuilder sb = new StringBuilder();
|
||||||
|
for (int y = 0; y < SIZE; y++) {
|
||||||
|
if (y == 3 || y == 6) sb.append("---------+---------+---------").append(LS);
|
||||||
|
for (int x = 0; x < SIZE; x++) {
|
||||||
|
if (x == 3 || x == 6) sb.append("|");
|
||||||
|
sb.append(" ").append(field(x, y)).append(" ");
|
||||||
|
}
|
||||||
|
sb.append(LS);
|
||||||
|
}
|
||||||
|
return sb.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Looks for an empty field with minimal domain.
|
||||||
|
*
|
||||||
|
* @return a field with minimal domain, or null no field is empty
|
||||||
|
*/
|
||||||
|
private Field findBestCandidate() {
|
||||||
|
Field best = null;
|
||||||
|
int min = Integer.MAX_VALUE;
|
||||||
|
for (Field f : board)
|
||||||
|
if (f.isEmpty() && f.getDomain().size() < min) {
|
||||||
|
best = f;
|
||||||
|
min = best.getDomain().size();
|
||||||
|
}
|
||||||
|
return best;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Tries to solve the current board. The board is in the solved state if a solution is found,
|
||||||
|
* and unmodified if no solution is found.
|
||||||
|
*
|
||||||
|
* @return true iff a solution has been found.
|
||||||
|
*/
|
||||||
|
public boolean solve() {
|
||||||
|
final Field field = findBestCandidate();
|
||||||
|
if (field == null)
|
||||||
|
// A solution has been found
|
||||||
|
return true;
|
||||||
|
|
||||||
|
// There are empty fields. Try all values of its domain
|
||||||
|
final List<Field> revoke = new ArrayList<>();
|
||||||
|
for (Value v : field.getDomain()) {
|
||||||
|
field.setValue(v);
|
||||||
|
boolean consistent = true;
|
||||||
|
for (Field dependent : field.getDependents())
|
||||||
|
if (dependent.getDomain().contains(v)) {
|
||||||
|
if (dependent.getDomain().size() == 1) {
|
||||||
|
// This is a dead end because field 'dependent'
|
||||||
|
// would have an empty domain
|
||||||
|
consistent = false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
revoke.add(dependent);
|
||||||
|
dependent.getDomain().remove(v);
|
||||||
|
}
|
||||||
|
if (consistent && solve())
|
||||||
|
return true;
|
||||||
|
|
||||||
|
// Choosing v as a value lead to a dead end.
|
||||||
|
// Revoke all modifications
|
||||||
|
field.clearValue();
|
||||||
|
for (Field f : revoke)
|
||||||
|
f.getDomain().add(v);
|
||||||
|
revoke.clear();
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<Sudoku> solveAll() {
|
||||||
|
List<Sudoku> solutions = new ArrayList<>();
|
||||||
|
solveAll(solutions);
|
||||||
|
return solutions;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void solveAll(List<Sudoku> solutions) {
|
||||||
|
final Field field = findBestCandidate();
|
||||||
|
if (field == null) {
|
||||||
|
// A solution has been found
|
||||||
|
Sudoku copy = new Sudoku();
|
||||||
|
copy.initialize(this.export());
|
||||||
|
solutions.add(copy);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// There are empty fields. Try all values of its domain
|
||||||
|
final List<Field> revoke = new ArrayList<>();
|
||||||
|
for (Value v : field.getDomain()) {
|
||||||
|
field.setValue(v);
|
||||||
|
boolean consistent = true;
|
||||||
|
for (Field dependent : field.getDependents())
|
||||||
|
if (dependent.getDomain().contains(v)) {
|
||||||
|
if (dependent.getDomain().size() == 1) {
|
||||||
|
// This is a dead end because field 'dependent'
|
||||||
|
// would have an empty domain
|
||||||
|
consistent = false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
revoke.add(dependent);
|
||||||
|
dependent.getDomain().remove(v);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (consistent) solveAll(solutions);
|
||||||
|
|
||||||
|
// Revoke all modifications
|
||||||
|
field.clearValue();
|
||||||
|
for (Field f : revoke)
|
||||||
|
f.getDomain().add(v);
|
||||||
|
revoke.clear();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private int[] export() {
|
||||||
|
int[] values = new int[SIZE * SIZE];
|
||||||
|
int idx = 0;
|
||||||
|
while (idx < values.length) {
|
||||||
|
Field f = board[idx];
|
||||||
|
if (f != null) {
|
||||||
|
Value value = f.getValue();
|
||||||
|
if (value != null) values[idx] = value.getId();
|
||||||
|
else values[idx] = 0;
|
||||||
|
}
|
||||||
|
else throw new IllegalStateException("at least one field is not set");
|
||||||
|
++idx;
|
||||||
|
}
|
||||||
|
return values;
|
||||||
|
}
|
||||||
|
}
|
68
uebung06/src/sudoku/SudokuApp.java
Normal file
68
uebung06/src/sudoku/SudokuApp.java
Normal file
@@ -0,0 +1,68 @@
|
|||||||
|
package sudoku;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
public class SudokuApp {
|
||||||
|
|
||||||
|
public static void main(String[] args) {
|
||||||
|
System.out.println("Sudoku Aufgabenblatt:");
|
||||||
|
System.out.println();
|
||||||
|
final Sudoku boardBlatt = new Sudoku();
|
||||||
|
boardBlatt.initialize(4, 5, 0, 0, 0, 0, 2, 0, 0,
|
||||||
|
6, 0, 0, 0, 2, 4, 8, 0, 0,
|
||||||
|
8, 0, 0, 0, 6, 1, 3, 0, 0,
|
||||||
|
0, 9, 0, 4, 0, 0, 0, 5, 0,
|
||||||
|
0, 1, 0, 2, 0, 8, 0, 7, 0,
|
||||||
|
0, 3, 0, 0, 0, 9, 0, 8, 0,
|
||||||
|
0, 0, 7, 1, 4, 0, 0, 0, 8,
|
||||||
|
0, 0, 2, 7, 9, 0, 0, 0, 6,
|
||||||
|
0, 0, 5, 0, 0, 0, 0, 2, 1);
|
||||||
|
printSolution(boardBlatt);
|
||||||
|
|
||||||
|
System.out.println("Sudoku Handzettel:");
|
||||||
|
System.out.println();
|
||||||
|
final Sudoku boardHandzettel = new Sudoku();
|
||||||
|
boardHandzettel.initialize(7, 0, 0, 0, 2, 5, 0, 0, 0,
|
||||||
|
0, 0, 0, 0, 0, 0, 0, 9, 1,
|
||||||
|
0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
|
4, 0, 9, 1, 0, 0, 0, 0, 0,
|
||||||
|
0, 0, 0, 6, 0, 0, 2, 0, 0,
|
||||||
|
0, 0, 0, 0, 0, 0, 0, 3, 0,
|
||||||
|
8, 2, 0, 0, 0, 0, 5, 0, 0,
|
||||||
|
0, 0, 0, 0, 3, 0, 6, 0, 0,
|
||||||
|
0, 0, 0, 9, 0, 0, 0, 0, 0);
|
||||||
|
printSolution(boardHandzettel);
|
||||||
|
|
||||||
|
System.out.println("Sudoku mit 2 Lösungen:");
|
||||||
|
System.out.println();
|
||||||
|
final Sudoku boardWithTwoSolutions = new Sudoku();
|
||||||
|
boardWithTwoSolutions.initialize(2, 9, 5, 7, 4, 3, 8, 6, 1,
|
||||||
|
4, 3, 1, 8, 6, 5, 9, 0, 0,
|
||||||
|
8, 7, 6, 1, 9, 2, 5, 4, 3,
|
||||||
|
3, 8, 7, 4, 5, 9, 2, 1, 6,
|
||||||
|
6, 1, 2, 3, 8, 7, 4, 9, 5,
|
||||||
|
5, 4, 9, 2, 1, 6, 7, 3, 8,
|
||||||
|
7, 6, 3, 5, 2, 4, 1, 8, 9,
|
||||||
|
9, 2, 8, 6, 7, 1, 3, 5, 4,
|
||||||
|
1, 5, 4, 9, 3, 8, 6, 0, 0);
|
||||||
|
System.out.println(boardWithTwoSolutions);
|
||||||
|
System.out.println("Solutions:");
|
||||||
|
System.out.println();
|
||||||
|
|
||||||
|
List<Sudoku> solutions = boardWithTwoSolutions.solveAll();
|
||||||
|
System.out.println(String.join(System.lineSeparator(), solutions.stream().map(Sudoku::toString).toList()));
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void printSolution(Sudoku sudoku) {
|
||||||
|
System.out.println(sudoku);
|
||||||
|
|
||||||
|
System.out.println();
|
||||||
|
if (sudoku.solve()) {
|
||||||
|
System.out.println("Solution:");
|
||||||
|
System.out.println();
|
||||||
|
System.out.println(sudoku);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
System.out.println("No solution!");
|
||||||
|
}
|
||||||
|
}
|
41
uebung06/src/sudoku/Value.java
Normal file
41
uebung06/src/sudoku/Value.java
Normal file
@@ -0,0 +1,41 @@
|
|||||||
|
package sudoku;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The enumeration type of all possible values of a Sudoku field.
|
||||||
|
*/
|
||||||
|
public enum Value {
|
||||||
|
ONE(1), TWO(2), THREE(3), FOUR(4), FIVE(5), SIX(6), SEVEN(7), EIGHT(8), NINE(9);
|
||||||
|
|
||||||
|
private final int id;
|
||||||
|
|
||||||
|
Value(int id) {
|
||||||
|
this.id = id;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns a string representation of this value. As a matter of fact, its id is returned.
|
||||||
|
*
|
||||||
|
* @return a string representation of this value.
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return String.valueOf(id);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the value with the specified id.
|
||||||
|
*
|
||||||
|
* @param id an id (1 <= id <= 9)
|
||||||
|
* @return the value with the specified id.
|
||||||
|
*/
|
||||||
|
public static Value of(int id) {
|
||||||
|
return values()[id - 1];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the id of this instance.
|
||||||
|
*
|
||||||
|
* @return the id of this instance.
|
||||||
|
*/
|
||||||
|
public int getId() {return id;}
|
||||||
|
}
|
65
uebung06/test/sudoku/FieldTest.java
Normal file
65
uebung06/test/sudoku/FieldTest.java
Normal file
@@ -0,0 +1,65 @@
|
|||||||
|
package uebung06.test.sudoku;
|
||||||
|
|
||||||
|
import org.junit.Before;
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
import sudoku.*;
|
||||||
|
|
||||||
|
import static org.junit.Assert.assertEquals;
|
||||||
|
import static org.junit.Assert.assertNull;
|
||||||
|
import static org.junit.Assert.assertTrue;
|
||||||
|
|
||||||
|
public class FieldTest {
|
||||||
|
private static final int X = 8;
|
||||||
|
private static final int Y = 5;
|
||||||
|
private static final int NUL = -1;
|
||||||
|
private static final Value VAL = Value.EIGHT;
|
||||||
|
private static Sudoku sudoku;
|
||||||
|
private static Field field;
|
||||||
|
|
||||||
|
@Before
|
||||||
|
public void init() {
|
||||||
|
sudoku = new Sudoku();
|
||||||
|
field = new Field(sudoku, X, Y);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test(expected = IllegalArgumentException.class)
|
||||||
|
public void illegalXLowerBoundFieldTest() {
|
||||||
|
field = new Field(sudoku, NUL, Y);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test(expected = IllegalArgumentException.class)
|
||||||
|
public void illegalXUpperBoundFieldTest() {
|
||||||
|
field = new Field(sudoku, Sudoku.SIZE, Y);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test(expected = IllegalArgumentException.class)
|
||||||
|
public void illegalYLowerBoundFieldTest() {
|
||||||
|
field = new Field(sudoku, X, NUL);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test(expected = IllegalArgumentException.class)
|
||||||
|
public void illegalYUpperBoundFieldTest() {
|
||||||
|
field = new Field(sudoku, X, Sudoku.SIZE);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void valueFieldTest() {
|
||||||
|
field.setValue(VAL);
|
||||||
|
assertEquals(field.getValue(), VAL);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void clearValueFieldTest() {
|
||||||
|
field.setValue(VAL);
|
||||||
|
field.clearValue();
|
||||||
|
assertNull(field.getValue());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void isValueEmptyFieldTest() {
|
||||||
|
field.setValue(VAL);
|
||||||
|
field.clearValue();
|
||||||
|
assertTrue(field.isEmpty());
|
||||||
|
}
|
||||||
|
}
|
129
uebung06/test/sudoku/SudokuAppTest.java
Normal file
129
uebung06/test/sudoku/SudokuAppTest.java
Normal file
@@ -0,0 +1,129 @@
|
|||||||
|
package uebung06.test.sudoku;
|
||||||
|
|
||||||
|
import org.junit.Before;
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
import sudoku.*;
|
||||||
|
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.HashSet;
|
||||||
|
import java.util.stream.IntStream;
|
||||||
|
|
||||||
|
import static org.junit.Assert.assertFalse;
|
||||||
|
import static org.junit.Assert.assertTrue;
|
||||||
|
|
||||||
|
public class SudokuAppTest {
|
||||||
|
private static final int MAX = 81;
|
||||||
|
private static final int MIN = 0;
|
||||||
|
private static final int SUDOKU_SIZE = 9;
|
||||||
|
private static Sudoku board;
|
||||||
|
private static int[] init;
|
||||||
|
private static int[] wrongSol;
|
||||||
|
|
||||||
|
@Before
|
||||||
|
public void init() {
|
||||||
|
board = new Sudoku();
|
||||||
|
init = IntStream.of(4, 5, 0, 0, 0, 0, 2, 0, 0,
|
||||||
|
6, 0, 0, 0, 2, 4, 8, 0, 0,
|
||||||
|
8, 0, 0, 0, 6, 1, 3, 0, 0,
|
||||||
|
0, 9, 0, 4, 0, 0, 0, 5, 0,
|
||||||
|
0, 1, 0, 2, 0, 8, 0, 7, 0,
|
||||||
|
0, 3, 0, 0, 0, 9, 0, 8, 0,
|
||||||
|
0, 0, 7, 1, 4, 0, 0, 0, 8,
|
||||||
|
0, 0, 2, 7, 9, 0, 0, 0, 6,
|
||||||
|
0, 0, 5, 0, 0, 0, 0, 2, 1).toArray();
|
||||||
|
wrongSol = IntStream.of(4, 5, 1, 8, 7, 3, 2, 6, 9,
|
||||||
|
6, 7, 3, 9, 2, 4, 8, 1, 5,
|
||||||
|
8, 2, 9, 5, 6, 1, 3, 4, 7,
|
||||||
|
2, 9, 8, 4, 1, 7, 6, 5, 3,
|
||||||
|
5, 1, 6, 2, 3, 8, 9, 7, 4,
|
||||||
|
7, 3, 4, 6, 5, 9, 1, 8, 2,
|
||||||
|
3, 6, 7, 1, 4, 2, 5, 9, 8,
|
||||||
|
1, 8, 2, 7, 9, 5, 4, 3, 6,
|
||||||
|
9, 5, 4, 3, 8, 6, 7, 2, 1).toArray();
|
||||||
|
}
|
||||||
|
|
||||||
|
//Testing first If-condition in Sudoku.init
|
||||||
|
@Test(expected = IllegalArgumentException.class)
|
||||||
|
public void illegalLowerBoundInitSudokuAppTest() {
|
||||||
|
board.initialize(IntStream.range(MIN, MIN+1).toArray());
|
||||||
|
}
|
||||||
|
|
||||||
|
//Testing first If-condition in Sudoku.init
|
||||||
|
@Test(expected = IllegalArgumentException.class)
|
||||||
|
public void illegalUpperBoundInitSudokuAppTest() {
|
||||||
|
board.initialize(IntStream.range(MIN, MAX+1).toArray());
|
||||||
|
}
|
||||||
|
|
||||||
|
//Testing ArrayIndex of Value
|
||||||
|
@Test(expected = ArrayIndexOutOfBoundsException.class)
|
||||||
|
public void illegalArrayIndexOutOfBoundInitSudokuAppTest() {
|
||||||
|
board.initialize(IntStream.range(MIN, MAX).toArray());
|
||||||
|
}
|
||||||
|
|
||||||
|
//Testing Sudoku.solve()
|
||||||
|
@Test
|
||||||
|
public void correctSolutionSudokuAppTest() {
|
||||||
|
board.initialize(init);
|
||||||
|
board.solve();
|
||||||
|
|
||||||
|
assertTrue(verifySudokuSol());
|
||||||
|
}
|
||||||
|
|
||||||
|
//Just testing verifySudokuSol-Method
|
||||||
|
@Test
|
||||||
|
public void wrongSolutionSudokuAppTest() {
|
||||||
|
try {
|
||||||
|
board.initialize(wrongSol);
|
||||||
|
} catch (final IllegalArgumentException e) {
|
||||||
|
//do nothing, just handling throwing exceptions from Sudoku-class
|
||||||
|
}
|
||||||
|
|
||||||
|
assertFalse(verifySudokuSol());
|
||||||
|
}
|
||||||
|
|
||||||
|
public Boolean verifySudokuSol() {
|
||||||
|
HashSet<Value> rows = new HashSet<>();
|
||||||
|
HashSet<Value> cols = new HashSet<>();
|
||||||
|
|
||||||
|
HashMap<Integer, HashSet<Value>> blocks = new HashMap<>();
|
||||||
|
IntStream.range(0, SUDOKU_SIZE)
|
||||||
|
.forEach(block -> blocks.put(block, new HashSet<>())); //init Hashsets for every block
|
||||||
|
|
||||||
|
for (int y = 0; y < SUDOKU_SIZE; y++) {
|
||||||
|
for (int x = 0; x < SUDOKU_SIZE; x++) {
|
||||||
|
//check column
|
||||||
|
Value val = board.field(x, y).getValue();
|
||||||
|
if (!cols.add(val))
|
||||||
|
return false;
|
||||||
|
if (cols.size() == SUDOKU_SIZE)
|
||||||
|
cols.clear();
|
||||||
|
|
||||||
|
//check row
|
||||||
|
val = board.field(y, x).getValue();
|
||||||
|
if (!rows.add(val))
|
||||||
|
return false;
|
||||||
|
if (rows.size() == SUDOKU_SIZE)
|
||||||
|
rows.clear();
|
||||||
|
|
||||||
|
//check 3x3 block
|
||||||
|
val = board.field(x, y).getValue();
|
||||||
|
if (!blocks.get(getBlockIndex(x, y)).add(val))
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getBlockIndex(int x, int y) {
|
||||||
|
return getColIndex(x) + getRowIndex(y);
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getColIndex(int x) {
|
||||||
|
return x / 3;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getRowIndex(int y) {
|
||||||
|
return (y/3)*3;
|
||||||
|
}
|
||||||
|
}
|
79
uebung07/src/oop/ch02/cards/Card.java
Normal file
79
uebung07/src/oop/ch02/cards/Card.java
Normal file
@@ -0,0 +1,79 @@
|
|||||||
|
package oop.ch02.cards;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Represents any card with a name and a unique serial number.
|
||||||
|
*
|
||||||
|
* @author Mark Minas
|
||||||
|
*/
|
||||||
|
public class Card {
|
||||||
|
/**
|
||||||
|
* The name of this card.
|
||||||
|
*/
|
||||||
|
private final String name;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Counts the number of instantiations of this class.
|
||||||
|
*/
|
||||||
|
private static int counter = 0;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The unique serial number of this card.
|
||||||
|
*/
|
||||||
|
private final int number;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a new card with the specified name.
|
||||||
|
*
|
||||||
|
* @param name the name of this card
|
||||||
|
*/
|
||||||
|
public Card(String name) {
|
||||||
|
if (name == null)
|
||||||
|
throw new NullPointerException("name is null");
|
||||||
|
this.name = name;
|
||||||
|
this.number = ++counter;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a new card for a student with the specified number.
|
||||||
|
*
|
||||||
|
* @param num the student's number
|
||||||
|
*/
|
||||||
|
public Card(int num) {
|
||||||
|
this("MatrNr. " + num);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the name of this card.
|
||||||
|
*
|
||||||
|
* @return the name
|
||||||
|
*/
|
||||||
|
public String getName() {
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the serial number of this card.
|
||||||
|
*
|
||||||
|
* @return the serial number
|
||||||
|
*/
|
||||||
|
public int getNumber() {
|
||||||
|
return number;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the number of instantiations of this class.
|
||||||
|
*
|
||||||
|
* @return the number of instantiations.
|
||||||
|
*/
|
||||||
|
public static int getCounter() {
|
||||||
|
return counter;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns a string representation of this card.
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return "Card " + name + " (no " + number + ")";
|
||||||
|
}
|
||||||
|
}
|
34
uebung07/src/oop/ch05/mensa/AccountCard.java
Normal file
34
uebung07/src/oop/ch05/mensa/AccountCard.java
Normal file
@@ -0,0 +1,34 @@
|
|||||||
|
package oop.ch05.mensa;
|
||||||
|
|
||||||
|
import oop.ch05.secured.AuthorizationException;
|
||||||
|
import oop.ch05.secured.SecuredContent;
|
||||||
|
import oop.ch05.secured.SecurityClient;
|
||||||
|
|
||||||
|
public class AccountCard extends MensaCard {
|
||||||
|
private final SecuredContent<String> account;
|
||||||
|
|
||||||
|
public AccountCard(String key, String account, int password) {
|
||||||
|
super(key, Color.white);
|
||||||
|
this.account = new SecuredContent<>(password, account);
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getAccount() {
|
||||||
|
return account.getContent();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setAccount(SecurityClient client, String account) throws AuthorizationException {
|
||||||
|
if (account == null || account.trim().isEmpty())
|
||||||
|
throw new IllegalArgumentException("Invalid account " + account);
|
||||||
|
this.account.setContent(client, account);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return super.toString() + " for account " + account.getContent();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void pass(CashPoint cashPoint) throws RejectedException, AuthorizationException {
|
||||||
|
cashPoint.charge(this);
|
||||||
|
}
|
||||||
|
}
|
51
uebung07/src/oop/ch05/mensa/AccountManagement.java
Normal file
51
uebung07/src/oop/ch05/mensa/AccountManagement.java
Normal file
@@ -0,0 +1,51 @@
|
|||||||
|
package oop.ch05.mensa;
|
||||||
|
|
||||||
|
import oop.ch05.secured.AuthorizationException;
|
||||||
|
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Random;
|
||||||
|
import java.util.TreeMap;
|
||||||
|
|
||||||
|
public class AccountManagement {
|
||||||
|
private final int password;
|
||||||
|
public final String name;
|
||||||
|
private final Random random = new Random();
|
||||||
|
private final Map<String, Integer> accounts = new TreeMap<>();
|
||||||
|
|
||||||
|
public AccountManagement(int password, String name) {
|
||||||
|
this.password = password;
|
||||||
|
this.name = name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void deposit(String account, int euros) {
|
||||||
|
final int amount = accounts.getOrDefault(account, 0);
|
||||||
|
accounts.put(account, amount + 100 * euros);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void pay(AccountCard card, int price, CashPoint cashPoint) throws RejectedException, AuthorizationException {
|
||||||
|
final int amount = accounts.getOrDefault(card.getAccount(), 0);
|
||||||
|
final int challenge = nextChallenge();
|
||||||
|
if (cashPoint.challengeResponse(challenge) != requiredResponse(challenge))
|
||||||
|
throw new AuthorizationException(cashPoint + " is not authorized to access accounts on " + name);
|
||||||
|
if (amount < price)
|
||||||
|
throw new RejectedException(card + " bounced");
|
||||||
|
accounts.put(card.getAccount(), amount - price);
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getAmount(String account) {
|
||||||
|
return accounts.getOrDefault(account, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
private int nextChallenge() {
|
||||||
|
return random.nextInt();
|
||||||
|
}
|
||||||
|
|
||||||
|
private int requiredResponse(int challenge) {
|
||||||
|
return challenge ^ password;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return "Account Management " + name + " " + accounts;
|
||||||
|
}
|
||||||
|
}
|
43
uebung07/src/oop/ch05/mensa/CashCard.java
Normal file
43
uebung07/src/oop/ch05/mensa/CashCard.java
Normal file
@@ -0,0 +1,43 @@
|
|||||||
|
package oop.ch05.mensa;
|
||||||
|
|
||||||
|
import oop.ch05.secured.AuthorizationException;
|
||||||
|
import oop.ch05.secured.SecuredContent;
|
||||||
|
|
||||||
|
public class CashCard extends MensaCard {
|
||||||
|
private final SecuredContent<Integer> balance;
|
||||||
|
|
||||||
|
public CashCard(String key, Color color, int password) {
|
||||||
|
super(key, color);
|
||||||
|
balance = new SecuredContent<>(password, 0);
|
||||||
|
if (color != Color.blue && color != Color.green)
|
||||||
|
throw new IllegalArgumentException("Invalid CashCard color " + color);
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getBalance() {
|
||||||
|
return balance.getContent();
|
||||||
|
}
|
||||||
|
|
||||||
|
void deposit(VendingMachine client, int cents)
|
||||||
|
throws AuthorizationException {
|
||||||
|
if (cents <= 0)
|
||||||
|
throw new IllegalArgumentException("Non-positive deposit");
|
||||||
|
final int newBalance = getBalance() + cents;
|
||||||
|
balance.setContent(client, newBalance);
|
||||||
|
}
|
||||||
|
|
||||||
|
void charge(CashPoint client, int cents) throws AuthorizationException {
|
||||||
|
if (cents < 0)
|
||||||
|
throw new IllegalArgumentException("Negative charge");
|
||||||
|
balance.setContent(client, getBalance() - cents);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return super.toString() + " with " + balance.getContent() + " cents";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void pass(CashPoint cashPoint) throws AuthorizationException, RejectedException {
|
||||||
|
cashPoint.charge(this);
|
||||||
|
}
|
||||||
|
}
|
65
uebung07/src/oop/ch05/mensa/CashPoint.java
Normal file
65
uebung07/src/oop/ch05/mensa/CashPoint.java
Normal file
@@ -0,0 +1,65 @@
|
|||||||
|
package oop.ch05.mensa;
|
||||||
|
|
||||||
|
import oop.ch05.secured.AuthorizationException;
|
||||||
|
import oop.ch05.secured.SecurityClient;
|
||||||
|
|
||||||
|
public class CashPoint implements SecurityClient {
|
||||||
|
private final int password;
|
||||||
|
public final String name;
|
||||||
|
private final AccountManagement accountMgmt;
|
||||||
|
private int counter;
|
||||||
|
private int cents;
|
||||||
|
|
||||||
|
public CashPoint(String name, int password, AccountManagement accountMgmt) {
|
||||||
|
this.name = name;
|
||||||
|
this.password = password;
|
||||||
|
this.accountMgmt = accountMgmt;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int challengeResponse(int challenge) {
|
||||||
|
return challenge ^ password;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return "Cash point " + name + " (" + getCounter() + " meals, " + getCents() + " cents charged)";
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getCounter() {
|
||||||
|
return counter;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getCents() {
|
||||||
|
return cents;
|
||||||
|
}
|
||||||
|
|
||||||
|
private int getPrice(Color color) {
|
||||||
|
return switch (color) {
|
||||||
|
case green -> 267;
|
||||||
|
case blue -> 357;
|
||||||
|
case white -> 495;
|
||||||
|
default -> 0;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
void count(MensaCard card) {
|
||||||
|
counter++;
|
||||||
|
}
|
||||||
|
|
||||||
|
void charge(CashCard cashCard) throws AuthorizationException, RejectedException {
|
||||||
|
final int price = getPrice(cashCard.color);
|
||||||
|
if (cashCard.getBalance() < price)
|
||||||
|
throw new RejectedException("insufficient payment");
|
||||||
|
cashCard.charge(this, price);
|
||||||
|
count(cashCard);
|
||||||
|
cents += price;
|
||||||
|
}
|
||||||
|
|
||||||
|
void charge(AccountCard accountCard) throws RejectedException, AuthorizationException {
|
||||||
|
final int price = getPrice(accountCard.color);
|
||||||
|
System.out.println("Charging " + price + " cents on account " + accountCard.getAccount());
|
||||||
|
accountMgmt.pay(accountCard, price, this);
|
||||||
|
count(accountCard);
|
||||||
|
cents += price;
|
||||||
|
}
|
||||||
|
}
|
5
uebung07/src/oop/ch05/mensa/Color.java
Normal file
5
uebung07/src/oop/ch05/mensa/Color.java
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
package oop.ch05.mensa;
|
||||||
|
|
||||||
|
public enum Color {
|
||||||
|
green, red, blue, white, gray
|
||||||
|
}
|
15
uebung07/src/oop/ch05/mensa/CountCard.java
Normal file
15
uebung07/src/oop/ch05/mensa/CountCard.java
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
package oop.ch05.mensa;
|
||||||
|
|
||||||
|
public class CountCard extends MensaCard {
|
||||||
|
|
||||||
|
public CountCard(String key, Color color) {
|
||||||
|
super(key, color);
|
||||||
|
if (color != Color.red && color != Color.gray)
|
||||||
|
throw new IllegalArgumentException("Invalid CountCard color " + color);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void pass(CashPoint cashPoint) {
|
||||||
|
cashPoint.count(this);
|
||||||
|
}
|
||||||
|
}
|
20
uebung07/src/oop/ch05/mensa/MensaCard.java
Normal file
20
uebung07/src/oop/ch05/mensa/MensaCard.java
Normal file
@@ -0,0 +1,20 @@
|
|||||||
|
package oop.ch05.mensa;
|
||||||
|
|
||||||
|
import oop.ch02.cards.Card;
|
||||||
|
import oop.ch05.secured.AuthorizationException;
|
||||||
|
|
||||||
|
public abstract class MensaCard extends Card {
|
||||||
|
public final Color color;
|
||||||
|
|
||||||
|
protected MensaCard(String name, Color color) {
|
||||||
|
super(name);
|
||||||
|
this.color = color;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return color + " card " + getNumber() + " (" + getName() + ")";
|
||||||
|
}
|
||||||
|
|
||||||
|
public abstract void pass(CashPoint cashPoint) throws RejectedException, AuthorizationException;
|
||||||
|
}
|
69
uebung07/src/oop/ch05/mensa/MensaExample.java
Normal file
69
uebung07/src/oop/ch05/mensa/MensaExample.java
Normal file
@@ -0,0 +1,69 @@
|
|||||||
|
package oop.ch05.mensa;
|
||||||
|
|
||||||
|
import oop.ch05.secured.AuthorizationException;
|
||||||
|
|
||||||
|
public class MensaExample {
|
||||||
|
public static void main(String[] args) {
|
||||||
|
AccountManagement mgmt = new AccountManagement(4711, "Uni");
|
||||||
|
VendingMachine vm1 = new VendingMachine("left", 4711);
|
||||||
|
VendingMachine vm2 = new VendingMachine("right", 4711);
|
||||||
|
VendingMachine tumVM = new VendingMachine("TUM Mensa", 3141);
|
||||||
|
CashPoint unibwMensa = new CashPoint("UniBw Mensa", 4711, mgmt);
|
||||||
|
|
||||||
|
AccountCard conf = new AccountCard("conference", "33-1298", 42);
|
||||||
|
MensaCard frankSmith = new CountCard("Frank Smith", Color.gray);
|
||||||
|
CashCard hansMueller = new CashCard("Hans Müller", Color.green, 4711);
|
||||||
|
CashCard peterSchmidt = new CashCard("Peter Schmidt", Color.green, 4711);
|
||||||
|
CashCard thomasMayer = new CashCard("Thomas Mayer", Color.blue, 4711);
|
||||||
|
|
||||||
|
deposit(vm1, hansMueller, 10);
|
||||||
|
deposit(vm1, peterSchmidt, 5);
|
||||||
|
deposit(vm2, thomasMayer, 2);
|
||||||
|
deposit(tumVM, hansMueller, 10);
|
||||||
|
|
||||||
|
System.out.println(vm1);
|
||||||
|
System.out.println(vm2);
|
||||||
|
System.out.println(tumVM);
|
||||||
|
System.out.println(hansMueller);
|
||||||
|
System.out.println(peterSchmidt);
|
||||||
|
System.out.println(thomasMayer);
|
||||||
|
System.out.println();
|
||||||
|
|
||||||
|
pass(hansMueller, unibwMensa);
|
||||||
|
System.out.println(hansMueller);
|
||||||
|
System.out.println(unibwMensa);
|
||||||
|
|
||||||
|
pass(frankSmith, unibwMensa);
|
||||||
|
pass(conf, unibwMensa);
|
||||||
|
pass(thomasMayer, unibwMensa);
|
||||||
|
pass(hansMueller, unibwMensa);
|
||||||
|
pass(hansMueller, unibwMensa);
|
||||||
|
pass(hansMueller, unibwMensa);
|
||||||
|
|
||||||
|
System.out.println(unibwMensa);
|
||||||
|
System.out.println(hansMueller);
|
||||||
|
System.out.println(peterSchmidt);
|
||||||
|
System.out.println(thomasMayer);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void pass(MensaCard mensaCard, CashPoint cashPoint) {
|
||||||
|
try {
|
||||||
|
mensaCard.pass(cashPoint);
|
||||||
|
}
|
||||||
|
catch (RejectedException e) {
|
||||||
|
System.out.println("rejected: " + e.getMessage());
|
||||||
|
}
|
||||||
|
catch (AuthorizationException e) {
|
||||||
|
System.out.println("authrozation failed: " + e.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void deposit(VendingMachine vm, CashCard cashCard, int euros) {
|
||||||
|
try {
|
||||||
|
vm.deposit(cashCard, euros);
|
||||||
|
}
|
||||||
|
catch (AuthorizationException e) {
|
||||||
|
System.out.println("authorization failed: " + e.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
7
uebung07/src/oop/ch05/mensa/RejectedException.java
Normal file
7
uebung07/src/oop/ch05/mensa/RejectedException.java
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
package oop.ch05.mensa;
|
||||||
|
|
||||||
|
public class RejectedException extends Exception {
|
||||||
|
public RejectedException(String message) {
|
||||||
|
super(message);
|
||||||
|
}
|
||||||
|
}
|
37
uebung07/src/oop/ch05/mensa/VendingMachine.java
Normal file
37
uebung07/src/oop/ch05/mensa/VendingMachine.java
Normal file
@@ -0,0 +1,37 @@
|
|||||||
|
package oop.ch05.mensa;
|
||||||
|
|
||||||
|
import oop.ch05.secured.AuthorizationException;
|
||||||
|
import oop.ch05.secured.SecurityClient;
|
||||||
|
|
||||||
|
public class VendingMachine implements SecurityClient {
|
||||||
|
private final int password;
|
||||||
|
public final String name;
|
||||||
|
private int euros;
|
||||||
|
|
||||||
|
public VendingMachine(String name, int password) {
|
||||||
|
this.name = name;
|
||||||
|
this.password = password;
|
||||||
|
this.euros = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int challengeResponse(int challenge) {
|
||||||
|
return challenge ^ password;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return "Vending machine " + name + " (contains EUR " + euros + ")";
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getEuros() {
|
||||||
|
return euros;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void deposit(CashCard card, int euros) throws AuthorizationException {
|
||||||
|
if (euros <= 0)
|
||||||
|
throw new IllegalArgumentException("Non-positive deposit");
|
||||||
|
card.deposit(this, euros * 100);
|
||||||
|
this.euros += euros;
|
||||||
|
}
|
||||||
|
}
|
20
uebung07/src/oop/ch05/secured/AuthorizationException.java
Normal file
20
uebung07/src/oop/ch05/secured/AuthorizationException.java
Normal file
@@ -0,0 +1,20 @@
|
|||||||
|
package oop.ch05.secured;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This class represents exceptions that are thrown whenever an authorization
|
||||||
|
* fails.
|
||||||
|
*
|
||||||
|
* @author Mark Minas
|
||||||
|
*/
|
||||||
|
public class AuthorizationException extends Exception {
|
||||||
|
/**
|
||||||
|
* Constructs a new authorization exception with the specified detail message
|
||||||
|
* and cause.
|
||||||
|
*
|
||||||
|
* @param message the detail message (which is saved for later retrieval by the
|
||||||
|
* {@link #getMessage()} method).
|
||||||
|
*/
|
||||||
|
public AuthorizationException(String message) {
|
||||||
|
super(message);
|
||||||
|
}
|
||||||
|
}
|
80
uebung07/src/oop/ch05/secured/SecuredContent.java
Normal file
80
uebung07/src/oop/ch05/secured/SecuredContent.java
Normal file
@@ -0,0 +1,80 @@
|
|||||||
|
package oop.ch05.secured;
|
||||||
|
|
||||||
|
import java.util.Random;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Represents containers for some content that is secured against modifications
|
||||||
|
* by a challenge-response approach. The content may be read at any time, but
|
||||||
|
* only authorized clients are allowed to modify the contents.
|
||||||
|
*
|
||||||
|
* @param <E> the type of the actual secured content
|
||||||
|
* @author Mark Minas
|
||||||
|
*/
|
||||||
|
public class SecuredContent<E> {
|
||||||
|
/**
|
||||||
|
* The actual, secured content
|
||||||
|
*/
|
||||||
|
private E content;
|
||||||
|
/**
|
||||||
|
* A random number generator used for generating challenges.
|
||||||
|
*/
|
||||||
|
private final Random random = new Random();
|
||||||
|
/**
|
||||||
|
* The password used for encryption.
|
||||||
|
*/
|
||||||
|
private final int password;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a new container containing the specified contents.
|
||||||
|
*
|
||||||
|
* @param password this password is used for computing the expected response for a
|
||||||
|
* challenge.
|
||||||
|
* @param content the contained content
|
||||||
|
*/
|
||||||
|
public SecuredContent(int password, E content) {
|
||||||
|
this.password = password;
|
||||||
|
this.content = content;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the contained contents. There is no authorization necessary for
|
||||||
|
* reading the contents.
|
||||||
|
*/
|
||||||
|
public E getContent() {
|
||||||
|
return content;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the new contained contents. Only authorized clients are allowed to do
|
||||||
|
* so.
|
||||||
|
*
|
||||||
|
* @param client The accessing client. Authorization is checked prior to really
|
||||||
|
* modifying he contained content.
|
||||||
|
* @param content The new contained contents
|
||||||
|
* @throws AuthorizationException if the specified client cannot authorize himself
|
||||||
|
*/
|
||||||
|
public void setContent(SecurityClient client, E content)
|
||||||
|
throws AuthorizationException {
|
||||||
|
final int challenge = nextChallenge();
|
||||||
|
if (client.challengeResponse(challenge) != requiredResponse(challenge))
|
||||||
|
throw new AuthorizationException(client
|
||||||
|
+ " is not authorized to access contents.");
|
||||||
|
this.content = content;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Computes the next random challenge.
|
||||||
|
*/
|
||||||
|
private int nextChallenge() {
|
||||||
|
return random.nextInt();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the expected response for the specified challenge.
|
||||||
|
*
|
||||||
|
* @param challenge an arbitrary integer used as a challenge
|
||||||
|
*/
|
||||||
|
private int requiredResponse(int challenge) {
|
||||||
|
return challenge ^ password;
|
||||||
|
}
|
||||||
|
}
|
18
uebung07/src/oop/ch05/secured/SecurityClient.java
Normal file
18
uebung07/src/oop/ch05/secured/SecurityClient.java
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
package oop.ch05.secured;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This interface must be implemented by any client that is going to be
|
||||||
|
* authorized by a challenge-response approach.
|
||||||
|
*
|
||||||
|
* @author Mark Minas
|
||||||
|
*/
|
||||||
|
public interface SecurityClient {
|
||||||
|
/**
|
||||||
|
* Returns the response for the specified challenge. Authorization succeeds
|
||||||
|
* if this response is the same as the one expected by the server.
|
||||||
|
*
|
||||||
|
* @param challenge the integer number for which the correct response has to be
|
||||||
|
* computed.
|
||||||
|
*/
|
||||||
|
int challengeResponse(int challenge);
|
||||||
|
}
|
22
uebung07/src/quantities/generic/Length.java
Normal file
22
uebung07/src/quantities/generic/Length.java
Normal file
@@ -0,0 +1,22 @@
|
|||||||
|
package quantities.generic;
|
||||||
|
|
||||||
|
import static quantities.generic.LengthUnit.METER;
|
||||||
|
import static quantities.generic.TimeUnit.SECOND;
|
||||||
|
import static quantities.generic.VelocityUnit.METER_PER_SECOND;
|
||||||
|
|
||||||
|
public class Length extends Quantity<Length>{
|
||||||
|
|
||||||
|
public Length(double value, Unit<Length> unit) {
|
||||||
|
super(value, unit);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Velocity div(Time t) {
|
||||||
|
return METER_PER_SECOND.quantity(this.value(METER) / t.value(SECOND));
|
||||||
|
}
|
||||||
|
|
||||||
|
public Time div(Velocity v) {
|
||||||
|
return SECOND.quantity(this.value(METER) / v.value(METER_PER_SECOND));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
19
uebung07/src/quantities/generic/LengthUnit.java
Normal file
19
uebung07/src/quantities/generic/LengthUnit.java
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
package quantities.generic;
|
||||||
|
|
||||||
|
public class LengthUnit extends Unit<Length> {
|
||||||
|
public LengthUnit(String name, double baseFactor) {
|
||||||
|
super(name, baseFactor);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static final LengthUnit METER = new LengthUnit("m", 1);
|
||||||
|
public static final LengthUnit MILLIMETER = new LengthUnit("mm", 0.001);
|
||||||
|
public static final LengthUnit KILOMETER = new LengthUnit("km", 1000);
|
||||||
|
public static final LengthUnit MILE = new LengthUnit("mi", 1609.344);
|
||||||
|
public static final LengthUnit LIGHTYEAR = new LengthUnit("ly", 9460730472580800.0);
|
||||||
|
public static final LengthUnit PARSEC = new LengthUnit("pc", 3.0856776e16);
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Length quantity(double value) {
|
||||||
|
return new Length(value, this);
|
||||||
|
}
|
||||||
|
}
|
55
uebung07/src/quantities/generic/Quantity.java
Normal file
55
uebung07/src/quantities/generic/Quantity.java
Normal file
@@ -0,0 +1,55 @@
|
|||||||
|
package quantities.generic;
|
||||||
|
|
||||||
|
public abstract class Quantity<Q extends Quantity<Q>> {
|
||||||
|
public final double value;
|
||||||
|
public final Unit<Q> unit;
|
||||||
|
|
||||||
|
protected Quantity(double value, Unit<Q> unit) {
|
||||||
|
this.value = value;
|
||||||
|
this.unit = unit;
|
||||||
|
}
|
||||||
|
|
||||||
|
public double getBaseValue() {
|
||||||
|
return value * unit.baseFactor;
|
||||||
|
}
|
||||||
|
|
||||||
|
public double value(Unit<Q> unit) {
|
||||||
|
return getBaseValue() / unit.baseFactor;
|
||||||
|
}
|
||||||
|
|
||||||
|
//neue Methoden
|
||||||
|
|
||||||
|
public Q plus(Q other) {
|
||||||
|
return unit.quantity(value + other.getBaseValue() / unit.baseFactor);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Q minus(Q other) {
|
||||||
|
return unit.quantity(value - other.getBaseValue() / unit.baseFactor);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Q mult(double f) {
|
||||||
|
return unit.quantity(value * f);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Q div(double f) {
|
||||||
|
return unit.quantity(value / f);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Q to(Unit<Q> unit) {
|
||||||
|
return unit.quantity(getBaseValue() / unit.baseFactor);
|
||||||
|
}
|
||||||
|
|
||||||
|
public double div(Q other) {
|
||||||
|
return getBaseValue() / other.getBaseValue();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return value + " " + unit;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String format(String fmt, Unit unit) {
|
||||||
|
return String.format(fmt, value(unit), unit);
|
||||||
|
}
|
||||||
|
}
|
11
uebung07/src/quantities/generic/Time.java
Normal file
11
uebung07/src/quantities/generic/Time.java
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
package quantities.generic;
|
||||||
|
|
||||||
|
public class Time extends Quantity<Time> {
|
||||||
|
public Time(double value, Unit<Time> unit) {
|
||||||
|
super(value, unit);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Length mult(Velocity v) {
|
||||||
|
return v.mult(this);
|
||||||
|
}
|
||||||
|
}
|
17
uebung07/src/quantities/generic/TimeUnit.java
Normal file
17
uebung07/src/quantities/generic/TimeUnit.java
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
package quantities.generic;
|
||||||
|
|
||||||
|
public class TimeUnit extends Unit<Time> {
|
||||||
|
public TimeUnit(String name, double baseFactor) {
|
||||||
|
super(name, baseFactor);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Time quantity(double value) {
|
||||||
|
return new Time(value, this);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static final TimeUnit SECOND = new TimeUnit("s", 1);
|
||||||
|
public static final TimeUnit MINUTE = new TimeUnit("min", 60);
|
||||||
|
public static final TimeUnit HOUR = new TimeUnit("h", 3600);
|
||||||
|
public static final TimeUnit DAY = new TimeUnit("d", 86400);
|
||||||
|
}
|
18
uebung07/src/quantities/generic/Unit.java
Normal file
18
uebung07/src/quantities/generic/Unit.java
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
package quantities.generic;
|
||||||
|
|
||||||
|
public abstract class Unit<T extends Quantity<T>> {
|
||||||
|
public final String name;
|
||||||
|
public final double baseFactor;
|
||||||
|
|
||||||
|
public Unit(String name, double baseFactor) {
|
||||||
|
this.name = name;
|
||||||
|
this.baseFactor = baseFactor;
|
||||||
|
}
|
||||||
|
|
||||||
|
public abstract T quantity(double value);
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
}
|
15
uebung07/src/quantities/generic/Velocity.java
Normal file
15
uebung07/src/quantities/generic/Velocity.java
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
package quantities.generic;
|
||||||
|
|
||||||
|
import static quantities.generic.LengthUnit.METER;
|
||||||
|
import static quantities.generic.TimeUnit.SECOND;
|
||||||
|
import static quantities.generic.VelocityUnit.METER_PER_SECOND;
|
||||||
|
|
||||||
|
public class Velocity extends Quantity<Velocity> {
|
||||||
|
public Velocity(double value, Unit<Velocity> unit) {
|
||||||
|
super(value, unit);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Length mult(Time t) {
|
||||||
|
return METER.quantity(this.value(METER_PER_SECOND) * t.value(SECOND));
|
||||||
|
}
|
||||||
|
}
|
16
uebung07/src/quantities/generic/VelocityUnit.java
Normal file
16
uebung07/src/quantities/generic/VelocityUnit.java
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
package quantities.generic;
|
||||||
|
|
||||||
|
public class VelocityUnit extends Unit<Velocity> {
|
||||||
|
public VelocityUnit(String name, double baseFactor) {
|
||||||
|
super(name, baseFactor);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Velocity quantity(double value) {
|
||||||
|
return new Velocity(value, this);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static final VelocityUnit METER_PER_SECOND = new VelocityUnit("m/s", 1);
|
||||||
|
public static final VelocityUnit KMH = new VelocityUnit("km/h", 1.0 / 3.6);
|
||||||
|
public static final VelocityUnit MPH = new VelocityUnit("mph", 0.44704);
|
||||||
|
}
|
46
uebung07/src/quantities/plain/Length.java
Normal file
46
uebung07/src/quantities/plain/Length.java
Normal file
@@ -0,0 +1,46 @@
|
|||||||
|
package quantities.plain;
|
||||||
|
|
||||||
|
import static quantities.plain.LengthUnit.METER;
|
||||||
|
import static quantities.plain.TimeUnit.SECOND;
|
||||||
|
import static quantities.plain.VelocityUnit.METER_PER_SECOND;
|
||||||
|
|
||||||
|
public class Length extends Quantity {
|
||||||
|
private final LengthUnit unit;
|
||||||
|
|
||||||
|
public Length(double value, LengthUnit unit) {
|
||||||
|
super(value, unit);
|
||||||
|
this.unit = unit;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Length plus(Length other) {
|
||||||
|
return new Length(value + other.getBaseValue() / unit.baseFactor, unit);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Length minus(Length other) {
|
||||||
|
return new Length(value - other.getBaseValue() / unit.baseFactor, unit);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Length mult(double f) {
|
||||||
|
return new Length(value * f, unit);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Length div(double f) {
|
||||||
|
return new Length(value / f, unit);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Length to(LengthUnit unit) {
|
||||||
|
return new Length(getBaseValue() / unit.baseFactor, unit);
|
||||||
|
}
|
||||||
|
|
||||||
|
public double div(Length other) {
|
||||||
|
return getBaseValue() / other.getBaseValue();
|
||||||
|
}
|
||||||
|
|
||||||
|
public Velocity div(Time t) {
|
||||||
|
return new Velocity(this.value(METER) / t.value(SECOND), METER_PER_SECOND);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Time div(Velocity v) {
|
||||||
|
return new Time(this.value(METER) / v.value(METER_PER_SECOND), SECOND);
|
||||||
|
}
|
||||||
|
}
|
14
uebung07/src/quantities/plain/LengthUnit.java
Normal file
14
uebung07/src/quantities/plain/LengthUnit.java
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
package quantities.plain;
|
||||||
|
|
||||||
|
public class LengthUnit extends Unit {
|
||||||
|
public LengthUnit(String name, double baseFactor) {
|
||||||
|
super(name, baseFactor);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static final LengthUnit METER = new LengthUnit("m", 1);
|
||||||
|
public static final LengthUnit MILLIMETER = new LengthUnit("mm", 0.001);
|
||||||
|
public static final LengthUnit KILOMETER = new LengthUnit("km", 1000);
|
||||||
|
public static final LengthUnit MILE = new LengthUnit("mi", 1609.344);
|
||||||
|
public static final LengthUnit LIGHTYEAR = new LengthUnit("ly", 9460730472580800.0);
|
||||||
|
public static final LengthUnit PARSEC = new LengthUnit("pc", 3.0856776e16);
|
||||||
|
}
|
60
uebung07/src/quantities/plain/PlainQuantitiesDemo.java
Normal file
60
uebung07/src/quantities/plain/PlainQuantitiesDemo.java
Normal file
@@ -0,0 +1,60 @@
|
|||||||
|
package quantities.plain;
|
||||||
|
|
||||||
|
import static quantities.plain.LengthUnit.KILOMETER;
|
||||||
|
import static quantities.plain.LengthUnit.MILE;
|
||||||
|
import static quantities.plain.LengthUnit.MILLIMETER;
|
||||||
|
import static quantities.plain.LengthUnit.PARSEC;
|
||||||
|
import static quantities.plain.TimeUnit.HOUR;
|
||||||
|
import static quantities.plain.TimeUnit.MINUTE;
|
||||||
|
import static quantities.plain.TimeUnit.SECOND;
|
||||||
|
import static quantities.plain.VelocityUnit.KMH;
|
||||||
|
import static quantities.plain.VelocityUnit.METER_PER_SECOND;
|
||||||
|
import static quantities.plain.VelocityUnit.MPH;
|
||||||
|
|
||||||
|
public class PlainQuantitiesDemo {
|
||||||
|
public static void main(String[] args) {
|
||||||
|
final Length l1 = new Length(1, KILOMETER);
|
||||||
|
final Length l2 = new Length(1200, MILLIMETER);
|
||||||
|
final Length l3 = new Length(1, MILE);
|
||||||
|
|
||||||
|
System.out.println(l1);
|
||||||
|
System.out.println(l2);
|
||||||
|
System.out.println(l1 + " + " + l2 + " = " + l1.plus(l2));
|
||||||
|
System.out.println(l1 + " + " + l2 + " (in mm) = " + l1.plus(l2).to(MILLIMETER));
|
||||||
|
|
||||||
|
System.out.println(l3 + " / " + l1 + " = " + l3.div(l1));
|
||||||
|
|
||||||
|
final Time t1 = new Time(100, SECOND);
|
||||||
|
final Time t2 = new Time(5, HOUR);
|
||||||
|
|
||||||
|
System.out.println(t1);
|
||||||
|
System.out.println(t2);
|
||||||
|
System.out.println(t1.plus(t2));
|
||||||
|
System.out.println(t1.plus(t2).to(MINUTE));
|
||||||
|
|
||||||
|
final Velocity v1 = new Velocity(12, KMH);
|
||||||
|
final Velocity v2 = new Velocity(100, METER_PER_SECOND);
|
||||||
|
|
||||||
|
System.out.println(v1);
|
||||||
|
System.out.println(v2);
|
||||||
|
System.out.println(v2.to(KMH));
|
||||||
|
System.out.println(v1.plus(v2));
|
||||||
|
|
||||||
|
final Length l4 = new Length(300, KILOMETER).to(PARSEC);
|
||||||
|
final Time t3 = new Time(2, HOUR);
|
||||||
|
final Velocity v3 = l4.div(t3);
|
||||||
|
System.out.println(l4 + " / " + l3 + " = " + v3);
|
||||||
|
|
||||||
|
System.out.println(v1 + " * " + t1 + " = " + v1.mult(t1).to(KILOMETER));
|
||||||
|
|
||||||
|
final Length l5 = v3.mult(t1.to(HOUR));
|
||||||
|
System.out.println(v3 + " * " + t1 + " = " + l5);
|
||||||
|
|
||||||
|
final Time t5 = l4.div(v2);
|
||||||
|
System.out.println(l4 + " / " + v2 + " = " + t5.to(MINUTE));
|
||||||
|
|
||||||
|
Velocity v5 = new Velocity(55, MPH);
|
||||||
|
System.out.println(v5 + " = " + v5.format("%4.1f %s", KMH));
|
||||||
|
System.out.println((v5.mult(new Time(30, MINUTE)).to(MILE)));
|
||||||
|
}
|
||||||
|
}
|
28
uebung07/src/quantities/plain/Quantity.java
Normal file
28
uebung07/src/quantities/plain/Quantity.java
Normal file
@@ -0,0 +1,28 @@
|
|||||||
|
package quantities.plain;
|
||||||
|
|
||||||
|
public abstract class Quantity {
|
||||||
|
public final double value;
|
||||||
|
public final Unit unit;
|
||||||
|
|
||||||
|
protected Quantity(double value, Unit unit) {
|
||||||
|
this.value = value;
|
||||||
|
this.unit = unit;
|
||||||
|
}
|
||||||
|
|
||||||
|
public double getBaseValue() {
|
||||||
|
return value * unit.baseFactor;
|
||||||
|
}
|
||||||
|
|
||||||
|
public double value(Unit unit) {
|
||||||
|
return getBaseValue() / unit.baseFactor;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return value + " " + unit;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String format(String fmt, Unit unit) {
|
||||||
|
return String.format(fmt, value(unit), unit);
|
||||||
|
}
|
||||||
|
}
|
34
uebung07/src/quantities/plain/Time.java
Normal file
34
uebung07/src/quantities/plain/Time.java
Normal file
@@ -0,0 +1,34 @@
|
|||||||
|
package quantities.plain;
|
||||||
|
|
||||||
|
public class Time extends Quantity{
|
||||||
|
private final TimeUnit unit;
|
||||||
|
|
||||||
|
public Time(double value, TimeUnit unit) {
|
||||||
|
super(value, unit);
|
||||||
|
this.unit = unit;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Time plus(Time other) {
|
||||||
|
return new Time(value + other.getBaseValue() / unit.baseFactor, unit);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Time minus(Time other) {
|
||||||
|
return new Time(value - other.getBaseValue() / unit.baseFactor, unit);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Time mult(double f) {
|
||||||
|
return new Time(value * f, unit);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Time div(double f) {
|
||||||
|
return new Time(value / f, unit);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Time to(TimeUnit unit) {
|
||||||
|
return new Time(getBaseValue() / unit.baseFactor, unit);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Length mult(Velocity v) {
|
||||||
|
return v.mult(this);
|
||||||
|
}
|
||||||
|
}
|
13
uebung07/src/quantities/plain/TimeUnit.java
Normal file
13
uebung07/src/quantities/plain/TimeUnit.java
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
package quantities.plain;
|
||||||
|
|
||||||
|
public class TimeUnit extends Unit{
|
||||||
|
|
||||||
|
public TimeUnit(String name, double baseFactor) {
|
||||||
|
super(name, baseFactor);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static final TimeUnit SECOND = new TimeUnit("s", 1);
|
||||||
|
public static final TimeUnit MINUTE = new TimeUnit("m", 60);
|
||||||
|
public static final TimeUnit HOUR = new TimeUnit("h", 3600);
|
||||||
|
|
||||||
|
}
|
16
uebung07/src/quantities/plain/Unit.java
Normal file
16
uebung07/src/quantities/plain/Unit.java
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
package quantities.plain;
|
||||||
|
|
||||||
|
public abstract class Unit {
|
||||||
|
public final String name;
|
||||||
|
public final double baseFactor;
|
||||||
|
|
||||||
|
public Unit(String name, double baseFactor) {
|
||||||
|
this.name = name;
|
||||||
|
this.baseFactor = baseFactor;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
}
|
38
uebung07/src/quantities/plain/Velocity.java
Normal file
38
uebung07/src/quantities/plain/Velocity.java
Normal file
@@ -0,0 +1,38 @@
|
|||||||
|
package quantities.plain;
|
||||||
|
|
||||||
|
import static quantities.plain.LengthUnit.METER;
|
||||||
|
import static quantities.plain.TimeUnit.SECOND;
|
||||||
|
import static quantities.plain.VelocityUnit.METER_PER_SECOND;
|
||||||
|
|
||||||
|
public class Velocity extends Quantity {
|
||||||
|
private final VelocityUnit unit;
|
||||||
|
|
||||||
|
public Velocity(double value, VelocityUnit unit) {
|
||||||
|
super(value, unit);
|
||||||
|
this.unit = unit;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Velocity plus(Velocity other) {
|
||||||
|
return new Velocity(value + other.getBaseValue() / unit.baseFactor, unit);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Velocity minus(Velocity other) {
|
||||||
|
return new Velocity(value - other.getBaseValue() / unit.baseFactor, unit);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Velocity mult(double f) {
|
||||||
|
return new Velocity(value * f, unit);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Velocity div(double f) {
|
||||||
|
return new Velocity(value / f, unit);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Velocity to(VelocityUnit unit) {
|
||||||
|
return new Velocity(getBaseValue() / unit.baseFactor, unit);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Length mult(Time t) {
|
||||||
|
return new Length(this.value(METER_PER_SECOND) * t.value(SECOND), METER);
|
||||||
|
}
|
||||||
|
}
|
13
uebung07/src/quantities/plain/VelocityUnit.java
Normal file
13
uebung07/src/quantities/plain/VelocityUnit.java
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
package quantities.plain;
|
||||||
|
|
||||||
|
public class VelocityUnit extends Unit{
|
||||||
|
|
||||||
|
public VelocityUnit(String name, double baseFactor) {
|
||||||
|
super(name, baseFactor);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static final VelocityUnit KMH = new VelocityUnit("kmh", 1000/3600); // 1/3.6
|
||||||
|
public static final VelocityUnit MPH = new VelocityUnit("mph", 1609.344/3600);
|
||||||
|
public static final VelocityUnit METER_PER_SECOND = new VelocityUnit("meter per second", 1);
|
||||||
|
|
||||||
|
}
|
82
uebung07/test/oop/ch05/generic/mensa/MensaTest.java
Normal file
82
uebung07/test/oop/ch05/generic/mensa/MensaTest.java
Normal file
@@ -0,0 +1,82 @@
|
|||||||
|
package oop.ch05.generic.mensa;
|
||||||
|
|
||||||
|
import oop.ch05.secured.AuthorizationException;
|
||||||
|
import oop.ch05.mensa.*;
|
||||||
|
|
||||||
|
import org.junit.Before;
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
import static org.junit.Assert.assertEquals;
|
||||||
|
import static org.junit.Assert.assertThrows;
|
||||||
|
|
||||||
|
public class MensaTest {
|
||||||
|
private static final String CONF_ACCOUNT = "33-1298";
|
||||||
|
private static final String OTHER_ACCOUNT = "33-1299";
|
||||||
|
private AccountManagement accountMgt;
|
||||||
|
private VendingMachine vm1;
|
||||||
|
private VendingMachine vm2;
|
||||||
|
private VendingMachine tumVM;
|
||||||
|
private CashPoint unibwMensa;
|
||||||
|
|
||||||
|
private AccountCard conf;
|
||||||
|
private MensaCard frankSmith;
|
||||||
|
private CashCard hansMueller;
|
||||||
|
private CashCard peterSchmidt;
|
||||||
|
private CashCard thomasMayer;
|
||||||
|
|
||||||
|
@Before
|
||||||
|
public void setup() {
|
||||||
|
accountMgt = new AccountManagement(4711, "UniBw admin");
|
||||||
|
|
||||||
|
vm1 = new VendingMachine("left", 4711);
|
||||||
|
vm2 = new VendingMachine("right", 4711);
|
||||||
|
tumVM = new VendingMachine("TUM Mensa", 3141);
|
||||||
|
unibwMensa = new CashPoint("UniBw Mensa", 4711, accountMgt);
|
||||||
|
|
||||||
|
conf = new AccountCard("conference", CONF_ACCOUNT, 42);
|
||||||
|
frankSmith = new CountCard("Frank Smith", Color.gray);
|
||||||
|
hansMueller = new CashCard("Hans Müller", Color.green, 4711);
|
||||||
|
peterSchmidt = new CashCard("Peter Schmidt", Color.green, 4711);
|
||||||
|
thomasMayer = new CashCard("Thomas Mayer", Color.blue, 4711);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testPayment() throws AuthorizationException, RejectedException {
|
||||||
|
vm1.deposit(hansMueller, 10);
|
||||||
|
vm1.deposit(peterSchmidt, 5);
|
||||||
|
vm2.deposit(thomasMayer, 2);
|
||||||
|
assertThrows(AuthorizationException.class, () -> tumVM.deposit(hansMueller, 10));
|
||||||
|
|
||||||
|
assertEquals(15, vm1.getEuros());
|
||||||
|
assertEquals(2, vm2.getEuros());
|
||||||
|
assertEquals(0, tumVM.getEuros());
|
||||||
|
assertEquals(1000, hansMueller.getBalance());
|
||||||
|
assertEquals(500, peterSchmidt.getBalance());
|
||||||
|
assertEquals(200, thomasMayer.getBalance());
|
||||||
|
|
||||||
|
hansMueller.pass(unibwMensa);
|
||||||
|
assertEquals(733, hansMueller.getBalance());
|
||||||
|
assertEquals(1, unibwMensa.getCounter());
|
||||||
|
assertEquals(267, unibwMensa.getCents());
|
||||||
|
|
||||||
|
frankSmith.pass(unibwMensa);
|
||||||
|
assertEquals(0, accountMgt.getAmount(CONF_ACCOUNT));
|
||||||
|
assertThrows(RejectedException.class, () -> conf.pass(unibwMensa));
|
||||||
|
assertThrows(RejectedException.class, () -> thomasMayer.pass(unibwMensa));
|
||||||
|
hansMueller.pass(unibwMensa);
|
||||||
|
hansMueller.pass(unibwMensa);
|
||||||
|
assertEquals(199, hansMueller.getBalance());
|
||||||
|
|
||||||
|
assertThrows(RejectedException.class, () -> hansMueller.pass(unibwMensa));
|
||||||
|
|
||||||
|
accountMgt.deposit(CONF_ACCOUNT, 1000);
|
||||||
|
accountMgt.deposit(OTHER_ACCOUNT, 2000);
|
||||||
|
assertEquals(100000, accountMgt.getAmount(CONF_ACCOUNT));
|
||||||
|
assertEquals(200000, accountMgt.getAmount(OTHER_ACCOUNT));
|
||||||
|
|
||||||
|
conf.pass(unibwMensa);
|
||||||
|
assertEquals(99505, accountMgt.getAmount(CONF_ACCOUNT));
|
||||||
|
assertEquals(200000, accountMgt.getAmount(OTHER_ACCOUNT));
|
||||||
|
assertEquals(5, unibwMensa.getCounter());
|
||||||
|
}
|
||||||
|
}
|
63
uebung08/src/doc/Book.java
Normal file
63
uebung08/src/doc/Book.java
Normal file
@@ -0,0 +1,63 @@
|
|||||||
|
package doc;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
|
||||||
|
public class Book{
|
||||||
|
private String title;
|
||||||
|
private String author;
|
||||||
|
private List<TextComponent> contents;
|
||||||
|
|
||||||
|
public Book(String author, String title, List<TextComponent> contents){
|
||||||
|
this.title = title;
|
||||||
|
this.author = author;
|
||||||
|
this.contents = contents;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int countWords(){
|
||||||
|
Section helpSection = new Section("help", contents);
|
||||||
|
return helpSection.countWords();
|
||||||
|
}
|
||||||
|
|
||||||
|
public int countWordsByVisitor(){
|
||||||
|
CountWordsVisitor countWords = new CountWordsVisitor();
|
||||||
|
int wordCount = 0;
|
||||||
|
for(TextComponent i : contents){
|
||||||
|
wordCount += i.accept(countWords);
|
||||||
|
}
|
||||||
|
return wordCount;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public List<String> tableOfContents(){
|
||||||
|
TableOfContentsVisitor contentTable = new TableOfContentsVisitor();
|
||||||
|
List<String> returnedContent = new ArrayList<String>();
|
||||||
|
|
||||||
|
for(TextComponent e : contents){
|
||||||
|
//contentTable.setPrefix(Integer.toString(itteration));
|
||||||
|
List<String> returned = e.accept(contentTable);
|
||||||
|
if(returned != null){
|
||||||
|
returnedContent.addAll(returned);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return returnedContent;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public String toText(){
|
||||||
|
StringBuilder st = new StringBuilder();
|
||||||
|
ToTextVisitor textVisitor = new ToTextVisitor();
|
||||||
|
st.append(" ");
|
||||||
|
st.append(author);
|
||||||
|
st.append("\n");
|
||||||
|
st.append(title);
|
||||||
|
st.append("\n\n");
|
||||||
|
for(TextComponent i : contents){
|
||||||
|
st.append(i.accept(textVisitor));
|
||||||
|
st.append("\n");
|
||||||
|
}
|
||||||
|
return st.toString();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
148
uebung08/src/doc/BookDemo.java
Normal file
148
uebung08/src/doc/BookDemo.java
Normal file
@@ -0,0 +1,148 @@
|
|||||||
|
package doc;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
public class BookDemo {
|
||||||
|
private static final String TEXT0 = "Über Entwurf und Realisierung eierlegender Wollmilchsäue.";
|
||||||
|
private static final String TEXT1 = "Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod " +
|
||||||
|
"tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. " +
|
||||||
|
"At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd " +
|
||||||
|
"gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum " +
|
||||||
|
"dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor " +
|
||||||
|
"invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua.";
|
||||||
|
private static final String TEXT2 = "Duis autem vel eum iriure dolor in hendrerit in vulputate velit esse molestie " +
|
||||||
|
"consequat, vel illum dolore eu feugiat nulla facilisis at vero eros et accumsan " +
|
||||||
|
"et iusto odio dignissim qui blandit praesent luptatum zzril delenit augue duis " +
|
||||||
|
"dolore te feugait nulla facilisi. Lorem ipsum dolor sit amet, consectetuer " +
|
||||||
|
"adipiscing elit, sed diam nonummy nibh euismod tincidunt ut laoreet dolore " +
|
||||||
|
"magna aliquam erat volutpat.";
|
||||||
|
private static final String TEXT3 = "Ut wisi enim ad minim veniam, quis nostrud exerci tation ullamcorper suscipit " +
|
||||||
|
"lobortis nisl ut aliquip ex ea commodo consequat. Duis autem vel eum iriure " +
|
||||||
|
"dolor in hendrerit in vulputate velit esse molestie consequat, vel illum dolore " +
|
||||||
|
"eu feugiat nulla facilisis at vero eros et accumsan et iusto odio dignissim " +
|
||||||
|
"qui blandit praesent luptatum zzril delenit augue duis dolore te feugait nulla " +
|
||||||
|
"facilisi.";
|
||||||
|
private static final String TEXT4 = "Nam liber tempor cum soluta nobis eleifend option congue nihil imperdiet doming " +
|
||||||
|
"id quod mazim placerat facer possim assum. Lorem ipsum dolor sit amet, " +
|
||||||
|
"consectetuer adipiscing elit, sed diam nonummy nibh euismod tincidunt ut laoreet " +
|
||||||
|
"dolore magna aliquam erat volutpat. Ut wisi enim ad minim veniam, quis nostrud " +
|
||||||
|
"exerci tation ullamcorper suscipit lobortis nisl ut aliquip ex ea commodo " +
|
||||||
|
"consequat.";
|
||||||
|
private static final String TEXT5 = "Duis autem vel eum iriure dolor in hendrerit in vulputate velit esse molestie " +
|
||||||
|
"consequat, vel illum dolore eu feugiat nulla facilisis.";
|
||||||
|
private static final String TEXT6 = "At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, " +
|
||||||
|
"no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, " +
|
||||||
|
"consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et " +
|
||||||
|
"dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo " +
|
||||||
|
"duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est " +
|
||||||
|
"Lorem ipsum dolor sit amet.";
|
||||||
|
private static final String TEXT7 = "Consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore " +
|
||||||
|
"et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et " +
|
||||||
|
"justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata " +
|
||||||
|
"sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur " +
|
||||||
|
"sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore " +
|
||||||
|
"magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo " +
|
||||||
|
"dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est " +
|
||||||
|
"Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing " +
|
||||||
|
"elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam " +
|
||||||
|
"erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea " +
|
||||||
|
"rebum. Stet clita kasd gubergren, no sea takimata sanctus.";
|
||||||
|
private static final String TEXT8 = "Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy " +
|
||||||
|
"eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam " +
|
||||||
|
"voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet " +
|
||||||
|
"clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit " +
|
||||||
|
"amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam " +
|
||||||
|
"nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed " +
|
||||||
|
"diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet " +
|
||||||
|
"clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. ";
|
||||||
|
private static final String TEXT9 = "Duis autem vel eum iriure dolor in hendrerit in vulputate velit esse molestie " +
|
||||||
|
"consequat, vel illum dolore eu feugiat nulla facilisis at vero eros et accumsan " +
|
||||||
|
"et iusto odio dignissim qui blandit praesent luptatum zzril delenit augue duis " +
|
||||||
|
"dolore te feugait nulla facilisi. Lorem ipsum dolor sit amet, consectetuer " +
|
||||||
|
"adipiscing elit, sed diam nonummy nibh euismod tincidunt ut laoreet dolore " +
|
||||||
|
"magna aliquam erat volutpat.";
|
||||||
|
private static final String TEXT10 = "Ut wisi enim ad minim veniam, quis nostrud exerci tation ullamcorper suscipit " +
|
||||||
|
"lobortis nisl ut aliquip ex ea commodo consequat. Duis autem vel eum iriure " +
|
||||||
|
"dolor in hendrerit in vulputate velit esse molestie consequat, vel illum " +
|
||||||
|
"dolore eu feugiat nulla facilisis at vero eros et accumsan et iusto odio " +
|
||||||
|
"dignissim qui blandit praesent luptatum zzril delenit augue duis dolore te " +
|
||||||
|
"feugait nulla facilisi.";
|
||||||
|
private static final String TEXT11 = "Nam liber tempor cum soluta nobis eleifend option congue nihil imperdiet " +
|
||||||
|
"doming id quod mazim placerat facer possim assum. Lorem ipsum dolor sit amet, " +
|
||||||
|
"consectetuer adipiscing elit, sed diam nonummy nibh euismod tincidunt ut " +
|
||||||
|
"laoreet dolore magna aliquam erat volutpat. Ut wisi enim ad minim veniam, " +
|
||||||
|
"quis nostrud exerci tation ullamcorper suscipit lobortis nisl ut aliquip ex " +
|
||||||
|
"ea commodo";
|
||||||
|
private static final String TEXT12 = "Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy " +
|
||||||
|
"eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam " +
|
||||||
|
"voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet " +
|
||||||
|
"clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit " +
|
||||||
|
"amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam " +
|
||||||
|
"nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed " +
|
||||||
|
"diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet " +
|
||||||
|
"clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet.";
|
||||||
|
private static final String TEXT13 = "Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy " +
|
||||||
|
"eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam " +
|
||||||
|
"voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita " +
|
||||||
|
"kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet.";
|
||||||
|
private static final String TEXT14 = "At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, " +
|
||||||
|
"no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit " +
|
||||||
|
"amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut " +
|
||||||
|
"labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam " +
|
||||||
|
"et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata " +
|
||||||
|
"sanctus est Lorem ipsum dolor sit amet.";
|
||||||
|
private static final String TEXT15 = "Lorem ipsum dolor sit amet, consetetur sadipscing " +
|
||||||
|
"elitr, At accusam aliquyam diam diam dolore dolores duo eirmod eos erat, et " +
|
||||||
|
"nonumy sed tempor et et invidunt justo labore Stet clita ea et gubergren, kasd " +
|
||||||
|
"magna no rebum. sanctus sea sed takimata ut vero voluptua. est Lorem ipsum " +
|
||||||
|
"dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed " +
|
||||||
|
"diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat.";
|
||||||
|
|
||||||
|
public static void main(String[] args) {
|
||||||
|
final Book book = makeBook();
|
||||||
|
|
||||||
|
// Aufgabe 1
|
||||||
|
System.out.println("Buch enthält " + book.countWords() + " Wörter");
|
||||||
|
|
||||||
|
// Aufgabe 2
|
||||||
|
System.out.println("Buch enthält " + book.countWordsByVisitor() + " Wörter");
|
||||||
|
System.out.println("Inhalt: " + book.tableOfContents());
|
||||||
|
System.out.println(book.toText());
|
||||||
|
}
|
||||||
|
|
||||||
|
private static Book makeBook() {
|
||||||
|
final Section sec1 = new Section("Einführung",
|
||||||
|
List.of(new Paragraph(TEXT1),
|
||||||
|
new Paragraph(TEXT2)));
|
||||||
|
final Section sec2 = new Section("Hintergrund",
|
||||||
|
List.of(new Paragraph(TEXT3),
|
||||||
|
new Section("Geschichte",
|
||||||
|
List.of(new Paragraph(TEXT4),
|
||||||
|
new Image("https://www.bekannt.de/p1.pdf",
|
||||||
|
"Bild 1"),
|
||||||
|
new Paragraph(TEXT5))),
|
||||||
|
new Section("Literatur",
|
||||||
|
List.of(new Paragraph(TEXT6),
|
||||||
|
new Image("https://www.eh-klar.de/p2.pdf",
|
||||||
|
"Bild 2"),
|
||||||
|
new Paragraph(TEXT7),
|
||||||
|
new Image("https://www.jeder-weiss-es.de/p3.pdf",
|
||||||
|
"Bild 3"),
|
||||||
|
new Paragraph(TEXT8)))));
|
||||||
|
final Section sec3 = new Section("Idee",
|
||||||
|
List.of(new Paragraph(TEXT9)));
|
||||||
|
final Section sec4 = new Section("Umsetzung",
|
||||||
|
List.of(new Paragraph(TEXT10),
|
||||||
|
new Section("Entwurf",
|
||||||
|
List.of(new Paragraph(TEXT11),
|
||||||
|
new Section("Grobentwurf",
|
||||||
|
List.of(new Paragraph(TEXT12))),
|
||||||
|
new Section("Feinentwurf",
|
||||||
|
List.of(new Paragraph(TEXT13))))),
|
||||||
|
new Section("Realisierung",
|
||||||
|
List.of(new Paragraph(TEXT14)))));
|
||||||
|
final Section sec5 = new Section("Zusammenfassung und Ausblick", List.of(new Paragraph(TEXT15)));
|
||||||
|
return new Book("Peter Mustermann", "Die eierlegende Wollmilchsau",
|
||||||
|
List.of(new Paragraph(TEXT0), sec1, sec2, sec3, sec4, sec5));
|
||||||
|
}
|
||||||
|
}
|
38
uebung08/src/doc/CountWordsVisitor.java
Normal file
38
uebung08/src/doc/CountWordsVisitor.java
Normal file
@@ -0,0 +1,38 @@
|
|||||||
|
package doc;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
public class CountWordsVisitor implements Visitor<Integer>{
|
||||||
|
|
||||||
|
public Integer visit(Paragraph e){
|
||||||
|
String text = e.getText();
|
||||||
|
int wordCount = 0;
|
||||||
|
boolean open = false;
|
||||||
|
for (char i : text.toCharArray()){
|
||||||
|
if(!open && Character.isAlphabetic(i)){
|
||||||
|
open = true;
|
||||||
|
}
|
||||||
|
else if(open && !Character.isAlphabetic(i)){
|
||||||
|
open = false;
|
||||||
|
wordCount++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (open){
|
||||||
|
open = false;
|
||||||
|
wordCount++;
|
||||||
|
}
|
||||||
|
return wordCount;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Integer visit(Image e){
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Integer visit(Section e){
|
||||||
|
List<TextComponent> contents = e.getContents();
|
||||||
|
int wordCount = 0;
|
||||||
|
for (TextComponent c: contents){
|
||||||
|
wordCount += c.accept(this);
|
||||||
|
}
|
||||||
|
return wordCount;
|
||||||
|
}
|
||||||
|
}
|
29
uebung08/src/doc/Image.java
Normal file
29
uebung08/src/doc/Image.java
Normal file
@@ -0,0 +1,29 @@
|
|||||||
|
package doc;
|
||||||
|
|
||||||
|
|
||||||
|
public class Image implements TextComponent{
|
||||||
|
private String url;
|
||||||
|
private String caption;
|
||||||
|
|
||||||
|
public Image(String url, String caption) {
|
||||||
|
|
||||||
|
this.url = url;
|
||||||
|
this.caption = caption;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int countWords(){
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getUrl(){
|
||||||
|
return url;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getCaption(){
|
||||||
|
return caption;
|
||||||
|
}
|
||||||
|
|
||||||
|
public <T> T accept(Visitor<T> v){
|
||||||
|
return v.visit(this);
|
||||||
|
}
|
||||||
|
}
|
39
uebung08/src/doc/Paragraph.java
Normal file
39
uebung08/src/doc/Paragraph.java
Normal file
@@ -0,0 +1,39 @@
|
|||||||
|
package doc;
|
||||||
|
|
||||||
|
public class Paragraph implements TextComponent{
|
||||||
|
private String text;
|
||||||
|
|
||||||
|
public Paragraph(String text){
|
||||||
|
this.text = text;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getText(){
|
||||||
|
return text;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int countWords(){
|
||||||
|
int wordCount = 0;
|
||||||
|
boolean open = false;
|
||||||
|
|
||||||
|
for(char i : text.toCharArray()){
|
||||||
|
if(!open && Character.isAlphabetic(i)){
|
||||||
|
open = true;}
|
||||||
|
else if(open && !Character.isAlphabetic(i)){
|
||||||
|
open = false;
|
||||||
|
wordCount ++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(open){
|
||||||
|
open = false;
|
||||||
|
wordCount++;
|
||||||
|
}
|
||||||
|
return wordCount;
|
||||||
|
}
|
||||||
|
|
||||||
|
public <T> T accept(Visitor<T> v){
|
||||||
|
return v.visit(this);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
35
uebung08/src/doc/Section.java
Normal file
35
uebung08/src/doc/Section.java
Normal file
@@ -0,0 +1,35 @@
|
|||||||
|
package doc;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
public class Section implements TextComponent{
|
||||||
|
|
||||||
|
private String header;
|
||||||
|
private List<TextComponent> contents;
|
||||||
|
|
||||||
|
public Section(String header, List<TextComponent> contents){
|
||||||
|
this.header = header;
|
||||||
|
this.contents = contents;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getHeader(){
|
||||||
|
return header;
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<TextComponent> getContents(){
|
||||||
|
return contents;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int countWords(){
|
||||||
|
int wordCount = 0;
|
||||||
|
for(TextComponent i : contents){
|
||||||
|
wordCount = wordCount + i.countWords();
|
||||||
|
}
|
||||||
|
return wordCount;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
public <T> T accept(Visitor<T> v){
|
||||||
|
return v.visit(this);
|
||||||
|
}
|
||||||
|
}
|
77
uebung08/src/doc/TableOfContentsVisitor.java
Normal file
77
uebung08/src/doc/TableOfContentsVisitor.java
Normal file
@@ -0,0 +1,77 @@
|
|||||||
|
package doc;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
public class TableOfContentsVisitor implements Visitor <List<String>>{
|
||||||
|
|
||||||
|
private String prefix = "1";
|
||||||
|
|
||||||
|
public TableOfContentsVisitor(){
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setPrefix(String pre){
|
||||||
|
prefix = pre;
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<String> visit(Paragraph e){
|
||||||
|
return null;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<String> visit(Image e){
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*public List<String> visit(Section e){
|
||||||
|
List<String> tabelOfContentsList = new ArrayList<String>();
|
||||||
|
List<TextComponent> copied = e.getContents();
|
||||||
|
|
||||||
|
String oldPrefix = prefix;
|
||||||
|
|
||||||
|
if(prefix.length() == 0){
|
||||||
|
tabelOfContentsList.add(prefix+ " " + e.getHeader());
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
tabelOfContentsList.add(prefix + " " + e.getHeader());
|
||||||
|
}
|
||||||
|
|
||||||
|
int chapter = 1;
|
||||||
|
for(TextComponent i : e.getContents()){
|
||||||
|
|
||||||
|
String savedPrefix = prefix;
|
||||||
|
setPrefix(prefix + "." + Integer.toString(chapter));
|
||||||
|
|
||||||
|
List<String> returnedContent = i.accept(this);
|
||||||
|
if (returnedContent != null){
|
||||||
|
tabelOfContentsList.addAll(i.accept(this));
|
||||||
|
chapter++;
|
||||||
|
}
|
||||||
|
setPrefix(savedPrefix);
|
||||||
|
}
|
||||||
|
setPrefix(oldPrefix);
|
||||||
|
return tabelOfContentsList;
|
||||||
|
|
||||||
|
}*/
|
||||||
|
|
||||||
|
//Alternative die immer den aktuellen Stand übergibt und somit auf jeder "Ebene" ein eigener Visitor agiert
|
||||||
|
|
||||||
|
private int sectionCtr = 1;
|
||||||
|
|
||||||
|
public TableOfContentsVisitor(String prefix) {
|
||||||
|
this.prefix = prefix;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<String> visit(Section section) {
|
||||||
|
final List<String> list = new ArrayList<>();
|
||||||
|
sectionCtr++;
|
||||||
|
list.add(prefix + sectionCtr + " " + section.getHeader());
|
||||||
|
final TableOfContentsVisitor subVisitor =
|
||||||
|
new TableOfContentsVisitor(prefix + sectionCtr + ".");
|
||||||
|
for (TextComponent c : section.getContents())
|
||||||
|
list.addAll(c.accept(subVisitor));
|
||||||
|
return list;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
7
uebung08/src/doc/TextComponent.java
Normal file
7
uebung08/src/doc/TextComponent.java
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
package doc;
|
||||||
|
|
||||||
|
public interface TextComponent {
|
||||||
|
int countWords();
|
||||||
|
<T> T accept(Visitor<T> visitor);
|
||||||
|
|
||||||
|
}
|
38
uebung08/src/doc/ToTextVisitor.java
Normal file
38
uebung08/src/doc/ToTextVisitor.java
Normal file
@@ -0,0 +1,38 @@
|
|||||||
|
package doc;
|
||||||
|
|
||||||
|
class ToTextVisitor implements Visitor<String> {
|
||||||
|
private final String prefix;
|
||||||
|
private int sectionCtr = 0;
|
||||||
|
private int imageCtr = 0;
|
||||||
|
|
||||||
|
public ToTextVisitor() {
|
||||||
|
this("");
|
||||||
|
}
|
||||||
|
|
||||||
|
public ToTextVisitor(String prefix) {
|
||||||
|
this.prefix = prefix;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String visit(Paragraph section) {
|
||||||
|
return section.getText();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String visit(Image image) {
|
||||||
|
imageCtr++;
|
||||||
|
final String num = prefix + imageCtr;
|
||||||
|
return "<image " + image.getUrl() + ">\nFig. " + num + ": " + image.getCaption();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String visit(Section section) {
|
||||||
|
final StringBuilder b = new StringBuilder();
|
||||||
|
sectionCtr++;
|
||||||
|
b.append(prefix).append(sectionCtr).append(" ").append(section.getHeader());
|
||||||
|
final ToTextVisitor subVisitor = new ToTextVisitor(prefix + sectionCtr + ".");
|
||||||
|
for (TextComponent c : section.getContents())
|
||||||
|
b.append("\n\n").append(c.accept(subVisitor));
|
||||||
|
return b.toString();
|
||||||
|
}
|
||||||
|
}
|
10
uebung08/src/doc/Visitor.java
Normal file
10
uebung08/src/doc/Visitor.java
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
package doc;
|
||||||
|
|
||||||
|
public interface Visitor<T> {
|
||||||
|
T visit(Image image);
|
||||||
|
T visit(Paragraph paragraph);
|
||||||
|
T visit(Section section);
|
||||||
|
|
||||||
|
// semantisch falsch
|
||||||
|
//T visit(TextComponent c);
|
||||||
|
}
|
70
uebung09/src/chess/Board.java
Normal file
70
uebung09/src/chess/Board.java
Normal file
@@ -0,0 +1,70 @@
|
|||||||
|
package chess;
|
||||||
|
|
||||||
|
import java.util.Iterator;
|
||||||
|
|
||||||
|
import iterator.Array2dIterator;
|
||||||
|
import iterator.SkipNullIterator;
|
||||||
|
|
||||||
|
public class Board implements Iterable<Piece> {
|
||||||
|
private final Piece[][] field = new Piece[8][8];
|
||||||
|
//private final List<Piece> pieces = new ArrayList<>();
|
||||||
|
|
||||||
|
void add(Piece piece) {
|
||||||
|
if (piece.getBoard() != this)
|
||||||
|
throw new IllegalArgumentException("wrong board");
|
||||||
|
final Piece existing = pieceAt(piece.getRow(), piece.getCol());
|
||||||
|
if (existing != null)
|
||||||
|
throw new IllegalArgumentException("already occupied by " + existing);
|
||||||
|
field[piece.getRow() - 1][piece.getCol() - 1] = piece;
|
||||||
|
//pieces.add(piece);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void printBoard() {
|
||||||
|
System.out.println(" 1 2 3 4 5 6 7 8");
|
||||||
|
System.out.println(" +---+---+---+---+---+---+---+---+");
|
||||||
|
for (int row = 1; row <= 8; row++) {
|
||||||
|
System.out.print("" + row + " ");
|
||||||
|
for (int col = 1; col <= 8; col++) {
|
||||||
|
final Piece p = pieceAt(row, col);
|
||||||
|
final char c = p == null ? ' ' : p.charRep();
|
||||||
|
System.out.print("| " + c + " ");
|
||||||
|
}
|
||||||
|
System.out.println("|");
|
||||||
|
System.out.println(" +---+---+---+---+---+---+---+---+");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public Piece pieceAt(int row, int col) {
|
||||||
|
return field[row - 1][col - 1];
|
||||||
|
}
|
||||||
|
|
||||||
|
public void check() {
|
||||||
|
for (Piece p1 : this) {
|
||||||
|
System.out.println(p1.toString());
|
||||||
|
for (Piece p2 : this)
|
||||||
|
if (p1 != p2)
|
||||||
|
if (p1.canCapture(p2))
|
||||||
|
System.out.println(" can capture " + p2.toString());
|
||||||
|
else
|
||||||
|
System.out.println(" cannot capture " + p2.toString());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public String toString() {
|
||||||
|
StringBuilder sb = new StringBuilder("[");
|
||||||
|
Iterator<Piece> it = iterator();
|
||||||
|
|
||||||
|
while (it.hasNext()) {
|
||||||
|
sb.append(it.next());
|
||||||
|
if (it.hasNext()) sb.append(", ");
|
||||||
|
}
|
||||||
|
|
||||||
|
sb.append("]");
|
||||||
|
return sb.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Iterator<Piece> iterator() {
|
||||||
|
return new SkipNullIterator<>(new Array2dIterator<>(field));
|
||||||
|
}
|
||||||
|
}
|
95
uebung09/src/chess/ChessApp.java
Normal file
95
uebung09/src/chess/ChessApp.java
Normal file
@@ -0,0 +1,95 @@
|
|||||||
|
package chess;
|
||||||
|
|
||||||
|
import java.io.InputStream;
|
||||||
|
import java.util.Iterator;
|
||||||
|
import java.util.NoSuchElementException;
|
||||||
|
import java.util.Scanner;
|
||||||
|
|
||||||
|
public class ChessApp {
|
||||||
|
private static final String HELP = "h";
|
||||||
|
private static final String CHECK = "c";
|
||||||
|
private static final String ABORT = "a";
|
||||||
|
private static final String WHITE_QUEEN = "q";
|
||||||
|
private static final String BLACK_QUEEN = "Q";
|
||||||
|
private static final String WHITE_KNIGHT = "n";
|
||||||
|
private static final String BLACK_KNIGHT = "N";
|
||||||
|
private static final String ITERATOR = "i";
|
||||||
|
|
||||||
|
private final Scanner scanner;
|
||||||
|
private final Board board;
|
||||||
|
|
||||||
|
public static void main(String[] args) {
|
||||||
|
new ChessApp(System.in, new Board()).playChess();
|
||||||
|
}
|
||||||
|
|
||||||
|
private ChessApp(InputStream in, Board board) {
|
||||||
|
scanner = new Scanner(in);
|
||||||
|
this.board = board;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void playChess() {
|
||||||
|
board.printBoard();
|
||||||
|
commandLoop();
|
||||||
|
System.out.println("Terminated");
|
||||||
|
}
|
||||||
|
|
||||||
|
private void commandLoop() {
|
||||||
|
while (true) {
|
||||||
|
System.out.printf("Type in command (%s for help):%n", HELP);
|
||||||
|
try {
|
||||||
|
final String command = scanner.next();
|
||||||
|
if (ABORT.equals(command)) return;
|
||||||
|
switch (command) {
|
||||||
|
case HELP -> help();
|
||||||
|
case CHECK -> board.check();
|
||||||
|
case BLACK_QUEEN -> addQueen(Color.black);
|
||||||
|
case WHITE_QUEEN -> addQueen(Color.white);
|
||||||
|
case BLACK_KNIGHT -> addKnight(Color.black);
|
||||||
|
case WHITE_KNIGHT -> addKnight(Color.white);
|
||||||
|
case ITERATOR -> iterate();
|
||||||
|
default -> System.out.println("Invalid command " + command);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (IllegalArgumentException ex) {
|
||||||
|
System.out.println(ex.getMessage());
|
||||||
|
}
|
||||||
|
catch (NoSuchElementException ex) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void addKnight(Color color) {
|
||||||
|
final int row = scanner.nextInt();
|
||||||
|
final int col = scanner.nextInt();
|
||||||
|
new Knight(color, board, row, col);
|
||||||
|
board.printBoard();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void addQueen(Color color) {
|
||||||
|
final int row = scanner.nextInt();
|
||||||
|
final int col = scanner.nextInt();
|
||||||
|
new Queen(color, board, row, col);
|
||||||
|
board.printBoard();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void iterate() {
|
||||||
|
final Iterator<Piece> it = board.iterator();
|
||||||
|
|
||||||
|
|
||||||
|
while (it.hasNext()) {
|
||||||
|
System.out.println(it.next());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void help() {
|
||||||
|
System.out.println("Commands:");
|
||||||
|
System.out.println(ABORT + ": terminate the program");
|
||||||
|
System.out.println(CHECK + ": check the pieces on the board");
|
||||||
|
System.out.println(WHITE_KNIGHT + " <int> <int>: place a new white knight at specified position");
|
||||||
|
System.out.println(BLACK_KNIGHT + " <int> <int>: place a new black knight at specified position");
|
||||||
|
System.out.println(WHITE_QUEEN + " <int> <int>: place a new white queen at specified position");
|
||||||
|
System.out.println(BLACK_QUEEN + " <int> <int>: place a new black queen at specified position");
|
||||||
|
System.out.println(ITERATOR + ": iterate over the board and print all pieces to the console");
|
||||||
|
}
|
||||||
|
}
|
5
uebung09/src/chess/Color.java
Normal file
5
uebung09/src/chess/Color.java
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
package chess;
|
||||||
|
|
||||||
|
public enum Color {
|
||||||
|
black, white
|
||||||
|
}
|
28
uebung09/src/chess/Knight.java
Normal file
28
uebung09/src/chess/Knight.java
Normal file
@@ -0,0 +1,28 @@
|
|||||||
|
package chess;
|
||||||
|
|
||||||
|
import static java.lang.Math.abs;
|
||||||
|
|
||||||
|
public class Knight extends Piece {
|
||||||
|
public Knight(Color color, Board board, int row, int col) {
|
||||||
|
super(color, board, row, col);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public char charRep() {
|
||||||
|
return getColor() == Color.white ? 'n' : 'N';
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return String.format("%s knight at (%d,%d)", getColor(), getRow(), getCol());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean canCapture(Piece other) {
|
||||||
|
if (getBoard() != other.getBoard() || getColor() == other.getColor())
|
||||||
|
return false;
|
||||||
|
final int dr = abs(getRow() - other.getRow());
|
||||||
|
final int dc = abs(getCol() - other.getCol());
|
||||||
|
return dr == 2 && dc == 1 || dr == 1 && dc == 2;
|
||||||
|
}
|
||||||
|
}
|
38
uebung09/src/chess/Piece.java
Normal file
38
uebung09/src/chess/Piece.java
Normal file
@@ -0,0 +1,38 @@
|
|||||||
|
package chess;
|
||||||
|
|
||||||
|
public abstract class Piece {
|
||||||
|
private Color color;
|
||||||
|
private Board board;
|
||||||
|
private int row;
|
||||||
|
private int col;
|
||||||
|
|
||||||
|
protected Piece(Color color, Board board, int row, int col) {
|
||||||
|
if (row < 1 || row > 8 || col < 1 || col > 8)
|
||||||
|
throw new IllegalArgumentException("Invalid pos " + row + "/" + col);
|
||||||
|
this.color = color;
|
||||||
|
this.board = board;
|
||||||
|
this.row = row;
|
||||||
|
this.col = col;
|
||||||
|
board.add(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Color getColor() {
|
||||||
|
return color;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Board getBoard() {
|
||||||
|
return board;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getRow() {
|
||||||
|
return row;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getCol() {
|
||||||
|
return col;
|
||||||
|
}
|
||||||
|
|
||||||
|
public abstract char charRep();
|
||||||
|
|
||||||
|
public abstract boolean canCapture(Piece other);
|
||||||
|
}
|
40
uebung09/src/chess/Queen.java
Normal file
40
uebung09/src/chess/Queen.java
Normal file
@@ -0,0 +1,40 @@
|
|||||||
|
package chess;
|
||||||
|
|
||||||
|
import static java.lang.Integer.signum;
|
||||||
|
import static java.lang.Math.abs;
|
||||||
|
|
||||||
|
public class Queen extends Piece {
|
||||||
|
public Queen(Color color, Board board, int row, int col) {
|
||||||
|
super(color, board, row, col);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public char charRep() {
|
||||||
|
return getColor() == Color.white ? 'q' : 'Q';
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return String.format("%s queen at (%d,%d)", getColor(), getRow(), getCol());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean canCapture(Piece other) {
|
||||||
|
if (getBoard() != other.getBoard() || getColor() == other.getColor())
|
||||||
|
return false;
|
||||||
|
if (other.getRow() != getRow() &&
|
||||||
|
other.getCol() != getCol() &&
|
||||||
|
abs(other.getRow() - getRow()) != abs(other.getCol() - getCol()))
|
||||||
|
return false;
|
||||||
|
final int dr = signum(other.getRow() - getRow());
|
||||||
|
final int dc = signum(other.getCol() - getCol());
|
||||||
|
int r = getRow() + dr;
|
||||||
|
int c = getCol() + dc;
|
||||||
|
while (r != other.getRow() || c != other.getCol()) {
|
||||||
|
if (getBoard().pieceAt(r, c) != null) return false;
|
||||||
|
r += dr;
|
||||||
|
c += dc;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
106
uebung09/src/collection/BigSet.java
Normal file
106
uebung09/src/collection/BigSet.java
Normal file
@@ -0,0 +1,106 @@
|
|||||||
|
package collection;
|
||||||
|
|
||||||
|
import java.util.Iterator;
|
||||||
|
import java.util.Objects;
|
||||||
|
|
||||||
|
class BigSet<E> implements Set<E> {
|
||||||
|
private final E first;
|
||||||
|
private final Set<E> rest;
|
||||||
|
private final int size;
|
||||||
|
|
||||||
|
BigSet(E first, Set<E> rest) {
|
||||||
|
this.first = Objects.requireNonNull(first);
|
||||||
|
this.rest = Objects.requireNonNull(rest);
|
||||||
|
size = 1 + rest.size();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int size() {
|
||||||
|
return size;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isEmpty() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean contains(Object el) {
|
||||||
|
return first.equals(el) || rest.contains(el);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean subsetOf(Set<?> other) {
|
||||||
|
return other.contains(first) && rest.subsetOf(other);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Set<E> union(Set<E> other) {
|
||||||
|
return rest.union(other).add(first);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Set<E> add(E element) {
|
||||||
|
if (contains(element))
|
||||||
|
return this;
|
||||||
|
return new BigSet<>(element, this);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Set<E> intersection(Set<E> other) {
|
||||||
|
final Set<E> set = rest.intersection(other);
|
||||||
|
if (!other.contains(first))
|
||||||
|
return set;
|
||||||
|
else if (set.isEmpty())
|
||||||
|
return SetFactory.create(first);
|
||||||
|
return new BigSet<>(first, set);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Iterator<E> iterator() {
|
||||||
|
return new Iterator<>() {
|
||||||
|
private int cnt;
|
||||||
|
private Iterator<E> restIt;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean hasNext() {
|
||||||
|
if (cnt == 0) return true;
|
||||||
|
if (restIt == null) restIt = rest.iterator();
|
||||||
|
return restIt.hasNext();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public E next() {
|
||||||
|
if (cnt++ == 0) return first;
|
||||||
|
if (restIt == null) restIt = rest.iterator();
|
||||||
|
return restIt.next();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
final StringBuilder b = new StringBuilder("{");
|
||||||
|
final Iterator<E> it = iterator();
|
||||||
|
while (it.hasNext()) {
|
||||||
|
b.append(it.next());
|
||||||
|
if (it.hasNext()) b.append(", ");
|
||||||
|
}
|
||||||
|
b.append('}');
|
||||||
|
return b.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int hashCode() {
|
||||||
|
return 31 * rest.hashCode() + first.hashCode();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean equals(Object obj) {
|
||||||
|
if (obj instanceof Set<?>) {
|
||||||
|
final Set<?> other = (Set<?>) obj;
|
||||||
|
return this.size() == other.size() && this.subsetOf(other);
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
76
uebung09/src/collection/EmptySet.java
Normal file
76
uebung09/src/collection/EmptySet.java
Normal file
@@ -0,0 +1,76 @@
|
|||||||
|
package collection;
|
||||||
|
|
||||||
|
import java.util.Iterator;
|
||||||
|
import java.util.NoSuchElementException;
|
||||||
|
|
||||||
|
class EmptySet<E> implements Set<E> {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int size() {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isEmpty() {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean contains(Object el) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean subsetOf(Set<?> other) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Set<E> union(Set<E> other) {
|
||||||
|
return other;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Set<E> add(E element) {
|
||||||
|
return SetFactory.create(element);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Set<E> intersection(Set<E> other) {
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Iterator<E> iterator() {
|
||||||
|
return new Iterator<>() {
|
||||||
|
@Override
|
||||||
|
public boolean hasNext() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public E next() {
|
||||||
|
throw new NoSuchElementException();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return "{}";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int hashCode() {
|
||||||
|
return 31;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean equals(Object obj) {
|
||||||
|
if (obj instanceof Set<?>) {
|
||||||
|
@SuppressWarnings("unchecked") final Set<E> other = (Set<E>) obj;
|
||||||
|
return other.isEmpty();
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
61
uebung09/src/collection/Set.java
Normal file
61
uebung09/src/collection/Set.java
Normal file
@@ -0,0 +1,61 @@
|
|||||||
|
package collection;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A set of elements that does not contain any element twice.
|
||||||
|
*
|
||||||
|
* @param <E> the type of all contained elements.
|
||||||
|
*/
|
||||||
|
public interface Set<E> extends Iterable<E> {
|
||||||
|
/**
|
||||||
|
* Returns the number of elements stored in this set.
|
||||||
|
*
|
||||||
|
* @return the number of elements in this set
|
||||||
|
*/
|
||||||
|
int size();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns true if this set contains no elements.
|
||||||
|
*
|
||||||
|
* @return true if this set contains no elements
|
||||||
|
*/
|
||||||
|
boolean isEmpty();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns true if this set contains the specified element.
|
||||||
|
*
|
||||||
|
* @return true if this set contains the specified element.
|
||||||
|
*/
|
||||||
|
boolean contains(Object el);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the union set of this set and the specified set.
|
||||||
|
*
|
||||||
|
* @param other a set
|
||||||
|
* @return the union set of this set and the specified set.
|
||||||
|
*/
|
||||||
|
Set<E> union(Set<E> other);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* returns the set resulting from adding the specified element to this set.
|
||||||
|
*
|
||||||
|
* @param element an element (must not be null)
|
||||||
|
* @return the set resulting from adding the specified element to this set.
|
||||||
|
*/
|
||||||
|
Set<E> add(E element);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the intersection of this set and the specified set.
|
||||||
|
*
|
||||||
|
* @param other a set
|
||||||
|
* @return the intersection of this set and the specified set.
|
||||||
|
*/
|
||||||
|
Set<E> intersection(Set<E> other);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns true if all elements of this set are contained in the specified set.
|
||||||
|
*
|
||||||
|
* @param other a set
|
||||||
|
* @return true if all elements of this set are contained in the specified set.
|
||||||
|
*/
|
||||||
|
boolean subsetOf(Set<?> other);
|
||||||
|
}
|
29
uebung09/src/collection/SetDemo.java
Normal file
29
uebung09/src/collection/SetDemo.java
Normal file
@@ -0,0 +1,29 @@
|
|||||||
|
package collection;
|
||||||
|
|
||||||
|
public class SetDemo {
|
||||||
|
public static void main(String[] args) {
|
||||||
|
final Set<String> set1 = SetFactory.create();
|
||||||
|
System.out.println("set1 = " + set1);
|
||||||
|
|
||||||
|
final Set<String> set2 = set1.add("foo");
|
||||||
|
System.out.println("set2 = " + set2);
|
||||||
|
|
||||||
|
final Set<String> set3 = set2.add("foo");
|
||||||
|
System.out.println("set3 = " + set3);
|
||||||
|
|
||||||
|
final Set<String> set4 = set3.add("bar");
|
||||||
|
System.out.println("set4 = " + set4);
|
||||||
|
|
||||||
|
final Set<String> set5 = SetFactory.create("foo", "baz", "foo");
|
||||||
|
System.out.println("set5 = " + set5);
|
||||||
|
|
||||||
|
final Set<String> set6 = set4.union(set5);
|
||||||
|
System.out.println("set6 = " + set6);
|
||||||
|
|
||||||
|
final Set<String> set7 = set4.intersection(set5);
|
||||||
|
System.out.println("set7 = " + set7);
|
||||||
|
|
||||||
|
final Set<String> set8 = set5.intersection(set4);
|
||||||
|
System.out.println("set8 = " + set8);
|
||||||
|
}
|
||||||
|
}
|
49
uebung09/src/collection/SetFactory.java
Normal file
49
uebung09/src/collection/SetFactory.java
Normal file
@@ -0,0 +1,49 @@
|
|||||||
|
package collection;
|
||||||
|
|
||||||
|
public class SetFactory {
|
||||||
|
|
||||||
|
// Notwendig um einen korrekten Vergleich von EmptySet zu ermöglichen
|
||||||
|
private static final EmptySet<Object> EMPTY_SET = new EmptySet<>();
|
||||||
|
|
||||||
|
private SetFactory() { /* don't instantiate */ }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the empty set.
|
||||||
|
*
|
||||||
|
* @param <T> the element type of the returned set.
|
||||||
|
* @return the empty set.
|
||||||
|
*/
|
||||||
|
static <T> Set<T> create() {
|
||||||
|
return (Set<T>) EMPTY_SET;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the singleton set containing the specified element.
|
||||||
|
*
|
||||||
|
* @param element an element (must not be null)
|
||||||
|
* @param <T> the element type of the returned set.
|
||||||
|
* @return the singleton set containing the specified element.
|
||||||
|
*/
|
||||||
|
static <T> Set<T> create(T element) {
|
||||||
|
return new SingeltonSet<>(element);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns a set containing the specified elements. The specified elements may contain equal elements.
|
||||||
|
*
|
||||||
|
* @param elems elements of the returned set (may contain equal elements)
|
||||||
|
* @param <T> the element type of the returned set.
|
||||||
|
* @return a set containing the specified elements.
|
||||||
|
*/
|
||||||
|
static <T> Set<T> create(T... elems) {
|
||||||
|
if (elems.length == 0) return create();
|
||||||
|
if (elems.length == 1) return create(elems[0]);
|
||||||
|
Set<T> result = create();
|
||||||
|
|
||||||
|
for (T t : elems) {
|
||||||
|
result = result.add(t);
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
}
|
89
uebung09/src/collection/SingeltonSet.java
Normal file
89
uebung09/src/collection/SingeltonSet.java
Normal file
@@ -0,0 +1,89 @@
|
|||||||
|
package collection;
|
||||||
|
|
||||||
|
import java.util.Iterator;
|
||||||
|
import java.util.NoSuchElementException;
|
||||||
|
import java.util.Objects;
|
||||||
|
|
||||||
|
class SingeltonSet<E> implements Set<E> {
|
||||||
|
private final E element;
|
||||||
|
|
||||||
|
SingeltonSet(E element) {
|
||||||
|
this.element = Objects.requireNonNull(element);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int size() {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isEmpty() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean contains(Object el) {
|
||||||
|
return element.equals(el);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean subsetOf(Set<?> other) {
|
||||||
|
return other.contains(element);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Set<E> union(Set<E> other) {
|
||||||
|
return other.add(element);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Set<E> add(E element) {
|
||||||
|
if (this.element.equals(element))
|
||||||
|
return this;
|
||||||
|
return new BigSet<>(element, this);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Set<E> intersection(Set<E> other) {
|
||||||
|
return other.contains(element) ? this : SetFactory.create();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Iterator<E> iterator() {
|
||||||
|
return new Iterator<>() {
|
||||||
|
boolean ready = true;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean hasNext() {
|
||||||
|
return ready;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public E next() {
|
||||||
|
if (!ready)
|
||||||
|
throw new NoSuchElementException();
|
||||||
|
ready = false;
|
||||||
|
return element;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return "{" + element + "}";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int hashCode() {
|
||||||
|
return 47 * element.hashCode();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean equals(Object obj) {
|
||||||
|
if (obj instanceof Set<?>) {
|
||||||
|
final Set<?> other = (Set<?>) obj;
|
||||||
|
return other.size() == 1 && other.contains(element);
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
38
uebung09/src/iterator/Array2dIterator.java
Normal file
38
uebung09/src/iterator/Array2dIterator.java
Normal file
@@ -0,0 +1,38 @@
|
|||||||
|
package iterator;
|
||||||
|
|
||||||
|
import java.util.Iterator;
|
||||||
|
import java.util.NoSuchElementException;
|
||||||
|
|
||||||
|
public class Array2dIterator<T> implements Iterator<T> {
|
||||||
|
|
||||||
|
private T[][] array;
|
||||||
|
private int row = 0;
|
||||||
|
private int col = 0;
|
||||||
|
|
||||||
|
public Array2dIterator(T[][] array) {
|
||||||
|
this.array = array;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean hasNext() {
|
||||||
|
if (row < array.length) {
|
||||||
|
if (col >= array[row].length) {
|
||||||
|
col = 0;
|
||||||
|
row++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (row < array.length && col < array[row].length) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public T next() {
|
||||||
|
if (!hasNext()) {
|
||||||
|
throw new NoSuchElementException();
|
||||||
|
}
|
||||||
|
|
||||||
|
return array[row][col++];
|
||||||
|
}
|
||||||
|
}
|
97
uebung09/src/iterator/IteratorDemo.java
Normal file
97
uebung09/src/iterator/IteratorDemo.java
Normal file
@@ -0,0 +1,97 @@
|
|||||||
|
package iterator;
|
||||||
|
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.Iterator;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
public class IteratorDemo {
|
||||||
|
private static void demoArray2dIterator() {
|
||||||
|
System.out.println("Array2dIterator {{}, {\"foo\", \"bar\"}, {\"baz\"}, {}}");
|
||||||
|
final String[][] array = {{}, {"foo", "bar"}, {"baz"}, {}};
|
||||||
|
final Iterator<String> it = new Array2dIterator<>(array);
|
||||||
|
while (it.hasNext())
|
||||||
|
System.out.println(it.next());
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void demoArray2dIteratorOnlyEmpty() {
|
||||||
|
System.out.println("Array2dIterator {{}, {}, {}}");
|
||||||
|
final String[][] array = {{}, {}, {}};
|
||||||
|
final Iterator<String> it = new Array2dIterator<>(array);
|
||||||
|
while (it.hasNext())
|
||||||
|
System.out.println(it.next());
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void demoArray2dIteratorEmpty() {
|
||||||
|
System.out.println("Array2dIterator {}");
|
||||||
|
final String[][] array = {};
|
||||||
|
final Iterator<String> it = new Array2dIterator<>(array);
|
||||||
|
while (it.hasNext())
|
||||||
|
System.out.println(it.next());
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void demoSkipNullIterator() {
|
||||||
|
System.out.println("SkipNullIterator [\"a\", \"b\", null, \"c\"]");
|
||||||
|
final Iterator<String> oriIt = Arrays.asList("a", "b", null, "c").iterator();
|
||||||
|
final Iterator<String> it = new SkipNullIterator<>(oriIt);
|
||||||
|
while (it.hasNext())
|
||||||
|
System.out.println(it.next());
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void demoSkipNullIteratorSingleton() {
|
||||||
|
System.out.println("SkipNullIterator [\"foo\"]");
|
||||||
|
final Iterator<String> oriIt = List.of("foo").iterator();
|
||||||
|
final Iterator<String> it = new SkipNullIterator<>(oriIt);
|
||||||
|
while (it.hasNext())
|
||||||
|
System.out.println(it.next());
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void demoSkipNullIteratorInfinity() {
|
||||||
|
System.out.println("SkipNullIterator [\"infinity\", \"infinity\", ...]");
|
||||||
|
final Iterator<String> oriIt = new Iterator<>() {
|
||||||
|
@Override
|
||||||
|
public boolean hasNext() {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String next() {
|
||||||
|
return "infinity";
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
final Iterator<String> it = new SkipNullIterator<>(oriIt);
|
||||||
|
for (int i = 0; i < 10; i++)
|
||||||
|
System.out.println(i + ": " + it.next());
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void demoPathological() {
|
||||||
|
System.out.println("SkipNullIterator [null, ..., null, \"infinity\", \"infinity\", ...]");
|
||||||
|
final Iterator<String> oriIt = new Iterator<>() {
|
||||||
|
private int ctr;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean hasNext() {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String next() {
|
||||||
|
return ctr++ > 100000 ? "infinity" : null;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
final SkipNullIterator<String> it = new SkipNullIterator<>(oriIt);
|
||||||
|
for (int i = 0; i < 10; i++)
|
||||||
|
System.out.println(i + ": " + it.next());
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void main(String[] args) {
|
||||||
|
demoArray2dIterator();
|
||||||
|
demoArray2dIteratorEmpty();
|
||||||
|
demoArray2dIteratorOnlyEmpty();
|
||||||
|
demoSkipNullIterator();
|
||||||
|
demoSkipNullIteratorSingleton();
|
||||||
|
demoSkipNullIteratorInfinity();
|
||||||
|
demoPathological();
|
||||||
|
}
|
||||||
|
}
|
34
uebung09/src/iterator/SkipNullIterator.java
Normal file
34
uebung09/src/iterator/SkipNullIterator.java
Normal file
@@ -0,0 +1,34 @@
|
|||||||
|
package iterator;
|
||||||
|
|
||||||
|
import java.util.Iterator;
|
||||||
|
import java.util.NoSuchElementException;
|
||||||
|
|
||||||
|
public class SkipNullIterator<T> implements Iterator<T> {
|
||||||
|
|
||||||
|
private final Iterator<T> iterator;
|
||||||
|
private T nextObj;
|
||||||
|
|
||||||
|
public SkipNullIterator(Iterator<T> iterator) {
|
||||||
|
this.iterator = iterator;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean hasNext() {
|
||||||
|
while (nextObj == null && iterator.hasNext()) {
|
||||||
|
nextObj = iterator.next();
|
||||||
|
}
|
||||||
|
return nextObj != null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public T next() {
|
||||||
|
if (!hasNext()) {
|
||||||
|
throw new NoSuchElementException();
|
||||||
|
}
|
||||||
|
|
||||||
|
final T ret = nextObj;
|
||||||
|
nextObj = null;
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
17
uebung09/test/collection/SetTest.java
Normal file
17
uebung09/test/collection/SetTest.java
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
package collection;
|
||||||
|
|
||||||
|
import static org.junit.Assert.assertTrue;
|
||||||
|
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
public class SetTest {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testAdd() {
|
||||||
|
Set<Integer> set = SetFactory.create();
|
||||||
|
set = set.add(1);
|
||||||
|
assertTrue(set.contains(1));
|
||||||
|
set = set.add(3);
|
||||||
|
assertTrue(set.contains(3));
|
||||||
|
}
|
||||||
|
}
|
43
uebung09/test/iterator/Array2dIteratorTest.java
Normal file
43
uebung09/test/iterator/Array2dIteratorTest.java
Normal file
@@ -0,0 +1,43 @@
|
|||||||
|
package iterator;
|
||||||
|
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
import java.util.Iterator;
|
||||||
|
import java.util.NoSuchElementException;
|
||||||
|
|
||||||
|
import static org.junit.Assert.assertEquals;
|
||||||
|
import static org.junit.Assert.assertFalse;
|
||||||
|
import static org.junit.Assert.assertThrows;
|
||||||
|
import static org.junit.Assert.assertTrue;
|
||||||
|
|
||||||
|
public class Array2dIteratorTest {
|
||||||
|
@Test
|
||||||
|
public void testArray2dIterator() {
|
||||||
|
final String[][] array = {{}, {"foo", "bar"}, {"baz"}, {}};
|
||||||
|
final Iterator<String> it = new Array2dIterator<>(array);
|
||||||
|
assertTrue(it.hasNext());
|
||||||
|
assertEquals("foo", it.next());
|
||||||
|
assertTrue(it.hasNext());
|
||||||
|
assertEquals("bar", it.next());
|
||||||
|
assertTrue(it.hasNext());
|
||||||
|
assertEquals("baz", it.next());
|
||||||
|
assertFalse(it.hasNext());
|
||||||
|
assertThrows(NoSuchElementException.class, it::next);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testArray2dIteratorOnlyEmpty() {
|
||||||
|
final String[][] array = {{}, {}, {}};
|
||||||
|
final Iterator<String> it = new Array2dIterator<>(array);
|
||||||
|
assertFalse(it.hasNext());
|
||||||
|
assertThrows(NoSuchElementException.class, it::next);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testArray2dIteratorEmpty() {
|
||||||
|
final String[][] array = {};
|
||||||
|
final Iterator<String> it = new Array2dIterator<>(array);
|
||||||
|
assertFalse(it.hasNext());
|
||||||
|
assertThrows(NoSuchElementException.class, it::next);
|
||||||
|
}
|
||||||
|
}
|
122
uebung09/test/iterator/SkipNullIteratorTest.java
Normal file
122
uebung09/test/iterator/SkipNullIteratorTest.java
Normal file
@@ -0,0 +1,122 @@
|
|||||||
|
package iterator;
|
||||||
|
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
import java.util.Iterator;
|
||||||
|
import java.util.NoSuchElementException;
|
||||||
|
|
||||||
|
import static java.util.Arrays.asList;
|
||||||
|
import static java.util.Collections.emptyList;
|
||||||
|
import static org.junit.Assert.assertEquals;
|
||||||
|
import static org.junit.Assert.assertFalse;
|
||||||
|
import static org.junit.Assert.assertThrows;
|
||||||
|
import static org.junit.Assert.assertTrue;
|
||||||
|
|
||||||
|
public class SkipNullIteratorTest {
|
||||||
|
@Test
|
||||||
|
public void testEmpty() {
|
||||||
|
final Iterator<Object> it = new SkipNullIterator<>(emptyList().iterator());
|
||||||
|
assertFalse(it.hasNext());
|
||||||
|
assertThrows(NoSuchElementException.class, it::next);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testNull() {
|
||||||
|
final Iterator<Object> it = new SkipNullIterator<>(asList(null, null).iterator());
|
||||||
|
assertFalse(it.hasNext());
|
||||||
|
assertThrows(NoSuchElementException.class, it::next);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testNonNull() {
|
||||||
|
final Iterator<String> it = new SkipNullIterator<>(asList("foo").iterator());
|
||||||
|
assertTrue(it.hasNext());
|
||||||
|
assertEquals("foo", it.next());
|
||||||
|
assertFalse(it.hasNext());
|
||||||
|
assertThrows(NoSuchElementException.class, it::next);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testMixed() {
|
||||||
|
final Iterator<String> it = new SkipNullIterator<>(asList(null, "foo", null).iterator());
|
||||||
|
assertTrue(it.hasNext());
|
||||||
|
assertEquals("foo", it.next());
|
||||||
|
assertFalse(it.hasNext());
|
||||||
|
assertThrows(NoSuchElementException.class, it::next);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testMixed2() {
|
||||||
|
final Iterator<String> oriIt = asList("a", "b", null, "c").iterator();
|
||||||
|
Iterator<String> it = new SkipNullIterator<>(oriIt);
|
||||||
|
assertTrue(it.hasNext());
|
||||||
|
assertEquals("a", it.next());
|
||||||
|
assertTrue(it.hasNext());
|
||||||
|
assertEquals("b", it.next());
|
||||||
|
assertTrue(it.hasNext());
|
||||||
|
assertEquals("c", it.next());
|
||||||
|
assertFalse(it.hasNext());
|
||||||
|
assertThrows(NoSuchElementException.class, it::next);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testDontCallInCtor() {
|
||||||
|
final Iterator<String> dontCallNext = new Iterator<>() {
|
||||||
|
@Override
|
||||||
|
public boolean hasNext() {
|
||||||
|
throw new RuntimeException();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String next() {
|
||||||
|
throw new RuntimeException();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
new SkipNullIterator<>(dontCallNext);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testSkipNullIteratorInfinity() {
|
||||||
|
final Iterator<String> oriIt = new Iterator<>() {
|
||||||
|
@Override
|
||||||
|
public boolean hasNext() {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String next() {
|
||||||
|
return "infinity";
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
final Iterator<String> it = new SkipNullIterator<>(oriIt);
|
||||||
|
for (int i = 0; i < 1000; i++) {
|
||||||
|
assertTrue(it.hasNext());
|
||||||
|
assertEquals("infinity", it.next());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testPathological() {
|
||||||
|
final Iterator<String> oriIt = new Iterator<>() {
|
||||||
|
private int ctr;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean hasNext() {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String next() {
|
||||||
|
return ctr++ > 100000 ? "infinity" : null;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
final Iterator<String> it = new SkipNullIterator<>(oriIt);
|
||||||
|
for (int i = 0; i < 1000; i++) {
|
||||||
|
assertTrue(it.hasNext());
|
||||||
|
assertEquals("infinity", it.next());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
Reference in New Issue
Block a user