<commit_before>var underscore = angular.module('underscore', []);

underscore.factory('_', function() {
    return window._; // assumes underscore has already been loaded on the page
});

var GameController = (function(){
    function GameController($scope, $timeout, $window, _, $interval) {
        var _this = this;

        this.$scope = $scope;
        this.$timeout = $timeout;
        this.$window = $window;
        this.$interval = $interval
        this.connection = null;
        this._ = _;
        this.game = {};

        this.$scope.players = [];
        this.$scope.throws = 0;

        this.$scope.url = 'http://' + $window.location.hostname + ':8042/controller';
        this.$scope.time = 30;
        this.$scope.timerStatus = 'Remain';
        this.$scope.timerVisible = false;
        this.$scope.idleVisible = true;

        this.$scope.totalScore = function (){
            var score = 0;
            _this.$scope.players.forEach(function(player){
                if (player.score){
                    score += player.score;
                }
            });
            return score;
        }

        $window.addEventListener("load", function () {
            var connection = new WebSocket("ws://" + $window.location.hostname + ":8043");

            connection.onopen = _this.onopen.bind(_this);
            connection.onclose = _this.onclose.bind(_this);
            connection.onerror = _this.onerror.bind(_this);
            connection.onmessage = _this.onmessage.bind(_this);

            _this.connection = connection;

            _this.game = new Game(_this.$window);

            // fuuuuuuuuujky fujky
            $('#foo').click(function (e){
                _this.game.throw(e);
            });
        });

        function updateTime() {
            _this.$scope.time -= 1;
            _this.$scope.time = _this.$scope.time < 0 ? 30 : _this.$scope.time;
        }

        this.stopTime = $interval(updateTime, 1000);

        // listen on DOM destroy (removal) event, and cancel the next UI update
        // to prevent updating time after the DOM element was removed.
//        this.on('$destroy', function() {
//            $interval.cancel(_this.stopTime);
//        });

        this.messageTypeToFunction = {
            CONTROLLER_NEW: this.onNewController.bind(_this),
            CONTROLLER_CONNECTION_CLOSE: this.onControllerClose.bind(_this),
            CONTROLLER_THROW: this.onControllerThrow.bind(_this)
        };
    }

    GameController.prototype.onopen = function(){
        this.connection.send('I_AM_DISPLAY');
    };

    GameController.prototype.onclose = function () {
        console.log("Connection closed");
    };

    GameController.prototype.onerror = function () {
        console.error("Connection error");
    };

    GameController.prototype.onmessage = function (event) {
        var _this = this;
        this.$timeout(function() {
            if(!event.data)
                return;
            var data = JSON.parse(event.data);
            console.log('onmessage |> '+data);

            if(!data || !data.type || !_this.messageTypeToFunction[data.type])
                return;

            _this.messageTypeToFunction[data.type](data);
        });
    };

    GameController.prototype.resetGame = function () {
        this.$scope.players.forEach(function (player) {
            player.score = 0;
        });
    };

    GameController.prototype.onNewController = function (data) {
        var _this = this;
        console.log(data);
        this.$timeout(function () {
            _this.$scope.idleVisible = false;
            _this.$scope.timerVisible = true;
            _this.$scope.time = 30;

            data.score = 0;
            _this.$scope.players.push(data);
            _this.resetGame();
        })
    };

    GameController.prototype.onControllerClose = function (data) {
        var _this = this;
        console.log(data);

        this.$timeout(function () {
            _this.$scope.players = _.without(_this.$scope.players, _.findWhere(_this.$scope.players, {key: data.key}));

            if (_this.$scope.players.length <= 0){
                _this.$scope.idleVisible = true;
                _this.$scope.timerVisible = false;
            }
        })
    };

    GameController.prototype.onControllerThrow = function(data) {
        var _this = this;
        console.log(data);

        var player = _.findWhere(_this.$scope.players, {key: data.key});
        if(!player)
            return;

        this.$timeout(function () {
            _this.$scope.throws++;
            player.score += _this.game.throw(data);
        })
    };

    return GameController;
})();

var gameModule = angular.module('Foo', ['underscore', 'angular-gestures']);

gameModule.controller('GameController', ['$scope', '$timeout', '$window', '_', '$interval', GameController]);

var ControllerController = (function () {
    function ControllerController($scope, $timeout, $window, _) {
        var _this = this;

        this.$scope = $scope;
        this.$timeout = $timeout;
        this.$window = $window;
        this.connection = null;

        $window.addEventListener("load", function () {
            var nickname = 'Foo';//prompt("Choose a nickname");
            if (!nickname)
                return;

            _this.connection = new WebSocket("ws://" + $window.location.hostname + ":8043");
            _this.connection.onopen = function () {
                _this.connection.send(JSON.stringify({
                    type: 'CONTROLLER_NEW',
                    nickname: nickname
                }));
            };
            _this.connection.onclose = function () {
                console.log("Connection closed");
            };
            _this.connection.onerror = function () {
                console.error("Connection error");
            };
            _this.connection.onmessage = function (event) {
                console.log(event.data);
            };

        });

        this.$scope.isConnectionOpened = function () {
            return _this.connection && _this.connection.readyState === WebSocket.OPEN
        };

        this.$scope.throw = function ($event){
            if(!_this.$scope.isConnectionOpened()) {
                console.log('connection not opend yet');
                return;
            }

            var endX = $event.gesture.srcEvent.pageX || $event.gesture.srcEvent.targetTouches[0].pageX;
                endY = $event.gesture.srcEvent.pageY || $event.gesture.srcEvent.targetTouches[0].pageY;

            console.log($event);

            var e = {
                normX: endX/_this.$window.innerWidth,
                normY: endY/_this.$window.innerHeight
            };

            e.normX = e.normX < 0 ? 0 : e.normX;
            e.normY = e.normY < 0 ? 0 : e.normY;

            e.normX = e.normX > 1 ? 1 : e.normX;
            e.normY = e.normY > 1 ? 1 : e.normY;

            e.normY = 0.7*e.normY + 0.3;

            var request = {
                type: 'CONTROLLER_THROW',
                event: e
            };

            //console.log(request);
            _this.connection.send(JSON.stringify(request));
        };
    };

    return ControllerController;
})();

gameModule.controller('ControllerController', ['$scope', '$timeout', '$window', '_', ControllerController]);<commit_msg>reset hry<commit_after>var underscore = angular.module('underscore', []);

underscore.factory('_', function() {
    return window._; // assumes underscore has already been loaded on the page
});

var GameController = (function(){
    function GameController($scope, $timeout, $window, _, $interval) {
        var _this = this;

        this.$scope = $scope;
        this.$timeout = $timeout;
        this.$window = $window;
        this.$interval = $interval
        this.connection = null;
        this._ = _;
        this.game = {};

        this.$scope.players = [];
        this.$scope.throws = 0;

        this.$scope.url = 'http://' + $window.location.hostname + ':8042/controller';
        this.$scope.time = 30;
        this.$scope.timerStatus = 'Remain';
        this.$scope.timerVisible = false;
        this.$scope.idleVisible = true;
        this.$scope.showtable = false;

        this.$scope.totalScore = function (){
            var score = 0;
            _this.$scope.players.forEach(function(player){
                if (player.score){
                    score += player.score;
                }
            });
            return score;
        }

        $window.addEventListener("load", function () {
            var connection = new WebSocket("ws://" + $window.location.hostname + ":8043");

            connection.onopen = _this.onopen.bind(_this);
            connection.onclose = _this.onclose.bind(_this);
            connection.onerror = _this.onerror.bind(_this);
            connection.onmessage = _this.onmessage.bind(_this);

            _this.connection = connection;

            _this.game = new Game(_this.$window);

            // fuuuuuuuuujky fujky
            $('#foo').click(function (e){
                _this.game.throw(e);
            });
        });

        function updateTime() {
            _this.$scope.time -= 1;

            if (_this.$scope.showtable && _this.$scope.time > 0){
                _this.$scope.timerVisible = true;
                return
            }

            if (_this.$scope.showtable && _this.$scope.time < 0){
                _this.$scope.idleVisible = false;
                _this.$scope.showtable = false;
                _this.$scope.time = 30;
                return
            }

            if(_this.$scope.idleVisible)
                return;

            if(_this.$scope.time < 0){
                _this.$scope.idleVisible = true;
                _this.$scope.timerVisible = true;
                _this.$scope.showtable = true;
                _this.$scope.time = 8;
                _this.resetGame();
                return;
            }

            _this.$scope.time = _this.$scope.time < 0 ? 30 : _this.$scope.time;
        }

        this.stopTime = $interval(updateTime, 1000);

        // listen on DOM destroy (removal) event, and cancel the next UI update
        // to prevent updating time after the DOM element was removed.
//        this.on('$destroy', function() {
//            $interval.cancel(_this.stopTime);
//        });

        this.messageTypeToFunction = {
            CONTROLLER_NEW: this.onNewController.bind(_this),
            CONTROLLER_CONNECTION_CLOSE: this.onControllerClose.bind(_this),
            CONTROLLER_THROW: this.onControllerThrow.bind(_this)
        };
    }

    GameController.prototype.onopen = function(){
        this.connection.send('I_AM_DISPLAY');
    };

    GameController.prototype.onclose = function () {
        console.log("Connection closed");
    };

    GameController.prototype.onerror = function () {
        console.error("Connection error");
    };

    GameController.prototype.onmessage = function (event) {
        var _this = this;
        this.$timeout(function() {
            if(!event.data)
                return;
            var data = JSON.parse(event.data);
            console.log('onmessage |> '+data);

            if(!data || !data.type || !_this.messageTypeToFunction[data.type])
                return;

            _this.messageTypeToFunction[data.type](data);
        });
    };

    GameController.prototype.resetGame = function () {
        this.$scope.players.forEach(function (player) {
            player.score = 0;
        });
    };

    GameController.prototype.onNewController = function (data) {
        var _this = this;
        console.log(data);
        this.$timeout(function () {
            _this.$scope.idleVisible = false;
            _this.$scope.timerVisible = true;
            _this.$scope.time = 30;

            data.score = 0;
            _this.$scope.players.push(data);
            _this.resetGame();
        })
    };

    GameController.prototype.onControllerClose = function (data) {
        var _this = this;
        console.log(data);

        this.$timeout(function () {
            _this.$scope.players = _.without(_this.$scope.players, _.findWhere(_this.$scope.players, {key: data.key}));

            if (_this.$scope.players.length <= 0){
                _this.$scope.idleVisible = true;
                _this.$scope.timerVisible = false;
            }
        })
    };

    GameController.prototype.onControllerThrow = function(data) {
        var _this = this;
        console.log(data);

        var player = _.findWhere(_this.$scope.players, {key: data.key});
        if(!player)
            return;

        this.$timeout(function () {
            _this.$scope.throws++;
            player.score += _this.game.throw(data);
        })
    };

    return GameController;
})();

var gameModule = angular.module('Foo', ['underscore', 'angular-gestures']);

gameModule.controller('GameController', ['$scope', '$timeout', '$window', '_', '$interval', GameController]);

var ControllerController = (function () {
    function ControllerController($scope, $timeout, $window, _) {
        var _this = this;

        this.$scope = $scope;
        this.$timeout = $timeout;
        this.$window = $window;
        this.connection = null;

        $window.addEventListener("load", function () {
            var nickname = 'Foo';//prompt("Choose a nickname");
            if (!nickname)
                return;

            _this.connection = new WebSocket("ws://" + $window.location.hostname + ":8043");
            _this.connection.onopen = function () {
                _this.connection.send(JSON.stringify({
                    type: 'CONTROLLER_NEW',
                    nickname: nickname
                }));
            };
            _this.connection.onclose = function () {
                console.log("Connection closed");
            };
            _this.connection.onerror = function () {
                console.error("Connection error");
            };
            _this.connection.onmessage = function (event) {
                console.log(event.data);
            };

        });

        this.$scope.isConnectionOpened = function () {
            return _this.connection && _this.connection.readyState === WebSocket.OPEN
        };

        this.$scope.throw = function ($event){
            if(!_this.$scope.isConnectionOpened()) {
                console.log('connection not opend yet');
                return;
            }

            var endX = $event.gesture.srcEvent.pageX || $event.gesture.srcEvent.targetTouches[0].pageX;
                endY = $event.gesture.srcEvent.pageY || $event.gesture.srcEvent.targetTouches[0].pageY;

            console.log($event);

            var e = {
                normX: endX/_this.$window.innerWidth,
                normY: endY/_this.$window.innerHeight
            };

            e.normX = e.normX < 0 ? 0 : e.normX;
            e.normY = e.normY < 0 ? 0 : e.normY;

            e.normX = e.normX > 1 ? 1 : e.normX;
            e.normY = e.normY > 1 ? 1 : e.normY;

            e.normY = 0.7*e.normY + 0.3;

            var request = {
                type: 'CONTROLLER_THROW',
                event: e
            };

            //console.log(request);
            _this.connection.send(JSON.stringify(request));
        };
    };

    return ControllerController;
})();

gameModule.controller('ControllerController', ['$scope', '$timeout', '$window', '_', ControllerController]);<|endoftext|>


<commit_before>
// http://html5doctor.com/finding-your-position-with-geolocation/

if (navigator.geolocation) {
  navigator.geolocation.getCurrentPosition(
    handlePosition,
    displayError,
    {
      enableHighAccuracy: false,
      timeout: 10000, // ms
      maximumAge: 10000 // ms
    }
  );
}
else {
  $( "#error-container" ).prepend( "
Selaimesi ei valitettavasti tue paikannusta.
" );
  console.log("navigator.geolocation not supported");
}

function handlePosition(position) {
  if (position.coords.accuracy > 500)
  {
    $( "#error-container" ).prepend( "
Tarkkaa sijaintiasi ei saatu selville, joten ao. lintuluettelo ei välttämättä ole aivan oikealta alueelta. Jos käytät tietokonetta, kokeile mielummin älypuhelimella jossa on GPS! (virhesäde " + position.coords.accuracy + " m)
" );
  }

  $.getJSON(
    "http://192.168.56.10/suomen-linnut/conversionwrapper.php?n=" + position.coords.latitude + "&e=" + position.coords.longitude,
    updatePage
  );
  console.log(position);
  console.log(position.coords);
}

function updatePage(data)
{
    // Coordinates is a JSON string
    console.log(data);

    $( "#main-container" ).load( "allspecies.php?grid=" + data.N + ":" + data.E );
}

function displayError(error) {
  var errors = {
    1: 'Olet kieltänyt paikannustiedon käytön. Salli se ja yritä uudelleen.',
    2: 'Sijaintia ei pystytty hakemaan. Siirry paikkaan, josta on esteettömämpi näkymä taivaalle.',
    3: 'Sijainnin hakeminen kesti liian kauan. Tarkista että puhelimesi GPS on päällä.'
  };
  console.log(errors[error.code]);
  $( "#error-container" ).prepend("
" + errors[error.code] + "
");
}

/*
    1: 'Permission denied',
    2: 'Position unavailable',
    3: 'Request timeout'
*/<commit_msg>Add event listener DOMContentLoaded<commit_after>
// http://html5doctor.com/finding-your-position-with-geolocation/

document.addEventListener("DOMContentLoaded", determineLocation);

function determineLocation(event)
{
  if (navigator.geolocation) {
    navigator.geolocation.getCurrentPosition(
      handlePosition,
      displayError,
      {
        enableHighAccuracy: false,
        timeout: 10000, // ms
        maximumAge: 10000 // ms
      }
    );
  }
  else {
    $( "#error-container" ).prepend( "
Selaimesi ei valitettavasti tue paikannusta.
" );
    console.log("navigator.geolocation not supported");
  }

  function handlePosition(position) {
    if (position.coords.accuracy > 500)
    {
      $( "#error-container" ).prepend( "
Tarkkaa sijaintiasi ei saatu selville, joten ao. lintuluettelo ei välttämättä ole aivan oikealta alueelta. Jos käytät tietokonetta, kokeile mielummin älypuhelimella jossa on GPS! (virhesäde " + position.coords.accuracy + " m)
" );
    }

    $.getJSON(
      "http://192.168.56.10/suomen-linnut/conversionwrapper.php?n=" + position.coords.latitude + "&e=" + position.coords.longitude,
      updatePage
    );
    console.log(position);
    console.log(position.coords);
  }

  function updatePage(data)
  {
      // Coordinates is a JSON string
      console.log(data);

      $( "#main-container" ).load( "allspecies.php?grid=" + data.N + ":" + data.E );
  }

  function displayError(error) {
    var errors = {
      1: 'Olet kieltänyt paikannustiedon käytön. Salli se ja yritä uudelleen.',
      2: 'Sijaintia ei pystytty hakemaan. Siirry paikkaan, josta on esteettömämpi näkymä taivaalle.',
      3: 'Sijainnin hakeminen kesti liian kauan. Tarkista että puhelimesi GPS on päällä.'
    };
    console.log(errors[error.code]);
    $( "#error-container" ).prepend("
" + errors[error.code] + "
");
  }

  /*
      1: 'Permission denied',
      2: 'Position unavailable',
      3: 'Request timeout'
  */
}<|endoftext|>


<commit_before>function Checkers() {
  this.board = [];
  this.redTeam = [];
  this.whiteTeam = [];
  // WHY DOESN'T THIS WORK WHEN this.currentSquare IS undefined?
  this.currentSquare = true;
  this.destinationSquare = undefined;
  this.team = undefined;
  this.selectedPiece = undefined;
  this.possibleSquareOne = false;
  this.possibleSquareTwo = false;
};

function Square(row, column, playable) {
  this.row = row;
  this.column = column;
  this.playable = playable;
  this.occupied = false;
  this.destination = false;
  this.isCurrentSquare = false;
};

function Piece(team, idNum, row, column) {
  this.team = team;
  this.id = idNum;
  this.row = row;
  this.column = column;
  this.king = false;
};

Piece.prototype.availableMoves = function() {
  // Highlights the moves available to the man
  // Determine direction the man is moving (team, basically)
  // Determine 'king' value
  // Determine if possible destinations are occupied

  // Loop that finds the squares?
  game.possibleSquareOne = game.board[this.row + 1][this.column - 1];
  game.possibleSquareTwo = game.board[this.row + 1][this.column + 1];
  if (game.possibleSquareOne.occupied === true) {
    game.possibleSquareOne = game.board[this.row + 2][this.column - 2];
  };
  if (game.possibleSquareTwo.occupied === true) {
    game.possibleSquareTwo = game.board[this.row + 2][this.column + 2];
  };

  game.possibleSquareOne.destination = true;
  game.possibleSquareTwo.destination = true;
  game.currentSquare.isCurrentSquare = true;

  drawBoard();
  drawPieces();
};

Piece.prototype.moveMan = function(destination) {
  // This will move the man
  // Changing coordinates
  // Capturing relevant pieces
  // Updating drawn position
  // Checking for possible chained moves
  // Occupy destination square
  // Unoccupy previous square
  game.board[this.row][this.column].occupied = false;
  this.row = destination.row;
  this.column = destination.column;
  game.board[this.row][this.column].occupied = true;
  // Update relevant values:
  // Last square > unoccupied
  // New square > occupied
  // Captured piece > out of play
  // Kinged man > kinged
};

// A simple looping function that puts eight arrays, representing rows, into
// the board array
function fillBoard() {
  for (var i = 0; i < 8; i++) {
    game.board[i] = fillRow(i);
  };
};

// This function is called by fillBoard() in order to fill each row that is
// created while filling the board array
function fillRow(rowNumber) {
  var row = [];
  // If the row is odd, reverse the black/white(playable/not) scheme
  if (isOdd(rowNumber)) {
    // Creates 8 squares in the row array, following the correct scheme of
    // playable/unplayable squares
    for (var i = 0; i < 8; i++) {
      if (isOdd(i)) {
        row[i] = new Square(rowNumber, i, false);
      } else {
        row[i] = new Square(rowNumber, i, true);
      }
    }
    // If the row is even, the normal scheme of black/white squares is followed
  } else {
    // Creates eight squares, following the correct scheme
    for (var i = 0; i < 8; i++) {
      if (isOdd(i)) {
        row[i] = new Square(rowNumber, i, true);
      } else {
        row[i] = new Square(rowNumber, i, false);
      }
    }
  }
  // Returns the row back to the loop in the fillBoard() function, which puts
  // this new row into its place in the board array
  return row;
};

// A simple function that returns true when a given number is odd, and false
// if it is not
function isOdd(num) {
  return (num % 2) == 1;
};

function drawBoard() {
  // Creates the div for the board to be drawn in
  $('body').empty();
  $('body').prepend('

');
  // Creates divs for each row array in the board array
  for (i = 0; i < game.board.length; i++) {
    $('#board').append('

');
    // Creates divs for each square object in the board array
    for (n = 0; n < game.board[i].length; n++) {
      // Checks if the square is a playable square and adds a class if it is
      if (game.board[i][n].playable) {
        $('#row' + i).append(
            '

'
            );
        if (game.board[i][n].destination) {
          $('#' + i + n).addClass('destination');
        };
        if (game.board[i][n].isCurrentSquare) {
          $('#' + i + n).addClass('currentSquare');
        };
      } else {
        $('#row' + i).append(
            '

'
            );
      };
    };
  };
};

// This will create all the pieces for both teams
// Currently it just creates one piece and gives it the desires values
// MAKE THIS MORE SUCCINCT
function createPieces() {
  var team = 'red';
  var row = 0;
  var column = 1;
  // Creates 12 pieces for the team
  for (i = 0; i < 12; i++) {
    game.redTeam[i] = new Piece(team, i, row, column);
  };
  for (i = 0; i < 3; i++) {
    game.redTeam[i*4].row = i;
    game.redTeam[i*4 + 1].row = i;
    game.redTeam[i*4 + 2].row = i;
    game.redTeam[i*4 + 3].row = i;
  };
  var n = 0;
  for (i = 0; i < 12; i++) {
    if (isOdd(game.redTeam[i].row)) {
      game.redTeam[i].column = n;
    } else {
      game.redTeam[i].column = n + 1;
    };
    if (n < 6) {
      n = n + 2;
    } else {
      n = 0;
    };
  };
};

// This clears all the pieces off the board and then redraws the pieces in
// their current positions.
function drawPieces() {
  $('.man').remove();
  for (i = 0; i < game.redTeam.length; i++) {
    game.board[game.redTeam[i].row][game.redTeam[i].column].occupied = true;
    $('#' + game.redTeam[i].row + game.redTeam[i].column).append(
        '

');
  };
  for (i = 0; i < game.whiteTeam.length; i++) {
    game.board[game.whiteTeam[i].row][game.whiteTeam[i].column].occupied = true;
    $('#' + game.whiteTeam[i].row + game.whiteTeam[i].column).append(
        '

');
  };
};

function getPiece(event, team) {
  if (team === 'red') {
    return game.redTeam[event.target.id];
  } else if (team === 'white') {
    return game.whiteTeam[event.target.id];
  };
};

function getSquare(thisSquare) {
  var row = thisSquare.charAt(0);
  var column = thisSquare.charAt(1);

  return game.board[row][column];
};

var game = new Checkers();

$(document).ready(function() {
  fillBoard();
  drawBoard();
  createPieces();
  drawPieces();
  $('body').on('click', '.man', function(event) {
    // Grab the ID of the piece clicked
    // Make sure the piece matches the player moving
    // Check for available moves
    // Highlight open squares
    // Move piece selected to square clicked
    // Remove captured men
    // Check for additional moves

    // Gets the Piece{} that corresponds with the .man element that has been
    // clicked by the player
    game.team = $(this).attr('class').split(' ')[0];
    game.selectedPiece = getPiece(event, game.team);

    game.selectedPiece.availableMoves();

    // Gets the Square{} that corresponds with the .playable element that has
    // been clicked by the player
    // MAYBE JUST GET THE COORDINATES OF THE SELECTED PIECE? IDK
    game.currentSquare = getSquare($(this).closest('.playable').attr('id'));
    game.currentSquare.isCurrentSquare = true;
  });

  $('body').on('click', '.currentSquare', function(event) {
    game.currentSquare.isCurrentSquare = false;

    game.possibleSquareOne.destination = false;
    game.possibleSquareTwo.destination = false;

    drawBoard();
    drawPieces();
  });

  $('body').on('click', '.destination', function(event) {
    game.destinationSquare = getSquare(event.currentTarget.id);

    game.selectedPiece.moveMan(game.destinationSquare);

    game.currentSquare.isCurrentSquare = false;

    game.possibleSquareOne.destination = false;
    game.possibleSquareTwo.destination = false;

    drawBoard();
    drawPieces();
  });
});

// To Do:
// Remove redundant variables/trackers
// Polish Piece.availableMoves
// Board drawing needs to properly update when moves are made
// - currentSquare bullcrap
// - possibleSquare
// Create Pieces function is too clunky
//
// P.S. Put something in your index.html, you dingus. It shouldn't be empty
<commit_msg>More to-do list action<commit_after>function Checkers() {
  this.board = [];
  this.redTeam = [];
  this.whiteTeam = [];
  // WHY DOESN'T THIS WORK WHEN this.currentSquare IS undefined?
  this.currentSquare = true;
  this.destinationSquare = undefined;
  this.team = undefined;
  this.selectedPiece = undefined;
  this.possibleSquareOne = false;
  this.possibleSquareTwo = false;
};

function Square(row, column, playable) {
  this.row = row;
  this.column = column;
  this.playable = playable;
  this.occupied = false;
  this.destination = false;
  this.isCurrentSquare = false;
};

function Piece(team, idNum, row, column) {
  this.team = team;
  this.id = idNum;
  this.row = row;
  this.column = column;
  this.king = false;
};

Piece.prototype.availableMoves = function() {
  // Highlights the moves available to the man
  // Determine direction the man is moving (team, basically)
  // Determine 'king' value
  // Determine if possible destinations are occupied

  // Loop that finds the squares?
  game.possibleSquareOne = game.board[this.row + 1][this.column - 1];
  game.possibleSquareTwo = game.board[this.row + 1][this.column + 1];
  if (game.possibleSquareOne.occupied === true) {
    game.possibleSquareOne = game.board[this.row + 2][this.column - 2];
  };
  if (game.possibleSquareTwo.occupied === true) {
    game.possibleSquareTwo = game.board[this.row + 2][this.column + 2];
  };

  game.possibleSquareOne.destination = true;
  game.possibleSquareTwo.destination = true;
  game.currentSquare.isCurrentSquare = true;
};

Piece.prototype.moveMan = function(destination) {
  // This will move the man
  // Changing coordinates
  // Capturing relevant pieces
  // Updating drawn position
  // Checking for possible chained moves
  // Occupy destination square
  // Unoccupy previous square
  game.board[this.row][this.column].occupied = false;
  this.row = destination.row;
  this.column = destination.column;
  game.board[this.row][this.column].occupied = true;
  // Update relevant values:
  // Last square > unoccupied
  // New square > occupied
  // Captured piece > out of play
  // Kinged man > kinged
};

// A simple looping function that puts eight arrays, representing rows, into
// the board array
function fillBoard() {
  for (var i = 0; i < 8; i++) {
    game.board[i] = fillRow(i);
  };
};

// This function is called by fillBoard() in order to fill each row that is
// created while filling the board array
function fillRow(rowNumber) {
  var row = [];
  // If the row is odd, reverse the black/white(playable/not) scheme
  if (isOdd(rowNumber)) {
    // Creates 8 squares in the row array, following the correct scheme of
    // playable/unplayable squares
    for (var i = 0; i < 8; i++) {
      if (isOdd(i)) {
        row[i] = new Square(rowNumber, i, false);
      } else {
        row[i] = new Square(rowNumber, i, true);
      }
    }
    // If the row is even, the normal scheme of black/white squares is followed
  } else {
    // Creates eight squares, following the correct scheme
    for (var i = 0; i < 8; i++) {
      if (isOdd(i)) {
        row[i] = new Square(rowNumber, i, true);
      } else {
        row[i] = new Square(rowNumber, i, false);
      }
    }
  }
  // Returns the row back to the loop in the fillBoard() function, which puts
  // this new row into its place in the board array
  return row;
};

// A simple function that returns true when a given number is odd, and false
// if it is not
function isOdd(num) {
  return (num % 2) == 1;
};

function drawBoard() {
  // Creates the div for the board to be drawn in
  $('body').empty();
  $('body').prepend('

');
  // Creates divs for each row array in the board array
  for (i = 0; i < game.board.length; i++) {
    $('#board').append('

');
    // Creates divs for each square object in the board array
    for (n = 0; n < game.board[i].length; n++) {
      // Checks if the square is a playable square and adds a class if it is
      if (game.board[i][n].playable) {
        $('#row' + i).append(
            '

'
            );
        if (game.board[i][n].destination) {
          $('#' + i + n).addClass('destination');
        };
        if (game.board[i][n].isCurrentSquare) {
          $('#' + i + n).addClass('currentSquare');
        };
      } else {
        $('#row' + i).append(
            '

'
            );
      };
    };
  };
};

// This will create all the pieces for both teams
// Currently it just creates one piece and gives it the desires values
// MAKE THIS MORE SUCCINCT
function createPieces() {
  var team = 'red';
  var row = 0;
  var column = 1;
  // Creates 12 pieces for the team
  for (i = 0; i < 12; i++) {
    game.redTeam[i] = new Piece(team, i, row, column);
  };
  for (i = 0; i < 3; i++) {
    game.redTeam[i*4].row = i;
    game.redTeam[i*4 + 1].row = i;
    game.redTeam[i*4 + 2].row = i;
    game.redTeam[i*4 + 3].row = i;
  };
  var n = 0;
  for (i = 0; i < 12; i++) {
    if (isOdd(game.redTeam[i].row)) {
      game.redTeam[i].column = n;
    } else {
      game.redTeam[i].column = n + 1;
    };
    if (n < 6) {
      n = n + 2;
    } else {
      n = 0;
    };
  };
};

// This clears all the pieces off the board and then redraws the pieces in
// their current positions.
function drawPieces() {
  $('.man').remove();
  for (i = 0; i < game.redTeam.length; i++) {
    game.board[game.redTeam[i].row][game.redTeam[i].column].occupied = true;
    $('#' + game.redTeam[i].row + game.redTeam[i].column).append(
        '

');
  };
  for (i = 0; i < game.whiteTeam.length; i++) {
    game.board[game.whiteTeam[i].row][game.whiteTeam[i].column].occupied = true;
    $('#' + game.whiteTeam[i].row + game.whiteTeam[i].column).append(
        '

');
  };
};

function getPiece(event, team) {
  if (team === 'red') {
    return game.redTeam[event.target.id];
  } else if (team === 'white') {
    return game.whiteTeam[event.target.id];
  };
};

function getSquare(thisSquare) {
  var row = thisSquare.charAt(0);
  var column = thisSquare.charAt(1);

  return game.board[row][column];
};

var game = new Checkers();

$(document).ready(function() {
  fillBoard();
  drawBoard();
  createPieces();
  drawPieces();
  $('body').on('click', '.man', function(event) {
    // Grab the ID of the piece clicked
    // Make sure the piece matches the player moving
    // Check for available moves
    // Highlight open squares
    // Move piece selected to square clicked
    // Remove captured men
    // Check for additional moves

    // Gets the Piece{} that corresponds with the .man element that has been
    // clicked by the player
    game.team = $(this).attr('class').split(' ')[0];
    game.selectedPiece = getPiece(event, game.team);

    game.selectedPiece.availableMoves();

    // Gets the Square{} that corresponds with the .playable element that has
    // been clicked by the player
    // MAYBE JUST GET THE COORDINATES OF THE SELECTED PIECE? IDK
    game.currentSquare = getSquare($(this).closest('.playable').attr('id'));
    game.currentSquare.isCurrentSquare = true;

    drawBoard();
    drawPieces();
  });

  $('body').on('click', '.currentSquare', function(event) {
    game.currentSquare.isCurrentSquare = false;

    game.possibleSquareOne.destination = false;
    game.possibleSquareTwo.destination = false;

    drawBoard();
    drawPieces();
  });

  $('body').on('click', '.destination', function(event) {
    game.destinationSquare = getSquare(event.currentTarget.id);

    game.selectedPiece.moveMan(game.destinationSquare);

    game.currentSquare.isCurrentSquare = false;

    game.possibleSquareOne.destination = false;
    game.possibleSquareTwo.destination = false;

    drawBoard();
    drawPieces();
  });
});

// To Do:
// Comment more of the code
//
// Remove redundant variables/trackers
//
// Polish Piece.availableMoves
// - needs to work for both teams
// - needs to not give errors when one possible destination isn't a real square
//
// Board drawing needs to properly update when moves are made
// - currentSquare bullcrap
// - possibleSquare
//
// Create Pieces function is too clunky and won't work well once it has to do
// two teams
//
// When a .man is clicked, game.currentSquare is set, but when a .man is clicked
// again, it is set to the new one WITHOUT resetting the old... fix that
//
// Make the .destination 'x' look nicer... probably with CSS, not JS, but I
// don't have a to do list in the CSS
//
// P.S. Put something in your index.html, you dingus. It shouldn't be empty
<|endoftext|>


<commit_before>(function() {

  // rAF
  window.requestAnimationFrame = function() {
    return window.requestAnimationFrame ||
      window.webkitRequestAnimationFrame ||
      window.mozRequestAnimationFrame ||
      window.msRequestAnimationFrame ||
      window.oRequestAnimationFrame ||
      function(f) {
        window.setTimeout(f,1e3/60);
      }
  }();

  // cAF
  window.cancelAnimationFrame = function() {
    return window.cancelAnimationFrame ||
      window.webkitCancelAnimationFrame ||
      window.mozCancelAnimationFrame ||
      window.msCancelAnimationFrame ||
      window.oCancelAnimationFrame ||
      function(f) {
        window.setTimeout(f,1e3/60);
      }
  }();

  var config = mit.config = {

  };

  var ui = mit.ui = {
    body: $('body'),
    score_board: $('#score_board'),
    start_screen: $('#start_screen'),
    start_game: $('#start_game'),
    tweet: $('#tweet'),
    fb: $('#fb'),
    fps_count: $('#fps_count')
  };

  /*
  Basic Canvas Inits
  */

  // Main Canvas

  var canvas = document.querySelector('#game_main');
  var ctx = canvas.getContext('2d');

  var W = canvas.width = ui.body.width();
  var H = canvas.height = ui.body.height();

  // Width x Height capped to 1000 x 500
  if (canvas.width > 1000) {
    W = canvas.width = 1000;
  }
  if (canvas.height > 500) {
    H = canvas.height = 500;
  }

  // Resizing Width/Height
  if (canvas.height < 500) {
    canvas.width = canvas.height * 1000/500;
  }
  if (canvas.width < 1000) {
    canvas.height = canvas.width * 500/1000;
  }

  // BG Canvas
  var bg_canvas = document.querySelector('#game_bg');
  var bg_ctx = bg_canvas.getContext('2d');

  bg_canvas.width = canvas.width;
  bg_canvas.height = canvas.height;

  var music = document.getElementById("start");
  /*
    Game Start Screen and Lolz
  */
  mit.game_started = 0;
  mit.game_over = 0;
  mit.start_btn_clicked = 0;

  ui.start_screen.css('width', canvas.width + 'px');
  ui.start_screen.css('height', canvas.height + 'px');

  // Start Button
  var startGame = function() {
    // Play the awesome music! Really awesome
    music.volume = 0.2;
    music.play();
    flap.pause();

    // Hide the Start Screen
    ui.start_screen.fadeOut();

    // Start btn has been clicked
    // Game hasnt started. Game will
    // start on flight.
    mit.start_btn_clicked = 1;
    mit.game_started = 0;

    mit.Backgrounds.common_bg_speed = 1;
    mit.Backgrounds.ground_bg_move_speed = 9;

    // Reset all accelerations and make
    // pappu stationary
    mit.Pappu.drawStatic(ctx);
    mit.ax = 0; mit.ay = 0;
    mit.vx = 0; mit.vy = 0;

    // reset score
    mit.score = 0;

    // Nuke all forks
    mit.ForkUtils.forks = [];
    // Nuke all branches
    mit.BranchUtils.branches = [];
    // Nuke all collectibles
    mit.CollectibleUtils.collecs = [];
  };

  ui.start_game.on('mousedown', function() {
    startGame();

    return false;
  });

  // startGame();

  // Share links
  var tweet = document.getElementById("tweet");
  tweet.href='http://twitter.com/share?url=http://khele.in/pappu-pakia/&text=I am playing Pappu Pakia, a cute HTML5 game on khele.in!&count=horiztonal&via=_rishabhp&related=solitarydesigns';

  var facebook = document.getElementById("fb");
  facebook.href='http://facebook.com/sharer.php?s=100&p[url]=http://khele.in/pappu-pakia/&p[title]=I am playing Pappu Pakia, a cute HTML5 game on khele.in!';

  // Score Board
  mit.score = 0;

  ui.score_board.css('width', canvas.width + 'px');
  ui.score_board.css('height', canvas.height + 'px');

  // Set Canvas Width/Height in Config
  mit.config.canvas_width = mit.W = W;
  mit.config.canvas_height = mit.H = H;

  // Gravity
  mit.gravity = 0.7;

  // Velocity x,y
  mit.vx = 0;
  mit.vy = 0;

  // Velocity cap on either sides of the
  // number system.
  //
  // You can console.log velocities in drawing methods
  // and from there decide what to set as the cap.
  mit.v_cap = 7.5;

  // Accelaration x,y
  mit.ax = 0;
  mit.ay = 0;

  // Flying up ?
  mit.flying_up = 0;

  mit.ascend = function() {
    if (!mit.start_btn_clicked)
      return;

    if (!mit.game_started)
      mit.game_started = 1;

    mit.ay = -1.5;
    mit.flying_up = 1;
  };

  mit.descend = function() {
    if (!mit.start_btn_clicked)
      return;

    mit.ay = 0;
    mit.flying_up = 0;
  };

  // Game play on mouse clicks too!
  window.addEventListener('mousedown', function(e) {
    mit.ascend();
  }, false);

  window.addEventListener('mouseup', function(e) {
    mit.descend();
  }, false);

  // Game play on touch too!
  window.addEventListener('touchstart', function(e) {
    mit.ascend();
  }, false);

  window.addEventListener('touchend', function(e) {
    mit.descend();
  }, false);

  // ... and keyzz...
  window.addEventListener('keydown', function(e) {

    if (e.keyCode === 38) {
      mit.ascend();
    }

    e.preventDefault();

  }, false);

  window.addEventListener('keyup', function(e) {

    mit.descend();
    e.preventDefault();
  }, false);

  /*
    Performing some game over tasks
  */
  mit.gameOver = function() {
    ui.start_screen.fadeIn();
    ui.start_game.html('re-start');
    ui.tweet.html('tweet score');
    ui.fb.html('post on fb');

    // Stop background
    mit.Backgrounds.common_bg_speed = 0;
    mit.Backgrounds.ground_bg_move_speed = 0;
    mit.Backgrounds.fps = 0;

    mit.game_over = 1;
    mit.start_btn_clicked = 0;

    // Pappu if invincible will be no morez
    mit.Pappu.invincible = 0;

    // Nuke all clones
    mit.Pappu.clones.length = 0;

    // Share
    var tweet = document.getElementById("tweet");
    tweet.href='http://twitter.com/share?url=http://khele.in/pappu-pakia/&text=I just scored ' +Math.floor(mit.score)+ ' points in Pappu Pakia!&count=horiztonal&via=_rishabhp&related=solitarydesigns';

    var facebook = document.getElementById("fb");
    facebook.href='http://facebook.com/sharer.php?s=100&p[url]=http://khele.in/pappu-pakia/&p[title]=I just scored ' +Math.floor(mit.score)+ ' points in the Pappu Pakia!';

  };

  mit.last_time = new Date();
  setInterval(function() {
    mit.ui.fps_count.html(mit.fps.toFixed(0) + ' FPS');
  }, 1000);

  // Initializations
  mit.Backgrounds.init(ctx);

  (function renderGame() {
    window.requestAnimationFrame(renderGame);

    // Draw Backgrounds on BG Canvas
    mit.Backgrounds.draw(bg_ctx);

    ctx.clearRect(0, 0, W, H);

    // Draw Digs (holds forks)
    // I am fine without Digs, but Kushagra
    // just WANTS me to do this extra work :/
    // mit.ForkUtils.drawDigs(ctx);

    // Draw Grass on Main Canvas
    mit.Backgrounds.drawGrass(ctx);

    if (mit.flying_up || !mit.game_started)
      mit.Pappu.updateFlyFrameCount();
    else
      mit.Pappu.updateFlyFrameCount(0);

    // Game over on reaching any boundary
    if (mit.Pappu.hasReachedBoundary(W, H)) {
      // Performing some game over tasks
      mit.gameOver();
      return;
    }

    //mit.ForkUtils.draw(ctx);
    //mit.BranchUtils.draw(ctx);

    //mit.ForkUtils.checkCollision();

    // Send over Pakias (Enemies)
    // mit.PakiaUtils.render(ctx);

    // Collectibles
    // mit.CollectibleUtils.draw(ctx);

    // mit.Pappu.createClones(3);

    if (mit.game_started) {

      // Drawin stuff
      mit.ForkUtils.draw(ctx);
      mit.BranchUtils.draw(ctx);
      mit.CollectibleUtils.draw(ctx);
      mit.Pappu.drawClones(ctx);

      // Check Collisions with pappu
      if (!mit.Pappu.invincible) {
        mit.ForkUtils.checkCollision();
        mit.BranchUtils.checkCollision();
        mit.PakiaUtils.checkCollision();
      }
      mit.CollectibleUtils.checkCollision();
      mit.Pappu.checkCloneCollision();

      // Send over Pakias (Enemies)
      if (mit.score > 199)
        mit.PakiaUtils.render(ctx);

      // Update score
      mit.score = mit.score += 0.4;
      ui.score_board.text(parseInt(mit.score));

      // Acceleration + Gravity
      // mit.ay = mit.ay + mit.gravity;

      // Velocity
      if (
        (mit.vy < mit.v_cap && mit.ay+mit.gravity > 0) ||
        (mit.vy > -mit.v_cap && mit.ay+mit.gravity < 0)
        ) {

        // console.log(mit.ay);
        mit.vy += mit.ay;
        mit.vy += mit.gravity;
      }

      // console.log(vy, ay)

      mit.Pappu.x += mit.vx;
      mit.Pappu.y += mit.vy;

      if (mit.vy > mit.v_cap) {
        mit.vy = mit.v_cap;
      }

      mit.Pappu.draw(ctx);
    }
    else {
      mit.Pappu.drawStatic(ctx);
    }

    // Calculate FPS
    mit.cur_time = new Date;
    mit.fps = 1e3 / (mit.cur_time - mit.last_time);
    mit.last_time = mit.cur_time;

    return;
  }());

}());<commit_msg>not drawing the grass layer anymore - moar optimizations<commit_after>(function() {

  // rAF
  window.requestAnimationFrame = function() {
    return window.requestAnimationFrame ||
      window.webkitRequestAnimationFrame ||
      window.mozRequestAnimationFrame ||
      window.msRequestAnimationFrame ||
      window.oRequestAnimationFrame ||
      function(f) {
        window.setTimeout(f,1e3/60);
      }
  }();

  // cAF
  window.cancelAnimationFrame = function() {
    return window.cancelAnimationFrame ||
      window.webkitCancelAnimationFrame ||
      window.mozCancelAnimationFrame ||
      window.msCancelAnimationFrame ||
      window.oCancelAnimationFrame ||
      function(f) {
        window.setTimeout(f,1e3/60);
      }
  }();

  var config = mit.config = {

  };

  var ui = mit.ui = {
    body: $('body'),
    score_board: $('#score_board'),
    start_screen: $('#start_screen'),
    start_game: $('#start_game'),
    tweet: $('#tweet'),
    fb: $('#fb'),
    fps_count: $('#fps_count')
  };

  /*
  Basic Canvas Inits
  */

  // Main Canvas

  var canvas = document.querySelector('#game_main');
  var ctx = canvas.getContext('2d');

  var W = canvas.width = ui.body.width();
  var H = canvas.height = ui.body.height();

  // Width x Height capped to 1000 x 500
  if (canvas.width > 1000) {
    W = canvas.width = 1000;
  }
  if (canvas.height > 500) {
    H = canvas.height = 500;
  }

  // Resizing Width/Height
  if (canvas.height < 500) {
    canvas.width = canvas.height * 1000/500;
  }
  if (canvas.width < 1000) {
    canvas.height = canvas.width * 500/1000;
  }

  // BG Canvas
  var bg_canvas = document.querySelector('#game_bg');
  var bg_ctx = bg_canvas.getContext('2d');

  bg_canvas.width = canvas.width;
  bg_canvas.height = canvas.height;

  var music = document.getElementById("start");
  /*
    Game Start Screen and Lolz
  */
  mit.game_started = 0;
  mit.game_over = 0;
  mit.start_btn_clicked = 0;

  ui.start_screen.css('width', canvas.width + 'px');
  ui.start_screen.css('height', canvas.height + 'px');

  // Start Button
  var startGame = function() {
    // Play the awesome music! Really awesome
    music.volume = 0.2;
    music.play();
    flap.pause();

    // Hide the Start Screen
    ui.start_screen.fadeOut();

    // Start btn has been clicked
    // Game hasnt started. Game will
    // start on flight.
    mit.start_btn_clicked = 1;
    mit.game_started = 0;

    mit.Backgrounds.common_bg_speed = 1;
    mit.Backgrounds.ground_bg_move_speed = 9;

    // Reset all accelerations and make
    // pappu stationary
    mit.Pappu.drawStatic(ctx);
    mit.ax = 0; mit.ay = 0;
    mit.vx = 0; mit.vy = 0;

    // reset score
    mit.score = 0;

    // Nuke all forks
    mit.ForkUtils.forks = [];
    // Nuke all branches
    mit.BranchUtils.branches = [];
    // Nuke all collectibles
    mit.CollectibleUtils.collecs = [];
  };

  ui.start_game.on('mousedown', function() {
    startGame();

    return false;
  });

  // startGame();

  // Share links
  var tweet = document.getElementById("tweet");
  tweet.href='http://twitter.com/share?url=http://khele.in/pappu-pakia/&text=I am playing Pappu Pakia, a cute HTML5 game on khele.in!&count=horiztonal&via=_rishabhp&related=solitarydesigns';

  var facebook = document.getElementById("fb");
  facebook.href='http://facebook.com/sharer.php?s=100&p[url]=http://khele.in/pappu-pakia/&p[title]=I am playing Pappu Pakia, a cute HTML5 game on khele.in!';

  // Score Board
  mit.score = 0;

  ui.score_board.css('width', canvas.width + 'px');
  ui.score_board.css('height', canvas.height + 'px');

  // Set Canvas Width/Height in Config
  mit.config.canvas_width = mit.W = W;
  mit.config.canvas_height = mit.H = H;

  // Gravity
  mit.gravity = 0.7;

  // Velocity x,y
  mit.vx = 0;
  mit.vy = 0;

  // Velocity cap on either sides of the
  // number system.
  //
  // You can console.log velocities in drawing methods
  // and from there decide what to set as the cap.
  mit.v_cap = 7.5;

  // Accelaration x,y
  mit.ax = 0;
  mit.ay = 0;

  // Flying up ?
  mit.flying_up = 0;

  mit.ascend = function() {
    if (!mit.start_btn_clicked)
      return;

    if (!mit.game_started)
      mit.game_started = 1;

    mit.ay = -1.5;
    mit.flying_up = 1;
  };

  mit.descend = function() {
    if (!mit.start_btn_clicked)
      return;

    mit.ay = 0;
    mit.flying_up = 0;
  };

  // Game play on mouse clicks too!
  window.addEventListener('mousedown', function(e) {
    mit.ascend();
  }, false);

  window.addEventListener('mouseup', function(e) {
    mit.descend();
  }, false);

  // Game play on touch too!
  window.addEventListener('touchstart', function(e) {
    mit.ascend();
  }, false);

  window.addEventListener('touchend', function(e) {
    mit.descend();
  }, false);

  // ... and keyzz...
  window.addEventListener('keydown', function(e) {

    if (e.keyCode === 38) {
      mit.ascend();
    }

    e.preventDefault();

  }, false);

  window.addEventListener('keyup', function(e) {

    mit.descend();
    e.preventDefault();
  }, false);

  /*
    Performing some game over tasks
  */
  mit.gameOver = function() {
    ui.start_screen.fadeIn();
    ui.start_game.html('re-start');
    ui.tweet.html('tweet score');
    ui.fb.html('post on fb');

    // Stop background
    mit.Backgrounds.common_bg_speed = 0;
    mit.Backgrounds.ground_bg_move_speed = 0;
    mit.Backgrounds.fps = 0;

    mit.game_over = 1;
    mit.start_btn_clicked = 0;

    // Pappu if invincible will be no morez
    mit.Pappu.invincible = 0;

    // Nuke all clones
    mit.Pappu.clones.length = 0;

    // Share
    var tweet = document.getElementById("tweet");
    tweet.href='http://twitter.com/share?url=http://khele.in/pappu-pakia/&text=I just scored ' +Math.floor(mit.score)+ ' points in Pappu Pakia!&count=horiztonal&via=_rishabhp&related=solitarydesigns';

    var facebook = document.getElementById("fb");
    facebook.href='http://facebook.com/sharer.php?s=100&p[url]=http://khele.in/pappu-pakia/&p[title]=I just scored ' +Math.floor(mit.score)+ ' points in the Pappu Pakia!';

  };

  mit.last_time = new Date();
  setInterval(function() {
    mit.ui.fps_count.html(mit.fps.toFixed(0) + ' FPS');
  }, 1000);

  // Initializations
  mit.Backgrounds.init(ctx);

  (function renderGame() {
    window.requestAnimationFrame(renderGame);

    // Draw Backgrounds on BG Canvas
    mit.Backgrounds.draw(bg_ctx);

    ctx.clearRect(0, 0, W, H);

    // Draw Digs (holds forks)
    // I am fine without Digs, but Kushagra
    // just WANTS me to do this extra work :/
    // mit.ForkUtils.drawDigs(ctx);

    // Draw Grass on Main Canvas
    // mit.Backgrounds.drawGrass(ctx);

    if (mit.flying_up || !mit.game_started)
      mit.Pappu.updateFlyFrameCount();
    else
      mit.Pappu.updateFlyFrameCount(0);

    // Game over on reaching any boundary
    if (mit.Pappu.hasReachedBoundary(W, H)) {
      // Performing some game over tasks
      mit.gameOver();
      return;
    }

    //mit.ForkUtils.draw(ctx);
    //mit.BranchUtils.draw(ctx);

    //mit.ForkUtils.checkCollision();

    // Send over Pakias (Enemies)
    // mit.PakiaUtils.render(ctx);

    // Collectibles
    // mit.CollectibleUtils.draw(ctx);

    // mit.Pappu.createClones(3);

    if (mit.game_started) {

      // Drawin stuff
      mit.ForkUtils.draw(ctx);
      mit.BranchUtils.draw(ctx);
      mit.CollectibleUtils.draw(ctx);
      mit.Pappu.drawClones(ctx);

      // Check Collisions with pappu
      if (!mit.Pappu.invincible) {
        mit.ForkUtils.checkCollision();
        mit.BranchUtils.checkCollision();
        mit.PakiaUtils.checkCollision();
      }
      mit.CollectibleUtils.checkCollision();
      mit.Pappu.checkCloneCollision();

      // Send over Pakias (Enemies)
      if (mit.score > 199)
        mit.PakiaUtils.render(ctx);

      // Update score
      mit.score = mit.score += 0.4;
      ui.score_board.text(parseInt(mit.score));

      // Acceleration + Gravity
      // mit.ay = mit.ay + mit.gravity;

      // Velocity
      if (
        (mit.vy < mit.v_cap && mit.ay+mit.gravity > 0) ||
        (mit.vy > -mit.v_cap && mit.ay+mit.gravity < 0)
        ) {

        // console.log(mit.ay);
        mit.vy += mit.ay;
        mit.vy += mit.gravity;
      }

      // console.log(vy, ay)

      mit.Pappu.x += mit.vx;
      mit.Pappu.y += mit.vy;

      if (mit.vy > mit.v_cap) {
        mit.vy = mit.v_cap;
      }

      mit.Pappu.draw(ctx);
    }
    else {
      mit.Pappu.drawStatic(ctx);
    }

    // Calculate FPS
    mit.cur_time = new Date;
    mit.fps = 1e3 / (mit.cur_time - mit.last_time);
    mit.last_time = mit.cur_time;

    return;
  }());

}());<|endoftext|>


<commit_before>var back = document.createElement('button');
back.appendChild(document.createTextNode('Back'));
back.id = 'back';
back.addEventListener('click', function (ev) {
  window.location.hash = '#';
});

var boxContainer = document.querySelector('.boxes');
boxContainer.parentNode.insertBefore(back, boxContainer);

var boxes = [].slice.call(document.querySelectorAll('.box'));
boxes.forEach(function (box) {
  box.addEventListener('click', function (ev) {
    window.location.hash = '#' + this.getAttribute('data-url');
  });
  box.classList.add('small');
});

var sectionHeaders = [].slice.call(document.querySelectorAll('.section'));

function hideAll() {
  boxes.forEach(function (box) {
    box.style.display = 'none';
  });
  sectionHeaders.forEach(function (header) {
    header.style.display = 'none';
  });
}

function showAll() {
  boxes.forEach(function (box) {
    box.style.display = 'inline-block';
    box.classList.add('small');
  });
  sectionHeaders.forEach(function (header) {
    header.style.display = 'block';
  });
}

window.addEventListener('hashchange', handleHashChange);

function handleHashChange() {
  var hash = window.location.hash.slice(1);

  if (!hash)
    return showIndex();
  showItemByUrl(hash);
}

function showIndex() {
  showAll();
  back.classList.remove('show');
}

function showItemByUrl(frag) {
  var el = document.querySelector('*[data-url="'+frag+'"]');
  if (el && el.classList.contains('small')) {
    hideAll();
    el.style.display = 'block';
    el.classList.remove('small');
    back.classList.add('show');
  }
}

handleHashChange();

function sortDates(data) {
  var today = new Date()

  // add formatted dates
  data.forEach(function(event) {
    event.startUTC = new Date(event.startdate)
    if (event.enddate) event.endUTC = new Date(event.enddate)
  })

  // sort the dates
  var sorted = data
  sorted.sort(function(a,b) {
    return a.startUTC - b.startUTC
  })

  // only upcoming events
  var freshies = []
  var todayBuffer = new Date()
  todayBuffer.setHours(today.getHours() - 24)

  sorted.forEach(function(event) {
    if (event.startUTC >= todayBuffer)
      freshies.push(event)
  })

  if (freshies.length != 0) {
    return freshies
  }
  else return {
    "name": "No upcoming events. Check out past events!",
    "tickets": "events.html"
  }
  return freshies
}
<commit_msg>edit js<commit_after>var back = document.createElement('button');
back.appendChild(document.createTextNode('Back'));
back.id = 'back';
back.addEventListener('click', function (ev) {
  window.location.hash = '#';
});

var boxContainer = document.querySelector('.boxes');
boxContainer.parentNode.insertBefore(back, boxContainer);

var boxes = [].slice.call(document.querySelectorAll('.box'));
boxes.forEach(function (box) {
  box.addEventListener('click', function (ev) {
    window.location.hash = '#' + this.getAttribute('data-url');
  });
  box.classList.add('small');
});

var sectionHeaders = [].slice.call(document.querySelectorAll('.section'));

function hideAll() {
  boxes.forEach(function (box) {
    box.style.display = 'none';
  });
  sectionHeaders.forEach(function (header) {
    header.style.display = 'none';
  });
}

function showAll() {
  boxes.forEach(function (box) {
    box.style.display = 'inline-block';
    box.classList.add('small');
  });
  sectionHeaders.forEach(function (header) {
    header.style.display = 'block';
  });
}

window.addEventListener('hashchange', handleHashChange);

function handleHashChange() {
  var hash = window.location.hash.slice(1);

  if (!hash)
    return showIndex();
  showItemByUrl(hash);
}

function showIndex() {
  showAll();
  back.classList.remove('show');
}

function showItemByUrl(frag) {
  var el = document.querySelector('*[data-url="'+frag+'"]');
  if (el && el.classList.contains('small')) {
    hideAll();
    el.style.display = 'block';
    el.classList.remove('small');
    back.classList.add('show');
  }
}

handleHashChange();

function sortDates(data) {
  var today = new Date()

  // add formatted dates
  data.forEach(function(event) {
    event.startUTC = new Date(event.startdate)
    if (event.enddate) event.endUTC = new Date(event.enddate)
  })

  // sort the dates
  var sorted = data
  sorted.sort(function(a,b) {
    return a.startUTC - b.startUTC
  })

  // only upcoming events
  var freshies = []
  var todayBuffer = new Date()
  todayBuffer.setHours(today.getHours() - 24)

  sorted.forEach(function(event) {
    if (event.startUTC >= todayBuffer)
      freshies.push(event)
  })

  if (freshies.length !== 0) {
    return freshies
  } else return {
    "name": "No upcoming events. Check out past events!",
    "tickets": "events.html"
  }
  return freshies
}
<|endoftext|>


<commit_before>var delay = 90;
var keyboardDirection = '';
var codeExample = [
    ''
];

var worker;
var time;
var running = false;
var countup;
var lastScore = 0;

var nanobar = new Nanobar();

var snake = new Snake();

function showShare() {
    getUrl(window.location.href, function(res) {
        $('#share-qr').attr('src',res + '.qr');
        var msgEn = "My AI script scored " + snake.totScore + " on snake game. Someone challenging me? -> " + res;
        $('#share-en').text(msgEn);
        var msgCn = '#贪吃蛇AI#我的贪吃蛇 AI 脚本刚刚得了 ' + snake.totScore + ' 分, 有人来围观/挑战我的代码么?  -> ' + res;
        $('#share-cn').text(msgCn);
        $('#modal-share').modal('show');
    });
}

function deepClone(obj) {
    var buffer;
    if(obj instanceof Array) {
        buffer = [];
        var i = obj.length;
        while(i--) {
            buffer[i] = deepClone(obj[i]);
        }
        return buffer;
    } else if (obj instanceof Object) {
        buffer = {};
        for(var k in obj) {
            buffer[k] = deepClone(obj[k]);
        }
        return buffer;
    } else {
        return obj;
    }
}

$(document).keydown(function(e) {
    var key = e.which;
    if(key == '66' || key == 'h' || key == '37') {
	keyboardDirection = 'left';
    } else if(key == '80' || key == '75' || key == '38') {
	keyboardDirection = "up";
    } else if(key == "70" || key == "76" || key == "39") {
	keyboardDirection = "right";
    } else if(key == "78" || key == "74" || key == "40") {
	keyboardDirection = "down";
    }
});

function updateUrl() {
    var js = $('#ai').val();
    document.location.hash = Base64.encode([js].join("\x7f"));
};

onkeyup = updateUrl;

function finish(snake) {
    console.log(snake.totScore);
    running = false;
    worker.terminate();
    snake.kill();
    refreshDisplay();
    clearTimeout(time);
    snake.init();
}

function refreshDisplay() {
    if(lastScore !== snake.totScore) {
        countup.stop();
        countup = new countUp("score", lastScore, snake.totScore, 0, 2.5, {
            useEasing : true
            ,useGrouping : true
            ,separator : ','
            ,decimal : '.'
        });
        lastScore = snake.totScore;
        countup.start();
    }
}

function loop() {
    if(running) {
        if(snake.tick < 10000) {
            setTimeout(function() {
                var state = {
                    snake: snake.snake
                    ,food: snake.food
                };
                worker.postMessage({
                    type: 'game state'
                ,data: deepClone(state)
                });
            }, delay);
        } else {
            finish(snake);
        }
    }
}

function paint() {
    var cw = width / 20;
    ctx.fillStyle = '#111';
    ctx.fillRect(0, 0, width, height);
    ctx.fillStyle = '#333';
    ctx.font = height + 'px Impact, sans-serif';
    ctx.textAlign = 'center';
    ctx.fillText(snake.score.toString(), width / 2, height * .9);
    for(var p in snake.snake) {
	var x = snake.snake[p].x;
	var y = snake.snake[p].y;
        ctx.fillStyle = "rgba(225, 220, 0, " + (1 - 0.7 * (p / snake.snake.length)).toString() + ")";
	ctx.fillRect(x * cw, y * cw, cw, cw);
	ctx.strokeStyle = 'white';
	ctx.strokeRect(x * cw, y * cw, cw, cw);
    }
    for(var p in snake.food) {
	var x = snake.food[p].x;
	var y = snake.food[p].y;
        ctx.fillStyle = '#0074D9';
        ctx.fillRect(x * cw, y * cw, cw, cw);
        ctx.strokeStyle = 'white';
        ctx.strokeRect(x * cw, y * cw, cw, cw);
    }
}

$(document).ready(function() {
    canvas = $('#playground')[0];
    ctx = canvas.getContext("2d");
    width = $('#playground').width();
    height = $('#playground').height();
    worker = new Worker('./../js/worker.js');

    $('#btn-load').click(function() {
        var src = 'data:text/javascript;base64,' + Base64.encode($('#ai').val());
        worker.terminate();
        worker = new Worker('./../js/worker.js');
        worker.postMessage({
            type: 'url'
            ,data: src
        });
        worker.onmessage = function(sdata) {
            var data = sdata.data;
            if(data.type === 'result') {
                snake.loop(data.data);
                refreshDisplay();
                paint();
                loop();
            }
        }
        worker.onerror = function(e){
            console.log(e.message);
            console.log(e.lineno);
            console.log(e.filename);
        };
    });

    $('#btn-start').click(function() {
        countup = new countUp("score", 0, snake.totScore, 0, 2.5, {
            useEasing : true
            ,useGrouping : true
            ,separator : ','
                    ,decimal : '.'
        });
        lastScore = 0;
        running = true;
        worker.postMessage({
            type: 'init'
            ,data: {
                w: 20
                ,h: 15
            }
        });
        snake.init('game');
        time = setTimeout(function() {
            finish(snake);
            console.log('Time out. ');
        }, 300 * 1000);
        loop();
    });

    $('#btn-reset').click(function() {
	$('#ai').val('');
        finish();
    });

    $('#btn-mode').click(function() {
	delay ^= 90;
    });

    $('#ai-examples').change(function() {
	$('#ai').val(codeExample[$('#ai-examples').get(0).selectedIndex]);
        updateUrl();
    });

    $('#ai').val(Base64.decode(unescape((location).hash).split("\x7F")[0]||""));

    paint();
    setInterval(function() {
        if(running) {
            nanobar.go(snake.tick * 100 / 10000);
        }
    }, 100);
});
<commit_msg>init game when ended<commit_after>var delay = 90;
var keyboardDirection = '';
var codeExample = [
    ''
];

var worker;
var time;
var running = false;
var countup;
var lastScore = 0;

var nanobar = new Nanobar();

var snake = new Snake();

function showShare() {
    getUrl(window.location.href, function(res) {
        $('#share-qr').attr('src',res + '.qr');
        var msgEn = "My AI script scored " + snake.totScore + " on snake game. Someone challenging me? -> " + res;
        $('#share-en').text(msgEn);
        var msgCn = '#贪吃蛇AI#我的贪吃蛇 AI 脚本刚刚得了 ' + snake.totScore + ' 分, 有人来围观/挑战我的代码么?  -> ' + res;
        $('#share-cn').text(msgCn);
        $('#modal-share').modal('show');
    });
}

function deepClone(obj) {
    var buffer;
    if(obj instanceof Array) {
        buffer = [];
        var i = obj.length;
        while(i--) {
            buffer[i] = deepClone(obj[i]);
        }
        return buffer;
    } else if (obj instanceof Object) {
        buffer = {};
        for(var k in obj) {
            buffer[k] = deepClone(obj[k]);
        }
        return buffer;
    } else {
        return obj;
    }
}

$(document).keydown(function(e) {
    var key = e.which;
    if(key == '66' || key == 'h' || key == '37') {
	keyboardDirection = 'left';
    } else if(key == '80' || key == '75' || key == '38') {
	keyboardDirection = "up";
    } else if(key == "70" || key == "76" || key == "39") {
	keyboardDirection = "right";
    } else if(key == "78" || key == "74" || key == "40") {
	keyboardDirection = "down";
    }
});

function updateUrl() {
    var js = $('#ai').val();
    document.location.hash = Base64.encode([js].join("\x7f"));
};

onkeyup = updateUrl;

function finish(snake) {
    console.log(snake.totScore);
    running = false;
    worker.terminate();
    snake.kill();
    refreshDisplay();
    clearTimeout(time);
    snake.init('game');
}

function refreshDisplay() {
    if(lastScore !== snake.totScore) {
        countup.stop();
        countup = new countUp("score", lastScore, snake.totScore, 0, 2.5, {
            useEasing : true
            ,useGrouping : true
            ,separator : ','
            ,decimal : '.'
        });
        lastScore = snake.totScore;
        countup.start();
    }
}

function loop() {
    if(running) {
        if(snake.tick < 10000) {
            setTimeout(function() {
                var state = {
                    snake: snake.snake
                    ,food: snake.food
                };
                worker.postMessage({
                    type: 'game state'
                ,data: deepClone(state)
                });
            }, delay);
        } else {
            finish(snake);
        }
    }
}

function paint() {
    var cw = width / 20;
    ctx.fillStyle = '#111';
    ctx.fillRect(0, 0, width, height);
    ctx.fillStyle = '#333';
    ctx.font = height + 'px Impact, sans-serif';
    ctx.textAlign = 'center';
    ctx.fillText(snake.score.toString(), width / 2, height * .9);
    for(var p in snake.snake) {
	var x = snake.snake[p].x;
	var y = snake.snake[p].y;
        ctx.fillStyle = "rgba(225, 220, 0, " + (1 - 0.7 * (p / snake.snake.length)).toString() + ")";
	ctx.fillRect(x * cw, y * cw, cw, cw);
	ctx.strokeStyle = 'white';
	ctx.strokeRect(x * cw, y * cw, cw, cw);
    }
    for(var p in snake.food) {
	var x = snake.food[p].x;
	var y = snake.food[p].y;
        ctx.fillStyle = '#0074D9';
        ctx.fillRect(x * cw, y * cw, cw, cw);
        ctx.strokeStyle = 'white';
        ctx.strokeRect(x * cw, y * cw, cw, cw);
    }
}

$(document).ready(function() {
    canvas = $('#playground')[0];
    ctx = canvas.getContext("2d");
    width = $('#playground').width();
    height = $('#playground').height();
    worker = new Worker('./../js/worker.js');

    $('#btn-load').click(function() {
        var src = 'data:text/javascript;base64,' + Base64.encode($('#ai').val());
        worker.terminate();
        worker = new Worker('./../js/worker.js');
        worker.postMessage({
            type: 'url'
            ,data: src
        });
        worker.onmessage = function(sdata) {
            var data = sdata.data;
            if(data.type === 'result') {
                snake.loop(data.data);
                refreshDisplay();
                paint();
                loop();
            }
        }
        worker.onerror = function(e){
            console.log(e.message);
            console.log(e.lineno);
            console.log(e.filename);
        };
    });

    $('#btn-start').click(function() {
        countup = new countUp("score", 0, snake.totScore, 0, 2.5, {
            useEasing : true
            ,useGrouping : true
            ,separator : ','
                    ,decimal : '.'
        });
        lastScore = 0;
        running = true;
        worker.postMessage({
            type: 'init'
            ,data: {
                w: 20
                ,h: 15
            }
        });
        snake.init('game');
        time = setTimeout(function() {
            finish(snake);
            console.log('Time out. ');
        }, 300 * 1000);
        loop();
    });

    $('#btn-reset').click(function() {
	$('#ai').val('');
        finish();
    });

    $('#btn-mode').click(function() {
	delay ^= 90;
    });

    $('#ai-examples').change(function() {
	$('#ai').val(codeExample[$('#ai-examples').get(0).selectedIndex]);
        updateUrl();
    });

    $('#ai').val(Base64.decode(unescape((location).hash).split("\x7F")[0]||""));

    paint();
    setInterval(function() {
        if(running) {
            nanobar.go(snake.tick * 100 / 10000);
        }
    }, 100);
});
<|endoftext|>


<commit_before>
var pl, controls, scene, renderer, composer;
var renderTargetParametersRGBA, renderTargetParametersRGB;
var colorTarget, depthTarget, depthPassPlugin;
var lightManager, dungeon;
var clock = new THREE.Clock();
var cache = new Cache();
var passes = {};

function init() {
	scene = new Physijs.Scene();
	scene.setGravity(new THREE.Vector3(0, -10 * UNIT, 0));
	scene.fog = new THREE.FogExp2(0x000000, 0.05);
	scene.addEventListener('update', function() {
		physicsStats.update();
	});

	pl = new Physijs.CapsuleMesh(
		new THREE.CylinderGeometry(0.8 * UNIT, 0.8 * UNIT, 2 * UNIT),
		new THREE.MeshBasicMaterial({ color: 0xff00ff }),
		100
	);
	pl.visible = false;
	// Add pl later to the scene

	pl.camera = new THREE.PerspectiveCamera(60, window.innerWidth / window.innerHeight, 0.1 * UNIT, 30 * UNIT);

	controls = new Controls(pl.camera, { mouse: mouseHandler });
	controls.movementSpeed = 10 * UNIT;
	controls.lookSpeed = 0.5;
	controls.lookVertical = true;
	controls.constrainVerticalLook = true;
	controls.verticalMin = 1.1;
	controls.verticalMax = 2.2;

	renderer = new THREE.WebGLRenderer({
		clearColor: 0x000000,
		maxLights: CONFIG.maxLights + 2, // Player light is separate
		antialias: CONFIG.antialias,
		preserveDrawingBuffer: true
	});
	renderer.setSize(window.innerWidth, window.innerHeight);
	renderer.shadowMapEnabled = CONFIG.shadows;
	renderer.shadowMapSoft = CONFIG.softShadows;
	renderer.shadowMapDebug = false;
	renderer.gammaInput = true;
	renderer.gammaOutput = true;
	renderer.physicallyBasedShading = CONFIG.physicalShading;
	renderer.autoClear = false;
	if (!CONFIG.anisotropy) CONFIG.anisotropy = renderer.getMaxAnisotropy();

	renderTargetParametersRGB  = { minFilter: THREE.LinearFilter, magFilter: THREE.LinearFilter, format: THREE.RGBFormat };
	renderTargetParametersRGBA = { minFilter: THREE.LinearFilter, magFilter: THREE.LinearFilter, format: THREE.RGBAFormat };
	depthTarget = new THREE.WebGLRenderTarget(window.innerWidth, window.innerHeight, renderTargetParametersRGBA);
	colorTarget = new THREE.WebGLRenderTarget(window.innerWidth, window.innerHeight, renderTargetParametersRGB);

	// Postprocessing effects
	passes.scene = new THREE.RenderPass(scene, pl.camera);
	passes.ssao = new THREE.ShaderPass(THREE.ShaderExtras.ssao);
	passes.ssao.uniforms.tDepth.value = depthTarget;
	passes.ssao.uniforms.size.value.set(window.innerWidth, window.innerHeight);
	passes.ssao.uniforms.cameraNear.value = pl.camera.near;
	passes.ssao.uniforms.cameraFar.value = pl.camera.far;
	passes.ssao.uniforms.fogNear.value = scene.fog.near;
	passes.ssao.uniforms.fogFar.value = scene.fog.far;
	passes.ssao.uniforms.fogEnabled.value = 0;
	passes.ssao.uniforms.aoClamp.value = 0.4;
	passes.ssao.uniforms.onlyAO.value = 0;
	passes.fxaa = new THREE.ShaderPass(THREE.ShaderExtras.fxaa);
	passes.fxaa.uniforms.resolution.value.set(1/window.innerWidth, 1/window.innerHeight);
	passes.bloom = new THREE.BloomPass(0.5);
	passes.adjust = new THREE.ShaderPass(THREE.ShaderExtras.hueSaturation);
	passes.adjust.uniforms.saturation.value = 0.2;

	composer = new THREE.EffectComposer(renderer, colorTarget);
	//composer.addPass(passes.scene);
	composer.addPass(passes.ssao);
	composer.addPass(passes.fxaa);
	composer.addPass(passes.bloom);
	composer.addPass(passes.adjust);
	composer.passes[composer.passes.length - 1].renderToScreen = true;

	// Depth pass
	depthPassPlugin = new THREE.DepthPassPlugin();
	depthPassPlugin.renderTarget = depthTarget;
	renderer.addPrePlugin(depthPassPlugin);

	lightManager = new LightManager({ maxLights: CONFIG.maxLights, maxShadows: CONFIG.maxShadows });

	// Create level and finalize player
	dungeon = new Dungeon(scene, pl);
	lightManager.update(pl);

	updateConfig();
	dumpInfo();
	initUI();

	var now = new Date().getTime();
	if (window.performance)
		console.log("Initialization took " + (now - window.performance.timing.navigationStart) + "ms");
}

function mouseHandler(button) {
	var _vector = new THREE.Vector3(0, 0, 1);
	var projector = new THREE.Projector();
	projector.unprojectVector(_vector, pl.camera);
	var ray = new THREE.Ray(pl.camera.position, _vector.subSelf(pl.camera.position).normalize());
	var intersections = ray.intersectObjects(dungeon.objects);
	if (intersections.length > 0) {
		var target = intersections[0].object;
		if (target.position.distanceToSquared(pl.position) < 9)
			target.applyCentralImpulse(_vector.multiplyScalar(10000));
	}
}

function animate(dt) {
	if (!dungeon.loaded) return;
	function getAnim(time) { return Math.abs(time - (time|0) - 0.5) * 2.0; }
	function fract(num) { return num - (num|0); }
	var i, v = new THREE.Vector3();

	/*for (i = 0; i < dungeon.monsters.length; ++i) {
		var monster = dungeon.monsters[i];
		monster.mesh.updateAnimation(1000 * dt);
		// Look at player
		v.copy(pl.position);
		v.subSelf(monster.position);
		v.y = 0;
		monster.mesh.lookAt(v.normalize());
		monster.setLinearVelocity(v.multiplyScalar(50 * dt));
	}*/

	// Lights
	var timeNow = new Date().getTime();
	for (i = 0; i < lightManager.lights.length; ++i) {
		var light = lightManager.lights[i];
		var anim = timeNow / (1000.0 + i);
		light.intensity = 0.5 + 0.5 * getAnim(anim);
		if (light.visible && light.emitter)
			light.emitter.update(dt).render();
	}
	if (dungeon.exitParticles) dungeon.exitParticles.update(dt).render();

	// Player light
	pl.light.intensity = 0.5 + 0.5 * getAnim(timeNow / 1000.0);
	pl.light.position.set(pl.position.x, pl.position.y + 0.2, pl.position.z);
	pl.shadow.position.copy(pl.light.position);
	pl.shadow.target.position.copy(controls.target);

	// Player weapon
	if (pl.rhand) {
		pl.rhand.position.set(pl.position.x, pl.position.y, pl.position.z);
		pl.rhand.rotation.copy(pl.camera.rotation);
		pl.rhand.updateMatrix();
		pl.rhand.rotation.y += Math.PI/3;
		pl.rhand.rotation.z += Math.PI/2;
		pl.rhand.translateX(0.2*UNIT);
		pl.rhand.translateY(0.2*UNIT);
		pl.rhand.translateZ(-0.5*UNIT);
	}

	//console.log(pl.position.x, pl.position.z);
}

$(document).ready(function() {
	var v0 = new THREE.Vector3();
	var v1 = new THREE.Vector3();
	function render() {
		requestAnimationFrame(render);
		if (!dungeon.loaded) return;

		// Player movement, controls and physics
		var dt = clock.getDelta();
		v0.set(pl.camera.position.x, 0, pl.camera.position.z);
		controls.update(dt);
		v1.set(pl.camera.position.x, 0, pl.camera.position.z);
		v1.subSelf(v0); // Becomes velocity
		v1.divideScalar(dt * UNIT);
		v0 = pl.getLinearVelocity();
		pl.setLinearVelocity({ x: v1.x, y: v0.y < 0 ? v0.y : 0, z: v1.z });
		scene.simulate(); // Simulate physics
		// FIXME: 0.5 below is magic number to rise camera
		controls.object.position.set(pl.position.x, pl.position.y + 0.5, pl.position.z);

		animate(dt);
		lightManager.update(pl);
		renderer.clear();
		if (CONFIG.postprocessing) {
			renderer.shadowMapEnabled = CONFIG.shadows;
			depthPassPlugin.enabled = true;
			renderer.render(scene, pl.camera, composer.renderTarget2, true);
			renderer.shadowMapEnabled = false;
			depthPassPlugin.enabled = false;
			composer.render(dt);
		} else renderer.render(scene, pl.camera);
		renderStats.update();
	}

	init();
	render();
});
<commit_msg>Fix player gravity.<commit_after>
var pl, controls, scene, renderer, composer;
var renderTargetParametersRGBA, renderTargetParametersRGB;
var colorTarget, depthTarget, depthPassPlugin;
var lightManager, dungeon;
var clock = new THREE.Clock();
var cache = new Cache();
var passes = {};

function init() {
	scene = new Physijs.Scene();
	scene.setGravity(new THREE.Vector3(0, -10 * UNIT, 0));
	scene.fog = new THREE.FogExp2(0x000000, 0.05);
	scene.addEventListener('update', function() {
		physicsStats.update();
	});

	pl = new Physijs.CapsuleMesh(
		new THREE.CylinderGeometry(0.8 * UNIT, 0.8 * UNIT, 2 * UNIT),
		new THREE.MeshBasicMaterial({ color: 0xff00ff }),
		100
	);
	pl.visible = false;
	// Add pl later to the scene

	pl.camera = new THREE.PerspectiveCamera(60, window.innerWidth / window.innerHeight, 0.1 * UNIT, 30 * UNIT);

	controls = new Controls(pl.camera, { mouse: mouseHandler });
	controls.movementSpeed = 10 * UNIT;
	controls.lookSpeed = 0.5;
	controls.lookVertical = true;
	controls.constrainVerticalLook = true;
	controls.verticalMin = 1.1;
	controls.verticalMax = 2.2;

	renderer = new THREE.WebGLRenderer({
		clearColor: 0x000000,
		maxLights: CONFIG.maxLights + 2, // Player light is separate
		antialias: CONFIG.antialias,
		preserveDrawingBuffer: true
	});
	renderer.setSize(window.innerWidth, window.innerHeight);
	renderer.shadowMapEnabled = CONFIG.shadows;
	renderer.shadowMapSoft = CONFIG.softShadows;
	renderer.shadowMapDebug = false;
	renderer.gammaInput = true;
	renderer.gammaOutput = true;
	renderer.physicallyBasedShading = CONFIG.physicalShading;
	renderer.autoClear = false;
	if (!CONFIG.anisotropy) CONFIG.anisotropy = renderer.getMaxAnisotropy();

	renderTargetParametersRGB  = { minFilter: THREE.LinearFilter, magFilter: THREE.LinearFilter, format: THREE.RGBFormat };
	renderTargetParametersRGBA = { minFilter: THREE.LinearFilter, magFilter: THREE.LinearFilter, format: THREE.RGBAFormat };
	depthTarget = new THREE.WebGLRenderTarget(window.innerWidth, window.innerHeight, renderTargetParametersRGBA);
	colorTarget = new THREE.WebGLRenderTarget(window.innerWidth, window.innerHeight, renderTargetParametersRGB);

	// Postprocessing effects
	passes.scene = new THREE.RenderPass(scene, pl.camera);
	passes.ssao = new THREE.ShaderPass(THREE.ShaderExtras.ssao);
	passes.ssao.uniforms.tDepth.value = depthTarget;
	passes.ssao.uniforms.size.value.set(window.innerWidth, window.innerHeight);
	passes.ssao.uniforms.cameraNear.value = pl.camera.near;
	passes.ssao.uniforms.cameraFar.value = pl.camera.far;
	passes.ssao.uniforms.fogNear.value = scene.fog.near;
	passes.ssao.uniforms.fogFar.value = scene.fog.far;
	passes.ssao.uniforms.fogEnabled.value = 0;
	passes.ssao.uniforms.aoClamp.value = 0.4;
	passes.ssao.uniforms.onlyAO.value = 0;
	passes.fxaa = new THREE.ShaderPass(THREE.ShaderExtras.fxaa);
	passes.fxaa.uniforms.resolution.value.set(1/window.innerWidth, 1/window.innerHeight);
	passes.bloom = new THREE.BloomPass(0.5);
	passes.adjust = new THREE.ShaderPass(THREE.ShaderExtras.hueSaturation);
	passes.adjust.uniforms.saturation.value = 0.2;

	composer = new THREE.EffectComposer(renderer, colorTarget);
	//composer.addPass(passes.scene);
	composer.addPass(passes.ssao);
	composer.addPass(passes.fxaa);
	composer.addPass(passes.bloom);
	composer.addPass(passes.adjust);
	composer.passes[composer.passes.length - 1].renderToScreen = true;

	// Depth pass
	depthPassPlugin = new THREE.DepthPassPlugin();
	depthPassPlugin.renderTarget = depthTarget;
	renderer.addPrePlugin(depthPassPlugin);

	lightManager = new LightManager({ maxLights: CONFIG.maxLights, maxShadows: CONFIG.maxShadows });

	// Create level and finalize player
	dungeon = new Dungeon(scene, pl);
	lightManager.update(pl);

	updateConfig();
	dumpInfo();
	initUI();

	var now = new Date().getTime();
	if (window.performance)
		console.log("Initialization took " + (now - window.performance.timing.navigationStart) + "ms");
}

function mouseHandler(button) {
	var _vector = new THREE.Vector3(0, 0, 1);
	var projector = new THREE.Projector();
	projector.unprojectVector(_vector, pl.camera);
	var ray = new THREE.Ray(pl.camera.position, _vector.subSelf(pl.camera.position).normalize());
	var intersections = ray.intersectObjects(dungeon.objects);
	if (intersections.length > 0) {
		var target = intersections[0].object;
		if (target.position.distanceToSquared(pl.position) < 9)
			target.applyCentralImpulse(_vector.multiplyScalar(10000));
	}
}

function animate(dt) {
	if (!dungeon.loaded) return;
	function getAnim(time) { return Math.abs(time - (time|0) - 0.5) * 2.0; }
	function fract(num) { return num - (num|0); }
	var i, v = new THREE.Vector3();

	/*for (i = 0; i < dungeon.monsters.length; ++i) {
		var monster = dungeon.monsters[i];
		monster.mesh.updateAnimation(1000 * dt);
		// Look at player
		v.copy(pl.position);
		v.subSelf(monster.position);
		v.y = 0;
		monster.mesh.lookAt(v.normalize());
		monster.setLinearVelocity(v.multiplyScalar(50 * dt));
	}*/

	// Lights
	var timeNow = new Date().getTime();
	for (i = 0; i < lightManager.lights.length; ++i) {
		var light = lightManager.lights[i];
		var anim = timeNow / (1000.0 + i);
		light.intensity = 0.5 + 0.5 * getAnim(anim);
		if (light.visible && light.emitter)
			light.emitter.update(dt).render();
	}
	if (dungeon.exitParticles) dungeon.exitParticles.update(dt).render();

	// Player light
	pl.light.intensity = 0.5 + 0.5 * getAnim(timeNow / 1000.0);
	pl.light.position.set(pl.position.x, pl.position.y + 0.2, pl.position.z);
	pl.shadow.position.copy(pl.light.position);
	pl.shadow.target.position.copy(controls.target);

	// Player weapon
	if (pl.rhand) {
		pl.rhand.position.set(pl.position.x, pl.position.y, pl.position.z);
		pl.rhand.rotation.copy(pl.camera.rotation);
		pl.rhand.updateMatrix();
		pl.rhand.rotation.y += Math.PI/3;
		pl.rhand.rotation.z += Math.PI/2;
		pl.rhand.translateX(0.2*UNIT);
		pl.rhand.translateY(0.2*UNIT);
		pl.rhand.translateZ(-0.5*UNIT);
	}

	//console.log(pl.position.x, pl.position.z);
}

$(document).ready(function() {
	var v0 = new THREE.Vector3();
	var v1 = new THREE.Vector3();
	function render() {
		requestAnimationFrame(render);
		if (!dungeon.loaded) return;

		// Player movement, controls and physics
		var dt = clock.getDelta();
		v0.set(pl.camera.position.x, 0, pl.camera.position.z);
		controls.update(dt);
		v1.set(pl.camera.position.x, 0, pl.camera.position.z);
		v1.subSelf(v0); // Becomes velocity
		v1.divideScalar(dt * UNIT);
		var vy = pl.getLinearVelocity().y;
		pl.setLinearVelocity({ x: v1.x, y: vy < 0 ? vy : 0, z: v1.z });
		scene.simulate(); // Simulate physics
		// FIXME: 0.5 below is magic number to rise camera
		controls.object.position.set(pl.position.x, pl.position.y + 0.5, pl.position.z);

		animate(dt);
		lightManager.update(pl);
		renderer.clear();
		if (CONFIG.postprocessing) {
			renderer.shadowMapEnabled = CONFIG.shadows;
			depthPassPlugin.enabled = true;
			renderer.render(scene, pl.camera, composer.renderTarget2, true);
			renderer.shadowMapEnabled = false;
			depthPassPlugin.enabled = false;
			composer.render(dt);
		} else renderer.render(scene, pl.camera);
		renderStats.update();
	}

	init();
	render();
});
<|endoftext|>


<commit_before>jQuery.fn.updateWithText = function(text, speed)
{
	var dummy = $('<div/>').html(text);

	if ($(this).html() != dummy.html())
	{
		$(this).fadeOut(speed/2, function() {
			$(this).html(text);
			$(this).fadeIn(speed/2, function() {
				//done
			});
		});
	}
}

jQuery.fn.outerHTML = function(s) {
    return s
        ? this.before(s).remove()
        : jQuery("<p>").append(this.eq(0).clone()).html();
};

jQuery(document).ready(function($) {

	var news = [];
	var newsIndex = 0;

	var lastCompliment;
	var compliment;

	(function checkVersion()
	{
		$.getJSON('githash.php', {}, function(json, textStatus) {
			if (json) {
				if (json.gitHash != gitHash) {
					window.location.reload();
					window.location.href=window.location.href;
				}
			}
		});
		setTimeout(function() {
			checkVersion();
		}, 3000);
	})();

	(function updateTime()
	{
		var now = new Date();
		var hh = now.getHours();
		var mm = now.getMinutes();
		var ss = now.getSeconds();

		hh = (hh < 10) ? '0' + hh : hh;
		mm = (mm < 10) ? '0' + mm : mm;
		ss = (ss < 10) ? '0' + ss : ss;

		var time = hh + ":" + mm;

		$('.time').html(time);

		setTimeout(function() {
			updateTime();
		}, 1000);
	})();

	(function updateCompliment()
	{
		//var compliments = ['Hey, handsome!','Hi, sexy!','Hello, beauty!', 'You look sexy!', 'Wow, you look hot!'];
		var compliments = ['Testing ...', 'Please wait ...'];

		while (compliment == lastCompliment) {
			compliment = Math.floor(Math.random()*compliments.length);
		}
		$('.compliment').updateWithText(compliments[compliment], 4000);

		lastCompliment = compliment;

		setTimeout(function() {
			updateCompliment();
		}, 5000);
	})();

	(function updateWeather()
	{
		var iconTable = {
			'01d':'wi-day-sunny',
			'02d':'wi-day-cloudy',
			'03d':'wi-cloudy',
			'04d':'wi-cloudy-windy',
			'09d':'wi-showers',
			'10d':'wi-rain',
			'11d':'wi-thunderstorm',
			'13d':'wi-snow',
			'50d':'wi-fog',
			'01n':'wi-night-clear',
			'02n':'wi-night-cloudy',
			'03n':'wi-night-cloudy',
			'04n':'wi-night-cloudy',
			'09n':'wi-night-showers',
			'10n':'wi-night-rain',
			'11n':'wi-night-thunderstorm',
			'13n':'wi-night-snow',
			'50n':'wi-night-alt-cloudy-windy'
		}
		var params = {
			'q':'Baarn,Netherlands',
			'units':'metric',
			'lang':'nl'
		}

		$.getJSON('http://api.openweathermap.org/data/2.5/weather', params, function(json, textStatus) {
			var temp = Math.round(json.main.temp * 10) / 10;
			var iconClass = iconTable[json.weather[0].icon];
			var icon = $('<span/>').addClass('icon').addClass(iconClass);
			$('.temp').updateWithText(icon.outerHTML()+temp+'°', 1000);
		});

		setTimeout(function() {
			updateWeather();
		}, 60000);
	})();

	(function fetchNews() {
		$.feedToJson({
			feed:'http://feeds.nos.nl/nosjournaal?format=rss',
			//feed:'http://www.nu.nl/feeds/rss/achterklap.rss',
			//feed:'http://www.nu.nl/feeds/rss/opmerkelijk.rss',
			success: function(data){
				news = [];
				for (var i in data.item) {
					var item = data.item[i];
					news.push(item.title);
				}
			}
		});
		setTimeout(function() {
			fetchNews();
		}, 60000);
	})();

	(function showNews() {
		var newsItem = news[newsIndex];
		$('.Bottom').updateWithText(newsItem,2000);

		newsIndex--;
		if (newsIndex < 0) newsIndex = news.length - 1;
		setTimeout(function() {
			showNews();
		}, 5000);
	})();

});<commit_msg>test commit<commit_after>jQuery.fn.updateWithText = function(text, speed)
{
	var dummy = $('<div/>').html(text);

	if ($(this).html() != dummy.html())
	{
		$(this).fadeOut(speed/2, function() {
			$(this).html(text);
			$(this).fadeIn(speed/2, function() {
				//done
			});
		});
	}
}

jQuery.fn.outerHTML = function(s) {
    return s
        ? this.before(s).remove()
        : jQuery("<p>").append(this.eq(0).clone()).html();
};

jQuery(document).ready(function($) {

	var news = [];
	var newsIndex = 0;

	var lastCompliment;
	var compliment;

	(function checkVersion()
	{
		$.getJSON('githash.php', {}, function(json, textStatus) {
			if (json) {
				if (json.gitHash != gitHash) {
					window.location.reload();
					window.location.href=window.location.href;
				}
			}
		});
		setTimeout(function() {
			checkVersion();
		}, 3000);
	})();

	(function updateTime()
	{
		var now = new Date();
		var hh = now.getHours();
		var mm = now.getMinutes();
		var ss = now.getSeconds();

		hh = (hh < 10) ? '0' + hh : hh;
		mm = (mm < 10) ? '0' + mm : mm;
		ss = (ss < 10) ? '0' + ss : ss;

		var time = hh + ":" + mm;

		$('.time').html(time);

		setTimeout(function() {
			updateTime();
		}, 1000);
	})();

	(function updateCompliment()
	{
		//var compliments = ['Hey, handsome!','Hi, sexy!','Hello, beauty!', 'You look sexy!', 'Wow, you look hot!'];
		var compliments = ['Testing ...', 'Please wait ...'];

		while (compliment == lastCompliment) {
			compliment = Math.floor(Math.random()*compliments.length);
		}
		$('.compliment').updateWithText(compliments[compliment], 4000);

		lastCompliment = compliment;

		setTimeout(function() {
			updateCompliment();
		}, 5000);
	})();

	(function updateWeather()
	{
		var iconTable = {
			'01d':'wi-day-sunny',
			'02d':'wi-day-cloudy',
			'03d':'wi-cloudy',
			'04d':'wi-cloudy-windy',
			'09d':'wi-showers',
			'10d':'wi-rain',
			'11d':'wi-thunderstorm',
			'13d':'wi-snow',
			'50d':'wi-fog',
			'01n':'wi-night-clear',
			'02n':'wi-night-cloudy',
			'03n':'wi-night-cloudy',
			'04n':'wi-night-cloudy',
			'09n':'wi-night-showers',
			'10n':'wi-night-rain',
			'11n':'wi-night-thunderstorm',
			'13n':'wi-night-snow',
			'50n':'wi-night-alt-cloudy-windy'
		}
		var params = {
			'q':'Baarn,Netherlands',
			'units':'metric',
			'lang':'nl'
		}

		$.getJSON('http://api.openweathermap.org/data/2.5/weather', params, function(json, textStatus) {
			var temp = Math.round(json.main.temp * 10) / 10;
			var iconClass = iconTable[json.weather[0].icon];
			var icon = $('<span/>').addClass('icon').addClass(iconClass);
			$('.temp').updateWithText(icon.outerHTML()+temp+'°', 1000);
		});

		setTimeout(function() {
			updateWeather();
		}, 60000);
	})();

	(function fetchNews() {
		$.feedToJson({
			feed:'http://feeds.nos.nl/nosjournaal?format=rss',
			//feed:'http://www.nu.nl/feeds/rss/achterklap.rss',
			//feed:'http://www.nu.nl/feeds/rss/opmerkelijk.rss',
			success: function(data){
				news = [];
				for (var i in data.item) {
					var item = data.item[i];
					news.push(item.title);
				}
			}
		});
		setTimeout(function() {
			fetchNews();
		}, 60000);
	})();

	(function showNews() {
		var newsItem = news[newsIndex];
		$('.Bottom').updateWithText(newsItem,2000);

		newsIndex--;
		if (newsIndex < 0) newsIndex = news.length - 1;
		setTimeout(function() {
			showNews();
		}, 5500);
	})();

});<|endoftext|>


<commit_before>var fn = null;

angular.module('wordBaseHack', [])
    .controller('wordBaseController', function () {

    var that = this;

    that.puzzle = [

        'BALHAWDBYH',
        'EMSUSOSROE',
        'USORDKOENI',
        'TIWEANGAVS',
        'OLGUSLIMDI',
        'EWBTIROBAL',
        'SUSAYENGBY',
        'QKDRIVIDAI',
        'IENAHSNREM',
        'MSKBTYLEST',
        'NUINUSRMTG',
        'IATOSESUGR',
        'DCRBWDAILA'];

        // 'CECTITAKSM',
        // 'LRAINOMRUO',
        // 'ISLOFRLTRU',
        // 'GRPNUWYIOL',
        // 'DYECEDISEP',
        // 'SEOEGLECOU',
        // 'FLPNORAMSR',
        // 'LFRMATNTEI',
        // 'MIATEYANKA',
        // 'USNEOBLEUL',
        // 'LXROBPYRCU',
        // 'HOCKAOUPIA',
        // 'PADMNRETSC'];

    that.startFromBottom = false;

    var WIDTH = that.puzzle[0].length;
    var HEIGHT = that.puzzle.length;

    for (var i = 0; i < HEIGHT; i++) {
        that.puzzle[i] = that.puzzle[i].split('');
        for (var j = 0; j < WIDTH; j++) {
            that.puzzle[i][j] = {
                letter: that.puzzle[i][j],
                highlighted: false
            }
        }
    }

    function init (dictionary, formableWords) {
        that.dictionary = dictionary;
        that.formableWords = formableWords
        console.log('READY!');
    }

    that.words = [];

    that.getWordFromSequence = function (sequence) {
        return sequence.map(function (object) {
            return object.letter;
        }).join('');
    };

    function resetHighlighting () {
        for (var i = 0; i < HEIGHT; i++) {
            for (var j = 0; j < WIDTH; j++) {
                that.puzzle[i][j].highlighted = false;
            }
        }
    }

    that.highlightLetters = function (sequence) {
        resetHighlighting();
        sequence.forEach(function (item) {
            that.puzzle[item.row][item.col].highlighted = true;
        });
    }

    that.findWordsFromCell = function (i, j) {
        resetHighlighting();
        var words = [];
        var count = 0;
        function traverse(currPuzzle, currSeq, i, j) {
            count++;
            if (i < 0 || i >= HEIGHT ||
                j < 0 ||
                j >= WIDTH) {
                return;
            }
            if (currPuzzle[i][j] === '*') {
                return;
            }
            currSeq.push({
                letter: currPuzzle[i][j].letter,
                row: i,
                col: j
            });
            currPuzzle[i][j].letter = '*';
            var puzzle = _.cloneDeep(currPuzzle);
            var currentWord = that.getWordFromSequence(currSeq);
            if (that.dictionary[currentWord]) {
                words.push(currSeq);
            }
            if (!that.formableWords[currentWord]) {
                return;
            }
            traverse(puzzle, _.cloneDeep(currSeq), i - 1, j - 1);
            traverse(puzzle, _.cloneDeep(currSeq), i - 1, j);
            traverse(puzzle, _.cloneDeep(currSeq), i - 1, j + 1);
            traverse(puzzle, _.cloneDeep(currSeq), i, j - 1);
            traverse(puzzle, _.cloneDeep(currSeq), i, j + 1);
            traverse(puzzle, _.cloneDeep(currSeq), i + 1, j - 1);
            traverse(puzzle, _.cloneDeep(currSeq), i + 1, j);
            traverse(puzzle, _.cloneDeep(currSeq), i + 1, j + 1);
        }

        traverse(_.cloneDeep(that.puzzle), [], i, j);

        words.sort(function (a, b) {
            return b.length - a.length;
        });

        that.words = words;
    }

    that.computeProgress = function (word) {
        var startRow = word[0].row;
        var maxDistance = 0;
        var minDistance = 0;
        word.forEach(function (obj) {
            var difference = startRow - obj.row;
            var differenceA = Math.max(difference, 0);
            if (differenceA > maxDistance) {
                maxDistance = differenceA;
            }
            var differenceB = Math.min(difference, 0);
            if (differenceB < minDistance) {
                minDistance = differenceB;
            }
        });
        return Math.abs(that.startFromBottom ? maxDistance : minDistance);
    }

    $(function () {
        $.get('data/words.json', function (data) {
            var dictionary = {};
            var formableWords = {};
            data.forEach(function (word) {
                dictionary[word] = true;
                for (var i = 1; i < word.length; i++) {
                    formableWords[word.slice(0, i)] = true;
                }
            });
            init(dictionary, formableWords);
        });
    });
});
<commit_msg>Shuling's game<commit_after>var fn = null;

angular.module('wordBaseHack', [])
    .controller('wordBaseController', function () {

    var that = this;

    that.puzzle = [

        'RITVILAGEM',
        'EPNYDNLRNO',
        'DMACIGCILT',
        'SOROLAEDSR',
        'VSGNMNDUOI',
        'EAILITNSLW',
        'RLNITSGIHE',
        'IEGUPEUNTN',
        'NGTIHAMRIH',
        'YANSDGEDOS',
        'KELERDAIEP',
        'OYSIABMDTY',
        'DULEDNEARG'];

    that.startFromBottom = false;

    var WIDTH = that.puzzle[0].length;
    var HEIGHT = that.puzzle.length;

    for (var i = 0; i < HEIGHT; i++) {
        that.puzzle[i] = that.puzzle[i].split('');
        for (var j = 0; j < WIDTH; j++) {
            that.puzzle[i][j] = {
                letter: that.puzzle[i][j],
                highlighted: false
            }
        }
    }

    function init (dictionary, formableWords) {
        that.dictionary = dictionary;
        that.formableWords = formableWords
        console.log('READY!');
    }

    that.words = [];

    that.getWordFromSequence = function (sequence) {
        return sequence.map(function (object) {
            return object.letter;
        }).join('');
    };

    function resetHighlighting () {
        for (var i = 0; i < HEIGHT; i++) {
            for (var j = 0; j < WIDTH; j++) {
                that.puzzle[i][j].highlighted = false;
            }
        }
    }

    that.highlightLetters = function (sequence) {
        resetHighlighting();
        sequence.forEach(function (item) {
            that.puzzle[item.row][item.col].highlighted = true;
        });
    }

    that.findWordsFromCell = function (i, j) {
        resetHighlighting();
        var words = [];
        var count = 0;
        function traverse(currPuzzle, currSeq, i, j) {
            count++;
            if (i < 0 || i >= HEIGHT ||
                j < 0 ||
                j >= WIDTH) {
                return;
            }
            if (currPuzzle[i][j] === '*') {
                return;
            }
            currSeq.push({
                letter: currPuzzle[i][j].letter,
                row: i,
                col: j
            });
            currPuzzle[i][j].letter = '*';
            var puzzle = _.cloneDeep(currPuzzle);
            var currentWord = that.getWordFromSequence(currSeq);
            if (that.dictionary[currentWord]) {
                words.push(currSeq);
            }
            if (!that.formableWords[currentWord]) {
                return;
            }
            traverse(puzzle, _.cloneDeep(currSeq), i - 1, j - 1);
            traverse(puzzle, _.cloneDeep(currSeq), i - 1, j);
            traverse(puzzle, _.cloneDeep(currSeq), i - 1, j + 1);
            traverse(puzzle, _.cloneDeep(currSeq), i, j - 1);
            traverse(puzzle, _.cloneDeep(currSeq), i, j + 1);
            traverse(puzzle, _.cloneDeep(currSeq), i + 1, j - 1);
            traverse(puzzle, _.cloneDeep(currSeq), i + 1, j);
            traverse(puzzle, _.cloneDeep(currSeq), i + 1, j + 1);
        }

        traverse(_.cloneDeep(that.puzzle), [], i, j);

        words.sort(function (a, b) {
            return b.length - a.length;
        });

        that.words = words;
    }

    that.computeProgress = function (word) {
        var startRow = word[0].row;
        var maxDistance = 0;
        var minDistance = 0;
        word.forEach(function (obj) {
            var difference = startRow - obj.row;
            var differenceA = Math.max(difference, 0);
            if (differenceA > maxDistance) {
                maxDistance = differenceA;
            }
            var differenceB = Math.min(difference, 0);
            if (differenceB < minDistance) {
                minDistance = differenceB;
            }
        });
        return Math.abs(that.startFromBottom ? maxDistance : minDistance);
    }

    $(function () {
        $.get('data/words.json', function (data) {
            var dictionary = {};
            var formableWords = {};
            data.forEach(function (word) {
                dictionary[word] = true;
                for (var i = 1; i < word.length; i++) {
                    formableWords[word.slice(0, i)] = true;
                }
            });
            init(dictionary, formableWords);
        });
    });
});
<|endoftext|>