Forum: Mikrocontroller und Digitale Elektronik Gewinnabfrage für 4-Gewinnt in C


von robert (Gast)


Lesenswert?

Also ich habe derzeit keine möglichkeit meinen Controller zu 
Programmieren da mein Paralell-Port kaputt ist, so geh ich morgen zu 
einem Freund bei dem es Funktioniert, jetz habe ich aber nur bis Montag 
Zeit mein Programm fertigzustellen, es funktioniert alles bis auf die 
Gewinnabfrage.
jetz würde ich gerne wissen ob das so funtionieren würde wie ich es 
Programmiert habe
also die Gesetzen steine werden in ein Array geschrieben.
Spielfeld[6][7]
1 für grün und
2 für rot
in meinem beispiel sind x und y immer der stein der als letztes gesetzt 
wurde
jetz würde ich gerne wissen ob meine gewinnabfrage so funktioniert wie 
ich sie geschrieben habe.
1
void gewinnabfrage(){
2
    
3
     for(m=1;m<=3;m++)       //Horizontal
4
     {
5
       if(spielfeld[x+m][y]==1) 
6
      {zaehler++;
7
      }
8
      if(spielfeld[x-m][y]==1)
9
      {zaehler++;
10
      }
11
     }
12
     if(zaehler>=4)win=1;
13
       else{            //Vertikal
14
       zaehler=0;
15
         for(m=1;m<=3;m++)
16
         {
17
           if(spielfeld[x][y-m]==1) 
18
          {zaehler++;
19
          }
20
      
21
         }
22
       }
23
       if(zaehler>=4)win=1;     
24
       else{            //Diagonal 1
25
       zaehler=0;
26
        for(m=1;m<=3;m++)
27
         {
28
           if(spielfeld[x-m][y-m]==1) 
29
          {zaehler++;
30
          }
31
          if(spielfeld[x+m][y+m]==1) 
32
          {zaehler++;
33
          }
34
      
35
         }
36
       }
37
     if(zaehler>=4)win=1;
38
       else{             //Diagonal 2
39
       zaehler=0;
40
         for(m=1;m<=3;m++)
41
         {
42
           if(spielfeld[x+m][y-m]==1) 
43
          {zaehler++;
44
          }
45
          if(spielfeld[x-m][y+m]==1) 
46
          {zaehler++;
47
          }
48
      
49
         }
50
       }
51
 }

von DirkB (Gast)


Lesenswert?

Probier es dochaus.
Die Abfrage sollte mit jedem C-Compiler zu machen sein.
Auch der zu deinem System gehört.

Auch Online, z.B. codepad.org

Oder im Simulator.

von robert (Gast)


Lesenswert?

ich habe den code ja in keil geschrieben und bereist compiliert, also es 
gibt keine errors, ich wollte nur fragen ob es von der logik her richtig 
geschrieben ist, ob das programm so wie ich es geschrieben habe auch 
seine zweck erfüllt

von Looser (Gast)


Lesenswert?

robert schrieb:
> ich habe den code ja in keil geschrieben und bereist compiliert, also es
> gibt keine errors,

tja, dann kannst du jetzt den Simulator anwerfen, im Keil ;-)

von robert (Gast)


Lesenswert?

aber am simulator seh ich doch keine led-matrix, und das seh ich nicht 
wie das funtioniert, außerdem hab ich keine ahnung wie der funktioniert, 
kann man dort eine mehrfarbige led-matrix und taster simulieren? und 
wenn ja wie?

von Looser (Gast)


Lesenswert?

Du kannst dort dein Programm debuggen. Du kannst die Inhalte der 
Variablen aunschauen, das Programm anhalten, schrittweise ausführen, 
Werte ändern, ...
Und so siehst du, ob das Programm das macht, was du willst. Bunte Knöpfe 
brauchst du nicht, schließlich weisst du doch was du programmiert hast.

von robert (Gast)


Lesenswert?

ja, wie setze ich z.b. den taster p3.1 und wie schaue ich nun was dann 
mit p0 passiert???

von Looser (Gast)


Lesenswert?


von Floh (Gast)


Lesenswert?

robert schrieb:
> void gewinnabfrage(){

Ich würde bei sowas lieber z.B. einen int zurückgeben, der dir sagt, 
0=kein Gewinner, 1=Rot gewonnen, 2=grün gewonnen.
So sparst du dir erstens die globale Variable, zweitens kannst du sobald 
du eine Viererreihe gefunden hast sofort beenden (mit return).
Außerdem wäre es meiner Meinung nach angebracht, den Zähler nur in der 
Funktion zu haben -> lokale Variable.

von ... (Gast)


Lesenswert?

Egal ob Simulator oder nicht, der Codeschnipsel oben wird jedenfalls 
nicht funktionieren. Und das geht gleich bei den ersten paar Zeilen los:
1
void gewinnabfrage(){
2
    
3
     for(m=1;m<=3;m++)       //Horizontal
4
     {
5
       if(spielfeld[x+m][y]==1)
Überleg mal was passiert, wenn der letzte Stein die Koordinate x=5 
hatte.
Und was passiert eigenlich, wenn der letze Stein rot war?

von ... (Gast)


Lesenswert?

Achso nochwas. Überlegt mal wie groß 'zaehler' in Deinen Zählschleifen 
werden kann. Und dann schau mal auf welchen Wert Du dann testest. Bei 
Dir kann man niemals gewinnen.

von DirkB (Gast)


Lesenswert?

robert schrieb:
> aber am simulator seh ich doch keine led-matrix, und das seh ich nicht
> wie das funtioniert,

Du willst doch nur die Funktion gewinnabfrage() überprüfen.
Dazu brauchst doch auch nur deine Array spielfeld.
Das kannst du auch mit Testwerten vorbesetzen.

von robert (Gast)


Lesenswert?

... schrieb:
> Überleg mal was passiert, wenn der letzte Stein die Koordinate x=5
> hatte.

ja dann geht das nicht ganz auf mit dem dimensionen vom array, aber wie 
mache ich das dann? -.-
... schrieb:
> Und was passiert eigenlich, wenn der letze Stein rot war?
1
void gewinnabfrage(){
2
     if(spielfeld[x][y]==1)a=1;
3
     else a=2;
4
    
5
     for(m=1;m<=3;m++)       //Horizontal
6
     {
7
       if(spielfeld[x+m][y]==a) 
8
      {zaehler++;
9
      }
10
      if(spielfeld[x-m][y]==a)
11
      {zaehler++;
12
      }
13
     }
14
     if(zaehler>=4)win=1;
dann villeicht so?

von Ulrich (Gast)


Lesenswert?

So klappt es auch noch nicht ganz. Die 4 Steine müssen zusammenhängend 
sein. So wird ein Bereich von 3 nach links bis 3 nach rechts überprüft, 
ob da 4 passende drin sind. Man muss aber aufhören zu zählen, wenn 1 
Stein nicht mehr passt.  Das wäre dann also eher je eine While Schleife 
nach links und rechts bis maximal 3, und dann die Summe von links und 
rechts anschauen.

Beim Index muss man dann noch aufpassen, wenn man den Rand des Feldes 
erreicht. Eventuell am Rand einfach noch je 3 leere Reihen vorsehen und 
das Feld dann 13 breit machen statt 7.

Wenn das Programm nicht nur Mensch gegen Mensch spielen soll, sondern 
mit eigener Intelligenz, würde ich die endliche Zahl der 
Gewinnmöglichkeiten (ca. 200) nutzen. Das sollte auch noch für einen µC 
passen - sowohl vom Speicher, als auch von der Geschwindigkeit.

von robert (Gast)


Lesenswert?

jetz wollte ich gerade versuchen das array größer zu machen, jetzt heißt 
es beim compilieren data segment too large. was jetzt?
geht das auch ohne das ich das array so groß machen muss?
wie kann man das sonst mit den rändern regeln?

von Ulrich (Gast)


Lesenswert?

Data Segment zu groß heißt das der Speicher (RAM) ausgeht.

Bei den Rändern kann man es auch so machen, das man noch extra 
kontrolliert das (x+m) auch im Bereich 1-7 liegt. Also dann Schleifen 
etwa der Form

m=1;
While ( (m < 4)&&((x+m)<=7) && (spielfeld[x+m][y]==a)) m++;

von R. M. (rmax)


Lesenswert?

Statt vom neuen Stein aus nach links und rechts zu laufen, könntest Du 
horizontal einfach immer über die ganze Zeile, in der der neue Stein 
gelandet ist und dabei die zusammenhängenden Steine der zu überprüfenden 
Farbe zählen. Hat der Zähler vier erreicht, mit "Gewonnen" 
herausspringen, bei einem Stein der anderen Farbe, den Zähler 
zurücksetzen.

Vertikal kannst Du den Überlauf am unteren Rand dadurch vermeiden, daß 
Du die Zählschleife überhaupt nur dann startest, wenn schon mindestens 
vier Steine im entsprechenden Schacht liegen. Sind weniger Steine im 
Schacht, kann in der Richtung ja noch kein Sieg vorliegen. Oben kann es 
eigentlich keinen Überlauf geben, denn in einen vollen Schacht kann man 
ja keinen weiteren Stein werfen (das muß der Programmteil, der für's 
Einwerfen zuständig ist, natürlich sicherstellen).

Für die Diagonalen sollte es auch möglich sein, die Schleifen so zu 
gestalten, daß sichergestellt ist, daß sie nur maximal von Rand zu Rand 
laufen aber niemals darüber, aber das tüftle ich heute nicht mehr aus.

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.