Skip to content

Instantly share code, notes, and snippets.

@ansisec
Last active May 1, 2023 14:07
Show Gist options
  • Save ansisec/b4c6834e0b9fd18103ce62f70d54c192 to your computer and use it in GitHub Desktop.
Save ansisec/b4c6834e0b9fd18103ce62f70d54c192 to your computer and use it in GitHub Desktop.
Ficheiros auxiliares do Trabalho Prático de Programação Avançada 2022-2023
Ficheiros auxiliares incluídos no enunciado do trabalho prático
Update: 2023.04.20
Correção nos métodos start e resume do GameEngine para retornarem true
Permite que possa ser feito o register e unregister sem o motor estar parado
Update: 2023.05.01
Maze e IMazeElement passam a ser Serializable
package pt.isec.pa.tinypac.gameengine;
import java.util.HashSet;
import java.util.Set;
public final class GameEngine implements IGameEngine {
private GameEngineState state;
private GameEngineThread controlThread;
private Set<IGameEngineEvolve> clients;
System.Logger logger;
private void setState(GameEngineState state) {
this.state = state;
logger.log(System.Logger.Level.INFO,state.toString());
}
public GameEngine() {
logger = System.getLogger("GameEngine");
clients = new HashSet<>();
setState(GameEngineState.READY);
}
@Override
public void registerClient(IGameEngineEvolve listener) {
clients.add(listener);
}
@Override
public void unregisterClient(IGameEngineEvolve listener) {
clients.remove(listener);
}
@Override
public boolean start(long interval) {
if (state != GameEngineState.READY)
return false;
controlThread = new GameEngineThread(interval);
setState(GameEngineState.RUNNING);
controlThread.start();
return true;
}
@Override
public boolean stop() {
if (state == GameEngineState.READY)
return false;
setState(GameEngineState.READY);
return true;
}
@Override
public boolean pause() {
if (state != GameEngineState.RUNNING)
return false;
setState(GameEngineState.PAUSED);
return true;
}
@Override
public boolean resume() {
if (state != GameEngineState.PAUSED)
return false;
setState(GameEngineState.RUNNING);
return true;
}
@Override
public GameEngineState getCurrentState() {
return state;
}
@Override
public long getInterval() {
return controlThread.interval;
}
@Override
public void setInterval(long newInterval) {
if (controlThread != null)
controlThread.interval = newInterval;
}
@Override
public void waitForTheEnd() {
//controlThread.setDaemon(false);
try {
controlThread.join();
} catch (InterruptedException e) {
}
}
private class GameEngineThread extends Thread {
long interval;
GameEngineThread(long interval) {
this.interval = interval;
this.setDaemon(true);
}
@Override
public void run() {
int errCounter = 0;
while (true) {
if (state == GameEngineState.READY)
break;
if (state == GameEngineState.RUNNING) {
new Thread(() -> {
long time = System.nanoTime();
List.copyOf(clients).forEach(client -> client.evolve(GameEngine.this, time));
}).start();
}
try {
//noinspection BusyWait
sleep(interval);
errCounter = 0;
} catch (InterruptedException e) {
if (state == GameEngineState.READY || errCounter++ > 10)
break;
}
}
}
}
}
package pt.isec.pa.tinypac.gameengine;
public enum GameEngineState {READY, RUNNING, PAUSED}
package pt.isec.pa.tinypac.gameengine;
public interface IGameEngine {
void registerClient(IGameEngineEvolve listener);
void unregisterClient(IGameEngineEvolve listener);
boolean start(long interval); //ms; only works in the READY state
boolean stop(); //only works in the RUNNING or PAUSED states
boolean pause(); // only works in the RUNNING state
boolean resume(); // only works in the PAUSED state
GameEngineState getCurrentState(); // returns the current state
long getInterval();
void setInterval(long newInterval);
void waitForTheEnd();
}
package pt.isec.pa.tinypac.gameengine;
public interface IGameEngineEvolve {
void evolve(IGameEngine gameEngine, long currentTime);
}
package pt.isec.pa.tinypac.model.data;
public interface IMazeElement extends Serializable {
char getSymbol(); // returns the symbol of this element
// The list of symbols is available
// in the description of this work
}
xxxxxxxxxxxxxxxxxxxxxxxxxxxxx
xooooooooooooxxxoooooooooooox
xoxxxxoxxxxxoxxxoxxxxxoxxxxox
xOxxxxoxxxxxoxxxoxxxxxoxxxxOx
xoxxxxoxxxxxoxxxoxxxxxoxxxxox
xooooooooooooooooooooooooooox
xoxxxxoxxoxxxxxxxxxoxxoxxxxox
xoxxxxoxxoxxxxxxxxxoxxoxxxxox
xooooooxxooooxxxooooxxoooooox
xxxxxxoxxxxxoxxxoxxxxxoxxxxxx
xxxxxxoxxxxxoxxxoxxxxxoxxxxxx
xxxxxxoxxoooooooooooxxoxxxxxx
xxxxxxoxxoxxxxYxxxxoxxoxxxxxx
xxxxxxoxxoxyyyyyyyxoxxoxxxxxx
xWooooooooxyyyyyyyxooooooooWx
xxxxxxoxxoxyyyyyyyxoxxoxxxxxx
xxxxxxoxxoxxxxxxxxxoxxoxxxxxx
xxxxxxoxxoooooFoooooxxoxxxxxx
xxxxxxoxxoxxxxxxxxxoxxoxxxxxx
xxxxxxoxxoxxxxxxxxxoxxoxxxxxx
xooooooooooooxxxoooooooooooox
xoxxxxoxxxxxoxxxoxxxxxoxxxxox
xoxxxxoxxxxxoxxxoxxxxxoxxxxox
xOooxxooooooooMooooooooxxooOx
xxxoxxoxxoxxxxxxxxxoxxoxxoxxx
xxxoxxoxxoxxxxxxxxxoxxoxxoxxx
xooooooxxooooxxxooooxxoooooox
xoxxxxxxxxxxoxxxoxxxxxxxxxxox
xoxxxxxxxxxxoxxxoxxxxxxxxxxox
xooooooooooooooooooooooooooox
xxxxxxxxxxxxxxxxxxxxxxxxxxxxx
package pt.isec.pa.tinypac.model.data;
public final class Maze implements Serializable {
private static final long serialVersionUID = 1L;
private final IMazeElement[][] board;
public Maze(int height, int width) {
board = new IMazeElement[height][width];
}
public boolean set(int y, int x,IMazeElement element) {
if (y < 0 || y >= board.length || x < 0 || x >= board[0].length)
return false;
board[y][x] = element; // can be null
return true;
}
public IMazeElement get(int y, int x) {
if (y < 0 || y >= board.length || x < 0 || x >= board[0].length)
return null;
return board[y][x]; // can be null
}
public char[][] getMaze() {
char[][] char_board = new char[board.length][board[0].length];
for(int y=0;y<board.length;y++)
for(int x=0;x<board[y].length;x++)
if (board[y][x]==null)
char_board[y][x] = ' ';
else
char_board[y][x] = board[y][x].getSymbol();
return char_board;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment