UNPKG

morris

Version:

Nine Men's Morris implementation in Node.js

194 lines (155 loc) 4.92 kB
var viewMenu = document.querySelector(".view.menu"); var viewGame = document.querySelector(".view.game"); var inputRowsCount = document.querySelector(".input-rows"); var startGameBtn = document.querySelector(".btn-startgame"); var menuBtn = document.querySelector(".btn-menu"); var exportBtn = document.querySelector(".btn-export"); var btnLoad = document.querySelector(".btn-load"); var fileInput = document.querySelector(".file-input"); var aiChecker = document.querySelector(".ai-check"); startGameBtn.addEventListener("click", function() { viewMenu.classList.remove("visible"); viewGame.classList.add("visible"); createUserGame(parseInt(inputRowsCount.value), [false, true, false], 9, [], [], [false, aiChecker.checked]); render(); }); function createUserGame(rows, points, piecesCount, defaultMap, defaultTeams, aiPlaying) { game = new MorrisGame({ board: { rows: rows, points: points, default: defaultMap }, pieces: piecesCount, rules: true, teams: defaultTeams }); ai = new MorrisAI(game, MorrisGame); teams = { "white": aiPlaying[0], "black": aiPlaying[1] }; } menuBtn.addEventListener("click", function() { viewMenu.classList.add("visible"); viewGame.classList.remove("visible"); }); exportBtn.addEventListener("click", function() { var exportData = { board: { points: game.board.points, rows: game.board.rows.length }, teams: game.teams.map(function(team) { delete team.activePieces; delete team.moveablePieces; return team; }), __lastChangeset: Object.assign({}, game.__lastChangeset) }; if (exportData.__lastChangeset) { exportData.__lastChangeset.targetPoint = game.board.map.indexOf(exportData.__lastChangeset.targetPoint); if ("startPoint" in exportData.__lastChangeset) { exportData.__lastChangeset.startPoint = game.board.map.indexOf(exportData.__lastChangeset.startPoint); } } var exportDataStr = JSON.stringify(exportData); window.open("data:text/json;charset=utf-8," + exportDataStr); }); btnLoad.addEventListener("click", function() { fileInput.click(); }); fileInput.addEventListener("change", function(event) { var reader = new FileReader(); reader.addEventListener("load", function(progress) { var gameData = JSON.parse(reader.result); var pointCount = gameData.board.rows * (gameData.board.points.length - 1) * 4; var boardMap = new Array(pointCount).fill(function(index) { for (var team of gameData.teams) { if (team.pieces.objectFromKey(index, "point")) { return team.name; } } return false; }); viewMenu.classList.remove("visible"); viewGame.classList.add("visible"); createUserGame(gameData.board.rows, gameData.board.points, gameData.teams[0].pieces.length, boardMap, gameData.teams); if (gameData.__lastChangeset) { gameData.__lastChangeset.targetPoint = game.board.map[gameData.__lastChangeset.targetPoint]; if ("startPoint" in gameData.__lastChangeset) { gameData.__lastChangeset.startPoint = game.board.map[gameData.__lastChangeset.startPoint]; } } game.__lastChangeset = gameData.__lastChangeset; render(); }); reader.readAsText(event.target.files[0]); }); var svgRenderDocument = document.getElementById("board"); var game, ai, teams; var userActions = { set: { handle(point) { return game.set(Object.assign({ team: game.nextTeam, }, point.position)); } }, move: { selected: null, handle(point) { if (!this.selected) { this.selected = point; } else { var movement = game.move(this.selected.position, point.position); this.selected = null; return movement; } } }, remove: { handle(point) { return game.remove(point.position); } } }; function handleUserMovement(point) { var actions = { set(move) { game.set(Object.assign({ team: game.nextTeam }, move.targetPoint.position)); }, move(move) { game.move(move.startPoint.position, move.targetPoint.position); }, remove(move) { game.remove(move.targetPoint.position); } }; var changeset = userActions[game.nextAction].handle(point); render(); if (changeset && changeset.success && teams[game.nextTeam] && game.nextAction != "remove") { // AI is doing next movement let bestMoves = ai.calcMoves(game); actions[bestMoves[0].action](bestMoves[0]); if (game.nextAction === "remove") { let bestMoves = ai.calcMoves(game); actions[bestMoves[0].action](bestMoves[0]); } render(); } else { console.log(changeset); } } function render() { renderGame(game, svgRenderDocument, { margin: 16, radius: 15, strokeWidth: 0.5, selected: [userActions.move.selected] }, handleUserMovement); }