add symlinks for marathon
1
solution/H00/src/main
Symbolic link
|
@ -0,0 +1 @@
|
||||||
|
/home/osh/Desktop/FOP-2425-Marathon/H00/src/main
|
|
@ -1,121 +0,0 @@
|
||||||
package h00;
|
|
||||||
|
|
||||||
import fopbot.Direction;
|
|
||||||
import fopbot.Robot;
|
|
||||||
import fopbot.RobotFamily;
|
|
||||||
import fopbot.World;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Main entry point in executing the program.
|
|
||||||
*/
|
|
||||||
public class Main {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The subtask to run.
|
|
||||||
*/
|
|
||||||
public static int runToSubtask = -1;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The world speed in milliseconds.
|
|
||||||
*/
|
|
||||||
public static int delay = 300;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Main entry point in executing the program.
|
|
||||||
*
|
|
||||||
* @param args program arguments, currently ignored
|
|
||||||
*/
|
|
||||||
public static void main(String[] args) {
|
|
||||||
// This sets up the FOPBot World with a 4x4 grid. (DO NOT TOUCH)
|
|
||||||
setupWorld();
|
|
||||||
|
|
||||||
// TODO: H0.4 - Initializing FOPBot
|
|
||||||
Robot kasper = new Robot(0, 0, Direction.DOWN, 4, RobotFamily.SQUARE_BLUE);
|
|
||||||
Robot alfred = new Robot(0, 3, Direction.DOWN, 0, RobotFamily.SQUARE_GREEN);
|
|
||||||
|
|
||||||
if (runToSubtask == 0) return; // DO NOT TOUCH!
|
|
||||||
// TODO: H0.5.1 - Turning with repeated instructions
|
|
||||||
alfred.turnLeft();
|
|
||||||
alfred.turnLeft();
|
|
||||||
|
|
||||||
if (runToSubtask == 1) return; // DO NOT TOUCH!
|
|
||||||
// TODO: H0.5.2 - Turning with for-loop
|
|
||||||
int numberOfTurns = 2;
|
|
||||||
for (int i = 0; i < numberOfTurns; i++) {
|
|
||||||
alfred.turnLeft();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (runToSubtask == 2) return; // DO NOT TOUCH!
|
|
||||||
// TODO: H0.5.3 - Turning with while-loop
|
|
||||||
while (!kasper.isFacingRight()) {
|
|
||||||
kasper.turnLeft();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (runToSubtask == 3) return; // DO NOT TOUCH!
|
|
||||||
// TODO: H0.6.1 - Put with repeated instructions
|
|
||||||
kasper.putCoin();
|
|
||||||
kasper.move();
|
|
||||||
kasper.move();
|
|
||||||
kasper.move();
|
|
||||||
kasper.turnLeft();
|
|
||||||
|
|
||||||
if (runToSubtask == 4) return; // DO NOT TOUCH!
|
|
||||||
// TODO: H0.6.2 - Pick with repeated instructions
|
|
||||||
alfred.move();
|
|
||||||
alfred.move();
|
|
||||||
alfred.move();
|
|
||||||
alfred.pickCoin();
|
|
||||||
alfred.turnLeft();
|
|
||||||
|
|
||||||
if (runToSubtask == 5) return; // DO NOT TOUCH!
|
|
||||||
// TODO: H0.6.3 - Put with for-loop
|
|
||||||
kasper.putCoin();
|
|
||||||
int numberOfSteps = 3;
|
|
||||||
for (int i = 0; i < numberOfSteps; i++) {
|
|
||||||
kasper.move();
|
|
||||||
}
|
|
||||||
kasper.turnLeft();
|
|
||||||
|
|
||||||
if (runToSubtask == 6) return; // DO NOT TOUCH!
|
|
||||||
// TODO: H0.7.1 - Pick with while-loop
|
|
||||||
while (alfred.isFrontClear()) {
|
|
||||||
alfred.move();
|
|
||||||
}
|
|
||||||
alfred.pickCoin();
|
|
||||||
alfred.turnLeft();
|
|
||||||
|
|
||||||
if (runToSubtask == 7) return; // DO NOT TOUCH!
|
|
||||||
// TODO: H0.7.2 - Pick and put with while-loop
|
|
||||||
kasper.putCoin();
|
|
||||||
while (alfred.isFrontClear()) {
|
|
||||||
kasper.move();
|
|
||||||
alfred.move();
|
|
||||||
}
|
|
||||||
alfred.pickCoin();
|
|
||||||
alfred.turnLeft();
|
|
||||||
kasper.turnLeft();
|
|
||||||
|
|
||||||
if (runToSubtask == 8) return; // DO NOT TOUCH!
|
|
||||||
// TODO: H0.7.3 - Put with reversed for-loop
|
|
||||||
for (int i = alfred.getNumberOfCoins(); i > 0; i--) {
|
|
||||||
alfred.putCoin();
|
|
||||||
alfred.move();
|
|
||||||
}
|
|
||||||
alfred.turnLeft();
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void setupWorld() {
|
|
||||||
// variable representing width/size of world
|
|
||||||
final int worldSize = 4;
|
|
||||||
|
|
||||||
// setting world size symmetrical, meaning height = width
|
|
||||||
World.setSize(worldSize, worldSize);
|
|
||||||
|
|
||||||
// speed of how fast the world gets refreshed (e.g. how fast the robot(s) act)
|
|
||||||
// the lower the number, the faster the refresh
|
|
||||||
World.setDelay(delay);
|
|
||||||
|
|
||||||
// make it possible to see the world window
|
|
||||||
World.setVisible(true);
|
|
||||||
}
|
|
||||||
}
|
|
1
solution/H00/src/test
Symbolic link
|
@ -0,0 +1 @@
|
||||||
|
/home/osh/Desktop/FOP-2425-Marathon/H00/src/test
|
|
@ -1,16 +0,0 @@
|
||||||
package h00;
|
|
||||||
|
|
||||||
import org.junit.jupiter.api.Test;
|
|
||||||
|
|
||||||
import static org.junit.jupiter.api.Assertions.*;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* An example JUnit test class.
|
|
||||||
*/
|
|
||||||
public class ExampleJUnitTest {
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testAddition() {
|
|
||||||
assertEquals(2, 1 + 1);
|
|
||||||
}
|
|
||||||
}
|
|
1
solution/H01/src/main
Symbolic link
|
@ -0,0 +1 @@
|
||||||
|
/home/osh/Desktop/FOP-2425-Marathon/H01/src/main
|
|
@ -1,50 +0,0 @@
|
||||||
package h01;
|
|
||||||
|
|
||||||
import org.tudalgo.algoutils.student.annotation.SolutionOnly;
|
|
||||||
import org.tudalgo.algoutils.student.annotation.StudentImplementationRequired;
|
|
||||||
|
|
||||||
import fopbot.Robot;
|
|
||||||
import h01.template.Families;
|
|
||||||
import h01.template.Ghost;
|
|
||||||
import h01.template.TickBased;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The {@link BlueGhost} is a {@link Robot} that looks like a blue ghost.
|
|
||||||
* It tries to move in a circle.
|
|
||||||
*/
|
|
||||||
public class BlueGhost extends Robot implements Ghost, TickBased {
|
|
||||||
/**
|
|
||||||
* Creates a new {@link BlueGhost} at the given position.
|
|
||||||
*
|
|
||||||
* @param x the x-coordinate
|
|
||||||
* @param y the y-coordinate
|
|
||||||
*/
|
|
||||||
public BlueGhost(int x, int y) {
|
|
||||||
super(x, y, Families.GHOST_BLUE);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Turns the robot to the right and then moves in the first direction that is
|
|
||||||
* clear.
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
@StudentImplementationRequired("H2.1")
|
|
||||||
public void doMove() {
|
|
||||||
turnRight();
|
|
||||||
while (!isFrontClear()) {
|
|
||||||
turnLeft();
|
|
||||||
}
|
|
||||||
move();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Turns the robot to the right.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
@SolutionOnly
|
|
||||||
private void turnRight() {
|
|
||||||
for (int i = 0; i < 3; i++) {
|
|
||||||
turnLeft();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,23 +0,0 @@
|
||||||
package h01;
|
|
||||||
|
|
||||||
import h01.template.GameControllerTemplate;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The {@link GameController} class is responsible for controlling the game.
|
|
||||||
*/
|
|
||||||
public class GameController extends GameControllerTemplate {
|
|
||||||
/**
|
|
||||||
* Creates a new {@link GameController} object and sets up the game.
|
|
||||||
*/
|
|
||||||
public GameController() {
|
|
||||||
setup();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Checks if the player has won the game.
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
public boolean checkWinCondition() {
|
|
||||||
return pacman.getNumberOfCoins() == totalCoins;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,16 +0,0 @@
|
||||||
package h01;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Main entry point in executing the program.
|
|
||||||
*/
|
|
||||||
public class Main {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Main entry point in executing the program.
|
|
||||||
*
|
|
||||||
* @param args program arguments, currently ignored
|
|
||||||
*/
|
|
||||||
public static void main(String[] args) {
|
|
||||||
new GameController().startGame();
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,53 +0,0 @@
|
||||||
package h01;
|
|
||||||
|
|
||||||
import org.tudalgo.algoutils.student.annotation.StudentImplementationRequired;
|
|
||||||
|
|
||||||
import fopbot.Robot;
|
|
||||||
import h01.template.Families;
|
|
||||||
import h01.template.Ghost;
|
|
||||||
import h01.template.TickBased;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* {@link OrangeGhost} is a {@link Robot} that looks like a orange ghost.
|
|
||||||
* It tries to move in a straight line and alternates between turning left and
|
|
||||||
* right.
|
|
||||||
*/
|
|
||||||
public class OrangeGhost extends Robot implements Ghost, TickBased {
|
|
||||||
/**
|
|
||||||
* Creates a new {@link OrangeGhost} at the given position.
|
|
||||||
*
|
|
||||||
* @param x the x-coordinate
|
|
||||||
* @param y the y-coordinate
|
|
||||||
*/
|
|
||||||
public OrangeGhost(int x, int y) {
|
|
||||||
super(x, y, Families.GHOST_ORANGE);
|
|
||||||
}
|
|
||||||
|
|
||||||
private boolean leftTurnNext = false;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Moves the robot in a straight line if possible.
|
|
||||||
* If the robot cannot move forward, it turns left or right until there is no
|
|
||||||
* wall in front.
|
|
||||||
* The robot alternates between turning left and right.
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
@StudentImplementationRequired("H2.3")
|
|
||||||
public void doMove() {
|
|
||||||
if (isFrontClear()) {
|
|
||||||
move();
|
|
||||||
return;
|
|
||||||
} else {
|
|
||||||
while (!isFrontClear()) {
|
|
||||||
if (leftTurnNext) {
|
|
||||||
turnLeft();
|
|
||||||
} else {
|
|
||||||
turnLeft();
|
|
||||||
turnLeft();
|
|
||||||
turnLeft();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
leftTurnNext = !leftTurnNext;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,74 +0,0 @@
|
||||||
package h01;
|
|
||||||
|
|
||||||
import org.tudalgo.algoutils.student.annotation.SolutionOnly;
|
|
||||||
import org.tudalgo.algoutils.student.annotation.StudentImplementationRequired;
|
|
||||||
|
|
||||||
import fopbot.Direction;
|
|
||||||
import fopbot.Robot;
|
|
||||||
import h01.template.Controllable;
|
|
||||||
import h01.template.Families;
|
|
||||||
import h01.template.TickBased;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* {@link Pacman} is a {@link Robot} that can be controlled by the user and
|
|
||||||
* looks like Pacman.
|
|
||||||
* It can move in four directions and pick up coins.
|
|
||||||
*/
|
|
||||||
public class Pacman extends Robot implements Controllable, TickBased {
|
|
||||||
/**
|
|
||||||
* Creates a new {@link Pacman} at the given position.
|
|
||||||
*
|
|
||||||
* @param x the x-coordinate
|
|
||||||
* @param y the y-coordinate
|
|
||||||
*/
|
|
||||||
public Pacman(int x, int y) {
|
|
||||||
super(x, y, Families.PACMAN);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Handles the key input of the user.
|
|
||||||
* The keys 0, 1, 2, 3 represent the arrow keys up, right, down, left.
|
|
||||||
* If the key is not in this range, the method does nothing.
|
|
||||||
* If the key is in the range, the robot turns in the corresponding direction,
|
|
||||||
* moves one field and collects a coin if there is one.
|
|
||||||
*
|
|
||||||
* @param k the int value of the pressed key
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
@StudentImplementationRequired("H1.1")
|
|
||||||
public void handleKeyInput(int k) {
|
|
||||||
if (k < 0 || k > 3) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (k == 0) {
|
|
||||||
turnDirection(Direction.UP);
|
|
||||||
} else if (k == 1) {
|
|
||||||
turnDirection(Direction.RIGHT);
|
|
||||||
} else if (k == 2) {
|
|
||||||
turnDirection(Direction.DOWN);
|
|
||||||
} else {
|
|
||||||
turnDirection(Direction.LEFT);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (isFrontClear()) {
|
|
||||||
move();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (isOnACoin()) {
|
|
||||||
pickCoin();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Turns the robot in the given direction.
|
|
||||||
*
|
|
||||||
* @param dir the direction to turn to
|
|
||||||
*/
|
|
||||||
@SolutionOnly
|
|
||||||
private void turnDirection(Direction dir) {
|
|
||||||
while (getDirection() != dir) {
|
|
||||||
turnLeft();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,50 +0,0 @@
|
||||||
package h01;
|
|
||||||
|
|
||||||
import org.tudalgo.algoutils.student.annotation.StudentImplementationRequired;
|
|
||||||
|
|
||||||
import fopbot.Robot;
|
|
||||||
import h01.template.Families;
|
|
||||||
import h01.template.Ghost;
|
|
||||||
import h01.template.TickBased;
|
|
||||||
import h01.template.Util;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The {@link PinkGhost} is a {@link Robot} that looks like a pink ghost.
|
|
||||||
* It tries to move in a random direction.
|
|
||||||
*/
|
|
||||||
public class PinkGhost extends Robot implements Ghost, TickBased {
|
|
||||||
/**
|
|
||||||
* Creates a new {@link PinkGhost} at the given position.
|
|
||||||
*
|
|
||||||
* @param x the x-coordinate
|
|
||||||
* @param y the y-coordinate
|
|
||||||
*/
|
|
||||||
public PinkGhost(int x, int y) {
|
|
||||||
super(x, y, Families.GHOST_PINK);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Finds in how many directions the ghost can move and then turns a random
|
|
||||||
* amount of times to the left.
|
|
||||||
* The ghost then moves forward or turns to the left until it can move forward.
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
@StudentImplementationRequired("H2.2")
|
|
||||||
public void doMove() {
|
|
||||||
int freeLanes = 0;
|
|
||||||
for (int i = 0; i < 4; i++) {
|
|
||||||
turnLeft();
|
|
||||||
if (isFrontClear()) {
|
|
||||||
freeLanes++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
int rand = Util.getRandomInteger(1, freeLanes);
|
|
||||||
for (int i = 0; i < rand; i++) {
|
|
||||||
do {
|
|
||||||
turnLeft();
|
|
||||||
} while (!isFrontClear());
|
|
||||||
}
|
|
||||||
move();
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,57 +0,0 @@
|
||||||
package h01;
|
|
||||||
|
|
||||||
import org.tudalgo.algoutils.student.annotation.SolutionOnly;
|
|
||||||
import org.tudalgo.algoutils.student.annotation.StudentImplementationRequired;
|
|
||||||
|
|
||||||
import fopbot.Direction;
|
|
||||||
import fopbot.Robot;
|
|
||||||
import h01.template.Families;
|
|
||||||
import h01.template.Ghost;
|
|
||||||
import h01.template.TickBased;
|
|
||||||
import h01.template.Util;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The {@link RedGhost} is a {@link Robot} that looks like a red ghost.
|
|
||||||
* It tries to move in the direction of the chased robot.
|
|
||||||
*/
|
|
||||||
public class RedGhost extends Robot implements Ghost, TickBased {
|
|
||||||
private final Robot chased;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Creates a new {@link RedGhost} at the given position.
|
|
||||||
*
|
|
||||||
* @param x the x-coordinate
|
|
||||||
* @param y the y-coordinate
|
|
||||||
* @param chased the robot that is being chased
|
|
||||||
*/
|
|
||||||
public RedGhost(int x, int y, Robot chased) {
|
|
||||||
super(x, y, Families.GHOST_RED);
|
|
||||||
this.chased = chased;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Moves the robot in the direction of the chased robot.
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
@StudentImplementationRequired("H2.4")
|
|
||||||
public void doMove() {
|
|
||||||
turnDirection(Util.furthestDirection(chased, this));
|
|
||||||
while (!isFrontClear()) {
|
|
||||||
turnLeft();
|
|
||||||
}
|
|
||||||
move();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Turns the robot in the given direction.
|
|
||||||
*
|
|
||||||
* @param dir the direction to turn to
|
|
||||||
*/
|
|
||||||
@SolutionOnly
|
|
||||||
private void turnDirection(Direction dir) {
|
|
||||||
while (getDirection() != dir) {
|
|
||||||
turnLeft();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
|
@ -1,5 +0,0 @@
|
||||||
package h01.template;
|
|
||||||
|
|
||||||
public interface Controllable {
|
|
||||||
void handleKeyInput(int k);
|
|
||||||
}
|
|
|
@ -1,36 +0,0 @@
|
||||||
package h01.template;
|
|
||||||
|
|
||||||
import fopbot.RobotFamily;
|
|
||||||
import fopbot.SvgBasedRobotFamily;
|
|
||||||
|
|
||||||
import java.awt.*;
|
|
||||||
|
|
||||||
public class Families {
|
|
||||||
public static RobotFamily GHOST_ORANGE = new SvgBasedRobotFamily(
|
|
||||||
"GHOST_ORANGE",
|
|
||||||
"/robots/ghost_orange.svg",
|
|
||||||
"/robots/ghost_orange.svg",
|
|
||||||
Color.ORANGE);
|
|
||||||
public static RobotFamily GHOST_BLUE = new SvgBasedRobotFamily(
|
|
||||||
"GHOST_BLUE",
|
|
||||||
"/robots/ghost_blue.svg",
|
|
||||||
"/robots/ghost_blue.svg",
|
|
||||||
Color.BLUE);
|
|
||||||
public static RobotFamily GHOST_RED = new SvgBasedRobotFamily(
|
|
||||||
"GHOST_RED",
|
|
||||||
"/robots/ghost_red.svg",
|
|
||||||
"/robots/ghost_red.svg",
|
|
||||||
Color.RED);
|
|
||||||
public static RobotFamily GHOST_PINK = new SvgBasedRobotFamily(
|
|
||||||
"GHOST_PINK",
|
|
||||||
"/robots/ghost_pink.svg",
|
|
||||||
"/robots/ghost_pink.svg",
|
|
||||||
Color.PINK);
|
|
||||||
public static RobotFamily PACMAN = new SvgBasedRobotFamily(
|
|
||||||
"PACMAN",
|
|
||||||
"/robots/pacman.svg",
|
|
||||||
"/robots/pacman.svg",
|
|
||||||
Color.YELLOW,
|
|
||||||
270,
|
|
||||||
270);
|
|
||||||
}
|
|
|
@ -1,378 +0,0 @@
|
||||||
package h01.template;
|
|
||||||
|
|
||||||
import java.awt.Color;
|
|
||||||
import java.awt.Graphics;
|
|
||||||
import java.awt.Graphics2D;
|
|
||||||
import java.awt.Point;
|
|
||||||
import java.awt.geom.Ellipse2D;
|
|
||||||
import java.awt.geom.Rectangle2D;
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.Map;
|
|
||||||
import java.util.Timer;
|
|
||||||
import java.util.TimerTask;
|
|
||||||
|
|
||||||
import fopbot.Coin;
|
|
||||||
import fopbot.ColorProfile;
|
|
||||||
import fopbot.GuiPanel;
|
|
||||||
import fopbot.PaintUtils;
|
|
||||||
import fopbot.Robot;
|
|
||||||
import fopbot.World;
|
|
||||||
import h01.BlueGhost;
|
|
||||||
import h01.OrangeGhost;
|
|
||||||
import h01.Pacman;
|
|
||||||
import h01.PinkGhost;
|
|
||||||
import h01.RedGhost;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* A {@link GameControllerTemplate} controls the game loop and the
|
|
||||||
* {@link Robot}s and checks the win condition.
|
|
||||||
*/
|
|
||||||
public abstract class GameControllerTemplate {
|
|
||||||
/**
|
|
||||||
* The {@link Timer} that controls the game loop.
|
|
||||||
*/
|
|
||||||
private final Timer gameLoopTimer = new Timer();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The {@link GameInputHandler} that handles the input of the user.
|
|
||||||
*/
|
|
||||||
private final GameInputHandler inputHandler = new GameInputHandler();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The total umber of coins in the map.
|
|
||||||
*/
|
|
||||||
protected int totalCoins;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The {@link Robot}s that are controlled by the {@link GameControllerTemplate}.
|
|
||||||
*/
|
|
||||||
protected final ArrayList<Robot> robots = new ArrayList<>();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The {@link Pacman} {@link Robot}.
|
|
||||||
*/
|
|
||||||
protected Robot pacman;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The {@link BlueGhost} {@link Robot}.
|
|
||||||
*/
|
|
||||||
protected Robot blue;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The {@link OrangeGhost} {@link Robot}.
|
|
||||||
*/
|
|
||||||
protected Robot orange;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The {@link PinkGhost} {@link Robot}.
|
|
||||||
*/
|
|
||||||
protected Robot pink;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The {@link RedGhost} {@link Robot}.
|
|
||||||
*/
|
|
||||||
protected Robot red;
|
|
||||||
|
|
||||||
private Point ghostField = new Point(4, 4);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* A {@link Map} that maps a {@link Robot} to the amount of ticks that have
|
|
||||||
* passed since the last tick action.
|
|
||||||
*/
|
|
||||||
private final Map<Robot, Integer> robotTicks = new HashMap<>();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The {@link TimerTask} that is executed every tick.
|
|
||||||
*/
|
|
||||||
private final TimerTask gameLoopTask = new TimerTask() {
|
|
||||||
@Override
|
|
||||||
public void run() {
|
|
||||||
for (final Robot robot : GameControllerTemplate.this.robots) {
|
|
||||||
if (!(robot instanceof final TickBased tb)) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
if (!GameControllerTemplate.this.robotTicks.containsKey(robot)) {
|
|
||||||
GameControllerTemplate.this.robotTicks.put(robot, 0);
|
|
||||||
}
|
|
||||||
if (GameControllerTemplate.this.robotTicks.get(robot) < tb.getUpdateDelay()) {
|
|
||||||
GameControllerTemplate.this.robotTicks.put(robot,
|
|
||||||
GameControllerTemplate.this.robotTicks.get(robot) + 1);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
GameControllerTemplate.this.robotTicks.put(robot, 0);
|
|
||||||
// do tick action
|
|
||||||
if (robot instanceof final Pacman r) {
|
|
||||||
r.handleKeyInput(
|
|
||||||
GameControllerTemplate.this.inputHandler.getDirection());
|
|
||||||
} else if (robot instanceof final Ghost r) {
|
|
||||||
r.doMove();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// check win condition
|
|
||||||
if (checkWinCondition())
|
|
||||||
stopGame(true);
|
|
||||||
if (checkLoseCondition())
|
|
||||||
stopGame(false);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Gets the {@link h01.Pacman} {@link Robot}.
|
|
||||||
*
|
|
||||||
* @return the {@link h01.Pacman} {@link Robot}
|
|
||||||
*/
|
|
||||||
public Robot getPacman() {
|
|
||||||
return pacman;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Gets the {@link BlueGhost} {@link Robot}.
|
|
||||||
*
|
|
||||||
* @return the {@link BlueGhost} {@link Robot}
|
|
||||||
*/
|
|
||||||
public Robot getBlue() {
|
|
||||||
return blue;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Gets the {@link OrangeGhost} {@link Robot}.
|
|
||||||
*
|
|
||||||
* @return the {@link OrangeGhost} {@link Robot}
|
|
||||||
*/
|
|
||||||
public Robot getOrange() {
|
|
||||||
return orange;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Gets the {@link PinkGhost} {@link Robot}.
|
|
||||||
*
|
|
||||||
* @return the {@link PinkGhost} {@link Robot}
|
|
||||||
*/
|
|
||||||
public Robot getPink() {
|
|
||||||
return pink;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Gets the {@link RedGhost} {@link Robot}.
|
|
||||||
*
|
|
||||||
* @return the {@link RedGhost} {@link Robot}
|
|
||||||
*/
|
|
||||||
public Robot getRed() {
|
|
||||||
return red;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Starts the game loop.
|
|
||||||
*/
|
|
||||||
public void startGame() {
|
|
||||||
System.out.println("Starting game...");
|
|
||||||
this.gameLoopTimer.scheduleAtFixedRate(this.gameLoopTask, 0, 200);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Stops the game loop.
|
|
||||||
*/
|
|
||||||
public void stopGame(boolean won) {
|
|
||||||
this.gameLoopTimer.cancel();
|
|
||||||
endscreen(won ? Color.GREEN : Color.RED);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void endscreen(Color color) {
|
|
||||||
World.getGlobalWorld().getGuiPanel().setColorProfile(
|
|
||||||
ColorProfile.DEFAULT.toBuilder()
|
|
||||||
.backgroundColorDark(Color.BLACK)
|
|
||||||
.backgroundColorLight(Color.BLACK)
|
|
||||||
.fieldColorDark(color)
|
|
||||||
.fieldColorLight(color)
|
|
||||||
.innerBorderColorLight(color)
|
|
||||||
.innerBorderColorDark(color)
|
|
||||||
.wallColorDark(Color.BLUE)
|
|
||||||
.wallColorLight(Color.BLUE)
|
|
||||||
.outerBorderColorDark(Color.BLUE)
|
|
||||||
.outerBorderColorLight(Color.BLUE)
|
|
||||||
.coinColorDark(color)
|
|
||||||
.coinColorLight(color)
|
|
||||||
.build());
|
|
||||||
World.getGlobalWorld().getGuiPanel().updateGui();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Sets up the game.
|
|
||||||
*/
|
|
||||||
protected void setup() {
|
|
||||||
setupWorld();
|
|
||||||
setupTheme();
|
|
||||||
setupRobots();
|
|
||||||
totalCoins = 2;// World.getHeight()*World.getWidth()-2;
|
|
||||||
setupCoins(totalCoins);
|
|
||||||
this.inputHandler.install();
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setupTheme() {
|
|
||||||
World.getGlobalWorld().getGuiPanel().setColorProfile(
|
|
||||||
ColorProfile.DEFAULT.toBuilder()
|
|
||||||
.backgroundColorDark(Color.BLACK)
|
|
||||||
.backgroundColorLight(Color.BLACK)
|
|
||||||
.fieldColorDark(Color.BLACK)
|
|
||||||
.fieldColorLight(Color.BLACK)
|
|
||||||
.innerBorderColorLight(Color.BLACK)
|
|
||||||
.innerBorderColorDark(Color.BLACK)
|
|
||||||
.wallColorDark(Color.BLUE)
|
|
||||||
.wallColorLight(Color.BLUE)
|
|
||||||
.outerBorderColorDark(Color.BLUE)
|
|
||||||
.outerBorderColorLight(Color.BLUE)
|
|
||||||
.build());
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Initializes the {@link World} and adds the {@link Robot}s to it.
|
|
||||||
*/
|
|
||||||
public void setupWorld() {
|
|
||||||
World.setSize(9, 9);
|
|
||||||
|
|
||||||
World.getGlobalWorld().setGuiPanel(new GuiPanel(World.getGlobalWorld()) {
|
|
||||||
@Override
|
|
||||||
@SuppressWarnings("UnstableApiUsage")
|
|
||||||
protected void drawCoin(final Coin c, final Graphics g, final boolean evadeRobots) {
|
|
||||||
final var g2d = (Graphics2D) g;
|
|
||||||
final var oldColor = g2d.getColor();
|
|
||||||
g2d.setColor(getColorProfile().getCoinColor());
|
|
||||||
final Rectangle2D fieldBounds = scale(PaintUtils.getFieldBounds(c, world));
|
|
||||||
final double radius = scale(5d);
|
|
||||||
g2d.fill(
|
|
||||||
new Ellipse2D.Double(
|
|
||||||
fieldBounds.getCenterX() - radius,
|
|
||||||
fieldBounds.getCenterY() - radius,
|
|
||||||
2 * radius,
|
|
||||||
2 * radius));
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
World.setDelay(0);
|
|
||||||
World.setVisible(true);
|
|
||||||
World.getGlobalWorld().setDrawTurnedOffRobots(false);
|
|
||||||
|
|
||||||
World.placeVerticalWall(0, 3);
|
|
||||||
World.placeVerticalWall(0, 4);
|
|
||||||
World.placeVerticalWall(0, 5);
|
|
||||||
|
|
||||||
World.placeVerticalWall(1, 2);
|
|
||||||
World.placeVerticalWall(1, 4);
|
|
||||||
World.placeVerticalWall(1, 6);
|
|
||||||
|
|
||||||
World.placeVerticalWall(2, 2);
|
|
||||||
World.placeVerticalWall(2, 3);
|
|
||||||
World.placeVerticalWall(2, 5);
|
|
||||||
World.placeVerticalWall(2, 6);
|
|
||||||
|
|
||||||
World.placeVerticalWall(3, 4);
|
|
||||||
World.placeVerticalWall(3, 7);
|
|
||||||
|
|
||||||
World.placeVerticalWall(4, 4);
|
|
||||||
World.placeVerticalWall(4, 1);
|
|
||||||
|
|
||||||
World.placeVerticalWall(5, 2);
|
|
||||||
World.placeVerticalWall(5, 3);
|
|
||||||
World.placeVerticalWall(5, 5);
|
|
||||||
World.placeVerticalWall(5, 6);
|
|
||||||
|
|
||||||
World.placeVerticalWall(6, 2);
|
|
||||||
World.placeVerticalWall(6, 4);
|
|
||||||
World.placeVerticalWall(6, 6);
|
|
||||||
|
|
||||||
World.placeVerticalWall(7, 3);
|
|
||||||
World.placeVerticalWall(7, 4);
|
|
||||||
World.placeVerticalWall(7, 5);
|
|
||||||
|
|
||||||
World.placeHorizontalWall(1, 0);
|
|
||||||
World.placeHorizontalWall(1, 1);
|
|
||||||
World.placeHorizontalWall(1, 6);
|
|
||||||
World.placeHorizontalWall(1, 7);
|
|
||||||
|
|
||||||
World.placeHorizontalWall(2, 0);
|
|
||||||
World.placeHorizontalWall(2, 7);
|
|
||||||
|
|
||||||
World.placeHorizontalWall(3, 0);
|
|
||||||
World.placeHorizontalWall(3, 2);
|
|
||||||
World.placeHorizontalWall(3, 5);
|
|
||||||
|
|
||||||
World.placeHorizontalWall(4, 1);
|
|
||||||
World.placeHorizontalWall(4, 3);
|
|
||||||
World.placeHorizontalWall(4, 6);
|
|
||||||
|
|
||||||
World.placeHorizontalWall(5, 2);
|
|
||||||
World.placeHorizontalWall(5, 5);
|
|
||||||
World.placeHorizontalWall(5, 7);
|
|
||||||
|
|
||||||
World.placeHorizontalWall(6, 0);
|
|
||||||
World.placeHorizontalWall(6, 7);
|
|
||||||
|
|
||||||
World.placeHorizontalWall(7, 0);
|
|
||||||
World.placeHorizontalWall(7, 1);
|
|
||||||
World.placeHorizontalWall(7, 6);
|
|
||||||
World.placeHorizontalWall(7, 7);
|
|
||||||
|
|
||||||
World.getGlobalWorld().setFieldColor(ghostField.x, ghostField.y, Color.YELLOW);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Adds the {@link Robot}s to the {@link World}.
|
|
||||||
*/
|
|
||||||
public void setupRobots() {
|
|
||||||
this.robots.add(pacman = new Pacman(4, 3));
|
|
||||||
this.robots.add(blue = new BlueGhost(ghostField.x, ghostField.y));
|
|
||||||
this.robots.add(orange = new OrangeGhost(ghostField.x, ghostField.y));
|
|
||||||
this.robots.add(pink = new PinkGhost(ghostField.x, ghostField.y));
|
|
||||||
this.robots.add(red = new RedGhost(ghostField.x, ghostField.y, pacman));
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setupCoins(int numberOfCoins) {
|
|
||||||
if (numberOfCoins > World.getHeight() * World.getWidth() - 2) {
|
|
||||||
throw new IllegalArgumentException("Too many coins for this world size.");
|
|
||||||
}
|
|
||||||
|
|
||||||
ArrayList<Point> Fields = new ArrayList<>();
|
|
||||||
for (int y = 0; y < World.getHeight(); y++) {
|
|
||||||
for (int x = 0; x < World.getWidth(); x++) {
|
|
||||||
if (!((x == ghostField.x && y == ghostField.y) || x == pacman.getX() && y == pacman.getY()))
|
|
||||||
Fields.add(new Point(x, y));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
for (int i = 0; i < numberOfCoins; i++) {
|
|
||||||
int randomIndex = (int) (Math.random() * Fields.size());
|
|
||||||
Point spot = Fields.remove(randomIndex);
|
|
||||||
World.putCoins(spot.x, spot.y, 1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Checks the win condition.
|
|
||||||
*
|
|
||||||
* @return Returns true if the game is won.
|
|
||||||
*/
|
|
||||||
public abstract boolean checkWinCondition();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Checks the lose condition.
|
|
||||||
*
|
|
||||||
* @return Returns true if the game is lost.
|
|
||||||
*/
|
|
||||||
public boolean checkLoseCondition() {
|
|
||||||
boolean gameDone = pacman.getX() == orange.getX() && pacman.getY() == orange.getY();
|
|
||||||
|
|
||||||
if (pacman.getX() == blue.getX() && pacman.getY() == blue.getY()) {
|
|
||||||
gameDone = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (pacman.getX() == pink.getX() && pacman.getY() == pink.getY()) {
|
|
||||||
gameDone = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (pacman.getX() == red.getX() && pacman.getY() == red.getY()) {
|
|
||||||
gameDone = true;
|
|
||||||
}
|
|
||||||
return gameDone;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,108 +0,0 @@
|
||||||
package h01.template;
|
|
||||||
|
|
||||||
import fopbot.Direction;
|
|
||||||
import fopbot.World;
|
|
||||||
|
|
||||||
import java.awt.event.KeyAdapter;
|
|
||||||
import java.awt.event.KeyEvent;
|
|
||||||
import java.util.HashSet;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Map;
|
|
||||||
import java.util.Optional;
|
|
||||||
import java.util.Set;
|
|
||||||
import java.util.concurrent.atomic.AtomicBoolean;
|
|
||||||
import java.util.concurrent.atomic.AtomicInteger;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* A {@link GameInputHandler} handles the input of the user.
|
|
||||||
*/
|
|
||||||
public class GameInputHandler {
|
|
||||||
/**
|
|
||||||
* The {@link fopbot.Direction} to turn to. If {@code -1} the robot should not turn.
|
|
||||||
*/
|
|
||||||
private final AtomicInteger direction = new AtomicInteger(-1);
|
|
||||||
/**
|
|
||||||
* If {@code true} the robot should put a coin on the current field.
|
|
||||||
*/
|
|
||||||
private final AtomicBoolean shouldPutCoins = new AtomicBoolean(false);
|
|
||||||
/**
|
|
||||||
* If {@code true} the robot should pick a coin from the current field.
|
|
||||||
*/
|
|
||||||
private final AtomicBoolean shouldPickCoins = new AtomicBoolean(false);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Parses the inputs to a direction.
|
|
||||||
*
|
|
||||||
* @param keysPressed the keys pressed
|
|
||||||
* @return the direction or null if no direction is pressed
|
|
||||||
*/
|
|
||||||
public static Direction getDirectionFromKeysPressed(final Set<Integer> keysPressed) {
|
|
||||||
final Map<Direction, List<Integer>> directionKeys = Map.of(
|
|
||||||
Direction.UP, List.of(KeyEvent.VK_UP, KeyEvent.VK_W),
|
|
||||||
Direction.LEFT, List.of(KeyEvent.VK_LEFT, KeyEvent.VK_A),
|
|
||||||
Direction.DOWN, List.of(KeyEvent.VK_DOWN, KeyEvent.VK_S),
|
|
||||||
Direction.RIGHT, List.of(KeyEvent.VK_RIGHT, KeyEvent.VK_D)
|
|
||||||
);
|
|
||||||
final Set<Direction> pressedDirections = new HashSet<>();
|
|
||||||
for (final Direction direction : directionKeys.keySet()) {
|
|
||||||
for (final Integer key : directionKeys.get(direction)) {
|
|
||||||
if (keysPressed.contains(key)) {
|
|
||||||
pressedDirections.add(direction);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (pressedDirections.size() == 1) {
|
|
||||||
return pressedDirections.iterator().next();
|
|
||||||
} else {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Installs the {@link GameInputHandler} to the {@link World}.
|
|
||||||
*/
|
|
||||||
public void install() {
|
|
||||||
World.getGlobalWorld().getInputHandler().addKeyListener(new KeyAdapter() {
|
|
||||||
@Override
|
|
||||||
public void keyTyped(final KeyEvent e) {
|
|
||||||
updateKeysPressed();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void keyPressed(final KeyEvent e) {
|
|
||||||
updateKeysPressed();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void keyReleased(final KeyEvent e) {
|
|
||||||
updateKeysPressed();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Updates the {@link #direction}, {@link #shouldPutCoins} and {@link #shouldPickCoins} based on the pressed keys.
|
|
||||||
*/
|
|
||||||
protected void updateKeysPressed() {
|
|
||||||
this.direction.set(
|
|
||||||
Optional.ofNullable(getDirectionFromKeysPressed(World.getGlobalWorld().getInputHandler().getKeysPressed()))
|
|
||||||
.map(Enum::ordinal)
|
|
||||||
.orElse(-1)
|
|
||||||
);
|
|
||||||
this.shouldPickCoins.set(
|
|
||||||
World.getGlobalWorld().getInputHandler().getKeysPressed().contains(java.awt.event.KeyEvent.VK_SPACE)
|
|
||||||
);
|
|
||||||
this.shouldPutCoins.set(
|
|
||||||
World.getGlobalWorld().getInputHandler().getKeysPressed().contains(java.awt.event.KeyEvent.VK_R)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns the current {@link fopbot.Direction} to turn to. If {@code -1} the robot should not turn.
|
|
||||||
*
|
|
||||||
* @return the current {@link fopbot.Direction} to turn to. If {@code -1} the robot should not turn.
|
|
||||||
*/
|
|
||||||
public int getDirection() {
|
|
||||||
return this.direction.get();
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,5 +0,0 @@
|
||||||
package h01.template;
|
|
||||||
|
|
||||||
public interface Ghost {
|
|
||||||
void doMove();
|
|
||||||
}
|
|
|
@ -1,15 +0,0 @@
|
||||||
package h01.template;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* An interface that enables an object to be updated every n-th tick.
|
|
||||||
*/
|
|
||||||
public interface TickBased {
|
|
||||||
/**
|
|
||||||
* Returns the number of ticks between two updates.
|
|
||||||
*
|
|
||||||
* @return the number of ticks between two updates
|
|
||||||
*/
|
|
||||||
default int getUpdateDelay() {
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,55 +0,0 @@
|
||||||
package h01.template;
|
|
||||||
|
|
||||||
import java.util.Random;
|
|
||||||
|
|
||||||
import fopbot.Direction;
|
|
||||||
import fopbot.Robot;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Utility class for the ghosts
|
|
||||||
*/
|
|
||||||
public class Util {
|
|
||||||
|
|
||||||
private static Random rnd = new Random();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns a random integer between min and max (both inclusive)
|
|
||||||
*
|
|
||||||
* @param min the minimum value
|
|
||||||
* @param max the maximum value
|
|
||||||
* @return a random integer between min and max (both inclusive)
|
|
||||||
*/
|
|
||||||
public static int getRandomInteger(int min, int max) {
|
|
||||||
return min + rnd.nextInt(max - min + 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns the direction in which the robot is the closest to the chaser
|
|
||||||
*
|
|
||||||
* @param pacman the robot that is being chased
|
|
||||||
* @param chaser the robot that is chasing
|
|
||||||
* @return the direction in which the robot is the closest to the chaser
|
|
||||||
*/
|
|
||||||
public static Direction furthestDirection(Robot pacman, Robot chaser) {
|
|
||||||
int px = pacman.getX();
|
|
||||||
int py = pacman.getY();
|
|
||||||
int cx = chaser.getX();
|
|
||||||
int cy = chaser.getY();
|
|
||||||
|
|
||||||
int xdelta = Math.abs(px - cx);
|
|
||||||
int ydelta = Math.abs(py - cy);
|
|
||||||
|
|
||||||
if (xdelta > ydelta) {
|
|
||||||
if (cx > px)
|
|
||||||
return Direction.LEFT;
|
|
||||||
else
|
|
||||||
return Direction.RIGHT;
|
|
||||||
} else {
|
|
||||||
if (cy > py)
|
|
||||||
return Direction.DOWN;
|
|
||||||
else
|
|
||||||
return Direction.UP;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
|
@ -1,67 +0,0 @@
|
||||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
|
||||||
<!-- Uploaded to: SVG Repo, www.svgrepo.com, Generator: SVG Repo Mixer Tools -->
|
|
||||||
|
|
||||||
<svg
|
|
||||||
height="800px"
|
|
||||||
width="800px"
|
|
||||||
version="1.1"
|
|
||||||
id="Layer_1"
|
|
||||||
viewBox="0 0 512.001 512.001"
|
|
||||||
xml:space="preserve"
|
|
||||||
sodipodi:docname="ghost_blue.svg"
|
|
||||||
inkscape:version="1.3.2 (091e20e, 2023-11-25, custom)"
|
|
||||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
|
||||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
|
||||||
xmlns="http://www.w3.org/2000/svg"
|
|
||||||
xmlns:svg="http://www.w3.org/2000/svg"><defs
|
|
||||||
id="defs8" /><sodipodi:namedview
|
|
||||||
id="namedview8"
|
|
||||||
pagecolor="#505050"
|
|
||||||
bordercolor="#eeeeee"
|
|
||||||
borderopacity="1"
|
|
||||||
inkscape:showpageshadow="0"
|
|
||||||
inkscape:pageopacity="0"
|
|
||||||
inkscape:pagecheckerboard="0"
|
|
||||||
inkscape:deskcolor="#d1d1d1"
|
|
||||||
inkscape:zoom="1.49875"
|
|
||||||
inkscape:cx="399.33278"
|
|
||||||
inkscape:cy="400"
|
|
||||||
inkscape:window-width="2560"
|
|
||||||
inkscape:window-height="1377"
|
|
||||||
inkscape:window-x="-8"
|
|
||||||
inkscape:window-y="-8"
|
|
||||||
inkscape:window-maximized="1"
|
|
||||||
inkscape:current-layer="Layer_1" />
|
|
||||||
<path
|
|
||||||
style="fill:#555bff;fill-opacity:1"
|
|
||||||
d="M248.399,0.135C135.421,4.152,47.514,100.436,47.514,213.484V508.8c0,2.792,3.432,4.127,5.319,2.069 l57.191-62.39c3.756-4.098,10.216-4.098,13.971,0l55.336,60.365c3.858,4.209,10.493,4.209,14.35,0l55.334-60.365 c3.756-4.098,10.216-4.098,13.971,0l55.334,60.365c3.858,4.209,10.493,4.209,14.35,0l55.336-60.365 c3.756-4.098,10.216-4.098,13.971,0l57.191,62.39c1.887,2.059,5.319,0.724,5.319-2.069V208.486 C464.489,90.819,367.009-4.082,248.399,0.135z"
|
|
||||||
id="path1" />
|
|
||||||
<path
|
|
||||||
style="fill:#325ca9;fill-opacity:1"
|
|
||||||
d="M151.758,227.632c0-107.205,79.072-199.275,183.593-211.938 C308.687,4.707,279.273-0.963,248.399,0.135C135.421,4.152,47.514,100.436,47.514,213.484V508.8c0,2.792,3.432,4.127,5.319,2.069 l57.191-62.39c3.755-4.098,10.216-4.098,13.971,0l27.762,30.285V227.632H151.758z"
|
|
||||||
id="path2" />
|
|
||||||
<path
|
|
||||||
style="fill:#FFFFFF;"
|
|
||||||
d="M186.385,303.255L186.385,303.255c-31.001,0-56.132-25.131-56.132-56.132v-20.412 c0-31.001,25.131-56.132,56.132-56.132l0,0c31.001,0,56.132,25.131,56.132,56.132v20.412 C242.515,278.124,217.385,303.255,186.385,303.255z"
|
|
||||||
id="path3" />
|
|
||||||
<path
|
|
||||||
style="fill:#E4EAF6;"
|
|
||||||
d="M217.002,293.049c-31.001,0-56.132-25.131-56.132-56.132v-20.412 c0-18.952,9.419-35.676,23.803-45.839c-30.201,0.912-54.421,25.621-54.421,56.045v20.412c0,31.001,25.131,56.132,56.132,56.132 c12.048,0,23.184-3.831,32.327-10.292C218.139,292.98,217.579,293.049,217.002,293.049z"
|
|
||||||
id="path4" />
|
|
||||||
<path
|
|
||||||
style="fill:#82B9FF;"
|
|
||||||
d="M201.693,262.431L201.693,262.431c-11.273,0-20.412-9.138-20.412-20.412v-10.205 c0-11.273,9.138-20.412,20.412-20.412l0,0c11.273,0,20.412,9.138,20.412,20.412v10.205 C222.105,253.294,212.966,262.431,201.693,262.431z"
|
|
||||||
id="path5" />
|
|
||||||
<path
|
|
||||||
style="fill:#FFFFFF;"
|
|
||||||
d="M325.619,303.255L325.619,303.255c-31.001,0-56.132-25.131-56.132-56.132v-20.412 c0-31.001,25.131-56.132,56.132-56.132l0,0c31.001,0,56.132,25.131,56.132,56.132v20.412 C381.75,278.124,356.619,303.255,325.619,303.255z"
|
|
||||||
id="path6" />
|
|
||||||
<path
|
|
||||||
style="fill:#E4EAF6;"
|
|
||||||
d="M356.236,293.049c-31.001,0-56.132-25.131-56.132-56.132v-20.412 c0-18.952,9.419-35.676,23.804-45.839c-30.201,0.912-54.421,25.621-54.421,56.045v20.412c0,31.001,25.131,56.132,56.132,56.132 c12.048,0,23.184-3.831,32.327-10.292C357.374,292.98,356.814,293.049,356.236,293.049z"
|
|
||||||
id="path7" />
|
|
||||||
<path
|
|
||||||
style="fill:#82B9FF;"
|
|
||||||
d="M340.927,262.431L340.927,262.431c-11.273,0-20.412-9.138-20.412-20.412v-10.205 c0-11.273,9.138-20.412,20.412-20.412l0,0c11.273,0,20.412,9.138,20.412,20.412v10.205 C361.339,253.294,352.201,262.431,340.927,262.431z"
|
|
||||||
id="path8" />
|
|
||||||
</svg>
|
|
Before Width: | Height: | Size: 3.6 KiB |
|
@ -1,31 +0,0 @@
|
||||||
<?xml version="1.0" encoding="iso-8859-1"?>
|
|
||||||
<!-- Uploaded to: SVG Repo, www.svgrepo.com, Generator: SVG Repo Mixer Tools -->
|
|
||||||
<svg height="800px" width="800px" version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"
|
|
||||||
viewBox="0 0 512.001 512.001" xml:space="preserve">
|
|
||||||
<path style="fill:#FFA05A;" d="M248.399,0.135C135.421,4.152,47.514,100.436,47.514,213.484V508.8c0,2.792,3.432,4.127,5.319,2.069
|
|
||||||
l57.191-62.39c3.756-4.098,10.216-4.098,13.971,0l55.336,60.365c3.858,4.209,10.493,4.209,14.35,0l55.334-60.365
|
|
||||||
c3.756-4.098,10.216-4.098,13.971,0l55.334,60.365c3.858,4.209,10.493,4.209,14.35,0l55.336-60.365
|
|
||||||
c3.756-4.098,10.216-4.098,13.971,0l57.191,62.39c1.887,2.059,5.319,0.724,5.319-2.069V208.486
|
|
||||||
C464.489,90.819,367.009-4.082,248.399,0.135z"/>
|
|
||||||
<path style="fill:#F08C46;" d="M151.758,227.632c0-107.205,79.072-199.275,183.593-211.938
|
|
||||||
C308.687,4.707,279.273-0.963,248.399,0.135C135.421,4.152,47.514,100.436,47.514,213.484V508.8c0,2.792,3.432,4.127,5.319,2.069
|
|
||||||
l57.191-62.39c3.755-4.098,10.216-4.098,13.971,0l27.762,30.285V227.632H151.758z"/>
|
|
||||||
<path style="fill:#FFFFFF;" d="M186.385,303.255L186.385,303.255c-31.001,0-56.132-25.131-56.132-56.132v-20.412
|
|
||||||
c0-31.001,25.131-56.132,56.132-56.132l0,0c31.001,0,56.132,25.131,56.132,56.132v20.412
|
|
||||||
C242.515,278.124,217.385,303.255,186.385,303.255z"/>
|
|
||||||
<path style="fill:#E4EAF6;" d="M217.002,293.049c-31.001,0-56.132-25.131-56.132-56.132v-20.412
|
|
||||||
c0-18.952,9.419-35.676,23.803-45.839c-30.201,0.912-54.421,25.621-54.421,56.045v20.412c0,31.001,25.131,56.132,56.132,56.132
|
|
||||||
c12.048,0,23.184-3.831,32.327-10.292C218.139,292.98,217.579,293.049,217.002,293.049z"/>
|
|
||||||
<path style="fill:#82B9FF;" d="M201.693,262.431L201.693,262.431c-11.273,0-20.412-9.138-20.412-20.412v-10.205
|
|
||||||
c0-11.273,9.138-20.412,20.412-20.412l0,0c11.273,0,20.412,9.138,20.412,20.412v10.205
|
|
||||||
C222.105,253.294,212.966,262.431,201.693,262.431z"/>
|
|
||||||
<path style="fill:#FFFFFF;" d="M325.619,303.255L325.619,303.255c-31.001,0-56.132-25.131-56.132-56.132v-20.412
|
|
||||||
c0-31.001,25.131-56.132,56.132-56.132l0,0c31.001,0,56.132,25.131,56.132,56.132v20.412
|
|
||||||
C381.75,278.124,356.619,303.255,325.619,303.255z"/>
|
|
||||||
<path style="fill:#E4EAF6;" d="M356.236,293.049c-31.001,0-56.132-25.131-56.132-56.132v-20.412
|
|
||||||
c0-18.952,9.419-35.676,23.804-45.839c-30.201,0.912-54.421,25.621-54.421,56.045v20.412c0,31.001,25.131,56.132,56.132,56.132
|
|
||||||
c12.048,0,23.184-3.831,32.327-10.292C357.374,292.98,356.814,293.049,356.236,293.049z"/>
|
|
||||||
<path style="fill:#82B9FF;" d="M340.927,262.431L340.927,262.431c-11.273,0-20.412-9.138-20.412-20.412v-10.205
|
|
||||||
c0-11.273,9.138-20.412,20.412-20.412l0,0c11.273,0,20.412,9.138,20.412,20.412v10.205
|
|
||||||
C361.339,253.294,352.201,262.431,340.927,262.431z"/>
|
|
||||||
</svg>
|
|
Before Width: | Height: | Size: 2.6 KiB |
|
@ -1,67 +0,0 @@
|
||||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
|
||||||
<!-- Uploaded to: SVG Repo, www.svgrepo.com, Generator: SVG Repo Mixer Tools -->
|
|
||||||
|
|
||||||
<svg
|
|
||||||
height="800px"
|
|
||||||
width="800px"
|
|
||||||
version="1.1"
|
|
||||||
id="Layer_1"
|
|
||||||
viewBox="0 0 512.001 512.001"
|
|
||||||
xml:space="preserve"
|
|
||||||
sodipodi:docname="ghost_pink.svg"
|
|
||||||
inkscape:version="1.3.2 (091e20e, 2023-11-25, custom)"
|
|
||||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
|
||||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
|
||||||
xmlns="http://www.w3.org/2000/svg"
|
|
||||||
xmlns:svg="http://www.w3.org/2000/svg"><defs
|
|
||||||
id="defs8" /><sodipodi:namedview
|
|
||||||
id="namedview8"
|
|
||||||
pagecolor="#505050"
|
|
||||||
bordercolor="#eeeeee"
|
|
||||||
borderopacity="1"
|
|
||||||
inkscape:showpageshadow="0"
|
|
||||||
inkscape:pageopacity="0"
|
|
||||||
inkscape:pagecheckerboard="0"
|
|
||||||
inkscape:deskcolor="#d1d1d1"
|
|
||||||
inkscape:zoom="1.49875"
|
|
||||||
inkscape:cx="399.33278"
|
|
||||||
inkscape:cy="400"
|
|
||||||
inkscape:window-width="2560"
|
|
||||||
inkscape:window-height="1377"
|
|
||||||
inkscape:window-x="-8"
|
|
||||||
inkscape:window-y="-8"
|
|
||||||
inkscape:window-maximized="1"
|
|
||||||
inkscape:current-layer="Layer_1" />
|
|
||||||
<path
|
|
||||||
style="fill:#e555ff;fill-opacity:1"
|
|
||||||
d="M248.399,0.135C135.421,4.152,47.514,100.436,47.514,213.484V508.8c0,2.792,3.432,4.127,5.319,2.069 l57.191-62.39c3.756-4.098,10.216-4.098,13.971,0l55.336,60.365c3.858,4.209,10.493,4.209,14.35,0l55.334-60.365 c3.756-4.098,10.216-4.098,13.971,0l55.334,60.365c3.858,4.209,10.493,4.209,14.35,0l55.336-60.365 c3.756-4.098,10.216-4.098,13.971,0l57.191,62.39c1.887,2.059,5.319,0.724,5.319-2.069V208.486 C464.489,90.819,367.009-4.082,248.399,0.135z"
|
|
||||||
id="path1" />
|
|
||||||
<path
|
|
||||||
style="fill:#c53bd0;fill-opacity:1"
|
|
||||||
d="M151.758,227.632c0-107.205,79.072-199.275,183.593-211.938 C308.687,4.707,279.273-0.963,248.399,0.135C135.421,4.152,47.514,100.436,47.514,213.484V508.8c0,2.792,3.432,4.127,5.319,2.069 l57.191-62.39c3.755-4.098,10.216-4.098,13.971,0l27.762,30.285V227.632H151.758z"
|
|
||||||
id="path2" />
|
|
||||||
<path
|
|
||||||
style="fill:#FFFFFF;"
|
|
||||||
d="M186.385,303.255L186.385,303.255c-31.001,0-56.132-25.131-56.132-56.132v-20.412 c0-31.001,25.131-56.132,56.132-56.132l0,0c31.001,0,56.132,25.131,56.132,56.132v20.412 C242.515,278.124,217.385,303.255,186.385,303.255z"
|
|
||||||
id="path3" />
|
|
||||||
<path
|
|
||||||
style="fill:#E4EAF6;"
|
|
||||||
d="M217.002,293.049c-31.001,0-56.132-25.131-56.132-56.132v-20.412 c0-18.952,9.419-35.676,23.803-45.839c-30.201,0.912-54.421,25.621-54.421,56.045v20.412c0,31.001,25.131,56.132,56.132,56.132 c12.048,0,23.184-3.831,32.327-10.292C218.139,292.98,217.579,293.049,217.002,293.049z"
|
|
||||||
id="path4" />
|
|
||||||
<path
|
|
||||||
style="fill:#82B9FF;"
|
|
||||||
d="M201.693,262.431L201.693,262.431c-11.273,0-20.412-9.138-20.412-20.412v-10.205 c0-11.273,9.138-20.412,20.412-20.412l0,0c11.273,0,20.412,9.138,20.412,20.412v10.205 C222.105,253.294,212.966,262.431,201.693,262.431z"
|
|
||||||
id="path5" />
|
|
||||||
<path
|
|
||||||
style="fill:#FFFFFF;"
|
|
||||||
d="M325.619,303.255L325.619,303.255c-31.001,0-56.132-25.131-56.132-56.132v-20.412 c0-31.001,25.131-56.132,56.132-56.132l0,0c31.001,0,56.132,25.131,56.132,56.132v20.412 C381.75,278.124,356.619,303.255,325.619,303.255z"
|
|
||||||
id="path6" />
|
|
||||||
<path
|
|
||||||
style="fill:#E4EAF6;"
|
|
||||||
d="M356.236,293.049c-31.001,0-56.132-25.131-56.132-56.132v-20.412 c0-18.952,9.419-35.676,23.804-45.839c-30.201,0.912-54.421,25.621-54.421,56.045v20.412c0,31.001,25.131,56.132,56.132,56.132 c12.048,0,23.184-3.831,32.327-10.292C357.374,292.98,356.814,293.049,356.236,293.049z"
|
|
||||||
id="path7" />
|
|
||||||
<path
|
|
||||||
style="fill:#82B9FF;"
|
|
||||||
d="M340.927,262.431L340.927,262.431c-11.273,0-20.412-9.138-20.412-20.412v-10.205 c0-11.273,9.138-20.412,20.412-20.412l0,0c11.273,0,20.412,9.138,20.412,20.412v10.205 C361.339,253.294,352.201,262.431,340.927,262.431z"
|
|
||||||
id="path8" />
|
|
||||||
</svg>
|
|
Before Width: | Height: | Size: 3.6 KiB |
|
@ -1,67 +0,0 @@
|
||||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
|
||||||
<!-- Uploaded to: SVG Repo, www.svgrepo.com, Generator: SVG Repo Mixer Tools -->
|
|
||||||
|
|
||||||
<svg
|
|
||||||
height="800px"
|
|
||||||
width="800px"
|
|
||||||
version="1.1"
|
|
||||||
id="Layer_1"
|
|
||||||
viewBox="0 0 512.001 512.001"
|
|
||||||
xml:space="preserve"
|
|
||||||
sodipodi:docname="ghost_red.svg"
|
|
||||||
inkscape:version="1.3.2 (091e20e, 2023-11-25, custom)"
|
|
||||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
|
||||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
|
||||||
xmlns="http://www.w3.org/2000/svg"
|
|
||||||
xmlns:svg="http://www.w3.org/2000/svg"><defs
|
|
||||||
id="defs8" /><sodipodi:namedview
|
|
||||||
id="namedview8"
|
|
||||||
pagecolor="#505050"
|
|
||||||
bordercolor="#eeeeee"
|
|
||||||
borderopacity="1"
|
|
||||||
inkscape:showpageshadow="0"
|
|
||||||
inkscape:pageopacity="0"
|
|
||||||
inkscape:pagecheckerboard="0"
|
|
||||||
inkscape:deskcolor="#d1d1d1"
|
|
||||||
inkscape:zoom="1.49875"
|
|
||||||
inkscape:cx="399.33278"
|
|
||||||
inkscape:cy="400"
|
|
||||||
inkscape:window-width="2560"
|
|
||||||
inkscape:window-height="1377"
|
|
||||||
inkscape:window-x="-8"
|
|
||||||
inkscape:window-y="-8"
|
|
||||||
inkscape:window-maximized="1"
|
|
||||||
inkscape:current-layer="Layer_1" />
|
|
||||||
<path
|
|
||||||
style="fill:#ff4040;fill-opacity:1"
|
|
||||||
d="M248.399,0.135C135.421,4.152,47.514,100.436,47.514,213.484V508.8c0,2.792,3.432,4.127,5.319,2.069 l57.191-62.39c3.756-4.098,10.216-4.098,13.971,0l55.336,60.365c3.858,4.209,10.493,4.209,14.35,0l55.334-60.365 c3.756-4.098,10.216-4.098,13.971,0l55.334,60.365c3.858,4.209,10.493,4.209,14.35,0l55.336-60.365 c3.756-4.098,10.216-4.098,13.971,0l57.191,62.39c1.887,2.059,5.319,0.724,5.319-2.069V208.486 C464.489,90.819,367.009-4.082,248.399,0.135z"
|
|
||||||
id="path1" />
|
|
||||||
<path
|
|
||||||
style="fill:#d03b3b;fill-opacity:1"
|
|
||||||
d="M151.758,227.632c0-107.205,79.072-199.275,183.593-211.938 C308.687,4.707,279.273-0.963,248.399,0.135C135.421,4.152,47.514,100.436,47.514,213.484V508.8c0,2.792,3.432,4.127,5.319,2.069 l57.191-62.39c3.755-4.098,10.216-4.098,13.971,0l27.762,30.285V227.632H151.758z"
|
|
||||||
id="path2" />
|
|
||||||
<path
|
|
||||||
style="fill:#FFFFFF;"
|
|
||||||
d="M186.385,303.255L186.385,303.255c-31.001,0-56.132-25.131-56.132-56.132v-20.412 c0-31.001,25.131-56.132,56.132-56.132l0,0c31.001,0,56.132,25.131,56.132,56.132v20.412 C242.515,278.124,217.385,303.255,186.385,303.255z"
|
|
||||||
id="path3" />
|
|
||||||
<path
|
|
||||||
style="fill:#E4EAF6;"
|
|
||||||
d="M217.002,293.049c-31.001,0-56.132-25.131-56.132-56.132v-20.412 c0-18.952,9.419-35.676,23.803-45.839c-30.201,0.912-54.421,25.621-54.421,56.045v20.412c0,31.001,25.131,56.132,56.132,56.132 c12.048,0,23.184-3.831,32.327-10.292C218.139,292.98,217.579,293.049,217.002,293.049z"
|
|
||||||
id="path4" />
|
|
||||||
<path
|
|
||||||
style="fill:#82B9FF;"
|
|
||||||
d="M201.693,262.431L201.693,262.431c-11.273,0-20.412-9.138-20.412-20.412v-10.205 c0-11.273,9.138-20.412,20.412-20.412l0,0c11.273,0,20.412,9.138,20.412,20.412v10.205 C222.105,253.294,212.966,262.431,201.693,262.431z"
|
|
||||||
id="path5" />
|
|
||||||
<path
|
|
||||||
style="fill:#FFFFFF;"
|
|
||||||
d="M325.619,303.255L325.619,303.255c-31.001,0-56.132-25.131-56.132-56.132v-20.412 c0-31.001,25.131-56.132,56.132-56.132l0,0c31.001,0,56.132,25.131,56.132,56.132v20.412 C381.75,278.124,356.619,303.255,325.619,303.255z"
|
|
||||||
id="path6" />
|
|
||||||
<path
|
|
||||||
style="fill:#E4EAF6;"
|
|
||||||
d="M356.236,293.049c-31.001,0-56.132-25.131-56.132-56.132v-20.412 c0-18.952,9.419-35.676,23.804-45.839c-30.201,0.912-54.421,25.621-54.421,56.045v20.412c0,31.001,25.131,56.132,56.132,56.132 c12.048,0,23.184-3.831,32.327-10.292C357.374,292.98,356.814,293.049,356.236,293.049z"
|
|
||||||
id="path7" />
|
|
||||||
<path
|
|
||||||
style="fill:#82B9FF;"
|
|
||||||
d="M340.927,262.431L340.927,262.431c-11.273,0-20.412-9.138-20.412-20.412v-10.205 c0-11.273,9.138-20.412,20.412-20.412l0,0c11.273,0,20.412,9.138,20.412,20.412v10.205 C361.339,253.294,352.201,262.431,340.927,262.431z"
|
|
||||||
id="path8" />
|
|
||||||
</svg>
|
|
Before Width: | Height: | Size: 3.6 KiB |
|
@ -1,61 +0,0 @@
|
||||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
|
||||||
<!-- Uploaded to: SVG Repo, www.svgrepo.com, Generator: SVG Repo Mixer Tools -->
|
|
||||||
|
|
||||||
<svg
|
|
||||||
height="800px"
|
|
||||||
width="800px"
|
|
||||||
version="1.1"
|
|
||||||
id="Layer_1"
|
|
||||||
viewBox="0 0 512 512"
|
|
||||||
xml:space="preserve"
|
|
||||||
sodipodi:docname="gamer-svgrepo-com.svg"
|
|
||||||
inkscape:version="1.3.2 (091e20e, 2023-11-25, custom)"
|
|
||||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
|
||||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
|
||||||
xmlns="http://www.w3.org/2000/svg"
|
|
||||||
xmlns:svg="http://www.w3.org/2000/svg"><defs
|
|
||||||
id="defs6" /><sodipodi:namedview
|
|
||||||
id="namedview6"
|
|
||||||
pagecolor="#505050"
|
|
||||||
bordercolor="#eeeeee"
|
|
||||||
borderopacity="1"
|
|
||||||
inkscape:showpageshadow="0"
|
|
||||||
inkscape:pageopacity="0"
|
|
||||||
inkscape:pagecheckerboard="0"
|
|
||||||
inkscape:deskcolor="#d1d1d1"
|
|
||||||
inkscape:zoom="1.49875"
|
|
||||||
inkscape:cx="399.66639"
|
|
||||||
inkscape:cy="400"
|
|
||||||
inkscape:window-width="2560"
|
|
||||||
inkscape:window-height="1377"
|
|
||||||
inkscape:window-x="-8"
|
|
||||||
inkscape:window-y="-8"
|
|
||||||
inkscape:window-maximized="1"
|
|
||||||
inkscape:current-layer="Layer_1" />
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
<g
|
|
||||||
id="g6"
|
|
||||||
transform="translate(83.607539,4.4703637e-4)"><path
|
|
||||||
style="fill:#ffd782"
|
|
||||||
d="m 209.638,244.628 129.736,-95.594 c 6.241,-4.599 7.204,-13.545 2.155,-19.428 C 301.171,82.587 238.774,55.049 170.311,63.221 81.862,73.778 10.999,145.353 1.223,233.893 c -12.937,117.155 78.443,216.313 192.983,216.313 58.996,0 111.782,-26.358 147.389,-67.889 5.021,-5.856 3.992,-14.775 -2.218,-19.35 L 209.638,267.37 c -7.661,-5.645 -7.661,-17.096 0,-22.742 z"
|
|
||||||
id="path1" /><path
|
|
||||||
style="fill:#ffc36e"
|
|
||||||
d="M 255.491,406.068 C 140.951,406.068 49.571,306.911 62.507,189.755 67.182,147.409 85.94,109.043 113.803,79.279 53.119,107.021 8.797,165.293 1.223,233.892 c -12.937,117.156 78.443,216.314 192.983,216.314 55.956,0 106.298,-23.738 141.721,-61.62 -24.506,11.197 -51.724,17.482 -80.436,17.482 z"
|
|
||||||
id="path2" /><circle
|
|
||||||
style="fill:#5b5d6e"
|
|
||||||
cx="220.689"
|
|
||||||
cy="150.06799"
|
|
||||||
r="26.483"
|
|
||||||
id="circle5" /><path
|
|
||||||
style="fill:#464655"
|
|
||||||
d="m 231.724,163.31 c -13.407,0 -24.276,-10.869 -24.276,-24.276 0,-5.134 1.614,-9.88 4.335,-13.802 -10.222,3.669 -17.577,13.351 -17.577,24.836 0,14.626 11.857,26.483 26.483,26.483 11.486,0 21.167,-7.354 24.836,-17.577 -3.921,2.72 -8.667,4.336 -13.801,4.336 z"
|
|
||||||
id="path6" /></g>
|
|
||||||
</svg>
|
|
Before Width: | Height: | Size: 2.3 KiB |
1
solution/H01/src/test
Symbolic link
|
@ -0,0 +1 @@
|
||||||
|
/home/osh/Desktop/FOP-2425-Marathon/H01/src/test
|
|
@ -1,16 +0,0 @@
|
||||||
package h01;
|
|
||||||
|
|
||||||
import org.junit.jupiter.api.Test;
|
|
||||||
|
|
||||||
import static org.junit.jupiter.api.Assertions.*;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* An example JUnit test class.
|
|
||||||
*/
|
|
||||||
public class ExampleJUnitTest {
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testAddition() {
|
|
||||||
assertEquals(2, 1 + 1);
|
|
||||||
}
|
|
||||||
}
|
|
1
solution/H02/src/main
Symbolic link
|
@ -0,0 +1 @@
|
||||||
|
/home/osh/Desktop/FOP-2425-Marathon/H02/src/main
|
|
@ -1,388 +0,0 @@
|
||||||
package h02;
|
|
||||||
|
|
||||||
import fopbot.Direction;
|
|
||||||
import fopbot.Robot;
|
|
||||||
import fopbot.RobotFamily;
|
|
||||||
import fopbot.World;
|
|
||||||
import h02.template.InputHandler;
|
|
||||||
import org.tudalgo.algoutils.student.annotation.DoNotTouch;
|
|
||||||
import org.tudalgo.algoutils.student.annotation.StudentImplementationRequired;
|
|
||||||
|
|
||||||
import java.util.Optional;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The {@link FourWins} class represents the main class of the FourWins game.
|
|
||||||
*/
|
|
||||||
public class FourWins {
|
|
||||||
private final InputHandler inputHandler = new InputHandler(this);
|
|
||||||
/**
|
|
||||||
* The width of the game board.
|
|
||||||
*/
|
|
||||||
private final int width;
|
|
||||||
/**
|
|
||||||
* The height of the game board.
|
|
||||||
*/
|
|
||||||
private final int height;
|
|
||||||
/**
|
|
||||||
* Indicates whether the game has finished.
|
|
||||||
*/
|
|
||||||
@SuppressWarnings({"FieldMayBeFinal", "FieldCanBeLocal"})
|
|
||||||
private boolean finished = false;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Creates a new {@link FourWins} instance with the given width and height.
|
|
||||||
*
|
|
||||||
* @param width the width of the game board
|
|
||||||
* @param height the height of the game board
|
|
||||||
*/
|
|
||||||
FourWins(final int width, final int height) {
|
|
||||||
this.width = width;
|
|
||||||
this.height = height;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Starts the game by setting up the world and executing the game loop.
|
|
||||||
*/
|
|
||||||
void startGame() {
|
|
||||||
setupWorld();
|
|
||||||
gameLoop();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Sets up the world and installs the {@link InputHandler}.
|
|
||||||
*/
|
|
||||||
void setupWorld() {
|
|
||||||
World.setSize(width, height);
|
|
||||||
World.setDelay(10);
|
|
||||||
World.setVisible(true);
|
|
||||||
inputHandler.install();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Validates if a given column index is within the bounds of the game board and not fully occupied.
|
|
||||||
*
|
|
||||||
* @param column The column index to validate.
|
|
||||||
* @param stones 2D array representing the game board, where each cell contains a RobotFamily color indicating the
|
|
||||||
* player that has placed a stone in that position.
|
|
||||||
* @return true if the column is within bounds and has at least one unoccupied cell; false otherwise.
|
|
||||||
*/
|
|
||||||
@StudentImplementationRequired("H2.2.1")
|
|
||||||
public static boolean validateInput(final int column, final RobotFamily[][] stones) {
|
|
||||||
return column >= 0 && column < World.getWidth() && stones[World.getHeight() - 1][column] == null;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Calculates the next unoccupied row index in the specified column. This row index is the next destination for a
|
|
||||||
* falling stone.
|
|
||||||
*
|
|
||||||
* @param column The column index where the stone is to be dropped.
|
|
||||||
* @param stones 2D array representing the game board, where each cell contains a RobotFamily object indicating the
|
|
||||||
* player that has placed a stone in that position.
|
|
||||||
* @return Index of the next unoccupied row index in the specified column.
|
|
||||||
*/
|
|
||||||
@StudentImplementationRequired("H2.2.2")
|
|
||||||
public static int getDestinationRow(final int column, final RobotFamily[][] stones) {
|
|
||||||
for (int row = 0; row < stones.length; row++) {
|
|
||||||
if (stones[row][column] == null) {
|
|
||||||
return row;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Drops a stone into the specified column of the game board, simulating a falling animation. This method gets the
|
|
||||||
* destination row for the stone in the specified column with the `getDestinationRow` method. It creates a new Robot
|
|
||||||
* instance to represent the stone with the currentPlayer's RobotFamily in the given column and the destination row.
|
|
||||||
* After that it simulates the stone's fall by decrementing its position until it reaches the destination row. Once
|
|
||||||
* the stone reaches its destination, the method updates the stones array (a 2D array of RobotFamily colors) to
|
|
||||||
* mark the slot as occupied by the currentPlayer.
|
|
||||||
*
|
|
||||||
* @param column The column index where the stone is to be dropped.
|
|
||||||
* @param stones 2D array representing the game board, where each cell contains a RobotFamily object
|
|
||||||
* indicating the player that has placed a stone in that position.
|
|
||||||
* @param currentPlayer The RobotFamily object representing the current player dropping the stone.
|
|
||||||
*/
|
|
||||||
@StudentImplementationRequired("H2.2.2")
|
|
||||||
public static void dropStone(final int column, final RobotFamily[][] stones, final RobotFamily currentPlayer) {
|
|
||||||
// spawn stone
|
|
||||||
final Robot stone = new Robot(column, World.getHeight() - 1, Direction.DOWN, 0, currentPlayer);
|
|
||||||
|
|
||||||
// let stone fall
|
|
||||||
final int row = getDestinationRow(column, stones);
|
|
||||||
for (int currentRow = World.getHeight() - 1; currentRow > row; currentRow--) {
|
|
||||||
stone.move();
|
|
||||||
}
|
|
||||||
|
|
||||||
// turn stone up
|
|
||||||
stone.turnLeft();
|
|
||||||
stone.turnLeft();
|
|
||||||
|
|
||||||
// set slot as occupied
|
|
||||||
stones[row][column] = currentPlayer;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Checks if the current player has won by any condition. The conditions can be a horizontal, vertical, diagonal, or
|
|
||||||
* anti-diagonal line of at least four stones.
|
|
||||||
*
|
|
||||||
* @param stones 2D array representing the game board, where each cell contains a RobotFamily color
|
|
||||||
* indicating the player that has placed a stone in that position.
|
|
||||||
* @param currentPlayer The RobotFamily color representing the current player to check for a win.
|
|
||||||
* @return true if the current player has formed a horizontal line of at least four stones; false otherwise.
|
|
||||||
*/
|
|
||||||
@StudentImplementationRequired("H2.2.3")
|
|
||||||
public static boolean testWinConditions(final RobotFamily[][] stones, final RobotFamily currentPlayer) {
|
|
||||||
return testWinVertical(stones, currentPlayer)
|
|
||||||
|| testWinHorizontal(stones, currentPlayer)
|
|
||||||
|| testWinDiagonal(stones, currentPlayer);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Checks if the current player has won by forming a horizontal line of at least consecutive four stones.
|
|
||||||
*
|
|
||||||
* @param stones 2D array representing the game board, where each cell contains a RobotFamily color
|
|
||||||
* indicating the player that has placed a stone in that position.
|
|
||||||
* @param currentPlayer The RobotFamily color representing the current player to check for a win.
|
|
||||||
* @return true if the current player has formed a horizontal line of at least four stones; false otherwise.
|
|
||||||
*/
|
|
||||||
@StudentImplementationRequired("H2.2.3")
|
|
||||||
public static boolean testWinHorizontal(final RobotFamily[][] stones, final RobotFamily currentPlayer) {
|
|
||||||
for (int row = 0; row < World.getHeight(); row++) {
|
|
||||||
int stoneCount = 0;
|
|
||||||
for (int column = 0; column < World.getWidth(); column++) {
|
|
||||||
stoneCount = stones[row][column] == currentPlayer ? stoneCount + 1 : 0;
|
|
||||||
if (stoneCount >= 4) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Checks if the current player has won by forming a vertical line of at least consecutive four stones.
|
|
||||||
*
|
|
||||||
* @param stones 2D array representing the game board, where each cell contains a RobotFamily color
|
|
||||||
* indicating the player that has placed a stone in that position.
|
|
||||||
* @param currentPlayer The RobotFamily color representing the current player to check for a win.
|
|
||||||
* @return true if the current player has formed a vertical line of at least four stones; false otherwise.
|
|
||||||
*/
|
|
||||||
@StudentImplementationRequired("H2.2.3")
|
|
||||||
public static boolean testWinVertical(final RobotFamily[][] stones, final RobotFamily currentPlayer) {
|
|
||||||
for (int column = 0; column < World.getWidth(); column++) {
|
|
||||||
int stoneCount = 0;
|
|
||||||
for (int row = 0; row < World.getHeight(); row++) {
|
|
||||||
stoneCount = stones[row][column] == currentPlayer ? stoneCount + 1 : 0;
|
|
||||||
if (stoneCount >= 4) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Checks if the current player has won by forming a diagonal line of at least consecutive four stones.
|
|
||||||
*
|
|
||||||
* @param stones 2D array representing the game board, where each cell contains a RobotFamily color
|
|
||||||
* indicating the player that has placed a stone in that position.
|
|
||||||
* @param currentPlayer The RobotFamily color representing the current player to check for a win.
|
|
||||||
* @return true if the current player has formed a diagonal line of at least four stones; false otherwise.
|
|
||||||
*/
|
|
||||||
@DoNotTouch
|
|
||||||
public static boolean testWinDiagonal(final RobotFamily[][] stones, final RobotFamily currentPlayer) {
|
|
||||||
@SuppressWarnings("CheckStyle") final int MAX_STONES = 4;
|
|
||||||
|
|
||||||
@SuppressWarnings("CheckStyle") final int WIDTH = World.getWidth();
|
|
||||||
@SuppressWarnings("CheckStyle") final int HEIGHT = World.getHeight();
|
|
||||||
int[] direction = new int[]{1, 1};
|
|
||||||
|
|
||||||
// for every field
|
|
||||||
for (int y = 0; y < HEIGHT; y++) {
|
|
||||||
for (int x = 0; x < WIDTH; x++) {
|
|
||||||
|
|
||||||
// for every direction
|
|
||||||
for (int nthDirection = 0; nthDirection < 4; nthDirection++) {
|
|
||||||
final int[] pos = {x, y};
|
|
||||||
|
|
||||||
// test for consecutive coins
|
|
||||||
int coinCount = 0; // start counting at 0
|
|
||||||
while (pos[0] >= 0 && pos[0] < WIDTH
|
|
||||||
&& pos[1] >= 0 && pos[1] < HEIGHT
|
|
||||||
&& stones[pos[1]][pos[0]] == currentPlayer) {
|
|
||||||
coinCount++; // count every stone that has currentPlayer's color
|
|
||||||
if (coinCount >= MAX_STONES) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
pos[0] += direction[0];
|
|
||||||
pos[1] += direction[1];
|
|
||||||
}
|
|
||||||
|
|
||||||
direction = new int[]{direction[1], -direction[0]}; // next direction (rotate by 90 deg)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Switches the player for each turn. If the current player is SQUARE_BLUE, SQUARE_RED is returned as the next
|
|
||||||
* player. If the current player is SQUARE_RED, SQUARE_BLUE is returned as the next player.
|
|
||||||
*
|
|
||||||
* @param currentPlayer The player color of the current player.
|
|
||||||
* @return The player color of the next player.
|
|
||||||
*/
|
|
||||||
@StudentImplementationRequired("H2.2.4")
|
|
||||||
public static RobotFamily nextPlayer(final RobotFamily currentPlayer) {
|
|
||||||
return currentPlayer == RobotFamily.SQUARE_BLUE ? RobotFamily.SQUARE_RED : RobotFamily.SQUARE_BLUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Displays a Message in the console and on the game board indicating the game is drawn.
|
|
||||||
*/
|
|
||||||
@StudentImplementationRequired("H2.2.4")
|
|
||||||
public void writeDrawMessage() {
|
|
||||||
inputHandler.displayDrawStatus();
|
|
||||||
|
|
||||||
// student implementation here:
|
|
||||||
System.out.println("No valid columns found. Hence, game ends with a draw.");
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Displays a Message in the console and on the game board indicating the game is won by a player.
|
|
||||||
*
|
|
||||||
* @param winner {@link RobotFamily} of the winning player
|
|
||||||
*/
|
|
||||||
@StudentImplementationRequired("H2.2.4")
|
|
||||||
public void writeWinnerMessage(final RobotFamily winner) {
|
|
||||||
inputHandler.displayWinnerStatus(winner);
|
|
||||||
|
|
||||||
// student implementation here:
|
|
||||||
System.out.println("Player " + winner + " wins the game!");
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Displays the winner of the game by printing the winning color in the console and filling the whole field with
|
|
||||||
* Robots of the winning color.
|
|
||||||
*
|
|
||||||
* @param winner The RobotFamily color of the winner.
|
|
||||||
*/
|
|
||||||
@StudentImplementationRequired("H2.2.4")
|
|
||||||
public static void colorFieldBackground(final RobotFamily winner) {
|
|
||||||
for (int x = 0; x < World.getWidth(); x++) {
|
|
||||||
for (int y = 0; y < World.getHeight(); y++) {
|
|
||||||
setFieldColor(x, y, winner);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Executes the main game loop, handling player turns, stone drops, and win condition checks. This method
|
|
||||||
* initializes the game board as a 2D array of RobotFamily colors, representing the slots that can be filled with
|
|
||||||
* players' stones. It starts with a predefined currentPlayer and continues in a loop until a win condition is met.
|
|
||||||
* Each iteration of the loop waits for player input to select a column to drop a stone into, switches the current
|
|
||||||
* player, drops the stone in the selected column, and checks for win conditions. If a win condition is met, the
|
|
||||||
* loop ends, and the winner is displayed.
|
|
||||||
*/
|
|
||||||
@StudentImplementationRequired("H2.2.4")
|
|
||||||
void gameLoop() {
|
|
||||||
final RobotFamily[][] stones = new RobotFamily[World.getHeight()][World.getWidth()];
|
|
||||||
RobotFamily currentPlayer = RobotFamily.SQUARE_BLUE;
|
|
||||||
|
|
||||||
boolean draw = false;
|
|
||||||
finished = false;
|
|
||||||
|
|
||||||
while (!finished) {
|
|
||||||
// student implementation here:
|
|
||||||
currentPlayer = nextPlayer(currentPlayer);
|
|
||||||
|
|
||||||
// wait for click in column (DO NOT TOUCH)
|
|
||||||
finished = draw = isGameBoardFull(stones);
|
|
||||||
if (draw) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
final int column = inputHandler.getNextInput(currentPlayer, stones);
|
|
||||||
|
|
||||||
// student implementation here:
|
|
||||||
dropStone(column, stones, currentPlayer);
|
|
||||||
finished = testWinConditions(stones, currentPlayer);
|
|
||||||
}
|
|
||||||
|
|
||||||
// displaying either draw or winner (DO NOT TOUCH)
|
|
||||||
if (draw) {
|
|
||||||
writeDrawMessage();
|
|
||||||
colorFieldBackground(getDrawnRobotFamily());
|
|
||||||
} else {
|
|
||||||
writeWinnerMessage(currentPlayer);
|
|
||||||
colorFieldBackground(currentPlayer);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Executes the main game loop, handling player turns, stone drops, and win condition checks. Sets the background
|
|
||||||
* color of a field at the specified coordinates. The color is derived from the {@link RobotFamily} SQUARE_BLUE or
|
|
||||||
* SQUARE_RED.
|
|
||||||
*
|
|
||||||
* @param x the x coordinate of the field
|
|
||||||
* @param y the y coordinate of the field
|
|
||||||
* @param color the {@link RobotFamily} corresponding to the field color to set
|
|
||||||
*/
|
|
||||||
@DoNotTouch
|
|
||||||
public static void setFieldColor(final int x, final int y, final RobotFamily color) {
|
|
||||||
World.getGlobalWorld().setFieldColor(x, y, color.getColor());
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns the {@link RobotFamily} which represents a drawn game.
|
|
||||||
*
|
|
||||||
* @return the {@link RobotFamily} which represents a drawn game.
|
|
||||||
*/
|
|
||||||
@DoNotTouch
|
|
||||||
@SuppressWarnings("UnstableApiUsage")
|
|
||||||
protected static RobotFamily getDrawnRobotFamily() {
|
|
||||||
return Optional.ofNullable(World.getGlobalWorld().getGuiPanel()).filter(guiPanel -> !guiPanel.isDarkMode()).map(guiPanel -> RobotFamily.SQUARE_ORANGE).orElse(RobotFamily.SQUARE_YELLOW);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Checks if all columns of the game board are fully occupied.
|
|
||||||
*
|
|
||||||
* @param stones 2D array representing the game board, where each cell contains a RobotFamily
|
|
||||||
* @return true if all columns of the game board are fully occupied; false otherwise.
|
|
||||||
*/
|
|
||||||
@DoNotTouch
|
|
||||||
public static boolean isGameBoardFull(final RobotFamily[][] stones) {
|
|
||||||
for (int x = 0; x < World.getWidth(); x++) {
|
|
||||||
if (FourWins.validateInput(x, stones)) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns this instance's {@link InputHandler}.
|
|
||||||
*
|
|
||||||
* @return the input handler
|
|
||||||
*/
|
|
||||||
@DoNotTouch
|
|
||||||
public InputHandler getInputHandler() {
|
|
||||||
return inputHandler;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns {@code true} when the game is finished, {@code false} otherwise.
|
|
||||||
*
|
|
||||||
* @return whether the game is finished.
|
|
||||||
*/
|
|
||||||
public boolean isFinished() {
|
|
||||||
return finished;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
|
@ -1,218 +0,0 @@
|
||||||
package h02;
|
|
||||||
|
|
||||||
import fopbot.RobotFamily;
|
|
||||||
import fopbot.World;
|
|
||||||
import org.tudalgo.algoutils.student.annotation.SolutionOnly;
|
|
||||||
import org.tudalgo.algoutils.student.annotation.StudentImplementationRequired;
|
|
||||||
|
|
||||||
import static org.tudalgo.algoutils.student.io.PropertyUtils.getIntProperty;
|
|
||||||
import static org.tudalgo.algoutils.student.test.StudentTestUtils.printTestResults;
|
|
||||||
import static org.tudalgo.algoutils.student.test.StudentTestUtils.testEquals;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Main entry point in executing the program.
|
|
||||||
*/
|
|
||||||
public class Main {
|
|
||||||
/**
|
|
||||||
* Main entry point in executing the program.
|
|
||||||
*
|
|
||||||
* @param args program arguments, currently ignored
|
|
||||||
*/
|
|
||||||
public static void main(final String[] args) {
|
|
||||||
// H1
|
|
||||||
sanityChecksH211();
|
|
||||||
sanityChecksH212();
|
|
||||||
printTestResults();
|
|
||||||
|
|
||||||
// H2
|
|
||||||
sanityChecksH22();
|
|
||||||
printTestResults();
|
|
||||||
|
|
||||||
// starting game (comment out if you just want to run the tests)
|
|
||||||
final var propFile = "h02.properties";
|
|
||||||
new FourWins(
|
|
||||||
getIntProperty(propFile, "FW_WORLD_WIDTH"),
|
|
||||||
getIntProperty(propFile, "FW_WORLD_HEIGHT")
|
|
||||||
).startGame();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Perform sanity checks for exercise H2.1.1.
|
|
||||||
*/
|
|
||||||
@StudentImplementationRequired("H2.3")
|
|
||||||
public static void sanityChecksH211() {
|
|
||||||
// push test
|
|
||||||
final int[] newArray = OneDimensionalArrayStuff.push(new int[]{0, 1}, 2);
|
|
||||||
final int[] expectedArray = {0, 1, 2};
|
|
||||||
testEquals(expectedArray.length, newArray.length);
|
|
||||||
for (int i = 0; i < newArray.length; i++) {
|
|
||||||
testEquals(expectedArray[i], newArray[i]);
|
|
||||||
}
|
|
||||||
|
|
||||||
// calculateNextFibonacci test
|
|
||||||
int[] fibonacciArray = {0, 1};
|
|
||||||
for (int i = 0; i < 20; i++) {
|
|
||||||
fibonacciArray = OneDimensionalArrayStuff.calculateNextFibonacci(fibonacciArray);
|
|
||||||
}
|
|
||||||
testEquals(22, fibonacciArray.length);
|
|
||||||
testEquals(0, fibonacciArray[0]);
|
|
||||||
testEquals(1, fibonacciArray[1]);
|
|
||||||
for (int i = 2; i < fibonacciArray.length; i++) {
|
|
||||||
testEquals(fibonacciArray[i - 1] + fibonacciArray[i - 2], fibonacciArray[i]);
|
|
||||||
}
|
|
||||||
|
|
||||||
// fibonacci test
|
|
||||||
final int[] reference = {0, 1, 1, 2, 3, 5, 8, 13, 21, 34};
|
|
||||||
for (int i = 0; i < 10; i++) {
|
|
||||||
testEquals(reference[i], OneDimensionalArrayStuff.fibonacci(i));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Perform sanity checks for exercise H2.1.2.
|
|
||||||
*/
|
|
||||||
@StudentImplementationRequired("H2.3")
|
|
||||||
public static void sanityChecksH212() {
|
|
||||||
// predefined simple test
|
|
||||||
final String[][] simpleTest = new String[][]{
|
|
||||||
"a b c d e f".split(" "),
|
|
||||||
"a b c d e f".split(" "),
|
|
||||||
"a b c d e f".split(" "),
|
|
||||||
};
|
|
||||||
// predefined complex test
|
|
||||||
final String[][] complexTest = new String[][]{
|
|
||||||
"a a b b c c".split(" "),
|
|
||||||
"a b c d e f".split(" "),
|
|
||||||
"a a a b b b c c c".split(" "),
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
// student implementation here:
|
|
||||||
|
|
||||||
sanityChecksH212Helper(
|
|
||||||
simpleTest,
|
|
||||||
"b",
|
|
||||||
new int[]{1, 1, 1},
|
|
||||||
1
|
|
||||||
);
|
|
||||||
|
|
||||||
sanityChecksH212Helper(
|
|
||||||
complexTest,
|
|
||||||
"b",
|
|
||||||
new int[]{2, 1, 3},
|
|
||||||
2
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Helper method for sanity checks for exercise H2.1.2.
|
|
||||||
*
|
|
||||||
* @param input the input array
|
|
||||||
* @param query the query string
|
|
||||||
* @param refOcc the reference occurrences
|
|
||||||
* @param refMean the reference mean
|
|
||||||
*/
|
|
||||||
@SolutionOnly
|
|
||||||
public static void sanityChecksH212Helper(
|
|
||||||
final String[][] input,
|
|
||||||
final String query,
|
|
||||||
final int[] refOcc,
|
|
||||||
final float refMean
|
|
||||||
) {
|
|
||||||
final int[] occ = TwoDimensionalArrayStuff.occurrences(input, query);
|
|
||||||
testEquals(refOcc.length, occ.length);
|
|
||||||
for (int i = 0; i < occ.length; i++) {
|
|
||||||
testEquals(refOcc[i], occ[i]);
|
|
||||||
}
|
|
||||||
testEquals(refMean, TwoDimensionalArrayStuff.meanOccurrencesPerLine(input, query));
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Perform sanity checks for exercise H2.2
|
|
||||||
*/
|
|
||||||
@StudentImplementationRequired("H2.4")
|
|
||||||
public static void sanityChecksH22() {
|
|
||||||
// setting world size
|
|
||||||
World.setSize(4, 5);
|
|
||||||
|
|
||||||
// predefined stones1 array
|
|
||||||
final RobotFamily[][] stones1 = {
|
|
||||||
{null, RobotFamily.SQUARE_BLUE, null, RobotFamily.SQUARE_RED},
|
|
||||||
{null, null, null, RobotFamily.SQUARE_BLUE},
|
|
||||||
{null, null, null, RobotFamily.SQUARE_RED},
|
|
||||||
{null, null, null, RobotFamily.SQUARE_BLUE},
|
|
||||||
{null, null, null, RobotFamily.SQUARE_RED},
|
|
||||||
};
|
|
||||||
|
|
||||||
// predefined stones2 array
|
|
||||||
final RobotFamily[][] stones2 = {
|
|
||||||
{RobotFamily.SQUARE_BLUE, RobotFamily.SQUARE_BLUE, RobotFamily.SQUARE_BLUE, RobotFamily.SQUARE_BLUE},
|
|
||||||
{RobotFamily.SQUARE_RED, RobotFamily.SQUARE_RED, RobotFamily.SQUARE_BLUE, RobotFamily.SQUARE_RED},
|
|
||||||
{RobotFamily.SQUARE_BLUE, RobotFamily.SQUARE_RED, RobotFamily.SQUARE_BLUE, RobotFamily.SQUARE_BLUE},
|
|
||||||
{RobotFamily.SQUARE_BLUE, RobotFamily.SQUARE_RED, RobotFamily.SQUARE_BLUE, RobotFamily.SQUARE_RED},
|
|
||||||
{RobotFamily.SQUARE_BLUE, RobotFamily.SQUARE_BLUE, RobotFamily.SQUARE_BLUE, RobotFamily.SQUARE_RED},
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
// student implementation here:
|
|
||||||
|
|
||||||
// H2.2.1 validateInput
|
|
||||||
final boolean isInCol1 = FourWins.validateInput(1, stones1);
|
|
||||||
final boolean isInCol3 = FourWins.validateInput(3, stones1);
|
|
||||||
|
|
||||||
testEquals(true, isInCol1);
|
|
||||||
testEquals(false, isInCol3);
|
|
||||||
|
|
||||||
|
|
||||||
// H2.2.2 getDestinationRow
|
|
||||||
final int rowCol1 = FourWins.getDestinationRow(1, stones1);
|
|
||||||
final int rowCol3 = FourWins.getDestinationRow(3, stones1);
|
|
||||||
|
|
||||||
testEquals(1, rowCol1);
|
|
||||||
testEquals(-1, rowCol3);
|
|
||||||
|
|
||||||
|
|
||||||
// H2.2.2 dropStone
|
|
||||||
FourWins.dropStone(1, stones1, RobotFamily.SQUARE_RED);
|
|
||||||
// System.out.println(Arrays.deepToString(stones1));
|
|
||||||
// System.out.println(stones1);
|
|
||||||
testEquals(RobotFamily.SQUARE_RED, stones1[1][1]);
|
|
||||||
|
|
||||||
|
|
||||||
// H2.2.3 testWinHorizontal
|
|
||||||
final boolean winRowBlue = FourWins.testWinHorizontal(stones2, RobotFamily.SQUARE_BLUE);
|
|
||||||
final boolean winRowRed = FourWins.testWinHorizontal(stones2, RobotFamily.SQUARE_RED);
|
|
||||||
|
|
||||||
testEquals(true, winRowBlue);
|
|
||||||
testEquals(false, winRowRed);
|
|
||||||
|
|
||||||
|
|
||||||
// H2.2.3 testWinVertical
|
|
||||||
final boolean winColStones2 = FourWins.testWinVertical(stones2, RobotFamily.SQUARE_BLUE);
|
|
||||||
final boolean winColStones1 = FourWins.testWinVertical(stones1, RobotFamily.SQUARE_BLUE);
|
|
||||||
|
|
||||||
testEquals(true, winColStones2);
|
|
||||||
testEquals(false, winColStones1);
|
|
||||||
|
|
||||||
|
|
||||||
// H2.2.3 testWinConditions
|
|
||||||
final boolean winStones2 = FourWins.testWinConditions(stones2, RobotFamily.SQUARE_BLUE);
|
|
||||||
final boolean winStones1 = FourWins.testWinConditions(stones1, RobotFamily.SQUARE_BLUE);
|
|
||||||
|
|
||||||
testEquals(true, winStones2);
|
|
||||||
testEquals(false, winStones1);
|
|
||||||
|
|
||||||
|
|
||||||
// H2.2.4 switchPlayer
|
|
||||||
final RobotFamily nextPlayer1 = FourWins.nextPlayer(RobotFamily.SQUARE_BLUE);
|
|
||||||
final RobotFamily nextPlayer2 = FourWins.nextPlayer(RobotFamily.SQUARE_RED);
|
|
||||||
|
|
||||||
testEquals(RobotFamily.SQUARE_RED, nextPlayer1);
|
|
||||||
testEquals(RobotFamily.SQUARE_BLUE, nextPlayer2);
|
|
||||||
|
|
||||||
|
|
||||||
// H2.2.4 colorFieldBackground, writeDrawMessage, writeWinnerMessage, gameLoop
|
|
||||||
// Test by playing
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
|
@ -1,64 +0,0 @@
|
||||||
package h02;
|
|
||||||
|
|
||||||
import org.tudalgo.algoutils.student.annotation.StudentImplementationRequired;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* This class serves as a container for the methods that are to be implemented by the students for exercise H2.1.1.
|
|
||||||
*/
|
|
||||||
public class OneDimensionalArrayStuff {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Prevent instantiation of this utility class.
|
|
||||||
*/
|
|
||||||
private OneDimensionalArrayStuff() {
|
|
||||||
throw new IllegalStateException("This class is not meant to be instantiated.");
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns a new array that is a copy of the input array with the given value appended at the end.
|
|
||||||
*
|
|
||||||
* @param array the input array
|
|
||||||
* @param value the value to append
|
|
||||||
* @return a new array that is a copy of the input array with the given value appended at the end
|
|
||||||
*/
|
|
||||||
@StudentImplementationRequired("H2.1.1")
|
|
||||||
public static int[] push(final int[] array, final int value) {
|
|
||||||
final int[] newArray = new int[array.length + 1];
|
|
||||||
//noinspection ManualArrayCopy
|
|
||||||
for (int i = 0; i < array.length; i++) {
|
|
||||||
newArray[i] = array[i];
|
|
||||||
}
|
|
||||||
newArray[array.length] = value;
|
|
||||||
return newArray;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Calculates the next Fibonacci number based on the given array and returns a new array with the next Fibonacci
|
|
||||||
* number appended at the end.
|
|
||||||
*
|
|
||||||
* @param array the input array containing the last two Fibonacci numbers up to the current point
|
|
||||||
* @return a new array with the next Fibonacci number appended at the end
|
|
||||||
*/
|
|
||||||
@StudentImplementationRequired("H2.1.1")
|
|
||||||
public static int[] calculateNextFibonacci(final int[] array) {
|
|
||||||
return push(array, array[array.length - 1] + array[array.length - 2]);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns the n-th Fibonacci number.
|
|
||||||
*
|
|
||||||
* @param n the index of the Fibonacci number to return
|
|
||||||
* @return the n-th Fibonacci number
|
|
||||||
*/
|
|
||||||
@StudentImplementationRequired("H2.1.1")
|
|
||||||
public static int fibonacci(final int n) {
|
|
||||||
if (n < 2) {
|
|
||||||
return n; // base case (n=0 or n=1)
|
|
||||||
}
|
|
||||||
int[] array = {0, 1};
|
|
||||||
for (int i = 2; i <= n; i++) {
|
|
||||||
array = calculateNextFibonacci(array);
|
|
||||||
}
|
|
||||||
return array[array.length - 1];
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,89 +0,0 @@
|
||||||
package h02;
|
|
||||||
|
|
||||||
import org.tudalgo.algoutils.student.annotation.DoNotTouch;
|
|
||||||
import org.tudalgo.algoutils.student.annotation.StudentImplementationRequired;
|
|
||||||
|
|
||||||
import java.util.Arrays;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* This class serves as a container for the methods that are to be implemented by the students for exercise H2.1.2.
|
|
||||||
*/
|
|
||||||
public class TwoDimensionalArrayStuff {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Prevent instantiation of this utility class.
|
|
||||||
*/
|
|
||||||
private TwoDimensionalArrayStuff() {
|
|
||||||
throw new IllegalStateException("This class is not meant to be instantiated.");
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns an array containing the number of occurrences of the query {@link String} in each line of the input array.
|
|
||||||
*
|
|
||||||
* @param input the input array
|
|
||||||
* @param query the query {@link String}
|
|
||||||
* @return an array containing the number of occurrences of the query {@link String} in each line of the input array
|
|
||||||
*/
|
|
||||||
@StudentImplementationRequired("H2.1.2")
|
|
||||||
public static int[] occurrences(final String[][] input, final String query) {
|
|
||||||
final int[] result = new int[input.length];
|
|
||||||
for (int row = 0; row < input.length; row++) {
|
|
||||||
for (int col = 0; col < input[row].length; col++) {
|
|
||||||
if (input[row][col].equals(query)) {
|
|
||||||
result[row]++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns the mean of the input array.
|
|
||||||
*
|
|
||||||
* @param input the input array
|
|
||||||
* @return the mean of the input array
|
|
||||||
*/
|
|
||||||
@StudentImplementationRequired("H2.1.2")
|
|
||||||
public static float mean(final int[] input) {
|
|
||||||
int sum = 0;
|
|
||||||
for (final int j : input) {
|
|
||||||
sum += j;
|
|
||||||
}
|
|
||||||
return (float) sum / input.length;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns the mean number of occurrences of the query {@link String} in each line of the input array.
|
|
||||||
*
|
|
||||||
* @param input the input array
|
|
||||||
* @param query the query {@link String}
|
|
||||||
* @return the mean number of occurrences of the query {@link String} in each line of the input array
|
|
||||||
*/
|
|
||||||
@DoNotTouch
|
|
||||||
public static float meanOccurrencesPerLine(final String[][] input, final String query) {
|
|
||||||
return mean(occurrences(input, query));
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Overload that splits the input string by lines and spaces, then calls regular meanOccurrencesPerLine.
|
|
||||||
*
|
|
||||||
* @param input the input string to split by lines and spaces
|
|
||||||
* @param query the query {@link String}
|
|
||||||
* @return the mean number of occurrences of the query {@link String} in each line of the input array
|
|
||||||
*/
|
|
||||||
@DoNotTouch
|
|
||||||
public static float meanOccurrencesPerLine(final String input, final String query) {
|
|
||||||
// filter out unwanted symbols
|
|
||||||
final String filteredInput = input.replaceAll("[^\\w\\s]", "");
|
|
||||||
// split by lines
|
|
||||||
final var processedInput = Arrays.stream(filteredInput.split("(\\r\\n|\\r|\\n)"))
|
|
||||||
// split by spaces
|
|
||||||
.map(line -> line.split("\\s"))
|
|
||||||
// collect to 2D array
|
|
||||||
.toArray(String[][]::new);
|
|
||||||
/// uncomment the following line to log processed input
|
|
||||||
// System.out.printf("Processed input: %s%n", Arrays.deepToString(processedInput));
|
|
||||||
// call regular meanOccurrencesPerLine
|
|
||||||
return meanOccurrencesPerLine(processedInput, query);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,201 +0,0 @@
|
||||||
package h02.template;
|
|
||||||
|
|
||||||
import fopbot.RobotFamily;
|
|
||||||
import fopbot.World;
|
|
||||||
import h02.FourWins;
|
|
||||||
import org.tudalgo.algoutils.student.annotation.DoNotTouch;
|
|
||||||
|
|
||||||
import javax.swing.*;
|
|
||||||
import javax.swing.border.EmptyBorder;
|
|
||||||
import java.awt.*;
|
|
||||||
import java.awt.event.ComponentAdapter;
|
|
||||||
import java.awt.event.ComponentEvent;
|
|
||||||
import java.beans.PropertyChangeEvent;
|
|
||||||
import java.util.concurrent.BlockingDeque;
|
|
||||||
import java.util.concurrent.LinkedBlockingDeque;
|
|
||||||
import java.util.concurrent.atomic.AtomicBoolean;
|
|
||||||
import java.util.function.Supplier;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The {@link InputHandler} handles the input of the users.
|
|
||||||
*/
|
|
||||||
@DoNotTouch
|
|
||||||
public class InputHandler {
|
|
||||||
/**
|
|
||||||
* The input queue.
|
|
||||||
*/
|
|
||||||
private final BlockingDeque<Integer> inputQueue = new LinkedBlockingDeque<>();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The {@link FourWins} instance.
|
|
||||||
*/
|
|
||||||
private final FourWins fourWins;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Whether the row select mode is active.
|
|
||||||
*/
|
|
||||||
private final AtomicBoolean rowSelectMode = new AtomicBoolean(false);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The status label.
|
|
||||||
*/
|
|
||||||
private final JLabel statusLabel = new JLabel("", SwingConstants.CENTER);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Creates a new {@link InputHandler} instance.
|
|
||||||
*
|
|
||||||
* @param fourWins the {@link FourWins} instance
|
|
||||||
*/
|
|
||||||
public InputHandler(final FourWins fourWins) {
|
|
||||||
this.fourWins = fourWins;
|
|
||||||
final int padding = 4; // Padding in pixels
|
|
||||||
statusLabel.setBorder(new EmptyBorder(padding, padding, padding, padding));
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Sets the color of the given column to the given color.
|
|
||||||
*
|
|
||||||
* @param column the column to set the color of
|
|
||||||
* @param colorSupplier the color to set
|
|
||||||
*/
|
|
||||||
private void setColumnColor(final int column, final Supplier<Color> colorSupplier) {
|
|
||||||
for (int i = 0; i < World.getHeight(); i++) {
|
|
||||||
final int finalI = i;
|
|
||||||
SwingUtilities.invokeLater(() -> World.getGlobalWorld().getField(column, finalI).setFieldColor(colorSupplier));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Executes the given action only if the game is running.
|
|
||||||
*
|
|
||||||
* @param action the action to execute
|
|
||||||
*/
|
|
||||||
private void whenGameIsRunning(final Runnable action) {
|
|
||||||
if (!fourWins.isFinished()) {
|
|
||||||
action.run();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Installs the input handler to the fopbot world.
|
|
||||||
*/
|
|
||||||
@SuppressWarnings("UnstableApiUsage")
|
|
||||||
public void install() {
|
|
||||||
final var guiPanel = World.getGlobalWorld().getGuiPanel();
|
|
||||||
final var guiFrame = World.getGlobalWorld().getGuiFrame();
|
|
||||||
World.getGlobalWorld().getInputHandler().addFieldClickListener(
|
|
||||||
e -> whenGameIsRunning(() -> addInput(e.getField().getX()))
|
|
||||||
);
|
|
||||||
World.getGlobalWorld().getInputHandler().addFieldHoverListener(e -> whenGameIsRunning(() -> {
|
|
||||||
// deselect last hovered field, if any
|
|
||||||
if (e.getPreviousField() != null) {
|
|
||||||
setColumnColor(e.getPreviousField().getX(), () -> null);
|
|
||||||
}
|
|
||||||
if (rowSelectMode.get()) {
|
|
||||||
// select current hovered field
|
|
||||||
if (e.getField() != null) {
|
|
||||||
setColumnColor(
|
|
||||||
e.getField().getX(),
|
|
||||||
() -> guiPanel.isDarkMode()
|
|
||||||
? Color.yellow
|
|
||||||
: Color.orange
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}));
|
|
||||||
statusLabel.setFont(statusLabel.getFont().deriveFont(guiPanel.scale(20.0f)));
|
|
||||||
guiFrame.add(statusLabel, BorderLayout.NORTH);
|
|
||||||
guiFrame.pack();
|
|
||||||
guiPanel.addDarkModeChangeListener(this::onDarkModeChange);
|
|
||||||
guiPanel.addComponentListener(new ComponentAdapter() {
|
|
||||||
@Override
|
|
||||||
public void componentResized(final ComponentEvent e) {
|
|
||||||
statusLabel.setFont(
|
|
||||||
statusLabel.getFont().deriveFont(
|
|
||||||
Math.max(20f, 0.04f * Math.min(guiPanel.getWidth(), guiPanel.getHeight()))
|
|
||||||
)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
// trigger dark mode change to set the correct color
|
|
||||||
guiPanel.setDarkMode(World.getGlobalWorld().getGuiPanel().isDarkMode());
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Called when the dark mode changes.
|
|
||||||
*
|
|
||||||
* @param e the property change event
|
|
||||||
*/
|
|
||||||
@SuppressWarnings("UnstableApiUsage")
|
|
||||||
public void onDarkModeChange(final PropertyChangeEvent e) {
|
|
||||||
final var darkMode = (boolean) e.getNewValue();
|
|
||||||
statusLabel.setForeground(darkMode ? Color.white : Color.black);
|
|
||||||
World.getGlobalWorld().getGuiFrame().getContentPane().setBackground(darkMode ? Color.black : Color.white);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Adds an input to the input queue. When {@link #getNextInput(RobotFamily, RobotFamily[][])} is called, the program
|
|
||||||
* will wait until this method is called.
|
|
||||||
*
|
|
||||||
* @param input the input to add
|
|
||||||
*/
|
|
||||||
public void addInput(final int input) {
|
|
||||||
inputQueue.add(input);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns the next input from the input queue. If the input is invalid, the user will be prompted to enter a new
|
|
||||||
* input. The program will halt until a valid input is entered.
|
|
||||||
*
|
|
||||||
* @param currentPlayer the current player
|
|
||||||
* @param stones the current state of the game board
|
|
||||||
* @return the next input from the input queue
|
|
||||||
*/
|
|
||||||
public int getNextInput(final RobotFamily currentPlayer, final RobotFamily[][] stones) {
|
|
||||||
rowSelectMode.set(true);
|
|
||||||
statusLabel.setText(
|
|
||||||
"<html>Click on a column to insert a disc.<br>Current Player: %s</html>".formatted(currentPlayer.getName())
|
|
||||||
);
|
|
||||||
try {
|
|
||||||
final int input = inputQueue.take();
|
|
||||||
System.out.println("Received column input: " + input);
|
|
||||||
if (!FourWins.validateInput(input, stones)) {
|
|
||||||
System.out.println("Invalid column input, please try again.");
|
|
||||||
return getNextInput(currentPlayer, stones);
|
|
||||||
}
|
|
||||||
rowSelectMode.set(false);
|
|
||||||
return input;
|
|
||||||
} catch (final InterruptedException e) {
|
|
||||||
rowSelectMode.set(false);
|
|
||||||
throw new RuntimeException(e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Sets a status message, saying that the game has ended in a draw.
|
|
||||||
*/
|
|
||||||
public void displayDrawStatus() {
|
|
||||||
statusLabel.setText("<html>No valid columns found. <br>Hence, game ends with a draw.</html>");
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Sets a status message, saying that the game has ended with a winner.
|
|
||||||
*
|
|
||||||
* @param winner the winner of the game
|
|
||||||
*/
|
|
||||||
public void displayWinnerStatus(final RobotFamily winner) {
|
|
||||||
statusLabel.setText("<html>Player %s has won the game!</html>".formatted(winner.getName()));
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns the {@link #statusLabel} of this {@link InputHandler}.
|
|
||||||
*
|
|
||||||
* <p>Use the {@link JLabel#getText()} method to get the current text of the label, and the
|
|
||||||
* {@link JLabel#setText(String)} method to update the text.
|
|
||||||
*
|
|
||||||
* @return the {@link #statusLabel} of this {@link InputHandler}
|
|
||||||
*/
|
|
||||||
public JLabel getStatusLabel() {
|
|
||||||
return statusLabel;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,2 +0,0 @@
|
||||||
FW_WORLD_WIDTH = 7
|
|
||||||
FW_WORLD_HEIGHT = 6
|
|
1
solution/H02/src/test
Symbolic link
|
@ -0,0 +1 @@
|
||||||
|
/home/osh/Desktop/FOP-2425-Marathon/H02/src/test
|
|
@ -1,16 +0,0 @@
|
||||||
package h02;
|
|
||||||
|
|
||||||
import org.junit.jupiter.api.Test;
|
|
||||||
|
|
||||||
import static org.junit.jupiter.api.Assertions.*;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* An example JUnit test class.
|
|
||||||
*/
|
|
||||||
public class ExampleJUnitTest {
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testAddition() {
|
|
||||||
assertEquals(2, 1 + 1);
|
|
||||||
}
|
|
||||||
}
|
|
1
solution/H03/src/main
Symbolic link
|
@ -0,0 +1 @@
|
||||||
|
/home/osh/Desktop/FOP-2425-Marathon/H03/src/main
|
|
@ -1,70 +0,0 @@
|
||||||
package h03;
|
|
||||||
|
|
||||||
import fopbot.World;
|
|
||||||
import h03.robots.DoublePowerRobot;
|
|
||||||
import h03.robots.HackingRobot;
|
|
||||||
import h03.robots.MovementType;
|
|
||||||
import h03.robots.VersatileRobot;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Main entry point in executing the program.
|
|
||||||
*/
|
|
||||||
public class Main {
|
|
||||||
/**
|
|
||||||
* Main entry point in executing the program.
|
|
||||||
*
|
|
||||||
* @param args program arguments, currently ignored
|
|
||||||
*/
|
|
||||||
public static void main(String[] args) {
|
|
||||||
// Create a 5x5 world and make it visible
|
|
||||||
World.setSize(5, 5);
|
|
||||||
World.setVisible(true);
|
|
||||||
|
|
||||||
// Create at least one Hacking Robot with different positions and both cases for the array shift
|
|
||||||
HackingRobot hackingRobot1 = new HackingRobot(1, 1, true);
|
|
||||||
HackingRobot hackingRobot2 = new HackingRobot(2, 2, false);
|
|
||||||
|
|
||||||
// Change the type of the Hacking Robot and check the current and next type
|
|
||||||
hackingRobot1.shuffle();
|
|
||||||
System.out.println("HackingRobot1 current type: " + hackingRobot1.getType());
|
|
||||||
System.out.println("HackingRobot1 next type: " + hackingRobot1.getNextType());
|
|
||||||
|
|
||||||
hackingRobot2.shuffle();
|
|
||||||
System.out.println("HackingRobot2 current type: " + hackingRobot2.getType());
|
|
||||||
System.out.println("HackingRobot2 next type: " + hackingRobot2.getNextType());
|
|
||||||
|
|
||||||
// Create at least two Versatile Robots with both cases for coordinate exchange
|
|
||||||
VersatileRobot versatileRobot1 = new VersatileRobot(1, 2, true, false);
|
|
||||||
VersatileRobot versatileRobot2 = new VersatileRobot(3, 4, false, true);
|
|
||||||
|
|
||||||
// Change the type of the Versatile Robot until the type is DIAGONAL and check coordinates
|
|
||||||
while (versatileRobot1.getType() != MovementType.DIAGONAL) {
|
|
||||||
versatileRobot1.shuffle();
|
|
||||||
}
|
|
||||||
System.out.println("VersatileRobot1 type is DIAGONAL. x: " + versatileRobot1.getX() + ", y: " + versatileRobot1.getY());
|
|
||||||
|
|
||||||
while (versatileRobot2.getType() != MovementType.DIAGONAL) {
|
|
||||||
versatileRobot2.shuffle();
|
|
||||||
}
|
|
||||||
System.out.println("VersatileRobot2 type is DIAGONAL. x: " + versatileRobot2.getX() + ", y: " + versatileRobot2.getY());
|
|
||||||
|
|
||||||
// Create at least three Double Power Robots and change their types to get all movement types
|
|
||||||
DoublePowerRobot doublePowerRobot1 = new DoublePowerRobot(0, 0, true);
|
|
||||||
DoublePowerRobot doublePowerRobot2 = new DoublePowerRobot(1, 1, false);
|
|
||||||
DoublePowerRobot doublePowerRobot3 = new DoublePowerRobot(2, 2, true);
|
|
||||||
|
|
||||||
// Create a RobotsChallenge with previously created Double Power Robots
|
|
||||||
DoublePowerRobot[] robots = {doublePowerRobot1, doublePowerRobot2, doublePowerRobot3};
|
|
||||||
RobotsChallenge challenge = new RobotsChallenge(0, 2, robots);
|
|
||||||
|
|
||||||
// Find and display the winning Double Power Robots
|
|
||||||
DoublePowerRobot[] winners = challenge.findWinners();
|
|
||||||
System.out.println("Winning DoublePowerRobots:");
|
|
||||||
for (DoublePowerRobot winner : winners) {
|
|
||||||
if (winner != null) {
|
|
||||||
//print the winner robot's coordinates
|
|
||||||
System.out.println("Winner robot coordinates: x: " + winner.getX() + ", y: " + winner.getY());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,88 +0,0 @@
|
||||||
package h03;
|
|
||||||
|
|
||||||
import h03.robots.DoublePowerRobot;
|
|
||||||
import h03.robots.MovementType;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The {@code RobotsChallenge} class performs a challenge between robots of the {@code DoublePowerRobot} class.
|
|
||||||
*/
|
|
||||||
public class RobotsChallenge {
|
|
||||||
|
|
||||||
private final DoublePowerRobot[] robots;
|
|
||||||
private final int goal;
|
|
||||||
private final int begin;
|
|
||||||
private final int winThreshold = 2;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Constructs a new {@code RobotsChallenge} with the specified starting position, goal, and array of robots.
|
|
||||||
*
|
|
||||||
* @param begin The starting position of the robots.
|
|
||||||
* @param goal The target coordinates.
|
|
||||||
* @param robots The array of {@code DoublePowerRobot} objects participating in the challenge.
|
|
||||||
*/
|
|
||||||
public RobotsChallenge(int begin, int goal, final DoublePowerRobot[] robots) {
|
|
||||||
this.begin = begin / 2;
|
|
||||||
this.goal = goal;
|
|
||||||
this.robots = robots;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Calculates the number of steps needed for a robot to reach the goal for the diagonal type.
|
|
||||||
*
|
|
||||||
* @return The number of steps required to reach the goal.
|
|
||||||
*/
|
|
||||||
public int calculateStepsDiagonal() {
|
|
||||||
return Math.abs(begin - goal);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Calculates the number of steps needed for a robot to reach the goal for the overstep type.
|
|
||||||
*
|
|
||||||
* @return The number of steps required to reach the goal.
|
|
||||||
*/
|
|
||||||
public int calculateStepsOverstep() {
|
|
||||||
return (Math.abs(begin - goal) % 2 == 0) ? Math.abs(begin - goal) : Math.abs(begin - goal) + 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Calculates the number of steps needed for a robot to reach the goal for the teleport type.
|
|
||||||
*
|
|
||||||
* @return The number of steps required to reach the goal.
|
|
||||||
*/
|
|
||||||
public int calculateStepsTeleport() {
|
|
||||||
return (Math.abs(begin - goal) % 2 == 0) ? Math.abs(begin - goal) / 2 : (Math.abs(begin - goal) / 2) + 2;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Calculates the number of steps needed for a robot to reach the goal based on its movement type.
|
|
||||||
*
|
|
||||||
* @param type The {@code MovementType} of the robot.
|
|
||||||
* @return The number of steps required to reach the goal.
|
|
||||||
*/
|
|
||||||
public int calculateSteps(MovementType type) {
|
|
||||||
return type == MovementType.DIAGONAL ? calculateStepsDiagonal() : type == MovementType.OVERSTEP ? calculateStepsOverstep() : calculateStepsTeleport();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Finds the winning robots in the challenge based on their movement types and the number of steps required to reach the goal.
|
|
||||||
*
|
|
||||||
* @return An array of {@code DoublePowerRobot} objects that are the winners of the challenge.
|
|
||||||
*/
|
|
||||||
public DoublePowerRobot[] findWinners() {
|
|
||||||
int winnerCount = 0;
|
|
||||||
DoublePowerRobot[] winners = new DoublePowerRobot[robots.length];
|
|
||||||
|
|
||||||
for (DoublePowerRobot robot : robots) {
|
|
||||||
int stepsFirstType = calculateSteps(robot.getType());
|
|
||||||
int stepsSecondType = calculateSteps(robot.getNextType());
|
|
||||||
int steps = Math.min(stepsFirstType, stepsSecondType);
|
|
||||||
|
|
||||||
if (steps <= winThreshold) {
|
|
||||||
winners[winnerCount] = robot;
|
|
||||||
winnerCount++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return winners;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,57 +0,0 @@
|
||||||
package h03.robots;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Subclass DoublePowerRobot, which inherits from the {@code HackingRobot} class and allows the robot to have two types simultaneously.
|
|
||||||
*/
|
|
||||||
public class DoublePowerRobot extends HackingRobot {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Private array doublePowerTypes containing the two types for the DoublePowerRobot.
|
|
||||||
*/
|
|
||||||
private MovementType[] doublePowerTypes = new MovementType[2];
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Constructor of the DoublePowerRobot class with parameters x, y, and order.
|
|
||||||
* Initializes the robot and assigns two movement types to the robot.
|
|
||||||
*
|
|
||||||
* @param x The x-coordinate of the robot.
|
|
||||||
* @param y The y-coordinate of the robot.
|
|
||||||
* @param order If true, the movement types are shifted to the right by one index, otherwise to the left by one index.
|
|
||||||
*/
|
|
||||||
public DoublePowerRobot(int x, int y, boolean order) {
|
|
||||||
super(x, y, order);
|
|
||||||
|
|
||||||
// Assigning the two types to doublePowerTypes
|
|
||||||
doublePowerTypes[0] = getType();
|
|
||||||
doublePowerTypes[1] = getNextType();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Overrides the shuffle method of the superclass.
|
|
||||||
* Shuffles the robot's type a specified number of times and updates the types in doublePowerTypes.
|
|
||||||
*
|
|
||||||
* @param itNr The number of iterations to shuffle the type.
|
|
||||||
* @return True if the types have changed, false otherwise.
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
public boolean shuffle(int itNr) {
|
|
||||||
boolean changed = super.shuffle(itNr);
|
|
||||||
|
|
||||||
// Updating the types in doublePowerTypes based on the new value of type
|
|
||||||
doublePowerTypes[0] = getType();
|
|
||||||
doublePowerTypes[1] = getNextType();
|
|
||||||
|
|
||||||
return changed;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Overrides the shuffle method of the superclass.
|
|
||||||
* Shuffles the robot's type until the type is different from the current type and updates the types in doublePowerTypes.
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
public void shuffle() {
|
|
||||||
super.shuffle();
|
|
||||||
doublePowerTypes[0] = getType();
|
|
||||||
doublePowerTypes[1] = getNextType();
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,111 +0,0 @@
|
||||||
package h03.robots;
|
|
||||||
|
|
||||||
import fopbot.Robot;
|
|
||||||
import java.util.Random;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The HackingRobot class extends the Robot class and provides additional methods for movement in the grid.
|
|
||||||
* The robot can have different types of movements which can be shuffled.
|
|
||||||
*/
|
|
||||||
public class HackingRobot extends Robot {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Private array "robotTypes" containing the elements of the enumeration MovementType in reverse alphabetical order.
|
|
||||||
*/
|
|
||||||
private MovementType[] robotTypes = {MovementType.TELEPORT, MovementType.OVERSTEP, MovementType.DIAGONAL};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Private variable that contains the type of the robot.
|
|
||||||
*/
|
|
||||||
private MovementType type;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Constructs a new HackingRobot at the specified coordinates.
|
|
||||||
* The order parameter determines the initial order of the movement types.
|
|
||||||
*
|
|
||||||
* @param x The x-coordinate of the robot.
|
|
||||||
* @param y The y-coordinate of the robot.
|
|
||||||
* @param order If true, the movement types are shifted to the right by one index, otherwise to the left by one index.
|
|
||||||
*/
|
|
||||||
public HackingRobot(int x, int y, boolean order) {
|
|
||||||
super(x, y);
|
|
||||||
|
|
||||||
if (order) {
|
|
||||||
// Move elements to the right by 1 index
|
|
||||||
MovementType lastElement = robotTypes[robotTypes.length - 1];
|
|
||||||
for (int i = robotTypes.length - 1; i > 0; i--) {
|
|
||||||
robotTypes[i] = robotTypes[i - 1];
|
|
||||||
}
|
|
||||||
robotTypes[0] = lastElement;
|
|
||||||
} else {
|
|
||||||
// Move elements to the left by 1 index
|
|
||||||
MovementType firstElement = robotTypes[0];
|
|
||||||
for (int i = 0; i < robotTypes.length - 1; i++) {
|
|
||||||
robotTypes[i] = robotTypes[i + 1];
|
|
||||||
}
|
|
||||||
robotTypes[robotTypes.length - 1] = firstElement;
|
|
||||||
}
|
|
||||||
|
|
||||||
this.type = robotTypes[0];
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns the current type of the robot.
|
|
||||||
*
|
|
||||||
* @return The current MovementType of the robot.
|
|
||||||
*/
|
|
||||||
public MovementType getType() {
|
|
||||||
return type;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns the movement type located 1 index to the right of the current type of the robot.
|
|
||||||
*
|
|
||||||
* @return The next MovementType of the robot.
|
|
||||||
*/
|
|
||||||
public MovementType getNextType() {
|
|
||||||
int currentIndex = -1;
|
|
||||||
for (int i = 0; i < robotTypes.length; i++) {
|
|
||||||
if (robotTypes[i] == type) {
|
|
||||||
currentIndex = i;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return robotTypes[(currentIndex + 1) % robotTypes.length];
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Generates a random number between zero (inclusive) and the specified limit (exclusive).
|
|
||||||
*
|
|
||||||
* @param limit The upper bound (exclusive) for the random number.
|
|
||||||
* @return A random integer between 0 (inclusive) and the specified limit (exclusive).
|
|
||||||
*/
|
|
||||||
public int getRandom(int limit) {
|
|
||||||
Random random = new Random();
|
|
||||||
return random.nextInt(limit);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Randomly changes the type of the robot a specified number of times.
|
|
||||||
*
|
|
||||||
* @param itNr The number of iterations to shuffle the type.
|
|
||||||
* @return True if the type changed after shuffling, false otherwise.
|
|
||||||
*/
|
|
||||||
public boolean shuffle(int itNr) {
|
|
||||||
MovementType previousType = this.type;
|
|
||||||
for (int i = 0; i < itNr; i++) {
|
|
||||||
int randomIndex = getRandom(robotTypes.length);
|
|
||||||
this.type = robotTypes[randomIndex];
|
|
||||||
}
|
|
||||||
|
|
||||||
return this.type != previousType;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Randomly changes the type of the robot until the type is different from the current type.
|
|
||||||
*/
|
|
||||||
public void shuffle() {
|
|
||||||
while (!shuffle(1)) {
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,21 +0,0 @@
|
||||||
package h03.robots;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The {@code MovementType} enum represents the different types of movements that a robot can perform.
|
|
||||||
*/
|
|
||||||
public enum MovementType {
|
|
||||||
/**
|
|
||||||
* Represents diagonal movement.
|
|
||||||
*/
|
|
||||||
DIAGONAL,
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Represents overstepping movement.
|
|
||||||
*/
|
|
||||||
OVERSTEP,
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Represents teleportation movement.
|
|
||||||
*/
|
|
||||||
TELEPORT
|
|
||||||
}
|
|
|
@ -1,59 +0,0 @@
|
||||||
package h03.robots;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Subclass VersatileRobot, which inherits from the class {@code HackingRobot}.
|
|
||||||
* This robot can switch its coordinates and has specific behavior when its type is DIAGONAL.
|
|
||||||
*/
|
|
||||||
public class VersatileRobot extends HackingRobot {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Constructor of the VersatileRobot class with the parameters x, y, order, and exchange.
|
|
||||||
* Initializes the robot and optionally exchanges its coordinates.
|
|
||||||
*
|
|
||||||
* @param x The x-coordinate of the robot.
|
|
||||||
* @param y The y-coordinate of the robot.
|
|
||||||
* @param order If true, the movement types are shifted to the right by one index, otherwise to the left by one index.
|
|
||||||
* @param exchange If true, the coordinates x and y are exchanged.
|
|
||||||
*/
|
|
||||||
public VersatileRobot(int x, int y, boolean order, boolean exchange) {
|
|
||||||
super(x, y, order);
|
|
||||||
|
|
||||||
if (exchange) {
|
|
||||||
int aux = x;
|
|
||||||
setX(y);
|
|
||||||
setY(aux);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (getType() == MovementType.DIAGONAL) {
|
|
||||||
setY(getX());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Overrides the shuffle method of the superclass.
|
|
||||||
* Shuffles the robot's type a specified number of times and adjusts the y-coordinate if the type is DIAGONAL.
|
|
||||||
*
|
|
||||||
* @param itNr The number of iterations to shuffle the type.
|
|
||||||
* @return True if the types have changed, false otherwise.
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
public boolean shuffle(int itNr) {
|
|
||||||
boolean changed = super.shuffle(itNr);
|
|
||||||
if (getType() == MovementType.DIAGONAL) {
|
|
||||||
setY(getX());
|
|
||||||
}
|
|
||||||
return changed;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Overrides the shuffle method of the superclass.
|
|
||||||
* Shuffles the robot's type until the type is different from the current type and adjusts the y-coordinate if the type is DIAGONAL.
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
public void shuffle() {
|
|
||||||
super.shuffle();
|
|
||||||
if (getType() == MovementType.DIAGONAL) {
|
|
||||||
setY(getX());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
1
solution/H03/src/test
Symbolic link
|
@ -0,0 +1 @@
|
||||||
|
/home/osh/Desktop/FOP-2425-Marathon/H03/src/test
|
|
@ -1,16 +0,0 @@
|
||||||
package h03;
|
|
||||||
|
|
||||||
import org.junit.jupiter.api.Test;
|
|
||||||
|
|
||||||
import static org.junit.jupiter.api.Assertions.*;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* An example JUnit test class.
|
|
||||||
*/
|
|
||||||
public class ExampleJUnitTest {
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testAddition() {
|
|
||||||
assertEquals(2, 1 + 1);
|
|
||||||
}
|
|
||||||
}
|
|
1
solution/H04/src/main
Symbolic link
|
@ -0,0 +1 @@
|
||||||
|
/home/osh/Desktop/FOP-2425-Marathon/H04/src/main
|
|
@ -1,18 +0,0 @@
|
||||||
package h04;
|
|
||||||
|
|
||||||
import h04.template.ChessUtils;
|
|
||||||
import h04.template.GameControllerTemplate;
|
|
||||||
import h04.chesspieces.King;
|
|
||||||
|
|
||||||
public class GameController extends GameControllerTemplate {
|
|
||||||
public GameController() {
|
|
||||||
super();
|
|
||||||
setup();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean checkWinCondition() {
|
|
||||||
final King[] kings = ChessUtils.getKings();
|
|
||||||
return (kings[0].isTurnedOff() || kings[1].isTurnedOff());
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,17 +0,0 @@
|
||||||
package h04;
|
|
||||||
|
|
||||||
import fopbot.World;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Main entry point in executing the program.
|
|
||||||
*/
|
|
||||||
public class Main {
|
|
||||||
/**
|
|
||||||
* Main entry point in executing the program.
|
|
||||||
*
|
|
||||||
* @param args program arguments, currently ignored
|
|
||||||
*/
|
|
||||||
public static void main(final String[] args) {
|
|
||||||
new GameController().startGame();
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,29 +0,0 @@
|
||||||
package h04.chesspieces;
|
|
||||||
|
|
||||||
import fopbot.Robot;
|
|
||||||
import h04.movement.DiagonalMover;
|
|
||||||
import h04.movement.MoveStrategy;
|
|
||||||
|
|
||||||
import java.awt.Point;
|
|
||||||
|
|
||||||
|
|
||||||
public class Bishop extends Robot implements ChessPiece, DiagonalMover {
|
|
||||||
|
|
||||||
private final Team team;
|
|
||||||
|
|
||||||
public Bishop(final int x, final int y, final Team team){
|
|
||||||
super(x, y, team == Team.WHITE ? Families.BISHOP_WHITE : Families.BISHOP_BLACK);
|
|
||||||
this.team = team;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Team getTeam() { return team;}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void moveStrategy(final int dx, final int dy, final MoveStrategy strategy){strategy.move(this, dx, dy);}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Point[] getPossibleMoveFields() {
|
|
||||||
return getDiagonalMoves();
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,20 +0,0 @@
|
||||||
package h04.chesspieces;
|
|
||||||
|
|
||||||
import h04.movement.MoveStrategy;
|
|
||||||
|
|
||||||
import java.awt.Point;
|
|
||||||
|
|
||||||
public interface ChessPiece {
|
|
||||||
Team getTeam();
|
|
||||||
int getX();
|
|
||||||
int getY();
|
|
||||||
/**
|
|
||||||
* Returns {@code true} if this robot is turned off.
|
|
||||||
*
|
|
||||||
* @return {@code true} if this robot is turned off
|
|
||||||
*/
|
|
||||||
boolean isTurnedOff();
|
|
||||||
void turnOff();
|
|
||||||
void moveStrategy(int dx, int dy, MoveStrategy strategy);
|
|
||||||
Point[] getPossibleMoveFields();
|
|
||||||
}
|
|
|
@ -1,81 +0,0 @@
|
||||||
package h04.chesspieces;
|
|
||||||
|
|
||||||
import fopbot.RobotFamily;
|
|
||||||
import fopbot.SvgBasedRobotFamily;
|
|
||||||
|
|
||||||
import java.awt.Color;
|
|
||||||
|
|
||||||
public class Families {
|
|
||||||
public static RobotFamily PAWN_WHITE = new SvgBasedRobotFamily(
|
|
||||||
"PAWN_WHITE",
|
|
||||||
"/pieces/pawn_white.svg",
|
|
||||||
"/pieces/pawn_white.svg",
|
|
||||||
Color.WHITE
|
|
||||||
);
|
|
||||||
public static RobotFamily PAWN_BLACK = new SvgBasedRobotFamily(
|
|
||||||
"PAWN_BLACK",
|
|
||||||
"/pieces/pawn_black.svg",
|
|
||||||
"/pieces/pawn_black.svg",
|
|
||||||
Color.BLACK
|
|
||||||
);
|
|
||||||
public static RobotFamily ROOK_WHITE = new SvgBasedRobotFamily(
|
|
||||||
"ROOK_WHITE",
|
|
||||||
"/pieces/rook_white.svg",
|
|
||||||
"/pieces/rook_white.svg",
|
|
||||||
Color.WHITE
|
|
||||||
);
|
|
||||||
public static RobotFamily ROOK_BLACK = new SvgBasedRobotFamily(
|
|
||||||
"ROOK_BLACK",
|
|
||||||
"/pieces/rook_black.svg",
|
|
||||||
"/pieces/rook_black.svg",
|
|
||||||
Color.BLACK
|
|
||||||
);
|
|
||||||
public static RobotFamily KNIGHT_WHITE = new SvgBasedRobotFamily(
|
|
||||||
"KNIGHT_WHITE",
|
|
||||||
"/pieces/knight_white.svg",
|
|
||||||
"/pieces/knight_white.svg",
|
|
||||||
Color.WHITE
|
|
||||||
);
|
|
||||||
public static RobotFamily KNIGHT_BLACK = new SvgBasedRobotFamily(
|
|
||||||
"KNIGHT_BLACK",
|
|
||||||
"/pieces/knight_black.svg",
|
|
||||||
"/pieces/knight_black.svg",
|
|
||||||
Color.BLACK
|
|
||||||
);
|
|
||||||
public static RobotFamily BISHOP_WHITE = new SvgBasedRobotFamily(
|
|
||||||
"BISHOP_WHITE",
|
|
||||||
"/pieces/bishop_white.svg",
|
|
||||||
"/pieces/bishop_white.svg",
|
|
||||||
Color.WHITE
|
|
||||||
);
|
|
||||||
public static RobotFamily BISHOP_BLACK = new SvgBasedRobotFamily(
|
|
||||||
"BISHOP_BLACK",
|
|
||||||
"/pieces/bishop_black.svg",
|
|
||||||
"/pieces/bishop_black.svg",
|
|
||||||
Color.BLACK
|
|
||||||
);
|
|
||||||
public static RobotFamily QUEEN_WHITE = new SvgBasedRobotFamily(
|
|
||||||
"QUEEN_WHITE",
|
|
||||||
"/pieces/queen_white.svg",
|
|
||||||
"/pieces/queen_white.svg",
|
|
||||||
Color.WHITE
|
|
||||||
);
|
|
||||||
public static RobotFamily QUEEN_BLACK = new SvgBasedRobotFamily(
|
|
||||||
"QUEEN_BLACK",
|
|
||||||
"/pieces/queen_black.svg",
|
|
||||||
"/pieces/queen_black.svg",
|
|
||||||
Color.BLACK
|
|
||||||
);
|
|
||||||
public static RobotFamily KING_WHITE = new SvgBasedRobotFamily(
|
|
||||||
"KING_WHITE",
|
|
||||||
"/pieces/king_white.svg",
|
|
||||||
"/pieces/king_white.svg",
|
|
||||||
Color.WHITE
|
|
||||||
);
|
|
||||||
public static RobotFamily KING_BLACK = new SvgBasedRobotFamily(
|
|
||||||
"KING_BLACK",
|
|
||||||
"/pieces/king_black.svg",
|
|
||||||
"/pieces/king_black.svg",
|
|
||||||
Color.BLACK
|
|
||||||
);
|
|
||||||
}
|
|
|
@ -1,45 +0,0 @@
|
||||||
package h04.chesspieces;
|
|
||||||
|
|
||||||
import fopbot.Robot;
|
|
||||||
import h04.movement.MoveStrategy;
|
|
||||||
import h04.template.ChessUtils;
|
|
||||||
|
|
||||||
import java.awt.Point;
|
|
||||||
|
|
||||||
public class King extends Robot implements ChessPiece {
|
|
||||||
|
|
||||||
private final Team team;
|
|
||||||
|
|
||||||
public King(final int x, final int y, final Team team) {
|
|
||||||
super(x, y, team == Team.WHITE ? Families.KING_WHITE : Families.KING_BLACK);
|
|
||||||
this.team = team;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Team getTeam() {
|
|
||||||
return team;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void moveStrategy(final int dx, final int dy, final MoveStrategy strategy) {
|
|
||||||
strategy.move(this, dx, dy);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Point[] getPossibleMoveFields() {
|
|
||||||
return ChessUtils.getAllowedMoves(
|
|
||||||
this,
|
|
||||||
new Point[]{
|
|
||||||
new Point(1, 0),
|
|
||||||
new Point(-1, 0),
|
|
||||||
new Point(0, 1),
|
|
||||||
new Point(0, -1),
|
|
||||||
new Point(1, 1),
|
|
||||||
new Point(-1, 1),
|
|
||||||
new Point(1, -1),
|
|
||||||
new Point(-1, -1)
|
|
||||||
},
|
|
||||||
1
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,44 +0,0 @@
|
||||||
package h04.chesspieces;
|
|
||||||
|
|
||||||
import fopbot.Robot;
|
|
||||||
import h04.movement.MoveStrategy;
|
|
||||||
import h04.template.ChessUtils;
|
|
||||||
|
|
||||||
import java.awt.Point;
|
|
||||||
|
|
||||||
public class Knight extends Robot implements ChessPiece {
|
|
||||||
|
|
||||||
private final Team team;
|
|
||||||
|
|
||||||
public Knight(final int x, final int y, final Team team) {
|
|
||||||
super(x, y, team == Team.WHITE ? Families.KNIGHT_WHITE : Families.KNIGHT_BLACK);
|
|
||||||
this.team = team;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Team getTeam() {
|
|
||||||
return team;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void moveStrategy(final int dx, final int dy, final MoveStrategy strategy) {
|
|
||||||
strategy.move(this, dx, dy);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Point[] getPossibleMoveFields() {
|
|
||||||
final Point[] possibleMoves = new Point[8];
|
|
||||||
int index = 0;
|
|
||||||
for (final Point delta : new Point[]{new Point(1, 2), new Point(2, 1)}) {
|
|
||||||
for (int i = 0; i < 4; i++) {
|
|
||||||
final Point move = new Point(getX() + delta.x, getY() + delta.y);
|
|
||||||
if (ChessUtils.isValidCoordinate(move) && ChessUtils.getTeamAt(move) != getTeam()) {
|
|
||||||
possibleMoves[index++] = move;
|
|
||||||
}
|
|
||||||
//noinspection SuspiciousNameCombination
|
|
||||||
delta.setLocation(-delta.y, delta.x);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return possibleMoves;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,54 +0,0 @@
|
||||||
package h04.chesspieces;
|
|
||||||
|
|
||||||
import fopbot.Robot;
|
|
||||||
import h04.movement.MoveStrategy;
|
|
||||||
|
|
||||||
import java.awt.Point;
|
|
||||||
|
|
||||||
import static h04.template.ChessUtils.getTeamAt;
|
|
||||||
import static h04.template.ChessUtils.isValidCoordinate;
|
|
||||||
|
|
||||||
public class Pawn extends Robot implements ChessPiece {
|
|
||||||
private final Team team;
|
|
||||||
|
|
||||||
boolean firstMove = true;
|
|
||||||
|
|
||||||
public Pawn(final int x, final int y, final Team team) {
|
|
||||||
super(x, y, team == Team.WHITE ? Families.PAWN_WHITE : Families.PAWN_BLACK);
|
|
||||||
this.team = team;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Team getTeam() {
|
|
||||||
return team;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void moveStrategy(final int dx, final int dy, final MoveStrategy strategy) {
|
|
||||||
strategy.move(this, dx, dy);
|
|
||||||
firstMove = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Point[] getPossibleMoveFields() {
|
|
||||||
final Point[] possibleMoves = new Point[4];
|
|
||||||
int index = 0;
|
|
||||||
final int direction = team == Team.WHITE ? 1 : -1;
|
|
||||||
final Point front1 = new Point(getX(), getY() + direction);
|
|
||||||
if (isValidCoordinate(front1) && getTeamAt(front1) == null) {
|
|
||||||
possibleMoves[index++] = front1;
|
|
||||||
final Point front2 = new Point(getX(), getY() + 2 * direction);
|
|
||||||
if (firstMove && isValidCoordinate(front2) && getTeamAt(front2) == null) {
|
|
||||||
possibleMoves[index++] = front2;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
//attack
|
|
||||||
for (final int i : new int[]{-1, 1}) {
|
|
||||||
final Point p = new Point(getX() + i, getY() + direction);
|
|
||||||
if (isValidCoordinate(p) && getTeamAt(p) == getTeam().getOpponent()) {
|
|
||||||
possibleMoves[index++] = p;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return possibleMoves;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,33 +0,0 @@
|
||||||
package h04.chesspieces;
|
|
||||||
|
|
||||||
import fopbot.Robot;
|
|
||||||
import h04.movement.DiagonalMover;
|
|
||||||
import h04.movement.MoveStrategy;
|
|
||||||
import h04.movement.OrthogonalMover;
|
|
||||||
import h04.template.ChessUtils;
|
|
||||||
|
|
||||||
import java.awt.Point;
|
|
||||||
|
|
||||||
public class Queen extends Robot implements OrthogonalMover, DiagonalMover {
|
|
||||||
private final Team team;
|
|
||||||
|
|
||||||
public Queen(final int x, final int y, final Team team) {
|
|
||||||
super(x, y, team == Team.WHITE ? Families.QUEEN_WHITE : Families.QUEEN_BLACK);
|
|
||||||
this.team = team;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Team getTeam() {
|
|
||||||
return team;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void moveStrategy(final int dx, final int dy, final MoveStrategy strategy) {
|
|
||||||
strategy.move(this, dx, dy);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Point[] getPossibleMoveFields() {
|
|
||||||
return ChessUtils.mergePoints(getOrthogonalMoves(), getDiagonalMoves());
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,32 +0,0 @@
|
||||||
package h04.chesspieces;
|
|
||||||
|
|
||||||
import fopbot.Robot;
|
|
||||||
import h04.movement.MoveStrategy;
|
|
||||||
import h04.movement.OrthogonalMover;
|
|
||||||
import h04.template.ChessUtils;
|
|
||||||
|
|
||||||
import java.awt.Point;
|
|
||||||
|
|
||||||
public class Rook extends Robot implements OrthogonalMover {
|
|
||||||
private final Team team;
|
|
||||||
|
|
||||||
public Rook(final int x, final int y, final Team team){
|
|
||||||
super(x, y, team == Team.WHITE ? Families.ROOK_WHITE : Families.ROOK_BLACK);
|
|
||||||
this.team = team;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Team getTeam() {
|
|
||||||
return team;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void moveStrategy(final int dx, final int dy, final MoveStrategy strategy) {
|
|
||||||
strategy.move(this, dx, dy);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Point[] getPossibleMoveFields() {
|
|
||||||
return getOrthogonalMoves();
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,25 +0,0 @@
|
||||||
package h04.chesspieces;
|
|
||||||
|
|
||||||
import java.awt.Color;
|
|
||||||
|
|
||||||
public enum Team {
|
|
||||||
WHITE(Color.WHITE),
|
|
||||||
BLACK(Color.BLACK);
|
|
||||||
private final Color color;
|
|
||||||
|
|
||||||
Team(final Color color) {
|
|
||||||
this.color = color;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Color getColor() {
|
|
||||||
return color;
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean isOpponent(final Team other) {
|
|
||||||
return this != other;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Team getOpponent() {
|
|
||||||
return this == WHITE ? BLACK : WHITE;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,21 +0,0 @@
|
||||||
package h04.movement;
|
|
||||||
|
|
||||||
import h04.chesspieces.ChessPiece;
|
|
||||||
import h04.template.ChessUtils;
|
|
||||||
|
|
||||||
import java.awt.Point;
|
|
||||||
|
|
||||||
public interface DiagonalMover extends ChessPiece {
|
|
||||||
default Point[] getDiagonalMoves() {
|
|
||||||
return ChessUtils.getAllowedMoves(
|
|
||||||
this,
|
|
||||||
new Point[]{
|
|
||||||
new Point(1, 1),
|
|
||||||
new Point(-1, 1),
|
|
||||||
new Point(1, -1),
|
|
||||||
new Point(-1, -1)
|
|
||||||
},
|
|
||||||
7
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,8 +0,0 @@
|
||||||
package h04.movement;
|
|
||||||
|
|
||||||
|
|
||||||
import fopbot.Robot;
|
|
||||||
|
|
||||||
public interface MoveStrategy {
|
|
||||||
void move(Robot r, int dx, int dy);
|
|
||||||
}
|
|
|
@ -1,21 +0,0 @@
|
||||||
package h04.movement;
|
|
||||||
|
|
||||||
import h04.chesspieces.ChessPiece;
|
|
||||||
import h04.template.ChessUtils;
|
|
||||||
|
|
||||||
import java.awt.Point;
|
|
||||||
|
|
||||||
public interface OrthogonalMover extends ChessPiece {
|
|
||||||
default Point[] getOrthogonalMoves() {
|
|
||||||
return ChessUtils.getAllowedMoves(
|
|
||||||
this,
|
|
||||||
new Point[]{
|
|
||||||
new Point(1, 0),
|
|
||||||
new Point(-1, 0),
|
|
||||||
new Point(0, 1),
|
|
||||||
new Point(0, -1)
|
|
||||||
},
|
|
||||||
7
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,10 +0,0 @@
|
||||||
package h04.movement;
|
|
||||||
|
|
||||||
import fopbot.Robot;
|
|
||||||
|
|
||||||
public class TeleportingMoveStrategy implements MoveStrategy {
|
|
||||||
@Override
|
|
||||||
public void move(final Robot r, final int dx, final int dy) {
|
|
||||||
r.setField(r.getX() + dx, r.getY() + dy);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,40 +0,0 @@
|
||||||
package h04.movement;
|
|
||||||
|
|
||||||
|
|
||||||
import fopbot.Direction;
|
|
||||||
import fopbot.Robot;
|
|
||||||
|
|
||||||
public class WalkingMoveStrategy implements MoveStrategy {
|
|
||||||
@Override
|
|
||||||
public void move(final Robot r, int dx, int dy) {
|
|
||||||
while (dx != 0) {
|
|
||||||
if (dx > 0) {
|
|
||||||
turnToDirection(r, Direction.RIGHT);
|
|
||||||
r.move();
|
|
||||||
dx--;
|
|
||||||
} else {
|
|
||||||
turnToDirection(r, Direction.LEFT);
|
|
||||||
r.move();
|
|
||||||
dx++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
while (dy != 0) {
|
|
||||||
if (dy > 0) {
|
|
||||||
turnToDirection(r, Direction.UP);
|
|
||||||
r.move();
|
|
||||||
dy--;
|
|
||||||
} else {
|
|
||||||
turnToDirection(r, Direction.DOWN);
|
|
||||||
r.move();
|
|
||||||
dy++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
turnToDirection(r, Direction.UP);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void turnToDirection(final Robot r, final Direction d) {
|
|
||||||
while (r.getDirection() != d) {
|
|
||||||
r.turnLeft();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,117 +0,0 @@
|
||||||
package h04.template;
|
|
||||||
|
|
||||||
import fopbot.World;
|
|
||||||
import h04.chesspieces.ChessPiece;
|
|
||||||
import h04.chesspieces.King;
|
|
||||||
import h04.chesspieces.Team;
|
|
||||||
import org.jetbrains.annotations.Nullable;
|
|
||||||
|
|
||||||
import java.awt.Color;
|
|
||||||
import java.awt.Point;
|
|
||||||
import java.util.Optional;
|
|
||||||
import java.util.function.Predicate;
|
|
||||||
|
|
||||||
public class ChessUtils {
|
|
||||||
|
|
||||||
public static @Nullable ChessPiece getPieceAt(final int x, final int y) {
|
|
||||||
return World.getGlobalWorld().getField(x, y).getEntities()
|
|
||||||
.stream()
|
|
||||||
.filter(ChessPiece.class::isInstance)
|
|
||||||
.map(ChessPiece.class::cast)
|
|
||||||
.filter(Predicate.not(ChessPiece::isTurnedOff))
|
|
||||||
.findFirst()
|
|
||||||
.orElse(null);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static @Nullable ChessPiece getPieceAt(final Point p) {
|
|
||||||
return getPieceAt(p.x, p.y);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static King[] getKings() {
|
|
||||||
return World.getGlobalWorld().getAllFieldEntities()
|
|
||||||
.stream()
|
|
||||||
.filter(King.class::isInstance)
|
|
||||||
.map(King.class::cast)
|
|
||||||
.toArray(King[]::new);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns the team at the given position, or {@code null} if there is no team.
|
|
||||||
*
|
|
||||||
* @param x the x-coordinate
|
|
||||||
* @param y the y-coordinate
|
|
||||||
* @return the team at the given position, or {@code null} if there is no team
|
|
||||||
*/
|
|
||||||
public static @Nullable Team getTeamAt(final int x, final int y) {
|
|
||||||
return Optional.ofNullable(getPieceAt(x, y))
|
|
||||||
.map(ChessPiece::getTeam)
|
|
||||||
.orElse(null);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static @Nullable Team getTeamAt(final Point p) {
|
|
||||||
return getTeamAt(p.x, p.y);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static Point[] getAllowedMoves(final ChessPiece piece, final Point[] directions, final int maxDistance) {
|
|
||||||
final Point[] moves = new Point[directions.length * maxDistance];
|
|
||||||
int index = 0;
|
|
||||||
for (final var p : directions) {
|
|
||||||
for (int i = 1; i <= maxDistance; i++) {
|
|
||||||
final var pos = new Point(piece.getX() + i * p.x, piece.getY() + i * p.y);
|
|
||||||
if (!isValidCoordinate(pos))
|
|
||||||
break;
|
|
||||||
final var team = getTeamAt(pos);
|
|
||||||
if (team == piece.getTeam())
|
|
||||||
break;
|
|
||||||
moves[index++] = pos;
|
|
||||||
if (team == piece.getTeam().getOpponent())
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return moves;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static boolean isValidCoordinate(final int x, final int y) {
|
|
||||||
return x >= 0 && x < 8 && y >= 0 && y < 8;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static boolean isValidCoordinate(final Point p) {
|
|
||||||
return isValidCoordinate(p.x, p.y);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static Point[] mergePoints(final Point[] a, final Point[] b) {
|
|
||||||
final Point[] result = new Point[a.length + b.length];
|
|
||||||
var index = 0;
|
|
||||||
for (final var p : a) {
|
|
||||||
if (p == null)
|
|
||||||
break;
|
|
||||||
result[index++] = p;
|
|
||||||
}
|
|
||||||
for (final var p : b) {
|
|
||||||
if (p == null)
|
|
||||||
break;
|
|
||||||
result[index++] = p;
|
|
||||||
}
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void setFieldColor(final Point field, final @Nullable Color c) {
|
|
||||||
World.getGlobalWorld().getField(field.x, field.y).setFieldColor(c);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void colorMoveFields(final Point... fields) {
|
|
||||||
for (final Point field : fields) {
|
|
||||||
if (field == null)
|
|
||||||
continue;
|
|
||||||
setFieldColor(field, getPieceAt(field) != null ? Color.RED : Color.GREEN);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void resetFieldColor() {
|
|
||||||
for (int y = 0; y < World.getHeight(); y++) {
|
|
||||||
for (int x = 0; x < World.getWidth(); x++) {
|
|
||||||
setFieldColor(new Point(x, y), null);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,179 +0,0 @@
|
||||||
package h04.template;
|
|
||||||
|
|
||||||
import fopbot.ColorProfile;
|
|
||||||
import fopbot.Robot;
|
|
||||||
import fopbot.World;
|
|
||||||
import h04.GameController;
|
|
||||||
import h04.template.InputHandler;
|
|
||||||
import h04.chesspieces.Bishop;
|
|
||||||
import h04.chesspieces.ChessPiece;
|
|
||||||
import h04.chesspieces.King;
|
|
||||||
import h04.chesspieces.Knight;
|
|
||||||
import h04.chesspieces.Pawn;
|
|
||||||
import h04.chesspieces.Queen;
|
|
||||||
import h04.chesspieces.Rook;
|
|
||||||
import h04.chesspieces.Team;
|
|
||||||
import h04.movement.MoveStrategy;
|
|
||||||
import h04.movement.TeleportingMoveStrategy;
|
|
||||||
import h04.movement.WalkingMoveStrategy;
|
|
||||||
import org.jetbrains.annotations.Nullable;
|
|
||||||
import org.tudalgo.algoutils.student.io.PropertyUtils;
|
|
||||||
|
|
||||||
import java.awt.Color;
|
|
||||||
import java.util.Arrays;
|
|
||||||
import java.util.Objects;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* A {@link GameControllerTemplate} controls the game loop and the {@link Robot}s and checks the win condition.
|
|
||||||
*/
|
|
||||||
public abstract class GameControllerTemplate {
|
|
||||||
/**
|
|
||||||
* The {@link InputHandler} that handles the input of the user.
|
|
||||||
*/
|
|
||||||
private final InputHandler inputHandler = new InputHandler((GameController) this);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The {@link Robot}s that are controlled by the {@link GameControllerTemplate}.
|
|
||||||
*/
|
|
||||||
|
|
||||||
protected Team nextToMove = Team.WHITE;
|
|
||||||
|
|
||||||
protected boolean gameOver = false;
|
|
||||||
|
|
||||||
protected @Nullable ChessPiece selectedPiece;
|
|
||||||
|
|
||||||
protected MoveStrategy moveStrategy = PropertyUtils.getBooleanProperty(
|
|
||||||
"h04.properties",
|
|
||||||
"USE_TELEPORT_MOVE_STRATEGY"
|
|
||||||
) ? new TeleportingMoveStrategy() : new WalkingMoveStrategy();
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Starts the game loop.
|
|
||||||
*/
|
|
||||||
public void startGame() {
|
|
||||||
System.out.println("Starting game...");
|
|
||||||
|
|
||||||
while (!gameOver) {
|
|
||||||
final var point = inputHandler.getNextInput(nextToMove);
|
|
||||||
if (ChessUtils.getTeamAt(point) == nextToMove) {
|
|
||||||
// select piece
|
|
||||||
selectedPiece = ChessUtils.getPieceAt(point);
|
|
||||||
//highlight possible moves
|
|
||||||
final var possibleMoves = Objects.requireNonNull(selectedPiece).getPossibleMoveFields();
|
|
||||||
ChessUtils.resetFieldColor();
|
|
||||||
ChessUtils.colorMoveFields(possibleMoves);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
if (selectedPiece != null) {
|
|
||||||
// check if piece can move to point
|
|
||||||
final var possibleMoves = selectedPiece.getPossibleMoveFields();
|
|
||||||
if (Arrays.stream(possibleMoves)
|
|
||||||
.filter(Objects::nonNull)
|
|
||||||
.noneMatch(point::equals)
|
|
||||||
) {
|
|
||||||
System.out.println("Invalid move");
|
|
||||||
// deselect piece
|
|
||||||
selectedPiece = null;
|
|
||||||
ChessUtils.resetFieldColor();
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
// valid move selected, move piece
|
|
||||||
final var oldPiece = ChessUtils.getPieceAt(point);
|
|
||||||
selectedPiece.moveStrategy(
|
|
||||||
point.x - selectedPiece.getX(),
|
|
||||||
point.y - selectedPiece.getY(),
|
|
||||||
moveStrategy
|
|
||||||
);
|
|
||||||
if (oldPiece != null) {
|
|
||||||
oldPiece.turnOff();
|
|
||||||
}
|
|
||||||
if (selectedPiece instanceof Pawn && (selectedPiece.getY() == 0 || selectedPiece.getY() == World.getHeight() - 1)) {
|
|
||||||
selectedPiece.turnOff();
|
|
||||||
new Queen(selectedPiece.getX(), selectedPiece.getY(), selectedPiece.getTeam());
|
|
||||||
}
|
|
||||||
ChessUtils.resetFieldColor();
|
|
||||||
if (checkWinCondition()) stopGame(nextToMove);
|
|
||||||
|
|
||||||
|
|
||||||
nextToMove = nextToMove.getOpponent();
|
|
||||||
selectedPiece = null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public abstract boolean checkWinCondition();
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Stops the game loop.
|
|
||||||
*/
|
|
||||||
public void stopGame(final Team winner) {
|
|
||||||
gameOver = true;
|
|
||||||
inputHandler.setStatusText(winner.name() + " wins!");
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Sets up the game.
|
|
||||||
*/
|
|
||||||
protected void setup() {
|
|
||||||
setupWorld();
|
|
||||||
setupTheme();
|
|
||||||
setupPieces();
|
|
||||||
//this.inputHandler.install();
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setupTheme() {
|
|
||||||
//noinspection UnstableApiUsage
|
|
||||||
World.getGlobalWorld().setColorProfile(
|
|
||||||
ColorProfile.DEFAULT.toBuilder()
|
|
||||||
.fieldColorLight(Color.decode("#e0ba97"))
|
|
||||||
.fieldColorDark(Color.decode("#8d4d2a"))
|
|
||||||
.customFieldColorPattern(
|
|
||||||
(cp, p) -> (p.x + p.y) % 2 == 0 ? cp.fieldColorLight() : cp.fieldColorDark()
|
|
||||||
)
|
|
||||||
.backgroundColorDark(Color.decode("#8d4d2a"))
|
|
||||||
.backgroundColorLight(Color.decode("#8d4d2a"))
|
|
||||||
.innerBorderColorLight(new Color(0, 0, 0, 0))
|
|
||||||
.innerBorderColorDark(new Color(0, 0, 0, 0))
|
|
||||||
.fieldBorderThickness(0)
|
|
||||||
.outerBorderColorDark(Color.BLACK)
|
|
||||||
.outerBorderColorLight(Color.BLACK)
|
|
||||||
.build()
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Initializes the {@link World} and adds the {@link Robot}s to it.
|
|
||||||
*/
|
|
||||||
public void setupWorld() {
|
|
||||||
World.setSize(8, 8);
|
|
||||||
|
|
||||||
World.setDelay(0);
|
|
||||||
World.setVisible(true);
|
|
||||||
World.getGlobalWorld().setDrawTurnedOffRobots(false);
|
|
||||||
inputHandler.install();
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setupPieces() {
|
|
||||||
for (final int y : new int[]{0, 1, World.getHeight() - 2, World.getHeight() - 1}) {
|
|
||||||
for (int x = 0; x < World.getWidth(); x++) {
|
|
||||||
if (y == 1 || y == World.getHeight() - 2)
|
|
||||||
new Pawn(x, y, y == 1 ? Team.WHITE : Team.BLACK);
|
|
||||||
else if (x == 0 || x == World.getWidth() - 1) {
|
|
||||||
new Rook(x, y, y == 0 ? Team.WHITE : Team.BLACK);
|
|
||||||
} else if (x == 1 || x == World.getWidth() - 2) {
|
|
||||||
new Knight(x, y, y == 0 ? Team.WHITE : Team.BLACK);
|
|
||||||
} else if (x == 2 || x == World.getWidth() - 3) {
|
|
||||||
new Bishop(x, y, y == 0 ? Team.WHITE : Team.BLACK);
|
|
||||||
} else if (x == 3) {
|
|
||||||
new Queen(x, y, y == 0 ? Team.WHITE : Team.BLACK);
|
|
||||||
} else if (x == World.getWidth() - 4) {
|
|
||||||
new King(x, y, y == 0 ? Team.WHITE : Team.BLACK);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
|
@ -1,68 +0,0 @@
|
||||||
package h04.template;
|
|
||||||
|
|
||||||
import fopbot.World;
|
|
||||||
import h04.GameController;
|
|
||||||
import h04.chesspieces.Team;
|
|
||||||
|
|
||||||
import java.awt.Color;
|
|
||||||
import java.awt.Point;
|
|
||||||
import java.util.concurrent.BlockingDeque;
|
|
||||||
import java.util.concurrent.LinkedBlockingDeque;
|
|
||||||
import javax.swing.JLabel;
|
|
||||||
import java.beans.PropertyChangeEvent;
|
|
||||||
|
|
||||||
public class InputHandler {
|
|
||||||
/**
|
|
||||||
* The input queue.
|
|
||||||
*/
|
|
||||||
private final BlockingDeque<Point> inputQueue = new LinkedBlockingDeque<>();
|
|
||||||
|
|
||||||
public final GameController controller;
|
|
||||||
|
|
||||||
private final JLabel statusLabel = new JLabel("");
|
|
||||||
|
|
||||||
public InputHandler(final GameController controller) {
|
|
||||||
this.controller = controller;
|
|
||||||
}
|
|
||||||
|
|
||||||
@SuppressWarnings("UnstableApiUsage")
|
|
||||||
public void install() {
|
|
||||||
final var guiPanel = World.getGlobalWorld().getGuiPanel();
|
|
||||||
World.getGlobalWorld().getInputHandler().addFieldClickListener(e -> addInput(e.getField().getX(), e.getField().getY()));
|
|
||||||
statusLabel.setFont(statusLabel.getFont().deriveFont(20.0f));
|
|
||||||
guiPanel.add(statusLabel, JLabel.CENTER);
|
|
||||||
guiPanel.addDarkModeChangeListener(this::onDarkModeChange);
|
|
||||||
// trigger dark mode change to set the correct color
|
|
||||||
guiPanel.setDarkMode(World.getGlobalWorld().getGuiPanel().isDarkMode());
|
|
||||||
}
|
|
||||||
|
|
||||||
public void onDarkModeChange(final PropertyChangeEvent e) {
|
|
||||||
final var darkMode = (boolean) e.getNewValue();
|
|
||||||
statusLabel.setForeground(darkMode ? Color.white : Color.black);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void addInput(final int x, final int y) {
|
|
||||||
inputQueue.add(new Point(x,y));
|
|
||||||
System.out.println("Added input: "+x+","+y);
|
|
||||||
}
|
|
||||||
|
|
||||||
public Point getNextInput(final Team currentPlayer) {
|
|
||||||
|
|
||||||
statusLabel.setText(currentPlayer.name()+" to move.");
|
|
||||||
|
|
||||||
try {
|
|
||||||
return inputQueue.take();
|
|
||||||
} catch (final InterruptedException e) {
|
|
||||||
throw new RuntimeException(e);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
public JLabel getStatusLabel() {
|
|
||||||
return statusLabel;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setStatusText(final String s) {
|
|
||||||
statusLabel.setText(s);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,2 +0,0 @@
|
||||||
# Whether to use the TeleportMoveStrategy or not. If not, the WalkingMoveStrategy will be used.
|
|
||||||
USE_TELEPORT_MOVE_STRATEGY=false
|
|
|
@ -1,46 +0,0 @@
|
||||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
|
||||||
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
|
||||||
|
|
||||||
<svg
|
|
||||||
width="24.200001mm"
|
|
||||||
height="25.799999mm"
|
|
||||||
viewBox="0 0 24.200001 25.799998"
|
|
||||||
version="1.1"
|
|
||||||
id="svg1"
|
|
||||||
inkscape:version="1.3.2 (091e20e, 2023-11-25, custom)"
|
|
||||||
sodipodi:docname="Bishop.svg"
|
|
||||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
|
||||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
|
||||||
xmlns="http://www.w3.org/2000/svg"
|
|
||||||
xmlns:svg="http://www.w3.org/2000/svg">
|
|
||||||
<sodipodi:namedview
|
|
||||||
id="namedview1"
|
|
||||||
pagecolor="#ffffff"
|
|
||||||
bordercolor="#000000"
|
|
||||||
borderopacity="0.25"
|
|
||||||
inkscape:showpageshadow="2"
|
|
||||||
inkscape:pageopacity="0.0"
|
|
||||||
inkscape:pagecheckerboard="0"
|
|
||||||
inkscape:deskcolor="#d1d1d1"
|
|
||||||
inkscape:document-units="mm"
|
|
||||||
inkscape:zoom="2.9255612"
|
|
||||||
inkscape:cx="14.698035"
|
|
||||||
inkscape:cy="43.923197"
|
|
||||||
inkscape:window-width="1920"
|
|
||||||
inkscape:window-height="1017"
|
|
||||||
inkscape:window-x="-8"
|
|
||||||
inkscape:window-y="-8"
|
|
||||||
inkscape:window-maximized="1"
|
|
||||||
inkscape:current-layer="layer1" />
|
|
||||||
<defs
|
|
||||||
id="defs1" />
|
|
||||||
<g
|
|
||||||
inkscape:label="Ebene 1"
|
|
||||||
inkscape:groupmode="layer"
|
|
||||||
id="layer1">
|
|
||||||
<path
|
|
||||||
d="m 10.443893,15.8801 c -1.1613884,0 -1.7420694,0.182173 -1.742043,0.546523 -3.17e-5,0.318796 0.5123392,0.512366 1.537097,0.580681 h 1.878673 c 2.277136,0 3.415771,-0.193564 3.415771,-0.580681 C 15.533359,16.062265 14.952683,15.8801 13.791348,15.8801 H 10.44384 m 0,-2.117778 c -1.0019768,0 -1.5599037,0.113863 -1.6737275,0.341577 -0.045572,0.04555 -0.068347,0.113861 -0.068315,0.204949 -3.17e-5,0.250489 0.2390749,0.398515 0.7173119,0.44405 0.5920316,0.06831 1.4915356,0.102473 2.6984846,0.102473 1.20695,0 2.117751,-0.03416 2.732617,-0.102473 0.4554,-0.04554 0.683127,-0.193561 0.683154,-0.44405 -3.2e-5,-0.364358 -0.580708,-0.546524 -1.742044,-0.546524 h -3.347507 m 6.353438,1.468782 0.683155,2.630143 c -2.7e-5,0.797005 -0.808435,1.263836 -2.425198,1.400466 1.184117,0.455428 2.28854,0.683154 3.313377,0.683154 0.136607,0 0.808382,-0.03416 2.015305,-0.102476 1.001924,0 1.821709,0.523743 2.459355,1.571255 0.09106,0.182171 0.204923,0.387112 0.341577,0.614839 l -1.229677,1.878674 c -0.364384,0.455427 -0.751496,0.751469 -1.161362,0.8881 -0.09112,-0.478208 -0.819812,-0.774224 -2.186094,-0.8881 l -0.819785,-0.06831 c -2.800879,-0.227716 -4.691062,-0.831162 -5.670285,-1.810359 -0.888127,0.933636 -2.2430573,1.468782 -4.0647929,1.605413 -0.4098925,0.04555 -0.9450391,0.11386 -1.6054121,0.204948 -1.662351,0.136629 -2.630144,0.375735 -2.903273,0.717312 -0.04554,0.06831 -0.07971,0.148016 -0.102476,0.239102 C 2.849608,24.544778 2.291681,23.975482 1.7679389,23.087381 1.5629899,22.723024 1.3238879,22.370069 1.0506269,22.028492 1.6654649,20.889911 2.325839,20.206757 3.031774,19.97903 3.282271,19.88794 3.555516,19.842399 3.851559,19.842399 l 2.015304,0.102476 c 1.047486,0 2.1519361,-0.227721 3.3133775,-0.683154 C 7.5634512,19.125093 6.755043,18.658259 6.755043,17.861255 c 0,-0.06831 0.182174,-0.648996 0.5465236,-1.742043 0.1138555,-0.364358 0.1707885,-0.614839 0.1707885,-0.75147 C 6.083266,13.682638 5.388735,12.191155 5.388735,10.893109 5.388735,9.3901699 6.128827,8.0239674 7.608986,6.7941841 8.929733,5.6783538 9.8861488,5.0862957 10.478128,5.0179803 9.9771126,4.4031415 9.7266316,3.7655222 9.726658,3.1051486 c -2.64e-5,-1.070266 0.53512,-1.7306396 1.605411,-1.9811471 0.25046,-0.068289 0.51234,-0.1024414 0.785628,-0.1024705 1.138555,2.91e-5 1.878647,0.4212696 2.220251,1.2638353 l 0.170788,0.7173119 v 0.1024731 c -2.6e-5,0.6376194 -0.250518,1.2752123 -0.751469,1.9128316 0.432646,0.1138582 1.081616,0.4668309 1.946989,1.058889 2.094971,1.4573779 3.142456,3.0628166 3.142456,4.8162101 -2.6e-5,1.320774 -0.68318,2.766748 -2.049462,4.338109 m -4.064794,-3.176588 v -1.571255 h 1.19552 V 9.1853556 h -1.19552 V 7.7165741 H 11.502779 V 9.1853556 H 10.30726 v 1.2979924 h 1.195519 v 1.571255 h 1.229677 M 12.117617,2.4221823 c -0.455453,0 -0.740119,0.204941 -0.853942,0.6148388 l -0.03415,0.2049409 c -2.9e-5,0.4326732 0.227687,0.7059348 0.683154,0.819785 0.06829,0.022773 0.136602,0.034155 0.204949,0.034155 0.569251,0 0.853916,-0.2846388 0.853942,-0.8539427 -2.9e-5,-0.5465233 -0.284691,-0.819785 -0.853942,-0.819785"
|
|
||||||
id="path4"
|
|
||||||
style="stroke-width:0.264583" />
|
|
||||||
</g>
|
|
||||||
</svg>
|
|
Before Width: | Height: | Size: 4.2 KiB |
|
@ -1,47 +0,0 @@
|
||||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
|
||||||
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
|
||||||
|
|
||||||
<svg
|
|
||||||
width="24.066mm"
|
|
||||||
height="25.671mm"
|
|
||||||
viewBox="0 0 24.066 25.670999"
|
|
||||||
version="1.1"
|
|
||||||
id="svg1"
|
|
||||||
inkscape:version="1.3.2 (091e20e, 2023-11-25, custom)"
|
|
||||||
sodipodi:docname="WhiteBishop.svg"
|
|
||||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
|
||||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
|
||||||
xmlns="http://www.w3.org/2000/svg"
|
|
||||||
xmlns:svg="http://www.w3.org/2000/svg">
|
|
||||||
<sodipodi:namedview
|
|
||||||
id="namedview1"
|
|
||||||
pagecolor="#ffffff"
|
|
||||||
bordercolor="#000000"
|
|
||||||
borderopacity="0.25"
|
|
||||||
inkscape:showpageshadow="2"
|
|
||||||
inkscape:pageopacity="0.0"
|
|
||||||
inkscape:pagecheckerboard="0"
|
|
||||||
inkscape:deskcolor="#d1d1d1"
|
|
||||||
inkscape:document-units="mm"
|
|
||||||
inkscape:zoom="16.549473"
|
|
||||||
inkscape:cx="64.08059"
|
|
||||||
inkscape:cy="78.461713"
|
|
||||||
inkscape:window-width="1920"
|
|
||||||
inkscape:window-height="1017"
|
|
||||||
inkscape:window-x="-8"
|
|
||||||
inkscape:window-y="-8"
|
|
||||||
inkscape:window-maximized="1"
|
|
||||||
inkscape:current-layer="layer1" />
|
|
||||||
<defs
|
|
||||||
id="defs1" />
|
|
||||||
<g
|
|
||||||
inkscape:label="Ebene 1"
|
|
||||||
inkscape:groupmode="layer"
|
|
||||||
id="layer1"
|
|
||||||
transform="translate(-63.764586,-42.333335)">
|
|
||||||
<path
|
|
||||||
d="m 75.772721,56.969419 c -1.594061,0 -2.83501,-0.06832 -3.723216,-0.204946 0.159371,0.318797 0.239075,0.592058 0.239101,0.819785 -2.6e-5,0.341577 -0.06834,0.626216 -0.204941,0.853943 0.660347,-0.204946 1.890025,-0.307419 3.689085,-0.307419 1.799061,0 3.028686,0.102475 3.689086,0.307419 -0.136658,-0.227719 -0.20497,-0.512366 -0.204944,-0.853943 -2.6e-5,-0.273261 0.06829,-0.546523 0.204944,-0.819785 -1.070293,0.136628 -2.29997,0.204946 -3.689086,0.204946 m 0,-12.365037 c -0.478234,0 -0.808434,0.216326 -0.990573,0.648997 -0.04557,0.113858 -0.06834,0.227721 -0.06832,0.341577 -2.6e-5,0.500988 0.25046,0.831162 0.75147,0.990573 0.09106,0.02278 0.193535,0.03416 0.307419,0.03416 0.523717,0 0.865294,-0.23911 1.024732,-0.717312 0.02273,-0.09109 0.03413,-0.193564 0.03416,-0.30742 -3.4e-5,-0.455427 -0.227748,-0.762846 -0.683154,-0.922258 -0.136657,-0.04554 -0.261906,-0.06831 -0.375735,-0.06831 m 0,14.516894 c -0.865346,0 -1.981173,0.0797 -3.347508,0.239104 -0.387112,0.04555 -0.614839,0.261877 -0.683154,0.648996 0,0.273262 0.626189,0.444051 1.878674,0.512366 -0.113888,-0.02278 -0.06834,-0.03416 0.136633,-0.03416 h 2.015305 c 2.664354,0 3.996531,-0.159401 3.996531,-0.478208 -3.2e-5,-0.523743 -0.6604,-0.808408 -1.981147,-0.853943 h -0.990574 c -0.296068,0 -0.546549,-0.01138 -0.751469,-0.03416 h -0.273258 m -0.03416,-3.142457 c 2.550424,0 4.110302,-0.239101 4.679685,-0.717311 0.387086,-0.296043 0.671724,-1.08167 0.853943,-2.356882 -0.113887,-1.138582 -0.853969,-2.231628 -2.220251,-3.279246 -1.275239,-1.001951 -2.391066,-1.559878 -3.347508,-1.673728 -0.888127,0.113861 -1.969797,0.671777 -3.24485,1.673728 -1.343528,1.047512 -2.072217,2.140558 -2.186094,3.279246 0.159406,1.184142 0.409893,1.935612 0.75147,2.254408 0.09109,0.09109 0.193561,0.170789 0.307419,0.239102 0.569304,0.387138 2.038059,0.580681 4.406371,0.580681 m -0.580681,-1.673728 v -1.502939 h -1.161362 v -1.332151 h 1.161362 V 50.00122 h 1.229677 v 1.468781 h 1.161363 v 1.332151 h -1.161363 v 1.502939 h -1.229677 m 0.546523,6.968067 c -0.20497,0 -0.808434,0.398515 -1.810358,1.195519 -0.705961,0.478208 -1.844516,0.762847 -3.415771,0.853943 -1.138581,0 -2.049462,0.05693 -2.732617,0.170789 -0.728689,0.159401 -1.093046,0.466831 -1.093046,0.922258 0.06831,0.455427 0.307419,0.683154 0.717312,0.683154 l 1.810358,-0.273262 c 1.184116,0 2.425197,-0.159401 3.723217,-0.478208 1.480132,-0.387111 2.436548,-1.00195 2.869141,-1.844516 0.614813,1.206924 2.208821,1.935612 4.782079,2.186094 l 0.888101,0.136633 h 0.8881 l 1.844516,0.273262 c 0.409867,0 0.64897,-0.227719 0.717312,-0.683155 -2.6e-5,-0.455427 -0.364384,-0.762846 -1.093046,-0.922258 L 80.144993,63.22015 C 78.983604,63.12906 77.867777,62.673626 76.797484,61.853841 76.31925,61.466703 75.954892,61.27316 75.704438,61.27316 m 0.06832,2.9718 c -0.888127,0.888101 -2.231655,1.434624 -4.030663,1.63957 -0.728689,0.06831 -2.003927,0.227717 -3.82561,0.478208 -0.478208,0.09109 -0.75147,0.30742 -0.819785,0.648997 -0.432673,-0.113858 -1.070266,-0.819785 -1.912832,-2.117778 -0.204946,-0.318797 -0.352954,-0.535146 -0.44405,-0.648997 0.75147,-1.434623 1.685105,-2.151935 2.800879,-2.151935 l 2.015305,0.102473 c 0.933635,0 2.026682,-0.216334 3.279246,-0.648997 C 71.218458,61.341558 70.41005,60.85197 70.41005,60.07772 l 0.683155,-2.595986 v -0.06832 c -1.366309,-1.502939 -2.049463,-2.914914 -2.049463,-4.235449 0,-1.50294 0.740093,-2.869142 2.220251,-4.098925 1.297967,-1.093047 2.254382,-1.673728 2.869142,-1.742044 -0.501015,-0.614838 -0.751496,-1.252431 -0.75147,-1.912831 -2.9e-5,-1.047512 0.523716,-1.707886 1.571255,-1.981147 0.25046,-0.06829 0.523716,-0.102447 0.819785,-0.102476 1.115801,2.9e-5 1.84449,0.42127 2.186093,1.263835 l 0.170789,0.717312 v 0.102468 c -2.7e-5,0.705935 -0.239136,1.343528 -0.717312,1.912832 0.614812,0.06832 1.582605,0.660373 2.903537,1.7762 1.457352,1.206897 2.186067,2.561828 2.186094,4.064794 -3e-5,1.275212 -0.683181,2.687108 -2.049463,4.23545 -2.6e-5,0.318823 0.113832,0.77425 0.341577,1.366308 0.22769,0.728689 0.341551,1.161362 0.341577,1.297993 -2.6e-5,0.77425 -0.808434,1.263835 -2.425197,1.468782 1.229651,0.432673 2.322698,0.648996 3.279246,0.648996 l 2.015304,-0.102473 c 1.115801,0 2.049437,0.717312 2.80088,2.151936 l -1.161362,1.7762 c -0.387139,0.500989 -0.785654,0.831162 -1.19552,0.990574 -0.09112,-0.455427 -0.751496,-0.740093 -1.981147,-0.853943 0.159371,0 -0.182203,-0.03416 -1.024732,-0.102473 -2.846387,-0.273262 -4.73657,-0.876723 -5.670285,-1.810358"
|
|
||||||
id="path10"
|
|
||||||
style="stroke-width:0.264583" />
|
|
||||||
</g>
|
|
||||||
</svg>
|
|
Before Width: | Height: | Size: 5.7 KiB |
|
@ -1,46 +0,0 @@
|
||||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
|
||||||
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
|
||||||
|
|
||||||
<svg
|
|
||||||
width="22.9mm"
|
|
||||||
height="24.5mm"
|
|
||||||
viewBox="0 0 22.9 24.5"
|
|
||||||
version="1.1"
|
|
||||||
id="svg1"
|
|
||||||
inkscape:version="1.3.2 (091e20e, 2023-11-25, custom)"
|
|
||||||
sodipodi:docname="King.svg"
|
|
||||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
|
||||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
|
||||||
xmlns="http://www.w3.org/2000/svg"
|
|
||||||
xmlns:svg="http://www.w3.org/2000/svg">
|
|
||||||
<sodipodi:namedview
|
|
||||||
id="namedview1"
|
|
||||||
pagecolor="#ffffff"
|
|
||||||
bordercolor="#000000"
|
|
||||||
borderopacity="0.25"
|
|
||||||
inkscape:showpageshadow="2"
|
|
||||||
inkscape:pageopacity="0.0"
|
|
||||||
inkscape:pagecheckerboard="0"
|
|
||||||
inkscape:deskcolor="#d1d1d1"
|
|
||||||
inkscape:document-units="mm"
|
|
||||||
inkscape:zoom="4.1373683"
|
|
||||||
inkscape:cx="-19.698512"
|
|
||||||
inkscape:cy="69.005218"
|
|
||||||
inkscape:window-width="1920"
|
|
||||||
inkscape:window-height="1017"
|
|
||||||
inkscape:window-x="-8"
|
|
||||||
inkscape:window-y="-8"
|
|
||||||
inkscape:window-maximized="1"
|
|
||||||
inkscape:current-layer="layer1" />
|
|
||||||
<defs
|
|
||||||
id="defs1" />
|
|
||||||
<g
|
|
||||||
inkscape:label="Ebene 1"
|
|
||||||
inkscape:groupmode="layer"
|
|
||||||
id="layer1">
|
|
||||||
<path
|
|
||||||
d="m 12.33603,14.91848 c 0,0.4099 -0.284639,0.61484 -0.853943,0.61484 -0.637619,0 -0.956416,-0.20494 -0.956416,-0.61484 0,-1.89005 -0.6262164,-3.42714 -1.8786744,-4.61116 C 7.5311692,9.3053702 6.4495262,8.8043902 5.4021462,8.8043902 c -1.548474,0 -2.516293,0.61483 -2.903273,1.8445098 l -0.13663,0.92226 v 0.0683 c 0,0.91085 0.671777,2.17471 2.015304,3.79147 0.364358,0.4099 0.671777,0.72869 0.922258,0.95642 0.364358,0.29602 0.967793,0.44405 1.810359,0.44405 0.8881,0 2.3227244,-0.17079 4.3039778,-0.51237 2.003928,0.34158 3.449904,0.51237 4.338104,0.51237 0.86532,0 1.46879,-0.14802 1.81036,-0.44405 0.95642,-0.84257 1.75342,-1.8673 2.39104,-3.07419 0.36436,-0.68316 0.54653,-1.24106 0.54653,-1.67373 0,-1.43462 -0.649,-2.3340998 -1.94699,-2.6984898 -0.34158,-0.0911 -0.70594,-0.13663 -1.09305,-0.13663 -1.04749,0 -2.11778,0.51237 -3.210719,1.5370998 -1.275212,1.13858 -1.912832,2.66435 -1.912832,4.57702 m 7.412301,-3.27924 c 0,0.91085 -0.62621,1.98115 -1.87867,3.21072 l -0.8881,0.75147 -0.34158,0.20494 c -0.43267,0.0683 -0.8881,0.10247 -1.36631,0.10247 -1.411842,0 -2.117776,-0.28464 -2.117776,-0.85394 0.04554,-1.75342 0.569304,-3.1197 1.571256,-4.09893 0.86532,-0.86534 1.75342,-1.2979898 2.66435,-1.2979898 1.16136,0 1.90146,0.4212698 2.22025,1.2638398 l 0.13664,0.71731 m -3.24485,8.67595 c 0,-0.59206 -1.67373,-0.8881 -5.021266,-0.8881 -0.910881,0 -1.7192624,0.0342 -2.4251974,0.10247 l -0.819785,0.0683 c -1.2296774,0.1594 -1.8445164,0.38711 -1.8445164,0.68315 0,0.34158 0.307419,0.51237 0.922258,0.51237 l 4.1330568,-0.34158 4.09893,0.34158 c 0.63759,0 0.95641,-0.1594 0.95641,-0.47821 m 1.91283,0.81978 c -0.0455,1.54848 -2.36826,2.32273 -6.968064,2.32273 -4.5542738,0 -6.8656738,-0.77425 -6.9339358,-2.32273 -0.02277,-1.4574 -0.239104,-2.75537 -0.648997,-3.89387 -0.250489,-0.61484 -0.728689,-1.40046 -1.434623,-2.35688 -0.888101,-1.2069 -1.332151,-2.27719 -1.332151,-3.21072 0,-1.4574 0.626216,-2.5846098 1.878674,-3.3816398 0.705935,-0.45543 1.491562,-0.68315 2.356882,-0.68315 1.184142,0 2.311347,0.43267 3.3816394,1.29799 0,-1.04751 0.102473,-1.76482 0.30742,-2.1519405 0.159401,-0.43267 0.683154,-0.95641 1.5712544,-1.57125 v -0.78563 l -1.4004664,-0.85394 v -1.22968 h 1.2638354 l 0.409893,-1.26383 h 1.161362 l 0.44405,1.26383 h 1.229678 v 1.22968 l -1.366309,0.85394 v 0.78563 c 0.86532,0.63762 1.400466,1.18414 1.605413,1.63957 l 0.239104,0.9905705 c 0.02278,0.27326 0.04555,0.63762 0.06831,1.09305 1.070271,-0.86532 2.174721,-1.29799 3.313381,-1.29799 1.52569,0 2.70986,0.58068 3.5523,1.74204 0.4782,0.6831498 0.71731,1.4573998 0.71731,2.3227198 0,0.93364 -0.44405,2.01531 -1.33215,3.24485 l -0.78563,1.09305 c -0.84254,1.27521 -1.27521,2.98318 -1.29799,5.12366 M 3.1484232,11.63895 c 0,-0.95641 0.478208,-1.57125 1.434624,-1.8445098 0.273261,-0.0911 0.5579,-0.13664 0.853942,-0.13664 0.956416,0 1.867297,0.4326698 2.7326174,1.2979898 0.979197,1.00196 1.491562,2.36826 1.537097,4.09893 0.02278,0.50099 -0.500989,0.78563 -1.5712554,0.85394 h -0.512365 c -0.455427,0 -0.922258,-0.0342 -1.400466,-0.10247 -0.75147,-0.36436 -1.502939,-1.08167 -2.254409,-2.15194 -0.546523,-0.797 -0.819785,-1.46878 -0.819785,-2.0153"
|
|
||||||
id="path1"
|
|
||||||
style="stroke-width:0.264583" />
|
|
||||||
</g>
|
|
||||||
</svg>
|
|
Before Width: | Height: | Size: 4.3 KiB |
|
@ -1,47 +0,0 @@
|
||||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
|
||||||
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
|
||||||
|
|
||||||
<svg
|
|
||||||
width="22.698999mm"
|
|
||||||
height="24.476mm"
|
|
||||||
viewBox="0 0 22.699 24.475999"
|
|
||||||
version="1.1"
|
|
||||||
id="svg1"
|
|
||||||
inkscape:version="1.3.2 (091e20e, 2023-11-25, custom)"
|
|
||||||
sodipodi:docname="WhiteKing.svg"
|
|
||||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
|
||||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
|
||||||
xmlns="http://www.w3.org/2000/svg"
|
|
||||||
xmlns:svg="http://www.w3.org/2000/svg">
|
|
||||||
<sodipodi:namedview
|
|
||||||
id="namedview1"
|
|
||||||
pagecolor="#ffffff"
|
|
||||||
bordercolor="#000000"
|
|
||||||
borderopacity="0.25"
|
|
||||||
inkscape:showpageshadow="2"
|
|
||||||
inkscape:pageopacity="0.0"
|
|
||||||
inkscape:pagecheckerboard="0"
|
|
||||||
inkscape:deskcolor="#d1d1d1"
|
|
||||||
inkscape:document-units="mm"
|
|
||||||
inkscape:zoom="2.9255612"
|
|
||||||
inkscape:cx="-65.799342"
|
|
||||||
inkscape:cy="55.544899"
|
|
||||||
inkscape:window-width="1920"
|
|
||||||
inkscape:window-height="1017"
|
|
||||||
inkscape:window-x="-8"
|
|
||||||
inkscape:window-y="-8"
|
|
||||||
inkscape:window-maximized="1"
|
|
||||||
inkscape:current-layer="layer1" />
|
|
||||||
<defs
|
|
||||||
id="defs1" />
|
|
||||||
<g
|
|
||||||
inkscape:label="Ebene 1"
|
|
||||||
inkscape:groupmode="layer"
|
|
||||||
id="layer1"
|
|
||||||
transform="translate(-72.23125,-105.56879)">
|
|
||||||
<path
|
|
||||||
d="m 83.564504,129.03939 c -4.531519,0 -6.831542,-0.76285 -6.899804,-2.28857 -0.113861,-2.09499 -0.466831,-3.67771 -1.058889,-4.74795 -0.250489,-0.43267 -0.603462,-0.95641 -1.058889,-1.57125 -0.77425,-1.02473 -1.206897,-1.89005 -1.297993,-2.59599 -0.02277,-0.18217 -0.03416,-0.37573 -0.03416,-0.58068 0,-1.43462 0.603461,-2.56182 1.810358,-3.38164 0.296043,-0.18217 0.603462,-0.3302 0.922258,-0.44405 1.206897,-0.43267 2.402417,-0.36435 3.586427,0.20495 0.432674,0.20494 0.86532,0.47821 1.297993,0.81979 l 0.03416,0.0342 c 0,-0.47821 0.02277,-0.99058 0.06831,-1.5371 0,-0.15941 0.0797,-0.37573 0.239101,-0.649 0.364358,-0.59205 0.797005,-1.05888 1.297993,-1.40046 0.09109,-0.0455 0.182174,-0.10248 0.273262,-0.17079 v -0.81978 l -1.400466,-0.81979 V 107.8616 H 82.608 l 0.44405,-1.29799 h 1.024732 l 0.44405,1.29799 h 1.263835 v 1.22968 l -1.400466,0.81979 v 0.81978 c 1.184143,0.75147 1.787578,1.50294 1.810358,2.25441 0.04554,0.45543 0.06832,0.95641 0.06832,1.50294 l 0.03416,-0.0342 c 1.434624,-1.2069 2.937669,-1.59401 4.508765,-1.16136 0.409892,0.11385 0.797004,0.28463 1.161362,0.51236 1.275212,0.77422 1.924209,1.92421 1.946989,3.4499 0,0.91088 -0.455427,1.99253 -1.366308,3.24485 -0.75147,1.04752 -1.218301,1.81036 -1.400466,2.28857 -0.387112,1.02473 -0.614839,2.34548 -0.683154,3.9624 -0.04554,1.52572 -2.345505,2.28857 -6.899804,2.28857 m 0,-11.51123 0.990573,-1.57126 c 0.159404,-0.34157 0.284639,-0.66037 0.375735,-0.95641 0.04555,-0.1594 0.06832,-0.48959 0.06832,-0.99057 0,-1.34353 -0.466831,-2.01531 -1.400466,-2.01531 -0.97917,0 -1.468782,0.67178 -1.468782,2.01531 0,0.50098 0.02278,0.83116 0.06832,0.99057 0.182173,0.61484 0.569304,1.34353 1.161362,2.18609 0.136633,0.15941 0.204949,0.27326 0.204949,0.34158 m 9.120187,-0.0683 c 0,-1.02473 -0.341577,-1.81035 -1.024731,-2.35688 -0.569278,-0.47821 -1.241055,-0.71731 -2.015305,-0.71731 -0.97917,0 -2.038085,0.50096 -3.176588,1.50294 -1.343527,1.16136 -2.1064,2.73262 -2.288566,4.71382 0,0.1594 0.42127,0.34157 1.263835,0.54652 0.979197,0.18218 2.641521,0.27326 4.987131,0.27326 l 1.537097,-2.04946 c 0.478208,-0.72869 0.717312,-1.36631 0.717312,-1.91283 m -9.120187,4.61115 c -0.569304,0.2505 -2.299944,0.46684 -5.191919,0.649 -0.432673,0.0228 -0.785627,0.0455 -1.058889,0.0683 0.227722,0.86532 0.375735,1.82173 0.44405,2.86914 1.571255,-0.50099 3.506788,-0.75147 5.806811,-0.75147 2.345478,0 4.281223,0.25049 5.80681,0.75147 0.06831,-1.13858 0.216331,-2.095 0.44405,-2.86914 l -5.055393,-0.4099 c -0.432674,-0.0683 -0.831163,-0.17078 -1.19552,-0.30742 m -9.120188,-4.61115 c 0,0.70593 0.557901,1.7762 1.673728,3.21072 0.273262,0.34157 0.466831,0.59208 0.580681,0.75146 h 0.614839 c 2.345505,0 4.053416,-0.1594 5.123656,-0.4782 0.341577,-0.0911 0.512366,-0.20494 0.512366,-0.34158 -0.182177,-1.98115 -0.945039,-3.5523 -2.288567,-4.71382 -1.115827,-1.00195 -2.174716,-1.50294 -3.176587,-1.50294 -0.318797,0 -0.660374,0.0683 -1.024732,0.20495 -0.910881,0.22772 -1.525719,0.83116 -1.844516,1.81036 l -0.170788,0.92226 v 0.13663 m 9.120187,10.3497 c 2.140532,0 3.620823,-0.13663 4.440502,-0.40989 0.204946,-0.0683 0.30742,-0.14802 0.30742,-0.23911 0,-0.59206 -1.571255,-0.8881 -4.713817,-0.8881 -1.206897,0 -2.379636,0.0797 -3.518165,0.23911 -0.842565,0.13662 -1.263835,0.35295 -1.263835,0.64899 0,0.34158 1.343528,0.5579 4.030663,0.649 h 0.717311"
|
|
||||||
id="path7"
|
|
||||||
style="stroke-width:0.264583" />
|
|
||||||
</g>
|
|
||||||
</svg>
|
|
Before Width: | Height: | Size: 4.6 KiB |
|
@ -1,46 +0,0 @@
|
||||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
|
||||||
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
|
||||||
|
|
||||||
<svg
|
|
||||||
width="22.5mm"
|
|
||||||
height="22.200001mm"
|
|
||||||
viewBox="0 0 22.5 22.200001"
|
|
||||||
version="1.1"
|
|
||||||
id="svg1"
|
|
||||||
inkscape:version="1.3.2 (091e20e, 2023-11-25, custom)"
|
|
||||||
sodipodi:docname="Knight.svg"
|
|
||||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
|
||||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
|
||||||
xmlns="http://www.w3.org/2000/svg"
|
|
||||||
xmlns:svg="http://www.w3.org/2000/svg">
|
|
||||||
<sodipodi:namedview
|
|
||||||
id="namedview1"
|
|
||||||
pagecolor="#ffffff"
|
|
||||||
bordercolor="#000000"
|
|
||||||
borderopacity="0.25"
|
|
||||||
inkscape:showpageshadow="2"
|
|
||||||
inkscape:pageopacity="0.0"
|
|
||||||
inkscape:pagecheckerboard="0"
|
|
||||||
inkscape:deskcolor="#d1d1d1"
|
|
||||||
inkscape:document-units="mm"
|
|
||||||
inkscape:zoom="8.2747365"
|
|
||||||
inkscape:cx="51.663276"
|
|
||||||
inkscape:cy="32.569013"
|
|
||||||
inkscape:window-width="1920"
|
|
||||||
inkscape:window-height="1017"
|
|
||||||
inkscape:window-x="-8"
|
|
||||||
inkscape:window-y="-8"
|
|
||||||
inkscape:window-maximized="1"
|
|
||||||
inkscape:current-layer="layer1" />
|
|
||||||
<defs
|
|
||||||
id="defs1" />
|
|
||||||
<g
|
|
||||||
inkscape:label="Ebene 1"
|
|
||||||
inkscape:groupmode="layer"
|
|
||||||
id="layer1">
|
|
||||||
<path
|
|
||||||
d="m 5.6964116,9.0092082 c 0.5692775,0 1.1727392,-0.3302 1.8103585,-0.990573 0.3415771,-0.341577 0.5123656,-0.63762 0.5123656,-0.888101 0,-0.2960419 -0.2732616,-0.4440499 -0.8197849,-0.4440499 -0.637593,0 -1.1727392,0.284639 -1.6054123,0.8539429 -0.2277242,0.273262 -0.3415771,0.5579 -0.3415771,0.853943 0,0.409892 0.1480132,0.614838 0.4440502,0.614838 M 5.1157306,1.5286443 c 0.045545,0 0.1594008,-0.01139 0.341577,-0.03416 1.0247313,0 2.1177779,0.341578 3.2792458,1.024732 l 0.2049489,0.136628 c 0.6603736,-1.070266 1.1613617,-1.605412 1.5029387,-1.605412 0.728689,0.409892 1.206924,0.853942 1.434624,1.33215 0.113861,0.227722 0.284639,0.705935 0.512366,1.434624 0.182173,-0.04555 0.364357,-0.06831 0.546523,-0.06831 1.912832,0 3.734594,1.172739 5.465233,3.5181649 2.072243,2.709862 3.108325,6.3989478 3.108325,11.0669908 0,1.047512 -0.04554,1.992524 -0.136628,2.835011 H 6.9603844 c 0.045548,-1.52572 0.6034616,-2.9718 1.6737277,-4.338109 0.1138608,-0.182173 0.2732616,-0.387112 0.4782079,-0.614838 0.8425656,-1.070266 1.354931,-1.890051 1.537097,-2.459355 0.09108,-0.296016 0.159401,-0.603462 0.204946,-0.922258 -1.5029391,0.592058 -2.6301434,1.468781 -3.3816395,2.630143 -0.341577,0.569278 -0.7173118,1.161362 -1.1272043,1.776201 -0.1138608,0.182176 -0.2846388,0.273262 -0.5123656,0.273262 -0.569304,0 -0.8539427,-0.352955 -0.8539427,-1.058889 -0.2277243,0.296042 -0.489585,0.44405 -0.7856273,0.44405 L 3.5104294,16.728481 C 2.531233,16.477987 1.8367018,16.045327 1.4268089,15.430488 1.2901809,15.225545 1.1421709,14.95228 0.9827589,14.610703 1.1421649,13.631507 1.9277979,11.684412 3.3396409,8.7697622 4.3643721,6.6747643 5.0019915,5.1716933 5.2524725,4.2609973 c 0.022781,-0.204946 0.034155,-0.500962 0.034155,-0.8881 0,-0.318797 -0.05693,-0.933635 -0.1707886,-1.844516 M 3.0663765,13.51771 c -0.5465234,0 -0.9108811,0.239101 -1.0930467,0.717311 -0.045543,0.113859 -0.068315,0.227717 -0.068315,0.341578 0,0.09108 0.034155,0.204946 0.1024731,0.341577 0.5920581,0 0.9564159,-0.250489 1.0930467,-0.75147 0.022781,-0.06832 0.03416,-0.148021 0.03416,-0.239104 0,-0.04554 -0.022781,-0.182173 -0.068315,-0.409892 m 16.7714084,5.260181 v -1.263835 c 0,-3.71184 -0.945039,-6.751902 -2.835011,-9.1201878 -1.63957,-2.0494619 -3.131079,-3.0741939 -4.474633,-3.0741939 l -0.409892,-0.06831 c -0.04554,0.02277 -0.0797,0.04554 -0.102476,0.06831 -0.296016,0 -0.44405,0.125244 -0.44405,0.375735 0,0.09109 0.06832,0.204949 0.204943,0.341577 1.229678,0.113856 2.573205,0.990574 4.030663,2.6301439 1.844516,2.1405318 2.766748,5.2374268 2.766748,9.2908428 v 0.204949 c 0,1.001951 0.216328,1.50294 0.648996,1.50294 0.364358,0 0.569304,-0.296043 0.614839,-0.888101"
|
|
||||||
id="path5"
|
|
||||||
style="stroke-width:0.264583" />
|
|
||||||
</g>
|
|
||||||
</svg>
|
|
Before Width: | Height: | Size: 3.9 KiB |
|
@ -1,47 +0,0 @@
|
||||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
|
||||||
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
|
||||||
|
|
||||||
<svg
|
|
||||||
width="22.392mm"
|
|
||||||
height="22.187mm"
|
|
||||||
viewBox="0 0 22.392001 22.187"
|
|
||||||
version="1.1"
|
|
||||||
id="svg1"
|
|
||||||
inkscape:version="1.3.2 (091e20e, 2023-11-25, custom)"
|
|
||||||
sodipodi:docname="WhiteKnight.svg"
|
|
||||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
|
||||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
|
||||||
xmlns="http://www.w3.org/2000/svg"
|
|
||||||
xmlns:svg="http://www.w3.org/2000/svg">
|
|
||||||
<sodipodi:namedview
|
|
||||||
id="namedview1"
|
|
||||||
pagecolor="#ffffff"
|
|
||||||
bordercolor="#000000"
|
|
||||||
borderopacity="0.25"
|
|
||||||
inkscape:showpageshadow="2"
|
|
||||||
inkscape:pageopacity="0.0"
|
|
||||||
inkscape:pagecheckerboard="0"
|
|
||||||
inkscape:deskcolor="#d1d1d1"
|
|
||||||
inkscape:document-units="mm"
|
|
||||||
inkscape:zoom="5.8511223"
|
|
||||||
inkscape:cx="53.23765"
|
|
||||||
inkscape:cy="73.062906"
|
|
||||||
inkscape:window-width="1920"
|
|
||||||
inkscape:window-height="1017"
|
|
||||||
inkscape:window-x="-8"
|
|
||||||
inkscape:window-y="-8"
|
|
||||||
inkscape:window-maximized="1"
|
|
||||||
inkscape:current-layer="layer1" />
|
|
||||||
<defs
|
|
||||||
id="defs1" />
|
|
||||||
<g
|
|
||||||
inkscape:label="Ebene 1"
|
|
||||||
inkscape:groupmode="layer"
|
|
||||||
id="layer1"
|
|
||||||
transform="translate(-66.145827,-72.495833)">
|
|
||||||
<path
|
|
||||||
d="m 69.600584,85.616668 c 0.318796,0 0.478208,0.216331 0.478208,0.648997 0,0.569304 -0.284639,0.853942 -0.853943,0.853942 -0.227714,0 -0.341577,-0.182173 -0.341577,-0.546523 0,-0.637619 0.239101,-0.956416 0.717312,-0.956416 m 2.459355,-4.167187 c -0.318797,0 -0.478208,-0.193556 -0.478208,-0.580681 0,-0.614839 0.364357,-1.115801 1.093046,-1.50294 0.318797,-0.1594 0.614839,-0.239101 0.888101,-0.239101 0.478208,0 0.740092,0.159401 0.785627,0.478208 0,0.523743 -0.409892,1.024731 -1.229677,1.502939 -0.409893,0.227724 -0.762847,0.341577 -1.058889,0.341577 M 72.3332,75.027781 c 0.09109,0.318797 0.136628,0.535147 0.136628,0.648997 0,0.06832 -0.03415,0.250489 -0.102473,0.546523 0.364358,0 0.865347,-0.182173 1.50294,-0.546523 -0.614839,-0.318797 -1.127205,-0.535146 -1.537097,-0.648997 m -4.064794,11.750146 c 0.136633,0.546523 0.500988,0.945039 1.093047,1.19552 0.227719,0.09109 0.44405,0.136628 0.648996,0.136628 h 0.06832 c 0.04554,0 0.296042,-0.136628 0.75147,-0.409893 0.136628,-0.09109 0.250489,-0.136628 0.341577,-0.136628 h 0.136628 c 0.113858,0 0.170794,0.06831 0.170794,0.204941 l -0.204949,0.648997 c 0,0.204946 0.159401,0.307419 0.478208,0.307419 0.04554,0 0.3302,-0.398515 0.853943,-1.19552 1.00195,-1.548474 2.425197,-2.721239 4.269581,-3.518164 0.182171,-1.229678 0.637619,-2.311347 1.366308,-3.24485 0.182176,-0.250492 0.364358,-0.375735 0.546523,-0.375735 0.204949,0 0.30742,0.148016 0.30742,0.44405 0,0.06832 -0.204947,0.717312 -0.614839,1.94699 -0.159404,0.523742 -0.239107,0.910881 -0.239107,1.161362 0,0.06831 0.02278,0.216331 0.06832,0.44405 0,1.616789 -0.683154,3.313377 -2.049462,5.089525 -0.910881,1.229677 -1.411844,2.208874 -1.50294,2.937668 h 11.272044 c 0.09109,-1.047511 0.136634,-1.821735 0.136634,-2.322724 0,-4.691062 -1.468782,-8.437033 -4.406371,-11.237912 -0.888101,-0.819785 -1.605413,-1.229678 -2.151936,-1.229678 h -2.049462 c -0.182177,-0.09109 -0.364358,-0.546523 -0.546524,-1.366308 -0.136628,-0.660373 -0.307419,-1.070266 -0.512365,-1.229677 -0.273262,0.819785 -1.115828,1.457404 -2.527671,1.912831 -0.751469,0.227717 -1.275212,0.455428 -1.571254,0.683154 -0.250489,0.797005 -0.990574,2.413821 -2.220251,4.850342 -1.206897,2.413794 -1.844516,3.848365 -1.912832,4.303977 m 19.128317,6.899804 H 73.084463 c 0.09109,-1.571254 0.683155,-3.074194 1.776201,-4.508764 0.842566,-1.138582 1.343528,-1.833139 1.502939,-2.083621 0.318797,-0.500988 0.512366,-1.104423 0.580681,-1.810358 -1.480158,0.637593 -2.630143,1.548474 -3.449902,2.732617 l -0.478207,0.785627 c -0.341578,0.546523 -0.557901,0.853943 -0.648997,0.922258 -0.136628,0.113858 -0.284639,0.170789 -0.44405,0.170789 -0.705908,0 -1.184143,-0.239104 -1.434624,-0.717312 -0.04555,-0.06832 -0.06832,-0.148016 -0.06832,-0.239104 -0.227719,0.113858 -0.455427,0.170788 -0.683154,0.170788 -1.093047,0 -1.958367,-0.683154 -2.595986,-2.049462 0.182174,-1.001951 1.138582,-3.313377 2.869142,-6.933936 0.182176,-0.341577 0.318823,-0.614838 0.409892,-0.819785 0.683154,-1.525719 1.024731,-2.675731 1.024731,-3.449902 0,-0.113855 -0.06831,-0.751469 -0.204948,-1.912831 h 0.273261 c 1.229678,0 2.402417,0.387112 3.518165,1.161362 0.614839,-1.070266 1.127204,-1.605412 1.537097,-1.605412 0.728689,0.387111 1.229677,0.933635 1.502939,1.63957 l 0.375735,1.127204 c 0.227713,-0.04555 0.421269,-0.06832 0.580681,-0.06832 1.821735,0 3.620823,1.161363 5.39697,3.484034 2.072243,2.709862 3.108325,6.421702 3.108325,11.135518 0,1.070266 -0.04554,2.026682 -0.136628,2.869142"
|
|
||||||
id="path11"
|
|
||||||
style="stroke-width:0.264583" />
|
|
||||||
</g>
|
|
||||||
</svg>
|
|
Before Width: | Height: | Size: 4.7 KiB |
|
@ -1,46 +0,0 @@
|
||||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
|
||||||
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
|
||||||
|
|
||||||
<svg
|
|
||||||
width="16.68mm"
|
|
||||||
height="22.1mm"
|
|
||||||
viewBox="0 0 16.679999 22.100002"
|
|
||||||
version="1.1"
|
|
||||||
id="svg1"
|
|
||||||
inkscape:version="1.3.2 (091e20e, 2023-11-25, custom)"
|
|
||||||
sodipodi:docname="Pawn.svg"
|
|
||||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
|
||||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
|
||||||
xmlns="http://www.w3.org/2000/svg"
|
|
||||||
xmlns:svg="http://www.w3.org/2000/svg">
|
|
||||||
<sodipodi:namedview
|
|
||||||
id="namedview1"
|
|
||||||
pagecolor="#ffffff"
|
|
||||||
bordercolor="#000000"
|
|
||||||
borderopacity="0.25"
|
|
||||||
inkscape:showpageshadow="2"
|
|
||||||
inkscape:pageopacity="0.0"
|
|
||||||
inkscape:pagecheckerboard="0"
|
|
||||||
inkscape:deskcolor="#d1d1d1"
|
|
||||||
inkscape:document-units="mm"
|
|
||||||
inkscape:zoom="2"
|
|
||||||
inkscape:cx="-66.25"
|
|
||||||
inkscape:cy="97.25"
|
|
||||||
inkscape:window-width="1920"
|
|
||||||
inkscape:window-height="1017"
|
|
||||||
inkscape:window-x="-8"
|
|
||||||
inkscape:window-y="-8"
|
|
||||||
inkscape:window-maximized="1"
|
|
||||||
inkscape:current-layer="layer1" />
|
|
||||||
<defs
|
|
||||||
id="defs1" />
|
|
||||||
<g
|
|
||||||
inkscape:label="Ebene 1"
|
|
||||||
inkscape:groupmode="layer"
|
|
||||||
id="layer1">
|
|
||||||
<path
|
|
||||||
d="m 1.0591685,21.100011 c -0.022754,-0.273262 -0.034152,-0.808408 -0.034152,-1.605412 0,-2.869142 0.8881004,-4.998509 2.664354,-6.387571 0.5237427,-0.432673 1.1613356,-0.831162 1.9128316,-1.19552 C 4.7141013,11.638246 4.1106397,10.966469 3.7918432,9.8962032 3.7007551,9.5546259 3.655215,9.2016719 3.655215,8.8373139 c 0,-1.525719 0.7856273,-2.607363 2.3568821,-3.24485 -0.409919,-0.683154 -0.614865,-1.33215 -0.614839,-1.946989 -2.9e-5,-1.024731 0.500962,-1.787578 1.502939,-2.288566 0.455401,-0.227719 0.944986,-0.3415769 1.468782,-0.3415769 1.138555,0 1.9811199,0.4440499 2.5276699,1.3321499 0.25046,0.387112 0.375708,0.819785 0.375735,1.297993 -2.7e-5,0.660374 -0.193588,1.30937 -0.580681,1.946989 0.842539,0.341577 1.445974,0.797005 1.810358,1.366309 0.364332,0.614838 0.546497,1.241054 0.546524,1.878674 -3.7e-5,1.1841161 -0.409919,2.0836201 -1.229678,2.6984851 -0.204975,0.182176 -0.432699,0.307419 -0.683154,0.375735 2.094971,1.070266 3.449902,2.470732 4.064794,4.201318 0.31877,0.956416 0.478181,2.083621 0.478208,3.38164 -2.7e-5,0.797004 -0.0114,1.332151 -0.03415,1.605412 H 1.0591817"
|
|
||||||
id="path6"
|
|
||||||
style="stroke-width:0.264583" />
|
|
||||||
</g>
|
|
||||||
</svg>
|
|
Before Width: | Height: | Size: 2.3 KiB |
|
@ -1,47 +0,0 @@
|
||||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
|
||||||
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
|
||||||
|
|
||||||
<svg
|
|
||||||
width="16.653999mm"
|
|
||||||
height="22.084999mm"
|
|
||||||
viewBox="0 0 16.653999 22.084999"
|
|
||||||
version="1.1"
|
|
||||||
id="svg1"
|
|
||||||
inkscape:version="1.3.2 (091e20e, 2023-11-25, custom)"
|
|
||||||
sodipodi:docname="WhitePawn.svg"
|
|
||||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
|
||||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
|
||||||
xmlns="http://www.w3.org/2000/svg"
|
|
||||||
xmlns:svg="http://www.w3.org/2000/svg">
|
|
||||||
<sodipodi:namedview
|
|
||||||
id="namedview1"
|
|
||||||
pagecolor="#ffffff"
|
|
||||||
bordercolor="#000000"
|
|
||||||
borderopacity="0.25"
|
|
||||||
inkscape:showpageshadow="2"
|
|
||||||
inkscape:pageopacity="0.0"
|
|
||||||
inkscape:pagecheckerboard="0"
|
|
||||||
inkscape:deskcolor="#d1d1d1"
|
|
||||||
inkscape:document-units="mm"
|
|
||||||
inkscape:zoom="4"
|
|
||||||
inkscape:cx="-9.375"
|
|
||||||
inkscape:cy="68.375"
|
|
||||||
inkscape:window-width="1920"
|
|
||||||
inkscape:window-height="1017"
|
|
||||||
inkscape:window-x="-8"
|
|
||||||
inkscape:window-y="-8"
|
|
||||||
inkscape:window-maximized="1"
|
|
||||||
inkscape:current-layer="layer1" />
|
|
||||||
<defs
|
|
||||||
id="defs1" />
|
|
||||||
<g
|
|
||||||
inkscape:label="Ebene 1"
|
|
||||||
inkscape:groupmode="layer"
|
|
||||||
id="layer1"
|
|
||||||
transform="translate(-91.545814,-119.85625)">
|
|
||||||
<path
|
|
||||||
d="m 105.96968,139.57435 c -3e-5,-2.39104 -0.64902,-4.17857 -1.94699,-5.36284 -0.4327,-0.40989 -0.96782,-0.797 -1.60541,-1.16136 -0.88813,-0.52375 -1.33218,-1.00195 -1.33215,-1.43463 -3e-5,-0.22772 0.22769,-0.4782 0.68315,-0.75147 0.70591,-0.38711 1.12718,-0.84256 1.26384,-1.3663 0.0455,-0.20494 0.0683,-0.45543 0.0683,-0.75147 -3e-5,-1.04752 -0.53517,-1.8673 -1.60541,-2.45936 l -0.61484,-0.44405 c -0.11389,-0.11385 -0.17082,-0.2391 -0.17079,-0.37573 -3e-5,-0.38712 0.1366,-0.77425 0.40989,-1.16137 0.18215,-0.25048 0.27324,-0.54652 0.27326,-0.8881 -2e-5,-0.59205 -0.31882,-1.02473 -0.95641,-1.29799 -0.20498,-0.0683 -0.40992,-0.10247 -0.614845,-0.10247 -0.637646,0 -1.093073,0.28464 -1.366308,0.85394 -0.09111,0.18218 -0.13666,0.36436 -0.136634,0.54652 -2.6e-5,0.20495 0.147995,0.59206 0.44405,1.16137 0.182148,0.31879 0.261848,0.61483 0.23911,0.8881 -3.7e-5,0.27326 -0.261911,0.54652 -0.785628,0.81978 -1.047538,0.61484 -1.571281,1.43463 -1.571254,2.45936 -3.5e-5,0.8881 0.444024,1.59403 1.33215,2.11777 0.432647,0.29602 0.64897,0.54653 0.648997,0.75147 -2.9e-5,0.43268 -0.444077,0.91088 -1.332151,1.43463 -1.63957,1.00195 -2.687108,2.22025 -3.142456,3.65495 -0.250489,0.79701 -0.375735,1.75342 -0.375735,2.86914 H 105.9698 m -13.389771,1.36631 c -0.02278,-0.27326 -0.03416,-0.797 -0.03416,-1.57125 0,-2.80088 0.819785,-4.89585 2.459355,-6.28492 0.546524,-0.45542 1.241029,-0.89947 2.083621,-1.33215 -0.86532,-0.27326 -1.446001,-0.93366 -1.742044,-1.98114 -0.113855,-0.34158 -0.170788,-0.69453 -0.170788,-1.05889 0,-1.5257 0.77425,-2.61877 2.322724,-3.27925 -0.364384,-0.6604 -0.54655,-1.30937 -0.546523,-1.94699 -2.9e-5,-1.04751 0.512339,-1.82173 1.537097,-2.32272 0.432646,-0.20495 0.899451,-0.30742 1.400466,-0.30742 1.161343,0 2.015283,0.44405 2.561833,1.33215 0.25046,0.38711 0.37571,0.81979 0.37573,1.29799 -2e-5,0.61484 -0.20497,1.26384 -0.61484,1.94699 1.57123,0.63762 2.35686,1.73064 2.35689,3.27925 -3e-5,1.20692 -0.44408,2.11778 -1.33215,2.73261 -0.1822,0.13664 -0.38714,0.23911 -0.61484,0.30742 2.04943,1.04752 3.38164,2.37967 3.99653,3.99654 0.38708,1.00195 0.58065,2.20887 0.58068,3.62082 -3e-5,0.75147 -0.0114,1.27521 -0.0342,1.57125 H 92.580034"
|
|
||||||
id="path12"
|
|
||||||
style="stroke-width:0.264583" />
|
|
||||||
</g>
|
|
||||||
</svg>
|
|
Before Width: | Height: | Size: 3.4 KiB |
Before Width: | Height: | Size: 6.5 KiB |
Before Width: | Height: | Size: 7.8 KiB |
|
@ -1,46 +0,0 @@
|
||||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
|
||||||
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
|
||||||
|
|
||||||
<svg
|
|
||||||
width="19.200001mm"
|
|
||||||
height="22mm"
|
|
||||||
viewBox="0 0 19.200001 22"
|
|
||||||
version="1.1"
|
|
||||||
id="svg1"
|
|
||||||
inkscape:version="1.3.2 (091e20e, 2023-11-25, custom)"
|
|
||||||
sodipodi:docname="Rook.svg"
|
|
||||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
|
||||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
|
||||||
xmlns="http://www.w3.org/2000/svg"
|
|
||||||
xmlns:svg="http://www.w3.org/2000/svg">
|
|
||||||
<sodipodi:namedview
|
|
||||||
id="namedview1"
|
|
||||||
pagecolor="#ffffff"
|
|
||||||
bordercolor="#000000"
|
|
||||||
borderopacity="0.25"
|
|
||||||
inkscape:showpageshadow="2"
|
|
||||||
inkscape:pageopacity="0.0"
|
|
||||||
inkscape:pagecheckerboard="0"
|
|
||||||
inkscape:deskcolor="#d1d1d1"
|
|
||||||
inkscape:document-units="mm"
|
|
||||||
inkscape:zoom="5.6568543"
|
|
||||||
inkscape:cx="21.92031"
|
|
||||||
inkscape:cy="49.055533"
|
|
||||||
inkscape:window-width="1920"
|
|
||||||
inkscape:window-height="1017"
|
|
||||||
inkscape:window-x="-8"
|
|
||||||
inkscape:window-y="-8"
|
|
||||||
inkscape:window-maximized="1"
|
|
||||||
inkscape:current-layer="layer1" />
|
|
||||||
<defs
|
|
||||||
id="defs1" />
|
|
||||||
<g
|
|
||||||
inkscape:label="Ebene 1"
|
|
||||||
inkscape:groupmode="layer"
|
|
||||||
id="layer1">
|
|
||||||
<path
|
|
||||||
d="m 1.7350659,20.999302 -0.649,-0.649 v -2.4252 L 4.535966,14.509332 V 7.7119213 l -2.6643501,-2.63014 v -3.04006 l 0.9564101,-0.95642 h 2.4252 l 0.61484,0.58068 v 0.85394 h 1.29799 v -0.85394 l 0.58068,-0.58068 h 3.791482 l 0.58068,0.58068 v 0.85394 h 1.298 v -0.85394 l 0.58068,-0.58068 h 2.45935 l 0.95642,0.95642 v 3.04006 l -2.66436,2.63014 v 6.7974107 l 3.44991,3.41577 v 2.4252 l -0.68316,0.649 H 1.7349259 m 4.0306701,-7.27552 v 1.16137 h 7.753882 v -1.16137 H 5.765596 m 0,-6.1483807 v 1.16136 h 7.753882 v -1.16136 H 5.765596"
|
|
||||||
id="path3"
|
|
||||||
style="stroke-width:0.264583" />
|
|
||||||
</g>
|
|
||||||
</svg>
|
|
Before Width: | Height: | Size: 1.8 KiB |
|
@ -1,47 +0,0 @@
|
||||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
|
||||||
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
|
||||||
|
|
||||||
<svg
|
|
||||||
width="19.146999mm"
|
|
||||||
height="22.049999mm"
|
|
||||||
viewBox="0 0 19.146999 22.049999"
|
|
||||||
version="1.1"
|
|
||||||
id="svg1"
|
|
||||||
inkscape:version="1.3.2 (091e20e, 2023-11-25, custom)"
|
|
||||||
sodipodi:docname="WhiteRook.svg"
|
|
||||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
|
||||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
|
||||||
xmlns="http://www.w3.org/2000/svg"
|
|
||||||
xmlns:svg="http://www.w3.org/2000/svg">
|
|
||||||
<sodipodi:namedview
|
|
||||||
id="namedview1"
|
|
||||||
pagecolor="#ffffff"
|
|
||||||
bordercolor="#000000"
|
|
||||||
borderopacity="0.25"
|
|
||||||
inkscape:showpageshadow="2"
|
|
||||||
inkscape:pageopacity="0.0"
|
|
||||||
inkscape:pagecheckerboard="0"
|
|
||||||
inkscape:deskcolor="#d1d1d1"
|
|
||||||
inkscape:document-units="mm"
|
|
||||||
inkscape:zoom="5.8511223"
|
|
||||||
inkscape:cx="55.459446"
|
|
||||||
inkscape:cy="56.313982"
|
|
||||||
inkscape:window-width="1920"
|
|
||||||
inkscape:window-height="1017"
|
|
||||||
inkscape:window-x="-8"
|
|
||||||
inkscape:window-y="-8"
|
|
||||||
inkscape:window-maximized="1"
|
|
||||||
inkscape:current-layer="layer1" />
|
|
||||||
<defs
|
|
||||||
id="defs1" />
|
|
||||||
<g
|
|
||||||
inkscape:label="Ebene 1"
|
|
||||||
inkscape:groupmode="layer"
|
|
||||||
id="layer1"
|
|
||||||
transform="translate(-86.518752,-131.49792)">
|
|
||||||
<path
|
|
||||||
d="m 92.197395,139.29413 v 6.04599 H 99.9854 v -6.04599 h -7.788005 m -4.030662,13.25324 -0.648997,-0.64899 v -2.35688 l 3.484033,-3.51817 v -6.83154 l -3.005931,-2.63014 v -3.10833 l 0.990574,-0.95641 h 3.074193 l 0.580682,0.58068 v 0.8881 h 0.990573 v -0.8881 l 0.580681,-0.58068 h 3.757348 l 0.580681,0.58068 v 0.8881 h 0.956416 v -0.8881 l 0.614834,-0.58068 h 3.0742 l 0.99058,0.95641 v 3.10833 l -3.00593,2.63014 v 6.83154 l 3.48403,3.51817 v 2.35688 l -0.649,0.64899 H 88.166627 m 0.546523,-2.69848 v 1.33215 h 14.75608 v -1.33215 H 88.71315 m 3.347508,-3.38164 -2.254408,2.18609 h 12.5701 l -2.25442,-2.18609 h -8.061325 m 2.732617,-12.53596 v 0.8881 l -0.512366,0.47821 h -2.220251 l -0.512365,-0.47821 v -0.95641 h -1.912832 l -0.44405,0.4782 v 1.91284 l 2.322724,1.87867 h 9.154318 l 2.32273,-1.87867 v -1.91284 l -0.44405,-0.4782 h -1.91283 v 0.95641 l -0.51237,0.47821 h -2.220254 l -0.512365,-0.47821 v -0.8881 h -2.595986"
|
|
||||||
id="path9"
|
|
||||||
style="stroke-width:0.264583" />
|
|
||||||
</g>
|
|
||||||
</svg>
|
|
Before Width: | Height: | Size: 2.3 KiB |
1
solution/H04/src/test
Symbolic link
|
@ -0,0 +1 @@
|
||||||
|
/home/osh/Desktop/FOP-2425-Marathon/H04/src/test
|
|
@ -1,16 +0,0 @@
|
||||||
package h04;
|
|
||||||
|
|
||||||
import org.junit.jupiter.api.Test;
|
|
||||||
|
|
||||||
import static org.junit.jupiter.api.Assertions.*;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* An example JUnit test class.
|
|
||||||
*/
|
|
||||||
public class ExampleJUnitTest {
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testAddition() {
|
|
||||||
assertEquals(2, 1 + 1);
|
|
||||||
}
|
|
||||||
}
|
|
1
solution/H05/src/main
Symbolic link
|
@ -0,0 +1 @@
|
||||||
|
/home/osh/Desktop/FOP-2425-Marathon/H05/src/main
|
|
@ -1,57 +0,0 @@
|
||||||
package h05;
|
|
||||||
|
|
||||||
import java.util.Collections;
|
|
||||||
import java.util.HashSet;
|
|
||||||
import java.util.Set;
|
|
||||||
|
|
||||||
public class Airspace {
|
|
||||||
|
|
||||||
private static Airspace INSTANCE = null;
|
|
||||||
|
|
||||||
|
|
||||||
public static Airspace get(){
|
|
||||||
if(INSTANCE == null){
|
|
||||||
INSTANCE = new Airspace();
|
|
||||||
}
|
|
||||||
return INSTANCE;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
private final Set<Flying> flyingInAirspace = new HashSet<>();
|
|
||||||
|
|
||||||
private Airspace(){
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
Set<Flying> getFlyingInAirspace() {
|
|
||||||
return Collections.unmodifiableSet(flyingInAirspace);
|
|
||||||
}
|
|
||||||
|
|
||||||
void register(Flying flying){
|
|
||||||
flyingInAirspace.add(flying);
|
|
||||||
}
|
|
||||||
|
|
||||||
void deregister(Flying flying){
|
|
||||||
flyingInAirspace.remove(flying);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void scanAirspace(){
|
|
||||||
System.out.println("Scanning...");
|
|
||||||
|
|
||||||
if (flyingInAirspace.isEmpty()){
|
|
||||||
System.out.println("Airspace is empty");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (Flying flying : flyingInAirspace){
|
|
||||||
System.out.print(flying.getIdentifier() + " is flying in airspace");
|
|
||||||
|
|
||||||
if(flying instanceof PassengerPlane passengerPlane){
|
|
||||||
System.out.print(" (" + passengerPlane.getPassengerCount() + " PAX)");
|
|
||||||
}
|
|
||||||
|
|
||||||
System.out.println();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,34 +0,0 @@
|
||||||
package h05;
|
|
||||||
|
|
||||||
public class CargoPlane extends Plane implements CarriesCargo{
|
|
||||||
|
|
||||||
/*
|
|
||||||
Stacks are a type of data structure that follows the Last In First Out (LIFO) principle.
|
|
||||||
Explanation will be found in Task description.
|
|
||||||
*/
|
|
||||||
private final CargoStack containers = new CargoStack();
|
|
||||||
|
|
||||||
public CargoPlane(String aircraftRegistration, int baseWeight, FuelType fuelType, double maxFuelLevel) {
|
|
||||||
super(aircraftRegistration, baseWeight, fuelType, maxFuelLevel);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void loadContainer(int cargoWeight) {
|
|
||||||
containers.push(cargoWeight);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean hasFreightLoaded() {
|
|
||||||
return !containers.empty();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int unloadNextContainer() {
|
|
||||||
return containers.pop();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected double mass() {
|
|
||||||
return baseWeight + containers.getSum();
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,27 +0,0 @@
|
||||||
package h05;
|
|
||||||
|
|
||||||
import java.util.Stack;
|
|
||||||
|
|
||||||
public class CargoStack {
|
|
||||||
private final Stack<Integer> stack = new Stack<>();
|
|
||||||
private int sum = 0;
|
|
||||||
|
|
||||||
public boolean empty(){
|
|
||||||
return stack.empty();
|
|
||||||
}
|
|
||||||
|
|
||||||
public void push(int value){
|
|
||||||
sum += value;
|
|
||||||
stack.push(value);
|
|
||||||
}
|
|
||||||
|
|
||||||
public int pop(){
|
|
||||||
int removedValue = stack.pop();
|
|
||||||
sum -= removedValue;
|
|
||||||
return removedValue;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getSum(){
|
|
||||||
return sum;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,8 +0,0 @@
|
||||||
package h05;
|
|
||||||
|
|
||||||
public interface CarriesCargo {
|
|
||||||
void loadContainer(int cargoWeight);
|
|
||||||
|
|
||||||
boolean hasFreightLoaded();
|
|
||||||
int unloadNextContainer();
|
|
||||||
}
|
|
|
@ -1,7 +0,0 @@
|
||||||
package h05;
|
|
||||||
|
|
||||||
public interface CarriesPassengers {
|
|
||||||
void board(int peopleCount);
|
|
||||||
int getPassengerCount();
|
|
||||||
void disembark();
|
|
||||||
}
|
|
|
@ -1,32 +0,0 @@
|
||||||
package h05;
|
|
||||||
|
|
||||||
|
|
||||||
public class CombinedPlane extends PassengerPlane implements CarriesCargo{
|
|
||||||
|
|
||||||
private final CargoStack containers = new CargoStack();
|
|
||||||
|
|
||||||
|
|
||||||
public CombinedPlane(String aircraftRegistration, int baseWeight, FuelType fuelType, double maxFuelLevel, int crew) {
|
|
||||||
super(aircraftRegistration, baseWeight, fuelType, maxFuelLevel, crew);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void loadContainer(int cargoWeight) {
|
|
||||||
containers.push(cargoWeight);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean hasFreightLoaded() {
|
|
||||||
return !containers.empty();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int unloadNextContainer() {
|
|
||||||
return containers.pop();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected double mass() {
|
|
||||||
return super.mass() + containers.getSum();
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,5 +0,0 @@
|
||||||
package h05;
|
|
||||||
|
|
||||||
public interface Flying {
|
|
||||||
String getIdentifier();
|
|
||||||
}
|
|
|
@ -1,14 +0,0 @@
|
||||||
package h05;
|
|
||||||
|
|
||||||
public enum FuelType {
|
|
||||||
JetA(1.0), JetB(1.2), AvGas(0.99), Biokerosin (1.02);
|
|
||||||
|
|
||||||
|
|
||||||
private final double consumptionMultiplicator;
|
|
||||||
FuelType(double consumptionMultiplicator){
|
|
||||||
this.consumptionMultiplicator = consumptionMultiplicator;
|
|
||||||
}
|
|
||||||
public double getConsumptionMultiplicator() {
|
|
||||||
return consumptionMultiplicator;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,69 +0,0 @@
|
||||||
package h05;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Main entry point in executing the program.
|
|
||||||
*/
|
|
||||||
public class Main {
|
|
||||||
/**
|
|
||||||
* Main entry point in executing the program.
|
|
||||||
*
|
|
||||||
* @param args program arguments, currently ignored
|
|
||||||
*/
|
|
||||||
public static void main(String[] args) {
|
|
||||||
Airspace airspace = Airspace.get();
|
|
||||||
airspace.scanAirspace();
|
|
||||||
|
|
||||||
/*
|
|
||||||
Die konkreten Zahlen sind noch nicht final und können sich ändern.
|
|
||||||
*/
|
|
||||||
Runway runway01 = new Runway(2000);
|
|
||||||
Runway runway02 = new Runway(4000);
|
|
||||||
|
|
||||||
WeatherBalloon weatherBalloon = new WeatherBalloon(99);
|
|
||||||
weatherBalloon.start();
|
|
||||||
|
|
||||||
Tank jetATank = new Tank(FuelType.JetA);
|
|
||||||
Tank jetBTank = new Tank(FuelType.JetB);
|
|
||||||
TankerPlane tankerPlane = new TankerPlane("D-ABCD", 10000, FuelType.JetA, 1000);
|
|
||||||
tankerPlane.loadFuel(FuelType.AvGas, 100000);
|
|
||||||
tankerPlane.loadFuel(FuelType.Biokerosin, 100000);
|
|
||||||
|
|
||||||
PassengerPlane passengerPlane = new PassengerPlane("GAG-67", 10000, FuelType.JetA, 1700, 5);
|
|
||||||
jetATank.refuelPlane(passengerPlane);
|
|
||||||
passengerPlane.board(100);
|
|
||||||
passengerPlane.takeOff();
|
|
||||||
|
|
||||||
airspace.scanAirspace();
|
|
||||||
|
|
||||||
CargoPlane cargoPlane = new CargoPlane("D-AFFF", 8000, FuelType.JetB, 1500);
|
|
||||||
cargoPlane.loadContainer(1000);
|
|
||||||
jetBTank.refuelPlane(cargoPlane);
|
|
||||||
|
|
||||||
passengerPlane.disembark();
|
|
||||||
|
|
||||||
airspace.scanAirspace();
|
|
||||||
|
|
||||||
cargoPlane.takeOff();
|
|
||||||
cargoPlane.fly(1000);
|
|
||||||
|
|
||||||
airspace.scanAirspace();
|
|
||||||
|
|
||||||
CombinedPlane combinedPlane = new CombinedPlane("D-ABBB", 9000, FuelType.AvGas, 10700, 5);
|
|
||||||
tankerPlane.refuelPlane(combinedPlane);
|
|
||||||
|
|
||||||
combinedPlane.board(30);
|
|
||||||
combinedPlane.loadContainer(400);
|
|
||||||
combinedPlane.takeOff();
|
|
||||||
combinedPlane.fly(3000);
|
|
||||||
airspace.scanAirspace();
|
|
||||||
|
|
||||||
runway01.land(combinedPlane);
|
|
||||||
runway02.land(cargoPlane);
|
|
||||||
|
|
||||||
airspace.scanAirspace();
|
|
||||||
|
|
||||||
weatherBalloon.pop();
|
|
||||||
|
|
||||||
airspace.scanAirspace();
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,36 +0,0 @@
|
||||||
package h05;
|
|
||||||
|
|
||||||
public class PassengerPlane extends Plane implements CarriesPassengers {
|
|
||||||
|
|
||||||
protected static final char AVERAGE_PEOPLE_WEIGHT = 100;
|
|
||||||
protected static final char AVERAGE_LUGGAGE_WEIGHT = 15;
|
|
||||||
|
|
||||||
private int passengerCount = 0;
|
|
||||||
|
|
||||||
private final int crewCount;
|
|
||||||
|
|
||||||
public PassengerPlane(String aircraftRegistration, int baseWeight, FuelType fuelType, double fuelCapacity, int crewCount) {
|
|
||||||
super(aircraftRegistration, baseWeight, fuelType, fuelCapacity);
|
|
||||||
this.crewCount = crewCount;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void board(int passengerCount) {
|
|
||||||
this.passengerCount += passengerCount;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void disembark() {
|
|
||||||
this.passengerCount = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int getPassengerCount() {
|
|
||||||
return passengerCount;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected double mass() {
|
|
||||||
return baseWeight + (passengerCount + crewCount) * AVERAGE_PEOPLE_WEIGHT + passengerCount * AVERAGE_LUGGAGE_WEIGHT;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,77 +0,0 @@
|
||||||
package h05;
|
|
||||||
|
|
||||||
public abstract class Plane implements Flying {
|
|
||||||
|
|
||||||
private static final double CONSUMPTION_PER_KM_KG = 1.1494e-4;
|
|
||||||
private final String aircraftRegistration;
|
|
||||||
|
|
||||||
protected final int baseWeight;
|
|
||||||
|
|
||||||
private double currentFuelLevel;
|
|
||||||
|
|
||||||
private final FuelType fuelType;
|
|
||||||
private final double fuelCapacity;
|
|
||||||
|
|
||||||
public Plane(String aircraftRegistration, int baseWeight, FuelType fuelType, double fuelCapacity){
|
|
||||||
this.aircraftRegistration = aircraftRegistration;
|
|
||||||
this.baseWeight = baseWeight;
|
|
||||||
this.fuelType = fuelType;
|
|
||||||
this.currentFuelLevel = 0;
|
|
||||||
this.fuelCapacity = fuelCapacity;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
protected abstract double mass();
|
|
||||||
|
|
||||||
protected double getFuelConsumptionPerKilometer(){
|
|
||||||
return CONSUMPTION_PER_KM_KG * mass() * fuelType.getConsumptionMultiplicator();
|
|
||||||
}
|
|
||||||
|
|
||||||
public void takeOff(){
|
|
||||||
Airspace.get().register(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void land(){
|
|
||||||
Airspace.get().deregister(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void fly(double distance){
|
|
||||||
double neededFuel = distance * getFuelConsumptionPerKilometer();
|
|
||||||
|
|
||||||
// if the plane does not have enough fuel to fly the distance, it will not fly
|
|
||||||
if(neededFuel > currentFuelLevel){
|
|
||||||
System.out.println("Plane " + aircraftRegistration + " does not have enough fuel to fly " + distance + " km.");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
currentFuelLevel -= neededFuel;
|
|
||||||
|
|
||||||
System.out.println("Plane " + aircraftRegistration + " flew " + distance + " km and has " + currentFuelLevel + " liters of fuel left.");
|
|
||||||
}
|
|
||||||
|
|
||||||
public FuelType getFuelType() {
|
|
||||||
return fuelType;
|
|
||||||
}
|
|
||||||
|
|
||||||
public double getFuelCapacity() {
|
|
||||||
return fuelCapacity;
|
|
||||||
}
|
|
||||||
|
|
||||||
public double getCurrentFuelLevel() {
|
|
||||||
return currentFuelLevel;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void refuel(double amount){
|
|
||||||
currentFuelLevel += amount;
|
|
||||||
|
|
||||||
if(currentFuelLevel > fuelCapacity){
|
|
||||||
currentFuelLevel = fuelCapacity;
|
|
||||||
System.out.println("The Tank of Plane " + aircraftRegistration + " has overflowed!");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String getIdentifier(){
|
|
||||||
return aircraftRegistration;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,5 +0,0 @@
|
||||||
package h05;
|
|
||||||
|
|
||||||
public interface Refuelling {
|
|
||||||
void refuelPlane(Plane plane);
|
|
||||||
}
|
|
|
@ -1,41 +0,0 @@
|
||||||
package h05;
|
|
||||||
|
|
||||||
public class Runway {
|
|
||||||
|
|
||||||
private final int runwayLength;
|
|
||||||
|
|
||||||
/*
|
|
||||||
TODO: Man könnte sich noch überlegen, wie Flugzeugtypen, die hier landen können, festgesetzt werden
|
|
||||||
*/
|
|
||||||
public Runway(int runwayLength){
|
|
||||||
this.runwayLength = runwayLength;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getRunwayLength(){
|
|
||||||
return runwayLength;
|
|
||||||
}
|
|
||||||
/*
|
|
||||||
TODO: hier müsste man sich noch eine bessere Formel für die Landung überlegen
|
|
||||||
*/
|
|
||||||
public static double calculateLandingDistance(double mass){
|
|
||||||
return mass/40;
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean canLand(Plane plane){
|
|
||||||
return calculateLandingDistance(plane.mass()) <= runwayLength;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
TODO: Man könnte auch stattdessen die land() methode in plane erweitern und diese hier weglassen
|
|
||||||
*/
|
|
||||||
public void land(Plane plane){
|
|
||||||
if(canLand(plane)){
|
|
||||||
plane.land();
|
|
||||||
System.out.println("Plane " + plane.getIdentifier() + " has landed successfully.");
|
|
||||||
} else {
|
|
||||||
System.out.println("Plane " + plane.getIdentifier() + " could not land. The runway is too short.");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
|
@ -1,21 +0,0 @@
|
||||||
package h05;
|
|
||||||
|
|
||||||
public class Tank implements Refuelling{
|
|
||||||
|
|
||||||
private final FuelType fuelType;
|
|
||||||
|
|
||||||
public Tank(FuelType fuelType){
|
|
||||||
this.fuelType = fuelType;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void refuelPlane(Plane plane) {
|
|
||||||
if(plane.getFuelType() != fuelType){
|
|
||||||
System.out.println("Incompatible fuel types, not refuelling");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
double missingFuel = plane.getFuelCapacity() - plane.getCurrentFuelLevel();
|
|
||||||
plane.refuel(missingFuel);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,35 +0,0 @@
|
||||||
package h05;
|
|
||||||
|
|
||||||
public class TankerPlane extends Plane implements Refuelling{
|
|
||||||
|
|
||||||
|
|
||||||
private final double[] availableAmount = new double[FuelType.values().length];
|
|
||||||
|
|
||||||
public TankerPlane(String aircraftRegistration, int baseWeight, FuelType fuelType, double maxFuelLevel) {
|
|
||||||
super(aircraftRegistration, baseWeight, fuelType, maxFuelLevel);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
public void loadFuel(FuelType fuelType, double amount){
|
|
||||||
availableAmount[fuelType.ordinal()] += amount;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected double mass() {
|
|
||||||
double totalAmount = 0;
|
|
||||||
for (int i = 0; i < FuelType.values().length; i++){
|
|
||||||
totalAmount += availableAmount[i];
|
|
||||||
}
|
|
||||||
|
|
||||||
return baseWeight + totalAmount;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void refuelPlane(Plane plane) {
|
|
||||||
double missingFuel = plane.getFuelCapacity() - plane.getCurrentFuelLevel();
|
|
||||||
double actualAmount = Math.min(availableAmount[plane.getFuelType().ordinal()], missingFuel);
|
|
||||||
availableAmount[plane.getFuelType().ordinal()] -= actualAmount;
|
|
||||||
plane.refuel(actualAmount);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,23 +0,0 @@
|
||||||
package h05;
|
|
||||||
|
|
||||||
public class WeatherBalloon implements Flying{
|
|
||||||
|
|
||||||
private final int balloonNumber;
|
|
||||||
|
|
||||||
public WeatherBalloon(int balloonNumber){
|
|
||||||
this.balloonNumber = balloonNumber;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void start(){
|
|
||||||
Airspace.get().register(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void pop(){
|
|
||||||
Airspace.get().deregister(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String getIdentifier() {
|
|
||||||
return "WeatherBalloon " + balloonNumber;
|
|
||||||
}
|
|
||||||
}
|
|
1
solution/H05/src/test
Symbolic link
|
@ -0,0 +1 @@
|
||||||
|
/home/osh/Desktop/FOP-2425-Marathon/H05/src/test
|
|
@ -1,16 +0,0 @@
|
||||||
package h05;
|
|
||||||
|
|
||||||
import org.junit.jupiter.api.Test;
|
|
||||||
|
|
||||||
import static org.junit.jupiter.api.Assertions.*;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* An example JUnit test class.
|
|
||||||
*/
|
|
||||||
public class ExampleJUnitTest {
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testAddition() {
|
|
||||||
assertEquals(2, 1 + 1);
|
|
||||||
}
|
|
||||||
}
|
|
1
solution/H06/src/main
Symbolic link
|
@ -0,0 +1 @@
|
||||||
|
/home/osh/Desktop/FOP-2425-Marathon/H06/src/main
|
|
@ -1,28 +0,0 @@
|
||||||
package h06;
|
|
||||||
|
|
||||||
import h06.problems.*;
|
|
||||||
import h06.ui.DrawInstruction;
|
|
||||||
import h06.ui.FractalVisualizer;
|
|
||||||
import org.tudalgo.algoutils.student.annotation.StudentImplementationRequired;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Main entry point in executing the program.
|
|
||||||
*/
|
|
||||||
public class Main {
|
|
||||||
/**
|
|
||||||
* Main entry point in executing the program.
|
|
||||||
*
|
|
||||||
* @param args program arguments, currently ignored
|
|
||||||
*/
|
|
||||||
@StudentImplementationRequired
|
|
||||||
public static void main(String[] args) {
|
|
||||||
DrawInstruction[] dragonCurveInstructions = Fractals.dragonCurve(14);
|
|
||||||
DrawInstruction[] kochSnowflakeInstructions = Fractals.kochSnowflake(5);
|
|
||||||
|
|
||||||
FractalVisualizer fracVis = new FractalVisualizer(dragonCurveInstructions, 90);
|
|
||||||
fracVis.setVisible(true);
|
|
||||||
|
|
||||||
FractalVisualizer fracVis2 = new FractalVisualizer(kochSnowflakeInstructions, 60);
|
|
||||||
fracVis2.setVisible(true);
|
|
||||||
}
|
|
||||||
}
|
|