Exemplo n.º 1
0
 def vrednost_pozicije(self):
     """Ocena vrednosti pozicije: sešteje vrednosti vseh štiric na plošči."""
     # Slovar, ki pove, koliko so vredne posamezne štirke, kjer "(x,y) : v" pomeni:
     # če imamo v stirici x znakov igralca in y znakov nasprotnika (in 4-x-y praznih polj),
     # potem je taka štirka za self.jaz vredna v.
     # Štirke, ki se ne pojavljajo v slovarju, so vredne 0.
     vrednost_stirice = {
         (4, 0): Minimax.ZMAGA,
         (0, 4): -Minimax.ZMAGA,
         (3, 0): Minimax.ZMAGA // 100,
         (0, 3): -Minimax.ZMAGA // 100,
         (2, 0): Minimax.ZMAGA // 10000,
         (0, 2): -Minimax.ZMAGA // 10000,
         (1, 0): Minimax.ZMAGA // 100000,
         (0, 1): -Minimax.ZMAGA // 100000
     }
     vrednost = 0
     for t in self.igra.stirice:
         x = 0  # Koliko jih imam jaz v štirici t
         y = 0  # Koliko jih ima nasprotnik v štirici t
         for (i, j) in t:
             if self.igra.stolpci[i][j] == self.jaz:
                 x += 1
             elif self.igra.stolpci[i][j] == nasprotnik(self.jaz):
                 y += 1
         vrednost += vrednost_stirice.get((x, y), 0)
     return vrednost
Exemplo n.º 2
0
 def vrednost_pozicije(self):
     """Ocena vrednosti pozicije: sešteje vrednosti vseh trojk na plošči."""
     # Slovar, ki pove, koliko so vredne posamezne trojke, kjer "(x,y) : v" pomeni:
     # če imamo v trojki x znakov igralca in y znakov nasprotnika (in 3-x-y praznih polj),
     # potem je taka trojka za self.jaz vredna v.
     # Trojke, ki se ne pojavljajo v slovarju, so vredne 0.
     vrednost_trojke = {
         (4,0) : ZMAGA,
         (0,4) : -ZMAGA//10,
         (3,0) : ZMAGA//100,
         (0,3) : -ZMAGA//1000,
         (2,0) : ZMAGA//10000,
         (0,2) : -ZMAGA//100000,
         (1,0) : ZMAGA//1000000,
         (0,1) : -ZMAGA//10000000
     }
     vrednost = 0
     for t in self.igra.trojke:
         x = 0
         y = 0
         for (j,i) in t:
             if self.igra.polje[j][i] == self.jaz:
                 x += 1
             elif self.igra.polje[j][i] == nasprotnik(self.jaz):
                 y += 1
         vrednost += vrednost_trojke.get((x,y), 0)
     return vrednost
Exemplo n.º 3
0
    def minimax(self, globina, maksimiziramo, alfa = -NESKONCNO, beta = NESKONCNO):
        """Glavna metoda minimax."""
        if self.prekinitev:
            # Sporočili so nam, da moramo prekiniti
            logging.debug ("Minimax prekinja, globina = {0}".format(globina))
            return (None, 0)
        (zmagovalec, lst) = self.igra.stanje_igre()
        if zmagovalec in (IGRALEC_M, IGRALEC_R, NEODLOCENO):
            # Igre je konec, vrnemo njeno vrednost
            if zmagovalec == self.jaz:
                return (None, ZMAGA)
            elif zmagovalec == nasprotnik(self.jaz):
                return (None, -ZMAGA)
            else:
                return (None, 0)
        elif zmagovalec == NI_KONEC:
            # Igre ni konec
            if globina == 0:
                return (None, self.vrednost_pozicije())
            else:
                # Naredimo eno stopnjo minimax
                if maksimiziramo:
                    # Maksimiziramo
                    najboljsa_poteza = None
                    vrednost = -NESKONCNO
                    #print(self.igra.veljavne_poteze())
                    for i, j in self.igra.veljavne_poteze()[::random.choice([1,-1])]:
                        
                        #######UPORABI PRAVO POLJE, DA BO VEDELO V KATERO VRSTICO POVLEČTI POTEZO!!!!#######
                        self.igra.povleci_potezo(i)
                        if vrednost < self.minimax(globina-1, not maksimiziramo, alfa, beta)[1]:
                            najboljsa_poteza = (j, i)
                            vrednost = self.minimax(globina-1, not maksimiziramo, alfa, beta)[1]
                        self.igra.razveljavi()
                        alfa = max(alfa, vrednost)
                        if beta <= alfa:
                            break

                else:
                    # Minimiziramo
                    najboljsa_poteza = None
                    vrednost = NESKONCNO
                    #print(self.igra.veljavne_poteze())
                    for i, j in self.igra.veljavne_poteze()[::random.choice([1,-1])]:
                        self.igra.povleci_potezo(i)
                        if vrednost > self.minimax(globina-1, maksimiziramo, alfa, beta)[1]:
                            najboljsa_poteza = (j, i)
                            vrednost = self.minimax(globina-1, maksimiziramo, alfa, beta)[1]
                        self.igra.razveljavi()
                        beta = min(beta, vrednost)
                        if beta <= alfa:
                            break

                assert (najboljsa_poteza is not None), "minimax: izračunana poteza je None"
                return (najboljsa_poteza, vrednost)
        else:
            assert False, "minimax: nedefinirano stanje igre"
Exemplo n.º 4
0
    def alfabeta(self, globina, alfa, beta, maksimiziramo):
        if self.prekinitev:
            logging.debug("Alfabeta prekinja, globina = {0}".format(globina))
            return (None, 0)

        (zmagovalec, stirica) = self.igra.stanje_igre()
        if zmagovalec in (MODRI, RDECI, NEODLOCENO):
            # Igre je konec, vrnemo njeno vrednost
            if zmagovalec == self.jaz:
                return (None, Alfabeta.ZMAGA)
            elif zmagovalec == nasprotnik(self.jaz):
                return (None, -Alfabeta.ZMAGA)
            else:
                return (None, 0)
        elif zmagovalec == NI_KONEC:
            # Igre ni konec
            if globina == 0:
                return (None, self.vrednost_pozicije())
            else:
                # Naredimo eno stopnjo alfabeta
                if maksimiziramo:
                    # Maksimiziramo
                    najboljsa_poteza = None
                    veljavne_poteze = self.igra.veljavne_poteze()
                    shuffle(veljavne_poteze)
                    for p in veljavne_poteze:
                        self.igra.povleci_potezo(p)
                        vrednost = self.alfabeta(globina - 1, alfa, beta,
                                                 not maksimiziramo)[1]
                        self.igra.razveljavi()
                        if vrednost > alfa:
                            alfa = vrednost
                            najboljsa_poteza = p
                        if alfa >= beta:
                            break
                    return (najboljsa_poteza, alfa)
                else:
                    # Minimiziramo
                    najboljsa_poteza = None
                    veljavne_poteze = self.igra.veljavne_poteze()
                    shuffle(veljavne_poteze)
                    for p in veljavne_poteze:
                        self.igra.povleci_potezo(p)
                        vrednost = self.alfabeta(globina - 1, alfa, beta,
                                                 not maksimiziramo)[1]
                        self.igra.razveljavi()
                        if vrednost < beta:
                            beta = vrednost
                            najboljsa_poteza = p
                        if alfa >= beta:
                            break
                    return (najboljsa_poteza, beta)

                assert (najboljsa_poteza
                        is not None), "alfabeta: izračunana poteza je None"
        else:
            assert False, "alfabeta: nedefinirano stanje igre"
Exemplo n.º 5
0
    def minimax(self, globina, maksimiziramo):
        if self.prekinitev:
            logging.debug("Minimax prekinja, globina = {0}".format(globina))
            return (None, 0)

        (zmagovalec, stirica) = self.igra.stanje_igre()
        if zmagovalec in (MODRI, RDECI, NEODLOCENO):
            # Igre je konec, vrnemo njeno vrednost
            if zmagovalec == self.jaz:
                return (None, Minimax.ZMAGA)
            elif zmagovalec == nasprotnik(self.jaz):
                return (None, -Minimax.ZMAGA)
            else:
                return (None, 0)
        elif zmagovalec == NI_KONEC:
            # Igre ni konec
            if globina == 0:
                return (None, self.vrednost_pozicije())
            else:
                # Naredimo eno stopnjo minimax
                if maksimiziramo:
                    # Maksimiziramo
                    najboljsa_poteza = None
                    vrednost_najboljse = -Minimax.NESKONCNO
                    veljavne_poteze = self.igra.veljavne_poteze()
                    # Veljavne poteze random premešamo, da ne bo računalnik v enaki sitauaciji vedno odigral enako
                    shuffle(veljavne_poteze)
                    for p in veljavne_poteze:
                        self.igra.povleci_potezo(p)
                        vrednost = self.minimax(globina - 1,
                                                not maksimiziramo)[1]
                        self.igra.razveljavi()
                        if vrednost > vrednost_najboljse:
                            vrednost_najboljse = vrednost
                            najboljsa_poteza = p
                else:
                    # Minimiziramo
                    najboljsa_poteza = None
                    vrednost_najboljse = Minimax.NESKONCNO
                    veljavne_poteze = self.igra.veljavne_poteze()
                    # Veljavne poteze random premešamo, da ne bo računalnik v enaki sitauaciji vedno odigral enako
                    shuffle(veljavne_poteze)
                    for p in veljavne_poteze:
                        self.igra.povleci_potezo(p)
                        vrednost = self.minimax(globina - 1,
                                                not maksimiziramo)[1]
                        self.igra.razveljavi()
                        if vrednost < vrednost_najboljse:
                            vrednost_najboljse = vrednost
                            najboljsa_poteza = p

                assert (najboljsa_poteza
                        is not None), "minimax: izračunana poteza je None"
                return (najboljsa_poteza, vrednost_najboljse)
        else:
            assert False, "minimax: nedefinirano stanje igre"
Exemplo n.º 6
0
 def neumna_cenilka(self):
     """Vsem potezam priredi enako vrednost, razen, če je konec igre."""
     (konec_ali_ne, na_vrsti) = self.igra.trenutno_stanje()
     if konec_ali_ne == KONEC_IGRE:
         # Igre je konec, vrnemo njeno vrednost
         if na_vrsti == self.jaz:
             return ZMAGA
         elif na_vrsti == nasprotnik(self.jaz):
             return -ZMAGA
         elif na_vrsti is None:
             return -ZMAGA + 1  # remi
     else:
         return 3  # naključno izbrana vrednost, važno da je za vse enaka
Exemplo n.º 7
0
    def minimax(self, globina, maksimiziramo):
        '''Glavna metoda Minimax.'''
        if self.prekinitev:
            # Sporočili so nam, da moramo prekiniti
            return (None, 0)

        (zmagovalec, stirka) = self.igra.stanje_igre()
        if zmagovalec in (IGRALEC_R, IGRALEC_Y, NEODLOCENO):
            k = 1 - self.igra.stevilo_zetonov() / (2 * 6 * 7)
            # Igre je konec, vrnemo njeno vrednost
            if zmagovalec == self.jaz:
                return (None, Minimax.ZMAGA * k)
            elif zmagovalec == nasprotnik(self.jaz):
                return (None, -Minimax.ZMAGA * k)
            else:
                return (None, 0)
        elif zmagovalec == NI_KONEC:
            # Igre ni konec
            if globina == 0:
                return (None, self.vrednost_pozicije())
            else:
                # Naredimo en korak minimax metode
                if maksimiziramo:
                    # Maksimiziramo
                    najboljsa_poteza = None
                    sez_naj_potez = []
                    vrednost_najboljse = -Minimax.NESKONCNO
                    for p in self.igra.veljavne_poteze():
                        self.igra.povleci_potezo(p)
                        vrednost = self.minimax(globina - 1,
                                                not maksimiziramo)[1]
                        self.igra.razveljavi()
                        if vrednost > vrednost_najboljse:
                            sez_naj_potez = [p]
                            vrednost_najboljse = vrednost
                        elif vrednost == vrednost_najboljse:
                            sez_naj_potez.append(p)
                    if len(sez_naj_potez) == 1:
                        najboljsa_poteza = sez_naj_potez[0]
                    elif len(sez_naj_potez) > 1:
                        rand_st = int(random.random() * len(sez_naj_potez))
                        najboljsa_poteza = sez_naj_potez[rand_st]
                else:
                    # Minimiziramo
                    najboljsa_poteza = None
                    sez_naj_potez = []
                    vrednost_najboljse = Minimax.NESKONCNO
                    for p in self.igra.veljavne_poteze():
                        self.igra.povleci_potezo(p)
                        vrednost = self.minimax(globina - 1,
                                                not maksimiziramo)[1]
                        self.igra.razveljavi()
                        if vrednost < vrednost_najboljse:
                            sez_naj_potez = [p]
                            vrednost_najboljse = vrednost
                        elif vrednost == vrednost_najboljse:
                            sez_naj_potez.append(p)
                    if len(sez_naj_potez) == 1:
                        najboljsa_poteza = sez_naj_potez[0]
                    elif len(sez_naj_potez) > 1:
                        rand_st = int(random.random() * len(sez_naj_potez))
                        najboljsa_poteza = sez_naj_potez[rand_st]
                assert (najboljsa_poteza
                        is not None), 'minimax: izračunana poteza je None'
                return (najboljsa_poteza, vrednost_najboljse)
        else:
            assert False, 'minimax: nedefinirano stanje igre'
Exemplo n.º 8
0
    def alfabeta(self, globina, maksimiziramo, alfa=-NESKONCNO, beta=NESKONCNO):
        """Glavna metoda alfabeta."""
        if self.prekinitev:
            # Sporočili so nam, da moramo prekiniti
            logging.debug("Alfabeta prekinja, globina = {0}".format(globina))
            return None, 0
        (konec_ali_ne, na_vrsti) = self.igra.trenutno_stanje()
        if konec_ali_ne == KONEC_IGRE:
            # Igre je konec, vrnemo njeno vrednost
            if na_vrsti == self.jaz:
                return None, ZMAGA
            elif na_vrsti == nasprotnik(self.jaz):
                return None, -ZMAGA
            elif na_vrsti is None:
                return None, -ZMAGA + 1  # remi
            else:
                assert False, 'stanje_igre vrne čudnega igralca, alfabeta'
        elif konec_ali_ne != KONEC_IGRE:
            # Igre ni konec
            if globina == -1:
                # v primeru, da imamo nastavljeno najlažjo težavnost
                # računalnik naredi en korak alfabeta z neumno cenilko:
                najboljsa_poteza = None
                vrednost_najboljse = -NESKONCNO
                for p in self.uredi_poteze(self.igra.mozne_poteze(),
                                           maksimiziramo):
                    poteza = [self.igra.polozaj_zoge] + p
                    self.igra.naredi_potezo(poteza)
                    vrednost = self.neumna_cenilka()
                    self.igra.razveljavi_potezo(poteza)
                    if vrednost > vrednost_najboljse:
                        vrednost_najboljse = vrednost
                        najboljsa_poteza = poteza
                assert (najboljsa_poteza is not None), \
                    "alfabeta: izračunana poteza je None"
                return najboljsa_poteza, vrednost_najboljse
            elif globina == 0:
                # print("konec rekurzije, globina 0")
                return None, self.pametna_cenilka()
            else:
                # Naredimo eno stopnjo alfabeta
                if maksimiziramo:
                    # Maksimiziramo
                    najboljsa_poteza = None
                    vrednost_najboljse = -NESKONCNO
                    for p in self.uredi_poteze(self.igra.mozne_poteze(),
                                               maksimiziramo):
                        poteza = [self.igra.polozaj_zoge] + p
                        self.igra.naredi_potezo(poteza)
                        vrednost = self.alfabeta(
                            globina - 1, not maksimiziramo, alfa, beta)[1]
                        self.igra.razveljavi_potezo(poteza)
                        if vrednost > vrednost_najboljse:
                            vrednost_najboljse = vrednost
                            najboljsa_poteza = poteza
                        alfa = max(alfa, vrednost_najboljse)
                        if beta <= alfa:
                            break

                else:
                    # Minimiziramo
                    najboljsa_poteza = None
                    vrednost_najboljse = NESKONCNO
                    for p in self.uredi_poteze(self.igra.mozne_poteze(),
                                               maksimiziramo):
                        poteza = [self.igra.polozaj_zoge] + p
                        self.igra.naredi_potezo(poteza)
                        vrednost = self.alfabeta(
                            globina - 1, not maksimiziramo, alfa, beta)[1]
                        self.igra.razveljavi_potezo(poteza)
                        if vrednost < vrednost_najboljse:
                            vrednost_najboljse = vrednost
                            najboljsa_poteza = poteza
                        beta = min(beta, vrednost_najboljse)
                        if beta <= alfa:
                            break

                assert (najboljsa_poteza is not None), \
                    "alfabeta: izračunana poteza je None"
                return najboljsa_poteza, vrednost_najboljse
        else:
            assert False, "alfabeta: ni vrnil cele poteze, ampak korak"