Advertisement
Guest User

Untitled

a guest
Dec 28th, 2016
83
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C# 53.55 KB | None | 0 0
  1. /////////////////////////////// THEMES.cs ///////////////////////////////
  2. // theme id and path to theme build
  3. $Chess::Themes::DEFAULT = 0;
  4. $Chess::Themes["default"] = $Chess::Themes::DEFAULT;
  5. $Chess::buildName[$Chess::Themes::DEFAULT] = "chessboard";
  6.  
  7. // theme datablock set (must be in order: rook knight bishop queen king bishop knight rook pawn)
  8. $Chess::datablockSet[$Chess::Themes::DEFAULT] = "rookItem knightItem bishopItem queenItem kingItem bishopItem knightItem rookItem pawnItem";
  9. for(%pieceId = 0; %pieceId < 8; %pieceId++)
  10. {
  11.     $Chess::DB[$Chess::Themes::DEFAULT, %pieceId]       = getWord($Chess::datablockSet[$Chess::Themes::DEFAULT], %pieceId);
  12.     $Chess::DB[$Chess::Themes::DEFAULT, %pieceId + 8]   = getWord($Chess::datablockSet[$Chess::Themes::DEFAULT], 8);
  13. }
  14.  
  15. // theme tile colors and colorfx
  16. $Chess::lightTileColorId[$Chess::Themes::DEFAULT] = 4;
  17. $Chess::darkTileColorId[$Chess::Themes::DEFAULT] = 16;
  18. $Chess::selectionColorId[$Chess::Themes::DEFAULT] = 29;
  19. $Chess::selectionColorFxId[$Chess::Themes::DEFAULT] = 3;
  20. $Chess::selectionEmitter[$Chess::Themes::DEFAULT] = "PlayerTeleportEmitterB";
  21. $Chess::lightAvailableMoveColorId[$Chess::Themes::DEFAULT] = 34;
  22. $Chess::darkAvailableMoveColorId[$Chess::Themes::DEFAULT] = 35;
  23. $Chess::availableMoveColorFxId[$Chess::Themes::DEFAULT] = 3;
  24. $Chess::checkColorId[$Chess::Themes::DEFAULT] = 11;
  25.  
  26.  
  27.  
  28.  
  29.  
  30.  
  31. $Chess::Themes::FUTURISTIC = 1;
  32. $Chess::Themes["futuristic"] = $Chess::Themes::FUTURISTIC;
  33. $Chess::buildName[$Chess::Themes::FUTURISTIC] = "futurechess3";
  34.  
  35. // theme datablock set (must be in order: rook knight bishop queen king bishop knight rook pawn)
  36. $Chess::datablockSet[$Chess::Themes::FUTURISTIC] = "rook_battleItem knight_battleItem bishop_battleItem queen_battleItem king_battleItem bishop_battleItem knight_battleItem rook_battleItem pawn_battleItem";
  37. for(%pieceId = 0; %pieceId < 8; %pieceId++)
  38. {
  39.     $Chess::DB[$Chess::Themes::FUTURISTIC, %pieceId]        = getWord($Chess::datablockSet[$Chess::Themes::FUTURISTIC], %pieceId);
  40.     $Chess::DB[$Chess::Themes::FUTURISTIC, %pieceId + 8]    = getWord($Chess::datablockSet[$Chess::Themes::FUTURISTIC], 8);
  41. }
  42.  
  43. // theme tile colors and colorfx
  44. $Chess::lightTileColorId[$Chess::Themes::FUTURISTIC] = 4;
  45. $Chess::darkTileColorId[$Chess::Themes::FUTURISTIC] = 16;
  46. $Chess::selectionColorId[$Chess::Themes::FUTURISTIC] = 30;
  47. $Chess::selectionColorFxId[$Chess::Themes::FUTURISTIC] = 3;
  48. $Chess::selectionEmitter[$Chess::Themes::FUTURISTIC] = "PlayerTeleportEmitterB";
  49. $Chess::lightAvailableMoveColorId[$Chess::Themes::FUTURISTIC] = 34;
  50. $Chess::darkAvailableMoveColorId[$Chess::Themes::FUTURISTIC] = 35;
  51. $Chess::availableMoveColorFxId[$Chess::Themes::FUTURISTIC] = 3;
  52. $Chess::checkColorId[$Chess::Themes::FUTURISTIC] = 11;
  53.  
  54. /////////////////////////////////////////////////////////////////////////
  55.  
  56. $Chess::letters = "abcdefgh";
  57. $Chess::timePerTurn = 500000;
  58. $Chess::lastoffset = "-100 -140 0";
  59. $Chess::offsetAmount = "-40 0 0";
  60.  
  61. function startChessGame(%client1, %client2, %theme)
  62. {
  63.     // one of the clients doesnt exist
  64.     if(!isObject(%client1) || !isObject(%client2))
  65.         return;
  66.  
  67.     if(%theme $= "")
  68.     {
  69.         talk("No theme given. Using default theme.");
  70.         %theme = $Chess::THEMES::DEFAULT;
  71.     }
  72.  
  73.     //create the game and load the board
  74.     %chessGame = chess_createGame(%client1, %client2, %theme);
  75.  
  76.     // find position to load chess board (still gotta implement func)
  77.     %boardPos = %chessGame.getOffset();
  78.     talk("loading chess board at " @ %boardPos);
  79.  
  80.     %chessGame.createBoard(%boardPos);
  81.     %chessGame.schedule(300, initialize);
  82.  
  83.     // move players there somehow
  84.     %whiteTransform = %chessGame.getBrick("whitespawn").position SPC "0 0 1" SPC $pi/2;
  85.     %blackTransform = %chessGame.getBrick("blackspawn").position SPC "0 0 1" SPC -$pi/2;
  86.  
  87.     %client1.boardGameSpawn = %whiteTransform;
  88.     %client1.inBoardGame = true;
  89.     %client1.boardGame = %chessGame;
  90.     %client1.color = "white";
  91.  
  92.     %client2.boardGameSpawn = %blackTransform;
  93.     %client2.inBoardGame = true;
  94.     %client2.boardGame = %chessGame;
  95.     %client2.color = "black";
  96.  
  97.     %client1.schedule(2000, spawnPlayer);
  98.     %client2.schedule(2000, spawnPlayer);
  99. }
  100.  
  101. function chess_createGame(%client1, %client2, %theme)
  102. {
  103.     %chessGame = new ScriptObject(ChessGame)
  104.     {
  105.         theme = %theme;
  106.         light = %client1;
  107.         dark = %client2;
  108.         player0 = %client1;
  109.         player1 = %client2;
  110.         currentTurn = %client1;
  111.  
  112.         selectedPieceId = -1;
  113.         selectedTile = "";
  114.         potentialMoves = "";
  115.     };
  116.  
  117.     %id = getNextGameBrickgroupId();
  118.     %chessGame.brickGroup = new SimGroup("BrickGroup_" @ %id);
  119.     %chessGame.brickGroup.bl_id = %id;
  120.     %chessGame.brickGroup.ispublicdomain = 0;
  121.     %chessGame.brickGroup.name = "Dope ass chess game: " @ %client1.name SPC "VS" SPC %client2.name;
  122.     mainBrickGroup.add(%chessGame.brickGroup);
  123.  
  124.     return %chessGame;
  125. }
  126.  
  127. function ChessGame::createBoard(%this, %pos)
  128. {
  129.     // get the name of the build
  130.     if((%buildName = $Chess::buildName[%this.theme]) $= "")
  131.     {
  132.         talk("Unable to find the build name for theme: " @ %this.theme @ ". Using the default build");
  133.         %buildName = $Chess::buildName[$Chess::Themes::DEFAULT];
  134.     }
  135.  
  136.     // load it in with the games brickgroup used
  137.     while(!loadBuild(%pos, %buildName, %this.brickGroup))
  138.     {
  139.         %pos = %this.getOffset();
  140.         %this.brickGroup.deleteAll();
  141.     }
  142.  
  143.     // record the original color and colorfx of each brick
  144.     %count = %this.brickGroup.getCount();
  145.     for(%i = 0; %i < %count; %i++)
  146.     {
  147.         %obj = %this.brickGroup.getObject(%i);
  148.         %obj.originalColor = %obj.getColorId();
  149.         %obj.originalColorFx = %obj.getColorFxId();
  150.     }
  151. }
  152.  
  153. function ChessGame::endGame(%this, %type)
  154. {
  155.     if (%type == 3) {
  156.         chatMessageAll('', "\c3" @ %this.player0.name @ "\c5 and \c3" @ %this.player1.name @ "\c5 have tied at \c3Chess\c5!");
  157.         %this.player0.chessTies++;
  158.         %this.player1.chessTies++;
  159.         $Pref::Server::BoardGames::ChessTies += 2;
  160.     } else if (%type == 1) {
  161.         chatMessageAll('', "\c3" @ %this.player1.name @ "\c5 has beaten \c3" @ %this.player0.name @ "\c5 at \c3Chess\c5!");
  162.         %this.player0.chessLosses++;
  163.         %this.player1.chessWins++;
  164.         $Pref::Server::BoardGames::chessWins++;
  165.         $Pref::Server::BoardGames::chessLosses++;
  166.     } else if (%type == 0) {
  167.         chatMessageAll('', "\c3" @ %this.player0.name @ "\c5 has beaten \c3" @ %this.player1.name @ "\c5 at \c3Chess\c5!");
  168.         %this.player0.chessWins++;
  169.         %this.player1.chessLosses++;
  170.         $Pref::Server::BoardGames::ChessWins++;
  171.         $Pref::Server::BoardGames::ChessLosses++;
  172.     } else if (%type < 0){
  173.         chatMessageAll('', "\c3" @ %this.player1.name @ "\c5 and \c3" @ %this.player0.name @ "\c5 have quit their \c3Chess\c5 game.");
  174.     }
  175.  
  176.     cancel(%this.turnTimer);
  177.     %this.hasEnded = true;
  178.  
  179.     %client1 = %this.light;
  180.     %client2 = %this.dark;
  181.  
  182.     %client1.boardGameSpawn = "";
  183.     %client1.inBoardGame = false;
  184.     %client1.boardGame = 0;
  185.     %client1.color = "";
  186.  
  187.     %client2.boardgmaeSpawn = "";
  188.     %client2.inBoardGame = false;
  189.     %client2.boardGame = 0;
  190.     %client2.color = "";
  191.  
  192.     %this.finished = true;
  193.     %this.currentTurn = -1;
  194.  
  195.     %this.schedule(10000, postEndGame);
  196. }
  197.  
  198. function ChessGame::postEndGame(%this)
  199. {
  200.     %this.light.spawnPlayer();
  201.     %this.dark.spawnPlayer();
  202.     chainKillBrickGroup(%this.brickGroup, %this.brickGroup.getCount());
  203.     %this.delete();
  204. }
  205.  
  206. function ChessGame::initialize(%this)
  207. {
  208.     // for each piece id, set the intial values and get the datablocks
  209.     for(%pieceId = 0; %pieceId < 16; %pieceId++)
  210.     {
  211.         %location1 = %this.tileFrom("a1", %pieceId % 8, mFloor(%pieceId / 8));
  212.         %location2 = %this.tileFrom("a8", %pieceId % 8, -mFloor(%pieceId / 8));
  213.  
  214.         %this.addPiece(%this.light, %pieceId, %location1);
  215.         %this.addPiece(%this.dark, %pieceId, %location2);
  216.     }
  217.  
  218.     // In order to get the initial moves for each player, we have to call this
  219.     %this.doLogic();
  220. }
  221.  
  222. function ChessGame::getOffset(%this)
  223. {
  224.     $Chess::lastOffset = vectorAdd($Chess::lastOffset, $Chess::offsetAmount);
  225.     return vectorSub($Chess::lastOffset, $Othello::Chess);
  226. }
  227.  
  228. function ChessGame::resetBoard(%this)
  229. {
  230.     %this.clearBoard();
  231.     %this.clearHighlightedTiles();
  232.     %this.initialize();
  233.  
  234.     %this.currentTurn = %this.light;
  235. }
  236.  
  237. function ChessGame::clearBoard(%this)
  238. {
  239.     %count = %this.brickGroup.getCount();
  240.  
  241.     for(%i = 0; %i < %count; %i++)
  242.         %this.brickGroup.getObject(%i).setItem("");
  243. }
  244.  
  245. function ChessGame::getMoveCount(%this, %client, %piece)
  246. {
  247.     return %this.moveCount[%client, %piece];
  248. }
  249.  
  250. function ChessGame::getPieceLocation(%this, %client, %piece)
  251. {
  252.     return %this.pieceLocation[%client, %piece];
  253. }
  254.  
  255. function ChessGame::isPieceAlive(%this, %client, %piece)
  256. {
  257.     return %this.pieceAlive[%client, %piece];
  258. }
  259.  
  260. function ChessGame::getOwnerOfPiece(%this, %piece)
  261. {
  262.     return strStr(%piece.dataBlock.getName(), "white") != -1 ? %this.light : %this.dark;
  263. }
  264.  
  265. function ChessGame::getDB(%this, %client, %pieceId)
  266. {
  267.     return %client.color @ "_" @ $Chess::DB[%this.theme, %pieceId];
  268. }
  269.  
  270. function ChessGame::getColorDirection(%this, %color)
  271. {
  272.     return %color $= "white" ? $Chess::EAST : $Chess::WEST;
  273. }
  274.  
  275. // location here is just name of the brick
  276. function ChessGame::getBrick(%this, %location)
  277. {
  278.     return %this.brickGroup.ntObject["", %location, 0];
  279. }
  280.  
  281. function ChessGame::getPieceAt(%this, %location)
  282. {
  283.     if(!isObject(%b = %this.getBrick(%location)))
  284.         return 0;
  285.  
  286.     if(!isObject(%b.item))
  287.         return 0;
  288.  
  289.     return %b.item;
  290. }
  291.  
  292. function ChessGame::validMove(%this, %client, %pieceId, %desiredSpot)
  293. {
  294.     return strStr(%this.availableMoves[%client, %pieceId], %desiredSpot) != -1 && %desiredSpot !$= "";
  295. }
  296.  
  297.  
  298. function ChessGame::addPiece(%this, %client, %pieceId, %location)
  299. {
  300.     if(%this.isPieceAlive(%client, %pieceId))
  301.     {
  302.         %pieceLocation = %this.getPieceLocation(%client, %pieceId);
  303.         %this.removePiece(%this, %pieceLocation);
  304.     }
  305.  
  306.     %tile = %this.getBrick(%location);
  307.     %tile.setItem(%this.getDB(%client, %pieceId));
  308.     %tile.setItemDirection(%client.color $= "white" ? $Chess::EAST : $Chess::WEST);
  309.     %tile.item.pieceId = %pieceId;
  310.  
  311.     %this.moveCount[%client, %pieceId] = 0;
  312.     %this.pieceLocation[%client, %pieceId] = %location;
  313.     %this.pieceAlive[%client, %pieceId] = true;
  314. }
  315.  
  316. function ChessGame::movePiece(%this, %client, %pieceId, %location)
  317. {
  318.     %pieceLocation = %this.getPieceLocation(%client, %pieceId);
  319.  
  320.     // is there a piece at %location, if so remove and setalive = 0
  321.     if(%piece = %this.getPieceAt(%location))
  322.         %this.removePiece(%location);
  323.  
  324.     // remove piece from old location
  325.     %brick = %this.getBrick(%pieceLocation);
  326.     %brick.setItem("");
  327.  
  328.     // place piece at new location and set pieceId
  329.     %brick = %this.getBrick(%location);
  330.  
  331.     if(%x = %this.truePieceId[%client, %pieceId])
  332.         %brick.setItem(%this.getDB(%client, %x));
  333.     else
  334.         %brick.setItem(%this.getDB(%client, %pieceId));
  335.  
  336.     %brick.setItemDirection(%this.getColorDirection(%client.color));
  337.     %brick.item.pieceId = %pieceId;
  338.  
  339.     // update move count and location
  340.     %this.moveCount[%client, %pieceId]++;
  341.     %this.pieceLocation[%client, %pieceId] = %location;
  342.  
  343.     // check if en passant becomes available
  344.     // did they move a pawn and move 2 squares
  345.     if(%this.getDB(%client, %pieceId) $= %this.getDB(%client, $Chess::PAWN0) && %this.tileFrom(%pieceLocation, 0, %client == %this.light ? 2 : -2) $= %location)
  346.     {
  347.         %opponent = %client == %this.light ? %this.dark : %this.light;
  348.  
  349.         // get the two pieces to the side of the pawn
  350.         %piece1 = %this.getPieceAt(%pos1 = %this.tileFrom(%location, 1, 0));
  351.         %piece2 = %this.getPieceAt(%pos2 = %this.tileFrom(%location, -1, 0));
  352.  
  353.  
  354.         if(%piece1 && %this.getDB(%client, %piece1.pieceId) $= %this.getDB(%client, $Chess::PAWN0) && %this.playerOwnsPiece(%opponent, %piece1))
  355.             %this.potentialEnPassant[%opponent] = %pos1 @ "|" @ %location;
  356.  
  357.         //talk(%otherClient.color);
  358.         if(%piece2 && %this.getDB(%client, %piece2.pieceId) $= %this.getDB(%client, $Chess::PAWN0) && %this.playerOwnsPiece(%opponent, %piece2))
  359.             %this.potentialEnPassant[%opponent] = %this.potentialEnPassant[%opponent] SPC %pos2 @ "|" @ %location;
  360.     }
  361.  
  362.  
  363.     // check if they moved a pawn to the other side of the board
  364.     if(%this.getDB(%client, %pieceId) $= %this.getDB(%client, $Chess::PAWN0) && (%client == %this.light && getSubStr(%location, 1, 1) == 8 || %client == %this.dark && getSubStr(%location, 1, 1) == 1))
  365.     {
  366.         %this.removePiece(%pieceLocation);
  367.         %brick.setItem(%this.getDB(%client, $Chess::QUEEN));
  368.         %brick.setItemDirection(%this.getColorDirection(%client.color));
  369.         %brick.item.pieceId = %pieceId;
  370.         %this.truePieceId[%client, %pieceId] = $Chess::QUEEN;
  371.     }
  372.  
  373.  
  374.     // remove all potential en passant moves if there were any
  375.     if(%this.potentialEnPassant[%client] !$= "")
  376.         %this.potentialEnPassant[%client] = "";
  377. }
  378.  
  379. function ChessGame::removePiece(%this, %location)
  380. {
  381.     if(!(%piece = %this.getPieceAt(%location)))
  382.         return;
  383.  
  384.     %pieceId = %piece.pieceId;
  385.     %client = %this.getOwnerOfPiece(%piece);
  386.  
  387.     %brick = %this.getBrick(%location);
  388.     %brick.setItem("");
  389.  
  390.     %this.pieceLocation[%client, %pieceId] = "";
  391.     %this.pieceAlive[%client, %pieceId] = false;
  392. }
  393.  
  394. function ChessGame::highlightTile(%this, %tile, %color, %colorfx, %emitter)
  395. {
  396.     if(!isObject(%brick = %this.getBrick(%tile)))
  397.         return;
  398.  
  399.     %brick.setColor(%color);
  400.     %brick.setColorFx(%colorfx);
  401.     %brick.setEmitter(%emitter);
  402.  
  403.     // add this tile to the list of highlighted tiles
  404.     %this.highlightedTiles = trim(%this.highlightedTiles SPC %tile);
  405. }
  406.  
  407. function ChessGame::highlightAvailableMoves(%this, %moves)
  408. {
  409.     // get the available color ids and fx
  410.     if((%darkAvailableMoveColor = $Chess::darkAvailableMoveColorId[%this.theme]) $= "")
  411.         %darkAvailableMoveColor = $Chess::darkAvailableMoveColorId[$Chess::Themes::DEFAULT];
  412.  
  413.     if((%lightAvailableMoveColor = $Chess::lightAvailableMoveColorId[%this.theme]) $= "")
  414.         %lightAvailableMoveColor = $Chess::lightAvailableMoveColorId[$Chess::Themes::DEFAULT];
  415.  
  416.     if((%availableMoveColorFx = $Chess::availableMoveColorFxId[%this.theme]) $= "")
  417.         %availableMoveColorFx = $Chess::availableMoveColorFxId[$Chess::Themes::DEFAULT];
  418.  
  419.     // highlight all the available moves
  420.     %count = getWordCount(%moves);
  421.  
  422.     for(%i = 0; %i < %count; %i++)
  423.     {
  424.         %tile = getWord(%moves, %i);
  425.         %brick = %this.getBrick(%tile);
  426.         // if this tile is a dark tile, use the dark available move color id, otherwise use light available color id
  427.         %this.highlightTile(%tile, %brick.getColorId() == $Chess::darkTileColorId[%this.theme] ? %darkAvailableMoveColor : %lightAvailableMoveColor, %availableMoveColorFx);
  428.     }
  429. }
  430.  
  431. function ChessGame::switchTurns(%this)
  432. {
  433.     %this.selectedPieceId = -1;
  434.     %this.clearHighlightedTiles();
  435.  
  436.     %this.currentTurn = %this.currentTurn == %this.light ? %this.dark : %this.light;
  437.  
  438.     if(%this.finished)
  439.         %this.currentTurn = -1;
  440.  
  441.     //messageClient(%this.currentTurn, '', "It is your turn.");
  442. }
  443.  
  444. function ChessGame::setSelectedPiece(%this, %client, %pieceId)
  445. {
  446.     %this.selectedPieceId = %pieceId;
  447.  
  448.     // unhighlight the previously highlighted tiles
  449.     %this.clearHighlightedTiles();
  450.  
  451.     // get the location of the piece and the available moves of this piece
  452.     %location = %this.getPieceLocation(%client, %pieceId);
  453.     %availableMoves = %this.availableMoves[%client, %pieceId];
  454.  
  455.     // get the color, colorfx, and emitter for the theme of the game
  456.     if((%colorId = $Chess::selectionColorId[%this.theme]) $= "")
  457.         %colorId = $Chess::selectionColorId[$Chess::Themes::DEFAULT];
  458.  
  459.     if((%colorFxId = $Chess::selectionColorFxId[%this.theme]) $= "")
  460.         %colorFxId = $Chess::selectionColorFxId[$Chess::Themes::DEFAULT];
  461.  
  462.     if((%emitter = $Chess::selectionEmitter[%this.theme]) $= "")
  463.         %emitter = $Chess::selectionEmitter[$Chess::Themes::DEFAULT];
  464.  
  465.     // highlight the location and the available moves
  466.     %this.highlightTile(%location, %colorId, %colorFxId, %emitter);
  467.     %this.highlightAvailableMoves(%availableMoves);
  468. }
  469.  
  470. function ChessGame::clearHighlightedTiles(%this)
  471. {
  472.     // get number of highlighted tiles
  473.     %count = getWordCount(%this.highlightedTiles);
  474.  
  475.     // remove all highlights
  476.     for(%i = 0; %i < %count; %i++)
  477.     {
  478.         %tile = getWord(%this.highlightedTiles, %i);
  479.         %brick = %this.getBrick(%tile);
  480.  
  481.         %brick.setColor(%brick.originalColor);
  482.         %brick.setColorFx(%brick.originalColorFx);
  483.         %brick.setEmitter(0);
  484.     }
  485.  
  486.     %this.highlightedTiles = "";
  487. }
  488.  
  489. function Chessgame::canCastle(%this, %client, %rookId)
  490. {
  491.     //talk("args: " @ %client.name SPC %rookId);
  492.     // have they moved either piece yet?
  493.     %opponent = %client.color $= "white" ? %this.dark : %this.light;
  494.     if(!(%this.getMoveCount(%client, $Chess::KING) == 0 && %this.getMoveCount(%client, %rookId) == 0))
  495.         return false;
  496.  
  497.     if(%this.isKingInCheck(%client))
  498.         return false;
  499.  
  500.     // are the spaces between them empty and not under threat
  501.     %column = getSubStr(%this.getPieceLocation(%client, %rookId), 0, 1);
  502.  
  503.     %row = %client.color $= "white" ? 1 : 8;
  504.     if(%column $= "a")
  505.     {
  506.         %c = !%this.getPieceAt("b" @ %row) && !%this.getPieceAt("c" @ %row) && !%this.getPieceAt("d" @ %row);
  507.         %d = strStr(%this.availableMoves[%opponent], "c" @ %row) == -1 && strStr(%this.availableMoves[%opponent], "d" @ %row) == -1;
  508.     }
  509.     else if(%column $= "h")
  510.     {
  511.         %c = !%this.getPieceAt("f" @ %row)  && !%this.getPieceAt("g" @ %row);
  512.         %d = strStr(%this.availableMoves[%opponent], "f" @ %row) == -1 && strStr(%this.availableMoves[%opponent], "g" @ %row) == -1;
  513.     }
  514.  
  515.     return %c && %d;
  516. }
  517.  
  518. function ChessGame::performCastle(%this, %client, %rookId)
  519. {
  520.     // get the king and rook location
  521.     %kingLocation = %this.getPieceLocation(%client, $Chess::KING);
  522.     %rookLocation = %this.getPieceLocation(%client, %rookId);
  523.  
  524.     // if the rook is rook0, (on a8 / a1), then we need to move the king left
  525.     if(%rookId == $Chess::ROOK0)
  526.         %dx = -1;
  527.     else
  528.         %dx = 1;
  529.  
  530.     // move king 2 to the left / right and move the rook to the inside
  531.     %newKingLocation = %this.tileFrom(%kingLocation, %dx * 2, 0);
  532.     %newRookLocation = %this.tileFrom(%newKingLocation, -%dx, 0);
  533.  
  534.     %this.movePiece(%client, $Chess::KING, %newKingLocation);
  535.     %this.movePiece(%client, %rookId, %newRookLocation);
  536. }
  537.  
  538. function ChessGame::performEnPassant(%this, %client, %pawnId, %victimLoc, %desiredLocation)
  539. {
  540.     // remove the other players pawn
  541.     %this.removePiece(%victimLoc);
  542.  
  543.     // move initators piece to new position
  544.     %this.movePiece(%client, %pawnId, %desiredLocation);
  545. }
  546.  
  547. function ChessGame::setKingInCheck(%this, %client, %threatPieceId, %pathToKing)
  548. {
  549.     // get the check color for this theme
  550.     if((%checkColor = $Chess::checkColorId[%this.theme]) $= "")
  551.         %checkColor = $Chess::checkColorId[$Chess::Themes::DEFAULT];
  552.  
  553.     if((%checkColorFx = $Chess::selectionColorFxId[%this.theme]) $= "")
  554.         %checkColorFx = $Chess::selectionColorFxId[$Chess::Themes::DEFAULT];
  555.  
  556.     // highlight the checked king and threatening piece
  557.     %opponent = %client == %this.light ? %this.dark : %this.light;
  558.     %this.highlightTile(%this.getPieceLocation(%opponent, %threatPieceId), %checkColor, %checkColorFx);
  559.     %this.highlightTile(%this.getPieceLocation(%client, $Chess::KING), %checkColor, %checkColorFx);
  560.  
  561.     // update the checks and path to king
  562.     %this.activeCheck[%client] = trim(%this.activeCheck[%client] SPC %threatPieceId);
  563.     %this.pathToKing[%client, %threatPieceId] = %pathToKing;
  564. }
  565.  
  566. function ChessGame::doLogic(%this)
  567. {
  568.     //talk("it is " @ %this.currentTurn.name @ "'s turn.");
  569.     %client = %this.currentTurn;
  570.     %opponent = %this.currentTurn == %this.light ? %this.dark : %this.light;
  571.  
  572.  
  573.     // reset all the previous moves from the last turn
  574.     %this.activeCheck[%client] = "";
  575.     %this.availableMoves[%client] = "";
  576.     %this.unrestrictedMoves[%client] = "";
  577.  
  578.  
  579.     %this.activeCheck[%opponent] = "";
  580.     %this.availableMoves[%opponent] = "";
  581.     %this.unrestrictedMoves[%opponent] = "";
  582.  
  583.     for(%i = 0; %i < 16; %i++)
  584.     {
  585.         %this.pathToKing[%client, %i] = "";
  586.         %this.potentialCheck[%client, %i] = "";
  587.  
  588.         %this.pathToKing[%opponent, %i] = "";
  589.         %this.potentialCheck[%opponent, %i] = "";
  590.     }
  591.  
  592.     // generate unrestricted moves for opponent. the unrestricted moves contain all the moves
  593.     // that could be under threat by %opponent
  594.     %this.generateUnrestrictedMoveSet(%opponent);
  595.  
  596.     // generate available moves for each player
  597.     %this.generateAvailableMoves(%opponent);
  598.     %this.generateAvailableMoves(%client);
  599.  
  600.     if(%this.availableMoves[%client] $= "")
  601.     {
  602.         if(%this.isKingInCheck(%client))
  603.             %this.endGame(%client == %this.player0 ? 1 : 0);
  604.         else
  605.             %this.endGame(3);
  606.     }
  607. }
  608.  
  609. function ChessGame::generateUnrestrictedMoveSet(%this, %client)
  610. {
  611.     if(!isobject(%client))
  612.         return;
  613.  
  614.     for(%pieceId = 0; %pieceId < 16; %pieceId++)
  615.     {
  616.         if(!%this.isPieceAlive(%client, %pieceId))
  617.             continue;
  618.  
  619.         %x = %this.truePieceId[%client, %pieceId];
  620.  
  621.         // get the location of the piece and the name of the piece
  622.         %pieceLocation = %this.getPieceLocation(%client, %pieceId);
  623.         %db = %this.getDB(%client, %x ? %x : %pieceId);
  624.         %index = strStr(%db, "_");
  625.         %hasSecondUnderScore = strPos(%db, "_", %index + 1);
  626.         %pieceName = strReplace(strLwr(getSubStr(%db, %index + 1, strLen(%db))), %hasSecondUnderScore == -1 ? "item" : strLwr(getSubStr(%db, %hasSecondUnderScore, strLen(%db))), "");
  627.  
  628.         %this.unrestrictedMoves[%client, %pieceId] = %pieceName.getUnrestrictedMoves(%client, %pieceLocation);
  629.         %this.unrestrictedMoves[%client] = trim(%this.unrestrictedMoves[%client] SPC %this.unrestrictedMoves[%client, %pieceId]);
  630.     }
  631. }
  632.  
  633. function ChessGame::generateAvailableMoves(%this, %client)
  634. {
  635.     if(!isobject(%client))
  636.         return;
  637.  
  638.     for(%pieceId = 0; %pieceId < 16; %pieceId++)
  639.     {
  640.         if(!%this.isPieceAlive(%client, %pieceId))
  641.             continue;
  642.  
  643.         %x = %this.truePieceId[%client, %pieceId];
  644.  
  645.         %pieceLocation = %this.getPieceLocation(%client, %pieceId);
  646.         %db = %this.getDB(%client, %x ? %x : %pieceId);
  647.         %index = strStr(%db, "_");
  648.         %hasSecondUnderScore = strPos(%db, "_", %index + 1);
  649.         %pieceName = strReplace(strLwr(getSubStr(%db, %index + 1, strLen(%db))), %hasSecondUnderScore == -1 ? "item" : strLwr(getSubStr(%db, %hasSecondUnderScore, strLen(%db))), "");
  650.  
  651.         %this.availableMoves[%client, %pieceId] = %pieceName.getAvailableMoves(%client, %pieceLocation, %client == %this.currentTurn ? false : true);
  652.         %this.availableMoves[%client] = trim(%this.availableMoves[%client] SPC %this.availableMoves[%client, %pieceId]);
  653.     }
  654. }
  655.  
  656. function ChessGame::isKingInCheck(%this, %client)
  657. {
  658.     return %this.activeCheck[%client] !$= "";
  659. }
  660.  
  661. function ChessGame::isPiecePinned(%this, %client, %pieceId)
  662. {
  663.     return %this.potentialCheck[%client, %pieceId] !$= "";    
  664. }
  665.  
  666. function ChessGame::getPathToKing(%this, %client, %pieceId)
  667. {
  668.     return %this.pathToKing[%client, %pieceId];
  669. }
  670.  
  671. function ChessGame::playerOwnsPiece(%this, %client, %item)
  672. {
  673.     return %item && strStr(%item.dataBlock.getName(), %client.color) != -1;
  674. }
  675.  
  676. function ChessGame::isValidPosition(%this, %pos)
  677. {
  678.     %column = getSubStr(%pos, 0, 1);
  679.     %row = getSubSTr(%pos, 1, 1);
  680.     return strStr($Chess::letters, %column) != -1 && %row > 0 && %row < 9 && strLen(%pos) == 2;
  681. }
  682.  
  683. function ChessGame::tileFrom(%this, %pos, %offX, %offY)
  684. {
  685.     %x = strPos($Chess::letters, getSubStr(%pos, 0, 1)) + %offX;
  686.  
  687.     if(%x < 0)
  688.         return "";
  689.  
  690.     %y = getSubStr(%pos, 1, 1) + %offY;
  691.     %potentialTile = getSubStr($Chess::letters, %x, 1) @ %y;
  692.  
  693.     if(%this.isValidPosition(%potentialTile))
  694.         return %potentialTile;
  695. }
  696.  
  697. function ChessGame::isSpecialMove(%this, %client, %selectedPieceId, %originalLocation, %desiredLocation)
  698. {
  699.     // check for castling
  700.     // if we are moving the king and the king is currently in original position
  701.     if(%selectedPieceId == $Chess::KING && (%originalLocation $= "e8") || %originalLocation $= "e1")
  702.     {
  703.         // is the desired location 2 to the right or left? if so this is castling
  704.         if(%desiredLocation $= %this.tileFrom(%originalLocation, 2, 0))
  705.         {
  706.             %this.performCastle(%client, $Chess::ROOK1);
  707.             return true;
  708.         }
  709.         else if(%desiredLocation $= %this.tileFrom(%originalLocation, -2, 0))
  710.         {
  711.             %this.performCastle(%client, $Chess::ROOK0);
  712.             return true;
  713.         }
  714.     }
  715.     // check for en passant
  716.     // is the original location in the en passant move list
  717.     else if(strStr(%this.potentialEnPassant[%client], %originalLocation) != -1)
  718.     {
  719.         // loop through each pair in the list until we find the one that has our position
  720.         %pairs = %this.potentialEnPassant[%client];
  721.         for(%i = 0; %i < getWordCount(%pairs); %i++)
  722.         {
  723.             if(strStr(%pair = getWord(%pairs, %i), %originalLocation) != -1)
  724.             {
  725.                 // get the second token
  726.                 %dy = %client == %this.light ? 1 : -1;
  727.                 %opponentPawnLocation = getToken(%pair, "|", 1);
  728.  
  729.                 if(%desiredLocation $= %this.tileFrom(%opponentPawnLocation, 0, %dy))
  730.                 {
  731.                     %this.performEnPassant(%client, %selectedPieceId, %opponentPawnLocation, %desiredLocation);
  732.                     return true;
  733.                 }
  734.             }
  735.         }
  736.     }
  737.  
  738.     return false;
  739. }
  740.  
  741. function getToken(%str, %delim, %index)
  742. {
  743.     for(%i = 0; %i <= %index; %i++)
  744.         %str = nextToken(%str, "x", %delim);
  745.  
  746.     return %x;
  747. }
  748.  
  749. function ChessGame::takeTurn(%this, %obj, %client)
  750. {
  751.     // is the player in a game and is it their turn
  752.     if(%this.currentTurn != %client)
  753.         return;
  754.  
  755.     %piece = %obj.item;
  756.     %location = strReplace(%obj.getName(), "_", "");
  757.  
  758.     if(%piece && %this.playerOwnsPiece(%client, %piece))
  759.         %this.setSelectedPiece(%client, %piece.pieceId);
  760.     else if(%this.validMove(%client, %this.selectedPieceId, %location))
  761.     {
  762.         %selectedPieceId = %this.selectedPieceId;
  763.         %originalLocation = %this.getPieceLocation(%this.currentTurn, %selectedPieceId);
  764.  
  765.         if(!%this.isSpecialMove(%client, %selectedPieceId, %originalLocation, %location))
  766.             %this.movePiece(%client, %this.selectedPieceId, %location);
  767.  
  768.         %this.switchTurns();
  769.         %this.doLogic();
  770.     }
  771. }
  772.  
  773. function pawn::getUnrestrictedMoves(%this, %owner, %location)
  774. {
  775.     if(!isObject(%chessGame = %owner.boardGame))
  776.         return;
  777.  
  778.     %opponent = %chessGame.light == %owner ? %chessGame.dark : %chessGame.light;
  779.     %pieceId = %chessGame.getPieceAt(%location).pieceId;
  780.  
  781.     %dy = %owner == %chessGame.light ? 1 : -1;
  782.  
  783.     %possibleLocation1 = %chessGame.tileFrom(%location, 1, %dy);
  784.     %possibleLocation2 = %chessGame.tileFrom(%location, -1, %dy);
  785.  
  786.     // if both locations are actually locations on the board, add them to unrestricted moves
  787.     if(%chessGame.isValidPosition(%possibleLocation1))
  788.     {
  789.         %unrestrictedMoves = %possibleLocation1;
  790.  
  791.         // if this possibleLocation is the location of the other players king, we set their king in check
  792.         if(%chessGame.getPieceLocation(%opponent, $Chess::KING) $= %possibleLocation1)
  793.             %chessGame.setKingInCheck(%opponent, %pieceId, %location);
  794.     }
  795.  
  796.     if(%chessGame.isValidPosition(%possibleLocation2))
  797.     {
  798.         %unrestrictedMoves = trim(%unrestrictedMoves SPC %possibleLocation2);
  799.  
  800.         if(%chessGame.getPieceLocation(%opponent, $Chess::KING) $= %possibleLocation2)
  801.             %chessGame.setKingInCheck(%opponent, %pieceId, %location);
  802.     }
  803.  
  804.     return %unrestrictedMoves;
  805. }
  806.  
  807. // pawn
  808. function pawn::getAvailableMoves(%this, %owner, %location, %passive)
  809. {
  810.     if(!isObject(%chessGame = %owner.boardGame))
  811.         return;
  812.  
  813.     %opponent = %chessGame.light == %owner ? %chessGame.dark : %chessGame.light;
  814.     %pieceId = %chessGame.getPieceAt(%location).pieceId;
  815.  
  816.     if(%owner == %chessGame.light)
  817.         %dy = 1;
  818.     else
  819.         %dy = -1;
  820.  
  821.     // can we skip a tile
  822.     %canSkip = (%owner == %chessGame.light && getSubStr(%location, 1, 1) == 2) || (%owner == %chessGame.dark && getSubStr(%location, 1, 1) == 7);
  823.  
  824.     %potentialMove1 = %chessGame.tileFrom(%location, 0, %dy);
  825.     %potentialMove2 = %chessGame.tileFrom(%location, 0, %dy * 2);
  826.     %potentialMove3 = %chessGame.tileFrom(%location, 1, %dy);
  827.     %potentialMove4 = %chessGame.tileFrom(%location, -1, %dy);
  828.  
  829.     // if our king is an in check
  830.     if(%chessGame.isKingInCheck(%owner))
  831.     {
  832.         %threateningPieces = %chessGame.activeCheck[%owner];
  833.         %tpc = getWordCount(%threateningPieces);
  834.  
  835.         for(%i = 0; %i < %tpc; %i++)
  836.             %pathToKing[%i] = %chessGame.getPathToKing(%owner, getWord(%threateningPieces, %i));
  837.     }
  838.    
  839.     // our we pinned from moving
  840.     if(%chessGame.isPiecePinned(%owner, %pieceId))
  841.         %potentialPathToKing = %chessGame.potentialCheck[%owner, %pieceId];
  842.  
  843.     // we are pinned or the king is in check
  844.     if(%threateningPieces !$= "" || %potentialPathToKing !$= "")
  845.     {
  846.         // if there are multiple checks or there is at least 1 check but this piece is pinned, it cant move anywhere
  847.         if(getWordCount(%threateningPieces) > 1 || %threateningPieces !$= "" && %potentialPathToKing !$= "")
  848.             return "";
  849.  
  850.         // at this point, the piece is either pinned with no checks or theres 1 check but piece isnt pinned
  851.         if(%potentialPathToKing !$= "")
  852.         {
  853.             // moves to do when pinned
  854.             if(%chessGame.isValidPosition(%potentialMove1) && !%chessGame.getPieceAt(%potentialMove1) && strStr(%potentialPathToKing, %potentialMove1) != -1)
  855.                 %availableMoves = %potentialMove1;
  856.  
  857.             if(%chessGame.isValidPosition(%potentialMove2) && strStr(%potentialPathToKing, %potentialMove2) != -1 && !%chessGame.getPieceAt(%potentialMove1) && !%chessGame.getPieceAt(%potentialMove2) && %canSkip)
  858.                 %availableMoves = trim(%availableMoves SPC %potentialMove2);
  859.  
  860.             if(%chessGame.isValidPosition(%potentialMove3) && (%piece = %chessGame.getPieceAt(%potentialMove3)) && !%chessGame.playerOwnsPiece(%owner, %piece) && strStr(%potentialPathToKing, %potentialMove3) != -1)
  861.                 %availableMoves = trim(%availableMoves SPC %potentialMove3);
  862.  
  863.             if(%chessGame.isValidPosition(%potentialMove4) && (%piece = %chessGame.getPieceAt(%potentialMove4)) && !%chessGame.playerOwnsPiece(%owner, %piece) && strStr(%potentialPathToKing, %potentialMove4) != -1)
  864.                 %availableMoves = trim(%availableMoves SPC %potentialMove4);
  865.  
  866.             %pairs = %chessGame.potentialEnPassant[%owner];
  867.             for(%i = 0; %i < getWordCount(%pairs); %i++)
  868.             {
  869.                 if(strStr(%pair = getWord(%pairs, %i), %location) != -1)
  870.                 {
  871.                     %potentialMove = %chessGame.tileFrom(getToken(%pair, "|", 1), 0, %dy);
  872.  
  873.                     if(%chessGame.isValidPosition(%potentialMove) && strStr(%potentialPathToKing, %potentialMove) != -1)
  874.                         %availableMoves = trim(%availableMoves SPC %potentialMove);
  875.  
  876.                     break;
  877.                 }
  878.             }
  879.         }
  880.         else
  881.         {
  882.             // these are the only moves available to a pawn whose king is in check
  883.             if(%chessGame.isValidPosition(%potentialMove1) && strStr(%pathToKing[0], %potentialMove1) != -1 && !%chessGame.getPieceAt(%potentialMove1))
  884.                 %availableMoves = %potentialMove1;
  885.  
  886.             if(%chessGame.isValidPosition(%potentialMove2) && strStr(%pathToKing[0], %potentialMove2) != -1 && !%chessGame.getPieceAt(%potentialMove1) && !%chessGame.getPieceAt(%potentialMove2) && %canSkip)
  887.                 %availableMoves = %potentialMove2;
  888.  
  889.  
  890.             if(%chessGame.isValidPosition(%potentialMove3) && (%piece = %chessGame.getPieceAt(%potentialMove3)) && !%chessGame.playerOwnsPiece(%owner, %piece) && strStr(%pathToKing[0], %potentialMove3) != -1)
  891.                 %availableMoves = trim(%availableMoves SPC %potentialMove3);
  892.  
  893.             if(%chessGame.isValidPosition(%potentialMove4) && (%piece = %chessGame.getPieceAt(%potentialMove4)) && !%chessGame.playerOwnsPiece(%owner, %piece) && strStr(%pathToKing[0], %potentialMove4) != -1)
  894.                 %availableMoves = trim(%availableMoves SPC %potentialMove4);
  895.  
  896.             // en passant to block king
  897.             %pairs = %chessGame.potentialEnPassant[%owner];
  898.             for(%i = 0; %i < getWordCount(%pairs) && !%canSkip; %i++)
  899.             {
  900.                 if(strStr(%pair = getWord(%pairs, %i), %location) != -1)
  901.                 {
  902.                     %potentialMove = %chessGame.tileFrom(getToken(%pair, "|", 1), 0, %dy);
  903.  
  904.                     if(%chessGame.isValidPosition(%potentialMove) && strStr(%pathToKing[0], %potentialMove) != -1)
  905.                         %availableMoves = trim(%availableMoves SPC %potentialMove);
  906.  
  907.                     break;
  908.                 }
  909.             }
  910.         }
  911.     }
  912.     else
  913.     {
  914.         if(%passive)
  915.         {
  916.             if(%chessGame.isValidPosition(%potentialMove3))
  917.                 %availableMoves = trim(%availableMoves SPC %potentialMove3);
  918.  
  919.             if(%chessGame.isValidPosition(%potentialMove4))
  920.                 %availableMoves = trim(%availableMoves SPC %potentialMove4);
  921.         }
  922.         else
  923.         {
  924.  
  925.             // no conditions, calculate available moves normally
  926.             if(%chessGame.isValidPosition(%potentialMove1) && !%chessGame.getPieceAt(%potentialMove1))
  927.                     %availableMoves = %potentialMove1;
  928.  
  929.             if(%chessGame.isValidPosition(%potentialMove2) && !%chessGame.getPieceAt(%potentialMove1) && !%chessGame.getPieceAt(%potentialMove2) && %canSkip)
  930.                 %availableMoves = trim(%availableMoves SPC %potentialMove2);
  931.  
  932.             if(%chessGame.isValidPosition(%potentialMove3) && (%piece = %chessGame.getPieceAt(%potentialMove3)) && !%chessGame.playerOwnsPiece(%owner, %piece))
  933.                 %availableMoves = trim(%availableMoves SPC %potentialMove3);
  934.  
  935.             if(%chessGame.isValidPosition(%potentialMove4) && (%piece = %chessGame.getPieceAt(%potentialMove4)) && !%chessGame.playerOwnsPiece(%owner, %piece))
  936.                 %availableMoves = trim(%availableMoves SPC %potentialMove4);
  937.  
  938.  
  939.             // if we can skip a tile, then we're in no position to perform en passant
  940.             %pairs = %chessGame.potentialEnPassant[%owner];
  941.             for(%i = 0; %i < getWordCount(%pairs) && !%canSkip; %i++)
  942.             {
  943.                 if(strStr(%pair = getWord(%pairs, %i), %location) != -1)
  944.                 {
  945.                     %availableMoves = trim(%availableMoves SPC %chessGame.tileFrom(getToken(%pair, "|", 1), 0, %dy));
  946.                     break;
  947.                 }
  948.             }
  949.         }
  950.     }
  951.  
  952.     return %availableMoves;
  953. }
  954.  
  955.  
  956. function rook::getUnrestrictedMoves(%this, %owner, %location)
  957. {
  958.     if(!isObject(%chessGame = %owner.boardGame))
  959.         return;
  960.  
  961.     %opponent = %chessGame.light == %owner ? %chessGame.dark : %chessGame.light;
  962.     %pieceId = %chessGame.getPieceAt(%location).pieceId;
  963.  
  964.     %opponentKingLocation = %chessGame.getPieceLocation(%opponent, $Chess::KING);
  965.  
  966.     // iterate over the 4 possible directions the rook and iterate through the tiles in each direction
  967.     for(%i = 0; %i < 4; %i++)
  968.     {
  969.         // the direction to iterate tiles in
  970.         %dx = getWord("0 1 0 -1", %i);
  971.         %dy = getWord("1 0 -1 0", %i);
  972.  
  973.         for(%j = 0; %j < 8; %j++)
  974.         {
  975.             // calculate the new location
  976.             %newLocation = %chessGame.tileFrom(%location, %dx * (%j + 1), %dy * (%j + 1));
  977.  
  978.             if(%newLocation $= %opponentKingLocation)
  979.                     %encounteredKing = %i;
  980.  
  981.             if(!%chessGame.isValidPosition(%newLocation))
  982.                 break;
  983.  
  984.             %path[%i] = trim(%path[%i] SPC %newLocation);
  985.  
  986.             // if we own the piece at the new location, we break now that we added its location to the path
  987.             if(%chessGame.playerOwnsPiece(%owner, %chessGame.getPieceAt(%newLocation)))
  988.                     break;
  989.  
  990.             // get the pieces between the opponents king and this piece
  991.             if((%piece = %chessGame.getPieceAt(%newLocation)) && %piece.pieceId != $Chess::KING && %encounteredKing $= "")
  992.                 %pathPieces[%i] = trim(%pathPieces[%i] SPC %piece.pieceId);
  993.         }
  994.  
  995.         %unrestrictedMoves = trim(%unrestrictedMoves SPC %path[%i]);
  996.         %chessGame.unrestrictedMoves[%owner, %pieceId, %i] = %path[%i];
  997.     }
  998.  
  999.     // if we encountered the king, the specific path is stored in the variable
  1000.     if(%encounteredKing !$= "")
  1001.     {
  1002.         %path[%encounteredKing] = trim(getField(strReplace(%path[%encounteredKing], %opponentKingLocation, "\t"), 0));
  1003.  
  1004.         if(getWordCount(%pathPieces[%encounteredKing]) == 0)
  1005.             %chessGame.setKingInCheck(%opponent, %pieceId, %location SPC %path[%encounteredKing]);
  1006.  
  1007.         // if theres 1 piece between our piece and the opponents king, thats a potential check (pin on the piece between)
  1008.         else if(getWordCount(%pathPieces[%encounteredKing]) == 1)
  1009.             %chessGame.potentialCheck[%opponent, %pathPieces[%encounteredKing]] = %location SPC %path[%encounteredKing];
  1010.             //talk("A potential check has been made against " @ %opponent.name @ "'s king.");
  1011.     }
  1012.  
  1013.     return %unrestrictedMoves;
  1014. }
  1015.  
  1016. function rook::getAvailableMoves(%this, %owner, %location, %passive)
  1017. {
  1018.     if(!isObject(%chessGame = %owner.boardGame))
  1019.         return;
  1020.  
  1021.     %opponent = %chessGame.light == %owner ? %chessGame.dark : %chessGame.light;
  1022.     %pieceId = %chessGame.getPieceAt(%location).pieceId;
  1023.  
  1024.     // generate all the potential moves of a rook
  1025.     for(%i = 0; %i < 4; %i++)
  1026.     {
  1027.         %dx = getWord("0 1 0 -1", %i);
  1028.         %dy = getWord("1 0 -1 0", %i);
  1029.  
  1030.         for(%j = 0; %j < 8; %j++)
  1031.         {
  1032.             %possibleLocation = %chessGame.tileFrom(%location, %dx * (%j + 1), %dy * (%j + 1));
  1033.  
  1034.             if(!%chessGame.isValidPosition(%possibleLocation))
  1035.                 break;
  1036.  
  1037.             %path[%i] = trim(%path[%i] SPC %possibleLocation);
  1038.         }
  1039.     }
  1040.  
  1041.     if(%chessGame.isKingInCheck(%owner))
  1042.     {
  1043.         %threateningPieces = %chessGame.activeCheck[%owner];
  1044.         %tpc = getWordCount(%threateningPieces);
  1045.  
  1046.         for(%i = 0; %i < %tpc; %i++)
  1047.             %pathToKing[%i] = %chessGame.getPathToKing(%owner, getWord(%threateningPieces, %i));
  1048.     }
  1049.    
  1050.     // our we pinned from moving
  1051.     if(%chessGame.isPiecePinned(%owner, %pieceId))
  1052.         %potentialPathToKing = %chessGame.potentialCheck[%owner, %pieceId];
  1053.  
  1054.     // we are pinned or the king is in check
  1055.     if(%threateningPieces !$= "" || %potentialPathToKing !$= "")
  1056.     {
  1057.         // if there are multiple checks or there is at least 1 check but this piece is pinned, it cant move anywhere
  1058.         if(getWordCount(%threateningPieces) > 1 || %threateningPieces !$= "" && %potentialPathToKing !$= "")
  1059.             return "";
  1060.  
  1061.         // at this point, the piece is either pinned with no checks or theres 1 check but piece isnt pinned
  1062.         if(%potentialPathToKing !$= "")
  1063.         {
  1064.             for(%i = 0; %i < 4; %i++)
  1065.             {
  1066.                 for(%j = 0; %j < getWordCount(%path[%i]); %j++)
  1067.                 {
  1068.                     %possibleLocation = getWord(%path[%i], %j);
  1069.                     if(strStr(%potentialPathToKing, %possibleLocation) == -1)
  1070.                         break;
  1071.  
  1072.                     %availableMoves = trim(%availableMoves SPC %possibleLocation);
  1073.                 }
  1074.             }
  1075.         }
  1076.         else
  1077.         {
  1078.             for(%i = 0; %i < 4; %i++)
  1079.             {
  1080.                 for(%j = 0; %j < getWordCount(%path[%i]); %j++)
  1081.                 {
  1082.                     %possibleLocation = getWord(%path[%i], %j);
  1083.                     //talk(%possibleLocation);
  1084.                     if((%piece = %chessGame.getPieceAt(%possibleLocation)) && strStr(%pathToKing[0], %possibleLocation)  == -1)
  1085.                         break;
  1086.  
  1087.  
  1088.                     if(strStr(%pathToKing[0], %possibleLocation) != -1)
  1089.                     {
  1090.                         %availableMoves = trim(%availableMoves SPC %possibleLocation);
  1091.                         break;
  1092.                     }
  1093.                 }
  1094.             }
  1095.         }
  1096.     }
  1097.     else
  1098.     {
  1099.         for(%i = 0; %i < 4; %i++)
  1100.         {
  1101.             for(%j = 0; %j < getWordCount(%path[%i]); %j++)
  1102.             {
  1103.                 %possibleLocation = getWord(%path[%i], %j);
  1104.  
  1105.                 if(%piece = %chessGame.getPieceAt(%possibleLocation))
  1106.                 {
  1107.                     if(!%chessGame.playerOwnsPiece(%owner, %piece))
  1108.                         %availableMoves = trim(%availableMoves SPC %possibleLocation);
  1109.                     else if(%passive)
  1110.                     {
  1111.                         %availableMoves = trim(%availableMoves SPC %possibleLocation);
  1112.                         break;
  1113.                     }
  1114.  
  1115.                     if(%passive && %possibleLocation $= %chessGame.getPieceLocation(%opponent, $Chess::KING))
  1116.                         continue;
  1117.                     else
  1118.                         break;
  1119.                 }
  1120.  
  1121.                 %availableMoves = trim(%availableMoves SPC %possibleLocation);
  1122.             }
  1123.         }
  1124.     }
  1125.  
  1126.     return %availableMoves;
  1127. }
  1128.  
  1129. function knight::getUnrestrictedMoves(%this, %owner, %location)
  1130. {
  1131.     if(!isObject(%chessGame = %owner.boardGame))
  1132.         return;
  1133.  
  1134.     %opponent = %chessGame.light == %owner ? %chessGame.dark : %chessGame.light;
  1135.     %pieceId = %chessGame.getPieceAt(%location).pieceId;
  1136.  
  1137.     for(%i = 0; %i < 8; %i++)
  1138.     {
  1139.         %possibleLocation = %chessGame.tileFrom(%location, getWord("1 2 2 1 -1 -2 -2 -1", %i), getWord("2 1 -1 -2 -2 -1 1 2", %i));
  1140.  
  1141.         if(%chessGame.isValidPosition(%possibleLocation))
  1142.         {
  1143.             %unrestrictedMoves = trim(%unrestrictedMoves SPC %possibleLocation);
  1144.  
  1145.             if(%possibleLocation $= %chessGame.getPieceLocation(%opponent, $Chess::KING))
  1146.                 %chessGame.setKingInCheck(%opponent, %pieceId, %location);
  1147.         }
  1148.     }
  1149.  
  1150.     return %unrestrictedMoves;
  1151. }
  1152.  
  1153. function knight::getAvailableMoves(%this, %owner, %location, %passive)
  1154. {
  1155.     if(!isObject(%chessGame = %owner.boardGame))
  1156.         return;
  1157.  
  1158.     %opponent = %chessGame.light == %owner ? %chessGame.dark : %chessGame.light;
  1159.     %pieceId = %chessGame.getPieceAt(%location).pieceId;
  1160.  
  1161.     for(%i = 0; %i < 8; %i++)
  1162.     {
  1163.         %newLocation = %chessGame.tileFrom(%location, getWord("1 2 2 1 -1 -2 -2 -1", %i), getWord("2 1 -1 -2 -2 -1 1 2", %i));
  1164.         %potentialMove[%i] = %newLocation;
  1165.     }
  1166.  
  1167.     if(%chessGame.isKingInCheck(%owner))
  1168.     {
  1169.         %threateningPieces = %chessGame.activeCheck[%owner];
  1170.         %tpc = getWordCount(%threateningPieces);
  1171.  
  1172.         for(%i = 0; %i < %tpc; %i++)
  1173.             %pathToKing[%i] = %chessGame.getPathToKing(%owner, getWord(%threateningPieces, %i));
  1174.     }
  1175.    
  1176.     // our we pinned from moving
  1177.     if(%chessGame.isPiecePinned(%owner, %pieceId))
  1178.         %potentialPathToKing = %chessGame.potentialCheck[%owner, %pieceId];
  1179.  
  1180.     // we are pinned or the king is in check
  1181.     if(%threateningPieces !$= "" || %potentialPathToKing !$= "")
  1182.     {
  1183.         // if there are multiple checks or there is at least 1 check but this piece is pinned, it cant move anywhere
  1184.         if(getWordCount(%threateningPieces) > 1 || %threateningPieces !$= "" && %potentialPathToKing !$= "")
  1185.             return "";
  1186.  
  1187.         // at this point, the piece is either pinned with no checks or theres 1 check but piece isnt pinned
  1188.         if(%potentialPathToKing !$= "")
  1189.         {
  1190.             for(%i = 0; %i < 8; %i++)
  1191.             {
  1192.                 if(%chessGame.isValidPosition(%potentialMove[%i]) && strStr(%potentialPathToKing, %potentialMove[%i]) != -1)
  1193.                     %availableMoves = trim(%availableMoves SPC %potentialMove[%i]);
  1194.             }
  1195.         }
  1196.         else
  1197.         {
  1198.             for(%i = 0; %i < 8; %i++)
  1199.             {
  1200.                 if(%chessGame.isValidPosition(%potentialMove[%i]) && strStr(%pathToKing[0], %potentialMove[%i]) != -1)
  1201.                     %availableMoves = trim(%availableMoves SPC %potentialMove[%i]);
  1202.             }
  1203.         }
  1204.     }
  1205.     else
  1206.     {
  1207.         for(%i = 0; %i < 8; %i++)
  1208.         {
  1209.             if(%chessGame.isValidPosition(%potentialMove[%i]) && (%passive || !%chessGame.playerOwnsPiece(%owner, %chessGame.getPieceAt(%potentialMove[%i]))))
  1210.                 %availableMoves = trim(%availableMoves SPC %potentialMove[%i]);
  1211.         }
  1212.     }
  1213.  
  1214.     return %availableMoves;
  1215. }
  1216.  
  1217. function bishop::getUnrestrictedMoves(%this, %owner, %location)
  1218. {
  1219.     if(!isObject(%chessGame = %owner.boardGame))
  1220.         return;
  1221.  
  1222.     %opponent = %chessGame.light == %owner ? %chessGame.dark : %chessGame.light;
  1223.     %pieceId = %chessGame.getPieceAt(%location).pieceId;
  1224.  
  1225.     %opponentKingLocation = %chessGame.getPieceLocation(%opponent, $Chess::KING);
  1226.  
  1227.     // iterate over the 4 possible directions the rook and iterate through the tiles in each direction
  1228.     for(%i = 0; %i < 4; %i++)
  1229.     {
  1230.         // the direction to iterate tiles in
  1231.         %dx = getWord("1 1 -1 -1", %i);
  1232.         %dy = getWord("1 -1 -1 1", %i);
  1233.  
  1234.         for(%j = 0; %j < 8; %j++)
  1235.         {
  1236.             // calculate the new location
  1237.             %newLocation = %chessGame.tileFrom(%location, %dx * (%j + 1), %dy * (%j + 1));
  1238.  
  1239.             if(%newLocation $= %opponentKingLocation)
  1240.                     %encounteredKing = %i;
  1241.  
  1242.             if(!%chessGame.isValidPosition(%newLocation))
  1243.                 break;
  1244.  
  1245.             %path[%i] = trim(%path[%i] SPC %newLocation);
  1246.  
  1247.             // if we own the piece at the new location, we break now that we added its location to the path
  1248.             if(%chessGame.playerOwnsPiece(%owner, %chessGame.getPieceAt(%newLocation)))
  1249.                     break;
  1250.  
  1251.             // get the pieces between the opponents king and this piece
  1252.             if((%piece = %chessGame.getPieceAt(%newLocation)) && %piece.pieceId != $Chess::KING && %encounteredKing $= "")
  1253.                 %pathPieces[%i] = trim(%pathPieces[%i] SPC %piece.pieceId);
  1254.         }
  1255.  
  1256.         %unrestrictedMoves = trim(%unrestrictedMoves SPC %path[%i]);
  1257.         %chessGame.unrestrictedMoves[%owner, %pieceId, %i] = %path[%i];
  1258.     }
  1259.  
  1260.     // if we encountered the king, the specific path is stored in the variable
  1261.     if(%encounteredKing !$= "")
  1262.     {
  1263.         %path[%encounteredKing] = trim(getField(strReplace(%path[%encounteredKing], %opponentKingLocation, "\t"), 0));
  1264.  
  1265.         if(getWordCount(%pathPieces[%encounteredKing]) == 0)
  1266.             %chessGame.setKingInCheck(%opponent, %pieceId, %location SPC %path[%encounteredKing]);
  1267.  
  1268.         // if theres 1 piece between our piece and the opponents king, thats a potential check (pin on the piece between)
  1269.         else if(getWordCount(%pathPieces[%encounteredKing]) == 1)
  1270.             %chessGame.potentialCheck[%opponent, %pathPieces[%encounteredKing]] = %location SPC %path[%encounteredKing];
  1271.             //talk("A potential check has been made against " @ %opponent.name @ "'s king.");
  1272.     }
  1273.  
  1274.     return %unrestrictedMoves;
  1275. }
  1276.  
  1277. function bishop::getAvailableMoves(%this, %owner, %location, %passive)
  1278. {
  1279.     if(!isObject(%chessGame = %owner.boardGame))
  1280.         return;
  1281.  
  1282.     %opponent = %chessGame.light == %owner ? %chessGame.dark : %chessGame.light;
  1283.     %pieceId = %chessGame.getPieceAt(%location).pieceId;
  1284.  
  1285.     // generate all the potential moves of a bishop
  1286.     for(%i = 0; %i < 4; %i++)
  1287.     {
  1288.         %dx = getWord("1 1 -1 -1", %i);
  1289.         %dy = getWord("1 -1 -1 1", %i);
  1290.  
  1291.         for(%j = 0; %j < 8; %j++)
  1292.         {
  1293.             %possibleLocation = %chessGame.tileFrom(%location, %dx * (%j + 1), %dy * (%j + 1));
  1294.  
  1295.             if(!%chessGame.isValidPosition(%possibleLocation))
  1296.                 break;
  1297.  
  1298.             %path[%i] = trim(%path[%i] SPC %possibleLocation);
  1299.         }
  1300.     }
  1301.  
  1302.     if(%chessGame.isKingInCheck(%owner))
  1303.     {
  1304.         %threateningPieces = %chessGame.activeCheck[%owner];
  1305.         %tpc = getWordCount(%threateningPieces);
  1306.  
  1307.         for(%i = 0; %i < %tpc; %i++)
  1308.             %pathToKing[%i] = %chessGame.getPathToKing(%owner, getWord(%threateningPieces, %i));
  1309.     }
  1310.    
  1311.     // our we pinned from moving
  1312.     if(%chessGame.isPiecePinned(%owner, %pieceId))
  1313.         %potentialPathToKing = %chessGame.potentialCheck[%owner, %pieceId];
  1314.  
  1315.     // we are pinned or the king is in check
  1316.     if(%threateningPieces !$= "" || %potentialPathToKing !$= "")
  1317.     {
  1318.         // if there are multiple checks or there is at least 1 check but this piece is pinned, it cant move anywhere
  1319.         if(getWordCount(%threateningPieces) > 1 || %threateningPieces !$= "" && %potentialPathToKing !$= "")
  1320.             return "";
  1321.  
  1322.         // at this point, the piece is either pinned with no checks or theres 1 check but piece isnt pinned
  1323.         if(%potentialPathToKing !$= "")
  1324.         {
  1325.             for(%i = 0; %i < 4; %i++)
  1326.             {
  1327.                 for(%j = 0; %j < getWordCount(%path[%i]); %j++)
  1328.                 {
  1329.                     %possibleLocation = getWord(%path[%i], %j);
  1330.                     if(strStr(%potentialPathToKing, %possibleLocation) == -1)
  1331.                         break;
  1332.  
  1333.                     %availableMoves = trim(%availableMoves SPC %possibleLocation);
  1334.                 }
  1335.             }
  1336.         }
  1337.         else
  1338.         {
  1339.             for(%i = 0; %i < 4; %i++)
  1340.             {
  1341.                 for(%j = 0; %j < getWordCount(%path[%i]); %j++)
  1342.                 {
  1343.                     %possibleLocation = getWord(%path[%i], %j);
  1344.                     //talk(%possibleLocation);
  1345.                     if((%piece = %chessGame.getPieceAt(%possibleLocation)) && strStr(%pathToKing[0], %possibleLocation)  == -1)
  1346.                         break;
  1347.  
  1348.  
  1349.                     if(strStr(%pathToKing[0], %possibleLocation) != -1)
  1350.                     {
  1351.                         %availableMoves = trim(%availableMoves SPC %possibleLocation);
  1352.                         break;
  1353.                     }
  1354.                 }
  1355.             }
  1356.         }
  1357.     }
  1358.     else
  1359.     {
  1360.         for(%i = 0; %i < 4; %i++)
  1361.         {
  1362.             for(%j = 0; %j < getWordCount(%path[%i]); %j++)
  1363.             {
  1364.                 %possibleLocation = getWord(%path[%i], %j);
  1365.  
  1366.                 if(%piece = %chessGame.getPieceAt(%possibleLocation))
  1367.                 {
  1368.                     if(!%chessGame.playerOwnsPiece(%owner, %piece))
  1369.                         %availableMoves = trim(%availableMoves SPC %possibleLocation);
  1370.                     else if(%passive)
  1371.                     {
  1372.                         %availableMoves = trim(%availableMoves SPC %possibleLocation);
  1373.                         break;
  1374.                     }
  1375.  
  1376.                     if(%passive && %possibleLocation $= %chessGame.getPieceLocation(%opponent, $Chess::KING))
  1377.                         continue;
  1378.                     else
  1379.                         break;
  1380.                 }
  1381.  
  1382.                 %availableMoves = trim(%availableMoves SPC %possibleLocation);
  1383.             }
  1384.         }
  1385.     }
  1386.  
  1387.     return %availableMoves;
  1388. }
  1389.  
  1390. function queen::getUnrestrictedMoves(%this, %owner, %location)
  1391. {
  1392.     if(!isObject(%chessGame = %owner.boardGame))
  1393.         return;
  1394.  
  1395.     %opponent = %chessGame.light == %owner ? %chessGame.dark : %chessGame.light;
  1396.     %pieceId = %chessGame.getPieceAt(%location).pieceId;
  1397.  
  1398.     %opponentKingLocation = %chessGame.getPieceLocation(%opponent, $Chess::KING);
  1399.  
  1400.     // iterate over the 4 possible directions the rook and iterate through the tiles in each direction
  1401.     for(%i = 0; %i < 8; %i++)
  1402.     {
  1403.         // the direction to iterate tiles in
  1404.         %dx = getWord("0 1 1 1 0 -1 -1 -1", %i);
  1405.         %dy = getWord("1 1 0 -1 -1 -1 0 1", %i);
  1406.  
  1407.         for(%j = 0; %j < 8; %j++)
  1408.         {
  1409.             // calculate the new location
  1410.             %newLocation = %chessGame.tileFrom(%location, %dx * (%j + 1), %dy * (%j + 1));
  1411.  
  1412.             if(%newLocation $= %opponentKingLocation)
  1413.                     %encounteredKing = %i;
  1414.  
  1415.             if(!%chessGame.isValidPosition(%newLocation))
  1416.                 break;
  1417.  
  1418.             %path[%i] = trim(%path[%i] SPC %newLocation);
  1419.  
  1420.             // if we own the piece at the new location, we break now that we added its location to the path
  1421.             if(%chessGame.playerOwnsPiece(%owner, %chessGame.getPieceAt(%newLocation)))
  1422.                     break;
  1423.  
  1424.             // get the pieces between the opponents king and this piece
  1425.             if((%piece = %chessGame.getPieceAt(%newLocation)) && %piece.pieceId != $Chess::KING && %encounteredKing $= "")
  1426.                 %pathPieces[%i] = trim(%pathPieces[%i] SPC %piece.pieceId);
  1427.         }
  1428.  
  1429.         %unrestrictedMoves = trim(%unrestrictedMoves SPC %path[%i]);
  1430.         %chessGame.unrestrictedMoves[%owner, %pieceId, %i] = %path[%i];
  1431.     }
  1432.  
  1433.     // if we encountered the king, the specific path is stored in the variable
  1434.     if(%encounteredKing !$= "")
  1435.     {
  1436.         %path[%encounteredKing] = trim(getField(strReplace(%path[%encounteredKing], %opponentKingLocation, "\t"), 0));
  1437.  
  1438.         if(getWordCount(%pathPieces[%encounteredKing]) == 0)
  1439.             %chessGame.setKingInCheck(%opponent, %pieceId, %location SPC %path[%encounteredKing]);
  1440.  
  1441.         // if theres 1 piece between our piece and the opponents king, thats a potential check (pin on the piece between)
  1442.         else if(getWordCount(%pathPieces[%encounteredKing]) == 1)
  1443.             %chessGame.potentialCheck[%opponent, %pathPieces[%encounteredKing]] = %location SPC %path[%encounteredKing];
  1444.             //talk("A potential check has been made against " @ %opponent.name @ "'s king.");
  1445.     }
  1446.  
  1447.     return %unrestrictedMoves;
  1448. }
  1449.  
  1450. function queen::getAvailableMoves(%this, %owner, %location, %passive)
  1451. {
  1452.     if(!isObject(%chessGame = %owner.boardGame))
  1453.         return;
  1454.  
  1455.     %opponent = %chessGame.light == %owner ? %chessGame.dark : %chessGame.light;
  1456.     %pieceId = %chessGame.getPieceAt(%location).pieceId;
  1457.  
  1458.     // generate all the potential moves of a bishop
  1459.     for(%i = 0; %i < 8; %i++)
  1460.     {
  1461.         %dx = getWord("0 1 1 1 0 -1 -1 -1", %i);
  1462.         %dy = getWord("1 1 0 -1 -1 -1 0 1", %i);
  1463.  
  1464.         for(%j = 0; %j < 8; %j++)
  1465.         {
  1466.             %possibleLocation = %chessGame.tileFrom(%location, %dx * (%j + 1), %dy * (%j + 1));
  1467.  
  1468.             if(!%chessGame.isValidPosition(%possibleLocation))
  1469.                 break;
  1470.  
  1471.             %path[%i] = trim(%path[%i] SPC %possibleLocation);
  1472.         }
  1473.     }
  1474.  
  1475.     if(%chessGame.isKingInCheck(%owner))
  1476.     {
  1477.         %threateningPieces = %chessGame.activeCheck[%owner];
  1478.         %tpc = getWordCount(%threateningPieces);
  1479.  
  1480.         for(%i = 0; %i < %tpc; %i++)
  1481.             %pathToKing[%i] = %chessGame.getPathToKing(%owner, getWord(%threateningPieces, %i));
  1482.     }
  1483.    
  1484.     // our we pinned from moving
  1485.     if(%chessGame.isPiecePinned(%owner, %pieceId))
  1486.         %potentialPathToKing = %chessGame.potentialCheck[%owner, %pieceId];
  1487.  
  1488.     // we are pinned or the king is in check
  1489.     if(%threateningPieces !$= "" || %potentialPathToKing !$= "")
  1490.     {
  1491.         // if there are multiple checks or there is at least 1 check but this piece is pinned, it cant move anywhere
  1492.         if(getWordCount(%threateningPieces) > 1 || %threateningPieces !$= "" && %potentialPathToKing !$= "")
  1493.             return "";
  1494.  
  1495.         // at this point, the piece is either pinned with no checks or theres 1 check but piece isnt pinned
  1496.         if(%potentialPathToKing !$= "")
  1497.         {
  1498.             for(%i = 0; %i < 8; %i++)
  1499.             {
  1500.                 for(%j = 0; %j < getWordCount(%path[%i]); %j++)
  1501.                 {
  1502.                     %possibleLocation = getWord(%path[%i], %j);
  1503.                     if(strStr(%potentialPathToKing, %possibleLocation) == -1)
  1504.                         break;
  1505.  
  1506.                     %availableMoves = trim(%availableMoves SPC %possibleLocation);
  1507.                 }
  1508.             }
  1509.         }
  1510.         else
  1511.         {
  1512.             for(%i = 0; %i < 8; %i++)
  1513.             {
  1514.                 for(%j = 0; %j < getWordCount(%path[%i]); %j++)
  1515.                 {
  1516.                     %possibleLocation = getWord(%path[%i], %j);
  1517.                     //talk(%possibleLocation);
  1518.                     if((%piece = %chessGame.getPieceAt(%possibleLocation)) && strStr(%pathToKing[0], %possibleLocation)  == -1)
  1519.                         break;
  1520.  
  1521.  
  1522.                     if(strStr(%pathToKing[0], %possibleLocation) != -1)
  1523.                     {
  1524.                         %availableMoves = trim(%availableMoves SPC %possibleLocation);
  1525.                         break;
  1526.                     }
  1527.                 }
  1528.             }
  1529.         }
  1530.     }
  1531.     else
  1532.     {
  1533.         for(%i = 0; %i < 8; %i++)
  1534.         {
  1535.             for(%j = 0; %j < getWordCount(%path[%i]); %j++)
  1536.             {
  1537.                 %possibleLocation = getWord(%path[%i], %j);
  1538.  
  1539.                 if(%piece = %chessGame.getPieceAt(%possibleLocation))
  1540.                 {
  1541.                     if(!%chessGame.playerOwnsPiece(%owner, %piece))
  1542.                         %availableMoves = trim(%availableMoves SPC %possibleLocation);
  1543.                     else if(%passive)
  1544.                     {
  1545.                         %availableMoves = trim(%availableMoves SPC %possibleLocation);
  1546.                         break;
  1547.                     }
  1548.  
  1549.                     if(%passive && %possibleLocation $= %chessGame.getPieceLocation(%opponent, $Chess::KING))
  1550.                         continue;
  1551.                     else
  1552.                         break;
  1553.                 }
  1554.  
  1555.                 %availableMoves = trim(%availableMoves SPC %possibleLocation);
  1556.             }
  1557.         }
  1558.     }
  1559.  
  1560.     return %availableMoves;
  1561. }
  1562.  
  1563. function king::getUnrestrictedMoves(%this, %owner, %location)
  1564. {
  1565.     if(!isObject(%chessGame = %owner.boardGame))
  1566.         return;
  1567.  
  1568.     %opponent = %chessGame.light == %owner ? %chessGame.dark : %chessGame.light;
  1569.     %pieceId = %chessGame.getPieceAt(%location).pieceId;
  1570.  
  1571.     for(%i = 0; %i < 8; %i++)
  1572.     {
  1573.         %possibleLocation = %chessGame.tileFrom(%location, getWord("0 1 1 1 0 -1 -1 -1", %i), getWord("1 1 0 -1 -1 -1 0 1", %i));
  1574.  
  1575.         if(%chessGame.isValidPosition(%possibleLocation))
  1576.             %unrestrictedMoves = trim(%unrestrictedMoves SPC %possibleLocation);
  1577.     }
  1578.  
  1579.     return %unrestrictedMoves;
  1580. }
  1581.  
  1582. function king::getAvailableMoves(%this, %owner, %location, %passive)
  1583. {
  1584.     if(!isObject(%chessGame = %owner.boardGame))
  1585.         return;
  1586.  
  1587.     %opponent = %chessGame.light == %owner ? %chessGame.dark : %chessGame.light;
  1588.     %pieceId = %chessGame.getPieceAt(%location).pieceId;
  1589.  
  1590.     for(%i = 0; %i < 8; %i++)
  1591.     {
  1592.         %newLocation = %chessGame.tileFrom(%location, getWord("0 1 1 1 0 -1 -1 -1", %i), getWord("1 1 0 -1 -1 -1 0 1", %i));
  1593.         %potentialMove[%i] = %newLocation;
  1594.     }
  1595.  
  1596.     // passive part so other king cant put itself into checck when near this king
  1597.     if(%passive)
  1598.     {
  1599.         for(%i = 0; %i < 8; %i++)
  1600.         {
  1601.             if(%chessGame.isValidPosition(%potentialMove[%i]))
  1602.                 %availableMoves = trim(%availableMoves SPC %potentialMove[%i]);
  1603.         }
  1604.     }
  1605.     else
  1606.     {
  1607.         //talk("loop starts");
  1608.         // loop through all potential moves
  1609.         for(%i = 0; %i < 8; %i++)
  1610.         {
  1611.             %testLocation = %potentialMove[%i];
  1612.  
  1613.             if(!%chessGame.isValidPosition(%testLocation))
  1614.                 continue;
  1615.  
  1616.  
  1617.             if(%chessGame.playerOwnsPiece(%owner, %chessGame.getPieceAt(%testLocation)))
  1618.                 continue;
  1619.  
  1620.  
  1621.             if(strStr(%chessGame.availableMoves[%opponent], %testLocation) != -1)
  1622.                 continue;
  1623.  
  1624.  
  1625.             %availableMoves = trim(%availableMoves SPC %testLocation);
  1626.         }
  1627.  
  1628.         if(%chessGame.canCastle(%owner, $Chess::ROOK0))
  1629.             %availableMoves = trim(%availableMoves SPC %chessGame.tileFrom(%location, -2, 0));
  1630.  
  1631.         if(%chessGame.canCastle(%owner, $Chess::ROOK1))
  1632.             %availableMoves = trim(%availableMoves SPC %chessGame.tileFrom(%location, 2, 0));
  1633.     }
  1634.  
  1635.     return %availableMoves;
  1636. }
  1637.  
  1638.  
  1639. if(!isObject(pawn))
  1640. {
  1641.     new scriptObject(pawn);
  1642.     new scriptObject(rook);
  1643.     new scriptObject(knight);
  1644.     new scriptObject(bishop);
  1645.     new scriptObject(queen);
  1646.     new scriptObject(king);
  1647. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement