From 7575fabe8f963897f76e235158e55bbab031bea8 Mon Sep 17 00:00:00 2001 From: Ryan Esch Date: Wed, 4 Apr 2018 14:58:42 -0500 Subject: [PATCH] Add AI --- .../java/org/libertybikes/game/bot/Walle.java | 174 ++++++++++++++++++ .../org/libertybikes/game/core/GameBoard.java | 13 +- 2 files changed, 185 insertions(+), 2 deletions(-) create mode 100644 game-service/src/main/java/org/libertybikes/game/bot/Walle.java diff --git a/game-service/src/main/java/org/libertybikes/game/bot/Walle.java b/game-service/src/main/java/org/libertybikes/game/bot/Walle.java new file mode 100644 index 0000000..2d616a6 --- /dev/null +++ b/game-service/src/main/java/org/libertybikes/game/bot/Walle.java @@ -0,0 +1,174 @@ +/** + * + */ +package org.libertybikes.game.bot; + +import java.util.Random; + +import org.libertybikes.game.core.DIRECTION; +import org.libertybikes.game.core.GameBoard; + +public class Walle extends AIPlayer { + + static Random ran = new Random(); + + private DIRECTION direction, lastDirection; + + private int locX, locY; + + public Walle(int startX, int startY, int width, int height, DIRECTION startDirection, short takenSpotNumber) { + super(startX, startY, width, height, startDirection, takenSpotNumber); + lastDirection = direction = startDirection; + locX = startX; + locY = startY; + } + + @Override + public DIRECTION processGameTick(short[][] board) { + lastDirection = direction; + direction = straightLine(board, locX, locY); + if (direction == DIRECTION.LEFT) { + locX--; + } else if (direction == DIRECTION.UP) { + locY--; + } else if (direction == DIRECTION.RIGHT) { + locX++; + } else { + locY++; + } + + return direction; + } + + private boolean movable(short[][] b, int x, int y, DIRECTION d) { + try { + if (d == DIRECTION.LEFT) { + if (b[x - 1][y] == GameBoard.SPOT_AVAILABLE && b[x - 1][y + 1] == GameBoard.SPOT_AVAILABLE && b[x - 1][y + 2] == GameBoard.SPOT_AVAILABLE) { + return true; + } + } else if (d == DIRECTION.RIGHT) { + if (b[x + 3][y] == GameBoard.SPOT_AVAILABLE && b[x + 3][y + 1] == GameBoard.SPOT_AVAILABLE && b[x + 3][y + 2] == GameBoard.SPOT_AVAILABLE) { + return true; + } + } else if (d == DIRECTION.UP) { + if (b[x][y - 1] == GameBoard.SPOT_AVAILABLE && b[x + 1][y - 1] == GameBoard.SPOT_AVAILABLE && b[x + 2][y - 1] == GameBoard.SPOT_AVAILABLE) { + return true; + } + } else if (d == DIRECTION.DOWN) { + if (b[x][y + 3] == GameBoard.SPOT_AVAILABLE && b[x + 1][y + 3] == GameBoard.SPOT_AVAILABLE && b[x + 2][y + 3] == GameBoard.SPOT_AVAILABLE) { + return true; + } + } + } catch (ArrayIndexOutOfBoundsException e) { + + } + + return false; + } + + private DIRECTION straightLine(short[][] b, int x, int y) { + int left = goUntilWall(b, x, y, DIRECTION.LEFT, 0); + int right = goUntilWall(b, x, y, DIRECTION.RIGHT, 0); + int up = goUntilWall(b, x, y, DIRECTION.UP, 0); + int down = goUntilWall(b, x, y, DIRECTION.DOWN, 0); + + if (x + 5 < GameBoard.BOARD_SIZE && y + 5 < GameBoard.BOARD_SIZE && b[x + 5][y + 5] == GameBoard.OBJECT_SPOT_TAKEN) { + right = right / 10; + down = down / 10; + } + if (x - 5 >= 0 && y + 5 < GameBoard.BOARD_SIZE && b[x - 5][y + 5] == GameBoard.OBJECT_SPOT_TAKEN) { + left = left / 10; + down = down / 10; + } + if (x + 5 < GameBoard.BOARD_SIZE && y - 5 >= 0 && b[x + 5][y - 5] == GameBoard.OBJECT_SPOT_TAKEN) { + right = right / 10; + up = up / 10; + } + if (x - 5 >= 0 && y - 5 >= 0 && b[x - 5][y - 5] == GameBoard.OBJECT_SPOT_TAKEN) { + left = left / 10; + up = up / 10; + } + + if (direction == DIRECTION.LEFT) { + if (left >= up) { + if (left >= down) { + return DIRECTION.LEFT; + } else { + return DIRECTION.DOWN; + } + } else if (down >= up) { + return DIRECTION.DOWN; + } else { + return DIRECTION.UP; + } + } else if (direction == DIRECTION.RIGHT) { + if (right >= up) { + if (right >= down) { + return DIRECTION.RIGHT; + } else { + return DIRECTION.DOWN; + } + } else if (down >= up) { + return DIRECTION.DOWN; + } else { + return DIRECTION.UP; + } + } else if (direction == DIRECTION.UP) { + if (left >= up) { + if (left >= right) { + return DIRECTION.LEFT; + } else { + return DIRECTION.RIGHT; + } + } else if (right >= up) { + return DIRECTION.RIGHT; + } else { + return DIRECTION.UP; + } + } else if (direction == DIRECTION.DOWN) { + if (left >= right) { + if (left >= down) { + return DIRECTION.LEFT; + } else { + return DIRECTION.DOWN; + } + } else if (down >= right) { + return DIRECTION.DOWN; + } else { + return DIRECTION.RIGHT; + } + } + return DIRECTION.LEFT; + } + + private int goUntilWall(short[][] b, int x, int y, DIRECTION d, int total) { + if (d == DIRECTION.LEFT) { + if (movable(b, x, y, d)) { + return goUntilWall(b, x - 1, y, d, total + 1); + } else { + return total; + } + } else if (d == DIRECTION.RIGHT) { + if (movable(b, x, y, d)) { + return goUntilWall(b, x + 1, y, d, total + 1); + } else { + return total; + } + } else if (d == DIRECTION.UP) { + if (movable(b, x, y, d)) { + return goUntilWall(b, x, y - 1, d, total + 1); + } else { + return total; + } + } else if (d == DIRECTION.DOWN) { + if (movable(b, x, y, d)) { + return goUntilWall(b, x, y + 1, d, total + 1); + } else { + return total; + } + } + return 0; + + } + +} diff --git a/game-service/src/main/java/org/libertybikes/game/core/GameBoard.java b/game-service/src/main/java/org/libertybikes/game/core/GameBoard.java index 96fd238..a613aab 100644 --- a/game-service/src/main/java/org/libertybikes/game/core/GameBoard.java +++ b/game-service/src/main/java/org/libertybikes/game/core/GameBoard.java @@ -12,6 +12,7 @@ import java.util.concurrent.ConcurrentHashMap; import javax.json.bind.annotation.JsonbTransient; import org.libertybikes.game.bot.Hal; +import org.libertybikes.game.bot.Walle; public class GameBoard { @@ -182,8 +183,16 @@ public class GameBoard { } // Initialize Player - Player p = new Player("Hal-" + playerNum, "Hal-" + playerNum, playerNum); - AI ai = new Hal(p.x, p.y, p.width, p.height, p.direction, playerNum); + Player p; + AI ai; + + if (Math.random() < .5) { + p = new Player("Hal-" + playerNum, "Hal-" + playerNum, playerNum); + ai = new Hal(p.x, p.y, p.width, p.height, p.direction, playerNum); + } else { + p = new Player("WALLE-" + playerNum, "WALLE-" + playerNum, playerNum); + ai = new Walle(p.x, p.y, p.width, p.height, p.direction, playerNum); + } if (p.x + p.width > BOARD_SIZE || p.y + p.height > BOARD_SIZE) throw new IllegalArgumentException("Player does not fit on board: " + p);