Commit 81508a87 authored by Joseph Walton-Rivers's avatar Joseph Walton-Rivers 😸

add hexagon code to git

parents
target/
.idea/
*.iml
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.fossgalaxy.games.hexagon</groupId>
<artifactId>hexagon</artifactId>
<version>0.1-SNAPSHOT</version>
<packaging>jar</packaging>
<name>Hexagon</name>
<parent>
<groupId>com.fossgalaxy.common</groupId>
<artifactId>parent-pom</artifactId>
<version>0.4</version>
</parent>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<dependencies>
<dependency>
<groupId>com.fossgalaxy.games.tbs</groupId>
<artifactId>basic-tbs</artifactId>
<version>0.1-SNAPSHOT</version>
</dependency>
</dependencies>
</project>
package com.fossgalaxy.games.hexagon;
import com.fossgalaxy.games.tbs.GameState;
import com.fossgalaxy.games.tbs.entity.Entity;
import com.fossgalaxy.games.tbs.parameters.ResourceType;
import org.codetome.hexameter.core.api.CubeCoordinate;
public class CloneOrder extends HexOrder {
public CloneOrder(CubeCoordinate newPos, ResourceType lockResouce) {
super(newPos, lockResouce);
}
@Override
public void doOrder(Entity entity, GameState gameState) {
if (!isLegal(entity, gameState, 1) || !useMoveLock(entity.getOwner(), gameState, lockResouce)) {
return;
}
// update the position
Entity child = new Entity(entity.getType(), newPos, entity.getOwner());
gameState.addEntity(child);
// update my peoples
updateAfterMove(gameState, child);
}
}
package com.fossgalaxy.games.hexagon;
import com.fossgalaxy.games.tbs.GameState;
import com.fossgalaxy.games.tbs.actions.AbstractAction;
import com.fossgalaxy.games.tbs.entity.Entity;
import com.fossgalaxy.games.tbs.order.Order;
import com.fossgalaxy.games.tbs.parameters.ResourceType;
import com.fossgalaxy.games.tbs.parameters.TerrainType;
import com.fossgalaxy.object.annotations.ObjectDef;
import org.codetome.hexameter.core.api.CubeCoordinate;
import java.awt.*;
public class CloneTo extends AbstractAction {
private static final Color CLONE_HINT = new Color(173, 255, 47, 100);
private ResourceType lock;
@ObjectDef("Clone")
public CloneTo(ResourceType lock){
this.lock = lock;
}
@Override
public boolean isPossible(Entity entity, GameState s, CubeCoordinate co) {
//cannot move into occupied space
Entity entityAtPos = s.getEntityAt(co);
if (entityAtPos != null) {
return false;
}
//cannot jump at any range other than 2
int range = s.getDistance(entity.getPos(), co);
if (range != 1) {
return false;
}
//check the entity is allowed to move to the space
TerrainType type = s.getTerrainAt(co);
if (type == null || !type.isPassible(entity)){
return false;
}
return HexOrder.hasMoveAvailable(entity.getOwner(), s, lock);
}
@Override
public Order generateOrder(CubeCoordinate cubeCoordinate, GameState gameState) {
return new CloneOrder(cubeCoordinate, lock);
}
@Override
public Color getHintColour() {
return CLONE_HINT;
}
@Override
public Color getBorderColour() {
return Color.GREEN;
}
@Override
public String toString() {
return "clone";
}
}
package com.fossgalaxy.games.hexagon;
import com.fossgalaxy.games.tbs.GameState;
import com.fossgalaxy.games.tbs.entity.Entity;
import com.fossgalaxy.games.tbs.entity.HexagonTile;
import com.fossgalaxy.games.tbs.order.Order;
import com.fossgalaxy.games.tbs.parameters.ResourceType;
import org.codetome.hexameter.core.api.CubeCoordinate;
import org.codetome.hexameter.core.api.Hexagon;
import java.util.Collection;
public class HexOrder implements Order {
protected final CubeCoordinate newPos;
protected final ResourceType lockResouce;
public HexOrder(CubeCoordinate newPos, ResourceType lockResouce) {
this.newPos = newPos;
this.lockResouce = lockResouce;
}
public boolean isLegal(Entity entity, GameState gameState, int distance){
//can't jump where someone is
Entity currEntity = gameState.getEntityAt(newPos);
if (currEntity != null) {
return false;
}
//can only jump distance
if (gameState.getDistance(entity.getPos(), newPos) != distance) {
return false;
}
//can only perform legal moves
if (!gameState.getTerrainAt(newPos).isPassible(entity)) {
return false;
}
return true;
}
public static boolean hasMoveAvailable(int playerID, GameState gameState, ResourceType lockResouce) {
int currTurn = gameState.getResource(playerID, lockResouce);
return currTurn <= gameState.getTime();
}
public static boolean useMoveLock(int playerID, GameState gameState, ResourceType lockResouce) {
if (!hasMoveAvailable(playerID, gameState, lockResouce)) {
return false;
}
//execute lock
gameState.setResource(playerID, lockResouce, gameState.getTime() + 1);
return true;
}
public void updateAfterMove(GameState state, Entity entity) {
Collection<Hexagon<HexagonTile>> neighbors = state.getNeighbors(entity.getPos());
for (Hexagon<HexagonTile> neighbor : neighbors) {
Entity nEntity = state.getEntityAt(neighbor.getCubeCoordinate());
if (nEntity != null && nEntity.getOwner() != entity.getOwner()) {
// changing owner doens't work right - need to delete and re-add
state.removeEntity(nEntity);
nEntity.setType(entity.getType());
nEntity.setOwner(entity.getOwner());
state.addEntity(nEntity); //warning, if it's legal to issue moves to this unit you'll get disqualified!
}
}
}
@Override
public void doOrder(Entity entity, GameState gameState) {
if (!isLegal(entity, gameState, 2) || !useMoveLock(entity.getOwner(), gameState, lockResouce)) {
return;
}
// update the position
entity.setPos(newPos);
// update my peoples
updateAfterMove(gameState, entity);
}
}
package com.fossgalaxy.games.hexagon;
import com.fossgalaxy.games.tbs.editor.Editor;
import com.fossgalaxy.games.tbs.io.SettingsIO;
import com.fossgalaxy.games.tbs.io.map2.MapDef;
import com.fossgalaxy.games.tbs.parameters.GameSettings;
public class HexagonEditor {
public static void main(String[] args) {
SettingsIO io = SettingsIO.buildWithExtras("com.fossgalaxy.games.hexagon");
Editor.run(io, "Hexagon.json", "Hexagon-map.json");
}
}
\ No newline at end of file
package com.fossgalaxy.games.hexagon;
import com.fossgalaxy.games.tbs.App;
import com.fossgalaxy.games.tbs.io.SettingsIO;
import com.fossgalaxy.games.tbs.io.map2.MapDef;
import com.fossgalaxy.games.tbs.parameters.GameSettings;
public class Hexagons {
public static void main(String[] args) {
SettingsIO io = SettingsIO.buildWithExtras("com.fossgalaxy.games.hexagon");
App.run(io, "Hexagon.json", "Hexagon-stuck.json", "Player", "Player");
}
}
\ No newline at end of file
package com.fossgalaxy.games.hexagon;
import com.fossgalaxy.games.tbs.GameState;
import com.fossgalaxy.games.tbs.entity.Entity;
import com.fossgalaxy.games.tbs.entity.HexagonTile;
import com.fossgalaxy.games.tbs.order.Order;
import com.fossgalaxy.games.tbs.parameters.ResourceType;
import org.codetome.hexameter.core.api.CubeCoordinate;
import org.codetome.hexameter.core.api.Hexagon;
import java.util.Collection;
public class JumpOrder extends HexOrder {
public JumpOrder(CubeCoordinate newPos, ResourceType lockResouce) {
super(newPos, lockResouce);
}
@Override
public void doOrder(Entity entity, GameState gameState) {
if (!isLegal(entity, gameState, 2) || !useMoveLock(entity.getOwner(), gameState, lockResouce)) {
return;
}
// update the position
entity.setPos(newPos);
// update my peoples
updateAfterMove(gameState, entity);
}
}
package com.fossgalaxy.games.hexagon;
import com.fossgalaxy.games.tbs.GameState;
import com.fossgalaxy.games.tbs.actions.AbstractAction;
import com.fossgalaxy.games.tbs.entity.Entity;
import com.fossgalaxy.games.tbs.order.Order;
import com.fossgalaxy.games.tbs.parameters.ResourceType;
import com.fossgalaxy.games.tbs.parameters.TerrainType;
import com.fossgalaxy.object.annotations.ObjectDef;
import org.codetome.hexameter.core.api.CubeCoordinate;
import java.awt.*;
public class JumpTo extends AbstractAction {
private static final Color JUMP_HINT = new Color(255, 255, 224, 200);
private ResourceType lock;
@ObjectDef("Jump")
public JumpTo(ResourceType lock){
this.lock = lock;
}
@Override
public boolean isPossible(Entity entity, GameState s, CubeCoordinate co) {
//cannot move into occupied space
Entity entityAtPos = s.getEntityAt(co);
if (entityAtPos != null) {
return false;
}
//cannot jump at any range other than 2
int range = s.getDistance(entity.getPos(), co);
if (range != 2) {
return false;
}
// check we're allowed to move there
TerrainType type = s.getTerrainAt(co);
if (type == null || !type.isPassible(entity)){
return false;
}
return HexOrder.hasMoveAvailable(entity.getOwner(), s, lock);
}
@Override
public Order generateOrder(CubeCoordinate cubeCoordinate, GameState gameState) {
return new JumpOrder(cubeCoordinate, lock);
}
@Override
public Color getHintColour() {
return JUMP_HINT;
}
@Override
public Color getBorderColour() {
return Color.YELLOW;
}
@Override
public String toString(){
return "jump";
}
}
package com.fossgalaxy.games.hexagon;
import com.fossgalaxy.games.tbs.GameState;
import com.fossgalaxy.games.tbs.entity.Entity;
import com.fossgalaxy.games.tbs.entity.HexagonTile;
import com.fossgalaxy.games.tbs.parameters.ResourceType;
import com.fossgalaxy.games.tbs.rules.Rule;
import com.fossgalaxy.games.tbs.ui.GameAction;
import com.fossgalaxy.object.annotations.ObjectDef;
import com.fossgalaxy.object.annotations.ObjectDefStatic;
import org.codetome.hexameter.core.api.Hexagon;
import java.util.Collection;
import java.util.List;
public class MostPieces implements Rule {
private final int numHexs;
private final String lock;
@ObjectDef("MostPiecesLock")
public MostPieces(int numHexes, String lock){
this.numHexs = numHexes;
this.lock = lock;
}
@ObjectDefStatic("MostPieces")
public static MostPieces MostPieces(int numHexes){
return new MostPieces(numHexes, null);
}
public Integer getWinner(GameState state) {
int numEntities = state.getEntities().size();
if (numEntities == numHexs) {
return countWinner(state);
}
for (int playerID=0; playerID<state.getNumberOfPlayers(); playerID++) {
if ( lock != null && !HexOrder.hasMoveAvailable(playerID, state, state.getSettings().getResourceType(lock) )) {
continue;
}
if (isStuck(playerID, state)) {
return countWinner(state);
}
}
return Rule.NO_WINNER;
}
protected boolean isStuck(int playerID, GameState state){
Collection<Entity> currEntities = state.getOwnedEntities(playerID);
for (Entity curr : currEntities) {
List<GameAction> actionList = curr.getType().getAvailableActions();
for (GameAction action : actionList) {
//this agent can't do anything - don't do the expensive check.
if (!action.isPossible(curr, state)) {
continue;
}
int range = action.getRange(curr);
Collection<Hexagon<HexagonTile>> tilesInRange = state.getRange(curr.getPos(), range);
boolean actionPossible = tilesInRange.stream().anyMatch(h -> action.isPossible(curr, state, h.getCubeCoordinate()));
if (actionPossible) {
return false;
}
}
}
return true;
}
protected Integer countWinner(GameState state){
int largestArmy = 0;
Integer winningPlayer = Rule.NO_WINNER;
for (int playerID = 0; playerID<state.getNumberOfPlayers(); playerID++) {
int nPieces = state.getOwnedEntities(playerID).size();
if (nPieces > largestArmy) {
largestArmy = nPieces;
winningPlayer = playerID;
}
}
return winningPlayer;
}
}
{
"random":"RandomController",
"noop":"NoOpController"
}
{
"width": 11,
"height": 11,
"players": 2,
"hexSize": 60,
"resources": [],
"entities": [
{
"type": "gems",
"location": {
"x": -1,
"z": 5
},
"owner": 0,
"properties": {
"health": 1
}
},
{
"type": "gems",
"location": {
"x": 3,
"z": 9
},
"owner": 0,
"properties": {
"health": 1
}
},
{
"type": "gems",
"location": {
"x": 7,
"z": 1
},
"owner": 0,
"properties": {
"health": 1
}
},
{
"type": "pearls",
"location": {
"x": 3,
"z": 1
},
"owner": 1,
"properties": {
"health": 1
}
},
{
"type": "pearls",
"location": {
"x": 7,
"z": 5
},
"owner": 1,
"properties": {
"health": 1
}
},
{
"type": "pearls",
"location": {
"x": -1,
"z": 9
},
"owner": 1,
"properties": {
"health": 1
}
}
],
"terrain": {
"board-edge": [
{
"x": 3,
"z": 0
},
{
"x": 4,
"z": 0
},
{
"x": 5,
"z": 0
},
{
"x": 6,
"z": 0
},
{
"x": 7,
"z": 0
},
{
"x": 2,
"z": 1
},
{
"x": 1,
"z": 2
},
{
"x": 0,
"z": 3
},
{
"x": -1,
"z": 4
},
{
"x": 4,
"z": 4
},
{
"x": 2,
"z": 5
},
{
"x": 3,
"z": 6
}
],
"board": [
{
"x": 3,
"z": 1
},
{
"x": 4,
"z": 1
},
{
"x": 5,
"z": 1
},
{
"x": 6,
"z": 1
},
{
"x": 7,
"z": 1
},
{
"x": 2,
"z": 2
},
{
"x": 3,
"z": 2
},
{
"x": 4,
"z": 2
},
{
"x": 5,
"z": 2
},
{
"x": 6,
"z": 2
},
{
"x": 7,
"z": 2
},
{
"x": 1,
"z": 3
},
{
"x": 2,
"z": 3
},
{
"x": 3,
"z": 3
},
{
"x": 4,
"z": 3
},
{
"x": 5,
"z": 3
},
{
"x": 6,
"z": 3
},
{
"x": 7,
"z": 3
},
{
"x": 0,
"z": 4
},
{
"x": 1,
"z": 4
},
{
"x": 2,
"z": 4
},
{
"x": 3,
"z": 4
},
{
"x": 5,
"z": 4
},
{
"x": 6,
"z": 4
},
{
"x": 7,
"z": 4
},
{
"x": -1,
"z": 5
},
{
"x": 0,
"z": 5
},
{
"x": 1,
"z": 5
},
{
"x": 3,
"z": 5
},
{
"x": 4,
"z": 5
},
{
"x": 5,