//////////////////// // Tres en Raya // //////////////////// PRESENCE.GAME.TER = (function(P,$,undefined){ //Gamecore var CORE = P.GAME //Games variables var game; //Game and player are objects defined in the gamecore. var name = "Tic Tac Toe" var player = null; var currentPlayer = null; var playing=true; //We must define our ACTION object. //The information exchanged between players is performed through the exchange of action type objects. //We can define our own types of actions, with different fields //function action(player,square) { //this.player = player; //this.square = square; //this.type = "general"; //} function action(player,square) { this.player = player; this.square = square; this.type = "general"; } //Html Divs var divID = null; var containerDivId = 'tresEnRayaContainerDivID'; var messageDivId = 'tresEnRayaMessageDivID'; //Boardgame variables var board = []; var boardDimension = null; var squareDimension = null; var middleSquareDimension = null; //////////////// // STARTER // //////////////// //The core will invoke this method automatically to start the game. //*myPlayer = myself //*myGame = Game object (is the same for all players) //*myDivID = Div to render the game var init = function(myPlayer,myGame,myDivID){ player = myPlayer; game = myGame; divID = myDivID; //Setting options game.options = settingOptions(myGame.options); //Init Graphics drawBoard(); //Init Logic settingBoard(); //Init Events setBoardEvents(); //Init game variables currentPlayer = game.players[0]; playing=true; //Start Play! if(player.id==currentPlayer.id){ showMessage("You start!") } else { showMessage(currentPlayer.name + " starts!") } }; //Set defaults for unspecified options var settingOptions = function(myOptions){ if (!('theme' in myOptions)){ myOptions['theme'] = "Modern" } if (!('rounds' in myOptions)){ myOptions['rounds'] = "1" } //Apply default options for non specified opts. return myOptions; }; //////////////////////////////// // CORE CONFIG CALLBACKS // //////////////////////////////// //Optional methods that can be invoked by the core //The Core provides basic validation //We can include our own validation conditions here! //The core will invoke this method automatically in the validation process var validateParams = function(myPlayer,myGame,myDivID){ if(myGame.players.length != 2){ return new CORE.createValidationResult(false,"This game needs two players"); } return new CORE.createValidationResult(true,"Ok"); } //MinimumRequirements to execute this game var minimumRequirements = function(){ var requirements = new Array(); return requirements; } ///////////////////////////////// // GAMECORE CALLS & CALLBACKS // * To send our actions to other players we will use the << sendAction >> method. ///////////////////////////////// * When some player send us a action, the core will invoke the << onActionReceived >> method. var sendAction = function(action){ CORE.sendAction(game,action) return; } var onActionReceived = function(action){ processAction(action); return; } ///////////////////////// // ACTION MANAGEMENT // * These methods are not mandatory, but are highly recommended. //////////////////////// //Processes an action of any player var processAction = function(action){ if(playing==false){ return } //Check if the action is legal. if(!checkAction(action)){ showMessage("Ilegal action") return false } if(player.id==action.player.id){ //Notify my actions! sendAction(action) } //Update logic updateLogic(action) //Update Graphics updateInterface(action) //Check for winner //If there is a winner, checkWinner() will return the winner's name. //If not, it will return "finish" if the game is over without a winner, or null if the game is not over. var winner = checkWinner() if(winner!=null){ processWinner(winner) finishGame() return } //We continue with the next turn if the game is not over. nextTurn(); } //Check if the action is legal. var checkAction = function(action){ if(currentPlayer.id!=action.player.id){ //The player has made an action out of his turn. return false; } if(board[action.square][2]!=0){ //Square is already occupied by another figure. return false; } return true; } //If we have a turn-based game we probably need a nextTurn method. //This is an example var nextTurn = function(){ var playersQuantity = game.players.length; var indexActualPlayer = game.players.indexOf(currentPlayer); if(indexActualPlayer==(playersQuantity-1)){ currentPlayer=game.players[0]; } else { currentPlayer=game.players[indexActualPlayer+1]; } if(player.id==currentPlayer.id){ showMessage("Is your turn!") } else { showMessage(currentPlayer.name + " turn") } } /////////////////////// // TER GAME METHODS // /////////////////////// var drawBoard = function(){ var containerDiv = document.createElement('div'); containerDiv.setAttribute('id', containerDivId); containerDiv.setAttribute('class', 'tresEnRayaContainerDivClass'); $("#" + divID).append(containerDiv); var messageDiv = document.createElement('div'); messageDiv.setAttribute('id', messageDivId); $(messageDiv).addClass('tresEnRayaMessageDivClass') $(messageDiv).addClass('tresEnRayaMessageTheme' + game.options['theme']) $("#" + divID).append(messageDiv); var p = document.createElement('p'); p.setAttribute('id', messageDivId + "p"); $(p).addClass('tresEnRayaMessagePTheme' + game.options['theme']) $("#" + messageDivId).append(p); var messageDivHeight = 12; //Adjust dimensions var parentWidth = $("#" + divID).width(); var parentHeight = $("#" + divID).height(); var maxDimension = 300; var minDimension = 100; var dimension = Math.max(Math.min(parentWidth,parentHeight,maxDimension),minDimension) boardDimension = dimension - messageDivHeight; $("#" + containerDivId).height(boardDimension) $("#" + containerDivId).width(boardDimension); $("#" + messageDivId).width(boardDimension); //Apply Theme $("#" + containerDivId).addClass('tresEnRayaContainerTheme' + game.options['theme']) }; var settingBoard = function(){ squareDimension = boardDimension/3; middleSquareDimension = squareDimension/2; //board[squareID] = [x,y,ElementInSquare {0=none,1=circle,2=aspa}] board[0] = [middleSquareDimension,middleSquareDimension,0] board[1] = [middleSquareDimension+squareDimension,middleSquareDimension,0] board[2] = [boardDimension-middleSquareDimension,middleSquareDimension,0] board[3] = [middleSquareDimension,middleSquareDimension+squareDimension,0] board[4] = [middleSquareDimension+squareDimension,middleSquareDimension+squareDimension,0] board[5] = [boardDimension-middleSquareDimension,middleSquareDimension+squareDimension,0] board[6] = [middleSquareDimension,boardDimension-middleSquareDimension,0] board[7] = [middleSquareDimension+squareDimension,boardDimension-middleSquareDimension,0] board[8] = [boardDimension-middleSquareDimension,boardDimension-middleSquareDimension,0] }; var setBoardEvents = function(){ $("#" + containerDivId).click(function (event) { var offsetX = event.pageX - $("#" + containerDivId).offset().left var offsetY = event.pageY - $("#" + containerDivId).offset().top if($(event.target).is('img')){ return; } if(currentPlayer.id!=player.id){ return; } square = getSquare(offsetX,offsetY) var actionNew = new action(currentPlayer,square); processAction(actionNew) }); }; var getSquare = function(x,y){ for(var i=0; i<board.length; i++){ if((Math.abs(x-board[i][0])<middleSquareDimension)&&(Math.abs(y-board[i][1])<middleSquareDimension)){ return i; } } return 0; } var showMessage = function(msg){ $("#" + messageDivId + "p").html(msg) } var finishGame = function(){ playing = false; } var updateLogic = function(action){ if(action.player.id == game.players[0].id){ var r = 1; } else { var r = 2; } board[action.square][2]=r; } var updateInterface = function(action){ var img = document.createElement('img'); if(action.player.id==game.players[0].id){ var figure = "circle"; } else { var figure = "aspa"; } $(img).attr("src","/assets/games/ter/" + game.options['theme'].toLowerCase() + "_" + figure + ".png"); $("#" + containerDivId).append(img); $(img).addClass('tresEnRayaImgTheme' + game.options['theme']) var figureSizePercent = 0.8; var xdisplacement = -squareDimension*figureSizePercent/2*0.7; var ydisplacement = 13; $(img).width(squareDimension*figureSizePercent) $(img).height(squareDimension*figureSizePercent) $(img).css("top",board[action.square][1]+ydisplacement) $(img).css("left",board[action.square][0]+xdisplacement) return; } //Return winner's name if exists and null if don't exits. //Return "finish" when the game is blocked. var checkWinner = function(){ //Check for finish game without winner. var finish=true; for(var i=0; i<board.length; i++){ if(board[i][2]==0){ finish = false; break; } } if(finish){ return "finish"; } //Check winner //Check if exists three squares with the same symbol consecutively //Check horizontal if((board[0][2]==board[1][2])&&(board[1][2]==board[2][2])&&(board[2][2]!=0)){ return game.players[board[0][2]-1]; } if((board[3][2]==board[4][2])&&(board[4][2]==board[5][2])&&(board[5][2]!=0)){ return game.players[board[3][2]-1]; } if((board[6][2]==board[7][2])&&(board[7][2]==board[8][2])&&(board[8][2]!=0)){ return game.players[board[6][2]-1]; } //Check vertical if((board[0][2]==board[3][2])&&(board[3][2]==board[6][2])&&(board[6][2]!=0)){ return game.players[board[0][2]-1]; } if((board[1][2]==board[4][2])&&(board[4][2]==board[7][2])&&(board[7][2]!=0)){ return game.players[board[1][2]-1]; } if((board[2][2]==board[5][2])&&(board[5][2]==board[8][2])&&(board[8][2]!=0)){ return game.players[board[2][2]-1]; } //Check diagonals if((board[0][2]==board[4][2])&&(board[4][2]==board[8][2])&&(board[8][2]!=0)){ return game.players[board[0][2]-1]; } if((board[6][2]==board[4][2])&&(board[4][2]==board[2][2])&&(board[2][2]!=0)){ return game.players[board[6][2]-1]; } return null; } var processWinner = function(winner){ if(winner!="finish"){ if(player.id==winner.id){ showMessage("You have won the game") } else { showMessage(winner.name + " has won the game") } } else { showMessage("Finished game"); } } //Getters var getName = function(){ return name } var getGame = function(){ return game; } var getBoard = function(){ return board; } var getMyplayer = function(){ return player; } var getCurrentPlayer = function(){ return currentPlayer; } return { init: init, getName: getName, validateParams: validateParams, minimumRequirements: minimumRequirements, onActionReceived: onActionReceived }; }) (PRESENCE, jQuery);