Spielfelder auch über die Tastatureingabe (1…9) ansteuern (Tic Tac Toe)

josef333

Neues Mitglied
Hallo zusammen, ich habe ein Tic Tac Toe Spiel programmiert, das mit dem Maus gespielt wird. Ich möchte aber neben der Maus auch über die Tastatureingabe die Spielfelder ansteuern, z.B bei Eingabe von '7' wird die linke obere Ecke vom Spielfeld gekreuzt.

Das ist mein Buttonplacement Klasse:
Java:
package tic_tac_toe;


public class buttonplacement {
  
    public static void place()
    {
        GUI.btn[0].setBounds(175,50,150,150);
        GUI.btn[1].setBounds(325,50,150,150);
        GUI.btn[2].setBounds(475,50,150,150);
      
        GUI.btn[3].setBounds(175,200,150,150);
        GUI.btn[4].setBounds(325,200,150,150);
        GUI.btn[5].setBounds(475,200,150,150);;
      
        GUI.btn[6].setBounds(175,350,150,150);
        GUI.btn[7].setBounds(325,350,150,150);
        GUI.btn[8].setBounds(475,350,150,150);
    }
  
}

GUI Klasse:
Java:
package tic_tac_toe;

import java.awt.Color;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JFrame;

public class GUI {
  
    JFrame jf ;
    Draw draw ;
    JButton  btnreset ;
  

   static JButton btn[] = new JButton[9];
   static int state[]= new int[9];
   static int player = 0 ;
   static int gwinner = 0 ;
   public GUI()
    {
        jf = new JFrame();
        jf.setSize(800, 600);
        jf.setLocationRelativeTo(null);
        jf.setResizable(false);
        jf.setTitle("tic tac toe");
      
        for (int i=0; i<btn.length; i++)
        {
            btn[i]= new JButton();
            btn[i].setVisible(true);
            btn[i].addActionListener(new actionshandler());
            btn[i].setFocusPainted(false);
            btn[i].setContentAreaFilled(false);
            btn[i].setBorder(null);
            jf.add(btn[i]);
        }
      
        buttonplacement.place();
      
      
        btnreset = new JButton("Play again");
        btnreset.setBounds(675,300,100,40);
        btnreset.setVisible(true);
        btnreset.setBackground(new Color(51,102,153));
        btnreset.setForeground(Color.white);
        btnreset.setFocusPainted(false);
        btnreset.addActionListener(new ActionListener(){
            @Override
            public void actionPerformed(ActionEvent ae) {
                funktion.reset();
            }
          
        });
  
        jf.add(btnreset);
        draw = new Draw () ;
        draw.setBounds(0, 0, 800, 600);
        draw.setVisible(true);
        jf.add(draw);
      
      
        jf.setVisible(true);
    
    }
  
  
  
}

Actionhandler Klasse:

Java:
package tic_tac_toe;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.Random;

public class actionshandler implements ActionListener {

    @Override
    public void actionPerformed(ActionEvent ae) {
         int mode = Tic_tac_toe.mode;
     if (mode == 1)
     {
        if(GUI.gwinner == 0){
            if(ae.getSource() == GUI.btn[0])
            {
                if(GUI.state[0]==0 && GUI.player==0){
                    GUI.state[0]=1;
                    GUI.player=1;
                    
                }else if(GUI.state[0]==0 && GUI.player==1){
                    GUI.state[0]=2;
                    GUI.player=0;
                }
            }else if (ae.getSource() == GUI.btn[1])
            {
                if(GUI.state[1]==0 && GUI.player==0){
                    GUI.state[1]=1;
                    GUI.player=1;
                    
                }else if(GUI.state[1]==0 && GUI.player==1){
                    GUI.state[1]=2;
                    GUI.player=0;
                    }
        
            }
           else if (ae.getSource() == GUI.btn[2])
            {
                if(GUI.state[2]==0 && GUI.player==0){
                    GUI.state[2]=1;
                    GUI.player=1;
                    
                }else if(GUI.state[2]==0 && GUI.player==1){
                    GUI.state[2]=2;
                    GUI.player=0;
                    }
        
            }
            else if (ae.getSource() == GUI.btn[3])
            {
                if(GUI.state[3]==0 && GUI.player==0){
                    GUI.state[3]=1;
                    GUI.player=1;
                    
                }else if(GUI.state[3]==0 && GUI.player==1){
                    GUI.state[3]=2;
                    GUI.player=0;
                    }
        
            }
            else if (ae.getSource() == GUI.btn[4])
            {
                if(GUI.state[4]==0 && GUI.player==0){
                    GUI.state[4]=1;
                    GUI.player=1;
                    
                }else if(GUI.state[4]==0 && GUI.player==1){
                    GUI.state[4]=2;
                    GUI.player=0;
                    }
        
            }
            else if (ae.getSource() == GUI.btn[5])
            {
                if(GUI.state[5]==0 && GUI.player==0){
                    GUI.state[5]=1;
                    GUI.player=1;
                    
                }else if(GUI.state[5]==0 && GUI.player==1){
                    GUI.state[5]=2;
                    GUI.player=0;
                    }
        
            }
            else if (ae.getSource() == GUI.btn[6])
            {
                if(GUI.state[6]==0 && GUI.player==0){
                    GUI.state[6]=1;
                    GUI.player=1;
                    
                }else if(GUI.state[6]==0 && GUI.player==1){
                    GUI.state[6]=2;
                    GUI.player=0;
                    }
        
            }
            else if (ae.getSource() == GUI.btn[7])
            {
                if(GUI.state[7]==0 && GUI.player==0){
                    GUI.state[7]=1;
                    GUI.player=1;
                    
                }else if(GUI.state[7]==0 && GUI.player==1){
                    GUI.state[7]=2;
                    GUI.player=0;
                    }
        
            }
            else if (ae.getSource() == GUI.btn[8])
            {
                if(GUI.state[8]==0 && GUI.player==0){
                    GUI.state[8]=1;
                    GUI.player=1;
                    
                }else if(GUI.state[8]==0 && GUI.player==1){
                    GUI.state[8]=2;
                    GUI.player=0;
                    }
        }
     }
            }

Vielen Dank!

bild.png
 
Da könntest Du einen KeyListener für verwenden, den Du dann den Componenten, die den Focus haben können, zuordnest.

Und den Code kannst Du deutlich vereinfachen:

a) Du hast viele Blöcke, die so aussehen:
Java:
if(ae.getSource() == GUI.btn[0])
            {
                if(GUI.state[0]==0 && GUI.player==0){
                    GUI.state[0]=1;
                    GUI.player=1;
                  
                }else if(GUI.state[0]==0 && GUI.player==1){
                    GUI.state[0]=2;
                    GUI.player=0;
                }
            }
Und das dann 9 mal. Das kann man optimieren über eine Schleife (Ansatz 1). Also einfach eine schleife von 0-9 drüber laufen lassen mit dem Inhalt wie gehabt.

Die Alternative könnte aber auch sein, dass man die Zuweisung heraus nimmt. Du hast dann nur etwas wie:
- Index bekommen
- Dann umsetzen.

b) Du hast da immer dieses if/else:
Java:
                if(GUI.state[0]==0 && GUI.player==0){
                    GUI.state[0]=1;
                    GUI.player=1;
                }else if(GUI.state[0]==0 && GUI.player==1){
                    GUI.state[0]=2;
                    GUI.player=0;
                }
Wenn GUI.player immer nur 0 oder 1 sein kann, dann wäre das GUI.state[0] immer GUI.player+1.
Und der Wechsel wäre dann auch über ein ähnliches Konstrukt denkbar.

Generell gilt aber auch:
- Sieh zu, dass Du das static los wirst. Du hast ja eine Instanz von GUI und in der bewegst Du Dich. Damit hättest Du dann nur noch player. statt GUI.player. (Und du könntest ohne Static auch mehrere GUI Instanzen haben ...).
- Evtl. weiter unterteilen und ggf. eigene Klassen / Typen erzeugen. Also z.B. ein enum Player { NONE; PLAYER_ONE, PLAYER_TWO), das dann benutzt werden kann. Und das hätte dann auch eine Methode next() oder so. Dann würde so Code oben einfach sein:

Java:
                if(state[i]==Player.NONE) {
                    state[i]=player;
                    player=player.next();
                }
(Wenn man also das gewählte Feld identifiziert hat .. Das wäre aber dann auch eine eigenständige Methode, denn die brauchst du dann jan icht nur beim click sondern auch bei der Eingabe über Tastatur.

Edit: Ich habe natürlich vergessen zu erwähnen: Der separate ActionHandler würde da dann auch entfallen. Das wandert dann mit in die Klasse GUI. Anders wäre ja auch der Zugriff nicht möglich auf die Instanzvariablen....
 

Zurück
Oben