Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- var PAWN = {
- move(src, dst, game, simulate) {
- var board = game.board;
- var black = board.getPiece(src).black;
- var dir = black ? -1 : 1;
- if ((dst.y == 0 || dst.y == 7) && game.promotePiece === null)
- return false;
- if (dst.y != src.y + dir) {
- if (dst.x != src.x)
- return false;
- if (dst.y != src.y + dir * 2)
- return false;
- if (src.y != (black ? 6 : 1))
- return false;
- if (board.getPiece(src.add(0, dir)) !== null || board.getPiece(dst) !== null)
- return false;
- if (!simulate)
- game.enPassantSquare = dst;
- } else if (dst.x == src.x) {
- if (board.getPiece(src.add(0, dir)) !== null)
- return false;
- if (!simulate)
- game.enPassantSquare = null;
- } else {
- if (Math.abs(dst.x - src.x) != 1)
- return false;
- if (board.getPiece(dst) === null) {
- var eps = dst.add(0, -dir);
- if (game.enPassantSquare === null || game.enPassantSquare.x != eps.x || game.enPassantSquare.y != eps.y)
- return false;
- if (!simulate)
- board.setPiece(eps, null);
- } else {
- if (board.getPiece(dst).black == black)
- return false;
- }
- if (!simulate)
- game.enPassantSquare = null;
- }
- if (!simulate) {
- var piece = board.getPiece(src);
- if (y == 0 || y == 7)
- piece.type = game.promotePiece;
- board.setPiece(dst, piece);
- board.setPiece(src, null);
- }
- return true;
- }
- };
- var ROOK = {
- move(src, dst, game, simulate) {
- var board = game.board;
- if (src.x == dst.x) {
- var minX = Math.min(src.x, dst.x);
- var maxX = Math.max(src.x, dst.x);
- for (var x = minX + 1; x < maxX; x++) {
- if (board.getPiece(new Coord(x, src.y)) !== null)
- return false;
- }
- } else if (src.y == dst.y) {
- var minY = Math.min(src.y, dst.y);
- var maxY = Math.max(src.y, dst.y);
- for (var y = minY + 1; y < maxY; y++) {
- if (board.getPiece(new Coord(src.x, y)) !== null)
- return false;
- }
- } else {
- return false;
- }
- if (board.getPiece(dst) !== null && board.getPiece(dst).black == board.getPiece(src).black)
- return false;
- if (!simulate) {
- board.setPiece(dst, board.getPiece(src));
- board.setPiece(src, null);
- if (src.x == 0) {
- if (src.y == 0)
- game.castleState[0].queenside = false;
- else if (src.y == 7)
- game.castleState[1].queenside = false;
- } else if (src.x == 7) {
- if (src.y == 0)
- game.castleState[0].kingside = false;
- else if (src.y == 7)
- game.castleState[1].kingside = false;
- }
- game.enPassantSquare = null;
- }
- return true;
- }
- };
- var KNIGHT = {
- move(src, dst, game, simulate) {
- var board = game.board;
- if (src.x == dst.x || src.y == dst.y)
- return false;
- if (Math.abs(dst.x - src.x) + Math.abs(dst.y - src.y) != 3)
- return false;
- if (board.getPiece(dst) !== null && board.getPiece(dst).black == board.getPiece(src).black)
- return false;
- if (!simulate) {
- board.setPiece(dst, board.getPiece(src));
- board.setPiece(src, null);
- game.enPassantSquare = null;
- }
- return true;
- }
- };
- var BISHOP = {
- move(src, dst, game, simulate) {
- var board = game.board;
- var black = board.getPiece(src).black;
- var dx = dst.x - src.x;
- var dy = dst.y - src.y;
- if (Math.abs(dx) != Math.abs(dy))
- return false;
- var dirX = Math.sign(dx);
- var dirY = Math.sign(dy);
- for (var x = src.x + dirX, y = src.y + dirY; x != dst.x; x += dirX, y += dirY) {
- if (board.getPiece(new Coord(x, y)) !== null)
- return false;
- }
- if (board.getPiece(dst) !== null && board.getPiece(dst).black == black)
- return false;
- if (!simulate) {
- board.getPiece(dst, board.getPiece(src));
- board.setPiece(src, null);
- game.enPassantSquare = null;
- }
- return true;
- }
- };
- var QUEEN = {
- move(src, dst, game, simulate) {
- var board = game.board;
- var black = board.getPiece(src).black;
- var dx = dst.x - src.x;
- var dy = dst.y - src.y;
- if (Math.abs(dx) != Math.abs(dy) && dx != 0 && dy != 0)
- return false;
- var dirX = Math.sign(dx);
- var dirY = Math.sign(dy);
- for (var x = src.x + dirX, y = src.y + dirY; x != dst.x || y != dst.y; x += dirX, y += dirY) {
- if (board.getPiece(new Coord(x, y)) !== null)
- return false;
- }
- if (board.getPiece(dst) !== null && board.getPiece(dst).black == black)
- return false;
- if (!simulate) {
- board.getPiece(dst, board.getPiece(src));
- board.setPiece(src, null);
- game.enPassantSquare = null;
- }
- return true;
- }
- };
- var KING = {
- move(src, dst, game, simulate) {
- var board = game.board;
- var black = board.getPiece(src).black;
- var dx = dst.x - src.x;
- var dy = dst.y - src.y;
- if (Math.abs(dy) > 1)
- return false;
- if (Math.abs(dx) > 2)
- return false;
- if (board.getPiece(dst) !== null && board.getPiece(dst).black == black)
- return false;
- if (Math.abs(dx) == 2) {
- if (dy != 0)
- return false;
- if (dx < 0) {
- if (!game.castleState[black ? 1 : 0].queenside)
- return false;
- if (board.getPiece(new Coord(1, src.y)) !== null)
- return false;
- } else {
- if (!game.castleState[black ? 1 : 0].kingside)
- return false;
- }
- if (board.getPiece(dst) !== null)
- return false;
- if (board.getPiece(src.add(dx / 2, 0)) !== null)
- return false;
- if (game.isPieceAttacked(src))
- return false;
- var piece = board.getPiece(src);
- board.setPiece(src.add(dx / 2, 0), piece);
- board.setPiece(src, null);
- if (game.isPieceAttacked(src.add(dx / 2, 0))) {
- board.setPiece(src.add(dx / 2, 0), null);
- board.setPiece(src, piece);
- return false;
- }
- if (!simulate) {
- board.setPiece(new Coord(dx < 0 ? 0 : 7, src.y), null);
- board.setPiece(src.add(dx / 2, 0), new PieceInstance("r", black));
- }
- }
- if (!simulate) {
- board.setPiece(dst, board.getPiece(src));
- board.setPiece(src, null);
- game.castleState[black ? 1 : 0].queenside = false;
- game.castleState[black ? 1 : 0].kingside = false;
- game.enPassantSquare = null;
- }
- return true;
- }
- };
- var pieceClasses = {
- "p": PAWN,
- "r": ROOK,
- "n": KNIGHT,
- "b": BISHOP,
- "q": QUEEN,
- "k": KING
- };
- class PieceInstance {
- constructor(type, black) {
- this.type = type;
- this.black = black;
- }
- }
- class Coord {
- constructor(x, y) {
- this.x = x;
- this.y = y;
- }
- add(x, y) {
- return new Coord(this.x + x, this.y + y);
- }
- }
- class Board {
- constructor() {
- this.tiles = [];
- for (int x = 0; x < 8; x++) {
- this.tiles[x] = [];
- for (int y = 0; y < 8; y++)
- this.tiles[x][y] = null;
- }
- }
- checkBounds(pos) {
- if (pos.x < 0 || pos.y < 0 || pos.x >= 8 || pos.y >= 8)
- throw (pos.x + ", " + pos.y + " out of bounds");
- }
- getPiece(pos) {
- checkBounds(pos);
- return this.tiles[pos.x][pos.y];
- }
- setPiece(pos, piece) {
- checkBounds(pos.x, pos.y);
- this.tiles[pos.x][pos.y] = piece;
- }
- }
- class Game {
- constructor(userWhite, userBlack) {
- this.userWhite = userWhite;
- this.userBlack = userBlack;
- this.blackToMove = false;
- this.castleState = [{queenside: true, kingside: true}, {queenside: true, kingside: true}]
- this.enPassantSquare = null;
- this.board = new Board();
- var majors = ["r", "n", "b", "q", "k", "b", "n", "r"];
- for (int x = 0; x < 8; x++) {
- this.board.setPiece(new Coord(x, 0), new PieceInstance(majors[x], false));
- this.board.setPiece(new Coord(x, 1), new PieceInstance("p", false));
- this.board.setPiece(new Coord(x, 6), new PieceInstance("p", true));
- this.board.setPiece(new Coord(x, 7), new PieceInstance(majors[x], true));
- }
- this.promotePiece = null;
- }
- isPieceAttacked(pos) {
- if (this.board.getPiece(pos) === null)
- return false;
- var black = this.board.getPiece(pos).black;
- for (x = 0; x < 8; x++) {
- for (y = 0; y < 8; y++) {
- var piece = this.board.getPiece(pos);
- if (piece !== null && piece.black != black) {
- if (pieceClasses[piece.type].move(new Coord(x, y), pos, this, true))
- return true;
- }
- }
- }
- return false;
- }
- }
- var games = storage.get("chessGames");
- if (games === null)
- games = [];
- else
- games = JSON.parse(games);
- function saveGames() {
- storage.set("chessGames", JSON.stringify(games));
- }
- function userName(user) {
- var userObj = guild.getUser(user);
- if (userObj.getNickname() === null)
- return userObj.getName();
- else
- return userObj.getNickname();
- }
- function parseMove(moveStr, game) {
- var regex = /^((((?<pieceType>[prnqkPRNBQK]|(b(?![xX])))?((?<fromX>[a-hA-H])|(?<fromY>(?<![bB])[1-8]))?((?<!^)[xX])?(?<toX>[a-hA-H])(?<toY>[1-8])))|(((?<simpleFromX>[a-hA-H])(?<simpleFromY>[1-8])[-xX]?(?<simpleToX>[a-hA-H])(?<simpleToY>[1-8])))|(?<kingsideCastle>0-0)|(?<queensideCastle>0-0-0))[\+#]*(=(?<promotePiece>[rnbqRNBQ]))?[\+#]*$/;
- var match = regex.exec(moveStr);
- if (match === null)
- return {error: "Invalid syntax"};
- var ret = {};
- if ("promotePiece" in match) {
- ret.promotePiece = match.promotePiece.toLowerCase();
- }
- if ("queensideCastle" in match) {
- if (!game.castleState[game.blackToMove ? 1 : 0].queenside) {
- return {error: "Illegal move"};
- }
- ret.fromX = 4;
- ret.fromY = game.blackToMove ? 7 : 0;
- ret.toX = 6;
- ret.toY = ret.fromY;
- } else if ("kingsideCastle" in match) {
- if (!game.castleState[game.blackToMove ? 1 : 0].kingside) {
- return {error: "Illegal move"};
- }
- ret.fromX = 4;
- ret.fromY = game.blackToMove ? 7 : 0;
- ret.toX = 2;
- ret.toY = ret.fromY;
- } else if ("simpleFromX" in match) {
- ret.fromX = match.simpleFromX.toLowerCase().charCodeAt(0) - 97;
- ret.fromY = parseInt(match.simpleFromY) - 1;
- ret.toX = match.simpleToX.toLowerCase().charCodeAt(0) - 97;
- ret.toY = parseInt(match.simpleToY) - 1;
- } else {
- var pieceType = ("pieceType" in match) ? match.pieceType.toLowerCase() : "p";
- ret.toX = match.toX.toLowerCase().charCodeAt(0) - 97;
- ret.toY = parseInt(match.toY) - 1;
- var dst = new Coord(ret.toX, ret.toY);
- var fromX = ("fromX" in match) ? match.fromX.toLowerCase().charCodeAt(0) - 97 : -1;
- var fromY = ("fromY" in match) ? parseInt(match.fromY) - 1 : -1;
- var foundPiece = false;
- for (int x = 0; x < 8; x++) {
- if (fromX == -1 || x == fromX) {
- for (int y = 0; y < 8; y++) {
- if (fromY == -1 || y == fromY) {
- var pos = new Coord(x, y);
- var piece = game.board.getPiece(pos);
- if (piece !== null && piece.black == game.blackToMove && piece.type == pieceType) {
- if (pieceClasses[pieceType].move(pos, dst, game, true)) {
- if (foundPiece) {
- return {error: "Ambiguous move"};
- }
- foundPiece = true;
- ret.fromX = fromX;
- ret.fromY = fromY;
- }
- }
- }
- }
- }
- }
- if (!foundPiece)
- return {error: "Invalid move"};
- return ret;
- }
- }
- function getGame(user) {
- for (int i = 0; i < games.length; i++) {
- var game = games[i];
- if (game.userWhite == user || game.userBlack == user)
- return game;
- }
- return null;
- }
- function startGame(userA, userB) {
- if (userA == userB) {
- channel.message("You cannot play yourself!");
- return;
- }
- if (getGame(userA) !== null) {
- channel.message(userName(userA) + " is already in a game");
- return;
- }
- if (getGame(userB) !== null) {
- channel.message(userName(userB) + " is already in a game");
- return;
- }
- var game;
- if (Math.random() < 0.5)
- game = new Game(userA, userB);
- else
- game = new Game(userB, userA);
- games.push(game);
- saveGames();
- printBoard(game);
- }
- function resignGame(resigner) {
- var game = getGame(resigner);
- if (game === null) {
- channel.message("You aren't in a game");
- return;
- }
- var opponent;
- if (resigner == game.userWhite)
- opponent = game.userBlack;
- else
- opponent = game.userWhite;
- games.splice(games.indexOf(game), 1);
- saveGames();
- channel.message("<@" + resigner + "> resigned, <@" + opponent + "> wins!");
- }
- function doMove(user, arg) {
- var game = getGame(user);
- if (game === null) {
- channel.message("You aren't in a game");
- return;
- }
- var black;
- if (user == game.userWhite)
- black = false;
- else
- black = true;
- if (black != game.blackToMove) {
- channel.message("It's not your turn");
- return;
- }
- var move = parseMove(arg, game);
- if ("error" in move) {
- channel.message(move.error);
- return;
- }
- if ("promotePiece" in move) {
- game.promotePiece = move.promotePiece;
- } else {
- game.promotePiece = null;
- }
- var src = new Coord(move.fromX, move.fromY);
- var dst = new Coord(move.toX, move.toZ);
- var piece = game.board.getPiece(src);
- if (piece === null || piece.black != black) {
- channel.message("Invalid piece");
- return;
- }
- if (!pieceClasses[piece.type].move(src, dst, game, false)) {
- channel.message("Invalid move");
- return;
- }
- var kingPos;
- for (var x = 0; x < 8; x++) {
- for (var y = 0; y < 8; y++) {
- kingPos = new Coord(x, y);
- var piece = game.board.getPiece(kingPos);
- if (piece !== null && piece.black == black && piece.type == "k") {
- break;
- }
- }
- }
- if (game.isPieceAttacked(kingPos)) {
- channel.message("Illegal move");
- return;
- }
- game.blackToMove = !game.blackToMove;
- printBoard(game);
- saveGames();
- }
- function printBoard(game) {
- var msg = "```";
- for (int y = 7; y >= 0; y--) {
- msg += "\n+-+-+-+-+-+-+-+-+";
- for (int x = 0; x < 8; x++) {
- msg += "|";
- var piece = game.board.getPiece(new Coord(x, y));
- if (piece === null)
- msg += " ";
- else if (piece.black)
- msg += piece.type;
- else
- msg += piece.type.toUpperCase();
- }
- msg += "|";
- }
- msg += "\n+-+-+-+-+-+-+-+-+"
- msg += "\n```"
- channel.message(msg);
- if (game.blackToMove)
- channel.message("Black to move <@" + game.userBlack + ">");
- else
- channel.message("White to move <@" + game.userWhite + ">");
- }
- function printUsage() {
- var usage = "```\n"
- + "//chess start <@opponent>\n"
- + "//chess <move>\n"
- + "//chess resign\n"
- + "//chess board\n"
- + "//chess help\n"
- + "```";
- }
- var arg = message.getContent();
- arg = arg.replace(/^\s*\S+\s*/, "");
- var args = arg.split(/s+/);
- if (args.length == 0) {
- printUsage();
- } else {
- arg = args[0];
- if (arg == "start") {
- if (args.length != 2) {
- printUsage();
- } else {
- var regex = /^<@(\d+)>$/
- var match = regex.match(args[1]);
- if (match === null) {
- printUsage();
- } else {
- startGame(message.getUser().getID(), parseInt(match[1]));
- }
- }
- } else if (arg == "resign") {
- resignGame(message.getUser().getID());
- } else if (arg == "help" || arg == "?") {
- printUsage();
- } else if (arg == "board") {
- var game = getGame(message.getUser().getID());
- if (game === null) {
- channel.message("You aren't in a game");
- } else {
- printBoard(game);
- }
- } else {
- if (args.length != 2)
- printUsage();
- else
- doMove(message.getUser().getID(), args[1]);
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement