Você está na página 1de 6

Anlise Assinttica de um Jogo de Cartas

Introduo
Como requisito de avaliao desta disciplina foi proposta uma atividade onde os alunos devem
desenvolver um algoritmo de um jogo de baralho para realizao de um estudo assinttico do
mesmo. Este estudo foca a observao do tamanho de entradas grandes o suficiente para
tornar relevante apenas a ordem de crescimento do tempo de execuo. A ordem de
crescimento do tempo de execuo do algoritmo deste jogo fornece uma caracterizao
simples da eficincia do algoritmo, e tambm permite comparar o desempenho relativo entre
outros algoritmos.
Para realizao deste estudo foi desenvolvido, em Java, um jogo de baralhos. Este jogo
composto de quatro jogadores, onde, cada jogador possui sete cartas na mo e dividido em
turnos. Em cada turno os jogadores puxam cartas de uma pilha de cartas. Esta pilha tem o
tamanho de cinquenta e duas cartas. Cada jogador puxa uma carta de cada vez. Considerando
que o jogador possui um limite de sete cartas na mo, a prxima vez que o jogador puxar uma
carta da pilha ele dever descarta uma de sua mo. A formao de jogo verificada a cada
puxada de carta da pilha e sua combinao composta por trs cartas seqenciadas do
mesmo naipe. Quando a pilha de cartas esta vazia coletada a pilha de descarte (pilha de
cartas pelos jogadores descartadas durante o jogo), embaralhada e forma-se uma nova pilha
de cartas para puxar. A condio de parada para o jogo ser quando a pilha de puxada de
cartas for reiniciada duas vezes ou um jogador bater. As estruturas utilizadas para
representao de cada elemento do jogo so pilhas e listas.
Para o desenvolvimento deste jogo foram selecionadas as estruturas de dados pilha e lista.
Neste trabalho, a estrutura utilizada para representao da pilha de puxada de cartas e
descarte uma pilha. Para armazenar a mo do jogador e a formao de jogos usada uma
lista. Com estas estruturas definidas, foi selecionado como parmetro de estudo assinttico o
nmero de cartas que o jogador possui na mo e nmero de cartas no baralho. Com a variao
destes parmetros foram criados grficos para discusso do desempenho do algoritmo.

Metodologia
O jogo foi desenvolvido na linguagem Java, tendo como IDE o NetBeans 7.3. As classes
envolvidas so: Bolo, Jogador, Carta e Principal. Estas quatro classes possuem seus mtodos e
variveis como mostrado na figura 1. A classe Bolo responsvel por gerenciar a pilha de
puxada de carta e a pilha de descarte. Como exemplo do uso desta classe ser citada o uso do
mtodo embaralhar() que reordena aleatoriamente todas as cartas atuais na pilha de cartas. A
classe Jogador responsvel em gerenciar o jogo de cada jogador. Nesta classe entre outros
mtodos utilizados, o mtodo formaJogo() responsvel em realizar todas as combinaes
possveis na mo do jogador e retornando um arrayList de tais combinaes. A classe Carta
responsvel por gerenciar cada carta do baralho. com esta classe que os valores e naipes de
cada carta so definidos. E finalmente, a classe Principal que gerencia a dinmica do jogo. Esta

classe realiza a instanciao de cada jogador, as cartas, o turno de jogos e a medida do tempo
de execuo de um jogo completo.
Classe Bolo
Na classe Bolo, o gerenciamento das pilhas de cartas armazenado na estrutura de pilha
representada pela varivel bolo. Ao iniciar a classe seu construtor inicializa a construo uma
pilha de baralhos com naipes (nmero de naipes do baralho) e valores (com os valores de cada
naipe). Ou seja, o construtor Bolo() realiza a operao de insero na pilha de cartas. Na figura
2 mostrada o pseudocdigo desta operao.

Bolo(naipes,valores)
1 For cada naipes do
2
For cada valores do
3
push (Carta(naipes,valores))
Figura 2: Operao de insero na classe Bolo.
Cada operao push() demora o tempo O(1) para cada naipes e valores dos loops.
Ainda na classe bolo encontramos o mtodo getProxCart() que retorna a prxima carta da
pilha de cartas. Segue o pseudocdigo na figura 3.
getProxCart(S)
1 If S.isEmpty()
2
then error vazio
3
else topo <- pop()
4 return topo
Figura 3: Operao de remoo na classe Bolo.
Cada operao pop() demora no mtodo getProxCart() demora o tempo O(1) para cada
operao realizada sobre a pilha bolo.
O mtodo embaralhar() tem como finalidade trocar a posio de cada carta na pilha restante
de cartas. Segue o pseudocdigo na figura 4.
embaralhar(S)
1 aux <-null
2 for todos os elementos de S do
3
x<- randon()
4
if not(aux.contais(S[x]))
5
aux <- S[x]
6 S.esvaziar()
7 S <- aux
Figura 4: embaralhar pilha com operao de busca na classe Bolo.

Para realizar um busca na pilha de carta S o mtodo embaralhar pode demora o tempo O(n).

Classe Jogador
Na classe Jogador, o gerenciamento dos jogadores realizado por meio das alteraes das
variveis cartaMao e jogada. A varivel cartaMao representada por uma lista, ArrayList em
Java, e armazena as cartas da mo do jogador. A varivel jogada definida como uma pilha,
Stack em Java, e guarda as sequncias de combinaes de carta do mesmo naipe. Na
construo desta classe definida as cartas que sero armazenadas na varivel cartaMo.
Portanto, esta operao insere as cartas que estaro na mo do jogador. Esta operao
representada no pseudo cdigo da figura 5.
Jogador()
1 for o tamnho da mao do
2
puxaCarta()
3
ordenar()
Figura 5: insero de cartas na mo do jogador na classe Jogador.
A demora de tempo para esta operao de O(h), onde h esta relacionada ao mtodo
puxaCarta() e o mtodo ordenar().
O mtodo puxaCarta() tem como finalidade adicionar na varivel cartaMo a prxima carta da
pilha de puxada de carta. Para atingir tal propsito este mtodo realizar as verificaes de
combinao de seqncia de carta do mesmo naipe na mo do jogador, se o nmero rodadas
foi satisfeita, se o nmero de cartas respeita o limite estabelecido para a mo do jogador e
realiza a ordenao das cartas na mo do jogador. Segue na figura 6 o pseudocdigo para o
mtodo puxaCarta().

puxaCarta (S)
1 if not(formaJogo()) or numero de turno no atingido then
2
x <- randon()
3
cartaMao <- getProxCart(S)
3
if numero de carta mao > limite then
4
cartaMao.remove(x)
5
jogada.remove(x)
6 ordenar()
Figura 6: verificao de cartas ao inseri-las na mo do jogador.
Neste procedimento esto sendo realizadas as operaes formaJogo(), getProxCart(),
cartaMao.remove() e jogada.remove(). Onde a demora de tempo de cada operao
respectivamente denotada em O(n), O(1), O(n) e O(n).

No mtodo formaJogo(), analisado todas combinaes seqenciadas de n cartas possveis na


mo do jogador. Segue na figura 7 o pseudo cdigo para este mtodo.

formaJogo ()
1 for i<-0 to comprimentoMao do
2
for j<-1 to comprimentoMao-1 do
3
for k<-2 comprimentoMao-2 do
4
if cartaMao.Busca(i) == cartaMao.Busca(j)+1 == cartaMao.Busca(k)+2 then
5
jogada.push(cartaMao.Busca(i))
6
jogada.push(cartaMao.Busca(j))
7
jogada.push(cartaMao.Busca(k))
Figura 7: combinaes possveis de sequncias de cartas do mesmo naipe.
O tempo de demora para este procedimento O(n). Pois no pior caso a operao
cartaMao.Busca() ir realizar buscas na lista de tamanho do comprimento da mo do jogador.
Para a operao jogada.push() o tempo de demora O(1) para cada operao.
No mtodo ordenar(), realizada a ordenao decrescente das cartas na mo do jogador. Para
este procedimento, segue o pseudocdigo na figura 8.

ordenar()
1 aux <- null
2 for i<-0 to comprimentoMao do
2
for j<-1 to comprimentoMao-1 do
3
if cartaMao.Busca(i) < cartaMao.Busca(j)
4
aux <- cartaMao.Busca(i)
5
cartaMao.inseri(i, cartaMao.Busca(j))
6
cartaMao.inseri(j, aux)
Figura 8: ordenao decrescente de cartas da Mao do jogador.
No o procedimento ordenar() a operao cartaMao.inseri() demora o tempo O(n).

Resultados
Para uma analise do algoritmo proposto foram gerados grficos que mostram o
comportamento assinttico deste. Os parmetros contidos neste algoritmo so: numJogadores
(representa o numero de jogadores), numNaipes (define o numero de naipes do baralho),
numValores (indica a numerao do baralho), numDiscates (representa o nmero de vezes que
a pilha de puxada de cartas termina) e maxCartaMao (significa o nmero de carta que um
jogador pode ter em mos). No entanto, para o estudo proposto foram considerados mais
relevantes os parmetros numValores e maxCartaMao. Para efeito de estudo foram variadas
somente estes dois paramentros.

Para a gerao do grfico da figura 9, foi considerado a variao do maxCartaMao a partir de 0


a 10000, sendo este incrementa de 10 em 10 cartas. Assim, tendo esta variao em funo do
tempo em milissegundos.

Figura 9: funo assinttica do maxCartaMao pelo tempo(ms).

Para a gerao do grfico da figura 10, foi considerado a variao do numValores a partir de 0
a 10000, sendo este incrementa de 10 em 10 cartas. Assim sendo a variao em funo do
tempo em milissegundos.

Figura 10: funo assinttica do numValores pelo tempo(ms).

Concluso
Analisando o grfico possvel notar que o comportamento do algoritmo descrito por uma
funo cbica f(x) = ax+bx+cx+d com a,b,c,d IR e a0. Este comportamento se deve
principalmente ao procedimento puxaCarta (S) que dispara outros procedimentos na medida
que cada jogador retira a ltima carta da pilha de puxada de cartas. Como o procedimento
analisa todas as possibilidades de combinao seqenciadas do mesmo naipe e ordena a mo
do jogador em uma estrutura de lista cujo valor de cada operao O(n) o custo de tempo
passar a ser relevante para valores prximos de 1000 cartas na mo do jogador, como visto na
figura 9. Para o grfico da figura 10 o comportamento semelhante ao comportamento do
grfico da figura 9, onde a relevncia do custo de tempo perceptvel para valores prximos
de 1000 cartas na pilha de puxada. Em sala de aula foram proposta outros algoritmos com
outras estruturas de armazenamento tais como tabale hash e arvores, ambos, para este
mesmo problema. Foi percebido que tais solues possuem um comportamento linear. Estes
resultados pressupem que a soluo proposta por este trabalho pode ser alterada para a
obteno de um comportamento assinttico linear.

Referncia
CORMEN, T.H.; LEISERSON, C.E.; RIVEST, R.L.; STEIN, C. Algoritmos : Teoria e Pratica.
Traduo da 2 edio americana. 6 Tiragem. Rio de Janeiro: Elsevier, 2002.