Merge branch 'gamelib' of https://gitlab.informatik.uni-ulm.de/sopra/ws20-marvelous-mashup/teams/team25 into gamelib
This commit is contained in:
commit
1e47a63cb7
@ -1,13 +1,16 @@
|
|||||||
package uulm.teamname.marvelous.gamelibrary;
|
package uulm.teamname.marvelous.gamelibrary;
|
||||||
|
|
||||||
import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
|
import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
|
||||||
|
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
|
||||||
import uulm.teamname.marvelous.gamelibrary.json.ingame.IntVector2Deserializer;
|
import uulm.teamname.marvelous.gamelibrary.json.ingame.IntVector2Deserializer;
|
||||||
|
import uulm.teamname.marvelous.gamelibrary.json.ingame.IntVector2Serializer;
|
||||||
|
|
||||||
import java.io.Serializable;
|
import java.io.Serializable;
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
|
|
||||||
/** Represents a 2d vector of integers. */
|
/** Represents a 2d vector of integers. */
|
||||||
@JsonDeserialize(using = IntVector2Deserializer.class)
|
@JsonDeserialize(using = IntVector2Deserializer.class)
|
||||||
|
@JsonSerialize(using = IntVector2Serializer.class)
|
||||||
public class IntVector2 implements Serializable {
|
public class IntVector2 implements Serializable {
|
||||||
private int x;
|
private int x;
|
||||||
private int y;
|
private int y;
|
||||||
|
@ -1,15 +1,18 @@
|
|||||||
package uulm.teamname.marvelous.gamelibrary.entities;
|
package uulm.teamname.marvelous.gamelibrary.entities;
|
||||||
|
|
||||||
import com.fasterxml.jackson.annotation.JsonProperty;
|
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||||
|
import com.fasterxml.jackson.annotation.JsonPropertyOrder;
|
||||||
import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
|
import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
|
||||||
import uulm.teamname.marvelous.gamelibrary.json.ingame.EntityIDDeserializer;
|
import uulm.teamname.marvelous.gamelibrary.json.ingame.EntityIDDeserializer;
|
||||||
|
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
|
|
||||||
/** Represents a distinct identification for every {@link Entity} in a game. */
|
/** Represents a distinct identification for every {@link Entity} in a game. */
|
||||||
|
@JsonPropertyOrder({"entityID", "ID"})
|
||||||
@JsonDeserialize(using = EntityIDDeserializer.class)
|
@JsonDeserialize(using = EntityIDDeserializer.class)
|
||||||
public class EntityID {
|
public class EntityID {
|
||||||
/** The index of the entity */
|
/** The index of the entity */
|
||||||
|
@JsonProperty("ID")
|
||||||
public final int id;
|
public final int id;
|
||||||
|
|
||||||
/** The type of the entity */
|
/** The type of the entity */
|
||||||
|
@ -3,17 +3,21 @@ package uulm.teamname.marvelous.gamelibrary.json;
|
|||||||
import com.fasterxml.jackson.core.JsonProcessingException;
|
import com.fasterxml.jackson.core.JsonProcessingException;
|
||||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||||
import jdk.jshell.spi.ExecutionControl;
|
import jdk.jshell.spi.ExecutionControl;
|
||||||
|
import uulm.teamname.marvelous.gamelibrary.json.basic.BasicMessage;
|
||||||
import uulm.teamname.marvelous.gamelibrary.json.basic.EventMessage;
|
import uulm.teamname.marvelous.gamelibrary.json.basic.EventMessage;
|
||||||
|
|
||||||
/** Contains JSON encoding and decoding.
|
/** Contains JSON encoding and decoding.
|
||||||
*/
|
*/
|
||||||
public class JSON {
|
public class JSON {
|
||||||
|
|
||||||
|
private static final ObjectMapper mapper = new ObjectMapper();
|
||||||
|
|
||||||
|
|
||||||
/** Deserializes an incoming network message into a {@link EventMessage}.
|
/** Deserializes an incoming network message into a {@link EventMessage}.
|
||||||
* @param input The JSON to deserialize.
|
* @param input The JSON to deserialize.
|
||||||
* @return The parsed message. */
|
* @return The parsed message. */
|
||||||
public static EventMessage parse(String input) {
|
public static EventMessage parse(String input) {
|
||||||
EventMessage result = null;
|
EventMessage result = null;
|
||||||
ObjectMapper mapper = new ObjectMapper();
|
|
||||||
try {
|
try {
|
||||||
result = mapper.readValue(input, EventMessage.class);
|
result = mapper.readValue(input, EventMessage.class);
|
||||||
} catch (JsonProcessingException e) {
|
} catch (JsonProcessingException e) {
|
||||||
@ -25,8 +29,13 @@ public class JSON {
|
|||||||
/** Serializes a {@link EventMessage} into a JSON string.
|
/** Serializes a {@link EventMessage} into a JSON string.
|
||||||
* @param input The message to serialize.
|
* @param input The message to serialize.
|
||||||
* @return The message as JSON. */
|
* @return The message as JSON. */
|
||||||
public static String stringify(EventMessage input) throws ExecutionControl.NotImplementedException {
|
public static String stringify(BasicMessage input) throws ExecutionControl.NotImplementedException {
|
||||||
//TODO: implement JSON.stringify
|
String result = null;
|
||||||
throw new ExecutionControl.NotImplementedException("JSON.stringify is not implemented");
|
try {
|
||||||
|
result = mapper.writeValueAsString(input);
|
||||||
|
} catch (JsonProcessingException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,17 +1,17 @@
|
|||||||
package uulm.teamname.marvelous.gamelibrary.json;
|
package uulm.teamname.marvelous.gamelibrary.json;
|
||||||
|
|
||||||
import com.fasterxml.jackson.core.JsonProcessingException;
|
import com.fasterxml.jackson.core.JsonProcessingException;
|
||||||
|
import com.fasterxml.jackson.core.ObjectCodec;
|
||||||
|
import com.fasterxml.jackson.databind.DeserializationContext;
|
||||||
import com.fasterxml.jackson.databind.JsonNode;
|
import com.fasterxml.jackson.databind.JsonNode;
|
||||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||||
|
|
||||||
public class JsonNodeUnwrapper {
|
public class JsonNodeUnwrapper {
|
||||||
|
|
||||||
private static final ObjectMapper mapper = new ObjectMapper();
|
public static <T> T unwrap(JsonNode subNode, Class<T> type, ObjectCodec codec)
|
||||||
|
throws JsonProcessingException {
|
||||||
public static <T> T unwrap (JsonNode rootNode, String key, Class<T> type) throws JsonProcessingException {
|
if (subNode != null) {
|
||||||
JsonNode subNode;
|
return codec.treeToValue(subNode, type);
|
||||||
if ((subNode = rootNode.get(key)) != null) {
|
|
||||||
return mapper.readValue(subNode.toString(), type);
|
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
@ -21,9 +21,6 @@ public class EntityDeserializer extends JsonDeserializer<Entity> {
|
|||||||
Rock
|
Rock
|
||||||
}
|
}
|
||||||
|
|
||||||
// static so that no reinitializations are needed
|
|
||||||
private static final ObjectMapper mapper = new ObjectMapper();
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Entity deserialize(JsonParser p, DeserializationContext ctxt) throws IOException {
|
public Entity deserialize(JsonParser p, DeserializationContext ctxt) throws IOException {
|
||||||
ObjectCodec codec = p.getCodec();
|
ObjectCodec codec = p.getCodec();
|
||||||
@ -40,7 +37,7 @@ public class EntityDeserializer extends JsonDeserializer<Entity> {
|
|||||||
node.get("ID").intValue());
|
node.get("ID").intValue());
|
||||||
result = new Character(
|
result = new Character(
|
||||||
id,
|
id,
|
||||||
mapper.readValue(node.get("position").toString(), IntVector2.class),
|
codec.treeToValue(node.get("position"), IntVector2.class),
|
||||||
node.get("name").asText(),
|
node.get("name").asText(),
|
||||||
node.get("HP").asInt(),
|
node.get("HP").asInt(),
|
||||||
node.get("MP").asInt(),
|
node.get("MP").asInt(),
|
||||||
@ -50,21 +47,21 @@ public class EntityDeserializer extends JsonDeserializer<Entity> {
|
|||||||
-1
|
-1
|
||||||
);
|
);
|
||||||
|
|
||||||
for (var i: mapper.readValue(node.get("stones").toString(), Integer[].class)) {
|
for (var i: codec.treeToValue(node.get("stones"), Integer[].class)) {
|
||||||
((Character) result).inventory.addStone(StoneType.valueOf(i));
|
((Character) result).inventory.addStone(StoneType.valueOf(i));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
case InfinityStone -> {
|
case InfinityStone -> {
|
||||||
result = new InfinityStone(
|
result = new InfinityStone(
|
||||||
new EntityID(EntityType.InfinityStones, node.get("ID").asInt()),
|
new EntityID(EntityType.InfinityStones, node.get("ID").asInt()),
|
||||||
mapper.readValue(node.get("position").toString(), IntVector2.class),
|
codec.treeToValue(node.get("position"), IntVector2.class),
|
||||||
StoneType.valueOf(node.get("ID").asInt())
|
StoneType.valueOf(node.get("ID").asInt())
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
case Rock -> {
|
case Rock -> {
|
||||||
result = new Rock(
|
result = new Rock(
|
||||||
new EntityID(EntityType.Rocks, node.get("ID").asInt()),
|
new EntityID(EntityType.Rocks, node.get("ID").asInt()),
|
||||||
mapper.readValue(node.get("position").toString(), IntVector2.class),
|
codec.treeToValue(node.get("position"), IntVector2.class),
|
||||||
node.get("HP").asInt()
|
node.get("HP").asInt()
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -1,12 +1,10 @@
|
|||||||
package uulm.teamname.marvelous.gamelibrary.json.ingame;
|
package uulm.teamname.marvelous.gamelibrary.json.ingame;
|
||||||
|
|
||||||
import com.fasterxml.jackson.core.JsonParser;
|
import com.fasterxml.jackson.core.JsonParser;
|
||||||
import com.fasterxml.jackson.core.JsonProcessingException;
|
|
||||||
import com.fasterxml.jackson.core.ObjectCodec;
|
import com.fasterxml.jackson.core.ObjectCodec;
|
||||||
import com.fasterxml.jackson.databind.DeserializationContext;
|
import com.fasterxml.jackson.databind.DeserializationContext;
|
||||||
import com.fasterxml.jackson.databind.JsonDeserializer;
|
import com.fasterxml.jackson.databind.JsonDeserializer;
|
||||||
import com.fasterxml.jackson.databind.JsonNode;
|
import com.fasterxml.jackson.databind.JsonNode;
|
||||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
|
||||||
import uulm.teamname.marvelous.gamelibrary.IntVector2;
|
import uulm.teamname.marvelous.gamelibrary.IntVector2;
|
||||||
import uulm.teamname.marvelous.gamelibrary.entities.Entity;
|
import uulm.teamname.marvelous.gamelibrary.entities.Entity;
|
||||||
import uulm.teamname.marvelous.gamelibrary.entities.EntityID;
|
import uulm.teamname.marvelous.gamelibrary.entities.EntityID;
|
||||||
@ -14,19 +12,14 @@ import uulm.teamname.marvelous.gamelibrary.entities.StoneType;
|
|||||||
import uulm.teamname.marvelous.gamelibrary.events.Event;
|
import uulm.teamname.marvelous.gamelibrary.events.Event;
|
||||||
import uulm.teamname.marvelous.gamelibrary.events.EventBuilder;
|
import uulm.teamname.marvelous.gamelibrary.events.EventBuilder;
|
||||||
import uulm.teamname.marvelous.gamelibrary.events.EventType;
|
import uulm.teamname.marvelous.gamelibrary.events.EventType;
|
||||||
import uulm.teamname.marvelous.gamelibrary.events.GamestateEvent;
|
|
||||||
|
|
||||||
import static uulm.teamname.marvelous.gamelibrary.json.JsonNodeUnwrapper.unwrap;
|
import static uulm.teamname.marvelous.gamelibrary.json.JsonNodeUnwrapper.unwrap;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.util.Arrays;
|
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
|
|
||||||
public class EventDeserializer extends JsonDeserializer<Event> {
|
public class EventDeserializer extends JsonDeserializer<Event> {
|
||||||
|
|
||||||
// static so that no reinitializations are needed
|
|
||||||
private static final ObjectMapper mapper = new ObjectMapper();
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Event deserialize(JsonParser p, DeserializationContext ctxt) throws IOException {
|
public Event deserialize(JsonParser p, DeserializationContext ctxt) throws IOException {
|
||||||
ObjectCodec codec = p.getCodec();
|
ObjectCodec codec = p.getCodec();
|
||||||
@ -76,40 +69,40 @@ public class EventDeserializer extends JsonDeserializer<Event> {
|
|||||||
// }
|
// }
|
||||||
|
|
||||||
// necessary because of exact type mismatch
|
// necessary because of exact type mismatch
|
||||||
var stoneTypeID = unwrap(node, "stoneType", EntityID.class);
|
var stoneTypeID = unwrap(node.get("stoneType"), EntityID.class, codec);
|
||||||
|
|
||||||
builder.withTargetEntity(unwrap(node, "targetEntity", EntityID.class))
|
builder.withTargetEntity(unwrap(node.get("targetEntity"), EntityID.class, codec))
|
||||||
.withTargetField(unwrap(node, "targetField", IntVector2.class))
|
.withTargetField(unwrap(node.get("targetField"), IntVector2.class, codec))
|
||||||
.withAmount(unwrap(node, "targetField", Integer.class))
|
.withAmount(unwrap(node.get("targetField"), Integer.class, codec))
|
||||||
.withEntity(unwrap(node, "entity", Entity.class))
|
.withEntity(unwrap(node.get("entity"), Entity.class, codec))
|
||||||
|
|
||||||
.withOriginEntity(unwrap(node, "originEntity", EntityID.class))
|
.withOriginEntity(unwrap(node.get("originEntity"), EntityID.class, codec))
|
||||||
.withOriginField(unwrap(node, "originField", IntVector2.class))
|
.withOriginField(unwrap(node.get("originField"), IntVector2.class, codec))
|
||||||
.withStoneType(stoneTypeID != null ? StoneType.valueOf(stoneTypeID.id) : null)
|
.withStoneType(stoneTypeID != null ? StoneType.valueOf(stoneTypeID.id) : null)
|
||||||
|
|
||||||
.withRoundCount(unwrap(node, "roundCount", Integer.class))
|
.withRoundCount(unwrap(node.get("roundCount"), Integer.class, codec))
|
||||||
.withTurnCount(unwrap(node, "turnCount", Integer.class))
|
.withTurnCount(unwrap(node.get("turnCount"), Integer.class, codec))
|
||||||
.withCharacterOrder(unwrap(node, "characterOrder", EntityID[].class))
|
.withCharacterOrder(unwrap(node.get("characterOrder"), EntityID[].class, codec))
|
||||||
.withNextCharacter(unwrap(node, "nextCharacter", EntityID.class))
|
.withNextCharacter(unwrap(node.get("nextCharacter"), EntityID.class, codec))
|
||||||
|
|
||||||
.withPlayerWon(unwrap(node, "playerWon", Integer.class))
|
.withPlayerWon(unwrap(node.get("playerWon"), Integer.class, codec))
|
||||||
|
|
||||||
.withMessage(unwrap(node, "message", String.class))
|
.withMessage(unwrap(node.get("message"), String.class, codec))
|
||||||
.withTimeLeft(unwrap(node, "timeLeft", Integer.class))
|
.withTimeLeft(unwrap(node.get("timeLeft"), Integer.class, codec))
|
||||||
|
|
||||||
.withEntities(unwrap(node, "entities", Entity[].class))
|
.withEntities(unwrap(node.get("entities"), Entity[].class, codec))
|
||||||
.withTurnOrder(unwrap(node, "turnOrder", EntityID[].class))
|
.withTurnOrder(unwrap(node.get("turnOrder"), EntityID[].class, codec))
|
||||||
.withMapSize(unwrap(node, "mapSize", IntVector2.class))
|
.withMapSize(unwrap(node.get("mapSize"), IntVector2.class, codec))
|
||||||
.withActiveCharacter(unwrap(node, "activeCharacter", EntityID.class))
|
.withActiveCharacter(unwrap(node.get("activeCharacter"), EntityID.class, codec))
|
||||||
.withStoneCooldowns(unwrap(node, "stoneCooldowns",Integer[].class))
|
.withStoneCooldowns(unwrap(node.get("stoneCooldowns"), Integer[].class, codec))
|
||||||
.withWinCondition(unwrap(node, "winCondition",Boolean.class))
|
.withWinCondition(unwrap(node.get("winCondition"), Boolean.class, codec))
|
||||||
|
|
||||||
.withTeamIdentifier(unwrap(node, "teamIdentifier", String.class))
|
.withTeamIdentifier(unwrap(node.get("teamIdentifier"), String.class, codec))
|
||||||
.withCustomContent(unwrap(node,"customContent", HashMap.class));
|
.withCustomContent(unwrap(node.get("customContent"), HashMap.class, codec));
|
||||||
|
|
||||||
|
|
||||||
builder.withTargetEntity(unwrap(node, "targetEntity", EntityID.class));
|
builder.withTargetEntity(unwrap(node.get("targetEntity"), EntityID.class, codec));
|
||||||
builder.withTargetField(unwrap(node, "targetField", IntVector2.class));
|
builder.withTargetField(unwrap(node.get("targetField"), IntVector2.class, codec));
|
||||||
|
|
||||||
switch (eventType) {
|
switch (eventType) {
|
||||||
case Ack, Nack, GamestateEvent -> { return builder.buildGameStateEvent(); }
|
case Ack, Nack, GamestateEvent -> { return builder.buildGameStateEvent(); }
|
||||||
|
@ -12,13 +12,9 @@ import uulm.teamname.marvelous.gamelibrary.IntVector2;
|
|||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
|
||||||
public class IntVector2Deserializer extends JsonDeserializer<IntVector2> {
|
public class IntVector2Deserializer extends JsonDeserializer<IntVector2> {
|
||||||
|
|
||||||
// static so that no reinitializations are needed
|
|
||||||
private static final ObjectMapper mapper = new ObjectMapper();
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public IntVector2 deserialize(JsonParser p, DeserializationContext ctxt) throws IOException {
|
public IntVector2 deserialize(JsonParser p, DeserializationContext ctxt) throws IOException {
|
||||||
var values = mapper.readValue(p, Integer[].class);
|
var values = p.readValueAs(Integer[].class);
|
||||||
IntVector2 result = new IntVector2(values[0], values[1]);
|
IntVector2 result = new IntVector2(values[0], values[1]);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,27 @@
|
|||||||
|
package uulm.teamname.marvelous.gamelibrary.json.ingame;
|
||||||
|
|
||||||
|
import com.fasterxml.jackson.core.JsonGenerator;
|
||||||
|
import com.fasterxml.jackson.databind.SerializerProvider;
|
||||||
|
import com.fasterxml.jackson.databind.ser.std.StdSerializer;
|
||||||
|
import uulm.teamname.marvelous.gamelibrary.IntVector2;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
|
||||||
|
public class IntVector2Serializer extends StdSerializer<IntVector2> {
|
||||||
|
|
||||||
|
public IntVector2Serializer() {
|
||||||
|
this(null);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected IntVector2Serializer(Class<IntVector2> t) {
|
||||||
|
super(t);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void serialize(IntVector2 value, JsonGenerator gen, SerializerProvider provider) throws IOException {
|
||||||
|
gen.writeStartArray();
|
||||||
|
gen.writeNumber(value.getX());
|
||||||
|
gen.writeNumber(value.getY());
|
||||||
|
gen.writeEndArray();
|
||||||
|
}
|
||||||
|
}
|
@ -6,12 +6,9 @@ import com.fasterxml.jackson.core.ObjectCodec;
|
|||||||
import com.fasterxml.jackson.databind.DeserializationContext;
|
import com.fasterxml.jackson.databind.DeserializationContext;
|
||||||
import com.fasterxml.jackson.databind.JsonDeserializer;
|
import com.fasterxml.jackson.databind.JsonDeserializer;
|
||||||
import com.fasterxml.jackson.databind.JsonNode;
|
import com.fasterxml.jackson.databind.JsonNode;
|
||||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
|
||||||
import uulm.teamname.marvelous.gamelibrary.IntVector2;
|
import uulm.teamname.marvelous.gamelibrary.IntVector2;
|
||||||
import uulm.teamname.marvelous.gamelibrary.entities.Entity;
|
|
||||||
import uulm.teamname.marvelous.gamelibrary.entities.EntityID;
|
import uulm.teamname.marvelous.gamelibrary.entities.EntityID;
|
||||||
import uulm.teamname.marvelous.gamelibrary.entities.StoneType;
|
import uulm.teamname.marvelous.gamelibrary.entities.StoneType;
|
||||||
import uulm.teamname.marvelous.gamelibrary.events.Event;
|
|
||||||
import uulm.teamname.marvelous.gamelibrary.requests.*;
|
import uulm.teamname.marvelous.gamelibrary.requests.*;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
@ -21,9 +18,6 @@ import static uulm.teamname.marvelous.gamelibrary.json.JsonNodeUnwrapper.unwrap;
|
|||||||
|
|
||||||
public class RequestDeserializer extends JsonDeserializer<Request> {
|
public class RequestDeserializer extends JsonDeserializer<Request> {
|
||||||
|
|
||||||
// static so that no reinitializations are needed
|
|
||||||
private static final ObjectMapper mapper = new ObjectMapper();
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Request deserialize(JsonParser p, DeserializationContext ctxt) throws IOException, JsonProcessingException {
|
public Request deserialize(JsonParser p, DeserializationContext ctxt) throws IOException, JsonProcessingException {
|
||||||
ObjectCodec codec = p.getCodec();
|
ObjectCodec codec = p.getCodec();
|
||||||
@ -38,12 +32,12 @@ public class RequestDeserializer extends JsonDeserializer<Request> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
var requestBuilder = new RequestBuilder(requestType)
|
var requestBuilder = new RequestBuilder(requestType)
|
||||||
.withValue(unwrap(node, "value", int.class))
|
.withValue(unwrap(node.get("value"), int.class, codec))
|
||||||
.withOriginEntity(unwrap(node, "originEntity", EntityID.class))
|
.withOriginEntity(unwrap(node.get("originEntity"), EntityID.class, codec))
|
||||||
.withTargetEntity(unwrap(node, "targetEntity", EntityID.class))
|
.withTargetEntity(unwrap(node.get("targetEntity"), EntityID.class, codec))
|
||||||
.withOriginField(unwrap(node, "originField", IntVector2.class))
|
.withOriginField(unwrap(node.get("originField"), IntVector2.class, codec))
|
||||||
.withTargetField(unwrap(node, "targetField", IntVector2.class))
|
.withTargetField(unwrap(node.get("targetField"), IntVector2.class, codec))
|
||||||
.withStoneType(Optional.ofNullable(unwrap(node, "stoneType", EntityID.class))
|
.withStoneType(Optional.ofNullable(unwrap(node.get("stoneType"), EntityID.class, codec))
|
||||||
.map(x -> StoneType.valueOf(x.id))
|
.map(x -> StoneType.valueOf(x.id))
|
||||||
.orElseGet(() -> null));
|
.orElseGet(() -> null));
|
||||||
|
|
||||||
|
@ -0,0 +1,83 @@
|
|||||||
|
package uulm.teamname.marvelous.gamelibrary.json.ingame;
|
||||||
|
|
||||||
|
import com.fasterxml.jackson.core.JsonGenerator;
|
||||||
|
import com.fasterxml.jackson.databind.SerializerProvider;
|
||||||
|
import com.fasterxml.jackson.databind.ser.std.StdSerializer;
|
||||||
|
import uulm.teamname.marvelous.gamelibrary.entities.EntityID;
|
||||||
|
import uulm.teamname.marvelous.gamelibrary.entities.EntityType;
|
||||||
|
import uulm.teamname.marvelous.gamelibrary.requests.CharacterRequest;
|
||||||
|
import uulm.teamname.marvelous.gamelibrary.requests.GameRequest;
|
||||||
|
import uulm.teamname.marvelous.gamelibrary.requests.Request;
|
||||||
|
import uulm.teamname.marvelous.gamelibrary.requests.RequestType;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
|
||||||
|
public class RequestSerializer extends StdSerializer<Request> {
|
||||||
|
|
||||||
|
public RequestSerializer() {
|
||||||
|
this(null);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected RequestSerializer(Class<Request> t) {
|
||||||
|
super(t);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void serialize(Request value, JsonGenerator gen, SerializerProvider provider) throws IOException {
|
||||||
|
|
||||||
|
gen.writeStartObject();
|
||||||
|
gen.writeObjectField("requestType", value.type);
|
||||||
|
|
||||||
|
|
||||||
|
if (value instanceof GameRequest) {
|
||||||
|
serializeGameRequest((GameRequest) value, gen, provider);
|
||||||
|
} else if (value instanceof CharacterRequest) {
|
||||||
|
serializeCharacterRequest((CharacterRequest) value, gen, provider);
|
||||||
|
}
|
||||||
|
|
||||||
|
gen.writeEndObject();
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Method invoked after writing the RequestType, and used to write any additional values required */
|
||||||
|
private void serializeGameRequest(GameRequest value, JsonGenerator gen, SerializerProvider provider)
|
||||||
|
throws IOException {
|
||||||
|
return; // does nothing, but still there for consistency
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Method invoked after writing the RequestType, and used to write any additional values required */
|
||||||
|
private void serializeCharacterRequest(CharacterRequest value, JsonGenerator gen, SerializerProvider provider)
|
||||||
|
throws IOException {
|
||||||
|
// The idea here is: if ([GUARD]) {gen.write...} for all fields.
|
||||||
|
|
||||||
|
boolean hasTargetEntity =
|
||||||
|
value.type == RequestType.MeleeAttackRequest ||
|
||||||
|
value.type == RequestType.RangedAttackRequest ||
|
||||||
|
value.type == RequestType.ExchangeInfinityStoneRequest;
|
||||||
|
|
||||||
|
boolean hasStoneType =
|
||||||
|
value.type == RequestType.ExchangeInfinityStoneRequest ||
|
||||||
|
value.type == RequestType.UseInfinityStoneRequest;
|
||||||
|
|
||||||
|
boolean hasValue =
|
||||||
|
value.type == RequestType.MeleeAttackRequest ||
|
||||||
|
value.type == RequestType.RangedAttackRequest;
|
||||||
|
|
||||||
|
|
||||||
|
gen.writeObjectField("originEntity", value.originEntity);
|
||||||
|
|
||||||
|
if (hasTargetEntity) {
|
||||||
|
gen.writeObjectField("targetEntity", value.targetEntity);
|
||||||
|
}
|
||||||
|
|
||||||
|
gen.writeObjectField("originField", value.originField);
|
||||||
|
gen.writeObjectField("targetField", value.targetField);
|
||||||
|
|
||||||
|
if (hasStoneType) {
|
||||||
|
gen.writeObjectField("stoneType", new EntityID(EntityType.InfinityStones, value.stoneType.getID()));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (hasValue) {
|
||||||
|
gen.writeObjectField("value", value.value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -1,5 +1,6 @@
|
|||||||
package uulm.teamname.marvelous.gamelibrary.requests;
|
package uulm.teamname.marvelous.gamelibrary.requests;
|
||||||
|
|
||||||
|
import com.fasterxml.jackson.annotation.JsonPropertyOrder;
|
||||||
import uulm.teamname.marvelous.gamelibrary.IntVector2;
|
import uulm.teamname.marvelous.gamelibrary.IntVector2;
|
||||||
import uulm.teamname.marvelous.gamelibrary.entities.EntityID;
|
import uulm.teamname.marvelous.gamelibrary.entities.EntityID;
|
||||||
import uulm.teamname.marvelous.gamelibrary.entities.StoneType;
|
import uulm.teamname.marvelous.gamelibrary.entities.StoneType;
|
||||||
@ -7,6 +8,7 @@ import uulm.teamname.marvelous.gamelibrary.entities.StoneType;
|
|||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
|
|
||||||
/** Represents a character event for: {@link RequestType#MeleeAttackRequest}, {@link RequestType#RangedAttackRequest}, {@link RequestType#MoveRequest}, {@link RequestType#ExchangeInfinityStoneRequest}, {@link RequestType#UseInfinityStoneRequest}. */
|
/** Represents a character event for: {@link RequestType#MeleeAttackRequest}, {@link RequestType#RangedAttackRequest}, {@link RequestType#MoveRequest}, {@link RequestType#ExchangeInfinityStoneRequest}, {@link RequestType#UseInfinityStoneRequest}. */
|
||||||
|
@JsonPropertyOrder({"requestType", "originEntity", "targetEntity", "originField", "targetField", "stoneType", "value"})
|
||||||
public class CharacterRequest extends Request {
|
public class CharacterRequest extends Request {
|
||||||
public EntityID originEntity = null;
|
public EntityID originEntity = null;
|
||||||
public EntityID targetEntity = null;
|
public EntityID targetEntity = null;
|
||||||
|
@ -1,15 +1,22 @@
|
|||||||
package uulm.teamname.marvelous.gamelibrary.requests;
|
package uulm.teamname.marvelous.gamelibrary.requests;
|
||||||
|
|
||||||
|
import com.fasterxml.jackson.annotation.JsonAlias;
|
||||||
|
import com.fasterxml.jackson.annotation.JsonKey;
|
||||||
|
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||||
import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
|
import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
|
||||||
|
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
|
||||||
import uulm.teamname.marvelous.gamelibrary.json.basic.EventMessage;
|
import uulm.teamname.marvelous.gamelibrary.json.basic.EventMessage;
|
||||||
import uulm.teamname.marvelous.gamelibrary.json.ingame.RequestDeserializer;
|
import uulm.teamname.marvelous.gamelibrary.json.ingame.RequestDeserializer;
|
||||||
|
import uulm.teamname.marvelous.gamelibrary.json.ingame.RequestSerializer;
|
||||||
|
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
|
|
||||||
/** Represents an abstract request sent inside a {@link EventMessage} between client and server. */
|
/** Represents an abstract request sent inside a {@link EventMessage} between client and server. */
|
||||||
@JsonDeserialize(using = RequestDeserializer.class)
|
@JsonDeserialize(using = RequestDeserializer.class)
|
||||||
|
@JsonSerialize(using = RequestSerializer.class)
|
||||||
public abstract class Request {
|
public abstract class Request {
|
||||||
public RequestType type;
|
|
||||||
|
@JsonProperty("requestType") public RequestType type;
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -2,19 +2,27 @@ package uulm.teamname.marvelous.gamelibrary.json;
|
|||||||
|
|
||||||
import com.fasterxml.jackson.core.JsonProcessingException;
|
import com.fasterxml.jackson.core.JsonProcessingException;
|
||||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||||
|
import net.jqwik.api.*;
|
||||||
|
import net.jqwik.api.lifecycle.BeforeContainer;
|
||||||
|
import net.jqwik.api.lifecycle.BeforeProperty;
|
||||||
import org.junit.jupiter.api.AfterEach;
|
import org.junit.jupiter.api.AfterEach;
|
||||||
import org.junit.jupiter.api.BeforeEach;
|
import org.junit.jupiter.api.BeforeEach;
|
||||||
import org.junit.jupiter.api.Disabled;
|
import org.junit.jupiter.api.Disabled;
|
||||||
import org.junit.jupiter.api.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
|
|
||||||
import static org.assertj.core.api.Assertions.*;
|
import static org.assertj.core.api.Assertions.*;
|
||||||
|
|
||||||
|
import uulm.teamname.marvelous.gamelibrary.IntVector2;
|
||||||
import uulm.teamname.marvelous.gamelibrary.entities.EntityID;
|
import uulm.teamname.marvelous.gamelibrary.entities.EntityID;
|
||||||
|
import uulm.teamname.marvelous.gamelibrary.entities.EntityType;
|
||||||
|
import uulm.teamname.marvelous.gamelibrary.entities.Rock;
|
||||||
import uulm.teamname.marvelous.gamelibrary.events.Event;
|
import uulm.teamname.marvelous.gamelibrary.events.Event;
|
||||||
import uulm.teamname.marvelous.gamelibrary.events.EventBuilder;
|
import uulm.teamname.marvelous.gamelibrary.events.EventBuilder;
|
||||||
import uulm.teamname.marvelous.gamelibrary.events.EventType;
|
import uulm.teamname.marvelous.gamelibrary.events.EventType;
|
||||||
import uulm.teamname.marvelous.gamelibrary.json.basic.EventMessage;
|
import uulm.teamname.marvelous.gamelibrary.json.basic.EventMessage;
|
||||||
|
import uulm.teamname.marvelous.gamelibrary.requests.*;
|
||||||
|
|
||||||
import java.util.HashMap;
|
import java.util.*;
|
||||||
|
|
||||||
class JSONTest {
|
class JSONTest {
|
||||||
|
|
||||||
@ -29,11 +37,11 @@ class JSONTest {
|
|||||||
@BeforeEach
|
@BeforeEach
|
||||||
void setUp() {
|
void setUp() {
|
||||||
messageStructureStart = """
|
messageStructureStart = """
|
||||||
{
|
{
|
||||||
"messages":[
|
"messages":[
|
||||||
""";
|
""";
|
||||||
messageStructureEnd = new String[] {
|
messageStructureEnd = new String[]{
|
||||||
"""
|
"""
|
||||||
],
|
],
|
||||||
"messageType": "REQUESTS",
|
"messageType": "REQUESTS",
|
||||||
"customContentType": "TestCustomContent",
|
"customContentType": "TestCustomContent",
|
||||||
@ -43,7 +51,7 @@ class JSONTest {
|
|||||||
"customProperty" = true
|
"customProperty" = true
|
||||||
}
|
}
|
||||||
""",
|
""",
|
||||||
"""
|
"""
|
||||||
],
|
],
|
||||||
"messageType": "EVENTS",
|
"messageType": "EVENTS",
|
||||||
"customContentType": "TestCustomContent",
|
"customContentType": "TestCustomContent",
|
||||||
@ -75,9 +83,9 @@ class JSONTest {
|
|||||||
};
|
};
|
||||||
|
|
||||||
String eventRepresentation = """
|
String eventRepresentation = """
|
||||||
{"eventType": "Ack"},
|
{"eventType": "Ack"},
|
||||||
{"eventType": "Nack"}
|
{"eventType": "Nack"}
|
||||||
""";
|
""";
|
||||||
String completeMessageStructure = messageStructureStart + eventRepresentation + messageStructureEnd[1];
|
String completeMessageStructure = messageStructureStart + eventRepresentation + messageStructureEnd[1];
|
||||||
|
|
||||||
target.messageType = MessageType.EVENTS;
|
target.messageType = MessageType.EVENTS;
|
||||||
@ -90,19 +98,19 @@ class JSONTest {
|
|||||||
@Test
|
@Test
|
||||||
void parseMoreComplicatedEvents() {
|
void parseMoreComplicatedEvents() {
|
||||||
String eventRepresentation = """
|
String eventRepresentation = """
|
||||||
{
|
{
|
||||||
"eventType": "GamestateEvent",
|
"eventType": "GamestateEvent",
|
||||||
"activeCharacter": {"entityID": "P2", "ID": 4},
|
"activeCharacter": {"entityID": "P2", "ID": 4},
|
||||||
"turnOrder": [
|
"turnOrder": [
|
||||||
{"entityID": "P2", "ID": 4},
|
{"entityID": "P2", "ID": 4},
|
||||||
{"entityID": "P2", "ID": 2},
|
{"entityID": "P2", "ID": 2},
|
||||||
{"entityID": "P1", "ID": 3},
|
{"entityID": "P1", "ID": 3},
|
||||||
{"entityID": "NPC", "ID": 1},
|
{"entityID": "NPC", "ID": 1},
|
||||||
{"entityID": "InfinityStones", "ID": 5},
|
{"entityID": "InfinityStones", "ID": 5},
|
||||||
{"entityID": "Rocks", "ID": 0}
|
{"entityID": "Rocks", "ID": 0}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
""";
|
""";
|
||||||
String completeMessageStructure = messageStructureStart + eventRepresentation + messageStructureEnd[1];
|
String completeMessageStructure = messageStructureStart + eventRepresentation + messageStructureEnd[1];
|
||||||
|
|
||||||
System.out.println(JSON.parse(completeMessageStructure));
|
System.out.println(JSON.parse(completeMessageStructure));
|
||||||
@ -112,11 +120,11 @@ class JSONTest {
|
|||||||
@Disabled
|
@Disabled
|
||||||
void simpleInDevTest() throws JsonProcessingException {
|
void simpleInDevTest() throws JsonProcessingException {
|
||||||
String simpleEntity = """
|
String simpleEntity = """
|
||||||
{
|
{
|
||||||
"entityID": "P2",
|
"entityID": "P2",
|
||||||
"ID": 4
|
"ID": 4
|
||||||
}
|
}
|
||||||
""";
|
""";
|
||||||
System.out.println(new ObjectMapper().readValue(simpleEntity, EntityID.class));
|
System.out.println(new ObjectMapper().readValue(simpleEntity, EntityID.class));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -0,0 +1,37 @@
|
|||||||
|
package uulm.teamname.marvelous.gamelibrary.json.ingame;
|
||||||
|
|
||||||
|
import com.fasterxml.jackson.core.JsonProcessingException;
|
||||||
|
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||||
|
import net.jqwik.api.*;
|
||||||
|
import net.jqwik.api.lifecycle.BeforeProperty;
|
||||||
|
import uulm.teamname.marvelous.gamelibrary.IntVector2;
|
||||||
|
|
||||||
|
import static org.mockito.Mockito.*;
|
||||||
|
import static org.junit.jupiter.api.Assertions.*;
|
||||||
|
import static org.assertj.core.api.Assertions.*;
|
||||||
|
|
||||||
|
class IntVector2SerializerTest {
|
||||||
|
|
||||||
|
ObjectMapper mapper = new ObjectMapper();
|
||||||
|
|
||||||
|
@BeforeProperty
|
||||||
|
void setup() {
|
||||||
|
mapper = new ObjectMapper();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Property
|
||||||
|
void vectorsGetProperlyDeserialized(@ForAll @From("positions") IntVector2 vector) throws JsonProcessingException {
|
||||||
|
var jsonRepresentingVector = String.format("[%d,%d]", vector.getX(), vector.getY());
|
||||||
|
assertThat(mapper.writeValueAsString(vector))
|
||||||
|
.isEqualTo(jsonRepresentingVector);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Provide("positions")
|
||||||
|
Arbitrary<IntVector2> positions() {
|
||||||
|
return Arbitraries.integers()
|
||||||
|
.tuple2()
|
||||||
|
.map(pos -> new IntVector2(pos.get1(), pos.get2()));
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,223 @@
|
|||||||
|
package uulm.teamname.marvelous.gamelibrary.json.ingame;
|
||||||
|
|
||||||
|
import com.fasterxml.jackson.core.JsonProcessingException;
|
||||||
|
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||||
|
import net.jqwik.api.*;
|
||||||
|
import net.jqwik.api.lifecycle.BeforeProperty;
|
||||||
|
import uulm.teamname.marvelous.gamelibrary.IntVector2;
|
||||||
|
import uulm.teamname.marvelous.gamelibrary.entities.EntityID;
|
||||||
|
import uulm.teamname.marvelous.gamelibrary.entities.EntityType;
|
||||||
|
import uulm.teamname.marvelous.gamelibrary.entities.StoneType;
|
||||||
|
import uulm.teamname.marvelous.gamelibrary.requests.CharacterRequest;
|
||||||
|
import uulm.teamname.marvelous.gamelibrary.requests.GameRequest;
|
||||||
|
import uulm.teamname.marvelous.gamelibrary.requests.RequestBuilder;
|
||||||
|
import uulm.teamname.marvelous.gamelibrary.requests.RequestType;
|
||||||
|
|
||||||
|
import java.util.HashSet;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
import static org.assertj.core.api.Assertions.assertThat;
|
||||||
|
|
||||||
|
public class RequestSerializerTest {
|
||||||
|
|
||||||
|
private ObjectMapper mapper;
|
||||||
|
@BeforeProperty
|
||||||
|
void setup() {
|
||||||
|
mapper = new ObjectMapper();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@Property
|
||||||
|
void gameRequestsGetSerializedProperly(
|
||||||
|
@ForAll @From("gameRequests") GameRequest request)
|
||||||
|
throws JsonProcessingException {
|
||||||
|
var jsonRepresentingRequest = String.format(
|
||||||
|
"{\"requestType\":\"%s\"}",
|
||||||
|
request.type);
|
||||||
|
|
||||||
|
assertThat(mapper.writeValueAsString(request))
|
||||||
|
.isEqualTo(jsonRepresentingRequest);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Property
|
||||||
|
void characterRequestsGetSerializedProperly(
|
||||||
|
@ForAll @From("characterRequests") CharacterRequest request)
|
||||||
|
throws JsonProcessingException {
|
||||||
|
|
||||||
|
var jsonRepresentingValue = request.type == RequestType.MeleeAttackRequest ||
|
||||||
|
request.type == RequestType.RangedAttackRequest ?
|
||||||
|
String.format("\"value\":%d", request.value) : "";
|
||||||
|
|
||||||
|
var jsonRepresentingTargetEntity = request.type == RequestType.MeleeAttackRequest ||
|
||||||
|
request.type == RequestType.RangedAttackRequest ||
|
||||||
|
request.type == RequestType.ExchangeInfinityStoneRequest ?
|
||||||
|
String.format(
|
||||||
|
"\"targetEntity\":{\"entityID\":\"%s\",\"ID\":%d},",
|
||||||
|
request.targetEntity.type,
|
||||||
|
request.targetEntity.id) : "";
|
||||||
|
|
||||||
|
var jsonRepresentingStoneType = request.type == RequestType.UseInfinityStoneRequest ||
|
||||||
|
request.type == RequestType.ExchangeInfinityStoneRequest ?
|
||||||
|
String.format(
|
||||||
|
"\"stoneType\":{\"entityID\":\"%s\",\"ID\":%d}",
|
||||||
|
EntityType.InfinityStones,
|
||||||
|
request.stoneType.getID()) : "";
|
||||||
|
|
||||||
|
var jsonRepresentingRequest = String.format(
|
||||||
|
"""
|
||||||
|
{
|
||||||
|
"requestType":"%s",
|
||||||
|
"originEntity":{"entityID":"%s","ID":%d},
|
||||||
|
%s
|
||||||
|
"originField":[%d,%d],
|
||||||
|
"targetField":[%d,%d]%s
|
||||||
|
%s%s
|
||||||
|
%s
|
||||||
|
}
|
||||||
|
""",
|
||||||
|
request.type,
|
||||||
|
request.originEntity.type,
|
||||||
|
request.originEntity.id,
|
||||||
|
jsonRepresentingTargetEntity,
|
||||||
|
request.originField.getX(),
|
||||||
|
request.originField.getY(),
|
||||||
|
request.targetField.getX(),
|
||||||
|
request.targetField.getY(),
|
||||||
|
jsonRepresentingStoneType.length() != 0 ? "," : "",
|
||||||
|
jsonRepresentingStoneType,
|
||||||
|
jsonRepresentingValue.length() != 0 ? "," : "",
|
||||||
|
jsonRepresentingValue
|
||||||
|
).replace("\n", "");
|
||||||
|
|
||||||
|
assertThat(mapper.writeValueAsString(request))
|
||||||
|
.isEqualTo(jsonRepresentingRequest);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Note that everything that follows could be extracted into another class,
|
||||||
|
// but that's complicated, so I won't do it
|
||||||
|
|
||||||
|
static Set<RequestType> characterRequestTypes;
|
||||||
|
static Set<RequestType> gameRequestTypes;
|
||||||
|
|
||||||
|
static {
|
||||||
|
characterRequestTypes = new HashSet<>();
|
||||||
|
characterRequestTypes.add(RequestType.MeleeAttackRequest);
|
||||||
|
characterRequestTypes.add(RequestType.RangedAttackRequest);
|
||||||
|
characterRequestTypes.add(RequestType.MoveRequest);
|
||||||
|
characterRequestTypes.add(RequestType.ExchangeInfinityStoneRequest);
|
||||||
|
characterRequestTypes.add(RequestType.UseInfinityStoneRequest);
|
||||||
|
|
||||||
|
gameRequestTypes = new HashSet<>();
|
||||||
|
gameRequestTypes.add(RequestType.PauseStopRequest);
|
||||||
|
gameRequestTypes.add(RequestType.PauseStartRequest);
|
||||||
|
gameRequestTypes.add(RequestType.EndRoundRequest);
|
||||||
|
gameRequestTypes.add(RequestType.DisconnectRequest);
|
||||||
|
gameRequestTypes.add(RequestType.Req);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Provide("gameRequests")
|
||||||
|
public static Arbitrary<GameRequest> gameRequests() {
|
||||||
|
return requestBuilders()
|
||||||
|
.map(RequestBuilder::buildGameRequest)
|
||||||
|
.filter(request -> gameRequestTypes.contains(request.type));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Provide("characterRequests")
|
||||||
|
public static Arbitrary<CharacterRequest> characterRequests() {
|
||||||
|
return requestBuilders()
|
||||||
|
.map(RequestBuilder::buildCharacterRequest)
|
||||||
|
.filter(request -> characterRequestTypes.contains(request.type));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Provide("filledRequestBuilders")
|
||||||
|
public static Arbitrary<RequestBuilder> requestBuilders() {
|
||||||
|
var emptyBuilders = Arbitraries.of(RequestType.class)
|
||||||
|
.map(RequestBuilder::new);
|
||||||
|
|
||||||
|
var buildersWithEntitiesAndValue = Combinators.combine(
|
||||||
|
emptyBuilders,
|
||||||
|
entityIDs().filter(x -> x.type == EntityType.P1 || x.type == EntityType.P2).tuple2(),
|
||||||
|
entityIDs().filter(x -> x.type == EntityType.Rocks),
|
||||||
|
Arbitraries.integers())
|
||||||
|
.as((builder, characterIDs, rockID, value) -> builder
|
||||||
|
.withOriginEntity(characterIDs.get1())
|
||||||
|
.withTargetEntity(value % 7 == 0 ? characterIDs.get2() : rockID)
|
||||||
|
.withValue(value)
|
||||||
|
);
|
||||||
|
|
||||||
|
var buildersWithStoneTypes = Combinators.combine(
|
||||||
|
buildersWithEntitiesAndValue,
|
||||||
|
Arbitraries.of(StoneType.class))
|
||||||
|
.as(RequestBuilder::withStoneType);
|
||||||
|
|
||||||
|
return Combinators.combine(
|
||||||
|
buildersWithStoneTypes,
|
||||||
|
randomPositions(),
|
||||||
|
directions(),
|
||||||
|
attackPositions())
|
||||||
|
.as((builder, position, direction, attackPos) -> {
|
||||||
|
var type = builder.buildGameRequest().type; // hacky but whatever
|
||||||
|
Tuple.Tuple2<IntVector2, IntVector2> originAndTargetPosition;
|
||||||
|
if (type == RequestType.RangedAttackRequest) {
|
||||||
|
originAndTargetPosition = attackPos;
|
||||||
|
} else {
|
||||||
|
originAndTargetPosition = Tuple.of(position, position.copy().add(direction));
|
||||||
|
}
|
||||||
|
return builder.withOriginField(originAndTargetPosition.get1())
|
||||||
|
.withTargetField(originAndTargetPosition.get2());
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
@Provide("entityIDs")
|
||||||
|
public static Arbitrary<EntityID> entityIDs() {
|
||||||
|
var entityTypes = Arbitraries.of(EntityType.class);
|
||||||
|
return Combinators.combine(entityTypes, Arbitraries.integers().greaterOrEqual(0))
|
||||||
|
.as((type, id) -> {
|
||||||
|
int actualID;
|
||||||
|
if (type == EntityType.P1 || type == EntityType.P2 || type == EntityType.InfinityStones) {
|
||||||
|
actualID = id % 6;
|
||||||
|
} else if (type == EntityType.NPC) {
|
||||||
|
actualID = id % 3;
|
||||||
|
} else {
|
||||||
|
actualID = id;
|
||||||
|
}
|
||||||
|
return new EntityID(type, id);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
@Provide("randomPositions")
|
||||||
|
public static Arbitrary<IntVector2> randomPositions() {
|
||||||
|
return Arbitraries.integers()
|
||||||
|
.greaterOrEqual(0)
|
||||||
|
.tuple2()
|
||||||
|
.map((pos) -> new IntVector2(pos.get1(), pos.get2()));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Provide("directions")
|
||||||
|
public static Arbitrary<IntVector2> directions() {
|
||||||
|
return Arbitraries.integers()
|
||||||
|
.between(-1, 1)
|
||||||
|
.tuple2()
|
||||||
|
.filter(pos -> pos.get1() != 0 && pos.get2() != 0) // eliminate zero vectors
|
||||||
|
.map(pos -> new IntVector2(pos.get1(), pos.get2()));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Provide("attackPositions")
|
||||||
|
/** Returns tuples of origin vectors (of an attack), and the vector pointing to the attack dir */
|
||||||
|
public static Arbitrary<Tuple.Tuple2<IntVector2, IntVector2>> attackPositions() {
|
||||||
|
return Combinators.combine(randomPositions(), directions().tuple5())
|
||||||
|
.as((origin, dir) -> {
|
||||||
|
var attackField = origin.copy()
|
||||||
|
.add(dir.get1().scale(3))
|
||||||
|
.add(dir.get2().scale(3))
|
||||||
|
.add(dir.get3().scale(3))
|
||||||
|
.add(dir.get4().scale(3));
|
||||||
|
if (attackField.length() == 0) {
|
||||||
|
attackField.add(dir.get5().scale(3));
|
||||||
|
}
|
||||||
|
return Tuple.<IntVector2, IntVector2>of(origin, attackField);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user