Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -27,3 +27,6 @@ hs_err_pid*

# .DStore files
*.DS_Store
.idea
lol2D.iml
lib
29 changes: 15 additions & 14 deletions src/main/java/lol/game/Arena.java
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
import java.net.*;
import lol.common.*;
import lol.game.action.*;
import java.util.function.*;

public class Arena {
private ArrayList<Team> teams;
Expand Down Expand Up @@ -42,21 +43,24 @@ public ApplyAction() {
championsWhoActed = new ArrayList<>();
}

public void visitSpawn(int teamID, int championID, int x, int y) {
if(!championsWhoActed.contains(championID)) {
if(teams.get(teamID).spawnChampion(championID, x, y)) {
championsWhoActed.add(championID);
private void tryExecuteChampionAction(int teamID, int championID, Predicate<Team> action) {
int uniqueChampionID = teamID * 1000 + championID;
if(!championsWhoActed.contains(uniqueChampionID)) {
if(action.test(teams.get(teamID))) {
championsWhoActed.add(uniqueChampionID);
}
}
}

public void visitSpawn(int teamID, int championID, int x, int y) {
tryExecuteChampionAction(teamID, championID,
(team) -> team.spawnChampion(championID, x, y));
}

public void visitMove(int teamID, int championID, int x, int y) {
if(phase == Phase.GAME) {
if(!championsWhoActed.contains(championID)) {
if(teams.get(teamID).moveChampion(championID, x, y)) {
championsWhoActed.add(championID);
}
}
tryExecuteChampionAction(teamID, championID,
(team) -> team.moveChampion(championID, x, y));
}
else {
System.out.println("Team " + teamID + " tried to move a champion outside a GAME phase.");
Expand All @@ -65,11 +69,8 @@ public void visitMove(int teamID, int championID, int x, int y) {

public void visitAttack(int teamID, int championID, int x, int y) {
if(phase == Phase.GAME) {
if(!championsWhoActed.contains(championID)) {
if(teams.get(teamID).championAttack(championID, x, y)) {
championsWhoActed.add(championID);
}
}
tryExecuteChampionAction(teamID, championID,
(team) -> team.championAttack(championID, x, y));
}
else {
System.out.println("Team " + teamID + " tried to move a champion outside a GAME phase.");
Expand Down
61 changes: 26 additions & 35 deletions src/main/java/lol/game/Attacker.java
Original file line number Diff line number Diff line change
Expand Up @@ -3,41 +3,32 @@

// class is abstract, since it should never be used alone
public abstract class Attacker extends Destructible {
private int rangeOfAttack;
private int damages;

public Attacker(int hp, int rangeOfAttack, int damages) {
super(hp);
this.rangeOfAttack = rangeOfAttack;
this.damages = damages;
}

public int attackRange() {
return rangeOfAttack;
}

public int damages() {
return damages;
}

public void boostDamages(int boost) {
this.damages += boost;
}

public boolean attack(Destructible d) {
if(canAttack(d.x(), d.y())) {
d.hit(damages);
return true;
}
return false;
}

protected int distanceFrom(int toX, int toY) {
return Math.max(Math.abs(toX - x()), Math.abs(toY - y()));
private int rangeOfAttack;
private int damages;

public Attacker(int hp, int rangeOfAttack, int damages) {
super(hp);
this.rangeOfAttack = rangeOfAttack;
this.damages = damages;
}

public int attackRange() {
return rangeOfAttack;
}

public boolean attack(Destructible d, Battlefield battlefield, BattlefieldTraversal traversal) {
if(canAttack(d.x(), d.y(), battlefield, traversal)) {
d.hit(damages);
return true;
}
return false;
}

protected int distanceFrom(int toX, int toY) {
return Math.max(Math.abs(toX - x()), Math.abs(toY - y()));
}

public boolean canAttack(int toX, int toY) {
return distanceFrom(toX, toY) <= rangeOfAttack;
}
}
public boolean canAttack(int toX, int toY, Battlefield battlefield, BattlefieldTraversal traversal) {
return distanceFrom(toX, toY) <= rangeOfAttack && traversal.noObstacles(x(), y(),toX,toY, battlefield);
}
}
1 change: 1 addition & 0 deletions src/main/java/lol/game/Battlefield.java
Original file line number Diff line number Diff line change
Expand Up @@ -129,6 +129,7 @@ public boolean placeAt(Destructible d, int x, int y) {
return false;
}


// Move a destructible object on the battlefield if `placeAt(d, x, y)` succeeds.
public boolean moveTo(Destructible d, int x, int y) {
int oldX = d.x();
Expand Down
119 changes: 118 additions & 1 deletion src/main/java/lol/game/BattlefieldTraversal.java
Original file line number Diff line number Diff line change
Expand Up @@ -45,4 +45,121 @@ public void visitAdjacent(int x, int y, int radius, TileVisitor visitor) {
}
}
}
}

public boolean noObstacles(int fromX, int fromY, int toX, int toY, Battlefield battlefield) {
int dx = Math.abs(toX - fromX);
int dy = Math.abs(toY - fromY);
if(Math.max(dy, dx) <= 1 ){
return true;
}
else if(dy == dx){
if(!diagonalCheck(fromX, fromY, toX, toY, battlefield)) {
System.out.println("Obstacle on the way to the target of pos "+ toX +" "+ toY +" ! Can't shoot.");
return false;
}
}
else if(fromY == toY){
if(!verticalCheck(fromX, fromY, toX, toY, battlefield)) {
System.out.println("Obstacle on the way to the target of pos "+ toX +" "+ toY +" ! Can't shoot.");
return false;
}
}
else if(fromX == toX){
if(!horizontalCheck(fromX, fromY, toX, toY, battlefield)) {
System.out.println("Obstacle on the way to the target of pos "+ toX +" "+ toY +" ! Can't shoot.");
return false;
}
}
return true;
}


public boolean diagonalCheck(int x, int y, int toX, int toY, Battlefield battlefield) {
System.out.println(x);
System.out.println(y);
System.out.println("------------------------");
if(x < toX && y < toY) {
for(int i = x; i < toX; i++) {
for(int j = y; j < toY; j++) {
if(!battlefield.canPlaceAt(i, j)) {
return false;
}
}
}
}
else if(x < toX && y > toY) {
for(int i = x; i < toX; i++) {
for(int j = y; j > toY; j--) {
if(!battlefield.canPlaceAt(i, j)) {
return false;
}
}
}
}
else if(x > toX && y > toY) {
for(int i = x; i > toX; i--) {
for(int j = y; j > toY; j--) {
if(!battlefield.canPlaceAt(i, j)) {
return false;
}
}
}
}
else if(x > toX && y < toY) {
for(int i = x; i > toX; i--) {
for(int j = y; j < toY; j++) {
if(!battlefield.canPlaceAt(i, j)) {
return false;
}
}
}
}
return true;
}

// - Case when y = toY
public boolean verticalCheck(int x, int y, int toX, int toY, Battlefield battlefield) {
System.out.println(x);
System.out.println(y);
System.out.println("------------------------");
if( x>toX ) {
for(int i = x; i > toX; i--){
if(!battlefield.canPlaceAt(i, y)){
return false;
}
}
}
else if( x < toX) {
for(int i = x; i > toX; i++){
if(!battlefield.canPlaceAt(i, y)){
return false;
}
}
}
return true;
}

// - Case when x = toX
public boolean horizontalCheck(int x, int y, int toX, int toY, Battlefield battlefield) {
System.out.println(x);
System.out.println(y);
System.out.println("------------------------");
if( y>=toY ) {
for(int j = y; j > toY; j--){
if(!battlefield.canPlaceAt(x, j)){
System.out.println("Obstacle on the way to the target of pos "+ toX +" "+ toY +" ! Can't shoot.");
return false;
}
}
}
else if( y <= toY) {
for(int j = y; j < toY; j++){
System.out.println("Obstacle on the way to the target of pos "+ toX +" "+ toY +" ! Can't shoot.");
if(!battlefield.canPlaceAt(x, j)){
return false;
}
}
}
return true;
}
}
2 changes: 1 addition & 1 deletion src/main/java/lol/game/Team.java
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ public boolean championAttack(int championID, int x, int y) {
boolean[] attacked = {false};
battlefield.visit(x, y, new TileVisitor(){
@Override public void visitDestructible(Destructible d) {
attacked[0] = champion.attack(d);
attacked[0] = champion.attack(d, battlefield, traversal);
sound.attackSound(champion.name());
if(d.isDead()) {
battlefield.destroy(d);
Expand Down
5 changes: 3 additions & 2 deletions src/main/java/lol/server/Server.java
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ public class Server implements Runnable {
private Arena arena;
private LOL2D ui;
private Battlefield battlefield;
private int MILLISECOND_PER_TURN = 2000;

public Server(LOL2D ui, Battlefield battlefield) {
this.ui = ui;
Expand Down Expand Up @@ -52,7 +53,7 @@ private void startGame() throws IOException {
spawnPhase();
arena.startGamePhase();
ui.update();
wait(2000);
wait(MILLISECOND_PER_TURN);
}

private void wait(int timeInMS) {
Expand Down Expand Up @@ -82,7 +83,7 @@ private void gameLoop() throws IOException {
arena.applyTurn(turn);
ui.update();
broadcast(turn);
wait(2000);
wait(MILLISECOND_PER_TURN);
}
}
}
Expand Down
52 changes: 50 additions & 2 deletions src/main/java/lol/ui/BattlefieldView.java
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ public class BattlefieldView implements TileVisitor
BattlefieldTraversal battlefieldTraversal;
Sprites sprites;
TilePane tiles;
TilePane wt = new TilePane();
Stage stage;
Scene scene;

Expand All @@ -44,7 +45,8 @@ public void update() {
initTilePane();
battlefieldTraversal.visitFullMap(this);
scene = new Scene(tiles);
stage.setScene(scene);});
stage.setScene(scene);
displayWinningScreen();});
}

ImageView groundView(Battlefield.GroundTile tile) {
Expand All @@ -65,7 +67,19 @@ ImageView championView(Champion champion) {

ImageView nexusView(Nexus nexus) {
int teamID = nexus.teamOfNexus();
return(sprites.nexusesView(teamID));
double hpPercentage = (nexus.currentHP())/(double)(nexus.initialHP());
if (hpPercentage<=1.0 && hpPercentage>=0.5){
return(sprites.nexusesView(teamID));
}
else if(hpPercentage< 0.5 && hpPercentage> 0.0){
return (sprites.nexusesOnfire(teamID));
}
else if(hpPercentage == 0.0){
return (sprites.nexusesDestroyed(teamID));
}
else{
throw new RuntimeException("Unsupported Nexus color");
}
}

ImageView towerView(Tower tower){
Expand Down Expand Up @@ -106,6 +120,40 @@ private void drawLifeBar(StackPane stack, Destructible d){
stack.getChildren().add(lifeBar);
}

private void displayWinningScreen(){
if (!battlefield.allNexusAlive()) {
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
Nexus nexus = battlefield.nexusOf(Nexus.BLUE);
if (nexus.isAlive()) {
displayWinner(Nexus.BLUE);
} else {
displayWinner(Nexus.RED);
}
scene = new Scene(wt);
} else {
scene = new Scene(tiles);
}
stage.setScene(scene);
}

private void displayWinner(int teamId) {
wt.setPrefColumns(1);
wt.setPrefRows(1);
wt.setTileAlignment(Pos.CENTER);
wt.setMinSize(640, 640);
StackPane stack = new StackPane();
sprites.finalSceneView(teamId).setFitWidth(640);
sprites.finalSceneView(teamId).setFitHeight(640);
sprites.finalSceneView(teamId).setPreserveRatio(true);
stack.setAlignment(Pos.CENTER);
stack.getChildren().addAll(new Rectangle(640,640, Color.WHITE ),sprites.finalSceneView(teamId));
wt.getChildren().add(stack);
}

@Override public void visitChampion(Champion champion) {
System.out.println("Display champion ");
displayDestructible(champion, championView(champion));
Expand Down
Loading