public int heuristic_crni(int dubina) { Koordinate beliKralj = NadjiFiguru(Tip.BeliKralj, this); Koordinate beliTop = NadjiFiguru(Tip.BeliTop, this); Koordinate crniKralj = NadjiFiguru(Tip.CrniKralj, this); double bonus = 0, penalty = 0; if (DaLiJeMat()) { penalty += 1000 / Math.Abs(dubina) + 1; } else if (DaLiJePat()) { bonus += 1000 / Math.Abs(dubina) + 1; } if (DalijeNapadnut(Tip.CrniKralj)) { penalty += 500; } if (ChebyshevDistance(crniKralj.x, crniKralj.y, beliTop.x, beliTop.y) == 1) { bonus += 250; } if (ChebyshevDistance(crniKralj.x, crniKralj.y, beliKralj.x, beliKralj.y) == 1) { bonus += 10; } int brojPoteza = FinalnaListaMogucihPoteza(this, new Potez(crniKralj.x, crniKralj.y)).Count; int CK_CMD = CMD[crniKralj.x, crniKralj.y]; double BT_CK_diff = Math.Abs(Math.Abs(crniKralj.y - beliTop.y) - Math.Abs(crniKralj.x - beliTop.x)); double vrati = (-9.3 * BT_CK_diff - 5.7 * CK_CMD + (10 * brojPoteza / (CK_CMD + 1)) + penalty - bonus) * 200; return((int)vrati); }
public bool DaLiJePat() { Koordinate crniKralj = NadjiFiguru(Tip.CrniKralj, this); if (FinalnaListaMogucihPoteza(this, new Potez(crniKralj.x, crniKralj.y)).Count == 0) { return(true); } return(false); }
/// <summary> /// Da li je kraj igre /// </summary> /// <returns></returns> public bool DaLiJeKraj() { Koordinate crniKralj = NadjiFiguru(Tip.CrniKralj, this); if (FinalnaListaMogucihPoteza(this, new Potez(crniKralj.x, crniKralj.y)).Count == 0) { if (!DalijeNapadnut(Tip.BeliTop)) { return(true); } } return(false); }
/// <summary> /// Vraca koordinate jedne trazene figure /// </summary> /// <param name="tip"></param> /// <param name="ctx"></param> /// <returns></returns> public Koordinate NadjiFiguru(Tip tip, Context ctx) { Koordinate retVal = new Koordinate(-10, -10); for (int i = 0; i < 8; i++) { for (int j = 0; j < 8; j++) { if (ctx.Stanje.matrica[i, j] == (int)tip) { retVal = new Koordinate(i, j); } } } return(retVal); }
private void btnIgraj_Click(object sender, EventArgs e) { if (kontekst.naPotezu == (int)Igra.Beli) { Potez p = kontekst.AlphaBeta(kontekst, 4, int.MinValue, int.MaxValue); lblPotezi.Text = Context.i.ToString(); Context.i = 0; Koordinate mestoFigureKojaIgra = kontekst.NadjiFiguru(p.tipFigure, kontekst); Koordinate beliTop = kontekst.NadjiFiguru(Tip.BeliTop, kontekst); Context context = new Context(kontekst); context.UradiPotez(new Potez(mestoFigureKojaIgra.x, mestoFigureKojaIgra.y), p); if (!context.DalijeNapadnut(Tip.BeliTop)) { kontekst.UradiPotez(new Potez(mestoFigureKojaIgra.x, mestoFigureKojaIgra.y), p); } else { List <Potez> listaFigureKojaIgra = kontekst.FinalnaListaMogucihPoteza(kontekst, new Potez(beliTop.x, beliTop.y)); if (listaFigureKojaIgra.Contains(new Potez(beliTop.x, 0))) { kontekst.UradiPotez(new Potez(beliTop.x, beliTop.y), new Potez(beliTop.x, 0)); } else { kontekst.UradiPotez(new Potez(beliTop.x, beliTop.y), new Potez(beliTop.x, 7)); } } Refresh(); label1.Text = kontekst.DalijeNapadnut(Tip.CrniKralj).ToString(); label3.Text = kontekst.DalijeNapadnut(Tip.BeliTop).ToString(); if (kontekst.DaLiJeKraj()) { if (kontekst.DaLiJeMat()) { MessageBox.Show("MAT!"); } else if (kontekst.DaLiJePat()) { MessageBox.Show("PAT!"); } kontekst.Seralization(Context.transposTable); MessageBox.Show("Serijalizacija transpozicione tabele uspesna!"); } } else { Context.i = 0; Potez p = kontekst.AlphaBeta(kontekst, 4, int.MinValue, int.MaxValue); lblPotezi.Text = Context.i.ToString(); Koordinate mestoFigureKojaIgra = kontekst.NadjiFiguru(p.tipFigure, kontekst); kontekst.UradiPotez(new Potez(mestoFigureKojaIgra.x, mestoFigureKojaIgra.y), p); Refresh(); label1.Text = kontekst.DalijeNapadnut(Tip.CrniKralj).ToString(); label3.Text = kontekst.DalijeNapadnut(Tip.BeliTop).ToString(); if (kontekst.DaLiJeKraj()) { if (kontekst.DaLiJeMat()) { MessageBox.Show("MAT!"); } else if (kontekst.DaLiJePat()) { MessageBox.Show("PAT!"); } kontekst.Seralization(Context.transposTable); MessageBox.Show("Serijalizacija transpozicione tabele uspesna!"); } } }
/// <summary> /// Proverava da li je unesen Tip figure napadnut /// </summary> /// <returns></returns> public bool DalijeNapadnut(Tip tip) { Koordinate koordinate = NadjiFiguru(tip, this); int x = koordinate.x; int y = koordinate.y; if (Stanje.matrica[x, y] == 1)//provera za crnog kralja { Koordinate beliKralj = NadjiFiguru(Tip.BeliKralj, this); Koordinate beliTop = NadjiFiguru(Tip.BeliTop, this); List <Potez> listaBelogTopa = FinalnaListaMogucihPoteza(this, new Potez(beliTop.x, beliTop.y)); int dwkbk = ChebyshevDistance(beliKralj.x, beliKralj.y, koordinate.x, koordinate.y); int dwrbk = ChebyshevDistance(beliTop.x, beliTop.y, koordinate.x, koordinate.y); if (koordinate.x == beliTop.x) { if (koordinate.x != beliKralj.x) { return(true); } else { if ((beliKralj.y < koordinate.y && koordinate.y < beliTop.y) || (beliTop.y < koordinate.y && koordinate.y < beliKralj.y)) { return(true); } else { if (dwrbk < dwkbk) { return(true); } } return(false); } } if (koordinate.y == beliTop.y) { if (koordinate.y != beliKralj.y) { return(true); } else { if ((beliKralj.x < koordinate.x && koordinate.x < beliTop.x) || (beliTop.x < koordinate.x && koordinate.x < beliKralj.x)) { return(true); } else { if (dwrbk < dwkbk) { return(true); } } return(false); } } if (ChebyshevDistance(beliKralj.x, beliKralj.y, koordinate.x, koordinate.y) == 1) //ovo nikad nece da se bude true { return(true); } } else //provera belog topa { Koordinate crniKralj = NadjiFiguru(Tip.CrniKralj, this); Koordinate beliKralj = NadjiFiguru(Tip.BeliKralj, this); if (ChebyshevDistance(crniKralj.x, crniKralj.y, koordinate.x, koordinate.y) == 1) { if (ChebyshevDistance(beliKralj.x, beliKralj.y, koordinate.x, koordinate.y) != 1) { return(true); } } } return(false); }
public Potez AlphaBeta(Context ctx, int depth, int alpha, int beta) { Potez najbolji = new Potez(); //ovaj potez vraca funkcija Potez pom = new Potez(); Context.i++; if (depth == 0 || ctx.DaLiJeKraj()) { najbolji.Value = ctx.Evaluate(depth - 4); return(najbolji); } Potez trenutnoMesto; Koordinate trenutneKoordinate; List <Potez> listaPoteza = new List <Potez>(); List <Potez> listaKralja = new List <Potez>(); List <Potez> listaTopa = new List <Potez>(); Koordinate beliKralj = NadjiFiguru(Tip.BeliKralj, ctx); Koordinate beliTop = NadjiFiguru(Tip.BeliTop, ctx); Koordinate crniKralj = NadjiFiguru(Tip.CrniKralj, ctx); if (ctx.naPotezu == (int)Igra.Beli) { listaKralja = FinalnaListaMogucihPoteza(ctx, new Potez(beliKralj.x, beliKralj.y)); listaTopa = FinalnaListaMogucihPoteza(ctx, new Potez(beliTop.x, beliTop.y)); listaPoteza.AddRange(listaTopa); listaPoteza.AddRange(listaKralja); } else { listaPoteza = FinalnaListaMogucihPoteza(ctx, new Potez(crniKralj.x, crniKralj.y)); } int v; if (ctx.naPotezu == (int)Igra.Beli) { v = int.MinValue; foreach (Potez pot in listaPoteza) { trenutneKoordinate = NadjiFiguru(pot.tipFigure, ctx); trenutnoMesto = new Potez(trenutneKoordinate.x, trenutneKoordinate.y); Context zaProsledjivanje = new Context(ctx); zaProsledjivanje.UradiPotez(trenutnoMesto, pot); if (transposTable.Contains(zaProsledjivanje.hashFunction() + zaProsledjivanje.hash2() + zaProsledjivanje.GetHashCode())) { int hash = (int)transposTable[zaProsledjivanje.hashFunction() + zaProsledjivanje.hash2() + zaProsledjivanje.GetHashCode()]; najbolji.Value = hash; return(najbolji); } pom = AlphaBeta(zaProsledjivanje, depth - 1, alpha, beta); if (v < pom.Value) { v = pom.Value; najbolji = pot; najbolji.Value = v; alpha = Math.Max(alpha, v); } if (beta <= alpha) { break; } } if (!transposTable.Contains(ctx.hashFunction() + ctx.hash2() + ctx.GetHashCode())) { transposTable.Add(ctx.hashFunction() + ctx.hash2() + ctx.GetHashCode(), najbolji.Value); } return(najbolji); } else { v = int.MaxValue; foreach (Potez pot in listaPoteza) { trenutneKoordinate = NadjiFiguru(Tip.CrniKralj, ctx); trenutnoMesto = new Potez(trenutneKoordinate.x, trenutneKoordinate.y); Context zaProsledjivanje = new Context(ctx); zaProsledjivanje.UradiPotez(trenutnoMesto, pot); if (transposTable.Contains(zaProsledjivanje.hashFunction() + zaProsledjivanje.hash2() + zaProsledjivanje.GetHashCode())) { int hash = (int)transposTable[zaProsledjivanje.hashFunction() + zaProsledjivanje.hash2() + zaProsledjivanje.GetHashCode()]; najbolji.Value = hash; return(najbolji); } pom = AlphaBeta(zaProsledjivanje, depth - 1, alpha, beta); if (v > pom.Value) { v = pom.Value; najbolji = pot; najbolji.Value = v; beta = Math.Min(beta, v); } if (beta <= alpha) { break; } } if (!transposTable.Contains(ctx.hashFunction() + ctx.hash2() + ctx.GetHashCode())) { transposTable.Add(ctx.hashFunction() + ctx.hash2() + ctx.GetHashCode(), najbolji.Value); } return(najbolji); } }
/// <summary> /// Kreira konacnu listu mogucih poteza koje figura moze odigradi /// </summary> /// <param name="ctx"></param> /// <param name="trenutneKoordinate"></param> /// <returns></returns> public List <Potez> FinalnaListaMogucihPoteza(Context ctx, Potez trenutneKoordinate) { List <Potez> listaZaVracanje = new List <Potez>(); List <Potez> listaNedozvoljenihPoteza = new List <Potez>(); Tip figura = (Tip)ctx.Stanje.matrica[trenutneKoordinate.x, trenutneKoordinate.y]; Koordinate beliKralj = NadjiFiguru(Tip.BeliKralj, ctx); Koordinate beliTop = NadjiFiguru(Tip.BeliTop, ctx); Koordinate crniKralj = NadjiFiguru(Tip.CrniKralj, ctx); //kreira listu svih poteza za figuru listaZaVracanje = ctx.listaMogucihPoteza(figura, trenutneKoordinate); switch (figura) { case Tip.CrniKralj: //treba da nadje polja koja napadaju beli kralj i top List <Potez> listaNedozvoljenihPotezaKralj = new List <Potez>(); List <Potez> listaNedozvoljenihPotezaTop = new List <Potez>(); listaNedozvoljenihPotezaKralj = listaMogucihPoteza(Tip.BeliKralj, new Potez(beliKralj.x, beliKralj.y)); listaNedozvoljenihPotezaTop = listaMogucihPoteza(Tip.BeliTop, new Potez(beliTop.x, beliTop.y)); if (beliKralj.x == beliTop.x || beliKralj.y == beliTop.y) { List <Potez> blokiraniPotezi = new List <Potez>(); if (beliKralj.x == beliTop.x) { if (beliKralj.y < beliTop.y) { for (int i = 0; i <= beliKralj.y; blokiraniPotezi.Add(new Potez(beliKralj.x, i++))) { ; } } else { for (int i = 7; i >= beliKralj.y; blokiraniPotezi.Add(new Potez(beliKralj.x, i--))) { ; } } } else if (beliKralj.y == beliTop.y) { if (beliKralj.x < beliTop.x) { for (int i = 0; i <= beliKralj.x; blokiraniPotezi.Add(new Potez(i++, beliKralj.y))) { ; } } else { for (int i = 7; i >= beliKralj.x; blokiraniPotezi.Add(new Potez(i--, beliKralj.y))) { ; } } } listaNedozvoljenihPotezaTop = listaNedozvoljenihPotezaTop.Except(blokiraniPotezi).ToList(); } listaNedozvoljenihPoteza.AddRange(listaNedozvoljenihPotezaKralj); listaNedozvoljenihPoteza.AddRange(listaNedozvoljenihPotezaTop); break; case Tip.BeliKralj: //treba da nadje polja koja napada crni kralj listaNedozvoljenihPoteza = listaMogucihPoteza(Tip.CrniKralj, new Potez(crniKralj.x, crniKralj.y)); break; case Tip.BeliTop: //treba da nadje polja koja napada crni kralj, a ne stiti beli kralj //i da mu onemoguci da preskace belog kralja listaNedozvoljenihPoteza = listaMogucihPoteza(Tip.CrniKralj, new Potez(crniKralj.x, crniKralj.y)); List <Potez> kretanjeBelogKralja = listaMogucihPoteza(Tip.BeliKralj, new Potez(beliKralj.x, beliKralj.y)); listaNedozvoljenihPoteza = listaNedozvoljenihPoteza.Except(kretanjeBelogKralja).ToList(); //proverava da li beli kralj blokira kretanje topa if (beliKralj.x == beliTop.x) { if (beliKralj.y < beliTop.y) { for (int i = 0; i <= beliKralj.y; listaNedozvoljenihPoteza.Add(new Potez(beliKralj.x, i++))) { ; } } else { for (int i = 7; i >= beliKralj.y; listaNedozvoljenihPoteza.Add(new Potez(beliKralj.x, i--))) { ; } } } else if (beliKralj.y == beliTop.y) { if (beliKralj.x < beliTop.x) { for (int i = 0; i <= beliKralj.x; listaNedozvoljenihPoteza.Add(new Potez(i++, beliKralj.y))) { ; } } else { for (int i = 7; i >= beliKralj.x; listaNedozvoljenihPoteza.Add(new Potez(i--, beliKralj.y))) { ; } } } break; } //iz liste mogucih poteza brise sve nedozvoljene poteze //u klasi potez funkcije Equals i GetHashCode su override-ovane da bi Except mogao da poredi poteze listaZaVracanje = listaZaVracanje.Except(listaNedozvoljenihPoteza).ToList(); return(listaZaVracanje); }