Fazer download em pdf ou txt
Fazer download em pdf ou txt
Você está na página 1de 7

Jogo

Baixe agora jogos de corrida, futebol estratgia e mais!

ZipCode Lista Mala Direta


Listas completas e segmentadas E-mails autorizados e Opt-in

Search:

VS.Net 2005

Empregos

VS.Net 2003

Internet Home

Go

> Artigos

>> >> >> >> >> >> >> >> >>

Home Missao

Um jogo quebra cabeas usando Generics


Eventos Artigos Livros Forum Galeria de Imagens Downloads Links Favoritos

Enviado por carlos em tera-feira, 31 de agosto de 2004 (EST)


O Visual Studio 2005 vem com o namespace Generic. Veja nesse artigo como um simples jogo pode ser uma maneira eficiente de trabalhar com listas genricas duplamente ligadas. Na sesso de Download voce vai encontrar o artigo e o cdigo completos.

Artigos Mais Populares


Instalando o Windows Vista
O Windows Vista vem ai. Como ficam questes como instalao e compatibilidade com o hardware?

Construindo um jogo (quebra cabeas) usando Generics


Introduo

Usando Interfaces no .Net


Porque as interfaces so pouco usadas pelos desenvolvedores? O artigo no se prope a responder essa pergunta, mas aborda alguns pontos que podem fazer parte da resposta.

Login Registrar Web Hosting By Brinkster

Indique esse site.

A primeira vez que precisei construir uma lista duplamente ligada, estava programando em assembly da Intel. Confesso que, na ocasio, tive alguma dificuldade em entender como funcionava esse tipo de estrutura. Com o tempo, tive que fazer a mesma coisa em C e C++. Apesar do C# ser uma linguagem bem mais suave que essas outras citadas e ter uma tima biblioteca de classes que auxiliam bastante o usurio, acredito que alguns desenvolvedores possam ainda ter alguma dificuldade de entender o funcionamento de uma lista duplamente ligada. Baseado nisso, resolvi criar esse pequeno jogo usando um Windows Form e C# que objetiva mostrar, visualmente, as funcionalidades oferecidas pela classe Generics ao programar uma lista duplamente ligada com uso genrico. Entender esses conceitos torna muito mais simples seu uso na implementao de programas utilizando o C# ou outras linguagens da plataforma .Net. Para rodar esse programa voc ter que fazer uso do Visual Studio C# Express ou ento o Visual Studio 2005 Beta 1. Voc pode fazer o download de ambos no endereo
http://lab.msdn.microsoft.com

Descubra qual a verso do .Net Framework roda na maquina


Com algumas linhas de cdigo e algumas chaves do registro do Windows possivel saber qual (ou quais) verso do .Net Framework esta instalada na maquina. Voce pode baixar o projeto completo na seo de downloads.

Links mais Populares


Download do .NET Framework
O Microsoft .NET Framework um componente integral do Windows para construir e executar a proxima gerao de aplicaes e os XML Web services. Prove uma alta produtividade, baseado em padres, aplicaes empresariais, ambiente multi-linguas que simplifica o desenvolvimento de aplicaes

ASP.NET
Esse um timo site onde voce encontra artigos, cdigos e componentes free para usar nas suas aplicaes ASP.NET.

Como o jogo funciona O funcionamento do jogo bastante simples. A Figura 1 mostra a tela inicial do jogo que possui dois painis e um conjunto de botes. Figura 1. Tela inicial do jogo. O painel superior (bege) ou painel de origem armazena as peas que devero ser movidas para o painel inferior (azul) ou painel de destino, onde devem ser posicionadas corretamente e, nesse caso, formar uma palavra. O painel de origem representa a lista de peas embaralhadas e o painel de destino representa a lista onde ser montada a resposta do jogo. As peas podem ser movimentadas livremente, de um painel para o outro, logicamente seguindo as regras existentes na utilizao de uma lista ligada. Os vrios botes so utilizados para movimentar as

Treinamento ASP.NET
Aprenda como construir Web sites dinamicos utilizando o Visual Studio .NET.

Novos Artigos
Como acessar um hardware remoto
Usando WMI para acessar uma maquina remota

Construa um browser em poucos minutos (revisado)


Veja como fazer um browser usando as novas funcionalidades do Visual Studio 2005. (Pegue o fonte completo na area de downloads)

Instalando o Windows Vista


O Windows Vista vem ai. Como ficam questes como instalao e compatibilidade com o hardware?

peas. Observe que os botes tm ttulos que representam os mtodos das listas genricas que so utilizados no programa. Desse modo, visualmente fica fcil para quem manipula o jogo, saber como cada mtodo funciona, uma vez que o mesmo est sendo representado visualmente quando acionado. Um outro ponto interessante que, como o programa esta manipulando listas ligadas, algumas regras tm que ser seguidas para o programa funcionar corretamente. Por exemplo, se clicar no boto Add After (Adiciona Depois) e se no houver nenhuma pea no painel destino, o usurio receber uma mensagem de erro dizendo que o programa no pode adicionar uma pea depois de uma outra pea, uma vez que ainda no existe nenhuma pea na janela azul. Parece obvio? Sim, mas a gente costuma no atentar para esses pequenos detalhes. Sobre o programa Apesar de ser um projeto apenas para demonstrar algumas das funcionalidades do namespace Generic, aproveitei para fazer uso onde foi possivel de algumas das novidades existentes no Visual Studio 2005 como o Refactoring para a gerao rpida e padronizada de trechos de cdigo, partial para dividir classes grandes e FxCop para analisar o cdigo e encontrar pontos a serem corrigidos. O objetivo foi ter uma melhor aderncia s boas praticas de programao. O diagrama da Figura 2 gerado pelo Visual Studio mostra a arquitetura utilizada no programa. Figura 2. Diagrama de Classes do programa. Como pode ser visto no diagrama, o programa usa as classes GameForm, GameItems, Item, LinkedItems<T> e LinkedList<T>. Classe GameForm O formulrio gerado pela classe GameForm que encapsula as funcionalidades que permitiro ao usurio interagir com o jogo. De acordo com a arquitetura utilizada, essa classe abstrai o modo como so manipuladas as listas que contm as peas. Dessa forma, quando um boto acionado, o controle passado para a classe GameItems na camada de lgica, que tem a funo de manipular as listas adequadamente. Quando se deseja mover uma pea, a classe GameForm precisa saber em qual dos dois painis est a pea em questo. Para isso, a classe faz uso da varivel booleana sourcePanelSelected que alterada de acordo com o evento MouseEnter o qual disparado quando o mouse entra na regio do painel, conforme mostra o cdigo abaixo:
private void sourcePn_MouseEnter(object sender, EventArgs e) { sourcePanelSelected = true; } private void targetPn_MouseEnter(object sender, EventArgs e)

Last Refreshed 6/5/2008 23:25:23

XML.com
XML.com features a rich mix of information and services for the XML community.

Introducing E4X Kurt Cagle introduces us to E4X, an XML library for JavaScript, and argues that XML and JSON are both indispensable parts of the web app developer's toolkit. Data Sources as Web Services Kyle Gabhart describes WS02's Data Services, a new feature in WS02 that allows for rapid creation of web services wrapping relational, Excel, CSV, and JNDI data sources quickly and easily. XForms Thick Clients Jack Cox explains an approach to building XForms client applications that work in a disconnected environment. jQuery and XML Uche Ogbuji returns with a new Agile Web column to explain how to use jQuery to process XML in JavaScript web applications. Extended XQuery for SOA Web service orchestration is an important part of web services and service oriented architecture. Gimzewski and Fancellu argue that XQuery is especially well-suited as an implementation language for service orchestrator components.

Copyright 2004, O'Reilly Media, Inc. Last


Refreshed 6/5/2008 23:25:23

{ sourcePanelSelected = false; }

Classe Item Essa classe armazena as funcionalidades de uma determinada pea como posio inicial da pea no painel, se selecionada ou no, etc. Vamos falar sobre seleo de itens mais adiante. Classe LinkedItems<T> Essa classe derivada da classe LinkedList<T> como mostra o cdigo:
public class LinkedItems<T> : LinkedList<T> { // codigo }

Desse modo, criamos uma lista duplamente ligada genrica que pode ser utilizada para armazenar diferentes tipos de objetos, sem que haja a necessidade de alterar seu cdigo. Da a caracterstica de lista genrica. Com o uso de Generic podemos construir lista fortemente tipadas aumentando a performance e obtendo um cdigo mais limpo e fcil de dar manutenao. Apesar a classe LinkedItems herdar os mtodos da classe base, resolvi criar mais alguns para facilitar a manipulao das peas no jogo. Veja tambm que, apesar de alguns mtodos aceitarem sobrecarga de parmetros, esse mtodos trabalham com o n da lista e, como a classe GameItems, que eu criei, manipula apenas as peas das listas, tive que implementar mtodos que aceitassem apenas os itens das listas e, internamente, chamar os mtodos da classe base passando os ns corretos como parametros. Veja, por exemplo, os casos dos mtodos AddAfterItem e AddBeforeItem abaixo:
public LinkedListNode<T> AddAfterItem(T newItem, T item) { LinkedListNode<T> node = Find(newItem); return base.AddAfter(node, item); } public LinkedListNode<T> AddBeforeItem(T newItem, T item) { LinkedListNode<T> node = Find(newItem); return base.AddBefore(node, item); }

Como os mtodos da classe base AddAfter e AddBefore s aceitam o primeiro parmetro como sendo um objeto do tipo LinkedListNode, ento foi necessrio primeiro achar o node correspondente ao item e, s ento, chamar a o mtodo da classe base. Um outro mtodo tambm adicionado a classe LinkedItems o mtodo GetSibilingItem que retorna o item vizinho ao item passado como referencia. Esse mtodo tambm tem como segundo parmetro um booleano que indica se o item a ser encontrado o vizinho antes ou depois da referencia. Veja no cdigo abaixo:

public T GetSibilingItem(T item, bool forward) { // porque a lista duplamente ligada, podemos facilmente // percorrer toda a lista para frente ou para tras LinkedListNode<T> node = null; Nullable<T> retNull = null; node = Find(item); if (node == null) return default(T); else { // procura para frente if (forward) { node = node.Next; } // procura para tras else { node = node.Previous; } } // se nao achar, retorna nulo if (node == null) return default(T); else return node.Value; }

Como voc pode ver, uma das grandes vantagens de uma lista duplamente ligada que ela pode ser facilmente percorrida para frente e para trs. Nesse caso, isso se torna uma grande dor de cabea em uma linguagem de baixo nvel, onde o programador deve se preocupar em atualizar os ponteiros da lista, uma vez que eles apontam para frente e para trs. Qualquer erro no uso incorreto desses ponteiros e voc corre o risco de no mais encontrar seus dados. No C#, que utiliza cdigo gerenciado, voc no tem que se preocupar com esses detalhes. Um outro ponto interessante desse mtodo o uso da classe Nullable<T>:
return default(T);

Veja que, se o item que ser usado como referencia no for encontrado na lista, o mtodo deve retornar null. A questo : como retornar null para um objeto T genrico? Se no cdigo eu forar o retorno de null, o compilador retorna um erro dizendo que no pode converter o null para o tipo T a ser retornado. A soluo utilizar o valor default do tipo ou, default(T). O valor default tambm conhecido como valor nulo do tipo nullable. Ocorre uma converso implcita entre o null literal para qualquer tipo nullable e essa converso produz o valor nulo para o tipo. Classe GameItems Para tornar a classe mais limpa, utilizei a palavra chave partial que permite quebrar uma classe, estrutura ou interface em vrios arquivos. Essa classe tem uma funo fundamental no funcionamento do programa, pois ela que vai fazer uso dos mtodos disponveis na lista ligada usada nesse programa. Ao ser instanciada, a classe GameItems cria as duas listas

ligadas do tipo LinketItems<T>, que recebem como parmetro a classe Item, como mostra o cdigo:
public GameItems(GameForm frm) { //savedItemsLocation = new List<Item>(); // creates a target linked list targetListItems = new LinkedItems<Item>(); // creates a source linked list sourceListItems = new LinkedItems<Item>(); // save the initial appearance of the game SaveSourceLocationAndItems(frm); }

Veja que as listas criadas targetListItems e sourceListItems so fortemente tipadas, pelo fato da lista genrica ter sido criada utilizando como parmetro um tipo pr-definido. Isso torna o uso dessas listas bem mais simples porque no h a necessidade de utilizar cast na retirada de um elemento da lista, uma vez que a lista s aceita um nico tipo de item. A classe GameItems tambm recebe, no construtor, uma referencia ao formulrio, que passada para o mtodo SaveSourceLocationAndItems, permitindo salvar as posies iniciais de todas as peas existentes no painel de origem. Um outro ponto interessante que a classe GameItems manipula as peas do jogo trocando as peas de uma lista para outra e atualizando suas posies, enquanto que a classe GameForm manipula as peas nos painis. Adicionando e retirando um item Adicionar um item ao inicio ou final de uma lista um procedimento bem simples e o prprio cdigo auto-explicativo nesse sentido. Veja que, tanto para adicionar como apagar um elemento da lista, h a necessidade de atualizar os ponteiros dessa lista, o que feito internamente pelo .Net Framework. Em uma linguagem de mais baixo nvel como C++, C ou assembly, isso tem que ser feito na mo pelo programador. Vamos verificar ento a adio de um item ANTES de um outro item, como mostra o cdigo:
public PictureBox AddPieceBefore() { Item selectedSrcItem = null; Item selectedTgtItem = null; // pega o item selecionado na lista de origem selectedSrcItem = GetSelectedItem(sourceListItems); // pega o item selecionado na lista de destino selectedTgtItem = GetSelectedItem(targetListItems); // se null, precisa selecionar um item if (selectedSrcItem != null && selectedTgtItem != null) { // adiciona item ao final da lista targetListItems.AddBeforeItem(selectedTgtItem, selectedSrcItem); // remove item da lista de origem sourceListItems.Remove(selectedSrcItem); // retira a seleo do item selectedSrcItem.IsSelected = false; selectedTgtItem.IsSelected = false; // tenta deslocar todos os item para acomodar o item adicionado Point nextPosition = solutionPosition; // atualiza a lista

UpdatePositionForEntireList(targetListItems, nextPosition); } else return null; return selectedSrcItem.PicItem; }

Quando se vai adicionar um item antes de um outro, algumas condies tm que ser satisfeitas. Veja que o trecho de cdigo abaixo:
if (selectedSrcItem != null && selectedTgtItem != null)

verifica se existe um item selecionado para ser retirado da lista de origem e se existe um item selecionado na lista de destino para ser usado como referencia, conforme o mtodo AddBeforeItem que pede esses dois parmetros. Se a insero do novo item for feita com sucesso, o item removido da lista de origem e as peas so tornadas no selecionadas. Aps a insero, h ainda a necessidade de atualizar as posies dos itens, o que equivaleria a atualizao de seus ponteiros, conforme citado acima. O mtodo UpdatePositionForEntireList faz essa atualizao, acomodando cada item em seu devido lugar. O mtodo AddAfterItem tem um funcionamento semelhante, mudando apenas o lugar onde ser feita a insero, ou seja, adiciona depois. Veja que para os mtodos de remoo, no existe um RemoveAntes ou RemoveDepois. Uma vez que o usurio escolhe uma pea para ser removida, no faz sentido, nesse programa, ter um mtodo que remove a pea que est antes ou depois da pea escolhida. Mas, se fosse necessrio, logicamente que isso poderia ser implementado. Selecionando um item Como j foi comentado acima, dependendo da operao a ser executada no jogo, h a necessidade de selecionar uma ou duas peas. Esse pedido de seleo feita pelo mtodo PieceItem_Click da classe GameForm que, por sua vez, repassa o pedido para o mtodo SelectPicItem da classe GemeItems. A mudana para situao de item selecionado feita pela propriedade IsSelected da classe Item, conforme mostrado no cdigo abaixo:
public bool IsSelected { get{ return selected;} set { selected = value; // if the item is selected, change its appearence // to notify the user if (selected) item.BorderStyle = BorderStyle.FixedSingle; else item.BorderStyle = BorderStyle.None; } }

Concluso O projeto mostra de forma visual e atravs de cdigo como

simples a manipulao de uma lista duplamente ligada usando o namespace Generic. A possibilidade de utilizao de uma lista fortemente tipada tambm facilita bastante a programao do sistema. Como o objetivo principal foi mostrar de forma visual esses conceitos, logicamente que algumas melhorias que poderiam ser feitas se o objetivo fosse criar um jogo acabaram no acontecendo. Veja que, os botes poderiam simplesmente ser retirados e a movimentao das peas poderia ser feita exclusivamente pelo mouse. Mas ai deixaramos de ter um tratamento visual. Boa diverso!

Por Carlos Roberto Lacerda Analista de Sistemas Snior


[email protected] www.byteshift.com

Avise-me quando um novo comentrio for colocado


Adicione seu Comentario

Home

Missao

Eventos

Artigos

Livros

Forum

Galeria de Imagens

Downloads

Links Favoritos

Você também pode gostar