Autor Beitrag
LINUS19
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 153
Erhaltene Danke: 1

Windows 10, 7
Java(Eclipse)
BeitragVerfasst: Mo 12.03.18 23:23 
Hallo,
ich habe jetzt für Viergewinnt folgende Bewertungsfunktion gemacht:
Anzahl der 2er Reihen und 3er Reihen zählen (für Spieler und Computer), wobei die 3er Reihen mit deutlich mehr Punkten bewertet werden als die 2er Reihen und eine 4er Reihe mit Integer.Max bewertet wird und dann das Spiel abgebrochen wird. ( mit Reihen meine ich auch Diagonalen usw.)
Aber es wird bei der Bewertung immer Null zurückgegeben.


Ich habe das ganze aufs wesentliche gkürzt:
ausblenden volle Höhe Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:
42:
43:
44:
45:
46:
47:
48:
49:
50:
51:
52:
53:
54:
        static int züge=0; // Anfangszüge, wird nach jedem Zug erhöht
        static final int MaxFaktor2 = 10; // für 2er Reihen
  static final int MinFaktor2 = 10;
  static final int MaxFaktor3 = 200; // für 3er Reihen
  static final int MinFaktor3 = 200;

 ...

static int zähleNachbarn(int i, int j, int di, int dj) { // i,j Koordinaten di dj SteigungsRichtungen(0,1,-1) für Diagonalen usw.
    int num = 0;
   char Player = SpieleramZug(züge); // Spieler am Zug in Abhängigkeit von den zügen
   
      for (int x=0; x<4; x++) {
        if (Feld[i+x*di][j+x*dj]==Player) num++;
        }          
    
    return num; // return  vom selben Spieler belegte Felder in Reihe
  } 

...

 public static int bewerteZug() {    
               char Player=SpieleramZug(züge); // Bewerte Spieler der am Zug ist        
                int min2er = 0; int max2er = 0;  // Reihen zählen
    int min3er = 0; int max3er = 0;
             
    for(int i=0; i<6; i++) {
     for(int j=0; j<7; j++) {
                   
       if(Player==Computer) {    // Bewertung Computer                   
         
         if( j<=3) {   // noch ausbaufähig zu einer 4er Reihe?     
              if(zähleNachbarn(i, j, 0, 1)==4) // Gewinn
        return Integer.MAX_VALUE;      
        if(zähleNachbarn(i, j, 0, 1)==3) max3er++; // Reihen zählen
        if(zähleNachbarn(i, j, 0, 1)==2) max2er++;          
         }         
         ....  Diagonalen,Spalten     
       }
      
       if(Player==Spieler) {  // Bewertung Spieler                                 
         if( j<=3) {   // noch ausbaufähig?  rechts     
           if(zähleNachbarn(i, j, 0, 1)==4) //Gewinn 
         return Integer.MIN_VALUE;      
        if(zähleNachbarn(i, j, 0, 1)==3) min3er++;
        if(zähleNachbarn(i, j, 0, 1)==2) min2er++;          
         }                          
      .... Diagonalen,Spalten
                   }                     
     }
    }                            
    if(Player== Computer) return  max2er*MaxFaktor2+max3er*MaxFaktor3; // Bewertungspunkte
    else return min2er*MinFaktor2+min3er*MinFaktor3;  
    }

Wäre das so den eine relativ starke Bewertungsfunktion(wenn sie funktionieren würde) und hat vielleicht noch jemand einen Vorschlag für eine bessere Bewertungsfunktion?

LG
LINUS19
LINUS19 Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 153
Erhaltene Danke: 1

Windows 10, 7
Java(Eclipse)
BeitragVerfasst: Di 13.03.18 18:57 
EDIT:
Wenn ich jetzt gegen den Computer mit Suchtiefe 8 spiele geht es einigermaßen, der Computer verhindert Siege von mir und spielt nicht schlecht aber nach 34 Zügen macht er keinen Zug mehr.
Ich vermute das der Fehler hier irgendwo liegt:
Wenn die Suchtiefe kleiner als die Anzahl der verbleibenden Felder ist, wie rufe ich dass dann richtig auf?
ausblenden Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
     for (int i = 42; i > 0; i--) {  
        if (i % 2 == 0 && i<=eingestellteTiefe) { // Computerzug                        
                    max(eingestellteTiefe, -10000, 10000);
          Feld[bestCol][bestRow] = Computer;
          FeldAusgeben(Feld);
          System.out.println();
            züge++;
        }

        if (i % 2 == 1  ) {  Spielerzug
          SpielerZug();
                züge++;
        }
        
        if(i<eingestellteTiefe && i%2==0) { //i< Suchtiefe         
        eingestellteTiefe--;
        max(eingestellteTiefe, -10000, 10000);
        züge++;
        }                        
        System.out.println(i);
LINUS19 Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 153
Erhaltene Danke: 1

Windows 10, 7
Java(Eclipse)
BeitragVerfasst: Mi 14.03.18 22:24 
Das mit den Aufrufen funktioniert jetzt, aber ich habe das Gefühl, dass die KI nicht wirklich gut spielt. Der Computer hat 'O' und beginnt und der Spieler hat 'X'. Das wäre doch kein wirklich guter Zug vom Computer, oder? Wie könnte ich das verbessern?
Und eigentlich müsste der Computer in der Mitte anfangen weil er dort ja die meisten Möglichkeiten hat, er setzt aber ein Feld links neben die Mitte, was ja auch nicht wirklich viel Sinn ergibt.
ausblenden Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
******* // Computer zieht
*******
*******
*******
***X***
O*OX***
39
*******
*******
*******
*******
***X***
OOOX***
38