# TutorVolley



## Apo (11. Dez 2006)

Hi,

da ich Tutor bei uns an der Uni dieses Semester bin, muss ich auch einige Aufgaben vorbereiten, die die Studenten bearbeiten müssen. Deshalb habe ich eine kleine Bitte an euch. Ist es für euch in einer endlichen Zeit (sagen wir mal 2 bis 4 Stunden) möglich, folgende Aufgabe zu lösen?

Die Aufgabe

Die Studenten haben über die Weihnachtsferien Zeit die Aufgabe zu lösen und ich habe die KI innerhalb von 10 Minuten geschrieben. Bin mir aber nicht sicher, ob es wirklich so leicht ist, weil ich ja den Rest des Programms selber geschrieben habe.

Würde mich deshalb riesig freuen, wenn einer von euch es mal testen und eine kleine KI schreiben könnte. Wäre auch Klasse, wenn ihr mir eure KI's in java oder class Form zukommen lassen könntet. Meine E-Mail Adresse lauet dirk@farafin.de

Alle anderen können gerne mal eine Runde spielen. *g*
€dit: Ach so Spieler 1 als Mensch (also der Linke) spielt mit den Pfeiltasten
der 2.Spieler als Mensch(also der Rechte) spielt mit wasd


MfG Apo


----------



## Murray (12. Dez 2006)

Bei eigenem Aufschlag ist es ja nicht besonders schwierig, die Easy-KI zu schlagen; dazu reicht vermutlich die Easy-KI selbst bereits aus - vielleicht solltet ihr die Aufgabenstellung da etwas konkretisieren.

Die Easy-KI selbst scheint mir etwas unglücklich realisiert zu sein; es sieht so aus, als steckte der gesamte Algorithmus da zweimal drin: einmal für das Spiel von links nach rechts und einmal für die andere Rcihtung. Eigentlich hätte ich erwartet, dass die Umgebung das bereits kapselt; wenn das aber nicht der Fall ist, dann sollte man wohl in der KI versuchen, beide Richtungen zu vereinheitlichen. Aber das ist bestimmt didaktisch so gewollt und das Lernziel bei dieser Aufgabe  :wink: 

Hilfreich wäre noch, wenn die Wertebereiche der relevanten Methoden (also quasi das Koordinatensystem) dokumentiert wäre.


----------



## Zunera (12. Dez 2006)

Hi,

also erstmal eins vorweg: Ein nettes Projekt - dass hätte mir in meinem Studium auch Spass gemacht!!  :toll: 

Einen KI-Player zu schreiben ist denke auch für Java-Neulinge (und für Informatik-Studenten(?) sowieso) besonders mit der Vorlage vom EasyPlayer eine recht einfache Angelegenheit. Das haben sie schnell und in absehbarer Zeit (ich brauchte ca ne halbe Stunde um meinen ersten Player zu schreiben - war sehr ähnlich dem EasyPlayer).
Die Zusatzaufgabe den BeatMe zu schlagen ist eine nette Herausforderung, aber nochmal 15 Minuten länger getippt und er ist platt - was nicht an der ausgereiften KI meines Spielers liegt sondern an der Tatsache, dass wenn ich an den Aufschlag komme, der BeatMe diesen Aufschlag nicht bekommt. Darauf habe ich nicht hinprogrammiert sondern es ist Zufall gewesen. Und selbst wenn der BeatMe den Aufschlag bekommt und das Spiel weitergeht und trotzdem der StudentenPlayer den Punkt macht dann läuft es die nächste Runde wieder ganz genauso - sprich: einmal einen Punkt für den Herausforderer, immer nur Punkte für den Herausforderer -> BeatMe platt.
In jedem Fall macht es mir sehr Spass, meinen Player noch bisschen aufzumotzen - ich schicke ihn dir dann gerne zu!

Grüße


----------



## Apo (12. Dez 2006)

danke für die netten Hinweise,

habe noch etwas zum Spielfeld geschrieben, damit auch jeder weiß wo das Netz ist usw.
Auch habe ich noch etwas am Easy-Player (damit nicht mehr alles doppelt drin steht) und BeatMe-Player gefeilt. Ich versuche es heute mal noch, dass der BeatMe-Player alle Aufschläge bekommt und somit andere Strategien notwenig sind. (Da die Aufgabe erst nächste Woche online geht für die Stundenten, kann ich statt BeatMe auch gerne einen Player von euch nehmen [natürlich mit Credits], wenn es jemand möchte  )

Leider habe ich bei den Tutorien bemerkt, dass obwohl es alles Informatiker, CV'ler, WIF'ler oder Ingeneurinformatiker sind ... und man somit davon ausgehen könnte, dass sie wenigstens schonmal programmiert haben ... es einige bis viele von Grund auf neu lernen müssen (noch nie was von oop gehört und vor vielen Jahren nur mal Pascal gehabt ...). Und deshalb habe ich die Aufgabe, wie schon erwähnt, recht einfach gestaltet. Und hoffe, dass gerade durch das "Einfache" viele den Spass haben werden, ihren Spieler so zu verbessern, dass er nicht nur easy schlägt, sondern auch die KI ihrer Freunde.
Die Einfachheit ist auch damit zu begründen, dass die Leute nicht jetzt schon vor dem Programmierwettbewerb im Januar abgeschreckt werden. Ich möchte ja das dort viele mitmachen. Jetzt sollen sie erstmal kennenlernen, wie man Klassen aus einer Jar mitnutzen kann und wie man richtig mit der API und deren Informationen umgeht. Und der Spieler selber ist dann das kleinste Problem. 

@zunera:
Ich freue mich schon auf den Spieler.


----------



## Zunera (13. Dez 2006)

Hallo Apo,

so, mein Player ist soweit fertig und ich möchte ihn als Herausforderung zur Verfügung stellen  

Herunterladen kann man ihn hier!

Nachdem mir die Unzulänglichkeiten von starren Spielzügen aufgefallen sind, hab ich eine kleine Zufallsvariable bei der Positionierung des Spielers eingebaut - das macht ihn etwas unberechenbarer und fehleranfälliger (kurz: "menschlicher"  :wink. Er hat noch manche Schwachstelle, beherrscht aber fünf grundlegende Strategien des Volleyballs: Grundlinienspiel, Netzspiel (mit Vorliebe), Ballverfolgung, Abwehr und Ball retten. Einen vernichtenden Schmetterangriff konnte ich ihm leider nicht beibringen...  

Also viel Spass damit und freue mich natürlich über Feedback!
Grüße

PS: Wie kann ich denn den rechten Spieler als Mensch spielen? Da ist immer schon der EasyPlayer eingestellt, wie mach ihn nen HumanPlayer draus? [edit: habs gecheckt - Human Klasse laden - eigentlich logisch - Frage erledigt]
PPS: Kann es sein, dass dein überarbeiteter BeatMe derzeit nur auf der linken Seite "vernünftig" spielt?


----------



## Deichwolf (14. Dez 2006)

Hallo Apo,

bin gerade dabei einen Player zusammenzufrickeln. Das ist ja ein sehr nettes Spielzeug!

BTW, wann ist eigentlich getBFirst() == true? Irgendwie kommt mir das Verhalten komisch vor. Ich würde erwarten, dass die Methode nur true liefert, solange der Ball auf den Aufschlag wartet (wie in der API beschrieben). Es sieht aber so aus, als wenn die Methode zwischendurch (evtl. vor der ersten gegnerischen Berührung) true liefert.

Gruß
Deichwolf


----------



## Apo (14. Dez 2006)

Guten Tag,

eigentlich müsste die Methode wie beschrieben nur true zurückliefern solange der Ball nicht berührt wurde. Ab dem ersten Ballkontakt liefert es für den Punkt nur false zurück. Muss ich mal beobachten, ob es da zu Problemen kommt.

@ zunera: großes thx an dich für den Spieler. Der spielt wirklich sehr menschlich. Manchmal haut er einem die Dinger nur so um die Ohren und manchmal lässt er die leichtesten Bälle fallen.
Ich versuche grad meinen eigenen Spieler richtig zu tunen. Er weiß nun immer wo er genau hinmuss und wann er abspringen muss. Jetzt nur noch ein bisschen mit random rumpsielen, damit er nicht immer alles gleich macht. 
Ach so den einzig wahren Schmetterschlag gibt es glaube ich nicht in diesem Spielchen, weil dafür ist die Kollisionsabfrage zu "komisch".


----------



## Zunera (15. Dez 2006)

Hello again,

wo bleiben denn die Computerspieler? Nach meinem ersten Versuch (danke für die Rückmeldung!) mit einem "RandomPlayer" habe ich nochmal fix einen simplen Gegner gestrickt - hat zwar noch bissel Zufall drin, aber positioniert sich jetzt definitiv berechnender. Erstaunlicherweise (?) ist so ein Spieler leichter und kürzer zu programmieren als ein fehleranfälligerer. Daher habe ich ihn "Simply" getauft und es gibt ihn hier!

Bin gespannt auf weitere Spieler! Schade dass ich nicht in Magdeburg studiere!  :wink: 
Grüße

@Apo: Nach der neuen Aufgabenstellung den BeatMe zu 0 zu schlagen ist eher demotivierend da mA unmöglich. Lieber einen richtig guten BeatMe (bin gespannt auf deinen getunten), den man auf beiden Seiten einfach nur besiegen muss...


----------



## Deichwolf (15. Dez 2006)

Hallo Apo,

wenn mich nicht alles täuscht, ist die Logik von getBFirst verdreht, sprich true wenn im Spiel und false vor dem Aufschlag.


----------



## Apo (15. Dez 2006)

@Deichwolf: du hast natürlich vollkommen recht!!! Sorry, verbessere das sofort in der API.

@Zunera: Was dagegen wenn ich simply als guten Spieler mit auf die Site packe??? Würde mich freuen wenn das geht.

@all: freue mich noch über neue Spieler


----------



## Zunera (15. Dez 2006)

Hi Apo,

klar, sehr gern - allerdings bitte nochmal "Simply" neu runterladen (Link in meinem vorigen Beitrag), hab gerade noch Werte angepasst, damit er auch auf der rechten Seite bissel vernünftiger spielt.
:?:  Gibts den getunten BeatMe schon?

[edit:  :!: Hab mir nochmal das ZipFile von der Aufgabenseite heruntergeladen und gesehen, dass Snowman und Simply drin sind *stolzsei*... leider laut Datum beides die "alten" Versionen! Bitte nochmal die aktuellen herunterladen...  Da sind nur ein paar Werte vonwegen Positionierung und bla geändert, aber das macht einiges aus... :lol: Danke!]


----------



## TheDestroyer (15. Dez 2006)

eine kurze Frage: in der methode think ist doch immer eine +15 bzw. -15. die ist doch für die tolereanz da, oder, sodass der spieler den ball nicht nur genau mit der mitte treffen muss, oder???? bLeft ist doch für den Ball? sprich er ist links


----------



## Zunera (15. Dez 2006)

Fast - die Zahlen sind weniger als Toleranz gedacht, sondern als Positionierungshilfe für den Spieler. Damit soll der Ball in eine bestimmte Richtung gelenkt werden - also wenn Ball nach rechts fliegen soll, muss ihn der Spieler etwas links anspielen (also etwas links vom Ball stehen bzw springen) - ergo Differenz zum Ball -15 (oder ein andere negativer Wert)...


----------



## Apo (15. Dez 2006)

das +15 bzw. -15 bedeutet folgendes ...
wenn ich nur überprüfe ob die Mitte des Kopfes des Spieler mit der Mitte des Balls übereinstimmt und dann hochspringe bedeutet dass ja das der Ball nur nach oben fliegt und keine Geschwindigkeit in x-Richtung bekommt
deshalb immer 15 Unterschied damit der Ball auch nach links und rechts fliegt.
[€dit]wie zunera schon sagte!!!

Habe ebend mal meinen Spieler gemacht und musste feststellen das einige Kollisionabfragen am Netz überhaupt nicht fkt. Der Ball flog einfach durch ... das Problem ist nun behoben ... außerdem konnte es vorkommen das Spieler 2 4 mal berührt und trotzdem den Punkt bekommt ... das ist auch behoben und die neue Version beinhaltet beide Spieler von Zunera und meinen neuen "Apo"  der hat nur Netzprobleme noch und mit Schmetterbällen also die kaum ySpeed haben sondern nur in x Richtung gehen auch ... sonst schlägt er sich sehr gut 

die neue Version steht on an alter Stelle

€dit²: Habe grad durch einen Studenten, der es schonmal ausprobiert hat, erfahren, dass die linke Seite 1 Pixel mehr zu laufen hatte als die rechte ... das ist nun auch verbessert ... mensch Sachen gibt es die gibt es gar nicht ... nun können beide 162 Pixel weit gehen

€dit³: Durch VIELE Anfragen von Studenten kann man nun auch die Gegnerkoordinaten herausbekommen. Wie genau steht auf der Site. Die alten KI's fkt trotzdem noch.


----------



## TheDestroyer (12. Jan 2007)

ich glaube jetzt ist die aufgabe doch fertig oder, könnt ihr mal ein paar codes hochladen? würd mir gerne mal anschauen was ich hätte besser machen können, obwohl meiner schon ganz gut klappt, allerdings noch gegen einen Großteil eurer Spieler verliert.


----------



## Zunera (12. Jan 2007)

Jo, wie ist denn das Volleyballturnier ausgegangen?? :wink:

Also das ist meine think-Methode des Simply. Ich hab festgestellt, das mein Simply auf der rechten Seite relativ mies spielt... vielleicht liegt es an den oben eingestellten Werten, damit kann man bissel rumspielen.


```
public boolean think(TutorVolleyBall ball, TutorVolleyPlayer player)
	{     
        int posToBall = (player.getXMiddle() < 200 ? -7 : 19), randomDiff = 20,
            jumpHeight = 10, calcHeight = 110, targetPos = (int)(ball.getXMiddle() + 2*posToBall);

        boolean jump = (ball.getY() > jumpHeight &&
                ((player.getXMiddle() < 200 && ball.getXMiddle() < 210) ||
                (player.getXMiddle() > 200 && ball.getXMiddle() > 190)));

        //calculate Position
        if ((!ball.getBFirst() && player.getXMiddle() < 200 && ball.getXMiddle() < 200) ||
            (!ball.getBFirst() && player.getXMiddle() > 200 && ball.getXMiddle() > 200)) 
        {
            //Aufschlag!
            targetPos = (int)(ball.getXMiddle() + 1.5*posToBall +
                            randomDiff*Math.random() - randomDiff);
            
            if((player.getXMiddle() > targetPos - 20) && (player.getXMiddle() < targetPos + 20))
                return true;
            
            jump = false;
        }

        else if(player.getY() > 145 &&
            ((Math.abs(ball.getXSpeed()) > 1 && ball.getY() < calcHeight) ||
            (player.getXMiddle() < 200 && ball.getXMiddle() > 200) ||
            (player.getXMiddle() > 200 && ball.getXMiddle() < 200)))
        {
            //guess the possible ball position at height "calcHeight"
            targetPos = (int)(ball.getXMiddle() +
                             (calcHeight - ball.getY()) /
                             (ball.getYSpeed() <= 0 ? 1 : ball.getYSpeed()) *
                              ball.getXSpeed());
            
            targetPos = (targetPos < -calcHeight / 2 ? 100 :
                        (targetPos > 400 + calcHeight / 2 ? 300 :
                         targetPos));
            //make it a little bit random!!
            targetPos = (int)(targetPos + 1.5*posToBall +
                        randomDiff*Math.random() - randomDiff);
        }

        else
        {
            //Ball hinterher rennen
            targetPos = (int) (ball.getXMiddle() + posToBall);
        }

        //jump-control
        //ball retten!
        if((player.getXMiddle() < 200 && ball.getXSpeed() < 2
           && player.getXMiddle() > ball.getXMiddle() && ball.getY() < 170) ||
               (player.getXMiddle() > 200 && ball.getXSpeed() > -2
               && player.getXMiddle() < ball.getXMiddle() && ball.getY() < 170))
        {
            jump = false;
        }

        //perform move
        player.setDirection(player.getXMiddle() < targetPos - 2 ? 1 :
                           (player.getXMiddle() > targetPos + 2 ? -1 : 0));

        return jump;
	}
```

posToBall: Abstand zum Ball einmal auf rechtem und dann auf linkem Feld.
randomDiff: In welchem (Pixel-)Rahmen soll sich der Spieler etwas zufällig hin und her bewegen.
jumpHeigth: Ab welcher y-Höhe soll der Spieler überhaupt springen. Wenn y-Ball < jumpHeight spring einfach net...
calcHeigh: Bis zu welcher y-Höhe soll die Position des Balles "berechnet" werden (ist keine Punktgenaue Berechnung sondern ein guter "Schätzwert"). Wenn Ball niedriger (also y-Ball > calcHeight) fliegt, laufe immer hinterher.
targetPos: Gibt immer die Zielposition des Spielers an. Der Anfangswert ist eigentlich unerheblich, da der Wert immer neu berechnet wird.

Also wen es interessiert... büdde 

[edit] FROHES NEUES!!!


----------



## Apo (15. Jan 2007)

ich sammele gerade alle (halbwegs guten) Spieler ein. Es gibt aber nur recht wenige die Simply immer schlagen.  Also so schlecht kann er nicht sein.
Wenn ich Sie alle habe, dann stelle ich Sie mal alle guten online (kann aber nicht versprechen, dass immer der Source-Code dabei ist ... manche Studenten wollen das nicht)
Wenn es soweit ist, melde ich mich nochmal und sage bescheid.


----------



## WrecKer (15. Jan 2007)

Hi, ich möchte hier einfach mal unsere KI posten(2 Leute, viele Stunden Arbeit^^), da in den Tutorien das "Kräftemessen" und Auswerten der Abreiten irgendwie zu kurz kam (die meisten hatten easy_KI in nen par Zeilen abgeändert). Spielt vll. mal gegen die KI und berichtet vom Resultat.

also viel Spaß damit, bei Bedarf gibts auch noch den Code dazu... 

achja ich wollte nur noch einmal betonen, dass keine einizge Zeile aus anderen KI´s genommen wurde, (man könnte aufgrund der spielweise auf Apo´s KI schließen ) 

Hier der Link:
BeatUs.class


----------



## Apo (15. Jan 2007)

oh auf der einen Seite hat Apo wunderprächtig mit 25 zu 4 gewonnen
Auf der anderen Seite kam der Fehler das der Ball auf dem Netz liegen blieb ... den hatte ich gar nicht mehr bedacht (war aber auch besser so, weil nunja der Apo lag 23 zu 17 hinten *g* )
Wenn ich genügend Spieler noch bekomme, dann entferne ich diesen Fehler noch und lasse sie alle gegeneinander antreten und werde dann eine Site mit den Auswertungen machen und kurz hier reinstellen. 
€dit: habe jetzt einfach mal eine neue Version on gestellt, die keine Fehler mehr haben müsste 

In meinem Tutorium gab es jemanden, den MatzeWalter Spieler der jetzt auch dabei ist, der den Spieler Apo fast immer zu 0 fertig gemacht. Sowas ist nicht fein 
Der Wettbewerbscharakter hat in den anderen Tutorien leider wirklich gefehlt, aber jetzt beim schafigen Programmierwettbewerb wird das besser. Falls hier jemand Lust aus dem Forum hat. Ab 1.2. könnt ihr euch gegen die Studenten in einem schafigen Contest messen. Und diesmal auch mit extra Site und ordentlicher Auswertung aller eingeschickten "Hunde".


Ok genug Werbung, falls wer noch einen Tutorvolleyspieler hat, bitte an mich schicken, damit das Tunier endlich beginnen kann.


----------



## Wrecker (20. Jan 2007)

hi, also ich habe jetzt die rechte Seite so angepasst, dass sie dort jetzt auch halbwegs passabel spielt. (das sowas wie gegen apo nich nochmal passiert )

also nochmal der link: BeatUs.class


----------

