From d48ac3970ef04a404c42f30c72cbdc327178f0dc Mon Sep 17 00:00:00 2001 From: Sébastien Dailly Date: Fri, 29 Aug 2014 14:44:44 +0200 Subject: Update js code --- qml/actions.js | 114 ----------------------- qml/javascript/goban_util.js | 212 +++++++++++++++++++++++++++++++++++++++++++ qml/pages/Goban.qml | 84 ++--------------- 3 files changed, 221 insertions(+), 189 deletions(-) delete mode 100644 qml/actions.js create mode 100644 qml/javascript/goban_util.js diff --git a/qml/actions.js b/qml/actions.js deleted file mode 100644 index 40b9330..0000000 --- a/qml/actions.js +++ /dev/null @@ -1,114 +0,0 @@ -.pragma library - -/** - * Check if the case on the grid belongs to the first column. - */ -function isFirstCol(index, cols) { - return index % cols == 0; -} - -/** - * Check if the case on the grid belongs to the last column. - */ -function isLastCol(index, cols) { - return index % cols == cols - 1; -} - -/** - * Check if the case on the grid belongs to the first row - */ -function isFirstRow(index, cols) { - return index < cols; -} - -/** - * Check if the case on the grid belongs to the last row. - */ -function isLastRow(index, cols, rows) { - return cols * (rows - 1) <= index; -} - -/** - * Get all the neighbors for a given position. - */ -function getNeighbors(index, cols, rows) { - - var neighbors = []; - if (!isFirstCol(index, cols)) { - neighbors.push(index - 1) - } - - if (!isLastCol(index, cols)) { - neighbors.push(index + 1) - } - - if (!isFirstRow(index, cols)) { - neighbors.push(index - cols) - } - - if (!isLastRow(index, cols, rows)) { - neighbors.push(index + cols) - } - - return neighbors; -} - -function getChainToRemove(index, datas, cols, rows, filter) { - - var piecesToCheck = []; - var piecesToRemove = []; - - /* - * filter wich keep only free places. - */ - function freePlaces(x) { - return datas.itemAt(x).getType() === ""; - } - - var piece = index; - while (piece !== undefined) { - - /* if the case has already been marked, do not check it again. - */ - if (!datas.itemAt(piece).mark) { - datas.itemAt(piece).mark = true; - piecesToRemove.push(piece); - - var neighbors = getNeighbors(piece, cols, rows); - - if (neighbors.length !== 0) { - /* - * If the place has liberty, return empty list. - */ - if (neighbors.some(freePlaces)) { - return []; - } - - /* - * Now update the check list. - */ - neighbors.filter(filter).forEach(function(x) { - piecesToCheck.push(x) - }); - - } - } else { - /* - * The piece may have been marked outside of this call. - * (We try to check chain in each direction, and return as soon as - * we find an empty place). - * If the piece is marked, but does not belongs to the piecesToRemove, - * we assume the piece is connected to a living chain, and - * subsequently this chain too. - */ - if (! piecesToRemove.some(function(x) { return x === piece})) { - return []; - } - } - - piece = piecesToCheck.pop(); - } - return piecesToRemove; - -} - diff --git a/qml/javascript/goban_util.js b/qml/javascript/goban_util.js new file mode 100644 index 0000000..dfaa70c --- /dev/null +++ b/qml/javascript/goban_util.js @@ -0,0 +1,212 @@ +.pragma library + +/** + * Check if the case on the grid belongs to the first column. + */ +function isFirstCol(index, cols) { + return index % cols == 0; +} + +/** + * Check if the case on the grid belongs to the last column. + */ +function isLastCol(index, cols) { + return index % cols == cols - 1; +} + +/** + * Check if the case on the grid belongs to the first row + */ +function isFirstRow(index, cols) { + return index < cols; +} + +/** + * Check if the case on the grid belongs to the last row. + */ +function isLastRow(index, cols, rows) { + return cols * (rows - 1) <= index; +} + +/** + * Get all the neighbors for a given position. + */ +function getNeighbors(index, cols, rows) { + + var neighbors = []; + if (!isFirstCol(index, cols)) { + neighbors.push(index - 1) + } + + if (!isLastCol(index, cols)) { + neighbors.push(index + 1) + } + + if (!isFirstRow(index, cols)) { + neighbors.push(index - cols) + } + + if (!isLastRow(index, cols, rows)) { + neighbors.push(index + cols) + } + + return neighbors; +} + +function getChainToRemove(index, grid, filter) { + + var piecesToCheck = []; + var piecesToRemove = []; + + /* + * filter wich keep only free places. + */ + function freePlaces(x) { + return grid.getElementAtIndex(x).getType() === ""; + } + + var piece = index; + while (piece !== undefined) { + + /* if the case has already been marked, do not check it again. + */ + if (!grid.getElementAtIndex(piece).mark) { + grid.getElementAtIndex(piece).mark = true; + piecesToRemove.push(piece); + + var neighbors = getNeighbors(piece, grid.columns, grid.rows); + + if (neighbors.length !== 0) { + /* + * If the place has liberty, return empty list. + */ + if (neighbors.some(freePlaces)) { + return []; + } + + /* + * Now update the check list. + */ + neighbors.filter(filter).forEach(function(x) { + piecesToCheck.push(x) + }); + + } + } else { + /* + * The piece may have been marked outside of this call. + * (We try to check chain in each direction, and return as soon as + * we find an empty place). + * If the piece is marked, but does not belongs to the piecesToRemove, + * we assume the piece is connected to a living chain, and + * subsequently this chain too. + */ + if (! piecesToRemove.some(function(x) { return x === piece})) { + return []; + } + } + + piece = piecesToCheck.pop(); + } + return piecesToRemove; + +} + +/** + * Add a new stone on the goban. + * + * Check if there are dead chained and remove them from the goban. + * + * index(int): the index where put the stone. + * grid(object): the grid where to put the stone: + * - grid.rows: number of rows in the grid + * - grid.columns: number of columes in the grid + * - grid.getElementAtIndex(index) should return the stone a the given index + * currentPlayer(bool): player color + * animation(bool): should we add animation on the goban + * allowSuicide(bool): if suicide an autorized action + * + * return true if the movement has been allowed. + */ +function addPiece(index, grid, currentPlayer, animation, allowSuicide, allowOveride) { + + var point = grid.getElementAtIndex(index); + var elementType = point.getType(); + + if (!allowOveride && elementType !== "") { + return false; + } + + var neighbors = getNeighbors(index, grid.columns, grid.rows); + + function isPlayer(x) { + return grid.getElementAtIndex(x).getType() === (currentPlayer ? "white" : "black"); + } + + function isOponnent(x) { + return grid.getElementAtIndex(x).getType() === (currentPlayer ? "black" : "white"); + } + + function freeOrChain(x) { + var pointType = grid.getElementAtIndex(x).getType(); + return pointType === "" || pointType === (currentPlayer ? "white" : "black"); + } + + point.put(currentPlayer, animation); + + if (neighbors.length === 0) { + return true; + } + + var somethingToRemove = false; + var movementAutorized = true; + + /* + * Check for pieces to remove. + */ + neighbors.filter(isOponnent).forEach(function(neighbor) { + + var piecesToRemove = getChainToRemove(neighbor, grid, isOponnent); + if (piecesToRemove.length !== 0) { + somethingToRemove = true; + } + piecesToRemove.forEach(function(x) { + grid.getElementAtIndex(x).remove(animation); + }) + }); + + /* + * Check for suicide. + */ + if (!somethingToRemove) { + var suicides = getChainToRemove(index, grid, isPlayer); + if (suicides.length !== 0) { + if (allowSuicide) { + suicides.forEach(function(x) { + grid.getElementAtIndex(x).remove(animation); + }); + } else { + point.remove(false); + movementAutorized = false; + } + } + + } + + /* + * Remove the marks in the cases. + * + * The call to getChainToRemove add marks on the cases in order to + * prevent infinite looping. We need to clean the cases before any new + * click. + * + * We do not need to remove them before as we are not filtering the + * same pieces. + */ + for (var i = 0; i < grid.columns * grid.rows; i++) { + grid.getElementAtIndex(i).mark = false; + } + + return movementAutorized; + +} diff --git a/qml/pages/Goban.qml b/qml/pages/Goban.qml index 0dee0c8..420d22d 100644 --- a/qml/pages/Goban.qml +++ b/qml/pages/Goban.qml @@ -1,6 +1,6 @@ import QtQuick 2.0 -import "../actions.js" as Actions +import "../javascript/goban_util.js" as Actions Item { @@ -54,6 +54,7 @@ Item { if (aw !== undefined) { aw.forEach(function (pos) { goban.getItemAt(pos[0], pos[1]).put(currentPlayer, false); +// Actions.addPiece(pos[0] + (pos[1] * goban.columns), goban, currentPlayer, false, true, true); }); } @@ -61,7 +62,7 @@ Item { if (ab !== undefined) { ab.forEach(function (pos) { goban.getItemAt(pos[0], pos[1]).put(!currentPlayer, false); - +// Actions.addPiece(pos[0] + (pos[1] * goban.columns), goban, !currentPlayer, false, true, true); }); } } @@ -106,78 +107,9 @@ Item { return; } - var point = repeater.itemAt(index); - var elementType = point.getType(); - - if (elementType !== "") { - return; - } - - var neighbors = Actions.getNeighbors(index, goban.columns, goban.rows); - - function isPlayer(x) { - return repeater.itemAt(x).getType() === (currentPlayer ? "white" : "black"); - } - - function isOponnent(x) { - return repeater.itemAt(x).getType() === (currentPlayer ? "black" : "white"); - } - - function freeOrChain(x) { - var pointType = repeater.itemAt(x).getType(); - return pointType === "" || pointType === (currentPlayer ? "white" : "black"); - } - - if (neighbors.length !== 0) { - - var somethingToRemove = false; - - point.put(currentPlayer, true); - - /* - * Check for pieces to remove. - */ - neighbors.filter(isOponnent).forEach(function(neighbor) { - - var piecesToRemove = Actions.getChainToRemove(neighbor, repeater, goban.columns, goban.rows, isOponnent); - if (piecesToRemove.length !== 0) { - somethingToRemove = true; - } - piecesToRemove.forEach(function(x) { - repeater.itemAt(x).remove(true); - }) - }); - - /* - * Check for suicide. - */ - if (!somethingToRemove) { - var suicides = Actions.getChainToRemove(index, repeater, goban.columns, goban.rows, isPlayer); - if (suicides.length !== 0) { -// suicides.forEach(function(x) { -// repeater.itemAt(x).remove(true); -// }); - point.remove(false); - currentPlayer = !currentPlayer; - } - - } - - /* - * Remove the marks in the cases. - * - * The call to getChainToRemove add marks on the cases in order to - * prevent infinite looping. We need to clean the cases before any new - * click. - * - * We do not need to remove them before as we are not filtering the - * same pieces. - */ - for (var i = 0; i < goban.columns * goban.rows; i++) { - repeater.itemAt(i).mark = false; - } + if (Actions.addPiece(index, goban, currentPlayer, true, false, false)) { + currentPlayer = !currentPlayer; } - currentPlayer = !currentPlayer; } @@ -233,8 +165,6 @@ Item { visible: (!((index === goban.columns - 1 && !limitRight) || (index === 0 && !limitLeft))); } - - } /* @@ -251,6 +181,10 @@ Item { return repeater.itemAt(x + y * columns) } + function getElementAtIndex(index) { + return repeater.itemAt(index); + } + Repeater { model: goban.columns * goban.rows id : repeater -- cgit v1.2.3