<email ⁄>
<windows live messenger ⁄>
<myCurriculum type="pdf" ⁄>
*{padding: 0; margin: 0;} body{ font-family: Verdana, Tahoma, Arial, sans-serif;font-size: 62.5%; color: #000;background-color: #fff;text-align: center; } div#board_title{ margin: 0 auto; text-align: center; font-weight: 900;color: #cc0000; font-size: 3em;width: 27.4em; margin-bottom: .5em; } div#board{margin: 0 auto;width: 27.4em;height: 27.4em;} div#board div{ float: left;border: solid 0.2em #ce5c00;cursor: pointer; width: 8.6em;height: 8.6em; line-height: 8.6em; } div#board div#square0,div#board div#square1, div#board div#square3,div#board div#square4, div#board div#square6,div#board div#square7{border-left: 0; border-top: 0;} div#board div#square2,div#board div#square5, div#board div#square8{border-right: 0; border-top: 0; border-left: 0;} div#board div#square6,div#board div#square7, div#board div#square8{border-bottom: 0;} div#board div.player1, div#info div#board_info div.player1{background: url("player1.gif") no-repeat center center; color: #fff;} div#board div.player2, div#info div#board_info div.player2{background: url("player2.gif") no-repeat center center;} div#board div.win{background-color: #ffff99;} div#board div.clear{background: none;} div#info{margin: 0 auto; width: 46em;} div#info div#board_console{ float: left; width: 26.5em; border: dashed .2em #cc0000; padding: .4em;line-height: 2em; } div#info div#board_console span{ color: #fff;font-weight: 700;padding: .1em; } div#info div#board_console span.player1{background-color: #204a87;} div#info div#board_console span.player2{background-color: #4e9a06;} div#info div#board_console span.draw{background-color: #cc0000;} div#info div#board_control, div#info div#board_info{ float: right; border: solid .5em #ce5C00; line-height: 1.8em; padding: .2em;width: 16.5em; } div#info div#board_control input{ background-color: #ffffd4; border: solid .1em #e9b96e; font-size: 1em; font-weight: 700; padding: .4em; } div#info div#board_control label.player{font-weight: 700; font-size: 2em;float: right;} div#info div#board_control label.one{color: #204a87;} div#info div#board_control label.two{color: #4e9a06;} div#info div#board_control label.draw{color: #cc0000;} div#info div#board_control span{float: left;} div#info div#board_info{margin-top: .4em; clear: right; height: 8em;color: #000;} div#info div#board_info div{height: 5.8em;background-position: center top;}
/** * Class Estática * Gerir Eventos */ Events = function(){} /** * Adicionar Evento * * Adaptada do seguinte url: * http://www.quirksmode.org/blog/archives/2005/10/_and_the_winner_1.html * * @param Object * @param Object * @param Object */ Events.AddEvent = function(obj, type, fn){ if(!obj) return; this.RemoveEvent(obj, type, fn); if (obj.addEventListener) { obj.addEventListener(type, fn, false); } else { if (obj.attachEvent) { obj["e" + type + fn] = fn; obj[type + fn] = function(){ obj["e" + type + fn](window.event); } obj.attachEvent("on" + type, obj[type + fn]); } } } /** * Remover Evento * * Adaptada do seguinte url: * http://www.quirksmode.org/blog/archives/2005/10/_and_the_winner_1.html * * @param Object * @param Object * @param Object */ Events.RemoveEvent = function(obj, type, fn){ if (obj.removeEventListener) { try{obj.removeEventListener(type, fn, false);}catch(e){} } else{ if (obj.detachEvent) { obj.detachEvent("on" + type, fn); obj[type + fn] = null; obj["e" + type + fn] = null; } } }
/** * Class estática * * Class de suporte à interacção com o DOM * * @author: pedrocorreia.net */ Dom = function(){} /** * Obter objecto Html * * @param String Id Objecto */ $=function(id){return document.getElementById(id);} /** * Obter, atribuir ou acrescentar a Class Css * a um objecto Html * * @param Object Objecto Html * @param Optional String Nome da Class * @param Optional Int Acrescentar Class? */ $class=function(obj /**, css_class**/ /**, append*/){ if(arguments[1] && arguments[2]){$(obj).className+=" "+arguments[1];} else if(arguments[1]){$(obj).className=arguments[1];} else{return $(obj).className;} }
/** * Class estática * * Class que contém as mensagens a serem * mostradas ao utilizador * * @author: pedrocorreia.net */ Messages = function(){} /** * Mensagem a ser exibidida se depois do fim do jogo * tentarmos clickar numa casa * * @param String Nome do Jogador * @param Int Quem ganhou o jogo */ Messages.AlreadyFinished = function (name, number){ var str=""; switch (number){ case 0: str="Houve um empate."; break; default: str=name+" "+number+", foi o Vencedor!"; break; } return "O jogo já terminou. "+str+"\n\nPressione o botão \"Novo Jogo\""; } /** * Mensagem de aviso que a casa já foi selecionada por um jogador */ Messages.SquareFilled = function(){ return "Esta Casa já se encontra preenchida"; } /** * Mensagem com informações de quem ganhou o jogo */ Messages.Winner = function(clss, name, number, path){ return "<span class='"+clss+"'>Vitória para "+name+": "+number+"<span> | Casas: "+path; } /** * Mensagem de empate */ Messages.Draw = function(clss){ return "<span class='"+clss+"'>O jogo terminou empatado!</span>" } /** * Mensagem a ser adicionada à consola. Descreve a jogada. * * @param String Nome do Jogador * @param Int Id do Jogador * @param Int Casa selecionada */ Messages.TraceMove = function(name, number, square){ return "<b>"+name+":</b> "+number+" | <b>Casa:</b> "+square; }
/** * Esta class tem como objectivo implementar o Jogo do Galo. * * O algoritmo de suporte à resolução do jogo, é baseado num * esquema brute-force, ou seja, são testadas todas as hipóteses possiveis. * * @author: pedrocorreia.net */ JogoGalo = function (){ //necessário para permitir os métodos privados //acederem aos métodos não-privados da Class var self=this; //guardar todas as jogadas var _board_moves; //possiveis combinações de jogadas vencedoras var _win_moves = { 1: {pos1: 0, pos2: 1, pos3: 2}, 2: {pos1: 3, pos2: 4, pos3: 5}, 3: {pos1: 6, pos2: 7, pos3: 8}, 4: {pos1: 2, pos2: 4, pos3: 6}, 5: {pos1: 0, pos2: 3, pos3: 6}, 6: {pos1: 1, pos2: 4, pos3: 7}, 7: {pos1: 2, pos2: 5, pos3: 8}, 8: {pos1: 0, pos2: 4, pos3: 8} } //definições do jogo var _settings = { num_squares: 9, //numero de casas min_plays_check: 5, //numero de casas apartir das quais se verifica o jogo player: "Jogador", //nome genérico dos jogadores prefix_square: "square", //prefixo do nome da casa class_player1: "player1", //class css do jogador 1 class_player2: "player2",//class css do jogador 1 lbl_points_player1: "lbl_player1", //label com a pontuação do jogador 1 lbl_points_player2: "lbl_player2", //label com a pontuação do jogador 2 lbl_points_draw: "lbl_draw", //label com o número de empates class_winning: "win", //class css das casas com a jogada vencedora class_draw: "draw", //class css da mensagem de empate console: "board_console" //para onde será escrito as informações } //estatisticas do jogo, importantes para tomar decisões var _stats = { current_player: 1, //jogador corrente num_plays: 1, //número de jogadadas totais winning_player: -1, //jogador vencedor points_player1: 0, //pontuação jogador 1 points_player2: 0, //pontuação jogador 2 points_draw: 0 //número de empates } /** * Método privado * Passar a vez ao próximo jogador */ var _NextPlayer = function(){ _stats.current_player=(_stats.current_player==1)?2:1; _stats.num_plays++; $class("next_player",_CurPlayerClass()); } /** * Método privado * Obter a class css do jogador corrente */ var _CurPlayerClass = function(){ return (_stats.current_player==1)?_settings.class_player1:_settings.class_player2; } /** * Método privado * Adicionar eventos às casas, para que exista uma * interacção com o click do rato e com o botão "Novo Jogo" e "Reset" */ var _EventHandlers = function(){ var fn; for (var i=0;i<_settings.num_squares;i++){ fn=(function(i){return function(){ _Select (i);}})(i); Events.AddEvent($(_settings.prefix_square+i),"click",fn); } Events.AddEvent($("bt_new_game"),"click",self.NewGame); Events.AddEvent($("bt_reset"),"click",_Reset); } /** * Método privado * Marcar casa selecionada pelo utilizador, verificando se a mesma já se * encontra ou não preenchida. * * Verificar se a jogada presente representa um caminho vencedor, caso não * seja, passar a vez ao próximo jogador * * @param Int Número da Casa */ var _Select = function(i){ //verificar se o jogo já terminou, havendo ou não um vencedor if(_stats.winning_player>-1 || _stats.num_plays>_settings.num_squares){ alert(Messages.AlreadyFinished(_settings.player,_stats.winning_player)); return; } if(_IsSquareEmpty(i)){ //verificar se a casa está vazia $class(_settings.prefix_square+i,_CurPlayerClass()); _MarkSquare(i,_stats.current_player); _TraceValidMove(i); _CheckBoard(_stats.current_player); _NextPlayer(); } else{ alert(Messages.SquareFilled()); //a casa já está preenchida } } /** * Método privado * Verificar se a casa se encontra preenchida * * @param Int Número da Casa * @return Bool */ var _IsSquareEmpty = function(pos){return (_board_moves[pos]==0);} /** * Método privado * Marcar casa como preenchida * * @param Int Número da Casa * @param Int Número do Jogador */ var _MarkSquare = function(pos, player){_board_moves[pos]=player;} /** * Método privado * Escrever informação para a consola * * @param Int Número da Casa */ var _TraceValidMove = function(square){ var str=Messages.TraceMove(_settings.player,_stats.current_player,square+1); $(_settings.console).innerHTML+=str+"<br/>"; } /** * Método privado * Verificar se na presente jogada existe * algum caminho vitorioso * * @param Int Número do Jogador */ var _CheckBoard = function(player){ //se o número de jogadas for inferior ao minimo, não verificar soluções if(_stats.num_plays<_settings.min_plays_check){return;} var count=0; var square=""; for (var move in _win_moves){ //percorrer todas as combinações vencedoras for (var i=1;i<=3;i++){ //percorrer as 3 coordenadas square=_board_moves[_win_moves[move]["pos"+i]]; if(square==player){count++;} //verificar se estão selecionadas no mesmo jogador } //se o jogador tiver selecionadas as 3 coordenadas correctamente, então ganhou o jogo if (count==3){ var path=""; for (var i=1;i<=3;i++){ square=_settings.prefix_square+_win_moves[move]["pos"+i]; $class(square,_settings.class_winning,1);//marcar as casas vencedoras path+=(_win_moves[move]["pos"+i]+1)+";"; //caminho selecionado } _stats.winning_player = player; $(_settings.console).innerHTML+=Messages.Winner(_CurPlayerClass(),_settings.player,player,path); _stats["points_player"+player]++; //incrementar contador vitórias $(_settings["lbl_points_player"+player]).innerHTML=_stats["points_player"+player]; //escrever pontuação return; } count=0; } //verificar se o jogo terminou empatado if(_stats.num_plays==_settings.num_squares){ _stats.points_draw++; //incrementar contador empates _stats.winning_player = 0; //marcar jogo como empate $(_settings.lbl_points_draw).innerHTML=_stats.points_draw; $(_settings.console).innerHTML+=Messages.Draw(_settings.class_draw); } } /** * Método privado * Reinicializar Estatisticas */ var _Reset = function(){ _stats.points_player1=0; _stats.points_player2=0; _stats.points_draw=0; $(_settings.lbl_points_player1).innerHTML=_stats.points_player1; $(_settings.lbl_points_player2).innerHTML=_stats.points_player2; $(_settings.lbl_points_draw).innerHTML=_stats.points_draw; self.NewGame(); } /** * Iniciar um novo jogo */ this.NewGame = function(){ for (var i=0;i<_settings.num_squares;i++){ $class(_settings.prefix_square+i,"clear"); $(_settings.prefix_square+i).innerHTML=(i+1); } _stats.num_plays=1; _stats.current_player=1; _stats.winning_player=-1; _board_moves = new Array(0,0,0,0,0,0,0,0,0); $(_settings.console).innerHTML=""; $class("next_player",_settings.class_player1); } //inicializar EventHandlers _EventHandlers(); }
/** * Função de Inicialização * * @author pedrocorreia.net */ Init = function(){ var jogo_galo=new JogoGalo(); jogo_galo.NewGame(); } Events.AddEvent(window,"load",Init);
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml" > <head> <title>Jogo do Galo</title> <link rel="stylesheet" href="style.css" /> <script type="text/javascript" src="Events.js"></script> <script type="text/javascript" src="Dom.js"></script> <script type="text/javascript" src="Messages.js"></script> <script type="text/javascript" src="JogoGalo.js"></script> <script type="text/javascript" src="Init.js"></script> </head> <body> <div id="board_title">Jogo do Galo</div> <div id="board"> <div id="square0"></div> <div id="square1"></div> <div id="square2"></div> <div id="square3"></div> <div id="square4"></div> <div id="square5"></div> <div id="square6"></div> <div id="square7"></div> <div id="square8"></div> </div> <div id="info"> <div id="board_console"></div> <div id="board_control"> <span>Pontuação Jogador 1:</span> <label id="lbl_player1" class="player one">0</label> <br /> <span>Pontuação Jogador 2:</span> <label id="lbl_player2" class="player two">0</label> <br /> <span>Empates:</span> <label id="lbl_draw" class="player draw">0</label> <br /><br /> <input type="button" value="Novo Jogo" id="bt_new_game" /> <input type="button" value="Reset" id="bt_reset" /> </div> <div id="board_info">Próxima Jogada<div id="next_player"></div></div> </div> </body> </html>