wip: implement action tree and minimax for ai

This commit is contained in:
2021-06-07 03:06:33 +02:00
parent 81cbec5348
commit 7a5d9dca76
7 changed files with 274 additions and 36 deletions

View File

@ -11,13 +11,22 @@ import java.util.Objects;
class Board {
private final Piece[][] data;
private final EntityType origin;
private final EntityID turn;
public final EntityType origin;
public final EntityID turn;
public final boolean ended;
private Board(Piece[][] data, EntityType origin, EntityID turn) {
this.data = data;
this.origin = origin;
this.turn = turn;
this.ended = false;
}
private Board(Piece[][] data, EntityType origin, EntityID turn, boolean ended) {
this.data = data;
this.origin = origin;
this.turn = turn;
this.ended = ended;
}
public static Board generate(GameStateView state, EntityID turn) {
@ -100,10 +109,16 @@ class Board {
}
for(IntVector2 dir: IntVector2.CardinalDirections) {
IntVector2 target = position.add(dir);
if(target.getX() < 0 || target.getX() >= state.getMapSize().getX() || target.getY() < 0 || target.getY() >= state.getMapSize().getY()) {
if(
target.getX() < 0 || target.getX() >= state.getMapSize().getX() ||
target.getY() < 0 || target.getY() >= state.getMapSize().getY()
) {
continue;
}
if(this.data[target.getY()][target.getX()].type == PieceType.Empty) {
if(
this.data[target.getY()][target.getX()].type == PieceType.Empty ||
this.data[target.getY()][target.getX()].type == PieceType.Character
) {
result.add(new Action(ActionType.Move, target));
}
}
@ -142,6 +157,9 @@ class Board {
continue;
}
for(StoneType stone: StoneType.values()) {
if(state.getStoneCooldown(stone) > 0) {
continue;
}
if(!character.inventory.hasStone(stone)) {
continue;
}
@ -223,6 +241,9 @@ class Board {
}
}
}
case EndTurn -> {
result.add(new Action(ActionType.EndTurn));
}
}
}
@ -251,6 +272,8 @@ class Board {
}
}
boolean ended = false;
//TODO: finalize action applying
switch(action.type) {
@ -262,9 +285,10 @@ class Board {
case MeleeAttack -> {
clone[action.target.getY()][action.target.getX()].hp.decreaseValue(character.meleeDamage);
current.ap.decreaseValue(1);
//todo: drop stones........
}
case RangedAttack -> {
clone[action.target.getY()][action.target.getX()].hp.decreaseValue(character.meleeDamage);
clone[action.target.getY()][action.target.getX()].hp.decreaseValue(character.rangedDamage);
current.ap.decreaseValue(1);
}
case UseStone -> {
@ -292,11 +316,31 @@ class Board {
case GiveStone -> {
}
case EndTurn -> {
ended = true;
}
}
//...get next turn in turn order...
//TODO: figure out next turn properly
return new Board(clone, origin, turn);
if(ended || (current.mp.getValue() == 0 && current.ap.getValue() == 0)) {
ArrayList<EntityID> alive = new ArrayList<>();
for(EntityID next: state.getTurnOrder()) {
if(next.type == EntityType.NPC && next.id == NPCType.Thanos.getID()) {
alive.add(next);
}else if(next.type == EntityType.P1 || next.type == EntityType.P2) {
if(((Character)state.getEntities().findEntity(next)).isAlive()) {
alive.add(next);
}
}
}
int index = alive.indexOf(turn);
if(index == alive.size() - 1) {
return new Board(clone, origin, turn, true);
}else {
return new Board(clone, origin, alive.get(index + 1));
}
}else {
return new Board(clone, origin, turn);
}
}
protected float calculateScore() {