public static int[,] ställning = new int[sida, sida]; // Där dragen lagras. #endregion Fields #region Methods // Kollar upp-ner public static int SammaLinje(Bräde.Fält drag, int påDrag /*<- Vilken spelares drag den ska leta efter */) { int antal = 0; for (int indexökning = drag.Y + 1; indexökning <= drag.Y + 4; indexökning++) // Kollar de fyra fälten närmast nedanför { if (indexökning >= Bräde.sida) // Om den hamnat utanför spelanen { break; } if (Bräde.ställning[drag.X, indexökning] == påDrag) // Om det finns ett eget drag på fältet antal++; else { break; } } for (int indexminskning = drag.Y - 1; indexminskning >= drag.Y - 4; indexminskning--) // Kollar de fyra fälten närmast ovanför { if (indexminskning < 0) // Om den hamnat utanför spelanen { break; } if (Bräde.ställning[drag.X, indexminskning] == påDrag) // Om det finns ett eget drag på fältet antal++; else { break; } } return antal; }
// Kollar vänster-höger public static int SammaRad(Bräde.Fält drag, int påDrag /*<- Vilken spelares drag den ska leta efter */) { int antal = 0; // Går igenom de fyra fälten närmast till höger for (int indexökning = drag.X + 1; indexökning <= drag.X + 4; indexökning++) { // Om den hamnat utanför spelplanen if (indexökning >= Bräde.sida) { break; } // Om det finns ett eget drag på fältet if (Bräde.ställning[indexökning, drag.Y] == påDrag) { antal++; } else { break; } } // Går igenom de fyra fälten närmast till vänster for (int indexminskning = drag.X - 1; indexminskning >= drag.X - 4; indexminskning--) { // Om den hamnat utanför spelanen if (indexminskning < 0) { break; } // Om det finns ett eget drag på fältet if (Bräde.ställning[indexminskning, drag.Y] == påDrag) antal++; else { break; } } return antal; }
public void RitaSenasteMotorDrag(Bräde.Fält drag) { Graphics g = CreateGraphics(); g.DrawString(spelarePåDrag.EgetTecken == Spelare.Tecken.Kryss ? "X" : "O", new Font(FontFamily.GenericSerif, teckenstorlek), new SolidBrush(Color.HotPink), new PointF(drag.X * fältstorlek, drag.Y * fältstorlek + menuStrip1.Height)); }
// Sköter det som ska hända när spelaren gjort ett drag private void Form1_MouseDown(object sender, MouseEventArgs e) { if (spelarePåDrag != null && spelarePåDrag.EgenTyp == Spelare.Typ.Människa) { // x och y-koordinaterna för fältet som klickades int x = e.X / fältstorlek; int y = (e.Y - menuStrip1.Size.Height) / fältstorlek; // Menyraden tar upp plats i yled // Kollar att spelaren tryckte på ett fält innanför spelplanen och att fältet är tomt if (x >= 0 && x < Bräde.sida && y >= 0 && y < Bräde.sida && Bräde.ställning[x, y] == 0) { Bräde.ställning[x, y] = spelarePåDrag.Teckenvärde; Refresh(); Bräde.Fält drag = new Bräde.Fält(x, y); Bräde.uppdateraMöjligaDrag(drag); Bräde.gjordaDrag.Add(drag); if (Bräde.ÄrVinstdrag(drag, spelarePåDrag.Teckenvärde)) { // Om motståndaren är en människa if ((spelarePåDrag == spelareEtt ? spelareTvå : spelareEtt).EgenTyp == Spelare.Typ.Människa) { MessageBox.Show("Vinst."); } else { MessageBox.Show("Fuskare."); } } // Om spelplanen är fylld else if (Bräde.gjordaDrag.Count == Bräde.antalFält) { MessageBox.Show("WTF?"); } else { SkötParti(); } } } }
private void startKnapp_Click(object sender, EventArgs e) { spelareEtt = new Spelare(spelareEttsArgument); spelareTvå = new Spelare(spelareTvåsArgument); Bräde.ställning = new int[Bräde.sida, Bräde.sida]; Bräde.gjordaDrag.Clear(); spelarePåDrag = spelareEtt; Bräde.möjligaDrag.Clear(); // Lägger till mittfältet i möjliga drag så att motorn börjar där Bräde.möjligaDrag.Add(new Bräde.Fält(Bräde.sida / 2, Bräde.sida / 2)); Refresh(); if (spelareEtt.EgenTyp != Spelare.Typ.Människa) { Bräde.ställning[Bräde.sida / 2, Bräde.sida / 2] = spelareEtt.Teckenvärde; Bräde.gjordaDrag.Add(new Bräde.Fält(Bräde.sida / 2, Bräde.sida / 2)); RitaSenasteMotorDrag(new Bräde.Fält(Bräde.sida / 2, Bräde.sida / 2)); Bräde.uppdateraMöjligaDrag(new Bräde.Fält(Bräde.sida / 2, Bräde.sida / 2)); SkötParti(); } }
private void SkötParti() { bytSpelarePådDrag(); while (spelarePåDrag.EgenTyp != Spelare.Typ.Människa) { Bräde.Fält nästaDrag = spelarePåDrag.användAI.BestämDrag(); Bräde.ställning[nästaDrag.X, nästaDrag.Y] = spelarePåDrag.Teckenvärde; Bräde.gjordaDrag.Add(nästaDrag); RitaSenasteMotorDrag(nästaDrag); Bräde.uppdateraMöjligaDrag(nästaDrag); if (Bräde.ÄrVinstdrag(nästaDrag, spelarePåDrag.Teckenvärde)) { bytSpelarePådDrag(); // Om motorn vann över en människa if (spelarePåDrag.EgenTyp == Spelare.Typ.Människa) { MessageBox.Show("Du blev ägd av en maskin."); } break; } // Om spelplanen är fylldd else if (Bräde.gjordaDrag.Count == Bräde.antalFält) { MessageBox.Show("WTF?"); break; } else { bytSpelarePådDrag(); } } Refresh(); }
public static int SnettUppHöger(Bräde.Fält drag, int påDrag /*<- Vilken spelares drag den ska leta efter */) { int antal = 0; for (int indexökning = 1; indexökning <= 4; indexökning++) // Kollar de fyra fälten närmast snett upp höger { if (drag.X + indexökning >= Bräde.sida || drag.Y - indexökning < 0) // Om den hamnat utanför spelanen { break; } else if (Bräde.ställning[drag.X + indexökning, drag.Y - indexökning] == påDrag) // Om det finns ett eget drag på fältet { antal++; } else { break; } } for (int indexökning = 1; indexökning <= 4; indexökning++) // Kollar de fyra fälten närmast snett ned vänster { if (drag.X - indexökning < 0 || drag.Y + indexökning >= Bräde.sida) // Om den hamnat utanför spelanen { break; } if (Bräde.ställning[drag.X - indexökning, drag.Y + indexökning] == påDrag) // Om det finns ett eget drag på fältet antal++; else { break; } } return antal; }
public static bool ÄrVinstdrag(Bräde.Fält drag, int teckenvärde) { if (SammaRad(drag, teckenvärde) >= 4 || SammaLinje(drag, teckenvärde) >= 4 || SnettUppHöger(drag, teckenvärde) >= 4 || SnettUppVänster(drag, teckenvärde) >= 4) { return true; } return false; }
public override Bräde.Fält BestämDrag() { List <Bräde.Fält> dragAttTaBort = new List <Bräde.Fält>(); Bräde.Fält bästaDrag = new Bräde.Fält(); int vinstdifferens = int.MinValue; // De AI:er som används i de simulerade partierna OriginalgangsterAI egnaSidan = new OriginalgangsterAI(egetTeckenvärde, tolerans: 0); OriginalgangsterAI andraSidan = new OriginalgangsterAI(-egetTeckenvärde, tolerans: 0); foreach (Bräde.Fält fält in Bräde.möjligaDrag) { int xkoordinat = fält.X; int ykoordinat = fält.Y; Bräde.Fält testdrag = new Bräde.Fält(xkoordinat, ykoordinat); if (Bräde.ÄrVinstdrag(testdrag, egetTeckenvärde)) { return(testdrag); } else { int antalVinster = 0; int antalFörluster = 0; // Sätter in draget i spelplanen tillfälligt Bräde.ställning[xkoordinat, ykoordinat] = egetTeckenvärde; for (int parti = 0; parti < 100; parti++) { Bräde.Fält drag; for (int dragNummer = 0; dragNummer < 25; dragNummer++) { drag = andraSidan.BestämDrag(); // Spelplanen är full // Partiet är oavgjort if (drag == Bräde.nåtHarGåttFel) { taBortFrånSpelplanen(dragAttTaBort); dragAttTaBort.Clear(); break; } // Förlust else if (Bräde.ÄrVinstdrag(drag, -egetTeckenvärde)) { antalFörluster++; taBortFrånSpelplanen(dragAttTaBort); dragAttTaBort.Clear(); break; } // Partiet fortsätter else { Bräde.ställning[drag.X, drag.Y] = -egetTeckenvärde; dragAttTaBort.Add(drag); } drag = egnaSidan.BestämDrag(); // Spelplanen är full // Partiet är oavgjort if (drag == Bräde.nåtHarGåttFel) { taBortFrånSpelplanen(dragAttTaBort); dragAttTaBort.Clear(); break; } // Vinst else if (Bräde.ÄrVinstdrag(drag, egetTeckenvärde)) { antalVinster++; taBortFrånSpelplanen(dragAttTaBort); dragAttTaBort.Clear(); break; } // Partiet fortsätter else { Bräde.ställning[drag.X, drag.Y] = egetTeckenvärde; dragAttTaBort.Add(drag); } } } taBortFrånSpelplanen(dragAttTaBort); dragAttTaBort.Clear(); int testDifferens = antalVinster - antalFörluster; if (testDifferens > vinstdifferens) { vinstdifferens = testDifferens; bästaDrag = testdrag; } else if (testDifferens == vinstdifferens && Math.Max(BeräknaDragvärde(testdrag, egetTeckenvärde), BeräknaDragvärde(testdrag, -egetTeckenvärde)) > Math.Max(BeräknaDragvärde(bästaDrag, egetTeckenvärde), BeräknaDragvärde(bästaDrag, -egetTeckenvärde))) { vinstdifferens = testDifferens; bästaDrag = testdrag; } // Tar bort draget ur spelplanen Bräde.ställning[testdrag.X, testdrag.Y] = 0; } } return(bästaDrag); }