Algoritmos para um jogador inteligente de Poker



Baixar 1,37 Mb.
Página5/6
Encontro12.07.2018
Tamanho1,37 Mb.
1   2   3   4   5   6

Constante

Algoritmo Genético

Bom Senso

Intervalo ODDS

9,6

2

Intervalo CHANCE

23,3

10

Intervalo POT

37,4

10

Intervalo RAISE

13,2

5

Intervalo FOLLOWERS

2,6

1

Intervalo NPLAYERS

3,5

Não usado

Intervalo QTYRAISE

3,5

Não usado

Intervalo INGAME

5,6

Não usado

BIG QTY

4

10

LITTLE QTY

2

2

Tabela 6: Constantes encontradas para ser utilizado pelo Jogador Esforço
Um retrato das decisões tomadas em diversas situações pelo jogador por esforço utilizando a configuração Bom Senso com 60 milhões de dados de informações pode ser visualizado na figura abaixo, sendo cada quadrado de cor a melhor decisão de um estado do jogo.

F
igura 2: Exemplo do mapa de conhecimento do jogador por reforço sendo cada ponto um estado do jogo pintado com a decisão a ser tomada

4.4. Disputas
Cada confronto é formado por 200 mesas. Cada mesa contem um número par de 2 a 10 jogadores igualmente distribuídos, sendo metade jogadores de um método e a outra metade outro método, e contem até 40 jogos ou até que um jogador ganhe todo o dinheiro dos adversários, o que ocorrer primeiro. Quando cada mesa acaba, é pontuado a vitória de um dos dois métodos confrontados. Ao fim de 100 mesas é feita a proporção de vitórias de cada método. Cada jogo começa com 1000 de dinheiro para cada jogador e o Small Blind é 10 e a ordem dos jogadores é aleatória.
4.4.1. MFS x Aleatório
Para essa avaliação foi testado vários possíveis valores para a constante do jogador MFS. MFS é um jogador que provavelmente mostraria melhores resultados que o jogador aleatório pois o MFS joga de acordo com a probabilidade de vencer e os resultados comprovaram (Gráfico 5). Isso demonstra que Poker não é somente sorte pois uma decisão inteligente melhora o desempenho do jogador.
Gráfico 5: Jogador MFS x Jogador Aleatório

4.4.2. MFS x Constante
Nessa disputa foram testados apenas alguns valores principais para o MFS e todas as decisões possíveis para o jogador constante com exceção de fugir. Era provável que igualmente o MFS obtivesse melhores resultados por considerar a probabilidade de vencer, ao contrário do jogador constante que sempre tem o mesmo comportamento. Como o jogador MFS joga justo de acordo com a probabilidade de vencer e foge quando a probabilidade de vencer não é boa, em geral aumentar muito a aposta faz o jogador MFS fugir. Por outro lado, aceitar as aumentadas de aposta do jogador MFS é a pior coisa a ser feita pois a longo prazo ele terá ótimos ganhos por jogar exatamente de acordo com a força do seu jogo. O jogador constante obteve melhores resultados quando sua decisão era sempre aumentar a aposta porque fazia o MFS fugir sempre, mas não foi suficiente para vence-lo pois quando o aumento de aposta favorecia o MFS, este recuperava todo o prejuízo e vencia. Segue os resultados graficamente:





Gráfico 6: Jogador MFS x Jogador Constante
4.4.3. Aleatório x Constante
Aqui, o jogador constante usou todas as decisões possíveis com exceção de fugir. Os resultados mostraram uma insignificante vantagem para o jogador constante:
G
ráfico 7:Jogador Aleatório x Jogador Constante

4.4.4. RH x Aleatório
O jogador RH joga com base no número de vezes que os adversários aumentaram a aposta, no número de jogadores que ainda tem no jogo, resumindo, em informações que podem dizer como estão os adversários. Como o jogador aleatório joga qualquer coisa, essa informação é pode ser de pouca utilidade. Mas mesmo assim, se o RH aposta mais quando ninguém está apostando, ele pode vencer porque os jogadores aleatórios fugiram. Os resultados constataram uma vantagem para o RH:
G
ráfico 8: Jogador RH x Jogador Aleatório


4.4.5. RH x Constante
Nessa disputa existe um problema para o RH: como o jogador RH de acordo com a ação do adversário, um adversário que joga constante fará o jogador RH jogar constante também, fazendo com que fique imprevisível os resultados:

G
ráfico 9: Jogador Constante x Jogador RH

4.4.6. RH x MFS
O MFS foge quando não tem muita chance de vencer e o adversário aumenta muito a aposta. Por isso, um jogador agressivo é mais forte contra o MFS do que um jogador menos agressivo. Porém, muita agressividade pode fazer com que o MFS se aproveite nas melhores situações e ganhe muito dinheiro em apenas uma rodada. Esse foi o resumo do resultado dessa disputa. O RH é mais agressivo quanto menor for a constante . O RH é o algoritmo que poderia vencer o MFS por se aproveitar dos momentos que o MFS não está aumentando para aumentar as apostas, mas o máximo que ele conseguiu foi quase um empate. O jogador MFS utilizou apenas um valor para sua constante , o valor “1”, que experimentalmente demonstrou bons resultados:
G
ráfico 10: Jogador RH x Jogador MFS


4.4.7. Reforço x Aleatório
Apesar de ter sido criado com muita informação aleatória, o jogador por reforço conseguiu vencer o jogador aleatório. Talvez porque exista realmente a melhor jogada em cada situação.





Gráfico 11: Jogador Reforço x Jogador Aleatório
4.4.8. Reforço x Constante
O jogador por reforço conseguiu aprender um jeito para vencer o jogador que sempre continua. O jogador que aumenta muito ele conseguiu melhorar o desempenho com mais informação.
Gráfico 12: Jogador Reforço x Jogador Constante

4.4.9. Reforço x MFS
O jogador MFS, que parecia ser o jogador mais difícil de vencer, foi o mais fácil. O jogador por reforço teve uma vitória bem significativa.

Gráfico 13: Jogador Reforço x Jogador MFS

4.4.10. Reforço x RH
O jogador RH surpreendeu, conseguindo empatar com o jogador por reforço quando configurado com a constante . Por algum motivo, o jogador não consegue evoluir contra este jogador.




Gráfico 14: Jogador Reforço x Jogador RH
4.5.11. Disputa entre os melhores de cada
Essa disputa foi feita com 10 jogadores em jogo sendo 2 jogadores de cada tipo. O MFS tinha um jogador com constante e outro com . O RH tinha um jogador com constante e outro com . O jogador constante teve um jogador que decidia sempre Continuar e outro que decidia sempre Aumentar Muito. Foi jogado 500 mesas e o jogador treinado jogou melhor. Apesar do jogador RH ter tido vantagem contra o jogador por Reforço jogando individualmente, quando jogou-se em grupo, o jogador RH teve um desempenho ruim.




Gráfico 15: Disputa entre todos os jogadores
4.5.12. Reforço x Humano
Contra jogadores humanos bem amadores, o jogador por reforço obteve um bom desempenho. Foram testados dez mesas e quatro jogadores humanos diferentes e a proporção de vitórias foi de 100% para o jogador por reforço. Cada mesa tinha um jogador humano e três jogadores por reforço treinados com a configuração encontrada por Bom Senso e com 60 milhões de dados. O jogador por reforço mostrou-se bem coerente com a sua probabilidade de vencer quando decidia fugir ou quando decidia apostar tudo. Mesmo assim, não é sempre que ele joga de acordo com a probabilidade de vencer e fica difícil prever a sua jogada.
5. CONCLUSÃO

Os algoritmos testados para jogar poker tiveram desempenhos diferentes, sendo que o melhor testado foi o jogador com aprendizado por reforço, que é o jogador que fica jogando aleatoriamente até ter dados suficientes para tomar uma decisão baseado nos casos já experimentados. O jogador MFS, que parecia um excelente jogador já que poker é um jogo de aposta e probabilidade de vencer e este jogador joga baseado na aposta e na probabilidade de vencer, ficou um pouco pior que o jogador de aprendizado por reforço quando jogado todos junto mas mesmo assim obteve um bom desempenho. O método Monte-Carlo para cálculo de probabilidade de vencer foi suficiente e eficiente.


Os ajustes feitos na configuração do jogador geraram diferentes formas de progresso, mas o efeito foi o mesmo. Até uma determinada quantidade de informação, o jogador melhorou o desempenho, mas com mais informação o desempenho do jogador não melhorou mais. Esse problema aconteceu com diversas configurações e fórmulas do jogador por aprendizado. Em geral os ajustes feitos em problemas relacionados a inteligência artificial são bastante trabalhosos e pouco determinístico.
O Poker se mostrou um jogo bem desafiador de criar um bom jogador pois não existe claramente um método ótimo de vencer neste jogo o que permite utilizar muitas técnicas diferentes da Inteligência Artificial para chegar a um bom resultado. Referências de outros trabalhos mostraram a utilização de técnicas bem diferentes como Minimax, Nash Equilibrium e Redes Neurais.
Neste trabalho, dois pontos críticos foram o desempenho do algoritmo e problemas de implementação. Muito código foi reescrito em C porque a lentidão do Matlab inviabilizava a continuação do trabalho. A divisão do trabalho em etapas para testar diferentes implementações em apenas uma etapa de todo o processo foi uma solução que também economizou muito tempo. Os problemas de implementação no sistema geraram grandes prejuízos no tempo em que demorou para o trabalho ficar pronto porque todos os resultados eram descartados toda vez que algum problema no sistema era encontrado e tinha que gerar tudo de novo, o que em alguns casos levavam dias.
Para trabalhos futuros, pode ser interessante testar algoritmos diferentes. Por exemplo, um algoritmo não discretizasse o conhecimento mas normalizasse as dimensões de forma que pudesse utilizar “K Nearest Neighbor” que classifica um dado de acordo com os casos mais próximos. Outra exemplo, utilizar métodos híbridos através de uma rede neural que identificasse qual método tem o melhor desempenho em determinada situação e utilizasse-o. Alguns trabalhos lidos procuraram uma forma de criar um jogador artificial de Poker que utilizasse informações mais detalhada do jogo, como o histórico de jogadas de cada jogador, o que pode ajudar a identificar e vencer adversários muito previsíveis como os jogadores estáticos apresentados neste trabalho.
Pode ser feita uma investigação mais aprofundada em porque o jogador não melhora continuamente com mais informação ou, pelo menos, se mantem no melhor desempenho com mais informação pode ser bastante útil para descobrir novas formas de criar jogadores mais eficientes.
6. REFERÊNCIAS BIBLIOGRÁFICAS
ECKEL, Bruce. Thinking in C++: Second Edition: Volume 1: Introduction to Standard C++. New Jersey: Prentice Hall, 2000. Disponível em: <http://www.mindview.net/Books/TICPP/ThinkingInCPP2e.html>. Acesso em 1 out. 2008.
FINDLER, Nicholas V.. Studies in Machine Cognition Using the Game of Poker. State University Of New York At Buffalo: R. J. Hanson, 1977.
HOLLAND, John H.. Genetic Algorithms and the Optimal Allocation of Trials. Siam Journal On Computing, Philadelphia, n. 2 , p.88-105, 3 ago. 1972.
JOHANSON, Michael Bradley. Robust Strategies and Counter-Strategies: Building a Champion Level Computer Poker Player. 2007. 97 f. Tese (Mestrado) - University Of Alberta, Alberta, 2007.
LUGER, George F.; STUBBLEFIELD, Willian A. Artificial Intelligence: Structures and Strategies for Complex Problem Solving. Harlow, England: Addison Wesley Longman, Inc., 1998.
NISAN, Noam et al. A Course In Game Theory. New York: Cambridge University Press, 2007.
RUSSEL, Stuart J.; NORVIG, Peter. Artificial Intelligence: A Modern Approach. New Jersey: Prentice Hall, 1995.
SKLANSKY, David. The Theory of Poker. Las Vegas Nv: Two Plus Two Pub, 1987.
SUTTON, Richard S.; BARTO, Andrew G.. Reinforcement Learning: An Introdution. E-Book. Disponível em: . Acesso em: 1 out. 2008.
Outras referências (sem autor):
MATLAB (Org.). The MathWorks: MATLAB and Simulink for Technical Computing. Disponível em: . Acesso em 1 out. 2008.
POKERAIWIKI (Org.). Computer Poker Ai Wiki. Disponível em: . Acesso em: 1 out. 2008.
POKERLOCO (Org.). Como Jogar Poker: Resumo. Disponível em: . Acesso em: 1 out. 2008.
WIKIPÉDIA MÉTODO DE MONTE CARLO (Org.). Método de Monte Carlo. Origem Wikipédia, a enciclopédia livre. Disponível em: . Acesso em: 1 out. 2008.
WIKIPEDIA POKER (Org.). Poker. From Wikipedia, the free encyclopedia. Disponível em: . Acesso em: 1 out. 2008.
WIKIPEDIA REINFORCEMENT LEARNING (Org.). Reinforcement Learning. From Wikipedia, the free encyclopedia. Disponível em: . Acesso em: 1 out. 2008.

7. ANEXOS
Esta sessão contém os códigos fontes implementados.
7.1. playpoker.m
Este método joga poker até que um jogador na mesa se torne campeão:
function [ results, winner ] = playpoker(nplayers,playersai,maxgames,initialmoney,smallblind,database,mode) %#ok

% PLAYPOKER Play a poker game.

% Play a poker game. It requests playersai their decision and make them

% learn with the results of the game.

%

% Arguments:



% nplayers - number of players that are gonna play

% playersai - players ai that are gonna play

% maxgames - max number of games

% initialmoney - initial money for each player

% smallblind - the small blind money

% database - database that receives game info

% mode - if 0, test, if 1, check victories, if 2, debug...

%

% @author Vinícius Sousa Fazio



%tic

%%

TEST_MODE = 0;



CHECKVIC_MODE = 1;

DEBUG_MODE = 2;

PLAYER_MODE = 3;

PHPLAYER=1;

PHODDS=2;

PHPOT=3;


PHRAISE=4;

PHROUND=5;

PHCHANCE=6;

PHNPLAYERS=7;

PHFOLLOWERS=8;

PHINGAME=9;

PHQTYRAISE=10;

PHDECISION=11;

PHSIZE=11;

if nargin ~= 7

disp('erro playpoker 1');

return;


end

if mode == TEST_MODE

showgame=0;

playgame(0); % test

return;

end


%% constantes

tablesize=5;

handsize=2;

probprecision=300;

%% aloca memória

hand=zeros(nplayers,handsize);

table=zeros(tablesize,1);

chances=zeros(nplayers,1);

money=zeros(nplayers,1)+initialmoney;

moneybefore=zeros(nplayers,1);

betmade=zeros(nplayers,nplayers);

potlimit=zeros(nplayers,1);

score=zeros(nplayers,1);

prescore=zeros(nplayers,1);

fold=zeros(nplayers,1);

out=zeros(nplayers,1);

if mode == TEST_MODE

results=createresults;

else

results={};



end

%% inicia as variaveis de todos os jogos

showgame=0;

if mode == DEBUG_MODE || mode == PLAYER_MODE

showgame = 1;

end


totalplayers=size(playersai,2);

if mode == CHECKVIC_MODE

playersids=1:totalplayers;

else


playersids=randperm(totalplayers);

end


tablecount=0;

%% joga todos os jogos

%inicia as variaveis de um jogo

tablecount=tablecount+1;

money(1:nplayers)=initialmoney;

money((nplayers+1):end)=0;

gamecount=0;

players(1:nplayers)=playersai(playersids(1:nplayers));

%joga todos os jogos

while gamecount < maxgames

% disp(['-game' int2str(gamecount+1)]);

%reseta o histórico

clear playhistory

playhistory=zeros(nplayers*20,PHSIZE);

playhistoryPointer=1;

numRaises=0;

% joga

gamecount=gamecount+1;



if showgame == 1

disp(['**** JOGO ' int2str(gamecount) ' ****']);

end

playgame;



if showgame == 1

for pp=1:nplayers

mondif=money(pp)-moneybefore(pp);

if mondif < 0

disp(['jogador ' int2str(pp) ' perdeu ' int2str(-mondif) ' com a mão ' int2str(prescore(pp)) ' ' hand2str(pp,5)]);

elseif mondif > 0

disp(['jogador ' int2str(pp) ' ganhou ' int2str(mondif) ' com a mão ' int2str(prescore(pp)) ' ' hand2str(pp,5)]);

else


disp(['jogador ' int2str(pp) ' não ganhou nem perdeu nada com a mão ' int2str(prescore(pp)) ' ' hand2str(pp,5)]);

end


end

disp('. .');

for pp=1:nplayers

disp(['dinheiro do jogador ' int2str(pp) ': ' int2str(money(pp))]);

end

disp('. .');



end

% salva as decisões dos jogadores em um banco de dados

if ~isempty(database)

for php=1:(playhistoryPointer-1)

ph=playhistory(php,:);

pp=ph(PHPLAYER);

result=(money(pp)-moneybefore(pp))/smallblind;

database.insert(ph(PHODDS),ph(PHPOT),ph(PHRAISE),ph(PHROUND),ph(PHCHANCE),ph(PHNPLAYERS),ph(PHFOLLOWERS),ph(PHINGAME),ph(PHQTYRAISE),ph(PHDECISION),result);

end

end


%pára o jogo caso apenas um jogador consiga pagar o bigblind

if size(money(money>=2*smallblind),1) <= 1

% disp('not enough players');

break;


end

end


%atualiza os vencedores

winner=1;

for g=2:nplayers

if money(winner)

winner=g;

end


end

winner=playersids(winner);

%%

function [ handstr ] = hand2str(num,st)



handstr=['-- mão ' int2card(hand(num,1)) ' ' int2card(hand(num,2)) ' / mesa'];

for ss=1:st

handstr=[handstr ' ' int2card(table(ss))]; %#ok

end


function [ card ] = int2card(num)

c = fix((num-1)/4)+2;

switch mod(num-1,4)

case 0


kind = 'p';

case 1


kind = 'e';

case 2


kind = 'o';

case 3


kind = 'c';

end


if c >= 2 && c <= 10

card=[int2str(c) kind];

end

switch c


case 11

card=['J' kind];

case 12

card=['Q' kind];



case 13

card=['K' kind];

case 14

card=['A' kind];



end

end


end

%% results object

% money é quanto cada jogador tem de dinheiro

% guarda os resultados dos jogos (para teste)

function [ r ] = createresults()

totalplayers=size(playersai,2);

r=struct('setgame',@setgame,'getgame',@getgame);

resultdata=zeros(nplayers,maxgames,fix(totalplayers/nplayers));

function [ ] = setgame(tableid,gameid,money)

resultdata(:,gameid,tableid)=money;

end

function [ g ] = getgame(tableid,gameid)



g=resultdata(:,gameid,tableid);

end


end

%% playgame function

%supõe-se que tenha 2 jogadores ou mais com dinheiro para o big blind.

function [] = playgame(testInternal) %#ok

if nargin == 1 % test case

money=[1000 1 50 0];

potlimit=[51 100 1050];

betmade=[[50 0 0 0]; [50 0 0 0]; [50 0 0 0]; [0 0 0 0]];

nplayersongame=3;

doBet(1,200,0);

if money(1) ~= 800 || sum(betmade(:,1)) ~= 151 || sum(betmade(:,2)) ~= 100 || sum(betmade(:,3)) ~= 99

disp('error playgame-doBet 1.1');

end

nplayers=5;



betmade=[[0 0 0 0 0];[0 0 0 0 0];[20 0 0 0 0];[10 0 0 0 0];[0 0 0 0 0]];

fold=[0 0 0 1 0];

out=[1 1 0 0 1];

potlimit=[980 4020 0 0 0];

money=[0 0 960 4010 0];

moneybefore=[0 0 980 4020 0];

prescore=[0 0 833927 10638331 0];

distributePrizes();

if money(3) ~= 990 || money(4) ~= 4010

disp('error playgame-distributePrizes 1.1');

end

return;


end

% variaveis gerais

betmade(:)=0;

moneybefore(:)=money(:);

%sorteia e distribue as cartas

deck=randperm(52);

table(1:tablesize)=deck(1:tablesize);

hand(1:(nplayers*handsize))=deck((tablesize+1):(tablesize+nplayers*handsize));

%calcula os limites de aposta (para o caso de all-in)

tmp=sort(money(money~=0));

nplayersongame=size(tmp,1);

potlimit(1:nplayersongame)=tmp(1:nplayersongame);

%elimina os jogadores sem dinheiro

out(:)=0;

for jj=1:nplayers

if money(jj) < 2*smallblind

out(jj)=1;

end


end

fold(:)=0;

%small blind e big blind

firstplayeronround=fix(rand()*nplayers)+1;

firstplayer=firstplayeronround;

lastplayer=firstplayer+2;

while firstplayer < lastplayer

p=rem(firstplayer,nplayers)+1;

if out(p)==1

lastplayer=lastplayer+1;

else

bet=smallblind*(3-(lastplayer-firstplayer));



doBet(p,bet,0);

end


firstplayer=firstplayer+1;

end


%primeiro round, antes do flop

raise=2*smallblind;

lastplayer=firstplayer+nplayers;

showntable=0;

round=1;

if showgame == 1

disp(['round ' int2str(round)]);

end


playround;

%flop, turn and river

for showntable=3:5

round=round+1;

firstplayer=firstplayeronround;

lastplayer=firstplayer+nplayers;

if showgame == 1

disp(['round ' int2str(round)]);

end

playround;



end

%distribui os prêmios

for jj=1:nplayers

prescore(jj)=pokeronerank(hand(jj,:),table);

end

distributePrizes();



%guarda os resultados

if ~isempty(results)

results.setgame(tablecount,gamecount,money);

end


function [] = distributePrizes()

for m=1:nplayers

pot = sum(betmade(:,m));

if pot == 0

continue;

end


for k=1:nplayers

if fold(k) == 0 && out(k) == 0 && potlimit(m) <= moneybefore(k)

score(k)=prescore(k);

else


score(k)=0;

end


end

[ignore, order]=sort(-score);

k1=order(1);

count=1;


for k=2:nplayers

k2=order(k);

if score(k1)==score(k2)

count=count+1;

else

break;


end

end


for k=1:count

o=order(k);

score(o)=0;

if out(o) == 0

money(o)=money(o)+(pot/count);

end


end

remaind=rem(pot,count);

if remaind~=0

o=order(fix(count*rand()+1));

if out(o) == 0

money(o)=money(o)+remaind;

end

end


end

end


%% playround function

function [] = playround()

for k=1:nplayers

chances(k)=pokerrank(handsize,showntable,hand(k,:),table,sum(out==0)-1,probprecision);

if mode == DEBUG_MODE

disp(['-- chance do player ' int2str(k) ' = ' int2str(chances(k)) '%']);

end

if mode == PLAYER_MODE && strcmp(functiontostring(players(k).decide),'createhumanplayer/decide')



disp(hand2str(k,showntable));

end


end

%% apostas

while firstplayer < lastplayer

p=rem(firstplayer,nplayers)+1;

m=money==0;

mm=zeros(nplayers,1);

for mmm=0:(lastplayer-firstplayer-1)

mm(rem(firstplayer+mmm,nplayers)+1)=1;

end

m=m&mm;


outfold=out+fold+m;

nplayersbetting = sum(outfold==0);

if out(p)~=1 && fold(p) ~= 1 && money(p) > 0 && nplayersbetting > 1

alreadybet=sum(betmade(p,:));

realraise=raise-alreadybet;

startingmoney=money(p)+alreadybet;

realraise = min( realraise, money(p));

realpot=sum(sum(betmade(:,potlimit<=startingmoney)));

odds=0;

if alreadybet ~= 0



odds=realpot/alreadybet;

end


outfold=out+fold;

ingame=sum(outfold==0);

followers=zeros(nplayers,1);

for mmm=0:(lastplayer-firstplayer-1)

followers(rem(firstplayer+mmm,nplayers)+1)=1;

end


followers=followers&(outfold==0);

followers=sum(followers);

if mode == PLAYER_MODE && strcmp(functiontostring(players(p).decide),'createhumanplayer/decide')

disp(['bankroll: ' int2str(money(p))]);

end

decision=players(p).decide(odds,realpot/smallblind,realraise/smallblind,round,chances(p),nplayers,followers,ingame,numRaises);



bet=0;

switch decision

case 1 % fold/call

bet=0;


case 2 % call

bet=realraise;

case 3 % raise low (2-4 smallblind)

bet=realraise+fix(rand()*(2*smallblind))+2*smallblind;

case 4 % raise medium (6-18 smallblind)

bet=realraise+fix(rand()*(12*smallblind))+6*smallblind;

case 5 % raise high (20-40 smallblind)

bet=realraise+fix(rand()*(20*smallblind))+20*smallblind;

case 6 % raise all-in

bet=money(p);

end

if (bet > money(p))



%% allin

bet=money(p);

end

if money(p) > 0 && bet == 0 && realraise > 0



fold(p)=1;

if showgame == 1

disp(['jogador ' int2str(p) ' fugiu']);

end


end

playhistory(playhistoryPointer,PHPLAYER)=p;

playhistory(playhistoryPointer,PHROUND)=round;

playhistory(playhistoryPointer,PHCHANCE)=chances(p);

playhistory(playhistoryPointer,PHPOT)=realpot/smallblind;

playhistory(playhistoryPointer,PHODDS)=odds;

playhistory(playhistoryPointer,PHRAISE)=realraise/smallblind;

playhistory(playhistoryPointer,PHNPLAYERS)=nplayers;

playhistory(playhistoryPointer,PHINGAME)=ingame;

playhistory(playhistoryPointer,PHFOLLOWERS)=followers;

playhistory(playhistoryPointer,PHQTYRAISE)=numRaises;

playhistory(playhistoryPointer,PHDECISION)=decision;

playhistoryPointer=playhistoryPointer+1;

if decision >= 3

numRaises = numRaises + 1;

end


doBet(p,bet,realraise);

bm = sum(betmade(p,:));

if sum(bm > raise)

raise = bm;

lastplayer = firstplayer+nplayers;

end


end

firstplayer=firstplayer+1;

end

end


function [] = doBet(p, bet, realraise)

if showgame == 1 && fold(p) == 0

if bet == 0

disp(['jogador ' int2str(p) ' pede mesa']);

elseif bet == money(p)

disp(['jogador ' int2str(p) ' aumenta all-in com ' int2str(bet)]);

elseif bet > realraise && realraise == 0

disp(['jogador ' int2str(p) ' aposta ' int2str(bet)]);

elseif bet > realraise

disp(['jogador ' int2str(p) ' paga ' int2str(realraise) ' e aumenta ' int2str(bet-realraise)]);

elseif bet == realraise

disp(['jogador ' int2str(p) ' paga ' int2str(bet)]);

else

disp(['jogador ' int2str(p) ' paga misteriosamente somente ' int2str(bet)]);



end

end


%tira o dinheiro

money(p)=money(p)-bet;

%coloca no pot

for i=1:nplayersongame

pl=potlimit(i);

b = bet;


bm = betmade(p,i);

if (bet + bm > pl)

b = pl - bm;

end


if b < 0

b = 0;


end

bet=bet-b;

betmade(p,i)=betmade(p,i)+b;

if bet == 0

break;

end


end

end


%% end of playgame

end


%% end of playpoker

%toc


end

7.2. compute_victory.h


Este método implementa o Monte-Carlo. Ele faz simulações aleatórias e retorna o número de simulações vitoriosas.
/*

* author Vinícius Sousa Fazio

*/

#include "getpower.h"


double computeRealVictoriesRandomly(int nCardsOnHand, int nCardsOnTable, int* allyHand, int* table, int nEnemies, int gameCount) {

int* pgc = playerGameCards;

int* egc = enemyGameCards;

int* adeck = deck;

// contador dos jogos

int iLose = 0;

//temporários

int i, j, c, pow;

// coloca a mesa no jogo de todo mundo.

for (i = 0; i < nCardsOnTable; i++) {

pgc[i] = table[i];

for (j = 0; j < nEnemies; j++) {

egc[j * GAME_SIZE + i] = table[i];

}

}



for (i = 0; i < nCardsOnHand; i++) {

pgc[TABLE_SIZE + i] = allyHand[i];

}

// comeca a jogar



for (c = gameCount; c > 0; c--)

{

// monta um baralho com as cartas que já saíram



int totalCards = (nEnemies + 1) * HAND_SIZE + TABLE_SIZE;

int deckP = 0;

for (i = 0; i < nCardsOnTable; i++) {

adeck[deckP++] = table[i];

}

for (i = 0; i < nCardsOnHand; i++) {



adeck[deckP++] = allyHand[i];

}

// sorteia o resto do baralho



pow = 0;

for (i = deckP; i < totalCards; i++) {

// O rand é bugado. Ele não sorteia todos os números.

// Com essa gambiarra funciona.

// os comentarios abaixo são debug

int card = (rand() % (CARDS_QUANTITY << 2)) >> 2;

bool repeated = false;

// mexPrintf ("%i | %i $ ", card, i);

for (j = 0; j < i && !repeated; j++)

{

// mexPrintf (" %i", adeck[j]);



repeated |= card == adeck[j];

}

// mexPrintf ("\n");



adeck[i] = card;

if (repeated)

{

i--;


}

// if (pow++ > 100) break;

}

// mexPrintf ("Contagem: %i\n", pow);



// sorteia o resto da mao.

for (i = nCardsOnHand; i < HAND_SIZE; i++) {

pgc[TABLE_SIZE + i] = adeck[deckP++];

}

// sorteia o resto da mesa.



for (i = nCardsOnTable; i < TABLE_SIZE; i++) {

int card = adeck[deckP++];

pgc[i] = card;

for (j = 0; j < nEnemies; j++) {

egc[j * GAME_SIZE + i] = card;

}

}



// sorteia as cartas dos inimigos

for (j = (nEnemies - 1) * GAME_SIZE; j >= 0; j -= GAME_SIZE) {

for (i = TABLE_SIZE; i < GAME_SIZE; i++) {

egc[j + i] = adeck[deckP++];

}

}

pow = getGameCardsPower(pgc);



for (j = (nEnemies - 1) * GAME_SIZE; j >= 0; j -= GAME_SIZE) {

if (pow < getGameCardsPower(egc + j)) {

iLose++;

break;


}

}

}



return gameCount - iLose;

}

7.3. getpower.h


Este método retorna um número representando o ranking de um jogador. Por exemplo, se o jogador tem um par com um K, J e 5 para desempate, esse jogo é transformado em um número inteiro sendo que o maior número é o maior jogo.
/*

* author Vinícius Sousa Fazio

*/

int getGameCardsPower(int* someoneGameCards) {



/**

*

* return int: 4 bits (game) + 20 bits (cards) game: 0: highcard 1: pair



* 2: 2 pairs 3: 3 of a kind 4: straight 5: flush 6: fullhouse 7: 4 of a

* kind 8: straight flush

*

* cartas: 4 bits por carta, em ordem descendente.



*

* os [>> 2], [<< 2] e [& 3] são para otimizar as contas [/

* CARD_TYPE_SIZE], [* CARD_TYPE_SIZE] e [%

* CARD_TYPE_SIZE] respectivamente.

*/

int nPair = 0;



int nThreeOfAKind = 0;

int nFourOfAKind = 0;

bool straight = false;

bool flush = false;

bool straightFlush = false;

int straightCard = 0;

int straightFlushCard = 0;

int power = 0;

int* sgc = sortedGameCards;

int* sgcs = sortedGameCardsShifted;

//temporário

int i, j, repeated;

for (i = 0; i < GAME_SIZE; i++)

{

sgc[i] = someoneGameCards[i];



}

// ordena as cartas em ordem descendente

for (i = 0; i < GAME_SIZE; i++) {

bool changed = false;

for (j = 0; j < GAME_SIZE - 1; j++) {

int s1 = sgc[j];

int s2 = sgc[j + 1];

if (s1 < s2) {

sgc[j] = s2;

sgc[j + 1] = s1;

changed = true;

}

}



if (!changed) break;

}

for (i = 0; i < GAME_SIZE; i++) {



sgcs[i] = sgc[i] >> 2;

}

// pair, 3-of-a-kind, 4-of-a-kind, full house e 2 pairs



repeated = 0;

for (i = 1; i < GAME_SIZE; i++) {

if ((sgcs[i - 1]) == (sgcs[i])) {

repeated++;

switch (repeated) {

case 1:


pairCards[nPair++] = i;

pairCards[nPair++] = i - 1;

break;

case 2:


threeOfAKindCards[nThreeOfAKind++] = i;

threeOfAKindCards[nThreeOfAKind++] = pairCards[--nPair];

threeOfAKindCards[nThreeOfAKind++] = pairCards[--nPair];

break;


case 3:

fourOfAKindCards[nFourOfAKind++] = i;

fourOfAKindCards[nFourOfAKind++] = threeOfAKindCards[--nThreeOfAKind];

fourOfAKindCards[nFourOfAKind++] = threeOfAKindCards[--nThreeOfAKind];

fourOfAKindCards[nFourOfAKind++] = threeOfAKindCards[--nThreeOfAKind];

break;


}

} else {


repeated = 0;

}

}



// straight flush

for (j = 0; j < GAME_SIZE - 3 && !straightFlush; j++) {

int cardsInARow = 1 << 2;

int a = sgc[j];

for (i = j + 1; i < GAME_SIZE; i++) {

int b = sgc[i];

if (a - b == cardsInARow) {

cardsInARow += 1 << 2;

if (cardsInARow == 5 << 2) {

straightFlushCard = j;

straightFlush = true;

break;


}

}

}



if (cardsInARow == 4 << 2 && // 4 cartas na sequencia

(a >> 2) == 3 && !straightFlush) // sequencia até 5

{

for (i = 0; i < CARD_TYPE_SIZE; i++) {



if (sgcs[i] == CARD_A) // tem A

{

if ((sgc[i] & 3) == (a & 3)) // mesmo



// naipe

{

straightFlushCard = j;



straightFlush = true;

break;


}

} else {


break;

}

}



}

}

if (!straightFlush) {



// flush

int nCardsOfEachType[CARD_TYPE_SIZE];

for (i = 0; i < CARD_TYPE_SIZE; i++) {

nCardsOfEachType[i] = 0;

}

for (i = 0; i < GAME_SIZE; i++) {



int t = sgc[i] & 3; // naipe

if (++nCardsOfEachType[t] == 5) {

int count = 0;

flush = true;

for (j = 0; j <= i; j++) {

if (t == (sgc[j] & 3)) {

flushCards[count++] = j;

}

}



break;

}

}



// straight

if (!flush) {

int cardsInARow = 1;

bool hasA = sgcs[0] == CARD_A;

int lastCard = sgcs[0];

straightCard = 0;

for (i = 1; i < GAME_SIZE && !straight; i++) {

int newCard = sgcs[i];

switch (lastCard - newCard) {

case 1:


switch (++cardsInARow) {

case 5:


straight = true;

break;


case 4:

if (hasA && newCard == 0) // seq de 'a' a '5'

{

straight = true;



}

break;


}

break;


case 0:

// carta repetida

break;

default:


cardsInARow = 1;

straightCard = i;

}

lastCard = newCard;



}

}

}



power = 0;

if (straightFlush) {

power = sgcs[straightFlushCard];

power |= 8 << (5 * CARD_BIT_SIZE);

} else if (nFourOfAKind == 4) {

power = sgcs[fourOfAKindCards[0]];

power <<= CARD_BIT_SIZE;

power |= getOtherCards(sgcs,

fourOfAKindCards, 4, 1);

power |= 7 << (5 * CARD_BIT_SIZE);

} else if ((nThreeOfAKind >= 3 && nPair >= 2)) {

power |= sgcs[threeOfAKindCards[0]];

power <<= CARD_BIT_SIZE;

if (nThreeOfAKind > 3) {

int card1 = sgcs[pairCards[0]];

int card2 = sgcs[threeOfAKindCards[3]];

power |= card1 > card2 ? card1 : card2;

} else {


power |= sgcs[pairCards[0]];

}

power |= 6 << (5 * CARD_BIT_SIZE);



} else if (nThreeOfAKind >= 6) {

power |= sgcs[threeOfAKindCards[0]];

power <<= CARD_BIT_SIZE;

power |= sgcs[threeOfAKindCards[3]];

power |= 6 << (5 * CARD_BIT_SIZE);

} else if (flush) {

for (i = 0; i < 5; i++) {

power <<= CARD_BIT_SIZE;

power |= sgcs[flushCards[i]];

}

power |= 5 << (5 * CARD_BIT_SIZE);



} else if (straight) {

power = sgcs[straightCard];

power |= 4 << (5 * CARD_BIT_SIZE);

} else if (nThreeOfAKind == 3) {

power = sgcs[threeOfAKindCards[0]];

power <<= 2 * CARD_BIT_SIZE;

power |= getOtherCards(sgcs,

threeOfAKindCards, 3, 2);

power |= 3 << (5 * CARD_BIT_SIZE);

} else if (nPair >= 4) {

power = sgcs[pairCards[0]];

power <<= CARD_BIT_SIZE;

power |= sgcs[pairCards[2]];

power <<= CARD_BIT_SIZE;

power |= getOtherCards(sgcs, pairCards, 4, 1);

power |= 2 << (5 * CARD_BIT_SIZE);

} else if (nPair == 2) {

power = sgcs[pairCards[0]];

power <<= 3 * CARD_BIT_SIZE;

power |= getOtherCards(sgcs, pairCards, 2, 3);

power |= 1 << (5 * CARD_BIT_SIZE);

} else // high card

{

power = sgcs[0];



power <<= CARD_BIT_SIZE;

power |= sgcs[1];

power <<= CARD_BIT_SIZE;

power |= sgcs[2];

power <<= CARD_BIT_SIZE;

power |= sgcs[3];

power <<= CARD_BIT_SIZE;

power |= sgcs[4];

}

return power;



}

int getOtherCards(int* hand, int* game, int gameCards,

int qty) {

int i, g, cards = 0;

for (i = 0; i < GAME_SIZE; i++) {

bool inGame = false;

for (g = 0; g < gameCards; g++) {

if (game[g] == i) {

inGame = true;

break;


}

}

if (!inGame && qty > 0) {



cards <<= CARD_BIT_SIZE;

cards |= hand[i];

qty--;

}

}



return cards;

}
7.4. pokeronerank.c


Este método faz a interface com o Matlab para retornar o ranking de um jogador.
/*

* author Vinícius Sousa Fazio

*/
#include "mex.h"

#define GAME_SIZE 7

#define CARD_TYPE_SIZE 13

#define CARD_A CARD_TYPE_SIZE - 1

#define CARD_BIT_SIZE 4

#define HAND_SIZE 2

#define TABLE_SIZE 5

#define CARDS_QUANTITY CARD_TYPE_SIZE << 2


int* sortedGameCards;

int* sortedGameCardsShifted;

int* pairCards;

int* threeOfAKindCards;

int* fourOfAKindCards;

int* flushCards;

#include "getpower.h"
void mexFunction( int nlhs, mxArray *plhs[],

int nrhs, const mxArray *prhs[] )

{

double r;



int* hand;

double* allyHandD;

double* tableD;

int i;


if (nrhs != 2){

mexErrMsgTxt ("Número de argumentos inválido.");

return;


}

allyHandD = mxGetPr(prhs[0]);

tableD = mxGetPr(prhs[1]);

hand = malloc(GAME_SIZE * sizeof(int));

sortedGameCards = malloc(GAME_SIZE * sizeof(int));

sortedGameCardsShifted = malloc(GAME_SIZE * sizeof(int));

pairCards = malloc(GAME_SIZE * sizeof(int));

threeOfAKindCards = malloc(GAME_SIZE * sizeof(int));

fourOfAKindCards = malloc(GAME_SIZE * sizeof(int));

flushCards = malloc(5 * sizeof(int));

for (i = 0; i < HAND_SIZE; i++)

{

hand[i] = (int)allyHandD[i]-1;



}

for (i = 0; i < TABLE_SIZE; i++)

{

hand[i+HAND_SIZE] = (int)tableD[i]-1;



}

r=getGameCardsPower(hand);



free(hand);

free(sortedGameCards);

free(sortedGameCardsShifted);

free(pairCards);

free(threeOfAKindCards);

free(fourOfAKindCards);

free(flushCards);

plhs[0] = mxCreateDoubleMatrix(1,1, mxREAL);



mxGetPr(plhs[0])[0] = r;

}
7.5. pokerrank.c


Este método faz a interface com o Matlab para retornar a probabilidade de vencer de um jogador pelo método Monte-Carlo.
/*

* author Vinícius Sousa Fazio

*/
#include "mex.h"
#define GAME_SIZE 7

#define CARD_TYPE_SIZE 13

#define CARD_A CARD_TYPE_SIZE - 1

#define CARD_BIT_SIZE 4

#define HAND_SIZE 2

#define TABLE_SIZE 5

#define CARDS_QUANTITY CARD_TYPE_SIZE << 2
int* sortedGameCards;

int* sortedGameCardsShifted;

int* pairCards;

int* threeOfAKindCards;

int* fourOfAKindCards;

int* flushCards;

int* playerGameCards;

int* enemyGameCards;

int* deck;

#include "compute_victory.h"


void mexFunction( int nlhs, mxArray *plhs[],

int nrhs, const mxArray *prhs[] )

{

double r;



int nCardsOnHand;

int nCardsOnTable;

int* allyHand;

int* table;

double* allyHandD;

double* tableD;

int nEnemies;

int gameCount;

int i;

if (nrhs != 6){



mexErrMsgTxt ("Número de argumentos inválido.");

return;


}

nCardsOnHand = mxGetScalar(prhs[0]);

nCardsOnTable = mxGetScalar(prhs[1]);

allyHandD = mxGetPr(prhs[2]);

tableD = mxGetPr(prhs[3]);

nEnemies = mxGetScalar(prhs[4]);

gameCount = mxGetScalar(prhs[5]);

allyHand = malloc(nCardsOnHand * sizeof(int));

table = malloc(nCardsOnTable * sizeof(int));

sortedGameCards = malloc(GAME_SIZE * sizeof(int));

sortedGameCardsShifted = malloc(GAME_SIZE * sizeof(int));

pairCards = malloc(GAME_SIZE * sizeof(int));

threeOfAKindCards = malloc(GAME_SIZE * sizeof(int));

fourOfAKindCards = malloc(GAME_SIZE * sizeof(int));

flushCards = malloc(5 * sizeof(int));

playerGameCards = malloc(GAME_SIZE * sizeof(int));

enemyGameCards = malloc(GAME_SIZE * nEnemies * sizeof(int));

deck = malloc(CARDS_QUANTITY * sizeof(int));;

for (i = 0; i < nCardsOnHand; i++)

{

allyHand[i] = (int)allyHandD[i]-1;



}

for (i = 0; i < nCardsOnTable; i++)

{

table[i] = (int)tableD[i]-1;



}

r = computeRealVictoriesRandomly(nCardsOnHand, nCardsOnTable, allyHand, table, nEnemies, gameCount);



free(allyHand);

free(table);

free(sortedGameCards);

free(sortedGameCardsShifted);

free(pairCards);

free(threeOfAKindCards);

free(fourOfAKindCards);

free(flushCards);

free(playerGameCards);

free(enemyGameCards);

free(deck);

plhs[0] = mxCreateDoubleMatrix(1,1, mxREAL);



mxGetPr(plhs[0])[0] = ((double) (100*r)) / (double) gameCount;

}
7.6. test_pokerrank.c


Este método faz a interface com o Matlab para gerar os dados para demonstrar a convergencia do método Monte-Carlo.
/*

* author Vinícius Sousa Fazio

*/
#include "mex.h"
#define GAME_SIZE 7

#define CARD_TYPE_SIZE 13

#define CARD_A CARD_TYPE_SIZE - 1

#define CARD_BIT_SIZE 4

#define HAND_SIZE 2

#define TABLE_SIZE 5

#define CARDS_QUANTITY CARD_TYPE_SIZE << 2
int* sortedGameCards;

int* sortedGameCardsShifted;

int* pairCards;

int* threeOfAKindCards;

int* fourOfAKindCards;

int* flushCards;

int* playerGameCards;

int* enemyGameCards;

int* deck;

#include "compute_victory.h"


void mexFunction( int nlhs, mxArray *plhs[],

int nrhs, const mxArray *prhs[] )

{

double r;



int nCardsOnHand;

int nCardsOnTable;

int* allyHand;

int* table;

double* allyHandD;

double* tableD;

int nEnemies;

int gameCount;

int i;

int winCount;



if (nrhs != 6){

mexErrMsgTxt ("Número de argumentos inválido.");

return;


}

nCardsOnHand = mxGetScalar(prhs[0]);

nCardsOnTable = mxGetScalar(prhs[1]);

allyHandD = mxGetPr(prhs[2]);

tableD = mxGetPr(prhs[3]);

nEnemies = mxGetScalar(prhs[4]);

gameCount = mxGetScalar(prhs[5]);

allyHand = malloc(nCardsOnHand * sizeof(int));

table = malloc(nCardsOnTable * sizeof(int));

sortedGameCards = malloc(GAME_SIZE * sizeof(int));

sortedGameCardsShifted = malloc(GAME_SIZE * sizeof(int));

pairCards = malloc(GAME_SIZE * sizeof(int));

threeOfAKindCards = malloc(GAME_SIZE * sizeof(int));

fourOfAKindCards = malloc(GAME_SIZE * sizeof(int));

flushCards = malloc(5 * sizeof(int));

playerGameCards = malloc(GAME_SIZE * sizeof(int));

enemyGameCards = malloc(GAME_SIZE * nEnemies * sizeof(int));

deck = malloc(CARDS_QUANTITY * sizeof(int));;

for (i = 0; i < nCardsOnHand; i++)

{

allyHand[i] = (int)allyHandD[i]-1;



}

for (i = 0; i < nCardsOnTable; i++)

{

table[i] = (int)tableD[i]-1;



}

plhs[0] = mxCreateDoubleMatrix(gameCount,1, mxREAL);

winCount = 0;

for (i = 0; i < gameCount; i++){

winCount += computeRealVictoriesRandomly(nCardsOnHand, nCardsOnTable, allyHand, table, nEnemies, 1);

mxGetPr(plhs[0])[i] = ((double) (100*winCount)) / (double) (i+1);

}

free(allyHand);



free(table);

free(sortedGameCards);

free(sortedGameCardsShifted);

free(pairCards);

free(threeOfAKindCards);

free(fourOfAKindCards);

free(flushCards);

free(playerGameCards);

free(enemyGameCards);

free(deck);

}
7.7. createconstantplayer.m


Este método cria o jogador Constante.
% @author Vinícius Sousa Fazio

function [ playerai ] = createconstantplayer(dec)

% Cria um jogador que joga sempre joga a mesma coisa

playerai=struct('decide',@decide,'learn',@learn,'get',@get);

d=dec;


function [ decision ] = decide(odds,pot,raise,round,chances,nplayers,followers,ingame,qtyraise) %#ok

decision=d;

end

function [] = get() %#ok



end

function [] = learn() %#ok

end
end

7.8. creatediscreteplayer.m


Este método cria o jogador com aprendizado por reforço.
% @author Vinícius Sousa Fazio

function [ playerai ] = creatediscreteplayer(stopLearn,oddsSc,chanceSc,potSc,raiseSc,qtyraiseSc,followersSc,ingameSc,nplayersSc,arraySiz,littleArraySiz)

% Cria um jogador que joga através do aprendizado por esforço

playerai=struct('decide',@decide,'learn',@learn,'get',@get);

%CUIDADO com o value de littleArraySiz e arraySiz para não estourar a

%memória
%personality paramenters

stopLearning=stopLearn;

verybigvalue=999999;

if oddsSc == -1

oddsScaling=verybigvalue;

oddsSize = 1;

else

oddsScaling=oddsSc;



oddsSize = arraySiz;

end
if chanceSc == -1

chancesScaling=verybigvalue;

chanceSize = 1;

else

chancesScaling=chanceSc;



chanceSize = arraySiz;

end
if potSc == -1

potScaling=verybigvalue;

potSize = 1;

else

potScaling=potSc;



potSize = arraySiz;

end
if raiseSc == -1

raiseScaling=verybigvalue;

raiseSize = 1;

else

raiseScaling=raiseSc;



raiseSize = arraySiz;

end
if qtyraiseSc == -1

qtyraiseScaling=verybigvalue;

qtyraiseSize = 1;

else

qtyraiseScaling=qtyraiseSc;



qtyraiseSize = littleArraySiz;

end
if followersSc == -1

followersScaling=verybigvalue;

followersSize = 1;

else

followersScaling=followersSc;



followersSize = littleArraySiz;

end
if ingameSc == -1

ingameScaling=verybigvalue;

ingameSize = 1;

else

ingameScaling=ingameSc;



ingameSize = littleArraySiz;

end
if nplayersSc == -1

nplayersScaling=verybigvalue;

nplayersSize = 1;

else

nplayersScaling=nplayersSc;



nplayersSize = littleArraySiz;

end


numrounds=2;

% odds, pot, raise, chances, round, qtyraise, followers, ingame, nplayers, win/lose, decision

db=zeros(oddsSize,potSize,raiseSize,chanceSize,numrounds,qtyraiseSize,followersSize,ingameSize,nplayersSize,2,6);

% odds, pot, raise, chances, round, qtyraise, followers, ingame, nplayers, win/lose, decision

qty=zeros(oddsSize,potSize,raiseSize,chanceSize,numrounds,qtyraiseSize,followersSize,ingameSize,nplayersSize,2,6);

RANDOM_DECISION=0;

BEST_REC_DIFFERENCE=1;

BEST_REC_RELATION=2;

BEST_VIC_RELATION=3;

WHEEL_REC_DIFFERENCE=4;

WHEEL_VIC_RELATION=5;

WHEEL_VIC_ABSOLUTE=6;

decisionkind=BEST_REC_DIFFERENCE;

function [ decision ] = decide(odds,pot,raise,round,chances,nplayers,followers,ingame,qtyraise)

if nargin == 1

decisionkind=odds;

elseif nargin == 0

%não decide nada, apenas plota as decisões.

disp(['stopLearning ' num2str(stopLearning)]);

disp(['oddsScaling ' num2str(oddsScaling)]);

disp(['chancesScaling ' num2str(chancesScaling)]);

disp(['potScaling ' num2str(potScaling)]);

disp(['raiseScaling ' num2str(raiseScaling)]);

disp(['qtyraiseScaling ' num2str(qtyraiseScaling)]);

disp(['followersScaling ' num2str(followersScaling)]);

disp(['ingameScaling ' num2str(ingameScaling)]);

disp(['nplayersScaling ' num2str(nplayersScaling)]);

clear tmp;

tmp=NaN(oddsSize*potSize,raiseSize*chanceSize*qtyraiseSize*followersSize*ingameSize*nplayersSize*numrounds);

k=0;


for nplayersD=1:nplayersSize;

for ingameD=1:ingameSize;

for followersD=1:followersSize;

for qtyraiseD=1:qtyraiseSize;

for round=1:2

for chancesD=1:chanceSize

for raiseD=1:raiseSize

for potD=1:potSize

for oddsD=1:oddsSize

k=k+1;


decision=decideWithGame();

tmp(k)=decision;

end

end


end

end


end

end


end

end


end

pcolor(tmp);

shading flat;

clear tmp;

else

%discretiza os argumentos



oddsD=min(fix(odds/oddsScaling)+1,oddsSize);

chancesD=min(fix(chances/chancesScaling)+1,chanceSize);

potD=min(fix(pot/potScaling)+1,potSize);

raiseD=min(fix(raise/raiseScaling)+1,raiseSize);

qtyraiseD=min(fix(qtyraise/qtyraiseScaling)+1,qtyraiseSize);

followersD=min(fix(followers/followersScaling)+1,followersSize);

ingameD=min(fix(ingame/ingameScaling)+1,ingameSize);

nplayersD=min(fix(nplayers/nplayersScaling)+1,nplayersSize);

round=min(round,numrounds);

decision=decideWithGame();

end
function [ decision ] = decideWithGame()

%extrai informação no banco para uma decisão

reswin=db(oddsD,potD,raiseD,chancesD,round,qtyraiseD,followersD,ingameD,nplayersD,1,:);

reslose=db(oddsD,potD,raiseD,chancesD,round,qtyraiseD,followersD,ingameD,nplayersD,2,:);

sizwin=qty(oddsD,potD,raiseD,chancesD,round,qtyraiseD,followersD,ingameD,nplayersD,1,:);

sizlose=qty(oddsD,potD,raiseD,chancesD,round,qtyraiseD,followersD,ingameD,nplayersD,2,:);

decision=NaN;

%só usa decisão se o numero de decisoes é maior que o limiar

if sum(sizwin)+sum(sizlose) > stopLearning

switch decisionkind

case BEST_REC_DIFFERENCE %melhor recompensa (diferença) em dinheiro

maxres=NaN;

for dec=1:6

sizw=sizwin(dec);

sizl=sizlose(dec);

if sizw + sizl > 0

res=(reswin(dec)-reslose(dec))/(sizw+sizl);

if isnan(maxres) || res > maxres

maxres=res;

decision=dec;

end

end


end

case BEST_REC_RELATION %melhor recompensa (relação) em dinheiro

maxres=NaN;

for dec=1:6

sizw=sizwin(dec);

sizl=sizlose(dec);

if sizw + sizl > 0

res=((reswin(dec)+1)/(reslose(dec)+1)) * ((sizl+1)/(sizw+1));

if isnan(maxres) || res > maxres

maxres=res;

decision=dec;

end


end

end


case BEST_VIC_RELATION %melhor vitória (relação)

maxres=NaN;

for dec=1:6

if sizwin(dec) + sizlose(dec) > 0

res=(sizwin(dec)/(sizlose(dec)+1));

if isnan(maxres) || res > maxres

maxres=res;

decision=dec;

end

end


end

case WHEEL_REC_DIFFERENCE %roleta de melhor (diferença) recompensa

receachdecision=[0 0 0 0 0 0];

for dec=1:6

sizw=sizwin(dec);

sizl=sizlose(dec);

if sizw + sizl > 0

res=fix(100*(reswin(dec)-reslose(dec))/(sizw+sizl));

receachdecision(dec)=res;

end


end

sumreceachdecision=sum(receachdecision(receachdecision > 0));

if sumreceachdecision == 0

receachdecision=receachdecision-min(receachdecision);

sumreceachdecision=sum(receachdecision(receachdecision > 0));

end


rnddecision=rand*sumreceachdecision;

for dec=1:6

if receachdecision(dec)>0

rnddecision=rnddecision-receachdecision(dec);

if rnddecision < 0

decision=dec;

break;

end


end

end


case WHEEL_VIC_RELATION %roleta de maior (relação) vitória

receachdecision=[0 0 0 0 0 0];

for dec=1:6

receachdecision(dec)=fix(sizwin(dec)/(1+sizlose(dec)));

end

sumreceachdecision=sum(receachdecision);



if sumreceachdecision >= 1

rnddecision=rand*sumreceachdecision;

for dec=1:6

rnddecision=rnddecision-receachdecision(dec);

if rnddecision < 0

decision=dec;

break;

end


end

else


decision=1;

end


case WHEEL_VIC_ABSOLUTE %roleta de maior (absoluto) vitória

sumsizwin=sum(sizwin);

if sumsizwin >= 1

rnddecision=sumsizwin*rand;

for dec=1:6

rnddecision=rnddecision-sizwin(dec);

if rnddecision < 0

decision=dec;

break;

end


end

end


case RANDOM_DECISION

% não faz nada pq vai tomar a decisão aleatória no fim

end

end


if isnan(decision)

switch fix(rand*9)

case 0

decision = 1;



case 1

decision = 3;

case 2

decision = 4;



case 3

decision = 5;

case 4

decision = 6;



otherwise

decision = 2;

end

% decision=0;



end

end


end

function [ rdb, rqty ] = get()

rdb=db;

rqty=qty;



end

function [] = learn(argdb,argqty)

if nargin == 0

% não aprende. Apenas plota learn qty

tmp=zeros(oddsSize*potSize*raiseSize*chanceSize,qtyraiseSize*followersSize*ingameSize*nplayersSize*numrounds*12);

tmp(:)=qty(:);

pcolor(tmp);

shading flat;

else

db=argdb;



qty=argqty;

end


end

end
7.9. createhumanplayer.m


Este método cria o jogador humano.
function [ playerai ] = createhumanplayer() %#ok

% @author Vinícius Sousa Fazio

% jogador humano
playerai=struct('decide',@decide,'learn',@learn,'get',@get);

function [ decision ] = decide(odds,pot,raise,round,chances,nplayers,followers,ingame,qtyraise) %#ok

disp(['odds: ' num2str(odds)]);

disp(['pot: ' num2str(pot)]);

disp(['raise: ' num2str(raise)]);

disp(['round: ' num2str(round)]);

disp(['chances: ' num2str(chances)]);

disp(['nplay: ' num2str(nplayers)]);

disp(['follow: ' num2str(followers)]);

disp(['ingame: ' num2str(ingame)]);

disp(['qtyraise: ' num2str(qtyraise)]);

repeat=1;

while repeat == 1

decision=input('Escolha a jogada:');

if decision==1 || decision==2 || decision==3 || decision==4 || decision==5 || decision==6

repeat=0;

end

end


end

function [] = get() %#ok

end

function [] = learn() %#ok



end

end


7.10. createmfsplayer.m
Este método cria o jogador MFS.
function [ playerai ] = createmfsplayer(argt)

% @author Vinícius Sousa Fazio

% Cria um jogador que joga matematicamente justo

playerai=struct('decide',@decide,'learn',@learn,'get',@get);

t = argt;

function [ decision ] = decide(odds,pot,raise,round,chances,nplayers,followers,ingame,qtyraise) %#ok

if (odds == 0)

decision=2;

else

othermoney=(pot*(odds-1))/odds;



mymoney=pot-othermoney+raise;

up=(chances*othermoney)/100;

down=((100-chances)*mymoney)/100;

dif=up-down;

if dif < -1 * t

decision = 1;

elseif dif < 1 * t

decision = 2;

elseif dif < 5 * t

decision = 3;

elseif dif < 10 * t

decision = 4;

elseif dif < 15 * t

decision = 5;

else

decision = 6;



end

end


end

function [] = get() %#ok

end

function [] = learn() %#ok



end
end

7.11. createrandomplayer.m


Este método cria o jogador Aleatório.
% @author Vinícius Sousa Fazio

function [ playerai ] = createrandomplayer() %#ok

% Jogador aleatório

playerai=struct('decide',@decide,'learn',@learn,'get',@get);

function [ decision ] = decide(odds,pot,raise,round,chances,nplayers,followers,ingame,qtyraise) %#ok

switch fix(rand*9)

case 0

decision = 1;



case 1

decision = 3;

case 2

decision = 4;



case 3

decision = 5;

case 4

decision = 6;



otherwise

decision = 2;

end

end


function [] = get() %#ok

end


function [] = learn() %#ok

end


end

7.12. createrhplayer.m


Este método cria o jogador RH.
% @author Vinícius Sousa Fazio

function [ playerai ] = createrhplayer(argt)

% Cria um jogador que joga de acordo com RH

playerai=struct('decide',@decide,'learn',@learn,'get',@get);

t = argt;

function [ decision ] = decide(odds,pot,raise,round,chances,nplayers,followers,ingame,qtyraise) %#ok

v = pot / ((qtyraise+1) * followers * ingame * (raise+1));

if v < t


decision = 1;

elseif v < 20*t

decision = 2;

elseif v < 50*t

decision = 3;

elseif v < 100*t

decision = 4;

elseif v < 1000*t

decision = 5;

else


decision = 6;

end


% disp(['v ' num2str(v) ' decision ' num2str(decision)]);

end


function [] = get() %#ok

end


function [] = learn() %#ok

end
end

7.13. createdatabase.m
Este método cria a base de dados de jogadas para ser utilizada mais tarde pelos jogadores evolutivos.
% @author Vinícius Sousa Fazio

function [ result ] = createdatabase()

% Cria uma base de dados de jogadas e resultados

NVARS=11;

result=struct('get',@get,'insert',@insert);

db = zeros(100000,NVARS);

size=0;

%% get database



function [ resdb,siz ] = get()

resdb=db;

siz=size;

end


%% insert a new element

function [ ndata ] = insert(odds,pot,raise,round,chances,nplayers,followers,ingame,qtyraise,decision,result)

if size < length(db) - 1

ndata=size;

if nargin ~= 0

size=size+1;

db(size,1:NVARS)=[odds pot raise round chances nplayers followers ingame qtyraise decision result];

end


else

ndata=0;


end

end


end

7.14. traindiscrete.c


Este método treina o jogador com aprendizado por esforço.
/*

* Treina o jogador discreto. Feito em C pelo maior desempenho

* author Vinícius Sousa Fazio

*/
#include "mex.h"


#define DECISIONS 6

#define ROUNDS 2

#define WINLOSES 2

#define HODD 0

#define HPOT 1

#define HRAISE 2

#define HROUND 3

#define HCHANCE 4

#define HNPLAY 5

#define HFOLLOW 6

#define HINGAME 7

#define HQTYRAISE 8

#define HDECISION 9

#define HRESULT 10


#define VERYBIGVALUE 999999
void mexFunction( int nlhs, mxArray *plhs[],

int nrhs, const mxArray *prhs[] )

{

// entrada



double to, tr, tc, tp, tq, tf, ti, tn;

int maxr, maxc, maxp, maxo, maxq, maxf, maxi, maxn;

int maxhistory,maxh,hsize;

mwSize *pdbsize;

mwSize *hdbsize;

double *qty;

double *pdb;

double *hdb;

// calculo

double odd, pot, raise, chance, round, qtyraise, follow, ingame, nplay, result;

int oddD, potD, raiseD, chanceD, roundD, qtyraiseD, followD, ingameD, nplayD, decision;

int winlose,siz;

double newres;

int ip;


// constantes

int hodd, hpot, hraise, hchance, hround, hqtyraise, hfollow, hingame, hnplay, hdecision, hresult;

int podd, ppot, praise, pchance, pround, pqtyraise, pfollow, pingame, pnplay, pdecision, pwinlose;

int i;


// checa número de argumentos

if (nrhs != 12){



mexErrMsgTxt ("Número de argumentos inválido.");

return;


}

// lê a entrada

to = mxGetScalar(prhs[0]);

tr = mxGetScalar(prhs[1]);

tc = mxGetScalar(prhs[2]);

tp = mxGetScalar(prhs[3]);

tq = mxGetScalar(prhs[4]);

tf = mxGetScalar(prhs[5]);

ti = mxGetScalar(prhs[6]);

tn = mxGetScalar(prhs[7]);

to = to == -1 ? VERYBIGVALUE : to;

tr = tr == -1 ? VERYBIGVALUE : tr;

tc = tc == -1 ? VERYBIGVALUE : tc;

tp = tp == -1 ? VERYBIGVALUE : tp;

tq = tq == -1 ? VERYBIGVALUE : tq;

tf = tf == -1 ? VERYBIGVALUE : tf;

ti = ti == -1 ? VERYBIGVALUE : ti;

tn = tn == -1 ? VERYBIGVALUE : tn;

qty = mxGetPr(prhs[8]);

pdb = mxGetPr(prhs[9]);

hsize = mxGetScalar(prhs[10]);

hdb = mxGetPr(prhs[11]);

pdbsize = mxGetDimensions(prhs[9]);

hdbsize = mxGetDimensions(prhs[11]);

maxo=(int)(pdbsize[0]);

maxp=(int)(pdbsize[1]);

maxr=(int)(pdbsize[2]);

maxc=(int)(pdbsize[3]);

maxq=(int)(pdbsize[5]);

maxf=(int)(pdbsize[6]);

maxi=(int)(pdbsize[7]);

maxn=(int)(pdbsize[8]);

maxhistory=((int)(hdbsize[0]));

maxh=(int)(hdbsize[1]);

// gera constantes para auxiliar os ponteiros das bases de dados

hodd=HODD * maxhistory;

hpot=HPOT * maxhistory;

hraise=HRAISE * maxhistory;

hchance=HCHANCE * maxhistory;

hround=HROUND * maxhistory;

hnplay=HNPLAY * maxhistory;

hfollow=HFOLLOW * maxhistory;

hingame=HINGAME * maxhistory;

hqtyraise=HQTYRAISE * maxhistory;

hresult=HRESULT * maxhistory;

hdecision=HDECISION * maxhistory;

i = 1;

podd=i;


i *= maxo;

ppot=i;


i *= maxp;

praise=i;

i *= maxr;

pchance=i;

i *= maxc;

pround=i;

i *= ROUNDS;

pqtyraise=i;

i *= maxq;

pfollow=i;

i *= maxf;

pingame=i;

i *= maxi;

pnplay=i;

i *= maxn;

pwinlose=i;

i *= WINLOSES;

pdecision=i;

// loop com toda a base de dados

for (i = 0; i < hsize; i++){

// separa a informação

odd=hdb[i+hodd];

pot=hdb[i+hpot];

raise=hdb[i+hraise];

chance=hdb[i+hchance];

round=hdb[i+hround]-1;

nplay=hdb[i+hnplay];

follow=hdb[i+hfollow];

ingame=hdb[i+hingame];

qtyraise=hdb[i+hqtyraise];

decision=(int)(hdb[i+hdecision])-1;

result=hdb[i+hresult];

// detecção básica de erro na base de dados

if (pot < 0 || raise < 0 || chance < 0 || decision < 0 ||

decision > 5 || odd < 0 || ingame < 0 || follow < 0 ||

nplay < 0 || follow > nplay || ingame > nplay ||

qtyraise < 0)

{

mexPrintf("index %i\n",i);



mexErrMsgTxt("Dado inconsistente");

}

// discretiza a informação



oddD=(int)(odd/to);

chanceD=(int)(chance/tr);

potD=(int)(pot/tp);

raiseD=(int)(raise/tr);

roundD=(int)round-1;

nplayD=(int)(nplay/tn);

followD=(int)(follow/tf);

ingameD=(int)(ingame/ti);

qtyraiseD=(int)(qtyraise/tq);

if(roundD>=ROUNDS) roundD=ROUNDS-1;

if(oddD>=maxo) oddD=maxo-1;

if(chanceD>=maxc) chanceD=maxc-1;

if(potD>=maxp) potD=maxp-1;

if(raiseD>=maxr) raiseD=maxr-1;

if(nplayD>=maxn) nplayD=maxn-1;

if(followD>=maxf) followD=maxf-1;

if(ingameD>=maxi) ingameD=maxi-1;

if(qtyraiseD>=maxq) qtyraiseD=maxq-1;

//insere na base do jogador as informações

winlose=0;

if (result < 0) {

winlose=1;

result=-result;

}

ip=(oddD*podd)+(potD*ppot)+(raiseD*praise)+(chanceD*pchance)+



(roundD*pround)+(followD*pfollow)+(nplayD*pnplay)+

(ingameD*pingame)+(qtyraiseD*pqtyraise)+(winlose*pwinlose)+

(decision*pdecision);

siz=(int)(qty[ip]);

qty[ip]=qty[ip]+1;

newres=0;

if (siz>0) {

newres=pdb[ip];

}

pdb[ip]=newres+result;



}

}

7.15. filldatabase.m


Este procedimento faz diversos jogos apenas para preencher a base de dados.
% @author Vinícius Sousa Fazio

while 1==1

if rand < 0.05

simulatealldispute;

end

tic


disp('treinando');

clear;


initialmoney=1000;

smallblind=10;

maxgames=1000;

to=2;


tc=10;

tp=10;


tr=5;

tf=1;


tn=-1;

tq=-1;


ti=-1;

n=10;


ln=2;

clear pd;

clear pdb;

clear qty;

nepochs=1;

pd=creatediscreteplayer(0,to,tc,tp,tr,tq,tf,ti,tn,n,ln);

[pdb,qty]=pd.get();

while exist (['simdatabase' int2str(nepochs) '.mat'], 'file') ~= 0

clear database;

clear hdb;

clear hsiz;

load(['simdatabase' int2str(nepochs)]);

[hdb,hsiz]=database.get();

traindiscrete(to,tr,tc,tp,tq,tf,ti,tn,qty,pdb,hsiz,hdb);

nepochs=nepochs+1;

end


clear database;

database=createdatabase();

clear simplayers;

for i=1:10

simplayers(i)=pd; %#ok

end


for i=11:15

simplayers(i)=createconstantplayer(2); %#ok

end

for i=16:20



simplayers(i)=createconstantplayer(5); %#ok

end


for i=21:25

simplayers(i)=createmfsplayer(1); %#ok

end

for i=26:30



simplayers(i)=createmfsplayer(5); %#ok

end


for i=31:35

simplayers(i)=createrhplayer(0.1); %#ok

end

for i=36:40



simplayers(i)=createrhplayer(0.001); %#ok

end


for i=41:50

simplayers(i)=createrandomplayer(); %#ok

end
disp('jogando');

nplayers=2;

while 1==1

nplayers=nplayers+1;

if nplayers>10

nplayers=2;

end

playpoker(nplayers,simplayers,maxgames,initialmoney,smallblind,database,999);



if database.insert() == 0

break;


end

end
disp(['salvando epoca ' int2str(nepochs)]);

save (['simdatabase' int2str(nepochs)], 'database');

disp(['salvo epoca ' int2str(nepochs)]);

toc

end


7.16. newsimulationdispute.m
Este método foi criado para fazer as disputas entre dois jogadores de tipos diferentes.
% @author Vinícius Sousa Fazio

function [ simulation ] = newsimulationdispute( pd ,mfs,rh,constantdecision )

playerdiscrete=pd;

playerhuman=createhumanplayer();

playermfs=createmfsplayer(mfs);

playerrh=createrhplayer(rh);

playerrandom=createrandomplayer();

playerconstant=createconstantplayer(constantdecision);

simulation = struct('dispute',@dispute);

function [ winb ] = dispute (a, b, qty)

function [ p ] = getplayer(pid)

if strcmp(pid, 'discrete')

p = playerdiscrete;

elseif strcmp(pid, 'mfs')

p = playermfs;

elseif strcmp(pid, 'rh')

p = playerrh;

elseif strcmp(pid, 'constant')

p = playerconstant;

elseif strcmp(pid, 'random')

p = playerrandom;

elseif strcmp(pid, 'human')

p = playerhuman;

end


end

playera = getplayer(a);

playerb = getplayer(b);

wina=0;


winb=0;

stylegame=1;

if strcmp(a,'human') || strcmp(b,'human')

stylegame=3;

end

for i=1:qty



nplayers=mod(i,5)*2+2;

if strcmp(a,'human')

simplayers(1)=playera; %#ok

for j=2:nplayers

simplayers(j)=playerb; %#ok

end


elseif strcmp(b,'human')

simplayers(1)=playerb; %#ok

for j=2:nplayers

simplayers(j)=playera; %#ok

end

else


for j=1:(nplayers/2)

simplayers(j)=playera; %#ok

end

for j=(nplayers/2+1):nplayers



simplayers(j)=playerb; %#ok

end


end

[ig,w]=playpoker(nplayers,simplayers,40,1000,10,{},stylegame);

if strcmp(functiontostring(simplayers(w).decide),[ 'create' a 'player/decide' ])

wina=wina+1;

elseif strcmp(functiontostring(simplayers(w).decide),[ 'create' b 'player/decide' ])

winb=winb+1;

end

% disp ([a ': ' num2str(wina*100/i) ' ' b ': ' num2str(winb*100/i)])



end

disp ([a ': ' num2str(wina*100/qty) ' ' b ': ' num2str(winb*100/qty)])

end
end

7.17. newsimulationdispute2.m


Este método faz a disputa entre todos os jogadores.
% @author Vinícius Sousa Fazio

disp('taining');

clear simplayers

to=2;


tc=10;

tp=10;


tr=5;

tf=1;


tn=-1;

tq=-1;


ti=-1;

n=10;


ln=2;

st=600;


clear pd;

clear pdb;

clear qty;

nepochs=1;

pd=creatediscreteplayer(0,to,tc,tp,tr,tq,tf,ti,tn,n,ln);

[pdb,qty]=pd.get();

while exist (['simdatabase' int2str(nepochs) '.mat'], 'file') ~= 0 && nepochs <= st

clear database;

clear hdb;

clear hsiz;

load(['simdatabase' int2str(nepochs)]);

[hdb,hsiz]=database.get();

traindiscrete(to,tr,tc,tp,tq,tf,ti,tn,qty,pdb,hsiz,hdb);

nepochs=nepochs+1;

end

disp('playing');



simplayers(1)=pd; %#ok

simplayers(2)=pd; %#ok

simplayers(3)=createmfsplayer(1); %#ok

simplayers(4)=createmfsplayer(5); %#ok

simplayers(5)=createrandomplayer(); %#ok

simplayers(6)=createrandomplayer(); %#ok

simplayers(7)=createconstantplayer(2); %#ok

simplayers(8)=createconstantplayer(5); %#ok

simplayers(9)=createrhplayer(0.1); %#ok

simplayers(10)=createrhplayer(0.001); %#ok


wins=[0 0 0 0 0 0 0 0 0 0];

for jj=1:500

[ig,w]=playpoker(10,simplayers,40,1000,10,{},1);

wins(w)=wins(w)+1;

disp(int2str(jj));

end


wins

disp ('end');

7.18. simulatealldispute.m
Este método foi usado para ajustar o jogador com aprendizado por reforço. Ele faz simulações de disputa contra todos os outros tipos de jogadores e retorna um “fitness”.
% @author Vinícius Sousa Fazio
function [ winb ] = simulatealldispute(args, nst)

% for amfs=[0.2 0.4 0.7 1 2 4 5 6 7 10 20]

% sim=newsimulationdispute(0,amfs,0,2);

% disp(['mfs=' num2str(amfs)]);

% sim.dispute('random','mfs',100);

% end


% disp '--------------------------';

% for aconstant=2:6

% sim=newsimulationdispute(0,1,0,aconstant);

% disp(['constant=' num2str(aconstant)]);

% sim.dispute('constant','random',100);

% end


% for amfs=[1 5 10]

% for aconstant=2:6

% sim=newsimulationdispute(0,amfs,0,aconstant);

% disp(['mfs=' num2str(amfs) ' constant=' num2str(aconstant)]);

% sim.dispute('constant','mfs',100);

% end


% end

% disp '--------------------------';

% for arh=[0.0001 0.001 0.01 0.05 0.1 0.5 1]

% disp(['rh=' num2str(arh)]);

% sim=newsimulationdispute(0,1,arh,0);

% sim.dispute('random','rh',100);

% end

% for arh=[0.001 0.01 0.1]



% for aconstant=[2 4 6]

% disp(['rh=' num2str(arh) ' constant=' num2str(aconstant)]);

% sim=newsimulationdispute(0,1,arh,aconstant);

% sim.dispute('constant','rh',100);

% end

% end


% for arh=[0.001 0.01 0.1]

% for amfs=[1 5]

% disp(['rh=' num2str(arh) ' mfs=' num2str(amfs)]);

% sim=newsimulationdispute(0,amfs,arh,0);

% sim.dispute('mfs','rh',100);

% end


% end

% disp 'compiling...';

% mex (which ('traindiscrete.c'));

to=9.6;


tc=23.3;

tp=37.4;


tr=13.2;

tf=2.6;


tn=3.5;

tq=3.5;


ti=5.6;

n=4;


ln=2;

if 1 == 1

to=2;

tc=10;


tp=10;

tr=5;


tf=1;

tn=-1;


tq=-1;

ti=-1;


n=10;

ln=2;


end

st=9999;


np=100;

if nargin == 1

to=args(1);

tc=args(2);

tp=args(3);

tr=args(4);

tf=args(5);

tn=args(6);

tq=args(7);

ti=args(8);

n=fix(args(9));

ln=fix(args(10));

st=800;

np=100;


end

if nargin == 2

st=nst;

np=100;


end

disp ([' STOP = ' int2str(st)]);

disp '-------------------------------------------------------------------------';

tic


clear pd;

clear pdb;

clear qty;

nepochs=1;

pd=creatediscreteplayer(0,to,tc,tp,tr,tq,tf,ti,tn,n,ln);

[pdb,qty]=pd.get();

while exist (['simdatabase' int2str(nepochs) '.mat'], 'file') ~= 0 && nepochs <= st

clear database;

clear hdb;

clear hsiz;

load(['simdatabase' int2str(nepochs)]);

[hdb,hsiz]=database.get();

traindiscrete(to,tr,tc,tp,tq,tf,ti,tn,qty,pdb,hsiz,hdb);

nepochs=nepochs+1;

end
disp(['@@ RECDIF to=' num2str(to) ' tc=' num2str(tc) ' tp=' num2str(tp) ' tr=' num2str(tr) ' tf=' num2str(tf) ' tn=' num2str(tn) ' tq=' num2str(tq) ' ti=' num2str(ti) ' n=' num2str(n) ' ln=' num2str(ln) ' mfs=1/5 cnt=2/5 rh=0.1/0.001']);

clear sim;

sim=newsimulationdispute(pd,1,0.1,2);

winb = 0;

winb = winb + 2 * sim.dispute('discrete','mfs',np);

winb = winb + 4 * sim.dispute('discrete','random',np);

winb = winb + sim.dispute('discrete','rh',np);

winb = winb + sim.dispute('discrete','constant',np);

clear sim;

sim=newsimulationdispute(pd,5,0.001,5);

winb = winb + 2 * sim.dispute('discrete','mfs',np);

winb = winb + sim.dispute('discrete','constant',np);

winb = winb + sim.dispute('discrete','rh',np);

disp(['result: ' num2str(winb)]);

clear pd;

clear pdb;

clear qty;

clear database;

clear hdb;

clear hsiz;

toc

end


7.19. simulatehuman.m
Este procedimento foi usado para jogar o jogador com aprendizado por reforço contra humanos.
% @author Vinícius Sousa Fazio

echo off;

to=9.6;

tc=23.3;


tp=37.4;

tr=13.2;


tf=2.6;

tn=3.5;


tq=3.5;

ti=5.6;


n=4;

ln=2;


st=999;

tic


clear pd;

clear pdb;

clear qty;

nepochs=1;

pd=creatediscreteplayer(0,to,tc,tp,tr,tq,tf,ti,tn,n,ln);

[pdb,qty]=pd.get();

while exist (['simdatabase' int2str(nepochs) '.mat'], 'file') ~= 0 && nepochs <= st

clear database;

clear hdb;

clear hsiz;

load(['simdatabase' int2str(nepochs)]);

[hdb,hsiz]=database.get();

traindiscrete(to,tr,tc,tp,tq,tf,ti,tn,qty,pdb,hsiz,hdb);

nepochs=nepochs+1;

end
disp(['@@ RECDIF to=' num2str(to) ' tc=' num2str(tc) ' tp=' num2str(tp) ' tr=' num2str(tr) ' tf=' num2str(tf) ' tn=' num2str(tn) ' tq=' num2str(tq) ' ti=' num2str(ti) ' n=' num2str(n) ' ln=' num2str(ln) ' mfs=1/5 cnt=2/5 rh=0.1/0.001']);

clear sim;

sim=newsimulationdispute(pd,1,0.01,2);

%sim.dispute('human','discrete',1);


Algoritmos para um jogador inteligente de Poker

Vinícius Sousa Fazio1

1Departamento de Informática e Estatística – Universidade Federal do Santa Catarina (UFSC)
Caixa Postal 476 – 88.040-900 – Florianópolis – SC – Brasil

sfazio@inf.ufsc.br



Abstract. Poker is a game of bluffing and probability of winning. The goal was to create and searh for algorithms that could learn to play well Poker. The evolving player created uses reinforcement learning where the game was divided in a huge state matrix with decision and reward's data. The player takes the decision with best average reward on each state. To compare the player's efficience, there were disputes with players that take decision based on formulas. The results were shown graphically on this paper.

Resumo. Poker é um jogo de blefe e probabilidade de vencer. O objetivo foi inventar de procurar algoritmos que aprendessem a jogar bem Poker. O jogador evolutivo criado utiliza aprendizado por reforço onde o jogo foi dividido em uma grande matriz de estados com dados de decisões e recompensas. O jogador toma a decisão com a melhor recompensa média para cada estado. Para comparar a eficiência do jogador, várias disputas com jogadores que tomam decisões baseado em fórmulas foram feitas. Os resultados foram mostrados graficamente no trabalho.


1   2   3   4   5   6


©livred.info 2017
enviar mensagem

    Página principal