Skip to content

Commit

Permalink
Update Jogador.py
Browse files Browse the repository at this point in the history
  • Loading branch information
lfmatosm authored Sep 27, 2018
1 parent a4e940c commit c092f7c
Showing 1 changed file with 85 additions and 65 deletions.
150 changes: 85 additions & 65 deletions classes_base/Jogador.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,33 @@
#Define a classe Jogador e seus atributos associados.
# MIT License
#
# Copyright (c) 2018 Luiz Felipe de Melo (lffloyd), Vítor Costa (vitorhardoim), Renato Bastos (RenatoBastos33)
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to deal
# in the Software without restriction, including without limitation the rights
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
# copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in all
# copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
# SOFTWARE.
##############################################################################################################


#Define a classe Jogador e seus atributos associados. A classe pode comportar-se como um jogador aleatório, humano ou
# de inteligência artificial.

#Escrito por: Luiz Felipe, Vítor Costa, Renato Bastos.

import random
import os
from classes_base.Cor import *
from classes_base.Peca import *
from classes_busca.Expectiminimax import *
Expand All @@ -13,10 +37,11 @@

class Jogador():
#Constantes para identificação do tipo de jogador.
RANDOM = 3
MCTS = 2
EXPECTMM = 1
HUMANO = 0
RANDOM = 3 #Jogador 'Random'. Executa qualquer das ações que tiver como disponíveis em qualquer momento do jogo.
MCTS = 2 #I.A. que emprega Monte Carlo tree search na determinação do melhor mov. a ser executado.
EXPECTMM = 1 #I.A. que emprega Expectiminimax para determinar a melhor jogada a ser feita.
HUMANO = 0 #Representa um jogador humano, que interage com o jogo escolhendo as jogadas que deseja realizar por
# linha de comando.

#Construtor define atributos como a "mão" do jogador (i.e. suas peças), as peças jogáveis num dado momento (i.e. aque-
#las que ele pode efetivamente encaixar no tabuleiro), qtd. de pontos acumulada e outros parãmetros de controle.
Expand All @@ -35,8 +60,7 @@ def __init__(self, ind=None, tipo=HUMANO):
elif (self.tipo == self.MCTS): self.tipoStr = "MCTS"
else: self.tipoStr = "RANDOM"

self.vezesQueComecou = 0

#Rerpesentação textual da instância de Jogador.
def __str__(self):
resp = "J" + str(self.__ind) + " ("+ self.tipoStr + ") -"
resp += "\tMão: "
Expand All @@ -51,7 +75,6 @@ def adicionaPeca(self, peca): self.__mao.append(peca)

#Remove uma dada instância de Peça da mão do jogador, caso ela exista. Necessita receber uma instância de Mesa
#para manter a consistência da variável que armazena as peças jogáveis num dado momento pelo jogador.

def removePeca(self, mesa, peca):
if (len(self.__mao) != 0):
self.__mao.remove(peca)
Expand Down Expand Up @@ -125,7 +148,6 @@ def pegaPecasJogaveis(self): return self.__maoJogaveis

#Retorna todas as possibilidades de jogadas disponíveis no dado momento a esta instância de Jogador.
#O retorno é composto de uma matriz contendo pares [Peça, Posição de jogada, Probabilidade da jogada].
#Nenhum cálculo mais elaborado é executado ainda para a probabilidade.
def possibilidadesJogaveis(self, mesa):
possibilidades = []
probabilidade = 1//7
Expand All @@ -141,13 +163,11 @@ def possibilidadesJogaveis(self, mesa):
else: possibilidades.append([peca, (0 if (peca.ehJogavel(esq)) else 1),
(self.probabilidadeJogada(peca, esq, mesa) if (peca.ehJogavel(esq)) else
self.probabilidadeJogada(peca, dir, mesa))])
#Distribui uma probabilidade equivalente para cada uma das possíveis escolhas a serem feitas.
#for jogada in possibilidades:
# print("Peça.:"+str(jogada[0]) +",\tPos.:"+ str(jogada[1]) +",\tProb.:"+ str(jogada[2]))
return possibilidades

#Calcula a probabilidade de uma dada peça ser encaixada numa dada posição do tabuleiro/mesa baseando-se no total
# de ocorrência dos valores das faces da peça no tabuleiro.
def probabilidadeJogada(self, peca, pos, mesa):
if (self.tipo == self.RANDOM): return 0
contagemMax = 7
contagem = 1
probMax = 1
Expand All @@ -157,7 +177,8 @@ def probabilidadeJogada(self, peca, pos, mesa):
return probabilidade

#Compra peças da mesa enquanto existirem peças disponíveis para compra na mesma e/ou enquanto o jogador não
#tiver nenhuma peça jogável em mãos.
#tiver nenhuma peça jogável em mãos. Invólucro para o métod de compra de peças disponibilizado pela classe Mesa
# (mesa.comprarPeca()).
def compraDaMesa(self, mesa):
self.atualizaPecasJogaveis(mesa)
while (len(self.pegaPecasJogaveis()) == 0):
Expand All @@ -168,7 +189,7 @@ def compraDaMesa(self, mesa):
else: break
return

#Elimina todas as cartas de um jogador.
#Elimina todas as peças da mão de um jogador.
def limparMao(self):
self.__mao = []
self.__maoJogaveis = []
Expand All @@ -186,15 +207,14 @@ def somatorioPecas(self):
for peca in self.__mao: soma += (peca.esq() + peca.dir())
return soma

#Incrementa a pontuação de um jogador.
#Incrementa a pontuação de um jogador de um valor passado por parâmetro.
def somaPontos(self, soma): self.__pontos += soma

#Retorna a qtd. de pontos acumulada até o momento do jogador.
def pegaPontos(self): return self.__pontos

#Método que coordena cada uma das jogadas do jogador. Até o momento, necessita da interação de um humano para realizar
# uma jogada. Aguarda até que o jogador escolha uma peça válida para encaixar ou até que não possua nenhuma peça válida
#para jogar, passando a vez a seu oponente.
#Método que coordena qual o tipo de método de jogar será chamado. Há diferentes métodos para cada um dos diferentes tipos
# de jogadores existentes.
def jogar(self, mesa, oponente):
if (self.tipo == self.HUMANO): return self.jogarHumano(mesa, oponente)
elif (self.tipo == self.EXPECTMM): return self.jogarExpectMM(mesa, oponente)
Expand All @@ -208,7 +228,7 @@ def jogarHumano(self, mesa, oponente):
self.atualizaPecasJogaveis(mesa)
# Caso não existam peças jogáveis em sua mão, executa a compra de peças enquanto for possível.
if (len(self.pegaPecasJogaveis()) == 0): self.compraDaMesa(mesa)
print("\n" + str(mesa))
#print("\n" + str(mesa))
print("\n" + self.pecasJogaveis(mesa, self.__mao))
print(self)
if (len(self.pegaPecasJogaveis()) == 0):
Expand Down Expand Up @@ -238,12 +258,11 @@ def jogarExpectMM(self, mesa, oponente):
self.atualizaPecasJogaveis(mesa)
#Caso não existam peças jogáveis em sua mão, executa a compra de peças enquanto for possível.
if (len(self.pegaPecasJogaveis()) == 0): self.compraDaMesa(mesa)
print("\n" + str(mesa))
#print("\n" + str(mesa))
print("\n" + self.pecasJogaveis(mesa, self.__mao))
print(self)
# Caso mesmo assim não seja possível conseguir uma peça jogável, pula esta rodada sem executar movimento.
if (len(self.pegaPecasJogaveis()) == 0):
#mesa.fechada = True
self.setaJogou(False)
print("J" + str(self.__ind) + " passou a vez.")
else:
Expand Down Expand Up @@ -272,54 +291,55 @@ def jogarExpectMM(self, mesa, oponente):
oponente.setaVez(True)
return

# Define o método 'jogar' para um jogador controlado por inteligência artificial (Monte-Carlo tree search).
# Define o método 'jogar' para um jogador controlado por inteligência artificial (Monte Carlo tree search).
def jogarMCTS(self, mesa, oponente):
if self.__vezAtual == False: return
else:
adicionou = False
while not adicionou:
print("\n" + self.pecasJogaveis(mesa, self.__mao))
print(self)
print("\n" + str(mesa))
while (len(self.__maoJogaveis) == 0):
if (len(mesa.pegaPecasAComprar()) != 0):
self.adicionaPeca(mesa.comprarPeca())
self.__maoJogaveis = []
print("\n" + self.pecasJogaveis(mesa, self.__mao))
print(self)
else:
self.setaJogou(False)
self.setaVez(False)
oponente.setaVez(True)
print("J" + str(self.__ind) + " passou a vez.")
return
estadoAtual = EstadoMCTS(self, oponente, mesa)
noTeste = MonteCarloNo(estadoAtual)
noTeste.expandir()
print(noTeste)
noTeste.melhorFilho()
escolhida = int(input("Qual peça deseja jogar? "))
if (len(mesa.pegaTabuleiro()) != 0): pos = int(input("Em que posição?(0 p/ esquerda, 1 p/ direita) "))
else: pos = 0
peca = self.__mao.pop(escolhida - 1)
adicionou = mesa.adicionarNaMesa(peca, pos)
if (not adicionou): self.__mao.append(peca)
else: self.setaJogou(True)
self.__maoJogaveis = []
peca.ordem(len(mesa.pegaTabuleiro()))
self.setaVez(False)
oponente.setaVez(True)
return
print("\n" + self.pecasJogaveis(mesa, self.__mao))
print(self)
#print("\n" + str(mesa))
while (len(self.__maoJogaveis) == 0):
if (len(mesa.pegaPecasAComprar()) != 0):
self.adicionaPeca(mesa.comprarPeca())
self.__maoJogaveis = []
print("\n" + self.pecasJogaveis(mesa, self.__mao))
print(self)
else:
self.setaJogou(False)
self.setaVez(False)
oponente.setaVez(True)
print("J" + str(self.__ind) + " passou a vez.")
return
estadoAtual = EstadoMCTS(self, oponente, mesa)
noTeste = MonteCarloNo(estadoAtual)
noTeste.expandir()
if len(noTeste.filhos)>1:
for i in range(100):
melhorfilho=noTeste.melhorFilho()
noTeste.gerarJogo(melhorfilho,False)
melhorfilho=noTeste.melhorFilho()
print(str(melhorfilho.UCT))
self.removePeca(mesa,melhorfilho.estado.ultimaPecaJogada)
mesa.adicionarNaMesa(melhorfilho.estado.ultimaPecaJogada, melhorfilho.estado.onde)
self.setaJogou(True)
self.__maoJogaveis = []
melhorfilho.estado.ultimaPecaJogada.ordem(len(mesa.pegaTabuleiro()))
#print("MCTS jogou a peça:"+ str(melhorfilho.estado.ultimaPecaJogada)+"na posição :"+ str(melhorfilho.estado.onde)+"\n" )
self.setaVez(False)
oponente.setaVez(True)
return

# Define o método 'jogar' para um jogador 'random', usado para testes.
# Define o método 'jogar' para um jogador 'random'. Usado para testes. Realiza escolhas de jogadas sem obedecer nenhum
# padrão específico de jogo, escolhendo apenas qualquer das possibilidades existentes para ele num dado momento.
def jogarRandom(self, mesa, oponente):
if (self.__vezAtual == False): return
if self.__vezAtual == False: return
self.atualizaPecasJogaveis(mesa)
# Caso não existam peças jogáveis em sua mão, executa a compra de peças enquanto for possível.
if (len(self.pegaPecasJogaveis()) == 0):
if (len(self.__mao) != 0): self.compraDaMesa(mesa)
if (len(self.pegaPecasJogaveis()) == 0):
self.setaJogou(False)
if (len(self.pegaPecasJogaveis()) == 0): self.compraDaMesa(mesa)
#print("\n" + str(mesa))
#print("\n" + self.pecasJogaveis(mesa, self.__mao))
#print(self)
if (len(self.pegaPecasJogaveis()) == 0): self.setaJogou(False)
#print("J" + str(self.__ind) + " passou a vez.")
else:
possibilidades = self.possibilidadesJogaveis(mesa)
Expand All @@ -339,4 +359,4 @@ def contarValor(self, valor):
cont = 0
for peca in self.__mao:
if (peca.esq() == valor) or (peca.dir() == valor): cont += 1
return cont
return cont

0 comments on commit c092f7c

Please sign in to comment.