DiceDnd

Os dados usados no RPG D&D
Os dados usados no RPG D&D

A minha idéia exploratória de criar um aplicativo para gerar jogada de dados no meu N800  ocupou umas horas da noite de sexta e início de madrugada do sábado.

O objetivo da aplicação é bem simples. Eu vou voltar a mestrar campanhas de RPG. Comprei o recente D&D 4ª Edição em português mais uma aventura para personagens iniciantes. Não tenho todos os tipos de dados necessários. São 6 tipos, por quantidade de faces: 4, 6, 8, 10, 12 e 20. Assim, queria simular a parada de dados pelo meu N800, um internet tablet da Nokia.

Uma das principais linguagens para programar nesses dispositivos é Python. Apesar de não conhecer muito a biblioteca Gtk (biblioteca gráfica), conheço a linguagem razoavelmente bem, por isso acreditava que conseguiria implementar o aplicativo no final de semana.

A primeira providência foi procurar documentação. A idéia do projeto já estava toda na minha cabeça mas não sabia por onde começar. Depois de um tempo, encontrei algumas coisas. Foram importantes os seguintes documentos:

A versão do sistema operacional é o OS 2008 (Diablo). O Python 2.5 já estava instalado. De fato, não precisei instalar outra coisa. Algumas documentações diziam que eu tinha de instalar o interpretador da linguagem. Talvez eu tenha feito isso algum tempo atrás.

Outra coisa que ajudou bastante, para ir escrevendo e testando rapidamente, foi acessar via SSH o dispositivo pelo Nautilus (num notebook com Ubuntu). Criei o arquivo da aplicação no cartão do N800 e depois abrir com o editor TextFlow. Daí era só escrever, salvar e ir no PDA executar a aplicação.

O cliente e servidor do SSH não vem instalado por default no N800. Nem o terminal. Por ele é que eu rodava o Python. Pelo notebook, eu usava também um terminal para acessar o N800 via ssh. Era útil para testar algumas coisas no interpretador interativo do Python.

As próximas tarefas envolvem melhorar o aspecto visual da aplicação e preparar um instalador para ficar mais fácil de dispobilizar. O código-fonte encontra-se abaixo:

#!/usr/bin/python2.5

import osso
import gtk
import hildon

def string_jogada(vezes, dado, soma):
    if soma > 0:
        sinal = '+'
    elif soma == 0:
        sinal = ''
    else:
        sinal = '-'
    return '%dd%d%s%s' % (vezes, dado, sinal, abs(soma) or '')

class DiceDnD(hildon.Program):
    def __init__(self):
        self.dado_atual = 0
        self.vezes = 0
        self.soma = 0
        hildon.Program.__init__(self)
        self.window = hildon.Window()
        self.window.set_title('DiceDnd')
        self.window.connect("destroy", self.quit)
        self.add_window(self.window)

        tabela = gtk.Table(5,4,True)
        self.window.add(tabela)

        self.dado4 = gtk.Button('4')
        self.dado6 = gtk.Button('6')
        self.dado8 = gtk.Button('8')
        self.dado10 = gtk.Button('10')
        self.dado12 = gtk.Button('12')
        self.dado20 = gtk.Button('20')
        self.botaoMais = gtk.Button('+')
        self.botaoMenos = gtk.Button('-')
        self.botaoJogar = gtk.Button('Jogar')
        self.frame = gtk.Frame()
        self.montagem = gtk.Label('Jogada')
        self.frame.add(self.montagem)

        tabela.attach(self.dado4,0,1,0,1)
        tabela.attach(self.dado6,1,2,0,1)
        tabela.attach(self.dado8,2,3,0,1)
        tabela.attach(self.dado10,0,1,1,2)
        tabela.attach(self.dado12,1,2,1,2)
        tabela.attach(self.dado20,2,3,1,2)
        tabela.attach(self.botaoMais,0,1,2,3)
        tabela.attach(self.botaoJogar,1,2,2,3)
        tabela.attach(self.botaoMenos,2,3,2,3)
        tabela.attach(self.frame,0, 3, 3, 4)

        self.dado4.connect('clicked',self.preparar,4)
        self.dado6.connect('clicked',self.preparar,6)
        self.dado8.connect('clicked',self.preparar,8)
        self.dado10.connect('clicked',self.preparar,10)
        self.dado12.connect('clicked',self.preparar,12)
        self.dado20.connect('clicked',self.preparar,20)
        self.botaoMais.connect('clicked',self.incrementar,1)
        self.botaoMenos.connect('clicked',self.incrementar,-1)
        self.botaoJogar.connect('clicked',self.mostrar)

        self.window.show_all()

    def mostrar(self, button):
        if self.dado_atual == 0:
            return
        import random
        total = 0
        for i in range(self.vezes):
            total += random.randint(1,self.dado_atual)
        total = total + self.soma
        jogada = string_jogada(self.vezes, self.dado_atual, self.soma)
        self.show_message('%s' % total)

    def preparar(self, button,valor):
        if valor  self.dado_atual:
            self.dado_atual = valor
            self.vezes = 1
            self.soma = 0
        else:
            self.vezes += 1
        self.montagem.set_text(string_jogada(self.vezes, self.dado_atual, self.soma))

    def incrementar(self, button,valor):
        self.soma = self.soma + valor
        self.montagem.set_text(string_jogada(self.vezes, self.dado_atual, self.soma))

    def show_message(self, message):
        dlg = hildon.Note('information', (self.window, message))
        dlg.run()
        dlg.destroy()
        #pango_markup = '%s\n%s' % ('DiceDnD', message)
        #hildon.hildon_banner_show_information_with_markup(gtk.Label(''), None, pango_markup)

    def quit(self, evt):
        gtk.main_quit()

    def run(self):
        gtk.main()

def main():
    prog = DiceDnD()
    prog.run()

if __name__ == "__main__":
    main()
Anúncios

Idéia exploratória

Uma boa idéia me surgiu agora, útil para o momento e ótima pedida para iniciar a exploração no mundo da programação de dispositivos Nokia que usam o sistema operacional Maemo: um rolador de dados.

Bobo, né? Inclusive, acho que já existe um. Mas é diferente do que eu estou pensando.

Gostaria que a tela do aplicativo mostrasse um quadrado com todos os tipos de dados usados no RPG D&D ou seja, os de 4, 6, 8, 10, 12 e 20 faces. E mais três botões: para o sinal de mais, o de menos e o de igual.

Ao apertar um dos dados ele saberá que quero jogar com ele. Ele esperará eu apertar no sinal de igual para a operação randômica executar. Os sinais servem para aumentar ou diminuir o que resultar do dado. Cada vez que eu apertar num deles incrementa-se ou descrementa-se em um.

Logicamente vou escrever esse aplicativo em Python. Vamos ver se tenho a sorte e produtividade de terminá-lo ainda neste final de semana. Quando concluir, posto por aqui.

Python for Unix and Linux System Administration

Estou lendo o livro Python for Unix and Linux System Administration e estou gostando muito, por isso estou aqui escrevendo sobre ele.

Este livro da editora O’Reilly, escrito por Noah Gift e Jeremy M. Jones é uma coleção de problemas-solução em Python. Nele você encontra de quase tudo. Seu lançamento recente (Agosto de 2008) contempla as novidades do Python 2.5, apesar de já estamos com Python 2.6 pronto para instalarmos em nossas máquinas.

Ele está voltado para administradores de sistemas que precisam resolver problemas recorrentes e repetitivos e necessitam de uma ferramente ágil e completa. Python pareceu ser a escolha adequada, apesar dos autores confessarem que a escolha ter sido bem subjetiva.

Ao ler suas páginas fica claro que  o material contido nele serve para todos os programadores. É uma forma maravilhosa de conhecer bibliotecas e funções nunca antes utilizadas por nós, ou descobrirmos novas formas de fazer as coisas com as que já conhecíamos (eu descobri).

Logicamente, tem coisas que são quase exclusivamente para administradores de redes e nos deleitamos como tarefas complexas podem ser resolvidas em poucas linhas de código. Sinaliza também o fato de que a vida de um administrador de redes já é dura e não precisa ficar pior. Desenvolver suas próprias ferramentas em Python é algo prazeroso.

Há um maravilhoso capítulo chamado Package Management explanando coisas como Setuptools e os Python Eggs, os ovos de cobra, os conhecidos arquivos de distribuição. Só por este capítulo eu compraria o livro.

E tem mais. Sobre persistência de dados, temos o simples shelve, o ZODB, SQLite, Storm ORM e SQLAlchemy. É uma aula de atualidades do mundo Python.

Há coisas que já li a respeito mas não me aprofundei, como, por exemplo, Buildout, Twisted, Scapy, entre outros.

Vou continuar lendo. Leitura recomendada.

Comunidade de Jogadores e Desportistas

O Mosaico Livre é essencialmente um blog sobre programação, engenharia de software, software livre. Ultimamente venho negligenciando esta essência. É como se tivesse perdido o rumo.

O barco, no entanto, deve seguir seu rumo correto.

Já há algum tempo, por curiosidade, li alguns tutoriais e assistir alguns vídeos sobre o Google App Engine, uma plataforma para desenvolver aplicações web que podem usar a infraestrutura do Google. Ou seja, podemos hospedar nossas aplicações nos servidores do Google.

O Google App Engine é implementado em Python. Um fator importante para que eu rapidamente pudesse desenvolver alguma coisa. Logo será possível usar outras linguagens. Até lá o interesse em aprender Python continuará.

E como Python cresceu desde 1999, o ano em que comecei a programar nesta linguagem! Ela já está entre as linguagens modernas mais comentadas. A falta de uma empresa forte que a utilizasse ou pelo menos incentivasse seu uso era um dos motivos para as pessoas não quererem conhecê-la. O Google mudou isso.

Atualmente desenvolvo uma aplicação para Google App Engine. Na verdade, é um portal para concentrar informações sobre esportes e jogos em geral, seja amador ou profissional. Um local onde o pessoal possa conhecer outros praticantes. Por exemplo, sinto necessidade de conhecer pessoas na minha cidade que joguem Go, um jogo de tabuleiro difundido no oriente, mas pouco por aqui. No site, posso informar os jogos que pratico. Quem tiver interessado em jogar comigo, pode enviar um e-mail. Depois, podemos informar no site o local onde jogaremos para que outras pessoas possam comparecer para apreciar a partida.

É raro encontrar algum portal da imprensa que dedique um espaço a esportes com poucos praticantes. A minha idéia é preencher esta lacuna.

Assim que eu tiver terminado, passo o endereço para vocês.

TurboGears 2: solução de problemas durante a instalação

Pediram-me para documentar a instalação do TurboGears 2. Vocês podem encontrar os passos para a instalação aqui.

O restante deste post é sobre como solucionar certos problemas. Então, se você seguiu a documentação oficial e não teve problemas não precisa mais ler este post.

É bom salientar que fiz a instalação no Ubuntu Linux.

Installing TurboGears 2 from Source

Nesse ponto, quando vocês forem instalar o tg2 com python setup.py develop, vocês não encontrarão o arquivo setup.py. Ocorre que agora o tg2 usa o paver como instalador. Ou seja, documentação desatualizada. Na raiz de tg2 execute sudo paver develop.

Pode ser que durante o download das dependências do tgdev, não seja encontrado a versão 0.8.7dev do ToscaWidgets. Se este for o caso, é melhor você esperar um tempo para eles disponibilizarem-na e então sincronize a cópia de trabalho com svn update. Depois, execute novamente sudo python setup.py develop.

Concluídas as demandas, você já pode brincar com o TurboGears 2. Comece pelo Wiki em 20 minutos.

Estou querendo instalar o TG2 no Windows, então os problemas que possa encontrar vou colocar como comentário aqui.

Primeiro contato com TurboGears 2

Como o Twitter não está muito bem, vai ser por aqui mesmo que informo aos amigos e colegas pythonistas que tive pela primeira vez contato com o TurboGears 2 hoje. Acabei de fazer o exemplo da Wiki.

Aos poucos, devo começar a me aprofundar no uso dele, uma vez que estamos pensando em adotar o framework para o desenvolvimento de um projeto. Queremos que nossa aplicação acompanhe o desenvolvimento do TurboGears, mesmo que isso seja arriscado.

Tive um razoável trabalho para instalá-lo na minha máquina. O trabalho não se deveu ao fato de tê-lo de obter via Subversion, mas sim porque alguns pacotes não estavam sendo encontrados pelo easy_install. Também precisei usar o Paver para baixar umas dependências. Isso a documentação de instalação não explicou. Devo fazer a instalação também no notebook do Stênio. Não anotei nada, espero conseguir.

Apesar dele manter a API bastante semelhante ao TurboGears 1, há componentes novos. A curiosidade foi aguçada por conta disso. Estava tão por fora, que somente agora fiquei sabendo sobre o Paver, criado pelo próprio Kevin Dangoor. Parece-me um melhoramento sobre o processo de instalação/distribuição/empacotamento.

Deixemos para outros posts demais conclusões sobre o TG2.

Sistemas de Controle de Versão em Python

Um amigo, Stênio, e eu conversávamos sobre um projeto secreto (o Google não pode saber) que ele tem em mente. Pretendemos implementá-lo em Python. Coube a idéia da escolha do controle de versões ao Stênio e ele disse que gostaria de experimentar o Mercurial. Isso por ele ser descentralizado e ter uma grande variedade de ferramentas. A referida característica faz parte dos sistemas de controle de versões chamados distribuídos, tais como o Monotone e o Git. Aliás, segundo li, o Mercurial e o Git seguem as idéias do Monotone.

Um fato importante a citar: o Git foi inicialmente desenvolvido pelo próprio Linus Torvalds para substituir uma solução proprietária, o BitKeeper, na tarefa de ser o repositório da árvore do kernel Linux.

O Mercurial e o Bazaar são exemplos recentes de controles de versões distribuídos desenvolvidos em Python. O Bazaar é utilizado pela Canonical, a empresa responsável pela distribuição Ubuntu, que aliás, sou um dos usuários satisfeitos. Pensei até em adotar o Bazaar em nosso projeto, mas em consideração ao amigo, ficamos mesmo com o Mercurial.

Aqui no trabalho, usamos o Subversion, o já tradicional controle de versões que veio a substituir o CVS na importante tarefa de versionar e centralizar o acesso ao código-fonte dos projetos.

Gostaria que esse post servisse também para os leitores-programadores a considerarem o uso de um sistema de controle de versões, mesmo para seus projetos caseiros. Aos programadores Python, considerem o uso do Bazaar e Mercurial, em especial.