public Solmu PuuPolitiikka(Solmu nykyinenSolmu) { nykyinenSolmu.Vierailut++; if (_peliLauta.TarkistaLoppuikoPeliTallaSiirrolla(nykyinenSolmu.X, nykyinenSolmu.Y, pelimerkinVari)) return nykyinenSolmu; if (!nykyinenSolmu.TaysinLaajennettu) { var laajennuksessaLuotuSolmu = nykyinenSolmu.Laajenna(); if (laajennuksessaLuotuSolmu != null) { laajennuksessaLuotuSolmu.Vierailut++; return laajennuksessaLuotuSolmu; } } nykyinenSolmu = EtsiParasLapsi(nykyinenSolmu); while (nykyinenSolmu.Vierailut > 0) { nykyinenSolmu.Vierailut++; if (_peliLauta.TarkistaLoppuikoPeliTallaSiirrolla(nykyinenSolmu.X, nykyinenSolmu.Y, pelimerkinVari)) return nykyinenSolmu; if (!nykyinenSolmu.TaysinLaajennettu) { var laajennuksessaLuotuSolmu = nykyinenSolmu.Laajenna(); if(laajennuksessaLuotuSolmu != null) return laajennuksessaLuotuSolmu; } nykyinenSolmu = EtsiParasLapsi(nykyinenSolmu); } return nykyinenSolmu; }
public void Init() { mcts = new Mcts(onkoPelaajanPelimerkkiValkoinen: true); solmu = new Solmu(new bool?[15, 15], new Koordinaatit(0, 1), merkinVari: true) { Vierailut = 36 }; solmu2 = new Solmu(new bool?[15, 15], new Koordinaatit(0, 6), merkinVari: true) { Vierailut = 360 }; lapsi1 = new Solmu(new bool?[15, 15], new Koordinaatit(5, 2), merkinVari: false) { Vierailut = 3, Pisteet = 0.5f }; lapsi2 = new Solmu(new bool?[15, 15], new Koordinaatit(9, 3), merkinVari: true) { Vierailut = 10, Pisteet = 0.3f }; lapsi3 = new Solmu(new bool?[15, 15], new Koordinaatit(4, 4), merkinVari: false) { Vierailut = 20, Pisteet = 0.99f }; lapsi4 = new Solmu(new bool?[15, 15], new Koordinaatit(12, 5), merkinVari: true) { Vierailut = 9, Pisteet = 0.1f }; solmu2lapsi1 = new Solmu(new bool?[15, 15], new Koordinaatit(9, 5), merkinVari: true) { Vierailut = 500, Pisteet = 0.1f }; mcts.PeliLauta.Lauta[0, 1] = true; mcts.PeliLauta.Lauta[5, 2] = false; mcts.PeliLauta.Lauta[9, 3] = true; mcts.PeliLauta.Lauta[4, 4] = false; mcts.PeliLauta.Lauta[12, 5] = true; mcts.Juuri.Lapsi = solmu; mcts.Juuri.LisaaLapselleSisarus(solmu2); solmu2.Lapsi = solmu2lapsi1; solmu.Lapsi = lapsi1; solmu.LisaaLapselleSisarus(lapsi2); solmu.LisaaLapselleSisarus(lapsi3); solmu.LisaaLapselleSisarus(lapsi4); }
public void TestEtsiParasLapsi_LoytyyLapsiJossaEiVierailtu_PalautetaanSe() { var lapsi5 = new Solmu(new bool?[15, 15], new Koordinaatit(0, 2), false) { Vierailut = 0, Pisteet = 0.0f }; solmu.Lapsi.Sisarukset.AddFirst(lapsi5); var tulos = mcts.EtsiParasLapsi(solmu); Assert.IsTrue(lapsi5 == tulos); }
public void TestEtsiParasLapsi_EnsimmaisessaLapsessaEiVierailtu_PalautetaanSe() { var lapsi5 = new Solmu(new bool?[15, 15], new Koordinaatit(0, 2), false) { Vierailut = 0, Pisteet = 0.0f }; solmu.Lapsi = lapsi5; var tulos = mcts.EtsiParasLapsi(solmu); Assert.IsTrue(lapsi5 == tulos); }
public Solmu EtsiParasLapsi(Solmu solmu) { double parasTulos = 0; Solmu parasSolmu = null; //ensimmäinen lapsi on erikoisasemassa kun käytetään linked listiä if (solmu.Lapsi.Vierailut == 0) return solmu.Lapsi; SelvitaSolmunArvo(solmu, solmu.Lapsi, ref parasTulos, ref parasSolmu); foreach (var jalkelainen in solmu.Lapsi.Sisarukset) { //jokaisessa jälkeläisessä täytyy vierailla ainakin kerran if (jalkelainen.Vierailut == 0) return jalkelainen; SelvitaSolmunArvo(solmu, jalkelainen, ref parasTulos, ref parasSolmu); } return parasSolmu; }
public void LisaaLapselleSisarus(Solmu uusiLapsi) { lapsi.sisarukset.AddFirst(uusiLapsi); }
public Mcts(bool onkoPelaajanPelimerkkiValkoinen) { pelimerkinVari = onkoPelaajanPelimerkkiValkoinen; _peliLauta = new PeliLauta(); _juuri = new Solmu(_peliLauta.Lauta, 7, 7, merkinVari: false, onkoJuuri: true); //pelin ensimmäinen siirto }
private void VaihdaJuuri(Solmu uusiJuuri) { _juuri = uusiJuuri; _juuri.Juurisolmu = true; _juuri.Sisarukset = null; }
private void PaivitaEdellisenLisätynLapsenPaikka(Solmu uusiLapsi) { if (edellisenLisatynSuunta == Suunta.Oikealle) { //Hakusuunta vuorottelee edellisenLisatynSuunta = Suunta.Vasemmalle; edellisenVasemmaltaLisätynLapsenPaikka = new Koordinaatit(uusiLapsi.X, uusiLapsi.Y); return; } //Hakusuunta vuorottelee edellisenLisatynSuunta = Suunta.Oikealle; edellisenOikealtaLisätynLapsenPaikka = new Koordinaatit(uusiLapsi.X, uusiLapsi.Y); }
private void SelvitaSolmunArvo(Solmu solmu, Solmu jalkelainen, ref double parasTulos, ref Solmu parasSolmu) { var solmunArvo = LaskeUcbArvo(solmu, jalkelainen); if (!(solmunArvo > parasTulos)) return; //todo entä jos monella solmulla sama arvo? Ei kai merkittävää vaikutusta? parasTulos = solmunArvo; parasSolmu = jalkelainen; }
private double LaskeUcbArvo(Solmu solmu, Solmu jalkelainen) { return (jalkelainen.Pisteet / jalkelainen.Vierailut) + (C * (Math.Sqrt((2 * Math.Log(solmu.Vierailut)) / jalkelainen.Vierailut))); }
public void PelaaPeliLoppuunSatunnaisillaSiirroillaTest() { const bool pelaajanPelimerkinVari = true; testiLauta[6, 6] = pelaajanPelimerkinVari; var solmunSijainti = new Koordinaatit(6, 6); var solmu = new Solmu(testiLauta, solmunSijainti, pelaajanPelimerkinVari); var tulos = lauta.PelaaPeliLoppuunSatunnaisillaSiirroilla(solmu, pelaajanPelimerkinVari); if(tulos != 1 && tulos != -1) Assert.Fail("Väärä tulos: " + tulos); }
public void TestPuupolitiikka_SolmullaEiLapsia() { var ainoaSolmu = new Solmu(mcts.PeliLauta.Lauta, new Koordinaatit(0, 0), false) { Vierailut = 0, Pisteet = 0.0f }; var tulos = mcts.PuuPolitiikka(ainoaSolmu); Assert.AreEqual(ainoaSolmu.Lapsi, tulos); }
private Solmu EtsiUusiLapsi() { var uudenLapsenSijainti = EtsiSeuraavaMahdollinenSiirto(); if (uudenLapsenSijainti == null) { taysinLaajennettu = true; return null; } if (OnkoKaikkiLapsetEtsitty(uudenLapsenSijainti)) { taysinLaajennettu = true; return null; } var paivitettyPelinTila = LuoUusiPelinTilaUudellaSiirrolla(uudenLapsenSijainti); //pitää kääntää väri koska gomokussa vuorottelee musta ja valkoinen var uusiLapsi = new Solmu(paivitettyPelinTila, uudenLapsenSijainti, !peliMerkinVari); LisaaUusiLapsiSolmulle(uusiLapsi); return uusiLapsi; }
private int Simulointi(Solmu nykyinenSolmu) { return _peliLauta.PelaaPeliLoppuunSatunnaisillaSiirroilla(nykyinenSolmu, this.pelimerkinVari); }
private void LisaaUusiLapsiSolmulle(Solmu uusiLapsi) { if (lapsi == null) lapsi = uusiLapsi; else { LisaaLapselleSisarus(uusiLapsi); } uusiLapsi.Vanhempi = this; PaivitaEdellisenLisätynLapsenPaikka(uusiLapsi); }
private void Takaisinkuljetus(int tulos, Solmu nykyinenSolmu) { nykyinenSolmu.Pisteet += tulos; while (!nykyinenSolmu.Juurisolmu) { nykyinenSolmu = nykyinenSolmu.Vanhempi; nykyinenSolmu.Pisteet += tulos; } }
//public void KaynnistaPeli(Player pelaaja1, Player pelaaja2) //{ // //TODO onko tarpeellinen? // musta = pelaaja1; // valkoinen = pelaaja2; // TeeValkeaSiirto(valkoinen.TeeSiirto(lauta)); //} /// <summary> /// Palauttaa 1 jos funktiota kutsuvan pelaajan väri voitti, -1 jos hävisi ja 0 jos tasapeli /// </summary> public int PelaaPeliLoppuunSatunnaisillaSiirroilla(Solmu nykyinenSolmu, bool pelaajanMerkinVari) { var temppiLauta = KloonaaLauta(nykyinenSolmu.Lauta); var temppiVari = pelaajanMerkinVari; if (TarkistaLoppuikoPeliTallaSiirrolla(nykyinenSolmu.X, nykyinenSolmu.Y, nykyinenSolmu.PeliMerkinVari, temppiLauta)) { if (nykyinenSolmu.PeliMerkinVari == pelaajanMerkinVari) return pelaajaVoitti; return pelaajaHavisi; } var mahdollisetSiirrot = new List<Koordinaatit>(); EtsiKaikkiMahdollisetSiirrot(ref mahdollisetSiirrot, temppiLauta); while (mahdollisetSiirrot.Count > 0) { var tehtySiirto = TeeSatunnainenSiirto(mahdollisetSiirrot, temppiLauta, ref temppiVari); if (TarkistaLoppuikoPeliTallaSiirrolla(tehtySiirto.X, tehtySiirto.Y, !temppiVari, temppiLauta)) { //pelaaja voitti, pitää kääntää temppiVari jotta saadaan väri mikä aiemmassa askeleessa asetettiin if (!temppiVari == pelaajanMerkinVari) return pelaajaVoitti; return pelaajaHavisi; } EtsiKaikkiMahdollisetSiirrot(ref mahdollisetSiirrot, temppiLauta); } //Ei löydy enää mahdollisia siirtoja mutta myöskään voittosiirtoa ei tehty. Tuli siis tasapeli return tasapeli; }
public void Init() { lauta = new PeliLauta(); testiLauta = lauta.Lauta; testiLauta[4, 10] = true; var sijainti = new Koordinaatit(4, 10); const bool valkoinenVari = true; const bool mustaVari = false; solmu = new Solmu(testiLauta, sijainti, valkoinenVari); juuri = new Solmu(new PeliLauta().Lauta, 7, 7, mustaVari, onkoJuuri: true); }