// MICHAEL MCELROY, MICHAELMCELROY.NET // COPYRIGHT, 2006, ALL RIGHTS RESERVED if (typeof (Development) == "undefined") Development = new Object (); Development . MessageBox = function () { this . window = null; this . initializedPredicate = 0; this . initiate = function () { this . initializedPredicate = 0; this . recycleWindow (); return; }; this . initialize = function () { var html; this . finalize (); this . initializedPredicate = 1; this . recycleWindow (); html = ""; html = html + "\n"; html = html + "\n"; html = html + " \n"; html = html + "\n"; html = html + " \n"; html = html + "\n"; html = html + " MessageBox\n"; html = html + "\n"; html = html + " \n"; html = html + "\n"; html = html + " \n"; html = html + "\n"; html = html + " \n"; html = html + "\n"; html = html + " \n"; html = html + "\n"; html = html + " \n"; html = html + "\n"; html = html + "
\n"; html = html + "\n"; html = html + " Message Box\n"; html = html + "\n"; html = html + "
\n"; html = html + "\n"; html = html + "
\n"; html = html + "\n"; html = html + "
\n"; html = html + "\n"; html = html + " \n"; html = html + "\n"; html = html + " \n"; this . window = window . open ('', (new Date ()) . toString (), 'height = 300, menubar = 0, resizable = 1, scrollbars = 1, status = 0, toolbar = 0, width = 900'); this . window . document . writeln (html); this . window . document . close (); return; }; this . finalize = function () { this . initializedPredicate = 0; this . recycleWindow (); return; } this . recycleWindow = function () { if (this . window != null) this . window . close (); this . window = null; return; }; this . getInitializedPredicate = function () { if (this . initializedPredicate == 0 ) return (0); if (this . window == null ) return (0); if (typeof (this . window . existsPredicate) == "undefined" ) return (0); return (1); }; this . addType = function (type) { if (this . getInitializedPredicate () == 1) if (typeof (this . window . addType) != "undefined") this . window . addType (type); return; }; this . addMessage = function (type, text) { if (this . getInitializedPredicate () == 1) if (typeof (this . window . addMessage) != "undefined") this . window . addMessage (type, text); return; }; this . removeMessages = function () { if (this . initializedPredicate == 1) if (typeof (this . window . removeMessages) != "undefined") this . window . removeMessages (); return; }; }; function InternetClient () { this . initiate = function () { } this . initialize = function () { } this . getPageHeight = function () { var height = 0; if (typeof (window . innerHeight) == 'number') height = window.innerHeight; // MOZILLA else if (document . documentElement && document . documentElement . clientHeight) height = document . documentElement . clientHeight; // INTERNET EXPLORER, "STANDARDS COMPLIANT MODE" else if (document . body && document . body . clientHeight) height = document . body . clientHeight; // INTERNET EXPLORER, "IE4 COMPATIBLE" return (height); } this . getPageWidth = function () { var width = 0; if (typeof (window . innerWidth) == 'number') width = window.innerWidth; // MOZILLA else if (document . documentElement && document . documentElement . clientWidth) width = document . documentElement . clientWidth; // INTERNET EXPLORER, "STANDARDS COMPLIANT MODE" else if (document . body && document . body . clientWidth) width = document . body . clientWidth; // INTERNET EXPLORER, "IE4 COMPATIBLE" return (width); } } function DocumentObjectModel () { this . document = null; this . getSupportedPredicate = function () { } this . initiate = function () { this . document = document; } this . initialize = function () { } this . appendNode = function (mainNode, appendageNode) { mainNode . appendChild (appendageNode); } this . clearNodes = function (node) { while (node . hasChildNodes ()) node . removeChild (node . firstChild); } this . createNode = function (tagName) { return (this . document . createElement (tagName)); } this . createTextNode = function (text) { return (this . document . createTextNode (text)); } this . getDocument = function () { return (this . document); } this . getNode = function (nodeName) { return (this . document . getElementById (nodeName)); } this . getValue = function (text) { return (parseInt (text)); } this . getLayerX = function (cursorEvent) { if (typeof (cursorEvent) != "undefined") if (typeof (cursorEvent . layerX) != "undefined") return (cursorEvent . layerX); if (typeof (event) != "undefined") if (typeof (event . offsetX) != "undefined") return (event . offsetX); return (0); } this . getLayerY = function (cursorEvent) { if (typeof (cursorEvent) != "undefined") if (typeof (cursorEvent . layerY) != "undefined") return (cursorEvent . layerY); if (typeof (event) != "undefined") if (typeof (event . offsetY) != "undefined") return (event . offsetY); return (0); } this . getKeyCode = function (keyEvent) { var keyCode = 0; if (navigator . userAgent . indexOf ("MSIE") == - 1) keyCode = keyEvent . which; else keyCode = window . event . keyCode; return (keyCode); } } function NetworkSocket () { this . division = null; this . script = null; this . initiate = function () { this . division = documentObjectModel . createNode ("div"); this . division . id = "NetworkSocket"; documentObjectModel . appendNode (documentObjectModel . getDocument () . body, this . division); } this . initialize = function () { documentObjectModel . clearNodes (this . division); this . script = null; } this . execute = function (command) { this . script = documentObjectModel . createNode ("script"); this . script . id = "NetworkSocket_Script"; this . script . type = "text/javascript"; this . script . src = command; documentObjectModel . clearNodes (this . division); documentObjectModel . appendNode (this . division, this . script); } } function CheckerPiece () { // STATE this . ownPredicate = 0; this . kingPredicate = 0; this . reversedPredicate = 0; // INTERFACE this . division = null; this . height = 0; this . width = 0; this . initiate = function () { this . division = documentObjectModel . createNode ("div"); } this . initialize = function () { this . ownPredicate = 0; this . kingPredicate = 0; this . reversedPredicate = 0; this . height = 50; this . width = 50; this . division . id = "CheckerPiece"; this . division . style . position = "absolute"; this . division . style . top = "0px"; this . division . style . left = "0px"; this . division . style . height = (this . height) + "px"; this . division . style . width = (this . width) + "px"; this . division . style . overflow = "hidden"; this . division . style . zIndex = "3"; } this . getNode = function () { return (this . division); } this . render = function (renderNode) { documentObjectModel . appendNode (renderNode, this . getNode ()); } this . elevate = function () { this . division . style . zIndex = "4"; } this . ground = function () { this . division . style . zIndex = "3"; } this . getHeight = function () { return (this . height); } this . getWidth = function () { return (this . width); } this . getOwnPredicate = function () { return (this . ownPredicate); } this . setOwnPredicate = function (predicate) { this . ownPredicate = predicate; this . update (); } this . getKingPredicate = function () { return (this . kingPredicate); } this . setKingPredicate = function (predicate) { this . kingPredicate = predicate; this . update (); } this . setCoordinates = function (top, left) { this . division . style . top = (top) + "px"; this . division . style . left = (left) + "px"; } this . reverse = function () { this . reversedPredicate = 1; this . ownPredicate = this . ownPredicate ? 0 : 1; this . update (); } this . update = function () { if (navigator . userAgent . indexOf ("Firefox") != - 1) { if ( this . reversedPredicate && this . ownPredicate && ! this . kingPredicate) this . division . style . backgroundImage = "url(/games/checkers/Checkers/pictures/piece.secondary.soldier.png)"; if ( this . reversedPredicate && this . ownPredicate && this . kingPredicate) this . division . style . backgroundImage = "url(/games/checkers/Checkers/pictures/piece.secondary.king.png)"; if ( this . reversedPredicate && ! this . ownPredicate && ! this . kingPredicate) this . division . style . backgroundImage = "url(/games/checkers/Checkers/pictures/piece.primary.soldier.png)"; if ( this . reversedPredicate && ! this . ownPredicate && this . kingPredicate) this . division . style . backgroundImage = "url(/games/checkers/Checkers/pictures/piece.primary.king.png)"; if (! this . reversedPredicate && this . ownPredicate && ! this . kingPredicate) this . division . style . backgroundImage = "url(/games/checkers/Checkers/pictures/piece.primary.soldier.png)"; if (! this . reversedPredicate && this . ownPredicate && this . kingPredicate) this . division . style . backgroundImage = "url(/games/checkers/Checkers/pictures/piece.primary.king.png)"; if (! this . reversedPredicate && ! this . ownPredicate && ! this . kingPredicate) this . division . style . backgroundImage = "url(/games/checkers/Checkers/pictures/piece.secondary.soldier.png)"; if (! this . reversedPredicate && ! this . ownPredicate && this . kingPredicate) this . division . style . backgroundImage = "url(/games/checkers/Checkers/pictures/piece.secondary.king.png)"; } else { if ( this . reversedPredicate && this . ownPredicate && ! this . kingPredicate) this . division . style . backgroundImage = "url(/games/checkers/Checkers/pictures/piece.secondary.soldier.gif)"; if ( this . reversedPredicate && this . ownPredicate && this . kingPredicate) this . division . style . backgroundImage = "url(/games/checkers/Checkers/pictures/piece.secondary.king.gif)"; if ( this . reversedPredicate && ! this . ownPredicate && ! this . kingPredicate) this . division . style . backgroundImage = "url(/games/checkers/Checkers/pictures/piece.primary.soldier.gif)"; if ( this . reversedPredicate && ! this . ownPredicate && this . kingPredicate) this . division . style . backgroundImage = "url(/games/checkers/Checkers/pictures/piece.primary.king.gif)"; if (! this . reversedPredicate && this . ownPredicate && ! this . kingPredicate) this . division . style . backgroundImage = "url(/games/checkers/Checkers/pictures/piece.primary.soldier.gif)"; if (! this . reversedPredicate && this . ownPredicate && this . kingPredicate) this . division . style . backgroundImage = "url(/games/checkers/Checkers/pictures/piece.primary.king.gif)"; if (! this . reversedPredicate && ! this . ownPredicate && ! this . kingPredicate) this . division . style . backgroundImage = "url(/games/checkers/Checkers/pictures/piece.secondary.soldier.gif)"; if (! this . reversedPredicate && ! this . ownPredicate && this . kingPredicate) this . division . style . backgroundImage = "url(/games/checkers/Checkers/pictures/piece.secondary.king.gif)"; } } } function CheckerPanel () { // STATE this . boardState = null; // AN ARRAY OF CODES THAT DESCRIBES WHAT OCCUPIES EACH SQUARE ON THE BOARD. this . ownPin = null; // A MULTI-DIGIT PIN THAT IS USED TO IDENTIFY {THIS PLAYER, THIS BOARD INSTANCE}. this . opponentPin = null; // A MULTI-DIGIT PIN THAT IS USED TO IDENTIFY {THAT PLAYER, THIS BOARD INSTANCE}. this . currentPlayerPin = null; // A COPY OF THE PIN THAT IS OWNED BY THE PLAYER WHO'S TURN IT IS. this . setOpponentPinDelegate = null; this . setRulesDelegate = null; this . okayButtonInstructions = null; // INTERFACE this . title = null; this . division = null; this . titleDivision = null; this . messageDivision = null; this . opponentPlayerTypeFormDivision = null; this . okayButtonDivision = null; this . pinFormDivision = null; this . pinDivision = null; this . ownPinArea = null; this . opponentPinArea = null; this . playerDivision = null; this . playerImage = null; this . capturedDivision = null; this . rulesFormDivision = null; this . rulesDivision = null; this . lowMessageColor = null; this . mediumMessageColor = null; this . highMessageColor = null; this . initiate = function () { this . division = documentObjectModel . createNode ("div"); this . titleDivision = documentObjectModel . createNode ("div"); this . messageDivision = documentObjectModel . createNode ("div"); this . opponentPlayerTypeFormDivision = documentObjectModel . createNode ("div"); this . okayButtonDivision = documentObjectModel . createNode ("div"); this . pinFormDivision = documentObjectModel . createNode ("div"); this . pinDivision = documentObjectModel . createNode ("div"); this . playerDivision = documentObjectModel . createNode ("div"); this . playerImage = documentObjectModel . createNode ("img"); this . capturedDivision = documentObjectModel . createNode ("div"); this . ownPinArea = documentObjectModel . createNode ("input"); this . opponentPinArea = documentObjectModel . createNode ("input"); this . rulesFormDivision = documentObjectModel . createNode ("div"); this . rulesDivision = documentObjectModel . createNode ("div"); this . lowMessageColor = "#7c7b51"; this . mediumMessageColor = "#495537"; this . highMessageColor = "#553737"; }; this . initialize = function () { this . title = "Checkers"; this . division . id = "CheckerPanel"; this . division . style . position = "absolute"; this . division . style . top = "0px"; this . division . style . left = "0px"; this . division . style . height = (50 * 8) + "px"; this . division . style . width = "175px"; this . division . style . backgroundColor = "#444444"; this . division . style . border = "#000000 2px solid"; this . division . style . overflow = "hidden"; this . titleDivision . id = "CheckerPanel_TitleDivision"; this . titleDivision . style . position = "relative"; this . titleDivision . style . color = "#ffffff"; this . titleDivision . style . backgroundColor = "#222222"; this . titleDivision . style . borderBottom = "#333333 0px solid"; this . titleDivision . style . padding = "8px"; this . titleDivision . style . textAlign = "center"; this . messageDivision . id = "CheckerPanel_MessageDivision"; this . messageDivision . style . position = "relative"; this . messageDivision . style . color = "#ffffff"; this . messageDivision . style . backgroundColor = this . lowMessageColor; this . messageDivision . style . borderBottom = "#333333 1px solid"; this . messageDivision . style . padding = "8px"; this . messageDivision . style . textAlign = "center"; this . opponentPlayerTypeFormDivision . id = "ReversiPanel_OpponentPlayerTypeFormDivision"; this . opponentPlayerTypeFormDivision . style . position = "relative"; this . opponentPlayerTypeFormDivision . style . color = "#ffffff"; this . opponentPlayerTypeFormDivision . style . backgroundColor = "#555555"; this . opponentPlayerTypeFormDivision . style . borderBottom = "#333333 1px solid"; this . opponentPlayerTypeFormDivision . style . padding = "8px"; this . opponentPlayerTypeFormDivision . style . textAlign = "center"; this . opponentPlayerTypeFormDivision . style . display = "none"; this . okayButtonDivision . id = "CheckerPanel_OkayButtonDivision"; this . okayButtonDivision . that = this; this . okayButtonDivision . style . position = "relative"; this . okayButtonDivision . style . cursor = "pointer"; this . okayButtonDivision . style . color = "#ffffff"; this . okayButtonDivision . style . backgroundColor = "#555555"; this . okayButtonDivision . style . borderBottom = "#333333 1px solid"; this . okayButtonDivision . style . padding = "8px"; this . okayButtonDivision . style . textAlign = "center"; this . okayButtonDivision . style . display = "none"; this . pinFormDivision . id = "CheckerPanel_pinFormDivision"; this . pinFormDivision . style . position = "relative"; this . pinFormDivision . style . color = "#ffffff"; this . pinFormDivision . style . backgroundColor = "#555555"; this . pinFormDivision . style . borderBottom = "#333333 1px solid"; this . pinFormDivision . style . padding = "8px"; this . pinFormDivision . style . textAlign = "center"; this . pinFormDivision . style . display = "none"; this . ownPinArea . id = "CheckerPanel_ownPinArea"; this . ownPinArea . style . position = "relative"; this . ownPinArea . style . width = "50px"; this . ownPinArea . style . color = "#ffffff"; this . ownPinArea . style . backgroundColor = "#555555"; this . ownPinArea . style . border = "#000000 1px solid"; this . ownPinArea . style . padding = "2px"; this . ownPinArea . style . textAlign = "center"; this . ownPinArea . value = this . ownPin; this . opponentPinArea . id = "CheckerPanel_opponentPinArea"; this . opponentPinArea . that = this; this . opponentPinArea . style . position = "relative"; this . opponentPinArea . style . width = "50px"; this . opponentPinArea . style . color = "#000000"; this . opponentPinArea . style . backgroundColor = "#ffffff"; this . opponentPinArea . style . border = "#000000 1px solid"; this . opponentPinArea . style . padding = "2px"; this . opponentPinArea . style . textAlign = "center"; this . opponentPinArea . value = ""; this . ownPinArea . onkeypress = function (keyEvent) { var keyCode = context . getKeyCode (keyEvent); return (false); }; this . opponentPinArea . onkeypress = function (keyEvent) { var keyCode = documentObjectModel . getKeyCode (keyEvent); // APPROVE CERTAIN CHARACTERS FIRST, REJECT OTHER CHARACTERS LATER. if (keyCode == 8) return (true); // BACKSPACE if (keyCode == 48) return (true); // 0 if (keyCode == 49) return (true); // 1 if (keyCode == 50) return (true); // 2 if (keyCode == 51) return (true); // 3 if (keyCode == 52) return (true); // 4 if (keyCode == 53) return (true); // 5 if (keyCode == 54) return (true); // 6 if (keyCode == 55) return (true); // 7 if (keyCode == 56) return (true); // 8 if (keyCode == 57) return (true); // 9 // AT THIS POINT, WE KNOW THE CHARACTER IS NOT ALLOWED, SO DISCARD IT. return (false); }; this . opponentPinArea . onkeyup = function () { if (this . value == this . that . ownPinArea . value) this . value = ""; if (this . value . length > 4) this . value = this . value . substring (0, 4); if (this . value . length == 4) { this . that . setOpponentPinDelegate (this . value); } }; this . okayButtonDivision . onclick = function () { this . that . hideOkayButton (); }; this . playerDivision . id = "ReversiPanel_PlayerDivision"; this . playerDivision . style . position = "relative"; this . playerDivision . style . color = "#ffffff"; this . playerDivision . style . backgroundColor = "#444444"; this . playerDivision . style . borderBottom = "#444444 1px solid"; this . playerDivision . style . padding = "8px"; this . playerDivision . style . textAlign = "center"; this . playerDivision . style . display = "block"; var javascriptText; javascriptText = ""; javascriptText = javascriptText + "javascript: "; javascriptText = javascriptText + "messageBox . initialize (); "; javascriptText = javascriptText + "messageBox . addType (\"Events\"); "; javascriptText = javascriptText + "messageBox . addType (\"Notes\"); "; javascriptText = javascriptText + "messageBox . addType (\"Warnings\"); "; javascriptText = javascriptText + "messageBox . addType (\"Errors\"); "; this . playerImage . that = this; this . playerImage . src = "/games/checkers/Checkers/pictures/piece.primary.soldier." + (navigator . userAgent . indexOf ("Firefox") != - 1 ? "png" : "gif"); this . playerImage . style . display = "block"; this . playerImage . style . marginLeft = "auto"; this . playerImage . style . marginRight = "auto"; this . playerImage . style . height = "50px"; this . playerImage . style . width = "50px"; this . playerImage . setAttribute ("onclick", javascriptText); this . pinDivision . id = "CheckerPanel_PinDivision"; this . pinDivision . style . position = "relative"; this . pinDivision . style . color = "#ffffff"; this . pinDivision . style . backgroundColor = "#555555"; this . pinDivision . style . borderBottom = "#333333 1px solid"; this . pinDivision . style . padding = "8px"; this . pinDivision . style . textAlign = "center"; this . pinDivision . style . display = "none"; this . capturedDivision . id = "CheckersPanel_capturedDivision"; this . capturedDivision . style . position = "relative"; this . capturedDivision . style . color = "#aaaaaa"; this . capturedDivision . style . backgroundColor = "#444444"; this . capturedDivision . style . borderBottom = "#444444 1px solid"; this . capturedDivision . style . padding = "8px"; this . capturedDivision . style . textAlign = "center"; this . capturedDivision . style . display = "none"; this . rulesFormDivision . id = "CheckerPanel_RulesFormDivision"; this . rulesFormDivision . style . position = "relative"; this . rulesFormDivision . style . color = "#ffffff"; this . rulesFormDivision . style . backgroundColor = "#555555"; this . rulesFormDivision . style . borderBottom = "#333333 1px solid"; this . rulesFormDivision . style . padding = "8px"; this . rulesFormDivision . style . textAlign = "center"; this . rulesFormDivision . style . display = "none"; this . rulesDivision . id = "CheckerPanel_RulesDivision"; this . rulesDivision . style . position = "relative"; this . rulesDivision . style . color = "#ffffff"; this . rulesDivision . style . backgroundColor = "#555555"; this . rulesDivision . style . borderBottom = "#333333 1px solid"; this . rulesDivision . style . padding = "8px"; this . rulesDivision . style . textAlign = "center"; this . rulesDivision . style . display = "none"; // APPEND THE MAJOR COMPONENTS TO THE PANEL. documentObjectModel . appendNode (this . getNode (), this . titleDivision); documentObjectModel . appendNode (this . getNode (), this . messageDivision); documentObjectModel . appendNode (this . getNode (), this . okayButtonDivision); documentObjectModel . appendNode (this . getNode (), this . opponentPlayerTypeFormDivision); documentObjectModel . appendNode (this . getNode (), this . rulesFormDivision); documentObjectModel . appendNode (this . getNode (), this . rulesDivision); documentObjectModel . appendNode (this . getNode (), this . pinFormDivision); documentObjectModel . appendNode (this . getNode (), this . pinDivision); documentObjectModel . appendNode (this . getNode (), this . playerDivision); documentObjectModel . appendNode (this . getNode (), this . capturedDivision); documentObjectModel . appendNode (this . playerDivision, this . playerImage); // APPEND THE MINOR COMPONENTS TO THE MAJOR COMPONENTS. var makaylaOption = documentObjectModel . createNode ("img"); var friendOption = documentObjectModel . createNode ("img"); makaylaOption . that = this; makaylaOption . style . cursor = "pointer"; makaylaOption . opponentPlayerType = "virtual"; makaylaOption . src = "/games/checkers/Checkers/pictures/button.makayla.jpg"; makaylaOption . onclick = function () {this . that . setOpponentPlayerTypeDelegate (this . opponentPlayerType);} friendOption . that = this; friendOption . style . cursor = "pointer"; friendOption . opponentPlayerType = "actual"; friendOption . src = "/games/checkers/Checkers/pictures/button.friend.jpg"; friendOption . onclick = function () {this . that . setOpponentPlayerTypeDelegate (this . opponentPlayerType);} documentObjectModel . appendNode (this . opponentPlayerTypeFormDivision, makaylaOption); documentObjectModel . appendNode (this . opponentPlayerTypeFormDivision, documentObjectModel . createNode ("br")); documentObjectModel . appendNode (this . opponentPlayerTypeFormDivision, friendOption); var internationalOption = documentObjectModel . createNode ("img"); var americanOption = documentObjectModel . createNode ("img"); var brazilianOption = documentObjectModel . createNode ("img"); var canadianOption = documentObjectModel . createNode ("img"); var polishOption = documentObjectModel . createNode ("img"); documentObjectModel . appendNode (this . rulesFormDivision, internationalOption); documentObjectModel . appendNode (this . rulesFormDivision, documentObjectModel . createNode ("br")); documentObjectModel . appendNode (this . rulesFormDivision, americanOption); documentObjectModel . appendNode (this . rulesFormDivision, documentObjectModel . createNode ("br")); documentObjectModel . appendNode (this . rulesFormDivision, brazilianOption); documentObjectModel . appendNode (this . rulesFormDivision, documentObjectModel . createNode ("br")); documentObjectModel . appendNode (this . rulesFormDivision, canadianOption); documentObjectModel . appendNode (this . rulesFormDivision, documentObjectModel . createNode ("br")); documentObjectModel . appendNode (this . rulesFormDivision, polishOption); internationalOption . that = this; internationalOption . style . cursor = "pointer"; internationalOption . rulesName = "Polish"; internationalOption . src = "/games/checkers/Checkers/pictures/button.international.jpg"; internationalOption . onclick = function () {this . that . setRulesDelegate (this . rulesName);} americanOption . that = this; americanOption . style . cursor = "pointer"; americanOption . rulesName = "American"; americanOption . src = "/games/checkers/Checkers/pictures/button.american.jpg"; americanOption . onclick = function () {this . that . setRulesDelegate (this . rulesName);} brazilianOption . that = this; brazilianOption . style . cursor = "pointer"; brazilianOption . rulesName = "Brazilian"; brazilianOption . src = "/games/checkers/Checkers/pictures/button.brazilian.jpg"; brazilianOption . onclick = function () {this . that . setRulesDelegate (this . rulesName);} canadianOption . that = this; canadianOption . style . cursor = "pointer"; canadianOption . rulesName = "Canadian"; canadianOption . src = "/games/checkers/Checkers/pictures/button.canadian.jpg"; canadianOption . onclick = function () {this . that . setRulesDelegate (this . rulesName);} polishOption . that = this; polishOption . style . cursor = "pointer"; polishOption . rulesName = "Polish"; polishOption . src = "/games/checkers/Checkers/pictures/button.polish.jpg"; polishOption . onclick = function () {this . that . setRulesDelegate (this . rulesName);} documentObjectModel . appendNode (this . titleDivision, documentObjectModel . createTextNode (this . title)); var okayOption; okayOption = documentObjectModel . createNode ("img"); okayOption . that = this; okayOption . style . cursor = "pointer"; okayOption . typeText = "okay"; okayOption . src = "/games/checkers/Checkers/pictures/button.okay.jpg"; documentObjectModel . appendNode (this . okayButtonDivision, okayOption); documentObjectModel . appendNode (this . pinFormDivision, this . ownPinArea); documentObjectModel . appendNode (this . pinFormDivision, documentObjectModel . createTextNode (" ")); documentObjectModel . appendNode (this . pinFormDivision, this . opponentPinArea); this . setMessage ("low", "Initializing"); }; this . setMessage = function (level, message) { if (level == "low") this . messageDivision . style . backgroundColor = this . lowMessageColor; if (level == "medium") this . messageDivision . style . backgroundColor = this . mediumMessageColor; if (level == "high") this . messageDivision . style . backgroundColor = this . highMessageColor; documentObjectModel . clearNodes (this . messageDivision); documentObjectModel . appendNode (this . messageDivision, documentObjectModel . createTextNode (message)); }; this . showPlayerMessage = function (player) { var message; var extension; if (navigator . userAgent . indexOf ("Firefox") != - 1) extension = "png"; else extension = "gif"; if (player == "primary") this . playerImage . src = "/games/checkers/Checkers/pictures/piece.primary.soldier." + extension; else this . playerImage . src = "/games/checkers/Checkers/pictures/piece.secondary.soldier." + extension; this . playerDivision . style . display = "block"; }; this . showCaptures = function (captures) { if (captures == null) return; if (captures . length == 0) return; var capturedTitle; capturedTitle = documentObjectModel . createNode ("span"); capturedTitle . style . color = "#ffffff"; documentObjectModel . appendNode (capturedTitle, documentObjectModel . createTextNode ("Captured")); documentObjectModel . clearNodes (this . capturedDivision); documentObjectModel . appendNode (this . capturedDivision, capturedTitle); documentObjectModel . appendNode (this . capturedDivision, documentObjectModel . createNode ("br")); for (var index = 0; index < captures . length; index = index + 1) { documentObjectModel . appendNode (this . capturedDivision, documentObjectModel . createTextNode (captures [index])); documentObjectModel . appendNode (this . capturedDivision, documentObjectModel . createNode ("br")); } this . capturedDivision . style . display = "block"; }; this . hideCaptures = function () { this . capturedDivision . style . display = "none"; }; this . displayOpponentPlayerTypePrompt = function (delegate) { this . setOpponentPlayerTypeDelegate = delegate; this . setMessage ("medium", "Who would you like to challenge?"); this . opponentPlayerTypeFormDivision . style . display = "block"; this . setOpponentPlayerTypeDelegate ("actual"); return; }; this . hideOpponentPlayerTypePrompt = function () { this . opponentPlayerTypeFormDivision . style . display = "none"; return; }; this . displayPinPrompt = function (ownPin, delegate) { this . ownPin = ownPin; this . ownPinArea . value = ownPin; this . setOpponentPinDelegate = delegate; this . setMessage ("medium", "please exchange codes with your friend"); this . pinFormDivision . style . display = "block"; } this . showPins = function (ownPin, opponentPin) { this . pinFormDivision . style . display = "none"; this . pinDivision . style . display = "block"; documentObjectModel . appendNode (this . pinDivision, documentObjectModel . createTextNode (ownPin + " : " + opponentPin)); } this . displayRulesPrompt = function (delegate) { this . setRulesDelegate = delegate; this . setMessage ("medium", "please select the rule set"); this . rulesFormDivision . style . display = "block"; } this . showRulesName = function (rulesName) { this . rulesFormDivision . style . display = "none"; this . rulesDivision . style . display = "block"; documentObjectModel . appendNode (this . rulesDivision, documentObjectModel . createTextNode (rulesName + " Checkers")); } this . showOkayButton = function (okayButtonInstructions) { this . okayButtonInstructions = okayButtonInstructions; this . okayButtonDivision . style . display = "block"; } this . hideOkayButton = function () { this . okayButtonDivision . style . display = "none"; setTimeout (this . okayButtonInstructions, 10); } this . getNode = function () { return (this . division); } this . render = function (renderNode) { documentObjectModel . appendNode (renderNode, this . getNode ()); } this . setRowPixelCount = function (rowPixelCount) { this . division . style . height = (rowPixelCount) + "px"; } this . setBoardSize = function (heightSquareCount, widthSquareCount) { for (var rowIndex = 0; rowIndex < heightSquareCount; rowIndex = rowIndex + 1) { this . boardState [rowIndex] = new Array (); } for (var rowIndex = 0; rowIndex < heightSquareCount; rowIndex = rowIndex + 1) for (var columnIndex = 0; columnIndex < widthSquareCount; columnIndex = columnIndex + 1) { this . boardState [rowIndex] [columnIndex] = new Array (); } } } function CheckerBoard () { // STATE this . boardState = null; // AN ARRAY OF CODES THAT DESCRIBES WHAT OCCUPIES EACH SQUARE ON THE BOARD. this . ownPin = null; // A MULTI-DIGIT PIN THAT IS USED TO IDENTIFY {THIS PLAYER, THIS BOARD INSTANCE}. this . opponentPin = null; // A MULTI-DIGIT PIN THAT IS USED TO IDENTIFY {THAT PLAYER, THIS BOARD INSTANCE}. this . currentPlayerPin = null; // A COPY OF THE PIN THAT IS OWNED BY THE PLAYER WHO'S TURN IT IS. this . rowCount = 0; this . columnCount = 0; this . selectedCheckerPiece = null; this . checkerPieces = null; // INTERFACE this . division = null; this . glassDivision = null; this . squareDivisions = null; this . borderThickness = 0; this . squareHeight = 0; this . squareWidth = 0; this . offColor = null; this . onColor = null; this . squareBorderColor = null; this . onStartUpLeftMarker = null; this . onStartUpRightMarker = null; this . onStartDownLeftMarker = null; this . onStartDownRightMarker = null; this . onStepUpLeftMarkers = null; this . onStepUpRightMarkers = null; this . onStepDownLeftMarkers = null; this . onStepDownRightMarkers = null; this . onCaptureMarkers = null; this . onDotMarker = null; // marks captures of the current jump this . onStopMarker = null; this . offStartUpLeftMarker = null; this . offStartUpRightMarker = null; this . offStartDownLeftMarker = null; this . offStartDownRightMarker = null; this . offStepUpLeftMarkers = null; this . offStepUpRightMarkers = null; this . offStepDownLeftMarkers = null; this . offStepDownRightMarkers = null; this . offCaptureMarkers = null; this . offDotMarker = null; // marks captures of the current jump this . offStopMarker = null; this . cache = null; this . getMarker = function (imageURL) { var division; division = documentObjectModel . createNode ("div"); division . style . position = "absolute"; division . style . top = "0px"; division . style . left = "0px"; division . style . height = "50px"; division . style . width = "50px"; division . style . backgroundImage = imageURL; division . style . overflow = "hidden"; division . style . display = "none"; division . style . zIndex = "2"; return (division); } this . initiate = function () { this . division = documentObjectModel . createNode ("div"); this . glassDivision = documentObjectModel . createNode ("div"); this . squareDivisions = new Array (); this . checkerDivisions = new Array (); this . onStepUpLeftMarkers = new Array (); this . onStepUpRightMarkers = new Array (); this . onStepDownLeftMarkers = new Array (); this . onStepDownRightMarkers = new Array (); this . onCaptureMarkers = new Array (); this . onDotMarkers = new Array (); this . offStepUpLeftMarkers = new Array (); this . offStepUpRightMarkers = new Array (); this . offStepDownLeftMarkers = new Array (); this . offStepDownRightMarkers = new Array (); this . offCaptureMarkers = new Array (); this . offDotMarkers = new Array (); this . onStartUpLeftMarker = this . getMarker ("url(/games/checkers/Checkers/pictures/marker.on.start.up.left.jpg)"); this . onStartUpRightMarker = this . getMarker ("url(/games/checkers/Checkers/pictures/marker.on.start.up.right.jpg)"); this . onStartDownLeftMarker = this . getMarker ("url(/games/checkers/Checkers/pictures/marker.on.start.down.left.jpg)"); this . onStartDownRightMarker = this . getMarker ("url(/games/checkers/Checkers/pictures/marker.on.start.down.right.jpg)"); this . offStartUpLeftMarker = this . getMarker ("url(/games/checkers/Checkers/pictures/marker.off.start.up.left.jpg)"); this . offStartUpRightMarker = this . getMarker ("url(/games/checkers/Checkers/pictures/marker.off.start.up.right.jpg)"); this . offStartDownLeftMarker = this . getMarker ("url(/games/checkers/Checkers/pictures/marker.off.start.down.left.jpg)"); this . offStartDownRightMarker = this . getMarker ("url(/games/checkers/Checkers/pictures/marker.off.start.down.right.jpg)"); this . onStopMarker = this . getMarker ("url(/games/checkers/Checkers/pictures/marker.on.stop.jpg)"); this . offStopMarker = this . getMarker ("url(/games/checkers/Checkers/pictures/marker.off.stop.jpg)"); documentObjectModel . appendNode (this . division, this . onStartUpLeftMarker); documentObjectModel . appendNode (this . division, this . onStartUpRightMarker); documentObjectModel . appendNode (this . division, this . onStartDownLeftMarker); documentObjectModel . appendNode (this . division, this . onStartDownRightMarker); documentObjectModel . appendNode (this . division, this . offStartUpLeftMarker); documentObjectModel . appendNode (this . division, this . offStartUpRightMarker); documentObjectModel . appendNode (this . division, this . offStartDownLeftMarker); documentObjectModel . appendNode (this . division, this . offStartDownRightMarker); documentObjectModel . appendNode (this . division, this . onStopMarker); documentObjectModel . appendNode (this . division, this . offStopMarker); for (var index = 0; index < 30; index = index + 1) { this . onStepUpLeftMarkers [index] = this . getMarker ("url(/games/checkers/Checkers/pictures/marker.on.step.up.left.jpg)"); this . onStepUpRightMarkers [index] = this . getMarker ("url(/games/checkers/Checkers/pictures/marker.on.step.up.right.jpg)"); this . onStepDownLeftMarkers [index] = this . getMarker ("url(/games/checkers/Checkers/pictures/marker.on.step.down.left.jpg)"); this . onStepDownRightMarkers [index] = this . getMarker ("url(/games/checkers/Checkers/pictures/marker.on.step.down.right.jpg)"); this . onCaptureMarkers [index] = this . getMarker ("url(/games/checkers/Checkers/pictures/marker.on.capture.jpg)"); this . onDotMarkers [index] = this . getMarker ("url(/games/checkers/Checkers/pictures/marker.on.dot.jpg)"); this . offStepUpLeftMarkers [index] = this . getMarker ("url(/games/checkers/Checkers/pictures/marker.off.step.up.left.jpg)"); this . offStepUpRightMarkers [index] = this . getMarker ("url(/games/checkers/Checkers/pictures/marker.off.step.up.right.jpg)"); this . offStepDownLeftMarkers [index] = this . getMarker ("url(/games/checkers/Checkers/pictures/marker.off.step.down.left.jpg)"); this . offStepDownRightMarkers [index] = this . getMarker ("url(/games/checkers/Checkers/pictures/marker.off.step.down.right.jpg)"); this . offCaptureMarkers [index] = this . getMarker ("url(/games/checkers/Checkers/pictures/marker.off.capture.jpg)"); this . offDotMarkers [index] = this . getMarker ("url(/games/checkers/Checkers/pictures/marker.off.dot.jpg)"); documentObjectModel . appendNode (this . division, this . onStepUpLeftMarkers [index]); documentObjectModel . appendNode (this . division, this . onStepUpRightMarkers [index]); documentObjectModel . appendNode (this . division, this . onStepDownLeftMarkers [index]); documentObjectModel . appendNode (this . division, this . onStepDownRightMarkers [index]); documentObjectModel . appendNode (this . division, this . offStepUpLeftMarkers [index]); documentObjectModel . appendNode (this . division, this . offStepUpRightMarkers [index]); documentObjectModel . appendNode (this . division, this . offStepDownLeftMarkers [index]); documentObjectModel . appendNode (this . division, this . offStepDownRightMarkers [index]); documentObjectModel . appendNode (this . division, this . onCaptureMarkers [index]); documentObjectModel . appendNode (this . division, this . offCaptureMarkers [index]); documentObjectModel . appendNode (this . division, this . onDotMarkers [index]); documentObjectModel . appendNode (this . division, this . offDotMarkers [index]); } } this . initialize = function () { this . rowCount = 8; this . columnCount = 8; this . squareHeight = 50; this . squareWidth = 50; this . borderThickness = 1; this . offColor = "#434343"; this . onColor = "#3f3f3f"; this . squareBorderColor = "#353535"; this . division . id = "CheckerBoard"; this . division . style . position = "absolute"; this . division . style . top = "0px"; this . division . style . left = "200px"; this . division . style . backgroundColor = this . squareBorderColor; this . division . style . border = "#000000 2px solid"; this . division . style . overflow = "hidden"; this . division . style . zIndex = "0"; this . glassDivision . id = "CheckerBoard_Glass"; this . glassDivision . that = this; this . glassDivision . style . position = "absolute"; this . glassDivision . style . top = "0px"; this . glassDivision . style . left = "0px"; this . glassDivision . style . height = "100%"; this . glassDivision . style . width = "100%"; this . glassDivision . style . backgroundColor = "transparent"; this . glassDivision . style . overflow = "hidden"; this . glassDivision . style . zIndex = "5"; this . checkerPieces = new Array (); } this . getNode = function () { return (this . division); } this . render = function (renderNode) { documentObjectModel . appendNode (this . getNode (), this . glassDivision); documentObjectModel . appendNode (renderNode, this . getNode ()); } this . scale = function () { if (! this . division . style . height) this . division . style . height = "0px"; if (this . division . style . height == "") this . division . style . height = "0px"; if (! this . division . style . width) this . division . style . width = "0px"; if (this . division . style . width == "") this . division . style . width = "0px"; if ((this . targetRowPixelCount + "px") == this . division . style . height) if ((this . targetColumnPixelCount + "px") == this . division . style . width) return; var deltaHeight = Math . floor ((this . targetRowPixelCount + parseInt (this . division . style . height, 10)) / 2); var deltaWidth = Math . floor ((this . targetColumnPixelCount + parseInt (this . division . style . width, 10)) / 2); if ((deltaHeight > (this . targetRowPixelCount - 2)) && (deltaHeight < (this . targetRowPixelCount + 2))) deltaHeight = this . targetRowPixelCount; if ((deltaWidth > (this . targetColumnPixelCount - 2)) && (deltaWidth < (this . targetColumnPixelCount + 2))) deltaWidth = this . targetColumnPixelCount; this . division . style . height = (deltaHeight) + "px"; this . division . style . width = (deltaWidth) + "px"; setTimeout ("checkers . checkerBoard . scale ()", 50); } this . clearCheckerPieceNodes = function () { for (var pieceIndex = 0; pieceIndex < this . checkerPieces . length; pieceIndex = pieceIndex + 1) { this . getNode () . removeChild (this . checkerPieces [pieceIndex] . getNode ()); this . checkerPieces [pieceIndex] = null; } this . checkerPieces = new Array (); } this . setBoardState = function (boardState, playerRank) { this . clearCheckerPieceNodes (); this . boardState = null; this . boardState = boardState; this . rowCount = this . boardState . length; this . columnCount = this . boardState [0] . length; for (var rowIndex = 0; rowIndex < this . rowCount; rowIndex = rowIndex + 1) for (var columnIndex = 0; columnIndex < this . columnCount; columnIndex = columnIndex + 1) { if (! this . squareDivisions [rowIndex]) this . squareDivisions [rowIndex] = new Array (); if (! this . squareDivisions [rowIndex] [columnIndex]) this . squareDivisions [rowIndex] [columnIndex] = documentObjectModel . createNode ("div"); this . squareDivisions [rowIndex] [columnIndex] . style . position = "absolute"; this . squareDivisions [rowIndex] [columnIndex] . style . top = (rowIndex * (this . squareHeight + this . borderThickness)) + "px"; this . squareDivisions [rowIndex] [columnIndex] . style . left = (columnIndex * (this . squareWidth + this . borderThickness)) + "px"; this . squareDivisions [rowIndex] [columnIndex] . style . height = (this . squareHeight) + "px"; this . squareDivisions [rowIndex] [columnIndex] . style . width = (this . squareWidth) + "px"; this . squareDivisions [rowIndex] [columnIndex] . style . zIndex = "1"; // this . squareDivisions [rowIndex] [columnIndex] . style . border = this . squareBorderColor + " 1px solid"; this . squareDivisions [rowIndex] [columnIndex] . style . backgroundColor = ((rowIndex % 2) == (columnIndex % 2)) ? this . offColor : this . onColor; this . squareDivisions [rowIndex] [columnIndex] . style . backgroundImage = ""; documentObjectModel . appendNode (this . getNode (), this . squareDivisions [rowIndex] [columnIndex]); } this . division . style . height = (this . rowCount * (this . squareHeight + this . borderThickness) - 1) + "px"; this . division . style . width = (this . columnCount * (this . squareWidth + this . borderThickness) - 1) + "px"; // if (navigator . userAgent . indexOf ("MSIE") != - 1) // // { // this . division . style . height = (this . rowCount * (this . squareHeight + this . borderThickness) - 1 + 4) + "px"; // this . division . style . width = (this . columnCount * (this . squareWidth + this . borderThickness) - 1 + 4) + "px"; // } for (var rowIndex = 0; rowIndex < this . rowCount; rowIndex = rowIndex + 1) for (var columnIndex = 0; columnIndex < this . columnCount; columnIndex = columnIndex + 1) { if (this . boardState [rowIndex] [columnIndex] != null) { var checkerPiece = this . boardState [rowIndex] [columnIndex]; this . checkerPieces . push (checkerPiece); documentObjectModel . appendNode (this . getNode (), checkerPiece . getNode ()); } } this . update (); if (playerRank == "secondary") this . reverse (); this . update (); } this . update = function () { // STABILIZE THE BOARD BY MAKING SURE THAT EACH CHECKER PIECE IS RENDERED IN THE RIGHT LOCATION ON THE BOARD. for (var rowIndex = 0; rowIndex < this . rowCount; rowIndex = rowIndex + 1) for (var columnIndex = 0; columnIndex < this . columnCount; columnIndex = columnIndex + 1) if (this . boardState [rowIndex] [columnIndex] != null) { var checkerPiece = this . boardState [rowIndex] [columnIndex]; checkerPiece . setCoordinates (rowIndex * (this . squareHeight + this . borderThickness), columnIndex * (this . squareWidth + this . borderThickness)); } // IF THE SELECTED CHECKER IS RETURNED TO IT'S ORIGINAL LOCATION, THEN UNSELECT THE CHECKER PIECE. // THIS IS NECESSARY SO THAT THE GUEST MAY CHOOSE ANOTHER PIECE TO USE DURING THIS TURN. if (checkers . midjumpPredicate == 0) if (this . selectedCheckerPiece) if (this . selectedCheckerPiece == this . boardState [this . selectedCheckerPiece . fromRowIndex] [this . selectedCheckerPiece . fromColumnIndex]) this . selectedCheckerPiece = null; } this . showMarkers = function (trace) { var traceArray = trace . split (","); var rowIndex; var columnIndex; var markerIndex; var onCaptureMarkerIndex = 0; var onStepUpLeftMarkerIndex = 0; var onStepUpRightMarkerIndex = 0; var onStepDownLeftMarkerIndex = 0; var onStepDownRightMarkerIndex = 0; var offCaptureMarkerIndex = 0; var offStepUpLeftMarkerIndex = 0; var offStepUpRightMarkerIndex = 0; var offStepDownLeftMarkerIndex = 0; var offStepDownRightMarkerIndex = 0; // MARK THE BEGINNING rowIndex = parseInt (traceArray [0]); columnIndex = parseInt (traceArray [1]); var marker; if ((rowIndex % 2) == (columnIndex % 2)) { if ((parseInt (traceArray [0]) > parseInt (traceArray [2])) && (parseInt (traceArray [1]) > parseInt (traceArray [3]))) marker = this . offStartUpLeftMarker; if ((parseInt (traceArray [0]) > parseInt (traceArray [2])) && (parseInt (traceArray [1]) < parseInt (traceArray [3]))) marker = this . offStartUpRightMarker; if ((parseInt (traceArray [0]) < parseInt (traceArray [2])) && (parseInt (traceArray [1]) > parseInt (traceArray [3]))) marker = this . offStartDownLeftMarker; if ((parseInt (traceArray [0]) < parseInt (traceArray [2])) && (parseInt (traceArray [1]) < parseInt (traceArray [3]))) marker = this . offStartDownRightMarker; marker . style . display = "block"; marker . style . top = (rowIndex * (this . squareHeight + this . borderThickness)) + "px"; marker . style . left = (columnIndex * (this . squareHeight + this . borderThickness)) + "px"; } else { if ((parseInt (traceArray [0]) > parseInt (traceArray [2])) && (parseInt (traceArray [1]) > parseInt (traceArray [3]))) marker = this . onStartUpLeftMarker; if ((parseInt (traceArray [0]) > parseInt (traceArray [2])) && (parseInt (traceArray [1]) < parseInt (traceArray [3]))) marker = this . onStartUpRightMarker; if ((parseInt (traceArray [0]) < parseInt (traceArray [2])) && (parseInt (traceArray [1]) > parseInt (traceArray [3]))) marker = this . onStartDownLeftMarker; if ((parseInt (traceArray [0]) < parseInt (traceArray [2])) && (parseInt (traceArray [1]) < parseInt (traceArray [3]))) marker = this . onStartDownRightMarker; marker . style . display = "block"; marker . style . top = (rowIndex * (this . squareHeight + this . borderThickness)) + "px"; marker . style . left = (columnIndex * (this . squareHeight + this . borderThickness)) + "px"; } // MARK EACH STEP AND MARK EACH CAPTURE for (var index = 2; index < (traceArray . length - 2); index = index + 2) { rowIndex = parseInt (traceArray [index + 0]); columnIndex = parseInt (traceArray [index + 1]); if (traceArray [index + 0] . indexOf ("x") != - 1) { if ((rowIndex % 2) == (columnIndex % 2)) { this . offCaptureMarkers [offCaptureMarkerIndex] . style . display = "block"; this . offCaptureMarkers [offCaptureMarkerIndex] . style . top = (rowIndex * (this . squareHeight + this . borderThickness)) + "px"; this . offCaptureMarkers [offCaptureMarkerIndex] . style . left = (columnIndex * (this . squareHeight + this . borderThickness)) + "px"; offCaptureMarkerIndex = offCaptureMarkerIndex + 1; } else { this . onCaptureMarkers [onCaptureMarkerIndex] . style . display = "block"; this . onCaptureMarkers [onCaptureMarkerIndex] . style . top = (rowIndex * (this . squareHeight + this . borderThickness)) + "px"; this . onCaptureMarkers [onCaptureMarkerIndex] . style . left = (columnIndex * (this . squareHeight + this . borderThickness)) + "px"; onCaptureMarkerIndex = onCaptureMarkerIndex + 1; } } else { if ((rowIndex % 2) == (columnIndex % 2)) { if ((parseInt (traceArray [index + 0]) > parseInt (traceArray [index + 4])) && (parseInt (traceArray [index + 1]) > parseInt (traceArray [index + 5]))) marker = this . offStepUpLeftMarkers; if ((parseInt (traceArray [index + 0]) > parseInt (traceArray [index + 4])) && (parseInt (traceArray [index + 1]) < parseInt (traceArray [index + 5]))) marker = this . offStepUpRightMarkers; if ((parseInt (traceArray [index + 0]) < parseInt (traceArray [index + 4])) && (parseInt (traceArray [index + 1]) > parseInt (traceArray [index + 5]))) marker = this . offStepDownLeftMarkers; if ((parseInt (traceArray [index + 0]) < parseInt (traceArray [index + 4])) && (parseInt (traceArray [index + 1]) < parseInt (traceArray [index + 5]))) marker = this . offStepDownRightMarkers; if ((parseInt (traceArray [index + 0]) > parseInt (traceArray [index + 4])) && (parseInt (traceArray [index + 1]) > parseInt (traceArray [index + 5]))) markerIndex = offStepUpLeftMarkerIndex; if ((parseInt (traceArray [index + 0]) > parseInt (traceArray [index + 4])) && (parseInt (traceArray [index + 1]) < parseInt (traceArray [index + 5]))) markerIndex = offStepUpRightMarkerIndex; if ((parseInt (traceArray [index + 0]) < parseInt (traceArray [index + 4])) && (parseInt (traceArray [index + 1]) > parseInt (traceArray [index + 5]))) markerIndex = offStepDownLeftMarkerIndex; if ((parseInt (traceArray [index + 0]) < parseInt (traceArray [index + 4])) && (parseInt (traceArray [index + 1]) < parseInt (traceArray [index + 5]))) markerIndex = offStepDownRightMarkerIndex; marker [markerIndex] . style . display = "block"; marker [markerIndex] . style . top = (rowIndex * (this . squareHeight + this . borderThickness)) + "px"; marker [markerIndex] . style . left = (columnIndex * (this . squareHeight + this . borderThickness)) + "px"; if ((parseInt (traceArray [index + 0]) > parseInt (traceArray [index + 4])) && (parseInt (traceArray [index + 1]) > parseInt (traceArray [index + 5]))) offStepUpLeftMarkerIndex = offStepUpLeftMarkerIndex + 1; if ((parseInt (traceArray [index + 0]) > parseInt (traceArray [index + 4])) && (parseInt (traceArray [index + 1]) < parseInt (traceArray [index + 5]))) offStepUpRightMarkerIndex = offStepUpRightMarkerIndex + 1; if ((parseInt (traceArray [index + 0]) < parseInt (traceArray [index + 4])) && (parseInt (traceArray [index + 1]) > parseInt (traceArray [index + 5]))) offStepDownLeftMarkerIndex = offStepDownLeftMarkerIndex + 1; if ((parseInt (traceArray [index + 0]) < parseInt (traceArray [index + 4])) && (parseInt (traceArray [index + 1]) < parseInt (traceArray [index + 5]))) offStepDownRightMarkerIndex = offStepDownRightMarkerIndex + 1; } else { if ((parseInt (traceArray [index + 0]) > parseInt (traceArray [index + 4])) && (parseInt (traceArray [index + 1]) > parseInt (traceArray [index + 5]))) marker = this . onStepUpLeftMarkers; if ((parseInt (traceArray [index + 0]) > parseInt (traceArray [index + 4])) && (parseInt (traceArray [index + 1]) < parseInt (traceArray [index + 5]))) marker = this . onStepUpRightMarkers; // alert ("up right: " + trace + " : " + traceArray [rowIndex + 0] + ", " + traceArray [columnIndex + 0] + ", " + traceArray [rowIndex + 4] + ", " + traceArray [columnIndex + 4]);} if ((parseInt (traceArray [index + 0]) < parseInt (traceArray [index + 4])) && (parseInt (traceArray [index + 1]) > parseInt (traceArray [index + 5]))) marker = this . onStepDownLeftMarkers; // alert ("down left: " + trace + " : " + traceArray [rowIndex + 0] + ", " + traceArray [columnIndex + 0] + ", " + traceArray [rowIndex + 4] + ", " + traceArray [columnIndex + 4]);} if ((parseInt (traceArray [index + 0]) < parseInt (traceArray [index + 4])) && (parseInt (traceArray [index + 1]) < parseInt (traceArray [index + 5]))) marker = this . onStepDownRightMarkers; if ((parseInt (traceArray [index + 0]) > parseInt (traceArray [index + 4])) && (parseInt (traceArray [index + 1]) > parseInt (traceArray [index + 5]))) markerIndex = onStepUpLeftMarkerIndex; if ((parseInt (traceArray [index + 0]) > parseInt (traceArray [index + 4])) && (parseInt (traceArray [index + 1]) < parseInt (traceArray [index + 5]))) markerIndex = onStepUpRightMarkerIndex; if ((parseInt (traceArray [index + 0]) < parseInt (traceArray [index + 4])) && (parseInt (traceArray [index + 1]) > parseInt (traceArray [index + 5]))) markerIndex = onStepDownLeftMarkerIndex; if ((parseInt (traceArray [index + 0]) < parseInt (traceArray [index + 4])) && (parseInt (traceArray [index + 1]) < parseInt (traceArray [index + 5]))) markerIndex = onStepDownRightMarkerIndex; marker [markerIndex] . style . display = "block"; marker [markerIndex] . style . top = (rowIndex * (this . squareHeight + this . borderThickness)) + "px"; marker [markerIndex] . style . left = (columnIndex * (this . squareHeight + this . borderThickness)) + "px"; if ((parseInt (traceArray [index + 0]) > parseInt (traceArray [index + 4])) && (parseInt (traceArray [index + 1]) > parseInt (traceArray [index + 5]))) onStepUpLeftMarkerIndex = onStepUpLeftMarkerIndex + 1; if ((parseInt (traceArray [index + 0]) > parseInt (traceArray [index + 4])) && (parseInt (traceArray [index + 1]) < parseInt (traceArray [index + 5]))) onStepUpRightMarkerIndex = onStepUpRightMarkerIndex + 1; if ((parseInt (traceArray [index + 0]) < parseInt (traceArray [index + 4])) && (parseInt (traceArray [index + 1]) > parseInt (traceArray [index + 5]))) onStepDownLeftMarkerIndex = onStepDownLeftMarkerIndex + 1; if ((parseInt (traceArray [index + 0]) < parseInt (traceArray [index + 4])) && (parseInt (traceArray [index + 1]) < parseInt (traceArray [index + 5]))) onStepDownRightMarkerIndex = onStepDownRightMarkerIndex + 1; } } } // MARK THE ENDING rowIndex = parseInt (traceArray [traceArray . length - 2]); columnIndex = parseInt (traceArray [traceArray . length - 1]); if ((rowIndex % 2) == (columnIndex % 2)) { this . offStopMarker . style . display = "block"; this . offStopMarker . style . top = (rowIndex * (this . squareHeight + this . borderThickness)) + "px"; this . offStopMarker . style . left = (columnIndex * (this . squareHeight + this . borderThickness)) + "px"; } else { this . onStopMarker . style . display = "block"; this . onStopMarker . style . top = (rowIndex * (this . squareHeight + this . borderThickness)) + "px"; this . onStopMarker . style . left = (columnIndex * (this . squareHeight + this . borderThickness)) + "px"; } } this . showJumpMarkers = function (trace) { if (trace != null) { var traceArray = trace . split (","); var rowIndex; var columnIndex; var markerIndex; var onDotMarkerIndex = 0; var offDotMarkerIndex = 0; // MARK EACH CAPTURE for (var index = 0; index < (traceArray . length - 0); index = index + 2) { rowIndex = parseInt (traceArray [index + 0]); columnIndex = parseInt (traceArray [index + 1]); if (traceArray [index + 0] . indexOf ("x") != - 1) { if ((rowIndex % 2) == (columnIndex % 2)) { this . offDotMarkers [offDotMarkerIndex] . style . display = "block"; this . offDotMarkers [offDotMarkerIndex] . style . top = (rowIndex * (this . squareHeight + this . borderThickness)) + "px"; this . offDotMarkers [offDotMarkerIndex] . style . left = (columnIndex * (this . squareHeight + this . borderThickness)) + "px"; offDotMarkerIndex = offDotMarkerIndex + 1; } else { this . onDotMarkers [onDotMarkerIndex] . style . display = "block"; this . onDotMarkers [onDotMarkerIndex] . style . top = (rowIndex * (this . squareHeight + this . borderThickness)) + "px"; this . onDotMarkers [onDotMarkerIndex] . style . left = (columnIndex * (this . squareHeight + this . borderThickness)) + "px"; onDotMarkerIndex = onDotMarkerIndex + 1; } } } } } this . hideMarkers = function () { for (var index = 0; index < 30; index = index + 1) { this . offStepUpLeftMarkers [index] . style . display = "none"; this . offStepUpRightMarkers [index] . style . display = "none"; this . offStepDownLeftMarkers [index] . style . display = "none"; this . offStepDownRightMarkers [index] . style . display = "none"; this . offCaptureMarkers [index] . style . display = "none"; this . offDotMarkers [index] . style . display = "none"; this . onStepUpLeftMarkers [index] . style . display = "none"; this . onStepUpRightMarkers [index] . style . display = "none"; this . onStepDownLeftMarkers [index] . style . display = "none"; this . onStepDownRightMarkers [index] . style . display = "none"; this . onCaptureMarkers [index] . style . display = "none"; this . onDotMarkers [index] . style . display = "none"; } this . offStartUpLeftMarker . style . display = "none"; this . offStartUpRightMarker . style . display = "none"; this . offStartDownLeftMarker . style . display = "none"; this . offStartDownRightMarker . style . display = "none"; this . offStopMarker . style . display = "none"; this . onStartUpLeftMarker . style . display = "none"; this . onStartUpRightMarker . style . display = "none"; this . onStartDownLeftMarker . style . display = "none"; this . onStartDownRightMarker . style . display = "none"; this . onStopMarker . style . display = "none"; } this . reverse = function () { for (var rowIndex = 0; rowIndex < (this . rowCount / 2); rowIndex = rowIndex + 1) for (var columnIndex = 0; columnIndex < this . columnCount; columnIndex = columnIndex + 1) { var checkerPiece0 = this . boardState [rowIndex] [columnIndex]; var checkerPiece1 = this . boardState [this . rowCount - 1 - rowIndex] [this . columnCount - 1 - columnIndex]; if (checkerPiece0) checkerPiece0 . reverse (); if (checkerPiece1) checkerPiece1 . reverse (); this . boardState [rowIndex] [columnIndex] = checkerPiece1; this . boardState [this . rowCount - 1 - rowIndex] [this . columnCount - 1 - columnIndex] = checkerPiece0; } } this . connectEventCues = function () { this . glassDivision . onmousedown = this . cursorDown; // this . glassDivision . onmouseup = this . cursorUp; } this . disconnectEventCues = function () { this . glassDivision . onmousedown = null; this . glassDivision . onmousemove = null; this . glassDivision . onmouseup = null; } this . cursorDown = function (cursorEvent) { var squareRowIndex = Math . floor (documentObjectModel . getLayerY (cursorEvent) / 51); var squareColumnIndex = Math . floor (documentObjectModel . getLayerX (cursorEvent) / 51); if (squareRowIndex < 0) return; if (squareRowIndex >= this . that . rowCount) return; if (squareColumnIndex < 0) return; if (squareColumnIndex >= this . that . columnCount) return; var targetedCheckerPiece = this . that . boardState [squareRowIndex] [squareColumnIndex]; if (targetedCheckerPiece != null) if (targetedCheckerPiece . getOwnPredicate () == 1) if ((this . that . selectedCheckerPiece == null) || (this . that . selectedCheckerPiece == targetedCheckerPiece)) { this . that . selectedCheckerPiece = targetedCheckerPiece; this . that . selectedCheckerPiece . setCoordinates (documentObjectModel . getLayerY (cursorEvent) - Math . floor (this . that . selectedCheckerPiece . getHeight () / 2), documentObjectModel . getLayerX (cursorEvent) - Math . floor (this . that . selectedCheckerPiece . getWidth () / 2)); this . that . selectedCheckerPiece . elevate (); this . that . selectedCheckerPiece . fromRowIndex = squareRowIndex; this . that . selectedCheckerPiece . fromColumnIndex = squareColumnIndex; this . onmousemove = this . that . cursorMove; this . onmouseup = this . that . cursorUp; } cursorEvent . stopPropagation (); cursorEvent . preventDefault (); return; }; this . cursorMove = function (cursorEvent) { if (this . that . selectedCheckerPiece) { this . that . selectedCheckerPiece . setCoordinates (documentObjectModel . getLayerY (cursorEvent) - Math . floor (this . that . selectedCheckerPiece . getHeight () / 2), documentObjectModel . getLayerX (cursorEvent) - Math . floor (this . that . selectedCheckerPiece . getWidth () / 2)); } cursorEvent . stopPropagation (); cursorEvent . preventDefault (); return; }; this . cursorUp = function (cursorEvent) { this . onmousemove = null; if (this . that . selectedCheckerPiece) { var toRowIndex = Math . floor (documentObjectModel . getLayerY (cursorEvent) / 51); var toColumnIndex = Math . floor (documentObjectModel . getLayerX (cursorEvent) / 51); var fromRowIndex = this . that . selectedCheckerPiece ? this . that . selectedCheckerPiece . fromRowIndex : 0; var fromColumnIndex = this . that . selectedCheckerPiece ? this . that . selectedCheckerPiece . fromColumnIndex : 0; if (toRowIndex < 0) {this . that . update (); return;} if (toRowIndex >= this . that . rowCount) {this . that . update (); return;} if (toColumnIndex < 0) {this . that . update (); return;} if (toColumnIndex >= this . that . columnCount) {this . that . update (); return;} var targetedCheckerPiece = this . that . boardState [toRowIndex] [toColumnIndex]; if (checkers . midjumpPredicate == 1) if (this . that . selectedCheckerPiece != this . that . jumpingCheckerPiece) { this . that . selectedCheckerPiece = null; this . that . that . checkerPanel . setMessage ("high", "You must continue with the same piece until your turn is over."); this . that . update (); return; } if (this . that . selectedCheckerPiece) if (targetedCheckerPiece == null) { if (this . that . that . rules . getLegalMovePredicate ((checkers . ownMove ? checkers . ownMove : fromRowIndex + "," + fromColumnIndex) + "," + toRowIndex + "," + toColumnIndex)) { this . that . jumpingCheckerPiece = this . that . selectedCheckerPiece; this . that . selectedCheckerPiece = null; this . that . that . checkerPanel . setMessage ("medium", "Your turn."); this . that . that . setMove (fromRowIndex, fromColumnIndex, toRowIndex, toColumnIndex); } else if (this . that . that . rules . getIllegalMovePredicate ((checkers . ownMove ? checkers . ownMove : fromRowIndex + "," + fromColumnIndex) + "," + toRowIndex + "," + toColumnIndex)) { if (checkers . midjumpPredicate == 0) this . that . selectedCheckerPiece = null; this . that . that . checkerPanel . setMessage ("high", "You must take the jump with the most captures."); } else { this . that . selectedCheckerPiece = null; this . that . that . checkerPanel . setMessage ("high", "That move is not allowed."); } } } this . that . update (); cursorEvent . stopPropagation (); cursorEvent . preventDefault (); return; }; } // MICHAEL MCELROY, MICHAELMCELROY.NET // COPYRIGHT, 2006, ALL RIGHTS RESERVED Kayla = function () { this . initialize = function () { checkers . getMove_Override = checkers . getMove; checkers . getMove = this . play; return; }; this . play = function (event) { checkers . opponentMove = kayla . getPreferredMove (); // Remember: Kayla is the opponent. checkers . getMove_Override (); return (false); }; this . getPreferredMove = function () { var preferredMove = null; var moves = null; moves = checkers . rules . legalMoves; jumps = checkers . rules . legalJumps; if (moves . length > 0) { preferredMove = checkers . rules . legalMoves [Math . floor (Math . random () * checkers . rules . legalMoves . length)]; } else { preferredMove = checkers . rules . legalJumps [Math . floor (Math . random () * checkers . rules . legalJumps . length)]; } return (preferredMove); }; }; function Node () { } function Rules () { // STATE this . boardState = null; this . rowCount = 0; this . columnCount = 0; this . initiate = function () { this . boardState = new Array (); this . rowCount = 8; this . columnCount = 8; } this . initialize = function () { for (var rowIndex = 0; rowIndex < this . rowCount; rowIndex = rowIndex + 1) for (var columnIndex = 0; columnIndex < this . columnCount; columnIndex = columnIndex + 1) { if (! this . boardState [rowIndex]) { this . boardState [rowIndex] = new Array (); } this . boardState [rowIndex] [columnIndex] = null; if ((rowIndex < 3) && ((rowIndex % 2) != (columnIndex % 2))) { var checkerPiece = null; checkerPiece = new CheckerPiece (); checkerPiece . initiate (); checkerPiece . initialize (); checkerPiece . setCoordinates (rowIndex * checkerPiece . getHeight () + rowIndex, columnIndex * checkerPiece . getWidth () + columnIndex); checkerPiece . setOwnPredicate (0); this . boardState [rowIndex] [columnIndex] = checkerPiece; } if ((rowIndex > 4) && ((rowIndex % 2) != (columnIndex % 2))) { var checkerPiece = null; checkerPiece = new CheckerPiece (); checkerPiece . initiate (); checkerPiece . initialize (); checkerPiece . setCoordinates (rowIndex * checkerPiece . getHeight () + rowIndex, columnIndex * checkerPiece . getWidth () + columnIndex); checkerPiece . setOwnPredicate (1); this . boardState [rowIndex] [columnIndex] = checkerPiece; } } } this . getBoardState = function () { return (this . boardState); } this . getRowCount = function () { return (this . rowCount); } this . getColumnCount = function () { return (this . columnCount); } } function AmericanRules () { // STATE this . boardState = null; this . rowCount = 0; this . columnCount = 0; this . illegalMoves = null; this . illegalJumps = null; this . legalMoves = null; this . legalJumps = null; this . initiate = function () { this . boardState = new Array (); this . rowCount = 8; this . columnCount = 8; } this . initialize = function () { for (var rowIndex = 0; rowIndex < this . rowCount; rowIndex = rowIndex + 1) for (var columnIndex = 0; columnIndex < this . columnCount; columnIndex = columnIndex + 1) { if (! this . boardState [rowIndex]) { this . boardState [rowIndex] = new Array (); } this . boardState [rowIndex] [columnIndex] = null; if ((rowIndex < 3) && ((rowIndex % 2) != (columnIndex % 2))) { var checkerPiece = null; checkerPiece = new CheckerPiece (); checkerPiece . initiate (); checkerPiece . initialize (); checkerPiece . setCoordinates (rowIndex * checkerPiece . getHeight () + rowIndex, columnIndex * checkerPiece . getWidth () + columnIndex); checkerPiece . setOwnPredicate (0); this . boardState [rowIndex] [columnIndex] = checkerPiece; } if ((rowIndex > 4) && ((rowIndex % 2) != (columnIndex % 2))) { var checkerPiece = null; checkerPiece = new CheckerPiece (); checkerPiece . initiate (); checkerPiece . initialize (); checkerPiece . setCoordinates (rowIndex * checkerPiece . getHeight () + rowIndex, columnIndex * checkerPiece . getWidth () + columnIndex); checkerPiece . setOwnPredicate (1); this . boardState [rowIndex] [columnIndex] = checkerPiece; } } } this . getBoardState = function () { return (this . boardState); } this . getRowCount = function () { return (this . rowCount); } this . getColumnCount = function () { return (this . columnCount); } this . getTranslatedMove = function (move) { var moveArray = move . split (","); move = this . rowCount - 1 - moveArray [0]; for (var index = 1; index < moveArray . length; index = index + 1) move = move + "," + ((index % 2 ? this . columnCount - 1 : this . rowCount - 1) - moveArray [index]); return (move); } this . evaluate = function (player) { var matchCode = (player == "own") ? 1 : 0; // FIND THE VALID REGULAR-MOVES. this . illegalMoves = new Array (); this . legalMoves = new Array (); for (var rowIndex = 0; rowIndex < this . rowCount; rowIndex = rowIndex + 1) for (var columnIndex = 0; columnIndex < this . columnCount; columnIndex = columnIndex + 1) if (this . boardState [rowIndex] [columnIndex]) if (this . boardState [rowIndex] [columnIndex] . getOwnPredicate () == matchCode) { var node = new Node (); node . ownerNode = null; node . upperLeftNode = null; node . upperRightNode = null; node . lowerLeftNode = null; node . lowerRightNode = null; node . rowIndex = rowIndex; node . columnIndex = columnIndex; node . originalRowIndex = rowIndex; node . originalColumnIndex = columnIndex; node . capturePath = ""; node . move = rowIndex + "," + columnIndex; this . scanMoves (player, node); } // FIND THE VALID JUMP-MOVES. this . illegalJumps = new Array (); this . legalJumps = new Array (); for (var rowIndex = 0; rowIndex < this . rowCount; rowIndex = rowIndex + 1) for (var columnIndex = 0; columnIndex < this . columnCount; columnIndex = columnIndex + 1) if (this . boardState [rowIndex] [columnIndex]) if (this . boardState [rowIndex] [columnIndex] . getOwnPredicate () == matchCode) { var node = new Node (); node . ownerNode = null; node . upperLeftNode = null; node . upperRightNode = null; node . lowerLeftNode = null; node . lowerRightNode = null; node . rowIndex = rowIndex; node . columnIndex = columnIndex; node . originalRowIndex = rowIndex; node . originalColumnIndex = columnIndex; node . capturePath = ""; node . move = rowIndex + "," + columnIndex; this . scanJumps (player, node); } // IF THERE ARE ANY VALID JUMP-MOVES, THEN ERASE THE REGULAR-MOVES. if (this . legalJumps . length > 0) { this . illegalMoves = this . legalMoves; this . legalMoves = new Array (); } // RECORD THE VALID MOVES/JUMPS IN THE MESSAGE BOX UNDER 'NOTES'. if (player == "own") if (this . legalMoves . length > 0) { var list = ""; for (var index = 0; index < this . legalMoves . length; index = index + 1) list = list + this . legalMoves [index] + "\n"; messageBox . addMessage ("Notes", "Available Moves\n\n" + list); } if (player == "own") if (this . legalJumps . length > 0) { var list = ""; for (var index = 0; index < this . legalJumps . length; index = index + 1) list = list + this . legalJumps [index] + "\n"; messageBox . addMessage ("Notes", "Available Jumps\n\n" + list); } } this . getMoveCount = function () { return (this . legalMoves . length + this . legalJumps . length); } this . scanMoves = function (player, node) { var matchCode = (player == "own") ? 1 : 0; var fromRowIndex; var fromColumnIndex; var toRowIndex; var toColumnIndex; fromRowIndex = node . rowIndex; fromColumnIndex = node . columnIndex; // SCAN UPPER-LEFT if (player == "own") { toRowIndex = fromRowIndex - 1; toColumnIndex = fromColumnIndex - 1; } else { toRowIndex = fromRowIndex + 1; toColumnIndex = fromColumnIndex + 1; } if (toRowIndex >= 0) if (toRowIndex < this . rowCount) if (toColumnIndex >= 0) if (toColumnIndex < this . columnCount) if (this . boardState [toRowIndex] [toColumnIndex] == null) this . legalMoves . push (fromRowIndex + "," + fromColumnIndex + "," + toRowIndex + "," + toColumnIndex); // SCAN UPPER-RIGHT if (player == "own") { toRowIndex = fromRowIndex - 1; toColumnIndex = fromColumnIndex + 1; } else { toRowIndex = fromRowIndex + 1; toColumnIndex = fromColumnIndex - 1; } if (toRowIndex >= 0) if (toRowIndex < this . rowCount) if (toColumnIndex >= 0) if (toColumnIndex < this . columnCount) if (this . boardState [toRowIndex] [toColumnIndex] == null) this . legalMoves . push (fromRowIndex + "," + fromColumnIndex + "," + toRowIndex + "," + toColumnIndex); // SCAN LOWER-LEFT IF KING if (player == "own") { toRowIndex = fromRowIndex + 1; toColumnIndex = fromColumnIndex - 1; } else { toRowIndex = fromRowIndex - 1; toColumnIndex = fromColumnIndex + 1; } if (toRowIndex >= 0) if (toRowIndex < this . rowCount) if (toColumnIndex >= 0) if (toColumnIndex < this . columnCount) if (this . boardState [toRowIndex] [toColumnIndex] == null) if (this . boardState [fromRowIndex] [fromColumnIndex] . getKingPredicate () == 1) this . legalMoves . push (fromRowIndex + "," + fromColumnIndex + "," + toRowIndex + "," + toColumnIndex); // SCAN LOWER-RIGHT IF KING if (player == "own") { toRowIndex = fromRowIndex + 1; toColumnIndex = fromColumnIndex + 1; } else { toRowIndex = fromRowIndex - 1; toColumnIndex = fromColumnIndex - 1; } if (toRowIndex >= 0) if (toRowIndex < this . rowCount) if (toColumnIndex >= 0) if (toColumnIndex < this . columnCount) if (this . boardState [toRowIndex] [toColumnIndex] == null) if (this . boardState [fromRowIndex] [fromColumnIndex] . getKingPredicate () == 1) this . legalMoves . push (fromRowIndex + "," + fromColumnIndex + "," + toRowIndex + "," + toColumnIndex); } this . scanJumps = function (player, node) { var matchCode = (player == "own") ? 1 : 0; var fromRowIndex; var fromColumnIndex; var toRowIndex; var toColumnIndex; fromRowIndex = node . rowIndex; fromColumnIndex = node . columnIndex; // SCAN UPPER-LEFT if (player == "own") { toRowIndex = fromRowIndex - 2; toColumnIndex = fromColumnIndex - 2; captureRowIndex = fromRowIndex - 1; captureColumnIndex = fromColumnIndex - 1; } else { toRowIndex = fromRowIndex + 2; toColumnIndex = fromColumnIndex + 2; captureRowIndex = fromRowIndex + 1; captureColumnIndex = fromColumnIndex + 1; } if (toRowIndex >= 0) if (toRowIndex < this . rowCount) if (toColumnIndex >= 0) if (toColumnIndex < this . columnCount) if (this . boardState [toRowIndex] [toColumnIndex] == null) if (this . boardState [captureRowIndex] [captureColumnIndex] != null) if (this . boardState [captureRowIndex] [captureColumnIndex] . getOwnPredicate () != matchCode) if (node . capturePath . indexOf ("[" + captureRowIndex + "," + captureColumnIndex + "]") == - 1) { // SEARCH FOR SUCCESSIVE JUMPS node . upperLeftNode = new Node (); node . upperLeftNode . ownerNode = node; node . upperLeftNode . upperLeftNode = null; node . upperLeftNode . upperRightNode = null; node . upperLeftNode . lowerLeftNode = null; node . upperLeftNode . lowerRightNode = null; node . upperLeftNode . rowIndex = toRowIndex; node . upperLeftNode . columnIndex = toColumnIndex; node . upperLeftNode . originalRowIndex = node . originalRowIndex; node . upperLeftNode . originalColumnIndex = node . originalColumnIndex; node . upperLeftNode . capturePath = node . capturePath + "[" + captureRowIndex + "," + captureColumnIndex + "]"; node . upperLeftNode . move = node . move + "," + toRowIndex + "," + toColumnIndex; this . scanJumps (player, node . upperLeftNode); } // SCAN UPPER-RIGHT if (player == "own") { toRowIndex = fromRowIndex - 2; toColumnIndex = fromColumnIndex + 2; captureRowIndex = fromRowIndex - 1; captureColumnIndex = fromColumnIndex + 1; } else { toRowIndex = fromRowIndex + 2; toColumnIndex = fromColumnIndex - 2; captureRowIndex = fromRowIndex + 1; captureColumnIndex = fromColumnIndex - 1; } if (toRowIndex >= 0) if (toRowIndex < this . rowCount) if (toColumnIndex >= 0) if (toColumnIndex < this . columnCount) if (this . boardState [toRowIndex] [toColumnIndex] == null) if (this . boardState [captureRowIndex] [captureColumnIndex] != null) if (this . boardState [captureRowIndex] [captureColumnIndex] . getOwnPredicate () != matchCode) if (node . capturePath . indexOf ("[" + captureRowIndex + "," + captureColumnIndex + "]") == - 1) { // SEARCH FOR SUCCESSIVE JUMPS node . upperRightNode = new Node (); node . upperRightNode . ownerNode = node; node . upperRightNode . upperLeftNode = null; node . upperRightNode . upperRightNode = null; node . upperRightNode . lowerLeftNode = null; node . upperRightNode . lowerRightNode = null; node . upperRightNode . rowIndex = toRowIndex; node . upperRightNode . columnIndex = toColumnIndex; node . upperRightNode . originalRowIndex = node . originalRowIndex; node . upperRightNode . originalColumnIndex = node . originalColumnIndex; node . upperRightNode . capturePath = node . capturePath + "[" + captureRowIndex + "," + captureColumnIndex + "]"; node . upperRightNode . move = node . move + "," + toRowIndex + "," + toColumnIndex; this . scanJumps (player, node . upperRightNode); } // SCAN LOWER-LEFT IF KING if (player == "own") { toRowIndex = fromRowIndex + 2; toColumnIndex = fromColumnIndex - 2; captureRowIndex = fromRowIndex + 1; captureColumnIndex = fromColumnIndex - 1; } else { toRowIndex = fromRowIndex - 2; toColumnIndex = fromColumnIndex + 2; captureRowIndex = fromRowIndex - 1; captureColumnIndex = fromColumnIndex + 1; } if (toRowIndex >= 0) if (toRowIndex < this . rowCount) if (toColumnIndex >= 0) if (toColumnIndex < this . columnCount) if (this . boardState [toRowIndex] [toColumnIndex] == null) if (this . boardState [captureRowIndex] [captureColumnIndex] != null) if (this . boardState [captureRowIndex] [captureColumnIndex] . getOwnPredicate () != matchCode) if (this . boardState [node . originalRowIndex] [node . originalColumnIndex]) if (this . boardState [node . originalRowIndex] [node . originalColumnIndex] . getKingPredicate () == 1) if (node . capturePath . indexOf ("[" + captureRowIndex + "," + captureColumnIndex + "]") == - 1) { // SEARCH FOR SUCCESSIVE JUMPS node . lowerLeftNode = new Node (); node . lowerLeftNode . ownerNode = node; node . lowerLeftNode . upperLeftNode = null; node . lowerLeftNode . upperRightNode = null; node . lowerLeftNode . lowerLeftNode = null; node . lowerLeftNode . lowerRightNode = null; node . lowerLeftNode . rowIndex = toRowIndex; node . lowerLeftNode . columnIndex = toColumnIndex; node . lowerLeftNode . originalRowIndex = node . originalRowIndex; node . lowerLeftNode . originalColumnIndex = node . originalColumnIndex; node . lowerLeftNode . capturePath = node . capturePath + "[" + captureRowIndex + "," + captureColumnIndex + "]"; node . lowerLeftNode . move = node . move + "," + toRowIndex + "," + toColumnIndex; this . scanJumps (player, node . lowerLeftNode); } // SCAN LOWER-RIGHT IF KING if (player == "own") { toRowIndex = fromRowIndex + 2; toColumnIndex = fromColumnIndex + 2; captureRowIndex = fromRowIndex + 1; captureColumnIndex = fromColumnIndex + 1; } else { toRowIndex = fromRowIndex - 2; toColumnIndex = fromColumnIndex - 2; captureRowIndex = fromRowIndex - 1; captureColumnIndex = fromColumnIndex - 1; } if (toRowIndex >= 0) if (toRowIndex < this . rowCount) if (toColumnIndex >= 0) if (toColumnIndex < this . columnCount) if (this . boardState [toRowIndex] [toColumnIndex] == null) if (this . boardState [captureRowIndex] [captureColumnIndex] != null) if (this . boardState [captureRowIndex] [captureColumnIndex] . getOwnPredicate () != matchCode) if (this . boardState [node . originalRowIndex] [node . originalColumnIndex]) if (this . boardState [node . originalRowIndex] [node . originalColumnIndex] . getKingPredicate () == 1) if (node . capturePath . indexOf ("[" + captureRowIndex + "," + captureColumnIndex + "]") == - 1) { // SEARCH FOR SUCCESSIVE JUMPS node . lowerRightNode = new Node (); node . lowerRightNode . ownerNode = node; node . lowerRightNode . upperLeftNode = null; node . lowerRightNode . upperRightNode = null; node . lowerRightNode . lowerLeftNode = null; node . lowerRightNode . lowerRightNode = null; node . lowerRightNode . rowIndex = toRowIndex; node . lowerRightNode . columnIndex = toColumnIndex; node . lowerRightNode . originalRowIndex = node . originalRowIndex; node . lowerRightNode . originalColumnIndex = node . originalColumnIndex; node . lowerRightNode . capturePath = node . capturePath + "[" + captureRowIndex + "," + captureColumnIndex + "]"; node . lowerRightNode . move = node . move + "," + toRowIndex + "," + toColumnIndex; this . scanJumps (player, node . lowerRightNode); } // IF NONE OF THE LEAD-NODES ARE USED, THEN RECORD THE MOVE. if (node . ownerNode != null) if (node . upperLeftNode == null) if (node . upperRightNode == null) if (node . lowerLeftNode == null) if (node . lowerRightNode == null) this . legalJumps . push (node . move); } this . getIllegalMovePredicate = function (move) { for (var index = 0; index < this . illegalMoves . length; index = index + 1) if (this . illegalMoves [index] . indexOf (move) == 0) return (1); for (var index = 0; index < this . illegalJumps . length; index = index + 1) if (this . illegalJumps [index] . indexOf (move) == 0) return (1); return (0); } this . getLegalMovePredicate = function (move) { for (var index = 0; index < this . legalMoves . length; index = index + 1) if (this . legalMoves [index] . indexOf (move) == 0) return (1); for (var index = 0; index < this . legalJumps . length; index = index + 1) if (this . legalJumps [index] . indexOf (move) == 0) return (1); return (0); } this . getTerminalMovePredicate = function (move) { if (this . getMoveCount () == 0) return (1); for (var index = 0; index < this . legalMoves . length; index = index + 1) if (this . legalMoves [index] == move) return (1); for (var index = 0; index < this . legalJumps . length; index = index + 1) if (this . legalJumps [index] == move) return (1); return (0); } } function BrazilianRules () { // STATE this . boardState = null; this . rowCount = 0; this . columnCount = 0; this . illegalMoves = null; this . illegalJumps = null; this . legalMoves = null; this . legalJumps = null; this . initiate = function () { this . boardState = new Array (); this . rowCount = 8; this . columnCount = 8; } this . initialize = function () { for (var rowIndex = 0; rowIndex < this . rowCount; rowIndex = rowIndex + 1) for (var columnIndex = 0; columnIndex < this . columnCount; columnIndex = columnIndex + 1) { if (! this . boardState [rowIndex]) { this . boardState [rowIndex] = new Array (); } this . boardState [rowIndex] [columnIndex] = null; if ((rowIndex < 3) && ((rowIndex % 2) != (columnIndex % 2))) { var checkerPiece = null; checkerPiece = new CheckerPiece (); checkerPiece . initiate (); checkerPiece . initialize (); checkerPiece . setCoordinates (rowIndex * checkerPiece . getHeight () + rowIndex, columnIndex * checkerPiece . getWidth () + columnIndex); checkerPiece . setOwnPredicate (0); this . boardState [rowIndex] [columnIndex] = checkerPiece; } if ((rowIndex > 4) && ((rowIndex % 2) != (columnIndex % 2))) { var checkerPiece = null; checkerPiece = new CheckerPiece (); checkerPiece . initiate (); checkerPiece . initialize (); checkerPiece . setCoordinates (rowIndex * checkerPiece . getHeight () + rowIndex, columnIndex * checkerPiece . getWidth () + columnIndex); checkerPiece . setOwnPredicate (1); this . boardState [rowIndex] [columnIndex] = checkerPiece; } } } this . getBoardState = function () { return (this . boardState); } this . getRowCount = function () { return (this . rowCount); } this . getColumnCount = function () { return (this . columnCount); } this . getTranslatedMove = function (move) { var moveArray = move . split (","); move = this . rowCount - 1 - moveArray [0]; for (var index = 1; index < moveArray . length; index = index + 1) move = move + "," + ((index % 2 ? this . columnCount - 1 : this . rowCount - 1) - moveArray [index]); return (move); } this . evaluate = function (player) { var matchCode = (player == "own") ? 1 : 0; // FIND THE VALID REGULAR-MOVES. this . illegalMoves = new Array (); this . legalMoves = new Array (); for (var rowIndex = 0; rowIndex < this . rowCount; rowIndex = rowIndex + 1) for (var columnIndex = 0; columnIndex < this . columnCount; columnIndex = columnIndex + 1) if (this . boardState [rowIndex] [columnIndex]) if (this . boardState [rowIndex] [columnIndex] . getOwnPredicate () == matchCode) { var node = new Node (); node . ownerNode = null; node . upperLeftNode = null; node . upperRightNode = null; node . lowerLeftNode = null; node . lowerRightNode = null; node . rowIndex = rowIndex; node . columnIndex = columnIndex; node . originalRowIndex = rowIndex; node . originalColumnIndex = columnIndex; node . capturePath = ""; node . move = rowIndex + "," + columnIndex; this . scanMoves (player, node); } // FIND THE VALID JUMP-MOVES. this . illegalJumps = new Array (); this . legalJumps = new Array (); for (var rowIndex = 0; rowIndex < this . rowCount; rowIndex = rowIndex + 1) for (var columnIndex = 0; columnIndex < this . columnCount; columnIndex = columnIndex + 1) if (this . boardState [rowIndex] [columnIndex]) if (this . boardState [rowIndex] [columnIndex] . getOwnPredicate () == matchCode) { var node = new Node (); node . ownerNode = null; node . upperLeftNodes = null; node . upperRightNodes = null; node . lowerLeftNodes = null; node . lowerRightNodes = null; node . rowIndex = rowIndex; node . columnIndex = columnIndex; node . originalRowIndex = rowIndex; node . originalColumnIndex = columnIndex; node . capturePath = ""; node . move = rowIndex + "," + columnIndex; this . scanJumps (player, node); } // IF THERE ARE ANY VALID JUMP-MOVES, THEN ERASE THE REGULAR-MOVES. if (this . legalJumps . length > 0) { this . illegalMoves = this . legalMoves; this . legalMoves = new Array (); } // IN INTERNATIONAL CHECKERS (AND VARIANTS), ONLY THE LONGEST JUMPS MAY BE USED, SO FILTER OUT THE SHORT ONES. var index = 0; var longestJumpLength = 0; var jumps = this . legalJumps; this . legalJumps = new Array (); // FIND THE LENGTH OF THE LONGEST JUMP. for (index = 0; index < jumps . length; index = index + 1) { var jumpArray = jumps [index] . split (","); if (jumpArray . length > longestJumpLength) longestJumpLength = jumpArray . length; } // ACCEPT ONLY THE LONGEST JUMPS. for (index = 0; index < jumps . length; index = index + 1) { var jumpArray = jumps [index] . split (","); if (jumpArray . length == longestJumpLength) this . legalJumps . push (jumps [index]); } // RECORD THE VALID MOVES/JUMPS IN THE MESSAGE BOX UNDER 'NOTES'. if (player == "own") if (this . legalMoves . length > 0) { var list = ""; for (var index = 0; index < this . legalMoves . length; index = index + 1) list = list + this . legalMoves [index] + "\n"; messageBox . addMessage ("Notes", "Available Moves\n\n" + list); } if (player == "own") if (this . legalJumps . length > 0) { var list = ""; for (var index = 0; index < this . legalJumps . length; index = index + 1) list = list + this . legalJumps [index] + "\n"; messageBox . addMessage ("Notes", "Available Jumps\n\n" + list); } } this . getMoveCount = function () { return (this . legalMoves . length + this . legalJumps . length); } this . getCheckerPieceCount = function (player, capturePath, ignoreRowIndex, ignoreColumnIndex, fromRowIndex, fromColumnIndex, toRowIndex, toColumnIndex) { var matchCode = (player == "own") ? 1 : 0; var checkerPieceCount = 0; var rowStep = 0; var columnStep = 0; if (fromRowIndex < toRowIndex) rowStep = 1; if (fromRowIndex > toRowIndex) rowStep = - 1; if (fromColumnIndex < toColumnIndex) columnStep = 1; if (fromColumnIndex > toColumnIndex) columnStep = - 1; var rowIndex = fromRowIndex + rowStep; var columnIndex = fromColumnIndex + columnStep; var index = 0; var initialValue = 0; var rowLimit = fromRowIndex < toRowIndex ? toRowIndex - fromRowIndex - 1 : fromRowIndex - toRowIndex - 1; var columnLimit = fromColumnIndex < toColumnIndex ? toColumnIndex - fromColumnIndex - 1 : fromColumnIndex - toColumnIndex - 1; var limit = rowLimit > columnLimit ? rowLimit : columnLimit; for (index = initialValue; index < limit; index = index + 1) { var capturedPredicate; capturedPredicate = 0; if (capturePath != null) if (capturePath . indexOf ("[" + rowIndex + "," + columnIndex + "]") != - 1) capturedPredicate = 1; if (rowIndex >= 0) if (rowIndex <= 11) if (columnIndex >= 0) if (columnIndex <= 11) if (capturedPredicate == 0) if (! ((rowIndex == ignoreRowIndex) && (columnIndex == ignoreColumnIndex))) if (this . boardState [rowIndex] [columnIndex]) if (this . boardState [rowIndex] [columnIndex] . getOwnPredicate () == matchCode) checkerPieceCount = checkerPieceCount + 1; if (capturedPredicate == 1) checkerPieceCount = checkerPieceCount + 1; // added on 2009-06-28 to follow the rule of not jumping over pieces that were removed during this jump rowIndex = rowIndex + rowStep; columnIndex = columnIndex + columnStep; } return (checkerPieceCount); } this . getCheckerPieceRow = function (capturePath, ignoreRowIndex, ignoreColumnIndex, fromRowIndex, fromColumnIndex, toRowIndex, toColumnIndex) { var checkerPieceRow = null; var rowStep = 0; var columnStep = 0; if (fromRowIndex < toRowIndex) rowStep = 1; if (fromRowIndex > toRowIndex) rowStep = - 1; if (fromColumnIndex < toColumnIndex) columnStep = 1; if (fromColumnIndex > toColumnIndex) columnStep = - 1; var rowIndex = fromRowIndex + rowStep; var columnIndex = fromColumnIndex + columnStep; var index = 0; var initialValue = 0; var rowLimit = fromRowIndex < toRowIndex ? toRowIndex - fromRowIndex - 1 : fromRowIndex - toRowIndex - 1; var columnLimit = fromColumnIndex < toColumnIndex ? toColumnIndex - fromColumnIndex - 1 : fromColumnIndex - toColumnIndex - 1; var limit = rowLimit > columnLimit ? rowLimit : columnLimit; for (index = initialValue; index < limit; index = index + 1) { var capturedPredicate; capturedPredicate = 0; if (capturePath != null) if (capturePath . indexOf ("[" + rowIndex + "," + columnIndex + "]") != - 1) capturedPredicate = 1; if (rowIndex >= 0) if (rowIndex <= 11) if (columnIndex >= 0) if (columnIndex <= 11) if (capturedPredicate == 0) if (! ((rowIndex == ignoreRowIndex) && (columnIndex == ignoreColumnIndex))) if (this . boardState [rowIndex] [columnIndex]) checkerPieceRow = rowIndex; rowIndex = rowIndex + rowStep; columnIndex = columnIndex + columnStep; } return (checkerPieceRow); } this . getCheckerPieceColumn = function (capturePath, ignoreRowIndex, ignoreColumnIndex, fromRowIndex, fromColumnIndex, toRowIndex, toColumnIndex) { var checkerPieceColumn = null; var rowStep = 0; var columnStep = 0; if (fromRowIndex < toRowIndex) rowStep = 1; if (fromRowIndex > toRowIndex) rowStep = - 1; if (fromColumnIndex < toColumnIndex) columnStep = 1; if (fromColumnIndex > toColumnIndex) columnStep = - 1; var rowIndex = fromRowIndex + rowStep; var columnIndex = fromColumnIndex + columnStep; var index = 0; var initialValue = 0; var rowLimit = fromRowIndex < toRowIndex ? toRowIndex - fromRowIndex - 1 : fromRowIndex - toRowIndex - 1; var columnLimit = fromColumnIndex < toColumnIndex ? toColumnIndex - fromColumnIndex - 1 : fromColumnIndex - toColumnIndex - 1; var limit = rowLimit > columnLimit ? rowLimit : columnLimit; for (index = initialValue; index < limit; index = index + 1) { var capturedPredicate; capturedPredicate = 0; if (capturePath != null) if (capturePath . indexOf ("[" + rowIndex + "," + columnIndex + "]") != - 1) capturedPredicate = 1; if (rowIndex >= 0) if (rowIndex <= 11) if (columnIndex >= 0) if (columnIndex <= 11) if (capturedPredicate == 0) if (! ((rowIndex == ignoreRowIndex) && (columnIndex == ignoreColumnIndex))) if (this . boardState [rowIndex] [columnIndex]) checkerPieceColumn = columnIndex; rowIndex = rowIndex + rowStep; columnIndex = columnIndex + columnStep; } return (checkerPieceColumn); } this . scanMoves = function (player, node) { var matchCode = (player == "own") ? 1 : 0; var distanceLimit = this . rowCount > this . columnCount ? this . rowCount : this . columnCount; var distanceIndex; var fromRowIndex; var fromColumnIndex; var toRowIndex; var toColumnIndex; fromRowIndex = node . rowIndex; fromColumnIndex = node . columnIndex; // SCAN UPPER-LEFT for (distanceIndex = 0; distanceIndex < distanceLimit; distanceIndex = distanceIndex + 1) { if (player == "own") { toRowIndex = fromRowIndex - 1 - distanceIndex; toColumnIndex = fromColumnIndex - 1 - distanceIndex; } else { toRowIndex = fromRowIndex + 1 + distanceIndex; toColumnIndex = fromColumnIndex + 1 + distanceIndex; } if ((distanceIndex == 0) || (this . boardState [node . originalRowIndex] [node . originalColumnIndex] . getKingPredicate () == 1)) if (toRowIndex >= 0) if (toRowIndex < this . rowCount) if (toColumnIndex >= 0) if (toColumnIndex < this . columnCount) if (this . boardState [toRowIndex] [toColumnIndex] == null) if (this . getCheckerPieceCount ("own", "", node . originalRowIndex, node . originalColumnIndex, fromRowIndex, fromColumnIndex, toRowIndex, toColumnIndex) == 0) if (this . getCheckerPieceCount ("opponent", "", node . originalRowIndex, node . originalColumnIndex, fromRowIndex, fromColumnIndex, toRowIndex, toColumnIndex) == 0) this . legalMoves . push (fromRowIndex + "," + fromColumnIndex + "," + toRowIndex + "," + toColumnIndex); } // SCAN UPPER-RIGHT for (distanceIndex = 0; distanceIndex < distanceLimit; distanceIndex = distanceIndex + 1) { if (player == "own") { toRowIndex = fromRowIndex - 1 - distanceIndex; toColumnIndex = fromColumnIndex + 1 + distanceIndex; } else { toRowIndex = fromRowIndex + 1 + distanceIndex; toColumnIndex = fromColumnIndex - 1 - distanceIndex; } if ((distanceIndex == 0) || (this . boardState [node . originalRowIndex] [node . originalColumnIndex] . getKingPredicate () == 1)) if (toRowIndex >= 0) if (toRowIndex < this . rowCount) if (toColumnIndex >= 0) if (toColumnIndex < this . columnCount) if (this . boardState [toRowIndex] [toColumnIndex] == null) if (this . getCheckerPieceCount ("own", "", node . originalRowIndex, node . originalColumnIndex, fromRowIndex, fromColumnIndex, toRowIndex, toColumnIndex) == 0) if (this . getCheckerPieceCount ("opponent", "", node . originalRowIndex, node . originalColumnIndex, fromRowIndex, fromColumnIndex, toRowIndex, toColumnIndex) == 0) this . legalMoves . push (fromRowIndex + "," + fromColumnIndex + "," + toRowIndex + "," + toColumnIndex); } // SCAN LOWER-LEFT IF KING if (this . boardState [node . originalRowIndex] [node . originalColumnIndex] . getKingPredicate () == 1) for (distanceIndex = 0; distanceIndex < distanceLimit; distanceIndex = distanceIndex + 1) { if (player == "own") { toRowIndex = fromRowIndex + 1 + distanceIndex; toColumnIndex = fromColumnIndex - 1 - distanceIndex; } else { toRowIndex = fromRowIndex - 1 - distanceIndex; toColumnIndex = fromColumnIndex + 1 + distanceIndex; } if ((distanceIndex == 0) || (this . boardState [node . originalRowIndex] [node . originalColumnIndex] . getKingPredicate () == 1)) if (toRowIndex >= 0) if (toRowIndex < this . rowCount) if (toColumnIndex >= 0) if (toColumnIndex < this . columnCount) if (this . boardState [toRowIndex] [toColumnIndex] == null) if (this . boardState [fromRowIndex] [fromColumnIndex] . getKingPredicate () == 1) if (this . getCheckerPieceCount ("own", "", node . originalRowIndex, node . originalColumnIndex, fromRowIndex, fromColumnIndex, toRowIndex, toColumnIndex) == 0) if (this . getCheckerPieceCount ("opponent", "", node . originalRowIndex, node . originalColumnIndex, fromRowIndex, fromColumnIndex, toRowIndex, toColumnIndex) == 0) this . legalMoves . push (fromRowIndex + "," + fromColumnIndex + "," + toRowIndex + "," + toColumnIndex); } // SCAN LOWER-RIGHT IF KING if (this . boardState [node . originalRowIndex] [node . originalColumnIndex] . getKingPredicate () == 1) for (distanceIndex = 0; distanceIndex < distanceLimit; distanceIndex = distanceIndex + 1) { if (player == "own") { toRowIndex = fromRowIndex + 1 + distanceIndex; toColumnIndex = fromColumnIndex + 1 + distanceIndex; } else { toRowIndex = fromRowIndex - 1 - distanceIndex; toColumnIndex = fromColumnIndex - 1 - distanceIndex; } if ((distanceIndex == 0) || (this . boardState [node . originalRowIndex] [node . originalColumnIndex] . getKingPredicate () == 1)) if (toRowIndex >= 0) if (toRowIndex < this . rowCount) if (toColumnIndex >= 0) if (toColumnIndex < this . columnCount) if (this . boardState [toRowIndex] [toColumnIndex] == null) if (this . boardState [fromRowIndex] [fromColumnIndex] . getKingPredicate () == 1) if (this . getCheckerPieceCount ("own", "", node . originalRowIndex, node . originalColumnIndex, fromRowIndex, fromColumnIndex, toRowIndex, toColumnIndex) == 0) if (this . getCheckerPieceCount ("opponent", "", node . originalRowIndex, node . originalColumnIndex, fromRowIndex, fromColumnIndex, toRowIndex, toColumnIndex) == 0) this . legalMoves . push (fromRowIndex + "," + fromColumnIndex + "," + toRowIndex + "," + toColumnIndex); } } this . scanJumps = function (player, node) { var otherPlayer = (player == "own") ? "opponent" : "own"; var matchCode = (player == "own") ? 1 : 0; var distanceLimit = this . rowCount > this . columnCount ? this . rowCount : this . columnCount; var distanceIndex; var fromRowIndex; var fromColumnIndex; var toRowIndex; var toColumnIndex; fromRowIndex = node . rowIndex; fromColumnIndex = node . columnIndex; // SCAN UPPER-LEFT for (distanceIndex = 0; distanceIndex < distanceLimit; distanceIndex = distanceIndex + 1) { if (player == "own") { toRowIndex = fromRowIndex - 2 - distanceIndex; toColumnIndex = fromColumnIndex - 2 - distanceIndex; } else { toRowIndex = fromRowIndex + 2 + distanceIndex; toColumnIndex = fromColumnIndex + 2 + distanceIndex; } if ((distanceIndex == 0) || (this . boardState [node . originalRowIndex] [node . originalColumnIndex] . getKingPredicate () == 1)) if (toRowIndex >= 0) if (toRowIndex < this . rowCount) if (toColumnIndex >= 0) if (toColumnIndex < this . columnCount) if (this . boardState [toRowIndex] [toColumnIndex] == null) if (this . getCheckerPieceCount (player, node . capturePath, node . originalRowIndex, node . originalColumnIndex, fromRowIndex, fromColumnIndex, toRowIndex, toColumnIndex) == 0) if (this . getCheckerPieceCount (otherPlayer, node . capturePath, node . originalRowIndex, node . originalColumnIndex, fromRowIndex, fromColumnIndex, toRowIndex, toColumnIndex) == 1) if (node . capturePath . indexOf ("[" + this . getCheckerPieceRow (node . capturePath, node . originalRowIndex, node . originalColumnIndex, fromRowIndex, fromColumnIndex, toRowIndex, toColumnIndex) + "," + this . getCheckerPieceColumn (node . capturePath, node . originalRowIndex, node . originalColumnIndex, fromRowIndex, fromColumnIndex, toRowIndex, toColumnIndex) + "]") == - 1) { // SEARCH FOR SUCCESSIVE JUMPS if (! node . upperLeftNodes) node . upperLeftNodes = new Array (); node . upperLeftNodes [distanceIndex] = new Node (); node . upperLeftNodes [distanceIndex] . ownerNode = node; node . upperLeftNodes [distanceIndex] . upperLeftNodes = null; node . upperLeftNodes [distanceIndex] . upperRightNodes = null; node . upperLeftNodes [distanceIndex] . lowerLeftNodes = null; node . upperLeftNodes [distanceIndex] . lowerRightNodes = null; node . upperLeftNodes [distanceIndex] . rowIndex = toRowIndex; node . upperLeftNodes [distanceIndex] . columnIndex = toColumnIndex; node . upperLeftNodes [distanceIndex] . originalRowIndex = node . originalRowIndex; node . upperLeftNodes [distanceIndex] . originalColumnIndex = node . originalColumnIndex; node . upperLeftNodes [distanceIndex] . capturePath = node . capturePath + "[" + this . getCheckerPieceRow (node . capturePath, node . originalRowIndex, node . originalColumnIndex, fromRowIndex, fromColumnIndex, toRowIndex, toColumnIndex) + "," + this . getCheckerPieceColumn (node . capturePath, node . originalRowIndex, node . originalColumnIndex, fromRowIndex, fromColumnIndex, toRowIndex, toColumnIndex) + "]"; node . upperLeftNodes [distanceIndex] . move = node . move + "," + toRowIndex + "," + toColumnIndex; this . scanJumps (player, node . upperLeftNodes [distanceIndex]); } } // SCAN UPPER-RIGHT for (distanceIndex = 0; distanceIndex < distanceLimit; distanceIndex = distanceIndex + 1) { if (player == "own") { toRowIndex = fromRowIndex - 2 - distanceIndex; toColumnIndex = fromColumnIndex + 2 + distanceIndex; } else { toRowIndex = fromRowIndex + 2 + distanceIndex; toColumnIndex = fromColumnIndex - 2 - distanceIndex; } if ((distanceIndex == 0) || (this . boardState [node . originalRowIndex] [node . originalColumnIndex] . getKingPredicate () == 1)) if (toRowIndex >= 0) if (toRowIndex < this . rowCount) if (toColumnIndex >= 0) if (toColumnIndex < this . columnCount) if (this . boardState [toRowIndex] [toColumnIndex] == null) if (this . getCheckerPieceCount (player, node . capturePath, node . originalRowIndex, node . originalColumnIndex, fromRowIndex, fromColumnIndex, toRowIndex, toColumnIndex) == 0) if (this . getCheckerPieceCount (otherPlayer, node . capturePath, node . originalRowIndex, node . originalColumnIndex, fromRowIndex, fromColumnIndex, toRowIndex, toColumnIndex) == 1) if (node . capturePath . indexOf ("[" + this . getCheckerPieceRow (node . capturePath, node . originalRowIndex, node . originalColumnIndex, fromRowIndex, fromColumnIndex, toRowIndex, toColumnIndex) + "," + this . getCheckerPieceColumn (node . capturePath, node . originalRowIndex, node . originalColumnIndex, fromRowIndex, fromColumnIndex, toRowIndex, toColumnIndex) + "]") == - 1) { // SEARCH FOR SUCCESSIVE JUMPS if (! node . upperRightNodes) node . upperRightNodes = new Array (); node . upperRightNodes [distanceIndex] = new Node (); node . upperRightNodes [distanceIndex] . ownerNode = node; node . upperRightNodes [distanceIndex] . upperLeftNodes = null; node . upperRightNodes [distanceIndex] . upperRightNodes = null; node . upperRightNodes [distanceIndex] . lowerLeftNodes = null; node . upperRightNodes [distanceIndex] . lowerRightNodes = null; node . upperRightNodes [distanceIndex] . rowIndex = toRowIndex; node . upperRightNodes [distanceIndex] . columnIndex = toColumnIndex; node . upperRightNodes [distanceIndex] . originalRowIndex = node . originalRowIndex; node . upperRightNodes [distanceIndex] . originalColumnIndex = node . originalColumnIndex; node . upperRightNodes [distanceIndex] . capturePath = node . capturePath + "[" + this . getCheckerPieceRow (node . capturePath, node . originalRowIndex, node . originalColumnIndex, fromRowIndex, fromColumnIndex, toRowIndex, toColumnIndex) + "," + this . getCheckerPieceColumn (node . capturePath, node . originalRowIndex, node . originalColumnIndex, fromRowIndex, fromColumnIndex, toRowIndex, toColumnIndex) + "]"; node . upperRightNodes [distanceIndex] . move = node . move + "," + toRowIndex + "," + toColumnIndex; this . scanJumps (player, node . upperRightNodes [distanceIndex]); } } // SCAN LOWER-LEFT for (distanceIndex = 0; distanceIndex < distanceLimit; distanceIndex = distanceIndex + 1) { if (player == "own") { toRowIndex = fromRowIndex + 2 + distanceIndex; toColumnIndex = fromColumnIndex - 2 - distanceIndex; } else { toRowIndex = fromRowIndex - 2 - distanceIndex; toColumnIndex = fromColumnIndex + 2 + distanceIndex; } if ((distanceIndex == 0) || (this . boardState [node . originalRowIndex] [node . originalColumnIndex] . getKingPredicate () == 1)) if (toRowIndex >= 0) if (toRowIndex < this . rowCount) if (toColumnIndex >= 0) if (toColumnIndex < this . columnCount) if (this . boardState [toRowIndex] [toColumnIndex] == null) if (this . getCheckerPieceCount (player, node . capturePath, node . originalRowIndex, node . originalColumnIndex, fromRowIndex, fromColumnIndex, toRowIndex, toColumnIndex) == 0) if (this . getCheckerPieceCount (otherPlayer, node . capturePath, node . originalRowIndex, node . originalColumnIndex, fromRowIndex, fromColumnIndex, toRowIndex, toColumnIndex) == 1) if (node . capturePath . indexOf ("[" + this . getCheckerPieceRow (node . capturePath, node . originalRowIndex, node . originalColumnIndex, fromRowIndex, fromColumnIndex, toRowIndex, toColumnIndex) + "," + this . getCheckerPieceColumn (node . capturePath, node . originalRowIndex, node . originalColumnIndex, fromRowIndex, fromColumnIndex, toRowIndex, toColumnIndex) + "]") == - 1) { // SEARCH FOR SUCCESSIVE JUMPS if (! node . lowerLeftNodes) node . lowerLeftNodes = new Array (); node . lowerLeftNodes [distanceIndex] = new Node (); node . lowerLeftNodes [distanceIndex] . ownerNode = node; node . lowerLeftNodes [distanceIndex] . upperLeftNodes = null; node . lowerLeftNodes [distanceIndex] . upperRightNodes = null; node . lowerLeftNodes [distanceIndex] . lowerLeftNodes = null; node . lowerLeftNodes [distanceIndex] . lowerRightNodes = null; node . lowerLeftNodes [distanceIndex] . rowIndex = toRowIndex; node . lowerLeftNodes [distanceIndex] . columnIndex = toColumnIndex; node . lowerLeftNodes [distanceIndex] . originalRowIndex = node . originalRowIndex; node . lowerLeftNodes [distanceIndex] . originalColumnIndex = node . originalColumnIndex; node . lowerLeftNodes [distanceIndex] . capturePath = node . capturePath + "[" + this . getCheckerPieceRow (node . capturePath, node . originalRowIndex, node . originalColumnIndex, fromRowIndex, fromColumnIndex, toRowIndex, toColumnIndex) + "," + this . getCheckerPieceColumn (node . capturePath, node . originalRowIndex, node . originalColumnIndex, fromRowIndex, fromColumnIndex, toRowIndex, toColumnIndex) + "]"; node . lowerLeftNodes [distanceIndex] . move = node . move + "," + toRowIndex + "," + toColumnIndex; this . scanJumps (player, node . lowerLeftNodes [distanceIndex]); } } // SCAN LOWER-RIGHT for (distanceIndex = 0; distanceIndex < distanceLimit; distanceIndex = distanceIndex + 1) { if (player == "own") { toRowIndex = fromRowIndex + 2 + distanceIndex; toColumnIndex = fromColumnIndex + 2 + distanceIndex; } else { toRowIndex = fromRowIndex - 2 - distanceIndex; toColumnIndex = fromColumnIndex - 2 - distanceIndex; } if ((distanceIndex == 0) || (this . boardState [node . originalRowIndex] [node . originalColumnIndex] . getKingPredicate () == 1)) if (toRowIndex >= 0) if (toRowIndex < this . rowCount) if (toColumnIndex >= 0) if (toColumnIndex < this . columnCount) if (this . boardState [toRowIndex] [toColumnIndex] == null) if (this . getCheckerPieceCount (player, node . capturePath, node . originalRowIndex, node . originalColumnIndex, fromRowIndex, fromColumnIndex, toRowIndex, toColumnIndex) == 0) if (this . getCheckerPieceCount (otherPlayer, node . capturePath, node . originalRowIndex, node . originalColumnIndex, fromRowIndex, fromColumnIndex, toRowIndex, toColumnIndex) == 1) if (node . capturePath . indexOf ("[" + this . getCheckerPieceRow (node . capturePath, node . originalRowIndex, node . originalColumnIndex, fromRowIndex, fromColumnIndex, toRowIndex, toColumnIndex) + "," + this . getCheckerPieceColumn (node . capturePath, node . originalRowIndex, node . originalColumnIndex, fromRowIndex, fromColumnIndex, toRowIndex, toColumnIndex) + "]") == - 1) { // SEARCH FOR SUCCESSIVE JUMPS if (! node . lowerRightNodes) node . lowerRightNodes = new Array (); node . lowerRightNodes [distanceIndex] = new Node (); node . lowerRightNodes [distanceIndex] . ownerNode = node; node . lowerRightNodes [distanceIndex] . upperLeftNodes = null; node . lowerRightNodes [distanceIndex] . upperRightNodes = null; node . lowerRightNodes [distanceIndex] . lowerLeftNodes = null; node . lowerRightNodes [distanceIndex] . lowerRightNodes = null; node . lowerRightNodes [distanceIndex] . rowIndex = toRowIndex; node . lowerRightNodes [distanceIndex] . columnIndex = toColumnIndex; node . lowerRightNodes [distanceIndex] . originalRowIndex = node . originalRowIndex; node . lowerRightNodes [distanceIndex] . originalColumnIndex = node . originalColumnIndex; node . lowerRightNodes [distanceIndex] . capturePath = node . capturePath + "[" + this . getCheckerPieceRow (node . capturePath, node . originalRowIndex, node . originalColumnIndex, fromRowIndex, fromColumnIndex, toRowIndex, toColumnIndex) + "," + this . getCheckerPieceColumn (node . capturePath, node . originalRowIndex, node . originalColumnIndex, fromRowIndex, fromColumnIndex, toRowIndex, toColumnIndex) + "]"; node . lowerRightNodes [distanceIndex] . move = node . move + "," + toRowIndex + "," + toColumnIndex; this . scanJumps (player, node . lowerRightNodes [distanceIndex]); } } // IF NONE OF THE LEAD-NODES ARE USED, THEN RECORD THE MOVE. if (node . ownerNode != null) if (node . upperLeftNodes == null) if (node . upperRightNodes == null) if (node . lowerLeftNodes == null) if (node . lowerRightNodes == null) this . legalJumps . push (node . move); } this . getIllegalMovePredicate = function (move) { for (var index = 0; index < this . illegalMoves . length; index = index + 1) if (this . illegalMoves [index] . indexOf (move) == 0) return (1); for (var index = 0; index < this . illegalJumps . length; index = index + 1) if (this . illegalJumps [index] . indexOf (move) == 0) return (1); return (0); } this . getLegalMovePredicate = function (move) { for (var index = 0; index < this . legalMoves . length; index = index + 1) if (this . legalMoves [index] . indexOf (move) == 0) return (1); for (var index = 0; index < this . legalJumps . length; index = index + 1) if (this . legalJumps [index] . indexOf (move) == 0) return (1); return (0); } this . getTerminalMovePredicate = function (move) { if (this . getMoveCount () == 0) return (1); for (var index = 0; index < this . legalMoves . length; index = index + 1) if (this . legalMoves [index] == move) return (1); for (var index = 0; index < this . legalJumps . length; index = index + 1) if (this . legalJumps [index] == move) return (1); return (0); } } function CanadianRules () { // STATE this . boardState = null; this . rowCount = 0; this . columnCount = 0; this . illegalMoves = null; this . illegalJumps = null; this . legalMoves = null; this . legalJumps = null; this . initiate = function () { this . boardState = new Array (); this . rowCount = 12; this . columnCount = 12; } this . initialize = function () { var predefinedPredicate = 0; var predefinedState = new Array (); if (predefinedPredicate == 1) { // from the perspective of the primary player // 0 = blank // 1 = primary player's man // 2 = primary player's king // 3 = secondary player's man // 4 = secondary player's king predefinedState [ 0] = "000000000000"; predefinedState [ 1] = "000004000000"; predefinedState [ 2] = "000000000000"; predefinedState [ 3] = "000303000000"; predefinedState [ 4] = "002000000000"; predefinedState [ 5] = "000003000000"; predefinedState [ 6] = "003000000000"; predefinedState [ 7] = "000000000000"; predefinedState [ 8] = "000000000000"; predefinedState [ 9] = "000000000000"; predefinedState [10] = "000000000000"; predefinedState [11] = "000000000000"; } for (var rowIndex = 0; rowIndex < this . rowCount; rowIndex = rowIndex + 1) for (var columnIndex = 0; columnIndex < this . columnCount; columnIndex = columnIndex + 1) { if (! this . boardState [rowIndex]) { this . boardState [rowIndex] = new Array (); } this . boardState [rowIndex] [columnIndex] = null; if ((rowIndex < 5) && ((rowIndex % 2) != (columnIndex % 2))) { var checkerPiece = null; checkerPiece = new CheckerPiece (); checkerPiece . initiate (); checkerPiece . initialize (); checkerPiece . setCoordinates (rowIndex * checkerPiece . getHeight () + rowIndex, columnIndex * checkerPiece . getWidth () + columnIndex); checkerPiece . setOwnPredicate (0); this . boardState [rowIndex] [columnIndex] = checkerPiece; } if ((rowIndex > 6) && ((rowIndex % 2) != (columnIndex % 2))) { var checkerPiece = null; checkerPiece = new CheckerPiece (); checkerPiece . initiate (); checkerPiece . initialize (); checkerPiece . setCoordinates (rowIndex * checkerPiece . getHeight () + rowIndex, columnIndex * checkerPiece . getWidth () + columnIndex); checkerPiece . setOwnPredicate (1); this . boardState [rowIndex] [columnIndex] = checkerPiece; } if (predefinedPredicate == 1) { var checkerPiece = null; var predefinedValue = predefinedState [rowIndex] . charAt (columnIndex); if (predefinedState [rowIndex] . charAt (columnIndex) != 0) { checkerPiece = new CheckerPiece (); checkerPiece . initiate (); checkerPiece . initialize (); checkerPiece . setCoordinates (rowIndex * checkerPiece . getHeight (), columnIndex * checkerPiece . getWidth ()); checkerPiece . setOwnPredicate (((predefinedValue == 1) || (predefinedValue == 2)) ? 1 : 0); checkerPiece . setKingPredicate (((predefinedValue == 2) || (predefinedValue == 4)) ? 1 : 0); this . boardState [rowIndex] [columnIndex] = checkerPiece; } else { this . boardState [rowIndex] [columnIndex] = null; } } } } this . getBoardState = function () { return (this . boardState); } this . getRowCount = function () { return (this . rowCount); } this . getColumnCount = function () { return (this . columnCount); } this . getTranslatedMove = function (move) { var moveArray = move . split (","); move = this . rowCount - 1 - moveArray [0]; for (var index = 1; index < moveArray . length; index = index + 1) move = move + "," + ((index % 2 ? this . columnCount - 1 : this . rowCount - 1) - moveArray [index]); return (move); } this . evaluate = function (player) { var matchCode = (player == "own") ? 1 : 0; // FIND THE VALID REGULAR-MOVES. this . illegalMoves = new Array (); this . legalMoves = new Array (); for (var rowIndex = 0; rowIndex < this . rowCount; rowIndex = rowIndex + 1) for (var columnIndex = 0; columnIndex < this . columnCount; columnIndex = columnIndex + 1) if (this . boardState [rowIndex] [columnIndex]) if (this . boardState [rowIndex] [columnIndex] . getOwnPredicate () == matchCode) { var node = new Node (); node . ownerNode = null; node . upperLeftNode = null; node . upperRightNode = null; node . lowerLeftNode = null; node . lowerRightNode = null; node . rowIndex = rowIndex; node . columnIndex = columnIndex; node . originalRowIndex = rowIndex; node . originalColumnIndex = columnIndex; node . capturePath = ""; node . move = rowIndex + "," + columnIndex; this . scanMoves (player, node); } // FIND THE VALID JUMP-MOVES. this . illegalJumps = new Array (); this . legalJumps = new Array (); for (var rowIndex = 0; rowIndex < this . rowCount; rowIndex = rowIndex + 1) for (var columnIndex = 0; columnIndex < this . columnCount; columnIndex = columnIndex + 1) if (this . boardState [rowIndex] [columnIndex]) if (this . boardState [rowIndex] [columnIndex] . getOwnPredicate () == matchCode) { var node = new Node (); node . ownerNode = null; node . upperLeftNodes = null; node . upperRightNodes = null; node . lowerLeftNodes = null; node . lowerRightNodes = null; node . rowIndex = rowIndex; node . columnIndex = columnIndex; node . originalRowIndex = rowIndex; node . originalColumnIndex = columnIndex; node . capturePath = ""; node . move = rowIndex + "," + columnIndex; this . scanJumps (player, node); } // IF THERE ARE ANY VALID JUMP-MOVES, THEN ERASE THE REGULAR-MOVES. if (this . legalJumps . length > 0) { this . illegalMoves = this . legalMoves; this . legalMoves = new Array (); } // IN INTERNATIONAL CHECKERS (AND VARIANTS), ONLY THE LONGEST JUMPS MAY BE USED, SO FILTER OUT THE SHORT ONES. var index = 0; var longestJumpLength = 0; var jumps = this . legalJumps; this . legalJumps = new Array (); // FIND THE LENGTH OF THE LONGEST JUMP. for (index = 0; index < jumps . length; index = index + 1) { var jumpArray = jumps [index] . split (","); if (jumpArray . length > longestJumpLength) longestJumpLength = jumpArray . length; } // ACCEPT ONLY THE LONGEST JUMPS. for (index = 0; index < jumps . length; index = index + 1) { var jumpArray = jumps [index] . split (","); if (jumpArray . length == longestJumpLength) this . legalJumps . push (jumps [index]); } // RECORD THE VALID MOVES/JUMPS IN THE MESSAGE BOX UNDER 'NOTES'. if (player == "own") if (this . legalMoves . length > 0) { var list = ""; for (var index = 0; index < this . legalMoves . length; index = index + 1) list = list + this . legalMoves [index] + "\n"; messageBox . addMessage ("Notes", "Available Moves\n\n" + list); } if (player == "own") if (this . legalJumps . length > 0) { var list = ""; for (var index = 0; index < this . legalJumps . length; index = index + 1) list = list + this . legalJumps [index] + "\n"; messageBox . addMessage ("Notes", "Available Jumps\n\n" + list); } } this . getMoveCount = function () { return (this . legalMoves . length + this . legalJumps . length); } this . getCheckerPieceCount = function (player, capturePath, ignoreRowIndex, ignoreColumnIndex, fromRowIndex, fromColumnIndex, toRowIndex, toColumnIndex) { var matchCode = (player == "own") ? 1 : 0; var checkerPieceCount = 0; var rowStep = 0; var columnStep = 0; if (fromRowIndex < toRowIndex) rowStep = 1; if (fromRowIndex > toRowIndex) rowStep = - 1; if (fromColumnIndex < toColumnIndex) columnStep = 1; if (fromColumnIndex > toColumnIndex) columnStep = - 1; var rowIndex = fromRowIndex + rowStep; var columnIndex = fromColumnIndex + columnStep; var index = 0; var initialValue = 0; var rowLimit = fromRowIndex < toRowIndex ? toRowIndex - fromRowIndex - 1 : fromRowIndex - toRowIndex - 1; var columnLimit = fromColumnIndex < toColumnIndex ? toColumnIndex - fromColumnIndex - 1 : fromColumnIndex - toColumnIndex - 1; var limit = rowLimit > columnLimit ? rowLimit : columnLimit; for (index = initialValue; index < limit; index = index + 1) { var capturedPredicate; capturedPredicate = 0; if (capturePath != null) if (capturePath . indexOf ("[" + rowIndex + "," + columnIndex + "]") != - 1) capturedPredicate = 1; if (rowIndex >= 0) if (rowIndex <= 11) if (columnIndex >= 0) if (columnIndex <= 11) if (capturedPredicate == 0) if (! ((rowIndex == ignoreRowIndex) && (columnIndex == ignoreColumnIndex))) if (this . boardState [rowIndex] [columnIndex]) if (this . boardState [rowIndex] [columnIndex] . getOwnPredicate () == matchCode) checkerPieceCount = checkerPieceCount + 1; if (capturedPredicate == 1) checkerPieceCount = checkerPieceCount + 1; // added on 2009-06-28 to follow the rule of not jumping over pieces that were removed during this jump rowIndex = rowIndex + rowStep; columnIndex = columnIndex + columnStep; } return (checkerPieceCount); } this . getCheckerPieceRow = function (capturePath, ignoreRowIndex, ignoreColumnIndex, fromRowIndex, fromColumnIndex, toRowIndex, toColumnIndex) { var checkerPieceRow = null; var rowStep = 0; var columnStep = 0; if (fromRowIndex < toRowIndex) rowStep = 1; if (fromRowIndex > toRowIndex) rowStep = - 1; if (fromColumnIndex < toColumnIndex) columnStep = 1; if (fromColumnIndex > toColumnIndex) columnStep = - 1; var rowIndex = fromRowIndex + rowStep; var columnIndex = fromColumnIndex + columnStep; var index = 0; var initialValue = 0; var rowLimit = fromRowIndex < toRowIndex ? toRowIndex - fromRowIndex - 1 : fromRowIndex - toRowIndex - 1; var columnLimit = fromColumnIndex < toColumnIndex ? toColumnIndex - fromColumnIndex - 1 : fromColumnIndex - toColumnIndex - 1; var limit = rowLimit > columnLimit ? rowLimit : columnLimit; for (index = initialValue; index < limit; index = index + 1) { var capturedPredicate; capturedPredicate = 0; if (capturePath != null) if (capturePath . indexOf ("[" + rowIndex + "," + columnIndex + "]") != - 1) capturedPredicate = 1; if (rowIndex >= 0) if (rowIndex <= 11) if (columnIndex >= 0) if (columnIndex <= 11) if (capturedPredicate == 0) if (! ((rowIndex == ignoreRowIndex) && (columnIndex == ignoreColumnIndex))) if (this . boardState [rowIndex] [columnIndex]) checkerPieceRow = rowIndex; rowIndex = rowIndex + rowStep; columnIndex = columnIndex + columnStep; } return (checkerPieceRow); } this . getCheckerPieceColumn = function (capturePath, ignoreRowIndex, ignoreColumnIndex, fromRowIndex, fromColumnIndex, toRowIndex, toColumnIndex) { var checkerPieceColumn = null; var rowStep = 0; var columnStep = 0; if (fromRowIndex < toRowIndex) rowStep = 1; if (fromRowIndex > toRowIndex) rowStep = - 1; if (fromColumnIndex < toColumnIndex) columnStep = 1; if (fromColumnIndex > toColumnIndex) columnStep = - 1; var rowIndex = fromRowIndex + rowStep; var columnIndex = fromColumnIndex + columnStep; var index = 0; var initialValue = 0; var rowLimit = fromRowIndex < toRowIndex ? toRowIndex - fromRowIndex - 1 : fromRowIndex - toRowIndex - 1; var columnLimit = fromColumnIndex < toColumnIndex ? toColumnIndex - fromColumnIndex - 1 : fromColumnIndex - toColumnIndex - 1; var limit = rowLimit > columnLimit ? rowLimit : columnLimit; for (index = initialValue; index < limit; index = index + 1) { var capturedPredicate; capturedPredicate = 0; if (capturePath != null) if (capturePath . indexOf ("[" + rowIndex + "," + columnIndex + "]") != - 1) capturedPredicate = 1; if (rowIndex >= 0) if (rowIndex <= 11) if (columnIndex >= 0) if (columnIndex <= 11) if (capturedPredicate == 0) if (! ((rowIndex == ignoreRowIndex) && (columnIndex == ignoreColumnIndex))) if (this . boardState [rowIndex] [columnIndex]) checkerPieceColumn = columnIndex; rowIndex = rowIndex + rowStep; columnIndex = columnIndex + columnStep; } return (checkerPieceColumn); } this . scanMoves = function (player, node) { var matchCode = (player == "own") ? 1 : 0; var distanceLimit = this . rowCount > this . columnCount ? this . rowCount : this . columnCount; var distanceIndex; var fromRowIndex; var fromColumnIndex; var toRowIndex; var toColumnIndex; fromRowIndex = node . rowIndex; fromColumnIndex = node . columnIndex; // SCAN UPPER-LEFT for (distanceIndex = 0; distanceIndex < distanceLimit; distanceIndex = distanceIndex + 1) { if (player == "own") { toRowIndex = fromRowIndex - 1 - distanceIndex; toColumnIndex = fromColumnIndex - 1 - distanceIndex; } else { toRowIndex = fromRowIndex + 1 + distanceIndex; toColumnIndex = fromColumnIndex + 1 + distanceIndex; } if ((distanceIndex == 0) || (this . boardState [node . originalRowIndex] [node . originalColumnIndex] . getKingPredicate () == 1)) if (toRowIndex >= 0) if (toRowIndex < this . rowCount) if (toColumnIndex >= 0) if (toColumnIndex < this . columnCount) if (this . boardState [toRowIndex] [toColumnIndex] == null) if (this . getCheckerPieceCount ("own", "", node . originalRowIndex, node . originalColumnIndex, fromRowIndex, fromColumnIndex, toRowIndex, toColumnIndex) == 0) if (this . getCheckerPieceCount ("opponent", "", node . originalRowIndex, node . originalColumnIndex, fromRowIndex, fromColumnIndex, toRowIndex, toColumnIndex) == 0) this . legalMoves . push (fromRowIndex + "," + fromColumnIndex + "," + toRowIndex + "," + toColumnIndex); } // SCAN UPPER-RIGHT for (distanceIndex = 0; distanceIndex < distanceLimit; distanceIndex = distanceIndex + 1) { if (player == "own") { toRowIndex = fromRowIndex - 1 - distanceIndex; toColumnIndex = fromColumnIndex + 1 + distanceIndex; } else { toRowIndex = fromRowIndex + 1 + distanceIndex; toColumnIndex = fromColumnIndex - 1 - distanceIndex; } if ((distanceIndex == 0) || (this . boardState [node . originalRowIndex] [node . originalColumnIndex] . getKingPredicate () == 1)) if (toRowIndex >= 0) if (toRowIndex < this . rowCount) if (toColumnIndex >= 0) if (toColumnIndex < this . columnCount) if (this . boardState [toRowIndex] [toColumnIndex] == null) if (this . getCheckerPieceCount ("own", "", node . originalRowIndex, node . originalColumnIndex, fromRowIndex, fromColumnIndex, toRowIndex, toColumnIndex) == 0) if (this . getCheckerPieceCount ("opponent", "", node . originalRowIndex, node . originalColumnIndex, fromRowIndex, fromColumnIndex, toRowIndex, toColumnIndex) == 0) this . legalMoves . push (fromRowIndex + "," + fromColumnIndex + "," + toRowIndex + "," + toColumnIndex); } // SCAN LOWER-LEFT IF KING if (this . boardState [node . originalRowIndex] [node . originalColumnIndex] . getKingPredicate () == 1) for (distanceIndex = 0; distanceIndex < distanceLimit; distanceIndex = distanceIndex + 1) { if (player == "own") { toRowIndex = fromRowIndex + 1 + distanceIndex; toColumnIndex = fromColumnIndex - 1 - distanceIndex; } else { toRowIndex = fromRowIndex - 1 - distanceIndex; toColumnIndex = fromColumnIndex + 1 + distanceIndex; } if ((distanceIndex == 0) || (this . boardState [node . originalRowIndex] [node . originalColumnIndex] . getKingPredicate () == 1)) if (toRowIndex >= 0) if (toRowIndex < this . rowCount) if (toColumnIndex >= 0) if (toColumnIndex < this . columnCount) if (this . boardState [toRowIndex] [toColumnIndex] == null) if (this . boardState [fromRowIndex] [fromColumnIndex] . getKingPredicate () == 1) if (this . getCheckerPieceCount ("own", "", node . originalRowIndex, node . originalColumnIndex, fromRowIndex, fromColumnIndex, toRowIndex, toColumnIndex) == 0) if (this . getCheckerPieceCount ("opponent", "", node . originalRowIndex, node . originalColumnIndex, fromRowIndex, fromColumnIndex, toRowIndex, toColumnIndex) == 0) this . legalMoves . push (fromRowIndex + "," + fromColumnIndex + "," + toRowIndex + "," + toColumnIndex); } // SCAN LOWER-RIGHT IF KING if (this . boardState [node . originalRowIndex] [node . originalColumnIndex] . getKingPredicate () == 1) for (distanceIndex = 0; distanceIndex < distanceLimit; distanceIndex = distanceIndex + 1) { if (player == "own") { toRowIndex = fromRowIndex + 1 + distanceIndex; toColumnIndex = fromColumnIndex + 1 + distanceIndex; } else { toRowIndex = fromRowIndex - 1 - distanceIndex; toColumnIndex = fromColumnIndex - 1 - distanceIndex; } if ((distanceIndex == 0) || (this . boardState [node . originalRowIndex] [node . originalColumnIndex] . getKingPredicate () == 1)) if (toRowIndex >= 0) if (toRowIndex < this . rowCount) if (toColumnIndex >= 0) if (toColumnIndex < this . columnCount) if (this . boardState [toRowIndex] [toColumnIndex] == null) if (this . boardState [fromRowIndex] [fromColumnIndex] . getKingPredicate () == 1) if (this . getCheckerPieceCount ("own", "", node . originalRowIndex, node . originalColumnIndex, fromRowIndex, fromColumnIndex, toRowIndex, toColumnIndex) == 0) if (this . getCheckerPieceCount ("opponent", "", node . originalRowIndex, node . originalColumnIndex, fromRowIndex, fromColumnIndex, toRowIndex, toColumnIndex) == 0) this . legalMoves . push (fromRowIndex + "," + fromColumnIndex + "," + toRowIndex + "," + toColumnIndex); } } this . scanJumps = function (player, node) { var otherPlayer = (player == "own") ? "opponent" : "own"; var matchCode = (player == "own") ? 1 : 0; var distanceLimit = this . rowCount > this . columnCount ? this . rowCount : this . columnCount; var distanceIndex; var fromRowIndex; var fromColumnIndex; var toRowIndex; var toColumnIndex; fromRowIndex = node . rowIndex; fromColumnIndex = node . columnIndex; // SCAN UPPER-LEFT for (distanceIndex = 0; distanceIndex < distanceLimit; distanceIndex = distanceIndex + 1) { if (player == "own") { toRowIndex = fromRowIndex - 2 - distanceIndex; toColumnIndex = fromColumnIndex - 2 - distanceIndex; } else { toRowIndex = fromRowIndex + 2 + distanceIndex; toColumnIndex = fromColumnIndex + 2 + distanceIndex; } if ((distanceIndex == 0) || (this . boardState [node . originalRowIndex] [node . originalColumnIndex] . getKingPredicate () == 1)) if (toRowIndex >= 0) if (toRowIndex < this . rowCount) if (toColumnIndex >= 0) if (toColumnIndex < this . columnCount) if ((this . boardState [toRowIndex] [toColumnIndex] == null) && (! ((toRowIndex == node . originalRowIndex) && (toColumnIndex == node . originalColumnIndex)))) if (this . getCheckerPieceCount (player, node . capturePath, node . originalRowIndex, node . originalColumnIndex, fromRowIndex, fromColumnIndex, toRowIndex, toColumnIndex) == 0) if (this . getCheckerPieceCount (otherPlayer, node . capturePath, node . originalRowIndex, node . originalColumnIndex, fromRowIndex, fromColumnIndex, toRowIndex, toColumnIndex) == 1) if (node . capturePath . indexOf ("[" + this . getCheckerPieceRow (node . capturePath, node . originalRowIndex, node . originalColumnIndex, fromRowIndex, fromColumnIndex, toRowIndex, toColumnIndex) + "," + this . getCheckerPieceColumn (node . capturePath, node . originalRowIndex, node . originalColumnIndex, fromRowIndex, fromColumnIndex, toRowIndex, toColumnIndex) + "]") == - 1) { // SEARCH FOR SUCCESSIVE JUMPS if (! node . upperLeftNodes) node . upperLeftNodes = new Array (); node . upperLeftNodes [distanceIndex] = new Node (); node . upperLeftNodes [distanceIndex] . ownerNode = node; node . upperLeftNodes [distanceIndex] . upperLeftNodes = null; node . upperLeftNodes [distanceIndex] . upperRightNodes = null; node . upperLeftNodes [distanceIndex] . lowerLeftNodes = null; node . upperLeftNodes [distanceIndex] . lowerRightNodes = null; node . upperLeftNodes [distanceIndex] . rowIndex = toRowIndex; node . upperLeftNodes [distanceIndex] . columnIndex = toColumnIndex; node . upperLeftNodes [distanceIndex] . originalRowIndex = node . originalRowIndex; node . upperLeftNodes [distanceIndex] . originalColumnIndex = node . originalColumnIndex; node . upperLeftNodes [distanceIndex] . capturePath = node . capturePath + "[" + this . getCheckerPieceRow (node . capturePath, node . originalRowIndex, node . originalColumnIndex, fromRowIndex, fromColumnIndex, toRowIndex, toColumnIndex) + "," + this . getCheckerPieceColumn (node . capturePath, node . originalRowIndex, node . originalColumnIndex, fromRowIndex, fromColumnIndex, toRowIndex, toColumnIndex) + "]"; node . upperLeftNodes [distanceIndex] . move = node . move + "," + toRowIndex + "," + toColumnIndex; this . scanJumps (player, node . upperLeftNodes [distanceIndex]); } } // SCAN UPPER-RIGHT for (distanceIndex = 0; distanceIndex < distanceLimit; distanceIndex = distanceIndex + 1) { if (player == "own") { toRowIndex = fromRowIndex - 2 - distanceIndex; toColumnIndex = fromColumnIndex + 2 + distanceIndex; } else { toRowIndex = fromRowIndex + 2 + distanceIndex; toColumnIndex = fromColumnIndex - 2 - distanceIndex; } if ((distanceIndex == 0) || (this . boardState [node . originalRowIndex] [node . originalColumnIndex] . getKingPredicate () == 1)) if (toRowIndex >= 0) if (toRowIndex < this . rowCount) if (toColumnIndex >= 0) if (toColumnIndex < this . columnCount) if ((this . boardState [toRowIndex] [toColumnIndex] == null) && (! ((toRowIndex == node . originalRowIndex) && (toColumnIndex == node . originalColumnIndex)))) if (this . getCheckerPieceCount (player, node . capturePath, node . originalRowIndex, node . originalColumnIndex, fromRowIndex, fromColumnIndex, toRowIndex, toColumnIndex) == 0) if (this . getCheckerPieceCount (otherPlayer, node . capturePath, node . originalRowIndex, node . originalColumnIndex, fromRowIndex, fromColumnIndex, toRowIndex, toColumnIndex) == 1) if (node . capturePath . indexOf ("[" + this . getCheckerPieceRow (node . capturePath, node . originalRowIndex, node . originalColumnIndex, fromRowIndex, fromColumnIndex, toRowIndex, toColumnIndex) + "," + this . getCheckerPieceColumn (node . capturePath, node . originalRowIndex, node . originalColumnIndex, fromRowIndex, fromColumnIndex, toRowIndex, toColumnIndex) + "]") == - 1) { // SEARCH FOR SUCCESSIVE JUMPS if (! node . upperRightNodes) node . upperRightNodes = new Array (); node . upperRightNodes [distanceIndex] = new Node (); node . upperRightNodes [distanceIndex] . ownerNode = node; node . upperRightNodes [distanceIndex] . upperLeftNodes = null; node . upperRightNodes [distanceIndex] . upperRightNodes = null; node . upperRightNodes [distanceIndex] . lowerLeftNodes = null; node . upperRightNodes [distanceIndex] . lowerRightNodes = null; node . upperRightNodes [distanceIndex] . rowIndex = toRowIndex; node . upperRightNodes [distanceIndex] . columnIndex = toColumnIndex; node . upperRightNodes [distanceIndex] . originalRowIndex = node . originalRowIndex; node . upperRightNodes [distanceIndex] . originalColumnIndex = node . originalColumnIndex; node . upperRightNodes [distanceIndex] . capturePath = node . capturePath + "[" + this . getCheckerPieceRow (node . capturePath, node . originalRowIndex, node . originalColumnIndex, fromRowIndex, fromColumnIndex, toRowIndex, toColumnIndex) + "," + this . getCheckerPieceColumn (node . capturePath, node . originalRowIndex, node . originalColumnIndex, fromRowIndex, fromColumnIndex, toRowIndex, toColumnIndex) + "]"; node . upperRightNodes [distanceIndex] . move = node . move + "," + toRowIndex + "," + toColumnIndex; this . scanJumps (player, node . upperRightNodes [distanceIndex]); } } // SCAN LOWER-LEFT for (distanceIndex = 0; distanceIndex < distanceLimit; distanceIndex = distanceIndex + 1) { if (player == "own") { toRowIndex = fromRowIndex + 2 + distanceIndex; toColumnIndex = fromColumnIndex - 2 - distanceIndex; } else { toRowIndex = fromRowIndex - 2 - distanceIndex; toColumnIndex = fromColumnIndex + 2 + distanceIndex; } if ((distanceIndex == 0) || (this . boardState [node . originalRowIndex] [node . originalColumnIndex] . getKingPredicate () == 1)) if (toRowIndex >= 0) if (toRowIndex < this . rowCount) if (toColumnIndex >= 0) if (toColumnIndex < this . columnCount) if ((this . boardState [toRowIndex] [toColumnIndex] == null) && (! ((toRowIndex == node . originalRowIndex) && (toColumnIndex == node . originalColumnIndex)))) if (this . getCheckerPieceCount (player, node . capturePath, node . originalRowIndex, node . originalColumnIndex, fromRowIndex, fromColumnIndex, toRowIndex, toColumnIndex) == 0) if (this . getCheckerPieceCount (otherPlayer, node . capturePath, node . originalRowIndex, node . originalColumnIndex, fromRowIndex, fromColumnIndex, toRowIndex, toColumnIndex) == 1) if (node . capturePath . indexOf ("[" + this . getCheckerPieceRow (node . capturePath, node . originalRowIndex, node . originalColumnIndex, fromRowIndex, fromColumnIndex, toRowIndex, toColumnIndex) + "," + this . getCheckerPieceColumn (node . capturePath, node . originalRowIndex, node . originalColumnIndex, fromRowIndex, fromColumnIndex, toRowIndex, toColumnIndex) + "]") == - 1) { // SEARCH FOR SUCCESSIVE JUMPS if (! node . lowerLeftNodes) node . lowerLeftNodes = new Array (); node . lowerLeftNodes [distanceIndex] = new Node (); node . lowerLeftNodes [distanceIndex] . ownerNode = node; node . lowerLeftNodes [distanceIndex] . upperLeftNodes = null; node . lowerLeftNodes [distanceIndex] . upperRightNodes = null; node . lowerLeftNodes [distanceIndex] . lowerLeftNodes = null; node . lowerLeftNodes [distanceIndex] . lowerRightNodes = null; node . lowerLeftNodes [distanceIndex] . rowIndex = toRowIndex; node . lowerLeftNodes [distanceIndex] . columnIndex = toColumnIndex; node . lowerLeftNodes [distanceIndex] . originalRowIndex = node . originalRowIndex; node . lowerLeftNodes [distanceIndex] . originalColumnIndex = node . originalColumnIndex; node . lowerLeftNodes [distanceIndex] . capturePath = node . capturePath + "[" + this . getCheckerPieceRow (node . capturePath, node . originalRowIndex, node . originalColumnIndex, fromRowIndex, fromColumnIndex, toRowIndex, toColumnIndex) + "," + this . getCheckerPieceColumn (node . capturePath, node . originalRowIndex, node . originalColumnIndex, fromRowIndex, fromColumnIndex, toRowIndex, toColumnIndex) + "]"; node . lowerLeftNodes [distanceIndex] . move = node . move + "," + toRowIndex + "," + toColumnIndex; this . scanJumps (player, node . lowerLeftNodes [distanceIndex]); } } // SCAN LOWER-RIGHT for (distanceIndex = 0; distanceIndex < distanceLimit; distanceIndex = distanceIndex + 1) { if (player == "own") { toRowIndex = fromRowIndex + 2 + distanceIndex; toColumnIndex = fromColumnIndex + 2 + distanceIndex; } else { toRowIndex = fromRowIndex - 2 - distanceIndex; toColumnIndex = fromColumnIndex - 2 - distanceIndex; } if ((distanceIndex == 0) || (this . boardState [node . originalRowIndex] [node . originalColumnIndex] . getKingPredicate () == 1)) if (toRowIndex >= 0) if (toRowIndex < this . rowCount) if (toColumnIndex >= 0) if (toColumnIndex < this . columnCount) if ((this . boardState [toRowIndex] [toColumnIndex] == null) && (! ((toRowIndex == node . originalRowIndex) && (toColumnIndex == node . originalColumnIndex)))) if (this . getCheckerPieceCount (player, node . capturePath, node . originalRowIndex, node . originalColumnIndex, fromRowIndex, fromColumnIndex, toRowIndex, toColumnIndex) == 0) if (this . getCheckerPieceCount (otherPlayer, node . capturePath, node . originalRowIndex, node . originalColumnIndex, fromRowIndex, fromColumnIndex, toRowIndex, toColumnIndex) == 1) if (node . capturePath . indexOf ("[" + this . getCheckerPieceRow (node . capturePath, node . originalRowIndex, node . originalColumnIndex, fromRowIndex, fromColumnIndex, toRowIndex, toColumnIndex) + "," + this . getCheckerPieceColumn (node . capturePath, node . originalRowIndex, node . originalColumnIndex, fromRowIndex, fromColumnIndex, toRowIndex, toColumnIndex) + "]") == - 1) { // SEARCH FOR SUCCESSIVE JUMPS if (! node . lowerRightNodes) node . lowerRightNodes = new Array (); node . lowerRightNodes [distanceIndex] = new Node (); node . lowerRightNodes [distanceIndex] . ownerNode = node; node . lowerRightNodes [distanceIndex] . upperLeftNodes = null; node . lowerRightNodes [distanceIndex] . upperRightNodes = null; node . lowerRightNodes [distanceIndex] . lowerLeftNodes = null; node . lowerRightNodes [distanceIndex] . lowerRightNodes = null; node . lowerRightNodes [distanceIndex] . rowIndex = toRowIndex; node . lowerRightNodes [distanceIndex] . columnIndex = toColumnIndex; node . lowerRightNodes [distanceIndex] . originalRowIndex = node . originalRowIndex; node . lowerRightNodes [distanceIndex] . originalColumnIndex = node . originalColumnIndex; node . lowerRightNodes [distanceIndex] . capturePath = node . capturePath + "[" + this . getCheckerPieceRow (node . capturePath, node . originalRowIndex, node . originalColumnIndex, fromRowIndex, fromColumnIndex, toRowIndex, toColumnIndex) + "," + this . getCheckerPieceColumn (node . capturePath, node . originalRowIndex, node . originalColumnIndex, fromRowIndex, fromColumnIndex, toRowIndex, toColumnIndex) + "]"; node . lowerRightNodes [distanceIndex] . move = node . move + "," + toRowIndex + "," + toColumnIndex; this . scanJumps (player, node . lowerRightNodes [distanceIndex]); } } // IF NONE OF THE LEAD-NODES ARE USED, THEN RECORD THE MOVE. if (node . ownerNode != null) if (node . upperLeftNodes == null) if (node . upperRightNodes == null) if (node . lowerLeftNodes == null) if (node . lowerRightNodes == null) this . legalJumps . push (node . move); } this . getIllegalMovePredicate = function (move) { for (var index = 0; index < this . illegalMoves . length; index = index + 1) if (this . illegalMoves [index] . indexOf (move) == 0) return (1); for (var index = 0; index < this . illegalJumps . length; index = index + 1) if (this . illegalJumps [index] . indexOf (move) == 0) return (1); return (0); } this . getLegalMovePredicate = function (move) { for (var index = 0; index < this . legalMoves . length; index = index + 1) if (this . legalMoves [index] . indexOf (move) == 0) return (1); for (var index = 0; index < this . legalJumps . length; index = index + 1) if (this . legalJumps [index] . indexOf (move) == 0) return (1); return (0); } this . getTerminalMovePredicate = function (move) { if (this . getMoveCount () == 0) return (1); for (var index = 0; index < this . legalMoves . length; index = index + 1) if (this . legalMoves [index] == move) return (1); for (var index = 0; index < this . legalJumps . length; index = index + 1) if (this . legalJumps [index] == move) return (1); return (0); } } function PolishRules () { // STATE this . boardState = null; this . rowCount = 0; this . columnCount = 0; this . illegalMoves = null; this . illegalJumps = null; this . legalMoves = null; this . legalJumps = null; this . initiate = function () { this . boardState = new Array (); this . rowCount = 10; this . columnCount = 10; } this . initialize = function () { for (var rowIndex = 0; rowIndex < this . rowCount; rowIndex = rowIndex + 1) for (var columnIndex = 0; columnIndex < this . columnCount; columnIndex = columnIndex + 1) { if (! this . boardState [rowIndex]) { this . boardState [rowIndex] = new Array (); } this . boardState [rowIndex] [columnIndex] = null; if ((rowIndex < 4) && ((rowIndex % 2) != (columnIndex % 2))) { var checkerPiece = null; checkerPiece = new CheckerPiece (); checkerPiece . initiate (); checkerPiece . initialize (); checkerPiece . setCoordinates (rowIndex * checkerPiece . getHeight () + rowIndex, columnIndex * checkerPiece . getWidth () + columnIndex); checkerPiece . setOwnPredicate (0); this . boardState [rowIndex] [columnIndex] = checkerPiece; } if ((rowIndex > 5) && ((rowIndex % 2) != (columnIndex % 2))) { var checkerPiece = null; checkerPiece = new CheckerPiece (); checkerPiece . initiate (); checkerPiece . initialize (); checkerPiece . setCoordinates (rowIndex * checkerPiece . getHeight () + rowIndex, columnIndex * checkerPiece . getWidth () + columnIndex); checkerPiece . setOwnPredicate (1); this . boardState [rowIndex] [columnIndex] = checkerPiece; } } } this . getBoardState = function () { return (this . boardState); } this . getRowCount = function () { return (this . rowCount); } this . getColumnCount = function () { return (this . columnCount); } this . getTranslatedMove = function (move) { var moveArray = move . split (","); move = this . rowCount - 1 - moveArray [0]; for (var index = 1; index < moveArray . length; index = index + 1) move = move + "," + ((index % 2 ? this . columnCount - 1 : this . rowCount - 1) - moveArray [index]); return (move); } this . evaluate = function (player) { var matchCode = (player == "own") ? 1 : 0; // FIND THE VALID REGULAR-MOVES. this . illegalMoves = new Array (); this . legalMoves = new Array (); for (var rowIndex = 0; rowIndex < this . rowCount; rowIndex = rowIndex + 1) for (var columnIndex = 0; columnIndex < this . columnCount; columnIndex = columnIndex + 1) if (this . boardState [rowIndex] [columnIndex]) if (this . boardState [rowIndex] [columnIndex] . getOwnPredicate () == matchCode) { var node = new Node (); node . ownerNode = null; node . upperLeftNode = null; node . upperRightNode = null; node . lowerLeftNode = null; node . lowerRightNode = null; node . rowIndex = rowIndex; node . columnIndex = columnIndex; node . originalRowIndex = rowIndex; node . originalColumnIndex = columnIndex; node . capturePath = ""; node . move = rowIndex + "," + columnIndex; this . scanMoves (player, node); } // FIND THE VALID JUMP-MOVES. this . illegalJumps = new Array (); this . legalJumps = new Array (); for (var rowIndex = 0; rowIndex < this . rowCount; rowIndex = rowIndex + 1) for (var columnIndex = 0; columnIndex < this . columnCount; columnIndex = columnIndex + 1) if (this . boardState [rowIndex] [columnIndex]) if (this . boardState [rowIndex] [columnIndex] . getOwnPredicate () == matchCode) { var node = new Node (); node . ownerNode = null; node . upperLeftNodes = null; node . upperRightNodes = null; node . lowerLeftNodes = null; node . lowerRightNodes = null; node . rowIndex = rowIndex; node . columnIndex = columnIndex; node . originalRowIndex = rowIndex; node . originalColumnIndex = columnIndex; node . capturePath = ""; node . move = rowIndex + "," + columnIndex; this . scanJumps (player, node); } // IF THERE ARE ANY VALID JUMP-MOVES, THEN ERASE THE REGULAR-MOVES. if (this . legalJumps . length > 0) { this . illegalMoves = this . legalMoves; this . legalMoves = new Array (); } // IN INTERNATIONAL CHECKERS (AND VARIANTS), ONLY THE LONGEST JUMPS MAY BE USED, SO FILTER OUT THE SHORT ONES. var index = 0; var longestJumpLength = 0; var jumps = this . legalJumps; this . legalJumps = new Array (); // FIND THE LENGTH OF THE LONGEST JUMP. for (index = 0; index < jumps . length; index = index + 1) { var jumpArray = jumps [index] . split (","); if (jumpArray . length > longestJumpLength) longestJumpLength = jumpArray . length; } // ACCEPT ONLY THE LONGEST JUMPS. for (index = 0; index < jumps . length; index = index + 1) { var jumpArray = jumps [index] . split (","); if (jumpArray . length == longestJumpLength) this . legalJumps . push (jumps [index]); } // RECORD THE VALID MOVES/JUMPS IN THE MESSAGE BOX UNDER 'NOTES'. if (player == "own") if (this . legalMoves . length > 0) { var list = ""; for (var index = 0; index < this . legalMoves . length; index = index + 1) list = list + this . legalMoves [index] + "\n"; messageBox . addMessage ("Notes", "Available Moves\n\n" + list); } if (player == "own") if (this . legalJumps . length > 0) { var list = ""; for (var index = 0; index < this . legalJumps . length; index = index + 1) list = list + this . legalJumps [index] + "\n"; messageBox . addMessage ("Notes", "Available Jumps\n\n" + list); } } this . getMoveCount = function () { return (this . legalMoves . length + this . legalJumps . length); } this . getCheckerPieceCount = function (player, capturePath, ignoreRowIndex, ignoreColumnIndex, fromRowIndex, fromColumnIndex, toRowIndex, toColumnIndex) { var matchCode = (player == "own") ? 1 : 0; var checkerPieceCount = 0; var rowStep = 0; var columnStep = 0; if (fromRowIndex < toRowIndex) rowStep = 1; if (fromRowIndex > toRowIndex) rowStep = - 1; if (fromColumnIndex < toColumnIndex) columnStep = 1; if (fromColumnIndex > toColumnIndex) columnStep = - 1; var rowIndex = fromRowIndex + rowStep; var columnIndex = fromColumnIndex + columnStep; var index = 0; var initialValue = 0; var rowLimit = fromRowIndex < toRowIndex ? toRowIndex - fromRowIndex - 1 : fromRowIndex - toRowIndex - 1; var columnLimit = fromColumnIndex < toColumnIndex ? toColumnIndex - fromColumnIndex - 1 : fromColumnIndex - toColumnIndex - 1; var limit = rowLimit > columnLimit ? rowLimit : columnLimit; for (index = initialValue; index < limit; index = index + 1) { var capturedPredicate; capturedPredicate = 0; if (capturePath != null) if (capturePath . indexOf ("[" + rowIndex + "," + columnIndex + "]") != - 1) capturedPredicate = 1; if (rowIndex >= 0) if (rowIndex <= 11) if (columnIndex >= 0) if (columnIndex <= 11) if (capturedPredicate == 0) if (! ((rowIndex == ignoreRowIndex) && (columnIndex == ignoreColumnIndex))) if (this . boardState [rowIndex] [columnIndex]) if (this . boardState [rowIndex] [columnIndex] . getOwnPredicate () == matchCode) checkerPieceCount = checkerPieceCount + 1; if (capturedPredicate == 1) checkerPieceCount = checkerPieceCount + 1; // added on 2009-06-28 to follow the rule of not jumping over pieces that were removed during this jump rowIndex = rowIndex + rowStep; columnIndex = columnIndex + columnStep; } return (checkerPieceCount); } this . getCheckerPieceRow = function (capturePath, ignoreRowIndex, ignoreColumnIndex, fromRowIndex, fromColumnIndex, toRowIndex, toColumnIndex) { var checkerPieceRow = null; var rowStep = 0; var columnStep = 0; if (fromRowIndex < toRowIndex) rowStep = 1; if (fromRowIndex > toRowIndex) rowStep = - 1; if (fromColumnIndex < toColumnIndex) columnStep = 1; if (fromColumnIndex > toColumnIndex) columnStep = - 1; var rowIndex = fromRowIndex + rowStep; var columnIndex = fromColumnIndex + columnStep; var index = 0; var initialValue = 0; var rowLimit = fromRowIndex < toRowIndex ? toRowIndex - fromRowIndex - 1 : fromRowIndex - toRowIndex - 1; var columnLimit = fromColumnIndex < toColumnIndex ? toColumnIndex - fromColumnIndex - 1 : fromColumnIndex - toColumnIndex - 1; var limit = rowLimit > columnLimit ? rowLimit : columnLimit; for (index = initialValue; index < limit; index = index + 1) { var capturedPredicate; capturedPredicate = 0; if (capturePath != null) if (capturePath . indexOf ("[" + rowIndex + "," + columnIndex + "]") != - 1) capturedPredicate = 1; if (rowIndex >= 0) if (rowIndex <= 11) if (columnIndex >= 0) if (columnIndex <= 11) if (capturedPredicate == 0) if (! ((rowIndex == ignoreRowIndex) && (columnIndex == ignoreColumnIndex))) if (this . boardState [rowIndex] [columnIndex]) checkerPieceRow = rowIndex; rowIndex = rowIndex + rowStep; columnIndex = columnIndex + columnStep; } return (checkerPieceRow); } this . getCheckerPieceColumn = function (capturePath, ignoreRowIndex, ignoreColumnIndex, fromRowIndex, fromColumnIndex, toRowIndex, toColumnIndex) { var checkerPieceColumn = null; var rowStep = 0; var columnStep = 0; if (fromRowIndex < toRowIndex) rowStep = 1; if (fromRowIndex > toRowIndex) rowStep = - 1; if (fromColumnIndex < toColumnIndex) columnStep = 1; if (fromColumnIndex > toColumnIndex) columnStep = - 1; var rowIndex = fromRowIndex + rowStep; var columnIndex = fromColumnIndex + columnStep; var index = 0; var initialValue = 0; var rowLimit = fromRowIndex < toRowIndex ? toRowIndex - fromRowIndex - 1 : fromRowIndex - toRowIndex - 1; var columnLimit = fromColumnIndex < toColumnIndex ? toColumnIndex - fromColumnIndex - 1 : fromColumnIndex - toColumnIndex - 1; var limit = rowLimit > columnLimit ? rowLimit : columnLimit; for (index = initialValue; index < limit; index = index + 1) { var capturedPredicate; capturedPredicate = 0; if (capturePath != null) if (capturePath . indexOf ("[" + rowIndex + "," + columnIndex + "]") != - 1) capturedPredicate = 1; if (rowIndex >= 0) if (rowIndex <= 11) if (columnIndex >= 0) if (columnIndex <= 11) if (capturedPredicate == 0) if (! ((rowIndex == ignoreRowIndex) && (columnIndex == ignoreColumnIndex))) if (this . boardState [rowIndex] [columnIndex]) checkerPieceColumn = columnIndex; rowIndex = rowIndex + rowStep; columnIndex = columnIndex + columnStep; } return (checkerPieceColumn); } this . scanMoves = function (player, node) { var matchCode = (player == "own") ? 1 : 0; var distanceLimit = this . rowCount > this . columnCount ? this . rowCount : this . columnCount; var distanceIndex; var fromRowIndex; var fromColumnIndex; var toRowIndex; var toColumnIndex; fromRowIndex = node . rowIndex; fromColumnIndex = node . columnIndex; // SCAN UPPER-LEFT for (distanceIndex = 0; distanceIndex < distanceLimit; distanceIndex = distanceIndex + 1) { if (player == "own") { toRowIndex = fromRowIndex - 1 - distanceIndex; toColumnIndex = fromColumnIndex - 1 - distanceIndex; } else { toRowIndex = fromRowIndex + 1 + distanceIndex; toColumnIndex = fromColumnIndex + 1 + distanceIndex; } if ((distanceIndex == 0) || (this . boardState [node . originalRowIndex] [node . originalColumnIndex] . getKingPredicate () == 1)) if (toRowIndex >= 0) if (toRowIndex < this . rowCount) if (toColumnIndex >= 0) if (toColumnIndex < this . columnCount) if (this . boardState [toRowIndex] [toColumnIndex] == null) if (this . getCheckerPieceCount ("own", "", node . originalRowIndex, node . originalColumnIndex, fromRowIndex, fromColumnIndex, toRowIndex, toColumnIndex) == 0) if (this . getCheckerPieceCount ("opponent", "", node . originalRowIndex, node . originalColumnIndex, fromRowIndex, fromColumnIndex, toRowIndex, toColumnIndex) == 0) this . legalMoves . push (fromRowIndex + "," + fromColumnIndex + "," + toRowIndex + "," + toColumnIndex); } // SCAN UPPER-RIGHT for (distanceIndex = 0; distanceIndex < distanceLimit; distanceIndex = distanceIndex + 1) { if (player == "own") { toRowIndex = fromRowIndex - 1 - distanceIndex; toColumnIndex = fromColumnIndex + 1 + distanceIndex; } else { toRowIndex = fromRowIndex + 1 + distanceIndex; toColumnIndex = fromColumnIndex - 1 - distanceIndex; } if ((distanceIndex == 0) || (this . boardState [node . originalRowIndex] [node . originalColumnIndex] . getKingPredicate () == 1)) if (toRowIndex >= 0) if (toRowIndex < this . rowCount) if (toColumnIndex >= 0) if (toColumnIndex < this . columnCount) if (this . boardState [toRowIndex] [toColumnIndex] == null) if (this . getCheckerPieceCount ("own", "", node . originalRowIndex, node . originalColumnIndex, fromRowIndex, fromColumnIndex, toRowIndex, toColumnIndex) == 0) if (this . getCheckerPieceCount ("opponent", "", node . originalRowIndex, node . originalColumnIndex, fromRowIndex, fromColumnIndex, toRowIndex, toColumnIndex) == 0) this . legalMoves . push (fromRowIndex + "," + fromColumnIndex + "," + toRowIndex + "," + toColumnIndex); } // SCAN LOWER-LEFT IF KING if (this . boardState [node . originalRowIndex] [node . originalColumnIndex] . getKingPredicate () == 1) for (distanceIndex = 0; distanceIndex < distanceLimit; distanceIndex = distanceIndex + 1) { if (player == "own") { toRowIndex = fromRowIndex + 1 + distanceIndex; toColumnIndex = fromColumnIndex - 1 - distanceIndex; } else { toRowIndex = fromRowIndex - 1 - distanceIndex; toColumnIndex = fromColumnIndex + 1 + distanceIndex; } if ((distanceIndex == 0) || (this . boardState [node . originalRowIndex] [node . originalColumnIndex] . getKingPredicate () == 1)) if (toRowIndex >= 0) if (toRowIndex < this . rowCount) if (toColumnIndex >= 0) if (toColumnIndex < this . columnCount) if (this . boardState [toRowIndex] [toColumnIndex] == null) if (this . boardState [fromRowIndex] [fromColumnIndex] . getKingPredicate () == 1) if (this . getCheckerPieceCount ("own", "", node . originalRowIndex, node . originalColumnIndex, fromRowIndex, fromColumnIndex, toRowIndex, toColumnIndex) == 0) if (this . getCheckerPieceCount ("opponent", "", node . originalRowIndex, node . originalColumnIndex, fromRowIndex, fromColumnIndex, toRowIndex, toColumnIndex) == 0) this . legalMoves . push (fromRowIndex + "," + fromColumnIndex + "," + toRowIndex + "," + toColumnIndex); } // SCAN LOWER-RIGHT IF KING if (this . boardState [node . originalRowIndex] [node . originalColumnIndex] . getKingPredicate () == 1) for (distanceIndex = 0; distanceIndex < distanceLimit; distanceIndex = distanceIndex + 1) { if (player == "own") { toRowIndex = fromRowIndex + 1 + distanceIndex; toColumnIndex = fromColumnIndex + 1 + distanceIndex; } else { toRowIndex = fromRowIndex - 1 - distanceIndex; toColumnIndex = fromColumnIndex - 1 - distanceIndex; } if ((distanceIndex == 0) || (this . boardState [node . originalRowIndex] [node . originalColumnIndex] . getKingPredicate () == 1)) if (toRowIndex >= 0) if (toRowIndex < this . rowCount) if (toColumnIndex >= 0) if (toColumnIndex < this . columnCount) if (this . boardState [toRowIndex] [toColumnIndex] == null) if (this . boardState [fromRowIndex] [fromColumnIndex] . getKingPredicate () == 1) if (this . getCheckerPieceCount ("own", "", node . originalRowIndex, node . originalColumnIndex, fromRowIndex, fromColumnIndex, toRowIndex, toColumnIndex) == 0) if (this . getCheckerPieceCount ("opponent", "", node . originalRowIndex, node . originalColumnIndex, fromRowIndex, fromColumnIndex, toRowIndex, toColumnIndex) == 0) this . legalMoves . push (fromRowIndex + "," + fromColumnIndex + "," + toRowIndex + "," + toColumnIndex); } } this . scanJumps = function (player, node) { var otherPlayer = (player == "own") ? "opponent" : "own"; var matchCode = (player == "own") ? 1 : 0; var distanceLimit = this . rowCount > this . columnCount ? this . rowCount : this . columnCount; var distanceIndex; var fromRowIndex; var fromColumnIndex; var toRowIndex; var toColumnIndex; fromRowIndex = node . rowIndex; fromColumnIndex = node . columnIndex; // SCAN UPPER-LEFT for (distanceIndex = 0; distanceIndex < distanceLimit; distanceIndex = distanceIndex + 1) { if (player == "own") { toRowIndex = fromRowIndex - 2 - distanceIndex; toColumnIndex = fromColumnIndex - 2 - distanceIndex; } else { toRowIndex = fromRowIndex + 2 + distanceIndex; toColumnIndex = fromColumnIndex + 2 + distanceIndex; } if ((distanceIndex == 0) || (this . boardState [node . originalRowIndex] [node . originalColumnIndex] . getKingPredicate () == 1)) if (toRowIndex >= 0) if (toRowIndex < this . rowCount) if (toColumnIndex >= 0) if (toColumnIndex < this . columnCount) if (this . boardState [toRowIndex] [toColumnIndex] == null) if (this . getCheckerPieceCount (player, node . capturePath, node . originalRowIndex, node . originalColumnIndex, fromRowIndex, fromColumnIndex, toRowIndex, toColumnIndex) == 0) if (this . getCheckerPieceCount (otherPlayer, node . capturePath, node . originalRowIndex, node . originalColumnIndex, fromRowIndex, fromColumnIndex, toRowIndex, toColumnIndex) == 1) if (node . capturePath . indexOf ("[" + this . getCheckerPieceRow (node . capturePath, node . originalRowIndex, node . originalColumnIndex, fromRowIndex, fromColumnIndex, toRowIndex, toColumnIndex) + "," + this . getCheckerPieceColumn (node . capturePath, node . originalRowIndex, node . originalColumnIndex, fromRowIndex, fromColumnIndex, toRowIndex, toColumnIndex) + "]") == - 1) { // SEARCH FOR SUCCESSIVE JUMPS if (! node . upperLeftNodes) node . upperLeftNodes = new Array (); node . upperLeftNodes [distanceIndex] = new Node (); node . upperLeftNodes [distanceIndex] . ownerNode = node; node . upperLeftNodes [distanceIndex] . upperLeftNodes = null; node . upperLeftNodes [distanceIndex] . upperRightNodes = null; node . upperLeftNodes [distanceIndex] . lowerLeftNodes = null; node . upperLeftNodes [distanceIndex] . lowerRightNodes = null; node . upperLeftNodes [distanceIndex] . rowIndex = toRowIndex; node . upperLeftNodes [distanceIndex] . columnIndex = toColumnIndex; node . upperLeftNodes [distanceIndex] . originalRowIndex = node . originalRowIndex; node . upperLeftNodes [distanceIndex] . originalColumnIndex = node . originalColumnIndex; node . upperLeftNodes [distanceIndex] . capturePath = node . capturePath + "[" + this . getCheckerPieceRow (node . capturePath, node . originalRowIndex, node . originalColumnIndex, fromRowIndex, fromColumnIndex, toRowIndex, toColumnIndex) + "," + this . getCheckerPieceColumn (node . capturePath, node . originalRowIndex, node . originalColumnIndex, fromRowIndex, fromColumnIndex, toRowIndex, toColumnIndex) + "]"; node . upperLeftNodes [distanceIndex] . move = node . move + "," + toRowIndex + "," + toColumnIndex; this . scanJumps (player, node . upperLeftNodes [distanceIndex]); } } // SCAN UPPER-RIGHT for (distanceIndex = 0; distanceIndex < distanceLimit; distanceIndex = distanceIndex + 1) { if (player == "own") { toRowIndex = fromRowIndex - 2 - distanceIndex; toColumnIndex = fromColumnIndex + 2 + distanceIndex; } else { toRowIndex = fromRowIndex + 2 + distanceIndex; toColumnIndex = fromColumnIndex - 2 - distanceIndex; } if ((distanceIndex == 0) || (this . boardState [node . originalRowIndex] [node . originalColumnIndex] . getKingPredicate () == 1)) if (toRowIndex >= 0) if (toRowIndex < this . rowCount) if (toColumnIndex >= 0) if (toColumnIndex < this . columnCount) if (this . boardState [toRowIndex] [toColumnIndex] == null) if (this . getCheckerPieceCount (player, node . capturePath, node . originalRowIndex, node . originalColumnIndex, fromRowIndex, fromColumnIndex, toRowIndex, toColumnIndex) == 0) if (this . getCheckerPieceCount (otherPlayer, node . capturePath, node . originalRowIndex, node . originalColumnIndex, fromRowIndex, fromColumnIndex, toRowIndex, toColumnIndex) == 1) if (node . capturePath . indexOf ("[" + this . getCheckerPieceRow (node . capturePath, node . originalRowIndex, node . originalColumnIndex, fromRowIndex, fromColumnIndex, toRowIndex, toColumnIndex) + "," + this . getCheckerPieceColumn (node . capturePath, node . originalRowIndex, node . originalColumnIndex, fromRowIndex, fromColumnIndex, toRowIndex, toColumnIndex) + "]") == - 1) { // SEARCH FOR SUCCESSIVE JUMPS if (! node . upperRightNodes) node . upperRightNodes = new Array (); node . upperRightNodes [distanceIndex] = new Node (); node . upperRightNodes [distanceIndex] . ownerNode = node; node . upperRightNodes [distanceIndex] . upperLeftNodes = null; node . upperRightNodes [distanceIndex] . upperRightNodes = null; node . upperRightNodes [distanceIndex] . lowerLeftNodes = null; node . upperRightNodes [distanceIndex] . lowerRightNodes = null; node . upperRightNodes [distanceIndex] . rowIndex = toRowIndex; node . upperRightNodes [distanceIndex] . columnIndex = toColumnIndex; node . upperRightNodes [distanceIndex] . originalRowIndex = node . originalRowIndex; node . upperRightNodes [distanceIndex] . originalColumnIndex = node . originalColumnIndex; node . upperRightNodes [distanceIndex] . capturePath = node . capturePath + "[" + this . getCheckerPieceRow (node . capturePath, node . originalRowIndex, node . originalColumnIndex, fromRowIndex, fromColumnIndex, toRowIndex, toColumnIndex) + "," + this . getCheckerPieceColumn (node . capturePath, node . originalRowIndex, node . originalColumnIndex, fromRowIndex, fromColumnIndex, toRowIndex, toColumnIndex) + "]"; node . upperRightNodes [distanceIndex] . move = node . move + "," + toRowIndex + "," + toColumnIndex; this . scanJumps (player, node . upperRightNodes [distanceIndex]); } } // SCAN LOWER-LEFT for (distanceIndex = 0; distanceIndex < distanceLimit; distanceIndex = distanceIndex + 1) { if (player == "own") { toRowIndex = fromRowIndex + 2 + distanceIndex; toColumnIndex = fromColumnIndex - 2 - distanceIndex; } else { toRowIndex = fromRowIndex - 2 - distanceIndex; toColumnIndex = fromColumnIndex + 2 + distanceIndex; } if ((distanceIndex == 0) || (this . boardState [node . originalRowIndex] [node . originalColumnIndex] . getKingPredicate () == 1)) if (toRowIndex >= 0) if (toRowIndex < this . rowCount) if (toColumnIndex >= 0) if (toColumnIndex < this . columnCount) if (this . boardState [toRowIndex] [toColumnIndex] == null) if (this . getCheckerPieceCount (player, node . capturePath, node . originalRowIndex, node . originalColumnIndex, fromRowIndex, fromColumnIndex, toRowIndex, toColumnIndex) == 0) if (this . getCheckerPieceCount (otherPlayer, node . capturePath, node . originalRowIndex, node . originalColumnIndex, fromRowIndex, fromColumnIndex, toRowIndex, toColumnIndex) == 1) if (node . capturePath . indexOf ("[" + this . getCheckerPieceRow (node . capturePath, node . originalRowIndex, node . originalColumnIndex, fromRowIndex, fromColumnIndex, toRowIndex, toColumnIndex) + "," + this . getCheckerPieceColumn (node . capturePath, node . originalRowIndex, node . originalColumnIndex, fromRowIndex, fromColumnIndex, toRowIndex, toColumnIndex) + "]") == - 1) { // SEARCH FOR SUCCESSIVE JUMPS if (! node . lowerLeftNodes) node . lowerLeftNodes = new Array (); node . lowerLeftNodes [distanceIndex] = new Node (); node . lowerLeftNodes [distanceIndex] . ownerNode = node; node . lowerLeftNodes [distanceIndex] . upperLeftNodes = null; node . lowerLeftNodes [distanceIndex] . upperRightNodes = null; node . lowerLeftNodes [distanceIndex] . lowerLeftNodes = null; node . lowerLeftNodes [distanceIndex] . lowerRightNodes = null; node . lowerLeftNodes [distanceIndex] . rowIndex = toRowIndex; node . lowerLeftNodes [distanceIndex] . columnIndex = toColumnIndex; node . lowerLeftNodes [distanceIndex] . originalRowIndex = node . originalRowIndex; node . lowerLeftNodes [distanceIndex] . originalColumnIndex = node . originalColumnIndex; node . lowerLeftNodes [distanceIndex] . capturePath = node . capturePath + "[" + this . getCheckerPieceRow (node . capturePath, node . originalRowIndex, node . originalColumnIndex, fromRowIndex, fromColumnIndex, toRowIndex, toColumnIndex) + "," + this . getCheckerPieceColumn (node . capturePath, node . originalRowIndex, node . originalColumnIndex, fromRowIndex, fromColumnIndex, toRowIndex, toColumnIndex) + "]"; node . lowerLeftNodes [distanceIndex] . move = node . move + "," + toRowIndex + "," + toColumnIndex; this . scanJumps (player, node . lowerLeftNodes [distanceIndex]); } } // SCAN LOWER-RIGHT for (distanceIndex = 0; distanceIndex < distanceLimit; distanceIndex = distanceIndex + 1) { if (player == "own") { toRowIndex = fromRowIndex + 2 + distanceIndex; toColumnIndex = fromColumnIndex + 2 + distanceIndex; } else { toRowIndex = fromRowIndex - 2 - distanceIndex; toColumnIndex = fromColumnIndex - 2 - distanceIndex; } if ((distanceIndex == 0) || (this . boardState [node . originalRowIndex] [node . originalColumnIndex] . getKingPredicate () == 1)) if (toRowIndex >= 0) if (toRowIndex < this . rowCount) if (toColumnIndex >= 0) if (toColumnIndex < this . columnCount) if (this . boardState [toRowIndex] [toColumnIndex] == null) if (this . getCheckerPieceCount (player, node . capturePath, node . originalRowIndex, node . originalColumnIndex, fromRowIndex, fromColumnIndex, toRowIndex, toColumnIndex) == 0) if (this . getCheckerPieceCount (otherPlayer, node . capturePath, node . originalRowIndex, node . originalColumnIndex, fromRowIndex, fromColumnIndex, toRowIndex, toColumnIndex) == 1) if (node . capturePath . indexOf ("[" + this . getCheckerPieceRow (node . capturePath, node . originalRowIndex, node . originalColumnIndex, fromRowIndex, fromColumnIndex, toRowIndex, toColumnIndex) + "," + this . getCheckerPieceColumn (node . capturePath, node . originalRowIndex, node . originalColumnIndex, fromRowIndex, fromColumnIndex, toRowIndex, toColumnIndex) + "]") == - 1) { // SEARCH FOR SUCCESSIVE JUMPS if (! node . lowerRightNodes) node . lowerRightNodes = new Array (); node . lowerRightNodes [distanceIndex] = new Node (); node . lowerRightNodes [distanceIndex] . ownerNode = node; node . lowerRightNodes [distanceIndex] . upperLeftNodes = null; node . lowerRightNodes [distanceIndex] . upperRightNodes = null; node . lowerRightNodes [distanceIndex] . lowerLeftNodes = null; node . lowerRightNodes [distanceIndex] . lowerRightNodes = null; node . lowerRightNodes [distanceIndex] . rowIndex = toRowIndex; node . lowerRightNodes [distanceIndex] . columnIndex = toColumnIndex; node . lowerRightNodes [distanceIndex] . originalRowIndex = node . originalRowIndex; node . lowerRightNodes [distanceIndex] . originalColumnIndex = node . originalColumnIndex; node . lowerRightNodes [distanceIndex] . capturePath = node . capturePath + "[" + this . getCheckerPieceRow (node . capturePath, node . originalRowIndex, node . originalColumnIndex, fromRowIndex, fromColumnIndex, toRowIndex, toColumnIndex) + "," + this . getCheckerPieceColumn (node . capturePath, node . originalRowIndex, node . originalColumnIndex, fromRowIndex, fromColumnIndex, toRowIndex, toColumnIndex) + "]"; node . lowerRightNodes [distanceIndex] . move = node . move + "," + toRowIndex + "," + toColumnIndex; this . scanJumps (player, node . lowerRightNodes [distanceIndex]); } } // IF NONE OF THE LEAD-NODES ARE USED, THEN RECORD THE MOVE. if (node . ownerNode != null) if (node . upperLeftNodes == null) if (node . upperRightNodes == null) if (node . lowerLeftNodes == null) if (node . lowerRightNodes == null) this . legalJumps . push (node . move); } this . getIllegalMovePredicate = function (move) { for (var index = 0; index < this . illegalMoves . length; index = index + 1) if (this . illegalMoves [index] . indexOf (move) == 0) return (1); for (var index = 0; index < this . illegalJumps . length; index = index + 1) if (this . illegalJumps [index] . indexOf (move) == 0) return (1); return (0); } this . getLegalMovePredicate = function (move) { for (var index = 0; index < this . legalMoves . length; index = index + 1) if (this . legalMoves [index] . indexOf (move) == 0) return (1); for (var index = 0; index < this . legalJumps . length; index = index + 1) if (this . legalJumps [index] . indexOf (move) == 0) return (1); return (0); } this . getTerminalMovePredicate = function (move) { if (this . getMoveCount () == 0) return (1); for (var index = 0; index < this . legalMoves . length; index = index + 1) if (this . legalMoves [index] == move) return (1); for (var index = 0; index < this . legalJumps . length; index = index + 1) if (this . legalJumps [index] == move) return (1); return (0); } } function Checkers () { // STATE this . gameCode = null; this . ownPin = null; this . opponentPin = null; this . currentPlayerPin = null; this . rules = null; this . ownMove = null; this . opponentMove = null; this . trace = null; this . showJumpMarkers = null; this . connectingPredicate = 0; this . gameExistsPredicate = 0; this . opponentPreviousMove = null; this . midjumpPredicate = 0; this . captures = null; // INTERFACE this . division = null; this . checkerPanel = null; this . checkerBoard = null; this . cache = null; // RESOURCES this . defaultRules = null; this . americanRules = null; this . brazilianRules = null; this . canadianRules = null; this . polishRules = null; // TIME-RELATED ENTITIES this . connectTimeDelay = 0; this . connectTimeLimit = 0; this . connectTimeCount = 0; this . receiveTimeDelay = 0; this . receiveTimeLimit = 0; this . receiveTimeCount = 0; this . cachePictures = function () { this . cache = new Array (); this . cache [ 0] = new Image (); this . cache [ 0] . src = "/games/checkers/Checkers/pictures/marker.on.start.up.left.jpg"; this . cache [ 1] = new Image (); this . cache [ 1] . src = "/games/checkers/Checkers/pictures/marker.on.start.up.right.jpg"; this . cache [ 2] = new Image (); this . cache [ 2] . src = "/games/checkers/Checkers/pictures/marker.on.start.down.left.jpg"; this . cache [ 3] = new Image (); this . cache [ 3] . src = "/games/checkers/Checkers/pictures/marker.on.start.down.right.jpg"; this . cache [ 4] = new Image (); this . cache [ 4] . src = "/games/checkers/Checkers/pictures/marker.off.start.up.left.jpg"; this . cache [ 5] = new Image (); this . cache [ 5] . src = "/games/checkers/Checkers/pictures/marker.off.start.up.right.jpg"; this . cache [ 6] = new Image (); this . cache [ 6] . src = "/games/checkers/Checkers/pictures/marker.off.start.down.left.jpg"; this . cache [ 7] = new Image (); this . cache [ 7] . src = "/games/checkers/Checkers/pictures/marker.off.start.down.right.jpg"; this . cache [ 8] = new Image (); this . cache [ 8] . src = "/games/checkers/Checkers/pictures/marker.on.stop.jpg"; this . cache [ 9] = new Image (); this . cache [ 9] . src = "/games/checkers/Checkers/pictures/marker.off.stop.jpg"; this . cache [10] = new Image (); this . cache [10] . src = "/games/checkers/Checkers/pictures/marker.on.step.up.left.jpg"; this . cache [11] = new Image (); this . cache [11] . src = "/games/checkers/Checkers/pictures/marker.on.step.up.right.jpg"; this . cache [12] = new Image (); this . cache [12] . src = "/games/checkers/Checkers/pictures/marker.on.step.down.left.jpg"; this . cache [13] = new Image (); this . cache [13] . src = "/games/checkers/Checkers/pictures/marker.on.step.down.right.jpg"; this . cache [14] = new Image (); this . cache [14] . src = "/games/checkers/Checkers/pictures/marker.off.step.up.left.jpg"; this . cache [15] = new Image (); this . cache [15] . src = "/games/checkers/Checkers/pictures/marker.off.step.up.right.jpg"; this . cache [16] = new Image (); this . cache [16] . src = "/games/checkers/Checkers/pictures/marker.off.step.down.left.jpg"; this . cache [17] = new Image (); this . cache [17] . src = "/games/checkers/Checkers/pictures/marker.off.step.down.right.jpg"; this . cache [18] = new Image (); this . cache [18] . src = "/games/checkers/Checkers/pictures/marker.on.capture.jpg"; this . cache [19] = new Image (); this . cache [19] . src = "/games/checkers/Checkers/pictures/marker.off.capture.jpg"; this . cache [20] = new Image (); this . cache [20] . src = "/games/checkers/Checkers/pictures/piece.primary.soldier.png"; this . cache [21] = new Image (); this . cache [21] . src = "/games/checkers/Checkers/pictures/piece.primary.king.png"; this . cache [22] = new Image (); this . cache [22] . src = "/games/checkers/Checkers/pictures/piece.secondary.soldier.png"; this . cache [23] = new Image (); this . cache [23] . src = "/games/checkers/Checkers/pictures/piece.secondary.king.png"; this . cache [24] = new Image (); this . cache [24] . src = "/games/checkers/Checkers/pictures/piece.primary.soldier.gif"; this . cache [25] = new Image (); this . cache [25] . src = "/games/checkers/Checkers/pictures/piece.primary.king.gif"; this . cache [26] = new Image (); this . cache [26] . src = "/games/checkers/Checkers/pictures/piece.secondary.soldier.gif"; this . cache [27] = new Image (); this . cache [27] . src = "/games/checkers/Checkers/pictures/piece.secondary.king.gif"; this . cache [28] = new Image (); this . cache [28] . src = "/games/checkers/Checkers/pictures/piece.primary.soldier.png"; this . cache [29] = new Image (); this . cache [29] . src = "/games/checkers/Checkers/pictures/piece.primary.king.png"; this . cache [30] = new Image (); this . cache [30] . src = "/games/checkers/Checkers/pictures/piece.secondary.soldier.png"; this . cache [31] = new Image (); this . cache [31] . src = "/games/checkers/Checkers/pictures/piece.secondary.king.png"; this . cache [32] = new Image (); this . cache [32] . src = "/games/checkers/Checkers/pictures/piece.primary.soldier.gif"; this . cache [33] = new Image (); this . cache [33] . src = "/games/checkers/Checkers/pictures/piece.primary.king.gif"; this . cache [34] = new Image (); this . cache [34] . src = "/games/checkers/Checkers/pictures/piece.secondary.soldier.gif"; this . cache [35] = new Image (); this . cache [35] . src = "/games/checkers/Checkers/pictures/piece.secondary.king.gif"; this . cache [36] = new Image (); this . cache [36] . src = "/games/checkers/Checkers/pictures/marker.on.dot.jpg"; this . cache [37] = new Image (); this . cache [37] . src = "/games/checkers/Checkers/pictures/marker.off.dot.jpg"; } this . initiate = function () { this . division = documentObjectModel . createNode ("div"); this . checkerPanel = new CheckerPanel (); this . checkerPanel . initiate (); this . checkerBoard = new CheckerBoard (); this . checkerBoard . initiate (); this . defaultRules = new Rules (); this . defaultRules . initiate (); this . americanRules = new AmericanRules (); this . americanRules . initiate (); this . brazilianRules = new BrazilianRules (); this . brazilianRules . initiate (); this . canadianRules = new CanadianRules (); this . canadianRules . initiate (); this . polishRules = new PolishRules (); this . polishRules . initiate (); this . cachePictures (); } this . initialize = function () { this . gameCode = null; this . opponentPreviousMove = ""; this . connectTimeLimit = 180000; this . connectTimeDelay = 4000; this . connectTimeCount = 0; this . receiveTimeLimit = 120000; this . receiveTimeDelay = 500; this . receiveTimeCount = 0; this . division . id = "Checkers"; this . division . style . position = "relative"; this . division . style . height = "400px"; this . division . style . width = (175 + 8 * 50) + "px"; this . division . style . marginLeft = "-" + ((175 + 8 * 50) / 2) + "px"; this . division . style . left = "50%"; this . checkerPanel . initialize (); this . checkerBoard . initialize (); this . defaultRules . initialize (); this . americanRules . initialize (); this . brazilianRules . initialize (); this . canadianRules . initialize (); this . polishRules . initialize (); this . checkerPanel . that = this; this . checkerBoard . that = this; this . setRules ("default"); } this . start = function () { this . checkerPanel . displayOpponentPlayerTypePrompt (this . setOpponentPlayerTypeDelegate); return; }; this . recordGame = function (winnerTitle) { var gameName; var styleName; var opponentType; // Only the primary player is to record a game. if (this . playerRank . toLowerCase () == "primary") { gameName = "Checkers"; if (this . styleName . toLowerCase () == "default") { styleName = "default"; } else if (this . styleName . toLowerCase () == "international") { styleName = "International"; } else if (this . styleName . toLowerCase () == "american") { styleName = "American"; } else if (this . styleName . toLowerCase () == "brazilian") { styleName = "Brazilian"; } else if (this . styleName . toLowerCase () == "canadian") { styleName = "Canadian"; } else if (this . styleName . toLowerCase () == "polish") { styleName = "Polish"; } else { styleName = ""; } if (this . opponentPlayerType == "virtual") { opponentType = "virtual"; } else { opponentType = "actual"; } if (winnerTitle . toLowerCase () == "primary") { winnerTitle = "primary"; } else if (winnerTitle . toLowerCase () == "secondary") { winnerTitle = "secondary"; } else { winnerTitle = ""; } networkSocket . execute ("/games/checkers/Checkers/php" + "/" + "recordGame" + "." + "p" + "h" + "p?refreshCode=" + getRefreshCode () + "&gameName=" + gameName + "&styleName=" + styleName + "&opponentType=" + opponentType + "&winnerTitle=" + winnerTitle); } return; }; this . setOpponentPlayerTypeDelegate = function (opponentPlayerType) { if (opponentPlayerType == "virtual") { checkers . opponentPlayerType = opponentPlayerType; checkers . checkerPanel . hideOpponentPlayerTypePrompt (); checkers . activateKayla (); } else { checkers . opponentPlayerType = opponentPlayerType; checkers . checkerPanel . hideOpponentPlayerTypePrompt (); checkers . checkerPanel . displayPinPrompt (checkers . ownPin, checkers . setOpponentPinDelegate); checkers . checkerPanel . opponentPinArea . focus (); } return; }; this . activateKayla = function () { kayla = new Kayla (); kayla . initialize (); this . ownPin = "0000"; // fake pin -- allow the guest to move first this . opponentPin = "0001"; // fake pin -- allow the guest to move first this . playerRank = "primary"; // Forced. this . checkerPanel . showPlayerMessage (this . playerRank); this . checkerPanel . displayRulesPrompt (this . setRulesDelegate); return; }; this . setOpponentPinDelegate = function (pin) { checkers . setOpponentPin (pin); return; }; this . setOpponentPin = function (pin) { if (this . connectingPredicate == 1) return; this . connectingPredicate = 1; this . opponentPin = pin; this . checkerPanel . showPins (this . ownPin, this . opponentPin); messageBox . addMessage ("Events", "Connecting: " + this . opponentPin); if (this . opponentPlayerType == "actual") { networkSocket . execute ("/games/checkers/Checkers/php/connect.php?refreshcode=" + getRefreshCode () + "&ownPin=" + this . ownPin + "&opponentPin=" + this . opponentPin); } this . connectTimeCount = 0; this . connect (); } this . connect = function () { this . checkerPanel . setMessage ("low", "connecting"); if (this . connectTimeCount > this . connectTimeLimit) { this . connectTimeCount = 0; this . checkerPanel . setMessage ("high", "continue?"); this . checkerPanel . showOkayButton ("checkers . connect ()"); } else if (this . gameCode == null) // IF NOT CONNECTED, THEN FIND OUT IF A CONNECTION HAS BEEN MADE. { if (this . opponentPlayerType == "actual") { networkSocket . execute ("/games/checkers/Checkers/php/getGameCode.php?refreshcode=" + getRefreshCode () + "&ownPin=" + this . ownPin + "&opponentPin=" + this . opponentPin); } setTimeout ("checkers . connect ()", this . connectTimeDelay); this . connectTimeCount = this . connectTimeCount + this . connectTimeDelay; } else { this . checkerPanel . showPlayerMessage (this . playerRank); if (this . playerRank == "primary") { this . showJumpMarkers = true; this . checkerPanel . displayRulesPrompt (this . setRulesDelegate); } else { messageBox . addMessage ("Events", "Asking for the rules."); this . showJumpMarkers = false; this . checkerBoard . reverse (); this . checkerBoard . update (); this . receiveTimeCount = 0; this . getRules (); } } } this . setRulesDelegate = function (rules) { checkers . setRules (rules); checkers . startTurn (); } this . setRules = function (rulesName) { this . styleName = rulesName; checkers . gameExistsPredicate = 1; if (this . rules) if (this . rules != this . defaultRules) return; if (rulesName != "default") { if (this . playerRank == "primary") messageBox . addMessage ("Events", "Sending the rules: " + rulesName); if (this . opponentPlayerType == "actual") { networkSocket . execute ("/games/checkers/Checkers/php/setRulesName.php?refreshcode=" + getRefreshCode () + "&gameCode=" + this . gameCode + "&ownPin=" + this . ownPin + "&opponentPin=" + this . opponentPin + "&rulesName=" + rulesName); } this . checkerPanel . showRulesName (rulesName); } if (rulesName == "default") this . rules = this . defaultRules; if (rulesName == "International") this . rules = this . polishRules; if (rulesName == "American") this . rules = this . americanRules; if (rulesName == "Brazilian") this . rules = this . brazilianRules; if (rulesName == "Canadian") this . rules = this . canadianRules; if (rulesName == "Polish") this . rules = this . polishRules; this . division . style . width = (2 + 200 + this . rules . getColumnCount () * (this . checkerBoard . squareWidth + this . checkerBoard . borderThickness)) + "px"; this . division . style . marginLeft = "-" + ((2 + 200 + this . rules . getColumnCount () * (this . checkerBoard . squareWidth + this . checkerBoard . borderThickness)) / 2) + "px"; documentObjectModel . getNode ("game") . style . height = (this . rules . getRowCount () * (this . checkerBoard . squareHeight + this . checkerBoard . borderThickness)) + "px"; this . checkerPanel . setRowPixelCount (this . rules . getRowCount () * (this . checkerBoard . squareHeight + this . checkerBoard . borderThickness) - 1); this . checkerBoard . setBoardState (this . rules . getBoardState (), this . playerRank); } this . getRules = function () { this . checkerPanel . setMessage ("low", "waiting for your friend to select the rules"); if (this . receiveTimeCount > this . receiveTimeLimit) { this . receiveTimeCount = 0; this . checkerPanel . setMessage ("high", "continue?"); this . checkerPanel . showOkayButton ("checkers . getRules ()"); } else if (this . rulesName == null) // IF NOT CONNECTED, THEN FIND OUT IF A CONNECTION HAS BEEN MADE. { if (this . opponentPlayerType == "actual") { networkSocket . execute ("/games/checkers/Checkers/php/getRulesName.php?refreshcode=" + getRefreshCode () + "&gameCode=" + this . gameCode + "&ownPin=" + this . ownPin + "&opponentPin=" + this . opponentPin); } setTimeout ("checkers . getRules ()", this . receiveTimeDelay); this . receiveTimeCount = this . receiveTimeCount + this . receiveTimeDelay; } else { messageBox . addMessage ("Events", "Received the rules: " + this . rulesName); this . setRules (this . rulesName); this . endTurn (); } } this . startTurn = function () { this . showJumpMarkers = true; this . checkerPanel . showCaptures (this . captures); this . ownMove = null; this . midjumpPredicate = 0; this . rules . evaluate ("own"); if (this . rules . getMoveCount () == 0) { this . recordGame ("secondary"); if (this . opponentPlayerType == "virtual") { this . checkerPanel . setMessage ("high", "The machine won. Thank you for playing."); } else { this . checkerPanel . setMessage ("high", "Your friend won. Thank you for playing."); } this . checkerBoard . disconnectEventCues (); } else { this . checkerBoard . connectEventCues (); this . checkerPanel . setMessage ("medium", "your turn"); } } this . endTurn = function () { this . showJumpMarkers = false; this . checkerPanel . hideCaptures (); this . captures = null; this . opponentMove = null; this . checkerBoard . hideMarkers (); this . rules . evaluate ("opponent"); if (this . rules . getMoveCount () == 0) { this . recordGame ("primary"); this . checkerPanel . setMessage ("high", "congratulations!"); this . checkerBoard . disconnectEventCues (); } else { this . checkerBoard . disconnectEventCues (); this . receiveTimeCount = 0; if (this . opponentPlayerType == "virtual") { this . checkerPanel . setMessage ("low", "machine's turn"); } else { this . checkerPanel . setMessage ("low", "your friend's turn"); } messageBox . addMessage ("Events", "Asking for the opponent's move."); setTimeout ("checkers . getMove ();", 1000); } } this . setMove = function (fromRowIndex, fromColumnIndex, toRowIndex, toColumnIndex) { this . checkerBoard . hideMarkers (); this . checkerBoard . boardState [toRowIndex] [toColumnIndex] = this . checkerBoard . boardState [fromRowIndex] [fromColumnIndex]; this . checkerBoard . boardState [fromRowIndex] [fromColumnIndex] = null; if ((this . ownMove == null) || (this . ownMove == "")) this . captures = new Array (); this . captureCheckerPiece (fromRowIndex, fromColumnIndex, toRowIndex, toColumnIndex); this . ownMove = (this . ownMove ? this . ownMove : fromRowIndex + "," + fromColumnIndex) + "," + toRowIndex + "," + toColumnIndex; this . opponentMove = null; if (this . rules . getTerminalMovePredicate (this . ownMove)) { messageBox . addMessage ("Events", "Sending the move: " + this . ownMove); var ownMoveArray = this . ownMove . split (","); if (ownMoveArray [ownMoveArray . length - 2] == 0) this . checkerBoard . boardState [ownMoveArray [ownMoveArray . length - 2]] [ownMoveArray [ownMoveArray . length - 1]] . setKingPredicate (1); if (this . opponentPlayerType == "actual") { networkSocket . execute ("/games/checkers/Checkers/php/setMove.php?refreshcode=" + getRefreshCode () + "&gameCode=" + this . gameCode + "&ownPin=" + this . ownPin + "&opponentPin=" + this . opponentPin + "&move=" + this . ownMove); } this . endTurn (); } else { messageBox . addMessage ("Events", "Setting the move: " + this . ownMove); this . midjumpPredicate = 1; this . checkerBoard . connectEventCues (); } } this . getMove = function () { if (this . gameExistsPredicate == 0) { this . checkerPanel . setMessage ("high", "this game is no longer active"); return; } if (this . opponentPlayerType == "virtual") { this . checkerPanel . setMessage ("low", "machine's turn"); } else { this . checkerPanel . setMessage ("low", "your friend's turn"); } if (this . receiveTimeCount > this . receiveTimeLimit) { this . receiveTimeCount = 0; this . checkerPanel . setMessage ("high", "continue?"); this . checkerPanel . showOkayButton ("checkers . getMove ()"); } else if (this . opponentMove == this . opponentPreviousMove) { // SENDMOVE FAILED, SO RESEND IT. this . opponentMove = null; messageBox . addMessage ("Events", "Resending move: " + this . ownMove); messageBox . addMessage ("Warnings", "Network Error\nThe move had to be resent: " + this . ownMove); if (this . opponentPlayerType == "actual") { networkSocket . execute ("/games/checkers/Checkers/php/setMove.php?refreshcode=" + getRefreshCode () + "&gameCode=" + this . gameCode + "&ownPin=" + this . ownPin + "&opponentPin=" + this . opponentPin + "&move=" + this . ownMove); } this . receiveTimeCount = this . receiveTimeCount + this . receiveTimeDelay; setTimeout ("checkers . getMove ()", this . receiveTimeDelay); } else if ((this . opponentMove == null) || (this . opponentMove == this . ownMove)) { if (this . opponentPlayerType == "actual") { networkSocket . execute ("/games/checkers/Checkers/php/getMove.php?refreshcode=" + getRefreshCode () + "&gameCode=" + this . gameCode + "&ownPin=" + this . ownPin + "&opponentPin=" + this . opponentPin); } this . receiveTimeCount = this . receiveTimeCount + this . receiveTimeDelay; setTimeout ("checkers . getMove ()", this . receiveTimeDelay); } else { this . getMovePredicate = 0; messageBox . addMessage ("Events", "Received the opponents move: " + this . opponentMove); this . opponentPreviousMove = this . opponentMove; this . trace = ""; var opponentMoveArray = this . opponentMove . split (","); // DUPLICATE THE OPPONENT'S MOVE ON THIS BOARD. this . captures = new Array (); for (var index = 0; index < (opponentMoveArray . length - 2); index = index + 2) { var fromRowIndex = parseInt (opponentMoveArray [index + 0]); var fromColumnIndex = parseInt (opponentMoveArray [index + 1]); var toRowIndex = parseInt (opponentMoveArray [index + 2]); var toColumnIndex = parseInt (opponentMoveArray [index + 3]); this . trace = this . trace + (this . trace == "" ? "" : ",") + fromRowIndex + "," + fromColumnIndex; this . captureCheckerPiece (fromRowIndex, fromColumnIndex, toRowIndex, toColumnIndex); this . checkerBoard . boardState [toRowIndex] [toColumnIndex] = this . checkerBoard . boardState [fromRowIndex] [fromColumnIndex]; this . checkerBoard . boardState [fromRowIndex] [fromColumnIndex] = null; } this . trace = this . trace + (this . trace == "" ? "" : ",") + parseInt (opponentMoveArray [opponentMoveArray . length - 2]) + "," + parseInt (opponentMoveArray [opponentMoveArray . length - 1]); // IF THE OPPONENT REACHED KINGS ROW ON THEIR LAST JUMP OR MOVE, THEN KING THEM. if (opponentMoveArray [opponentMoveArray . length - 2] == (this . rules . getRowCount () - 1)) this . checkerBoard . boardState [opponentMoveArray [opponentMoveArray . length - 2]] [opponentMoveArray [opponentMoveArray . length - 1]] . setKingPredicate (1); this . checkerBoard . showMarkers (this . trace); this . checkerBoard . update (); this . startTurn (); } } this . captureCheckerPiece = function (fromRowIndex, fromColumnIndex, toRowIndex, toColumnIndex) { var rowStep = 0; var columnStep = 0; if (fromRowIndex < toRowIndex) rowStep = 1; if (fromRowIndex > toRowIndex) rowStep = - 1; if (fromColumnIndex < toColumnIndex) columnStep = 1; if (fromColumnIndex > toColumnIndex) columnStep = - 1; var rowIndex = fromRowIndex + rowStep; var columnIndex = fromColumnIndex + columnStep; var index = 0; var initialValue = 0; var rowLimit = fromRowIndex < toRowIndex ? toRowIndex - fromRowIndex - 1 : fromRowIndex - toRowIndex - 1; var columnLimit = fromColumnIndex < toColumnIndex ? toColumnIndex - fromColumnIndex - 1 : fromColumnIndex - toColumnIndex - 1; var limit = rowLimit > columnLimit ? rowLimit : columnLimit; for (index = initialValue; index < limit; index = index + 1) { // LET THE PLAYER KNOW WHICH PIECE WAS CAPTURED, IF ANY. if (this . checkerBoard . boardState [rowIndex] [columnIndex] != null) if (this . checkerBoard . boardState [rowIndex] [columnIndex] . getKingPredicate () == 0) this . captures . push ("Soldier"); if (this . checkerBoard . boardState [rowIndex] [columnIndex] != null) if (this . checkerBoard . boardState [rowIndex] [columnIndex] . getKingPredicate () == 1) this . captures . push ("King"); if (this . checkerBoard . boardState [rowIndex] [columnIndex]) this . trace = this . trace + (this . trace == "" ? "" : ",") + "" + rowIndex + "x," + columnIndex + "x"; if (this . checkerBoard . boardState [rowIndex] [columnIndex]) this . checkerBoard . boardState [rowIndex] [columnIndex] . getNode () . style . display = "none"; this . checkerBoard . boardState [rowIndex] [columnIndex] = null; rowIndex = rowIndex + rowStep; columnIndex = columnIndex + columnStep; } if (this . showJumpMarkers == true) {this . checkerBoard . showJumpMarkers (this . trace);} this . checkerBoard . update (); } this . getNode = function () { return (this . division); } this . render = function (renderNode) { documentObjectModel . appendNode (renderNode, this . getNode ()); this . checkerPanel . render (this . getNode ()); this . checkerBoard . render (this . getNode ()); } this . setOwnPin = function (pin) { this . ownPin = pin; } } var kayla = null; var checkers = null; var checkersAreaNode = null; var internetClient = null; var documentObjectModel = null; var networkSocket = null; var messageBox = null; var setupCheckers = function () { var documentObjectModel = new DocumentObjectModel (); documentObjectModel . initiate (); documentObjectModel . initialize (); var division = documentObjectModel . createNode ("div"); var span = documentObjectModel . createNode ("span"); var link = documentObjectModel . createNode ("a"); division . style . color = "#545f36"; division . style . textAlign = "center"; span . style . fontSize = "18px"; span . style . borderTop = "#757e87 0px solid"; span . style . display = "block"; span . style . width = "100%"; span . style . color = "#3e4625"; link . style . color = "#545f36"; link . target = "_blank"; link . href = "http://www.mozilla.com/firefox"; documentObjectModel . appendNode (documentObjectModel . getNode ("game"), division); documentObjectModel . appendNode (division, span); documentObjectModel . appendNode (division, documentObjectModel . createNode ("br")); if (navigator . userAgent . indexOf ("MSIE") != - 1) { documentObjectModel . appendNode (division, documentObjectModel . createTextNode ("Internet Explorer requires additional time to initialize the game.")); // documentObjectModel . appendNode (division, documentObjectModel . createTextNode ("Internet Explorer requires extra time to initialize the game.")); // documentObjectModel . appendNode (division, documentObjectModel . createNode ("br")); // documentObjectModel . appendNode (division, documentObjectModel . createTextNode ("Internet Explorer also requires extra time to start the game, so please be patient.")); // documentObjectModel . appendNode (division, documentObjectModel . createNode ("br")); // documentObjectModel . appendNode (division, documentObjectModel . createTextNode ("Please consider using ")); // documentObjectModel . appendNode (division, link); // documentObjectModel . appendNode (division, documentObjectModel . createTextNode (".")); // documentObjectModel . appendNode (division, documentObjectModel . createNode ("br")); } documentObjectModel . appendNode (span, documentObjectModel . createTextNode ("loading ...")); // documentObjectModel . appendNode (link, documentObjectModel . createTextNode ("Firefox")); setTimeout ("initializeCheckers ();", 500); } var initializeCheckers = function () { messageBox = new Development . MessageBox (); messageBox . initiate (); documentObjectModel = new DocumentObjectModel (); documentObjectModel . initiate (); documentObjectModel . initialize (); networkSocket = new NetworkSocket (); networkSocket . initiate (); networkSocket . initialize (); checkersAreaNode = documentObjectModel . getNode ("game"); checkers = new Checkers (); checkers . initiate (); checkers . initialize (); checkers . setOwnPin ('2596'); documentObjectModel . getNode ("game") . style . textAlign = "left"; documentObjectModel . clearNodes (checkersAreaNode); checkers . render (checkersAreaNode); checkers . start (); checkers . checkerPanel . opponentPinArea . focus (); checkersAreaNode = null; } var getRefreshCode = function () { var date = new Date (); var refreshCode = ""; refreshCode = refreshCode + getPaddedText (date . getUTCFullYear () , "0", 4); refreshCode = refreshCode + getPaddedText (date . getUTCMonth () , "0", 2); refreshCode = refreshCode + getPaddedText (date . getUTCDay () , "0", 2); refreshCode = refreshCode + getPaddedText (date . getUTCHours () , "0", 2); refreshCode = refreshCode + getPaddedText (date . getUTCMinutes () , "0", 2); refreshCode = refreshCode + getPaddedText (date . getUTCSeconds () , "0", 2); refreshCode = refreshCode + getPaddedText (date . getUTCMilliseconds () , "0", 3); return (refreshCode); } var getPaddedText = function (text, padCharacter, characterCount) { text = text . toString (); while (text . length < characterCount) text = padCharacter + "" + text; return (text); }