fix: resolve various issues with ai, cloning and turn order handling

This commit is contained in:
punchready 2021-06-05 04:00:25 +02:00
parent cd992b0fa6
commit f2a961d159
6 changed files with 50 additions and 37 deletions

View File

@ -1,9 +1,6 @@
package uulm.teamname.marvelous.gamelibrary.entities; package uulm.teamname.marvelous.gamelibrary.entities;
import java.util.ArrayList; import java.util.*;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Objects;
/** Represents an inventory of 6 slots of {@link StoneType StoneTypes} that can be manipulated. */ /** Represents an inventory of 6 slots of {@link StoneType StoneTypes} that can be manipulated. */
public class Inventory implements Iterable<StoneType> { public class Inventory implements Iterable<StoneType> {
@ -85,12 +82,12 @@ public class Inventory implements Iterable<StoneType> {
* @return The array of stones the inventory has * @return The array of stones the inventory has
*/ */
public StoneType[] getStonesAsArray() { public StoneType[] getStonesAsArray() {
var toReturn = new StoneType[content.size()]; StoneType[] result = new StoneType[content.size()];
var iterator = content.iterator(); int i = 0;
for (int i = 0; i < content.size(); i++) { for(StoneType stone: content) {
toReturn[i] = iterator.next(); result[i++] = stone;
} }
return toReturn; return result;
} }
/** /**

View File

@ -60,7 +60,7 @@ public class EntityManager {
if(entity.id.isSameType(EntityType.Rocks)) { if(entity.id.isSameType(EntityType.Rocks)) {
usedRockSlots.add(entity.id.id); usedRockSlots.add(entity.id.id);
} }
entities.add(entity); entities.add(entity.clone());
} }
/** /**
@ -69,7 +69,7 @@ public class EntityManager {
*/ */
void addEntities(Entity... entities) { void addEntities(Entity... entities) {
for(Entity e: entities) { for(Entity e: entities) {
this.addEntity(e); this.addEntity(e.clone());
} }
} }
@ -89,18 +89,13 @@ public class EntityManager {
* @param entityid The {@link EntityID} of the {@link Entity} to remove * @param entityid The {@link EntityID} of the {@link Entity} to remove
*/ */
boolean removeEntity(EntityID entityid) { boolean removeEntity(EntityID entityid) {
Entity entity = findEntity(entityid); return entities.removeIf(e -> e.id.equals(entityid));
if(entity != null) {
return entities.remove(entity);
}else {
return false;
}
} }
/** /**
* Finds an entity with an {@link EntityID}. * Finds an entity with an {@link EntityID}.
* @param id The id to search for * @param id The id to search for
* @return The found {@link Entity} or null if none found * @return The found {@link Entity} or {@code null} if none found
*/ */
public Entity findEntity(EntityID id) { public Entity findEntity(EntityID id) {
for(Entity entity: entities) { for(Entity entity: entities) {

View File

@ -1,5 +1,6 @@
package uulm.teamname.marvelous.gamelibrary.gamelogic; package uulm.teamname.marvelous.gamelibrary.gamelogic;
import org.tinylog.Logger;
import uulm.teamname.marvelous.gamelibrary.ArrayTools; import uulm.teamname.marvelous.gamelibrary.ArrayTools;
import uulm.teamname.marvelous.gamelibrary.IntVector2; import uulm.teamname.marvelous.gamelibrary.IntVector2;
import uulm.teamname.marvelous.gamelibrary.config.FieldType; import uulm.teamname.marvelous.gamelibrary.config.FieldType;
@ -187,7 +188,7 @@ public class GameLogic {
} }
} }
}catch(InvalidRequestException exception) { }catch(InvalidRequestException exception) {
System.out.println("Request denied: " + exception.getMessage()); Logger.debug("Request denied: " + exception.getMessage());
return false; return false;
}catch(Exception ignored) { }catch(Exception ignored) {
return false; return false;
@ -332,7 +333,6 @@ public class GameLogic {
if(target.hp.getValue() <= data.value) { if(target.hp.getValue() <= data.value) {
List<StoneType> stones = Arrays.asList(target.inventory.getStonesAsArray()); List<StoneType> stones = Arrays.asList(target.inventory.getStonesAsArray());
target.inventory.clear();
Collections.shuffle(stones); // required by documents Collections.shuffle(stones); // required by documents
for(StoneType stone: stones) { for(StoneType stone: stones) {
@ -504,6 +504,7 @@ public class GameLogic {
EntityType opposing = target.id.type == EntityType.P1 ? EntityType.P2 : EntityType.P1; EntityType opposing = target.id.type == EntityType.P1 ? EntityType.P2 : EntityType.P1;
state.winConditions.increaseValue(opposing, WinCondition.TotalDamage, data.amount); state.winConditions.increaseValue(opposing, WinCondition.TotalDamage, data.amount);
if(!target.isAlive()) { if(!target.isAlive()) {
target.inventory.clear();
state.winConditions.increaseValue(opposing, WinCondition.TotalKnockouts, 1); state.winConditions.increaseValue(opposing, WinCondition.TotalKnockouts, 1);
} }
@ -716,7 +717,7 @@ public class GameLogic {
* @return The list of resulting {@link Event Events} * @return The list of resulting {@link Event Events}
*/ */
protected static ArrayList<Event> startGame(GameState state, ArrayList<Integer> selectedCharacters1, ArrayList<Integer> selectedCharacters2) { protected static ArrayList<Event> startGame(GameState state, ArrayList<Integer> selectedCharacters1, ArrayList<Integer> selectedCharacters2) {
System.out.println("Starting game"); Logger.trace("Starting game");
ArrayList<Event> result = new ArrayList<>(); ArrayList<Event> result = new ArrayList<>();
@ -823,7 +824,11 @@ public class GameLogic {
continue; continue;
} }
Character character = ((Character)state.entities.findEntity(id)); Entity found = state.entities.findEntity(id);
if(found == null) {
continue;
}
Character character = ((Character)found);
if(character.isAlive()){ if(character.isAlive()){
anyAlive = true; anyAlive = true;
@ -868,8 +873,6 @@ public class GameLogic {
* @return The list of resulting {@link Event Events} * @return The list of resulting {@link Event Events}
*/ */
private static ArrayList<Event> handleRoundStart(GameState state) { private static ArrayList<Event> handleRoundStart(GameState state) {
System.out.println("Starting round " + (state.roundNumber + 1));
ArrayList<Event> result = new ArrayList<>(); ArrayList<Event> result = new ArrayList<>();
state.roundNumber++; state.roundNumber++;
@ -898,7 +901,11 @@ public class GameLogic {
Collections.shuffle(state.turnOrder); Collections.shuffle(state.turnOrder);
for (EntityID id: state.turnOrder) { for (EntityID id: state.turnOrder) {
if(id.type == EntityType.NPC || revived.contains(id) || ((Character)state.entities.findEntity(id)).isAlive()){ Entity found = state.entities.findEntity(id);
if(found == null) {
continue;
}
if(id.type == EntityType.NPC || revived.contains(id) || ((Character)found).isAlive()){
state.activeCharacter = id; state.activeCharacter = id;
break; break;
}else { // again send empty turns for knocked out characters }else { // again send empty turns for knocked out characters
@ -973,6 +980,9 @@ public class GameLogic {
ArrayList<IntVector2> targetOptions = new ArrayList<>(); ArrayList<IntVector2> targetOptions = new ArrayList<>();
int lowest = -1; int lowest = -1;
for(EntityID id: state.turnOrder) { for(EntityID id: state.turnOrder) {
if(id.type == EntityType.NPC) {
continue;
}
Character character = (Character)state.entities.findEntity(id); Character character = (Character)state.entities.findEntity(id);
characters.add(character); characters.add(character);
@ -1037,6 +1047,9 @@ public class GameLogic {
int maxMP = -1; int maxMP = -1;
for(EntityID id: state.turnOrder) { for(EntityID id: state.turnOrder) {
if(id.type == EntityType.NPC) {
continue;
}
Character character = (Character)state.entities.findEntity(id); Character character = (Character)state.entities.findEntity(id);
if(character.mp.getMax() > maxMP) { if(character.mp.getMax() > maxMP) {
@ -1095,7 +1108,7 @@ public class GameLogic {
ArrayList<IntVector2> path = GameLogic.Bresenham4Connected(thanos.getPosition(), picked); ArrayList<IntVector2> path = GameLogic.Bresenham4Connected(thanos.getPosition(), picked);
int mp = thanos.mp.getValue(); int mp = thanos.mp.getMax();
if(mp <= 0) { if(mp <= 0) {
return result; return result;
@ -1145,6 +1158,10 @@ public class GameLogic {
break; break;
} }
if(entity instanceof InfinityStone) { if(entity instanceof InfinityStone) {
result.add(new EventBuilder(EventType.DestroyedEntityEvent)
.withTargetEntity(entity.id)
.withTargetField(pos)
.buildEntityEvent());
break; break;
} }
} }
@ -1162,10 +1179,14 @@ public class GameLogic {
if(id.type == EntityType.NPC) { if(id.type == EntityType.NPC) {
continue; continue;
} }
Entity found = state.entities.findEntity(id);
if(found == null) {
continue;
}
if(rand.nextBoolean()) { if(rand.nextBoolean()) {
result.add(new EventBuilder(EventType.DestroyedEntityEvent) result.add(new EventBuilder(EventType.DestroyedEntityEvent)
.withTargetEntity(id) .withTargetEntity(id)
.withTargetField(state.entities.findEntity(id).getPosition()) .withTargetField(found.getPosition())
.buildEntityEvent()); .buildEntityEvent());
} }
} }
@ -1204,7 +1225,7 @@ public class GameLogic {
* @return The list of resulting {@link Event Events} * @return The list of resulting {@link Event Events}
*/ */
private static ArrayList<Event> handlePlayerWin(GameState state, EntityType winner) { private static ArrayList<Event> handlePlayerWin(GameState state, EntityType winner) {
System.out.println("Player " + winner + " won"); Logger.trace("Player " + winner + " won");
ArrayList<Event> result = new ArrayList<>(); ArrayList<Event> result = new ArrayList<>();

View File

@ -142,6 +142,7 @@ class GameState {
sb.append("T"); sb.append("T");
} }
} }
sb.append(entities.get(0).id.equals(activeCharacter) ? "'" : " ");
} }
case P1, P2 -> { case P1, P2 -> {
if(((Character)entities.get(0)).isAlive()) { if(((Character)entities.get(0)).isAlive()) {
@ -149,6 +150,7 @@ class GameState {
}else { }else {
sb.append("x"); sb.append("x");
} }
sb.append(entities.get(0).id.equals(activeCharacter) ? "'" : " ");
} }
case Rocks -> { case Rocks -> {
sb.append("O "); sb.append("O ");

View File

@ -39,9 +39,7 @@ class AITest extends BaseGameLogicTest {
void main() throws InterruptedException { void main() throws InterruptedException {
serverSend(server.startGame(player1Selection, player2Selection).toArray(new Event[0])); serverSend(server.startGame(player1Selection, player2Selection).toArray(new Event[0]));
Thread.sleep(1000); Thread.sleep(10000);
System.out.println(server.toString());
} }
private void clientSend(Request[] requests) { private void clientSend(Request[] requests) {

View File

@ -17,7 +17,7 @@ public class BaseGameLogicTest {
protected static final ArrayList<Integer> player2Selection = new ArrayList<>(); protected static final ArrayList<Integer> player2Selection = new ArrayList<>();
protected static void generate() { protected static void generate() {
partyConfig.maxRounds = 100; partyConfig.maxRounds = 50;
partyConfig.mindStoneCD = 2; partyConfig.mindStoneCD = 2;
partyConfig.powerStoneCD = 3; partyConfig.powerStoneCD = 3;
partyConfig.realityStoneCD = 4; partyConfig.realityStoneCD = 4;