• Herzlich Willkommen!

    Nach der Schließung von inDiablo.de wurden die Inhalte und eure Accounts in dieses Forum konvertiert. Ihr könnt euch hier mit eurem alten Account weiterhin einloggen, müsst euch dafür allerdings über die "Passwort vergessen" Funktion ein neues Passwort setzen lassen.

    Solltet ihr keinen Zugriff mehr auf die mit eurem Account verknüpfte Emailadresse haben, so könnt ihr euch unter Angabe eures Accountnamens, eurer alten Emailadresse sowie eurer gewünschten neuen Emailadresse an einen Administrator wenden.

Hilfe bei Javaprogrammieren !=

Registriert
31 Dezember 2007
Beiträge
237
Punkte Reaktionen
0
Hallo liebe Community

Kommen wir gleich zum Geschäft:
Ich habe die Aufgabe erhalten ein 4-Gewinnt Spiel im Java-Editor zu programmieren.
Da ich aber nicht ganz so gut damit umgehen kann könnte ich etwas hilfe gut gebrauchen...
Also das spiel soll einer KI(künstliche Intelligenz) ausgestattet sein und eben strategisch vorgehen... das wäre der sozusagen hauptpunkt den ich erledigen müsste.
Dann habe ich noch ein paar kleine Problemchen wie z.B.:
Ich brauche den "wait" befehl, aber irgendwie geht das nicht.
Also ich habe das Spielfeld in 42 jPanels unterteilt (7x6)
und über den jPanels 7 jButtons gemacht, jeweils einer über eine Rheie von panels. ich wollte erstmal damit anfangen das man, wenn man auf einen der buttons klickt, der erste panel darunter seine farbe ändert, und diese dann an den panel darunter "weitergibt" also so als würde der stein fallen... ich habe die panels so benannt:

(7 buttons _ _ _ _ _ _ _)
a1 b1 c1... ...g1
a2 b2 ... ... g2
a3 b3 ... ... g3
a4 b4 ... ... g4
a5 b5 ... ... g5
a6 b6 ... ... g6

nun sollte (wenn man auf den ersten button drückt) a1 kurz gelb werden, dann wieder schwarz und a2 gelb, der dann auch wider schwarz und a3 gelb usw. bis man auf den letzten "a"-panel kommt.

hier mal den programmcode:

public void jButton1_ActionPerformed(ActionEvent evt) {

a1.setBackground(Color.YELLOW);
//...
wait(50);
//...
a1.setBackground(Color.BLACK);
//...
}

und naja... genau der wait befehl macht mir etwas zu schaffen xD kann man mir da kruz sagen wie das nochmal ging? ich wäre euch sehr dankbar :)

achja da kommt mir die frage: kann man (den fall der steine zum boden [über die panels]) auch mit einer schleife machen, die einfach den panelwert hochzählt? und wenn ja wie geht das?
 
Zuletzt bearbeitet:
1. lern googlen! bei einfachen dingen, jetzt kommst du noch damit weiter in foren zu fragen - später bist du verloren.
2. sleep != wait, verrät dir google innerhalb von 10sekunden, das was du suchst ist sleep. jedoch benötigt sleep grundverständniss über threads, damit solltest du dann anfangen. geht auch ohne (ebenfalls google, 10sec):

public static void wait (int n){
long t0,t1;
t0=System.currentTimeMillis();
do{
t1=System.currentTimeMillis();
}
while (t1-t0<1000);
}

deine schleife ist total billig:
actionevent bla(evt){
for (int i = 0; i < 7; i++){
ai.setBackground(Color.BLACK);
ai+1.setBackground(YELLOW);
}
}

in grundzügen. die schleife pimpst du jetzt nochn bisserl auf, denn die macht beim ersten durchgang nicht das was sie soll - aber da ist nu selber denken angesagt.
 
:hy:

ein Klassenkamerad hat das in der 13. mal programmiert. Mit ner recht guten KI auch ;)
Ist auf jeden Fall nicht gerade SO einfach, das Programm mit der KI zu machen.

Ich schreib dir dann ne PN, falls ich von den beiden die Erlaubnis bekomm, ihre Email bzw das Programm weiter zu leiten. ;) Davor mach ich leider nix.

Ansonsten hast du einiges an Arbeit vor dir, so einfach wie mit paar Buttons wird das nix.

Würde die Buttons in mehrdimensionale Arrays schreiben ( [7][4]) die per Schleife dort per Referenz(?) ( verweiß der Speicheradresse oder so ^^ ) speichern und dann von dort zu greifen.
Aber das ist bei mir auch schon ein gutes Jahr her ;) Und hab mich ja damit nie beschäftigt.

mfg
 
Typischer Fehler von Multithreading so wie es aussieht.
Wenn ich das Problem richtig fasse, liegt es daran, dass sich wait() nur auf den aktuellen Thread (der mit deinem Programcode) auswirkt, die Bildschirmaktion allerdings von einem weiteren Thread im Hintergrund (irgendwas wie ein AWT-Render) erledigt wird. Wann der Bildschirm neu gezeichnet wird, überlegt dieser sich selbst. In deinem Fall vermutlich zu spät.

Möglich wäre ein Anforderung zum neuzeichnen mit repaint(). wait(50) ist übrigens an der Grenze der Wahrnehmungsschwelle (1/20 Sekunde).Vielleicht liegt es auch daran. Outdatet, siehe unten

TenthManDowns Vorschlag die Elemente als 2D-Array zu speichern kann ich mich im übrigen von anschließen. Alles andere ist murks^3.

Nachtrag: repaint() kann nicht klappen, wenn es über ein ActionListener ausgeführt wird.
Was aber klappt ist folgendes
Code:
public void jButton1_ActionPerformed(ActionEvent evt) {
	new Thread(new Runnable(){
		@Override
		public void run() {
			a1.setBackground(Color.RED);
			try {
				Thread.sleep(1000l);
			} catch (InterruptedException e) {}
			a1.setBackground(Color.BLUE);
		}
	}).start();
}
 
Zuletzt bearbeitet:
Ehrlich gesagt würde ich auf deinem Stand der Kenntnisse komplett die Finger von Threads lassen. Außerdem geht es ja wohl eher um die Strategie, nicht um irgendwelche Grafikspielereien. 4-Gewinnt ist ursprünglich ein Spiel, dass man mit Zettel und Stift spielt und genau das würde ich auch implementieren. Grafische Spielereien sind nur Gimmicks, ich glaube kaum, dass dies Bestandteil der Aufgabe ist.

KI heißt nichts weiter, als dass das Spiel versucht, auf bestimmte Situationen logisch zu reagieren und im Idealfall sogar mehrere mögliche Reaktionen kennt und davon eine bevorzugt. Also ist die erste Aufgabe, die verschiedenen Situationen des Spiels zu erfassen und eine passende Reaktion darauf zu kennen. Z.B. muss das Spiel erkennen, dass zwei gleichfarbige Steine nebeneinander eine gute Chance für den Besitzer sind, wenn der Gegner nicht darauf reagiert.

Und so sollte man die Spielsituationen analysieren und zumindest eine Reaktion pro Situation definieren, die das Programm auführen soll. Und dann macht man sich Gedanken darüber, wie diese Reaktion in Programmiercode aussehen muss.

Das meiste davon kann man übrigens per Google leicht herausfinden.
 
danke für die antworten :kiss:
das mit dem 2Dimensonalen array klingt logisch...
aber wie mach ich das dann? für spielfeld[7][6] hab ich dann noch überlegt ob es gehen würde dann doch ein dreidimensionales zu machen: spielfeld[x][y]["feldbelegt"]
im letzten kommt dann der wert 0 bis 2 rein (0=kein stein; 1 un 2 = steine von player 1 oder 2)
ich hab ein freund gefragt, der das besser kennt als ich, aber irgendwie hat ers doch nicht verstanden ;)

die KI soll eigentlich nicht unbedingt ne KI sein, (wenn dann eine sehr primitive) sondern eher eine gute Strategie nach der das programm handelt.
Und das geht dann (denk ich mal) am besten mit der 3D-Array variante oder?

PS: sorry für mein etwas stümperhaftes wissen übre java, aber ich lern das erst seit nem halben jahr ^^ deswegen frage ich ja hier
 
Hallo, dafür brauchst du nur zwei Dimensionen. Du kannst ja dem Array[x][y] dann einfach die Werte 0, 1 oder 2 zuweisen.
 
ja, sowas hab ich mir vorgestellt... wie geht das dann?
ich hab den ansatz so gemacht, aber ich weis nicht ob es so stimmt, und wie ich dann weitermachen soll^^

public class spielfeld{
public static void main(String [] args){
int spielbrett[][]=new int[7][6];

wenn das was hilft, kann ich den gesammten programmcode vom spielfeld posten... is aber ziehmlich viel :eek:

€: @tenthmandown: das spiel, das du da hast, hat das bei dir auch 30 klassen mit networklistener und der gleichen?
weil da kann ich wirklich nichts überblicken, ich muss es ganz simpel gestalten mit 3-4 klassen ^^
 
ja, sowas hab ich mir
public class spielfeld{
public static void main(String [] args){
int spielbrett[][]=new int[7][6];

Also das Spielfeld-Array in main() zu definieren ist ziemlicher Mist. Damit ist diese sowohl statisch als auch von aussen nicht sichtbar. Man kann somit eigentlich nichts damit anfangen.
Eine saubere Möglichkeit ist die Initialisierung des Spielfelds im Konstruktor der Klasse Spielfeld. Das so erzeugte Spielfeld-Objekt wird dann der Spiellogik zur Verfügung gestellt. Noch besser als das Spielfeld als int-Array zu verwalten, wäre die Definition einer passendenden Enumeration.

private enum FeldZustand {LEER, ROT, GELB};
und einem Array
FeldZustand spielfeld[][] = new Feldzustand[7][6]

Aber ich vermute dies geht weit über deinen derzeitigen Stand hinaus. Die Lektüre eines passenden Buches über Javaprogrammierung wäre vermutlich sinnvoll. Ganz brauchbar ist sicherlich Java ist auch eine Insel

Nochmal edit
public class spielfeld{
Klassen beginnen nach Konvention in Java mit einem Grossbuchstaben, zumindest in Sprachräumen mit lateinischen Zeichensätzen.
Mit welchem Java-Editor (gemäß deines ersten Posts) arbeitest du? Wenn ich solche Kleinigkeiten ignoriere, haut mir Eclipse massenhaft Warnings und sonstige Meckereien um die Ohren.
Im Prinzip ist es völlig egal wie man seine Klassen nennt. Wenn man aber länger dabei ist, dann merkt man den Sinn von solchen Konventionen. Von daher kann ich nur dazu raten, so früh wie möglich damit anzufangen.
 
Zuletzt bearbeitet:
€: @tenthmandown: das spiel, das du da hast, hat das bei dir auch 30 klassen mit networklistener und der gleichen?
weil da kann ich wirklich nichts überblicken, ich muss es ganz simpel gestalten mit 3-4 klassen ^^

Die 2 Jungs haben das anhand diese Beispiels halt hochgezogen ;).

Die Idee extra Klassen für das Spielfeld und die Spieler zu machen ist vllt gar nicht so schlecht.
So kann man später auch viel einfacher erweitern ^^
 
Na und jetzt füllst du dein Spielfeld eben auf:
spielbrett[x][y]=z, wobei z halt entweder für Spieler 1, oder für Spieler 2, oder für gar nix steht. Soweit das Prinzip. Und dann überlegste dir, unter welchen Bedingungen wo welche Zahlen reinkommen. Aber das ist jetzt wirklich genug geholfen. ;)
 
Was ich zur KI raten kann:
Erstell noch so etwas wie ein Eröffnungsbuch, wie man es beispielsweise von Schachengines kennt.
Bei den ersten paar Zügen hat das Programm quasi auswendig gelernt, wie es auf welchen Zug antworten soll. So etwas erhöht die Spielstärke immens. Beispielsweise bei der Broodforce Methode; wenn anstatt von 100000 nur noch 1000 (nach ~5 festen Zügen beispielsweise) Möglichkeiten übrig sind, welche durchgerechnet werden müssen geht dass ganze um einiges effektiver/schneller.

Zum Spielspaß würde ich es so machen:
Die ersten 1/2 Züge zufällige auswählen (Beispiel: 50% Chanche für 'in die Mitte', 30% für eins daneben, ... ;damit abwechslung beim Spielen herrscht), dann anschließend 2-3 Top Züge (passender Schwierigkeitsgrad vorrausgesetzt).
Hier gabs denke ich ein paar Links zum "perfekten Spiel".
Wenn dir das nicht klappt kannst du dir auch mit dem Programm "perfekte" Züge ausrechen. Solange auf Infinite rechnen lassen, bis er zieht (so hab ichs zumindest in Erinnerung).
Viel Glück bei dem Projekt :hy:

Edit:
Ich kann dir doch noch direkt diesen Link ans Herz legen.
 
Zuletzt bearbeitet:
danke an alle^^
ich hab es jetzt schon sogut wie fertig...
nur noch die Strategie fehlt^^ und die "fallanimation der spielsteine" ... da könntet ihr ein paar tipps geben, wegen dem Thread.sleep, ich hab das nähmlich damit gemacht, und ... geht nich^^
 
wegen dem Thread.sleep, ich hab das nähmlich damit gemacht, und ... geht nich^^

Hast du dir mein Beispiel genauer angesehen? Damit sollte es wunderbar klappen. Da ich heute meinen extrem altruistischen Tag habe, poste ich dir sogar ein komplett lauffähiges Beispielprogramm. Den Rest solltest du dann hoffentlich selbst hinkriegen. Wichtig ist es sich von der AWT-EventQueue (ganz grob läuft dort alles ab, was mit der GUI zu tun hat) mit einem zweiten Tread zu trennen und dort die Animation zu kontrollieren. Einfach nur Thread.sleep() lässt nur den AWT-Thread einschlafen. Da dieser gleichzeitig auch das Zeichnen steuert, klappt eine Animation so nicht.

Code:
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;

public class Animation extends JFrame{
	JButton jButton1 = new JButton("Start"); 
	JPanel panels[] = new JPanel[8];
	
	public Animation() {
		this.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
		this.getContentPane().setLayout(new GridLayout(9,1));
		
		for (int i=0; i<8;i++){		//Init Panels
			panels[i] = new JPanel();
			panels[i].setBackground(Color.GRAY);
			this.getContentPane().add(panels[i]);
		}
		this.getContentPane().add(jButton1);
		
		jButton1.addActionListener(new ActionListener(){
			@Override
			public void actionPerformed(ActionEvent arg0) {	
				new Thread(new Runnable(){ //Animation im Thread
					@Override
					public void run() {
						for (int i=0;i<8;i++){
							panels[i].setBackground(Color.GREEN);
							try { Thread.sleep(500l); } catch (InterruptedException e) {}
							panels[i].setBackground(Color.GRAY);
						}
					}
				}).start();
			}
		});
		this.pack();
		this.setVisible(true);
	}
	
	public static void main(String[] args){
		new Animation();
	}
}
 
Zurück
Oben