summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSébastien Dailly <sebastien@chimrod.com>2014-08-29 14:44:44 +0200
committerSébastien Dailly <sebastien@chimrod.com>2014-08-29 14:44:44 +0200
commitd48ac3970ef04a404c42f30c72cbdc327178f0dc (patch)
tree2425a3bd33d91623cf4ae95380bd875ff3bcf2a8
parente0184289f4d95d1d41959b5e043c9584cc66cefb (diff)
Update js code
-rw-r--r--qml/actions.js114
-rw-r--r--qml/javascript/goban_util.js212
-rw-r--r--qml/pages/Goban.qml84
3 files changed, 221 insertions, 189 deletions
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