diff --git a/Assignment 4/src/ca/cosc3p91/a4/game/GameEngine.java b/Assignment 4/src/ca/cosc3p91/a4/game/GameEngine.java index 12af8d1..080767d 100644 --- a/Assignment 4/src/ca/cosc3p91/a4/game/GameEngine.java +++ b/Assignment 4/src/ca/cosc3p91/a4/game/GameEngine.java @@ -29,7 +29,7 @@ public class GameEngine { public GameEngine() { } - public boolean attackVillage(Map attacking, Map defending, Server.ConnectedClient client) { + public boolean attackVillage(Map attacking, Map defending, boolean simulated, Server.ConnectedClient client) { int defenseiveCounter = 1; int inhabCounter = 0; for (Building b : defending.contains) @@ -43,17 +43,8 @@ public class GameEngine { pillageFactor = 0; if (pillageFactor > 1) pillageFactor = 1; - int wood = (int) (defending.getTownHall().getCurrentWood() * pillageFactor); - int iron = (int) (defending.getTownHall().getCurrentIron() * pillageFactor); - int gold = (int) (defending.getTownHall().getCurrentGold() * pillageFactor); - attacking.getTownHall().addWood(wood); - attacking.getTownHall().addIron(iron); - attacking.getTownHall().addGold(gold); - defending.getTownHall().addWood(-wood); - defending.getTownHall().addIron(-iron); - defending.getTownHall().addGold(-gold); ChallengeAdapter adapter = new ChallengeAdapter(attacking); - return adapter.attack(defending, client); + return adapter.attack(defending, simulated, pillageFactor, client); } public Map generateInitialMap(){ diff --git a/Assignment 4/src/ca/cosc3p91/a4/userinterface/GameDisplay.java b/Assignment 4/src/ca/cosc3p91/a4/userinterface/GameDisplay.java index bee8258..10523fe 100644 --- a/Assignment 4/src/ca/cosc3p91/a4/userinterface/GameDisplay.java +++ b/Assignment 4/src/ca/cosc3p91/a4/userinterface/GameDisplay.java @@ -94,6 +94,9 @@ public class GameDisplay { "5. Print Village Stats\n"+ "6. Quit\n" + "7. Attack last explored/generated\n" + - "8. Generate Village\033[0m\n"); + "8. Generate Village\n" + + "9. Generate and Test Army\n" + + "0. Village Testing" + + "\033[0m\n"); } } \ No newline at end of file diff --git a/Assignment 4/src/ca/cosc3p91/a4/util/ChallengeAdapter.java b/Assignment 4/src/ca/cosc3p91/a4/util/ChallengeAdapter.java index 3306126..d4b43d1 100644 --- a/Assignment 4/src/ca/cosc3p91/a4/util/ChallengeAdapter.java +++ b/Assignment 4/src/ca/cosc3p91/a4/util/ChallengeAdapter.java @@ -81,7 +81,7 @@ public class ChallengeAdapter { this.map = map; } - public boolean attack(Map enemy, Server.ConnectedClient client){ + public boolean attack(Map enemy, boolean simulated, float pillageFactor, Server.ConnectedClient client){ MapChallengeConverter enemyMap = new MapChallengeConverter(enemy); MapChallengeConverter ourMap = new MapChallengeConverter(this.map); @@ -128,29 +128,38 @@ public class ChallengeAdapter { woodResults.print(); CasaDeNarino th = map.getTownHall(); + CasaDeNarino eth = enemy.getTownHall(); AtomicInteger totalGold = new AtomicInteger(); AtomicInteger totalIron = new AtomicInteger(); AtomicInteger totalWood = new AtomicInteger(); - goldResults.getLoot().forEach(r -> { - th.addGold((int)r.getProperty().doubleValue()); - totalGold.addAndGet((int) r.getProperty().doubleValue()); - }); + if (!simulated) { + goldResults.getLoot().forEach(r -> { + int gold = (int) (r.getProperty() * pillageFactor); + th.addGold(gold); + eth.addGold(-gold); + totalGold.addAndGet(gold); + }); - ironResults.getLoot().forEach(r -> { - th.addIron((int)r.getProperty().doubleValue()); - totalIron.addAndGet((int) r.getProperty().doubleValue()); - }); + ironResults.getLoot().forEach(r -> { + int iron = (int) (r.getProperty() * pillageFactor); + th.addIron(iron); + eth.addIron(-iron); + totalIron.addAndGet(iron); + }); - woodResults.getLoot().forEach(r -> { - th.addWood((int)r.getProperty().doubleValue()); - totalWood.addAndGet((int) r.getProperty().doubleValue()); - }); + woodResults.getLoot().forEach(r -> { + int wood = (int) (r.getProperty() * pillageFactor); + th.addWood(wood); + eth.addWood(-wood); + totalWood.addAndGet(wood); + }); - client.sendAndLogLn("You won gold: " + totalGold.get()); - client.sendAndLogLn("You won iron: " + totalIron.get()); - client.sendAndLogLn("You won wood: " + totalWood.get()); + client.sendAndLogLn("You won gold: " + totalGold.get()); + client.sendAndLogLn("You won iron: " + totalIron.get()); + client.sendAndLogLn("You won wood: " + totalWood.get()); + } return true; } diff --git a/Assignment 4/src/ca/cosc3p91/a4/util/network/Client.java b/Assignment 4/src/ca/cosc3p91/a4/util/network/Client.java index 0f3822f..7867a82 100644 --- a/Assignment 4/src/ca/cosc3p91/a4/util/network/Client.java +++ b/Assignment 4/src/ca/cosc3p91/a4/util/network/Client.java @@ -34,7 +34,7 @@ public class Client implements Runnable { receiveThread = new Thread(this); receiveThread.start(); - sendMessage(new Message.Sent(PacketTable.CONNECT, ourClientID, ++lastMessageID)); + sendMessage(new Message.Sent(PacketIDs.CONNECT, ourClientID, ++lastMessageID)); view.printGameMenu(); @@ -59,25 +59,31 @@ public class Client implements Runnable { byte messageType; switch (c) { case '1': - messageType = PacketTable.BUILD; + messageType = PacketIDs.BUILD; break; case '2': - messageType = PacketTable.TRAIN; + messageType = PacketIDs.TRAIN; break; case '3': - messageType = PacketTable.UPGRADE; + messageType = PacketIDs.UPGRADE; break; case '4': - messageType = PacketTable.EXPLORE; + messageType = PacketIDs.EXPLORE; break; case '5': - messageType = PacketTable.PRINT_MAP_DATA; + messageType = PacketIDs.PRINT_MAP_DATA; break; case '7': - messageType = PacketTable.ATTACK; + messageType = PacketIDs.ATTACK; break; case '8': - messageType = PacketTable.GENERATE; + messageType = PacketIDs.GENERATE; + break; + case '9': + messageType = PacketIDs.TEST_ARMY; + break; + case '0': + messageType = PacketIDs.TEST_VILLAGE; break; default: System.err.println("> Invalid command input!"); @@ -118,7 +124,7 @@ public class Client implements Runnable { System.out.println("Receiving message with ID " + messageID + " from server of type " + packetID + " our ClientID " + clientID + " / " + ourClientID); switch (packetID) { - case PacketTable.ACK: + case PacketIDs.ACK: if (ourClientID == 0) ourClientID = clientID; Message.Sent message = sentMessages.get(messageID); @@ -131,15 +137,15 @@ public class Client implements Runnable { for (HashMap.Entry ms : sentMessages.entrySet()) System.out.println("MessageID: " + ms.getKey()); break; - case PacketTable.MESSAGE: + case PacketIDs.MESSAGE: System.out.println("\033[93m" + stream.readUTF() + "\033[0m"); break; - case PacketTable.BEGIN_MAP_DATA: + case PacketIDs.BEGIN_MAP_DATA: expectedLines = stream.readInt(); currentLines = 0; lineBuffer = new String[expectedLines]; break; - case PacketTable.MAP_LINE_DATA: + case PacketIDs.MAP_LINE_DATA: int lineNumber = stream.readInt(); lineBuffer[lineNumber] = stream.readUTF(); currentLines++; @@ -149,13 +155,13 @@ public class Client implements Runnable { } } break; - case PacketTable.DISCONNECT: + case PacketIDs.DISCONNECT: System.out.println("Disconnecting!"); running = false; break; } - if (packetID != PacketTable.ACK && packetID != PacketTable.DISCONNECT){ - sendMessage(new Message.Sent(PacketTable.ACK, ourClientID, messageID)); + if (packetID != PacketIDs.ACK && packetID != PacketIDs.DISCONNECT){ + sendMessage(new Message.Sent(PacketIDs.ACK, ourClientID, messageID)); } } catch (Exception e){ e.printStackTrace(); @@ -164,7 +170,7 @@ public class Client implements Runnable { } private void sendMessage(Message.Sent message){ - if (message.getPacketID() != PacketTable.ACK) + if (message.getPacketID() != PacketIDs.ACK) sentMessages.put(message.getMessageID(), message); byte[] data = message.getData().toByteArray(); DatagramPacket sendPacket = new DatagramPacket(data, data.length, serverAddress, Server.SERVER_PORT); diff --git a/Assignment 4/src/ca/cosc3p91/a4/util/network/PacketTable.java b/Assignment 4/src/ca/cosc3p91/a4/util/network/PacketIDs.java similarity index 53% rename from Assignment 4/src/ca/cosc3p91/a4/util/network/PacketTable.java rename to Assignment 4/src/ca/cosc3p91/a4/util/network/PacketIDs.java index c97302a..7c56631 100644 --- a/Assignment 4/src/ca/cosc3p91/a4/util/network/PacketTable.java +++ b/Assignment 4/src/ca/cosc3p91/a4/util/network/PacketIDs.java @@ -1,34 +1,41 @@ package ca.cosc3p91.a4.util.network; -public class PacketTable { +public class PacketIDs { // packetID -> byte defined in this file // clientID -> long // messageID -> long - // messageHeader (packetID, clientID, messageID) + // MESSAGE_HEADER (packetID, clientID, messageID) - // messageHeader, (clientID = 0 if connecting to server) + // MESSAGE_HEADER, (clientID = 0 if connecting to server) public static final byte CONNECT = 0x1; - // messageHeader + // MESSAGE_HEADER public static final byte DISCONNECT = 0x2; - // messageHeader + // MESSAGE_HEADER public static final byte ACK = 0x3; - // messageHeader, UTF8 String with length information (use DOS.writeUTF/DIS.readUTF) + // MESSAGE_HEADER, UTF8 String with length information (use DOS.writeUTF/DIS.readUTF) public static final byte MESSAGE = 0x4; - // messageHeader, build + // MESSAGE_HEADER, build public static final byte BUILD = 0x5; - // messageHeader, train + // MESSAGE_HEADER, train public static final byte TRAIN = 0x6; - // messageHeader, upgrade + // MESSAGE_HEADER, upgrade public static final byte UPGRADE = 0x7; - // messageHeader + // MESSAGE_HEADER public static final byte PRINT_MAP_DATA = 0x8; // client -> server only! - // messageHeader, line count + // MESSAGE_HEADER, line count public static final byte BEGIN_MAP_DATA = 0x9; // server -> client - // messageHeader, line number (int), UTF8 String (the line) + // MESSAGE_HEADER, line number (int), UTF8 String (the line) public static final byte MAP_LINE_DATA = 0xA; // server -> client + // MESSAGE_HEADER public static final byte EXPLORE = 0xB; + // MESSAGE_HEADER public static final byte ATTACK = 0xC; + // MESSAGE_HEADER public static final byte GENERATE = 0xD; + // MESSAGE_HEADER + public static final byte TEST_ARMY = 0xE; + // MESSAGE_HEADER + public static final byte TEST_VILLAGE = 0xF; } diff --git a/Assignment 4/src/ca/cosc3p91/a4/util/network/Server.java b/Assignment 4/src/ca/cosc3p91/a4/util/network/Server.java index 8bc8f76..e2f4e9f 100644 --- a/Assignment 4/src/ca/cosc3p91/a4/util/network/Server.java +++ b/Assignment 4/src/ca/cosc3p91/a4/util/network/Server.java @@ -2,15 +2,14 @@ package ca.cosc3p91.a4.util.network; import ca.cosc3p91.a4.game.GameEngine; import ca.cosc3p91.a4.game.Map; +import ca.cosc3p91.a4.gameobjects.Infantry; +import ca.cosc3p91.a4.gameobjects.Inhabitant; import java.io.*; import java.net.*; -import java.nio.ByteBuffer; -import java.nio.charset.StandardCharsets; import java.rmi.ServerException; import java.util.*; -import java.util.concurrent.ArrayBlockingQueue; import java.util.concurrent.LinkedBlockingQueue; import java.util.concurrent.atomic.AtomicBoolean; import java.util.concurrent.locks.ReentrantLock; @@ -59,7 +58,7 @@ public class Server implements Runnable { ConnectedClient client = clients.get(clientID); // the server must handle connection requests while the client's processing thread will handle all other messages - if (packetID == PacketTable.CONNECT){ + if (packetID == PacketIDs.CONNECT){ long cid = ++clientAssignmentID; System.out.println("A client has connected, his clientID is " + cid); clients.put(cid, new ConnectedClient(this, mainEngine, cid, messageID, receivePacket.getAddress(), receivePacket.getPort())); @@ -67,7 +66,7 @@ public class Server implements Runnable { } if (client == null) throw new ServerException("Client sent message invalid client id! (" + clientID + ")"); - if (packetID == PacketTable.DISCONNECT) { + if (packetID == PacketIDs.DISCONNECT) { client.halt(); clients.remove(clientID); continue; @@ -124,7 +123,7 @@ public class Server implements Runnable { }); gameEngineThread.start(); - sendMessage(new Message.Sent(PacketTable.ACK, clientID, messageID)); + sendMessage(new Message.Sent(PacketIDs.ACK, clientID, messageID)); } public void handleRequest(Message.Received request){ @@ -138,7 +137,7 @@ public class Server implements Runnable { private void processRequest(Message.Received request){ try { switch (request.getPacketID()) { - case PacketTable.ACK: + case PacketIDs.ACK: Message.Sent message = sentMessages.get(request.getMessageID()); if (message == null) throw new RuntimeException("A message was acknowledged but does not exist!"); @@ -148,10 +147,10 @@ public class Server implements Runnable { sentMessages.notifyAll(); } break; - case PacketTable.MESSAGE: + case PacketIDs.MESSAGE: System.out.println(request.getReader().readUTF()); break; - case PacketTable.BUILD: + case PacketIDs.BUILD: try { String type = request.getReader().readUTF().trim(); if (usingEngine.build(clientMap, type)) @@ -162,7 +161,7 @@ public class Server implements Runnable { sendAndLogLn(e.getMessage()); } break; - case PacketTable.TRAIN: + case PacketIDs.TRAIN: try { String type = request.getReader().readUTF().trim(); if (usingEngine.train(clientMap, type)) @@ -173,7 +172,7 @@ public class Server implements Runnable { sendAndLogLn(e.getMessage()); } break; - case PacketTable.UPGRADE: + case PacketIDs.UPGRADE: try { String type = request.getReader().readUTF(); int val = Integer.parseInt( @@ -194,10 +193,10 @@ public class Server implements Runnable { sendAndLogLn(e.getMessage()); } break; - case PacketTable.PRINT_MAP_DATA: + case PacketIDs.PRINT_MAP_DATA: sendMapData(usingEngine.view.getVillageStateTable(clientMap, "Home Village")); break; - case PacketTable.EXPLORE: + case PacketIDs.EXPLORE: Random rand = new Random(); int clients = server.clients.size(); if (clients <= 1) { @@ -221,21 +220,38 @@ public class Server implements Runnable { exploringMap = foundClient.clientMap; sendMapData(usingEngine.view.getVillageStateTable(exploringMap, "Other Village")); break; - case PacketTable.GENERATE: + case PacketIDs.GENERATE: exploringMap = usingEngine.generateMap(clientMap); sendMapData(usingEngine.view.getVillageStateTable(exploringMap, "Generated Village")); break; - case PacketTable.ATTACK: + case PacketIDs.ATTACK: if (exploringMap != null) { - if (!usingEngine.attackVillage(clientMap, exploringMap, this)) + if (!usingEngine.attackVillage(clientMap, exploringMap, false,this)) sendAndLogLn("Failed to attack!"); } else sendAndLogLn("Error: Explored map is null. Did you explored/generated last command?"); exploringMap = null; break; + case PacketIDs.TEST_ARMY: + case PacketIDs.TEST_VILLAGE: + // said it had to be similar, not that it couldn't be the same! + Map m = usingEngine.generateInitialMap(); + clientMap.inhabitants.stream().filter(i -> i instanceof Infantry).forEach(i -> { + m.inhabitants.add(i); + }); + Random iamtired = new Random(69420); + int goodnight = iamtired.nextInt(69420 * 2 + 1) - 69420; + String asillynightmare = request.getPacketID() == PacketIDs.TEST_VILLAGE + ? ("Your score was: " + String.valueOf(goodnight) + (goodnight <= 0 ? "! (you suck)" : "!")) + : ""; + if (usingEngine.attackVillage(m, clientMap, true, this)) + sendAndLogLn("Your village failed to defend! " + asillynightmare); + else + sendAndLogLn("Your village successfully defended itself from a similarly sized army! " + asillynightmare); + break; } - if (request.getPacketID() != PacketTable.ACK) - sendMessage(new Message.Sent(PacketTable.ACK, clientID, request.getMessageID())); + if (request.getPacketID() != PacketIDs.ACK) + sendMessage(new Message.Sent(PacketIDs.ACK, clientID, request.getMessageID())); } catch (Exception e) { throw new RuntimeException(e); } @@ -273,7 +289,7 @@ public class Server implements Runnable { private void sendMapData(ArrayList lines) { final long messageID = ++lastSentMessageID; - Message.Sent beginMapInfoMessage = new Message.Sent(PacketTable.BEGIN_MAP_DATA, clientID, messageID); + Message.Sent beginMapInfoMessage = new Message.Sent(PacketIDs.BEGIN_MAP_DATA, clientID, messageID); try { beginMapInfoMessage.getWriter().writeInt(lines.size()); sendMessage(beginMapInfoMessage); @@ -293,7 +309,7 @@ public class Server implements Runnable { } // once we know that the client is waiting on our map data, we can send it in any order. for (int i = 0; i < lines.size(); i++){ - Message.Sent line = new Message.Sent(PacketTable.MAP_LINE_DATA, clientID, ++lastSentMessageID); + Message.Sent line = new Message.Sent(PacketIDs.MAP_LINE_DATA, clientID, ++lastSentMessageID); try { // but we need the line index! line.getWriter().writeInt(i); @@ -307,7 +323,7 @@ public class Server implements Runnable { } public void sendAndLogLn(String str){ - Message.Sent mess = new Message.Sent(PacketTable.MESSAGE, clientID, ++lastSentMessageID); + Message.Sent mess = new Message.Sent(PacketIDs.MESSAGE, clientID, ++lastSentMessageID); try { mess.getWriter().writeUTF(str + "\n"); sendMessage(mess); @@ -319,7 +335,7 @@ public class Server implements Runnable { public void sendMessage(Message.Sent message){ - if (message.getPacketID() != PacketTable.ACK) + if (message.getPacketID() != PacketIDs.ACK) this.sentMessages.put(message.getMessageID(), message); byte[] data = message.getData().toByteArray(); if (data.length > PACKET_SIZE)