last features

main
Brett 2023-04-20 19:53:16 -04:00
parent 92f2c9f309
commit 213bbd3f68
6 changed files with 110 additions and 78 deletions

View File

@ -29,7 +29,7 @@ public class GameEngine {
public 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 defenseiveCounter = 1;
int inhabCounter = 0; int inhabCounter = 0;
for (Building b : defending.contains) for (Building b : defending.contains)
@ -43,17 +43,8 @@ public class GameEngine {
pillageFactor = 0; pillageFactor = 0;
if (pillageFactor > 1) if (pillageFactor > 1)
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); ChallengeAdapter adapter = new ChallengeAdapter(attacking);
return adapter.attack(defending, client); return adapter.attack(defending, simulated, pillageFactor, client);
} }
public Map generateInitialMap(){ public Map generateInitialMap(){

View File

@ -94,6 +94,9 @@ public class GameDisplay {
"5. Print Village Stats\n"+ "5. Print Village Stats\n"+
"6. Quit\n" + "6. Quit\n" +
"7. Attack last explored/generated\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");
} }
} }

View File

@ -81,7 +81,7 @@ public class ChallengeAdapter {
this.map = map; 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 enemyMap = new MapChallengeConverter(enemy);
MapChallengeConverter ourMap = new MapChallengeConverter(this.map); MapChallengeConverter ourMap = new MapChallengeConverter(this.map);
@ -128,29 +128,38 @@ public class ChallengeAdapter {
woodResults.print(); woodResults.print();
CasaDeNarino th = map.getTownHall(); CasaDeNarino th = map.getTownHall();
CasaDeNarino eth = enemy.getTownHall();
AtomicInteger totalGold = new AtomicInteger(); AtomicInteger totalGold = new AtomicInteger();
AtomicInteger totalIron = new AtomicInteger(); AtomicInteger totalIron = new AtomicInteger();
AtomicInteger totalWood = new AtomicInteger(); AtomicInteger totalWood = new AtomicInteger();
if (!simulated) {
goldResults.getLoot().forEach(r -> { goldResults.getLoot().forEach(r -> {
th.addGold((int)r.getProperty().doubleValue()); int gold = (int) (r.getProperty() * pillageFactor);
totalGold.addAndGet((int) r.getProperty().doubleValue()); th.addGold(gold);
eth.addGold(-gold);
totalGold.addAndGet(gold);
}); });
ironResults.getLoot().forEach(r -> { ironResults.getLoot().forEach(r -> {
th.addIron((int)r.getProperty().doubleValue()); int iron = (int) (r.getProperty() * pillageFactor);
totalIron.addAndGet((int) r.getProperty().doubleValue()); th.addIron(iron);
eth.addIron(-iron);
totalIron.addAndGet(iron);
}); });
woodResults.getLoot().forEach(r -> { woodResults.getLoot().forEach(r -> {
th.addWood((int)r.getProperty().doubleValue()); int wood = (int) (r.getProperty() * pillageFactor);
totalWood.addAndGet((int) r.getProperty().doubleValue()); th.addWood(wood);
eth.addWood(-wood);
totalWood.addAndGet(wood);
}); });
client.sendAndLogLn("You won gold: " + totalGold.get()); client.sendAndLogLn("You won gold: " + totalGold.get());
client.sendAndLogLn("You won iron: " + totalIron.get()); client.sendAndLogLn("You won iron: " + totalIron.get());
client.sendAndLogLn("You won wood: " + totalWood.get()); client.sendAndLogLn("You won wood: " + totalWood.get());
}
return true; return true;
} }

View File

@ -34,7 +34,7 @@ public class Client implements Runnable {
receiveThread = new Thread(this); receiveThread = new Thread(this);
receiveThread.start(); receiveThread.start();
sendMessage(new Message.Sent(PacketTable.CONNECT, ourClientID, ++lastMessageID)); sendMessage(new Message.Sent(PacketIDs.CONNECT, ourClientID, ++lastMessageID));
view.printGameMenu(); view.printGameMenu();
@ -59,25 +59,31 @@ public class Client implements Runnable {
byte messageType; byte messageType;
switch (c) { switch (c) {
case '1': case '1':
messageType = PacketTable.BUILD; messageType = PacketIDs.BUILD;
break; break;
case '2': case '2':
messageType = PacketTable.TRAIN; messageType = PacketIDs.TRAIN;
break; break;
case '3': case '3':
messageType = PacketTable.UPGRADE; messageType = PacketIDs.UPGRADE;
break; break;
case '4': case '4':
messageType = PacketTable.EXPLORE; messageType = PacketIDs.EXPLORE;
break; break;
case '5': case '5':
messageType = PacketTable.PRINT_MAP_DATA; messageType = PacketIDs.PRINT_MAP_DATA;
break; break;
case '7': case '7':
messageType = PacketTable.ATTACK; messageType = PacketIDs.ATTACK;
break; break;
case '8': case '8':
messageType = PacketTable.GENERATE; messageType = PacketIDs.GENERATE;
break;
case '9':
messageType = PacketIDs.TEST_ARMY;
break;
case '0':
messageType = PacketIDs.TEST_VILLAGE;
break; break;
default: default:
System.err.println("> Invalid command input!"); 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); System.out.println("Receiving message with ID " + messageID + " from server of type " + packetID + " our ClientID " + clientID + " / " + ourClientID);
switch (packetID) { switch (packetID) {
case PacketTable.ACK: case PacketIDs.ACK:
if (ourClientID == 0) if (ourClientID == 0)
ourClientID = clientID; ourClientID = clientID;
Message.Sent message = sentMessages.get(messageID); Message.Sent message = sentMessages.get(messageID);
@ -131,15 +137,15 @@ public class Client implements Runnable {
for (HashMap.Entry<Long, Message.Sent> ms : sentMessages.entrySet()) for (HashMap.Entry<Long, Message.Sent> ms : sentMessages.entrySet())
System.out.println("MessageID: " + ms.getKey()); System.out.println("MessageID: " + ms.getKey());
break; break;
case PacketTable.MESSAGE: case PacketIDs.MESSAGE:
System.out.println("\033[93m" + stream.readUTF() + "\033[0m"); System.out.println("\033[93m" + stream.readUTF() + "\033[0m");
break; break;
case PacketTable.BEGIN_MAP_DATA: case PacketIDs.BEGIN_MAP_DATA:
expectedLines = stream.readInt(); expectedLines = stream.readInt();
currentLines = 0; currentLines = 0;
lineBuffer = new String[expectedLines]; lineBuffer = new String[expectedLines];
break; break;
case PacketTable.MAP_LINE_DATA: case PacketIDs.MAP_LINE_DATA:
int lineNumber = stream.readInt(); int lineNumber = stream.readInt();
lineBuffer[lineNumber] = stream.readUTF(); lineBuffer[lineNumber] = stream.readUTF();
currentLines++; currentLines++;
@ -149,13 +155,13 @@ public class Client implements Runnable {
} }
} }
break; break;
case PacketTable.DISCONNECT: case PacketIDs.DISCONNECT:
System.out.println("Disconnecting!"); System.out.println("Disconnecting!");
running = false; running = false;
break; break;
} }
if (packetID != PacketTable.ACK && packetID != PacketTable.DISCONNECT){ if (packetID != PacketIDs.ACK && packetID != PacketIDs.DISCONNECT){
sendMessage(new Message.Sent(PacketTable.ACK, ourClientID, messageID)); sendMessage(new Message.Sent(PacketIDs.ACK, ourClientID, messageID));
} }
} catch (Exception e){ } catch (Exception e){
e.printStackTrace(); e.printStackTrace();
@ -164,7 +170,7 @@ public class Client implements Runnable {
} }
private void sendMessage(Message.Sent message){ private void sendMessage(Message.Sent message){
if (message.getPacketID() != PacketTable.ACK) if (message.getPacketID() != PacketIDs.ACK)
sentMessages.put(message.getMessageID(), message); sentMessages.put(message.getMessageID(), message);
byte[] data = message.getData().toByteArray(); byte[] data = message.getData().toByteArray();
DatagramPacket sendPacket = new DatagramPacket(data, data.length, serverAddress, Server.SERVER_PORT); DatagramPacket sendPacket = new DatagramPacket(data, data.length, serverAddress, Server.SERVER_PORT);

View File

@ -1,34 +1,41 @@
package ca.cosc3p91.a4.util.network; package ca.cosc3p91.a4.util.network;
public class PacketTable { public class PacketIDs {
// packetID -> byte defined in this file // packetID -> byte defined in this file
// clientID -> long // clientID -> long
// messageID -> 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; public static final byte CONNECT = 0x1;
// messageHeader // MESSAGE_HEADER
public static final byte DISCONNECT = 0x2; public static final byte DISCONNECT = 0x2;
// messageHeader // MESSAGE_HEADER
public static final byte ACK = 0x3; 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; public static final byte MESSAGE = 0x4;
// messageHeader, build // MESSAGE_HEADER, build
public static final byte BUILD = 0x5; public static final byte BUILD = 0x5;
// messageHeader, train // MESSAGE_HEADER, train
public static final byte TRAIN = 0x6; public static final byte TRAIN = 0x6;
// messageHeader, upgrade // MESSAGE_HEADER, upgrade
public static final byte UPGRADE = 0x7; public static final byte UPGRADE = 0x7;
// messageHeader // MESSAGE_HEADER
public static final byte PRINT_MAP_DATA = 0x8; // client -> server only! 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 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 public static final byte MAP_LINE_DATA = 0xA; // server -> client
// MESSAGE_HEADER
public static final byte EXPLORE = 0xB; public static final byte EXPLORE = 0xB;
// MESSAGE_HEADER
public static final byte ATTACK = 0xC; public static final byte ATTACK = 0xC;
// MESSAGE_HEADER
public static final byte GENERATE = 0xD; public static final byte GENERATE = 0xD;
// MESSAGE_HEADER
public static final byte TEST_ARMY = 0xE;
// MESSAGE_HEADER
public static final byte TEST_VILLAGE = 0xF;
} }

View File

@ -2,15 +2,14 @@ package ca.cosc3p91.a4.util.network;
import ca.cosc3p91.a4.game.GameEngine; import ca.cosc3p91.a4.game.GameEngine;
import ca.cosc3p91.a4.game.Map; import ca.cosc3p91.a4.game.Map;
import ca.cosc3p91.a4.gameobjects.Infantry;
import ca.cosc3p91.a4.gameobjects.Inhabitant;
import java.io.*; import java.io.*;
import java.net.*; import java.net.*;
import java.nio.ByteBuffer;
import java.nio.charset.StandardCharsets;
import java.rmi.ServerException; import java.rmi.ServerException;
import java.util.*; import java.util.*;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.LinkedBlockingQueue; import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.atomic.AtomicBoolean; import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.locks.ReentrantLock; import java.util.concurrent.locks.ReentrantLock;
@ -59,7 +58,7 @@ public class Server implements Runnable {
ConnectedClient client = clients.get(clientID); ConnectedClient client = clients.get(clientID);
// the server must handle connection requests while the client's processing thread will handle all other messages // 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; long cid = ++clientAssignmentID;
System.out.println("A client has connected, his clientID is " + cid); System.out.println("A client has connected, his clientID is " + cid);
clients.put(cid, new ConnectedClient(this, mainEngine, cid, messageID, receivePacket.getAddress(), receivePacket.getPort())); 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) if (client == null)
throw new ServerException("Client sent message invalid client id! (" + clientID + ")"); throw new ServerException("Client sent message invalid client id! (" + clientID + ")");
if (packetID == PacketTable.DISCONNECT) { if (packetID == PacketIDs.DISCONNECT) {
client.halt(); client.halt();
clients.remove(clientID); clients.remove(clientID);
continue; continue;
@ -124,7 +123,7 @@ public class Server implements Runnable {
}); });
gameEngineThread.start(); gameEngineThread.start();
sendMessage(new Message.Sent(PacketTable.ACK, clientID, messageID)); sendMessage(new Message.Sent(PacketIDs.ACK, clientID, messageID));
} }
public void handleRequest(Message.Received request){ public void handleRequest(Message.Received request){
@ -138,7 +137,7 @@ public class Server implements Runnable {
private void processRequest(Message.Received request){ private void processRequest(Message.Received request){
try { try {
switch (request.getPacketID()) { switch (request.getPacketID()) {
case PacketTable.ACK: case PacketIDs.ACK:
Message.Sent message = sentMessages.get(request.getMessageID()); Message.Sent message = sentMessages.get(request.getMessageID());
if (message == null) if (message == null)
throw new RuntimeException("A message was acknowledged but does not exist!"); throw new RuntimeException("A message was acknowledged but does not exist!");
@ -148,10 +147,10 @@ public class Server implements Runnable {
sentMessages.notifyAll(); sentMessages.notifyAll();
} }
break; break;
case PacketTable.MESSAGE: case PacketIDs.MESSAGE:
System.out.println(request.getReader().readUTF()); System.out.println(request.getReader().readUTF());
break; break;
case PacketTable.BUILD: case PacketIDs.BUILD:
try { try {
String type = request.getReader().readUTF().trim(); String type = request.getReader().readUTF().trim();
if (usingEngine.build(clientMap, type)) if (usingEngine.build(clientMap, type))
@ -162,7 +161,7 @@ public class Server implements Runnable {
sendAndLogLn(e.getMessage()); sendAndLogLn(e.getMessage());
} }
break; break;
case PacketTable.TRAIN: case PacketIDs.TRAIN:
try { try {
String type = request.getReader().readUTF().trim(); String type = request.getReader().readUTF().trim();
if (usingEngine.train(clientMap, type)) if (usingEngine.train(clientMap, type))
@ -173,7 +172,7 @@ public class Server implements Runnable {
sendAndLogLn(e.getMessage()); sendAndLogLn(e.getMessage());
} }
break; break;
case PacketTable.UPGRADE: case PacketIDs.UPGRADE:
try { try {
String type = request.getReader().readUTF(); String type = request.getReader().readUTF();
int val = Integer.parseInt( int val = Integer.parseInt(
@ -194,10 +193,10 @@ public class Server implements Runnable {
sendAndLogLn(e.getMessage()); sendAndLogLn(e.getMessage());
} }
break; break;
case PacketTable.PRINT_MAP_DATA: case PacketIDs.PRINT_MAP_DATA:
sendMapData(usingEngine.view.getVillageStateTable(clientMap, "Home Village")); sendMapData(usingEngine.view.getVillageStateTable(clientMap, "Home Village"));
break; break;
case PacketTable.EXPLORE: case PacketIDs.EXPLORE:
Random rand = new Random(); Random rand = new Random();
int clients = server.clients.size(); int clients = server.clients.size();
if (clients <= 1) { if (clients <= 1) {
@ -221,21 +220,38 @@ public class Server implements Runnable {
exploringMap = foundClient.clientMap; exploringMap = foundClient.clientMap;
sendMapData(usingEngine.view.getVillageStateTable(exploringMap, "Other Village")); sendMapData(usingEngine.view.getVillageStateTable(exploringMap, "Other Village"));
break; break;
case PacketTable.GENERATE: case PacketIDs.GENERATE:
exploringMap = usingEngine.generateMap(clientMap); exploringMap = usingEngine.generateMap(clientMap);
sendMapData(usingEngine.view.getVillageStateTable(exploringMap, "Generated Village")); sendMapData(usingEngine.view.getVillageStateTable(exploringMap, "Generated Village"));
break; break;
case PacketTable.ATTACK: case PacketIDs.ATTACK:
if (exploringMap != null) { if (exploringMap != null) {
if (!usingEngine.attackVillage(clientMap, exploringMap, this)) if (!usingEngine.attackVillage(clientMap, exploringMap, false,this))
sendAndLogLn("Failed to attack!"); sendAndLogLn("Failed to attack!");
} else } else
sendAndLogLn("Error: Explored map is null. Did you explored/generated last command?"); sendAndLogLn("Error: Explored map is null. Did you explored/generated last command?");
exploringMap = null; exploringMap = null;
break; 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) if (request.getPacketID() != PacketIDs.ACK)
sendMessage(new Message.Sent(PacketTable.ACK, clientID, request.getMessageID())); sendMessage(new Message.Sent(PacketIDs.ACK, clientID, request.getMessageID()));
} catch (Exception e) { } catch (Exception e) {
throw new RuntimeException(e); throw new RuntimeException(e);
} }
@ -273,7 +289,7 @@ public class Server implements Runnable {
private void sendMapData(ArrayList<String> lines) { private void sendMapData(ArrayList<String> lines) {
final long messageID = ++lastSentMessageID; 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 { try {
beginMapInfoMessage.getWriter().writeInt(lines.size()); beginMapInfoMessage.getWriter().writeInt(lines.size());
sendMessage(beginMapInfoMessage); 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. // 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++){ 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 { try {
// but we need the line index! // but we need the line index!
line.getWriter().writeInt(i); line.getWriter().writeInt(i);
@ -307,7 +323,7 @@ public class Server implements Runnable {
} }
public void sendAndLogLn(String str){ 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 { try {
mess.getWriter().writeUTF(str + "\n"); mess.getWriter().writeUTF(str + "\n");
sendMessage(mess); sendMessage(mess);
@ -319,7 +335,7 @@ public class Server implements Runnable {
public void sendMessage(Message.Sent message){ public void sendMessage(Message.Sent message){
if (message.getPacketID() != PacketTable.ACK) if (message.getPacketID() != PacketIDs.ACK)
this.sentMessages.put(message.getMessageID(), message); this.sentMessages.put(message.getMessageID(), message);
byte[] data = message.getData().toByteArray(); byte[] data = message.getData().toByteArray();
if (data.length > PACKET_SIZE) if (data.length > PACKET_SIZE)