mirror of
https://github.com/ysoftdevs/pf2015.git
synced 2026-01-13 15:24:03 +01:00
370 lines
11 KiB
JavaScript
370 lines
11 KiB
JavaScript
angular.module('app', ['angular-flippy', 'level-selector', 'level-complete'])
|
|
.controller('PexesoController', function($scope, $timeout, $rootScope) {
|
|
|
|
$scope.isLevelVisible = false;
|
|
|
|
// Is start information with confirmation visible
|
|
$scope.isStartConfirmation = true;
|
|
|
|
$scope.instructions = [];
|
|
|
|
$scope.levelIndex = 0;
|
|
|
|
// How many cards must be found as the same.
|
|
$scope.chainLength = 2;
|
|
|
|
// Which card types are active
|
|
$scope.currentCardTypes = [ 'picture', 'picture' ];
|
|
|
|
// Fit defined number of items on screen
|
|
$scope.containerStyle = {
|
|
"max-width": "280px"
|
|
};
|
|
|
|
// Card style - define dimensions
|
|
$scope.cardStyle = {
|
|
width: "60px",
|
|
height: "60px"
|
|
};
|
|
|
|
/**
|
|
* Level descriptor:
|
|
*
|
|
* totalCards - How many cards are on the board
|
|
* chainLength - How many cards must be found from the same kind
|
|
* cardType - Define type of game
|
|
* - picture - display image of item
|
|
* - key - display ID as text
|
|
* - "name" - use text field from card set
|
|
*/
|
|
$scope.levels = [
|
|
{
|
|
levelName: "01: 2 Pictures",
|
|
instructions: ['fa-picture-o', 'fa-plus', 'fa-picture-o'],
|
|
totalCards: 2*2,
|
|
cardsPerRow: 2,
|
|
chainLength: 2,
|
|
cardSet: basicCards,
|
|
cardTypes: ['picture', 'picture']
|
|
},
|
|
{
|
|
levelName: "02: 3 Pictures",
|
|
instructions: ['fa-picture-o', 'fa-plus', 'fa-picture-o', 'fa-plus', 'fa-picture-o'],
|
|
totalCards: 3*3,
|
|
cardsPerRow: 3,
|
|
chainLength: 3,
|
|
cardSet: basicCards,
|
|
cardTypes: ['picture', 'picture', 'picture']
|
|
},
|
|
{
|
|
levelName: "03: 4 Pictures",
|
|
instructions: ['fa-picture-o', 'fa-plus', 'fa-picture-o', 'fa-plus', 'fa-picture-o', 'fa-plus', 'fa-picture-o'],
|
|
totalCards: 4*4,
|
|
cardsPerRow: 4,
|
|
chainLength: 4,
|
|
cardSet: basicCards,
|
|
cardTypes: ['picture', 'picture', 'picture', 'picture']
|
|
}, {
|
|
levelName: "04: Math",
|
|
instructions: ['fa-circle-o', 'fa-plus', 'fa-calculator'],
|
|
totalCards: 4*4,
|
|
cardsPerRow: 4,
|
|
chainLength: 2,
|
|
cardSet: mathCards,
|
|
cardTypes: ['arabic', 'math']
|
|
}, {
|
|
levelName: "05: Roman",
|
|
instructions: ['fa-circle-o', 'fa-plus', 'fa-file-excel-o'],
|
|
totalCards: 4*4,
|
|
cardsPerRow: 4,
|
|
chainLength: 2,
|
|
cardSet: mathCards,
|
|
cardTypes: ['arabic', 'roman']
|
|
}, {
|
|
levelName: "06: Japanese",
|
|
instructions: ['fa-circle-o', 'fa-plus', 'fa-jpy'],
|
|
totalCards: 4*4,
|
|
cardsPerRow: 4,
|
|
chainLength: 2,
|
|
cardSet: mathCards,
|
|
cardTypes: ['arabic', 'japanese']
|
|
}, {
|
|
levelName: "07: 4x MIX",
|
|
instructions: ['fa-circle-o', 'fa-plus', 'fa-calculator', 'fa-plus', 'fa-file-excel-o', 'fa-plus', 'fa-jpy'],
|
|
totalCards: 4*4,
|
|
cardsPerRow: 4,
|
|
chainLength: 4,
|
|
cardSet: mathCards,
|
|
cardTypes: ['arabic', 'math', 'roman', 'japanese']
|
|
},{
|
|
levelName: "08: Morse",
|
|
instructions: ['fa-font', 'fa-plus', 'fa-circle', 'fa-minus'],
|
|
totalCards: 4*4,
|
|
cardsPerRow: 4,
|
|
chainLength: 2,
|
|
cardSet: alphabetCards,
|
|
cardTypes: ['key', 'morse']
|
|
}, {
|
|
levelName: "Finale",
|
|
instructions: ['fa-smile-o'],
|
|
totalCards: 7*1,
|
|
cardsPerRow: 7,
|
|
chainLength: 7,
|
|
cardSet: finaleCards,
|
|
cardTypes: ['1','2','3','4','5','6','7']
|
|
}
|
|
];
|
|
|
|
$scope.currentLevel = $scope.levels[0];
|
|
|
|
$scope.cards = basicCards;
|
|
|
|
$scope.board = [];
|
|
|
|
/**
|
|
* Generate playing card object.
|
|
*/
|
|
$scope.getCard = function(card, cardId, index) {
|
|
return {
|
|
cardId: cardId,
|
|
card: card,
|
|
cardType: 'picture',
|
|
index: index,
|
|
state: 'mystery',
|
|
flipState: ''
|
|
};
|
|
};
|
|
|
|
$scope.isFinallevel = function() {
|
|
return ($scope.levelIndex == $scope.levels.length - 1);
|
|
};
|
|
|
|
/**
|
|
* Generate game board.
|
|
*/
|
|
$scope.generateBoard = function(totalCount) {
|
|
$scope.board = [];
|
|
var fullStack = []
|
|
var stack = [];
|
|
angular.forEach($scope.currentLevel.cardSet, function(card, cardId) {
|
|
fullStack.push($scope.getCard(card, cardId, 1));
|
|
});
|
|
|
|
for (var groupIndex = 0; groupIndex < totalCount / $scope.chainLength; groupIndex++) {
|
|
var cardIndex = Math.floor((Math.random() * fullStack.length));
|
|
var card = fullStack[cardIndex];
|
|
fullStack.splice(cardIndex, 1);
|
|
for (var instanceIndex = 0; instanceIndex < $scope.chainLength; instanceIndex++) {
|
|
var tempCard = $scope.getCard(card, card.cardId, instanceIndex + 1);
|
|
tempCard.cardType = $scope.currentCardTypes[instanceIndex];
|
|
if (tempCard.cardType == 'picture') {
|
|
tempCard.image = tempCard.cardId;
|
|
tempCard.label = "";
|
|
} else {
|
|
tempCard.image = 'question';
|
|
if (tempCard.cardType == 'key') {
|
|
tempCard.label = tempCard.cardId;
|
|
} else {
|
|
tempCard.label = tempCard.card.card[tempCard.cardType];
|
|
}
|
|
}
|
|
stack.push(tempCard);
|
|
}
|
|
}
|
|
|
|
var isFinalLevel = $scope.isFinallevel();
|
|
for (var index = 0; index < totalCount; index++) {
|
|
var coordinate = 0;
|
|
|
|
if (!isFinalLevel) {
|
|
coordinate = Math.floor((Math.random()* stack.length));
|
|
}
|
|
|
|
$scope.board.push(stack[coordinate]);
|
|
stack.splice(coordinate, 1);
|
|
}
|
|
};
|
|
|
|
$scope.selectionCounter = 0;
|
|
|
|
$scope.selectedCards = [];
|
|
|
|
/**
|
|
* Set state of all selected cards to defined state.
|
|
*/
|
|
$scope.setSelectionState = function(state) {
|
|
$scope.selectionCounter = 0;
|
|
angular.forEach($scope.selectedCards, function(card) {
|
|
card.state = state;
|
|
if (state == "mystery") {
|
|
card.flipState = '';
|
|
} else {
|
|
card.flipState = 'flipped';
|
|
}
|
|
});
|
|
$scope.selectedCards = [];
|
|
};
|
|
|
|
/**
|
|
* Check whether all cards were selected.
|
|
*/
|
|
$scope.areAllSelectedSame = function() {
|
|
var previous = null;
|
|
|
|
// At least n-cards must match
|
|
if ($scope.selectedCards.length < $scope.chainLength) {
|
|
return false;
|
|
}
|
|
|
|
for (var index=0; index<$scope.selectedCards.length; index++) {
|
|
|
|
var card = $scope.selectedCards[index];
|
|
if (previous === null) {
|
|
previous = card;
|
|
} else {
|
|
if (previous.cardId != card.cardId) {
|
|
return false;
|
|
}
|
|
}
|
|
}
|
|
return true;
|
|
};
|
|
|
|
/**
|
|
* Check whether all items on the board are solved.
|
|
*/
|
|
$scope.isLevelComplete = function() {
|
|
for (var index=0; index < $scope.board.length; index++) {
|
|
var item = $scope.board[index];
|
|
if (item.state != "solved") {
|
|
return false;
|
|
}
|
|
}
|
|
return true;
|
|
};
|
|
|
|
/**
|
|
* Reset selection of current cards
|
|
*/
|
|
$scope.resetSelection = function() {
|
|
$scope.setSelectionState('mystery');
|
|
};
|
|
|
|
/**
|
|
* Click handler to select card.
|
|
*/
|
|
$scope.selectCard = function(card) {
|
|
// only mystery cards are processed
|
|
if (card.state != 'mystery') {
|
|
return;
|
|
}
|
|
|
|
$scope.selectionCounter += 1;
|
|
|
|
|
|
if ($scope.selectionCounter == $scope.chainLength + 1) {
|
|
$scope.resetSelection();
|
|
return;
|
|
} else {
|
|
$scope.selectedCards.push(card);
|
|
}
|
|
|
|
if (card.state == 'mystery') {
|
|
card.state = 'selected' + $scope.selectionCounter;
|
|
card.flipState = 'flipped';
|
|
}
|
|
|
|
if ($scope.areAllSelectedSame()) {
|
|
$scope.setSelectionState('solved');
|
|
if ($scope.isLevelComplete()) {
|
|
$timeout($scope.completeLevel, 2000);
|
|
}
|
|
} else if ($scope.selectionCounter == $scope.chainLength) {
|
|
$timeout($scope.resetSelection, 1000);
|
|
}
|
|
|
|
};
|
|
|
|
|
|
/**
|
|
* Adjust size of card
|
|
*/
|
|
$scope.computeCardSize = function(cardsPerRow) {
|
|
var cardSize = Math.floor(Math.min(window.innerWidth, window.innerHeight) / cardsPerRow) - 20;
|
|
|
|
if (cardSize < 14) {
|
|
cardSize = 14;
|
|
}
|
|
|
|
var fontSize = Math.floor(cardSize * 0.6);
|
|
if (fontSize < 12) {
|
|
fontSize = 12;
|
|
}
|
|
|
|
$scope.cardStyle = {
|
|
width: cardSize + "px",
|
|
height: cardSize + "px",
|
|
"font-size": fontSize + "px"
|
|
};
|
|
|
|
var paddingLeft = Math.floor((window.innerWidth - (cardSize + 10) * cardsPerRow) / 2);
|
|
var paddingTop = Math.floor((window.innerHeight - (cardSize + 10) * cardsPerRow) / 2) - 32;
|
|
|
|
if (paddingLeft < 0) {
|
|
paddingLeft = 0;
|
|
}
|
|
|
|
if (paddingTop < 0) {
|
|
paddingTop = 0;
|
|
}
|
|
|
|
$scope.containerStyle = {
|
|
"max-width": (cardSize + 20) * cardsPerRow + "px",
|
|
"padding-left": paddingLeft + "px",
|
|
"margin-top": paddingTop + "px"
|
|
};
|
|
};
|
|
|
|
/**
|
|
* Start Level
|
|
*/
|
|
$scope.initLevel = function(event, args) {
|
|
$scope.levelIndex = args.levelIndex;
|
|
$scope.currentLevel = $scope.levels[$scope.levelIndex];
|
|
$scope.currentCardTypes = $scope.currentLevel.cardTypes;
|
|
$scope.instructions = $scope.currentLevel.instructions;
|
|
$scope.chainLength = $scope.currentLevel.chainLength;
|
|
|
|
$scope.computeCardSize($scope.currentLevel.cardsPerRow);
|
|
$scope.generateBoard($scope.currentLevel.totalCards);
|
|
|
|
$scope.isLevelVisible = true;
|
|
$scope.isStartConfirmation= true;
|
|
};
|
|
|
|
$scope.playLevel = function() {
|
|
$scope.isStartConfirmation = false;
|
|
}
|
|
|
|
/**
|
|
* Level complete - display level outro screen.
|
|
*/
|
|
$scope.completeLevel = function() {
|
|
var args = {
|
|
levelIndex: $scope.levelIndex,
|
|
isFinalLevel: $scope.isFinallevel()
|
|
};
|
|
$rootScope.$emit('completeLevel', args);
|
|
};
|
|
|
|
/**
|
|
* Return to level selection screen
|
|
*/
|
|
$scope.cancelLevel = function() {
|
|
$scope.isLevelVisible = false;
|
|
$rootScope.$emit('cancelLevel', {});
|
|
};
|
|
|
|
$rootScope.$on('startLevel', $scope.initLevel);
|
|
|
|
}); |