Gegnerischen Spieler entfernen

Hier kann über Fragen zum Spiel, dem Server und den Client diskutiert werden.
R'lyestux
Beiträge: 24
Registriert: Mi 21. Dez 2016, 16:46

Gegnerischen Spieler entfernen

Beitragvon R'lyestux » Sa 11. Feb 2017, 20:35

Hallo,
ich möchte nicht allzu sehr auf die Funktionsweise meiner KI eigehen, daher werde ich mich kurz halten.

Es gibt situationen wo meine KI mehere Spielzüge mit move.perform simuliert, dabei ist immer nur der erste Zug ein Zug, wo darauf geachtet wird, dass der Gegner entsprechend abgedrägt wird.
Will ich nun zwei Züge testen und beim zweiten Zug landet mein Schiff auf den Gegner, wird dieser nicht abgedrängt. Das ist auch gut so. Jedenfalls wird dann ein Exeption geworfen, obwohl alles eigentlich wie gewollt ablief. Deshalb will ich nach der Simulation des ersten Zuges den Gegner (in der Kopie von GameState) vom Brett nehmen. Die Funktion put wäre dazu ganz gut geeignet (ich kann ihn einfach auf das Feld 999,999 setzten) allerdings ist diese Funktion Protectet. Gibt es eine Alternative um mein Problem zu lösen.

Für Hilfe wäre ich sehr dankbar.

Ps. Bitte keine Fragen, warum ich dies erreichen möchte. Ist alles so gewollt.

SvenK
Beiträge: 114
Registriert: Mo 17. Okt 2011, 08:40

Re: Gegnerischen Spieler entfernen

Beitragvon SvenK » Mo 13. Feb 2017, 09:38

Im Moment koennte man die Methode zum versetzen des Spielers nur per Reflection von aussen Aufrufen. Das ist aber keine saubere objektorientierte Programmierung, daher habe ich die Klassen GameState und Player etwas erweitert, um ein sinnvolles Ableiten der Klassen zu ermoeglichen. Das heisst konkret in Version mq_0.12 der Software, die ich gleich veroeffentlichen werde, kannst Du folgendes tun:

1. GameState ableiten. In dieser abgeleiteten Klasse hast Du Zugriff auf die protected Methoden von GameState:

Code: Alles auswählen

package sc.player2017;

import sc.plugin2017.GameState;

public class TestGameState extends GameState {

  protected TestPlayer redTestPlayer;
  protected TestPlayer blueTestPlayer;

  public TestGameState(GameState stateToClone) throws CloneNotSupportedException {
    super(stateToClone);
    // change players to own implementation
    redTestPlayer = new TestPlayer(super.getRedPlayer());
    setRedPlayer(redTestPlayer);
    blueTestPlayer = new TestPlayer(super.getBluePlayer());
    setBluePlayer(blueTestPlayer);
  }

  public TestPlayer getRedTestPlayer() {
    return redTestPlayer;
  }

  public TestPlayer getBlueTestPlayer() {
    return blueTestPlayer;
  }

}


2. Player ableiten. Hier kann man nun eine public Methode implementieren, die den Spieler aus dem Weg raeumt:

Code: Alles auswählen

package sc.player2017;

import sc.plugin2017.Player;

public class TestPlayer extends Player {

  public TestPlayer(Player playerToClone) {
    super(playerToClone);
  }

  public void moveAway() {
    put(99, 99, 10);
  }
}


3. Im Code des Computerspielers den GameState zu einem TestGameState machen, um ihn dann beliebig manipulieren zu koennen:

Code: Alles auswählen

    try {
      TestGameState testGameState = new TestGameState(gameState);
      testGameState.getRedTestPlayer().moveAway();
      // testGameState.getRedPlayer().getX() gibt jetzt 99 zurueck.
      // ...
    } catch (CloneNotSupportedException e) {
      log.error("Got clone exception", e);
    }


Ich habe das rudimentaer getestet. Bitte melde Dich, wenn es mit dem Ansatz Probleme gibt.

R'lyestux
Beiträge: 24
Registriert: Mi 21. Dez 2016, 16:46

Re: Gegnerischen Spieler entfernen

Beitragvon R'lyestux » Do 16. Feb 2017, 21:16

danke für die Hilfe,
dass mit der neuen API funktioiert so halb. Ich kann den neuen Code ohne Fehler debuggen und ausführen allerdings werden nun:
sc.plugin2017.util.InvalidMoveException: Keine Bewegunspunkte mehr vorhanden
und
sc.plugin2017.util.InvalidMoveException: Es sind 3 Bewegungspunkte zuviel verbraucht worden.
häufig geworfen, was vorher noch nie passiert ist. Hier ist eine Codeteil:

Code: Alles auswählen

      GameState cloneGame = null;
      try {
         cloneGame = gameState.clone();
      } catch (CloneNotSupportedException e) {
         e.printStackTrace(); continue;
      }
      cloneGame.getCurrentPlayer().setFreeAcc(1);
      cloneGame.getCurrentPlayer().setFreeTurns(1);

          try {
            for(Move m : temp_all_moves.list){
               //   System.out.println(m);
                  m.perform(cloneGame, cloneGame.getCurrentPlayer());
                  cloneGame.getCurrentPlayer().setFreeAcc(1);
                  cloneGame.getCurrentPlayer().setFreeTurns(1);
               }
              }catch (InvalidMoveException e) {
                  e.printStackTrace(); continue;
              }

cloneGame ist von der Klasse GameState. Ich habe also keine änderung an meinen Code vorgenommen und totzdem werden diese Exeptions geworfen.

Außerdem habe ich noch das Problem, dass die Runable JAR File nach einer Exeption nicht mehr weiter rechnet (CPU bei 0%), obwohl sie abgefangen wird und es Problemlos funktiniert, wenn ich es über eclipse direkt starte.

R'lyestux
Beiträge: 24
Registriert: Mi 21. Dez 2016, 16:46

Re: Gegnerischen Spieler entfernen

Beitragvon R'lyestux » Do 16. Feb 2017, 22:38

Habe nun vorraussichtlich alle Problem gelöst.

R'lyestux
Beiträge: 24
Registriert: Mi 21. Dez 2016, 16:46

Re: Gegnerischen Spieler entfernen

Beitragvon R'lyestux » Di 28. Feb 2017, 15:34

R'lyestux hat geschrieben:Außerdem habe ich noch das Problem, dass die Runable JAR File nach einer Exeption nicht mehr weiter rechnet (CPU bei 0%), obwohl sie abgefangen wird und es Problemlos funktiniert, wenn ich es über eclipse direkt starte.

Das Problem ist nun wieder da.
Es könnte allerdings sein, dass es nur bei mir zuhause nicht funktioniert. Habe viele Freundschaftsspiele gemacht und dabei ist mir nie so ein fehler passiert, allerdings bin ich mir da unsicher. Wäre blöd wenn ich wegen etwas verliere was in der Runable JAR nicht funktioiert allerdings in eclipse. :/
p.s. Habe die neuste Version des Servers

R'lyestux
Beiträge: 24
Registriert: Mi 21. Dez 2016, 16:46

Re: Gegnerischen Spieler entfernen

Beitragvon R'lyestux » Di 28. Feb 2017, 16:35

Ok, habe den fehler gefunden:

Code: Alles auswählen

catch (InvalidMoveException e) {
               System.out.print(possibleMove);
               e.printStackTrace();
            }

es muss an einer dieser beiden Ausgaben liegen. Warum dies dazu führt, dass die Runable Jar nicht mehr funktioniert, ist mir ein Rätsel. Vielleicht sollte man die Allgemeinheit drauf hinweisen.

Xerus
Beiträge: 10
Registriert: Sa 15. Okt 2016, 18:16

Re: Gegnerischen Spieler entfernen

Beitragvon Xerus » Mi 1. Mär 2017, 12:44

Wäre es nicht möglich, dass man die Methode put direkt public macht?
Ich würde einfach gerne, ohne irgendwelche Klassen abzuleiten, den Spieler wegbewegen, da ich sowieso immer einfach mit clones arbeite.

SvenK
Beiträge: 114
Registriert: Mo 17. Okt 2011, 08:40

Re: Gegnerischen Spieler entfernen

Beitragvon SvenK » Mi 1. Mär 2017, 14:45

Nein, put bleibt protected.

Xerus
Beiträge: 10
Registriert: Sa 15. Okt 2016, 18:16

Re: Gegnerischen Spieler entfernen

Beitragvon Xerus » So 5. Mär 2017, 19:58

wie findet die Methode move.perform eigentlich heraus, ob eine Kollision stattfindet? Da sie ja wahrscheinlich gamestate.getotherplayer verwendet, ist das entfernen eines Testspielers doch ziemlich nutzlos? und irgendwie arbeitet sie teilweise mit den eigenschaften des Spielers vom gamestate und teilweise mit dem gegebenen...

SvenK
Beiträge: 114
Registriert: Mo 17. Okt 2011, 08:40

Re: Gegnerischen Spieler entfernen

Beitragvon SvenK » Mo 6. Mär 2017, 12:11

perform verwendet den uebergebenen Spieler als aktuellen Spieler (der gerade den Zug gemacht hat) und gameState.getOtherPlayer() als Gegner (der gerade nicht an der Reihe ist). Durch die weiter oben im Thread gezeigten Klassen-Ableitungen kann man beide Spieler beliebig versetzen, was eventuelle Kollisionen verhindert.

Dass man den aktuellen Spieler direkt uebergeben kann, macht es leichter, Zuege zu testen, wenn man den Gegner nicht versetzen kann/muss. In diesem Fall muss man nur einen veraenderten eigenen Spieler uebergeben und kann beliebig viele Tests auf dem aktuellen Gamestate durchfuehren.