예제 #1
0
파일: Game.py 프로젝트: YamiJosema/TFG-RN
def opciones(tablero, ):
    rangos = rango_por_letra(FORMAS)
    rango = rangos[tablero.pentominos[0]]
    opciones = []
    #     print("Rango "+str(rango))
    for r in range(rango[0], rango[1] + 1):
        pent = tablero.fichas[r - 1]
        pentomino = Pentomino(pent[0], int(pent[1]), int(pent[2]))
        #         print("Pentomino "+str(pentomino))
        x, y = tablero.comprobar_pentomino(pentomino)
        #         print("("+str(x)+","+str(y)+")")
        if x != -1:
            opciones.append([pentomino, x, y])
    return opciones
예제 #2
0
def get_max(siguiente_letra, solucion):
    rangos = rango_por_letra(Formas)
    print("Siguiente letra " + str(siguiente_letra))

    zona = rangos[siguiente_letra]
    print("Zona " + str(zona))
    solucion_cortado = solucion[zona[0]:zona[1] + 1]
    print("Cortado " + str(solucion_cortado))
    solucion_maximo = np.where(solucion_cortado == np.amax(
        solucion_cortado))  #cogemos los indices que tengan el valor maximo
    print("Maximo " + str(solucion_maximo))
    solucion_relativo = solucion_maximo[0][0]
    action = posicion_real(solucion_relativo, siguiente_letra, Formas)
    print("Action " + str(action))

    return action
예제 #3
0
def crear_conjunto_entrenamiento(
):  #Darle solo los valores maximos, las que son mas prometedoras
    rangos = rango_por_letra(Formas)
    #     pentominos = cargar_pentominos(Formas)
    if os.path.isfile('../Pentominos/csv/entrenamiento-v4.csv') == False:
        print(
            "Fichero de entrenamiento no encontrado, procedemos a su creación")
        with open('../Pentominos/csv/entrenamiento-v4.csv', 'w') as csvfile:
            filewriter = csv.writer(csvfile,
                                    delimiter=',',
                                    quotechar='|',
                                    quoting=csv.QUOTE_MINIMAL)
            if os.path.isfile('../Pentominos/learning/alfabetico.txt') == True:
                print("Fichero qlearning encontrado")
                qtable = np.loadtxt('../Pentominos/learning/alfabetico.txt',
                                    dtype=float32)

            letra_i = 0
            for row in range(len(qtable)):
                #                 print("Fila "+str(row))
                letra = Formas[letra_i]
                zona = rangos[letra]

                row_plano = np.squeeze(np.asarray(qtable[row]))
                row_cortado = row_plano[zona[0]:zona[1] + 1]

                row_maximo = np.where(row_cortado == np.amax(row_cortado))

                for index in row_maximo[0]:
                    action = posicion_real(index, letra[0], Formas)
                    filewriter.writerow([row, action])
                    filewriter.writerow([row, action])

                if row == zona[0] - 1 or letra == 'F':
                    letra_i += 1

                if letra == 'Z':
                    break

        print("Completada la creacion de entrenamiento-v4.csv")
    else:
        print("Fichero encontrado")
예제 #4
0
파일: Game.py 프로젝트: YamiJosema/TFG-RN
def game2(gameDisplay, modo):

    pulsadas = []
    descartadas = []

    pygame.display.set_caption('Q-Learning')

    turno = piedra_papel_tijeras(gameDisplay)
    TURNOS.append(turno)

    clock = pygame.time.Clock()

    gameDisplay.fill(BLACK)
    logo = pygame.image.load('images/logo.png')
    logo = pygame.transform.scale(logo, (250, 57))
    gameDisplay.blit(logo, (10, 0))
    tablero = Tablero(8, 8, FORMAS)
    tablero.seleccion_modo(modo)

    qtable = qlearning(tablero.copy(), modo)

    tablero.seleccion_modo_real()
    board(tablero, gameDisplay)

    out = False
    replay = False

    p1, p2 = 0, 0
    print("COMIENZA EL JUEGO")

    while not out:

        i, _ = tablero.siguiente_zero()
        p1, p2 = get_puntuacion(tablero)
        pygame.draw.rect(gameDisplay, BLACK,
                         [0, display_height * 0.85 - 60, display_width, 100])
        display_text("P1:" + str(p1), display_width * 0.2,
                     display_height * 0.85, 85, WHITE, gameDisplay)
        display_text("P2:" + str(p2), display_width * 0.8,
                     display_height * 0.85, 85, WHITE, gameDisplay)

        for event in pygame.event.get():
            if event.type is pygame.QUIT:
                out = True
        if i != -1:
            panel_letras(pulsadas, descartadas, gameDisplay)
            if TURNOS[-1] == 1:
                print("Turno jugador 1")
                op = opciones(tablero)
                while not op:
                    #                     print("Descartamos la "+tablero.pentominos[0])
                    descartadas.append(tablero.pentominos[0])
                    tablero.pentominos.pop(0)
                    op = opciones(tablero)
                ficha_colocada, replay, out = colocar_letra(
                    tablero, op, gameDisplay)
                aux_pent = [
                    ficha_colocada.letra,
                    str(ficha_colocada.rotacion),
                    str(ficha_colocada.invertido)
                ]
                action = tablero.fichas.index(aux_pent)
                tablero.piezas.append(action)
                pulsadas.append(ficha_colocada.letra)
                TURNOS.append(2)
                pygame.display.update()
                #                 print("Ficha: "+str(tablero.movimientos[-1][0]))
                print(tablero)
            else:
                print("Turno jugador 2")
                op = opciones(tablero)
                while not op:
                    print("Descartamos la " + tablero.pentominos[0])
                    descartadas.append(tablero.pentominos[0])
                    tablero.pentominos.pop(0)
                    op = opciones(tablero)

                valida = False
                if not tablero.movimientos:
                    state = 0
                else:
                    ultimo_movimiento = tablero.movimientos[-1][0]
                    state = tablero.fichas.index(ultimo_movimiento) + 1

                rangos = rango_por_letra(FORMAS)
                key = get_key(tablero)
                #                 print("Piezas "+str(tablero.piezas))
                action_completo = np.copy(qtable[state])
                action_plano = np.squeeze(np.asarray(action_completo))
                zona = rangos[tablero.pentominos[0]]
                action_cortado_diccionario = action_plano[zona[0]:zona[1] + 1]
                #                 print("Action Diccionario "+str(action_cortado_diccionario))
                action_cortado = []
                for dic in action_cortado_diccionario:
                    #                     print("Key "+str(key))
                    if key in dic:
                        action_cortado.append(dic[key])
                    else:
                        action_cortado.append(0.0)
                action_cortado = np.copy(action_cortado)

                while not valida:
                    #                     print("Zona "+str(action_cortado))
                    action_maximo = np.where(
                        action_cortado == np.amax(action_cortado)
                    )  #cogemos los indices que tengan el valor maximo
                    #                     print("Maximos "+str(action_maximo))
                    rand = random.randint(0, len(action_maximo[0]) - 1)
                    action_relativo = action_maximo[0][
                        rand]  #nos quedamos con el primero ya que todos serian iguales (se podria aleatorizar con epsilon)
                    action = posicion_real(
                        action_relativo, tablero.pentominos[0], FORMAS
                    )  #obtenemos el indice real ya que le anterior era el indice ralivo al array cortado
                    action += 1

                    print("Ficha(numero) " + str(action))
                    pent = tablero.fichas[
                        action -
                        1]  #Comprobar que entra, si no entra ponemos a -1000 esa posicion en la qtable y elegimos otro de los maximos
                    print("Ficha: " + str(pent))
                    pentomino = Pentomino(pent[0], int(pent[1]), int(pent[2]))

                    x, y = tablero.comprobar_pentomino(pentomino)

                    if x == -1:
                        print("No es valida")
                        action_cortado[action_relativo] = -1000
                    else:
                        print("Es valida")
                        valida = True

                tablero.colocar_pentomino_2p(pentomino, x, y, TURNOS[-1])
                aux_pent = [
                    pentomino.letra,
                    str(pentomino.rotacion),
                    str(pentomino.invertido)
                ]
                action = tablero.fichas.index(aux_pent)
                tablero.piezas.append(action)
                teclas_escR(gameDisplay)
                pulsadas.append(pentomino.letra)
                tablero.buscar_huecos(TURNOS[-1])
                print(tablero)
                board(tablero, gameDisplay)
                TURNOS.append(1)
                pygame.display.update()
        elif i == -1:
            panel_letras(pulsadas, descartadas, gameDisplay)
            win(p1, p2, gameDisplay)
            teclas_escR(gameDisplay)
            pr = parar_reiniciar()
            if pr == "Replay":
                tablero.reset(FORMAS, modo)
                tablero.seleccion_modo_real()
                pulsadas = []
                descartadas = []
                board(tablero, gameDisplay)
                turno = random.randint(1, 2)
                TURNOS.append(turno)
            elif pr == "Stop":
                out = True
        if replay:
            replay = False
            tablero.reset(FORMAS, modo)
            tablero.seleccion_modo_real()
            pulsadas = []
            board(tablero, gameDisplay)
            turno = random.randint(1, 2)
            TURNOS.append(turno)
        pygame.display.update()

        clock.tick(30)
예제 #5
0
def qlearning(tablero,
              modo=0,
              epochs=40000,
              gamma=0.4,
              epsilon=0.95,
              decay=0.001,
              limit=200):
    fichero = '../Pentominos/learning/alfabetico.txt'
    if modo == 2:
        fichero = '../Pentominos/learning/esquinas.txt'
    elif modo == 3:
        fichero = '../Pentominos/learning/centro.txt'
    if os.path.isfile(fichero) == True:
        qtable = [[{} for i in range(64)] for _ in range(64)]
        with open(fichero) as file:
            i = 0
            for line in file:
                split1 = line.split("}]")
                split = split1[0].split("}, ")
                j = 0
                for trozo in split:
                    trozo = trozo.strip('[{')
                    trozo = trozo.strip('\n')
                    if trozo != '':
                        posibles = trozo.split(', ')
                        for p in posibles:
                            real = p.split(': ')
                            #                             print(real)
                            dic = {real[0].strip("'"): float(real[1])}
                            qtable[i][j].update(dic)
                    j += 1
                i += 1

        print("Fichero qlearning encontrado")


#         qtable = np.loadtxt('../Pentominos/learning/alfabetico.txt', dtype=float32)
    else:
        print(
            "Fichero no encontrado, pasamos a hacer el proceso de aprendizaje, esto llevara unos segundos"
        )
        modo_aux = modo
        orden = tablero.pentominos
        pentominos = cargar_pentominos(orden)
        no_colocadas = []
        rangos = rango_por_letra(orden)

        qtable = [[{} for i in range(len(pentominos) + 1)]
                  for _ in range(len(pentominos) + 1)]

        for i in range(epochs):
            state, penalty, done = tablero.reset(orden, modo)
            steps = 0

            no_colocadas = []
            fila_aux = []
            last_state = state
            while not done:
                letra_actual = tablero.pentominos[0]
                if last_state != state or not np.any(fila_aux):
                    fila_aux = np.copy(qtable[state])
                last_state = state

                key = get_key(tablero)
                action_completo = fila_aux
                action_plano = np.squeeze(np.asarray(action_completo))
                zona = rangos[tablero.pentominos[0]]
                action_cortado_diccionario = action_plano[zona[0]:zona[1] + 1]
                action_cortado = []
                for dic in action_cortado_diccionario:
                    if key in dic:
                        action_cortado.append(dic[key])
                    else:
                        action_cortado.append(0.0)
                action_cortado = np.copy(action_cortado)

                if np.random.uniform() < epsilon:
                    if np.count_nonzero(action_cortado) != len(action_cortado):
                        action_minimo = np.where(
                            action_cortado ==
                            0)  #cogemos los indices que tengan el valor maximo
                        rand = random.randint(0, len(action_minimo[0]) - 1)
                        action_relativo = action_minimo[0][
                            rand]  #nos quedamos con el primero ya que todos serian iguales (se podria aleatorizar con epsilon)
                        action = posicion_real(action_relativo,
                                               tablero.pentominos[0], orden)
                    else:
                        action = tablero.ficha_aleatoria(
                        )  #Usamos colocar random para poner una ficha aleatoria
                else:
                    action_maximo = np.where(
                        action_cortado == np.amax(action_cortado)
                    )  #cogemos los indices que tengan el valor maximo
                    rand = random.randint(0, len(action_maximo[0]) - 1)
                    action_relativo = action_maximo[0][
                        rand]  #nos quedamos con el primero ya que todos serian iguales (se podria aleatorizar con epsilon)
                    action = posicion_real(
                        action_relativo, tablero.pentominos[0], orden
                    )  #obtenemos el indice real ya que le anterior era el indice ralivo al array cortado

                action += 1  #Sumamos uno para contar en la tabla el hueco para la posicion 0

                next_state, penalty, done = tablero.colocar_siguiente(
                    action, state
                )  #Importante comprobar que la letra no este ya usada y que no quedan huecos para el reward

                if done or not tablero.pentominos:
                    faltantes = len(tablero.pentominos) + len(no_colocadas)

                    qtable[state][action].update(
                        {key: 50 + penalty - 10 * faltantes})
                    if faltantes <= modo:
                        if modo_aux == 0:
                            epsilon -= decay * epsilon
                            modo_aux = modo
                        else:
                            modo_aux -= 1

                else:
                    if penalty == -1000:

                        fila_aux[action].update({get_key(tablero): penalty})

                        reward_completo = fila_aux  #Buscamos en el estado
                        zona = rangos[
                            letra_actual]  #Obtenemos la zona de la table que afecta a la letra actual #Convertimos en array "aplaanamos"
                        reward_plano = np.squeeze(
                            np.asarray(reward_completo
                                       ))  #Convertimos en array "aplaanamos"

                        reward_cortado_diccionario = reward_plano[
                            zona[0]:zona[1] +
                            1]  #cortamos el array para quedarnos solo con la zona de siguietes acciones
                        reward_cortado = []
                        for dic in reward_cortado_diccionario:
                            if key in dic:
                                reward_cortado.append(dic[key])
                            else:
                                reward_cortado.append(0.0)

                        reward_maximo = np.amax(reward_cortado)
                        if reward_maximo == -1000:
                            no_colocadas.append(
                                letra_actual
                            )  #La ficha se ha probado en todas direcciones y no cabe en el tablero, asi que se pasa turno
                            tablero.pentominos.pop(0)
                    else:
                        reward_maximo = valor_maximo(qtable, rangos,
                                                     tablero.pentominos[0],
                                                     next_state, tablero)
                        qtable[state][action].update(
                            {key: penalty + gamma * reward_maximo})

                state = next_state

                steps += 1

                if steps > limit or not tablero.pentominos:
                    done = True
            print(" ")
            print("epoch #", i + 1, "/", epochs, " .Step: ", steps)
            print(tablero)
            no_colocadas.append(tablero.pentominos)
            print(no_colocadas)
            print(tablero.piezas)
            print("Epsilon " + str(epsilon))
            print("\nDone in", steps, "steps".format(steps))
        with open(fichero, 'w+') as f:
            for item in qtable:
                f.write(str(item))
                f.write("\n")
    return qtable