mirror of
https://gitlab.com/arnekeller/kit-programmieren-ws1920-final2.git
synced 2024-11-08 18:00:37 +00:00
Implement more commands and add test case
This commit is contained in:
parent
e36116701b
commit
bffdf9112c
117
game1_input.txt
Normal file
117
game1_input.txt
Normal file
@ -0,0 +1,117 @@
|
|||||||
|
startn
|
||||||
|
wood
|
||||||
|
wood
|
||||||
|
wood
|
||||||
|
wood
|
||||||
|
wood
|
||||||
|
wood
|
||||||
|
wood
|
||||||
|
wood
|
||||||
|
wood
|
||||||
|
wood
|
||||||
|
wood
|
||||||
|
wood
|
||||||
|
wood
|
||||||
|
wood
|
||||||
|
wood
|
||||||
|
wood
|
||||||
|
plastic
|
||||||
|
plastic
|
||||||
|
plastic
|
||||||
|
plastic
|
||||||
|
plastic
|
||||||
|
plastic
|
||||||
|
plastic
|
||||||
|
plastic
|
||||||
|
plastic
|
||||||
|
plastic
|
||||||
|
plastic
|
||||||
|
plastic
|
||||||
|
plastic
|
||||||
|
plastic
|
||||||
|
plastic
|
||||||
|
plastic
|
||||||
|
metal
|
||||||
|
metal
|
||||||
|
metal
|
||||||
|
metal
|
||||||
|
metal
|
||||||
|
metal
|
||||||
|
metal
|
||||||
|
metal
|
||||||
|
metal
|
||||||
|
metal
|
||||||
|
metal
|
||||||
|
metal
|
||||||
|
metal
|
||||||
|
metal
|
||||||
|
metal
|
||||||
|
metal
|
||||||
|
spider
|
||||||
|
spider
|
||||||
|
spider
|
||||||
|
spider
|
||||||
|
spider
|
||||||
|
snake
|
||||||
|
snake
|
||||||
|
snake
|
||||||
|
snake
|
||||||
|
snake
|
||||||
|
tiger
|
||||||
|
tiger
|
||||||
|
tiger
|
||||||
|
tiger
|
||||||
|
tiger
|
||||||
|
thunderstorm
|
||||||
|
draw
|
||||||
|
draw
|
||||||
|
draw
|
||||||
|
draw
|
||||||
|
draw
|
||||||
|
draw
|
||||||
|
draw
|
||||||
|
draw
|
||||||
|
draw
|
||||||
|
draw
|
||||||
|
draw
|
||||||
|
draw
|
||||||
|
draw
|
||||||
|
draw
|
||||||
|
draw
|
||||||
|
draw
|
||||||
|
draw
|
||||||
|
draw
|
||||||
|
draw
|
||||||
|
draw
|
||||||
|
draw
|
||||||
|
draw
|
||||||
|
draw
|
||||||
|
draw
|
||||||
|
draw
|
||||||
|
draw
|
||||||
|
draw
|
||||||
|
draw
|
||||||
|
draw
|
||||||
|
draw
|
||||||
|
draw
|
||||||
|
draw
|
||||||
|
draw
|
||||||
|
draw
|
||||||
|
draw
|
||||||
|
draw
|
||||||
|
draw
|
||||||
|
draw
|
||||||
|
draw
|
||||||
|
draw
|
||||||
|
draw
|
||||||
|
draw
|
||||||
|
draw
|
||||||
|
draw
|
||||||
|
draw
|
||||||
|
draw
|
||||||
|
draw
|
||||||
|
draw
|
||||||
|
build?
|
||||||
|
build steamboat
|
||||||
|
build fireplace
|
||||||
|
build steamboat
|
60
game1_output.txt
Normal file
60
game1_output.txt
Normal file
@ -0,0 +1,60 @@
|
|||||||
|
OK
|
||||||
|
wood
|
||||||
|
wood
|
||||||
|
wood
|
||||||
|
wood
|
||||||
|
wood
|
||||||
|
wood
|
||||||
|
wood
|
||||||
|
wood
|
||||||
|
wood
|
||||||
|
wood
|
||||||
|
wood
|
||||||
|
wood
|
||||||
|
wood
|
||||||
|
wood
|
||||||
|
wood
|
||||||
|
wood
|
||||||
|
plastic
|
||||||
|
plastic
|
||||||
|
plastic
|
||||||
|
plastic
|
||||||
|
plastic
|
||||||
|
plastic
|
||||||
|
plastic
|
||||||
|
plastic
|
||||||
|
plastic
|
||||||
|
plastic
|
||||||
|
plastic
|
||||||
|
plastic
|
||||||
|
plastic
|
||||||
|
plastic
|
||||||
|
plastic
|
||||||
|
plastic
|
||||||
|
metal
|
||||||
|
metal
|
||||||
|
metal
|
||||||
|
metal
|
||||||
|
metal
|
||||||
|
metal
|
||||||
|
metal
|
||||||
|
metal
|
||||||
|
metal
|
||||||
|
metal
|
||||||
|
metal
|
||||||
|
metal
|
||||||
|
metal
|
||||||
|
metal
|
||||||
|
metal
|
||||||
|
metal
|
||||||
|
axe
|
||||||
|
ballon
|
||||||
|
club
|
||||||
|
fireplace
|
||||||
|
hangglider
|
||||||
|
sailingraft
|
||||||
|
shack
|
||||||
|
steamboat
|
||||||
|
Error, need fireplace to build
|
||||||
|
OK
|
||||||
|
OK
|
30
src/edu/kit/informatik/MainTest.java
Normal file
30
src/edu/kit/informatik/MainTest.java
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
package edu.kit.informatik;
|
||||||
|
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
|
||||||
|
import java.io.*;
|
||||||
|
import java.nio.file.Files;
|
||||||
|
|
||||||
|
import static org.junit.jupiter.api.Assertions.*;
|
||||||
|
|
||||||
|
class MainTest {
|
||||||
|
@Test
|
||||||
|
void game1() throws IOException {
|
||||||
|
cmpInOut("game1_input.txt", "game1_output.txt");
|
||||||
|
}
|
||||||
|
|
||||||
|
private void cmpInOut(String in, String out) throws IOException {
|
||||||
|
System.setIn(new ByteArrayInputStream(readFile(in)));
|
||||||
|
ByteArrayOutputStream output = new ByteArrayOutputStream();
|
||||||
|
System.setOut(new PrintStream(output));
|
||||||
|
Terminal.reload();
|
||||||
|
Main.main(null);
|
||||||
|
String expected = new String(readFile(out));
|
||||||
|
assertEquals(expected, output.toString());
|
||||||
|
}
|
||||||
|
|
||||||
|
private byte[] readFile(String name) throws IOException {
|
||||||
|
File file = new File(name);
|
||||||
|
return Files.readAllBytes(file.toPath());
|
||||||
|
}
|
||||||
|
}
|
@ -8,16 +8,21 @@ import java.util.Arrays;
|
|||||||
import java.util.Deque;
|
import java.util.Deque;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
import static edu.kit.informatik.model.Item.AXE;
|
import static edu.kit.informatik.model.Item.AXE;
|
||||||
|
import static edu.kit.informatik.model.Item.BALLOON;
|
||||||
import static edu.kit.informatik.model.Item.CLUB;
|
import static edu.kit.informatik.model.Item.CLUB;
|
||||||
import static edu.kit.informatik.model.Item.FIREPLACE;
|
import static edu.kit.informatik.model.Item.FIREPLACE;
|
||||||
|
import static edu.kit.informatik.model.Item.HANG_GLIDER;
|
||||||
|
import static edu.kit.informatik.model.Item.SAILING_RAFT;
|
||||||
import static edu.kit.informatik.model.Item.SHACK;
|
import static edu.kit.informatik.model.Item.SHACK;
|
||||||
|
import static edu.kit.informatik.model.Item.STEAMBOAT;
|
||||||
|
|
||||||
public class CardGame {
|
public class CardGame {
|
||||||
private Deque<Card> cardStack;
|
private Deque<Card> cardStack;
|
||||||
private Deque<Card> resources = new ArrayDeque<>();
|
private Deque<Card> resources = new ArrayDeque<>();
|
||||||
private List<Item> buildings = new ArrayList<>();
|
private List<Item> items = new ArrayList<>();
|
||||||
private boolean fightingAnimal = false;
|
private boolean fightingAnimal = false;
|
||||||
private Integer awaitedDiceSize = null;
|
private Integer awaitedDiceSize = null;
|
||||||
private Integer minimumDiceRoll = null;
|
private Integer minimumDiceRoll = null;
|
||||||
@ -52,7 +57,7 @@ public class CardGame {
|
|||||||
minimumDiceRoll = card.minimumDiceRollNeeded();
|
minimumDiceRoll = card.minimumDiceRollNeeded();
|
||||||
} else if (card.isCatastrophe()) {
|
} else if (card.isCatastrophe()) {
|
||||||
clearResources();
|
clearResources();
|
||||||
buildings.remove(FIREPLACE);
|
items.remove(FIREPLACE);
|
||||||
}
|
}
|
||||||
return card;
|
return card;
|
||||||
}
|
}
|
||||||
@ -65,22 +70,24 @@ public class CardGame {
|
|||||||
throw new InvalidInputException("unexpected dice size");
|
throw new InvalidInputException("unexpected dice size");
|
||||||
}
|
}
|
||||||
if (fightingAnimal) {
|
if (fightingAnimal) {
|
||||||
int bonus = buildings.contains(AXE) ? 2 : buildings.contains(CLUB) ? 1 : 0;
|
int bonus = items.contains(AXE) ? 2 : items.contains(CLUB) ? 1 : 0;
|
||||||
if (roll + bonus < minimumDiceRoll) {
|
if (roll + bonus >= minimumDiceRoll) {
|
||||||
|
return "survived";
|
||||||
|
} else {
|
||||||
clearResources();
|
clearResources();
|
||||||
return "lose";
|
return "lose";
|
||||||
} else {
|
|
||||||
return "survived";
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// TODO trying to flee
|
if (roll >= minimumDiceRoll) {
|
||||||
return "win";
|
return "win";
|
||||||
// return "lose";
|
} else {
|
||||||
|
return "lose";
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void clearResources() {
|
public void clearResources() {
|
||||||
int keepLastResources = buildings.contains(SHACK) ? 5 : 0;
|
int keepLastResources = items.contains(SHACK) ? 5 : 0;
|
||||||
while (resources.size() > keepLastResources) {
|
while (resources.size() > keepLastResources) {
|
||||||
resources.removeFirst();
|
resources.removeFirst();
|
||||||
}
|
}
|
||||||
@ -90,6 +97,32 @@ public class CardGame {
|
|||||||
if (item == null) {
|
if (item == null) {
|
||||||
throw new InvalidInputException("can not build null item");
|
throw new InvalidInputException("can not build null item");
|
||||||
}
|
}
|
||||||
|
if (item.requiresFireplace() && !items.contains(FIREPLACE)) {
|
||||||
|
throw new InvalidInputException("need fireplace to build");
|
||||||
|
}
|
||||||
|
if (canBuild(item)) {
|
||||||
|
// remove used resources
|
||||||
|
for (Card resource : item.resourcesNeeded()) {
|
||||||
|
assert(resources.removeLastOccurrence(resource)); // TODO: remove assert
|
||||||
|
}
|
||||||
|
items.add(item);
|
||||||
|
// TODO: building to flee
|
||||||
|
if (items.equals(STEAMBOAT) || items.equals(BALLOON)) {
|
||||||
|
// player won
|
||||||
|
reset();
|
||||||
|
} else if (items.equals(SAILING_RAFT) || items.equals(HANG_GLIDER)) {
|
||||||
|
// need at least a 4/d6
|
||||||
|
fightingAnimal = false;
|
||||||
|
awaitedDiceSize = 6;
|
||||||
|
minimumDiceRoll = 4;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
} else {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean canBuild(Item item) {
|
||||||
Card[] resourcesNeeded = item.resourcesNeeded();
|
Card[] resourcesNeeded = item.resourcesNeeded();
|
||||||
for (Card resource : resources) {
|
for (Card resource : resources) {
|
||||||
for (int j = 0; j < resourcesNeeded.length; j++) {
|
for (int j = 0; j < resourcesNeeded.length; j++) {
|
||||||
@ -99,17 +132,7 @@ public class CardGame {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (Arrays.stream(resourcesNeeded).allMatch(Objects::isNull)) {
|
return Arrays.stream(resourcesNeeded).allMatch(Objects::isNull);
|
||||||
// remove used resources
|
|
||||||
for (Card resource : item.resourcesNeeded()) {
|
|
||||||
assert(resources.remove(resource)); // TODO: remove assert
|
|
||||||
}
|
|
||||||
buildings.add(item);
|
|
||||||
// TODO: building to flee
|
|
||||||
return true;
|
|
||||||
} else {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public Deque<Card> getResources() {
|
public Deque<Card> getResources() {
|
||||||
@ -117,15 +140,19 @@ public class CardGame {
|
|||||||
return new ArrayDeque<>(resources);
|
return new ArrayDeque<>(resources);
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<Item> getBuildings() {
|
public List<Item> getItems() {
|
||||||
// do not allow caller to modify internal list
|
// do not allow caller to modify internal list
|
||||||
return new ArrayList<>(buildings);
|
return new ArrayList<>(items);
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<Item> getBuildableItems() {
|
||||||
|
return Arrays.stream(Item.values()).filter(this::canBuild).collect(Collectors.toList());
|
||||||
}
|
}
|
||||||
|
|
||||||
public void reset() {
|
public void reset() {
|
||||||
this.cardStack = null;
|
this.cardStack = null;
|
||||||
this.resources = new ArrayDeque<>();
|
this.resources = new ArrayDeque<>();
|
||||||
this.buildings = new ArrayList<>();
|
this.items = new ArrayList<>();
|
||||||
this.fightingAnimal = false;
|
this.fightingAnimal = false;
|
||||||
this.awaitedDiceSize = null;
|
this.awaitedDiceSize = null;
|
||||||
this.minimumDiceRoll = null;
|
this.minimumDiceRoll = null;
|
||||||
|
@ -37,6 +37,10 @@ public enum Item {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public boolean requiresFireplace() {
|
||||||
|
return this.equals(STEAMBOAT) || this.equals(BALLOON);
|
||||||
|
}
|
||||||
|
|
||||||
public static Item parse(String input) {
|
public static Item parse(String input) {
|
||||||
switch (input) {
|
switch (input) {
|
||||||
case "axe":
|
case "axe":
|
||||||
|
@ -5,6 +5,9 @@ import edu.kit.informatik.Terminal;
|
|||||||
import edu.kit.informatik.ui.command.Command;
|
import edu.kit.informatik.ui.command.Command;
|
||||||
import edu.kit.informatik.ui.command.CommandFactory;
|
import edu.kit.informatik.ui.command.CommandFactory;
|
||||||
|
|
||||||
|
import java.util.StringJoiner;
|
||||||
|
import java.util.stream.IntStream;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Interactive game runner, gets user inputs and processes commands specified.
|
* Interactive game runner, gets user inputs and processes commands specified.
|
||||||
*
|
*
|
||||||
@ -39,6 +42,12 @@ public final class CommandLine {
|
|||||||
if (input.startsWith("#")) {
|
if (input.startsWith("#")) {
|
||||||
continue; // TODO remove
|
continue; // TODO remove
|
||||||
}
|
}
|
||||||
|
if (input.startsWith("startn")) {
|
||||||
|
// TODO remove
|
||||||
|
StringJoiner j = new StringJoiner(",");
|
||||||
|
IntStream.range(0, 64).mapToObj(x -> Terminal.readLine()).forEach(j::add);
|
||||||
|
input = "start " + j.toString();
|
||||||
|
}
|
||||||
|
|
||||||
if (input.startsWith(QUIT)) {
|
if (input.startsWith(QUIT)) {
|
||||||
if (input.length() != QUIT.length()) {
|
if (input.length() != QUIT.length()) {
|
||||||
|
@ -19,6 +19,8 @@ public class Build extends Command {
|
|||||||
public void apply(CardGame game) throws InvalidInputException {
|
public void apply(CardGame game) throws InvalidInputException {
|
||||||
if (game.build(item)) {
|
if (game.build(item)) {
|
||||||
Terminal.printLine("OK");
|
Terminal.printLine("OK");
|
||||||
|
} else {
|
||||||
|
Terminal.printError("could not build item");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,14 +1,25 @@
|
|||||||
package edu.kit.informatik.ui.command;
|
package edu.kit.informatik.ui.command;
|
||||||
|
|
||||||
|
import edu.kit.informatik.Terminal;
|
||||||
import edu.kit.informatik.model.CardGame;
|
import edu.kit.informatik.model.CardGame;
|
||||||
|
import edu.kit.informatik.model.Item;
|
||||||
import edu.kit.informatik.ui.InvalidInputException;
|
import edu.kit.informatik.ui.InvalidInputException;
|
||||||
|
|
||||||
|
import java.util.Comparator;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
import static edu.kit.informatik.ui.command.CommandFactory.BUILDABLE;
|
import static edu.kit.informatik.ui.command.CommandFactory.BUILDABLE;
|
||||||
|
|
||||||
public class Buildable extends Command {
|
public class Buildable extends Command {
|
||||||
@Override
|
@Override
|
||||||
public void apply(CardGame game) {
|
public void apply(CardGame game) {
|
||||||
|
List<Item> buildable = game.getBuildableItems();
|
||||||
|
if (buildable.isEmpty()) {
|
||||||
|
Terminal.printLine("EMPTY");
|
||||||
|
} else {
|
||||||
|
buildable.sort(Comparator.comparing(Object::toString));
|
||||||
|
buildable.forEach(Terminal::printLine);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -12,7 +12,7 @@ import static edu.kit.informatik.ui.command.CommandFactory.LIST_BUILDINGS;
|
|||||||
public class ListBuildings extends Command {
|
public class ListBuildings extends Command {
|
||||||
@Override
|
@Override
|
||||||
public void apply(CardGame game) throws InvalidInputException {
|
public void apply(CardGame game) throws InvalidInputException {
|
||||||
List<Item> items = game.getBuildings();
|
List<Item> items = game.getItems();
|
||||||
if (items.isEmpty()) {
|
if (items.isEmpty()) {
|
||||||
Terminal.printLine("EMPTY");
|
Terminal.printLine("EMPTY");
|
||||||
} else {
|
} else {
|
||||||
|
@ -5,14 +5,14 @@ import edu.kit.informatik.model.Card;
|
|||||||
import edu.kit.informatik.model.CardGame;
|
import edu.kit.informatik.model.CardGame;
|
||||||
import edu.kit.informatik.ui.InvalidInputException;
|
import edu.kit.informatik.ui.InvalidInputException;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.Deque;
|
||||||
|
|
||||||
import static edu.kit.informatik.ui.command.CommandFactory.LIST_RESOURCES;
|
import static edu.kit.informatik.ui.command.CommandFactory.LIST_RESOURCES;
|
||||||
|
|
||||||
public class ListResources extends Command {
|
public class ListResources extends Command {
|
||||||
@Override
|
@Override
|
||||||
public void apply(CardGame game) throws InvalidInputException {
|
public void apply(CardGame game) throws InvalidInputException {
|
||||||
List<Card> resources = game.getResources();
|
Deque<Card> resources = game.getResources();
|
||||||
if (resources.isEmpty()) {
|
if (resources.isEmpty()) {
|
||||||
Terminal.printLine("EMPTY");
|
Terminal.printLine("EMPTY");
|
||||||
} else {
|
} else {
|
||||||
|
@ -6,6 +6,7 @@ import edu.kit.informatik.model.CardGame;
|
|||||||
import edu.kit.informatik.ui.InvalidInputException;
|
import edu.kit.informatik.ui.InvalidInputException;
|
||||||
|
|
||||||
import java.util.ArrayDeque;
|
import java.util.ArrayDeque;
|
||||||
|
import java.util.Arrays;
|
||||||
import java.util.Deque;
|
import java.util.Deque;
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
import java.util.regex.Matcher;
|
import java.util.regex.Matcher;
|
||||||
@ -16,7 +17,7 @@ import java.util.stream.IntStream;
|
|||||||
import static edu.kit.informatik.ui.command.CommandFactory.CARD;
|
import static edu.kit.informatik.ui.command.CommandFactory.CARD;
|
||||||
|
|
||||||
public class Start extends Command {
|
public class Start extends Command {
|
||||||
private static final Pattern START_ARGUMENTS = Pattern.compile("start (?:(" + CARD + "),){63},(" + CARD + ")");
|
private static final Pattern START_ARGUMENTS = Pattern.compile("start ((?:(?:" + CARD + "),){63}(?:" + CARD + "))");
|
||||||
|
|
||||||
private Deque<Card> cards;
|
private Deque<Card> cards;
|
||||||
|
|
||||||
@ -38,8 +39,7 @@ public class Start extends Command {
|
|||||||
if (!matcher.matches()) {
|
if (!matcher.matches()) {
|
||||||
throw new InvalidInputException("invalid start arguments");
|
throw new InvalidInputException("invalid start arguments");
|
||||||
}
|
}
|
||||||
cards = IntStream.rangeClosed(1, matcher.groupCount())
|
cards = Arrays.stream(matcher.group(1).split(","))
|
||||||
.mapToObj(matcher::group)
|
|
||||||
.map(Card::parse)
|
.map(Card::parse)
|
||||||
.collect(Collectors.toCollection(ArrayDeque::new));
|
.collect(Collectors.toCollection(ArrayDeque::new));
|
||||||
if (cards.stream().anyMatch(Objects::isNull)) {
|
if (cards.stream().anyMatch(Objects::isNull)) {
|
||||||
|
Loading…
Reference in New Issue
Block a user