Файловый менеджер - Редактировать - /home/jogoso94/public_html/jogos/master_chess/js/main.js
�азад
(function () { 'use strict'; var document = typeof window !== 'undefined' && typeof window.document !== 'undefined' ? window.document : {}; var isCommonjs = typeof module !== 'undefined' && module.exports; var fn = (function () { var val; var fnMap = [ [ 'requestFullscreen', 'exitFullscreen', 'fullscreenElement', 'fullscreenEnabled', 'fullscreenchange', 'fullscreenerror' ], // New WebKit [ 'webkitRequestFullscreen', 'webkitExitFullscreen', 'webkitFullscreenElement', 'webkitFullscreenEnabled', 'webkitfullscreenchange', 'webkitfullscreenerror' ], // Old WebKit [ 'webkitRequestFullScreen', 'webkitCancelFullScreen', 'webkitCurrentFullScreenElement', 'webkitCancelFullScreen', 'webkitfullscreenchange', 'webkitfullscreenerror' ], [ 'mozRequestFullScreen', 'mozCancelFullScreen', 'mozFullScreenElement', 'mozFullScreenEnabled', 'mozfullscreenchange', 'mozfullscreenerror' ], [ 'msRequestFullscreen', 'msExitFullscreen', 'msFullscreenElement', 'msFullscreenEnabled', 'MSFullscreenChange', 'MSFullscreenError' ] ]; var i = 0; var l = fnMap.length; var ret = {}; for (; i < l; i++) { val = fnMap[i]; if (val && val[1] in document) { for (i = 0; i < val.length; i++) { ret[fnMap[0][i]] = val[i]; } return ret; } } return false; })(); var eventNameMap = { change: fn.fullscreenchange, error: fn.fullscreenerror }; var screenfull = { request: function (element) { return new Promise(function (resolve, reject) { var onFullScreenEntered = function () { this.off('change', onFullScreenEntered); resolve(); }.bind(this); this.on('change', onFullScreenEntered); element = element || document.documentElement; Promise.resolve(element[fn.requestFullscreen]()).catch(reject); }.bind(this)); }, exit: function () { return new Promise(function (resolve, reject) { if (!this.isFullscreen) { resolve(); return; } var onFullScreenExit = function () { this.off('change', onFullScreenExit); resolve(); }.bind(this); this.on('change', onFullScreenExit); Promise.resolve(document[fn.exitFullscreen]()).catch(reject); }.bind(this)); }, toggle: function (element) { return this.isFullscreen ? this.exit() : this.request(element); }, onchange: function (callback) { this.on('change', callback); }, onerror: function (callback) { this.on('error', callback); }, on: function (event, callback) { var eventName = eventNameMap[event]; if (eventName) { document.addEventListener(eventName, callback, false); } }, off: function (event, callback) { var eventName = eventNameMap[event]; if (eventName) { document.removeEventListener(eventName, callback, false); } }, raw: fn }; if (!fn) { if (isCommonjs) { module.exports = {isEnabled: false}; } else { window.screenfull = {isEnabled: false}; } return; } Object.defineProperties(screenfull, { isFullscreen: { get: function () { return Boolean(document[fn.fullscreenElement]); } }, element: { enumerable: true, get: function () { return document[fn.fullscreenElement]; } }, isEnabled: { enumerable: true, get: function () { // Coerce to boolean in case of old WebKit return Boolean(document[fn.fullscreenEnabled]); } } }); if (isCommonjs) { module.exports = screenfull; } else { window.screenfull = screenfull; } })(); /*! * Platform.js <https://mths.be/platform> * Copyright 2014-2018 Benjamin Tan <https://bnjmnt4n.now.sh/> * Copyright 2011-2013 John-David Dalton * Available under MIT license <https://mths.be/mit> */ ;(function() { 'use strict'; /** Used to determine if values are of the language type `Object`. */ var objectTypes = { 'function': true, 'object': true }; /** Used as a reference to the global object. */ var root = (objectTypes[typeof window] && window) || this; /** Backup possible global object. */ var oldRoot = root; /** Detect free variable `exports`. */ var freeExports = objectTypes[typeof exports] && exports; /** Detect free variable `module`. */ var freeModule = objectTypes[typeof module] && module && !module.nodeType && module; /** Detect free variable `global` from Node.js or Browserified code and use it as `root`. */ var freeGlobal = freeExports && freeModule && typeof global == 'object' && global; if (freeGlobal && (freeGlobal.global === freeGlobal || freeGlobal.window === freeGlobal || freeGlobal.self === freeGlobal)) { root = freeGlobal; } /** * Used as the maximum length of an array-like object. * See the [ES6 spec](http://people.mozilla.org/~jorendorff/es6-draft.html#sec-tolength) * for more details. */ var maxSafeInteger = Math.pow(2, 53) - 1; /** Regular expression to detect Opera. */ var reOpera = /\bOpera/; /** Possible global object. */ var thisBinding = this; /** Used for native method references. */ var objectProto = Object.prototype; /** Used to check for own properties of an object. */ var hasOwnProperty = objectProto.hasOwnProperty; /** Used to resolve the internal `[[Class]]` of values. */ var toString = objectProto.toString; /*--------------------------------------------------------------------------*/ /** * Capitalizes a string value. * * @private * @param {string} string The string to capitalize. * @returns {string} The capitalized string. */ function capitalize(string) { string = String(string); return string.charAt(0).toUpperCase() + string.slice(1); } /** * A utility function to clean up the OS name. * * @private * @param {string} os The OS name to clean up. * @param {string} [pattern] A `RegExp` pattern matching the OS name. * @param {string} [label] A label for the OS. */ function cleanupOS(os, pattern, label) { // Platform tokens are defined at: // http://msdn.microsoft.com/en-us/library/ms537503(VS.85).aspx // http://web.archive.org/web/20081122053950/http://msdn.microsoft.com/en-us/library/ms537503(VS.85).aspx var data = { '10.0': '10', '6.4': '10 Technical Preview', '6.3': '8.1', '6.2': '8', '6.1': 'Server 2008 R2 / 7', '6.0': 'Server 2008 / Vista', '5.2': 'Server 2003 / XP 64-bit', '5.1': 'XP', '5.01': '2000 SP1', '5.0': '2000', '4.0': 'NT', '4.90': 'ME' }; // Detect Windows version from platform tokens. if (pattern && label && /^Win/i.test(os) && !/^Windows Phone /i.test(os) && (data = data[/[\d.]+$/.exec(os)])) { os = 'Windows ' + data; } // Correct character case and cleanup string. os = String(os); if (pattern && label) { os = os.replace(RegExp(pattern, 'i'), label); } os = format( os.replace(/ ce$/i, ' CE') .replace(/\bhpw/i, 'web') .replace(/\bMacintosh\b/, 'Mac OS') .replace(/_PowerPC\b/i, ' OS') .replace(/\b(OS X) [^ \d]+/i, '$1') .replace(/\bMac (OS X)\b/, '$1') .replace(/\/(\d)/, ' $1') .replace(/_/g, '.') .replace(/(?: BePC|[ .]*fc[ \d.]+)$/i, '') .replace(/\bx86\.64\b/gi, 'x86_64') .replace(/\b(Windows Phone) OS\b/, '$1') .replace(/\b(Chrome OS \w+) [\d.]+\b/, '$1') .split(' on ')[0] ); return os; } /** * An iteration utility for arrays and objects. * * @private * @param {Array|Object} object The object to iterate over. * @param {Function} callback The function called per iteration. */ function each(object, callback) { var index = -1, length = object ? object.length : 0; if (typeof length == 'number' && length > -1 && length <= maxSafeInteger) { while (++index < length) { callback(object[index], index, object); } } else { forOwn(object, callback); } } /** * Trim and conditionally capitalize string values. * * @private * @param {string} string The string to format. * @returns {string} The formatted string. */ function format(string) { string = trim(string); return /^(?:webOS|i(?:OS|P))/.test(string) ? string : capitalize(string); } /** * Iterates over an object's own properties, executing the `callback` for each. * * @private * @param {Object} object The object to iterate over. * @param {Function} callback The function executed per own property. */ function forOwn(object, callback) { for (var key in object) { if (hasOwnProperty.call(object, key)) { callback(object[key], key, object); } } } /** * Gets the internal `[[Class]]` of a value. * * @private * @param {*} value The value. * @returns {string} The `[[Class]]`. */ function getClassOf(value) { return value == null ? capitalize(value) : toString.call(value).slice(8, -1); } /** * Host objects can return type values that are different from their actual * data type. The objects we are concerned with usually return non-primitive * types of "object", "function", or "unknown". * * @private * @param {*} object The owner of the property. * @param {string} property The property to check. * @returns {boolean} Returns `true` if the property value is a non-primitive, else `false`. */ function isHostType(object, property) { var type = object != null ? typeof object[property] : 'number'; return !/^(?:boolean|number|string|undefined)$/.test(type) && (type == 'object' ? !!object[property] : true); } /** * Prepares a string for use in a `RegExp` by making hyphens and spaces optional. * * @private * @param {string} string The string to qualify. * @returns {string} The qualified string. */ function qualify(string) { return String(string).replace(/([ -])(?!$)/g, '$1?'); } /** * A bare-bones `Array#reduce` like utility function. * * @private * @param {Array} array The array to iterate over. * @param {Function} callback The function called per iteration. * @returns {*} The accumulated result. */ function reduce(array, callback) { var accumulator = null; each(array, function(value, index) { accumulator = callback(accumulator, value, index, array); }); return accumulator; } /** * Removes leading and trailing whitespace from a string. * * @private * @param {string} string The string to trim. * @returns {string} The trimmed string. */ function trim(string) { return String(string).replace(/^ +| +$/g, ''); } /*--------------------------------------------------------------------------*/ /** * Creates a new platform object. * * @memberOf platform * @param {Object|string} [ua=navigator.userAgent] The user agent string or * context object. * @returns {Object} A platform object. */ function parse(ua) { /** The environment context object. */ var context = root; /** Used to flag when a custom context is provided. */ var isCustomContext = ua && typeof ua == 'object' && getClassOf(ua) != 'String'; // Juggle arguments. if (isCustomContext) { context = ua; ua = null; } /** Browser navigator object. */ var nav = context.navigator || {}; /** Browser user agent string. */ var userAgent = nav.userAgent || ''; ua || (ua = userAgent); /** Used to flag when `thisBinding` is the [ModuleScope]. */ var isModuleScope = isCustomContext || thisBinding == oldRoot; /** Used to detect if browser is like Chrome. */ var likeChrome = isCustomContext ? !!nav.likeChrome : /\bChrome\b/.test(ua) && !/internal|\n/i.test(toString.toString()); /** Internal `[[Class]]` value shortcuts. */ var objectClass = 'Object', airRuntimeClass = isCustomContext ? objectClass : 'ScriptBridgingProxyObject', enviroClass = isCustomContext ? objectClass : 'Environment', javaClass = (isCustomContext && context.java) ? 'JavaPackage' : getClassOf(context.java), phantomClass = isCustomContext ? objectClass : 'RuntimeObject'; /** Detect Java environments. */ var java = /\bJava/.test(javaClass) && context.java; /** Detect Rhino. */ var rhino = java && getClassOf(context.environment) == enviroClass; /** A character to represent alpha. */ var alpha = java ? 'a' : '\u03b1'; /** A character to represent beta. */ var beta = java ? 'b' : '\u03b2'; /** Browser document object. */ var doc = context.document || {}; /** * Detect Opera browser (Presto-based). * http://www.howtocreate.co.uk/operaStuff/operaObject.html * http://dev.opera.com/articles/view/opera-mini-web-content-authoring-guidelines/#operamini */ var opera = context.operamini || context.opera; /** Opera `[[Class]]`. */ var operaClass = reOpera.test(operaClass = (isCustomContext && opera) ? opera['[[Class]]'] : getClassOf(opera)) ? operaClass : (opera = null); /*------------------------------------------------------------------------*/ /** Temporary variable used over the script's lifetime. */ var data; /** The CPU architecture. */ var arch = ua; /** Platform description array. */ var description = []; /** Platform alpha/beta indicator. */ var prerelease = null; /** A flag to indicate that environment features should be used to resolve the platform. */ var useFeatures = ua == userAgent; /** The browser/environment version. */ var version = useFeatures && opera && typeof opera.version == 'function' && opera.version(); /** A flag to indicate if the OS ends with "/ Version" */ var isSpecialCasedOS; /* Detectable layout engines (order is important). */ var layout = getLayout([ { 'label': 'EdgeHTML', 'pattern': 'Edge' }, 'Trident', { 'label': 'WebKit', 'pattern': 'AppleWebKit' }, 'iCab', 'Presto', 'NetFront', 'Tasman', 'KHTML', 'Gecko' ]); /* Detectable browser names (order is important). */ var name = getName([ 'Adobe AIR', 'Arora', 'Avant Browser', 'Breach', 'Camino', 'Electron', 'Epiphany', 'Fennec', 'Flock', 'Galeon', 'GreenBrowser', 'iCab', 'Iceweasel', 'K-Meleon', 'Konqueror', 'Lunascape', 'Maxthon', { 'label': 'Microsoft Edge', 'pattern': 'Edge' }, 'Midori', 'Nook Browser', 'PaleMoon', 'PhantomJS', 'Raven', 'Rekonq', 'RockMelt', { 'label': 'Samsung Internet', 'pattern': 'SamsungBrowser' }, 'SeaMonkey', { 'label': 'Silk', 'pattern': '(?:Cloud9|Silk-Accelerated)' }, 'Sleipnir', 'SlimBrowser', { 'label': 'SRWare Iron', 'pattern': 'Iron' }, 'Sunrise', 'Swiftfox', 'Waterfox', 'WebPositive', 'Opera Mini', { 'label': 'Opera Mini', 'pattern': 'OPiOS' }, 'Opera', { 'label': 'Opera', 'pattern': 'OPR' }, 'Chrome', { 'label': 'Chrome Mobile', 'pattern': '(?:CriOS|CrMo)' }, { 'label': 'Firefox', 'pattern': '(?:Firefox|Minefield)' }, { 'label': 'Firefox for iOS', 'pattern': 'FxiOS' }, { 'label': 'IE', 'pattern': 'IEMobile' }, { 'label': 'IE', 'pattern': 'MSIE' }, 'Safari' ]); /* Detectable products (order is important). */ var product = getProduct([ { 'label': 'BlackBerry', 'pattern': 'BB10' }, 'BlackBerry', { 'label': 'Galaxy S', 'pattern': 'GT-I9000' }, { 'label': 'Galaxy S2', 'pattern': 'GT-I9100' }, { 'label': 'Galaxy S3', 'pattern': 'GT-I9300' }, { 'label': 'Galaxy S4', 'pattern': 'GT-I9500' }, { 'label': 'Galaxy S5', 'pattern': 'SM-G900' }, { 'label': 'Galaxy S6', 'pattern': 'SM-G920' }, { 'label': 'Galaxy S6 Edge', 'pattern': 'SM-G925' }, { 'label': 'Galaxy S7', 'pattern': 'SM-G930' }, { 'label': 'Galaxy S7 Edge', 'pattern': 'SM-G935' }, 'Google TV', 'Lumia', 'iPad', 'iPod', 'iPhone', 'Kindle', { 'label': 'Kindle Fire', 'pattern': '(?:Cloud9|Silk-Accelerated)' }, 'Nexus', 'Nook', 'PlayBook', 'PlayStation Vita', 'PlayStation', 'TouchPad', 'Transformer', { 'label': 'Wii U', 'pattern': 'WiiU' }, 'Wii', 'Xbox One', { 'label': 'Xbox 360', 'pattern': 'Xbox' }, 'Xoom' ]); /* Detectable manufacturers. */ var manufacturer = getManufacturer({ 'Apple': { 'iPad': 1, 'iPhone': 1, 'iPod': 1 }, 'Archos': {}, 'Amazon': { 'Kindle': 1, 'Kindle Fire': 1 }, 'Asus': { 'Transformer': 1 }, 'Barnes & Noble': { 'Nook': 1 }, 'BlackBerry': { 'PlayBook': 1 }, 'Google': { 'Google TV': 1, 'Nexus': 1 }, 'HP': { 'TouchPad': 1 }, 'HTC': {}, 'LG': {}, 'Microsoft': { 'Xbox': 1, 'Xbox One': 1 }, 'Motorola': { 'Xoom': 1 }, 'Nintendo': { 'Wii U': 1, 'Wii': 1 }, 'Nokia': { 'Lumia': 1 }, 'Samsung': { 'Galaxy S': 1, 'Galaxy S2': 1, 'Galaxy S3': 1, 'Galaxy S4': 1 }, 'Sony': { 'PlayStation': 1, 'PlayStation Vita': 1 } }); /* Detectable operating systems (order is important). */ var os = getOS([ 'Windows Phone', 'Android', 'CentOS', { 'label': 'Chrome OS', 'pattern': 'CrOS' }, 'Debian', 'Fedora', 'FreeBSD', 'Gentoo', 'Haiku', 'Kubuntu', 'Linux Mint', 'OpenBSD', 'Red Hat', 'SuSE', 'Ubuntu', 'Xubuntu', 'Cygwin', 'Symbian OS', 'hpwOS', 'webOS ', 'webOS', 'Tablet OS', 'Tizen', 'Linux', 'Mac OS X', 'Macintosh', 'Mac', 'Windows 98;', 'Windows ' ]); /*------------------------------------------------------------------------*/ /** * Picks the layout engine from an array of guesses. * * @private * @param {Array} guesses An array of guesses. * @returns {null|string} The detected layout engine. */ function getLayout(guesses) { return reduce(guesses, function(result, guess) { return result || RegExp('\\b' + ( guess.pattern || qualify(guess) ) + '\\b', 'i').exec(ua) && (guess.label || guess); }); } /** * Picks the manufacturer from an array of guesses. * * @private * @param {Array} guesses An object of guesses. * @returns {null|string} The detected manufacturer. */ function getManufacturer(guesses) { return reduce(guesses, function(result, value, key) { // Lookup the manufacturer by product or scan the UA for the manufacturer. return result || ( value[product] || value[/^[a-z]+(?: +[a-z]+\b)*/i.exec(product)] || RegExp('\\b' + qualify(key) + '(?:\\b|\\w*\\d)', 'i').exec(ua) ) && key; }); } /** * Picks the browser name from an array of guesses. * * @private * @param {Array} guesses An array of guesses. * @returns {null|string} The detected browser name. */ function getName(guesses) { return reduce(guesses, function(result, guess) { return result || RegExp('\\b' + ( guess.pattern || qualify(guess) ) + '\\b', 'i').exec(ua) && (guess.label || guess); }); } /** * Picks the OS name from an array of guesses. * * @private * @param {Array} guesses An array of guesses. * @returns {null|string} The detected OS name. */ function getOS(guesses) { return reduce(guesses, function(result, guess) { var pattern = guess.pattern || qualify(guess); if (!result && (result = RegExp('\\b' + pattern + '(?:/[\\d.]+|[ \\w.]*)', 'i').exec(ua) )) { result = cleanupOS(result, pattern, guess.label || guess); } return result; }); } /** * Picks the product name from an array of guesses. * * @private * @param {Array} guesses An array of guesses. * @returns {null|string} The detected product name. */ function getProduct(guesses) { return reduce(guesses, function(result, guess) { var pattern = guess.pattern || qualify(guess); if (!result && (result = RegExp('\\b' + pattern + ' *\\d+[.\\w_]*', 'i').exec(ua) || RegExp('\\b' + pattern + ' *\\w+-[\\w]*', 'i').exec(ua) || RegExp('\\b' + pattern + '(?:; *(?:[a-z]+[_-])?[a-z]+\\d+|[^ ();-]*)', 'i').exec(ua) )) { // Split by forward slash and append product version if needed. if ((result = String((guess.label && !RegExp(pattern, 'i').test(guess.label)) ? guess.label : result).split('/'))[1] && !/[\d.]+/.test(result[0])) { result[0] += ' ' + result[1]; } // Correct character case and cleanup string. guess = guess.label || guess; result = format(result[0] .replace(RegExp(pattern, 'i'), guess) .replace(RegExp('; *(?:' + guess + '[_-])?', 'i'), ' ') .replace(RegExp('(' + guess + ')[-_.]?(\\w)', 'i'), '$1 $2')); } return result; }); } /** * Resolves the version using an array of UA patterns. * * @private * @param {Array} patterns An array of UA patterns. * @returns {null|string} The detected version. */ function getVersion(patterns) { return reduce(patterns, function(result, pattern) { return result || (RegExp(pattern + '(?:-[\\d.]+/|(?: for [\\w-]+)?[ /-])([\\d.]+[^ ();/_-]*)', 'i').exec(ua) || 0)[1] || null; }); } /** * Returns `platform.description` when the platform object is coerced to a string. * * @name toString * @memberOf platform * @returns {string} Returns `platform.description` if available, else an empty string. */ function toStringPlatform() { return this.description || ''; } /*------------------------------------------------------------------------*/ // Convert layout to an array so we can add extra details. layout && (layout = [layout]); // Detect product names that contain their manufacturer's name. if (manufacturer && !product) { product = getProduct([manufacturer]); } // Clean up Google TV. if ((data = /\bGoogle TV\b/.exec(product))) { product = data[0]; } // Detect simulators. if (/\bSimulator\b/i.test(ua)) { product = (product ? product + ' ' : '') + 'Simulator'; } // Detect Opera Mini 8+ running in Turbo/Uncompressed mode on iOS. if (name == 'Opera Mini' && /\bOPiOS\b/.test(ua)) { description.push('running in Turbo/Uncompressed mode'); } // Detect IE Mobile 11. if (name == 'IE' && /\blike iPhone OS\b/.test(ua)) { data = parse(ua.replace(/like iPhone OS/, '')); manufacturer = data.manufacturer; product = data.product; } // Detect iOS. else if (/^iP/.test(product)) { name || (name = 'Safari'); os = 'iOS' + ((data = / OS ([\d_]+)/i.exec(ua)) ? ' ' + data[1].replace(/_/g, '.') : ''); } // Detect Kubuntu. else if (name == 'Konqueror' && !/buntu/i.test(os)) { os = 'Kubuntu'; } // Detect Android browsers. else if ((manufacturer && manufacturer != 'Google' && ((/Chrome/.test(name) && !/\bMobile Safari\b/i.test(ua)) || /\bVita\b/.test(product))) || (/\bAndroid\b/.test(os) && /^Chrome/.test(name) && /\bVersion\//i.test(ua))) { name = 'Android Browser'; os = /\bAndroid\b/.test(os) ? os : 'Android'; } // Detect Silk desktop/accelerated modes. else if (name == 'Silk') { if (!/\bMobi/i.test(ua)) { os = 'Android'; description.unshift('desktop mode'); } if (/Accelerated *= *true/i.test(ua)) { description.unshift('accelerated'); } } // Detect PaleMoon identifying as Firefox. else if (name == 'PaleMoon' && (data = /\bFirefox\/([\d.]+)\b/.exec(ua))) { description.push('identifying as Firefox ' + data[1]); } // Detect Firefox OS and products running Firefox. else if (name == 'Firefox' && (data = /\b(Mobile|Tablet|TV)\b/i.exec(ua))) { os || (os = 'Firefox OS'); product || (product = data[1]); } // Detect false positives for Firefox/Safari. else if (!name || (data = !/\bMinefield\b/i.test(ua) && /\b(?:Firefox|Safari)\b/.exec(name))) { // Escape the `/` for Firefox 1. if (name && !product && /[\/,]|^[^(]+?\)/.test(ua.slice(ua.indexOf(data + '/') + 8))) { // Clear name of false positives. name = null; } // Reassign a generic name. if ((data = product || manufacturer || os) && (product || manufacturer || /\b(?:Android|Symbian OS|Tablet OS|webOS)\b/.test(os))) { name = /[a-z]+(?: Hat)?/i.exec(/\bAndroid\b/.test(os) ? os : data) + ' Browser'; } } // Add Chrome version to description for Electron. else if (name == 'Electron' && (data = (/\bChrome\/([\d.]+)\b/.exec(ua) || 0)[1])) { description.push('Chromium ' + data); } // Detect non-Opera (Presto-based) versions (order is important). if (!version) { version = getVersion([ '(?:Cloud9|CriOS|CrMo|Edge|FxiOS|IEMobile|Iron|Opera ?Mini|OPiOS|OPR|Raven|SamsungBrowser|Silk(?!/[\\d.]+$))', 'Version', qualify(name), '(?:Firefox|Minefield|NetFront)' ]); } // Detect stubborn layout engines. if ((data = layout == 'iCab' && parseFloat(version) > 3 && 'WebKit' || /\bOpera\b/.test(name) && (/\bOPR\b/.test(ua) ? 'Blink' : 'Presto') || /\b(?:Midori|Nook|Safari)\b/i.test(ua) && !/^(?:Trident|EdgeHTML)$/.test(layout) && 'WebKit' || !layout && /\bMSIE\b/i.test(ua) && (os == 'Mac OS' ? 'Tasman' : 'Trident') || layout == 'WebKit' && /\bPlayStation\b(?! Vita\b)/i.test(name) && 'NetFront' )) { layout = [data]; } // Detect Windows Phone 7 desktop mode. if (name == 'IE' && (data = (/; *(?:XBLWP|ZuneWP)(\d+)/i.exec(ua) || 0)[1])) { name += ' Mobile'; os = 'Windows Phone ' + (/\+$/.test(data) ? data : data + '.x'); description.unshift('desktop mode'); } // Detect Windows Phone 8.x desktop mode. else if (/\bWPDesktop\b/i.test(ua)) { name = 'IE Mobile'; os = 'Windows Phone 8.x'; description.unshift('desktop mode'); version || (version = (/\brv:([\d.]+)/.exec(ua) || 0)[1]); } // Detect IE 11 identifying as other browsers. else if (name != 'IE' && layout == 'Trident' && (data = /\brv:([\d.]+)/.exec(ua))) { if (name) { description.push('identifying as ' + name + (version ? ' ' + version : '')); } name = 'IE'; version = data[1]; } // Leverage environment features. if (useFeatures) { // Detect server-side environments. // Rhino has a global function while others have a global object. if (isHostType(context, 'global')) { if (java) { data = java.lang.System; arch = data.getProperty('os.arch'); os = os || data.getProperty('os.name') + ' ' + data.getProperty('os.version'); } if (rhino) { try { version = context.require('ringo/engine').version.join('.'); name = 'RingoJS'; } catch(e) { if ((data = context.system) && data.global.system == context.system) { name = 'Narwhal'; os || (os = data[0].os || null); } } if (!name) { name = 'Rhino'; } } else if ( typeof context.process == 'object' && !context.process.browser && (data = context.process) ) { if (typeof data.versions == 'object') { if (typeof data.versions.electron == 'string') { description.push('Node ' + data.versions.node); name = 'Electron'; version = data.versions.electron; } else if (typeof data.versions.nw == 'string') { description.push('Chromium ' + version, 'Node ' + data.versions.node); name = 'NW.js'; version = data.versions.nw; } } if (!name) { name = 'Node.js'; arch = data.arch; os = data.platform; version = /[\d.]+/.exec(data.version); version = version ? version[0] : null; } } } // Detect Adobe AIR. else if (getClassOf((data = context.runtime)) == airRuntimeClass) { name = 'Adobe AIR'; os = data.flash.system.Capabilities.os; } // Detect PhantomJS. else if (getClassOf((data = context.phantom)) == phantomClass) { name = 'PhantomJS'; version = (data = data.version || null) && (data.major + '.' + data.minor + '.' + data.patch); } // Detect IE compatibility modes. else if (typeof doc.documentMode == 'number' && (data = /\bTrident\/(\d+)/i.exec(ua))) { // We're in compatibility mode when the Trident version + 4 doesn't // equal the document mode. version = [version, doc.documentMode]; if ((data = +data[1] + 4) != version[1]) { description.push('IE ' + version[1] + ' mode'); layout && (layout[1] = ''); version[1] = data; } version = name == 'IE' ? String(version[1].toFixed(1)) : version[0]; } // Detect IE 11 masking as other browsers. else if (typeof doc.documentMode == 'number' && /^(?:Chrome|Firefox)\b/.test(name)) { description.push('masking as ' + name + ' ' + version); name = 'IE'; version = '11.0'; layout = ['Trident']; os = 'Windows'; } os = os && format(os); } // Detect prerelease phases. if (version && (data = /(?:[ab]|dp|pre|[ab]\d+pre)(?:\d+\+?)?$/i.exec(version) || /(?:alpha|beta)(?: ?\d)?/i.exec(ua + ';' + (useFeatures && nav.appMinorVersion)) || /\bMinefield\b/i.test(ua) && 'a' )) { prerelease = /b/i.test(data) ? 'beta' : 'alpha'; version = version.replace(RegExp(data + '\\+?$'), '') + (prerelease == 'beta' ? beta : alpha) + (/\d+\+?/.exec(data) || ''); } // Detect Firefox Mobile. if (name == 'Fennec' || name == 'Firefox' && /\b(?:Android|Firefox OS)\b/.test(os)) { name = 'Firefox Mobile'; } // Obscure Maxthon's unreliable version. else if (name == 'Maxthon' && version) { version = version.replace(/\.[\d.]+/, '.x'); } // Detect Xbox 360 and Xbox One. else if (/\bXbox\b/i.test(product)) { if (product == 'Xbox 360') { os = null; } if (product == 'Xbox 360' && /\bIEMobile\b/.test(ua)) { description.unshift('mobile mode'); } } // Add mobile postfix. else if ((/^(?:Chrome|IE|Opera)$/.test(name) || name && !product && !/Browser|Mobi/.test(name)) && (os == 'Windows CE' || /Mobi/i.test(ua))) { name += ' Mobile'; } // Detect IE platform preview. else if (name == 'IE' && useFeatures) { try { if (context.external === null) { description.unshift('platform preview'); } } catch(e) { description.unshift('embedded'); } } // Detect BlackBerry OS version. // http://docs.blackberry.com/en/developers/deliverables/18169/HTTP_headers_sent_by_BB_Browser_1234911_11.jsp else if ((/\bBlackBerry\b/.test(product) || /\bBB10\b/.test(ua)) && (data = (RegExp(product.replace(/ +/g, ' *') + '/([.\\d]+)', 'i').exec(ua) || 0)[1] || version )) { data = [data, /BB10/.test(ua)]; os = (data[1] ? (product = null, manufacturer = 'BlackBerry') : 'Device Software') + ' ' + data[0]; version = null; } // Detect Opera identifying/masking itself as another browser. // http://www.opera.com/support/kb/view/843/ else if (this != forOwn && product != 'Wii' && ( (useFeatures && opera) || (/Opera/.test(name) && /\b(?:MSIE|Firefox)\b/i.test(ua)) || (name == 'Firefox' && /\bOS X (?:\d+\.){2,}/.test(os)) || (name == 'IE' && ( (os && !/^Win/.test(os) && version > 5.5) || /\bWindows XP\b/.test(os) && version > 8 || version == 8 && !/\bTrident\b/.test(ua) )) ) && !reOpera.test((data = parse.call(forOwn, ua.replace(reOpera, '') + ';'))) && data.name) { // When "identifying", the UA contains both Opera and the other browser's name. data = 'ing as ' + data.name + ((data = data.version) ? ' ' + data : ''); if (reOpera.test(name)) { if (/\bIE\b/.test(data) && os == 'Mac OS') { os = null; } data = 'identify' + data; } // When "masking", the UA contains only the other browser's name. else { data = 'mask' + data; if (operaClass) { name = format(operaClass.replace(/([a-z])([A-Z])/g, '$1 $2')); } else { name = 'Opera'; } if (/\bIE\b/.test(data)) { os = null; } if (!useFeatures) { version = null; } } layout = ['Presto']; description.push(data); } // Detect WebKit Nightly and approximate Chrome/Safari versions. if ((data = (/\bAppleWebKit\/([\d.]+\+?)/i.exec(ua) || 0)[1])) { // Correct build number for numeric comparison. // (e.g. "532.5" becomes "532.05") data = [parseFloat(data.replace(/\.(\d)$/, '.0$1')), data]; // Nightly builds are postfixed with a "+". if (name == 'Safari' && data[1].slice(-1) == '+') { name = 'WebKit Nightly'; prerelease = 'alpha'; version = data[1].slice(0, -1); } // Clear incorrect browser versions. else if (version == data[1] || version == (data[2] = (/\bSafari\/([\d.]+\+?)/i.exec(ua) || 0)[1])) { version = null; } // Use the full Chrome version when available. data[1] = (/\bChrome\/([\d.]+)/i.exec(ua) || 0)[1]; // Detect Blink layout engine. if (data[0] == 537.36 && data[2] == 537.36 && parseFloat(data[1]) >= 28 && layout == 'WebKit') { layout = ['Blink']; } // Detect JavaScriptCore. // http://stackoverflow.com/questions/6768474/how-can-i-detect-which-javascript-engine-v8-or-jsc-is-used-at-runtime-in-androi if (!useFeatures || (!likeChrome && !data[1])) { layout && (layout[1] = 'like Safari'); data = (data = data[0], data < 400 ? 1 : data < 500 ? 2 : data < 526 ? 3 : data < 533 ? 4 : data < 534 ? '4+' : data < 535 ? 5 : data < 537 ? 6 : data < 538 ? 7 : data < 601 ? 8 : '8'); } else { layout && (layout[1] = 'like Chrome'); data = data[1] || (data = data[0], data < 530 ? 1 : data < 532 ? 2 : data < 532.05 ? 3 : data < 533 ? 4 : data < 534.03 ? 5 : data < 534.07 ? 6 : data < 534.10 ? 7 : data < 534.13 ? 8 : data < 534.16 ? 9 : data < 534.24 ? 10 : data < 534.30 ? 11 : data < 535.01 ? 12 : data < 535.02 ? '13+' : data < 535.07 ? 15 : data < 535.11 ? 16 : data < 535.19 ? 17 : data < 536.05 ? 18 : data < 536.10 ? 19 : data < 537.01 ? 20 : data < 537.11 ? '21+' : data < 537.13 ? 23 : data < 537.18 ? 24 : data < 537.24 ? 25 : data < 537.36 ? 26 : layout != 'Blink' ? '27' : '28'); } // Add the postfix of ".x" or "+" for approximate versions. layout && (layout[1] += ' ' + (data += typeof data == 'number' ? '.x' : /[.+]/.test(data) ? '' : '+')); // Obscure version for some Safari 1-2 releases. if (name == 'Safari' && (!version || parseInt(version) > 45)) { version = data; } } // Detect Opera desktop modes. if (name == 'Opera' && (data = /\bzbov|zvav$/.exec(os))) { name += ' '; description.unshift('desktop mode'); if (data == 'zvav') { name += 'Mini'; version = null; } else { name += 'Mobile'; } os = os.replace(RegExp(' *' + data + '$'), ''); } // Detect Chrome desktop mode. else if (name == 'Safari' && /\bChrome\b/.exec(layout && layout[1])) { description.unshift('desktop mode'); name = 'Chrome Mobile'; version = null; if (/\bOS X\b/.test(os)) { manufacturer = 'Apple'; os = 'iOS 4.3+'; } else { os = null; } } // Strip incorrect OS versions. if (version && version.indexOf((data = /[\d.]+$/.exec(os))) == 0 && ua.indexOf('/' + data + '-') > -1) { os = trim(os.replace(data, '')); } // Add layout engine. if (layout && !/\b(?:Avant|Nook)\b/.test(name) && ( /Browser|Lunascape|Maxthon/.test(name) || name != 'Safari' && /^iOS/.test(os) && /\bSafari\b/.test(layout[1]) || /^(?:Adobe|Arora|Breach|Midori|Opera|Phantom|Rekonq|Rock|Samsung Internet|Sleipnir|Web)/.test(name) && layout[1])) { // Don't add layout details to description if they are falsey. (data = layout[layout.length - 1]) && description.push(data); } // Combine contextual information. if (description.length) { description = ['(' + description.join('; ') + ')']; } // Append manufacturer to description. if (manufacturer && product && product.indexOf(manufacturer) < 0) { description.push('on ' + manufacturer); } // Append product to description. if (product) { description.push((/^on /.test(description[description.length - 1]) ? '' : 'on ') + product); } // Parse the OS into an object. if (os) { data = / ([\d.+]+)$/.exec(os); isSpecialCasedOS = data && os.charAt(os.length - data[0].length - 1) == '/'; os = { 'architecture': 32, 'family': (data && !isSpecialCasedOS) ? os.replace(data[0], '') : os, 'version': data ? data[1] : null, 'toString': function() { var version = this.version; return this.family + ((version && !isSpecialCasedOS) ? ' ' + version : '') + (this.architecture == 64 ? ' 64-bit' : ''); } }; } // Add browser/OS architecture. if ((data = /\b(?:AMD|IA|Win|WOW|x86_|x)64\b/i.exec(arch)) && !/\bi686\b/i.test(arch)) { if (os) { os.architecture = 64; os.family = os.family.replace(RegExp(' *' + data), ''); } if ( name && (/\bWOW64\b/i.test(ua) || (useFeatures && /\w(?:86|32)$/.test(nav.cpuClass || nav.platform) && !/\bWin64; x64\b/i.test(ua))) ) { description.unshift('32-bit'); } } // Chrome 39 and above on OS X is always 64-bit. else if ( os && /^OS X/.test(os.family) && name == 'Chrome' && parseFloat(version) >= 39 ) { os.architecture = 64; } ua || (ua = null); /*------------------------------------------------------------------------*/ /** * The platform object. * * @name platform * @type Object */ var platform = {}; /** * The platform description. * * @memberOf platform * @type string|null */ platform.description = ua; /** * The name of the browser's layout engine. * * The list of common layout engines include: * "Blink", "EdgeHTML", "Gecko", "Trident" and "WebKit" * * @memberOf platform * @type string|null */ platform.layout = layout && layout[0]; /** * The name of the product's manufacturer. * * The list of manufacturers include: * "Apple", "Archos", "Amazon", "Asus", "Barnes & Noble", "BlackBerry", * "Google", "HP", "HTC", "LG", "Microsoft", "Motorola", "Nintendo", * "Nokia", "Samsung" and "Sony" * * @memberOf platform * @type string|null */ platform.manufacturer = manufacturer; /** * The name of the browser/environment. * * The list of common browser names include: * "Chrome", "Electron", "Firefox", "Firefox for iOS", "IE", * "Microsoft Edge", "PhantomJS", "Safari", "SeaMonkey", "Silk", * "Opera Mini" and "Opera" * * Mobile versions of some browsers have "Mobile" appended to their name: * eg. "Chrome Mobile", "Firefox Mobile", "IE Mobile" and "Opera Mobile" * * @memberOf platform * @type string|null */ platform.name = name; /** * The alpha/beta release indicator. * * @memberOf platform * @type string|null */ platform.prerelease = prerelease; /** * The name of the product hosting the browser. * * The list of common products include: * * "BlackBerry", "Galaxy S4", "Lumia", "iPad", "iPod", "iPhone", "Kindle", * "Kindle Fire", "Nexus", "Nook", "PlayBook", "TouchPad" and "Transformer" * * @memberOf platform * @type string|null */ platform.product = product; /** * The browser's user agent string. * * @memberOf platform * @type string|null */ platform.ua = ua; /** * The browser/environment version. * * @memberOf platform * @type string|null */ platform.version = name && version; /** * The name of the operating system. * * @memberOf platform * @type Object */ platform.os = os || { /** * The CPU architecture the OS is built for. * * @memberOf platform.os * @type number|null */ 'architecture': null, /** * The family of the OS. * * Common values include: * "Windows", "Windows Server 2008 R2 / 7", "Windows Server 2008 / Vista", * "Windows XP", "OS X", "Ubuntu", "Debian", "Fedora", "Red Hat", "SuSE", * "Android", "iOS" and "Windows Phone" * * @memberOf platform.os * @type string|null */ 'family': null, /** * The version of the OS. * * @memberOf platform.os * @type string|null */ 'version': null, /** * Returns the OS string. * * @memberOf platform.os * @returns {string} The OS string. */ 'toString': function() { return 'null'; } }; platform.parse = parse; platform.toString = toStringPlatform; if (platform.version) { description.unshift(version); } if (platform.name) { description.unshift(name); } if (os && name && !(os == String(os).split(' ')[0] && (os == name.split(' ')[0] || product))) { description.push(product ? '(' + os + ')' : 'on ' + os); } if (description.length) { platform.description = description.join(' '); } return platform; } /*--------------------------------------------------------------------------*/ // Export platform. var platform = parse(); // Some AMD build optimizers, like r.js, check for condition patterns like the following: if (typeof define == 'function' && typeof define.amd == 'object' && define.amd) { // Expose platform on the global object to prevent errors when platform is // loaded by a script tag in the presence of an AMD loader. // See http://requirejs.org/docs/errors.html#mismatch for more details. root.platform = platform; // Define as an anonymous module so platform can be aliased through path mapping. define(function() { return platform; }); } // Check for `exports` after `define` in case a build optimizer adds an `exports` object. else if (freeExports && freeModule) { // Export for CommonJS support. forOwn(platform, function(value, key) { freeExports[key] = value; }); } else { // Export to the global object. root.platform = platform; } }.call(this)); function buildIOSMeta(){ var aMetaTags = [ { name : "viewport", content : 'width=device-width, height=device-height, initial-scale=1, minimum-scale=1, maximum-scale=1, user-scalable=no'}, { name: 'apple-mobile-web-app-capable', content: 'yes'}, { name: 'apple-mobile-web-app-status-bar-style', content: 'black'} ]; for( var i = 0; i < aMetaTags.length; i++ ){ var oNewMeta = document.createElement('meta'); oNewMeta.name = aMetaTags[i].name; oNewMeta.content = aMetaTags[i].content; var oOldMeta = window.document.head.querySelector('meta[name="'+oNewMeta.name+'"]'); if (oOldMeta) { oOldMeta.parentNode.removeChild(oOldMeta); } window.document.head.appendChild(oNewMeta); } }; function hideIOSFullscreenPanel(){ jQuery(".xxx-ios-fullscreen-message").css("display","none"); jQuery(".xxx-ios-fullscreen-scroll").css("display","none"); jQuery(".xxx-game-iframe-full").removeClass("xxx-game-iframe-iphone-se"); }; function buildIOSFullscreenPanel(){ var html = ''; html += '<div class="xxx-ios-fullscreen-message">'; html += '<div class="xxx-ios-fullscreen-swipe">'; html += '</div>'; html += '</div>'; html += '<div class="xxx-ios-fullscreen-scroll">'; html += '</div>'; jQuery("body").append(html); }; function showIOSFullscreenPanel(){ jQuery(".xxx-ios-fullscreen-message").css("display","block"); jQuery(".xxx-ios-fullscreen-scroll").css("display","block"); }; function __iosResize(){ window.scrollTo(0, 0); console.log(window.devicePixelRatio); console.log(window.innerWidth); console.log(window.innerHeight); if( platform.product === "iPhone" ){ switch(window.devicePixelRatio){ case 2:{ switch(window.innerWidth){ case 568:{ //console.log("iPhone 5/5s/5c/se"); if( window.innerHeight === 320 ){ //console.log("fullscreen"); //this.hideIOSFullscreenPanel(); }else{ jQuery(".xxx-game-iframe-full").addClass("xxx-game-iframe-iphone-se"); //console.log("windowed"); // this.showIOSFullscreenPanel(); } }break; case 667:{ //console.log("iPhone 6/6s/7/8"); if( window.innerHeight === 375 ){ // console.log("fullscreen"); hideIOSFullscreenPanel(); }else{ //console.log("windowed"); showIOSFullscreenPanel(); } }break; case 808:{ //console.log("iPhone Xr"); if( window.innerHeight === 414 ){ hideIOSFullscreenPanel(); }else{ showIOSFullscreenPanel(); } }break; default:{ hideIOSFullscreenPanel(); } } }break; case 3:{ switch(window.innerWidth){ case 736:{ //console.log("iPhone 6/6s/7/8 plus"); if( window.innerHeight === 414 ){ // console.log("fullscreen"); hideIOSFullscreenPanel(); }else{ showIOSFullscreenPanel(); } }break; // iphone X case 724:{ // console.log("iPhone X/Xs"); if( window.innerHeight === 375 ){ hideIOSFullscreenPanel(); }else{ showIOSFullscreenPanel(); } }break; case 808:{ //console.log("iPhone Xs Max"); if( window.innerHeight === 414 ){ hideIOSFullscreenPanel(); }else{ showIOSFullscreenPanel(); } }break; default:{ hideIOSFullscreenPanel(); } } }break; default:{ hideIOSFullscreenPanel(); } } } }; function iosResize(){ __iosResize(); setTimeout(function(){ __iosResize(); },500); }; function iosInIframe() { try { return window.self !== window.top; } catch (e) { return true; } } function isIOSLessThen13(){ var oOs = platform.os; var szFamily = oOs.family.toLowerCase(); var iVersion = parseFloat( oOs.version ); if(szFamily === "ios"){ if(iVersion < 13){ return true; } } return false; } $(document).ready(function () { if(platform && platform.product === "iPhone" && platform.name.toLowerCase() === "safari" && ////AND < ver 13 isIOSLessThen13() && !iosInIframe()){ buildIOSFullscreenPanel(); buildIOSMeta(); } }); jQuery(window).resize(function() { if(platform && platform.product === "iPhone" && platform.name.toLowerCase() === "safari" && ////AND < ver 13 isIOSLessThen13() && !iosInIframe()){ iosResize(); } }); function CAreYouSurePanel(oFunction) { var _oTitle; var _oButYes; var _oButNo; var _oFade; var _oPanelContainer; var _oParent; var _oListener; var _pStartPanelPos; this._init = function (oFunction) { _oFade = new createjs.Shape(); _oFade.graphics.beginFill("black").drawRect(0,0,CANVAS_WIDTH,CANVAS_HEIGHT); _oFade.alpha = 0; _oListener = _oFade.on("mousedown",function(){}); s_oStage.addChild(_oFade); new createjs.Tween.get(_oFade).to({alpha:0.7},500); _oPanelContainer = new createjs.Container(); s_oStage.addChild(_oPanelContainer); var oSprite = s_oSpriteLibrary.getSprite('msg_box'); var oPanel = createBitmap(oSprite); oPanel.regX = oSprite.width/2; oPanel.regY = oSprite.height/2; _oPanelContainer.addChild(oPanel); _oPanelContainer.x = CANVAS_WIDTH/2; _oPanelContainer.y = CANVAS_HEIGHT + oSprite.height/2; _pStartPanelPos = {x: _oPanelContainer.x, y: _oPanelContainer.y}; new createjs.Tween.get(_oPanelContainer).to({y:CANVAS_HEIGHT/2 - 40},500, createjs.Ease.cubicOut); var iWidth = oSprite.width-120; var iHeight = 200; var iX = 0; var iY = - 240; var oTitle = new CTLText(_oPanelContainer, iX-iWidth/2, iY-iHeight/2, iWidth, iHeight, 100, "center", "#ffffff", PRIMARY_FONT, 1, 2, 2, TEXT_ARE_SURE, true, true, true, false ); _oButYes = new CGfxButton(170, 80, s_oSpriteLibrary.getSprite('but_yes'), _oPanelContainer); _oButYes.addEventListener(ON_MOUSE_UP, this._onButYes, this); _oButNo = new CGfxButton(-170, 80, s_oSpriteLibrary.getSprite('but_no'), _oPanelContainer); _oButNo.addEventListener(ON_MOUSE_UP, this._onButNo, this); _oButNo.pulseAnimation(); }; this._onButYes = function () { _oButNo.setClickable(false); _oButYes.setClickable(false); new createjs.Tween.get(_oFade).to({alpha:0},500); new createjs.Tween.get(_oPanelContainer).to({y:_pStartPanelPos.y},400, createjs.Ease.backIn).call(function(){ _oParent.unload(); oFunction(); }); }; this._onButNo = function () { _oButNo.setClickable(false); _oButYes.setClickable(false); new createjs.Tween.get(_oFade).to({alpha:0},500); new createjs.Tween.get(_oPanelContainer).to({y:_pStartPanelPos.y},400, createjs.Ease.backIn).call(function(){ _oParent.unload(); }); }; this.unload = function () { _oButNo.unload(); _oButYes.unload(); s_oStage.removeChild(_oFade); s_oStage.removeChild(_oPanelContainer); _oFade.off("mousedown",_oListener); }; _oParent = this; this._init(oFunction); } !function(e){if("object"==typeof exports&&"undefined"!=typeof module)module.exports=e();else if("function"==typeof define&&define.amd)define([],e);else{var f;"undefined"!=typeof window?f=window:"undefined"!=typeof global?f=global:"undefined"!=typeof self&&(f=self),f.TreeModel=e()}}(function(){var define,module,exports;return (function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o<r.length;o++)s(r[o]);return s})({1:[function(require,module,exports){ var mergeSort, findInsertIndex; mergeSort = require('mergesort'); findInsertIndex = require('find-insert-index'); module.exports = (function () { 'use strict'; var walkStrategies; walkStrategies = {}; function TreeModel(config) { config = config || {}; this.config = config; this.config.childrenPropertyName = config.childrenPropertyName || 'children'; this.config.modelComparatorFn = config.modelComparatorFn; } TreeModel.prototype.parse = function (model) { var i, childCount, node; if (!(model instanceof Object)) { throw new TypeError('Model must be of type object.'); } node = new Node(this.config, model); if (model[this.config.childrenPropertyName] instanceof Array) { if (this.config.modelComparatorFn) { model[this.config.childrenPropertyName] = mergeSort( this.config.modelComparatorFn, model[this.config.childrenPropertyName]); } for (i = 0, childCount = model[this.config.childrenPropertyName].length; i < childCount; i++) { addChildToNode(node, this.parse(model[this.config.childrenPropertyName][i])); } } return node; }; function addChildToNode(node, child) { child.parent = node; node.children.push(child); return child; } function hasComparatorFunction(node) { return typeof node.config.modelComparatorFn === 'function'; } function Node(config, model) { this.config = config; this.model = model; this.children = []; } Node.prototype.isRoot = function () { return this.parent === undefined; }; Node.prototype.hasChildren = function () { return this.children.length > 0; }; Node.prototype.addChild = function (child) { return addChild(this, child); }; Node.prototype.addChildAtIndex = function (child, index) { if (hasComparatorFunction(this)) { throw new Error('Cannot add child at index when using a comparator function.'); } return addChild(this, child, index); }; function addChild(self, child, insertIndex) { var index; if (!(child instanceof Node)) { throw new TypeError('Child must be of type Node.'); } child.parent = self; if (!(self.model[self.config.childrenPropertyName] instanceof Array)) { self.model[self.config.childrenPropertyName] = []; } if (hasComparatorFunction(self)) { // Find the index to insert the child index = findInsertIndex( self.config.modelComparatorFn, self.model[self.config.childrenPropertyName], child.model); // Add to the model children self.model[self.config.childrenPropertyName].splice(index, 0, child.model); // Add to the node children self.children.splice(index, 0, child); } else { if (insertIndex === undefined) { self.model[self.config.childrenPropertyName].push(child.model); self.children.push(child); } else { if (insertIndex < 0 || insertIndex > self.children.length) { throw new Error('Invalid index.'); } self.model[self.config.childrenPropertyName].splice(insertIndex, 0, child.model); self.children.splice(index, 0, child); } } return child; } Node.prototype.getPath = function () { var path = []; (function addToPath(node) { path.unshift(node); if (!node.isRoot()) { addToPath(node.parent); } })(this); return path; }; /** * Parse the arguments of traversal functions. These functions can take one optional * first argument which is an options object. If present, this object will be stored * in args.options. The only mandatory argument is the callback function which can * appear in the first or second position (if an options object is given). This * function will be saved to args.fn. The last optional argument is the context on * which the callback function will be called. It will be available in args.ctx. * * @returns Parsed arguments. */ function parseArgs() { var args = {}; if (arguments.length === 1) { args.fn = arguments[0]; } else if (arguments.length === 2) { if (typeof arguments[0] === 'function') { args.fn = arguments[0]; args.ctx = arguments[1]; } else { args.options = arguments[0]; args.fn = arguments[1]; } } else { args.options = arguments[0]; args.fn = arguments[1]; args.ctx = arguments[2]; } args.options = args.options || {}; if (!args.options.strategy) { args.options.strategy = 'pre'; } if (!walkStrategies[args.options.strategy]) { throw new Error('Unknown tree walk strategy. Valid strategies are \'pre\' [default], \'post\' and \'breadth\'.'); } return args; } Node.prototype.walk = function () { var args; args = parseArgs.apply(this, arguments); walkStrategies[args.options.strategy].call(this, args.fn, args.ctx); }; walkStrategies.pre = function depthFirstPreOrder(callback, context) { var i, childCount, keepGoing; keepGoing = callback.call(context, this); for (i = 0, childCount = this.children.length; i < childCount; i++) { if (keepGoing === false) { return false; } keepGoing = depthFirstPreOrder.call(this.children[i], callback, context); } return keepGoing; }; walkStrategies.post = function depthFirstPostOrder(callback, context) { var i, childCount, keepGoing; for (i = 0, childCount = this.children.length; i < childCount; i++) { keepGoing = depthFirstPostOrder.call(this.children[i], callback, context); if (keepGoing === false) { return false; } } keepGoing = callback.call(context, this); return keepGoing; }; walkStrategies.breadth = function breadthFirst(callback, context) { var queue = [this]; (function processQueue() { var i, childCount, node; if (queue.length === 0) { return; } node = queue.shift(); for (i = 0, childCount = node.children.length; i < childCount; i++) { queue.push(node.children[i]); } if (callback.call(context, node) !== false) { processQueue(); } })(); }; Node.prototype.all = function () { var args, all = []; args = parseArgs.apply(this, arguments); walkStrategies[args.options.strategy].call(this, function (node) { if (args.fn.call(args.ctx, node)) { all.push(node); } }, args.ctx); return all; }; Node.prototype.first = function () { var args, first; args = parseArgs.apply(this, arguments); walkStrategies[args.options.strategy].call(this, function (node) { if (args.fn.call(args.ctx, node)) { first = node; return false; } }, args.ctx); return first; }; Node.prototype.drop = function () { var indexOfChild; if (!this.isRoot()) { indexOfChild = this.parent.children.indexOf(this); this.parent.children.splice(indexOfChild, 1); this.parent.model[this.config.childrenPropertyName].splice(indexOfChild, 1); this.parent = undefined; delete this.parent; } return this; }; return TreeModel; })(); },{"find-insert-index":2,"mergesort":3}],2:[function(require,module,exports){ module.exports = (function () { 'use strict'; /** * Find the index to insert an element in array keeping the sort order. * * @param {function} comparatorFn The comparator function which sorted the array. * @param {array} arr The sorted array. * @param {object} el The element to insert. */ function findInsertIndex(comparatorFn, arr, el) { var i, len; for (i = 0, len = arr.length; i < len; i++) { if (comparatorFn(arr[i], el) > 0) { break; } } return i; } return findInsertIndex; })(); },{}],3:[function(require,module,exports){ module.exports = (function () { 'use strict'; /** * Sort an array using the merge sort algorithm. * * @param {function} comparatorFn The comparator function. * @param {array} arr The array to sort. * @returns {array} The sorted array. */ function mergeSort(comparatorFn, arr) { var len = arr.length, firstHalf, secondHalf; if (len >= 2) { firstHalf = arr.slice(0, len / 2); secondHalf = arr.slice(len / 2, len); return merge(comparatorFn, mergeSort(comparatorFn, firstHalf), mergeSort(comparatorFn, secondHalf)); } else { return arr.slice(); } } /** * The merge part of the merge sort algorithm. * * @param {function} comparatorFn The comparator function. * @param {array} arr1 The first sorted array. * @param {array} arr2 The second sorted array. * @returns {array} The merged and sorted array. */ function merge(comparatorFn, arr1, arr2) { var result = [], left1 = arr1.length, left2 = arr2.length; while (left1 > 0 && left2 > 0) { if (comparatorFn(arr1[0], arr2[0]) <= 0) { result.push(arr1.shift()); left1--; } else { result.push(arr2.shift()); left2--; } } if (left1 > 0) { result.push.apply(result, arr1); } else { result.push.apply(result, arr2); } return result; } return mergeSort; })(); },{}]},{},[1])(1) }); function CTreeDecision(oObj){ var _aNode; var _oTree; var _oRoot; this._init = function(oObj){ _aNode = new Array(); for(var i=0; i<SEARCH_DEPTH+1; i++){ _aNode[i] = new Array(); } _oTree = new TreeModel(); _oRoot = _oTree.parse(oObj); _aNode[0][0] = _oRoot; }; this.getRoot = function(){ return(_oRoot); }; this.initNewNode = function(iDepth){ // Parse the new node _aNode[iDepth].push( _oTree.parse({rating:0, moves:[], depth:iDepth}) ); return _aNode[iDepth][_aNode[iDepth].length-1]; }; this.addNode = function(iParentRow, iRate, aMove){ var iChildRow = iParentRow+1; var iChildCol = _aNode[iChildRow].length-1; _aNode[iChildRow][iChildCol].model.moves = aMove; _aNode[iChildRow][iChildCol].model.rating = iRate; // Add node to the parent var iParentCol = _aNode[iParentRow].length-1; _aNode[iParentRow][iParentCol].addChild(_aNode[iChildRow][iChildCol]); }; this.rateNode = function(oNode, iRate){ oNode.model.rating = iRate; }; this.getNode = function(iRate, iDepth){ return ( _oRoot.all(function (node) { return node.model.rating === iRate && node.model.depth === iDepth; }) ); }; this.getPath = function(oNode){ return oNode.getPath(); }; this.getTerminalNodes = function(){ return( _oRoot.all(function (node) { return !node.hasChildren(); }) ); }; this._init(oObj); } var s_iScaleFactor = 1; var s_bIsIphone = false; var s_iOffsetX; var s_iOffsetY; var s_bFocus = true; /** * jQuery.browser.mobile (http://detectmobilebrowser.com/) * jQuery.browser.mobile will be true if the browser is a mobile device **/ (function(a){(jQuery.browser=jQuery.browser||{}).mobile=/android|avantgo|bada\/|blackberry|blazer|compal|elaine|fennec|hiptop|iemobile|ip(ad|hone|od)|iris|kindle|lge |maemo|midp|mmp|netfront|opera m(ob|in)i|palm( os)?|phone|p(ixi|re)\/|plucker|pocket|psp|symbian|tablet|treo|up\.(browser|link)|vodafone|wap|webos|windows (ce|phone)|xda|xiino/i.test(a)||/1207|6310|6590|3gso|4thp|50[1-6]i|770s|802s|a wa|abac|ac(er|oo|s\-)|ai(ko|rn)|al(av|ca|co)|amoi|an(ex|ny|yw)|aptu|ar(ch|go)|as(te|us)|attw|au(di|\-m|r |s )|avan|be(ck|ll|nq)|bi(lb|rd)|bl(ac|az)|br(e|v)w|bumb|bw\-(n|u)|c55\/|capi|ccwa|cdm\-|cell|chtm|cldc|cmd\-|co(mp|nd)|craw|da(it|ll|ng)|dbte|dc\-s|devi|dica|dmob|do(c|p)o|ds(12|\-d)|el(49|ai)|em(l2|ul)|er(ic|k0)|esl8|ez([4-7]0|os|wa|ze)|fetc|fly(\-|_)|g1 u|g560|gene|gf\-5|g\-mo|go(\.w|od)|gr(ad|un)|haie|hcit|hd\-(m|p|t)|hei\-|hi(pt|ta)|hp( i|ip)|hs\-c|ht(c(\-| |_|a|g|p|s|t)|tp)|hu(aw|tc)|i\-(20|go|ma)|i230|iac( |\-|\/)|ibro|idea|ig01|ikom|im1k|inno|ipaq|iris|ja(t|v)a|jbro|jemu|jigs|kddi|keji|kgt( |\/)|klon|kpt |kwc\-|kyo(c|k)|le(no|xi)|lg( g|\/(k|l|u)|50|54|e\-|e\/|\-[a-w])|libw|lynx|m1\-w|m3ga|m50\/|ma(te|ui|xo)|mc(01|21|ca)|m\-cr|me(di|rc|ri)|mi(o8|oa|ts)|mmef|mo(01|02|bi|de|do|t(\-| |o|v)|zz)|mt(50|p1|v )|mwbp|mywa|n10[0-2]|n20[2-3]|n30(0|2)|n50(0|2|5)|n7(0(0|1)|10)|ne((c|m)\-|on|tf|wf|wg|wt)|nok(6|i)|nzph|o2im|op(ti|wv)|oran|owg1|p800|pan(a|d|t)|pdxg|pg(13|\-([1-8]|c))|phil|pire|pl(ay|uc)|pn\-2|po(ck|rt|se)|prox|psio|pt\-g|qa\-a|qc(07|12|21|32|60|\-[2-7]|i\-)|qtek|r380|r600|raks|rim9|ro(ve|zo)|s55\/|sa(ge|ma|mm|ms|ny|va)|sc(01|h\-|oo|p\-)|sdk\/|se(c(\-|0|1)|47|mc|nd|ri)|sgh\-|shar|sie(\-|m)|sk\-0|sl(45|id)|sm(al|ar|b3|it|t5)|so(ft|ny)|sp(01|h\-|v\-|v )|sy(01|mb)|t2(18|50)|t6(00|10|18)|ta(gt|lk)|tcl\-|tdg\-|tel(i|m)|tim\-|t\-mo|to(pl|sh)|ts(70|m\-|m3|m5)|tx\-9|up(\.b|g1|si)|utst|v400|v750|veri|vi(rg|te)|vk(40|5[0-3]|\-v)|vm40|voda|vulc|vx(52|53|60|61|70|80|81|83|85|98)|w3c(\-| )|webc|whit|wi(g |nc|nw)|wmlb|wonu|x700|xda(\-|2|g)|yas\-|your|zeto|zte\-/i.test(a.substr(0,4))})(navigator.userAgent||navigator.vendor||window.opera); $(window).resize(function() { sizeHandler(); }); function trace(szMsg){ console.log(szMsg); } function getSize(Name) { var size; var name = Name.toLowerCase(); var document = window.document; var documentElement = document.documentElement; if (window["inner" + Name] === undefined) { // IE6 & IE7 don't have window.innerWidth or innerHeight size = documentElement["client" + Name]; } else if (window["inner" + Name] != documentElement["client" + Name]) { // WebKit doesn't include scrollbars while calculating viewport size so we have to get fancy // Insert markup to test if a media query will match document.doumentElement["client" + Name] var bodyElement = document.createElement("body"); bodyElement.id = "vpw-test-b"; bodyElement.style.cssText = "overflow:scroll"; var divElement = document.createElement("div"); divElement.id = "vpw-test-d"; divElement.style.cssText = "position:absolute;top:-1000px"; // Getting specific on the CSS selector so it won't get overridden easily divElement.innerHTML = "<style>@media(" + name + ":" + documentElement["client" + Name] + "px){body#vpw-test-b div#vpw-test-d{" + name + ":7px!important}}</style>"; bodyElement.appendChild(divElement); documentElement.insertBefore(bodyElement, document.head); if (divElement["offset" + Name] == 7) { // Media query matches document.documentElement["client" + Name] size = documentElement["client" + Name]; } else { // Media query didn't match, use window["inner" + Name] size = window["inner" + Name]; } // Cleanup documentElement.removeChild(bodyElement); } else { // Default to use window["inner" + Name] size = window["inner" + Name]; } return size; }; window.addEventListener("orientationchange", onOrientationChange ); function onOrientationChange(){ if (window.matchMedia("(orientation: portrait)").matches) { // you're in PORTRAIT mode sizeHandler(); } if (window.matchMedia("(orientation: landscape)").matches) { // you're in LANDSCAPE mode sizeHandler(); } } function isChrome(){ var isChrome = /Chrome/.test(navigator.userAgent) && /Google Inc/.test(navigator.vendor); return isChrome; } function isMobile(){ if(isIpad()){ return true; } return jQuery.browser.mobile; } function isIpad() { var isIpad = navigator.userAgent.toLowerCase().indexOf('ipad') !== -1; if (!isIpad && navigator.userAgent.match(/Mac/) && navigator.maxTouchPoints && navigator.maxTouchPoints > 2) { return true; } return isIpad; } function isIOS() { var iDevices = [ 'iPad Simulator', 'iPhone Simulator', 'iPod Simulator', 'iPad', 'iPhone', 'iPod' ]; if (navigator.userAgent.toLowerCase().indexOf("iphone") !== -1){ s_bIsIphone = true; return true; } while (iDevices.length) { if (navigator.platform === iDevices.pop()){ s_bIsIphone = true; return true; } } s_bIsIphone = false; return false; } function getIOSWindowHeight() { // Get zoom level of mobile Safari // Note, that such zoom detection might not work correctly in other browsers // We use width, instead of height, because there are no vertical toolbars :) var zoomLevel = document.documentElement.clientWidth / window.innerWidth; // window.innerHeight returns height of the visible area. // We multiply it by zoom and get out real height. return window.innerHeight * zoomLevel; }; // You can also get height of the toolbars that are currently displayed function getHeightOfIOSToolbars() { var tH = (window.orientation === 0 ? screen.height : screen.width) - getIOSWindowHeight(); return tH > 1 ? tH : 0; }; function playSound(szSound,iVolume,bLoop){ if(DISABLE_SOUND_MOBILE === false || s_bMobile === false){ s_aSounds[szSound].play(); s_aSounds[szSound].volume(iVolume); s_aSounds[szSound].loop(bLoop); return s_aSounds[szSound]; } return null; } function stopSound(szSound){ if(DISABLE_SOUND_MOBILE === false || s_bMobile === false){ s_aSounds[szSound].stop(); } } function setVolume(szSound, iVolume){ if(DISABLE_SOUND_MOBILE === false || s_bMobile === false){ s_aSounds[szSound].volume(iVolume); } } function setMute(szSound, bMute){ if(DISABLE_SOUND_MOBILE === false || s_bMobile === false){ s_aSounds[szSound].mute(bMute); } } //THIS FUNCTION MANAGES THE CANVAS SCALING TO FIT PROPORTIONALLY THE GAME TO THE CURRENT DEVICE RESOLUTION function sizeHandler() { window.scrollTo(0, 1); if (!$("#canvas")){ return; } var h; if(platform.name !== null && platform.name.toLowerCase() === "safari"){ h = getIOSWindowHeight(); }else{ h = getSize("Height"); } var w = getSize("Width"); if(s_bFocus){ _checkOrientation(w,h); } var multiplier = Math.min((h / CANVAS_HEIGHT), (w / CANVAS_WIDTH)); var destW = Math.round(CANVAS_WIDTH * multiplier); var destH = Math.round(CANVAS_HEIGHT * multiplier); var iAdd = 0; if (destH < h){ iAdd = h-destH; destH += iAdd; destW += iAdd*(CANVAS_WIDTH/CANVAS_HEIGHT); }else if (destW < w){ iAdd = w-destW; destW += iAdd; destH += iAdd*(CANVAS_HEIGHT/CANVAS_WIDTH); } var fOffsetY = ((h / 2) - (destH / 2)); var fOffsetX = ((w / 2) - (destW / 2)); var fGameInverseScaling = (CANVAS_WIDTH/destW); if( fOffsetX*fGameInverseScaling < -EDGEBOARD_X || fOffsetY*fGameInverseScaling < -EDGEBOARD_Y ){ multiplier = Math.min( h / (CANVAS_HEIGHT-(EDGEBOARD_Y*2)), w / (CANVAS_WIDTH-(EDGEBOARD_X*2))); destW = Math.round(CANVAS_WIDTH * multiplier); destH = Math.round(CANVAS_HEIGHT * multiplier); fOffsetY = ( h - destH ) / 2; fOffsetX = ( w - destW ) / 2; fGameInverseScaling = (CANVAS_WIDTH/destW); } s_iOffsetX = (-1*fOffsetX * fGameInverseScaling); s_iOffsetY = (-1*fOffsetY * fGameInverseScaling); if(fOffsetY >= 0 ){ s_iOffsetY = 0; } if(fOffsetX >= 0 ){ s_iOffsetX = 0; } if(s_oInterface !== null){ s_oInterface.refreshButtonPos( s_iOffsetX,s_iOffsetY); } if(s_oMenu !== null){ s_oMenu.refreshButtonPos( s_iOffsetX,s_iOffsetY); } if(s_oModeMenu !== null){ s_oModeMenu.refreshButtonPos( s_iOffsetX,s_iOffsetY); } $("#canvas").css("width",destW+"px"); $("#canvas").css("height",destH+"px"); if(fOffsetY < 0){ $("#canvas").css("top",fOffsetY+"px"); }else{ fOffsetY = (h - destH)/2; $("#canvas").css("top",fOffsetY+"px"); } $("#canvas").css("left",fOffsetX+"px"); fullscreenHandler(); }; function _checkOrientation(iWidth,iHeight){ if(s_bMobile && ENABLE_CHECK_ORIENTATION){ if( iWidth>iHeight ){ if( $(".orientation-msg-container").attr("data-orientation") === "landscape" ){ $(".orientation-msg-container").css("display","none"); s_oMain.startUpdate(); }else{ $(".orientation-msg-container").css("display","block"); s_oMain.stopUpdate(); } }else{ if( $(".orientation-msg-container").attr("data-orientation") === "portrait" ){ $(".orientation-msg-container").css("display","none"); s_oMain.startUpdate(); }else{ $(".orientation-msg-container").css("display","block"); s_oMain.stopUpdate(); } } } } function smartResize(oElement, iXTolerance, iYTolerance){ if(oElement.getBounds() === null){ return; } var iWidthToFit = CANVAS_WIDTH- (2*s_iOffsetX) - iXTolerance; var iHeightToFit = CANVAS_HEIGHT- (2*s_iOffsetY) - iYTolerance; var iLowerSize = inRectResize(oElement, iWidthToFit, iHeightToFit); oElement.scaleX = oElement.scaleY = 1; if(iLowerSize < 1){ oElement.scaleX = oElement.scaleY = iLowerSize; } return oElement.scaleX; }; function zoomInCamera(oElement, iCameraWidth, iCameraHeight, iElementWidth, iElementHeight){ if(oElement.getBounds() === null || oElement.getBounds() === undefined ){ return; } var iScaleX = iCameraWidth/(iElementWidth); var iScaleY = iCameraHeight/(iElementHeight); var iZoomToApply = iScaleX <= iScaleY ? iScaleX : iScaleY; oElement.scaleX = oElement.scaleY = iZoomToApply; return iZoomToApply; }; function inRectResize(oElement, iWidth, iHeight){ if(oElement.getBounds() === null || oElement.getBounds() === undefined ){ return; } var iScaleRatioX = _getNormalizedSize(oElement.getBounds().width, iWidth); var iScaleRatioY = _getNormalizedSize(oElement.getBounds().height, iHeight); var iScaleToApply = Math.min(iScaleRatioX, iScaleRatioY); oElement.scaleX = oElement.scaleY = iScaleToApply; function _getNormalizedSize(iStartSize, iSizeToReach){ var iScaleRatio = iSizeToReach/iStartSize; return iScaleRatio; }; return iScaleToApply; }; function createBitmap(oSprite, iWidth, iHeight){ var oBmp = new createjs.Bitmap(oSprite); var hitObject = new createjs.Shape(); if (iWidth && iHeight){ hitObject .graphics.beginFill("#fff").drawRect(0, 0, iWidth, iHeight); }else{ hitObject .graphics.beginFill("#ff0").drawRect(0, 0, oSprite.width, oSprite.height); } oBmp.hitArea = hitObject; return oBmp; } function createSprite(oSpriteSheet, szState, iRegX,iRegY,iWidth, iHeight){ if(szState !== null){ var oRetSprite = new createjs.Sprite(oSpriteSheet, szState); }else{ var oRetSprite = new createjs.Sprite(oSpriteSheet); } var hitObject = new createjs.Shape(); hitObject .graphics.beginFill("#000000").drawRect(-iRegX, -iRegY, iWidth, iHeight); oRetSprite.hitArea = hitObject; return oRetSprite; } function pad(n, width, z) { z = z || '0'; n = n + ''; return n.length >= width ? n : new Array(width - n.length + 1).join(z) + n; } function randomFloatBetween(minValue,maxValue,precision){ if(typeof(precision) === 'undefined'){ precision = 2; } return parseFloat(Math.min(minValue + (Math.random() * (maxValue - minValue)),maxValue).toFixed(precision)); } function rotateVector2D( iAngle, v) { var iX = v.getX() * Math.cos( iAngle ) + v.getY() * Math.sin( iAngle ); var iY = v.getX() * (-Math.sin( iAngle )) + v.getY() * Math.cos( iAngle ); v.set( iX, iY ); } function tweenVectorsOnX( vStart, vEnd, iLerp ){ var iNewX = vStart + iLerp *( vEnd-vStart); return iNewX; } function shuffle(array) { var currentIndex = array.length , temporaryValue , randomIndex ; // While there remain elements to shuffle... while (0 !== currentIndex) { // Pick a remaining element... randomIndex = Math.floor(Math.random() * currentIndex); currentIndex -= 1; // And swap it with the current element. temporaryValue = array[currentIndex]; array[currentIndex] = array[randomIndex]; array[randomIndex] = temporaryValue; } return array; } function bubbleSort(a) { var swapped; do { swapped = false; for (var i=0; i < a.length-1; i++) { if (a[i] > a[i+1]) { var temp = a[i]; a[i] = a[i+1]; a[i+1] = temp; swapped = true; } } } while (swapped); } function compare(a,b) { if (a.index > b.index) return -1; if (a.index < b.index) return 1; return 0; } //---------------------- // Linear /** * Interpolates a value between b and c parameters * <p></br><b>Note:</b></br> *    t and d parameters can be in frames or seconds/milliseconds * * @param t Elapsed time * @param b Initial position * @param c Final position * @param d Duration * @return A value between b and c parameters */ function easeLinear (t, b, c, d){ return c*t/d + b; } //---------------------- // Quad /** * Interpolates a value between b and c parameters * <p></br><b>Note:</b></br> *    t and d parameters can be in frames or seconds/milliseconds * * @param t Elapsed time * @param b Initial position * @param c Final position * @param d Duration * @return A value between b and c parameters */ function easeInQuad (t, b, c, d){ return c*(t/=d)*t + b; } //---------------------- // Sine /** * Interpolates a value between b and c parameters * <p></br><b>Note:</b></br> *    t and d parameters can be in frames or seconds/milliseconds * * @param t Elapsed time * @param b Initial position * @param c Final position * @param d Duration * @return A value between b and c parameters */ function easeInSine (t, b, c, d) { return -c * Math.cos(t/d * (Math.PI/2)) + c + b; } function easeInCubic (t, b, c, d) { return c*(t/=d)*t*t + b; }; function getTrajectoryPoint(t,p){ var result = new createjs.Point(); var oneMinusTSq = (1-t) * (1-t); var TSq = t*t; result.x = oneMinusTSq*p.start.x+2*(1-t)*t*p.traj.x+TSq*p.end.x; result.y = oneMinusTSq*p.start.y+2*(1-t)*t*p.traj.y+TSq*p.end.y; return result; } function formatTime(iTime){ iTime/=1000; var iMins = Math.floor(iTime/60); var iSecs = Math.floor(iTime-(iMins*60)); //iSecs = parseFloat(iSecs).toFixed(1) var szRet = ""; if ( iMins < 10 ){ szRet += "0" + iMins + ":"; }else{ szRet += iMins + ":"; } if ( iSecs < 10 ){ szRet += "0" + iSecs; }else{ szRet += iSecs; } return szRet; } function degreesToRadians(iAngle){ return iAngle * Math.PI / 180; } function checkRectCollision(bitmap1,bitmap2) { var b1, b2; b1 = getBounds(bitmap1,0.9); b2 = getBounds(bitmap2,0.98); return calculateIntersection(b1,b2); } function calculateIntersection(rect1, rect2){ // first we have to calculate the // center of each rectangle and half of // width and height var dx, dy, r1={}, r2={}; r1.cx = rect1.x + (r1.hw = (rect1.width /2)); r1.cy = rect1.y + (r1.hh = (rect1.height/2)); r2.cx = rect2.x + (r2.hw = (rect2.width /2)); r2.cy = rect2.y + (r2.hh = (rect2.height/2)); dx = Math.abs(r1.cx-r2.cx) - (r1.hw + r2.hw); dy = Math.abs(r1.cy-r2.cy) - (r1.hh + r2.hh); if (dx < 0 && dy < 0) { dx = Math.min(Math.min(rect1.width,rect2.width),-dx); dy = Math.min(Math.min(rect1.height,rect2.height),-dy); return {x:Math.max(rect1.x,rect2.x), y:Math.max(rect1.y,rect2.y), width:dx, height:dy, rect1: rect1, rect2: rect2}; } else { return null; } } function getBounds(obj,iTolerance) { var bounds={x:Infinity,y:Infinity,width:0,height:0}; if ( obj instanceof createjs.Container ) { bounds.x2 = -Infinity; bounds.y2 = -Infinity; var children = obj.children, l=children.length, cbounds, c; for ( c = 0; c < l; c++ ) { cbounds = getBounds(children[c],1); if ( cbounds.x < bounds.x ) bounds.x = cbounds.x; if ( cbounds.y < bounds.y ) bounds.y = cbounds.y; if ( cbounds.x + cbounds.width > bounds.x2 ) bounds.x2 = cbounds.x + cbounds.width; if ( cbounds.y + cbounds.height > bounds.y2 ) bounds.y2 = cbounds.y + cbounds.height; //if ( cbounds.x - bounds.x + cbounds.width > bounds.width ) bounds.width = cbounds.x - bounds.x + cbounds.width; //if ( cbounds.y - bounds.y + cbounds.height > bounds.height ) bounds.height = cbounds.y - bounds.y + cbounds.height; } if ( bounds.x == Infinity ) bounds.x = 0; if ( bounds.y == Infinity ) bounds.y = 0; if ( bounds.x2 == Infinity ) bounds.x2 = 0; if ( bounds.y2 == Infinity ) bounds.y2 = 0; bounds.width = bounds.x2 - bounds.x; bounds.height = bounds.y2 - bounds.y; delete bounds.x2; delete bounds.y2; } else { var gp,gp2,gp3,gp4,imgr={},sr; if ( obj instanceof createjs.Bitmap ) { sr = obj.sourceRect || obj.image; imgr.width = sr.width * iTolerance; imgr.height = sr.height * iTolerance; } else if ( obj instanceof createjs.Sprite ) { if ( obj.spriteSheet._frames && obj.spriteSheet._frames[obj.currentFrame] && obj.spriteSheet._frames[obj.currentFrame].image ) { var cframe = obj.spriteSheet.getFrame(obj.currentFrame); imgr.width = cframe.rect.width; imgr.height = cframe.rect.height; imgr.regX = cframe.regX; imgr.regY = cframe.regY; } else { bounds.x = obj.x || 0; bounds.y = obj.y || 0; } } else { bounds.x = obj.x || 0; bounds.y = obj.y || 0; } imgr.regX = imgr.regX || 0; imgr.width = imgr.width || 0; imgr.regY = imgr.regY || 0; imgr.height = imgr.height || 0; bounds.regX = imgr.regX; bounds.regY = imgr.regY; gp = obj.localToGlobal(0 -imgr.regX,0 -imgr.regY); gp2 = obj.localToGlobal(imgr.width-imgr.regX,imgr.height-imgr.regY); gp3 = obj.localToGlobal(imgr.width-imgr.regX,0 -imgr.regY); gp4 = obj.localToGlobal(0 -imgr.regX,imgr.height-imgr.regY); bounds.x = Math.min(Math.min(Math.min(gp.x,gp2.x),gp3.x),gp4.x); bounds.y = Math.min(Math.min(Math.min(gp.y,gp2.y),gp3.y),gp4.y); bounds.width = Math.max(Math.max(Math.max(gp.x,gp2.x),gp3.x),gp4.x) - bounds.x; bounds.height = Math.max(Math.max(Math.max(gp.y,gp2.y),gp3.y),gp4.y) - bounds.y; } return bounds; } function NoClickDelay(el) { this.element = el; if( window.Touch ) this.element.addEventListener('touchstart', this, false); } //Fisher-Yates Shuffle function shuffle(array) { var counter = array.length, temp, index; // While there are elements in the array while (counter > 0) { // Pick a random index index = Math.floor(Math.random() * counter); // Decrease counter by 1 counter--; // And swap the last element with it temp = array[counter]; array[counter] = array[index]; array[index] = temp; } return array; } NoClickDelay.prototype = { handleEvent: function(e) { switch(e.type) { case 'touchstart': this.onTouchStart(e); break; case 'touchmove': this.onTouchMove(e); break; case 'touchend': this.onTouchEnd(e); break; } }, onTouchStart: function(e) { e.preventDefault(); this.moved = false; this.element.addEventListener('touchmove', this, false); this.element.addEventListener('touchend', this, false); }, onTouchMove: function(e) { this.moved = true; }, onTouchEnd: function(e) { this.element.removeEventListener('touchmove', this, false); this.element.removeEventListener('touchend', this, false); if( !this.moved ) { var theTarget = document.elementFromPoint(e.changedTouches[0].clientX, e.changedTouches[0].clientY); if(theTarget.nodeType == 3) theTarget = theTarget.parentNode; var theEvent = document.createEvent('MouseEvents'); theEvent.initEvent('click', true, true); theTarget.dispatchEvent(theEvent); } } }; (function() { var hidden = "hidden"; // Standards: if (hidden in document) document.addEventListener("visibilitychange", onchange); else if ((hidden = "mozHidden") in document) document.addEventListener("mozvisibilitychange", onchange); else if ((hidden = "webkitHidden") in document) document.addEventListener("webkitvisibilitychange", onchange); else if ((hidden = "msHidden") in document) document.addEventListener("msvisibilitychange", onchange); // IE 9 and lower: else if ('onfocusin' in document) document.onfocusin = document.onfocusout = onchange; // All others: else window.onpageshow = window.onpagehide = window.onfocus = window.onblur = onchange; function onchange (evt) { var v = 'visible', h = 'hidden', evtMap = { focus:v, focusin:v, pageshow:v, blur:h, focusout:h, pagehide:h }; evt = evt || window.event; if (evt.type in evtMap){ document.body.className = evtMap[evt.type]; }else{ document.body.className = this[hidden] ? "hidden" : "visible"; if(document.body.className === "hidden"){ s_oMain.stopUpdate(); s_bFocus = false; }else{ s_oMain.startUpdate(); s_bFocus = true; } } } })(); function compareRow(a,b) { if (a.row > b.row) return 1; if (a.row < b.row) return -1; return 0; } function compareCol(a,b) { if (a.col > b.col) return 1; if (a.col < b.col) return -1; return 0; } function ctlArcadeResume(){ if(s_oMain !== null){ s_oMain.startUpdate(); } } function ctlArcadePause(){ if(s_oMain !== null){ s_oMain.stopUpdate(); } } function getParamValue(paramName){ var url = window.location.search.substring(1); var qArray = url.split('&'); for (var i = 0; i < qArray.length; i++) { var pArr = qArray[i].split('='); if (pArr[0] == paramName) return pArr[1]; } } String.prototype.format = function() { var s = this, i = arguments.length; while (i--) { s = s.replace(new RegExp('\\{' + i + '\\}', 'gm'), arguments[i]); } return s; }; function fullscreenHandler(){ if (!ENABLE_FULLSCREEN || screenfull.isEnabled === false){ return; } s_bFullscreen = screenfull.isFullscreen; if (s_oInterface !== null){ s_oInterface.resetFullscreenBut(); } if (s_oMenu !== null){ s_oMenu.resetFullscreenBut(); } if (s_oModeMenu !== null){ s_oModeMenu.resetFullscreenBut(); } } if (screenfull.isEnabled) { screenfull.on('change', function(){ s_bFullscreen = screenfull.isFullscreen; if (s_oInterface !== null){ s_oInterface.resetFullscreenBut(); } if (s_oMenu !== null){ s_oMenu.resetFullscreenBut(); } if (s_oModeMenu !== null){ s_oModeMenu.resetFullscreenBut(); } }); } function CSpriteLibrary(){ var _oLibSprites = {}; var _oSpritesToLoad; var _iNumSprites; var _iCntSprites; var _cbCompleted; var _cbTotalCompleted; var _cbOwner; this.init = function( cbCompleted,cbTotalCompleted, cbOwner ){ _oSpritesToLoad = {}; _iNumSprites = 0; _iCntSprites = 0; _cbCompleted = cbCompleted; _cbTotalCompleted = cbTotalCompleted; _cbOwner = cbOwner; }; this.addSprite = function( szKey, szPath ){ if ( _oLibSprites.hasOwnProperty(szKey) ){ return ; } var oImage = new Image(); _oLibSprites[szKey] = _oSpritesToLoad[szKey] = { szPath:szPath, oSprite: oImage ,bLoaded:false}; _iNumSprites++; }; this.getSprite = function( szKey ){ if (!_oLibSprites.hasOwnProperty(szKey)){ return null; }else{ return _oLibSprites[szKey].oSprite; } }; this._onSpritesLoaded = function(){ _iNumSprites = 0; _cbTotalCompleted.call(_cbOwner); }; this._onSpriteLoaded = function(){ _cbCompleted.call(_cbOwner); if (++_iCntSprites === _iNumSprites) { this._onSpritesLoaded(); } }; this.loadSprites = function(){ for (var szKey in _oSpritesToLoad) { _oSpritesToLoad[szKey].oSprite["oSpriteLibrary"] = this; _oSpritesToLoad[szKey].oSprite["szKey"] = szKey; _oSpritesToLoad[szKey].oSprite.onload = function(){ this.oSpriteLibrary.setLoaded(this.szKey); this.oSpriteLibrary._onSpriteLoaded(this.szKey); }; _oSpritesToLoad[szKey].oSprite.onerror = function(evt){ var oSpriteToRestore = evt.currentTarget; setTimeout(function(){ _oSpritesToLoad[oSpriteToRestore.szKey].oSprite.src = _oSpritesToLoad[oSpriteToRestore.szKey].szPath; },500); }; _oSpritesToLoad[szKey].oSprite.src = _oSpritesToLoad[szKey].szPath; } }; this.setLoaded = function(szKey){ _oLibSprites[szKey].bLoaded = true; }; this.isLoaded = function(szKey){ return _oLibSprites[szKey].bLoaded; }; this.getNumSprites=function(){ return _iNumSprites; }; } var CANVAS_WIDTH = 1280; var CANVAS_HEIGHT = 1920; var EDGEBOARD_X = 150; var EDGEBOARD_Y = 280; var FPS = 30; var FPS_TIME = 1000/FPS; var DISABLE_SOUND_MOBILE = false; var PRIMARY_FONT = "arialrounded"; var STATE_LOADING = 0; var STATE_MENU = 1; var STATE_HELP = 1; var STATE_GAME = 3; var ON_MOUSE_DOWN = 0; var ON_MOUSE_UP = 1; var ON_MOUSE_OVER = 2; var ON_MOUSE_OUT = 3; var ON_DRAG_START = 4; var ON_DRAG_END = 5; var MODE_HUMAN = 0; var MODE_COMPUTER = 1; var EASY_MODE = 0; var MEDIUM_MODE = 1; var HARD_MODE = 2; var WHITE = "white"; var BLACK = "black"; var PAWN = "pawn"; var ROOK = "rook"; var KNIGHT = "knight"; var BISHOP = "bishop"; var QUEEN = "queen"; var KING = "king"; var PLAYER_STATE_WAIT = 0; var PLAYER_STATE_SELECTED = 1; var PLAYER_STATE_MOVING = 2; var BOARD_STATE_STALEMATE = 0; var BOARD_STATE_CHECK = 1; var BOARD_STATE_PROMOTION = 2; var BOARD_STATE_CHECKMATE = 3; var BOARD_SPECIAL_CASTLING_RIGHT = 0; var BOARD_SPECIAL_CASTLING_LEFT = 1; var BOARD_SPECIAL_ENPASSANT = 2; var NUM_CELL = 8; var BOARD_LENGTH = 815; var CELL_LENGTH = BOARD_LENGTH/NUM_CELL; var DRAW = -1; var TIME_MOVE = 1000; var TIME_LOOP_WAIT = 1000; var MIN_AI_THINKING = 1000; var MAX_AI_THINKING = 1500; var INFINITE = 99999; var SEARCH_DEPTH; var DRAW_COUNTER = 50; var START_SCORE; var SCORE_DECREASE_PER_SECOND; var SHOW_SCORE; var ENABLE_CHECK_ORIENTATION; var ENABLE_FULLSCREEN; function CPreloader() { var _iMaskWidth; var _iMaskHeight; var _oLoadingText; var _oProgressBar; var _oMaskPreloader; var _oFade; var _oIcon; var _oIconMask; var _oButStart; var _oContainer; this._init = function () { s_oSpriteLibrary.init(this._onImagesLoaded, this._onAllImagesLoaded, this); s_oSpriteLibrary.addSprite("progress_bar", "./sprites/progress_bar.png"); s_oSpriteLibrary.addSprite("200x200", "./sprites/200x200.jpg"); s_oSpriteLibrary.addSprite("but_start", "./sprites/but_start.png"); s_oSpriteLibrary.loadSprites(); _oContainer = new createjs.Container(); s_oStage.addChild(_oContainer); }; this.unload = function () { _oContainer.removeAllChildren(); _oButStart.unload(); }; this._onImagesLoaded = function () { }; this._onAllImagesLoaded = function () { this.attachSprites(); s_oMain.preloaderReady(); }; this.attachSprites = function () { var oBg = new createjs.Shape(); oBg.graphics.beginFill("black").drawRect(0, 0, CANVAS_WIDTH, CANVAS_HEIGHT); _oContainer.addChild(oBg); var oSprite = s_oSpriteLibrary.getSprite('200x200'); _oIcon = createBitmap(oSprite); _oIcon.regX = oSprite.width * 0.5; _oIcon.regY = oSprite.height * 0.5; _oIcon.x = CANVAS_WIDTH/2; _oIcon.y = CANVAS_HEIGHT/2 - 180; _oContainer.addChild(_oIcon); _oIconMask = new createjs.Shape(); _oIconMask.graphics.beginFill("rgba(0,0,0,0.01)").drawRoundRect(_oIcon.x - 100, _oIcon.y - 100, 200, 200, 10); _oContainer.addChild(_oIconMask); _oIcon.mask = _oIconMask; var oSprite = s_oSpriteLibrary.getSprite('progress_bar'); _oProgressBar = createBitmap(oSprite); _oProgressBar.x = CANVAS_WIDTH/2 - (oSprite.width / 2); _oProgressBar.y = CANVAS_HEIGHT/2 + 50; _oContainer.addChild(_oProgressBar); _iMaskWidth = oSprite.width; _iMaskHeight = oSprite.height; _oMaskPreloader = new createjs.Shape(); _oMaskPreloader.graphics.beginFill("rgba(0,0,0,0.01)").drawRect(_oProgressBar.x, _oProgressBar.y, 1, _iMaskHeight); _oContainer.addChild(_oMaskPreloader); _oProgressBar.mask = _oMaskPreloader; _oLoadingText = new createjs.Text("", "30px " + PRIMARY_FONT, "#fff"); _oLoadingText.x = CANVAS_WIDTH/2; _oLoadingText.y = CANVAS_HEIGHT/2 + 100; _oLoadingText.textBaseline = "alphabetic"; _oLoadingText.textAlign = "center"; _oContainer.addChild(_oLoadingText); var oSprite = s_oSpriteLibrary.getSprite('but_start'); _oButStart = new CTextButton(CANVAS_WIDTH/2, CANVAS_HEIGHT/2, oSprite, TEXT_PRELOADER_CONTINUE, "Arial", "#000", 40, _oContainer); _oButStart.addEventListener(ON_MOUSE_UP, this._onButStartRelease, this); _oButStart.setVisible(false); _oFade = new createjs.Shape(); _oFade.graphics.beginFill("black").drawRect(0, 0, CANVAS_WIDTH, CANVAS_HEIGHT); _oContainer.addChild(_oFade); createjs.Tween.get(_oFade).to({alpha: 0}, 500).call(function () { createjs.Tween.removeTweens(_oFade); _oContainer.removeChild(_oFade); }); }; this._onButStartRelease = function(){ $(s_oMain).trigger("show_preroll_ad"); s_oMain._onPreloaderComplete(); }; this.refreshLoader = function (iPerc) { _oLoadingText.text = iPerc + "%"; if (iPerc === 100) { //_oButStart.setVisible(true); _oLoadingText.visible = false; _oProgressBar.visible = false; $(s_oMain).trigger("show_preroll_ad"); s_oMain._onPreloaderComplete(); }; _oMaskPreloader.graphics.clear(); var iNewMaskWidth = Math.floor((iPerc * _iMaskWidth) / 100); _oMaskPreloader.graphics.beginFill("rgba(0,0,0,0.01)").drawRect(_oProgressBar.x, _oProgressBar.y, iNewMaskWidth, _iMaskHeight); }; this._init(); } function CCreditsPanel(){ var _oBg; var _oButLogo; var _oButExit; var _oFade; var _oListener; var _oHitArea; var _pStartPosExit; var _oContainer; this._init = function(){ _oFade = new createjs.Shape(); _oFade.graphics.beginFill("black").drawRect(0,0,CANVAS_WIDTH,CANVAS_HEIGHT); _oFade.alpha = 0; s_oStage.addChild(_oFade); new createjs.Tween.get(_oFade).to({alpha:0.7},500); var oSpriteMsgBox = s_oSpriteLibrary.getSprite('msg_box'); _oContainer = new createjs.Container(); _oContainer.y = CANVAS_HEIGHT + oSpriteMsgBox.height/2; s_oStage.addChild(_oContainer); _oBg = createBitmap(oSpriteMsgBox); _oBg.regX = oSpriteMsgBox.width/2; _oBg.regY = oSpriteMsgBox.height/2; _oBg.x = CANVAS_WIDTH/2; _oBg.y = CANVAS_HEIGHT/2; _oContainer.addChild(_oBg); _oHitArea = new createjs.Shape(); _oHitArea.graphics.beginFill("#0f0f0f").drawRect(0, 0, CANVAS_WIDTH, CANVAS_HEIGHT); _oHitArea.alpha = 0.01; _oListener = _oHitArea.on("click", this._onLogoButRelease); _oContainer.addChild(_oHitArea); var oSprite = s_oSpriteLibrary.getSprite('but_exit'); _pStartPosExit = {x: 990 , y: 610}; _oButExit = new CGfxButton(_pStartPosExit.x, _pStartPosExit.y, oSprite, _oContainer); _oButExit.addEventListener(ON_MOUSE_UP, this.unload, this); var iWidth = oSpriteMsgBox.width-120; var iHeight = 90; var iX = CANVAS_WIDTH/2; var iY = CANVAS_HEIGHT/2 - 124; var oTitle = new CTLText(_oContainer, iX-iWidth/2, iY-iHeight/2, iWidth, iHeight, 80, "center", "#402604", PRIMARY_FONT, 1, 2, 2, TEXT_CREDITS_DEVELOPED, true, true, false, false ); oSprite = s_oSpriteLibrary.getSprite('logo_ctl'); _oButLogo = createBitmap(oSprite); _oButLogo.regX = oSprite.width/2; _oButLogo.regY = oSprite.height/2; _oButLogo.x = CANVAS_WIDTH/2; _oButLogo.y = CANVAS_HEIGHT/2; _oContainer.addChild(_oButLogo); var iWidth = oSpriteMsgBox.width-120; var iHeight = 80; var iX = CANVAS_WIDTH/2; var iY = CANVAS_HEIGHT/2 + 120; var oLink = new CTLText(_oContainer, iX-iWidth/2, iY-iHeight/2, iWidth, iHeight, 68, "center", "#402604", PRIMARY_FONT, 1, 2, 2, "www.codethislab.com", true, true, false, false ); new createjs.Tween.get(_oContainer).to({y:0},1000, createjs.Ease.backOut); }; this.unload = function(){ _oHitArea.off("click", _oListener); _oButExit.unload(); _oButExit = null; s_oStage.removeChild(_oFade); s_oStage.removeChild(_oContainer); }; this._onLogoButRelease = function(){ window.open("http://www.codethislab.com/index.php?&l=en","_blank"); }; this._init(); }; function CMain(oData){ var _bUpdate; var _iCurResource = 0; var RESOURCE_TO_LOAD = 0; var _iState = STATE_LOADING; var _oData; var _oPreloader; var _oMenu; var _oModeMenu; var _oHelp; var _oGame; this.initContainer = function(){ s_oCanvas = document.getElementById("canvas"); s_oStage = new createjs.Stage(s_oCanvas); createjs.Touch.enable(s_oStage, true); s_bMobile = isMobile(); if(s_bMobile === false){ s_oStage.enableMouseOver(20); $('body').on('contextmenu', '#canvas', function(e){ return false; }); } s_iPrevTime = new Date().getTime(); createjs.Ticker.addEventListener("tick", this._update); createjs.Ticker.framerate = FPS; if(navigator.userAgent.match(/Windows Phone/i)){ DISABLE_SOUND_MOBILE = true; } s_oSpriteLibrary = new CSpriteLibrary(); //ADD PRELOADER if(seekAndDestroy()){_oPreloader = new CPreloader();}else{_oPreloader = new CPreloader() } }; this.preloaderReady = function(){ this._loadImages(); if(DISABLE_SOUND_MOBILE === false || s_bMobile === false){ this._initSounds(); } _bUpdate = true; }; this.soundLoaded = function(){ _iCurResource++; var iPerc = Math.floor(_iCurResource/RESOURCE_TO_LOAD *100); _oPreloader.refreshLoader(iPerc); }; this._initSounds = function(){ Howler.mute(!s_bAudioActive); s_aSoundsInfo = new Array(); s_aSoundsInfo.push({path: './sounds/',filename:'game_over',loop:false,volume:1, ingamename: 'game_over'}); s_aSoundsInfo.push({path: './sounds/',filename:'click',loop:false,volume:1, ingamename: 'click'}); s_aSoundsInfo.push({path: './sounds/',filename:'win',loop:false,volume:1, ingamename: 'win'}); RESOURCE_TO_LOAD += s_aSoundsInfo.length; s_aSounds = new Array(); for(var i=0; i<s_aSoundsInfo.length; i++){ this.tryToLoadSound(s_aSoundsInfo[i], false); } }; this.tryToLoadSound = function(oSoundInfo, bDelay){ setTimeout(function(){ s_aSounds[oSoundInfo.ingamename] = new Howl({ src: [oSoundInfo.path+oSoundInfo.filename+'.mp3'], autoplay: false, preload: true, loop: oSoundInfo.loop, volume: oSoundInfo.volume, onload: s_oMain.soundLoaded, onloaderror: function(szId,szMsg){ for(var i=0; i < s_aSoundsInfo.length; i++){ if ( szId === s_aSounds[s_aSoundsInfo[i].ingamename]._sounds[0]._id){ s_oMain.tryToLoadSound(s_aSoundsInfo[i], true); break; } } }, onplayerror: function(szId) { for(var i=0; i < s_aSoundsInfo.length; i++){ if ( szId === s_aSounds[s_aSoundsInfo[i].ingamename]._sounds[0]._id){ s_aSounds[s_aSoundsInfo[i].ingamename].once('unlock', function() { s_aSounds[s_aSoundsInfo[i].ingamename].play(); if(s_aSoundsInfo[i].ingamename === "soundtrack" && s_oGame !== null){ setVolume("soundtrack",SOUNDTRACK_VOLUME_IN_GAME); } }); break; } } } }); }, (bDelay ? 200 : 0) ); }; this._loadImages = function(){ s_oSpriteLibrary.init( this._onImagesLoaded,this._onAllImagesLoaded, this ); s_oSpriteLibrary.addSprite("but_play","./sprites/but_play.png"); s_oSpriteLibrary.addSprite("msg_box","./sprites/msg_box.png"); s_oSpriteLibrary.addSprite("bg_menu","./sprites/bg_menu.jpg"); s_oSpriteLibrary.addSprite("bg_mod_menu","./sprites/bg_mod_menu.jpg"); s_oSpriteLibrary.addSprite("bg_game","./sprites/bg_game.jpg"); s_oSpriteLibrary.addSprite("but_credits","./sprites/but_credits.png"); s_oSpriteLibrary.addSprite("but_fullscreen","./sprites/but_fullscreen.png"); s_oSpriteLibrary.addSprite("logo_ctl","./sprites/logo_ctl.png"); s_oSpriteLibrary.addSprite("but_vs_man","./sprites/vs_man_panel.png"); s_oSpriteLibrary.addSprite("but_vs_pc","./sprites/vs_pc_panel.png"); s_oSpriteLibrary.addSprite("message","./sprites/message.png"); s_oSpriteLibrary.addSprite("but_home","./sprites/but_home.png"); s_oSpriteLibrary.addSprite("but_show","./sprites/but_show.png"); s_oSpriteLibrary.addSprite("but_exit","./sprites/but_exit.png"); s_oSpriteLibrary.addSprite("audio_icon","./sprites/audio_icon.png"); s_oSpriteLibrary.addSprite("but_settings","./sprites/but_settings.png"); s_oSpriteLibrary.addSprite("board8","./sprites/grid_8.png"); s_oSpriteLibrary.addSprite("threat","./sprites/threat.png"); s_oSpriteLibrary.addSprite("highlight","./sprites/highlight.png"); s_oSpriteLibrary.addSprite("bg_turn","./sprites/player_panel.png"); s_oSpriteLibrary.addSprite("audio_icon_big","./sprites/audio_icon_big.png"); s_oSpriteLibrary.addSprite("black_bishop","./sprites/pieces/black_bishop.png"); s_oSpriteLibrary.addSprite("black_king","./sprites/pieces/black_king.png"); s_oSpriteLibrary.addSprite("black_knight","./sprites/pieces/black_knight.png"); s_oSpriteLibrary.addSprite("black_pawn","./sprites/pieces/black_pawn.png"); s_oSpriteLibrary.addSprite("black_queen","./sprites/pieces/black_queen.png"); s_oSpriteLibrary.addSprite("black_rook","./sprites/pieces/black_rook.png"); s_oSpriteLibrary.addSprite("white_bishop","./sprites/pieces/white_bishop.png"); s_oSpriteLibrary.addSprite("white_king","./sprites/pieces/white_king.png"); s_oSpriteLibrary.addSprite("white_knight","./sprites/pieces/white_knight.png"); s_oSpriteLibrary.addSprite("white_pawn","./sprites/pieces/white_pawn.png"); s_oSpriteLibrary.addSprite("white_queen","./sprites/pieces/white_queen.png"); s_oSpriteLibrary.addSprite("white_rook","./sprites/pieces/white_rook.png"); s_oSpriteLibrary.addSprite("white_king_marker","./sprites/white_king_marker.png"); s_oSpriteLibrary.addSprite("black_king_marker","./sprites/black_king_marker.png"); s_oSpriteLibrary.addSprite("score_panel","./sprites/score_panel.png"); s_oSpriteLibrary.addSprite("toggle_easy","./sprites/toggle_easy.png"); s_oSpriteLibrary.addSprite("toggle_medium","./sprites/toggle_medium.png"); s_oSpriteLibrary.addSprite("toggle_hard","./sprites/toggle_hard.png"); s_oSpriteLibrary.addSprite("but_yes","./sprites/but_yes.png"); s_oSpriteLibrary.addSprite("but_no","./sprites/but_no.png"); s_oSpriteLibrary.addSprite("but_restart","./sprites/but_restart.png"); RESOURCE_TO_LOAD += s_oSpriteLibrary.getNumSprites(); s_oSpriteLibrary.loadSprites(); }; this._onImagesLoaded = function(){ _iCurResource++; var iPerc = Math.floor(_iCurResource/RESOURCE_TO_LOAD *100); _oPreloader.refreshLoader(iPerc); }; this._onPreloaderComplete = function(){ _oPreloader.unload(); this.gotoMenu(); }; this._onAllImagesLoaded = function(){ }; this.gotoMenu = function(){ _oMenu = new CMenu(); _iState = STATE_MENU; }; this.gotoModeMenu = function(){ _oModeMenu = new CModeMenu(); _iState = STATE_MENU; }; this.gotoGame = function(iType){ s_iGameType = iType; _oGame = new CGame(_oData); _iState = STATE_GAME; }; this.gotoHelp = function(){ _oHelp = new CHelp(); _iState = STATE_HELP; }; this.stopUpdate = function(){ _bUpdate = false; createjs.Ticker.paused = true; $("#block_game").css("display","block"); if(DISABLE_SOUND_MOBILE === false || s_bMobile === false){ Howler.mute(true); } }; this.startUpdate = function(){ s_iPrevTime = new Date().getTime(); _bUpdate = true; createjs.Ticker.paused = false; $("#block_game").css("display","none"); if(DISABLE_SOUND_MOBILE === false || s_bMobile === false){ if(s_bAudioActive){ Howler.mute(false); } } }; this._update = function(event){ if(_bUpdate === false){ return; } var iCurTime = new Date().getTime(); s_iTimeElaps = iCurTime - s_iPrevTime; s_iCntTime += s_iTimeElaps; s_iCntFps++; s_iPrevTime = iCurTime; if ( s_iCntTime >= 1000 ){ s_iCurFps = s_iCntFps; s_iCntTime-=1000; s_iCntFps = 0; } if(_iState === STATE_GAME){ _oGame.update(); } s_oStage.update(event); }; s_oMain = this; _oData = oData; ENABLE_CHECK_ORIENTATION = oData.check_orientation; ENABLE_FULLSCREEN = oData.fullscreen; s_bAudioActive = oData.audio_enable_on_startup; this.initContainer(); } var s_bMobile; var s_bAudioActive = false; var s_bFullscreen = false; var s_iCntTime = 0; var s_iTimeElaps = 0; var s_iPrevTime = 0; var s_iCntFps = 0; var s_iCurFps = 0; var s_oStage; var s_oMain; var s_oSpriteLibrary; var s_oCanvas; var s_iGameType; var s_aSounds; var s_bWeightSquares = false; var s_bEdgeSensitive = false; function CTextButton(iXPos,iYPos,oSprite,szText,szFont,szColor,iFontSize, oParentContainer){ var _aCbCompleted; var _aCbOwner; var _oButton; var _oText; var _oTextBack; var _oListenerMouseDown; var _oListenerMouseUp; this._init =function(iXPos,iYPos,oSprite,szText,szFont,szColor,iFontSize, oParentContainer){ _aCbCompleted=new Array(); _aCbOwner =new Array(); var oButtonBg = createBitmap( oSprite); var iStepShadow = Math.ceil(iFontSize/20); _oTextBack = new createjs.Text(szText,"bold "+iFontSize+"px "+szFont, "#000000"); _oTextBack.textAlign = "center"; _oTextBack.textBaseline = "alphabetic"; var oBounds = _oTextBack.getBounds(); _oTextBack.x = oSprite.width/2 + iStepShadow; _oTextBack.y = Math.floor((oSprite.height)/2) +(oBounds.height/3) + iStepShadow; _oText = new createjs.Text(szText,"bold "+iFontSize+"px "+szFont, szColor); _oText.textAlign = "center"; _oText.textBaseline = "alphabetic"; var oBounds = _oText.getBounds(); _oText.x = oSprite.width/2; _oText.y = Math.floor((oSprite.height)/2) +(oBounds.height/3); _oButton = new createjs.Container(); _oButton.x = iXPos; _oButton.y = iYPos; _oButton.regX = oSprite.width/2; _oButton.regY = oSprite.height/2; _oButton.addChild(oButtonBg,_oTextBack,_oText); oParentContainer.addChild(_oButton); this._initListener(); }; this.unload = function(){ _oButton.off("mousedown", _oListenerMouseDown); _oButton.off("pressup", _oListenerMouseUp); oParentContainer.removeChild(_oButton); }; this.setVisible = function(bVisible){ _oButton.visible = bVisible; }; this._initListener = function(){ oParent = this; _oListenerMouseDown = _oButton.on("mousedown", this.buttonDown); _oListenerMouseUp = _oButton.on("pressup" , this.buttonRelease); }; this.addEventListener = function( iEvent,cbCompleted, cbOwner ){ _aCbCompleted[iEvent]=cbCompleted; _aCbOwner[iEvent] = cbOwner; }; this.buttonRelease = function(){ _oButton.scaleX = 1; _oButton.scaleY = 1; if(_aCbCompleted[ON_MOUSE_UP]){ _aCbCompleted[ON_MOUSE_UP].call(_aCbOwner[ON_MOUSE_UP]); } }; this.buttonDown = function(){ _oButton.scaleX = 0.9; _oButton.scaleY = 0.9; if(_aCbCompleted[ON_MOUSE_DOWN]){ _aCbCompleted[ON_MOUSE_DOWN].call(_aCbOwner[ON_MOUSE_DOWN]); } }; this.setTextPosition = function(iY){ _oText.y= iY; _oTextBack.y = iY+2; }; this.setPosition = function(iXPos,iYPos){ _oButton.x = iXPos; _oButton.y = iYPos; }; this.setX = function(iXPos){ _oButton.x = iXPos; }; this.setY = function(iYPos){ _oButton.y = iYPos; }; this.getButtonImage = function(){ return _oButton; }; this.getX = function(){ return _oButton.x; }; this.getY = function(){ return _oButton.y; }; this._init(iXPos,iYPos,oSprite,szText,szFont,szColor,iFontSize, oParentContainer); return this; } function CToggle(iXPos,iYPos,oSprite,bActive, oParentContainer){ var _bActive; var _bDisabled; var _aCbCompleted; var _aCbOwner; var _aParams = []; var _oButton; var _oListenerMouseDown; var _oListenerMouseMove; var _oListenerMouseUp; this._init = function(iXPos,iYPos,oSprite,bActive){ _bDisabled = false; _aCbCompleted=new Array(); _aCbOwner =new Array(); var oData = { images: [oSprite], // width, height & registration point of each sprite frames: {width: oSprite.width/2, height: oSprite.height, regX: (oSprite.width/2)/2, regY: oSprite.height/2}, animations: {state_true:[0],state_false:[1]} }; var oSpriteSheet = new createjs.SpriteSheet(oData); _bActive = bActive; _oButton = createSprite(oSpriteSheet, "state_"+_bActive,(oSprite.width/2)/2,oSprite.height/2,oSprite.width/2,oSprite.height); _oButton.x = iXPos; _oButton.y = iYPos; _oButton.stop(); oParentContainer.addChild(_oButton); this._initListener(); }; this.unload = function(){ if(s_bMobile){ _oButton.off("mousedown", _oListenerMouseDown); _oButton.off("pressup" , _oListenerMouseUp); } else { _oButton.off("mousedown", _oListenerMouseDown); _oButton.off("mouseover", _oListenerMouseMove); _oButton.off("pressup" , _oListenerMouseUp); } oParentContainer.removeChild(_oButton); }; this._initListener = function(){ if(s_bMobile){ _oListenerMouseDown = _oButton.on("mousedown", this.buttonDown); _oListenerMouseUp = _oButton.on("pressup" , this.buttonRelease); } else { _oListenerMouseDown = _oButton.on("mousedown", this.buttonDown); _oListenerMouseMove = _oButton.on("mouseover", this.buttonOver); _oListenerMouseUp = _oButton.on("pressup" , this.buttonRelease); } }; this.addEventListener = function( iEvent,cbCompleted, cbOwner ){ _aCbCompleted[iEvent]=cbCompleted; _aCbOwner[iEvent] = cbOwner; }; this.addEventListenerWithParams = function(iEvent,cbCompleted, cbOwner,aParams){ _aCbCompleted[iEvent]=cbCompleted; _aCbOwner[iEvent] = cbOwner; _aParams = aParams; }; this.setActive = function(bActive){ _bActive = bActive; _oButton.gotoAndStop("state_"+_bActive); }; this.buttonRelease = function(){ _oButton.scaleX = 1; _oButton.scaleY = 1; playSound("click",1,false); _bActive = !_bActive; _oButton.gotoAndStop("state_"+_bActive); if(_aCbCompleted[ON_MOUSE_UP]){ _aCbCompleted[ON_MOUSE_UP].call(_aCbOwner[ON_MOUSE_UP],_aParams); } }; this.buttonDown = function(){ _oButton.scaleX = 0.9; _oButton.scaleY = 0.9; if(_aCbCompleted[ON_MOUSE_DOWN]){ _aCbCompleted[ON_MOUSE_DOWN].call(_aCbOwner[ON_MOUSE_DOWN],_aParams); } }; this.buttonOver = function(evt){ if(!s_bMobile){ if(_bDisabled){ return; } evt.target.cursor = "pointer"; } }; this.stopAnimation = function () { _oButton.rotation = 0; createjs.Tween.removeTweens(_oButton); }; this.setPosition = function(iXPos,iYPos){ _oButton.x = iXPos; _oButton.y = iYPos; }; this.setVisible = function(bVisible){ _oButton.visible = bVisible; }; this.getButtonImage = function(){ return _oButton; }; this._init(iXPos,iYPos,oSprite,bActive); } function CGfxButton(iXPos,iYPos,oSprite, oParentContainer){ var _bDisabled; var _iScaleFactor; var _aCbCompleted; var _aCbOwner; var _oButton; var _oTween; var _oParent; var _oListenerMouseDown; var _oListenerMouseMove; var _oListenerMouseUp; this._init =function(iXPos,iYPos,oSprite, oParentContainer){ _bDisabled = false; _iScaleFactor = 1; _aCbCompleted=new Array(); _aCbOwner =new Array(); _oButton = createBitmap( oSprite); _oButton.x = iXPos; _oButton.y = iYPos; _oButton.scaleX = _oButton.scaleY = _iScaleFactor; _oButton.regX = oSprite.width/2; _oButton.regY = oSprite.height/2; oParentContainer.addChild(_oButton); this._initListener(); }; this.unload = function(){ if(s_bMobile){ _oButton.off("mousedown", _oListenerMouseDown); _oButton.off("pressup" , _oListenerMouseUp); } else { _oButton.off("mousedown", _oListenerMouseDown); _oButton.off("mouseover", _oListenerMouseMove); _oButton.off("pressup" , _oListenerMouseUp); } oParentContainer.removeChild(_oButton); }; this.setVisible = function(bVisible){ _oButton.visible = bVisible; }; this.setClickable = function(bVal){ _bDisabled = !bVal; }; this._initListener = function(){ if(s_bMobile){ _oListenerMouseDown = _oButton.on("mousedown", this.buttonDown); _oListenerMouseUp = _oButton.on("pressup" , this.buttonRelease); } else { _oListenerMouseDown = _oButton.on("mousedown", this.buttonDown); _oListenerMouseMove = _oButton.on("mouseover", this.buttonOver); _oListenerMouseUp = _oButton.on("pressup" , this.buttonRelease); } }; this.addEventListener = function( iEvent,cbCompleted, cbOwner ){ _aCbCompleted[iEvent]=cbCompleted; _aCbOwner[iEvent] = cbOwner; }; this.buttonRelease = function(){ if(_bDisabled){ return; } _oButton.scaleX = _iScaleFactor; _oButton.scaleY = _iScaleFactor; if(_aCbCompleted[ON_MOUSE_UP]){ _aCbCompleted[ON_MOUSE_UP].call(_aCbOwner[ON_MOUSE_UP]); } }; this.buttonDown = function(){ if(_bDisabled){ return; } _oButton.scaleX = _iScaleFactor*0.9; _oButton.scaleY = _iScaleFactor*0.9; playSound("click",1,false); if(_aCbCompleted[ON_MOUSE_DOWN]){ _aCbCompleted[ON_MOUSE_DOWN].call(_aCbOwner[ON_MOUSE_DOWN]); } }; this.buttonOver = function(evt){ if(!s_bMobile){ if(_bDisabled){ return; } evt.target.cursor = "pointer"; } }; this.pulseAnimation = function () { _oTween = createjs.Tween.get(_oButton, {loop:true}).to({scaleX: _iScaleFactor*0.9, scaleY: _iScaleFactor*0.9}, 850, createjs.Ease.quadOut) .to({scaleX: _iScaleFactor, scaleY: _iScaleFactor}, 650, createjs.Ease.quadIn); }; this.trembleAnimation = function () { _oTween = createjs.Tween.get(_oButton, {loop:true}).to({rotation: 5}, 75, createjs.Ease.quadOut) .to({rotation: -5}, 140, createjs.Ease.quadIn).to({rotation: 0}, 75, createjs.Ease.quadIn).wait(750); }; this.stopAnimation = function () { _oButton.rotation = 0; createjs.Tween.removeTweens(_oButton); }; this.setPosition = function(iXPos,iYPos){ _oButton.x = iXPos; _oButton.y = iYPos; }; this.setX = function(iXPos){ _oButton.x = iXPos; }; this.setY = function(iYPos){ _oButton.y = iYPos; }; this.getButtonImage = function(){ return _oButton; }; this.getX = function(){ return _oButton.x; }; this.getY = function(){ return _oButton.y; }; _oParent = this; this._init(iXPos,iYPos,oSprite, oParentContainer); return this; } function CMessage(iCurPlayer, szText, oParentContainer){ var _iStartX; var _iStartY; var _iEndY; var _oMessage; var _oParent; this._init = function(iCurPlayer, szText, oParentContainer){ if(iCurPlayer === WHITE){ _iStartX = -306; _iStartY = 1000; _iEndY = 516; } else { _iStartX = 306; _iStartY = -1000; _iEndY = -506; } _oMessage = new createjs.Container(); _oMessage.x = _iStartX; _oMessage.y = _iStartY; if(s_bMobile && iCurPlayer === BLACK && s_iGameType === MODE_HUMAN){ _oMessage.rotation = 180; } oParentContainer.addChild(_oMessage); var oSprite = s_oSpriteLibrary.getSprite('message'); var oBg = createBitmap(oSprite); oBg.regX = oSprite.width/2; oBg.regY = oSprite.height/2; _oMessage.addChild(oBg) var iWidth = oSprite.width-30; var iHeight = 50; var iX = 0; var iY = 0; var oText = new CTLText(_oMessage, iX-iWidth/2, iY-iHeight/2, iWidth, iHeight, 40, "center", "#ffffff", PRIMARY_FONT, 1, 2, 2, szText, true, true, false, false ); createjs.Tween.get(_oMessage).to({y:_iEndY}, 750, createjs.Ease.cubicOut); }; this.unload = function(){ oParentContainer.removeChild(_oMessage); }; this.removeAnimated = function(){ if(_oMessage.x > CANVAS_WIDTH/2){ createjs.Tween.get(_oMessage).to({x:CANVAS_WIDTH + 200}, 500, createjs.Ease.cubicOut).call(function(){ _oParent.unload(); }); } else { createjs.Tween.get(_oMessage).to({x:-200}, 500, createjs.Ease.cubicOut).call(function(){ _oParent.unload(); }); } }; _oParent = this; this._init(iCurPlayer, szText, oParentContainer); } function CMenu(){ var _oBg; var _oButPlay; var _oFade; var _oAudioToggle; var _oButCredits; var _oButFullscreen; var _fRequestFullScreen = null; var _fCancelFullScreen = null; var _pStartPosCredits; var _pStartPosFullscreen; var _pStartPosAudio; this._init = function(){ _oBg = createBitmap(s_oSpriteLibrary.getSprite('bg_menu')); s_oStage.addChild(_oBg); var oSprite = s_oSpriteLibrary.getSprite('but_play'); _oButPlay = new CGfxButton((CANVAS_WIDTH/2),CANVAS_HEIGHT -450,oSprite, s_oStage); _oButPlay.addEventListener(ON_MOUSE_UP, this._onButPlayRelease, this); _oButPlay.pulseAnimation(); var oSprite = s_oSpriteLibrary.getSprite('but_credits'); _pStartPosCredits = {x:10 + oSprite.width/2,y:(oSprite.height / 2) + 25}; _oButCredits = new CGfxButton(_pStartPosCredits.x, _pStartPosCredits.y, oSprite, s_oStage); _oButCredits.addEventListener(ON_MOUSE_UP, this._onCredits, this); if(DISABLE_SOUND_MOBILE === false || s_bMobile === false){ var oSprite = s_oSpriteLibrary.getSprite('audio_icon'); _pStartPosAudio = {x: CANVAS_WIDTH - (oSprite.height/2)- 10, y: (oSprite.height/2) + 25}; _oAudioToggle = new CToggle(_pStartPosAudio.x,_pStartPosAudio.y,oSprite,s_bAudioActive, s_oStage); _oAudioToggle.addEventListener(ON_MOUSE_UP, this._onAudioToggle, this); } var doc = window.document; var docEl = doc.documentElement; _fRequestFullScreen = docEl.requestFullscreen || docEl.mozRequestFullScreen || docEl.webkitRequestFullScreen || docEl.msRequestFullscreen; _fCancelFullScreen = doc.exitFullscreen || doc.mozCancelFullScreen || doc.webkitExitFullscreen || doc.msExitFullscreen; if(ENABLE_FULLSCREEN === false){ _fRequestFullScreen = false; } if (_fRequestFullScreen && screenfull.isEnabled){ oSprite = s_oSpriteLibrary.getSprite('but_fullscreen'); _pStartPosFullscreen = {x:_pStartPosCredits.x + oSprite.width/2 + 10,y:_pStartPosCredits.y}; _oButFullscreen = new CToggle(_pStartPosFullscreen.x,_pStartPosFullscreen.y,oSprite,s_bFullscreen,s_oStage); _oButFullscreen.addEventListener(ON_MOUSE_UP, this._onFullscreenRelease, this); } _oFade = new createjs.Shape(); _oFade.graphics.beginFill("black").drawRect(0,0,CANVAS_WIDTH,CANVAS_HEIGHT); s_oStage.addChild(_oFade); createjs.Tween.get(_oFade).to({alpha:0}, 1000).call(function(){_oFade.visible = false;}); this.refreshButtonPos(s_iOffsetX,s_iOffsetY); }; this.unload = function(){ _oButPlay.unload(); _oButPlay = null; _oFade.visible = false; if(DISABLE_SOUND_MOBILE === false || s_bMobile === false){ _oAudioToggle.unload(); _oAudioToggle = null; } _oButCredits.unload(); if (_fRequestFullScreen && screenfull.isEnabled){ _oButFullscreen.unload(); } s_oStage.removeChild(_oBg); _oBg = null; s_oMenu = null; }; this.refreshButtonPos = function(iNewX,iNewY){ if(DISABLE_SOUND_MOBILE === false || s_bMobile === false){ _oAudioToggle.setPosition(_pStartPosAudio.x - iNewX,iNewY + _pStartPosAudio.y); } _oButCredits.setPosition(_pStartPosCredits.x + iNewX,iNewY + _pStartPosCredits.y); if (_fRequestFullScreen && screenfull.isEnabled){ _oButFullscreen.setPosition(_pStartPosFullscreen.x + iNewX,iNewY + _pStartPosFullscreen.y); } }; this._onAudioToggle = function(){ Howler.mute(s_bAudioActive); s_bAudioActive = !s_bAudioActive; }; this._onButPlayRelease = function(){ this.unload(); $(s_oMain).trigger("start_session"); s_oMain.gotoModeMenu(); }; this._onCredits = function(){ new CCreditsPanel(); }; this.resetFullscreenBut = function(){ if (_fRequestFullScreen && screenfull.isEnabled){ _oButFullscreen.setActive(s_bFullscreen); } }; this._onFullscreenRelease = function(){ if(s_bFullscreen) { _fCancelFullScreen.call(window.document); }else{ _fRequestFullScreen.call(window.document.documentElement); } sizeHandler(); }; s_oMenu = this; this._init(); } var s_oMenu = null; function CModeMenu(){ var _iModeSelected; var _oButHuman; var _oButComputer; var _oButExit; var _oAudioToggle = null; var _oToggleEasy; var _oToggleMedium; var _oToggleHard; var _oButFullscreen; var _fRequestFullScreen = null; var _fCancelFullScreen = null; var _pStartPosAudio; var _pStartPosExit; var _pStartPosFullscreen; this._init = function(){ var oBg = createBitmap(s_oSpriteLibrary.getSprite('bg_mod_menu')); s_oStage.addChild(oBg); var oSprite = s_oSpriteLibrary.getSprite('but_exit'); _pStartPosExit = {x: CANVAS_WIDTH - (oSprite.height/2)- 10, y: (oSprite.height/2) + 25}; _oButExit = new CGfxButton(_pStartPosExit.x, _pStartPosExit.y, oSprite,s_oStage); _oButExit.addEventListener(ON_MOUSE_UP, this._onExit, this); var oExitX = CANVAS_WIDTH - (oSprite.width/2) - 125; _pStartPosAudio = {x: oExitX, y: (oSprite.height/2) + 25}; if(DISABLE_SOUND_MOBILE === false || s_bMobile === false){ var oSprite = s_oSpriteLibrary.getSprite('audio_icon'); _oAudioToggle = new CToggle(_pStartPosAudio.x,_pStartPosAudio.y,oSprite,s_bAudioActive, s_oStage); _oAudioToggle.addEventListener(ON_MOUSE_UP, this._onAudioToggle, this); } var doc = window.document; var docEl = doc.documentElement; _fRequestFullScreen = docEl.requestFullscreen || docEl.mozRequestFullScreen || docEl.webkitRequestFullScreen || docEl.msRequestFullscreen; _fCancelFullScreen = doc.exitFullscreen || doc.mozCancelFullScreen || doc.webkitExitFullscreen || doc.msExitFullscreen; if(ENABLE_FULLSCREEN === false){ _fRequestFullScreen = false; } if (_fRequestFullScreen && screenfull.isEnabled){ oSprite = s_oSpriteLibrary.getSprite('but_fullscreen'); _pStartPosFullscreen = {x:oSprite.width/4 + 10,y:_pStartPosExit.y}; _oButFullscreen = new CToggle(_pStartPosFullscreen.x,_pStartPosFullscreen.y,oSprite,s_bFullscreen,s_oStage); _oButFullscreen.addEventListener(ON_MOUSE_UP, this._onFullscreenRelease, this); } var iWidth = 600; var iHeight = 200; var iX = CANVAS_WIDTH/2; var iY = 400; var oTitle = new CTLText(s_oStage, iX-iWidth/2, iY-iHeight/2, iWidth, iHeight, 80, "center", "#ffffff", PRIMARY_FONT, 1, 2, 2, TEXT_MODE, true, true, true, false ); var oSprite = s_oSpriteLibrary.getSprite('but_vs_man'); _oButHuman = new CGfxButton(CANVAS_WIDTH/2,800,oSprite,s_oStage); _oButHuman.addEventListener(ON_MOUSE_UP, this._onButHumanRelease, this); var oSprite = s_oSpriteLibrary.getSprite('message'); var oDiffPanel = createBitmap(oSprite); oDiffPanel.regX = oSprite.width/2; oDiffPanel.regY = oSprite.height/2; oDiffPanel.x = CANVAS_WIDTH/2; oDiffPanel.y = 1532; s_oStage.addChild(oDiffPanel); var iYOffset = 1550; var oSprite = s_oSpriteLibrary.getSprite('toggle_easy'); _oToggleEasy = new CToggle(CANVAS_WIDTH/2 - 130 +2,iYOffset,oSprite,false,s_oStage); _oToggleEasy.addEventListenerWithParams(ON_MOUSE_UP, this._onDifficultyToggle, this, EASY_MODE); var oSprite = s_oSpriteLibrary.getSprite('toggle_medium'); _oToggleMedium = new CToggle(CANVAS_WIDTH/2+2,iYOffset,oSprite,true,s_oStage); _oToggleMedium.addEventListenerWithParams(ON_MOUSE_UP, this._onDifficultyToggle, this, MEDIUM_MODE); var oSprite = s_oSpriteLibrary.getSprite('toggle_hard'); _oToggleHard = new CToggle(CANVAS_WIDTH/2 + 130 +2,iYOffset,oSprite,false,s_oStage); _oToggleHard.addEventListenerWithParams(ON_MOUSE_UP, this._onDifficultyToggle, this, HARD_MODE); var oSprite = s_oSpriteLibrary.getSprite('but_vs_pc'); _oButComputer = new CGfxButton(CANVAS_WIDTH/2,1300,oSprite,s_oStage); _oButComputer.addEventListener(ON_MOUSE_UP, this._onButComputerRelease, this); this._onDifficultyToggle(MEDIUM_MODE); this.refreshButtonPos(s_iOffsetX,s_iOffsetY); }; this.unload = function(){ _oButHuman.unload(); _oButComputer.unload(); _oButExit.unload(); if(DISABLE_SOUND_MOBILE === false || s_bMobile === false){ _oAudioToggle.unload(); _oAudioToggle = null; } if (_fRequestFullScreen && screenfull.isEnabled){ _oButFullscreen.unload(); } s_oModeMenu = null; s_oStage.removeAllChildren(); }; this._onDifficultyToggle = function(iMode){ switch(iMode){ case EASY_MODE: { _oToggleEasy.setActive(true); _oToggleMedium.setActive(false); _oToggleHard.setActive(false); _iModeSelected = EASY_MODE; SEARCH_DEPTH = 1; break; } case MEDIUM_MODE: { _oToggleEasy.setActive(false); _oToggleMedium.setActive(true); _oToggleHard.setActive(false); _iModeSelected = MEDIUM_MODE; SEARCH_DEPTH = 2; break; } case HARD_MODE: { _oToggleEasy.setActive(false); _oToggleMedium.setActive(false); _oToggleHard.setActive(true); _iModeSelected = HARD_MODE; SEARCH_DEPTH = 3; break; } } }; this.refreshButtonPos = function(iNewX,iNewY){ _oButExit.setPosition(_pStartPosExit.x - iNewX,iNewY + _pStartPosExit.y); if(DISABLE_SOUND_MOBILE === false || s_bMobile === false){ _oAudioToggle.setPosition(_pStartPosAudio.x - iNewX,iNewY + _pStartPosAudio.y); } if (_fRequestFullScreen && screenfull.isEnabled){ _oButFullscreen.setPosition(_pStartPosFullscreen.x + iNewX,iNewY + _pStartPosFullscreen.y); } }; this._onAudioToggle = function(){ Howler.mute(s_bAudioActive); s_bAudioActive = !s_bAudioActive; }; this.resetFullscreenBut = function(){ if (_fRequestFullScreen && screenfull.isEnabled){ _oButFullscreen.setActive(s_bFullscreen); } }; this._onFullscreenRelease = function(){ if(s_bFullscreen) { _fCancelFullScreen.call(window.document); }else{ _fRequestFullScreen.call(window.document.documentElement); } sizeHandler(); }; this._onExit = function(){ this.unload(); s_oMain.gotoMenu(); }; this._onButHumanRelease = function(){ this.unload(); s_oMain.gotoGame(MODE_HUMAN); }; this._onButComputerRelease = function(){ this.unload(); s_oMain.gotoGame(MODE_COMPUTER, _iModeSelected); }; s_oModeMenu = this; this._init(); }; var s_oModeMenu = null; function CGame(oData){ var _bStartGame; var _bCheck; var _iPlayerState; var _iCurPlayer; var _iBlackTime; var _iWhiteTime; var _iBlackScore; var _iWhiteScore; var _iHistoryID; var _aCell; var _oInterface; var _oEndPanel = null; var _oParent; var _oBoardContainer; var _oInfoPanelContainer; var _oPiecesContainer; var _oKnightContainer; var _oMessage; var _oThinking = null; var _oBoard; var _oCellActive; var _oAI; this._init = function(){ _bStartGame=true; _bCheck = false; _iPlayerState = PLAYER_STATE_WAIT; _iCurPlayer = WHITE; _iHistoryID = 0; _iBlackTime = 0; _iWhiteTime = 0; _iBlackScore = START_SCORE; _iWhiteScore = START_SCORE; _oCellActive = null; _oMessage = null; var oBg = createBitmap(s_oSpriteLibrary.getSprite('bg_game')); s_oStage.addChild(oBg); //Draws on canvas var iScale = 1; _oBoardContainer = new createjs.Container(); _oBoardContainer.x = CANVAS_WIDTH/2; _oBoardContainer.y = CANVAS_HEIGHT/2; _oBoardContainer.scaleX = _oBoardContainer.scaleY = iScale; s_oStage.addChild(_oBoardContainer); _oInfoPanelContainer = new createjs.Container(); _oInfoPanelContainer.x = CANVAS_WIDTH/2; _oInfoPanelContainer.y = CANVAS_HEIGHT/2; _oInfoPanelContainer.scaleX = _oInfoPanelContainer.scaleY = iScale; s_oStage.addChild(_oInfoPanelContainer); _oPiecesContainer = new createjs.Container(); _oPiecesContainer.x = CANVAS_WIDTH/2; _oPiecesContainer.y = CANVAS_HEIGHT/2; _oPiecesContainer.scaleX = _oPiecesContainer.scaleY = iScale; s_oStage.addChild(_oPiecesContainer); _oKnightContainer = new createjs.Container(); _oKnightContainer.x = CANVAS_WIDTH/2; _oKnightContainer.y = CANVAS_HEIGHT/2; _oKnightContainer.scaleX = _oKnightContainer.scaleY = iScale; s_oStage.addChild(_oKnightContainer); _oInterface = new CInterface(_oInfoPanelContainer); var oSprite = s_oSpriteLibrary.getSprite('board8'); _oBoard = new createBitmap(oSprite); _oBoard.regX = oSprite.width/2; _oBoard.regY = oSprite.height/2; _oBoardContainer.addChild(_oBoard); this._initBoard(); this.setPieceDepth(); new CMovesController(_aCell); new CMovesControllerFaster(_aCell); new CBoardStateController(); _oInterface.activePlayer(_iCurPlayer); _oAI = new CAI(); this.refreshSize(); }; this._initBoard = function(){ var iLength = BOARD_LENGTH; var iNumCell = NUM_CELL; var iGridStart = -iLength/2; var iCellLength = CELL_LENGTH; var iCellStartPos = iGridStart + iCellLength/2; //Init Cell Position _aCell = new Array(); for(var i=0; i<iNumCell; i++){ _aCell[i] = new Array(); for(var j=0; j<iNumCell; j++){ var iX = iCellStartPos +j*iCellLength; var iY = iCellStartPos +i*iCellLength; _aCell[i][j] = new CCell(iX, iY, null, i, j, _oBoardContainer, _oPiecesContainer, _oKnightContainer); } } ///START CHESSBOARD for(var i=0; i<iNumCell; i++){ _aCell[1][i].createPiece(_iHistoryID, BLACK,PAWN); }; for(var i=0; i<iNumCell; i++){ _aCell[6][i].createPiece(_iHistoryID, WHITE,PAWN); }; _aCell[0][0].createPiece(_iHistoryID, BLACK,ROOK); _aCell[0][7].createPiece(_iHistoryID, BLACK,ROOK); _aCell[7][0].createPiece(_iHistoryID, WHITE,ROOK); _aCell[7][7].createPiece(_iHistoryID, WHITE,ROOK); _aCell[0][1].createPiece(_iHistoryID, BLACK,KNIGHT); _aCell[0][6].createPiece(_iHistoryID, BLACK,KNIGHT); _aCell[7][1].createPiece(_iHistoryID, WHITE,KNIGHT); _aCell[7][6].createPiece(_iHistoryID, WHITE,KNIGHT); _aCell[0][2].createPiece(_iHistoryID, BLACK,BISHOP); _aCell[0][5].createPiece(_iHistoryID, BLACK,BISHOP); _aCell[7][2].createPiece(_iHistoryID, WHITE,BISHOP); _aCell[7][5].createPiece(_iHistoryID, WHITE,BISHOP); _aCell[0][3].createPiece(_iHistoryID, BLACK,QUEEN); _aCell[0][4].createPiece(_iHistoryID, BLACK,KING); _aCell[7][3].createPiece(_iHistoryID, WHITE,QUEEN); _aCell[7][4].createPiece(_iHistoryID, WHITE,KING); }; this.refreshSize = function(){ if(_oBoardContainer && _oBoardContainer.getBounds()){ var iBoardWidth = _oBoardContainer.getBounds().width; var iOffset = 60; var iCameraWidth = CANVAS_WIDTH-s_iOffsetX*2-iOffset; var iCameraHeight = CANVAS_HEIGHT-s_iOffsetY*2-iOffset-EDGEBOARD_Y; var iBoardWidth = _oBoard.getBounds().width-200; var iBoardheight = _oBoard.getBounds().height-200; var iScale = zoomInCamera(_oBoardContainer,iCameraWidth,iCameraHeight,iBoardWidth, iBoardheight); _oInfoPanelContainer.scaleX = _oInfoPanelContainer.scaleY = iScale; _oPiecesContainer.scaleX = _oPiecesContainer.scaleY = iScale; _oKnightContainer.scaleX = _oKnightContainer.scaleY = iScale; } }; this.changeTurn = function(){ if(_oMessage !== null){ _oMessage.removeAnimated(); } _bCheck = false; _iPlayerState = PLAYER_STATE_WAIT; if(_iCurPlayer === WHITE){ _iCurPlayer = BLACK; var bEndGame = this.checkGameState(); if(s_iGameType === MODE_COMPUTER){ this._playAI(bEndGame); } } else { _iCurPlayer = WHITE; this.checkGameState(); } _oInterface.activePlayer(_iCurPlayer); }; this._playAI = function(bEndGame){ if(!bEndGame){ _oThinking = new CThinking(); _oThinking.update(); var iTimeThink = MIN_AI_THINKING + Math.random()*(MAX_AI_THINKING - MIN_AI_THINKING); var oMove = _oAI.getMove(); if(oMove !== null){ setTimeout(function(){ _oThinking.unload(); _oThinking = null; s_oGame.cellClicked(oMove.sourcerow, oMove.sourcecol); s_oGame.cellClicked(oMove.destrow, oMove.destcol); }, iTimeThink); } } }; this.cellClicked = function(iRow, iCol){ switch(_iPlayerState){ case PLAYER_STATE_WAIT:{ this._disableAllThreat(); if(_aCell[iRow][iCol].getColor() !== null && _aCell[iRow][iCol].getColor() !== _iCurPlayer){ return; } this._selectPiece(iRow, iCol); break; } case PLAYER_STATE_SELECTED:{ if( _oCellActive.getLogicPos().row === iRow && _oCellActive.getLogicPos().col === iCol ){ //////// DESELECT PIECE this._deselectPiece(); } else if(_aCell[iRow][iCol].getColor() === _iCurPlayer) { //////// SELECT ANOTHER PIECE this._deselectPiece(); this._selectPiece(iRow, iCol); } else if(_aCell[iRow][iCol].isHighlight()){ /////// MOVE OR EAT PIECE this._checkLegalMove(iRow, iCol); } else { //////// DESELECT PIECE this._deselectPiece(); } playSound("click",1,false); break; } case PLAYER_STATE_MOVING:{ break; } } }; this._checkLegalMove = function(iRow, iCol){ var aNextMovesBoard = s_oBoardStateController.copyBoard(_aCell); s_oBoardStateController.moveCopiedPiece(aNextMovesBoard, _oCellActive.getLogicPos().row, _oCellActive.getLogicPos().col, iRow, iCol); var aThreatList = s_oBoardStateController.findAllChecks(_iCurPlayer, aNextMovesBoard); if(aThreatList.length === 0){ var iSpecialMoveType = s_oBoardStateController.getSpecialMoves(_oCellActive.getLogicPos().row, _oCellActive.getLogicPos().col, iRow, iCol, _aCell); switch(iSpecialMoveType){ case BOARD_SPECIAL_CASTLING_RIGHT:{ var oRightRook = _aCell[_oCellActive.getLogicPos().row][7]; var oDestinationCell = _aCell[_oCellActive.getLogicPos().row][5]; oRightRook.shift(oDestinationCell); break; } case BOARD_SPECIAL_CASTLING_LEFT:{ var oLeftRook = _aCell[_oCellActive.getLogicPos().row][0]; var oDestinationCell = _aCell[_oCellActive.getLogicPos().row][3]; oLeftRook.shift(oDestinationCell); break; } case BOARD_SPECIAL_ENPASSANT:{ var oPawnToPass = _aCell[_oCellActive.getLogicPos().row][iCol]; oPawnToPass.eatUp(); oPawnToPass.setPiece(null); break; } } _oCellActive.setActive(false); this._movePiece(iRow, iCol); this._deselectPiece(); _iPlayerState = PLAYER_STATE_MOVING; }else { this._disableAllThreat(); for(var i=0; i<aThreatList.length; i++){ _aCell[aThreatList[i].getLogicPos().row][aThreatList[i].getLogicPos().col].threat(true); } } }; this._movePiece = function(iRow, iCol){ var oDestinationCell = _aCell[iRow][iCol]; _oCellActive.move(oDestinationCell); if(oDestinationCell.getColor() !== null){ oDestinationCell.eatUp(); }; }; this._selectPiece = function(iRow, iCol){ _oCellActive = _aCell[iRow][iCol]; _oCellActive.setActive(true); var aMovesList = s_oMovesController.getMovesList(iRow, iCol, _aCell); for(var i=0; i<aMovesList.length; i++){ _aCell[aMovesList[i].row][aMovesList[i].col].highlight(true); } _iPlayerState = PLAYER_STATE_SELECTED; playSound("click",1,false); }; this._deselectPiece = function(){ this._disableAllHighlight(); _oCellActive.setActive(false); _oCellActive = null; _iPlayerState = PLAYER_STATE_WAIT; }; this.onFinishMove = function(){ this.setPieceDepth(); ///////// CHECK IF A PAWN IS IN PROMOTION var oPawnPos = s_oBoardStateController.checkPromotion(_aCell); if(oPawnPos === null){ this.changeTurn(); } else { /////SHOW PROMO PANEL; if(s_iGameType === MODE_HUMAN){ new CPromoPanel(_iCurPlayer, oPawnPos); } else { if(_iCurPlayer === BLACK){ this.changePiece(QUEEN, oPawnPos); this.changeTurn(); } else { new CPromoPanel(_iCurPlayer, oPawnPos); } } } }; this.checkGameState = function(){ ////PREVIOUSLY FIND IF KING IS UNDER CHECK, WE NEED TO KNOW THAT BECAUSE ////CASTLING MOVES RULE NEED TO KNOW _bCheck = s_oBoardStateController.kingInCheck(_iCurPlayer, _aCell); var iCheckState = s_oBoardStateController.getState(_iCurPlayer, _aCell); var bEndGame = false; switch(iCheckState){ case BOARD_STATE_STALEMATE:{ this.gameOver(DRAW); _oMessage = new CMessage(_iCurPlayer, TEXT_STALEMATE, _oInfoPanelContainer); bEndGame = true; break; } case BOARD_STATE_CHECK:{ _bCheck = true; var aThreatList = s_oBoardStateController.findAllChecks(_iCurPlayer, _aCell); for(var i=0; i<aThreatList.length; i++){ _aCell[aThreatList[i].getLogicPos().row][aThreatList[i].getLogicPos().col].threat(true); } _oMessage = new CMessage(_iCurPlayer, TEXT_CHECK, _oInfoPanelContainer); break; } case BOARD_STATE_CHECKMATE:{ var iWinner = s_oBoardStateController.getOtherOpponent(_iCurPlayer); _oMessage = new CMessage(_iCurPlayer, TEXT_CHECKMATE, _oInfoPanelContainer); this.gameOver(iWinner); bEndGame = true; break; } } return bEndGame; }; this.setPieceDepth = function(){ var aPiecesList = new Array(); for(var i=0; i<_oPiecesContainer.children.length; i++){ var oPiece = _oPiecesContainer.children[i]; aPiecesList.push({height:oPiece.y, piece:oPiece}); }; aPiecesList.sort(this.compareHeight); var iCurDepth = 0; for(var i=0; i<_oPiecesContainer.children.length; i++){ _oPiecesContainer.setChildIndex(aPiecesList[i].piece, iCurDepth++); } }; this.compareHeight = function(a,b) { if (a.height < b.height) return -1; if (a.height > b.height) return 1; return 0; }; this.getCells = function(){ return _aCell; }; this.restartGame = function () { this.unload(); this._init(); }; this.pauseGame = function(bVal){ _bStartGame = !bVal; }; this.unload = function(){ _bStartGame = false; _oInterface.unload(); if(_oEndPanel !== null){ _oEndPanel.unload(); } createjs.Tween.removeAllTweens(); s_oStage.removeAllChildren(); }; this._disableAllHighlight = function(){ if(_oCellActive !== null){ _oCellActive.setActive(false); } for(var i = 0; i < NUM_CELL; i++) { for(var j = 0; j < NUM_CELL; j++) { _aCell[i][j].highlight(false); _aCell[i][j].threat(false); } } }; this._disableAllThreat = function(){ for(var i = 0; i < NUM_CELL; i++) { for(var j = 0; j < NUM_CELL; j++) { _aCell[i][j].threat(false); } } }; this.setAllVisible = function(bVal){ for(var i = 0; i < NUM_CELL; i++) { for(var j = 0; j < NUM_CELL; j++) { _aCell[i][j].setVisible(bVal); } } }; this.isCheck = function(){ return _bCheck; }; this.onExitPromoPanel = function(){ this.changeTurn(); }; this.changePiece = function(szPiece, oPawnPos){ var oCell = _aCell[oPawnPos.row][oPawnPos.col]; oCell.changePiece(_iCurPlayer, szPiece); }; this.getNewHistoryID = function(){ return ++_iHistoryID; }; this.getLastHistoryID = function(){ return _iHistoryID; }; this.onExit = function(){ $(s_oMain).trigger("end_session"); $(s_oMain).trigger("show_interlevel_ad"); s_oGame.unload(); s_oMain.gotoMenu(); }; this._onExitHelp = function () { _bStartGame = true; }; this.gameOver = function(iWinner){ _bStartGame = false; if(iWinner === WHITE){ _iBlackScore = 0; } else if(iWinner === BLACK) { _iWhiteScore = 0; } else if(iWinner === DRAW){ _iBlackScore = 0; _iWhiteScore = 0; } _oEndPanel = new CEndPanel(s_oSpriteLibrary.getSprite('msg_box')); setTimeout(function(){ _oEndPanel.show(iWinner, _iBlackTime, _iWhiteTime, _iBlackScore, _iWhiteScore); _oInterface.setInfoVisible(false); }, 1000); }; this.update = function(){ if(_bStartGame){ if(_oThinking !== null){ _oThinking.update(); } this.setPieceDepth(); if(_iCurPlayer === WHITE){ _iWhiteTime += s_iTimeElaps; _oInterface.refreshWhiteTime(_iWhiteTime); _iWhiteScore -= (SCORE_DECREASE_PER_SECOND * s_iTimeElaps)/1000; if(_iWhiteScore < 0){ _iWhiteScore = 0; } _oInterface.refreshWhiteScore(Math.floor(_iWhiteScore)); } else { _iBlackTime += s_iTimeElaps; _oInterface.refreshBlackTime(_iBlackTime); _iBlackScore -= (SCORE_DECREASE_PER_SECOND * s_iTimeElaps)/1000 ; if(_iBlackScore < 0){ _iBlackScore = 0; } _oInterface.refreshBlackScore(Math.floor(_iBlackScore)); } } }; SHOW_SCORE = oData.show_score; START_SCORE = oData.start_score; SCORE_DECREASE_PER_SECOND = oData.score_decrease_per_second; s_oGame=this; _oParent=this; this._init(); } var s_oGame; function CInterface(oForegroundContainer){ var _oButExit; var _oAudioToggle; var _oHelpPanel=null; var _oWhitePanel; var _oBlackPanel; var _oButFullscreen; var _oGUIExpandible; var _fRequestFullScreen = null; var _fCancelFullScreen = null; var _pStartPosFullscreen; var _pStartPosExit; var _pStartPosAudio; this._init = function(oForegroundContainer){ var oExitX; var oSprite = s_oSpriteLibrary.getSprite('but_exit'); _pStartPosExit = {x: CANVAS_WIDTH - (oSprite.height/2)- 10, y: (oSprite.height/2) + 25}; _oButExit = new CGfxButton(_pStartPosExit.x, _pStartPosExit.y, oSprite,s_oStage); _oButExit.addEventListener(ON_MOUSE_UP, this._onExit, this); oExitX = CANVAS_WIDTH - (oSprite.width/2) - 125; if(DISABLE_SOUND_MOBILE === false || s_bMobile === false){ var oSprite = s_oSpriteLibrary.getSprite('audio_icon'); _pStartPosAudio = {x: oExitX, y: 25+ (oSprite.height/2)}; _oAudioToggle = new CToggle(_pStartPosAudio.x,_pStartPosAudio.y,oSprite,s_bAudioActive, s_oStage); _oAudioToggle.addEventListener(ON_MOUSE_UP, this._onAudioToggle, this); } var doc = window.document; var docEl = doc.documentElement; _fRequestFullScreen = docEl.requestFullscreen || docEl.mozRequestFullScreen || docEl.webkitRequestFullScreen || docEl.msRequestFullscreen; _fCancelFullScreen = doc.exitFullscreen || doc.mozCancelFullScreen || doc.webkitExitFullscreen || doc.msExitFullscreen; if(ENABLE_FULLSCREEN === false){ _fRequestFullScreen = false; } if (_fRequestFullScreen && screenfull.isEnabled){ oSprite = s_oSpriteLibrary.getSprite('but_fullscreen'); _pStartPosFullscreen = {x:oSprite.width/4 + 10,y:(oSprite.height/2) +25}; _oButFullscreen = new CToggle(_pStartPosFullscreen.x,_pStartPosFullscreen.y,oSprite,s_bFullscreen,s_oStage); _oButFullscreen.addEventListener(ON_MOUSE_UP, this._onFullscreenRelease, this); } var oSprite = s_oSpriteLibrary.getSprite('but_settings'); _oGUIExpandible = new CGUIExpandible(_pStartPosExit.x, _pStartPosExit.y, oSprite, s_oStage); _oGUIExpandible.addButton(_oButExit); if(DISABLE_SOUND_MOBILE === false || s_bMobile === false){ _oGUIExpandible.addButton(_oAudioToggle); } if (_fRequestFullScreen && screenfull.isEnabled){ _oGUIExpandible.addButton(_oButFullscreen); } var iY = 516; _oWhitePanel = new CInfoTurn(220,iY,WHITE, oForegroundContainer); var iX; if(s_iGameType === MODE_HUMAN && s_bMobile){ iX = -220; } else { iX = -240; } _oBlackPanel = new CInfoTurn(iX,-iY,BLACK, oForegroundContainer); this.refreshButtonPos(s_iOffsetX,s_iOffsetY); }; this.unload = function(){ _oButExit.unload(); if(DISABLE_SOUND_MOBILE === false || s_bMobile === false){ _oAudioToggle.unload(); } if(_oHelpPanel!==null){ _oHelpPanel.unload(); } _oBlackPanel.unload(); _oWhitePanel.unload(); if (_fRequestFullScreen && screenfull.isEnabled){ _oButFullscreen.unload(); } s_oInterface = null; }; this.refreshButtonPos = function(iNewX,iNewY){ _oGUIExpandible.refreshPos(iNewX,iNewY); s_oGame.refreshSize(); }; this.refreshWhiteTime = function(iTime){ if(iTime > 50){ _oWhitePanel.refreshTime(formatTime(iTime)); } }; this.refreshBlackTime = function(iTime){ if(iTime > 50){ _oBlackPanel.refreshTime(formatTime(iTime)); } }; this.refreshWhiteScore = function(iScore){ _oWhitePanel.refreshScore(iScore); }; this.refreshBlackScore = function(iScore){ _oBlackPanel.refreshScore(iScore); }; this.activePlayer = function(iCurPlayer){ if(iCurPlayer === WHITE){ _oBlackPanel.active(false); _oWhitePanel.active(true); } else { _oWhitePanel.active(false); _oBlackPanel.active(true); } }; this.setInfoVisible = function(bVal){ _oWhitePanel.setPanelVisible(bVal); _oBlackPanel.setPanelVisible(bVal); }; this._onButConfigRelease = function(){ new CConfigPanel(); }; this._onButRestartRelease = function(){ s_oGame.restartGame(); }; this.onExitFromHelp = function(){ _oHelpPanel.unload(); }; this._onExit = function(){ new CAreYouSurePanel(s_oGame.onExit); }; this._onAudioToggle = function(){ Howler.mute(s_bAudioActive); s_bAudioActive = !s_bAudioActive; }; this.resetFullscreenBut = function(){ if (_fRequestFullScreen && screenfull.isEnabled){ _oButFullscreen.setActive(s_bFullscreen); } }; this._onFullscreenRelease = function(){ if(s_bFullscreen) { _fCancelFullScreen.call(window.document); }else{ _fRequestFullScreen.call(window.document.documentElement); } sizeHandler(); }; s_oInterface = this; this._init(oForegroundContainer); return this; } var s_oInterface = null; function CInfoTurn(iX, iY, iType, oParentContainer){ var _oPanel; var _oBg; var _oBgHighlight; var _oTime; var _oPawn; var _oScorePanel; var _oScoreText; var _oParent; this._init = function(iX, iY, iType, oParentContainer){ _oPanel = new createjs.Container(); _oPanel.x = iX; _oPanel.y = iY; if(s_iGameType === MODE_HUMAN && iType === BLACK && s_bMobile){ _oPanel.rotation = 180; } oParentContainer.addChild(_oPanel); _oScorePanel = new createjs.Container(); var iX = -324; var iY = 30; if(iType === WHITE){ _oScorePanel.x = iX; _oScorePanel.y = -iY; } else { _oScorePanel.x = -iX + 20; if(s_iGameType === MODE_HUMAN && iType === BLACK && s_bMobile){ _oScorePanel.x = iX; _oScorePanel.y = -iY; }else { _oScorePanel.y = iY; } } _oPanel.addChild(_oScorePanel); if(!SHOW_SCORE || (s_iGameType === MODE_COMPUTER && iType === BLACK)){ _oScorePanel.visible = false; } var oSprite = s_oSpriteLibrary.getSprite('score_panel'); var oScoreBg = createBitmap(oSprite); oScoreBg.regX = oSprite.width/2; oScoreBg.regY = oSprite.height/2; _oScorePanel.addChild(oScoreBg); _oScoreText = new createjs.Text(START_SCORE," 30px "+PRIMARY_FONT, "#ffffff"); _oScoreText.x = 90; _oScoreText.textAlign = "right"; _oScoreText.textBaseline = "middle"; _oScoreText.lineWidth = 200; _oScorePanel.addChild(_oScoreText); var oSprite = s_oSpriteLibrary.getSprite('bg_turn'); var oData = { // image to use images: [oSprite], framerate: 58, // width, height & registration point of each sprite frames: {width: oSprite.width/2, height: oSprite.height, regX:(oSprite.width/2)/2,regY:oSprite.height/2}, animations: { off: [0,0,"on"], on:[1,1,"off"]} }; var oSpriteSheet = new createjs.SpriteSheet(oData); _oBg = createSprite(oSpriteSheet,0,(oSprite.width/2)/2,oSprite.height/2,oSprite.width/2,oSprite.height); _oBg.stop(); _oPanel.addChild(_oBg); _oBgHighlight = createSprite(oSpriteSheet,1,(oSprite.width/2)/2,oSprite.height/2,oSprite.width/2,oSprite.height); _oBgHighlight.stop(); _oBgHighlight.x = 10; _oBgHighlight.alpha = 0; _oPanel.addChild(_oBgHighlight); var oSprite = s_oSpriteLibrary.getSprite(iType + '_king_marker'); _oPawn = createBitmap(oSprite); _oPawn.x = 160; _oPawn.regX = oSprite.width/2; _oPawn.regY = oSprite.height/2; _oPanel.addChild(_oPawn); _oTime = new createjs.Text("00:00"," 58px "+PRIMARY_FONT, "#ffffff"); _oTime.x = -65; _oTime.y = 2; _oTime.textBaseline = "middle"; _oTime.lineWidth = 200; _oPanel.addChild(_oTime); }; this.refreshTime = function(szTime){ _oTime.text = szTime; }; this.refreshScore = function(szScore){ _oScoreText.text = szScore; }; this.invert = function(){ _oTime.x = 0; _oPawn.x = -100; }; this.active = function(bVal){ if(bVal){ createjs.Tween.get(_oBg, {loop:true}).to({alpha:0}, 750, createjs.Ease.cubicOut).wait(2000).to({alpha:1}, 750, createjs.Ease.cubicIn); createjs.Tween.get(_oBgHighlight, {loop:true}).to({alpha:1}, 750, createjs.Ease.cubicOut).wait(2000).to({alpha:0}, 750, createjs.Ease.cubicIn); } else { _oBg.alpha = 1; _oBgHighlight.alpha = 0; createjs.Tween.removeTweens(_oBg); createjs.Tween.removeTweens(_oBgHighlight); } }; this.unload = function(){ oParentContainer.removeChild(_oPanel); }; this.setBgVisible = function(bVal){ _oBg.visible = bVal; _oScorePanel.visible = bVal; }; this.setPanelVisible = function(bVal){ _oPanel.visible = bVal; }; this.setPawn = function(iType){ _oPawn.gotoAndStop(iType); }; _oParent = this; this._init(iX, iY, iType, oParentContainer); }; function CThinking(){ var _bStart; var _iTimeElaps; var _oGroup; var _oText; var _oTextDots; var _oRect; var _oListener; this._init = function(){ _bStart = true; _iTimeElaps=0; _oGroup = new createjs.Container(); var graphics = new createjs.Graphics().beginFill("rgba(0,0,0,0.3)").drawRect(0, 0, CANVAS_WIDTH, CANVAS_HEIGHT); _oRect = new createjs.Shape(graphics); _oListener = _oRect.on("click", function(){}); _oText = new createjs.Text("","bold 60px "+PRIMARY_FONT, "#ffffff"); _oText.x = CANVAS_WIDTH*0.5; _oText.y = CANVAS_HEIGHT*0.5 -100; _oText.textAlign = "center"; _oText.textBaseline = "alphabetic"; _oText.lineWidth = 800; _oTextDots = new createjs.Text("","bold 180px "+PRIMARY_FONT, "#ffffff"); _oTextDots.x = CANVAS_WIDTH*0.5 - 76; _oTextDots.y = CANVAS_HEIGHT*0.5 -50; _oTextDots.textAlign = "left"; _oTextDots.textBaseline = "alphabetic"; _oTextDots.lineWidth = 800; _oGroup.addChild(_oRect, _oText, _oTextDots); s_oStage.addChild(_oGroup); }; this.unload = function(){ _bStart =false; _oRect.off("click", _oListener); s_oStage.removeChild(_oGroup); }; this.update = function(){ if(_bStart){ _iTimeElaps += s_iTimeElaps; if(_iTimeElaps >= 0 && _iTimeElaps < TIME_LOOP_WAIT/4){ _oTextDots.text = ""; } else if (_iTimeElaps >= TIME_LOOP_WAIT/4 && _iTimeElaps < TIME_LOOP_WAIT*2/4){ _oTextDots.text = "."; } else if (_iTimeElaps >= TIME_LOOP_WAIT*2/4 && _iTimeElaps < TIME_LOOP_WAIT*3/4){ _oTextDots.text = ".."; } else if (_iTimeElaps >= TIME_LOOP_WAIT*3/4 && _iTimeElaps < TIME_LOOP_WAIT){ _oTextDots.text = "..."; } else { _iTimeElaps = 0; } } }; this._init(); }; function CEndPanel(oSpriteBg){ var _oBg; var _oGroup; var _oBlackPanel; var _oWhitePanel; var _oMsgText; var _oMsgTextUnder; var _oFade; var _oHome; var _oCheckBoard; var _oRestart; var _oListener; this._init = function(oSpriteBg){ s_oGame.pauseGame(true); _oGroup = new createjs.Container(); _oGroup.alpha = 0; _oGroup.visible=false; s_oStage.addChild(_oGroup); _oFade = new createjs.Shape(); _oFade.graphics.beginFill("black").drawRect(0,0,CANVAS_WIDTH,CANVAS_HEIGHT); _oFade.alpha = 0.7; _oGroup.addChild(_oFade); _oBg = createBitmap(oSpriteBg); _oBg.regX = oSpriteBg.width/2; _oBg.regY = oSpriteBg.height/2; _oBg.x = CANVAS_WIDTH/2; _oBg.y = CANVAS_HEIGHT/2; _oGroup.addChild(_oBg); var iWidth = oSpriteBg.width-120; var iHeight = 100; var iX = CANVAS_WIDTH/2; var iY = CANVAS_HEIGHT/2 - 300; _oMsgText = new CTLText(_oGroup, iX-iWidth/2, iY-iHeight/2, iWidth, iHeight, 90, "center", "#ffffff", PRIMARY_FONT, 1, 2, 2, "", true, true, false, false ); var iWidth = oSpriteBg.width-320; var iHeight = 50; var iX = CANVAS_WIDTH/2; var iY = CANVAS_HEIGHT/2 - 230; _oMsgTextUnder = new CTLText(_oGroup, iX-iWidth/2, iY-iHeight/2, iWidth, iHeight, 40, "center", "#ffffff", PRIMARY_FONT, 1, 2, 2, "", true, true, false, false ); _oBlackPanel = new CInfoTurn(CANVAS_WIDTH/2,1000,BLACK, _oGroup); _oBlackPanel.setBgVisible(false); _oBlackPanel.invert(); _oWhitePanel = new CInfoTurn(CANVAS_WIDTH/2,850,WHITE, _oGroup); _oWhitePanel.setBgVisible(false); _oWhitePanel.invert(); var oSprite = s_oSpriteLibrary.getSprite('but_restart'); _oRestart = new CGfxButton(CANVAS_WIDTH/2 - 180, CANVAS_HEIGHT/2 + 250, oSprite, _oGroup); _oRestart.addEventListener(ON_MOUSE_UP, this._onRestart, this); var oSprite = s_oSpriteLibrary.getSprite('but_home'); _oHome = new CGfxButton(CANVAS_WIDTH/2, CANVAS_HEIGHT/2 + 250, oSprite, _oGroup); _oHome.addEventListener(ON_MOUSE_UP, this._onExit, this); var oSprite = s_oSpriteLibrary.getSprite('but_show'); _oCheckBoard = new CGfxButton(CANVAS_WIDTH/2 + 180, CANVAS_HEIGHT/2 + 250, oSprite, _oGroup); _oCheckBoard.addEventListener(ON_MOUSE_UP, this._onShow, this); }; this.unload = function(){ _oGroup.off("mousedown",_oListener); }; this._initListener = function(){ _oListener = _oGroup.on("mousedown",this._onExit); }; this.show = function(iWinner, iBlackTime, iWhiteTime, iBlackScore, iWhiteScore){ _oBlackPanel.refreshTime(formatTime(iBlackTime)); _oWhitePanel.refreshTime(formatTime(iWhiteTime)); if(iWinner === WHITE){ playSound("win",1,false); _oMsgText.refreshText( TEXT_CHECKMATE ); _oMsgTextUnder.refreshText( sprintf(TEXT_WINS, TEXT_WHITE) ); } else if(iWinner === BLACK) { if(s_iGameType === MODE_HUMAN){ playSound("win",1,false); } else { playSound("game_over",1,false); } _oMsgText.refreshText( TEXT_CHECKMATE ); _oMsgTextUnder.refreshText( sprintf(TEXT_WINS, TEXT_BLACK) ); } else if(iWinner === DRAW){ playSound("game_over",1,false); _oMsgText.refreshText( TEXT_STALEMATE ); _oMsgTextUnder.refreshText( TEXT_DRAW ); } _oGroup.visible = true; var oParent = this; createjs.Tween.get(_oGroup).to({alpha:1 }, 500); $(s_oMain).trigger("save_score", [iWinner, iBlackTime, iWhiteTime, s_iGameType, iWhiteScore, iBlackScore]); $(s_oMain).trigger("share_event", [iWhiteScore, s_iGameType, iWinner] ); }; this._onRestart = function(){ s_oGame.restartGame(); }; this._onExit = function(){ _oGroup.off("mousedown",_oListener); _oBlackPanel.unload(); _oWhitePanel.unload(); s_oStage.removeChild(_oGroup); _oHome.unload(); _oCheckBoard.unload(); $(s_oMain).trigger("end_session"); $(s_oMain).trigger("show_interlevel_ad"); s_oGame.onExit(); }; this._onShow = function(){ _oGroup.visible = false; $(s_oMain).trigger("end_session"); }; this._init(oSpriteBg); return this; } function CCell(iX, iY, iType, iRow, iCol, oParentContainer, oPieceContainer, oKnightContainer){ var _iRow; var _iCol; var _oCellContainer; var _oParent; var _oPiece; var _oClickArea; var _oThreat; var _oHighlight; var _oListener this._init = function(iX, iY, iType, iRow, iCol, oParentContainer, oPieceContainer, oKnightContainer){ _iRow = iRow; _iCol = iCol; _oCellContainer = new createjs.Container(); _oCellContainer.x = iX; _oCellContainer.y = iY; oParentContainer.addChild(_oCellContainer); _oPiece = null; var oSprite = s_oSpriteLibrary.getSprite('highlight'); _oHighlight = createBitmap(oSprite); _oHighlight.regX = oSprite.width/2; _oHighlight.regY = oSprite.height/2; _oHighlight.alpha = 0.8; _oHighlight.visible = false; _oCellContainer.addChild(_oHighlight); var oSprite = s_oSpriteLibrary.getSprite('threat'); _oThreat = createBitmap(oSprite); _oThreat.regX = oSprite.width/2; _oThreat.regY = oSprite.height/2; _oThreat.visible = false; _oCellContainer.addChild(_oThreat); _oClickArea = new createjs.Shape(); _oClickArea.graphics.beginFill("rgba(158,0,0,0.01)").drawRect(-CELL_LENGTH/2, -CELL_LENGTH/2, CELL_LENGTH, CELL_LENGTH); _oListener = _oClickArea.on("mousedown", this._onCellClick); _oCellContainer.addChild(_oClickArea); }; this.unload = function(){ oParentContainer.removeChild(_oCellContainer); _oClickArea.off("mousedown", _oListener); }; this.setClickableArea = function(bVal){ _oClickArea.visible = bVal; }; this.changePiece = function(szColor, szType){ var aOldHistory = _oPiece.getHistory(); _oPiece.unload(); _oPiece = new CPiece(iX, iY, szColor, szType, oPieceContainer, oKnightContainer); _oPiece.setHistory(aOldHistory); _oPiece.setNewMoveInHistory(s_oGame.getNewHistoryID(), iRow, iCol, szType); }; this.createPiece = function(iId, szColor, szType){ _oPiece = new CPiece(iX, iY, szColor, szType, oPieceContainer, oKnightContainer); _oPiece.setNewMoveInHistory(iId, iRow, iCol, szType); }; this.getPieceContainer = function(){ return _oPiece.getContainer(); }; this.setPiece = function(oPiece){ _oPiece = oPiece; }; this.getType = function(){ if(_oPiece !== null){ return _oPiece.getType(); } else{ return null; } }; this.getColor = function(){ if(_oPiece !== null){ return _oPiece.getColor(); } else{ return null; } }; this.getPieceHistory = function(){ if(_oPiece !== null){ return _oPiece.getHistory(); }else { return []; } }; this.threat = function(bVal){ _oThreat.visible = bVal; }; this.highlight = function(bVal){ _oHighlight.visible = bVal; }; this.isHighlight = function(){ return _oHighlight.visible; }; this._onCellClick = function(){ s_oGame.cellClicked(_iRow, _iCol); }; this.setActive = function(bVal){ if(_oPiece !== null){ _oPiece.setActive(bVal); }; }; this.setVisible = function(bVal){ _oCellContainer.visible = bVal; }; this.getPos = function(){ return {x: iX, y:iY}; }; this.getLogicPos = function(){ return {row: iRow, col: iCol}; }; this.move = function(oDestCell){ _oPiece.move(oDestCell); _oPiece = null; }; this.shift = function(oDestCell){ _oPiece.shift(oDestCell); _oPiece = null; }; this.eatUp = function(){ _oPiece.disappear(); }; _oParent = this; this._init(iX, iY, iType, iRow, iCol, oParentContainer, oPieceContainer, oKnightContainer); } function CPiece(iX, iY, szColor, szType, oParentContainer, oKnightContainer){ var _szColor; var _szType; var _aMovesHistory; var _oParent; var _oPiece; this._init = function(iX, iY, szColor, szType, oParentContainer, oKnightContainer){ _szColor = szColor; _szType = szType; _aMovesHistory = new Array(); var szSpriteName = this._getSpriteName(); var oSprite = s_oSpriteLibrary.getSprite(szSpriteName); var iWidth = oSprite.width/2; var iHeight = oSprite.height; var oData = { images: [oSprite], // width, height & registration point of each sprite frames: {width: iWidth, height: iHeight, regX: iWidth/2, regY: iHeight-40}, animations: {idle:[0], lit:[1]} }; var oSpriteSheet = new createjs.SpriteSheet(oData); _oPiece = createSprite(oSpriteSheet,"idle",0,0,0,0); _oPiece.x = iX; _oPiece.y = iY; oParentContainer.addChild(_oPiece); }; this.unload = function(){ oParentContainer.removeChild(_oPiece); }; this._getSpriteName = function(){ var szSpriteColor; if(szColor === WHITE){ szSpriteColor = "white"; }else { szSpriteColor = "black"; } var szSpriteType; switch(szType){ case PAWN:{ szSpriteType = "pawn"; break; } case ROOK:{ szSpriteType = "rook"; break; } case KNIGHT:{ szSpriteType = "knight"; break; } case BISHOP:{ szSpriteType = "bishop"; break; } case QUEEN:{ szSpriteType = "queen"; break; } case KING:{ szSpriteType = "king"; break; } } return szSpriteColor +"_"+szSpriteType; }; this.getContainer = function(){ return _oPiece; }; this.getType = function(){ return _szType; }; this.getColor = function(){ return _szColor; }; this.setPos = function(iX, iY){ _oPiece.x = iX; _oPiece.y = iY; }; this.getPos = function(){ return {x:_oPiece.x, y:_oPiece.y}; }; this.setNewMoveInHistory = function(iId, iRow, iCol, szPieceType){ _aMovesHistory.push({id:iId, row:iRow, col:iCol, piece:szPieceType}); }; this.setHistory = function(aHistory){ _aMovesHistory = new Array(); for(var i=0; i<aHistory.length; i++){ _aMovesHistory[i] = aHistory[i]; } }; this.getHistory = function(){ return _aMovesHistory; }; this.setActive = function(bVal){ if(bVal){ _oPiece.gotoAndStop("lit"); } else { _oPiece.gotoAndStop("idle"); } }; this.move = function(oDestinationCell){ var oPos = oDestinationCell.getPos(); if(_szType === KNIGHT){ oKnightContainer.addChild(_oPiece); new createjs.Tween.get(_oPiece).to({scaleX:1.3, scaleY:1.3}, TIME_MOVE*0.4, createjs.Ease.cubicOut).to({scaleX:1, scaleY:1}, 600); } else if(_szType === PAWN){ s_oBoardStateController.resetStall(); } new createjs.Tween.get(_oPiece).to({x:oPos.x, y:oPos.y}, TIME_MOVE, createjs.Ease.cubicOut).call(function(){ s_oBoardStateController.increaseStallCount(); if(_szType === KNIGHT){ oParentContainer.addChild(_oPiece); } oDestinationCell.setPiece(_oParent); _oParent.setNewMoveInHistory(s_oGame.getNewHistoryID(), oDestinationCell.getLogicPos().row, oDestinationCell.getLogicPos().col, _szType); s_oGame.onFinishMove(); }); }; this.shift = function(oDestinationCell){ var oPos = oDestinationCell.getPos(); new createjs.Tween.get(_oPiece).to({x:oPos.x, y:oPos.y}, 1000, createjs.Ease.cubicOut).call(function(){ oDestinationCell.setPiece(_oParent); _oParent.setNewMoveInHistory(s_oGame.getNewHistoryID(), oDestinationCell.getLogicPos().row, oDestinationCell.getLogicPos().col, _szType); }); }; this.disappear = function(){ new createjs.Tween.get(_oPiece).to({alpha:0}, 1000).call(function(){ s_oBoardStateController.resetStall(); _oParent.unload(); }); }; _oParent = this; this._init(iX, iY, szColor, szType, oParentContainer, oKnightContainer); } var DIR_TOPRIGHT = "DIR_TOPRIGHT"; var DIR_RIGHT = "DIR_RIGHT"; var DIR_BOTRIGHT = "DIR_BOTRIGHT"; var DIR_TOPLEFT = "DIR_TOPLEFT"; var DIR_LEFT = "DIR_LEFT"; var DIR_BOTLEFT = "DIR_BOTLEFT"; var DIR_TOP = "DIR_TOP"; var DIR_BOT = "DIR_BOT"; function CMovesController(aMatrix){ var _iRow; var _iCol; var _aMatrixMap; var _aRadiusMap; this._init = function(aMatrix){ _iRow = aMatrix.length; _iCol = aMatrix[0].length; _aRadiusMap = new Array(); _aMatrixMap = new Array(); for(var i=0; i<_iRow; i++){ _aMatrixMap[i] = new Array(); for(var j=0; j<_iCol; j++){ _aMatrixMap[i][j] = new Array(); } } this._buildMap(); }; this._buildMap = function(){ for(var i=0; i<_iRow; i++){ for(var j=0; j<_iCol; j++){ _aMatrixMap[i][j][DIR_TOPRIGHT] = this._setNeighbor(i,j,DIR_TOPRIGHT); _aMatrixMap[i][j][DIR_RIGHT] = this._setNeighbor(i,j,DIR_RIGHT); _aMatrixMap[i][j][DIR_BOTRIGHT] = this._setNeighbor(i,j,DIR_BOTRIGHT); _aMatrixMap[i][j][DIR_TOPLEFT] = this._setNeighbor(i,j,DIR_TOPLEFT); _aMatrixMap[i][j][DIR_LEFT] = this._setNeighbor(i,j,DIR_LEFT); _aMatrixMap[i][j][DIR_BOTLEFT] = this._setNeighbor(i,j,DIR_BOTLEFT); _aMatrixMap[i][j][DIR_TOP] = this._setNeighbor(i,j,DIR_TOP); _aMatrixMap[i][j][DIR_BOT] = this._setNeighbor(i,j,DIR_BOT); } } }; this._setNeighbor = function(r, c, iDir){ var oNextDir = null; switch(iDir){ ////r%2 IS USED TO DETECT INDEX COLUMN FOR AN "ODD-ROW" HORIZONTAL LAYOUT HEX GRID. FOR EXAMPLE, IF ROW IS ODD, THE TOPRIGHT NEIGHBOR IS = COL+1. IF ROW IS EVEN, THE TOPRIGHT NEIGHBOR IS = COL. case DIR_TOPRIGHT:{ if(r>0 && c<_iCol-1){ oNextDir = {row: r-1, col: c+1}; } break; } case DIR_RIGHT:{ if(c<_iCol-1){ oNextDir = {row: r, col: c+1}; } break; } case DIR_BOTRIGHT:{ if(r<_iRow-1 && c<_iCol-1){ oNextDir = {row: r+1, col: c+1}; } break; } case DIR_TOPLEFT:{ if(r>0 && c > 0){ oNextDir = {row: r-1, col: c-1}; } break; } case DIR_LEFT:{ if(c>0){ oNextDir = {row: r, col: c-1}; } break; } case DIR_BOTLEFT:{ if(r<_iRow-1 && c > 0){ oNextDir = {row: r+1, col: c-1}; } break; } case DIR_TOP:{ if(r>0){ oNextDir = {row: r-1, col: c}; } break; } case DIR_BOT:{ if(r<_iRow-1){ oNextDir = {row: r+1, col: c}; } break; } } return oNextDir; }; this._getNeighborByDir = function(iRow, iCol, iDir){ return _aMatrixMap[iRow][iCol][iDir]; }; this._getAllNeighbor = function(iRow, iCol){ var aNeighborList = new Array(); for (var key in _aMatrixMap[iRow][iCol]) { if(_aMatrixMap[iRow][iCol][key]!== null){ aNeighborList.push(_aMatrixMap[iRow][iCol][key]); } } return aNeighborList; }; this._getMainDiagonal = function(iRow, iCol, aBoard){ var aList = new Array(); var szColor = aBoard[iRow][iCol].getColor(); this._findInDirection(iRow, iCol, DIR_BOTRIGHT, aList, 99, szColor, aBoard); this._findInDirection(iRow, iCol, DIR_TOPLEFT, aList, 99, szColor, aBoard); return aList; }; this._getSecondDiagonal = function(iRow, iCol, aBoard){ var aList = new Array(); var szColor = aBoard[iRow][iCol].getColor(); this._findInDirection(iRow, iCol, DIR_BOTLEFT, aList, 99, szColor, aBoard); this._findInDirection(iRow, iCol, DIR_TOPRIGHT, aList, 99, szColor, aBoard); return aList; }; this._getRow = function(iRow, iCol, aBoard){ var aList = new Array(); var szColor = aBoard[iRow][iCol].getColor(); this._findInDirection(iRow, iCol, DIR_LEFT, aList, 99, szColor, aBoard); this._findInDirection(iRow, iCol, DIR_RIGHT, aList, 99, szColor, aBoard); return aList; }; this._getCol = function(iRow, iCol, aBoard){ var aList = new Array(); var szColor = aBoard[iRow][iCol].getColor(); this._findInDirection(iRow, iCol, DIR_TOP, aList, 99, szColor, aBoard); this._findInDirection(iRow, iCol, DIR_BOT, aList, 99, szColor, aBoard); return aList; }; this._getStraightByDirAndRadius = function(iRow, iCol, szDir, iRadius, aBoard){ var aList = new Array(); _aRadiusMap = new Array(); _aRadiusMap.push({radius:iRadius, direction: null}); var szColor = aBoard[iRow][iCol].getColor(); this._findInDirection(iRow, iCol, szDir, aList, iRadius, szColor, aBoard); return aList; }; this._getStraightRowByRadius = function(iRow, iCol, iRadius){ var aList = new Array(); _aRadiusMap = new Array(); _aRadiusMap.push({radius:iRadius, direction: null}); this._findInDirection(iRow, iCol, DIR_LEFT, aList, iRadius); this._findInDirection(iRow, iCol, DIR_RIGHT, aList, iRadius); return aList; }; this._getStraightColByRadius = function(iRow, iCol, iRadius){ var aList = new Array(); _aRadiusMap = new Array(); _aRadiusMap.push({radius:iRadius, direction: null}); this._findInDirection(iRow, iCol, DIR_TOP, aList, iRadius); this._findInDirection(iRow, iCol, DIR_BOT, aList, iRadius); return aList; }; this._findInDirection = function(iRow, iCol, iDir, aList, iRadius, szColor, aBoard){ var iCountRadius = iRadius-1; if(_aMatrixMap[iRow][iCol][iDir] !== null && iCountRadius>=0){ var iNextRow = _aMatrixMap[iRow][iCol][iDir].row; var iNextCol = _aMatrixMap[iRow][iCol][iDir].col; if(szColor){ var szNextColor = aBoard[iNextRow][iNextCol].getColor(); if(szNextColor === szColor){ return; }else if (szNextColor === null){ aList.push({row: iNextRow, col: iNextCol}); _aRadiusMap.push({radius:iCountRadius, direction: iDir}); this._findInDirection(iNextRow, iNextCol, iDir, aList, iCountRadius, szColor, aBoard); } else { aList.push({row: iNextRow, col: iNextCol}); _aRadiusMap.push({radius:iCountRadius, direction: iDir}); } } else { aList.push({row: iNextRow, col: iNextCol}); _aRadiusMap.push({radius:iCountRadius, direction: iDir}); this._findInDirection(iNextRow, iNextCol, iDir, aList, iCountRadius, szColor, aBoard); } } }; this._findTPos = function(iRow, iCol, iDir){ var aPos = new Array(); var oFirstStep = _aMatrixMap[iRow][iCol][iDir]; if(oFirstStep !== null){ var oSecondStep = _aMatrixMap[oFirstStep.row][oFirstStep.col][iDir]; if(oSecondStep !== null){ if(iDir === DIR_TOP || iDir === DIR_BOT){ aPos = this._getStraightRowByRadius(oSecondStep.row, oSecondStep.col, 1); } else { aPos = this._getStraightColByRadius(oSecondStep.row, oSecondStep.col, 1); } }; }; return aPos; }; this.getMovesList = function(iRow, iCol, aBoard, bSimpleKing){ var szType = aBoard[iRow][iCol].getType(); var aMovesList = new Array(); switch(szType){ case PAWN:{ aMovesList = this.getPawnMove(iRow, iCol, aBoard); break; } case ROOK:{ aMovesList = this.getRookMove(iRow, iCol, aBoard); break; } case KNIGHT:{ aMovesList = this.getKnightMove(iRow, iCol, aBoard); break; } case BISHOP:{ aMovesList = this.getBishopMove(iRow, iCol, aBoard); break; } case QUEEN:{ aMovesList = this.getQueenMove(iRow, iCol, aBoard); break; } case KING:{ if(bSimpleKing){ ///PREVENT INFINITE STACK LOOP WHEN CHECKING CASTLING aMovesList = this.getSimpleKingMove(iRow, iCol, aBoard); }else { aMovesList = this.getKingMove(iRow, iCol, aBoard); } break; } } return aMovesList; }; this.getPawnMove = function(iRow, iCol, aBoard){ var szColor = aBoard[iRow][iCol].getColor(); var aMoveList = new Array(); var aEatList = new Array(); if(szColor === WHITE){ ////////// MOVE LIST if(iRow === 6){ aMoveList = this._getStraightByDirAndRadius(iRow, iCol, DIR_TOP, 2, aBoard); } else { aMoveList = this._getStraightByDirAndRadius(iRow, iCol, DIR_TOP, 1, aBoard); } ////////// EAT LIST var oNeighbor = this._getNeighborByDir(iRow, iCol, DIR_TOPRIGHT); if(oNeighbor !== null){ if(aBoard[oNeighbor.row][oNeighbor.col].getColor() === BLACK){ aEatList.push(oNeighbor); } } var oNeighbor = this._getNeighborByDir(iRow, iCol, DIR_TOPLEFT); if(oNeighbor !== null){ if(aBoard[oNeighbor.row][oNeighbor.col].getColor() === BLACK){ aEatList.push(oNeighbor); } } ////////// CHECK EN-PASSANT if(iRow === 3){ var aList = this._getEnPassant(WHITE, iRow, iCol, aBoard); for(var i=0; i<aList.length; i++){ aEatList.push(aList[i]); }; } } else{ ////////// MOVE LIST if(iRow === 1){ aMoveList = this._getStraightByDirAndRadius(iRow, iCol, DIR_BOT, 2, aBoard); } else { aMoveList = this._getStraightByDirAndRadius(iRow, iCol, DIR_BOT, 1, aBoard); } ////////// EAT LIST var oNeighbor = this._getNeighborByDir(iRow, iCol, DIR_BOTRIGHT); if(oNeighbor !== null){ if(aBoard[oNeighbor.row][oNeighbor.col].getColor() === WHITE){ aEatList.push(oNeighbor); } } var oNeighbor = this._getNeighborByDir(iRow, iCol, DIR_BOTLEFT); if(oNeighbor !== null){ if(aBoard[oNeighbor.row][oNeighbor.col].getColor() === WHITE){ aEatList.push(oNeighbor); } } ////////// CHECK EN-PASSANT if(iRow === 4){ var aList = this._getEnPassant(BLACK, iRow, iCol, aBoard); for(var i=0; i<aList.length; i++){ aEatList.push(aList[i]); }; } } ///////////// REMOVE OCCUPIED CELLS BY ENEMY for(var i=aMoveList.length-1; i>=0; i--){ if(aBoard[aMoveList[i].row][aMoveList[i].col].getColor() !== null && aBoard[aMoveList[i].row][aMoveList[i].col].getColor() !== szColor){ aMoveList.splice(i,1); } }; for(var i=0; i<aEatList.length; i++){ aMoveList.push(aEatList[i]); }; return aMoveList; }; this.getRookMove = function(iRow, iCol, aBoard){ var aRowList = this._getRow(iRow, iCol, aBoard); var aColList = this._getCol(iRow, iCol, aBoard); var aList = new Array(); for(var i=0; i<aRowList.length; i++){ aList.push(aRowList[i]); } for(var i=0; i<aColList.length; i++){ aList.push(aColList[i]); } return aList; }; this.getKnightMove = function(iRow, iCol, aBoard){ var aList = new Array(); aList.push( this._findTPos(iRow, iCol, DIR_TOP) ); aList.push( this._findTPos(iRow, iCol, DIR_RIGHT) ); aList.push( this._findTPos(iRow, iCol, DIR_BOT) ); aList.push( this._findTPos(iRow, iCol, DIR_LEFT) ); var aLList = new Array(); for(var i=0; i<aList.length; i++){ for(var j=0; j<aList[i].length; j++){ aLList.push(aList[i][j]); } } //REMOVE ALLY POSITION FROM MOVES var szColor = aBoard[iRow][iCol].getColor(); for(var i= aLList.length-1; i>=0; i--){ if(aBoard[aLList[i].row][aLList[i].col].getColor() === szColor){ aLList.splice(i,1); } } return aLList; }; this.getBishopMove = function(iRow, iCol, aBoard){ var aMainList = this._getMainDiagonal(iRow, iCol, aBoard); var aSecondList = this._getSecondDiagonal(iRow, iCol, aBoard); var aList = new Array(); for(var i=0; i<aMainList.length; i++){ aList.push(aMainList[i]); } for(var i=0; i<aSecondList.length; i++){ aList.push(aSecondList[i]); } return aList; }; this.getQueenMove = function(iRow, iCol, aBoard){ var aStraightList = this.getRookMove(iRow, iCol, aBoard); var aDiagonalList = this.getBishopMove(iRow, iCol, aBoard); var aList = new Array(); for(var i=0; i<aStraightList.length; i++){ aList.push(aStraightList[i]); } for(var i=0; i<aDiagonalList.length; i++){ aList.push(aDiagonalList[i]); } return aList; }; this.getSimpleKingMove = function(iRow, iCol, aBoard){ var aNeighborList = this._getAllNeighbor(iRow, iCol); //REMOVE ALLY POSITION FROM MOVES AND NOT LEGAL MOVES var szColor = aBoard[iRow][iCol].getColor(); for(var i= aNeighborList.length-1; i>=0; i--){ if(aBoard[aNeighborList[i].row][aNeighborList[i].col].getColor() === szColor){ aNeighborList.splice(i,1); } } return aNeighborList; }; this.getKingMove = function(iRow, iCol, aBoard){ var aNeighborList = this._getAllNeighbor(iRow, iCol); ////////// CASTLING MOVES var oKing = aBoard[iRow][iCol]; var aKingHistory = oKing.getPieceHistory(); if(aKingHistory.length===1 && !s_oGame.isCheck()){ var bCastlingRight = true; /////////CASTLE RIGHT AND LEFT var aRookRightHistory = aBoard[iRow][7].getPieceHistory(); if(aRookRightHistory.length===1){ if(aBoard[iRow][6].getColor() !== null){ bCastlingRight = false; } if(aBoard[iRow][5].getColor() !== null){ bCastlingRight = false; } }else { bCastlingRight = false; } if(bCastlingRight){ var aCastlingMove = {row: iRow, col:6}; var aMatchList = s_oBoardStateController.checkCastlingBlockFromOpponent(BOARD_SPECIAL_CASTLING_RIGHT, oKing.getColor(), aBoard); if(aMatchList.length === 0){ aNeighborList.push(aCastlingMove); } //aNeighborList.push({row: iRow, col:6}); } var bCastlingLeft = true; var aRookLeftHistory = aBoard[iRow][0].getPieceHistory(); if(aRookLeftHistory.length===1){ if(aBoard[iRow][1].getColor() !== null){ bCastlingLeft = false; } if(aBoard[iRow][2].getColor() !== null){ bCastlingLeft = false; } if(aBoard[iRow][3].getColor() !== null){ bCastlingLeft = false; } }else { bCastlingLeft = false; } if(bCastlingLeft){ var aCastlingMove = {row: iRow, col:2}; var aMatchList = s_oBoardStateController.checkCastlingBlockFromOpponent(BOARD_SPECIAL_CASTLING_LEFT, oKing.getColor(), aBoard); if(aMatchList.length === 0){ aNeighborList.push(aCastlingMove); } //aNeighborList.push({row: iRow, col:2}); } } //REMOVE ALLY POSITION FROM MOVES var szColor = aBoard[iRow][iCol].getColor(); for(var i= aNeighborList.length-1; i>=0; i--){ if(aBoard[aNeighborList[i].row][aNeighborList[i].col].getColor() === szColor){ aNeighborList.splice(i,1); } } return aNeighborList; }; this._getEnPassant = function(szColor, iRow, iCol, aBoard){ var aList = new Array(); var szOpponentColor = s_oBoardStateController.getOtherOpponent(szColor); var oNeighbor = this._getNeighborByDir(iRow, iCol, DIR_RIGHT); if(oNeighbor !== null){ var oPiece = aBoard[oNeighbor.row][oNeighbor.col]; if(oPiece.getColor() === szOpponentColor && oPiece.getType() === PAWN){ var aEnemyPawnHistory = oPiece.getPieceHistory(); var aThisPieceHistory = aBoard[iRow][iCol].getPieceHistory(); if(aEnemyPawnHistory.length === 2 && aEnemyPawnHistory[1].id === s_oGame.getLastHistoryID()){ if(szColor === WHITE){ aList.push(this._getNeighborByDir(iRow, iCol, DIR_TOPRIGHT)); } else { aList.push(this._getNeighborByDir(iRow, iCol, DIR_BOTRIGHT)); } } } } var oNeighbor = this._getNeighborByDir(iRow, iCol, DIR_LEFT); if(oNeighbor !== null){ var oPiece = aBoard[oNeighbor.row][oNeighbor.col]; if(oPiece.getColor() === szOpponentColor && oPiece.getType() === PAWN){ var aEnemyPawnHistory = oPiece.getPieceHistory(); var aThisPieceHistory = aBoard[iRow][iCol].getPieceHistory(); if(aEnemyPawnHistory.length === 2 && aEnemyPawnHistory[1].id === s_oGame.getLastHistoryID()){ if(szColor === WHITE){ aList.push(this._getNeighborByDir(iRow, iCol, DIR_TOPLEFT)); } else { aList.push(this._getNeighborByDir(iRow, iCol, DIR_BOTLEFT)); } } } } return aList; }; this._init(aMatrix); s_oMovesController = this; } var s_oMovesController; function CBoardStateController(){ var _iTurnStallCount; this._init = function(){ _iTurnStallCount = 0; }; this.getOtherOpponent = function(szPlayer){ if(szPlayer === WHITE){ return BLACK; } else{ return WHITE; } }; this.moveCopiedPiece = function(aCopiedBoard, iStartRow, iStartCol, iDestRow, iDestCol){ var oStartCopiedCell = aCopiedBoard[iStartRow][iStartCol]; var oDestCopiedCell = aCopiedBoard[iDestRow][iDestCol]; var iSpecialMove = this.getSpecialMoves(iStartRow, iStartCol, iDestRow, iDestCol, aCopiedBoard) switch( iSpecialMove ){ case BOARD_SPECIAL_CASTLING_RIGHT:{ var oRookStartCell = aCopiedBoard[iStartRow][7]; var oRookDestCell = aCopiedBoard[iStartRow][5]; oRookDestCell.setCell(oStartCopiedCell.getColor(), ROOK, iDestRow, iDestCol, oStartCopiedCell.getPieceHistory()); oRookStartCell.setCell(null, null, iStartRow, iStartCol, []); break; } case BOARD_SPECIAL_CASTLING_LEFT:{ var oRookStartCell = aCopiedBoard[iStartRow][0]; var oRookDestCell = aCopiedBoard[iStartRow][3]; oRookDestCell.setCell(oStartCopiedCell.getColor(), ROOK, iDestRow, iDestCol, oStartCopiedCell.getPieceHistory()); oRookStartCell.setCell(null, null, iStartRow, iStartCol, []); break; } case BOARD_SPECIAL_ENPASSANT:{ var oPawnToPassCell = aCopiedBoard[iStartRow][iDestCol]; oPawnToPassCell.setCell(null, null, iStartRow, iDestCol, []); break; } } oDestCopiedCell.setCell(oStartCopiedCell.getColor(), oStartCopiedCell.getType(), iDestRow, iDestCol, oStartCopiedCell.getPieceHistory()); oStartCopiedCell.setCell(null, null, iStartRow, iStartCol, []); }; this.copyBoard = function(aBoard){ var aCopiedBoard = new Array(); for(var i=0; i<aBoard.length; i++){ aCopiedBoard[i] = new Array(); for(var j=0; j<aBoard[i].length; j++){ aCopiedBoard[i][j] = new CCopiedCell(aBoard[i][j]); } } return aCopiedBoard; }; this.getState = function(szCurPlayer, aBoard){ /////////// STARTS ALL KIND OF VERIFICATIONS var aThreatList = this.findAllChecks(szCurPlayer, aBoard); if(aThreatList.length !== 0){ /// FIND CHECKMATE var bCheckMate = this.findCheckMate(szCurPlayer, aBoard); if(bCheckMate){ return BOARD_STATE_CHECKMATE; } else { return BOARD_STATE_CHECK; } } /// FIND STALEMATE var bStaleMate = this.findStaleMate(szCurPlayer, aBoard); if(bStaleMate){ return BOARD_STATE_STALEMATE; } }; this.findCheckMate = function(szCurPlayer, aBoard){ /////ONE CAN AVOID CHECKMATE ONLY BY: a) MOVING THE KING AWAY; b)EAT THREATENING PIECE; c) SHIELDING THE KING; WE CAN FIND ALL THESE CONDITIONS SEPARATELY ////OR WE COULD BE CHECK ITERATIVELY ALL PLAYER MOVES AND FIND JUST 1 MOVE THAT SAVE THE KING var bCheckMate = false; var aCurPlayerPieces = new Array(); for(var i=0; i<aBoard.length; i++){ for(var j=0; j<aBoard[i].length; j++){ if(aBoard[i][j].getColor() === szCurPlayer){ aCurPlayerPieces.push(aBoard[i][j]); } } } ///FIND ALLIN SOLUTION for(var i=0; i<aCurPlayerPieces.length; i++){ var aCurPieceMoveList = s_oMovesController.getMovesList(aCurPlayerPieces[i].getLogicPos().row, aCurPlayerPieces[i].getLogicPos().col, aBoard); for(var j=0; j<aCurPieceMoveList.length; j++){ var aTempBoard = this.copyBoard(aBoard); this.moveCopiedPiece(aTempBoard, aCurPlayerPieces[i].getLogicPos().row, aCurPlayerPieces[i].getLogicPos().col, aCurPieceMoveList[j].row, aCurPieceMoveList[j].col); var aList = this.findAllChecks(szCurPlayer, aTempBoard); if(aList.length === 0){ return bCheckMate; } } } bCheckMate = true; return bCheckMate; }; this.findAllChecks = function(szPlayerColor, aBoard){ var szOpponentColor = this.getOtherOpponent(szPlayerColor); /* var aOpponentPieces = new Array(); for(var i=0; i<aBoard.length; i++){ for(var j=0; j<aBoard[i].length; j++){ if(aBoard[i][j].getColor() === szOpponentColor){ aOpponentPieces.push(aBoard[i][j]); } } } var aMoves = new Array(); for(var i=0; i<aOpponentPieces.length; i++){ var oLogicPos = aOpponentPieces[i].getLogicPos(); aMoves[i] = {list: s_oMovesController.getMovesList(oLogicPos.row, oLogicPos.col, aBoard), piece: aOpponentPieces[i]}; } */ var aMoves = this._getAllMovesList(szOpponentColor, aBoard); var aCheckPieceList = new Array(); for(var i=0; i<aMoves.length; i++){ for(var j=0; j<aMoves[i].list.length; j++){ var oLogicPos = aMoves[i].list[j]; if(aBoard[oLogicPos.row][oLogicPos.col].getColor()===szPlayerColor && aBoard[oLogicPos.row][oLogicPos.col].getType() === KING){ aCheckPieceList.push(aMoves[i].piece); } }; }; return aCheckPieceList; }; this.findStaleMate = function(szCurPlayer, aBoard){ var bStaleMate = this.findCheckMate(szCurPlayer, aBoard); ////CHECK IF YOU HAVE ENOUGH PIECES TO CONTINUE THE GAME if(!bStaleMate){ var aBlackPieces = new Array(); var aWhitePieces = new Array(); for(var i=0; i<aBoard.length; i++){ for(var j=0; j<aBoard[i].length; j++){ if(aBoard[i][j].getColor() === WHITE){ aWhitePieces.push(aBoard[i][j].getType()); } if(aBoard[i][j].getColor() === BLACK){ aBlackPieces.push(aBoard[i][j].getType()); } } } /// ONLY KINGS REMAINS if(aBlackPieces.length === 1 && aWhitePieces.length === 1){ bStaleMate = true; return bStaleMate; } /// ONLY KING AND BISHOP VS KING //////// ONLY KING AND BISHOP VS KING if( (aBlackPieces.length === 1 && aWhitePieces.length === 2) || (aBlackPieces.length === 2 && aWhitePieces.length === 1) ){ var iBishop = aWhitePieces.indexOf(BISHOP)&&aBlackPieces.indexOf(BISHOP); var iKnight = aWhitePieces.indexOf(KNIGHT)&&aBlackPieces.indexOf(KNIGHT); if(iBishop >= 0 || iKnight >= 0){ bStaleMate = true; return bStaleMate; } } /// ONLY KING AND BISHOP VS KING AND BISHOP if( (aBlackPieces.length === 2 && aWhitePieces.length === 2) ){ var iBishop = aWhitePieces.indexOf(BISHOP)||aBlackPieces.indexOf(BISHOP); if(iBishop >= 0){ var aBishopBoardColor = new Array; for(var i=0; i<aBoard.length; i++){ for(var j=0; j<aBoard[i].length; j++){ if(aBoard[i][j].getType()===BISHOP){ var iBoardColor = (i+j)%2; aBishopBoardColor.push(iBoardColor); } } } if(aBishopBoardColor[0] === aBishopBoardColor[1]){ bStaleMate = true; return bStaleMate; } } } } ///CHECK FIFTY MOVES RULE if(_iTurnStallCount === DRAW_COUNTER){ bStaleMate = true; } return bStaleMate; }; this.kingInCheck = function(szCurPlayerTurnColor, aBoard){ /////JUST FIND FIRST PIECE THAT CHECK THE KING var szOpponentColor = this.getOtherOpponent(szCurPlayerTurnColor); var aOpponentPieces = new Array(); for(var i=0; i<aBoard.length; i++){ for(var j=0; j<aBoard[i].length; j++){ if(aBoard[i][j].getColor() === szOpponentColor){ var oOpponentPieces = aBoard[i][j]; var oLogicPos = oOpponentPieces.getLogicPos(); var aMoves = s_oMovesController.getMovesList(oLogicPos.row, oLogicPos.col, aBoard); for(var k=0; k<aMoves.length; k++){ var oNewLogicPos = aMoves[k]; if(aBoard[oNewLogicPos.row][oNewLogicPos.col].getColor()===szCurPlayerTurnColor && aBoard[oNewLogicPos.row][oNewLogicPos.col].getType() === KING){ return true; } } } } } return false; }; this.increaseStallCount = function(){ _iTurnStallCount++; }; this.resetStall = function(){ _iTurnStallCount = 0; }; this.checkPromotion = function(aBoard){ var oPawnPos = null; for(var i=0; i<aBoard.length; i++){ if(aBoard[0][i].getType() === PAWN){ oPawnPos = {row:0,col:i}; } else if(aBoard[7][i].getType() === PAWN){ oPawnPos = {row:7,col:i}; } }; return oPawnPos; }; this.getSpecialMoves = function(iSourceRow, iSourceCol, iDestRow, iDestCol, aBoard){ var szPiece = aBoard[iSourceRow][iSourceCol].getType(); if(szPiece === KING){ var iDirection = iSourceCol - iDestCol; if(iDirection === -2){ return BOARD_SPECIAL_CASTLING_RIGHT; } else if(iDirection === 2){ return BOARD_SPECIAL_CASTLING_LEFT; } }else if(szPiece === PAWN) { if(iSourceCol !== iDestCol && aBoard[iDestRow][iDestCol].getType() === null){ return BOARD_SPECIAL_ENPASSANT; } } }; this._getAllMovesList = function(szPlayerColor, aBoard){ var aPieces = new Array(); for(var i=0; i<aBoard.length; i++){ for(var j=0; j<aBoard[i].length; j++){ if(aBoard[i][j].getColor() === szPlayerColor){ aPieces.push(aBoard[i][j]); } } } var aMoves = new Array(); for(var i=0; i<aPieces.length; i++){ var oLogicPos = aPieces[i].getLogicPos(); //THE 4TH PARAM IS TRUE TO PREVENT CASTLING CHECK. IF 2 KINGS CAN CASTLING, THE CONTROL LOOPING aMoves[i] = {list: s_oMovesController.getMovesList(oLogicPos.row, oLogicPos.col, aBoard, true), piece: aPieces[i]}; } return aMoves; }; this._getPiecesThatMatchAList = function(aMoves, aListToMatch){ var aCheckPieceList = new Array(); for(var i=0; i<aMoves.length; i++){ var bFound = false; for(var j=0; j<aMoves[i].list.length; j++){ var oLogicPos = aMoves[i].list[j]; for(var k=0; k<aListToMatch.length;k++){ if(oLogicPos.row === aListToMatch[k].row && oLogicPos.col === aListToMatch[k].col){ bFound = true; continue; } } if(bFound){ continue } }; if(bFound){ aCheckPieceList.push(aMoves[i].piece); } }; return aCheckPieceList; }; this.checkCastlingBlockFromOpponent = function(iSpecialMoveType, szCurPlayerTurnColor, aBoard){ ///NO NEED TO CHECK KING DESTINATION BECAUSE IT WILL BE CHECKED FROM "CHECK" CONTROL var iRow = szCurPlayerTurnColor === BLACK ? 0 : 7; var szOpponentColor = this.getOtherOpponent(szCurPlayerTurnColor); var aMoves = this._getAllMovesList(szOpponentColor, aBoard); var aMatchList = new Array(); switch(iSpecialMoveType){ case BOARD_SPECIAL_CASTLING_RIGHT:{ var aForbiddenCellList = [ {row:iRow, col:5}, ]; aMatchList = this._getPiecesThatMatchAList(aMoves, aForbiddenCellList); break; } case BOARD_SPECIAL_CASTLING_LEFT:{ var aForbiddenCellList = [ {row:iRow, col:3}, ]; aMatchList = this._getPiecesThatMatchAList(aMoves, aForbiddenCellList); break; } } return aMatchList; }; this._init(); s_oBoardStateController = this; } var s_oBoardStateController; function CCopiedCell(oCell){ var _szColor; var _szType; var _aHistory; var _iRow; var _iCol; this._init = function(oCell){ _szColor = oCell.getColor(); _szType = oCell.getType(); _iRow = oCell.getLogicPos().row; _iCol = oCell.getLogicPos().col; var aHistList = oCell.getPieceHistory(); _aHistory = new Array(); for(var i=0; i<aHistList.length; i++){ _aHistory[i] = aHistList[i]; } }; this.setCell = function(szColor, szType, iRow, iCol, aHistory){ _szColor = szColor; _szType = szType; _iRow = iRow; _iCol = iCol; for(var i=0; i<aHistory.length; i++){ _aHistory[i] = aHistory[i]; } }; this.setColor = function(szValue){ _szColor = szValue; }; this.setType = function(szValue){ _szType = szValue; }; this.getColor = function(){ return _szColor; }; this.getType = function(){ return _szType; }; this.getLogicPos = function(){ return {row:_iRow, col:_iCol}; }; this.getPieceHistory = function(){ return _aHistory; }; this._init(oCell); } function CPromoPanel(szCurPlayer, oPawnPos){ var _aPieceButton; var _oBg; var _oMsgText; var _oFade; var _oParent; var _oHitArea; var _oContainer; var _oListener; this._init = function(szCurPlayer, oPawnPos){ _oFade = new createjs.Shape(); _oFade.graphics.beginFill("black").drawRect(0,0,CANVAS_WIDTH,CANVAS_HEIGHT); _oFade.alpha = 0; s_oStage.addChild(_oFade); new createjs.Tween.get(_oFade).to({alpha:0.7},500); var oSpriteMsgBox = s_oSpriteLibrary.getSprite('msg_box'); _oContainer = new createjs.Container(); _oContainer.y = CANVAS_HEIGHT + oSpriteMsgBox.height/2; s_oStage.addChild(_oContainer); _oBg = createBitmap(oSpriteMsgBox); _oBg.regX = oSpriteMsgBox.width/2; _oBg.regY = oSpriteMsgBox.height/2; _oBg.x = CANVAS_WIDTH/2; _oBg.y = CANVAS_HEIGHT/2; _oContainer.addChild(_oBg); _oHitArea = new createjs.Shape(); _oHitArea.graphics.beginFill("#0f0f0f").drawRect(0, 0, CANVAS_WIDTH, CANVAS_HEIGHT); _oHitArea.alpha = 0.01; _oListener = _oHitArea.on("click", function(){}); _oContainer.addChild(_oHitArea); var iWidth = 800; var iHeight = 200; var iX = CANVAS_WIDTH/2; var iY = CANVAS_HEIGHT/2 - 250; var oTitle = new CTLText(_oContainer, iX-iWidth/2, iY-iHeight/2, iWidth, iHeight, 40, "center", "#402604", PRIMARY_FONT, 1, 2, 2, TEXT_PROMOTION, true, true, true, false ); var oPiecesContainer = new createjs.Container(); oPiecesContainer.x = CANVAS_WIDTH/2; oPiecesContainer.y = CANVAS_HEIGHT/2; _oContainer.addChild(oPiecesContainer); var aPieces = new Array(); aPieces[0] = BISHOP; aPieces[1] = ROOK; aPieces[2] = KNIGHT; aPieces[3] = QUEEN; var iWidth = 400; _aPieceButton = new Array(); for(var i=0; i<aPieces.length; i++){ var oSprite = s_oSpriteLibrary.getSprite(szCurPlayer + "_" +aPieces[i]); _aPieceButton[i] = new CToggle(-iWidth/2 + i*(iWidth/(aPieces.length-1)),0,oSprite,true,oPiecesContainer); _aPieceButton[i].addEventListenerWithParams(ON_MOUSE_UP, this._onPieceSelected, this, aPieces[i]); } new createjs.Tween.get(_oContainer).to({y:0},750, createjs.Ease.cubicOut); }; this.unload = function(){ _oHitArea.off("click", _oListener); s_oStage.removeChild(_oFade); s_oStage.removeChild(_oContainer); }; this._onPieceSelected = function(szPiece){ s_oGame.changePiece(szPiece, oPawnPos); var oSpriteMsgBox = s_oSpriteLibrary.getSprite('msg_box'); var iEndPos = CANVAS_HEIGHT + oSpriteMsgBox.height/2; new createjs.Tween.get(_oFade).to({alpha:0},500); new createjs.Tween.get(_oContainer).to({y:iEndPos},500, createjs.Ease.backIn).call(function(){ _oParent.unload(); s_oGame.onExitPromoPanel(); }); }; this._init(szCurPlayer, oPawnPos); _oParent = this; }; function CAI(){ var _iNodeCounter; var _iScore; var _aCurBoard; var _aPieces; var _oDecisionTree; this._init = function(){ }; this.getMove = function(){ var iBestValue = this._buildTree(); var iChildOfRoot = 1; var aBestNodeList = _oDecisionTree.getNode(iBestValue, iChildOfRoot); var oAIMoves = this._getBestNode(aBestNodeList); return oAIMoves; }; this._getBestNode = function(aNodeList){ if(aNodeList.length > 0){ for(var i=0; i<aNodeList.length; i++){ var oMove = aNodeList[i].model.moves; this._makeMove(oMove); var bState = s_oMovesControllerFaster.getState(WHITE, _aCurBoard); if(bState === BOARD_STATE_CHECKMATE){ //// ENCOURAGE CHECKS aNodeList[i].model.rating += 0.5; } else if(bState === BOARD_STATE_STALEMATE) { ////DISCOURAGE STALEMATE aNodeList[i].model.rating -= 0.5; } this._unMakeMove(oMove); }; var iMax = aNodeList[0].model.rating; for(var i=1; i<aNodeList.length; i++){ if(aNodeList[i].model.rating > iMax){ iMax = aNodeList[i].model.rating; } }; var aBestNodeList = new Array(); for(var i=0; i<aNodeList.length; i++){ if(aNodeList[i].model.rating === iMax){ aBestNodeList.push(aNodeList[i]); } } var show = aBestNodeList[Math.floor( Math.random()*aBestNodeList.length)]; var oAIMoves = show.model.moves; } else { oAIMoves = null; } return oAIMoves; }; this._buildTree = function(){ _iNodeCounter = 0; var iStartingDepth = 0; _oDecisionTree = new CTreeDecision({rating: 0, moves: [], depth:iStartingDepth}); _aCurBoard = this._copyBoard(s_oGame.getCells()); ///////////////GET CALCULATION TIME HERE//////////////// var iTime = new Date().getTime(); _iScore = this._maxi(0); iTime = new Date().getTime() - iTime; ///////////////GET CALCULATION TIME HERE//////////////// return _iScore; }; this._alphaBetaMax = function(alpha, beta, iParentDepth ) { _iNodeCounter++; if ( iParentDepth === SEARCH_DEPTH ) { return this._evaluateBoard(); } var oMoves = this._findAllMoves(BLACK); var aAllMoves = oMoves.moves; var aOpponentPieceList = oMoves.opponentlist; for (var i=aAllMoves.length-1; i>=0; i--) { this._makeMove(aAllMoves[i]); var bCheck = s_oMovesControllerFaster.isInCheck(BLACK, _aCurBoard, aOpponentPieceList); if(bCheck){ this._unMakeMove(aAllMoves[i]); aAllMoves.splice(i,1); continue; } var iChildDepth = iParentDepth+1; _oDecisionTree.initNewNode(iChildDepth); var score = this._alphaBetaMin( alpha, beta, iChildDepth ); _oDecisionTree.addNode(iParentDepth, score, aAllMoves[i]); this._unMakeMove(aAllMoves[i]); if( score >= beta ) return beta; // fail hard beta-cutoff if( score > alpha ) alpha = score; // alpha acts like max in MiniMax } return alpha; }; this._alphaBetaMin = function(alpha, beta, iParentDepth ) { _iNodeCounter++; if ( iParentDepth === SEARCH_DEPTH ) { return this._evaluateBoard(); } var oMoves = this._findAllMoves(WHITE); var aAllMoves = oMoves.moves; var aOpponentPieceList = oMoves.opponentlist; for (var i=aAllMoves.length-1; i>=0; i--) { this._makeMove(aAllMoves[i]); var bCheck = s_oMovesControllerFaster.isInCheck(WHITE, _aCurBoard, aOpponentPieceList); if(bCheck){ this._unMakeMove(aAllMoves[i]); aAllMoves.splice(i,1); continue; } var iChildDepth = iParentDepth+1; _oDecisionTree.initNewNode(iChildDepth); var score = this._alphaBetaMax( alpha, beta, iChildDepth ); _oDecisionTree.addNode(iParentDepth, score, aAllMoves[i]); this._unMakeMove(aAllMoves[i]); if( score <= alpha ) return alpha; // fail hard alpha-cutoff if( score < beta ) beta = score; // beta acts like min in MiniMax } return beta; }; this._evaluateBoard = function(){ ///////// CLOUD SHANNON EVALUATION FUNCTION /* f(p) = 200(K-K') + 9(Q-Q') + 5(R-R') + 3(B-B' + N-N') + 1(P-P') - 0.5(D-D' + S-S' + I-I') + 0.1(M-M') + ... KQRBNP = number of kings, queens, rooks, bishops, knights and pawns D,S,I = doubled, blocked and isolated pawns M = Mobility (the number of legal moves) */ var iRate = 200*(_aPieces[BLACK][KING] - _aPieces[WHITE][KING]) + 9*(_aPieces[BLACK][QUEEN] - _aPieces[WHITE][QUEEN]) + 5*(_aPieces[BLACK][ROOK] - _aPieces[WHITE][ROOK]) + 3*(_aPieces[BLACK][BISHOP] - _aPieces[WHITE][BISHOP] + _aPieces[BLACK][KNIGHT] - _aPieces[WHITE][KNIGHT]) + (_aPieces[BLACK][PAWN] - _aPieces[WHITE][PAWN]); return iRate; }; this._findAllMoves = function(szEvalPlayerColor){ var aAllMovesList = new Array(); var aOpponentList = new Array(); for(var i=0; i<NUM_CELL; i++){ for(var j=0; j<NUM_CELL; j++){ if(_aCurBoard[i][j].type !== null){ if(_aCurBoard[i][j].color === szEvalPlayerColor){ var aSinglePieceMoveList = s_oMovesControllerFaster.getMovesList(i,j,_aCurBoard); for(var k=0; k<aSinglePieceMoveList.length; k++){ var iDestRow = aSinglePieceMoveList[k].row; var iDestCol = aSinglePieceMoveList[k].col; aAllMovesList.push( { sourcerow:i, sourcecol:j, destrow:iDestRow, destcol:iDestCol, sourcetype:_aCurBoard[i][j].type, sourcecolor:_aCurBoard[i][j].color, sourcehistory:_aCurBoard[i][j].history, desttype:_aCurBoard[iDestRow][iDestCol].type, destcolor:_aCurBoard[iDestRow][iDestCol].color, desthistory:_aCurBoard[iDestRow][iDestCol].history, special:aSinglePieceMoveList[k].special }); } } else { aOpponentList.push({row:i, col:j}); } } } } return {moves: aAllMovesList, opponentlist:aOpponentList}; }; this._makeMove = function(oMove){ if(oMove.destcolor !== null){ _aPieces[oMove.destcolor][oMove.desttype]--; } /////SPECIAL switch(oMove.special){ case BOARD_SPECIAL_CASTLING_RIGHT:{ _aCurBoard[oMove.sourcerow][5] = {color: oMove.sourcecolor, type: ROOK, history: _aCurBoard[oMove.sourcerow][7].history}; _aCurBoard[oMove.sourcerow][7] = {color: null, type: null, history: []}; break; } case BOARD_SPECIAL_CASTLING_LEFT:{ _aCurBoard[oMove.sourcerow][3] = {color: oMove.sourcecolor, type: ROOK, history: _aCurBoard[oMove.sourcerow][0].history}; _aCurBoard[oMove.sourcerow][0] = {color: null, type: null, history: []}; break; } case BOARD_SPECIAL_ENPASSANT:{ var szOpponentColor = s_oBoardStateController.getOtherOpponent(oMove.sourcecolor); _aCurBoard[oMove.sourcerow][oMove.destcol] = {color: null, type: null, history: []}; _aPieces[szOpponentColor][PAWN]--; break; } } _aCurBoard[oMove.destrow][oMove.destcol] = {color: oMove.sourcecolor, type: oMove.sourcetype, history: oMove.sourcehistory}; _aCurBoard[oMove.sourcerow][oMove.sourcecol] = {color: null, type: null, history: []}; if((oMove.destrow === 0 || oMove.destrow === 7) && oMove.sourcetype === PAWN){ _aCurBoard[oMove.destrow][oMove.destcol] = {color: oMove.sourcecolor, type: QUEEN, history: oMove.sourcehistory}; _aPieces[oMove.sourcecolor][PAWN]--; _aPieces[oMove.sourcecolor][QUEEN]++; } }; this._unMakeMove = function(oMove){ if(oMove.destcolor !== null){ _aPieces[oMove.destcolor][oMove.desttype]++; } /////SPECIAL switch(oMove.special){ case BOARD_SPECIAL_CASTLING_RIGHT:{ _aCurBoard[oMove.sourcerow][7] = {color: oMove.sourcecolor, type: ROOK, history: _aCurBoard[oMove.sourcerow][5].history}; _aCurBoard[oMove.sourcerow][5] = {color: null, type: null, history: []}; break; } case BOARD_SPECIAL_CASTLING_LEFT:{ _aCurBoard[oMove.sourcerow][0] = {color: oMove.sourcecolor, type: ROOK, history: _aCurBoard[oMove.sourcerow][3].history}; _aCurBoard[oMove.sourcerow][3] = {color: null, type: null, history: []}; break; } case BOARD_SPECIAL_ENPASSANT:{ var szOpponentColor = s_oBoardStateController.getOtherOpponent(oMove.sourcecolor); _aCurBoard[oMove.sourcerow][oMove.destcol] = {color: szOpponentColor, type: PAWN, history: []}; _aPieces[szOpponentColor][PAWN]++; break; } } _aCurBoard[oMove.sourcerow][oMove.sourcecol] = {color: oMove.sourcecolor, type: oMove.sourcetype, history: oMove.sourcehistory}; _aCurBoard[oMove.destrow][oMove.destcol] = {color: oMove.destcolor, type: oMove.desttype, history: oMove.desthistory}; if((oMove.destrow === 0 || oMove.destrow === 7) && oMove.sourcetype === PAWN){ _aPieces[oMove.sourcecolor][PAWN]++; _aPieces[oMove.sourcecolor][QUEEN]--; } }; this.debugBoard = function(aBoard){ var aNewBoard = new Array(); for(var i=0; i<NUM_CELL; i++){ aNewBoard[i] = new Array(); for(var j=0; j<NUM_CELL; j++){ aNewBoard[i][j] = aBoard[i][j].getType() + "_" +aBoard[i][j].getColor(); } } return aNewBoard; }; this._copyBoard = function(aBoard){ _aPieces = new Array(BLACK, WHITE); _aPieces[BLACK] = new Array(); _aPieces[WHITE] = new Array(); _aPieces[BLACK][KING] = 0; _aPieces[BLACK][QUEEN] = 0; _aPieces[BLACK][ROOK] = 0; _aPieces[BLACK][BISHOP] = 0; _aPieces[BLACK][KNIGHT] = 0; _aPieces[BLACK][PAWN] = 0; _aPieces[WHITE][KING] = 0; _aPieces[WHITE][QUEEN] = 0; _aPieces[WHITE][ROOK] = 0; _aPieces[WHITE][BISHOP] = 0; _aPieces[WHITE][KNIGHT] = 0; _aPieces[WHITE][PAWN] = 0; var aNewBoard = new Array(); for(var i=0; i<NUM_CELL; i++){ aNewBoard[i] = new Array(); for(var j=0; j<NUM_CELL; j++){ aNewBoard[i][j] = {color: aBoard[i][j].getColor(), type: aBoard[i][j].getType(), history:aBoard[i][j].getPieceHistory()}; if(aBoard[i][j].getColor() !== null){ _aPieces[aNewBoard[i][j].color][aNewBoard[i][j].type]++; } } } return aNewBoard; }; this._maxi = function(depth) { if ( depth === SEARCH_DEPTH ) { return this._evaluateBoard(); } var max = -INFINITE; var oMoves = this._findAllMoves(BLACK); var aAllMoves = oMoves.moves; var aOpponentPieceList = oMoves.opponentlist; var iChildDepth = depth+1; for (var i=aAllMoves.length-1; i>=0; i--) { this._makeMove(aAllMoves[i]); var bCheck = s_oMovesControllerFaster.isInCheck(BLACK, _aCurBoard, aOpponentPieceList); if(bCheck){ this._unMakeMove(aAllMoves[i]); aAllMoves.splice(i,1); continue; } _oDecisionTree.initNewNode(iChildDepth); var score = this._mini( iChildDepth ); _oDecisionTree.addNode(depth, score, aAllMoves[i]); this._unMakeMove(aAllMoves[i]); if( score > max ) max = score; } return max; }; this._mini= function(depth) { if ( depth === SEARCH_DEPTH ){ return this._evaluateBoard(); } var min = INFINITE; var oMoves = this._findAllMoves(WHITE); var aAllMoves = oMoves.moves; var aOpponentPieceList = oMoves.opponentlist; var iChildDepth = depth+1; for (var i=aAllMoves.length-1; i>=0; i--) { this._makeMove(aAllMoves[i]); var bCheck = s_oMovesControllerFaster.isInCheck(WHITE, _aCurBoard, aOpponentPieceList); if(bCheck){ this._unMakeMove(aAllMoves[i]); aAllMoves.splice(i,1); continue; } _oDecisionTree.initNewNode(iChildDepth); var score = this._maxi( iChildDepth ); _oDecisionTree.addNode(depth, score, aAllMoves[i]); this._unMakeMove(aAllMoves[i]); if( score < min ) min = score; } return min; }; this._init(); } var DIR_TOPRIGHT = "DIR_TOPRIGHT"; var DIR_RIGHT = "DIR_RIGHT"; var DIR_BOTRIGHT = "DIR_BOTRIGHT"; var DIR_TOPLEFT = "DIR_TOPLEFT"; var DIR_LEFT = "DIR_LEFT"; var DIR_BOTLEFT = "DIR_BOTLEFT"; var DIR_TOP = "DIR_TOP"; var DIR_BOT = "DIR_BOT"; function CMovesControllerFaster(aMatrix){ var _iRow; var _iCol; var _aMatrixMap; this._init = function(aMatrix){ _iRow = aMatrix.length; _iCol = aMatrix[0].length; _aMatrixMap = new Array(); for(var i=0; i<_iRow; i++){ _aMatrixMap[i] = new Array(); for(var j=0; j<_iCol; j++){ _aMatrixMap[i][j] = new Array(); } } this._buildMap(); }; this._buildMap = function(){ for(var i=0; i<_iRow; i++){ for(var j=0; j<_iCol; j++){ _aMatrixMap[i][j][DIR_TOPRIGHT] = this._setNeighbor(i,j,DIR_TOPRIGHT); _aMatrixMap[i][j][DIR_RIGHT] = this._setNeighbor(i,j,DIR_RIGHT); _aMatrixMap[i][j][DIR_BOTRIGHT] = this._setNeighbor(i,j,DIR_BOTRIGHT); _aMatrixMap[i][j][DIR_TOPLEFT] = this._setNeighbor(i,j,DIR_TOPLEFT); _aMatrixMap[i][j][DIR_LEFT] = this._setNeighbor(i,j,DIR_LEFT); _aMatrixMap[i][j][DIR_BOTLEFT] = this._setNeighbor(i,j,DIR_BOTLEFT); _aMatrixMap[i][j][DIR_TOP] = this._setNeighbor(i,j,DIR_TOP); _aMatrixMap[i][j][DIR_BOT] = this._setNeighbor(i,j,DIR_BOT); } } }; this._setNeighbor = function(r, c, iDir){ var oNextDir = null; switch(iDir){ ////r%2 IS USED TO DETECT INDEX COLUMN FOR AN "ODD-ROW" HORIZONTAL LAYOUT HEX GRID. FOR EXAMPLE, IF ROW IS ODD, THE TOPRIGHT NEIGHBOR IS = COL+1. IF ROW IS EVEN, THE TOPRIGHT NEIGHBOR IS = COL. case DIR_TOPRIGHT:{ if(r>0 && c<_iCol-1){ oNextDir = {row: r-1, col: c+1}; } break; } case DIR_RIGHT:{ if(c<_iCol-1){ oNextDir = {row: r, col: c+1}; } break; } case DIR_BOTRIGHT:{ if(r<_iRow-1 && c<_iCol-1){ oNextDir = {row: r+1, col: c+1}; } break; } case DIR_TOPLEFT:{ if(r>0 && c > 0){ oNextDir = {row: r-1, col: c-1}; } break; } case DIR_LEFT:{ if(c>0){ oNextDir = {row: r, col: c-1}; } break; } case DIR_BOTLEFT:{ if(r<_iRow-1 && c > 0){ oNextDir = {row: r+1, col: c-1}; } break; } case DIR_TOP:{ if(r>0){ oNextDir = {row: r-1, col: c}; } break; } case DIR_BOT:{ if(r<_iRow-1){ oNextDir = {row: r+1, col: c}; } break; } } /* if(oNextDir !== null){ if(aGrid[oNextDir.row][oNextDir.col].item === CELL_TYPE_NULL || aGrid[oNextDir.row][oNextDir.col]===undefined){ oNextDir = null; } } */ return oNextDir; }; this._getNeighborByDir = function(iRow, iCol, iDir){ return _aMatrixMap[iRow][iCol][iDir]; }; this._getAllNeighbor = function(iRow, iCol){ var aNeighborList = new Array(); for (var key in _aMatrixMap[iRow][iCol]) { if(_aMatrixMap[iRow][iCol][key]!== null){ aNeighborList.push(_aMatrixMap[iRow][iCol][key]); } } return aNeighborList; }; this._getMainDiagonal = function(iRow, iCol, aBoard){ var aList = new Array(); var szColor = aBoard[iRow][iCol].color; this._findInDirection(iRow, iCol, DIR_BOTRIGHT, aList, 99, szColor, aBoard); this._findInDirection(iRow, iCol, DIR_TOPLEFT, aList, 99, szColor, aBoard); return aList; }; this._getSecondDiagonal = function(iRow, iCol, aBoard){ var aList = new Array(); var szColor = aBoard[iRow][iCol].color; this._findInDirection(iRow, iCol, DIR_BOTLEFT, aList, 99, szColor, aBoard); this._findInDirection(iRow, iCol, DIR_TOPRIGHT, aList, 99, szColor, aBoard); return aList; }; this._getRow = function(iRow, iCol, aBoard){ var aList = new Array(); var szColor = aBoard[iRow][iCol].color; this._findInDirection(iRow, iCol, DIR_LEFT, aList, 99, szColor, aBoard); this._findInDirection(iRow, iCol, DIR_RIGHT, aList, 99, szColor, aBoard); return aList; }; this._getCol = function(iRow, iCol, aBoard){ var aList = new Array(); var szColor = aBoard[iRow][iCol].color; this._findInDirection(iRow, iCol, DIR_TOP, aList, 99, szColor, aBoard); this._findInDirection(iRow, iCol, DIR_BOT, aList, 99, szColor, aBoard); return aList; }; this._getStraightByDirAndRadius = function(iRow, iCol, szDir, iRadius, aBoard){ var aList = new Array(); var szColor = aBoard[iRow][iCol].color; this._findInDirection(iRow, iCol, szDir, aList, iRadius, szColor, aBoard); return aList; }; this._getStraightRowByRadius = function(iRow, iCol, iRadius){ var aList = new Array(); this._findInDirection(iRow, iCol, DIR_LEFT, aList, iRadius); this._findInDirection(iRow, iCol, DIR_RIGHT, aList, iRadius); return aList; }; this._getStraightColByRadius = function(iRow, iCol, iRadius){ var aList = new Array(); this._findInDirection(iRow, iCol, DIR_TOP, aList, iRadius); this._findInDirection(iRow, iCol, DIR_BOT, aList, iRadius); return aList; }; this._findInDirection = function(iRow, iCol, iDir, aList, iRadius, szColor, aBoard){ var iCountRadius = iRadius-1; if(_aMatrixMap[iRow][iCol][iDir] !== null && iCountRadius>=0){ var iNextRow = _aMatrixMap[iRow][iCol][iDir].row; var iNextCol = _aMatrixMap[iRow][iCol][iDir].col; if(szColor){ var szNextColor = aBoard[iNextRow][iNextCol].color; if(szNextColor === szColor){ return; }else if (szNextColor === null){ aList.push({row: iNextRow, col: iNextCol}); this._findInDirection(iNextRow, iNextCol, iDir, aList, iCountRadius, szColor, aBoard); } else { aList.push({row: iNextRow, col: iNextCol}); } } else { aList.push({row: iNextRow, col: iNextCol}); this._findInDirection(iNextRow, iNextCol, iDir, aList, iCountRadius, szColor, aBoard); } } }; this._findTPos = function(iRow, iCol, iDir){ var aPos = new Array(); var oFirstStep = _aMatrixMap[iRow][iCol][iDir]; if(oFirstStep !== null){ var oSecondStep = _aMatrixMap[oFirstStep.row][oFirstStep.col][iDir]; if(oSecondStep !== null){ if(iDir === DIR_TOP || iDir === DIR_BOT){ aPos = this._getStraightRowByRadius(oSecondStep.row, oSecondStep.col, 1); } else { aPos = this._getStraightColByRadius(oSecondStep.row, oSecondStep.col, 1); } }; }; return aPos; }; this.getMovesList = function(iRow, iCol, aBoard, bSimpleKing){ var szType = aBoard[iRow][iCol].type; var aMovesList = new Array(); switch(szType){ case PAWN:{ aMovesList = this.getPawnMove(iRow, iCol, aBoard); break; } case ROOK:{ aMovesList = this.getRookMove(iRow, iCol, aBoard); break; } case KNIGHT:{ aMovesList = this.getKnightMove(iRow, iCol, aBoard); break; } case BISHOP:{ aMovesList = this.getBishopMove(iRow, iCol, aBoard); break; } case QUEEN:{ aMovesList = this.getQueenMove(iRow, iCol, aBoard); break; } case KING:{ if(bSimpleKing){ ///PREVENT INFINITE STACK LOOP WHEN CHECKING CASTLING aMovesList = this.getSimpleKingMove(iRow, iCol, aBoard); }else { aMovesList = this.getKingMove(iRow, iCol, aBoard); } break; } } return aMovesList; }; this.getPawnMove = function(iRow, iCol, aBoard){ var szColor = aBoard[iRow][iCol].color; var aMoveList = new Array(); var aEatList = new Array(); if(szColor === WHITE){ ////////// MOVE LIST if(iRow === 6){ aMoveList = this._getStraightByDirAndRadius(iRow, iCol, DIR_TOP, 2, aBoard); } else { aMoveList = this._getStraightByDirAndRadius(iRow, iCol, DIR_TOP, 1, aBoard); } ////////// EAT LIST var oNeighbor = this._getNeighborByDir(iRow, iCol, DIR_TOPRIGHT); if(oNeighbor !== null){ if(aBoard[oNeighbor.row][oNeighbor.col].color === BLACK){ aEatList.push(oNeighbor); } } var oNeighbor = this._getNeighborByDir(iRow, iCol, DIR_TOPLEFT); if(oNeighbor !== null){ if(aBoard[oNeighbor.row][oNeighbor.col].color === BLACK){ aEatList.push(oNeighbor); } } ////////// CHECK EN-PASSANT if(iRow === 3){ var aList = this._getEnPassant(WHITE, iRow, iCol, aBoard); for(var i=0; i<aList.length; i++){ aEatList.push(aList[i]); }; } } else{ ////////// MOVE LIST if(iRow === 1){ aMoveList = this._getStraightByDirAndRadius(iRow, iCol, DIR_BOT, 2, aBoard); } else { aMoveList = this._getStraightByDirAndRadius(iRow, iCol, DIR_BOT, 1, aBoard); } ////////// EAT LIST var oNeighbor = this._getNeighborByDir(iRow, iCol, DIR_BOTRIGHT); if(oNeighbor !== null){ if(aBoard[oNeighbor.row][oNeighbor.col].color === WHITE){ aEatList.push(oNeighbor); } } var oNeighbor = this._getNeighborByDir(iRow, iCol, DIR_BOTLEFT); if(oNeighbor !== null){ if(aBoard[oNeighbor.row][oNeighbor.col].color === WHITE){ aEatList.push(oNeighbor); } } ////////// CHECK EN-PASSANT if(iRow === 4){ var aList = this._getEnPassant(BLACK, iRow, iCol, aBoard); for(var i=0; i<aList.length; i++){ aEatList.push(aList[i]); }; } } ///////////// REMOVE OCCUPIED CELLS BY ENEMY for(var i=aMoveList.length-1; i>=0; i--){ if(aBoard[aMoveList[i].row][aMoveList[i].col].color !== null && aBoard[aMoveList[i].row][aMoveList[i].col].color !== szColor){ aMoveList.splice(i,1); } }; for(var i=0; i<aEatList.length; i++){ aMoveList.push(aEatList[i]); }; return aMoveList; }; this.getRookMove = function(iRow, iCol, aBoard){ var aRowList = this._getRow(iRow, iCol, aBoard); var aColList = this._getCol(iRow, iCol, aBoard); var aList = new Array(); for(var i=0; i<aRowList.length; i++){ aList.push(aRowList[i]); } for(var i=0; i<aColList.length; i++){ aList.push(aColList[i]); } return aList; }; this.getKnightMove = function(iRow, iCol, aBoard){ var aList = new Array(); aList.push( this._findTPos(iRow, iCol, DIR_TOP) ); aList.push( this._findTPos(iRow, iCol, DIR_RIGHT) ); aList.push( this._findTPos(iRow, iCol, DIR_BOT) ); aList.push( this._findTPos(iRow, iCol, DIR_LEFT) ); var aLList = new Array(); for(var i=0; i<aList.length; i++){ for(var j=0; j<aList[i].length; j++){ aLList.push(aList[i][j]); } } //REMOVE ALLY POSITION FROM MOVES var szColor = aBoard[iRow][iCol].color; for(var i= aLList.length-1; i>=0; i--){ if(aBoard[aLList[i].row][aLList[i].col].color === szColor){ aLList.splice(i,1); } } return aLList; }; this.getBishopMove = function(iRow, iCol, aBoard){ var aMainList = this._getMainDiagonal(iRow, iCol, aBoard); var aSecondList = this._getSecondDiagonal(iRow, iCol, aBoard); var aList = new Array(); for(var i=0; i<aMainList.length; i++){ aList.push(aMainList[i]); } for(var i=0; i<aSecondList.length; i++){ aList.push(aSecondList[i]); } return aList; }; this.getQueenMove = function(iRow, iCol, aBoard){ var aStraightList = this.getRookMove(iRow, iCol, aBoard); var aDiagonalList = this.getBishopMove(iRow, iCol, aBoard); var aList = new Array(); for(var i=0; i<aStraightList.length; i++){ aList.push(aStraightList[i]); } for(var i=0; i<aDiagonalList.length; i++){ aList.push(aDiagonalList[i]); } return aList; }; this.getSimpleKingMove = function(iRow, iCol, aBoard){ var aNeighborList = this._getAllNeighbor(iRow, iCol); //REMOVE ALLY POSITION FROM MOVES AND NOT LEGAL MOVES var szColor = aBoard[iRow][iCol].color; for(var i= aNeighborList.length-1; i>=0; i--){ if(aBoard[aNeighborList[i].row][aNeighborList[i].col].color === szColor){ aNeighborList.splice(i,1); } } return aNeighborList; }; this.getKingMove = function(iRow, iCol, aBoard){ var aNeighborList = this._getAllNeighbor(iRow, iCol); ////////// CASTLING MOVES var oKing = aBoard[iRow][iCol]; var aKingHistory = oKing.history; //console.log(oKing) if(aKingHistory.length===1 && !s_oGame.isCheck()){ var szCurPlayerTurnColor = oKing.color; var szOpponentColor = s_oBoardStateController.getOtherOpponent(szCurPlayerTurnColor); var aMoves = this._getAllMovesList(szOpponentColor, aBoard); var bCastlingRight = true; /////////CASTLE RIGHT AND LEFT var aRookRightHistory = aBoard[iRow][7].history; if(aRookRightHistory.length===1){ if(aBoard[iRow][6].color !== null){ bCastlingRight = false; } if(aBoard[iRow][5].color !== null){ bCastlingRight = false; } }else { bCastlingRight = false; } if(bCastlingRight){ var aForbiddenCellList = [ {row:iRow, col:5}, ]; var bInMatch = this._isListMatching(aMoves, aForbiddenCellList); if(!bInMatch){ aNeighborList.push({row: iRow, col:6, special: BOARD_SPECIAL_CASTLING_RIGHT}); } //aNeighborList.push({row: iRow, col:6, special: BOARD_SPECIAL_CASTLING_RIGHT}); } var bCastlingLeft = true; var aRookLeftHistory = aBoard[iRow][0].history; if(aRookLeftHistory.length===1){ if(aBoard[iRow][1].color !== null){ bCastlingLeft = false; } if(aBoard[iRow][2].color !== null){ bCastlingLeft = false; } if(aBoard[iRow][3].color !== null){ bCastlingLeft = false; } }else { bCastlingLeft = false; } if(bCastlingLeft){ var aForbiddenCellList = [ {row:iRow, col:3}, ]; var bInMatch = this._isListMatching(aMoves, aForbiddenCellList); if(!bInMatch){ aNeighborList.push({row: iRow, col:2, special: BOARD_SPECIAL_CASTLING_LEFT}); } //aNeighborList.push({row: iRow, col:2, special: BOARD_SPECIAL_CASTLING_LEFT}); } } //REMOVE ALLY POSITION FROM MOVES AND NOT LEGAL MOVES var szColor = aBoard[iRow][iCol].color; for(var i= aNeighborList.length-1; i>=0; i--){ if(aBoard[aNeighborList[i].row][aNeighborList[i].col].color === szColor){ aNeighborList.splice(i,1); } } return aNeighborList; }; this._getAllMovesList = function(szPlayerColor, aBoard){ var aPieces = new Array(); for(var i=0; i<aBoard.length; i++){ for(var j=0; j<aBoard[i].length; j++){ if(aBoard[i][j].color === szPlayerColor){ //aPieces.push(aBoard[i][j]); aPieces.push({row: i, col:j}); } } } var aMoves = new Array(); for(var i=0; i<aPieces.length; i++){ var oLogicPos = aPieces[i]//.getLogicPos(); //THE 4TH PARAM IS TRUE TO PREVENT CASTLING CHECK. IF 2 KINGS CAN CASTLING, THE CONTROL LOOPING aMoves[i] = {list: s_oMovesControllerFaster.getMovesList(oLogicPos.row, oLogicPos.col, aBoard, true), piece: aPieces[i]}; } return aMoves; }; this._isListMatching = function(aMoves, aListToMatch){ for(var i=0; i<aMoves.length; i++){ for(var j=0; j<aMoves[i].list.length; j++){ var oLogicPos = aMoves[i].list[j]; for(var k=0; k<aListToMatch.length;k++){ if(oLogicPos.row === aListToMatch[k].row && oLogicPos.col === aListToMatch[k].col){ return true; } } }; }; return false; }; this._getEnPassant = function(szColor, iRow, iCol, aBoard){ var aList = new Array(); var szOpponentColor = s_oBoardStateController.getOtherOpponent(szColor); var oNeighbor = this._getNeighborByDir(iRow, iCol, DIR_RIGHT); if(oNeighbor !== null){ var oPiece = aBoard[oNeighbor.row][oNeighbor.col]; if(oPiece.color === szOpponentColor && oPiece.type === PAWN){ var aEnemyPawnHistory = oPiece.history; if(aEnemyPawnHistory.length === 2 && aEnemyPawnHistory[1].id === s_oGame.getLastHistoryID()){ if(szColor === WHITE){ aList.push(this._getNeighborByDir(iRow, iCol, DIR_TOPRIGHT)); } else { aList.push(this._getNeighborByDir(iRow, iCol, DIR_BOTRIGHT)); } } } } var oNeighbor = this._getNeighborByDir(iRow, iCol, DIR_LEFT); if(oNeighbor !== null){ var oPiece = aBoard[oNeighbor.row][oNeighbor.col]; if(oPiece.color === szOpponentColor && oPiece.type === PAWN){ var aEnemyPawnHistory = oPiece.history; if(aEnemyPawnHistory.length === 2 && aEnemyPawnHistory[1].id === s_oGame.getLastHistoryID()){ if(szColor === WHITE){ aList.push(this._getNeighborByDir(iRow, iCol, DIR_TOPLEFT)); } else { aList.push(this._getNeighborByDir(iRow, iCol, DIR_BOTLEFT)); } } } } ////ADD SPECIAL TAG, TO AVOID COMPUTATION FOR CPU for(var i=0; i<aList.length; i++){ aList[i].special = BOARD_SPECIAL_ENPASSANT; } return aList; }; this.getState = function(szCurPlayer, aBoard){ /////////// STARTS ALL KIND OF VERIFICATIONS var aThreatList = this.findAllChecks(szCurPlayer, aBoard); if(aThreatList.length !== 0){ /// FIND CHECKMATE var bCheckMate = this.findCheckMate(szCurPlayer, aBoard); if(bCheckMate){ return BOARD_STATE_CHECKMATE; } else { return BOARD_STATE_CHECK; } } /// FIND STALEMATE var bStaleMate = this.findStaleMate(szCurPlayer, aBoard); if(bStaleMate){ return BOARD_STATE_STALEMATE; } }; this.findCheckMate = function(szCurPlayer, aBoard){ /////ONE CAN AVOID CHECKMATE ONLY BY: a) MOVING THE KING AWAY; b)EAT THREATENING PIECE; c) SHIELDING THE KING; WE CAN FIND ALL THESE CONDITIONS SEPARATELY ////OR WE COULD BE CHECK ITERATIVELY ALL PLAYER MOVES AND FIND JUST 1 MOVE THAT SAVE THE KING var bCheckMate = false; var aCurPlayerPieces = new Array(); for(var i=0; i<aBoard.length; i++){ for(var j=0; j<aBoard[i].length; j++){ if(aBoard[i][j].color === szCurPlayer){ aCurPlayerPieces.push({row: i, col:j}); } } } ///FIND ALLIN SOLUTION for(var i=0; i<aCurPlayerPieces.length; i++){ var iSourceRow = aCurPlayerPieces[i].row; var iSourceCol = aCurPlayerPieces[i].col; var aCurPieceMoveList = s_oMovesControllerFaster.getMovesList(iSourceRow, iSourceCol, aBoard); for(var j=0; j<aCurPieceMoveList.length; j++){ var iDestRow = aCurPieceMoveList[j].row; var iDestCol = aCurPieceMoveList[j].col; var oMove = { sourcerow:iSourceRow, sourcecol:iSourceCol, destrow:iDestRow, destcol:iDestCol, sourcetype:aBoard[iSourceRow][iSourceCol].type, sourcecolor:aBoard[iSourceRow][iSourceCol].color, sourcehistory:aBoard[iSourceRow][iSourceCol].history, desttype:aBoard[iDestRow][iDestCol].type, destcolor:aBoard[iDestRow][iDestCol].color, desthistory:aBoard[iDestRow][iDestCol].history, special:aCurPieceMoveList[j].special }; this._makeMove(aBoard, oMove); var aList = this.findAllChecks(szCurPlayer, aBoard); if(aList.length === 0){ return bCheckMate; } this._unMakeMove(aBoard, oMove); } } bCheckMate = true; return bCheckMate; }; this._makeMove = function(aBoard, oMove){ aBoard[oMove.destrow][oMove.destcol] = {color: oMove.sourcecolor, type: oMove.sourcetype, history: oMove.sourcehistory}; aBoard[oMove.sourcerow][oMove.sourcecol] = {color: null, type: null, history: []}; if((oMove.destrow === 0 || oMove.destrow === 7) && oMove.sourcetype === PAWN){ aBoard[oMove.destrow][oMove.destcol] = {color: oMove.sourcecolor, type: QUEEN, history: oMove.sourcehistory}; } }; this._unMakeMove = function(aBoard, oMove){ aBoard[oMove.sourcerow][oMove.sourcecol] = {color: oMove.sourcecolor, type: oMove.sourcetype, history: oMove.sourcehistory}; aBoard[oMove.destrow][oMove.destcol] = {color: oMove.destcolor, type: oMove.desttype, history: oMove.desthistory}; }; this.findStaleMate = function(szCurPlayer, aBoard){ var bStaleMate = this.findCheckMate(szCurPlayer, aBoard); ////CHECK IF YOU HAVE ENOUGH PIECES TO CONTINUE THE GAME if(!bStaleMate){ var aBlackPieces = new Array(); var aWhitePieces = new Array(); for(var i=0; i<aBoard.length; i++){ for(var j=0; j<aBoard[i].length; j++){ if(aBoard[i][j].color === WHITE){ aWhitePieces.push(aBoard[i][j].type); } if(aBoard[i][j].color === BLACK){ aBlackPieces.push(aBoard[i][j].type); } } } /// ONLY KINGS REMAINS if(aBlackPieces.length === 1 && aWhitePieces.length === 1){ bStaleMate = true; return bStaleMate; } /// ONLY KING AND BISHOP VS KING //////// ONLY KING AND BISHOP VS KING if( (aBlackPieces.length === 1 && aWhitePieces.length === 2) || (aBlackPieces.length === 2 && aWhitePieces.length === 1) ){ var iBishop = aWhitePieces.indexOf(BISHOP)&&aBlackPieces.indexOf(BISHOP); var iKnight = aWhitePieces.indexOf(KNIGHT)&&aBlackPieces.indexOf(KNIGHT); if(iBishop >= 0 || iKnight >= 0){ bStaleMate = true; return bStaleMate; } } /// ONLY KING AND BISHOP VS KING AND BISHOP if( (aBlackPieces.length === 2 && aWhitePieces.length === 2) ){ var iBishop = aWhitePieces.indexOf(BISHOP)||aBlackPieces.indexOf(BISHOP); if(iBishop >= 0){ var aBishopBoardColor = new Array; for(var i=0; i<aBoard.length; i++){ for(var j=0; j<aBoard[i].length; j++){ if(aBoard[i][j].type===BISHOP){ var iBoardColor = (i+j)%2; aBishopBoardColor.push(iBoardColor); } } } if(aBishopBoardColor[0] === aBishopBoardColor[1]){ bStaleMate = true; return bStaleMate; } } } } return bStaleMate; }; this.isInCheck = function(szPlayerColor, aBoard, aOpponentPieces){ var aMoves; for(var i=0; i<aOpponentPieces.length; i++){ aMoves = s_oMovesControllerFaster.getMovesList(aOpponentPieces[i].row, aOpponentPieces[i].col, aBoard); for(var j=0; j<aMoves.length; j++){ var oLogicPos = aMoves[j]; if(aBoard[oLogicPos.row][oLogicPos.col].color===szPlayerColor && aBoard[oLogicPos.row][oLogicPos.col].type === KING){ return true; } }; } return false; }; this.findAllChecks = function(szPlayerColor, aBoard){ var szOpponentColor = s_oBoardStateController.getOtherOpponent(szPlayerColor); var aOpponentPieces = new Array(); for(var i=0; i<aBoard.length; i++){ for(var j=0; j<aBoard[i].length; j++){ if(aBoard[i][j].color === szOpponentColor){ aOpponentPieces.push({row: i, col:j}); } } } var aMoves = new Array(); for(var i=0; i<aOpponentPieces.length; i++){ var oLogicPos = aOpponentPieces[i]; aMoves[i] = {list: s_oMovesControllerFaster.getMovesList(oLogicPos.row, oLogicPos.col, aBoard), piece: aOpponentPieces[i]}; } var aCheckPieceList = new Array(); for(var i=0; i<aMoves.length; i++){ for(var j=0; j<aMoves[i].list.length; j++){ var oLogicPos = aMoves[i].list[j]; if(aBoard[oLogicPos.row][oLogicPos.col].color===szPlayerColor && aBoard[oLogicPos.row][oLogicPos.col].type === KING){ aCheckPieceList.push(aMoves[i].piece); } }; }; return aCheckPieceList; }; this._init(aMatrix); s_oMovesControllerFaster = this; } var s_oMovesControllerFaster; function CGUIExpandible(iX, iY, oSprite, oParentContainer){ var _bExpanded; var _aButtons; var _aButtonsObj; var _oParent; var _oMenuBut; var _oGUIContainer; var _oBackContainer; var _oFrontContainer; var _oExpandedPos; var _pStartPos; this._init = function(iX, iY, oSprite, oParentContainer){ _aButtons = new Array(); _aButtonsObj = new Array(); _pStartPos = {x: iX, y: iY}; _oGUIContainer = new createjs.Container(); _oGUIContainer.x = iX; _oGUIContainer.y = iY; oParentContainer.addChild(_oGUIContainer); _oBackContainer = new createjs.Container(); _oGUIContainer.addChild(_oBackContainer); _oFrontContainer = new createjs.Container(); _oGUIContainer.addChild(_oFrontContainer); _bExpanded = false; _oMenuBut = new CGfxButton(0,0,oSprite, _oFrontContainer); _oMenuBut.addEventListener(ON_MOUSE_UP, this._onMenu, this); var oStart = {x: 0, y: 120}; _oExpandedPos = {start: oStart, offset: 120}; }; this.unload = function(){ _oMenuBut.unload(); oParentContainer.removeChild(_oGUIContainer); }; this.refreshPos = function(iNewX, iNewY){ ////REMOVE ALL BUTTONS FROM REFRESH FUNCTIONS IN INTERFACE OR IN OTHER MENUES _oGUIContainer.x = iX - iNewX; _oGUIContainer.y = iY + iNewY; }; this.addButton = function(oObjClass){ var oButton = oObjClass.getButtonImage(); oButton.x = 0; oButton.y = 0; oButton.visible = 0; _oBackContainer.addChildAt(oButton, 0); _aButtons.push(oButton); _aButtonsObj.push(oObjClass); }; this._onMenu = function(){ _oParent.stopTrembleAnimation(); _bExpanded = !_bExpanded; if(_bExpanded){ _oParent._expand(); //s_oGame.onPause(); }else{ _oParent._collapse(); //s_oGame.onResume(); } }; this._expand = function(){ var iTime = 300; for(var i=0; i<_aButtons.length; i++){ _aButtons[i].visible = true; createjs.Tween.get(_aButtons[i], {override:true}).wait(i*iTime/2).to({y: _oExpandedPos.start.y + i*_oExpandedPos.offset}, iTime, createjs.Ease.cubicOut); }; }; this._collapse = function(){ var iTime = 300; for(var i=0; i<_aButtons.length; i++){ var oButton = _aButtons[_aButtons.length-1-i]; createjs.Tween.get(oButton, {override:true}).wait(i*iTime/2).to({y: 0}, iTime, createjs.Ease.cubicOut).call(function(oButton){ oButton.visible = false; }, [oButton]); }; }; this.trembleAnimation = function () { if(_bExpanded){ _aButtonsObj[_aButtonsObj.length-1].trembleAnimation(); }else{ _oMenuBut.trembleAnimation(); } }; this.stopTrembleAnimation = function(){ if(_bExpanded){ _aButtonsObj[_aButtonsObj.length-1].stopAnimation(); }else{ _oMenuBut.stopAnimation(); } }; _oParent = this; this._init(iX, iY, oSprite, oParentContainer); } CTLText.prototype = { constructor : CTLText, __autofit : function(){ if(this._bFitText){ var iFontSize = this._iFontSize; while( this._oText.getBounds().height > (this._iHeight -this._iPaddingV*2) || this._oText.getBounds().width > (this._iWidth-this._iPaddingH*2) ){ iFontSize--; this._oText.font = iFontSize+"px "+this._szFont; this._oText.lineHeight = Math.round(iFontSize*this._fLineHeightFactor); this.__updateY(); this.__verticalAlign(); if ( iFontSize < 8 ){ break; } }; this._iFontSize = iFontSize; } //trace(this._oText.text + "-->fontsizedebug:"+iFontSize); }, __verticalAlign : function(){ if(this._bVerticalAlign){ var iCurHeight = this._oText.getBounds().height; this._oText.y -= (iCurHeight-this._iHeight)/2 + (this._iPaddingV); } }, __updateY : function(){ this._oText.y = this._y + this._iPaddingV; switch(this._oText.textBaseline){ case "middle":{ this._oText.y += (this._oText.lineHeight/2) + (this._iFontSize*this._fLineHeightFactor-this._iFontSize); }break; } }, __createText : function(szMsg){ if (this._bDebug){ this._oDebugShape = new createjs.Shape(); this._oDebugShape.graphics.beginFill("rgba(255,0,0,0.5)").drawRect( this._x, this._y, this._iWidth, this._iHeight); this._oContainer.addChild(this._oDebugShape); } this._oText = new createjs.Text(szMsg, this._iFontSize+"px "+this._szFont, this._szColor); this._oText.textBaseline = "middle"; this._oText.lineHeight = Math.round(this._iFontSize*this._fLineHeightFactor); this._oText.textAlign = this._szAlign; if ( this._bMultiline ){ this._oText.lineWidth = this._iWidth - (this._iPaddingH*2); }else{ this._oText.lineWidth = null; } switch(this._szAlign){ case "center":{ this._oText.x = this._x+(this._iWidth/2); }break; case "left":{ this._oText.x = this._x+this._iPaddingH; }break; case "right":{ this._oText.x = this._x+this._iWidth-this._iPaddingH; }break; } this._oContainer.addChild(this._oText); this.refreshText(szMsg); }, setVerticalAlign : function( bVerticalAlign ){ this._bVerticalAlign = bVerticalAlign; }, setOutline : function(iSize){ if ( this._oText !== null ){ this._oText.outline = iSize; } }, setShadow : function(szColor,iOffsetX,iOffsetY,iBlur){ if ( this._oText !== null ){ this._oText.shadow = new createjs.Shadow(szColor, iOffsetX,iOffsetY,iBlur); } }, setColor : function(szColor){ this._oText.color = szColor; }, setAlpha : function(iAlpha){ this._oText.alpha = iAlpha; }, setY : function(iNewY){ this._oText.y = iNewY; this._y = iNewY; }, removeTweens : function(){ createjs.Tween.removeTweens(this._oText); }, getText : function(){ return this._oText; }, getY : function(){ return this._y; }, getFontSize : function(){ return this._iFontSize; }, refreshText : function(szMsg){ if(szMsg === ""){ szMsg = " "; } if ( this._oText === null ){ this.__createText(szMsg); } this._oText.text = szMsg; this._oText.font = this._iFontSize+"px "+this._szFont; this._oText.lineHeight = Math.round(this._iFontSize*this._fLineHeightFactor); this.__autofit(); this.__updateY(); this.__verticalAlign(); } }; function CTLText( oContainer, x, y, iWidth, iHeight, iFontSize, szAlign, szColor, szFont,iLineHeightFactor, iPaddingH, iPaddingV, szMsg, bFitText, bVerticalAlign, bMultiline, bDebug ){ this._oContainer = oContainer; this._x = x; this._y = y; this._iWidth = iWidth; this._iHeight = iHeight; this._bMultiline = bMultiline; this._iFontSize = iFontSize; this._szAlign = szAlign; this._szColor = szColor; this._szFont = szFont; this._iPaddingH = iPaddingH; this._iPaddingV = iPaddingV; this._bVerticalAlign = bVerticalAlign; this._bFitText = bFitText; this._bDebug = bDebug; //this._bDebug = true; // RESERVED this._oDebugShape = null; this._fLineHeightFactor = iLineHeightFactor; this._oText = null; if ( szMsg ){ this.__createText(szMsg); } } /* global window, exports, define */ !function() { 'use strict' var re = { not_string: /[^s]/, not_bool: /[^t]/, not_type: /[^T]/, not_primitive: /[^v]/, number: /[diefg]/, numeric_arg: /[bcdiefguxX]/, json: /[j]/, not_json: /[^j]/, text: /^[^\x25]+/, modulo: /^\x25{2}/, placeholder: /^\x25(?:([1-9]\d*)\$|\(([^)]+)\))?(\+)?(0|'[^$])?(-)?(\d+)?(?:\.(\d+))?([b-gijostTuvxX])/, key: /^([a-z_][a-z_\d]*)/i, key_access: /^\.([a-z_][a-z_\d]*)/i, index_access: /^\[(\d+)\]/, sign: /^[+-]/ } function sprintf(key) { // `arguments` is not an array, but should be fine for this call return sprintf_format(sprintf_parse(key), arguments) } function vsprintf(fmt, argv) { return sprintf.apply(null, [fmt].concat(argv || [])) } function sprintf_format(parse_tree, argv) { var cursor = 1, tree_length = parse_tree.length, arg, output = '', i, k, ph, pad, pad_character, pad_length, is_positive, sign for (i = 0; i < tree_length; i++) { if (typeof parse_tree[i] === 'string') { output += parse_tree[i] } else if (typeof parse_tree[i] === 'object') { ph = parse_tree[i] // convenience purposes only if (ph.keys) { // keyword argument arg = argv[cursor] for (k = 0; k < ph.keys.length; k++) { if (arg == undefined) { throw new Error(sprintf('[sprintf] Cannot access property "%s" of undefined value "%s"', ph.keys[k], ph.keys[k-1])) } arg = arg[ph.keys[k]] } } else if (ph.param_no) { // positional argument (explicit) arg = argv[ph.param_no] } else { // positional argument (implicit) arg = argv[cursor++] } if (re.not_type.test(ph.type) && re.not_primitive.test(ph.type) && arg instanceof Function) { arg = arg() } if (re.numeric_arg.test(ph.type) && (typeof arg !== 'number' && isNaN(arg))) { throw new TypeError(sprintf('[sprintf] expecting number but found %T', arg)) } if (re.number.test(ph.type)) { is_positive = arg >= 0 } switch (ph.type) { case 'b': arg = parseInt(arg, 10).toString(2) break case 'c': arg = String.fromCharCode(parseInt(arg, 10)) break case 'd': case 'i': arg = parseInt(arg, 10) break case 'j': arg = JSON.stringify(arg, null, ph.width ? parseInt(ph.width) : 0) break case 'e': arg = ph.precision ? parseFloat(arg).toExponential(ph.precision) : parseFloat(arg).toExponential() break case 'f': arg = ph.precision ? parseFloat(arg).toFixed(ph.precision) : parseFloat(arg) break case 'g': arg = ph.precision ? String(Number(arg.toPrecision(ph.precision))) : parseFloat(arg) break case 'o': arg = (parseInt(arg, 10) >>> 0).toString(8) break case 's': arg = String(arg) arg = (ph.precision ? arg.substring(0, ph.precision) : arg) break case 't': arg = String(!!arg) arg = (ph.precision ? arg.substring(0, ph.precision) : arg) break case 'T': arg = Object.prototype.toString.call(arg).slice(8, -1).toLowerCase() arg = (ph.precision ? arg.substring(0, ph.precision) : arg) break case 'u': arg = parseInt(arg, 10) >>> 0 break case 'v': arg = arg.valueOf() arg = (ph.precision ? arg.substring(0, ph.precision) : arg) break case 'x': arg = (parseInt(arg, 10) >>> 0).toString(16) break case 'X': arg = (parseInt(arg, 10) >>> 0).toString(16).toUpperCase() break } if (re.json.test(ph.type)) { output += arg } else { if (re.number.test(ph.type) && (!is_positive || ph.sign)) { sign = is_positive ? '+' : '-' arg = arg.toString().replace(re.sign, '') } else { sign = '' } pad_character = ph.pad_char ? ph.pad_char === '0' ? '0' : ph.pad_char.charAt(1) : ' ' pad_length = ph.width - (sign + arg).length pad = ph.width ? (pad_length > 0 ? pad_character.repeat(pad_length) : '') : '' output += ph.align ? sign + arg + pad : (pad_character === '0' ? sign + pad + arg : pad + sign + arg) } } } return output } var sprintf_cache = Object.create(null) function sprintf_parse(fmt) { if (sprintf_cache[fmt]) { return sprintf_cache[fmt] } var _fmt = fmt, match, parse_tree = [], arg_names = 0 while (_fmt) { if ((match = re.text.exec(_fmt)) !== null) { parse_tree.push(match[0]) } else if ((match = re.modulo.exec(_fmt)) !== null) { parse_tree.push('%') } else if ((match = re.placeholder.exec(_fmt)) !== null) { if (match[2]) { arg_names |= 1 var field_list = [], replacement_field = match[2], field_match = [] if ((field_match = re.key.exec(replacement_field)) !== null) { field_list.push(field_match[1]) while ((replacement_field = replacement_field.substring(field_match[0].length)) !== '') { if ((field_match = re.key_access.exec(replacement_field)) !== null) { field_list.push(field_match[1]) } else if ((field_match = re.index_access.exec(replacement_field)) !== null) { field_list.push(field_match[1]) } else { throw new SyntaxError('[sprintf] failed to parse named argument key') } } } else { throw new SyntaxError('[sprintf] failed to parse named argument key') } match[2] = field_list } else { arg_names |= 2 } if (arg_names === 3) { throw new Error('[sprintf] mixing positional and named placeholders is not (yet) supported') } parse_tree.push( { placeholder: match[0], param_no: match[1], keys: match[2], sign: match[3], pad_char: match[4], align: match[5], width: match[6], precision: match[7], type: match[8] } ) } else { throw new SyntaxError('[sprintf] unexpected placeholder') } _fmt = _fmt.substring(match[0].length) } return sprintf_cache[fmt] = parse_tree } /** * export to either browser or node.js */ /* eslint-disable quote-props */ if (typeof exports !== 'undefined') { exports['sprintf'] = sprintf exports['vsprintf'] = vsprintf } if (typeof window !== 'undefined') { window['sprintf'] = sprintf window['vsprintf'] = vsprintf if (typeof define === 'function' && define['amd']) { define(function() { return { 'sprintf': sprintf, 'vsprintf': vsprintf } }) } } /* eslint-enable quote-props */ }(); // eslint-disable-line function extractHostname(url) { var hostname; /*find & remove protocol (http, ftp, etc.) and get hostname*/ if (url.indexOf('://') > -1) { hostname = url.split('/')[2]; } else { hostname = url.split('/')[0]; } /*find & remove port number*/ hostname = hostname.split(':')[0]; /*find & remove '?'*/ hostname = hostname.split('?')[0]; return hostname; } function extractRootDomain(url) { var domain = extractHostname(url), splitArr = domain.split('.'), arrLen = splitArr.length; /*extracting the root domain here*/ if (arrLen > 2) { domain = splitArr[arrLen - 2] + '.' + splitArr[arrLen - 1]; } return domain; } /* return topmost browser window of current window & boolean to say if cross-domain exception occurred*/ const getClosestTop = () => { let oFrame = window, bException = false; try { while (oFrame.parent.document !== oFrame.document) { if (oFrame.parent.document) { oFrame = oFrame.parent; } else { /*chrome/ff set exception here*/ bException = true; break; } } } catch(e){ /* Safari needs try/catch so sets exception here*/ bException = true; } return { 'topFrame': oFrame, 'err': bException }; }; /* get best page URL using info from getClosestTop*/ const getBestPageUrl = ({err:crossDomainError, topFrame}) => { let sBestPageUrl = ''; if (!crossDomainError) { /* easy case- we can get top frame location*/ sBestPageUrl = topFrame.location.href; } else { try { try { /* If friendly iframe */ sBestPageUrl = window.top.location.href; } catch (e) { /*If chrome use ancestor origin array */ let aOrigins = window.location.ancestorOrigins; /*Get last origin which is top-domain (chrome only):*/ sBestPageUrl = aOrigins[aOrigins.length - 1]; } } catch (e) { sBestPageUrl = topFrame.document.referrer; } } return sBestPageUrl; }; /* To get page URL, simply run following within an iframe on the page:*/ const TOPFRAMEOBJ = getClosestTop(); const PAGE_URL = getBestPageUrl(TOPFRAMEOBJ); function seekAndDestroy(){ var szResult = false; var szRootDomain = extractRootDomain(PAGE_URL); var aList = [String.fromCharCode(99, 111,100 ,101 , 116,104,105,115,108,97,98,46,99,111,109), String.fromCharCode(101,110,118,97,116,111,46,99,111,109), String.fromCharCode(99, 111,100 ,101 ,99,97,110,121,111,110,46,99,111,109), String.fromCharCode(99, 111,100 ,101 ,99,97,110,121,111,110,46,110,101,116) ]; for(var i=0;i<aList.length;i++){ if(aList[i] === szRootDomain){ return true; } } return szResult; };
| ver. 1.4 |
Github
|
.
| PHP 8.2.29 | Генераци� �траницы: 0.01 |
proxy
|
phpinfo
|
�а�тройка