mirror of
				https://athene2.informatik.unibw-muenchen.de/progproj/gruppen-ht24/Gruppe-02.git
				synced 2025-10-31 22:39:02 +01:00 
			
		
		
		
	Merge branch 'main' into 'gui'
# Conflicts: # Projekte/jme-common/src/main/resources/Interface/Lemur/pp-styles.groovy # Projekte/monopoly/client/src/main/java/pp/monopoly/client/GameSound.java # Projekte/monopoly/client/src/main/java/pp/monopoly/client/MonopolyApp.java # Projekte/monopoly/client/src/main/java/pp/monopoly/client/StartMenu.java # Projekte/monopoly/model/src/main/java/pp/monopoly/game/client/ClientGameLogic.java # Projekte/monopoly/model/src/main/java/pp/monopoly/game/server/ServerGameLogic.java # Projekte/monopoly/model/src/main/resources/monopoly.properties
This commit is contained in:
		| @@ -5,10 +5,10 @@ | |||||||
| import com.simsilica.lemur.* | import com.simsilica.lemur.* | ||||||
| import com.simsilica.lemur.component.QuadBackgroundComponent | import com.simsilica.lemur.component.QuadBackgroundComponent | ||||||
|  |  | ||||||
| // Farben und allgemeine Stile |  | ||||||
| def bgColor = color(1, 1, 1, 1) | def bgColor = color(1, 1, 1, 1) | ||||||
| def buttonEnabledColor = color(0.8, 0.9, 1, 1) | def buttonEnabledColor = color(0.8, 0.9, 1, 1) | ||||||
| def buttonDisabledColor = color(0.8, 0.9, 1, 0.2) | def buttonDisabledColor = color(0.8, 0.9, 1, 0.2) | ||||||
|  | //def buttonBgColor = color(0, 0.75, 0.75, 1) | ||||||
| def sliderColor = color(0.6, 0.8, 0.8, 1) | def sliderColor = color(0.6, 0.8, 0.8, 1) | ||||||
| def sliderBgColor = color(0.5, 0.75, 0.75, 1) | def sliderBgColor = color(0.5, 0.75, 0.75, 1) | ||||||
| def gradientColor = color(1, 1, 1, 1) | def gradientColor = color(1, 1, 1, 1) | ||||||
| @@ -16,7 +16,13 @@ def tabbuttonEnabledColor = color(0.4, 0.45, 0.5, 1) | |||||||
| def playButtonBorderColor = color(1, 0.6, 0, 1) // For "Spielen" button | def playButtonBorderColor = color(1, 0.6, 0, 1) // For "Spielen" button | ||||||
| def blackColor = color(0, 0, 0, 1) // Define black color for border | def blackColor = color(0, 0, 0, 1) // Define black color for border | ||||||
|  |  | ||||||
| // Hintergrundverläufe | def playButtonBorderColor = color(1, 0.6, 0, 1) // Orange border for "Spielen" button | ||||||
|  | def playButtonTextColor = color(0, 0, 0, 1) // Black text color for "Spielen" button | ||||||
|  | def buttonBgColor = color(1, 1, 1, 1) // White background for "Spiel beenden" and "Einstellungen" buttons | ||||||
|  | def buttonTextColor = color(0, 0, 0, 1) // Black text color for "Spiel beenden" and "Einstellungen" buttons | ||||||
|  | def borderColor = color(0, 0, 0, 1) // Black border for "Spiel beenden" and "Einstellungen" | ||||||
|  |  | ||||||
|  |  | ||||||
| def gradient = TbtQuadBackgroundComponent.create( | def gradient = TbtQuadBackgroundComponent.create( | ||||||
|         texture(name: "/com/simsilica/lemur/icons/bordered-gradient.png", generateMips: false), |         texture(name: "/com/simsilica/lemur/icons/bordered-gradient.png", generateMips: false), | ||||||
|        1, 1, 1, 126, 126, 1f, false) |        1, 1, 1, 126, 126, 1f, false) | ||||||
| @@ -49,49 +55,24 @@ selector("slider", "pp") { | |||||||
|     background = new QuadBackgroundComponent(sliderBgColor) |     background = new QuadBackgroundComponent(sliderBgColor) | ||||||
| } | } | ||||||
|  |  | ||||||
| // Slider-Thumb Stil | selector("play-button", "pp") { | ||||||
| selector("slider.thumb.button", "pp") { |     color = playButtonTextColor // Black text color | ||||||
|     text = "[]" // Symbol für den Thumb |     background = new QuadBackgroundComponent(playButtonBorderColor) // Orange border background | ||||||
|     color = sliderColor |     insets = new Insets3f(15, 25, 15, 25) // Padding for larger button size | ||||||
|     insets = new Insets3f(2, 2, 2, 2) |     background.setMargin(5, 5) // Thin border effect around the background color | ||||||
|  |     fontSize = 36 // Larger font size for prominence | ||||||
| } | } | ||||||
|  |  | ||||||
| // Slider links/rechts Buttons |  | ||||||
| selector("slider.left.button", "pp") { |  | ||||||
|     text = "-" |  | ||||||
|     color = sliderColor |  | ||||||
|     background = doubleGradient.clone() |  | ||||||
|     insets = new Insets3f(5, 5, 5, 5) |  | ||||||
| } |  | ||||||
|  |  | ||||||
| selector("slider.right.button", "pp") { |  | ||||||
|     text = "+" |  | ||||||
|     color = sliderColor |  | ||||||
|     background = doubleGradient.clone() |  | ||||||
|     insets = new Insets3f(5, 5, 5, 5) |  | ||||||
| } |  | ||||||
|  |  | ||||||
| // Style für alle Buttons im Menü |  | ||||||
| selector("menu-button", "pp") { | selector("menu-button", "pp") { | ||||||
|     color = color(0, 0, 0, 1) // Schwarzer Text |     color = buttonTextColor // Black text color | ||||||
|     background = new QuadBackgroundComponent(bgColor) |     background = new QuadBackgroundComponent(buttonBgColor) // White background | ||||||
|     insets = new Insets3f(10, 20, 10, 20) |     insets = new Insets3f(10, 20, 10, 20) // Padding | ||||||
|     fontSize = 24 |     background.setMargin(1, 1) // Thin black border | ||||||
|  |     background.setColor(borderColor) // Set black border color | ||||||
|  |  | ||||||
|  |     fontSize = 24 // Standard font size | ||||||
| } | } | ||||||
|  |  | ||||||
| // Apply border to all buttons in the "pp" style |  | ||||||
| selector("button", "pp") { |  | ||||||
|     background = gradient.clone() |  | ||||||
|     background.setColor(bgColor) // Set background color |  | ||||||
|     background.setBorderColor(blackColor) // Set border color to black |  | ||||||
|     background.setBorderSize(2) // Set border thickness (adjust as needed) |  | ||||||
|  |  | ||||||
|     color = buttonEnabledColor |  | ||||||
|     insets = new Insets3f(2, 2, 2, 2) |  | ||||||
|     buttonCommands = stdButtonCommands |  | ||||||
| } |  | ||||||
|  |  | ||||||
| // Standard Button Commands (Animationseffekt) |  | ||||||
| def pressedCommand = new Command<Button>() { | def pressedCommand = new Command<Button>() { | ||||||
|     void execute(Button source) { |     void execute(Button source) { | ||||||
|         if (source.isPressed()) |         if (source.isPressed()) | ||||||
|   | |||||||
| @@ -55,6 +55,55 @@ public class MonopolyApp extends SimpleApplication implements MonopolyClient, Ga | |||||||
|         setSettings(makeSettings()); |         setSettings(makeSettings()); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|  |     /** | ||||||
|  |      * Creates and configures application settings from the client configuration. | ||||||
|  |      * | ||||||
|  |      * @return A configured {@link AppSettings} object. | ||||||
|  |      */ | ||||||
|  |     private AppSettings makeSettings() { | ||||||
|  |         final AppSettings settings = new AppSettings(true); | ||||||
|  |         settings.setTitle(lookup("monopoly.name")); | ||||||
|  |         settings.setResolution(config.getResolutionWidth(), config.getResolutionHeight()); | ||||||
|  |         settings.setFullscreen(config.fullScreen()); | ||||||
|  |         settings.setUseRetinaFrameBuffer(config.useRetinaFrameBuffer()); | ||||||
|  |         settings.setGammaCorrection(config.useGammaCorrection()); | ||||||
|  |         return settings; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     /** | ||||||
|  |      * Factory method for creating a server connection based on the current | ||||||
|  |      * client configuration. | ||||||
|  |      * | ||||||
|  |      * @return A {@link ServerConnection} instance, which could be a real or mock server. | ||||||
|  |      */ | ||||||
|  |     private ServerConnection makeServerConnection() { | ||||||
|  |         return new NetworkSupport(this); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     /** | ||||||
|  |      * Returns the dialog manager responsible for managing in-game dialogs. | ||||||
|  |      * | ||||||
|  |      * @return The {@link DialogManager} instance. | ||||||
|  |      */ | ||||||
|  |     public DialogManager getDialogManager() { | ||||||
|  |         return dialogManager; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     /** | ||||||
|  |      * Returns the game logic handler for the client. | ||||||
|  |      * | ||||||
|  |      * @return The {@link ClientGameLogic} instance. | ||||||
|  |      */ | ||||||
|  |     @Override | ||||||
|  |     public ClientGameLogic getGameLogic() { | ||||||
|  |         return logic; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     /** | ||||||
|  |      * Returns the current configuration settings for the Monopoly client. | ||||||
|  |      * | ||||||
|  |      * @return The {@link MonopolyClientConfig} instance. | ||||||
|  |      */ | ||||||
|     @Override |     @Override | ||||||
|     public MonopolyAppConfig getConfig() { |     public MonopolyAppConfig getConfig() { | ||||||
|         return config; |         return config; | ||||||
|   | |||||||
| @@ -1,123 +1,117 @@ | |||||||
| package pp.monopoly.client; | package pp.monopoly.client; | ||||||
|  |  | ||||||
|  | import com.jme3.asset.TextureKey; | ||||||
| import com.jme3.material.Material; | import com.jme3.material.Material; | ||||||
| import com.jme3.math.ColorRGBA; |  | ||||||
| import com.jme3.math.Vector3f; | import com.jme3.math.Vector3f; | ||||||
| import com.jme3.scene.Geometry; | import com.jme3.scene.Geometry; | ||||||
| import com.jme3.scene.shape.Quad; | import com.jme3.scene.shape.Quad; | ||||||
| import com.jme3.texture.Texture; | import com.jme3.texture.Texture; | ||||||
| import com.simsilica.lemur.Axis; |  | ||||||
| import com.simsilica.lemur.Button; | import com.simsilica.lemur.Button; | ||||||
| import com.simsilica.lemur.Container; | import com.simsilica.lemur.Insets3f; | ||||||
| import com.simsilica.lemur.HAlignment; |  | ||||||
| import com.simsilica.lemur.Label; | import com.simsilica.lemur.Label; | ||||||
|  | import com.simsilica.lemur.Panel; | ||||||
|  | import com.simsilica.lemur.style.ElementId; | ||||||
| import com.simsilica.lemur.component.QuadBackgroundComponent; | import com.simsilica.lemur.component.QuadBackgroundComponent; | ||||||
| import com.simsilica.lemur.component.SpringGridLayout; | import com.jme3.math.ColorRGBA; | ||||||
|  |  | ||||||
| import pp.dialog.Dialog; | import pp.dialog.Dialog; | ||||||
| import pp.monopoly.client.gui.CreateGameMenu; | import pp.monopoly.client.gui.GameMenu; | ||||||
| import pp.monopoly.client.gui.SettingsMenu; | import pp.dialog.DialogManager; | ||||||
|  |  | ||||||
|  | import java.util.prefs.Preferences; | ||||||
|  |  | ||||||
|  | import static pp.monopoly.Resources.lookup; | ||||||
|  | import static pp.util.PreferencesUtils.getPreferences; | ||||||
|  |  | ||||||
| /** |  | ||||||
|  * Constructs the startup menu dialog for the Monopoly application. |  | ||||||
|  */ |  | ||||||
| public class StartMenu extends Dialog { | public class StartMenu extends Dialog { | ||||||
|  |     private static final Preferences PREFERENCES = getPreferences(StartMenu.class); | ||||||
|     private final MonopolyApp app; |     private final MonopolyApp app; | ||||||
|  |  | ||||||
|  |     // Buttons for the menu | ||||||
|  |     private final Button playButton = new Button(lookup("button.play")); | ||||||
|  |     private final Button quitButton = new Button(lookup("menu.quit")); | ||||||
|  |     private final Button settingsButton = new Button("Einstellungen", new ElementId("menu-button")); | ||||||
|  |  | ||||||
|     /** |     /** | ||||||
|      * Constructs the Startup Menu dialog for the Monopoly application. |      * Constructs the StartMenu dialog for the Monopoly application. | ||||||
|      * |      * | ||||||
|      * @param app the MonopolyApp instance |      * @param app the MonopolyApp instance | ||||||
|      */ |      */ | ||||||
|     public StartMenu(MonopolyApp app) { |     public StartMenu(MonopolyApp app) { | ||||||
|         super(app.getDialogManager()); |         super(app.getDialogManager()); | ||||||
|         this.app = app; |         this.app = app; | ||||||
|     } |  | ||||||
|  |  | ||||||
|     /** |         // Load and display the background image | ||||||
|      * Creates and displays the Start Menu with buttons for starting the game, |         TextureKey backgroundKey = new TextureKey("unibw-bib", false); | ||||||
|      * opening settings, and quitting the application. |         Texture backgroundTexture = app.getAssetManager().loadTexture(backgroundKey); | ||||||
|      */ |  | ||||||
|     public static void createStartMenu(MonopolyApp app) { |  | ||||||
|         int screenWidth = app.getContext().getSettings().getWidth(); |  | ||||||
|         int screenHeight = app.getContext().getSettings().getHeight(); |  | ||||||
|  |  | ||||||
|         // Set up the background image |  | ||||||
|         Texture backgroundImage = app.getAssetManager().loadTexture("Pictures/unibw-Bib2.png"); |  | ||||||
|         Quad quad = new Quad(screenWidth, screenHeight); |  | ||||||
|         Geometry background = new Geometry("Background", quad); |  | ||||||
|         Material backgroundMaterial = new Material(app.getAssetManager(), "Common/MatDefs/Misc/Unshaded.j3md"); |         Material backgroundMaterial = new Material(app.getAssetManager(), "Common/MatDefs/Misc/Unshaded.j3md"); | ||||||
|         backgroundMaterial.setTexture("ColorMap", backgroundImage); |         backgroundMaterial.setTexture("ColorMap", backgroundTexture); | ||||||
|  |  | ||||||
|  |         // Create a large Quad for the background | ||||||
|  |         Quad backgroundQuad = new Quad(16, 9); // Adjust size as necessary to fill the screen | ||||||
|  |         Geometry background = new Geometry("Background", backgroundQuad); | ||||||
|         background.setMaterial(backgroundMaterial); |         background.setMaterial(backgroundMaterial); | ||||||
|         background.setLocalTranslation(0, 0, -1); // Ensure it is behind other GUI elements |         background.setLocalTranslation(new Vector3f(-8, -4.5f, -1)); // Position it behind the UI components | ||||||
|  |  | ||||||
|  |         // Attach the background as the first element | ||||||
|         app.getGuiNode().attachChild(background); |         app.getGuiNode().attachChild(background); | ||||||
|  |  | ||||||
|         // Center container for title and play button |         // Load and display the Monopoly logo | ||||||
|         Container centerMenu = new Container(new SpringGridLayout(Axis.Y, Axis.X)); |         TextureKey monopolyLogoKey = new TextureKey("log-Monopoly", false); | ||||||
|  |         Texture monopolyLogoTexture = app.getAssetManager().loadTexture(monopolyLogoKey); | ||||||
|  |         Material monopolyLogoMaterial = new Material(app.getAssetManager(), "Common/MatDefs/Misc/Unshaded.j3md"); | ||||||
|  |         monopolyLogoMaterial.setTexture("ColorMap", monopolyLogoTexture); | ||||||
|  |  | ||||||
|         Button startButton = new Button("Spielen"); |         Quad monopolyQuad = new Quad(5, 1.5f); // Adjust dimensions as necessary | ||||||
|         startButton.setPreferredSize(new Vector3f(190, 60, 0)); // Increase button size (width, height) |         Geometry monopolyLogo = new Geometry("MonopolyLogo", monopolyQuad); | ||||||
|         startButton.setFontSize(40); // Set the font size for the button text |         monopolyLogo.setMaterial(monopolyLogoMaterial); | ||||||
|         startButton.setTextHAlignment(HAlignment.Center); // Center the text horizontally |         monopolyLogo.setLocalTranslation(new Vector3f(0, 5, 0)); // Position Monopoly logo at the top | ||||||
|  |  | ||||||
|         // Set a custom border and background color |         Panel monopolyLogoPanel = new Panel(); | ||||||
|         ColorRGBA borderColor = ColorRGBA.Orange; // Example: White border |         addChild(monopolyLogoPanel); | ||||||
|         ColorRGBA backgroundColor = ColorRGBA.LightGray; // Example: light gray background |  | ||||||
|         QuadBackgroundComponent backgroundColorSp = new QuadBackgroundComponent(backgroundColor); |  | ||||||
|         backgroundColorSp.setMargin(2, 2); // Optional: Adjust margin for the border |  | ||||||
|         backgroundColorSp.setColor(borderColor); // Set border color |  | ||||||
|         startButton.setBackground(backgroundColorSp); |  | ||||||
|  |  | ||||||
|         startButton.addClickCommands(source -> startGame(app)); |         // Load and display the university logo | ||||||
|         centerMenu.addChild(startButton); |         TextureKey universityLogoKey = new TextureKey("unibw-logo.png", false); | ||||||
|  |         Texture universityLogoTexture = app.getAssetManager().loadTexture(universityLogoKey); | ||||||
|  |         Material universityLogoMaterial = new Material(app.getAssetManager(), "Common/MatDefs/Misc/Unshaded.j3md"); | ||||||
|  |         universityLogoMaterial.setTexture("ColorMap", universityLogoTexture); | ||||||
|  |  | ||||||
|         // Position the center container in the middle of the screen |         Quad universityQuad = new Quad(4, 1); // Adjust dimensions to fit below Monopoly logo | ||||||
|         centerMenu.setLocalTranslation(new Vector3f(screenWidth / 2f - centerMenu.getPreferredSize().x / 2f, |         Geometry universityLogo = new Geometry("UniversityLogo", universityQuad); | ||||||
|                                                     screenHeight / 2f - 280 + centerMenu.getPreferredSize().y / 2f, |         universityLogo.setMaterial(universityLogoMaterial); | ||||||
|                                                     0)); |         universityLogo.setLocalTranslation(new Vector3f(0, 3, 0)); // Position below the Monopoly logo | ||||||
|         app.getGuiNode().attachChild(centerMenu); |  | ||||||
|  |  | ||||||
|         // Lower-left container for "Spiel beenden" button |         Panel universityLogoPanel = new Panel(); | ||||||
|         Container lowerLeftMenu = new Container(); |         addChild(universityLogoPanel); | ||||||
|         lowerLeftMenu.setLocalTranslation(new Vector3f(100, 90, 0)); |  | ||||||
|         Button quitButton = new Button("Spiel beenden"); |  | ||||||
|         quitButton.setPreferredSize(new Vector3f(130, 40, 0)); // Increase button size slightly (width, height) |  | ||||||
|         quitButton.setFontSize(20); |  | ||||||
|         quitButton.addClickCommands(source -> quitGame()); |  | ||||||
|         lowerLeftMenu.addChild(quitButton); |  | ||||||
|         app.getGuiNode().attachChild(lowerLeftMenu); |  | ||||||
|  |  | ||||||
|         // Lower-right container for "Einstellungen" button |  | ||||||
|         Container lowerRightMenu = new Container(); |  | ||||||
|         lowerRightMenu.setLocalTranslation(new Vector3f(screenWidth - 200, 90, 0)); |         // Button actions | ||||||
|         Button settingsButton = new Button("Einstellungen"); |         playButton.addClickCommands(source -> startGame()); | ||||||
|         settingsButton.setPreferredSize(new Vector3f(130, 40, 0)); // Increase button size slightly (width, height) |         quitButton.addClickCommands(source -> app.closeApp()); | ||||||
|         settingsButton.setFontSize(20); // Increase the font size for the text |         settingsButton.addClickCommands(source -> openSettings()); | ||||||
|         settingsButton.addClickCommands(source -> openSettings(app)); |  | ||||||
|         lowerRightMenu.addChild(settingsButton); |         addChild(monopolyLogoPanel); | ||||||
|         app.getGuiNode().attachChild(lowerRightMenu); |         addChild(universityLogoPanel); | ||||||
|  |         addChild(playButton); | ||||||
|  |         addChild(quitButton); | ||||||
|  |         addChild(settingsButton); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     /** |     private void startGame() { | ||||||
|      * Starts the game by transitioning to the CreateGameMenu. |         System.out.println("Starting game..."); | ||||||
|      */ |  | ||||||
|     private static void startGame(MonopolyApp app) { |  | ||||||
|         app.getGuiNode().detachAllChildren(); |  | ||||||
|         new CreateGameMenu(app); |  | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     /** |     private void openSettings() { | ||||||
|      * Opens the settings menu. |         app.getDialogManager().close(this); | ||||||
|      */ |         app.getDialogManager().open(new GameMenu(app)); | ||||||
|     private static void openSettings(MonopolyApp app) { |  | ||||||
|         app.getGuiNode().detachAllChildren(); |  | ||||||
|         new SettingsMenu(app); |  | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     /** |     @Override | ||||||
|      * Quits the game application. |     public void update() { | ||||||
|      */ |     } | ||||||
|     private static void quitGame() { |  | ||||||
|         System.exit(0); |     @Override | ||||||
|  |     public void escape() { | ||||||
|  |         close(); | ||||||
|     } |     } | ||||||
| } | } | ||||||
|   | |||||||
| @@ -0,0 +1,50 @@ | |||||||
|  | package pp.monopoly.client.gui; | ||||||
|  |  | ||||||
|  |  | ||||||
|  | import com.jme3.math.ColorRGBA; | ||||||
|  | import com.simsilica.lemur.Button; | ||||||
|  | import com.simsilica.lemur.Label; | ||||||
|  | import com.simsilica.lemur.style.ElementId; | ||||||
|  | import pp.dialog.Dialog; | ||||||
|  | import pp.monopoly.client.MonopolyApp; | ||||||
|  |  | ||||||
|  | public class GameMenu extends Dialog { | ||||||
|  |     private final MonopolyApp app; | ||||||
|  |  | ||||||
|  |     /** | ||||||
|  |      * Constructs the SettingsMenu dialog for the Monopoly application. | ||||||
|  |      * | ||||||
|  |      * @param app the MonopolyApp instance | ||||||
|  |      */ | ||||||
|  |     public GameMenu(MonopolyApp app) { | ||||||
|  |         super(app.getDialogManager()); | ||||||
|  |         this.app = app; | ||||||
|  |  | ||||||
|  |         // Add a title label for Settings | ||||||
|  |         Label settingsTitle = new Label("Einstellungen", new ElementId("settings-title")); | ||||||
|  |         settingsTitle.setFontSize(48);  // Set font size for the title | ||||||
|  |         settingsTitle.setColor(ColorRGBA.White); | ||||||
|  |  | ||||||
|  |         // Add any settings-related components here, such as volume control, toggles, etc. | ||||||
|  |  | ||||||
|  |         // Add a back button to return to StartMenu | ||||||
|  |         Button backButton = new Button("Zurück", new ElementId("menu-button")); | ||||||
|  |         backButton.setColor(ColorRGBA.White); | ||||||
|  |         backButton.setFontSize(24); | ||||||
|  |         backButton.addClickCommands(source -> returnToStartMenu()); | ||||||
|  |  | ||||||
|  |         // Add components to this dialog | ||||||
|  |         addChild(settingsTitle); | ||||||
|  |         addChild(backButton); | ||||||
|  |  | ||||||
|  |         // You can add more settings components here, like checkboxes or sliders. | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     /** | ||||||
|  |      * Returns to the StartMenu when the back button is clicked. | ||||||
|  |      */ | ||||||
|  |     private void returnToStartMenu() { | ||||||
|  |         app.getDialogManager().close(this); // Close the current settings dialog | ||||||
|  |         //TODO return zum Ausgangsmenü | ||||||
|  |     } | ||||||
|  | } | ||||||
										
											Binary file not shown.
										
									
								
							| After Width: | Height: | Size: 144 KiB | 
| @@ -7,6 +7,30 @@ | |||||||
|  |  | ||||||
| package pp.monopoly.game.client; | package pp.monopoly.game.client; | ||||||
|  |  | ||||||
|  | import pp.monopoly.message.client.ClientMessage; | ||||||
|  | import pp.monopoly.message.server.BuyPropertyResponse; | ||||||
|  | import pp.monopoly.message.server.DiceResult; | ||||||
|  | import pp.monopoly.message.server.EventDrawCard; | ||||||
|  | import pp.monopoly.message.server.GameOver; | ||||||
|  | import pp.monopoly.message.server.GameStart; | ||||||
|  | import pp.monopoly.message.server.JailEvent; | ||||||
|  | import pp.monopoly.message.server.PlayerStatusUpdate; | ||||||
|  | import pp.monopoly.message.server.ServerInterpreter; | ||||||
|  | import pp.monopoly.message.server.TimeOutWarning; | ||||||
|  | import pp.monopoly.message.server.TradeReply; | ||||||
|  | import pp.monopoly.message.server.TradeRequest; | ||||||
|  | import pp.monopoly.message.server.UpdatePlayerAssets; | ||||||
|  | import pp.monopoly.message.server.ViewAssetsResponse; | ||||||
|  | import pp.monopoly.model.IntPoint; | ||||||
|  | import pp.monopoly.model.Board; | ||||||
|  | import pp.monopoly.notification.ClientStateEvent; | ||||||
|  | import pp.monopoly.notification.GameEvent; | ||||||
|  | import pp.monopoly.notification.GameEventBroker; | ||||||
|  | import pp.monopoly.notification.GameEventListener; | ||||||
|  | import pp.monopoly.notification.InfoTextEvent; | ||||||
|  | import pp.monopoly.notification.Sound; | ||||||
|  | import pp.monopoly.notification.SoundEvent; | ||||||
|  |  | ||||||
| import java.io.File; | import java.io.File; | ||||||
| import java.io.IOException; | import java.io.IOException; | ||||||
| import java.lang.System.Logger; | import java.lang.System.Logger; | ||||||
| @@ -168,4 +192,76 @@ public class ClientGameLogic implements ServerInterpreter, GameEventBroker { | |||||||
|     public void update(float delta) { |     public void update(float delta) { | ||||||
|         state.update(delta); |         state.update(delta); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|  |     @Override | ||||||
|  |     public void received(BuyPropertyResponse msg) { | ||||||
|  |         // TODO Auto-generated method stub | ||||||
|  |         throw new UnsupportedOperationException("Unimplemented method 'received'"); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     @Override | ||||||
|  |     public void received(DiceResult msg) { | ||||||
|  |         // TODO Auto-generated method stub | ||||||
|  |         throw new UnsupportedOperationException("Unimplemented method 'received'"); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     @Override | ||||||
|  |     public void received(EventDrawCard msg) { | ||||||
|  |         // TODO Auto-generated method stub | ||||||
|  |         throw new UnsupportedOperationException("Unimplemented method 'received'"); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     @Override | ||||||
|  |     public void received(GameOver msg) { | ||||||
|  |         // TODO Auto-generated method stub | ||||||
|  |         throw new UnsupportedOperationException("Unimplemented method 'received'"); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     @Override | ||||||
|  |     public void received(GameStart msg) { | ||||||
|  |         // TODO Auto-generated method stub | ||||||
|  |         throw new UnsupportedOperationException("Unimplemented method 'received'"); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     @Override | ||||||
|  |     public void received(JailEvent msg) { | ||||||
|  |         // TODO Auto-generated method stub | ||||||
|  |         throw new UnsupportedOperationException("Unimplemented method 'received'"); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     @Override | ||||||
|  |     public void received(PlayerStatusUpdate msg) { | ||||||
|  |         // TODO Auto-generated method stub | ||||||
|  |         throw new UnsupportedOperationException("Unimplemented method 'received'"); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     @Override | ||||||
|  |     public void received(TimeOutWarning msg) { | ||||||
|  |         // TODO Auto-generated method stub | ||||||
|  |         throw new UnsupportedOperationException("Unimplemented method 'received'"); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     @Override | ||||||
|  |     public void received(UpdatePlayerAssets msg) { | ||||||
|  |         // TODO Auto-generated method stub | ||||||
|  |         throw new UnsupportedOperationException("Unimplemented method 'received'"); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     @Override | ||||||
|  |     public void received(ViewAssetsResponse msg) { | ||||||
|  |         // TODO Auto-generated method stub | ||||||
|  |         throw new UnsupportedOperationException("Unimplemented method 'received'"); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     @Override | ||||||
|  |     public void received(TradeReply msg) { | ||||||
|  |         // TODO Auto-generated method stub | ||||||
|  |         throw new UnsupportedOperationException("Unimplemented method 'received'"); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     @Override | ||||||
|  |     public void received(TradeRequest msg) { | ||||||
|  |         // TODO Auto-generated method stub | ||||||
|  |         throw new UnsupportedOperationException("Unimplemented method 'received'"); | ||||||
|  |     } | ||||||
| } | } | ||||||
|   | |||||||
| @@ -7,9 +7,481 @@ | |||||||
|  |  | ||||||
| package pp.monopoly.game.server; | package pp.monopoly.game.server; | ||||||
|  |  | ||||||
|  | import java.util.List; | ||||||
|  | import java.util.Random; | ||||||
|  |  | ||||||
|  | import pp.monopoly.message.server.DiceResult; | ||||||
|  | import pp.monopoly.model.FieldVisitor; | ||||||
|  | import pp.monopoly.model.Figure; | ||||||
|  | import pp.monopoly.model.card.DeckHelper; | ||||||
|  | import pp.monopoly.model.fields.BuildingProperty; | ||||||
|  | import pp.monopoly.model.fields.EventField; | ||||||
|  | import pp.monopoly.model.fields.FineField; | ||||||
|  | import pp.monopoly.model.fields.FoodField; | ||||||
|  | import pp.monopoly.model.fields.GateField; | ||||||
|  | import pp.monopoly.model.fields.GoField; | ||||||
|  | import pp.monopoly.model.fields.GulagField; | ||||||
|  | import pp.monopoly.model.fields.PropertyField; | ||||||
|  | import pp.monopoly.model.fields.TestStreckeField; | ||||||
|  | import pp.monopoly.model.fields.WacheField; | ||||||
|  |  | ||||||
| /** | /** | ||||||
|  * Class representing a player |  * Class representing a player | ||||||
|  */ |  */ | ||||||
| public class Player { | public class Player implements FieldVisitor<Void>{ | ||||||
|   |     private final int id; | ||||||
|  |     private String name; | ||||||
|  |     private PlayerColor color; | ||||||
|  |     private int accountBalance = 0; | ||||||
|  |     private Figure figure; | ||||||
|  |     private List<PropertyField> properties; | ||||||
|  |     private int getOutOfJailCard; | ||||||
|  |     private int fieldID; | ||||||
|  |     private DiceResult rollResult; | ||||||
|  |     private final PlayerHandler handler; | ||||||
|  |     private PlayerState state = new LobbyState(); | ||||||
|  |  | ||||||
|  |     /** | ||||||
|  |      * Constructs a player with the speciefied params | ||||||
|  |      * @param id the id of the player | ||||||
|  |      * @param name the name of the player | ||||||
|  |      * @param handler the PlayerHandler thispalyer is a part of | ||||||
|  |      */ | ||||||
|  |     public Player(int id, String name, PlayerHandler handler) { | ||||||
|  |         this.name = name; | ||||||
|  |         this.id = id; | ||||||
|  |         this.handler = handler; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     /** | ||||||
|  |      * Constructs a player with the specified id | ||||||
|  |      * @param id the id of the player | ||||||
|  |      * @param handler the PlayerHandler this player is a part of | ||||||
|  |      */ | ||||||
|  |     public Player(int id, PlayerHandler handler) { | ||||||
|  |         this.id = id; | ||||||
|  |         this.handler = handler; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     /** | ||||||
|  |      * Set the name of the Player | ||||||
|  |      * @param name the new name | ||||||
|  |      */ | ||||||
|  |     void setName(String name) { | ||||||
|  |         this.name = name; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     /** | ||||||
|  |      * Set the PlayerColor | ||||||
|  |      * @param color the color to be set to | ||||||
|  |      */ | ||||||
|  |     void setColor(PlayerColor color) { | ||||||
|  |         this.color = color; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     /** | ||||||
|  |      * Returns this players id | ||||||
|  |      * @return th eid of this player | ||||||
|  |      */ | ||||||
|  |     public int getId() { | ||||||
|  |         return id; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     /** | ||||||
|  |      * Returns the current position of the player | ||||||
|  |      * @return the current position of this player | ||||||
|  |      */ | ||||||
|  |     public int getFieldID() { | ||||||
|  |         return fieldID; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     /** | ||||||
|  |      * Moves by the specified amount of steps | ||||||
|  |      * @param steps the number of steps to move | ||||||
|  |      * @return the new position | ||||||
|  |      */ | ||||||
|  |     public int move(int steps){ | ||||||
|  |         return movePos(fieldID+steps); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     /** | ||||||
|  |      * Moves the player to the specified Position on the board | ||||||
|  |      * @param position the position to move to | ||||||
|  |      * @return the new position | ||||||
|  |      */ | ||||||
|  |     public int movePos(int position){ | ||||||
|  |         fieldID = fieldID+position; | ||||||
|  |         if(fieldID >= 40) { | ||||||
|  |             fieldID = fieldID%40; | ||||||
|  |             earnMoney(2000); | ||||||
|  |         } | ||||||
|  |         return fieldID; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     /** | ||||||
|  |      * Gets all the properties owned by this player | ||||||
|  |      * @return List of all properties owned by this player | ||||||
|  |      */ | ||||||
|  |     public List<PropertyField> getProperties() { | ||||||
|  |         return properties; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     /** | ||||||
|  |      * Buy the speciefied property. | ||||||
|  |      * Properties can olny be bought when they are not sold yet and you have enough money left to buy | ||||||
|  |      * @param property to property to be bought | ||||||
|  |      */ | ||||||
|  |     public void buyProperty(PropertyField property) { | ||||||
|  |         if (property.getOwner() == null && accountBalance >= property.getPrice()) { | ||||||
|  |             properties.add(property); | ||||||
|  |             pay(property.getPrice()); | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     /** | ||||||
|  |      * Sell the property | ||||||
|  |      * @param property the property to be sold | ||||||
|  |      */ | ||||||
|  |     public void sellProperty(PropertyField property) { | ||||||
|  |         if (property.getOwner() == this) { | ||||||
|  |             properties.remove(property); | ||||||
|  |             property.setOwner(null); | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     /** | ||||||
|  |      * Gets this players current accountBalanece | ||||||
|  |      * @return the amount of money currently owned by this player | ||||||
|  |      */ | ||||||
|  |     public int getAccountBalance() { | ||||||
|  |         return accountBalance; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     /** | ||||||
|  |      * Removed the speciefied amount of money to this players accountabalance | ||||||
|  |      * @param amount the amount to be removed | ||||||
|  |      */ | ||||||
|  |     public void pay(int amount) { | ||||||
|  |         accountBalance -= amount; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     /** | ||||||
|  |      * Add the speciefied amount of money to this players accountabalance | ||||||
|  |      * @param amount the amount to be added | ||||||
|  |      */ | ||||||
|  |     public void earnMoney(int amount) { | ||||||
|  |         accountBalance += amount; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     /** | ||||||
|  |      * Return the players name | ||||||
|  |      * @return the name of this player | ||||||
|  |      */ | ||||||
|  |     public String getName() { | ||||||
|  |         return name; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     /** | ||||||
|  |      * Return the number of GEtOutOfJailCards owned by this player | ||||||
|  |      * @return | ||||||
|  |      */ | ||||||
|  |     public int getNumJailCard() { | ||||||
|  |         return getOutOfJailCard; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     /** | ||||||
|  |      * Adds a GetOutOfJailCard | ||||||
|  |      */ | ||||||
|  |     public void addJailCard() { | ||||||
|  |         getOutOfJailCard++; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     /** | ||||||
|  |      * Removes a GetOutOfJailCard. | ||||||
|  |      * Removes one single card per call, to a minimum of 0 cards | ||||||
|  |      */ | ||||||
|  |     public void removeJailCard() { | ||||||
|  |         if (getOutOfJailCard ==0) { | ||||||
|  |             throw new IllegalStateException("Has no JailCard to remove"); | ||||||
|  |         } | ||||||
|  |         getOutOfJailCard--; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     /** | ||||||
|  |      * Handles the logic of paying the jail bail | ||||||
|  |      */ | ||||||
|  |     public void payBail() { | ||||||
|  |         state.payBail(); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     /** | ||||||
|  |      * Handles the logic of using a GetOutOfJailCard | ||||||
|  |      */ | ||||||
|  |     public void useJailCard() { | ||||||
|  |         state.useJailCard(); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     @Override | ||||||
|  |     public Void visit(BuildingProperty field) { | ||||||
|  |         int rent = field.calcRent(); | ||||||
|  |  | ||||||
|  |         field.getOwner().earnMoney(rent); | ||||||
|  |         pay(rent); | ||||||
|  |         return null; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     @Override | ||||||
|  |     public Void visit(FoodField field) { | ||||||
|  |         int factor = 4; | ||||||
|  |         if (field.getOwner().getNumProp(field) == 2) { | ||||||
|  |             factor = 10; | ||||||
|  |         } | ||||||
|  |         field.getOwner().earnMoney(rollResult.calcTotal()*factor); | ||||||
|  |         pay(rollResult.calcTotal()*factor); | ||||||
|  |         return null; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     @Override | ||||||
|  |     public Void visit(GateField field) { | ||||||
|  |         int rent = field.calcRent() * field.getOwner().getNumProp(field); | ||||||
|  |  | ||||||
|  |         field.getOwner().earnMoney(rent); | ||||||
|  |         pay(rent); | ||||||
|  |         return null; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     @Override | ||||||
|  |     public Void visit(GulagField field) { | ||||||
|  |         state = new JailState(); | ||||||
|  |         return null; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     @Override | ||||||
|  |     public Void visit(TestStreckeField field) { | ||||||
|  |         earnMoney(field.collectMoney()); | ||||||
|  |         return null; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     @Override | ||||||
|  |     public Void visit(EventField field) { | ||||||
|  |         DeckHelper.drawCard(); | ||||||
|  |         return null; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     @Override | ||||||
|  |     public Void visit(WacheField field) { | ||||||
|  |         movePos(10); | ||||||
|  |         return null; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     @Override | ||||||
|  |     public Void visit(GoField field) { | ||||||
|  |         earnMoney(2000); | ||||||
|  |         GulagField res = (GulagField) handler.getLogic().getBoardManager().getFieldAtIndex(10); | ||||||
|  |         res.accept(this); | ||||||
|  |         return null; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     @Override | ||||||
|  |     public Void visit(FineField field) { | ||||||
|  |         int amount = field.getFine(); | ||||||
|  |         pay(amount); | ||||||
|  |         TestStreckeField res =(TestStreckeField) handler.getLogic().getBoardManager().getFieldAtIndex(20); | ||||||
|  |         res.addMoney(amount); | ||||||
|  |         return null; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     /** | ||||||
|  |      * Return the number of Properties of the speciefied fild type | ||||||
|  |      * @param field the type of field to search for | ||||||
|  |      * @return the number of the fields owned with the specified type | ||||||
|  |      */ | ||||||
|  |     public int getNumProp(PropertyField field) { | ||||||
|  |         int count = 0; | ||||||
|  |         for (PropertyField propertyField : properties) { | ||||||
|  |             if (propertyField.getClass() == field.getClass()) { | ||||||
|  |                 count++; | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         return count; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |         /** | ||||||
|  |      * Inner class for dice functionality in the game. | ||||||
|  |      * Rolls random dice values. | ||||||
|  |      */ | ||||||
|  |     private class Dice { | ||||||
|  |         private static Random random = new Random(); | ||||||
|  |  | ||||||
|  |         /** | ||||||
|  |          * Rolls a single die and returns a random value from 1 to 6. | ||||||
|  |          * | ||||||
|  |          * @return the result of a dice roll (1 to 6) | ||||||
|  |          */ | ||||||
|  |         private static int rollDice() { | ||||||
|  |             return random.nextInt(6) + 1; | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     /** | ||||||
|  |      * Rolls two dice and returns a list with the results. | ||||||
|  |      * | ||||||
|  |      * @return a List of two integers representing the dice roll results | ||||||
|  |      */ | ||||||
|  |     DiceResult rollDice() { | ||||||
|  |         return state.rollDice(); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     /** | ||||||
|  |      * A interface representing the PlayerStates | ||||||
|  |      */ | ||||||
|  |     private interface PlayerState { | ||||||
|  |         /** | ||||||
|  |          * Handles the logic for rolling Dice | ||||||
|  |          * @return the {@link DiceResult} of this the DiceRoll | ||||||
|  |          */ | ||||||
|  |         DiceResult rollDice(); | ||||||
|  |  | ||||||
|  |         /** | ||||||
|  |          * Handles the logic for paying the Jail Bail | ||||||
|  |          */ | ||||||
|  |         void payBail(); | ||||||
|  |  | ||||||
|  |         /** | ||||||
|  |          * Handles the action of using a GetOutOfJail Card | ||||||
|  |          */ | ||||||
|  |         void useJailCard(); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |  | ||||||
|  |     /** | ||||||
|  |      * Class to represent the Active PlayerState | ||||||
|  |      * This class is set when it is the Players turn to do actions | ||||||
|  |      */ | ||||||
|  |     private class ActiveState implements PlayerState { | ||||||
|  |  | ||||||
|  |         @Override | ||||||
|  |         public DiceResult rollDice() { | ||||||
|  |             List<Integer> roll = List.of(Dice.rollDice(), Dice.rollDice()); | ||||||
|  |             rollResult = new DiceResult(roll); | ||||||
|  |             return rollResult; | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         @Override | ||||||
|  |         public void payBail() { | ||||||
|  |             // do nothing | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         @Override | ||||||
|  |         public void useJailCard() { | ||||||
|  |             // do nothings | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |  | ||||||
|  |     /** | ||||||
|  |      * A class to represent the Lobby PlayerState | ||||||
|  |      * Set when in Lobby | ||||||
|  |      */ | ||||||
|  |     private class LobbyState implements PlayerState{ | ||||||
|  |  | ||||||
|  |         @Override | ||||||
|  |         public DiceResult rollDice() { | ||||||
|  |             //do nothing | ||||||
|  |             return null; | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         @Override | ||||||
|  |         public void payBail() { | ||||||
|  |             //do nothing | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         @Override | ||||||
|  |         public void useJailCard() { | ||||||
|  |             // do nothing | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |  | ||||||
|  |     /** | ||||||
|  |      * A class to represent the Jailed PlayerState | ||||||
|  |      * Set when in Gulag | ||||||
|  |      */ | ||||||
|  |     private class JailState implements PlayerState { | ||||||
|  |  | ||||||
|  |         private int DoubletsCounter = 3; | ||||||
|  |  | ||||||
|  |         @Override | ||||||
|  |         public DiceResult rollDice() { | ||||||
|  |             List<Integer> roll = List.of(Dice.rollDice(), Dice.rollDice()); | ||||||
|  |             rollResult = new DiceResult(roll); | ||||||
|  |             if (rollResult.isDoublets()) { | ||||||
|  |                 state = new ActiveState(); | ||||||
|  |             } else if (DoubletsCounter == 0) { | ||||||
|  |  | ||||||
|  |             } else { | ||||||
|  |                 DoubletsCounter--; | ||||||
|  |             } | ||||||
|  |             return rollResult; | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         @Override | ||||||
|  |         public void payBail() { | ||||||
|  |             pay(500); | ||||||
|  |             state = new ActiveState(); | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         @Override | ||||||
|  |         public void useJailCard() { | ||||||
|  |             getOutOfJailCard--; | ||||||
|  |             state = new ActiveState(); | ||||||
|  |         } | ||||||
|  |          | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     private class BankruptState implements PlayerState { | ||||||
|  |  | ||||||
|  |         @Override | ||||||
|  |         public DiceResult rollDice() { | ||||||
|  |             // TODO Auto-generated method stub | ||||||
|  |             throw new UnsupportedOperationException("Unimplemented method 'rollDice'"); | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         @Override | ||||||
|  |         public void payBail() { | ||||||
|  |             // TODO Auto-generated method stub | ||||||
|  |             throw new UnsupportedOperationException("Unimplemented method 'payBail'"); | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         @Override | ||||||
|  |         public void useJailCard() { | ||||||
|  |             // TODO Auto-generated method stub | ||||||
|  |             throw new UnsupportedOperationException("Unimplemented method 'useJailCard'"); | ||||||
|  |         } | ||||||
|  |          | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     private class WaitForTurnState implements PlayerState { | ||||||
|  |  | ||||||
|  |         @Override | ||||||
|  |         public DiceResult rollDice() { | ||||||
|  |             // TODO Auto-generated method stub | ||||||
|  |             throw new UnsupportedOperationException("Unimplemented method 'rollDice'"); | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         @Override | ||||||
|  |         public void payBail() { | ||||||
|  |             // TODO Auto-generated method stub | ||||||
|  |             throw new UnsupportedOperationException("Unimplemented method 'payBail'"); | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         @Override | ||||||
|  |         public void useJailCard() { | ||||||
|  |             // TODO Auto-generated method stub | ||||||
|  |             throw new UnsupportedOperationException("Unimplemented method 'useJailCard'"); | ||||||
|  |         } | ||||||
|  |          | ||||||
|  |     } | ||||||
| } | } | ||||||
|   | |||||||
| @@ -0,0 +1,35 @@ | |||||||
|  | package pp.monopoly.game.server; | ||||||
|  |  | ||||||
|  | import com.jme3.math.ColorRGBA; | ||||||
|  |  | ||||||
|  | /** | ||||||
|  |  * Enum representing six distinct colors for players in the game. | ||||||
|  |  */ | ||||||
|  | public enum PlayerColor { | ||||||
|  |     GREEN_LIGHT(new ColorRGBA(0 / 255f, 204 / 255f, 0 / 255f, 1)),   // Hex: 00cc00 | ||||||
|  |     RED(new ColorRGBA(255 / 255f, 0 / 255f, 0 / 255f, 1)),           // Hex: ff0000 | ||||||
|  |     BLUE(new ColorRGBA(0 / 255f, 0 / 255f, 204 / 255f, 1)),          // Hex: 0000cc | ||||||
|  |     PINK(new ColorRGBA(255 / 255f, 77 / 255f, 166 / 255f, 1)),       // Hex: ff4da6 | ||||||
|  |     GREEN_DARK(new ColorRGBA(0 / 255f, 102 / 255f, 0 / 255f, 1)),    // Hex: 006600 | ||||||
|  |     YELLOW(new ColorRGBA(255 / 255f, 255 / 255f, 0 / 255f, 1));      // Hex: ffff00 | ||||||
|  |  | ||||||
|  |     private final ColorRGBA color; | ||||||
|  |  | ||||||
|  |     /** | ||||||
|  |      * Constructs a PlayerColor with the specified ColorRGBA value. | ||||||
|  |      * | ||||||
|  |      * @param color the ColorRGBA value associated with the player color | ||||||
|  |      */ | ||||||
|  |     PlayerColor(ColorRGBA color) { | ||||||
|  |         this.color = color; | ||||||
|  |     }  | ||||||
|  |  | ||||||
|  |     /** | ||||||
|  |      * Gets the ColorRGBA value of the player color. | ||||||
|  |      * | ||||||
|  |      * @return the ColorRGBA value | ||||||
|  |      */ | ||||||
|  |     public ColorRGBA getColor() { | ||||||
|  |         return color; | ||||||
|  |     } | ||||||
|  | } | ||||||
| @@ -0,0 +1,135 @@ | |||||||
|  | package pp.monopoly.game.server; | ||||||
|  |  | ||||||
|  | import java.util.LinkedList; | ||||||
|  | import java.util.Collection; | ||||||
|  | import java.util.HashSet; | ||||||
|  | import java.util.List; | ||||||
|  | import java.util.NoSuchElementException; | ||||||
|  | import java.util.Set; | ||||||
|  | /** | ||||||
|  |  * A class for helping with player actions and managing thier turns | ||||||
|  |  */ | ||||||
|  | public class PlayerHandler { | ||||||
|  |     private List<Player> players = new LinkedList<>(); | ||||||
|  |     private Set<Player> readyPlayers = new HashSet<>(); | ||||||
|  |     private ServerGameLogic logic; | ||||||
|  |  | ||||||
|  |     /** | ||||||
|  |      * Contructs a PlayerHandler | ||||||
|  |      * @param logic the {@link ServerGameLogic} this PlayerHandler is a part of | ||||||
|  |      */ | ||||||
|  |     PlayerHandler(ServerGameLogic logic) { | ||||||
|  |         this.logic = logic; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     /** | ||||||
|  |      * Contructs a PlayerHandler | ||||||
|  |      * @param logic the {@link ServerGameLogic} this PlayerHandler is a part of | ||||||
|  |      * @param p1 a Player to be added | ||||||
|  |      */ | ||||||
|  |     PlayerHandler(ServerGameLogic logic, Player p1) { | ||||||
|  |         this(logic); | ||||||
|  |         players.add(p1); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     /** | ||||||
|  |      * Contructs a PlayerHandler | ||||||
|  |      * @param logic the {@link ServerGameLogic} this PlayerHandler is a part of | ||||||
|  |      * @param players a Collection of Players to be added | ||||||
|  |      */ | ||||||
|  |     PlayerHandler(ServerGameLogic logic, Collection<Player> players) { | ||||||
|  |         this(logic); | ||||||
|  |         players.addAll(players); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     /** | ||||||
|  |      * Return the number of players | ||||||
|  |      * @return number of players in the game | ||||||
|  |      */ | ||||||
|  |     public int getPlayerCount() { | ||||||
|  |         return players.size(); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     /** | ||||||
|  |      * Chechs if all players are ready to start the game | ||||||
|  |      * @return {@code true} if all players are ready, otherwise {@code false} | ||||||
|  |      */ | ||||||
|  |     public boolean allPlayersReady() { | ||||||
|  |         if (readyPlayers.size() == players.size()) return true; | ||||||
|  |         return false; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     /** | ||||||
|  |      * Sets a players Ready status | ||||||
|  |      * @param player the player to alter | ||||||
|  |      * @param ready the new Status | ||||||
|  |      */ | ||||||
|  |     void setPlayerReady(Player player, boolean ready) { | ||||||
|  |         if (!players.contains(player)) { | ||||||
|  |             throw new IllegalArgumentException("Player does not belong to this PlayerHandler"); | ||||||
|  |         } else { | ||||||
|  |             if (ready) { | ||||||
|  |                 readyPlayers.add(player); | ||||||
|  |             } else { | ||||||
|  |                 readyPlayers.remove(player); | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     /** | ||||||
|  |      * Adds a player to the Queue | ||||||
|  |      * @param player the player to be added to the queue | ||||||
|  |      */ | ||||||
|  |     void addPlayer(Player player) { | ||||||
|  |         if (players.contains(player)) { | ||||||
|  |             throw new IllegalArgumentException("Player already registered"); | ||||||
|  |         } | ||||||
|  |         players.add(player); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     /** | ||||||
|  |      * Removes the specified Player from the Queue | ||||||
|  |      * @param player the player to be removed | ||||||
|  |      */ | ||||||
|  |     void removePlayer(Player player) { | ||||||
|  |         players.remove(player); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     /** | ||||||
|  |      * Gets Player based on their id in the Queue | ||||||
|  |      * @param index the index of the queue | ||||||
|  |      * @return the Player at the required index | ||||||
|  |      */ | ||||||
|  |     Player getPlayerAtIndex(int index) { | ||||||
|  |         return players.get(index); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     /** | ||||||
|  |      * Completes a player turn and return the next player | ||||||
|  |      * @return the next players who is active | ||||||
|  |      */ | ||||||
|  |     Player nextPlayer() { | ||||||
|  |         players.addLast(players.removeFirst()); | ||||||
|  |         return players.getFirst(); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     /** | ||||||
|  |      * Returns the {@link ServerGameLogic} of this PlayerHandler | ||||||
|  |      * @return the {@link ServerGameLogic} of this PlayerHandler | ||||||
|  |      */ | ||||||
|  |     ServerGameLogic getLogic() { | ||||||
|  |         return logic; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     /** | ||||||
|  |      * Gets a player based on their id | ||||||
|  |      * @param id the id to be searched for | ||||||
|  |      * @return the player with the required id | ||||||
|  |      */ | ||||||
|  |     Player getPlayerById(int id) { | ||||||
|  |         for (Player player : players) { | ||||||
|  |             if (player.getId() == id) return player; | ||||||
|  |         } | ||||||
|  |         throw new NoSuchElementException("Player mit id "+id+" existiert nicht"); | ||||||
|  |     } | ||||||
|  | } | ||||||
| @@ -1,18 +1,16 @@ | |||||||
| //////////////////////////////////////// |  | ||||||
| // Programming project code |  | ||||||
| // UniBw M, 2022, 2023, 2024 |  | ||||||
| // www.unibw.de/inf2 |  | ||||||
| // (c) Mark Minas (mark.minas@unibw.de) |  | ||||||
| //////////////////////////////////////// |  | ||||||
|  |  | ||||||
| package pp.monopoly.game.server; | package pp.monopoly.game.server; | ||||||
|  |  | ||||||
|  | import pp.monopoly.MonopolyConfig; | ||||||
|  | import pp.monopoly.message.client.*; | ||||||
|  | import pp.monopoly.message.server.ServerMessage; | ||||||
|  | import pp.monopoly.message.server.TradeReply; | ||||||
|  | import pp.monopoly.message.server.TradeRequest; | ||||||
|  | import pp.monopoly.message.server.ViewAssetsResponse; | ||||||
|  | import pp.monopoly.model.fields.BoardManager; | ||||||
|  | import pp.monopoly.model.fields.PropertyField; | ||||||
|  |  | ||||||
| import java.lang.System.Logger; | import java.lang.System.Logger; | ||||||
| import java.lang.System.Logger.Level; | import java.lang.System.Logger.Level; | ||||||
| import java.util.ArrayList; |  | ||||||
| import java.util.HashSet; |  | ||||||
| import java.util.List; |  | ||||||
| import java.util.Set; |  | ||||||
|  |  | ||||||
| import pp.monopoly.MonopolyConfig; | import pp.monopoly.MonopolyConfig; | ||||||
| import pp.monopoly.message.client.ClientInterpreter; | import pp.monopoly.message.client.ClientInterpreter; | ||||||
| @@ -26,14 +24,14 @@ public class ServerGameLogic implements ClientInterpreter { | |||||||
|     private static final Logger LOGGER = System.getLogger(ServerGameLogic.class.getName()); |     private static final Logger LOGGER = System.getLogger(ServerGameLogic.class.getName()); | ||||||
|  |  | ||||||
|     private final MonopolyConfig config; |     private final MonopolyConfig config; | ||||||
|     private final List<Player> players = new ArrayList<>(2); |     private final PlayerHandler playerHandler = new PlayerHandler(this); | ||||||
|     private final Set<Player> readyPlayers = new HashSet<>(); |  | ||||||
|     private final ServerSender serverSender; |     private final ServerSender serverSender; | ||||||
|     private Player activePlayer; |     private ServerState state = ServerState.CREATEGAME; | ||||||
|     private ServerState state = ServerState.WAIT; |     private static final int MAX_PLAYERS = 6; | ||||||
|  |     private BoardManager boardManager = new BoardManager(); | ||||||
|  |  | ||||||
|     /** |     /** | ||||||
|      * Constructs a ServerGameLogic with the specified sender and configuration. |      * Constructs a ServerGameLogic instance with the specified sender and configuration. | ||||||
|      * |      * | ||||||
|      * @param serverSender the sender used to send messages to clients |      * @param serverSender the sender used to send messages to clients | ||||||
|      * @param config       the game configuration |      * @param config       the game configuration | ||||||
| @@ -44,80 +42,218 @@ public class ServerGameLogic implements ClientInterpreter { | |||||||
|     } |     } | ||||||
|  |  | ||||||
|     /** |     /** | ||||||
|      * Returns the  state of the game. |      * Retrieves the current state of the game. | ||||||
|  |      * | ||||||
|  |      * @return the current ServerState | ||||||
|      */ |      */ | ||||||
|     ServerState getState() { |     ServerState getState() { | ||||||
|         return state; |         return state; | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     /** |     /** | ||||||
|      * Sets the new state of the game and logs the state transition. |      * Sets a new state for the game and logs the state transition. | ||||||
|      * |      * | ||||||
|      * @param newState the new state to set |      * @param newState the new ServerState to transition to | ||||||
|      */ |      */ | ||||||
|     void setState(ServerState newState) { |     void setState(ServerState newState) { | ||||||
|         LOGGER.log(Level.DEBUG, "state transition {0} --> {1}", state, newState); //NON-NLS |         LOGGER.log(Level.DEBUG, "State transition {0} --> {1}", state, newState); | ||||||
|         state = newState; |         state = newState; | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     /** |     /** | ||||||
|      * Returns the opponent of the specified player. |      * Sends a message to a specified player. | ||||||
|      * |      * | ||||||
|      * @param p the player |      * @param player the Player to whom the message is sent | ||||||
|      * @return the opponent of the player |      * @param msg    the ServerMessage to send | ||||||
|      */ |  | ||||||
|     Player getOpponent(Player p) { |  | ||||||
|         if (players.size() != 2) |  | ||||||
|             throw new RuntimeException("trying to find opponent without having 2 players"); |  | ||||||
|         final int index = players.indexOf(p); |  | ||||||
|         if (index < 0) |  | ||||||
|             throw new RuntimeException("Nonexistent player " + p); |  | ||||||
|         return players.get(1 - index); |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     /** |  | ||||||
|      * Returns the player representing the client with the specified connection ID. |  | ||||||
|      * |  | ||||||
|      * @param id the ID of the client |  | ||||||
|      * @return the player associated with the client ID, or null if not found |  | ||||||
|      */ |  | ||||||
|     public Player getPlayerById(int id) { |  | ||||||
|         // TODO Auto-generated method stub |  | ||||||
|         throw new UnsupportedOperationException("Unimplemented method"); |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     /** |  | ||||||
|      * Sends a message to the specified player. |  | ||||||
|      * |  | ||||||
|      * @param player the player to send the message to |  | ||||||
|      * @param msg    the message to send |  | ||||||
|      */ |      */ | ||||||
|     void send(Player player, ServerMessage msg) { |     void send(Player player, ServerMessage msg) { | ||||||
|         // TODO Auto-generated method stub |         if (player != null && msg != null) { | ||||||
|         throw new UnsupportedOperationException("Unimplemented method"); |             serverSender.send(player.getId(), msg); | ||||||
|  |             LOGGER.log(Level.DEBUG, "Message sent to player {0}: {1}", player.getName(), msg.getClass().getSimpleName()); | ||||||
|  |         } else { | ||||||
|  |             LOGGER.log(Level.WARNING, "Attempted to send a null message or to a null player"); | ||||||
|  |         } | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     /** |     /** | ||||||
|      * Adds a new player to the game if there are less than two players. |      * Adds a new player to the game if the game is in the LOBBY state and the maximum | ||||||
|      * Transitions the state to SET_UP if two players are present. |      * player limit has not been reached. | ||||||
|      * |      * | ||||||
|      * @param id the connection ID of the new player |      * @param player the Player to add to the game | ||||||
|      * @return the player added to the game, or null if the game is not in the right state |      * @return the added Player, or null if the player could not be added | ||||||
|  |      */ | ||||||
|  |     public Player addPlayer(Player player) { | ||||||
|  |         if (state != ServerState.LOBBY) { | ||||||
|  |             LOGGER.log(Level.WARNING, "Cannot add player; game is not in LOBBY state."); | ||||||
|  |             return null; | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         if (playerHandler.getPlayerCount() >= MAX_PLAYERS) { | ||||||
|  |             LOGGER.log(Level.WARNING, "Cannot add player; maximum player limit reached."); | ||||||
|  |             return null; | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         playerHandler.addPlayer(player); | ||||||
|  |         LOGGER.log(Level.DEBUG, "Player added: {0}", player.getId()); | ||||||
|  |  | ||||||
|  |         return player; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     /** | ||||||
|  |      * Adds a new player to the game if the game is in the LOBBY state and the maximum | ||||||
|  |      * player limit has not been reached. | ||||||
|  |      * | ||||||
|  |      * @param id the id of the player to add to the game | ||||||
|  |      * @return the added Player, or null if the player could not be added | ||||||
|      */ |      */ | ||||||
|     public Player addPlayer(int id) { |     public Player addPlayer(int id) { | ||||||
|         // TODO Auto-generated method stub |         Player player = new Player(id, playerHandler); | ||||||
|         throw new UnsupportedOperationException("Unimplemented method"); |         if (state != ServerState.LOBBY) { | ||||||
|  |             LOGGER.log(Level.WARNING, "Cannot add player; game is not in LOBBY state."); | ||||||
|  |             return null; | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         if (playerHandler.getPlayerCount() >= MAX_PLAYERS) { | ||||||
|  |             LOGGER.log(Level.WARNING, "Cannot add player; maximum player limit reached."); | ||||||
|  |             return null; | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         playerHandler.addPlayer(player); | ||||||
|  |         LOGGER.log(Level.DEBUG, "Player added: {0}", player.getId()); | ||||||
|  |  | ||||||
|  |         return player; | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     /** |     /** | ||||||
|      * Marks the player as ready  |      * Handles a BuyPropertyRequest from a player, allowing the player to purchase a property | ||||||
|      * Transitions the state to PLAY if both players are ready. |      * if it is unowned and they have sufficient funds. | ||||||
|      * |      * | ||||||
|      * @param player the player who is ready |      * @param msg  the BuyPropertyRequest received from the player | ||||||
|  |      * @param from the connection ID of the player who sent the request | ||||||
|      */ |      */ | ||||||
|     void playerReady(Player player) { |     @Override | ||||||
|         // TODO Auto-generated method stub |     public void received(BuyPropertyRequest msg, int from) { | ||||||
|         throw new UnsupportedOperationException("Unimplemented method"); |         Player player = playerHandler.getPlayerById(from); | ||||||
|  |         if (player != null && state == ServerState.INGAME) { | ||||||
|  |             PropertyField property = (PropertyField) boardManager.getFieldAtIndex(player.move(0)); // Assuming player position for property | ||||||
|  |              | ||||||
|  |             if (property.getOwner() == null && player.getAccountBalance() >= property.getPrice()) { | ||||||
|  |                 player.buyProperty(property); | ||||||
|  |                 property.setOwner(player); | ||||||
|  |                 player.earnMoney(-property.getPrice()); | ||||||
|  |                 LOGGER.log(Level.INFO, "Player {0} bought property {1}", player.getName(), property.getName()); | ||||||
|  |             } else { | ||||||
|  |                 LOGGER.log(Level.WARNING, "Player {0} cannot buy property {1}", player.getName(), property.getName()); | ||||||
|  |             } | ||||||
|  |         } | ||||||
|     } |     } | ||||||
|  |  | ||||||
|  |     /** | ||||||
|  |      * Handles an EndTurn request, ending the player's turn and advancing to the next player. | ||||||
|  |      * | ||||||
|  |      * @param msg  the EndTurn message received from the player | ||||||
|  |      * @param from the connection ID of the player who sent the request | ||||||
|  |      */ | ||||||
|  |     @Override | ||||||
|  |     public void received(EndTurn msg, int from) { | ||||||
|  |         Player player = playerHandler.getPlayerById(from); | ||||||
|  |         if (player != null && state == ServerState.INGAME) { | ||||||
|  |             LOGGER.log(Level.DEBUG, "Ending turn for player {0}", player.getName()); | ||||||
|  |             playerHandler.nextPlayer(); | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     /** | ||||||
|  |      * Handles a PlayerReady message, marking the player as ready. | ||||||
|  |      * | ||||||
|  |      * @param msg  the PlayerReady message received from the player | ||||||
|  |      * @param from the connection ID of the player who sent the request | ||||||
|  |      */ | ||||||
|  |     @Override | ||||||
|  |     public void received(PlayerReady msg, int from) { | ||||||
|  |         Player player = playerHandler.getPlayerById(from); | ||||||
|  |         if (player != null) { | ||||||
|  |             player.setName(msg.getName()); | ||||||
|  |             player.setColor(msg.getColor()); | ||||||
|  |             player.setName(msg.getName()); | ||||||
|  |             LOGGER.log(Level.DEBUG, "Player {0} is ready", player.getName()); | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     /** | ||||||
|  |      * Handles a RollDice message, rolling dice for the player and moving them on the board. | ||||||
|  |      * | ||||||
|  |      * @param msg  the RollDice message received from the player | ||||||
|  |      * @param from the connection ID of the player who sent the request | ||||||
|  |      */ | ||||||
|  |     @Override | ||||||
|  |     public void received(RollDice msg, int from) { | ||||||
|  |         Player player = playerHandler.getPlayerById(from); | ||||||
|  |         if (player != null && state == ServerState.INGAME) { | ||||||
|  |             send(player, player.rollDice()); | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     /** | ||||||
|  |      * Handles a TradeOffer message by forwarding the trade offer to the receiving player. | ||||||
|  |      * | ||||||
|  |      * @param msg  the TradeOffer message received from the initiating player | ||||||
|  |      * @param from the connection ID of the player who sent the offer | ||||||
|  |      */ | ||||||
|  |     @Override | ||||||
|  |     public void received(TradeOffer msg, int from) { | ||||||
|  |         Player sender = playerHandler.getPlayerById(from); | ||||||
|  |         Player receiver = playerHandler.getPlayerById(msg.getReceiverId()); | ||||||
|  |          | ||||||
|  |         if (sender != null && receiver != null) { | ||||||
|  |             LOGGER.log(Level.INFO, "Player {0} offers a trade to player {1}", sender.getName(), receiver.getName()); | ||||||
|  |             send(playerHandler.getPlayerById(msg.getReceiverId()), new TradeRequest(msg.getReceiverId(), msg.getTradeHandler())); | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     /** | ||||||
|  |      * Handles a TradeResponse message by forwarding the response back to the initiating player. | ||||||
|  |      * | ||||||
|  |      * @param msg  the TradeResponse message received from the receiving player | ||||||
|  |      * @param from the connection ID of the player who sent the response | ||||||
|  |      */ | ||||||
|  |     @Override | ||||||
|  |     public void received(TradeResponse msg, int from) { | ||||||
|  |         Player responder = playerHandler.getPlayerById(from); | ||||||
|  |         Player initiator = playerHandler.getPlayerById(msg.getInitiatorId()); | ||||||
|  |          | ||||||
|  |         if (responder != null && initiator != null) { | ||||||
|  |             LOGGER.log(Level.INFO, "Player {0} responded to trade with player {1}", responder.getName(), initiator.getName()); | ||||||
|  |             send(initiator, new TradeReply(msg.getInitiatorId(), msg.getTradeHandler())); | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     /** | ||||||
|  |      * Handles a ViewAssetsRequest message, sending the player a response containing their assets. | ||||||
|  |      * | ||||||
|  |      * @param msg  the ViewAssetsRequest message received from the player | ||||||
|  |      * @param from the connection ID of the player who sent the request | ||||||
|  |      */ | ||||||
|  |     @Override | ||||||
|  |     public void received(ViewAssetsRequest msg, int from) { | ||||||
|  |         Player player = playerHandler.getPlayerById(from); | ||||||
|  |         if (player != null) { | ||||||
|  |             LOGGER.log(Level.DEBUG, "Processing ViewAssetsRequest for player {0}", player.getName()); | ||||||
|  |              | ||||||
|  |             send(player, new ViewAssetsResponse(player.getProperties(), player.getAccountBalance(), player.getNumJailCard())); | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     /** | ||||||
|  |      * Retrieves the board manager, which manages the game board. | ||||||
|  |      * | ||||||
|  |      * @return the BoardManager instance managing the game board | ||||||
|  |      */ | ||||||
|  |     public BoardManager getBoardManager() { | ||||||
|  |         return boardManager; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     public Player getPlayerById(int id) { | ||||||
|  |         return playerHandler.getPlayerById(id); | ||||||
|  |     } | ||||||
| } | } | ||||||
|   | |||||||
| @@ -14,20 +14,20 @@ enum ServerState { | |||||||
|     /** |     /** | ||||||
|      * The server is waiting for clients to connect. |      * The server is waiting for clients to connect. | ||||||
|      */ |      */ | ||||||
|     WAIT, |     CREATEGAME, | ||||||
|  |  | ||||||
|     /** |     /** | ||||||
|      * The server is waiting for clients to set up their maps. |      * The server is waiting for clients to set up their status to ready | ||||||
|      */ |      */ | ||||||
|     SET_UP, |     LOBBY, | ||||||
|  |  | ||||||
|     /** |     /** | ||||||
|      * The battle of the game where players take turns |      * The battle of the game where players take turns | ||||||
|      */ |      */ | ||||||
|     BATTLE, |     INGAME, | ||||||
|  |  | ||||||
|     /** |     /** | ||||||
|      * The game has ended because all the players went bankrott |      * The game has ended because all the players went bankrupt | ||||||
|      */ |      */ | ||||||
|     GAME_OVER |     GAMEOVER | ||||||
| } | } | ||||||
|   | |||||||
| @@ -0,0 +1,31 @@ | |||||||
|  | package pp.monopoly.message.client; | ||||||
|  |  | ||||||
|  | /** | ||||||
|  |  * Represents a request from a player to buy a property. | ||||||
|  |  */ | ||||||
|  | public class BuyPropertyRequest extends ClientMessage{ | ||||||
|  |     private int propertyId; | ||||||
|  |  | ||||||
|  |     /** | ||||||
|  |      * Constructs a BuyPropertyRequest with the specified property ID. | ||||||
|  |      * | ||||||
|  |      * @param propertyId the ID of the property to buy | ||||||
|  |      */ | ||||||
|  |     public BuyPropertyRequest(int propertyId) { | ||||||
|  |         this.propertyId = propertyId; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     /** | ||||||
|  |      * Gets the ID of the property to buy. | ||||||
|  |      * | ||||||
|  |      * @return the property ID | ||||||
|  |      */ | ||||||
|  |     public int getPropertyId() { | ||||||
|  |         return propertyId; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     @Override | ||||||
|  |     public void accept(ClientInterpreter interpreter, int from) { | ||||||
|  |         interpreter.received(this, from); | ||||||
|  |     } | ||||||
|  | } | ||||||
| @@ -11,5 +11,59 @@ package pp.monopoly.message.client; | |||||||
|  * Visitor interface for processing all client messages. |  * Visitor interface for processing all client messages. | ||||||
|  */ |  */ | ||||||
| public interface ClientInterpreter { | public interface ClientInterpreter { | ||||||
|  |     /** | ||||||
|  |      * Processes a received BuyPropertyRequest. | ||||||
|  |      * | ||||||
|  |      * @param msg  the BuyPropertyRequest to be processed | ||||||
|  |      * @param from the connection ID from which the message was received | ||||||
|  |      */ | ||||||
|  |     void received(BuyPropertyRequest msg, int from); | ||||||
|  |  | ||||||
|  |     /** | ||||||
|  |      * Processes a received EndTurn. | ||||||
|  |      * | ||||||
|  |      * @param msg  the EndTurn to be processed | ||||||
|  |      * @param from the connection ID from which the message was received | ||||||
|  |      */ | ||||||
|  |     void received(EndTurn msg, int from); | ||||||
|  |  | ||||||
|  |     /** | ||||||
|  |      * Processes a received PlayerReady. | ||||||
|  |      * | ||||||
|  |      * @param msg  the PlayerReady to be processed | ||||||
|  |      * @param from the connection ID from which the message was received | ||||||
|  |      */ | ||||||
|  |     void received(PlayerReady msg, int from); | ||||||
|  |  | ||||||
|  |     /** | ||||||
|  |      * Processes a received RollDice. | ||||||
|  |      * | ||||||
|  |      * @param msg  the RollDice to be processed | ||||||
|  |      * @param from the connection ID from which the message was received | ||||||
|  |      */ | ||||||
|  |     void received(RollDice msg, int from); | ||||||
|  |  | ||||||
|  |     /** | ||||||
|  |      * Processes a received TradeOffer. | ||||||
|  |      * | ||||||
|  |      * @param msg  the TradeOffer to be processed | ||||||
|  |      * @param from the connection ID from which the message was received | ||||||
|  |      */ | ||||||
|  |     void received(TradeOffer msg, int from); | ||||||
|  |  | ||||||
|  |     /** | ||||||
|  |      * Processes a received TradeResponse. | ||||||
|  |      * | ||||||
|  |      * @param msg  the TradeResponse to be processed | ||||||
|  |      * @param from the connection ID from which the message was received | ||||||
|  |      */ | ||||||
|  |     void received(TradeResponse msg, int from); | ||||||
|  |  | ||||||
|  |     /** | ||||||
|  |      * Processes a received ViewAssetsRequest. | ||||||
|  |      * | ||||||
|  |      * @param msg  the ViewAssetsRequest to be processed | ||||||
|  |      * @param from the connection ID from which the message was received | ||||||
|  |      */ | ||||||
|  |     void received(ViewAssetsRequest msg, int from); | ||||||
| } | } | ||||||
|   | |||||||
| @@ -0,0 +1,12 @@ | |||||||
|  | package pp.monopoly.message.client; | ||||||
|  | /** | ||||||
|  |  * Represents a message indicating the player wants to end their turn. | ||||||
|  |  */ | ||||||
|  | public class EndTurn extends ClientMessage{ | ||||||
|  |  | ||||||
|  |     @Override | ||||||
|  |     public void accept(ClientInterpreter interpreter, int from) { | ||||||
|  |         interpreter.received(this, from); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  | } | ||||||
| @@ -0,0 +1,52 @@ | |||||||
|  | package pp.monopoly.message.client; | ||||||
|  |  | ||||||
|  | import pp.monopoly.game.server.PlayerColor; | ||||||
|  |  | ||||||
|  | /** | ||||||
|  |  * Represents a message indicating the player is ready to play. | ||||||
|  |  */ | ||||||
|  | public class PlayerReady extends ClientMessage{ | ||||||
|  |     private boolean isReady; | ||||||
|  |     private String name; | ||||||
|  |     private PlayerColor color; | ||||||
|  |  | ||||||
|  |     /** | ||||||
|  |      * Constructs a PlayerReady message. | ||||||
|  |      * | ||||||
|  |      * @param isReady true if the player is ready, false otherwise | ||||||
|  |      */ | ||||||
|  |     public PlayerReady(boolean isReady) { | ||||||
|  |         this.isReady = isReady; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     /** | ||||||
|  |      * Getter for the Name | ||||||
|  |      * @return the Name | ||||||
|  |      */ | ||||||
|  |     public String getName() { | ||||||
|  |         return name; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     /** | ||||||
|  |      * Getter for the Playercolor | ||||||
|  |      * @return the Playercolor | ||||||
|  |      */ | ||||||
|  |     public PlayerColor getColor() { | ||||||
|  |         return color; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     /** | ||||||
|  |      * Checks if the player is ready. | ||||||
|  |      * | ||||||
|  |      * @return true if ready, false otherwise | ||||||
|  |      */ | ||||||
|  |     public boolean isReady() { | ||||||
|  |         return isReady; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |  | ||||||
|  |     @Override | ||||||
|  |     public void accept(ClientInterpreter interpreter, int from) { | ||||||
|  |         interpreter.received(this, from); | ||||||
|  |     } | ||||||
|  | } | ||||||
| @@ -0,0 +1,12 @@ | |||||||
|  | package pp.monopoly.message.client; | ||||||
|  | /** | ||||||
|  |  * Represents a message requesting to roll the dice. | ||||||
|  |  */ | ||||||
|  | public class RollDice extends ClientMessage{ | ||||||
|  |  | ||||||
|  |     @Override | ||||||
|  |     public void accept(ClientInterpreter interpreter, int from) { | ||||||
|  |         interpreter.received(this, from); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  | } | ||||||
| @@ -0,0 +1,32 @@ | |||||||
|  | package pp.monopoly.message.client; | ||||||
|  |  | ||||||
|  | import pp.monopoly.model.TradeHandler; | ||||||
|  |  | ||||||
|  | /** | ||||||
|  |  * Represents a trade Request message from one player to another. | ||||||
|  |  */ | ||||||
|  | public class TradeOffer extends ClientMessage{ | ||||||
|  |     private int receiverId; | ||||||
|  |     private TradeHandler tradehandler; | ||||||
|  |  | ||||||
|  |  | ||||||
|  |     /** | ||||||
|  |      * Constructs a TradeOffer with the specified details. | ||||||
|  |      * | ||||||
|  |      * @param receiverId the ID of the player receiving the Request | ||||||
|  |      * @param tradehandler the tradehandler | ||||||
|  |      */ | ||||||
|  |     public TradeOffer(int receiverId, TradeHandler tradehandler) { | ||||||
|  |         this.receiverId = receiverId; | ||||||
|  |         this.tradehandler = tradehandler; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     public int getReceiverId() { return receiverId; } | ||||||
|  |     public TradeHandler getTradeHandler() { return tradehandler; } | ||||||
|  |  | ||||||
|  |     @Override | ||||||
|  |     public void accept(ClientInterpreter interpreter, int from) { | ||||||
|  |         interpreter.received(this, from); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  | } | ||||||
| @@ -0,0 +1,32 @@ | |||||||
|  | package pp.monopoly.message.client; | ||||||
|  |  | ||||||
|  | import pp.monopoly.model.TradeHandler; | ||||||
|  |  | ||||||
|  | /** | ||||||
|  |  * Represents a response to a trade offer. | ||||||
|  |  */ | ||||||
|  | public class TradeResponse extends ClientMessage{ | ||||||
|  |     private int initiatorId; | ||||||
|  |     private TradeHandler tradeHandler; | ||||||
|  |  | ||||||
|  |     /** | ||||||
|  |      * Constructs a TradeResponse with the specified response details. | ||||||
|  |      * | ||||||
|  |      * @param initiatorId the ID of the player who initiated the trade | ||||||
|  |      * @param accepted true if the offer is accepted, false if declined | ||||||
|  |      */ | ||||||
|  |     public TradeResponse(int initiatorId, TradeHandler tradeHandler) { | ||||||
|  |         this.initiatorId = initiatorId; | ||||||
|  |         this.tradeHandler = tradeHandler; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     public int getInitiatorId() { return initiatorId; } | ||||||
|  |     public TradeHandler getTradeHandler() { | ||||||
|  |         return tradeHandler; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     @Override | ||||||
|  |     public void accept(ClientInterpreter interpreter, int from) { | ||||||
|  |         interpreter.received(this, from); | ||||||
|  |     } | ||||||
|  | } | ||||||
| @@ -0,0 +1,12 @@ | |||||||
|  | package pp.monopoly.message.client; | ||||||
|  | /** | ||||||
|  |  * Represents a request from a player to view their assets. | ||||||
|  |  */ | ||||||
|  | public class ViewAssetsRequest extends ClientMessage{ | ||||||
|  |  | ||||||
|  |     @Override | ||||||
|  |     public void accept(ClientInterpreter interpreter, int from) { | ||||||
|  |         interpreter.received(this, from); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  | } | ||||||
| @@ -0,0 +1,17 @@ | |||||||
|  | package pp.monopoly.message.server; | ||||||
|  |  | ||||||
|  | public class BuyPropertyResponse extends ServerMessage{ | ||||||
|  |  | ||||||
|  |     @Override | ||||||
|  |     public void accept(ServerInterpreter interpreter) { | ||||||
|  |         // TODO Auto-generated method stub | ||||||
|  |         throw new UnsupportedOperationException("Unimplemented method 'accept'"); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     @Override | ||||||
|  |     public String getInfoTextKey() { | ||||||
|  |         // TODO Auto-generated method stub | ||||||
|  |         throw new UnsupportedOperationException("Unimplemented method 'getInfoTextKey'"); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  | } | ||||||
| @@ -0,0 +1,35 @@ | |||||||
|  | package pp.monopoly.message.server; | ||||||
|  |  | ||||||
|  | import java.util.List; | ||||||
|  |  | ||||||
|  | public class DiceResult extends ServerMessage{ | ||||||
|  |  | ||||||
|  |     private List<Integer> rollResult; | ||||||
|  |  | ||||||
|  |     public DiceResult(List<Integer> rollResult) { | ||||||
|  |         this.rollResult = rollResult; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     public List<Integer> getRollResult() { | ||||||
|  |         return rollResult; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     @Override | ||||||
|  |     public void accept(ServerInterpreter interpreter) { | ||||||
|  |         interpreter.received(this); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     @Override | ||||||
|  |     public String getInfoTextKey() { | ||||||
|  |         // TODO Auto-generated method stub | ||||||
|  |         throw new UnsupportedOperationException("Unimplemented method 'getInfoTextKey'"); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     public boolean isDoublets() { | ||||||
|  |         return rollResult.get(0) == rollResult.get(1); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     public int calcTotal() { | ||||||
|  |         return rollResult.get(0)+rollResult.get(1); | ||||||
|  |     } | ||||||
|  | } | ||||||
| @@ -0,0 +1,16 @@ | |||||||
|  | package pp.monopoly.message.server; | ||||||
|  |  | ||||||
|  | public class EventDrawCard extends ServerMessage{ | ||||||
|  |  | ||||||
|  |     @Override | ||||||
|  |     public void accept(ServerInterpreter interpreter) { | ||||||
|  |         interpreter.received(this); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     @Override | ||||||
|  |     public String getInfoTextKey() { | ||||||
|  |         // TODO Auto-generated method stub | ||||||
|  |         throw new UnsupportedOperationException("Unimplemented method 'getInfoTextKey'"); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  | } | ||||||
| @@ -0,0 +1,16 @@ | |||||||
|  | package pp.monopoly.message.server; | ||||||
|  |  | ||||||
|  | public class GameOver extends ServerMessage{ | ||||||
|  |  | ||||||
|  |     @Override | ||||||
|  |     public void accept(ServerInterpreter interpreter) { | ||||||
|  |         interpreter.received(this); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     @Override | ||||||
|  |     public String getInfoTextKey() { | ||||||
|  |         // TODO Auto-generated method stub | ||||||
|  |         throw new UnsupportedOperationException("Unimplemented method 'getInfoTextKey'"); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  | } | ||||||
| @@ -0,0 +1,16 @@ | |||||||
|  | package pp.monopoly.message.server; | ||||||
|  |  | ||||||
|  | public class GameStart extends ServerMessage{ | ||||||
|  |  | ||||||
|  |     @Override | ||||||
|  |     public void accept(ServerInterpreter interpreter) { | ||||||
|  |         interpreter.received(this); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     @Override | ||||||
|  |     public String getInfoTextKey() { | ||||||
|  |         // TODO Auto-generated method stub | ||||||
|  |         throw new UnsupportedOperationException("Unimplemented method 'getInfoTextKey'"); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  | } | ||||||
| @@ -0,0 +1,16 @@ | |||||||
|  | package pp.monopoly.message.server; | ||||||
|  |  | ||||||
|  | public class JailEvent extends ServerMessage{ | ||||||
|  |  | ||||||
|  |     @Override | ||||||
|  |     public void accept(ServerInterpreter interpreter) { | ||||||
|  |         interpreter.received(this); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     @Override | ||||||
|  |     public String getInfoTextKey() { | ||||||
|  |         // TODO Auto-generated method stub | ||||||
|  |         throw new UnsupportedOperationException("Unimplemented method 'getInfoTextKey'"); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  | } | ||||||
| @@ -0,0 +1,16 @@ | |||||||
|  | package pp.monopoly.message.server; | ||||||
|  |  | ||||||
|  | public class PlayerStatusUpdate extends ServerMessage{ | ||||||
|  |  | ||||||
|  |     @Override | ||||||
|  |     public void accept(ServerInterpreter interpreter) { | ||||||
|  |         interpreter.received(this); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     @Override | ||||||
|  |     public String getInfoTextKey() { | ||||||
|  |         // TODO Auto-generated method stub | ||||||
|  |         throw new UnsupportedOperationException("Unimplemented method 'getInfoTextKey'"); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  | } | ||||||
| @@ -13,4 +13,87 @@ package pp.monopoly.message.server; | |||||||
|  */ |  */ | ||||||
| public interface ServerInterpreter { | public interface ServerInterpreter { | ||||||
|  |  | ||||||
|  |     /** | ||||||
|  |      * Handles a BuyPropertyResponse message received from the server. | ||||||
|  |      * | ||||||
|  |      * @param msg the BuyPropertyResponse message received | ||||||
|  |      */ | ||||||
|  |     void received(BuyPropertyResponse msg); | ||||||
|  |  | ||||||
|  |     /** | ||||||
|  |      * Handles a DiceResult message received from the server. | ||||||
|  |      * | ||||||
|  |      * @param msg the DiceResult message received | ||||||
|  |      */ | ||||||
|  |     void received(DiceResult msg); | ||||||
|  |  | ||||||
|  |     /** | ||||||
|  |      * Handles a EventDrawCard message received from the server. | ||||||
|  |      * | ||||||
|  |      * @param msg the EventDrawCard message received | ||||||
|  |      */ | ||||||
|  |     void received(EventDrawCard msg); | ||||||
|  |  | ||||||
|  |     /** | ||||||
|  |      * Handles a GameOver message received from the server. | ||||||
|  |      * | ||||||
|  |      * @param msg the GameOver message received | ||||||
|  |      */ | ||||||
|  |     void received(GameOver msg); | ||||||
|  |  | ||||||
|  |     /** | ||||||
|  |      * Handles a GameStart message received from the server. | ||||||
|  |      * | ||||||
|  |      * @param msg the GameStart message received | ||||||
|  |      */ | ||||||
|  |     void received(GameStart msg); | ||||||
|  |  | ||||||
|  |     /** | ||||||
|  |      * Handles a JailEvent message received from the server. | ||||||
|  |      * | ||||||
|  |      * @param msg the JailEvent message received | ||||||
|  |      */ | ||||||
|  |     void received(JailEvent msg); | ||||||
|  |  | ||||||
|  |     /** | ||||||
|  |      * Handles a PlayerStatusUpdate message received from the server. | ||||||
|  |      * | ||||||
|  |      * @param msg the PlayerStatusUpdate message received | ||||||
|  |      */ | ||||||
|  |     void received(PlayerStatusUpdate msg); | ||||||
|  |  | ||||||
|  |     /** | ||||||
|  |      * Handles a TimeOutWarning message received from the server. | ||||||
|  |      * | ||||||
|  |      * @param msg the TimeOutWarning message received | ||||||
|  |      */ | ||||||
|  |     void received(TimeOutWarning msg); | ||||||
|  |  | ||||||
|  |     /** | ||||||
|  |      * Handles a UpdatePlayerAssets message received from the server. | ||||||
|  |      * | ||||||
|  |      * @param msg the UpdatePlayerAssets message received | ||||||
|  |      */ | ||||||
|  |     void received(UpdatePlayerAssets msg); | ||||||
|  |  | ||||||
|  |     /** | ||||||
|  |      * Handles a ViewAssetsResponse message received from the server. | ||||||
|  |      * | ||||||
|  |      * @param msg the ViewAssetsResponse message received | ||||||
|  |      */ | ||||||
|  |     void received(ViewAssetsResponse msg); | ||||||
|  |  | ||||||
|  |     /** | ||||||
|  |      * Handles a TradeReply message received from the server. | ||||||
|  |      * | ||||||
|  |      * @param msg the TradeReply message received | ||||||
|  |      */ | ||||||
|  |     void received(TradeReply msg); | ||||||
|  |              | ||||||
|  |     /** | ||||||
|  |      * Handles a TradeRequest message received from the server. | ||||||
|  |      * | ||||||
|  |      * @param msg the TradeRequest message received | ||||||
|  |      */ | ||||||
|  |     void received(TradeRequest msg); | ||||||
| } | } | ||||||
|   | |||||||
| @@ -0,0 +1,16 @@ | |||||||
|  | package pp.monopoly.message.server; | ||||||
|  |  | ||||||
|  | public class TimeOutWarning extends ServerMessage{ | ||||||
|  |  | ||||||
|  |     @Override | ||||||
|  |     public void accept(ServerInterpreter interpreter) { | ||||||
|  |         interpreter.received(this); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     @Override | ||||||
|  |     public String getInfoTextKey() { | ||||||
|  |         // TODO Auto-generated method stub | ||||||
|  |         throw new UnsupportedOperationException("Unimplemented method 'getInfoTextKey'"); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  | } | ||||||
| @@ -0,0 +1,39 @@ | |||||||
|  | package pp.monopoly.message.server; | ||||||
|  |  | ||||||
|  | import pp.monopoly.model.TradeHandler; | ||||||
|  |  | ||||||
|  | /** | ||||||
|  |  * Represents a response to a trade offer. | ||||||
|  |  */ | ||||||
|  | public class TradeReply extends ServerMessage{ | ||||||
|  |     private int initiatorId; | ||||||
|  |     private TradeHandler tradeHandler; | ||||||
|  |  | ||||||
|  |     /** | ||||||
|  |      * Constructs a TradeResponse with the specified response details. | ||||||
|  |      * | ||||||
|  |      * @param initiatorId the ID of the player who initiated the trade | ||||||
|  |      * @param accepted true if the offer is accepted, false if declined | ||||||
|  |      */ | ||||||
|  |     public TradeReply(int initiatorId, TradeHandler tradeHandler) { | ||||||
|  |         this.initiatorId = initiatorId; | ||||||
|  |         this.tradeHandler = tradeHandler; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     public int getInitiatorId() { return initiatorId; } | ||||||
|  |     public TradeHandler getTradeHandler() { | ||||||
|  |         return tradeHandler; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     @Override | ||||||
|  |     public void accept(ServerInterpreter interpreter) { | ||||||
|  |         interpreter.received(this); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     @Override | ||||||
|  |     public String getInfoTextKey() { | ||||||
|  |         // TODO Auto-generated method stub | ||||||
|  |         throw new UnsupportedOperationException("Unimplemented method 'getInfoTextKey'"); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  | } | ||||||
| @@ -0,0 +1,39 @@ | |||||||
|  | package pp.monopoly.message.server; | ||||||
|  |  | ||||||
|  | import pp.monopoly.model.TradeHandler; | ||||||
|  |  | ||||||
|  | /** | ||||||
|  |  * Represents a trade Request message from one player to another. | ||||||
|  |  */ | ||||||
|  | public class TradeRequest extends ServerMessage{ | ||||||
|  |     private int receiverId; | ||||||
|  |     private TradeHandler tradehandler; | ||||||
|  |  | ||||||
|  |  | ||||||
|  |     /** | ||||||
|  |      * Constructs a TradeRequest with the specified details. | ||||||
|  |      * | ||||||
|  |      * @param receiverId the ID of the player receiving the Request | ||||||
|  |      * @param tradehandler the tradehandler | ||||||
|  |      */ | ||||||
|  |     public TradeRequest(int receiverId, TradeHandler tradehandler) { | ||||||
|  |         this.receiverId = receiverId; | ||||||
|  |         this.tradehandler = tradehandler; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     public int getReceiverId() { return receiverId; } | ||||||
|  |     public TradeHandler getTradeHandler() { return tradehandler; } | ||||||
|  |  | ||||||
|  |  | ||||||
|  |     @Override | ||||||
|  |     public void accept(ServerInterpreter interpreter) { | ||||||
|  |         interpreter.received(this); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     @Override | ||||||
|  |     public String getInfoTextKey() { | ||||||
|  |         // TODO Auto-generated method stub | ||||||
|  |         throw new UnsupportedOperationException("Unimplemented method 'getInfoTextKey'"); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  | } | ||||||
| @@ -0,0 +1,16 @@ | |||||||
|  | package pp.monopoly.message.server; | ||||||
|  |  | ||||||
|  | public class UpdatePlayerAssets extends ServerMessage{ | ||||||
|  |  | ||||||
|  |     @Override | ||||||
|  |     public void accept(ServerInterpreter interpreter) { | ||||||
|  |         interpreter.received(this); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     @Override | ||||||
|  |     public String getInfoTextKey() { | ||||||
|  |         // TODO Auto-generated method stub | ||||||
|  |         throw new UnsupportedOperationException("Unimplemented method 'getInfoTextKey'"); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  | } | ||||||
| @@ -0,0 +1,50 @@ | |||||||
|  | package pp.monopoly.message.server; | ||||||
|  |  | ||||||
|  | import java.util.List; | ||||||
|  |  | ||||||
|  | import pp.monopoly.model.fields.PropertyField; | ||||||
|  | /** | ||||||
|  |  * Represents a response containing the player's assets. | ||||||
|  |  */ | ||||||
|  | public class ViewAssetsResponse extends ServerMessage{ | ||||||
|  |  | ||||||
|  |     private List<PropertyField> properties; | ||||||
|  |     private int accountBalance; | ||||||
|  |     private int jailCards; | ||||||
|  |  | ||||||
|  |     /** | ||||||
|  |      * Constructs a ViewAssetsResponse with the specified properties and account balance. | ||||||
|  |      * | ||||||
|  |      * @param properties    a List of PropertyField objects representing the player's properties | ||||||
|  |      * @param accountBalance the player's current account balance | ||||||
|  |      */ | ||||||
|  |     public ViewAssetsResponse(List<PropertyField> properties, int accountBalance, int jailCards) { | ||||||
|  |         this.properties = properties; | ||||||
|  |         this.accountBalance = accountBalance; | ||||||
|  |         this.jailCards = jailCards; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     @Override | ||||||
|  |     public void accept(ServerInterpreter interpreter) { | ||||||
|  |         interpreter.received(this); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     @Override | ||||||
|  |     public String getInfoTextKey() { | ||||||
|  |         // TODO Auto-generated method stub | ||||||
|  |         throw new UnsupportedOperationException("Unimplemented method 'getInfoTextKey'"); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     public List<PropertyField> getProperties() { | ||||||
|  |         return properties; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     public int getAccountBalance() { | ||||||
|  |         return accountBalance; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     public int getJailCards() { | ||||||
|  |         return jailCards; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  | } | ||||||
| @@ -0,0 +1,7 @@ | |||||||
|  | package pp.monopoly.model; | ||||||
|  |  | ||||||
|  | import pp.monopoly.model.card.Card; | ||||||
|  |  | ||||||
|  | public interface CardVisitor<T> { | ||||||
|  |     T visit(Card c); | ||||||
|  | } | ||||||
| @@ -0,0 +1,23 @@ | |||||||
|  | package pp.monopoly.model; | ||||||
|  |  | ||||||
|  | import pp.monopoly.model.fields.BuildingProperty; | ||||||
|  | import pp.monopoly.model.fields.EventField; | ||||||
|  | import pp.monopoly.model.fields.FineField; | ||||||
|  | import pp.monopoly.model.fields.FoodField; | ||||||
|  | import pp.monopoly.model.fields.GateField; | ||||||
|  | import pp.monopoly.model.fields.GoField; | ||||||
|  | import pp.monopoly.model.fields.GulagField; | ||||||
|  | import pp.monopoly.model.fields.TestStreckeField; | ||||||
|  | import pp.monopoly.model.fields.WacheField; | ||||||
|  |  | ||||||
|  | public interface FieldVisitor<T> { | ||||||
|  |     T visit(BuildingProperty field); | ||||||
|  |     T visit(FoodField field); | ||||||
|  |     T visit(GateField field); | ||||||
|  |     T visit(GulagField field); | ||||||
|  |     T visit(TestStreckeField field); | ||||||
|  |     T visit(EventField field); | ||||||
|  |     T visit(WacheField field); | ||||||
|  |     T visit(GoField field); | ||||||
|  |     T visit(FineField field); | ||||||
|  | } | ||||||
| @@ -0,0 +1,17 @@ | |||||||
|  | package pp.monopoly.model; | ||||||
|  |  | ||||||
|  | public class Figure implements Item{ | ||||||
|  |  | ||||||
|  |     @Override | ||||||
|  |     public <T> T accept(Visitor<T> visitor) { | ||||||
|  |         // TODO Auto-generated method stub | ||||||
|  |         throw new UnsupportedOperationException("Unimplemented method 'accept'"); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     @Override | ||||||
|  |     public void accept(VoidVisitor visitor) { | ||||||
|  |         // TODO Auto-generated method stub | ||||||
|  |         throw new UnsupportedOperationException("Unimplemented method 'accept'"); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  | } | ||||||
| @@ -0,0 +1,183 @@ | |||||||
|  | package pp.monopoly.model; | ||||||
|  |  | ||||||
|  | import pp.monopoly.game.server.Player; | ||||||
|  | import pp.monopoly.model.fields.PropertyField; | ||||||
|  |  | ||||||
|  | import java.util.List; | ||||||
|  |  | ||||||
|  | /** | ||||||
|  |  * Helper class that handles the trade logic between two players. | ||||||
|  |  * Manages trade initiation, validation, acceptance, and rejection involving multiple properties, money, and jail cards. | ||||||
|  |  */ | ||||||
|  | public class TradeHandler { | ||||||
|  |  | ||||||
|  |     /** | ||||||
|  |      * Initiates a trade offer between two players involving properties, money, and jail cards. | ||||||
|  |      * | ||||||
|  |      * @param sender             the Player who is initiating the trade | ||||||
|  |      * @param receiver           the Player who is the target of the trade offer | ||||||
|  |      * @param offeredAmount      the amount of money the sender offers | ||||||
|  |      * @param offeredProperties  the list of properties the sender offers | ||||||
|  |      * @param offeredJailCards   the number of jail cards the sender offers | ||||||
|  |      * @param requestedAmount    the amount of money the sender requests from the receiver | ||||||
|  |      * @param requestedProperties the list of properties the sender requests from the receiver | ||||||
|  |      * @param requestedJailCards the number of jail cards the sender requests from the receiver | ||||||
|  |      * @return true if the trade offer is valid and initiated, false otherwise | ||||||
|  |      */ | ||||||
|  |     public boolean initiateTrade(Player sender, Player receiver, int offeredAmount, List<PropertyField> offeredProperties, | ||||||
|  |                                  int offeredJailCards, int requestedAmount, List<PropertyField> requestedProperties, int requestedJailCards) { | ||||||
|  |         // Validate the trade offer | ||||||
|  |         if (!validateTrade(sender, offeredAmount, offeredProperties, offeredJailCards, receiver, requestedAmount, requestedProperties, requestedJailCards)) { | ||||||
|  |             System.out.println("Trade offer is invalid."); | ||||||
|  |             return false; | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         // Notify the receiver about the trade offer (this would be an actual message in a real implementation) | ||||||
|  |         System.out.println("Trade offer initiated by " + sender.getName() + " to " + receiver.getName()); | ||||||
|  |         return true; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     /** | ||||||
|  |      * Accepts the trade offer and completes the trade between two players. | ||||||
|  |      * | ||||||
|  |      * @param sender             the Player who initiated the trade | ||||||
|  |      * @param receiver           the Player who accepted the trade | ||||||
|  |      * @param offeredAmount      the amount of money to transfer from the sender to the receiver | ||||||
|  |      * @param offeredProperties  the list of properties to transfer from the sender to the receiver | ||||||
|  |      * @param offeredJailCards   the number of jail cards to transfer from the sender to the receiver | ||||||
|  |      * @param requestedAmount    the amount of money to transfer from the receiver to the sender | ||||||
|  |      * @param requestedProperties the list of properties to transfer from the receiver to the sender | ||||||
|  |      * @param requestedJailCards the number of jail cards to transfer from the receiver to the sender | ||||||
|  |      */ | ||||||
|  |     public void acceptTrade(Player sender, Player receiver, int offeredAmount, List<PropertyField> offeredProperties, | ||||||
|  |                             int offeredJailCards, int requestedAmount, List<PropertyField> requestedProperties, int requestedJailCards) { | ||||||
|  |         // Transfer money | ||||||
|  |         sender.earnMoney(-offeredAmount);  // Deduct money from the sender | ||||||
|  |         receiver.earnMoney(offeredAmount); // Add money to the receiver | ||||||
|  |  | ||||||
|  |         receiver.earnMoney(-requestedAmount); // Deduct money from the receiver | ||||||
|  |         sender.earnMoney(requestedAmount);    // Add money to the sender | ||||||
|  |  | ||||||
|  |         // Transfer ownership of the properties from sender to receiver | ||||||
|  |         if (offeredProperties != null) { | ||||||
|  |             for (PropertyField property : offeredProperties) { | ||||||
|  |                 transferProperty(sender, receiver, property); | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         // Transfer ownership of the properties from receiver to sender | ||||||
|  |         if (requestedProperties != null) { | ||||||
|  |             for (PropertyField property : requestedProperties) { | ||||||
|  |                 transferProperty(receiver, sender, property); | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         // Transfer jail cards | ||||||
|  |         transferJailCards(sender, receiver, offeredJailCards); | ||||||
|  |         transferJailCards(receiver, sender, requestedJailCards); | ||||||
|  |  | ||||||
|  |         System.out.println("Trade accepted. " + sender.getName() + " and " + receiver.getName() + " completed the trade."); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     /** | ||||||
|  |      * Rejects the trade offer. | ||||||
|  |      * | ||||||
|  |      * @param receiver the Player who is rejecting the trade | ||||||
|  |      */ | ||||||
|  |     public void rejectTrade(Player receiver) { | ||||||
|  |         System.out.println("Trade rejected by " + receiver.getName()); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     /** | ||||||
|  |      * Validates a trade offer by checking if the sender and receiver own the properties involved, | ||||||
|  |      * have sufficient funds for the money involved in the trade, and have enough jail cards. | ||||||
|  |      * | ||||||
|  |      * @param sender             the Player initiating the trade | ||||||
|  |      * @param offeredAmount      the amount of money the sender is offering | ||||||
|  |      * @param offeredProperties  the list of properties the sender is offering | ||||||
|  |      * @param offeredJailCards   the number of jail cards the sender is offering | ||||||
|  |      * @param receiver           the Player receiving the trade offer | ||||||
|  |      * @param requestedAmount    the amount of money the sender is requesting | ||||||
|  |      * @param requestedProperties the list of properties the sender is requesting from the receiver | ||||||
|  |      * @param requestedJailCards the number of jail cards the sender is requesting from the receiver | ||||||
|  |      * @return true if the trade offer is valid, false otherwise | ||||||
|  |      */ | ||||||
|  |     private boolean validateTrade(Player sender, int offeredAmount, List<PropertyField> offeredProperties, int offeredJailCards, | ||||||
|  |                                   Player receiver, int requestedAmount, List<PropertyField> requestedProperties, int requestedJailCards) { | ||||||
|  |         // Check if sender has enough money to offer | ||||||
|  |         if (sender.getAccountBalance() < offeredAmount) { | ||||||
|  |             System.out.println("Sender does not have enough balance to make this offer."); | ||||||
|  |             return false; | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         // Check if receiver has enough money to offer | ||||||
|  |         if (receiver.getAccountBalance() < requestedAmount) { | ||||||
|  |             System.out.println("Receiver does not have enough balance to fulfill requested amount."); | ||||||
|  |             return false; | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         // Check if sender owns all the offered properties | ||||||
|  |         if (offeredProperties != null) { | ||||||
|  |             for (PropertyField property : offeredProperties) { | ||||||
|  |                 if (!sender.getProperties().contains(property)) { | ||||||
|  |                     System.out.println("Sender does not own the property " + property.getName() + " being offered."); | ||||||
|  |                     return false; | ||||||
|  |                 } | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         // Check if receiver owns all the requested properties | ||||||
|  |         if (requestedProperties != null) { | ||||||
|  |             for (PropertyField property : requestedProperties) { | ||||||
|  |                 if (!receiver.getProperties().contains(property)) { | ||||||
|  |                     System.out.println("Receiver does not own the property " + property.getName() + " requested."); | ||||||
|  |                     return false; | ||||||
|  |                 } | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         // Check if sender has enough jail cards to offer | ||||||
|  |         if (sender.getNumJailCard() < offeredJailCards) { | ||||||
|  |             System.out.println("Sender does not have enough jail cards to offer."); | ||||||
|  |             return false; | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         // Check if receiver has enough jail cards to fulfill the request | ||||||
|  |         if (receiver.getNumJailCard() < requestedJailCards) { | ||||||
|  |             System.out.println("Receiver does not have enough jail cards to fulfill the request."); | ||||||
|  |             return false; | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         return true; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     /** | ||||||
|  |      * Transfers a property from one player to another. | ||||||
|  |      * | ||||||
|  |      * @param from     the Player transferring the property | ||||||
|  |      * @param to       the Player receiving the property | ||||||
|  |      * @param property the PropertyField being transferred | ||||||
|  |      */ | ||||||
|  |     private void transferProperty(Player from, Player to, PropertyField property) { | ||||||
|  |         from.sellProperty(property); | ||||||
|  |         to.buyProperty(property); | ||||||
|  |         property.setOwner(to); // Update the property's owner | ||||||
|  |  | ||||||
|  |         System.out.println("Property " + property.getName() + " transferred from " + from.getName() + " to " + to.getName()); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     /** | ||||||
|  |      * Transfers jail cards between players. | ||||||
|  |      * | ||||||
|  |      * @param from the Player transferring jail cards | ||||||
|  |      * @param to   the Player receiving jail cards | ||||||
|  |      * @param numCards the number of jail cards to transfer | ||||||
|  |      */ | ||||||
|  |     private void transferJailCards(Player from, Player to, int numCards) { | ||||||
|  |         for (int i = 0; i < numCards; i++) { | ||||||
|  |             from.removeJailCard(); | ||||||
|  |             to.addJailCard(); | ||||||
|  |         } | ||||||
|  |         System.out.println("Transferred " + numCards + " jail card(s) from " + from.getName() + " to " + to.getName()); | ||||||
|  |     } | ||||||
|  | } | ||||||
| @@ -0,0 +1,23 @@ | |||||||
|  | package pp.monopoly.model.card; | ||||||
|  |  | ||||||
|  | public class Card { | ||||||
|  |     private final String description; | ||||||
|  |     private final String keyword; | ||||||
|  |  | ||||||
|  |     Card(String description, String keyword) { | ||||||
|  |         this.description = description; | ||||||
|  |         this.keyword = keyword; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     public void accept(DeckHelper visitor) { | ||||||
|  |         visitor.visit(this); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     String getDescription() { | ||||||
|  |         return description; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     String getKeyword() { | ||||||
|  |         return keyword; | ||||||
|  |     } | ||||||
|  | } | ||||||
| @@ -0,0 +1,34 @@ | |||||||
|  | package pp.monopoly.model.card; | ||||||
|  |  | ||||||
|  | import java.util.ArrayList; | ||||||
|  | import java.util.Collections; | ||||||
|  | import java.util.List; | ||||||
|  | import java.util.Queue; | ||||||
|  |  | ||||||
|  | import pp.monopoly.model.CardVisitor; | ||||||
|  |  | ||||||
|  | public class DeckHelper implements CardVisitor<Void>{ | ||||||
|  |  | ||||||
|  |     private static Queue<Card> cards; | ||||||
|  |  | ||||||
|  |     private DeckHelper() { | ||||||
|  |          | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     @Override | ||||||
|  |     public Void visit(Card c) { | ||||||
|  |         // TODO Auto-generated method stub | ||||||
|  |         throw new UnsupportedOperationException("Unimplemented method 'visit'"); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     private void shuffle() { | ||||||
|  |         List<Card> cardList = new ArrayList<>(cards); | ||||||
|  |         Collections.shuffle(cardList); | ||||||
|  |         cards.clear(); | ||||||
|  |         cards.addAll(cardList); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     public static Card drawCard() { | ||||||
|  |         return cards != null ? cards.poll() : null; | ||||||
|  |     } | ||||||
|  | } | ||||||
| @@ -0,0 +1,91 @@ | |||||||
|  | package pp.monopoly.model.fields; | ||||||
|  |  | ||||||
|  | import java.util.ArrayList; | ||||||
|  | import java.util.List; | ||||||
|  | import java.util.NoSuchElementException; | ||||||
|  |  | ||||||
|  | /** | ||||||
|  |  * Simple Manager class responsible for managing the GameBoard of Monopoly | ||||||
|  |  */ | ||||||
|  | public class BoardManager { | ||||||
|  |  | ||||||
|  |     private List<Field> board; | ||||||
|  |  | ||||||
|  |     /** | ||||||
|  |      * Constructs a BoardManager | ||||||
|  |      */ | ||||||
|  |     public BoardManager() { | ||||||
|  |         board = createBoard(); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     /** | ||||||
|  |      * Creates a Monopoly GameBoard | ||||||
|  |      * @return the List of Fields in correct  Order | ||||||
|  |      */ | ||||||
|  |     private static List<Field> createBoard() { | ||||||
|  |         ArrayList<Field> fields = new ArrayList<>(); | ||||||
|  |  | ||||||
|  |         fields.addLast(new GoField()); | ||||||
|  |         fields.addLast(new BuildingProperty("Gym", 1, 600, 20)); | ||||||
|  |         fields.addLast(new EventField("Hausfeier", 2)); | ||||||
|  |         fields.addLast(new BuildingProperty("Sportplatz", 3, 600, 40)); | ||||||
|  |         fields.addLast(new FineField("Diszi", 4, 2000)); | ||||||
|  |         fields.addLast(new GateField("Südtor", 5)); | ||||||
|  |         fields.addLast(new BuildingProperty("Studium+", 6, 1000, 60)); | ||||||
|  |         fields.addLast(new EventField("Üvas", 7)); | ||||||
|  |         fields.addLast(new BuildingProperty("PhysikHörsaal", 8, 1000, 60)); | ||||||
|  |         fields.addLast(new BuildingProperty("Audimax", 9, 1200, 80)); | ||||||
|  |         fields.addLast(new GulagField()); | ||||||
|  |         fields.addLast(new BuildingProperty("99er", 11, 1400, 100)); | ||||||
|  |         fields.addLast(new FoodField("Brandl", 12)); | ||||||
|  |         fields.addLast(new BuildingProperty("12er", 13, 1400, 100)); | ||||||
|  |         fields.addLast(new BuildingProperty("23er", 14, 1600, 120)); | ||||||
|  |         fields.addLast(new GateField("HauptWache", 15)); | ||||||
|  |         fields.addLast(new BuildingProperty("Schwimmhalle", 16, 1800, 140)); | ||||||
|  |         fields.addLast(new BuildingProperty("CISM-Bahn", 17, 1800, 140)); | ||||||
|  |         fields.addLast(new EventField("Marine-Welcome-Party", 18)); | ||||||
|  |         fields.addLast(new BuildingProperty("Kletterturm", 19, 2000, 160)); | ||||||
|  |         fields.addLast(new TestStreckeField()); | ||||||
|  |         fields.addLast(new BuildingProperty("StudFBer C", 21, 2200, 180)); | ||||||
|  |         fields.addLast(new EventField("Üvas", 22)); | ||||||
|  |         fields.addLast(new BuildingProperty("StudFBer B", 23, 2200, 180)); | ||||||
|  |         fields.addLast(new BuildingProperty("StudFBer A", 24, 2400, 200)); | ||||||
|  |         fields.addLast(new GateField("Nordtor", 25)); | ||||||
|  |         fields.addLast(new BuildingProperty("Cascada", 26, 2600, 220)); | ||||||
|  |         fields.addLast(new BuildingProperty("Fakultätsgebäude", 27, 2600, 220)); | ||||||
|  |         fields.addLast(new FoodField("Truppenküche", 28)); | ||||||
|  |         fields.addLast(new BuildingProperty("Prüfungsamt", 29, 2800, 240)); | ||||||
|  |         fields.addLast(new WacheField()); | ||||||
|  |         fields.addLast(new BuildingProperty("Feuerwehr", 31, 3000, 260)); | ||||||
|  |         fields.addLast(new BuildingProperty("SanZ", 32, 300, 260)); | ||||||
|  |         fields.addLast(new EventField("Maibock", 33)); | ||||||
|  |         fields.addLast(new BuildingProperty("Rechenzentrum", 34, 3200, 280)); | ||||||
|  |         fields.addLast(new GateField("Osttor", 35)); | ||||||
|  |         fields.addLast(new EventField("Üvas", 36)); | ||||||
|  |         fields.addLast(new BuildingProperty("2er", 37, 3500, 350)); | ||||||
|  |         fields.addLast(new FineField("EZM", 38, 1000)); | ||||||
|  |         fields.addLast(new BuildingProperty("20er", 39, 4000, 500)); | ||||||
|  |  | ||||||
|  |         return fields; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |  | ||||||
|  |     /** | ||||||
|  |      * Method to find the Field at specific index | ||||||
|  |      * @param index the index for which to find the field | ||||||
|  |      * @return the field at the index | ||||||
|  |      */ | ||||||
|  |     public Field getFieldAtIndex(int index) { | ||||||
|  |         return board.get(index); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     /** | ||||||
|  |      * Method to find the index of a Monopoly field | ||||||
|  |      * @param field the Field to get the Index of | ||||||
|  |      * @return the Index of the field | ||||||
|  |      */ | ||||||
|  |     public int getIndexOfField(Field field) { | ||||||
|  |         if (board.contains(field)) return field.getId(); | ||||||
|  |         else throw new NoSuchElementException(); | ||||||
|  |     } | ||||||
|  | } | ||||||
| @@ -0,0 +1,70 @@ | |||||||
|  | package pp.monopoly.model.fields; | ||||||
|  |  | ||||||
|  | import pp.monopoly.game.server.Player; | ||||||
|  |  | ||||||
|  | public class BuildingProperty extends PropertyField { | ||||||
|  |  | ||||||
|  |     private int houses; | ||||||
|  |     private boolean hotel = false; | ||||||
|  |  | ||||||
|  |     BuildingProperty(String name, int id, int price, int rent) { | ||||||
|  |         super(name, id, price, rent); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     @Override | ||||||
|  |     public int calcRent() { | ||||||
|  |         if (hotel) { | ||||||
|  |             return (int) Math.round(rent*70/10)*10; | ||||||
|  |         } | ||||||
|  |         switch (houses) { | ||||||
|  |             case 1: | ||||||
|  |                 return (int) Math.round(rent*5/10)*10; | ||||||
|  |             case 2: | ||||||
|  |                 return (int) Math.round(rent*15/10)*10; | ||||||
|  |             case 3: | ||||||
|  |                 return (int) Math.round(rent*40/10)*10; | ||||||
|  |             case 4: | ||||||
|  |             return (int) Math.round(rent*55/10)*10; | ||||||
|  |  | ||||||
|  |             default: | ||||||
|  |                 return rent; | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     public boolean buildHouse() { | ||||||
|  |         if (houses < 4) { | ||||||
|  |             houses++; | ||||||
|  |             return true; | ||||||
|  |         } | ||||||
|  |         return false; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     public boolean buildHotel() { | ||||||
|  |         if (hotel) { | ||||||
|  |             return false; | ||||||
|  |         } | ||||||
|  |         hotel = true; | ||||||
|  |         return true; | ||||||
|  |     } | ||||||
|  |      | ||||||
|  |     public boolean removeHouse() { | ||||||
|  |         if (houses == 0) { | ||||||
|  |             return false; | ||||||
|  |         } | ||||||
|  |         houses--; | ||||||
|  |         return true; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     public boolean removeHotel() { | ||||||
|  |         if (!hotel) { | ||||||
|  |             return false; | ||||||
|  |         } | ||||||
|  |         hotel = false; | ||||||
|  |         return true; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     @Override | ||||||
|  |     public void accept(Player player) { | ||||||
|  |         player.visit(this); | ||||||
|  |     } | ||||||
|  | } | ||||||
| @@ -0,0 +1,23 @@ | |||||||
|  | package pp.monopoly.model.fields; | ||||||
|  |  | ||||||
|  |  | ||||||
|  | import pp.monopoly.game.server.Player; | ||||||
|  | import pp.monopoly.model.card.Card; | ||||||
|  | import pp.monopoly.model.card.DeckHelper; | ||||||
|  |  | ||||||
|  | public class EventField extends Field{ | ||||||
|  |  | ||||||
|  |     public EventField(String name, int id) { | ||||||
|  |         super(name, id); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     @Override | ||||||
|  |     public void accept(Player player) { | ||||||
|  |         player.visit(this); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     public Card drawCard() { | ||||||
|  |         return DeckHelper.drawCard(); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  | } | ||||||
| @@ -0,0 +1,23 @@ | |||||||
|  | package pp.monopoly.model.fields; | ||||||
|  |  | ||||||
|  | import pp.monopoly.game.server.Player; | ||||||
|  |  | ||||||
|  | abstract class Field { | ||||||
|  |     protected final String name; | ||||||
|  |     protected final int id; | ||||||
|  |  | ||||||
|  |     protected Field(String name, int id) { | ||||||
|  |         this.name = name; | ||||||
|  |         this.id= id; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     public abstract void accept(Player player); | ||||||
|  |  | ||||||
|  |     public int getId() { | ||||||
|  |         return id; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     public String getName() { | ||||||
|  |         return name; | ||||||
|  |     } | ||||||
|  | } | ||||||
| @@ -0,0 +1,23 @@ | |||||||
|  | package pp.monopoly.model.fields; | ||||||
|  |  | ||||||
|  | import pp.monopoly.game.server.Player; | ||||||
|  |  | ||||||
|  | public class FineField extends Field{ | ||||||
|  |  | ||||||
|  |     private final int fine; | ||||||
|  |  | ||||||
|  |     FineField(String name, int id, int fine) { | ||||||
|  |         super(name, id); | ||||||
|  |         this.fine = fine; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     public int getFine() { | ||||||
|  |         return fine; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     @Override | ||||||
|  |     public void accept(Player player) { | ||||||
|  |         player.visit(this); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  | } | ||||||
| @@ -0,0 +1,20 @@ | |||||||
|  | package pp.monopoly.model.fields; | ||||||
|  |  | ||||||
|  | import pp.monopoly.game.server.Player; | ||||||
|  |  | ||||||
|  | public class FoodField extends PropertyField { | ||||||
|  |  | ||||||
|  |     public FoodField(String name, int id) { | ||||||
|  |         super(name, id, 1500,0); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     @Override | ||||||
|  |     public int calcRent() { | ||||||
|  |         return 0; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     @Override | ||||||
|  |     public void accept(Player player) { | ||||||
|  |         player.visit(this); | ||||||
|  |     } | ||||||
|  | } | ||||||
| @@ -0,0 +1,21 @@ | |||||||
|  | package pp.monopoly.model.fields; | ||||||
|  |  | ||||||
|  | import pp.monopoly.game.server.Player; | ||||||
|  |  | ||||||
|  | public class GateField extends PropertyField{ | ||||||
|  |  | ||||||
|  |     GateField(String name, int id) { | ||||||
|  |         super(name, id, 2000, 25); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     @Override | ||||||
|  |     public int calcRent() { | ||||||
|  |         return rent; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     @Override | ||||||
|  |     public void accept(Player player) { | ||||||
|  |         player.visit(this); | ||||||
|  |     } | ||||||
|  |      | ||||||
|  | } | ||||||
| @@ -0,0 +1,15 @@ | |||||||
|  | package pp.monopoly.model.fields; | ||||||
|  |  | ||||||
|  | import pp.monopoly.game.server.Player; | ||||||
|  |  | ||||||
|  | public class GoField extends Field{ | ||||||
|  |  | ||||||
|  |     public GoField() { | ||||||
|  |         super("Monatsgehalt", 0); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     @Override | ||||||
|  |     public void accept(Player player) { | ||||||
|  |         player.visit(this); | ||||||
|  |     } | ||||||
|  | } | ||||||
| @@ -0,0 +1,18 @@ | |||||||
|  | package pp.monopoly.model.fields; | ||||||
|  |  | ||||||
|  | import pp.monopoly.game.server.Player; | ||||||
|  |  | ||||||
|  | public class GulagField extends Field{ | ||||||
|  |  | ||||||
|  |     private int bailCost = 500; | ||||||
|  |  | ||||||
|  |     GulagField() { | ||||||
|  |         super("Gulag", 10); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     @Override | ||||||
|  |     public void accept(Player player) { | ||||||
|  |         player.visit(this); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  | } | ||||||
| @@ -0,0 +1,92 @@ | |||||||
|  | package pp.monopoly.model.fields; | ||||||
|  |  | ||||||
|  | import pp.monopoly.game.server.Player; | ||||||
|  |  | ||||||
|  | /** | ||||||
|  |  * Represents an abstract property field in the Monopoly game. | ||||||
|  |  * Contains attributes related to ownership, price, rent, and mortgage status. | ||||||
|  |  */ | ||||||
|  | public abstract class PropertyField extends Field { | ||||||
|  |  | ||||||
|  |     private final int price; | ||||||
|  |     protected final int rent; | ||||||
|  |     private Player owner; | ||||||
|  |     private boolean mortgaged = false; | ||||||
|  |  | ||||||
|  |     /** | ||||||
|  |      * Constructs a PropertyField with the specified name, ID, price, and rent. | ||||||
|  |      * | ||||||
|  |      * @param name  the name of the property | ||||||
|  |      * @param id    the unique identifier for the property | ||||||
|  |      * @param price the purchase price of the property | ||||||
|  |      * @param rent  the base rent for the property | ||||||
|  |      */ | ||||||
|  |     protected PropertyField(String name, int id, int price, int rent) { | ||||||
|  |         super(name, id); | ||||||
|  |         this.price = price; | ||||||
|  |         this.rent = rent; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     /** | ||||||
|  |      * Calculates the rent for this property. | ||||||
|  |      * The calculation may depend on various factors specific to property type. | ||||||
|  |      * | ||||||
|  |      * @return the calculated rent for this property | ||||||
|  |      */ | ||||||
|  |     public abstract int calcRent(); | ||||||
|  |  | ||||||
|  |     /** | ||||||
|  |      * Gets the purchase price of the property. | ||||||
|  |      * | ||||||
|  |      * @return the price of the property | ||||||
|  |      */ | ||||||
|  |     public int getPrice() { | ||||||
|  |         return price; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     /** | ||||||
|  |      * Gets the mortgage value (hypothecary value) of the property. | ||||||
|  |      * Typically, this is half of the property price. | ||||||
|  |      * | ||||||
|  |      * @return the mortgage value of the property | ||||||
|  |      */ | ||||||
|  |     public int getHypo() { | ||||||
|  |         return price / 2; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     /** | ||||||
|  |      * Gets the owner of the property. | ||||||
|  |      * | ||||||
|  |      * @return the Player who owns the property, or null if the property is unowned | ||||||
|  |      */ | ||||||
|  |     public Player getOwner() { | ||||||
|  |         return owner; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     /** | ||||||
|  |      * Sets the owner of the property. | ||||||
|  |      * | ||||||
|  |      * @param player the Player who will own this property | ||||||
|  |      */ | ||||||
|  |     public void setOwner(Player player) { | ||||||
|  |         owner = player; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     /** | ||||||
|  |      * Checks if the property is currently mortgaged. | ||||||
|  |      * | ||||||
|  |      * @return true if the property is mortgaged, false otherwise | ||||||
|  |      */ | ||||||
|  |     public boolean isMortgaged() { | ||||||
|  |         return mortgaged; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     /** | ||||||
|  |      * Sets the mortgage status of the property. | ||||||
|  |      * | ||||||
|  |      * @param mortgaged true to mark the property as mortgaged, false to unmark it | ||||||
|  |      */ | ||||||
|  |     public void setMortgaged(boolean mortgaged) { | ||||||
|  |         this.mortgaged = mortgaged; | ||||||
|  |     } | ||||||
|  | } | ||||||
| @@ -0,0 +1,24 @@ | |||||||
|  | package pp.monopoly.model.fields; | ||||||
|  |  | ||||||
|  | import pp.monopoly.game.server.Player; | ||||||
|  |  | ||||||
|  | public class TestStreckeField extends Field{ | ||||||
|  |     private int money; | ||||||
|  |  | ||||||
|  |     TestStreckeField() { | ||||||
|  |         super("Teststrecke", 20); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     @Override | ||||||
|  |     public void accept(Player player) { | ||||||
|  |         player.visit(this); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     public void addMoney(int amount) { | ||||||
|  |         money += amount; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     public int collectMoney() { | ||||||
|  |         return money = 0; | ||||||
|  |     } | ||||||
|  | } | ||||||
| @@ -0,0 +1,16 @@ | |||||||
|  | package pp.monopoly.model.fields; | ||||||
|  |  | ||||||
|  | import pp.monopoly.game.server.Player; | ||||||
|  |  | ||||||
|  | public class WacheField extends Field{ | ||||||
|  |  | ||||||
|  |     public WacheField() { | ||||||
|  |         super("Wache", 30); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     @Override | ||||||
|  |     public void accept(Player player) { | ||||||
|  |         player.visit(this); | ||||||
|  |     } | ||||||
|  |   | ||||||
|  | } | ||||||
| @@ -0,0 +1,385 @@ | |||||||
|  | package pp.monopoly; | ||||||
|  | import org.junit.Test; | ||||||
|  | import static org.junit.Assert.assertNotNull; | ||||||
|  | import static org.junit.Assert.assertTrue; | ||||||
|  | import static org.junit.Assert.assertEquals; | ||||||
|  | public class Testhandbuch { | ||||||
|  |  | ||||||
|  |  | ||||||
|  |  | ||||||
|  |  | ||||||
|  |  | ||||||
|  |         // T001 UC-game-01 - testStartApplication | ||||||
|  |         @Test | ||||||
|  |         public void testStartApplication() { | ||||||
|  |             MonopolyApp app = new MonopolyApp(); | ||||||
|  |             app.simpleInitApp(); | ||||||
|  |             MainMenu mainMenu = app.getStateManager().getState(MainMenu.class); | ||||||
|  |             assertNotNull(mainMenu); | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         // T002 UC-game-02 - testOpenStartMenu | ||||||
|  |         @Test | ||||||
|  |         public void testOpenStartMenu() { | ||||||
|  |             MonopolyApp app = new MonopolyApp(); | ||||||
|  |             app.simpleInitApp(); | ||||||
|  |             MainMenu mainMenu = app.getStateManager().getState(MainMenu.class); | ||||||
|  |             mainMenu.showMenu(); | ||||||
|  |             assertTrue(mainMenu.isMenuVisible()); | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         // T003 UC-game-03 - testNavigateToPlayOption | ||||||
|  |         @Test | ||||||
|  |         public void testNavigateToPlayOption() { | ||||||
|  |             MonopolyApp app = new MonopolyApp(); | ||||||
|  |             app.simpleInitApp(); | ||||||
|  |             MainMenu mainMenu = app.getStateManager().getState(MainMenu.class); | ||||||
|  |             mainMenu.showMenu(); | ||||||
|  |             mainMenu.startNewGame(); | ||||||
|  |             NewGameMenu newGameMenu = app.getStateManager().getState(NewGameMenu.class); | ||||||
|  |             assertNotNull(newGameMenu); | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         // T004 UC-game-04 - testExitApplicationFromMenu | ||||||
|  |         @Test | ||||||
|  |         public void testExitApplicationFromMenu() { | ||||||
|  |             MonopolyApp app = new MonopolyApp(); | ||||||
|  |             app.simpleInitApp(); | ||||||
|  |             MainMenu mainMenu = app.getStateManager().getState(MainMenu.class); | ||||||
|  |             mainMenu.showMenu(); | ||||||
|  |             mainMenu.exitGame(); | ||||||
|  |             assertTrue(app.isClosed()); | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         // T005 UC-game-05 - testOpenSettingsFromMenu | ||||||
|  |         @Test | ||||||
|  |         public void testOpenSettingsFromMenu() { | ||||||
|  |             MonopolyApp app = new MonopolyApp(); | ||||||
|  |             app.simpleInitApp(); | ||||||
|  |             MainMenu mainMenu = app.getStateManager().getState(MainMenu.class); | ||||||
|  |             mainMenu.showMenu(); | ||||||
|  |             mainMenu.openSettings(); | ||||||
|  |             SettingMenu settingMenu = app.getStateManager().getState(SettingMenu.class); | ||||||
|  |             assertNotNull(settingMenu); | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         // T006 UC-game-06 - testOpenGameMenuWithESC | ||||||
|  |         @Test | ||||||
|  |         public void testOpenGameMenuWithESC() { | ||||||
|  |             MonopolyApp app = new MonopolyApp(); | ||||||
|  |             app.simpleInitApp(); | ||||||
|  |             app.simpleUpdate(0.1f); | ||||||
|  |             GameMenu gameMenu = app.getStateManager().getState(GameMenu.class); | ||||||
|  |             assertTrue(gameMenu.isVisible()); | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         // T007 UC-game-07 - testEnterHostName | ||||||
|  |         @Test | ||||||
|  |         public void testEnterHostName() { | ||||||
|  |             MonopolyApp app = new MonopolyApp(); | ||||||
|  |             app.simpleInitApp(); | ||||||
|  |             NewGameMenu newGameMenu = app.getStateManager().getState(NewGameMenu.class); | ||||||
|  |             newGameMenu.showMenu(); | ||||||
|  |             newGameMenu.enterHostName("localhost"); | ||||||
|  |             assertEquals("localhost", newGameMenu.getHostName()); | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         // T008 UC-game-07 - testEnterPortNumber | ||||||
|  |         @Test | ||||||
|  |         public void testEnterPortNumber() { | ||||||
|  |             MonopolyApp app = new MonopolyApp(); | ||||||
|  |             app.simpleInitApp(); | ||||||
|  |             NewGameMenu newGameMenu = app.getStateManager().getState(NewGameMenu.class); | ||||||
|  |             newGameMenu.showMenu(); | ||||||
|  |             newGameMenu.enterPortNumber(12345); | ||||||
|  |             assertEquals(12345, newGameMenu.getPortNumber()); | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         // T009 UC-game-07 - testCancelGameCreation | ||||||
|  |         @Test | ||||||
|  |         public void testCancelGameCreation() { | ||||||
|  |             MonopolyApp app = new MonopolyApp(); | ||||||
|  |             app.simpleInitApp(); | ||||||
|  |             NewGameMenu newGameMenu = app.getStateManager().getState(NewGameMenu.class); | ||||||
|  |             newGameMenu.showMenu(); | ||||||
|  |             newGameMenu.cancel(); | ||||||
|  |             MainMenu mainMenu = app.getStateManager().getState(MainMenu.class); | ||||||
|  |             assertTrue(mainMenu.isMenuVisible()); | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         // T010 UC-game-08 - testEnterPlayerLobby | ||||||
|  |         @Test | ||||||
|  |         public void testEnterPlayerLobby() { | ||||||
|  |             MonopolyApp app = new MonopolyApp(); | ||||||
|  |             app.simpleInitApp(); | ||||||
|  |             app.getStateManager().getState(NetworkDialog.class).connect(); | ||||||
|  |             Lobby lobby = app.getStateManager().getState(Lobby.class); | ||||||
|  |             assertNotNull(lobby); | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         // T011 UC-game-09 - testEnterStartingCapital | ||||||
|  |         @Test | ||||||
|  |         public void testEnterStartingCapital() { | ||||||
|  |             MonopolyApp app = new MonopolyApp(); | ||||||
|  |             app.simpleInitApp(); | ||||||
|  |             NewGameMenu newGameMenu = app.getStateManager().getState(NewGameMenu.class); | ||||||
|  |             newGameMenu.showMenu(); | ||||||
|  |             newGameMenu.enterStartingCapital(1500); | ||||||
|  |             assertEquals(1500, newGameMenu.getStartingCapital()); | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         // T012 UC-game-09 - testIncreaseStartingCapital | ||||||
|  |         @Test | ||||||
|  |         public void testIncreaseStartingCapital() { | ||||||
|  |             MonopolyApp app = new MonopolyApp(); | ||||||
|  |             app.simpleInitApp(); | ||||||
|  |             NewGameMenu newGameMenu = app.getStateManager().getState(NewGameMenu.class); | ||||||
|  |             newGameMenu.showMenu(); | ||||||
|  |             newGameMenu.enterStartingCapital(1500); | ||||||
|  |             newGameMenu.increaseStartingCapital(100); | ||||||
|  |             assertEquals(1600, newGameMenu.getStartingCapital()); | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         // T013 UC-game-09 - testDecreaseStartingCapital | ||||||
|  |         @Test | ||||||
|  |         public void testDecreaseStartingCapital() { | ||||||
|  |             MonopolyApp app = new MonopolyApp(); | ||||||
|  |             app.simpleInitApp(); | ||||||
|  |             NewGameMenu newGameMenu = app.getStateManager().getState(NewGameMenu.class); | ||||||
|  |             newGameMenu.showMenu(); | ||||||
|  |             newGameMenu.enterStartingCapital(1500); | ||||||
|  |             newGameMenu.decreaseStartingCapital(100); | ||||||
|  |             assertEquals(1400, newGameMenu.getStartingCapital()); | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         // T014 UC-game-10 - testDefaultPlayerName | ||||||
|  |         @Test | ||||||
|  |         public void testDefaultPlayerName() { | ||||||
|  |             MonopolyApp app = new MonopolyApp(); | ||||||
|  |             app.simpleInitApp(); | ||||||
|  |             app.getStateManager().getState(Lobby.class).initializePlayerNames(); | ||||||
|  |             assertEquals("Spieler 1", app.getStateManager().getState(Lobby.class).getPlayerName(0)); | ||||||
|  |             assertEquals("Spieler 2", app.getStateManager().getState(Lobby.class).getPlayerName(1)); | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         // T015 UC-game-11 - testEnterDisplayName | ||||||
|  |         @Test | ||||||
|  |         public void testEnterDisplayName() { | ||||||
|  |             MonopolyApp app = new MonopolyApp(); | ||||||
|  |             app.simpleInitApp(); | ||||||
|  |             Lobby lobby = app.getStateManager().getState(Lobby.class); | ||||||
|  |             lobby.enterDisplayName("TestPlayer"); | ||||||
|  |             assertEquals("TestPlayer", lobby.getPlayerName(0)); | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         // T016 UC-game-11 - testDuplicateNameEntry | ||||||
|  |         @Test | ||||||
|  |         public void testDuplicateNameEntry() { | ||||||
|  |             MonopolyApp app = new MonopolyApp(); | ||||||
|  |             app.simpleInitApp(); | ||||||
|  |             Lobby lobby = app.getStateManager().getState(Lobby.class); | ||||||
|  |             lobby.enterDisplayName("Player1"); | ||||||
|  |             assertTrue(lobby.isDuplicateName("Player1")); | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         // T017 UC-game-12 - testSelectPlayerColor | ||||||
|  |         @Test | ||||||
|  |         public void testSelectPlayerColor() { | ||||||
|  |             MonopolyApp app = new MonopolyApp(); | ||||||
|  |             app.simpleInitApp(); | ||||||
|  |             Lobby lobby = app.getStateManager().getState(Lobby.class); | ||||||
|  |             lobby.selectColor("Red"); | ||||||
|  |             assertEquals("Red", lobby.getPlayerColor(0)); | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         // T018 UC-game-12 - testSelectOccupiedColor | ||||||
|  |         @Test | ||||||
|  |         public void testSelectOccupiedColor() { | ||||||
|  |             MonopolyApp app = new MonopolyApp(); | ||||||
|  |             app.simpleInitApp(); | ||||||
|  |             Lobby lobby = app.getStateManager().getState(Lobby.class); | ||||||
|  |             lobby.selectColor("Red"); | ||||||
|  |             assertTrue(lobby.isColorOccupied("Red")); | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         // T019 UC-game-13 - testSelectPlayerToken | ||||||
|  |         @Test | ||||||
|  |         public void testSelectPlayerToken() { | ||||||
|  |             MonopolyApp app = new MonopolyApp(); | ||||||
|  |             app.simpleInitApp(); | ||||||
|  |             Lobby lobby = app.getStateManager().getState(Lobby.class); | ||||||
|  |             lobby.selectToken("Ship"); | ||||||
|  |             assertEquals("Ship", lobby.getPlayerToken(0)); | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         // T020 UC-game-13 - testSelectOccupiedToken | ||||||
|  |         @Test | ||||||
|  |         public void testSelectOccupiedToken() { | ||||||
|  |             MonopolyApp app = new MonopolyApp(); | ||||||
|  |             app.simpleInitApp(); | ||||||
|  |             Lobby lobby = app.getStateManager().getState(Lobby.class); | ||||||
|  |             lobby.selectToken("Ship"); | ||||||
|  |             assertTrue(lobby.isTokenOccupied("Ship")); | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         // T021 UC-game-14 - testCancelPlayerLobby | ||||||
|  |         @Test | ||||||
|  |         public void testCancelPlayerLobby() { | ||||||
|  |             MonopolyApp app = new MonopolyApp(); | ||||||
|  |             app.simpleInitApp(); | ||||||
|  |             Lobby lobby = app.getStateManager().getState(Lobby.class); | ||||||
|  |             lobby.cancel(); | ||||||
|  |             MainMenu mainMenu = app.getStateManager().getState(MainMenu.class); | ||||||
|  |             assertTrue(mainMenu.isMenuVisible()); | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         // T022 UC-game-15 - testOpenLobbyMenuWithESC | ||||||
|  |         @Test | ||||||
|  |         public void testOpenLobbyMenuWithESC() { | ||||||
|  |             MonopolyApp app = new MonopolyApp(); | ||||||
|  |             app.simpleInitApp(); | ||||||
|  |             app.simpleUpdate(0.1f); | ||||||
|  |             LobbyMenu lobbyMenu = app.getStateManager().getState(LobbyMenu.class); | ||||||
|  |             assertTrue(lobbyMenu.isVisible()); | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         // T023 UC-game-16 - testPlayerReadyConfirmation | ||||||
|  |         @Test | ||||||
|  |         public void testPlayerReadyConfirmation() { | ||||||
|  |             MonopolyApp app = new MonopolyApp(); | ||||||
|  |             app.simpleInitApp(); | ||||||
|  |             Lobby lobby = app.getStateManager().getState(Lobby.class); | ||||||
|  |             lobby.setPlayerReady(true); | ||||||
|  |             assertTrue(lobby.isPlayerReady(0)); | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         // T024 UC-game-17 - testStartGame | ||||||
|  |         @Test | ||||||
|  |         public void testStartGame() { | ||||||
|  |             MonopolyApp app = new MonopolyApp(); | ||||||
|  |             app.simpleInitApp(); | ||||||
|  |             Lobby lobby = app.getStateManager().getState(Lobby.class); | ||||||
|  |             lobby.startGame(); | ||||||
|  |             assertEquals(GameState.InGame, lobby.getGameState()); | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         // T025 UC-game-18 - testPlayerMovement | ||||||
|  |         @Test | ||||||
|  |         public void testPlayerMovement() { | ||||||
|  |             MonopolyApp app = new MonopolyApp(); | ||||||
|  |             app.simpleInitApp(); | ||||||
|  |             Game game = app.getStateManager().getState(Game.class); | ||||||
|  |             Player player = game.getPlayer(0); | ||||||
|  |             player.move(5); | ||||||
|  |             assertEquals(5, player.getPosition()); | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         // T026 UC-game-19 - testPurchaseProperty | ||||||
|  |         @Test | ||||||
|  |         public void testPurchaseProperty() { | ||||||
|  |             MonopolyApp app = new MonopolyApp(); | ||||||
|  |             app.simpleInitApp(); | ||||||
|  |             Game game = app.getStateManager().getState(Game.class); | ||||||
|  |             Player player = game.getPlayer(0); | ||||||
|  |             Property property = game.getProperty(0); | ||||||
|  |             player.buyProperty(property); | ||||||
|  |             assertTrue(player.getProperties().contains(property)); | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         // T027 UC-game-20 - testMovePlayerOnDiceRoll | ||||||
|  |         @Test | ||||||
|  |         public void testMovePlayerOnDiceRoll() { | ||||||
|  |             MonopolyApp app = new MonopolyApp(); | ||||||
|  |             app.simpleInitApp(); | ||||||
|  |             Game game = app.getStateManager().getState(Game.class); | ||||||
|  |             Player player = game.getPlayer(0); | ||||||
|  |             int initialPosition = player.getPosition(); | ||||||
|  |             player.rollDice(); | ||||||
|  |             assertTrue(player.getPosition() > initialPosition); | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         // T028 UC-game-21 - testPassGo | ||||||
|  |         @Test | ||||||
|  |         public void testPassGo() { | ||||||
|  |             MonopolyApp app = new MonopolyApp(); | ||||||
|  |             app.simpleInitApp(); | ||||||
|  |             Game game = app.getStateManager().getState(Game.class); | ||||||
|  |             Player player = game.getPlayer(0); | ||||||
|  |             player.move(40);  // Assuming 40 steps moves player to Go | ||||||
|  |             assertTrue(player.passedGo()); | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         // T029 UC-game-22 - testCollectMoneyFromGo | ||||||
|  |         @Test | ||||||
|  |         public void testCollectMoneyFromGo() { | ||||||
|  |             MonopolyApp app = new MonopolyApp(); | ||||||
|  |             app.simpleInitApp(); | ||||||
|  |             Game game = app.getStateManager().getState(Game.class); | ||||||
|  |             Player player = game.getPlayer(0); | ||||||
|  |             int initialBalance = player.getBalance(); | ||||||
|  |             player.move(40);  // Move to Go | ||||||
|  |             assertTrue(player.getBalance() > initialBalance); | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         // T030 UC-game-23 - testPayRent | ||||||
|  |         @Test | ||||||
|  |         public void testPayRent() { | ||||||
|  |             MonopolyApp app = new MonopolyApp(); | ||||||
|  |             app.simpleInitApp(); | ||||||
|  |             Game game = app.getStateManager().getState(Game.class); | ||||||
|  |             Player player = game.getPlayer(0); | ||||||
|  |             PropertyField property = (PropertyField) game.getField(1); | ||||||
|  |             player.move(1); | ||||||
|  |             int initialBalance = player.getBalance(); | ||||||
|  |             player.payRent(property); | ||||||
|  |             assertTrue(player.getBalance() < initialBalance); | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         // T031 UC-game-24 - testDeclareBankruptcy | ||||||
|  |         @Test | ||||||
|  |         public void testDeclareBankruptcy() { | ||||||
|  |             MonopolyApp app = new MonopolyApp(); | ||||||
|  |             app.simpleInitApp(); | ||||||
|  |             Game game = app.getStateManager().getState(Game.class); | ||||||
|  |             Player player = game.getPlayer(0); | ||||||
|  |             player.declareBankruptcy(); | ||||||
|  |             assertEquals(PlayerState.Bankrupt, player.getState()); | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         // T032 UC-game-25 - testTradeProperty | ||||||
|  |         @Test | ||||||
|  |         public void testTradeProperty() { | ||||||
|  |             MonopolyApp app = new MonopolyApp(); | ||||||
|  |             app.simpleInitApp(); | ||||||
|  |             Game game = app.getStateManager().getState(Game.class); | ||||||
|  |             Player player1 = game.getPlayer(0); | ||||||
|  |             Player player2 = game.getPlayer(1); | ||||||
|  |             Property property = game.getProperty(0); | ||||||
|  |             player1.offerTrade(player2, property); | ||||||
|  |             assertTrue(player2.hasProperty(property)); | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         // T033 UC-game-26 - testGameOverCondition | ||||||
|  |         @Test | ||||||
|  |         public void testGameOverCondition() { | ||||||
|  |             MonopolyApp app = new MonopolyApp(); | ||||||
|  |             app.simpleInitApp(); | ||||||
|  |             Game game = app.getStateManager().getState(Game.class); | ||||||
|  |             Player player = game.getPlayer(0); | ||||||
|  |             player.declareBankruptcy(); | ||||||
|  |             assertTrue(game.isGameOver()); | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         // T034 UC-game-27 - testPlayerInJail | ||||||
|  |         @Test | ||||||
|  |         public void testPlayerInJail() { | ||||||
|  |             MonopolyApp app = new MonopolyApp(); | ||||||
|  |             app.simpleInitApp(); | ||||||
|  |             Game game = app.getStateManager().getState(Game.class); | ||||||
|  |             Player player = game.getPlayer(0); | ||||||
|  |             game.sendToJail(player); | ||||||
|  |             assertEquals(PlayerState.InJail, player.getState()); | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |  | ||||||
| @@ -1,7 +1,161 @@ | |||||||
| package pp.monopoly.client; | package pp.monopoly.client; | ||||||
|  |  | ||||||
|  | import com.jme3.input.KeyInput; | ||||||
|  | import com.jme3.scene.Spatial; | ||||||
|  | import com.simsilica.lemur.Button; | ||||||
|  | import org.junit.Before; | ||||||
| import org.junit.Test; | import org.junit.Test; | ||||||
|  |  | ||||||
|  | import static org.junit.Assert.assertNotNull; | ||||||
|  | import static org.junit.Assert.assertNull; | ||||||
|  |  | ||||||
| public class ClientLogicTest { | public class ClientLogicTest { | ||||||
|  |  | ||||||
|  |     private MonopolyApp app; | ||||||
|  |  | ||||||
|  |     @Before | ||||||
|  |     public void setUp() { | ||||||
|  |         app = new MonopolyApp(); | ||||||
|  |         app.simpleInitApp(); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     @Test | ||||||
|  |     // T001: UC-game-01 - Überprüft, ob die Anwendung erfolgreich gestartet wird und das Hauptmenü angezeigt wird | ||||||
|  |     public void testStartApplication() { | ||||||
|  |         Spatial mainMenu = app.getGuiNode().getChild("MainMenu"); | ||||||
|  |         assertNotNull("Das Hauptmenü sollte sichtbar sein", mainMenu); | ||||||
|  |     } | ||||||
|  | /* | ||||||
|  |     @Test | ||||||
|  |     // T002: UC-game-02 - Überprüft, ob das Startmenü nach dem Start der Anwendung angezeigt wird | ||||||
|  |     public void testOpenStartMenu() { | ||||||
|  |         Spatial startMenu = app.getGuiNode().getChild("StartMenu"); | ||||||
|  |         assertNotNull("Das Startmenü sollte sichtbar sein", startMenu); | ||||||
|  |     } | ||||||
|  | */ | ||||||
|  | @Test | ||||||
|  | // T002: UC-game-02 - Überprüft, ob das Startmenü (MainMenu) angezeigt wird und die Buttons korrekt funktionieren | ||||||
|  | public void testMainMenuButtons() { | ||||||
|  |     Spatial mainMenu = app.getGuiNode().getChild("MainMenu"); | ||||||
|  |     assertNotNull("Das Hauptmenü (MainMenu) sollte sichtbar sein", mainMenu); | ||||||
|  |  | ||||||
|  |     Spatial playButtonSpatial = app.getGuiNode().getChild("PlayButton"); | ||||||
|  |     assertNotNull("Der 'Spielen'-Button sollte existieren", playButtonSpatial); | ||||||
|  |  | ||||||
|  |     Spatial settingsButtonSpatial = app.getGuiNode().getChild("SettingsButton"); | ||||||
|  |     assertNotNull("Der 'Einstellungen'-Button sollte existieren", settingsButtonSpatial); | ||||||
|  |  | ||||||
|  |     Spatial exitButtonSpatial = app.getGuiNode().getChild("ExitButton"); | ||||||
|  |     assertNotNull("Der 'Spiel beenden'-Button sollte existieren", exitButtonSpatial); | ||||||
|  |  | ||||||
|  |     // Optional: Überprüfung der Funktionalität (Simulation von Button-Klicks) | ||||||
|  |     if (playButtonSpatial instanceof Button) { | ||||||
|  |         Button playButton = (Button) playButtonSpatial; | ||||||
|  |         playButton.click(); | ||||||
|  |  | ||||||
|  |         Spatial newGameMenu = app.getGuiNode().getChild("NewGameMenu"); | ||||||
|  |         assertNotNull("Das Spielerstellungsmenü sollte nach dem Klicken auf 'Spielen' sichtbar sein", newGameMenu); | ||||||
|  |     } else { | ||||||
|  |         throw new AssertionError("'PlayButton' ist kein Button-Objekt."); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     if (settingsButtonSpatial instanceof Button) { | ||||||
|  |         Button settingsButton = (Button) settingsButtonSpatial; | ||||||
|  |         settingsButton.click(); | ||||||
|  |  | ||||||
|  |         Spatial settingsMenu = app.getGuiNode().getChild("SettingsMenu"); | ||||||
|  |         assertNotNull("Das Einstellungsmenü sollte nach dem Klicken auf 'Einstellungen' sichtbar sein", settingsMenu); | ||||||
|  |     } else { | ||||||
|  |         throw new AssertionError("'SettingsButton' ist kein Button-Objekt."); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     if (exitButtonSpatial instanceof Button) { | ||||||
|  |         Button exitButton = (Button) exitButtonSpatial; | ||||||
|  |         exitButton.click(); | ||||||
|  |  | ||||||
|  |         Spatial mainMenuAfterExit = app.getGuiNode().getChild("MainMenu"); | ||||||
|  |         assertNull("Das Hauptmenü sollte nach dem Klicken auf 'Spiel beenden' nicht mehr sichtbar sein", mainMenuAfterExit); | ||||||
|  |     } else { | ||||||
|  |         throw new AssertionError("'ExitButton' ist kein Button-Objekt."); | ||||||
|  |     } | ||||||
| } | } | ||||||
|  |     @Test | ||||||
|  |     // T003: UC-game-03 - Überprüft, ob der „Spiel starten“-Button das Spielerstellungsmenü öffnet | ||||||
|  |     public void testNavigateToPlayOption() { | ||||||
|  |         Spatial startGameButtonSpatial = app.getGuiNode().getChild("StartGameButton"); | ||||||
|  |         assertNotNull("Der 'Spiel starten'-Button sollte existieren", startGameButtonSpatial); | ||||||
|  |  | ||||||
|  |         if (startGameButtonSpatial instanceof Button) { | ||||||
|  |             Button startGameButton = (Button) startGameButtonSpatial; | ||||||
|  |             startGameButton.click(); | ||||||
|  |  | ||||||
|  |             Spatial newGameMenu = app.getGuiNode().getChild("NewGameMenu"); | ||||||
|  |             assertNotNull("Das Spielerstellungsmenü sollte sichtbar sein", newGameMenu); | ||||||
|  |         } else { | ||||||
|  |             throw new AssertionError("'StartGameButton' ist kein Button-Objekt."); | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     @Test | ||||||
|  |     // T004: UC-game-04 - Testet, ob die Anwendung geschlossen wird, wenn „Beenden“ im Hauptmenü gewählt wird | ||||||
|  |     public void testExitApplicationFromMenu() { | ||||||
|  |         Spatial exitButtonSpatial = app.getGuiNode().getChild("ExitButton"); | ||||||
|  |         assertNotNull("Der 'Beenden'-Button sollte existieren", exitButtonSpatial); | ||||||
|  |  | ||||||
|  |         if (exitButtonSpatial instanceof Button) { | ||||||
|  |             Button exitButton = (Button) exitButtonSpatial; | ||||||
|  |             exitButton.click(); | ||||||
|  |  | ||||||
|  |             Spatial mainMenuAfterExit = app.getGuiNode().getChild("MainMenu"); | ||||||
|  |             assertNull("Das Hauptmenü sollte nach dem Beenden nicht mehr sichtbar sein", mainMenuAfterExit); | ||||||
|  |         } else { | ||||||
|  |             throw new AssertionError("'ExitButton' ist kein Button-Objekt."); | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     @Test | ||||||
|  |     // T005: UC-game-05 - Überprüft, ob das Einstellungen-Menü aus dem Hauptmenü aufgerufen werden kann | ||||||
|  |     public void testOpenSettingsFromMenu() { | ||||||
|  |         Spatial settingsButtonSpatial = app.getGuiNode().getChild("SettingsButton"); | ||||||
|  |         assertNotNull("Der 'Einstellungen'-Button sollte existieren", settingsButtonSpatial); | ||||||
|  |  | ||||||
|  |         if (settingsButtonSpatial instanceof Button) { | ||||||
|  |             Button settingsButton = (Button) settingsButtonSpatial; | ||||||
|  |             settingsButton.click(); | ||||||
|  |  | ||||||
|  |             Spatial settingsMenu = app.getGuiNode().getChild("SettingsMenu"); | ||||||
|  |             assertNotNull("Das Einstellungsmenü sollte sichtbar sein", settingsMenu); | ||||||
|  |         } else { | ||||||
|  |             throw new AssertionError("'SettingsButton' ist kein Button-Objekt."); | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     @Test | ||||||
|  |     // T006: UC-game-06 - Testet, ob das Spielmenü geöffnet wird, wenn der Spieler im Spiel „ESC“ drückt | ||||||
|  |     public void testOpenGameMenuWithESC() { | ||||||
|  |         app.escape(true); // Simuliert das Drücken der ESC-Taste | ||||||
|  |  | ||||||
|  |         Spatial gameMenu = app.getGuiNode().getChild("GameMenu"); | ||||||
|  |         assertNotNull("Das Spielmenü sollte nach Drücken von ESC sichtbar sein", gameMenu); | ||||||
|  |  | ||||||
|  |         app.escape(false); // Simuliert das Loslassen der ESC-Taste | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |  | ||||||
|  |     @Test | ||||||
|  |     // T083: UC-menu-05 - Überprüfen, ob der Spieler erfolgreich ins Spiel zurückkehren kann | ||||||
|  |     public void testReturnToGame() { | ||||||
|  |         Spatial returnButtonSpatial = app.getGuiNode().getChild("ReturnButton"); | ||||||
|  |         assertNotNull("Der 'Zurück'-Button sollte existieren", returnButtonSpatial); | ||||||
|  |  | ||||||
|  |         if (returnButtonSpatial instanceof Button) { | ||||||
|  |             Button returnButton = (Button) returnButtonSpatial; | ||||||
|  |             returnButton.click(); | ||||||
|  |  | ||||||
|  |             Spatial gameScene = app.getGuiNode().getChild("GameScene"); | ||||||
|  |             assertNotNull("Die Spielszene sollte nach dem Klick auf 'Zurück' sichtbar sein", gameScene); | ||||||
|  |         } else { | ||||||
|  |             throw new AssertionError("'ReturnButton' ist kein Button-Objekt."); | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | } | ||||||
| @@ -1,20 +1,606 @@ | |||||||
| //////////////////////////////////////// |  | ||||||
| // Programming project code |  | ||||||
| // UniBw M, 2022, 2023, 2024 |  | ||||||
| // www.unibw.de/inf2 |  | ||||||
| // (c) Mark Minas (mark.minas@unibw.de) |  | ||||||
| //////////////////////////////////////// |  | ||||||
|  |  | ||||||
| package pp.monopoly.game.client; | package pp.monopoly.game.client; | ||||||
|  |  | ||||||
|  | import com.jme3.scene.Spatial; | ||||||
|  | import com.simsilica.lemur.Button; | ||||||
|  | import com.simsilica.lemur.TextField; | ||||||
| import org.junit.Before; | import org.junit.Before; | ||||||
| import org.junit.Test; | import org.junit.Test; | ||||||
|  | import pp.monopoly.client.MonopolyApp; | ||||||
|  | import pp.monopoly.game.server.Player; | ||||||
|  | import pp.monopoly.message.server.DiceResult; | ||||||
|  | import pp.monopoly.notification.ClientStateEvent; | ||||||
|  |  | ||||||
| import static org.junit.Assert.assertEquals; | import static org.junit.Assert.assertEquals; | ||||||
| import static org.junit.Assert.assertFalse; | import static org.junit.Assert.assertNotNull; | ||||||
| import static org.junit.Assert.assertTrue; | import static org.junit.Assert.assertTrue; | ||||||
|  |  | ||||||
| public class ClientGameLogicTest { | public class ClientGameLogicTest { | ||||||
|  |  | ||||||
| } |     private MonopolyApp app; | ||||||
|  |  | ||||||
|  |     private MonopolyApp app; | ||||||
|  |     private NewGameMenu newGameMenu; | ||||||
|  |  | ||||||
|  |     @Before | ||||||
|  |     public void setUp() { | ||||||
|  |         app = new MonopolyApp(); | ||||||
|  |         app.simpleInitApp(); // Initialisiert die App mit GUI und Spielzuständen | ||||||
|  |         newGameMenu = new NewGameMenu(); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     @Test | ||||||
|  |     // T006: UC-game-06 - Testet, ob das Spielmenü geöffnet wird, wenn der Spieler im Spiel „ESC“ drückt | ||||||
|  |     public void testOpenGameMenuWithESC() { | ||||||
|  |         app.escape(true); // Simuliert das Drücken der ESC-Taste | ||||||
|  |  | ||||||
|  |         Spatial gameMenu = app.getGuiNode().getChild("GameMenu"); | ||||||
|  |         assertNotNull("Das Spielmenü sollte sichtbar sein, nachdem ESC gedrückt wurde", gameMenu); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     @Test | ||||||
|  |     // T007: UC-game-07 - Testet, ob der Spieler erfolgreich den Namen des Hosts eingeben kann | ||||||
|  |     public void testEnterHostName() { | ||||||
|  |         Spatial hostNameField = app.getGuiNode().getChild("HostNameField"); | ||||||
|  |         assertNotNull("Das Eingabefeld für den Hostnamen sollte sichtbar sein", hostNameField); | ||||||
|  |  | ||||||
|  |         if (hostNameField instanceof TextField) { | ||||||
|  |             TextField hostNameInput = (TextField) hostNameField; | ||||||
|  |             hostNameInput.setText("TestHost"); | ||||||
|  |  | ||||||
|  |             assertEquals("Der eingegebene Hostname sollte 'TestHost' sein", "TestHost", hostNameInput.getText()); | ||||||
|  |         } | ||||||
|  |         else { | ||||||
|  |             throw new AssertionError("'HostNameField' ist kein TextField-Objekt."); | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     @Test | ||||||
|  |     // T008: UC-game-08 - Testet, ob der Spieler die Portnummer des Hosts eingeben kann | ||||||
|  |     public void testEnterPortNumber() { | ||||||
|  |         Spatial portNumberField = app.getGuiNode().getChild("PortNumberField"); | ||||||
|  |         assertNotNull("Das Eingabefeld für die Portnummer sollte sichtbar sein", portNumberField); | ||||||
|  |  | ||||||
|  |         if (portNumberField instanceof TextField) { | ||||||
|  |             TextField portNumberInput = (TextField) portNumberField; | ||||||
|  |             portNumberInput.setText("12345"); | ||||||
|  |  | ||||||
|  |             assertEquals("Die eingegebene Portnummer sollte '12345' sein", "12345", portNumberInput.getText()); | ||||||
|  |         } | ||||||
|  |         else { | ||||||
|  |             throw new AssertionError("'PortNumberField' ist kein TextField-Objekt."); | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     @Test | ||||||
|  |     // T009: UC-game-09 - Testet, ob der Spieler das Erstellen eines Spiels abbrechen kann | ||||||
|  |     public void testCancelGameCreation() { | ||||||
|  |         Spatial cancelButtonSpatial = app.getGuiNode().getChild("CancelButton"); | ||||||
|  |         assertNotNull("Der 'Abbrechen'-Button sollte existieren", cancelButtonSpatial); | ||||||
|  |  | ||||||
|  |         if (cancelButtonSpatial instanceof Button) { | ||||||
|  |             Button cancelButton = (Button) cancelButtonSpatial; | ||||||
|  |             cancelButton.click(); | ||||||
|  |  | ||||||
|  |             Spatial mainMenu = app.getGuiNode().getChild("MainMenu"); | ||||||
|  |             assertNotNull("Das Hauptmenü sollte nach dem Abbrechen des Spiels sichtbar sein", mainMenu); | ||||||
|  |         } | ||||||
|  |         else { | ||||||
|  |             throw new AssertionError("'CancelButton' ist kein Button-Objekt."); | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     /* | ||||||
|  |         @Test | ||||||
|  |         // T010: UC-game-10 - Testet, ob der Spieler die Spielerlobby betreten kann | ||||||
|  |         public void testEnterPlayerLobby() { | ||||||
|  |             app.receivedEvent(new pp.monopoly.notification.ClientStateEvent(pp.monopoly.notification.ClientStateEvent.State.LOBBY)); | ||||||
|  |  | ||||||
|  |             Spatial playerLobby = app.getGuiNode().getChild("PlayerLobby"); | ||||||
|  |             assertNotNull("Die Spielerlobby sollte nach dem Beitritt sichtbar sein", playerLobby); | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |  | ||||||
|  |         @Test | ||||||
|  |         // T010: UC-game-10 - Testet, ob der Spieler die Spielerlobby betreten kann | ||||||
|  |         public void testEnterPlayerLobby() { | ||||||
|  |             // Simuliert den Empfang eines ClientStateEvent für den Lobby-State | ||||||
|  |             app.receivedEvent(new ClientStateEvent(ClientStateEvent.State.LOBBY)); | ||||||
|  |  | ||||||
|  |             // Überprüft, ob das Lobby-UI sichtbar ist | ||||||
|  |             Spatial playerLobby = app.getGuiNode().getChild("PlayerLobby"); | ||||||
|  |             assertNotNull("Die Spielerlobby sollte nach dem Beitritt sichtbar sein", playerLobby); | ||||||
|  |     */ | ||||||
|  |     @Test | ||||||
|  |     // T011: UC-game-11 - Testet, ob der hostende Spieler einen Startbetrag eingeben kann | ||||||
|  |     public void testEnterStartingCapital() { | ||||||
|  |         Spatial startingCapitalField = app.getGuiNode().getChild("StartingCapitalField"); | ||||||
|  |         assertNotNull("Das Eingabefeld für den Startbetrag sollte existieren", startingCapitalField); | ||||||
|  |  | ||||||
|  |         if (startingCapitalField instanceof TextField) { | ||||||
|  |             TextField startingCapitalInput = (TextField) startingCapitalField; | ||||||
|  |             startingCapitalInput.setText("1500"); | ||||||
|  |  | ||||||
|  |             assertEquals("Der eingegebene Startbetrag sollte '1500' sein", "1500", startingCapitalInput.getText()); | ||||||
|  |         } | ||||||
|  |         else { | ||||||
|  |             throw new AssertionError("'StartingCapitalField' ist kein TextField-Objekt."); | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     @Test | ||||||
|  |     // T012: UC-game-12 - Testet, ob der Spieler den Startbetrag um 100 € erhöhen kann | ||||||
|  |     public void testIncreaseStartingCapital() { | ||||||
|  |         Spatial increaseButton = app.getGuiNode().getChild("IncreaseCapitalButton"); | ||||||
|  |         assertNotNull("Der 'Erhöhen'-Button sollte existieren", increaseButton); | ||||||
|  |  | ||||||
|  |         if (increaseButton instanceof Button) { | ||||||
|  |             Button increaseCapitalButton = (Button) increaseButton; | ||||||
|  |             increaseCapitalButton.click(); | ||||||
|  |  | ||||||
|  |             Spatial startingCapitalField = app.getGuiNode().getChild("StartingCapitalField"); | ||||||
|  |             if (startingCapitalField instanceof TextField) { | ||||||
|  |                 TextField startingCapitalInput = (TextField) startingCapitalField; | ||||||
|  |                 assertEquals("Der Startbetrag sollte um 100 erhöht worden sein", "1600", startingCapitalInput.getText()); | ||||||
|  |             } | ||||||
|  |             else { | ||||||
|  |                 throw new AssertionError("'StartingCapitalField' ist kein TextField-Objekt."); | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |         else { | ||||||
|  |             throw new AssertionError("'IncreaseCapitalButton' ist kein Button-Objekt."); | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     @Test | ||||||
|  |     // T013: UC-game-13 - Testet, ob der Spieler den Startbetrag um 100 € senken kann | ||||||
|  |     public void testDecreaseStartingCapital() { | ||||||
|  |         Spatial decreaseButton = app.getGuiNode().getChild("DecreaseCapitalButton"); | ||||||
|  |         assertNotNull("Der 'Senken'-Button sollte existieren", decreaseButton); | ||||||
|  |  | ||||||
|  |         if (decreaseButton instanceof Button) { | ||||||
|  |             Button decreaseCapitalButton = (Button) decreaseButton; | ||||||
|  |             decreaseCapitalButton.click(); | ||||||
|  |  | ||||||
|  |             Spatial startingCapitalField = app.getGuiNode().getChild("StartingCapitalField"); | ||||||
|  |             if (startingCapitalField instanceof TextField) { | ||||||
|  |                 TextField startingCapitalInput = (TextField) startingCapitalField; | ||||||
|  |                 assertEquals("Der Startbetrag sollte um 100 gesenkt worden sein", "1400", startingCapitalInput.getText()); | ||||||
|  |             } | ||||||
|  |             else { | ||||||
|  |                 throw new AssertionError("'StartingCapitalField' ist kein TextField-Objekt."); | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |         else { | ||||||
|  |             throw new AssertionError("'DecreaseCapitalButton' ist kein Button-Objekt."); | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     @Test | ||||||
|  |     // T014: UC-game-14 - Testet, ob die Standard-Spielernamen korrekt voreingestellt sind | ||||||
|  |     public void testDefaultPlayerName() { | ||||||
|  |         Spatial playerNameField = app.getGuiNode().getChild("PlayerNameField"); | ||||||
|  |         assertNotNull("Das Eingabefeld für den Spielernamen sollte existieren", playerNameField); | ||||||
|  |  | ||||||
|  |         if (playerNameField instanceof TextField) { | ||||||
|  |             TextField playerNameInput = (TextField) playerNameField; | ||||||
|  |             assertEquals("Der voreingestellte Spielername sollte 'Spieler 1' sein", "Spieler 1", playerNameInput.getText()); | ||||||
|  |         } | ||||||
|  |         else { | ||||||
|  |             throw new AssertionError("'PlayerNameField' ist kein TextField-Objekt."); | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     @Test | ||||||
|  |     // T015: UC-game-15 - Testet, ob der Spieler einen Anzeigenamen eingeben kann | ||||||
|  |     public void testEnterDisplayName() { | ||||||
|  |         Spatial displayNameField = app.getGuiNode().getChild("DisplayNameField"); | ||||||
|  |         assertNotNull("Das Eingabefeld für den Anzeigenamen sollte existieren", displayNameField); | ||||||
|  |  | ||||||
|  |         if (displayNameField instanceof TextField) { | ||||||
|  |             TextField displayNameInput = (TextField) displayNameField; | ||||||
|  |             displayNameInput.setText("MaxMustermann"); | ||||||
|  |  | ||||||
|  |             assertEquals("Der eingegebene Anzeigename sollte 'MaxMustermann' sein", "MaxMustermann", displayNameInput.getText()); | ||||||
|  |         } | ||||||
|  |         else { | ||||||
|  |             throw new AssertionError("'DisplayNameField' ist kein TextField-Objekt."); | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     @Test | ||||||
|  |     // T016: UC-game-16 - Testet, ob eine Warnung angezeigt wird, wenn ein Spieler einen bereits belegten Namen eingibt | ||||||
|  |     public void testDuplicateNameEntry() { | ||||||
|  |         Spatial playerNameField = app.getGuiNode().getChild("PlayerNameField"); | ||||||
|  |         assertNotNull("Das Eingabefeld für den Spielernamen sollte existieren", playerNameField); | ||||||
|  |  | ||||||
|  |         if (playerNameField instanceof TextField) { | ||||||
|  |             TextField playerNameInput = (TextField) playerNameField; | ||||||
|  |             playerNameInput.setText("Spieler 1"); | ||||||
|  |             app.getGuiNode().getChild("AddPlayerButton").click(); // Spieler hinzufügen | ||||||
|  |             playerNameInput.setText("Spieler 1"); | ||||||
|  |             app.getGuiNode().getChild("AddPlayerButton").click(); // Spieler mit gleichem Namen hinzufügen | ||||||
|  |  | ||||||
|  |             Spatial warning = app.getGuiNode().getChild("DuplicateNameWarning"); | ||||||
|  |             assertNotNull("Es sollte eine Warnung angezeigt werden, wenn ein Name doppelt vergeben wird", warning); | ||||||
|  |         } | ||||||
|  |         else { | ||||||
|  |             throw new AssertionError("'PlayerNameField' ist kein TextField-Objekt."); | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     @Test | ||||||
|  |     // T017: UC-game-17 - Testet, ob der Spieler eine verfügbare Spielfigurfarbe auswählen kann | ||||||
|  |     public void testSelectPlayerColor() { | ||||||
|  |         Spatial colorSelector = app.getGuiNode().getChild("ColorSelector"); | ||||||
|  |         assertNotNull("Der Farbwähler sollte existieren", colorSelector); | ||||||
|  |  | ||||||
|  |         if (colorSelector instanceof Button) { | ||||||
|  |             Button colorButton = (Button) colorSelector; | ||||||
|  |             colorButton.click(); | ||||||
|  |  | ||||||
|  |             Spatial selectedColor = app.getGuiNode().getChild("SelectedColor"); | ||||||
|  |             assertNotNull("Die gewählte Farbe sollte sichtbar sein", selectedColor); | ||||||
|  |         } | ||||||
|  |         else { | ||||||
|  |             throw new AssertionError("'ColorSelector' ist kein Button-Objekt."); | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     @Test | ||||||
|  |     // T018: UC-game-18 - Testet, ob eine belegte Spielfigurfarbe nicht ausgewählt werden kann | ||||||
|  |     public void testSelectOccupiedColor() { | ||||||
|  |         app.getGuiNode().getChild("ColorSelectorRed").click(); // Spieler 1 wählt Rot | ||||||
|  |         app.getGuiNode().getChild("AddPlayerButton").click(); // Spieler 1 hinzufügen | ||||||
|  |  | ||||||
|  |         app.getGuiNode().getChild("ColorSelectorRed").click(); // Spieler 2 versucht Rot zu wählen | ||||||
|  |         Spatial warning = app.getGuiNode().getChild("ColorOccupiedWarning"); | ||||||
|  |         assertNotNull("Es sollte eine Warnung angezeigt werden, wenn eine belegte Farbe ausgewählt wird", warning); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     @Test | ||||||
|  |     // T019: UC-game-19 - Testet, ob der Spieler eine Spielfigur auswählen kann | ||||||
|  |     public void testSelectPlayerToken() { | ||||||
|  |         Spatial tokenSelector = app.getGuiNode().getChild("TokenSelector"); | ||||||
|  |         assertNotNull("Der Token-Wähler sollte existieren", tokenSelector); | ||||||
|  |  | ||||||
|  |         if (tokenSelector instanceof Button) { | ||||||
|  |             Button tokenButton = (Button) tokenSelector; | ||||||
|  |             tokenButton.click(); | ||||||
|  |  | ||||||
|  |             Spatial selectedToken = app.getGuiNode().getChild("SelectedToken"); | ||||||
|  |             assertNotNull("Die gewählte Spielfigur sollte sichtbar sein", selectedToken); | ||||||
|  |         } | ||||||
|  |         else { | ||||||
|  |             throw new AssertionError("'TokenSelector' ist kein Button-Objekt."); | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     @Test | ||||||
|  |     // T020: UC-game-20 - Testet, ob eine belegte Spielfigur nicht ausgewählt werden kann | ||||||
|  |     public void testSelectOccupiedToken() { | ||||||
|  |         app.getGuiNode().getChild("TokenSelectorShip").click(); | ||||||
|  |         app.getGuiNode().getChild("AddPlayerButton").click(); | ||||||
|  |  | ||||||
|  |         app.getGuiNode().getChild("TokenSelectorShip").click(); | ||||||
|  |         Spatial warning = app.getGuiNode().getChild("TokenOccupiedWarning"); | ||||||
|  |         assertNotNull("Es sollte eine Warnung angezeigt werden, wenn eine belegte Spielfigur ausgewählt wird", warning); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     @Test | ||||||
|  |     // T021: UC-game-14 - Überprüft, ob der Spieler zur „Spiel erstellen“-Ansicht zurückkehrt, wenn Abbrechen gedrückt wird | ||||||
|  |     public void testCancelPlayerLobby() { | ||||||
|  |         Spatial cancelButtonSpatial = app.getGuiNode().getChild("CancelLobbyButton"); | ||||||
|  |         assertNotNull("Der 'Abbrechen'-Button in der Lobby sollte existieren", cancelButtonSpatial); | ||||||
|  |  | ||||||
|  |         if (cancelButtonSpatial instanceof Button) { | ||||||
|  |             Button cancelButton = (Button) cancelButtonSpatial; | ||||||
|  |             cancelButton.click(); | ||||||
|  |  | ||||||
|  |             Spatial mainMenu = app.getGuiNode().getChild("MainMenu"); | ||||||
|  |             assertNotNull("Das Hauptmenü sollte nach dem Abbrechen der Lobby sichtbar sein", mainMenu); | ||||||
|  |         } | ||||||
|  |         else { | ||||||
|  |             throw new AssertionError("'CancelLobbyButton' ist kein Button-Objekt."); | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     @Test | ||||||
|  |     // T022: UC-game-15 - Überprüft, ob das Spielmenü in der Lobby durch Drücken der ESC-Taste geöffnet wird | ||||||
|  |     public void testOpenLobbyMenuWithESC() { | ||||||
|  |         app.escape(true); // Simuliert das Drücken der ESC-Taste | ||||||
|  |  | ||||||
|  |         Spatial lobbyMenu = app.getGuiNode().getChild("LobbyMenu"); | ||||||
|  |         assertNotNull("Das Lobby-Menü sollte sichtbar sein, nachdem ESC in der Lobby gedrückt wurde", lobbyMenu); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     @Test | ||||||
|  |     // T023: UC-game-16 - Testet, ob der Spieler die Auswahl der Spielfigur bestätigen kann | ||||||
|  |     public void testPlayerReadyConfirmation() { | ||||||
|  |         Spatial confirmButtonSpatial = app.getGuiNode().getChild("ConfirmTokenButton"); | ||||||
|  |         assertNotNull("Der 'Bestätigen'-Button für die Spielfigur sollte existieren", confirmButtonSpatial); | ||||||
|  |  | ||||||
|  |         if (confirmButtonSpatial instanceof Button) { | ||||||
|  |             Button confirmButton = (Button) confirmButtonSpatial; | ||||||
|  |             confirmButton.click(); | ||||||
|  |  | ||||||
|  |             Spatial readyStatus = app.getGuiNode().getChild("PlayerReadyStatus"); | ||||||
|  |             assertNotNull("Der Status 'Bereit' sollte angezeigt werden, nachdem die Spielfigur bestätigt wurde", readyStatus); | ||||||
|  |         } | ||||||
|  |         else { | ||||||
|  |             throw new AssertionError("'ConfirmTokenButton' ist kein Button-Objekt."); | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  |         @Test | ||||||
|  |         // T024: UC-game-16 - Überprüft, ob das Spiel startet, wenn alle Spieler ihre Auswahl bestätigt haben | ||||||
|  |         public void testAllPlayersReady() { | ||||||
|  |             app.receivedEvent(new pp.monopoly.notification.ClientStateEvent(pp.monopoly.notification.ClientStateEvent.State.ALL_PLAYERS_READY)); | ||||||
|  |  | ||||||
|  |             Spatial gameScreen = app.getGuiNode().getChild("GameScreen"); | ||||||
|  |             assertNotNull("Das Spiel sollte starten, wenn alle Spieler bereit sind", gameScreen); | ||||||
|  |         } | ||||||
|  |         @Test | ||||||
|  |         // T025: UC-game-17 - Testet, ob das Einstellungen-Menü während des Spiels geöffnet wird | ||||||
|  |         public void testOpenMainGameSettings () { | ||||||
|  |             app.escape(true); | ||||||
|  |  | ||||||
|  |             Spatial settingsButton = app.getGuiNode().getChild("SettingsButton"); | ||||||
|  |             assertNotNull("Der 'Einstellungen'-Button sollte im Spielmenü vorhanden sein", settingsButton); | ||||||
|  |  | ||||||
|  |             if (settingsButton instanceof Button) { | ||||||
|  |                 ((Button) settingsButton).click(); | ||||||
|  |                 Spatial settingsMenu = app.getGuiNode().getChild("SettingsMenu"); | ||||||
|  |                 assertNotNull("Das Einstellungen-Menü sollte im Spiel angezeigt werden", settingsMenu); | ||||||
|  |             } | ||||||
|  |             else { | ||||||
|  |                 throw new AssertionError("'SettingsButton' ist kein Button-Objekt."); | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |     @Test | ||||||
|  | // T026: UC-gameplay-01 - Überprüft, ob der Spieler erfolgreich würfeln kann | ||||||
|  |     public void testRollDice() { | ||||||
|  |         Spatial rollDiceButton = app.getGuiNode().getChild("RollDiceButton"); | ||||||
|  |         assertNotNull("Der 'Würfeln'-Button sollte sichtbar sein", rollDiceButton); | ||||||
|  |  | ||||||
|  |         if (rollDiceButton instanceof Button) { | ||||||
|  |             ((Button) rollDiceButton).click(); // Simuliert einen Würfelwurf | ||||||
|  |             Spatial diceResult = app.getGuiNode().getChild("DiceResult"); | ||||||
|  |             assertNotNull("Das Ergebnis des Würfelwurfs sollte angezeigt werden", diceResult); | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  |     @Test | ||||||
|  | // T027: UC-gameplay-01 - Überprüft, ob der aktive Spieler die richtige Anzahl an Feldern basierend auf dem Wurf bewegt | ||||||
|  |     public void testMovePlayerAutomatically() { | ||||||
|  |         Game game = new Game(); // Initialisiert ein neues Spiel | ||||||
|  |         PlayerHandler playerHandler = game.getPlayerHandler(); // Holt den PlayerHandler, der die Spieler verwaltet | ||||||
|  |  | ||||||
|  |         Player activePlayer = playerHandler.getActivePlayer(); // Holt den aktuellen aktiven Spieler | ||||||
|  |         assertNotNull("Es sollte einen aktiven Spieler geben", activePlayer); | ||||||
|  |  | ||||||
|  |         DiceResult diceResult = game.rollDice(); // Würfelwurf simulieren | ||||||
|  |         int steps = diceResult.getTotal(); | ||||||
|  |  | ||||||
|  |         int initialPosition = activePlayer.getFieldId(); // Ursprüngliche Position des aktiven Spielers | ||||||
|  |         playerHandler.moveActivePlayer(steps); // Bewegt den aktiven Spieler basierend auf dem Wurf | ||||||
|  |  | ||||||
|  |         int expectedPosition = (initialPosition + steps) % game.getGameBoard().getNumberOfFields(); // Zielposition berechnen | ||||||
|  |         int newPosition = activePlayer.getFieldId(); | ||||||
|  |  | ||||||
|  |         assertEquals("Der aktive Spieler sollte sich korrekt bewegen", expectedPosition, newPosition); | ||||||
|  |  | ||||||
|  |         // Überprüfen, dass alle anderen Spieler im WaitForTurn-State bleiben | ||||||
|  |         playerHandler.getPlayers().stream() | ||||||
|  |                      .filter(player -> player != activePlayer) | ||||||
|  |                      .forEach(player -> assertTrue("Andere Spieler sollten im WaitForTurn-State sein", player.getState() instanceof WaitForTurnState)); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     @Test | ||||||
|  | // T028: UC-gameplay-02 - Überprüft, ob die Würfel zufällige Zahlen generieren | ||||||
|  |     public void testGenerationDice() { | ||||||
|  |         boolean isRandom = false; | ||||||
|  |         DiceResult previousResult = null; | ||||||
|  |  | ||||||
|  |         for (int i = 0; i < 10; i++) { | ||||||
|  |             DiceResult currentResult = app.getGame().rollDice(); | ||||||
|  |  | ||||||
|  |             assertNotNull("Das Würfelergebnis sollte nicht null sein", currentResult); | ||||||
|  |             assertTrue("Die Würfelzahl 1 sollte zwischen 1 und 6 liegen", currentResult.getDice1() >= 1 && currentResult.getDice1() <= 6); | ||||||
|  |             assertTrue("Die Würfelzahl 2 sollte zwischen 1 und 6 liegen", currentResult.getDice2() >= 1 && currentResult.getDice2() <= 6); | ||||||
|  |  | ||||||
|  |             if (previousResult != null && (currentResult.getDice1() != previousResult.getDice1() || currentResult.getDice2() != previousResult.getDice2())) { | ||||||
|  |                 isRandom = true; // Unterschiedliche Würfelwerte gefunden | ||||||
|  |                 break; | ||||||
|  |             } | ||||||
|  |             previousResult = currentResult; | ||||||
|  |         } | ||||||
|  |         assertTrue("Die Würfelergebnisse sollten zufällig sein", isRandom); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     @Test | ||||||
|  | // T029: UC-gameplay-03 - Überprüft, ob die richtigen Augenzahlen angezeigt werden | ||||||
|  |     public void testDisplayResults() { | ||||||
|  |         DiceResult result = app.getGame().rollDice(); | ||||||
|  |  | ||||||
|  |         assertNotNull("Das Würfelergebnis sollte nicht null sein", result); | ||||||
|  |         assertTrue("Die Würfelzahl 1 sollte zwischen 1 und 6 liegen", result.getDice1() >= 1 && result.getDice1() <= 6); | ||||||
|  |         assertTrue("Die Würfelzahl 2 sollte zwischen 1 und 6 liegen", result.getDice2() >= 1 && result.getDice2() <= 6); | ||||||
|  |         assertEquals("Die Summe sollte korrekt berechnet werden", result.getDice1() + result.getDice2(), result.getTotal()); | ||||||
|  |     } | ||||||
|  |     @Test | ||||||
|  |     // T030: UC-gameplay-04 - Überprüfen, ob die Summe der Würfelergebnisse korrekt berechnet wird | ||||||
|  |     public void testSumDiceResults() { | ||||||
|  |         Spatial rollDiceButton = app.getGuiNode().getChild("RollDiceButton"); | ||||||
|  |         assertNotNull("Der 'Würfeln'-Button sollte sichtbar sein", rollDiceButton); | ||||||
|  |  | ||||||
|  |         if (rollDiceButton instanceof Button) { | ||||||
|  |             ((Button) rollDiceButton).click(); // Simuliert einen Würfelwurf | ||||||
|  |             Spatial diceResult1 = app.getGuiNode().getChild("DiceResult1"); | ||||||
|  |             Spatial diceResult2 = app.getGuiNode().getChild("DiceResult2"); | ||||||
|  |  | ||||||
|  |             assertNotNull("Die Ergebnisse des Würfelwurfs sollten angezeigt werden", diceResult1); | ||||||
|  |             assertNotNull("Die Ergebnisse des Würfelwurfs sollten angezeigt werden", diceResult2); | ||||||
|  |  | ||||||
|  |             int result1 = Integer.parseInt(diceResult1.getUserData("value").toString()); | ||||||
|  |             int result2 = Integer.parseInt(diceResult2.getUserData("value").toString()); | ||||||
|  |             int expectedSum = result1 + result2; | ||||||
|  |  | ||||||
|  |             Spatial sumDisplay = app.getGuiNode().getChild("DiceSum"); | ||||||
|  |             assertEquals("Die Summe der Würfelergebnisse sollte korrekt angezeigt werden", expectedSum, Integer.parseInt(sumDisplay.getUserData("value").toString())); | ||||||
|  |         } else { | ||||||
|  |             throw new AssertionError("'RollDiceButton' ist kein Button-Objekt."); | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     @Test | ||||||
|  |     // T031: UC-gameplay-05 - Überprüfen, ob die Würfel nach dem Wurf ausgegraut werden | ||||||
|  |     public void testGrayOutDiceAfterRoll() { | ||||||
|  |         Spatial rollDiceButton = app.getGuiNode().getChild("RollDiceButton"); | ||||||
|  |         assertNotNull("Der 'Würfeln'-Button sollte sichtbar sein", rollDiceButton); | ||||||
|  |  | ||||||
|  |         if (rollDiceButton instanceof Button) { | ||||||
|  |             ((Button) rollDiceButton).click(); // Simuliert einen Würfelwurf | ||||||
|  |  | ||||||
|  |             Spatial diceDisplay = app.getGuiNode().getChild("DiceDisplay"); | ||||||
|  |             assertNotNull("Die Würfelanzeige sollte nach dem Wurf sichtbar sein", diceDisplay); | ||||||
|  |  | ||||||
|  |             boolean isGrayedOut = diceDisplay.getUserData("grayedOut"); | ||||||
|  |             assertTrue("Die Würfel sollten nach dem Wurf ausgegraut sein", isGrayedOut); | ||||||
|  |         } else { | ||||||
|  |             throw new AssertionError("'RollDiceButton' ist kein Button-Objekt."); | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     @Test | ||||||
|  |     // T032: UC-gameplay-06 - Überprüfen, ob das Würfeln eines Paschs erkannt wird | ||||||
|  |     public void testDetectDouble() { | ||||||
|  |         Spatial rollDiceButton = app.getGuiNode().getChild("RollDiceButton"); | ||||||
|  |         assertNotNull("Der 'Würfeln'-Button sollte sichtbar sein", rollDiceButton); | ||||||
|  |  | ||||||
|  |         if (rollDiceButton instanceof Button) { | ||||||
|  |             // Simuliert mehrere Würfe, um einen Pasch zu erkennen | ||||||
|  |             for (int i = 0; i < 10; i++) { | ||||||
|  |                 ((Button) rollDiceButton).click(); | ||||||
|  |                 Spatial diceResult1 = app.getGuiNode().getChild("DiceResult1"); | ||||||
|  |                 Spatial diceResult2 = app.getGuiNode().getChild("DiceResult2"); | ||||||
|  |  | ||||||
|  |                 int result1 = Integer.parseInt(diceResult1.getUserData("value").toString()); | ||||||
|  |                 int result2 = Integer.parseInt(diceResult2.getUserData("value").toString()); | ||||||
|  |  | ||||||
|  |                 if (result1 == result2) { | ||||||
|  |                     Spatial doubleIndicator = app.getGuiNode().getChild("DoubleIndicator"); | ||||||
|  |                     assertNotNull("Ein Pasch sollte angezeigt werden, wenn zwei identische Zahlen geworfen werden", doubleIndicator); | ||||||
|  |                     break; | ||||||
|  |                 } | ||||||
|  |             } | ||||||
|  |         } else { | ||||||
|  |             throw new AssertionError("'RollDiceButton' ist kein Button-Objekt."); | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     @Test | ||||||
|  |     // T033: UC-gameplay-06 - Überprüfen, ob der Spieler bei einem Pasch erneut würfeln darf | ||||||
|  |     public void testDoubleRoll() { | ||||||
|  |         Spatial rollDiceButton = app.getGuiNode().getChild("RollDiceButton"); | ||||||
|  |         assertNotNull("Der 'Würfeln'-Button sollte sichtbar sein", rollDiceButton); | ||||||
|  |  | ||||||
|  |         if (rollDiceButton instanceof Button) { | ||||||
|  |             // Simuliert das Würfeln eines Paschs | ||||||
|  |             ((Button) rollDiceButton).click(); | ||||||
|  |             Spatial diceResult1 = app.getGuiNode().getChild("DiceResult1"); | ||||||
|  |             Spatial diceResult2 = app.getGuiNode().getChild("DiceResult2"); | ||||||
|  |  | ||||||
|  |             int result1 = Integer.parseInt(diceResult1.getUserData("value").toString()); | ||||||
|  |             int result2 = Integer.parseInt(diceResult2.getUserData("value").toString()); | ||||||
|  |  | ||||||
|  |             if (result1 == result2) { // Überprüft, ob ein Pasch geworfen wurde | ||||||
|  |                 Spatial rollAgainIndicator = app.getGuiNode().getChild("RollAgainIndicator"); | ||||||
|  |                 assertNotNull("Der Spieler sollte bei einem Pasch erneut würfeln dürfen", rollAgainIndicator); | ||||||
|  |             } | ||||||
|  |         } else { | ||||||
|  |             throw new AssertionError("'RollDiceButton' ist kein Button-Objekt."); | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     @Test | ||||||
|  |     // T034: UC-gameplay-06 - Überprüfen, ob der Spieler nach dem dritten Pasch ins Gefängnis muss | ||||||
|  |     public void testTripleDoubleGulag() { | ||||||
|  |         int doubleCount = 0; | ||||||
|  |  | ||||||
|  |         for (int i = 0; i < 3; i++) { | ||||||
|  |             Spatial rollDiceButton = app.getGuiNode().getChild("RollDiceButton"); | ||||||
|  |             assertNotNull("Der 'Würfeln'-Button sollte sichtbar sein", rollDiceButton); | ||||||
|  |  | ||||||
|  |             if (rollDiceButton instanceof Button) { | ||||||
|  |                 ((Button) rollDiceButton).click(); | ||||||
|  |                 Spatial diceResult1 = app.getGuiNode().getChild("DiceResult1"); | ||||||
|  |                 Spatial diceResult2 = app.getGuiNode().getChild("DiceResult2"); | ||||||
|  |  | ||||||
|  |                 int result1 = Integer.parseInt(diceResult1.getUserData("value").toString()); | ||||||
|  |                 int result2 = Integer.parseInt(diceResult2.getUserData("value").toString()); | ||||||
|  |  | ||||||
|  |                 if (result1 == result2) { | ||||||
|  |                     doubleCount++; | ||||||
|  |                 } | ||||||
|  |  | ||||||
|  |                 if (doubleCount == 3) { | ||||||
|  |                     Spatial jailIndicator = app.getGuiNode().getChild("JailIndicator"); | ||||||
|  |                     assertNotNull("Der Spieler sollte nach dem dritten Pasch ins Gefängnis gehen", jailIndicator); | ||||||
|  |                     break; | ||||||
|  |                 } | ||||||
|  |             } else { | ||||||
|  |                 throw new AssertionError("'RollDiceButton' ist kein Button-Objekt."); | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         assertTrue("Der Spieler sollte drei Paschs geworfen haben", doubleCount == 3); | ||||||
|  |     } | ||||||
|  |     @Test | ||||||
|  | // T035: UC-gameplay-07 - Überprüfen, ob ein Spieler für Steuerfelder korrekt belastet wird | ||||||
|  |     public void testTaxFieldCharges() { | ||||||
|  |         Game game = new Game(); | ||||||
|  |         PlayerHandler playerHandler = game.getPlayerHandler(); | ||||||
|  |         Player activePlayer = playerHandler.getActivePlayer(); | ||||||
|  |         assertNotNull("Es sollte einen aktiven Spieler geben", activePlayer); | ||||||
|  |  | ||||||
|  |         int initialBalance = activePlayer.getAccountBalance(); | ||||||
|  |  | ||||||
|  |         activePlayer.moveToField(game.getGameBoard().getFieldById(4)); // ID 4: Steuerfeld "Diszi" | ||||||
|  |         game.getGameBoard().applyFieldEffect(activePlayer); | ||||||
|  |  | ||||||
|  |         int expectedBalance = initialBalance - 200; // Beispielsteuer: 200 € | ||||||
|  |         assertEquals("Der Spieler sollte für das Steuerfeld korrekt belastet werden", expectedBalance, activePlayer.getAccountBalance()); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     @Test | ||||||
|  | // T036: UC-gameplay-08 - Überprüfen, ob ein Spieler korrekt ins Gefängnis geschickt wird | ||||||
|  |     public void testGoToJailField() { | ||||||
|  |         Game game = new Game(); | ||||||
|  |         PlayerHandler playerHandler = game.getPlayerHandler(); | ||||||
|  |         Player activePlayer = playerHandler.getActivePlayer(); | ||||||
|  |         assertNotNull("Es sollte einen aktiven Spieler geben", activePlayer); | ||||||
|  |  | ||||||
|  |         activePlayer.moveToField(game.getGameBoard().getFieldById(30)); // ID 30: Ab ins Gefängnis | ||||||
|  |         game.getGameBoard().applyFieldEffect(activePlayer); | ||||||
|  |  | ||||||
|  |         assertEquals("Der Spieler sollte ins Gefängnis geschickt werden", 10, activePlayer.getFieldId()); // ID 10: Gefängnis | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     @Test | ||||||
|  | // T037: UC-gameplay-09 - Überprüfen, ob ein Spieler bei "Frei Parken" keine Gebühren zahlt | ||||||
|  |     public void testFreeParking() { | ||||||
|  |         Game game = new Game(); | ||||||
|  |         PlayerHandler playerHandler = game.getPlayerHandler(); | ||||||
|  |         Player activePlayer = playerHandler.getActivePlayer(); | ||||||
|  |         assertNotNull("Es sollte einen aktiven Spieler geben", activePlayer); | ||||||
|  |  | ||||||
|  |         int initialBalance = activePlayer.getAccountBalance(); | ||||||
|  |  | ||||||
|  |         activePlayer.moveToField(game.getGameBoard().getFieldById(20)); // ID 20: Frei Parken | ||||||
|  |         game.getGameBoard().applyFieldEffect(activePlayer); | ||||||
|  |  | ||||||
|  |         assertEquals("Der Spieler sollte bei 'Frei Parken' keine Gebühren zahlen", initialBalance, activePlayer.getAccountBalance()); | ||||||
|  |     } | ||||||
|  | } | ||||||
|  |  | ||||||
|  |  | ||||||
|  |  | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user