mirror of
https://gitlab.com/arnekeller/kit-programmieren-ws1920-final2.git
synced 2024-11-24 01:15:03 +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.List;
|
||||
import java.util.Objects;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
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.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.STEAMBOAT;
|
||||
|
||||
public class CardGame {
|
||||
private Deque<Card> cardStack;
|
||||
private Deque<Card> resources = new ArrayDeque<>();
|
||||
private List<Item> buildings = new ArrayList<>();
|
||||
private List<Item> items = new ArrayList<>();
|
||||
private boolean fightingAnimal = false;
|
||||
private Integer awaitedDiceSize = null;
|
||||
private Integer minimumDiceRoll = null;
|
||||
@ -52,7 +57,7 @@ public class CardGame {
|
||||
minimumDiceRoll = card.minimumDiceRollNeeded();
|
||||
} else if (card.isCatastrophe()) {
|
||||
clearResources();
|
||||
buildings.remove(FIREPLACE);
|
||||
items.remove(FIREPLACE);
|
||||
}
|
||||
return card;
|
||||
}
|
||||
@ -65,22 +70,24 @@ public class CardGame {
|
||||
throw new InvalidInputException("unexpected dice size");
|
||||
}
|
||||
if (fightingAnimal) {
|
||||
int bonus = buildings.contains(AXE) ? 2 : buildings.contains(CLUB) ? 1 : 0;
|
||||
if (roll + bonus < minimumDiceRoll) {
|
||||
int bonus = items.contains(AXE) ? 2 : items.contains(CLUB) ? 1 : 0;
|
||||
if (roll + bonus >= minimumDiceRoll) {
|
||||
return "survived";
|
||||
} else {
|
||||
clearResources();
|
||||
return "lose";
|
||||
} else {
|
||||
return "survived";
|
||||
}
|
||||
} else {
|
||||
// TODO trying to flee
|
||||
if (roll >= minimumDiceRoll) {
|
||||
return "win";
|
||||
// return "lose";
|
||||
} else {
|
||||
return "lose";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void clearResources() {
|
||||
int keepLastResources = buildings.contains(SHACK) ? 5 : 0;
|
||||
int keepLastResources = items.contains(SHACK) ? 5 : 0;
|
||||
while (resources.size() > keepLastResources) {
|
||||
resources.removeFirst();
|
||||
}
|
||||
@ -90,6 +97,32 @@ public class CardGame {
|
||||
if (item == null) {
|
||||
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();
|
||||
for (Card resource : resources) {
|
||||
for (int j = 0; j < resourcesNeeded.length; j++) {
|
||||
@ -99,17 +132,7 @@ public class CardGame {
|
||||
}
|
||||
}
|
||||
}
|
||||
if (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;
|
||||
}
|
||||
return Arrays.stream(resourcesNeeded).allMatch(Objects::isNull);
|
||||
}
|
||||
|
||||
public Deque<Card> getResources() {
|
||||
@ -117,15 +140,19 @@ public class CardGame {
|
||||
return new ArrayDeque<>(resources);
|
||||
}
|
||||
|
||||
public List<Item> getBuildings() {
|
||||
public List<Item> getItems() {
|
||||
// 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() {
|
||||
this.cardStack = null;
|
||||
this.resources = new ArrayDeque<>();
|
||||
this.buildings = new ArrayList<>();
|
||||
this.items = new ArrayList<>();
|
||||
this.fightingAnimal = false;
|
||||
this.awaitedDiceSize = 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) {
|
||||
switch (input) {
|
||||
case "axe":
|
||||
|
@ -5,6 +5,9 @@ import edu.kit.informatik.Terminal;
|
||||
import edu.kit.informatik.ui.command.Command;
|
||||
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.
|
||||
*
|
||||
@ -39,6 +42,12 @@ public final class CommandLine {
|
||||
if (input.startsWith("#")) {
|
||||
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.length() != QUIT.length()) {
|
||||
|
@ -19,6 +19,8 @@ public class Build extends Command {
|
||||
public void apply(CardGame game) throws InvalidInputException {
|
||||
if (game.build(item)) {
|
||||
Terminal.printLine("OK");
|
||||
} else {
|
||||
Terminal.printError("could not build item");
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1,14 +1,25 @@
|
||||
package edu.kit.informatik.ui.command;
|
||||
|
||||
import edu.kit.informatik.Terminal;
|
||||
import edu.kit.informatik.model.CardGame;
|
||||
import edu.kit.informatik.model.Item;
|
||||
import edu.kit.informatik.ui.InvalidInputException;
|
||||
|
||||
import java.util.Comparator;
|
||||
import java.util.List;
|
||||
|
||||
import static edu.kit.informatik.ui.command.CommandFactory.BUILDABLE;
|
||||
|
||||
public class Buildable extends Command {
|
||||
@Override
|
||||
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
|
||||
|
@ -12,7 +12,7 @@ import static edu.kit.informatik.ui.command.CommandFactory.LIST_BUILDINGS;
|
||||
public class ListBuildings extends Command {
|
||||
@Override
|
||||
public void apply(CardGame game) throws InvalidInputException {
|
||||
List<Item> items = game.getBuildings();
|
||||
List<Item> items = game.getItems();
|
||||
if (items.isEmpty()) {
|
||||
Terminal.printLine("EMPTY");
|
||||
} else {
|
||||
|
@ -5,14 +5,14 @@ import edu.kit.informatik.model.Card;
|
||||
import edu.kit.informatik.model.CardGame;
|
||||
import edu.kit.informatik.ui.InvalidInputException;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Deque;
|
||||
|
||||
import static edu.kit.informatik.ui.command.CommandFactory.LIST_RESOURCES;
|
||||
|
||||
public class ListResources extends Command {
|
||||
@Override
|
||||
public void apply(CardGame game) throws InvalidInputException {
|
||||
List<Card> resources = game.getResources();
|
||||
Deque<Card> resources = game.getResources();
|
||||
if (resources.isEmpty()) {
|
||||
Terminal.printLine("EMPTY");
|
||||
} else {
|
||||
|
@ -6,6 +6,7 @@ import edu.kit.informatik.model.CardGame;
|
||||
import edu.kit.informatik.ui.InvalidInputException;
|
||||
|
||||
import java.util.ArrayDeque;
|
||||
import java.util.Arrays;
|
||||
import java.util.Deque;
|
||||
import java.util.Objects;
|
||||
import java.util.regex.Matcher;
|
||||
@ -16,7 +17,7 @@ import java.util.stream.IntStream;
|
||||
import static edu.kit.informatik.ui.command.CommandFactory.CARD;
|
||||
|
||||
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;
|
||||
|
||||
@ -38,8 +39,7 @@ public class Start extends Command {
|
||||
if (!matcher.matches()) {
|
||||
throw new InvalidInputException("invalid start arguments");
|
||||
}
|
||||
cards = IntStream.rangeClosed(1, matcher.groupCount())
|
||||
.mapToObj(matcher::group)
|
||||
cards = Arrays.stream(matcher.group(1).split(","))
|
||||
.map(Card::parse)
|
||||
.collect(Collectors.toCollection(ArrayDeque::new));
|
||||
if (cards.stream().anyMatch(Objects::isNull)) {
|
||||
|
Loading…
Reference in New Issue
Block a user