Kółko i krzyżyk - komputerowy przeciwnik

0

Cześć, próbuję napisać wirtualnego przeciwnika do gry Kołko i krzyżyk.
Próbowałem robić to w ten sposób:

runda++;
		 
		 switch(runda){
		 case 1:
			 litera = "X";
			 if(buttons[1].getText() == ""){
				
		        	buttons[1].setText("O");
		        	buttons[1].setEnabled(false);
		        	break;
		        }else if(buttons[2].getText() == ""){
		        	
		        	buttons[2].setText("O");
		        	buttons[2].setEnabled(false);
		        	break;
		        }else if(buttons[3].getText() == ""){
		        
		        	buttons[3].setText("O");
		        	buttons[3].setEnabled(false);
		        	break;
		        }else if(buttons[4].getText() == ""){
		        
		        	buttons[4].setText("O");
		        	buttons[4].setEnabled(false);
		        	break;
		        }
		        else if(buttons[5].getText() == ""){
		       
		        	buttons[5].setText("O");
		        	buttons[5].setEnabled(false);
		        	break;
		        }
		        else if(buttons[6].getText() == ""){
		        	
		        	buttons[6].setText("O");
		        	buttons[6].setEnabled(false);
		        	break;
		        }
		        else if(buttons[7].getText() == ""){
		        	
		        	buttons[7].setText("O");
		        	buttons[7].setEnabled(false);
		        	break;
		        }else if(buttons[8].getText() == ""){
		        	
		        	buttons[8].setText("O");
		        	buttons[8].setEnabled(false);
		        	break;
		        }else if(buttons[9].getText() == ""){
		        	
		        	buttons[9].setText("O");
		        	buttons[9].setEnabled(false);
		        	break;
		        }

(buttony to kolejne pole w siatce 3x3)
Gdy zaznaczę pierwsze wolne miejsce to komputer nie narysuje nic, a powinien (?) zaznaczyć drugie pole. Tak samo będzie, gdy zrobię to w kolejnej rundzie. I kolejnej. Każdy ruch będzie mój, a komputer zostanie pominięty (mimo, że nie został, jednak nie widać jego działania).
jakieś pomysły jak to rozwiązać?

0

Po pierwsze - prawdopodobnie nie trafia do tego case 1:
Po drugie - czemu nie tak:
Po trzecie - czy jest break po wszystkich if'ach?
runda++;

             switch(runda){
             case 1:
                     litera = "X";
                     for(int i=0;i<9;++i)
                       {
                        if(buttons[i].getText() == ""){
                            buttons[i].setText("O");
                            buttons[i].setEnabled(false);
                            break;
                        }
                    }
             break;
0
_13th_Dragon napisał(a):

Po pierwsze - prawdopodobnie nie trafia do tego case 1:
Po drugie - czemu nie tak:
Po trzecie - czy jest break po wszystkich if'ach?
runda++;

             switch(runda){
             case 1:
                     litera = "X";
                     for(int i=0;i<9;++i)
                       {
                        if(buttons[i].getText() == ""){
                            buttons[i].setText("O");
                            buttons[i].setEnabled(false);
                            break;
                        }
                    }
             break;

Dlatego:

Exception in thread "AWT-EventQueue-0" java.lang.NullPointerException
at kolkoiKrzyzyk.KolkoiKrzyzykKomp.actionPerformed(KolkoiKrzyzyk.java:299)
at javax.swing.AbstractButton.fireActionPerformed(Unknown Source)
at javax.swing.AbstractButton$Handler.actionPerformed(Unknown Source)
at javax.swing.DefaultButtonModel.fireActionPerformed(Unknown Source)
at javax.swing.DefaultButtonModel.setPressed(Unknown Source)
at javax.swing.plaf.basic.BasicButtonListener.mouseReleased(Unknown Source)
at java.awt.Component.processMouseEvent(Unknown Source)
at javax.swing.JComponent.processMouseEvent(Unknown Source)
at java.awt.Component.processEvent(Unknown Source)
at java.awt.Container.processEvent(Unknown Source)
at java.awt.Component.dispatchEventImpl(Unknown Source)
at java.awt.Container.dispatchEventImpl(Unknown Source)
at java.awt.Component.dispatchEvent(Unknown Source)
at java.awt.LightweightDispatcher.retargetMouseEvent(Unknown Source)
at java.awt.LightweightDispatcher.processMouseEvent(Unknown Source)
at java.awt.LightweightDispatcher.dispatchEvent(Unknown Source)
at java.awt.Container.dispatchEventImpl(Unknown Source)
at java.awt.Window.dispatchEventImpl(Unknown Source)
at java.awt.Component.dispatchEvent(Unknown Source)
at java.awt.EventQueue.dispatchEventImpl(Unknown Source)
at java.awt.EventQueue.access$000(Unknown Source)
at java.awt.EventQueue$3.run(Unknown Source)
at java.awt.EventQueue$3.run(Unknown Source)
at java.security.AccessController.doPrivileged(Native Method)
at java.security.ProtectionDomain$1.doIntersectionPrivilege(Unknown Source)
at java.security.ProtectionDomain$1.doIntersectionPrivilege(Unknown Source)
at java.awt.EventQueue$4.run(Unknown Source)
at java.awt.EventQueue$4.run(Unknown Source)
at java.security.AccessController.doPrivileged(Native Method)
at java.security.ProtectionDomain$1.doIntersectionPrivilege(Unknown Source)
at java.awt.EventQueue.dispatchEvent(Unknown Source)
at java.awt.EventDispatchThread.pumpOneEventForFilters(Unknown Source)
at java.awt.EventDispatchThread.pumpEventsForFilter(Unknown Source)
at java.awt.EventDispatchThread.pumpEventsForHierarchy(Unknown Source)
at java.awt.EventDispatchThread.pumpEvents(Unknown Source)
at java.awt.EventDispatchThread.pumpEvents(Unknown Source)
at java.awt.EventDispatchThread.run(Unknown Source)

Nie używam wątków, tworzenie buttonków w konstruktorze mam zapętlone tak jak ty podałeś, jednak dalej w kodzie już nie mogłem.

0

Więc niepoprawnie tworzysz.

0

Fakt, poprawiłem, zapętliłem tak jak mówiłeś:

		 runda++;
		 switch(runda){
		 case 1:
             litera = "X";
             for(int i=0;i<9;++i)
               {
                if(buttons[i].getText() == ""){
                    buttons[i].setText("O");
                    buttons[i].setEnabled(false);
                    break;
                }
            }
     break; 

jednak nic sie nie zmieniło.

0

Pewnie na początku masz runda=1, przed switchem masz runda++ wiec na wejściu w to miejsce runda powinna wynosić 0. Ewentualnie button ma inna wartość niż "".

0

Po litera = "X"; wstaw wyświetlenie komunikatu "weszło do case 1", jeżeli komunikat się pojawi to pokazuj jak tworzysz tablicę buttons. Jeżeli się nie pojawi, postaw wyświetlenie komunikatu przed switch z wyświetleniem wartości runda.

Komunikat się pojawia, numer rundy po po pierwszym kliknięciu to 1.

JButton buttons[] = new JButton[10];
int runda=0;
//tak wypełniam buttonki, wstawiam na okno i przysłuchuje im się:
 for(int i = 1; i<=9; i++){
		        buttons[i] = new JButton();
		        okno.getContentPane().add(buttons[i]);
		        buttons[i].addActionListener(this);
		    }

Pewnie na początku masz runda=1, przed switchem masz runda++ wiec na wejściu w to miejsce runda powinna wynosić 0. Ewentualnie button ma inna wartość niż ""

runda jest wyzerowana, wartość buttonka sprawdziłem przed pętlą w case 1:

zc.showMessageDialog(null, buttons[1].getText());

jest pusty.

0

Przyjrzyj się tym fragmentom:

 for(int i = 1; i<=9; i++){
                        buttons[i] = new JButton();
 ...
 for(int i=0;i<9;++i){
                if(buttons[i].getText() == "")

i wyciągnij wnioski. Co się stanie w drugiej pętli dla i==0?

0

Sprobuj raczej skorzystac z algorytmu np. minmax. Do tego typu gier nadaje sie idealnie jako "AI".

0
bogdans napisał(a):

Przyjrzy się tym fragmentom:

 for(int i = 1; i<=9; i++){
                        buttons[i] = new JButton();
 ...
 for(int i=0;i<9;++i){
                if(buttons[i].getText() == "")

i wyciągnij wnioski. Co się stanie w drugiej pętli dla i==0?

Poprawiłem, wstawiłem msgBoxa z pokazaniem wartości każdego buttona, gdy w pierwszym moim ruchu klikam pierwsze pole, to komputer nie postawi w innym, ale w tym samym, jednak tego nie widać.

0

Poprawiłeś, tzn. co zrobiłeś? Błędny jest ten fragment:

 for(int i = 1; i<=9; i++){
      buttons[i] = new JButton();
0

Już wiem co było źle, nie dałem całego kodu i wprowadziłem zamęt ;)
Blok switch zmieniłem na:

 for(int i = 0; i<10; i++){
	            if(a.getSource() == buttons[i]){
	                buttons[i].setText("X");
	                buttons[i].setEnabled(false);
	            }
	        }
	        
	        runda++;      
	        komputer();

W funkcji komputer umieściłem:

 public void komputer(){
        	runda++;
        	   for(int i=0;i<9;i++)
               {

                if(buttons[i].getText() == "" || buttons[i].getText() == null || buttons[i].getText().equals(null) || buttons[i].getText().equals("")){ //tak, zbędne powtarzanie, //ale szukałem wszędzie błędu
  
                    buttons[i].setText("O");
                    buttons[i].setEnabled(false);
                    break;
                }
            }
        	
        }

A co przyprawiło tyle kłopotu? Blok ifów pod switchem. Jak?
case 1 zmieniało wartość litera na X, dalej była pętla for z zmianą danego pola na O, ale to pole było jeszcze puste, bo zmiana pola gracza była po zmianie przez komputer.
Zawile, więc łatwiej:
litera na X -> stawienie O na polu -> nadpisanie pola przez X

A tutaj tutaj cała klasa gry z komputerem:

class KolkoiKrzyzykKomp implements ActionListener {
	JButton buttons[] = new JButton[10];
	int runda=0;
	String litera="";
	boolean wygrana=false;
	/**
	 * @wbp.parser.entryPoint
	 */
	KolkoiKrzyzykKomp(){
		JFrame okno = new JFrame();
		okno.setBounds(10, 10, 185, 200);
		okno.setTitle("LOL");
		okno.setVisible(true);
		okno.getContentPane().setLayout(new GridLayout(3,3));
		
	
		  for(int i = 0; i<9; i++){
		        buttons[i] = new JButton();
		        okno.getContentPane().add(buttons[i]);
		        buttons[i].addActionListener(this);
		    }
	    okno.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		
	}

	 public void actionPerformed(ActionEvent a) {
		  /*Write the letter to the button and deactivate it*/
	        for(int i = 0; i<10; i++){
	            if(a.getSource() == buttons[i]){
	                buttons[i].setText("X");
	                buttons[i].setEnabled(false);
	            }
	        }
	        
	        runda++;      
	        komputer();
	        if( buttons[0].getText() == buttons[1].getText() && buttons[1].getText() == buttons[2].getText() && buttons[0].getText() != ""){
				 JOptionPane z = new JOptionPane();
				 wygrana=true;
				 z.showMessageDialog(null, "Wygrałeś "+litera);
				 for(int i=0; i<9; i++)
				buttons[i].setEnabled(false);
			 }
			 else if(buttons[3].getText() == buttons[4].getText() && buttons[4].getText() == buttons[5].getText() && buttons[3].getText() != ""){
				 wygrana=true;
				 JOptionPane z = new JOptionPane();
				 z.showMessageDialog(null, "Wygrałeś "+litera);
				 for(int i=0; i<9; i++)
						buttons[i].setEnabled(false);
				}

				else if(buttons[6].getText() == buttons[7].getText() && buttons[7].getText() == buttons[8].getText() && buttons[6].getText() != ""){
					 JOptionPane z = new JOptionPane();
					 wygrana=true;
					 z.showMessageDialog(null, "Wygrałeś "+litera);
					 for(int i=0; i<9; i++)
							buttons[i].setEnabled(false);
				}
			 
			//pionowo
				else if(buttons[0].getText() == buttons[3].getText() && buttons[3].getText() == buttons[6].getText() && buttons[0].getText() != ""){
					JOptionPane z = new JOptionPane();
					 wygrana=true;
					 z.showMessageDialog(null, "Wygrałeś "+litera);
					 for(int i=0; i<9; i++)
							buttons[i].setEnabled(false);
				}

				else if(buttons[1].getText() == buttons[4].getText() && buttons[4].getText() == buttons[7].getText() && buttons[1].getText() != ""){
					JOptionPane z = new JOptionPane();
					 wygrana=true;
					 z.showMessageDialog(null, "Wygrałeś "+litera);
					 for(int i=0; i<9; i++)
							buttons[i].setEnabled(false);
				}

				else if(buttons[2].getText() == buttons[5].getText() && buttons[5].getText() == buttons[8].getText() && buttons[2].getText() != ""){
					JOptionPane z = new JOptionPane();
					 wygrana=true;
					 z.showMessageDialog(null, "Wygrałeś "+litera);
					 for(int i=0; i<9; i++)
							buttons[i].setEnabled(false);
				}

				        

				//przekątna

				else if(buttons[0].getText() == buttons[4].getText() && buttons[4].getText() == buttons[8].getText() && buttons[0].getText() != ""){
					JOptionPane z = new JOptionPane();
					 wygrana=true;
					 z.showMessageDialog(null, "Wygrałeś "+litera);
					 for(int i=0; i<9; i++)
							buttons[i].setEnabled(false);
				}

				else if(buttons[2].getText() == buttons[4].getText() && buttons[4].getText() == buttons[6].getText() && buttons[2].getText() != ""){
					JOptionPane z = new JOptionPane();

					 wygrana=true;
					 z.showMessageDialog(null, "Wygrałeś "+litera);
					 for(int i=0; i<9; i++)
							buttons[i].setEnabled(false);
				}

				else if(runda==9 && wygrana==false) {
					JOptionPane z = new JOptionPane();
					 z.showMessageDialog(null, "Nikt nie wygrał nananan");

					 
				}
			 

			 }
	  
		 //sprawdzenie wygranej
		 //tutaj poziomo
		 
	    public void komputer(){
        	runda++;
        	   for(int i=0;i<9;i++)
               {

                if(buttons[i].getText() == "" || buttons[i].getText() == null || buttons[i].getText().equals(null) || buttons[i].getText().equals("")){
  
                    buttons[i].setText("O");
                    buttons[i].setEnabled(false);
                    break;
                }
            }
        	
        }

Popatrzę co jeszcze można uprościć i oddaje nauczycielce, aby w końcu dała mi szóstkę z informatyki na koniec.

0

(buttons[i].getText() == "" || buttons[i].getText() == null || buttons[i].getText().equals(null) || buttons[i].getText().equals(""))

to jest to samo, tylko 4 razy.

 for(int i=0;i<9;i++)
               {
 
                if(buttons[i].getText() == "" || buttons[i].getText() == null || buttons[i].getText().equals(null) || buttons[i].getText().equals("")){
 
                    buttons[i].setText("O");
                    buttons[i].setEnabled(false);
                    break;
                }

za taki algorytm na jej miejscu nie dałbym szóstki

Na matematyce uczą, że można wspólne elementy wyrzucić poza nawias. Więc zrób coś z tym, bo powtarzasz to 9 razy...

JOptionPane z = new JOptionPane(); 
 
                                         wygrana=true;
                                         z.showMessageDialog(null, "Wygrałeś "+litera);
                                         for(int i=0; i<9; i++)
                                                        buttons[i].setEnabled(false);

ogólnie to jeszcze bym się przyczepił, że sprawdzanie wygranych można krócej zapisać, ale tak też może być.

0
Sopelek napisał(a):

(buttons[i].getText() == "" || buttons[i].getText() == null || buttons[i].getText().equals(null) || buttons[i].getText().equals(""))

Na matematyce uczą, że można wspólne elementy wyrzucić poza nawias. Więc zrób coś z tym, bo powtarzasz to 9 razy...
JOptionPane z = new JOptionPane();

                                     wygrana=true;
                                     z.showMessageDialog(null, "Wygrałeś "+litera);
                                     for(int i=0; i<9; i++)
                                                    buttons[i].setEnabled(false);

Wywaliłem do oddzielnej funkcji.

Napisz co ze sprawdzaniem wygranej, jakaś wskazówka, postaram się sprostać.

1 użytkowników online, w tym zalogowanych: 0, gości: 1