<?xml version='1.0' encoding='UTF-8'?><?xml-stylesheet href="http://www.blogger.com/styles/atom.css" type="text/css"?><feed xmlns='http://www.w3.org/2005/Atom' xmlns:openSearch='http://a9.com/-/spec/opensearchrss/1.0/' xmlns:georss='http://www.georss.org/georss' xmlns:gd='http://schemas.google.com/g/2005' xmlns:thr='http://purl.org/syndication/thread/1.0'><id>tag:blogger.com,1999:blog-4797202738159530784</id><updated>2011-07-08T00:02:47.022-07:00</updated><category term='style code'/><category term='design patterns'/><category term='mau cheiro'/><category term='controle de versão'/><category term='programação dinâmica'/><category term='commit'/><category term='programação orientada a objetos'/><category term='maratona de programação'/><category term='SVN'/><category term='estilo'/><category term='jogos'/><category term='busca'/><category term='SPGameShow'/><title type='text'>O fantástico mundo de Natan</title><subtitle type='html'></subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://natanlima.blogspot.com/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4797202738159530784/posts/default?max-results=100'/><link rel='alternate' type='text/html' href='http://natanlima.blogspot.com/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><author><name>Natan Costa Lima</name><uri>http://www.blogger.com/profile/04100311392587071301</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>9</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>100</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-4797202738159530784.post-3854842697443556651</id><published>2010-10-04T18:31:00.000-07:00</published><updated>2010-10-04T18:45:24.726-07:00</updated><title type='text'>Achievement</title><content type='html'>&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/_MZMl3eWbRzA/TKqC9hirwtI/AAAAAAAAABc/pU437qru__g/s1600/Achievement.png"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 440px; height: 311px;" src="http://2.bp.blogspot.com/_MZMl3eWbRzA/TKqC9hirwtI/AAAAAAAAABc/pU437qru__g/s400/Achievement.png" border="0" alt="" id="BLOGGER_PHOTO_ID_5524371886410810066" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;div style="text-align: center;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: center;"&gt;Ganhei um achievement. Tomara que venham outros esse ano!!&lt;/div&gt;&lt;div style="text-align: center;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4797202738159530784-3854842697443556651?l=natanlima.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://natanlima.blogspot.com/feeds/3854842697443556651/comments/default' title='Postar comentários'/><link rel='replies' type='text/html' href='http://natanlima.blogspot.com/2010/10/achievement.html#comment-form' title='1 Comentários'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4797202738159530784/posts/default/3854842697443556651'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4797202738159530784/posts/default/3854842697443556651'/><link rel='alternate' type='text/html' href='http://natanlima.blogspot.com/2010/10/achievement.html' title='Achievement'/><author><name>Natan Costa Lima</name><uri>http://www.blogger.com/profile/04100311392587071301</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://2.bp.blogspot.com/_MZMl3eWbRzA/TKqC9hirwtI/AAAAAAAAABc/pU437qru__g/s72-c/Achievement.png' height='72' width='72'/><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4797202738159530784.post-1859664901948018630</id><published>2010-09-03T06:53:00.000-07:00</published><updated>2010-09-07T21:28:08.613-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='maratona de programação'/><category scheme='http://www.blogger.com/atom/ns#' term='style code'/><category scheme='http://www.blogger.com/atom/ns#' term='mau cheiro'/><category scheme='http://www.blogger.com/atom/ns#' term='estilo'/><title type='text'>Legibilidade de código e código fedido!</title><content type='html'>&lt;div style="text-align: justify;"&gt;Código legível é um assunto meio difícil pois sai da nossa racionalidade matemática e entra na parte mais humana, onde o que é bom para um não necessariamente é bom para outros.&lt;br /&gt;&lt;br /&gt;Gostei muito de ler o livro &lt;span style="font-style: italic;"&gt;Refactoring: Improving the Design of Existing Code&lt;/span&gt; (Martin Fowler, Kent Beck e outros). Há um capítulo que disserta sobre maus cheiros no código e acho que eles são um bom indicativo sobre a qualidade do código. Alguns maus cheiros que o livro cita são: Classes grandes, métodos grandes, números mágicos pelo código.&lt;br /&gt;&lt;br /&gt;Há uma frase bem interessante que atribuem ao Donald Knuth mas posteriormente ele disse ser de autoria de outra pessoa que diz: &lt;span style="font-style: italic;"&gt;We should forget about small efficiencies, say about 97% of the time: premature optimization is the root of all evil&lt;/span&gt;. Acho esta frase bem interessante e a interpreto como: "prefira legibilidade a pequenas otimizações", porém, isto também é só mais um fator de ilegibilidade.&lt;br /&gt;&lt;br /&gt;Participando de projetos um pouco maiores, com mais de 3 ou 4 pessoas trabalhando, começo a perceber que além de otimizações prematuras e maus cheiros, há um outro fator que torna o código&lt;br /&gt;sujo, ilegível ou fedido. O estilo de programação é um fator que influencia tanto empresas grandes como o &lt;a href="http://google-styleguide.googlecode.com/svn/trunk/cppguide.xml"&gt;Google&lt;/a&gt;, como projetos open source como o &lt;a href="http://www.chris-lott.org/resources/cstyle/LinuxKernelCodingStyle.txt"&gt;kernel do linux&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;Todo programador tem um estilo próprio de produzir código e, quando estamos participando de um projeto grande, precisamos adotar o estilo do projeto. Apesar de adotarmos um estilo diferente, podemos tirar proveito de suas vantagens para melhorar nosso próprio estilo.&lt;br /&gt;&lt;br /&gt;Atualmente eu tenho basicamente dois estilos diferentes: um que uso em um projeto na faculdade e outro que uso ao resolver problemas de maratona de programação. Já me deparei com pessoas/empresas que diziam que a maratona estragava a pessoa e a fazia escrever códigos difíceis de entender. Eu sou totalmente contra este tipo de idéia. Acho que na maratona é fundamental ter um estilo e produzir código limpo, caso contrário o resto do time não poderá ajudá-lo sem perder muito tempo. Claro que isto não se aplica a times russos/poloneses que nunca erram. =)&lt;br /&gt;&lt;br /&gt;Em suma, acho que esses dois estilos que uso atualmente,se ajudam entre si e me dão a oportunidade de melhorar meu estilo de programação no geral. Na minha opinião, devemos sempre tentar melhorar nosso estilo e não estacionar quando uma prática ou outra nos convém.&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4797202738159530784-1859664901948018630?l=natanlima.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://natanlima.blogspot.com/feeds/1859664901948018630/comments/default' title='Postar comentários'/><link rel='replies' type='text/html' href='http://natanlima.blogspot.com/2010/09/legibilidade-de-codigo-e-codigo-fedido.html#comment-form' title='3 Comentários'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4797202738159530784/posts/default/1859664901948018630'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4797202738159530784/posts/default/1859664901948018630'/><link rel='alternate' type='text/html' href='http://natanlima.blogspot.com/2010/09/legibilidade-de-codigo-e-codigo-fedido.html' title='Legibilidade de código e código fedido!'/><author><name>Natan Costa Lima</name><uri>http://www.blogger.com/profile/04100311392587071301</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4797202738159530784.post-8692018496073610803</id><published>2010-07-20T17:22:00.000-07:00</published><updated>2010-07-20T19:11:15.961-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='jogos'/><category scheme='http://www.blogger.com/atom/ns#' term='SPGameShow'/><title type='text'>Portfólio para trabalhar com games e SP Game Show</title><content type='html'>&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://twitpic.com/25yhtu"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer; width: 320px; height: 245px;" src="http://2.bp.blogspot.com/_MZMl3eWbRzA/TEZUR3XqziI/AAAAAAAAAAM/GVAOKY01_v8/s320/mario-eu.jpg" alt="" id="BLOGGER_PHOTO_ID_5496173061150002722" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;div style="text-align: justify;"&gt;Faz tempo desde minha última postagem. Enfrentei um fim de semestre turbulento, mas aqui estou de volta com algumas impressões que tirei do SP Game Show. O evento foi bem interessante! Ele aconteceu junto com o Anime Frieds, o Comic Fair e o Asian Fest. Desses, eu só conhecia o Anime Friends.&lt;br /&gt;&lt;br /&gt;O meu objetivo maior esse ano foi o SP Game Show e eu fui na sexta-feira (16 de Julho). Assisti palestras que me motivaram e também outras que me desmotivaram.  Acho que o objetivo maior de um desenvolvedor de jogos é fazer jogos que eles chamavam de triple A, ou seja, os jogos top de linha. Mas no Brasil, pelo que eu percebi, a praia é outra: Temos que nos focar em jogos de celular e redes sociais para conseguir crescer e ganhar maturidade para os grandes. Outras opções frequentes dos brasileiros são os &lt;span style="font-style: italic;"&gt;advergames&lt;/span&gt;, os games mais casuais e, por fim, um ramo não muito explorado mas promissor pode ser os &lt;span style="font-style: italic;"&gt;serious games&lt;/span&gt;. Um &lt;span style="font-style: italic;"&gt;advergame&lt;/span&gt; bem interessante mostrado pela &lt;a href="http://twitter.com/ViviWerneck"&gt;Viviane Werneck&lt;/a&gt; na palestra dela foi o &lt;a href="http://www.musicscore.com.br/"&gt;Music Score&lt;/a&gt; feito para promover a banda Bet Set. Muito bem feito e parece ser bem divertido (fórmula do guitar hero não tem erro =P).&lt;br /&gt;&lt;br /&gt;Uma dúvida que eu tinha era a respeito do curso que fiz (bacharelado em ciência da computação). Conversei com o Júlio César da empresa &lt;a href="http://www.coopergames.com.br/"&gt;Cooper Games&lt;/a&gt; e a resposta foi positiva. Segundo ele, as empresas olham com bons olhos os formados em ciência da computação!&lt;br /&gt;&lt;br /&gt;Perguntei também se a falta de conhecimento em determinadas tecnologias atrapalhava. Só para explicar a intenção da pergunta, o curso que eu fiz no IME-USP tem uma abordagem bem teórica sobre ciência da computação, muitas vezes deixando parte da tecnologia atual um pouco de lado e o mercado muitas vezes exige que dominemos tecnologias específicas, como Flash, Java, OpenGL. Eu concordo que são tecnologias básicas e fundamentais na área de games, mas creio que o curso dê o conhecimento necessário para sermos versáteis e aprendermos com facilidade tecnologias atuais e futuras. A resposta de Júlio novamente foi positiva: ele me disse que o curso cobria diversas áreas importantes no desenvolvimento de jogos, como física e álgebra linear, apesar do gosto das empresas pelo conhecimento em tecnologia.&lt;br /&gt;&lt;br /&gt;Para entrar no mundo das empresas de games ele me deu uma dica bem interessante: a criação de um portfólio. Ele disse que poderia ser um portfólio simples, com jogos como tetris ou pac-man, algum joguinho usando OpenGL também não faria mal.&lt;br /&gt;&lt;br /&gt;Já fiz alguns joguinhos simples e atualmente estou em um projeto maior com um grupo de estudantes da USP, mas ainda não "documentamos" nada. Em breve, pretendo começar a criar um portfólio bem legal e ir postando a situação dos jogos! Uma sequência bem conhecida para começar a programar jogos é: Primeiro alguma cópia do tetris, em seguida uma cópia de Arkanoid  e depois Pac-man. Essa ordem é sugerida pois a dificuldade para criá-los é diferente e eles acabam abrangendo grande parte do que jogos mais avançados usam.&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4797202738159530784-8692018496073610803?l=natanlima.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://natanlima.blogspot.com/feeds/8692018496073610803/comments/default' title='Postar comentários'/><link rel='replies' type='text/html' href='http://natanlima.blogspot.com/2010/07/portfolio-para-trabalhar-com-games-e-sp.html#comment-form' title='2 Comentários'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4797202738159530784/posts/default/8692018496073610803'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4797202738159530784/posts/default/8692018496073610803'/><link rel='alternate' type='text/html' href='http://natanlima.blogspot.com/2010/07/portfolio-para-trabalhar-com-games-e-sp.html' title='Portfólio para trabalhar com games e SP Game Show'/><author><name>Natan Costa Lima</name><uri>http://www.blogger.com/profile/04100311392587071301</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://2.bp.blogspot.com/_MZMl3eWbRzA/TEZUR3XqziI/AAAAAAAAAAM/GVAOKY01_v8/s72-c/mario-eu.jpg' height='72' width='72'/><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4797202738159530784.post-2489261527315854708</id><published>2010-05-28T04:28:00.000-07:00</published><updated>2010-06-01T12:01:45.478-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='controle de versão'/><category scheme='http://www.blogger.com/atom/ns#' term='commit'/><category scheme='http://www.blogger.com/atom/ns#' term='SVN'/><title type='text'>Políticas de commit para projetos grandes</title><content type='html'>&lt;div style="text-align: justify;"&gt;Participando de projetos grandes começamos a perceber a importância de certas atitudes que não colocamos em prática sempre. Respeitar alguma política ao &lt;span style="font-style: italic;"&gt;commitar&lt;/span&gt; é uma delas.&lt;br /&gt;&lt;br /&gt;Encontrei na internet a &lt;a href="http://techbase.kde.org/Policies/SVN_Commit_Policy"&gt;política de commits do KDE&lt;/a&gt; e concordei com muitos itens, então, irei traduzir uma parte dela e adicionar comentários pessoais.&lt;br /&gt;&lt;br /&gt;&lt;/div&gt;&lt;h2 style="text-align: justify;"&gt;Pense duas vezes antes de &lt;span style="font-style: italic;"&gt;commitar&lt;/span&gt;&lt;br /&gt;&lt;/h2&gt;&lt;div style="text-align: justify;"&gt;&lt;span style="font-style: italic;"&gt;Commitar&lt;/span&gt; algo pelo controle de versão tem várias consequências. Todos os desenvolvedores pegarão suas mudanças e se estas quebram alguma coisa, quebrará para todos. Todos os &lt;span style="font-style: italic;"&gt;commits&lt;/span&gt; serão públicos no repositório para sempre.&lt;br /&gt;&lt;br /&gt;Por outro lado, o controle de versão permite recuperações de versões antigas, possibilitando eventuais consertos de &lt;span style="font-style: italic;"&gt;commits&lt;/span&gt; errados. O trabalho de recuperação é simples quando é necessário mudar poucos arquivos, mas pode ser trabalhoso quando são &lt;span style="font-style: italic;"&gt;commitados&lt;/span&gt; grandes mudanças.&lt;br /&gt;&lt;br /&gt;&lt;/div&gt;&lt;h2 style="text-align: justify;"&gt;Nunca &lt;span style="font-style: italic;"&gt;commite&lt;/span&gt; código que não compile&lt;br /&gt;&lt;/h2&gt;&lt;div style="text-align: justify;"&gt;Corrija os erros e compile o código antes de &lt;span style="font-style: italic;"&gt;commitar&lt;/span&gt;. Certifique-se que os arquivos novos foram adicionados e serão &lt;span style="font-style: italic;"&gt;commitados&lt;/span&gt;. Se forem esquecidos, podem fazer o projeto compilar localmente, mas para o resto do grupo não compilará.&lt;br /&gt;&lt;br /&gt;&lt;/div&gt;&lt;h2 style="text-align: justify;"&gt;Faça testes e certifique que eles passem&lt;br /&gt;&lt;/h2&gt;&lt;div style="text-align: justify;"&gt;Rode a aplicação e veja se a parte afetada pela sua mudança funciona como esperado. Caso o projeto tenha testes de unidade ou testes de regressão, rode-os e certifique-se de que eles passem. Se não o fizer, quando outras pessoas fizerem mudanças no projeto, verão o teste quebrado e pensarão que quebraram algo, perdendo tempo com depuração.&lt;br /&gt;&lt;br /&gt;&lt;/div&gt;&lt;h2 style="text-align: justify;"&gt;Cheque mais de uma vez o que irá &lt;span style="font-style: italic;"&gt;commitar&lt;/span&gt;&lt;br /&gt;&lt;/h2&gt;&lt;div style="text-align: justify;"&gt;Faça update e &lt;span style="font-style: italic;"&gt;diffs&lt;/span&gt; antes de &lt;span style="font-style: italic;"&gt;commitar&lt;/span&gt;. Leve a sério mensagens de conflito e de arquivos desconhecidos que o controle de versão emitir. Geralmente há várias ferramentas que mostram exatamente o que você está &lt;span style="font-style: italic;"&gt;commitando&lt;/span&gt;. Cheque se é isso mesmo que você deseja &lt;span style="font-style: italic;"&gt;commitar&lt;/span&gt;.&lt;br /&gt;&lt;br /&gt;&lt;/div&gt;&lt;h2 style="text-align: justify;"&gt;Sempre escreva mensagens de log descritivas.&lt;br /&gt;&lt;/h2&gt;&lt;div style="text-align: justify;"&gt;Mensagens de &lt;span style="font-style: italic;"&gt;log&lt;/span&gt; devem ser compreendidas por alguém que olhe apenas para o &lt;span style="font-style: italic;"&gt;log&lt;/span&gt;. Elas não dependem de informações fora do contexto do &lt;span style="font-style: italic;"&gt;commit&lt;/span&gt;.&lt;br /&gt;&lt;br /&gt;Em particular, coloque toda informação relevante que não podem ser vistas no &lt;span style="font-style: italic;"&gt;diff&lt;/span&gt; na mensagem de log.&lt;br /&gt;&lt;br /&gt;&lt;/div&gt;&lt;h2 style="text-align: justify;"&gt;Respeite políticas de &lt;span style="font-style: italic;"&gt;commit&lt;/span&gt; definidas nos planos de lançamento&lt;br /&gt;&lt;/h2&gt;&lt;div style="text-align: justify;"&gt;Evite &lt;span style="font-style: italic;"&gt;commitar&lt;/span&gt; novas funcionalidades e código pouco antes do lançamento. Além disto, controles de versão não substituem a comunicação entre os desenvolvedores.&lt;br /&gt;&lt;br /&gt;&lt;/div&gt;&lt;h2 style="text-align: justify;"&gt;Seja responsável pelos seus &lt;span style="font-style: italic;"&gt;commits&lt;/span&gt;&lt;br /&gt;&lt;/h2&gt;&lt;div style="text-align: justify;"&gt;Se suas mudanças quebraram algo ou apresentam efeitos colaterais em código alheio, se responsabilize por arrumar e ajudar a arrumar os problemas.&lt;br /&gt;&lt;br /&gt;&lt;/div&gt;&lt;h2 style="text-align: justify;"&gt; Não mande código que você não entenda&lt;br /&gt;&lt;/h2&gt;&lt;div style="text-align: justify;"&gt;Evite frases como "Eu não sei porque dá esse erro, mas quando faço isso ele funciona", ou "Não tenho certeza que funciona, mas pra mim tá funcionando".&lt;br /&gt;&lt;br /&gt;Se não encontrar solução para algum problema, discuta com outros desenvolvedores.&lt;br /&gt;&lt;br /&gt;&lt;/div&gt;&lt;h2 style="text-align: justify;"&gt; Não &lt;span style="font-style: italic;"&gt;commita&lt;/span&gt; código se outra pessoa discorda&lt;br /&gt;&lt;/h2&gt;&lt;div style="text-align: justify;"&gt;Se existe divergência de opiniões, discuta em listas de e-mail ou em particular, mas não force um código por &lt;span style="font-style: italic;"&gt;commit&lt;/span&gt; para os outros.&lt;br /&gt;&lt;br /&gt;&lt;/div&gt;&lt;h2 style="text-align: justify;"&gt;Não adicione arquivos gerados automaticamente ao repositório.&lt;br /&gt;&lt;/h2&gt;&lt;div style="text-align: justify;"&gt;Arquivos gerados em tempo de compilação não devem ir ao repositório pois podem causa conflitos. Apenas arquivos com código fonte devem estar no repositório. Uma excessão são arquivos gerados por ferramentas como cmake ou scripts necessários para a compilação.&lt;br /&gt;&lt;br /&gt;&lt;/div&gt;&lt;h2 style="text-align: justify;"&gt;Commitar conjunto de mudanças completos.&lt;br /&gt;&lt;/h2&gt;&lt;div style="text-align: justify;"&gt;Geralmente controles de versão têm a habilidade de submeter vários arquivos por vez. Sempre &lt;span style="font-style: italic;"&gt;commite&lt;/span&gt; todas as mudanças feitas e diretórios criados no mesmo &lt;span style="font-style: italic;"&gt;commit&lt;/span&gt;. Desta maneira você garante que o repositório continue em um estato compilável antes e depois de um &lt;span style="font-style: italic;"&gt;commit&lt;/span&gt;.&lt;br /&gt;&lt;br /&gt;&lt;/div&gt;&lt;h2 style="text-align: justify;"&gt;Não misture mudanças de formatação com mudanças no código.&lt;br /&gt;&lt;/h2&gt;&lt;div style="text-align: justify;"&gt;Mudar formatação, como espaços e identação, faz os &lt;span style="font-style: italic;"&gt;diffs&lt;/span&gt; ficarem mais extensos e fica mais difícil achar mudanças de código se elas estão misturadas com&lt;br /&gt;re-identações e coisas similares, tanto no log como nos &lt;span style="font-style: italic;"&gt;diffs&lt;/span&gt;.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Acabei omitindo algumas e mudando o conteúdo de outras, mas basicamente está tudo aí. No caso do KDE, eles usam SVN como controle de versão então há bastante referência ao SVN, mas as idéias servem para qualquer projeto usando qualquer controle de versão.&lt;br /&gt;&lt;br /&gt;Creio que são dicas até meio óbvias, mas geralmente não colocamos em prática algumas delas em projetinhos pequenos, trabalhos de faculdade e etc. Porém, são dicas bem úteis para um projeto um pouco maior e até mesmo para estes projetos.&lt;br /&gt;&lt;br /&gt;Coloquem em prática a maioria delas e contem a experiência.&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4797202738159530784-2489261527315854708?l=natanlima.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://natanlima.blogspot.com/feeds/2489261527315854708/comments/default' title='Postar comentários'/><link rel='replies' type='text/html' href='http://natanlima.blogspot.com/2010/05/politicas-de-commit-para-projetos.html#comment-form' title='4 Comentários'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4797202738159530784/posts/default/2489261527315854708'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4797202738159530784/posts/default/2489261527315854708'/><link rel='alternate' type='text/html' href='http://natanlima.blogspot.com/2010/05/politicas-de-commit-para-projetos.html' title='Políticas de commit para projetos grandes'/><author><name>Natan Costa Lima</name><uri>http://www.blogger.com/profile/04100311392587071301</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>4</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4797202738159530784.post-4899657565923366013</id><published>2010-05-26T10:39:00.000-07:00</published><updated>2010-06-01T12:06:46.556-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='jogos'/><category scheme='http://www.blogger.com/atom/ns#' term='design patterns'/><category scheme='http://www.blogger.com/atom/ns#' term='programação orientada a objetos'/><title type='text'>Design pattern Strategy para fazer a IA nos jogos</title><content type='html'>&lt;div style="text-align: justify;"&gt;Recentemente tive que entregar um trabalho em que o objetivo principal era comparar inteligência artificial superficial e inteligência artificial aparente. Não há uma definição muito formal desses tipos de inteligência artificial. Vejam a &lt;a href="http://www.youtube.com/watch?v=B1INAQ32f-I"&gt;palestra&lt;/a&gt; que o professor Flávio Soares Corrêa da Silva (que passou o trabalho) apresentou sobre o assunto na Campus Party. Basicamente, inteligência artificial aparente é a inteligência usada nos games.&lt;br /&gt;&lt;br /&gt;   Para o trabalho tivemos que implementar um jogo não jogável, onde existe duas partículas: uma é a partícula perseguida e a outra a perseguidora. No caso como era um projetinho rápido, a perseguida anda pelo labirinto de maneira aleatória. Para a perseguidora, tivemos que implementar duas inteligências: uma utilizando apenas A* e indo atrás da perseguida e outra que apenas vai atrás da perseguida quando a enxerga.&lt;br /&gt;&lt;br /&gt;   Como tenho estudado alguns conceitos de programação orientada a objetos, decidi fazer o trabalho em &lt;a href="http://www.adobe.com/devnet/actionscript/articles/actionscript3_overview.html"&gt;Action Script &lt;/a&gt; e usar o&lt;span style="font-style: italic;"&gt; design pattern &lt;a href="http://en.wikipedia.org/wiki/Strategy_pattern"&gt;Strategy&lt;/a&gt;&lt;/span&gt; para implementar a parte da inteligência artificial.&lt;br /&gt;&lt;br /&gt;   Primeiro, decidi que a inteligência seria bem simples: ela apenas recebe um ponto do mapa (a posição da partícula) e decide para qual posição irá. Sendo assim criei uma interface &lt;span style="font-style: italic;"&gt;Strategy&lt;/span&gt;:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;public interface Strategy{&lt;br /&gt;     function execute(point:Point):Point;&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;   Nas classes referentes às partículas, basta ter uma instância de alguma classe que implemente a interface e chamar o &lt;span style="font-style: italic;"&gt;execute&lt;/span&gt; quando for necessário uma atualização da posição. Cada partícula deveria ter um tempo diferente de atualização então coloquei isso na classe das partículas também.&lt;br /&gt;&lt;br /&gt;As classes relacionadas a inteligência ficaram bem modularizadas e fáceis de programar. O uso do &lt;span style="font-style: italic;"&gt;design pattern&lt;/span&gt; valeu a pena!&lt;br /&gt;&lt;br /&gt;Eis o resultado final:&lt;br /&gt;&lt;br /&gt;Use a tecla 'a' para gerar blocos aleatórios na tela.&lt;br /&gt;Use a tecla '0' e clique para colocar uma partícula que se move aleatoriamente sem colidir com as paredes.&lt;br /&gt;Use a tecla '1' e clique para colocar uma partícula que usa o algoritmo A* para pegar a partícula gerada acima.&lt;br /&gt;Em vez de '1', use a tecla '2' para colocar uma partícula que persegue a partícula aleatória apenas se esta for visível.&lt;br /&gt;&lt;br /&gt;&lt;object height="600" width="600"&gt;&lt;/object&gt;&lt;br /&gt;&lt;object height="600" width="600"&gt;&lt;embed src="http://www.ime.usp.br/%7Enatan/MAC5789/main.swf" height="600" width="600"&gt;&lt;/embed&gt;&lt;/object&gt;&lt;br /&gt;&lt;object height="600" width="600"&gt;&lt;/object&gt;&lt;br /&gt;&lt;br /&gt;Se quiser dar uma olhada no código para ver como implementei as inteligências e outras coisas do projeto pode baixá-lo em: &lt;a href="http://www.ime.usp.br/%7Enatan/projeto2NatanCostaLima.tar.gz"&gt;projeto&lt;/a&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4797202738159530784-4899657565923366013?l=natanlima.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://natanlima.blogspot.com/feeds/4899657565923366013/comments/default' title='Postar comentários'/><link rel='replies' type='text/html' href='http://natanlima.blogspot.com/2010/05/design-pattern-strategy-para-fazer-ia.html#comment-form' title='0 Comentários'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4797202738159530784/posts/default/4899657565923366013'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4797202738159530784/posts/default/4899657565923366013'/><link rel='alternate' type='text/html' href='http://natanlima.blogspot.com/2010/05/design-pattern-strategy-para-fazer-ia.html' title='Design pattern Strategy para fazer a IA nos jogos'/><author><name>Natan Costa Lima</name><uri>http://www.blogger.com/profile/04100311392587071301</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4797202738159530784.post-6269638070431375001</id><published>2010-05-07T06:54:00.000-07:00</published><updated>2010-08-06T04:50:34.765-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='jogos'/><category scheme='http://www.blogger.com/atom/ns#' term='design patterns'/><category scheme='http://www.blogger.com/atom/ns#' term='programação orientada a objetos'/><title type='text'>Double dispatch no tratamento de colisões em jogos</title><content type='html'>&lt;div style="text-align: justify;"&gt;É recorrente em algumas aulas de programação orientada a objetos, meu professor dizer que é uma heresia perguntar a classe de um objeto.&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: justify;"&gt;&lt;br /&gt;Participo de um grupo de jogos e chegamos em um determinado ponto em que precisamos tratar as colisões. O problema aqui é um problema de engenharia mesmo, não algorítmico. Sabendo que existe colisão entre dois objetos, como fazemos para tratá-lo.&lt;br /&gt;&lt;br /&gt;Vamos supor que temos as classes Jogador, Inimigo, Tiro e BonusDeVida. No caso todas essas classes herdam de uma classe em comum chamada ObjetoDeJogo.&lt;br /&gt;&lt;br /&gt;Mostrarei um exemplo de como poderia ser a classe Jogador em C++ com uma solução não muito bonita.&lt;br /&gt;&lt;br /&gt;&lt;pre class="brush:cpp"&gt;class Jogador : public ObjetoDeJogo{&lt;br /&gt;   public:&lt;br /&gt;   virtual void trataColisao(ObjetoDeJogo* obj){&lt;br /&gt;      if((Inimigo *inimigo = dynamic_cast&amp;lt;&amp;lt;Inimigo&amp;gt; *&amp;gt;( obj )) != NULL){&lt;br /&gt;         cout &amp;lt;&amp;lt; "Colidiu com inimigo!" &amp;lt;&amp;lt; endl;&lt;br /&gt;      }&lt;br /&gt;      if((Tiro *tiro = dynamic_cast&amp;lt;&amp;lt;Tiro&amp;gt; *&amp;gt;( obj )) != NULL){&lt;br /&gt;         cout &amp;lt;&amp;lt; "Colidiu com tiro!" &amp;lt;&amp;lt; endl;&lt;br /&gt;      }&lt;br /&gt;      if((BonusDeVida *bonus = dynamic_cast&amp;lt;&amp;lt;BonusDeVida&amp;gt; *&amp;gt;( obj )) != NULL){&lt;br /&gt;         cout &amp;lt;&amp;lt; "Colidiu com bonus!" &amp;lt;&amp;lt; endl;&lt;br /&gt;      }&lt;br /&gt;   }&lt;br /&gt;};&lt;/pre&gt;&lt;br /&gt;Deste modo funciona, porém estamos cometendo a heresia de perguntar a classe do objeto em que o Jogador está colidindo. É um método bem simples de resolvermos o problema, porém vai contra alguns princípios de orientação a objetos. Pela falta de polimorfismo desta abordagem, sofreríamos no futuro com algumas desvantagens.&lt;br /&gt;&lt;br /&gt;Existiriam várias classes implementando esses métodos que tratam colisões e com o passar do tempo, os métodos ficariam bem grandes com a adição de novos tipos de colisão.&lt;br /&gt;O tratamento de colisão não está muito bem encapsulado, caso fizessemos métodos para cada tipo de colisão, ainda assim teríamos que mexer no conjunto de "ifs" sempre que quisessemos adicionar uma nova colisão.&lt;br /&gt;&lt;br /&gt;Uma solução interessante para o problema é o uso de &lt;a href="http://en.wikipedia.org/wiki/Double_dispatch"&gt;double dispatch&lt;/a&gt;, a página da wikipedia explica bem a técnica e há uma implementação em C++, mas para completar a postagem vou mostrar como ficaria a classe Jogador usando a técnica de double dispatch.&lt;br /&gt;&lt;br /&gt;&lt;pre class="brush:cpp"&gt;class Jogador : public ObjetoDeJogo{&lt;br /&gt;   public:&lt;br /&gt;   virtual void trataColisao(ObjetoDeJogo* obj){&lt;br /&gt;      obj-&gt;trataColisao(this);&lt;br /&gt;   }&lt;br /&gt;   virtual void trataColisao(Inimigo* obj){&lt;br /&gt;      cout &amp;lt;&amp;lt; "Colidiu com inimigo!" &amp;lt;&amp;lt; endl;&lt;br /&gt;   }&lt;br /&gt;   virtual void trataColisao(Tiro* obj){&lt;br /&gt;      cout &amp;lt;&amp;lt; "Colidiu com tiro!" &amp;lt;&amp;lt; endl;&lt;br /&gt;   }&lt;br /&gt;   virtual void trataColisao(BonusDeVida* obj){&lt;br /&gt;      cout &amp;lt;&amp;lt; "Colidiu com bonus!" &amp;lt;&amp;lt; endl;&lt;br /&gt;   }&lt;br /&gt;};&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;O C++ não implementa double dispatch nativamente, por isso devemos tomar alguns cuidados. Por exemplo, todos os tipos possíveis da função trataColisao devem existir na classe ObjetoDeJogo para que este método funcione do jeito esperado.&lt;br /&gt;&lt;br /&gt;Após as classes terem sido criadas, podemos usar os objetos no loop principal do jogo, da seguinte maneira:&lt;br /&gt;&lt;br /&gt;&lt;pre class="brush:cpp"&gt;vector&amp;lt;ObjetoDeJogo *&amp;gt; objetosDeJogo;&lt;br /&gt;objetosDeJogo.push_back(new Jogador());&lt;br /&gt;objetosDeJogo.push_back(new Inimigo());&lt;br /&gt;objetosDeJogo.push_back(new BonusDeVida());&lt;br /&gt;&lt;br /&gt;for(int i = 0;i &amp;lt; objetosDeJogo.size();i++){&lt;br /&gt;   for(int j = i+1;j &amp;lt; objetosDeJogo.size();j++){&lt;br /&gt;      objetosDeJogo[i]-&amp;gt;trataColisao(objetosDeJogo[j]);&lt;br /&gt;      objetosDeJogo[j]-&amp;gt;trataColisao(objetosDeJogo[i]);&lt;br /&gt;   }&lt;br /&gt;}&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;O loop principal continua o mesmo nos dois casos, usando dynamic_cast e double dispatch, porém com double dispatch aproveitamos melhor o polimorfismo que orientação a objetos nos oferece. Com double dispatch, se adicionarmos uma classe nova colidível, precisaríamos escrever uma assinatura nova do método trataColisão na classe ObjetoDeJogo e também implementar os métodos necessários nas classes que mudam algo com a colisão deste objeto de jogo novo.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;O que você acha de double dispatch? Sabe resolver este problema de um jeito melhor?&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4797202738159530784-6269638070431375001?l=natanlima.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://natanlima.blogspot.com/feeds/6269638070431375001/comments/default' title='Postar comentários'/><link rel='replies' type='text/html' href='http://natanlima.blogspot.com/2010/05/double-dispatch-no-tratamento-de.html#comment-form' title='0 Comentários'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4797202738159530784/posts/default/6269638070431375001'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4797202738159530784/posts/default/6269638070431375001'/><link rel='alternate' type='text/html' href='http://natanlima.blogspot.com/2010/05/double-dispatch-no-tratamento-de.html' title='Double dispatch no tratamento de colisões em jogos'/><author><name>Natan Costa Lima</name><uri>http://www.blogger.com/profile/04100311392587071301</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4797202738159530784.post-6879759702591495336</id><published>2010-04-24T12:22:00.000-07:00</published><updated>2010-06-01T12:04:50.397-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='maratona de programação'/><category scheme='http://www.blogger.com/atom/ns#' term='jogos'/><category scheme='http://www.blogger.com/atom/ns#' term='programação dinâmica'/><category scheme='http://www.blogger.com/atom/ns#' term='busca'/><title type='text'>Maratona de programação e Jogos continuação</title><content type='html'>&lt;div style="text-align: justify;"&gt;Anteriormente no fantástico mundo de Natan, eu contei sobre o problema &lt;a href="https://br.spoj.pl/problems/ZAK/"&gt;ZAK GALOU&lt;/a&gt;, para resumir, temos um mago que quer ir de uma sala à outra em uma masmorra e precisa matar os monstros no caminho e também ensinei a matar os monstros. Contarei como resolvi o próximo problema, o de atravessar a masmorra.&lt;br /&gt;&lt;br /&gt;Para representar a masmorra podemos usar um grafo, os vértices deste grafo serão as salas da masmorra e as arestas são representações dos corredores entre as salas (vértices). O custo de cada aresta &lt;span style="font-style: italic;"&gt;vw&lt;/span&gt; será o custo mínimo de mana necessária para matar todos os monstros do vértice &lt;span style="font-style: italic;"&gt;w&lt;/span&gt;.&lt;br /&gt;&lt;br /&gt;Para calcular o custo mínimo de mana necessária usada no vértice &lt;span style="font-style: italic;"&gt;w&lt;/span&gt; basta usarmos o seguinte algoritmo:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;custo_vertice(vertice V){&lt;br /&gt;   para todo monstro M no vértice V&lt;br /&gt;       soma = soma + mata_monstro(M)&lt;br /&gt;   devolva soma&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Deste modo temos um grafo com custo nas arestas e podemos usar o algoritmo de Dijkstra para calcular o menor caminho entre os dois vértices pedidos.&lt;br /&gt;&lt;br /&gt;Como estou envolvido em alguns projetos de jogos no momento, comecei a pesquisar alguns algoritmos de busca, eu conhecia os mais clássicos como BFS, DFS e Dijkstra, e já tinha ouvido falar bastante do A*, porém nunca tinha parado para pensar sobre ele. Em jogos é incomum o uso de BFS ou DFS, a BFS não funciona quando temos custos nas arestas e a DFS pode nos devolver caminhos bem estranhos então eu gostaria de fazer uma comparação entre o algoritmo de Dijkstra e o algoritmo A*.&lt;br /&gt;&lt;br /&gt;Assintoticamente os dois algoritmos são parecidos (Se a função heurística for descente), porém, para a maioria das aplicações práticas em jogos, o algoritmo A* parece ser melhor do que o algoritmo de Dijkstra. Por que??&lt;br /&gt;&lt;br /&gt;O algoritmo de Dijkstra não pressupõe nada sobre o destino, ele não faz uso desta informação para procurar o melhor caminho, ou seja, quando ele finalmente chega ao destino, potencialmente o algoritmo já visitou todos os vértices que tenham distância menor ou igual ao destino. Enquanto isso, no lustre do castelo, temos o A* que usa alguma informação extra como heurística para chegar ao destino. Esta informação depende da representação do grafo, por exemplo, em um  &lt;span style="font-style: italic;"&gt;grid &lt;/span&gt;poderíamos usar a &lt;a href="http://en.wikipedia.org/wiki/Taxicab_geometry"&gt;distância de manhattan&lt;/a&gt; ou a distância euclideana produzindo caminhos possivelmente diferentes.&lt;br /&gt;&lt;br /&gt;Se você ficou interessado mas não tem idéia do que estou falando, pode começar pelos seguintes links:&lt;br /&gt;&lt;br /&gt;&lt;a href="http://en.wikipedia.org/wiki/Dijkstra%27s_algorithm"&gt;Algoritmo de Dijkstra&lt;/a&gt;&lt;br /&gt;&lt;a href="http://en.wikipedia.org/wiki/A*_search_algorithm"&gt;Algoritmo A*&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Sim, eu gosto da wikipedia =)&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4797202738159530784-6879759702591495336?l=natanlima.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://natanlima.blogspot.com/feeds/6879759702591495336/comments/default' title='Postar comentários'/><link rel='replies' type='text/html' href='http://natanlima.blogspot.com/2010/04/maratona-de-programacao-e-jogos_24.html#comment-form' title='0 Comentários'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4797202738159530784/posts/default/6879759702591495336'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4797202738159530784/posts/default/6879759702591495336'/><link rel='alternate' type='text/html' href='http://natanlima.blogspot.com/2010/04/maratona-de-programacao-e-jogos_24.html' title='Maratona de programação e Jogos continuação'/><author><name>Natan Costa Lima</name><uri>http://www.blogger.com/profile/04100311392587071301</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4797202738159530784.post-5485868881101224564</id><published>2010-04-23T06:51:00.000-07:00</published><updated>2010-08-06T04:08:36.952-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='maratona de programação'/><category scheme='http://www.blogger.com/atom/ns#' term='jogos'/><category scheme='http://www.blogger.com/atom/ns#' term='programação dinâmica'/><category scheme='http://www.blogger.com/atom/ns#' term='busca'/><title type='text'>Maratona de programação e Jogos</title><content type='html'>&lt;div style="text-align: justify;"&gt;Estou muito interessado no mercado de jogos, além disto estou participando de um grupo de desenvolvimento de jogos da USP, o que me faz buscar várias referências literárias sobre o assunto. Minha outra paixãozinha é a maratona de programação, uma competição onde são dados alguns problemas e temos que fazer um código (geralmente em C, C++ ou JAVA) que passe nos casos de testes de um juíz.&lt;br /&gt;&lt;br /&gt;Apresento-lhes um dos meus problemas favoritos, uma mistura de jogo com a maratona: &lt;a href="https://br.spoj.pl/problems/ZAK/"&gt;https://br.spoj.pl/problems/ZAK/&lt;/a&gt;. Este problema foi dado em uma prova regional aqui no Brasil.&lt;br /&gt;&lt;br /&gt;Para resumir a história, temos um mago que deseja atravessar uma masmorra infestada de inimigos, sabemos quais são as magias do mago e o problema consiste em descobrir o mínimo de mana necessária para atravessar a masmorra.&lt;br /&gt;&lt;br /&gt;Um sub-problema que encontramos aqui é: como matar um inimigo com o menor custo de mana possível. Como os inimigos são simples, ou seja, não têm resistências ou fraquezas, se soubermos matar um inimigo com &lt;span style="font-style: italic;"&gt;x&lt;/span&gt; de vida, conseguiremos matar qualquer um com &lt;span style="font-style: italic;"&gt;x&lt;/span&gt; de vida.&lt;br /&gt;&lt;br /&gt;Sabemos também que os inimigos têm no máximo &lt;span style="font-style: italic;"&gt;1000 &lt;/span&gt;de vida, ou seja, se usarmos um algoritmo parecido com o algoritmo de programação dinâmica usado no problema da mochila (&lt;a href="http://en.wikipedia.org/wiki/Knapsack_problem"&gt;http://en.wikipedia.org/wiki/Knapsack_problem&lt;/a&gt;), resolveremos o problema de um modo satisfatório.&lt;br /&gt;&lt;br /&gt;Um pseudocódigo com a idéia da mochila:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;Mata_monstro( Inteiro vida){&lt;br /&gt;    variável mínimo = infinito&lt;br /&gt;    Se vida &lt;= 0&lt;br /&gt;        devolva 0&lt;br /&gt;    Para cada magia &lt;span style="font-style: italic;"&gt;M&lt;/span&gt; disponível&lt;br /&gt;        aux = (Mata_monstro(vida - dano de &lt;span style="font-style: italic;"&gt;M&lt;/span&gt;) + custo de &lt;span style="font-style: italic;"&gt;M&lt;/span&gt;)&lt;br /&gt;        mínimo = menor entre mínimo e aux&lt;br /&gt;    devolva mínimo&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Claro que podemos usar uma tabela para memorizar esta função. Se chamarmos ela para todos os valores de&lt;span style="font-style: italic;"&gt; 1&lt;/span&gt; até &lt;span style="font-style: italic;"&gt;1000 &lt;/span&gt;teremos a tabela inteira preenchida no final e conseguiremos fazer consultas de modo bem eficiente quando precisarmos saber quanto de mana gastaremos para um determinado monstro.&lt;br /&gt;&lt;br /&gt;to be continued...&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Quem estudar na USP e estiver interessado no grupo de jogos que eu citei no começo, mande um email para mim (lima ponto natan arroba gmail ponto com) que podemos conversar. Precisamos de músicos, desenhistas, roteiristas e também programadores.&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4797202738159530784-5485868881101224564?l=natanlima.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://natanlima.blogspot.com/feeds/5485868881101224564/comments/default' title='Postar comentários'/><link rel='replies' type='text/html' href='http://natanlima.blogspot.com/2010/04/maratona-de-programacao-e-jogos.html#comment-form' title='0 Comentários'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4797202738159530784/posts/default/5485868881101224564'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4797202738159530784/posts/default/5485868881101224564'/><link rel='alternate' type='text/html' href='http://natanlima.blogspot.com/2010/04/maratona-de-programacao-e-jogos.html' title='Maratona de programação e Jogos'/><author><name>Natan Costa Lima</name><uri>http://www.blogger.com/profile/04100311392587071301</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4797202738159530784.post-4802641561374514827</id><published>2010-04-21T18:54:00.000-07:00</published><updated>2010-04-23T07:49:39.991-07:00</updated><title type='text'>Prólogo</title><content type='html'>&lt;div style="text-align: justify;"&gt;O título do blog foi idéia da minha namorada. Eu não lembrava muito bem do desenho "O fantástico mundo de Bob". Como faço com quase todos os assuntos que não sei ou não lembro muito bem, fui a wikipedia para dar uma olhada no artigo e li a seguinte frase:  "It was about the daily life of Bobby Generic and his very overactive imagination on how he sees the world".&lt;br /&gt;&lt;br /&gt;Fiquei bastante impressionado pois passei a amar o título do meu blog, ele descreve fielmemente o que quero passar. Vou reformular a frase em português para definir meu blog formalmente: Este blog apresentará minha vida (talvez não diariamente) e minha imaginação fértil ao ver o mundo. Voilà.&lt;br /&gt;&lt;br /&gt;to be continued ...&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4797202738159530784-4802641561374514827?l=natanlima.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://natanlima.blogspot.com/feeds/4802641561374514827/comments/default' title='Postar comentários'/><link rel='replies' type='text/html' href='http://natanlima.blogspot.com/2010/04/prologo.html#comment-form' title='2 Comentários'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4797202738159530784/posts/default/4802641561374514827'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4797202738159530784/posts/default/4802641561374514827'/><link rel='alternate' type='text/html' href='http://natanlima.blogspot.com/2010/04/prologo.html' title='Prólogo'/><author><name>Natan Costa Lima</name><uri>http://www.blogger.com/profile/04100311392587071301</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>2</thr:total></entry></feed>
