Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- using System;
- using System.Collections.Generic;
- using System.Linq;
- using System.Text;
- namespace Malomjáték
- {
- // Az AbsztraktÁllapot osztályt ki kellett bővíteni a GetHeurisztika metódussal.
- // Egyébként megegyezik az előző fejezetben tárgyalt változattal.
- abstract class AbsztraktÁllapot : ICloneable
- {
- public abstract bool ÁllapotE();
- public abstract bool CélÁllapotE();
- public abstract int OperátorokSzáma();
- public abstract bool SzuperOperátor(int i);
- public virtual object Clone() { return MemberwiseClone(); }
- public override bool Equals(Object a) { return false; }
- public override int GetHashCode() { return base.GetHashCode(); }
- // Ez a metódus adja vissza, mennyire jó az adott állapot
- // Ez csak egy hook, felül kell írni, ha
- // kétszemélyes játékot vagy best-first algoritmus alkalmazunk,
- // vagy bármilyen más algoritmust, ami heurisztikán alapszik.
- // Más esetben, pl. backtrack esetén, nem kell felülírni.
- // Jobb állás esetén nagyobb számot kell visszaadnia.
- public virtual int GetHeurisztika() { return 0; }
- }
- class bábu
- {
- //a bábu neve
- string _név;
- public string név
- {
- get { return _név; }
- set { _név = value; }
- }
- //ebben tárolom, hogy a táblán a legbelső/középső/külső "négyzetben" helyezkedik-e el a bábu
- int _négyzet;
- public int négyzet
- {
- get { return _négyzet; }
- set
- {
- Console.WriteLine("A négyzet megváltozott!: {0} {1}", _név, value);
- _négyzet = value;
- }
- }
- // 2 különleges érték:
- //-1: még nincs a táblán
- // -2: már nincs a táblán (leütötték)
- //ebben pedig, hogy az adott "négyzeten" belül pontosan hanyadik mezőn a lehetséges 8-ból
- int _pozíció;
- public int pozíció
- {
- get { return _pozíció; }
- set {
- Console.WriteLine("A pozíció megváltozott!: {0} {1}", _név, value);
- _pozíció = value;
- }
- }
- //ha 0 akkor fehér a bábu, ha 1 akkor pedig fekete
- int _Szín;
- public int Szín
- {
- get { return _Szín; }
- set { _Szín = value; }
- }
- public bábu(string p_név, int p_négyzet, int p_pozíció, int p_szín)
- {
- név = p_név;
- négyzet = p_négyzet;
- pozíció = p_pozíció;
- Szín = p_szín;
- }
- } //bábu class vége
- struct Indexpár
- {
- public int négyzetI, pozícióI;
- public Indexpár(int négyzetindex, int pozícióindex)
- {
- négyzetI = négyzetindex;
- pozícióI = pozícióindex;
- }
- public override bool Equals(object obj)
- {
- Indexpár pindex = (Indexpár)obj;
- return pindex.négyzetI == négyzetI && pindex.pozícióI == pozícióI;
- }
- }
- class MalomÁllapot : AbsztraktÁllapot
- {
- public bábu[,] tábla = new bábu[3, 8];
- public bábu[] fehérbábuk = new bábu[9];
- public bábu[] feketebábuk = new bábu[9];
- public bool fehérlép;
- public int fehérBábukKézben, fehérBábukTáblán, feketeBábukKézben, feketeBábukTáblán;
- public int fehérfázis, feketefázis;
- public int fázis
- {
- set
- {
- if (fehérlép) fehérfázis = value;
- else feketefázis = value;
- }
- get
- {
- return fehérlép ? fehérfázis : feketefázis;
- }
- }
- public MalomÁllapot()
- {
- for (int i = 0; i < fehérbábuk.Length; i++)
- {
- fehérbábuk[i] = new bábu(String.Format("wh{0}", i + 1), -1, -1, 0);
- }
- for (int i = 0; i < feketebábuk.Length; i++)
- {
- feketebábuk[i] = new bábu(String.Format("bk{0}", i + 1), -1, -1, 1);
- }
- fehérBábukKézben = 9;
- fehérBábukTáblán = 0;
- feketeBábukKézben = 9;
- feketeBábukTáblán = 0;
- fehérlép = false;
- fehérfázis = 1;
- feketefázis = 1;
- }
- public MalomÁllapot(MalomÁllapot másolandó)
- {
- tábla = (bábu[,])másolandó.tábla.Clone();
- fehérbábuk = (bábu[])másolandó.fehérbábuk.Clone();
- feketebábuk = (bábu[])másolandó.feketebábuk.Clone();
- feketeBábukKézben = másolandó.feketeBábukKézben;
- fehérBábukKézben = másolandó.fehérBábukKézben;
- fehérfázis = másolandó.fehérfázis;
- feketefázis = másolandó.feketefázis;
- fehérlép = másolandó.fehérlép;
- }
- public override bool ÁllapotE()
- {
- return true;
- }
- public override bool CélÁllapotE()
- {
- return (fehérBábukKézben == 0 && fehérBábukTáblán == 2) || (feketeBábukKézben == 0 && feketeBábukTáblán == 2); // || nemtudlépni();
- }
- //private bool nemtudlépni()
- //{
- // return ;
- //}
- public override int OperátorokSzáma()
- {
- // hány bábumvan (9)
- // hány négyzetre tehetem le(3)
- // egy adott négyzeten belül hány pozícióra tehetem le (8)
- // az ellenfél hány bábuja közül vehetek le egyet (9)
- return 9 * 3 * 8 * 9;
- }
- public override bool SzuperOperátor(int i)
- {
- int bábuIndex = i / (3 * 8 * 9);
- int maradék = i % (3 * 8 * 9);
- int négyzetIndex = maradék / (8 * 9);
- maradék = maradék % (8 * 8);
- int pozícióIndex = maradék / 9;
- maradék = maradék % 9;
- int melyikBábutVeszemLeHaMalomIndex = maradék;
- return Lépés(bábuIndex, négyzetIndex, pozícióIndex, melyikBábutVeszemLeHaMalomIndex);
- }
- private bool Lépés(int bábuIndex, int négyzetIndex, int pozícióIndex, int melyikBábutVeszemLe)
- {
- if (!preLépés(bábuIndex, négyzetIndex, pozícióIndex, melyikBábutVeszemLe)) return false;
- if (fehérlép)
- {
- if (fázis == 1)
- {
- tábla[négyzetIndex, pozícióIndex] = fehérbábuk[bábuIndex];
- fehérbábuk[bábuIndex].négyzet = négyzetIndex;
- fehérbábuk[bábuIndex].pozíció = pozícióIndex;
- fehérBábukTáblán++;
- fehérBábukKézben--;
- //a fekete játékosnál váltunk fázist amint elfogytak a bábuk, mert ő az utolsó az első fázisban
- }
- else if (fázis == 2)
- {
- //lépünk a bábuval
- tábla[négyzetIndex, pozícióIndex] = fehérbábuk[bábuIndex];
- //üressé tesszük a mezőt, ahonnan elléptünk
- tábla[fehérbábuk[bábuIndex].négyzet, fehérbábuk[bábuIndex].pozíció] = null;
- //a bábu objektumban is beállítjuk, hogy épp melyik mezőre lépett
- fehérbábuk[bábuIndex].négyzet = négyzetIndex;
- fehérbábuk[bábuIndex].pozíció = pozícióIndex;
- //megnézzük, hogy a lépés malmot eredményezett-e
- bool malomvan = malomvane(fehérbábuk[bábuIndex].négyzet, fehérbábuk[bábuIndex].pozíció);
- //ha malom van, akkor bizony levehetünk egy fekete bábut, ami épp nincs malomban!
- if (malomvan)
- {
- //ha malom van, akkor bekérem, hogy mit akar leütni
- Console.WriteLine("Add meg, hogy melyik fekete bábut szeretnéd levenni (a nevét, és nem lehet épp malomban!):");
- string leütöttbábunév = Console.ReadLine();
- //megkeresem a táblán, hogy jó bábut adott-e meg, és azt tényleg le lehet-e ütni
- int leütöttbábuindex = -1;
- for (int i = 0; i < fehérbábuk.Length; i++)
- {
- if (leütöttbábunév == feketebábuk[i].név) leütöttbábuindex = i;
- }
- if (leüthetőe(leütöttbábuindex))
- {
- //leütjük
- tábla[feketebábuk[leütöttbábuindex].négyzet, feketebábuk[leütöttbábuindex].pozíció] = null;
- feketebábuk[leütöttbábuindex].négyzet = -2;
- feketeBábukTáblán--;
- //majd megnézzük, hogy a leütést követően 3 bábuja lett-e, mert ha igen, akkor bizony átlépünk a 3. fázisba
- if (feketeBábukTáblán == 3) feketefázis = 3;
- }
- } //ha malomvan, akkor leüt egy bábut if vége
- //a lépés/leütés-t követően átadjuk a lépést
- fehérlép = false;
- }
- else if (fázis == 3)
- {
- }
- }
- else //tehát a fekete következik
- {
- if (fázis == 1)
- {
- //letesszük az adott bábut
- tábla[négyzetIndex, pozícióIndex] = feketebábuk[bábuIndex];
- feketebábuk[bábuIndex].négyzet = négyzetIndex;
- feketebábuk[bábuIndex].pozíció = pozícióIndex;
- feketeBábukTáblán++;
- feketeBábukKézben--;
- //amint letette a fekete játékos is az utolsó bábuját, fázistváltunk
- if (feketeBábukKézben == 0 && fehérBábukKézben == 0)
- {
- feketefázis = 2;
- fehérfázis = 2;
- }
- }
- else if (fázis == 2)
- {
- //lépünk a bábuval
- tábla[négyzetIndex, pozícióIndex] = feketebábuk[bábuIndex];
- //üressé tesszük a mezőt, ahonnan elléptünk
- tábla[feketebábuk[bábuIndex].négyzet, feketebábuk[bábuIndex].pozíció] = null;
- //a bábu objektumban is beállítjuk, hogy épp melyik mezőre lépett
- feketebábuk[bábuIndex].négyzet = négyzetIndex;
- feketebábuk[bábuIndex].pozíció = pozícióIndex;
- if (malomvane(feketebábuk[bábuIndex].négyzet, feketebábuk[bábuIndex].pozíció))
- {
- bool leüthető = leüthetőe(melyikBábutVeszemLe);
- if (leüthető)
- {
- tábla[fehérbábuk[melyikBábutVeszemLe].négyzet, fehérbábuk[melyikBábutVeszemLe].pozíció] = null;
- fehérbábuk[melyikBábutVeszemLe].négyzet = -2;
- fehérBábukTáblán--;
- //majd megnézzük, hogy a leütést követően 3 bábuja lett-e, mert ha igen, akkor bizony átlépünk a 3. fázisba
- if (fehérBábukTáblán == 3) fehérfázis = 3;
- }
- } //ha malomvan, akkor leüt egy bábut if vége
- //a lépés/leütés-t követően átadjuk a lépést
- fehérlép = true;
- }
- else if (fázis == 3)
- {
- }
- }
- return ÁllapotE();
- }
- private bool preLépés(int bábuIndex, int négyzetIndex, int pozícióIndex, int melyikBábutVeszemLe)
- {
- if (fázis == 1)
- {
- bool temp = (fehérlép ? fehérbábuk[bábuIndex].négyzet : feketebábuk[bábuIndex].négyzet) == -1 &&
- (fehérlép ? fehérbábuk[bábuIndex].pozíció : feketebábuk[bábuIndex].pozíció) == -1 &&
- tábla[négyzetIndex, pozícióIndex] == null;
- return temp;
- }
- else if (fázis == 2)
- {
- var lista = szomszédosÜresMezők(fehérlép ? fehérbábuk[bábuIndex].négyzet : feketebábuk[bábuIndex].négyzet, fehérlép ? fehérbábuk[bábuIndex].pozíció : feketebábuk[bábuIndex].pozíció);
- return lista.Contains(new Indexpár(négyzetIndex, pozícióIndex));
- }
- else
- {
- return tábla[négyzetIndex, pozícióIndex] == null;
- }
- }
- private List<Indexpár> szomszédosÜresMezők(int négyzetI, int pozícióI)
- {
- List<Indexpár> lista = new List<Indexpár>();
- Indexpár indexek;
- if (pozícióI % 1 == 1) // kereszteződés
- {
- indexek.négyzetI = négyzetI;
- indexek.pozícióI = pozícióI - 1;
- if (tábla[indexek.négyzetI, indexek.pozícióI] == null)
- lista.Add(indexek);
- indexek.pozícióI = pozícióI == tábla.GetLength(1) - 1 ? 0 : pozícióI + 1;
- if (tábla[indexek.négyzetI, indexek.pozícióI] == null)
- lista.Add(indexek);
- indexek.pozícióI = pozícióI;
- if (négyzetI == 0 || négyzetI == 2)
- {
- indexek.négyzetI = 1;
- if (tábla[indexek.négyzetI, indexek.pozícióI] == null)
- lista.Add(indexek);
- }
- else
- {
- indexek.négyzetI = 0;
- if (tábla[indexek.négyzetI, indexek.pozícióI] == null)
- lista.Add(indexek);
- indexek.négyzetI = 2;
- if (tábla[indexek.négyzetI, indexek.pozícióI] == null)
- lista.Add(indexek);
- }
- }
- else // sarok
- {
- indexek.négyzetI = négyzetI;
- indexek.pozícióI = pozícióI == 0 ? tábla.GetLength(1) - 1 : pozícióI + 1;
- if (tábla[indexek.négyzetI, indexek.pozícióI] == null)
- lista.Add(indexek);
- indexek.pozícióI = pozícióI + 1;
- if (tábla[indexek.négyzetI, indexek.pozícióI] == null)
- lista.Add(indexek);
- }
- return lista.Count > 0 ? lista : null;
- }
- // A 8 mező egy ponttól indul és a négyzeten végighaladva a vonalán számlálja a pontokat.
- // Hasznos, mert így minden második csomópont kereszteződés.
- private bool malomvane(int négyzetI, int pozícióI)
- {
- if (pozícióI % 2 == 1) // Keresztezősédben van
- {
- // valamelyik oldal, előtte és utána lévő elemeket vizsgálom.
- // ha a szín megegyezik, akkor malom (a tömb utolsó eleme külön kezelve, az őt követő elem a nulladik)
- if (tábla[négyzetI, pozícióI - 1].Szín == tábla[négyzetI, pozícióI].Szín &&
- tábla[négyzetI, pozícióI].Szín == tábla[négyzetI, pozícióI != tábla.GetLength(1) - 1 ? pozícióI + 1 : 0].Szín)
- return true;
- // Ha nem oldalon van malom, akkor még a közbenső utakon is meg kell nézni a bábukat.
- // Függően attól, hogy hanyadik négyzeten van a bábu, beállítom az x-et, amit mindig hozzáadok a négyzetindexhez
- int x = 0;
- switch (pozícióI)
- {
- case 0: break;
- case 1: x--; break;
- case 2: x -= 2; break;
- default: return false;
- }
- return tábla[négyzetI + x, pozícióI].Szín == tábla[négyzetI + x + 1, pozícióI].Szín &&
- tábla[négyzetI + x + 1, pozícióI].Szín == tábla[négyzetI + x + 2, pozícióI].Szín;
- }
- else // Sarkon van
- {
- // Előtte lévő bábun van azonos szín? Első elem külön kezelve
- if (tábla[négyzetI, pozícióI == 0 ? tábla.GetLength(1) - 1 : pozícióI - 1].Szín == tábla[négyzetI, pozícióI].Szín)
- {
- return tábla[négyzetI, pozícióI == 0 ? tábla.GetLength(1) - 2 : pozícióI - 2].Szín == tábla[négyzetI, pozícióI - 1].Szín;
- }
- // És az utánakövetkezőben?
- else if (tábla[négyzetI, pozícióI + 1].Szín == tábla[négyzetI, pozícióI].Szín)
- {
- return tábla[négyzetI, pozícióI + 2 == tábla.GetLength(1) ? 0 : pozícióI + 2].Szín == tábla[négyzetI, pozícióI + 1].Szín;
- }
- }
- return false;
- }
- private bool leüthetőe(int bábuindex)
- {
- return !malomvane(fehérlép ? fehérbábuk[bábuindex].négyzet : feketebábuk[bábuindex].négyzet, fehérlép ? fehérbábuk[bábuindex].pozíció : feketebábuk[bábuindex].pozíció);
- }
- public override object Clone()
- {
- return new MalomÁllapot(this);
- }
- }
- class Csúcs
- {
- AbsztraktÁllapot állapot;
- int mélység;
- Csúcs szülő;
- // A szülőkön túl a gyermekeket is tartalmazza a Csúcs osztály.
- List<Csúcs> gyermekek = new List<Csúcs>();
- // Ez a mező tartalmazza, hogy melyik operátor segítségével jutottunk ebbe a csúcsba a szülő csúcsból.
- // Ennek segítségével tudom megmondani, melyik az ajánlott lépés NegaMaxMódszer esetén.
- int melyikOperátorralJutottamIde = -1; // ha -1, akkor még nincs beállítva
- public Csúcs(AbsztraktÁllapot kezdőÁllapot)
- {
- állapot = kezdőÁllapot;
- mélység = 0;
- szülő = null;
- }
- public Csúcs(Csúcs szülő)
- {
- állapot = (AbsztraktÁllapot)szülő.állapot.Clone();
- mélység = szülő.mélység + 1;
- this.szülő = szülő;
- }
- // Erre a metódusra azért van szükség, hogy a kiterjesztés működjön a JátékCsúcsra is.
- protected virtual Csúcs createGyermekCsúcs(Csúcs szülő) { return new Csúcs(szülő); }
- public Csúcs GetSzülő() { return szülő; }
- public int GetMélység() { return mélység; }
- public bool TerminálisCsúcsE() { return állapot.CélÁllapotE(); }
- public int OperátorokSzáma() { return állapot.OperátorokSzáma(); }
- public bool SzuperOperátor(int i)
- {
- // megjegyzem, melyik operátorral jutottam ebbe az állapotba
- melyikOperátorralJutottamIde = i;
- return állapot.SzuperOperátor(i);
- }
- public override bool Equals(Object obj)
- {
- Csúcs cs = (Csúcs)obj;
- return állapot.Equals(cs.állapot);
- }
- public override int GetHashCode() { return állapot.GetHashCode(); }
- public override String ToString() { return állapot.ToString(); }
- // Alkalmazza az összes alkalmazható operátort.
- // Visszaadja az így előálló új csúcsokat.
- public List<Csúcs> Kiterjesztés()
- {
- gyermekek = new List<Csúcs>();
- for (int i = 0; i < OperátorokSzáma(); i++)
- {
- // Új gyermek csúcsot készítek.
- // Ezzel a sorral nem működik a Kiterjesztés a JátékCsúcsban.
- // --- Csúcs újCsúcs = new Csúcs(this); ---
- // Ezért ezt használjuk:
- Csúcs újCsúcs = createGyermekCsúcs(this);
- // Kipróbálom az i.-dik alapoperátort. Alkalmazható?
- if (újCsúcs.SzuperOperátor(i))
- {
- // Ha igen, hozzáadom az újakhoz.
- gyermekek.Add(újCsúcs);
- }
- }
- return gyermekek;
- }
- // Visszaadja a csúcs heurisztikáját.
- // Ha saját heurisztikát akarunk írni, akkor azt a saját állapot osztályunkba kell megírni.
- public int GetHeurisztika() { return állapot.GetHeurisztika(); }
- // Visszaadja melyik operátorral jutottunk ide.
- // Ezzel az int értékkel kell majd meghívni a SzuperOperátor-t.
- public int GetMelyikOperátorralJutottamIde() { return melyikOperátorralJutottamIde; }
- // Nyomkövetéshez hasznos.
- public void Kiir()
- {
- Console.WriteLine(this);
- foreach (Csúcs gyermek in gyermekek) { gyermek.Kiir(); }
- }
- } // A
- // játék csúcs a
- // csúcs osztály kibővítése egy heurisztika értékkel.
- // Ezt a fajta csúcsot fel lehet használni a best first algoritmushoz is.
- class JátékCsúcs : Csúcs
- {
- int mennyireJó = -1; // mennyire jó, ha -1, akkor még nincs beállítva
- // Konstruktor:
- // A belső állapotot beállítja a start csúcsra.
- // A hívó felelősége, hogy a kezdő állapottal hívja meg.
- // A start csúcs mélysége 0, szülője nincs.
- public JátékCsúcs(AbsztraktÁllapot kezdőÁllapot) :
- base(kezdőÁllapot) { }
- // Egy új gyermek csúcsot készít.
- // Erre még meg kell hívni egy alkalmazható operátor is, csak azután lesz kész.
- public JátékCsúcs(Csúcs szülő) : base(szülő) { }
- // Erre a metódusra azért van szükség, hogy a kiterjesztés
- // működjön a JátékCsúcsra is.
- protected override Csúcs createGyermekCsúcs(Csúcs szülő)
- {
- return new JátékCsúcs(szülő);
- }
- // Visszaadja a csúcshoz tartozó heurisztikát.
- // Ez a csúcsban lévő állapot heurisztikája
- // megszorozva a paraméterben megkapott szor értékkel.
- // NegaMax esetén a szor általában 1, ha az a játékos lép,
- // akinek jó lépést keresünk, -1, ha az ellenfél lép.
- // Mivel minden állapothoz csak egy heurisztika van, ami nem
- // veszi figyelembe, hogy ki lép, ezért a MiniMax-nak is
- // úgy kell használni ezt a metódust, mint a NegaMax-nak.
- public int GetMennyireJó(int szor)
- {
- if (mennyireJó == -1) mennyireJó = GetHeurisztika() * szor;
- return mennyireJó;
- }
- }
- // Ebből kell leszármaztatni a lépés ajánló algoritmusokat, mint a NegaMax módszer.
- abstract class Stratégia
- {
- // Ha a start csúcs zsákutca, akkor null-t ad vissza.
- // Egyébként azt a csúcsot, amibe a stratégia szerint érdemes lépni.
- public abstract JátékCsúcs MitLépjek(JátékCsúcs start);
- } // Egy lépést ajánl valamely játékosnak a
- // NegaMax módszer alapján.
- // Ehhez előre tekint és a heurisztika meghatározása után megkeresi a legkedvezőbb utat a játék fában.
- // Ha a játékfa levelei terminális csúcsok, akkor a legkedvezőbb út a nyerő stratégia lesz.
- class NegaMaxMódszer : Stratégia
- {
- int maxMélység; // Ennyi lépésre tekintünk előre.
- // Minél több lépésre tekintünk előre, annál intelligensebbnek tűnik a gép, hiszen jobb lépést választ.
- // Ezt a TicTacToe esetén figyelhetjük meg.
- // Ugyanakkor minél több lépést generálunk, annál lassabb lesz az algoritmus.
- // Ennek egy megoldása az Alfabéta-vágás, de ezt nem programoztuk le.
- public NegaMaxMódszer(int intelligencia) { maxMélység = intelligencia; }
- // Egy játékcsúcsot ad vissza.
- // Ennek a GetMelyikOperátorralJutottamIde() függvénye mondja meg,
- // melyik lépést ajánlja a NegaMax módszer.
- // Ha zsákutcában van, akkor null-t ad vissza.
- public override JátékCsúcs MitLépjek(JátékCsúcs start)
- {
- Csúcs levél = MaxLépés(start, start.GetMélység() + maxMélység);
- if (levél == start) return null;
- while (levél.GetSzülő() != start) { levél = levél.GetSzülő(); }
- //levél.Kiir(); // Nyomkövetés esetén hasznos segítség
- return (JátékCsúcs)levél;
- }
- // Feltételezi, hogy a start csúcsban a kérdező játékos kérdezi, mit lépjen.
- // A kérdező játékos legjobb lépését, tehát a legnagyobb heurisztikájú
- // csúcs felé vezető lépést választja.
- // A gyermek csúcsok heurisztikáját NegaMax módszerrel számoljuk.
- private JátékCsúcs MaxLépés(JátékCsúcs start, int maxMélység)
- {
- JátékCsúcs akt = start;
- if (akt.GetMélység() == maxMélység) { return akt; }
- if (akt.TerminálisCsúcsE()) { return akt; }
- List<Csúcs> gyermekek = null;
- gyermekek = akt.Kiterjesztés();
- if (gyermekek.Count == 0) { return akt; }
- JátékCsúcs elsőGyermek = (JátékCsúcs)gyermekek[0];
- JátékCsúcs leg = MinLépés(elsőGyermek, maxMélység);
- int h = leg.GetMennyireJó(+1);
- for (int i = 1; i < gyermekek.Count; i++)
- {
- JátékCsúcs gyermek = (JátékCsúcs)gyermekek[i];
- JátékCsúcs legE = MinLépés(gyermek, maxMélység);
- int hE = legE.GetMennyireJó(+1);
- if (hE > h) { h = hE; leg = legE; }
- }
- return leg;
- }
- // Felételezi, hogy a start csúcsban a a kérdező játékos ellenfele lép.
- // Az ellenfél játékos legjobb lépését választja, tehát azt,
- // ami a kérdező játékosnak a legrosszabb.
- // Egybe lehetne vonni a MaxLépéssel, hiszen csak 5 helyen más.
- // Ezek a sorokat megjelöltük.
- private JátékCsúcs MinLépés(JátékCsúcs start, int maxMélység)
- {
- JátékCsúcs akt = start;
- if (akt.GetMélység() == maxMélység) { return akt; }
- if (akt.TerminálisCsúcsE()) { return akt; }
- List<Csúcs> gyermekek = null;
- gyermekek = akt.Kiterjesztés();
- if (gyermekek.Count == 0) { return akt; }
- JátékCsúcs elsőGyermek = (JátékCsúcs)gyermekek[0];
- JátékCsúcs leg = MaxLépés(elsőGyermek, maxMélység); //más
- int h = leg.GetMennyireJó(-1); // más
- for (int i = 1; i < gyermekek.Count; i++)
- {
- JátékCsúcs gyermek = (JátékCsúcs)gyermekek[i];
- JátékCsúcs legE = MaxLépés(gyermek, maxMélység); //más
- int hE = legE.GetMennyireJó(-1); //más
- if (hE < h) { h = hE; leg = legE; } //más
- }
- return leg;
- }
- }
- // Egy játékot vezényel le.
- // Ez egybevonható a főprogramból, hiszen abból emeltük ki.
- class Játék
- {
- AbsztraktÁllapot startÁllapot;
- Stratégia strat;
- public Játék(AbsztraktÁllapot startÁllapot, Stratégia strat)
- {
- this.startÁllapot = startÁllapot;
- this.strat = strat;
- }
- private int[] bekérés(MalomÁllapot akt)
- {
- if (akt.fázis == 1)
- {
- Console.WriteLine("Fehér játékos, add meg, hogy hová szeretnéd a {0}. bábudat elhelyezni a táblán:", akt.fehérBábukTáblán + 1);
- Console.WriteLine("1: belső négyzet, 2: középső négyzet, 3: külső négyzet");
- int négyzet = int.Parse(Console.ReadLine());
- Console.WriteLine("Add meg a négyzeten belüli pozíciót (1-8 -- bal felső sarokból, óramutató járásával megegyező irányban növekszik):");
- int pozíció = int.Parse(Console.ReadLine());
- int[] adatok = new int[4];
- adatok[0] = akt.fehérBábukTáblán; //bábu index (hanyadik báburól van szó, azaz amit majd lerakunk
- adatok[1] = négyzet - 1; //négyzet pozíció
- adatok[2] = pozíció - 1; //négyzeten belüli pozíció
- adatok[3] = 0;
- return adatok;
- }
- else if (akt.fázis == 2)
- {
- Console.WriteLine("Add meg a bábu nevét, amelyikkel lépni szeretnél (és tudsz is) :");
- string babunev = Console.ReadLine();
- Console.WriteLine("Add meg, hogy hova szeretnél lépni vele (négyzet, 1-3) :");
- int negyzet = int.Parse(Console.ReadLine());
- Console.WriteLine("Add meg, hogy hova szeretnél lépni vele (négyzeten belüli pozíció, 1-8) :");
- int pozicio = int.Parse(Console.ReadLine());
- int babuindex = -1;
- for (int i = 0; i < akt.fehérbábuk.Length; i++)
- {
- if (babunev == akt.fehérbábuk[i].név) babuindex = i;
- }
- int[] adatok = new int[4];
- adatok[0] = babuindex;
- adatok[1] = negyzet - 1;
- adatok[2] = pozicio - 1;
- adatok[3] = 0; // temporary
- return adatok;
- }
- else if (akt.fázis == 3)
- {
- Console.WriteLine("Add meg a bábu nevét, amelyikkel ugrani szeretnél egy tetszőleges mezőre (és tudsz is) :");
- string babunev = Console.ReadLine();
- Console.WriteLine("Add meg, hogy hova szeretnél ugrani vele (négyzet, 1-3) :");
- int negyzet = int.Parse(Console.ReadLine());
- Console.WriteLine("Add meg, hogy hova szeretnél ugrani vele (négyzeten belüli pozíció, 1-8) :");
- int pozicio = int.Parse(Console.ReadLine());
- int babuindex = -1;
- for (int i = 0; i < akt.fehérbábuk.Length; i++)
- {
- if (babunev == akt.fehérbábuk[i].név) babuindex = i;
- }
- int[] adatok = new int[4];
- adatok[0] = babuindex;
- adatok[1] = negyzet - 1;
- adatok[2] = pozicio - 1;
- adatok[3] = 0; // temporary
- return adatok;
- }
- return null;
- } //bekérés függvény vége
- public void start()
- {
- JátékCsúcs akt = new JátékCsúcs(startÁllapot);
- Console.WriteLine("Játszhat a gép ellen!");
- while (!akt.TerminálisCsúcsE())
- {
- // Ellenfél lépése.
- Console.WriteLine("Jelenlegi állás: {0}", akt);
- akt = strat.MitLépjek(akt);
- int i = akt.GetMelyikOperátorralJutottamIde();
- Console.WriteLine("A gép ezt az operátort választotta: {0}", i);
- // Nyertes állás?
- if (akt.TerminálisCsúcsE()) break;
- // Saját lépésem.
- bool b = false;
- while (!b)
- {
- Console.WriteLine("Jelenlegi állás: {0}", akt);
- Console.WriteLine("Melyik operátort választja? (0,..,{0}): ", akt.OperátorokSzáma() - 1);
- int k = akt.OperátorokSzáma() - 1;
- try
- {
- //k = int.Parse(Console.ReadLine());
- int[] tomb = bekérés(startÁllapot as MalomÁllapot);
- // a b c d - d + c*9 + b*8*9 + a*3*8*9
- k = tomb[0] * 3 * 8 * 9 + tomb[1] * 8 * 9 + tomb[2] * 9 + tomb[3];
- }
- catch (Exception e)
- {
- Console.WriteLine("Hiba: {0}", e.ToString());
- Console.WriteLine("Érvénytelen lépés. Újra!");
- continue;
- }
- b = akt.SzuperOperátor(k);
- if (!b) Console.WriteLine("Ez az operátor nem alkalmazható. Újra!");
- }
- }
- Console.WriteLine("Jelenlegi állás: {0}", akt);
- Console.WriteLine("Aki utoljára lépett, az nyert, vagy döntetlen.");
- }
- }
- // Főprogram.
- class Program
- {
- static void Main(string[] args)
- {
- Stratégia stratégia = new NegaMaxMódszer(5); // 5 mélységbe tekint előre
- //AbsztraktÁllapot startFejben21Állapot = new Fejben21Állapot();
- //Játék fejben21 = new Játék(startFejben21Állapot, strat);
- //Console.WriteLine("A Fejben 21 játék kezdetét veszi!");
- //fejben21.start();
- //Console.ReadLine();
- var startMalomÁllapot = new MalomÁllapot();
- var malom = new Játék(startMalomÁllapot, stratégia);
- malom.start();
- Console.ReadLine();
- }
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment