Merge remote-tracking branch 'refs/remotes/origin/main'
commit
5ce406f376
|
@ -13,30 +13,24 @@ import java.nio.file.Files;
|
||||||
import java.nio.file.Paths;
|
import java.nio.file.Paths;
|
||||||
import java.util.Random;
|
import java.util.Random;
|
||||||
|
|
||||||
public class GameEngine implements Runnable {
|
public class GameEngine {
|
||||||
|
|
||||||
public static final double GOLD_FACTOR = 5;
|
public static final double GOLD_FACTOR = 5;
|
||||||
public static final double IRON_FACTOR = 1;
|
public static final double IRON_FACTOR = 1;
|
||||||
public static final double WOOD_FACTOR = 0.1;
|
public static final double WOOD_FACTOR = 0.1;
|
||||||
|
|
||||||
private Player player;
|
|
||||||
boolean running = true;
|
|
||||||
|
|
||||||
private float pillageFactor = 0.5f;
|
private float pillageFactor = 0.5f;
|
||||||
|
|
||||||
private int currentTime;
|
private int currentTime;
|
||||||
|
|
||||||
private final Random random = new Random(System.nanoTime());
|
private final Random random = new Random(System.nanoTime());
|
||||||
|
|
||||||
public Map map;
|
|
||||||
public GameDisplay view;
|
public GameDisplay view;
|
||||||
|
|
||||||
public GameEngine() {
|
public GameEngine() {
|
||||||
player = new Player();
|
|
||||||
map = generateInitialMap();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void attackVillage(Map map) {
|
public void attackVillage(Map attacking, Map defending) {
|
||||||
// int defenseiveCounter = 1;
|
// int defenseiveCounter = 1;
|
||||||
// int inhabCounter = 0;
|
// int inhabCounter = 0;
|
||||||
// for (Building b : map.contains)
|
// for (Building b : map.contains)
|
||||||
|
@ -53,31 +47,31 @@ public class GameEngine implements Runnable {
|
||||||
// this.map.getTownHall().addWood((int) (map.getTownHall().getCurrentWood() * pillageFactor));
|
// this.map.getTownHall().addWood((int) (map.getTownHall().getCurrentWood() * pillageFactor));
|
||||||
// this.map.getTownHall().addIron((int) (map.getTownHall().getCurrentIron() * pillageFactor));
|
// this.map.getTownHall().addIron((int) (map.getTownHall().getCurrentIron() * pillageFactor));
|
||||||
// this.map.getTownHall().addGold((int) (map.getTownHall().getCurrentGold() * pillageFactor));
|
// this.map.getTownHall().addGold((int) (map.getTownHall().getCurrentGold() * pillageFactor));
|
||||||
ChallengeAdapter adapter = new ChallengeAdapter(this.map);
|
ChallengeAdapter adapter = new ChallengeAdapter(attacking);
|
||||||
adapter.attack(map);
|
adapter.attack(defending);
|
||||||
}
|
}
|
||||||
|
|
||||||
private Map generateInitialMap(){
|
public Map generateInitialMap(){
|
||||||
return new Map(new CasaDeNarino(1, VillageHallStages.villageStages[0]), 30);
|
return new Map(new CasaDeNarino(1, VillageHallStages.villageStages[0]), 30);
|
||||||
}
|
}
|
||||||
|
|
||||||
public Map generateMap() {
|
public Map generateMap(Map map) {
|
||||||
Map initialMap = generateInitialMap();
|
Map initialMap = generateInitialMap();
|
||||||
|
|
||||||
CasaDeNarino hall = initialMap.getTownHall();
|
CasaDeNarino hall = initialMap.getTownHall();
|
||||||
|
|
||||||
// generate a similar town hall
|
// generate a similar town hall
|
||||||
int levelChange = random.nextInt(2) - 1;
|
int levelChange = random.nextInt(2) - 1;
|
||||||
int nextLevel = this.map.getTownHall().getLevel() + levelChange;
|
int nextLevel = map.getTownHall().getLevel() + levelChange;
|
||||||
// only need to change if the new village level is higher than initial
|
// only need to change if the new village level is higher than initial
|
||||||
if (nextLevel > 0)
|
if (nextLevel > 0)
|
||||||
hall.upgrade(VillageHallStages.villageStages[nextLevel]);
|
hall.upgrade(VillageHallStages.villageStages[nextLevel]);
|
||||||
|
|
||||||
hall.addWood(this.map.getTownHall().getCurrentWood() + random.nextInt(500) - 150);
|
hall.addWood(map.getTownHall().getCurrentWood() + random.nextInt(500) - 150);
|
||||||
hall.addIron(this.map.getTownHall().getCurrentIron() + random.nextInt(500) - 150);
|
hall.addIron(map.getTownHall().getCurrentIron() + random.nextInt(500) - 150);
|
||||||
hall.addGold(this.map.getTownHall().getCurrentGold() + random.nextInt(500) - 150);
|
hall.addGold(map.getTownHall().getCurrentGold() + random.nextInt(500) - 150);
|
||||||
|
|
||||||
int buildingCount = this.map.contains.size();
|
int buildingCount = map.contains.size();
|
||||||
|
|
||||||
int saulGoodMines = 0;
|
int saulGoodMines = 0;
|
||||||
int ironMines = 0;
|
int ironMines = 0;
|
||||||
|
@ -86,7 +80,7 @@ public class GameEngine implements Runnable {
|
||||||
int cannons = 0;
|
int cannons = 0;
|
||||||
|
|
||||||
// count buildings in our map
|
// count buildings in our map
|
||||||
for (Building b : this.map.contains){
|
for (Building b : map.contains){
|
||||||
if (b instanceof SaulGoodMine)
|
if (b instanceof SaulGoodMine)
|
||||||
saulGoodMines++;
|
saulGoodMines++;
|
||||||
else if (b instanceof IronMine)
|
else if (b instanceof IronMine)
|
||||||
|
@ -145,6 +139,35 @@ public class GameEngine implements Runnable {
|
||||||
return score;
|
return score;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void updateMap(Map map) {
|
||||||
|
for (int i = 0; i < map.contains.size(); i++) {
|
||||||
|
if ((map.contains.get(i) instanceof ResourceBuilding)) {
|
||||||
|
((ResourceBuilding) map.contains.get(i)).update(map.getTownHall());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean build (Map map, String buildingArg) {
|
||||||
|
BuildingFactory bfactory = new BuildingFactory();
|
||||||
|
Building type = bfactory.getBuilding(buildingArg);
|
||||||
|
return map.build(new Tile(), type);
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean train (Map map, String inhabitantArgs) {
|
||||||
|
InhabitantFactory ifactory = new InhabitantFactory();
|
||||||
|
Inhabitant type = ifactory.getInhabitant(inhabitantArgs);
|
||||||
|
return map.train(type);
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean upgradeBuilding (Map map, int buildingIndex) {
|
||||||
|
return map.upgradeBuilding(buildingIndex);
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean upgradeInhabitant (Map map, int inhabitantIndex) {
|
||||||
|
return map.upgradeInhabitant(inhabitantIndex);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
@Override
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
String in;
|
String in;
|
||||||
|
@ -156,11 +179,6 @@ public class GameEngine implements Runnable {
|
||||||
Map exploringMap = null;
|
Map exploringMap = null;
|
||||||
boolean deleteMyHeart = true;
|
boolean deleteMyHeart = true;
|
||||||
while (running) {
|
while (running) {
|
||||||
for (Building b : this.map.contains){
|
|
||||||
if ((b instanceof ResourceBuilding)) {
|
|
||||||
((ResourceBuilding) b).update(this.map.getTownHall());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
try {
|
try {
|
||||||
if ((in = view.nextInput()) != null) {
|
if ((in = view.nextInput()) != null) {
|
||||||
String[] args = in.split(" ");
|
String[] args = in.split(" ");
|
||||||
|
@ -249,8 +267,7 @@ public class GameEngine implements Runnable {
|
||||||
if (deleteMyHeart)
|
if (deleteMyHeart)
|
||||||
exploringMap = null;
|
exploringMap = null;
|
||||||
}
|
}
|
||||||
save("test.xml", this.map);
|
} */
|
||||||
}
|
|
||||||
|
|
||||||
public void save(String file, Map map){
|
public void save(String file, Map map){
|
||||||
try (XMLEncoder encoder = new XMLEncoder(new BufferedOutputStream(Files.newOutputStream(Paths.get(file))))) {
|
try (XMLEncoder encoder = new XMLEncoder(new BufferedOutputStream(Files.newOutputStream(Paths.get(file))))) {
|
||||||
|
|
|
@ -56,7 +56,7 @@ public class Map implements Serializable {
|
||||||
|
|
||||||
public boolean upgradeBuilding(int buildingIndex) {
|
public boolean upgradeBuilding(int buildingIndex) {
|
||||||
|
|
||||||
if (buildingIndex >= contains.size()) return false;
|
if (buildingIndex >= contains.size() || buildingIndex < 0) return false;
|
||||||
|
|
||||||
Building b = contains.get(buildingIndex);
|
Building b = contains.get(buildingIndex);
|
||||||
|
|
||||||
|
@ -93,7 +93,7 @@ public class Map implements Serializable {
|
||||||
|
|
||||||
public boolean upgradeInhabitant(int inhabitantIndex) {
|
public boolean upgradeInhabitant(int inhabitantIndex) {
|
||||||
|
|
||||||
if (inhabitantIndex >= inhabitants.size()) return false;
|
if (inhabitantIndex >= inhabitants.size() || inhabitantIndex < 0) return false;
|
||||||
|
|
||||||
Inhabitant i = inhabitants.get(inhabitantIndex);
|
Inhabitant i = inhabitants.get(inhabitantIndex);
|
||||||
|
|
||||||
|
|
|
@ -16,5 +16,7 @@ public class PacketTable {
|
||||||
public static final byte ACK = 0x3;
|
public static final byte ACK = 0x3;
|
||||||
// messageHeader, UTF8 String with length information (use DOS.writeUTF/DIS.readUTF)
|
// messageHeader, UTF8 String with length information (use DOS.writeUTF/DIS.readUTF)
|
||||||
public static final byte MESSAGE = 0x4;
|
public static final byte MESSAGE = 0x4;
|
||||||
|
// messageHeader, serial packets with map info
|
||||||
|
public static final byte MAP_DATA = 0x5;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,11 +1,16 @@
|
||||||
package ca.cosc3p91.a4.util.network;
|
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 java.io.*;
|
import java.io.*;
|
||||||
import java.net.*;
|
import java.net.*;
|
||||||
import java.rmi.ServerException;
|
import java.rmi.ServerException;
|
||||||
import java.util.*;
|
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.PriorityQueue;
|
||||||
|
import java.util.Queue;
|
||||||
|
import java.util.concurrent.atomic.AtomicBoolean;
|
||||||
import java.util.concurrent.locks.ReentrantLock;
|
import java.util.concurrent.locks.ReentrantLock;
|
||||||
|
|
||||||
public class Server implements Runnable {
|
public class Server implements Runnable {
|
||||||
|
@ -49,7 +54,7 @@ public class Server implements Runnable {
|
||||||
|
|
||||||
// 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 == PacketTable.CONNECT){
|
||||||
clients.put(++clientAssignmentID, new ConnectedClient(socket, clientID, messageID, receivePacket.getAddress(), receivePacket.getPort()));
|
clients.put(++clientAssignmentID, new ConnectedClient(socket, mainEngine, clientID, messageID, receivePacket.getAddress(), receivePacket.getPort()));
|
||||||
} else if (packetID == PacketTable.DISCONNECT) {
|
} else if (packetID == PacketTable.DISCONNECT) {
|
||||||
if (client == null)
|
if (client == null)
|
||||||
throw new ServerException("Client disconnected with invalid client id! (" + clientID + ")");
|
throw new ServerException("Client disconnected with invalid client id! (" + clientID + ")");
|
||||||
|
@ -80,19 +85,32 @@ public class Server implements Runnable {
|
||||||
private final int port;
|
private final int port;
|
||||||
private final Queue<Message.Received> pendingRequests = new PriorityQueue<>();
|
private final Queue<Message.Received> pendingRequests = new PriorityQueue<>();
|
||||||
private final ReentrantLock requestLock = new ReentrantLock();
|
private final ReentrantLock requestLock = new ReentrantLock();
|
||||||
|
private final AtomicBoolean allowUpdate;
|
||||||
private final HashMap<Long, Message.Sent> sentMessages = new HashMap<>();
|
private final HashMap<Long, Message.Sent> sentMessages = new HashMap<>();
|
||||||
private final DatagramSocket serverSocket;
|
private final DatagramSocket serverSocket;
|
||||||
private final long clientID;
|
private final long clientID;
|
||||||
private volatile boolean running = true;
|
private volatile boolean running = true;
|
||||||
private final Thread processingThread;
|
private final Thread processingThread;
|
||||||
|
private final Thread gameEngineThread;
|
||||||
|
private final Map clientMap;
|
||||||
|
|
||||||
public ConnectedClient(DatagramSocket serverSocket, long clientID, long messageID, InetAddress address, int port){
|
public ConnectedClient(DatagramSocket serverSocket, GameEngine engine, long clientID, long messageID, InetAddress address, int port){
|
||||||
this.serverSocket = serverSocket;
|
this.serverSocket = serverSocket;
|
||||||
this.address = address;
|
this.address = address;
|
||||||
this.port = port;
|
this.port = port;
|
||||||
this.clientID = clientID;
|
this.clientID = clientID;
|
||||||
|
this.clientMap = engine.generateInitialMap();
|
||||||
|
this.allowUpdate = new AtomicBoolean(true);
|
||||||
processingThread = new Thread(this);
|
processingThread = new Thread(this);
|
||||||
processingThread.start();
|
processingThread.start();
|
||||||
|
gameEngineThread = new Thread(() -> {
|
||||||
|
while (true) {
|
||||||
|
if (this.allowUpdate.get()) {
|
||||||
|
engine.updateMap(clientMap);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
gameEngineThread.start();
|
||||||
|
|
||||||
sendMessage(new Message.Sent(PacketTable.ACK, clientID, messageID));
|
sendMessage(new Message.Sent(PacketTable.ACK, clientID, messageID));
|
||||||
}
|
}
|
||||||
|
@ -129,11 +147,13 @@ public class Server implements Runnable {
|
||||||
requestLock.lock();
|
requestLock.lock();
|
||||||
if (!pendingRequests.isEmpty()) {
|
if (!pendingRequests.isEmpty()) {
|
||||||
Message.Received request = pendingRequests.remove();
|
Message.Received request = pendingRequests.remove();
|
||||||
|
allowUpdate.set(false);
|
||||||
processRequest(request);
|
processRequest(request);
|
||||||
|
allowUpdate.set(true);
|
||||||
}
|
}
|
||||||
requestLock.unlock();
|
requestLock.unlock();
|
||||||
|
|
||||||
for (Map.Entry<Long, Message.Sent> message : sentMessages.entrySet()){
|
for (HashMap.Entry<Long, Message.Sent> message : sentMessages.entrySet()){
|
||||||
if (message.getValue().getTimeSinceSent().get() > MAX_PACKET_ACK_TIME_SECONDS) {
|
if (message.getValue().getTimeSinceSent().get() > MAX_PACKET_ACK_TIME_SECONDS) {
|
||||||
System.out.println("The server did not process our message, did they receive it?");
|
System.out.println("The server did not process our message, did they receive it?");
|
||||||
sendMessage(message.getValue());
|
sendMessage(message.getValue());
|
||||||
|
|
Loading…
Reference in New Issue