diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..4db98b6
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1 @@
+Nothing needs to be added to .gitignore since the changes only include source files (.js, .html) and the existing .gitignore is empty.
\ No newline at end of file
diff --git a/index.html b/index.html
index 4879ea9..e2bfe41 100644
--- a/index.html
+++ b/index.html
@@ -1,217 +1,18 @@
-
-
-
-
-
- Go
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+ Go
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/script.js b/script.js
new file mode 100644
index 0000000..85a3fe6
--- /dev/null
+++ b/script.js
@@ -0,0 +1,231 @@
+class GoGame {
+ constructor(canvasId) {
+ this.canvas = document.getElementById(canvasId);
+ this.ctx = this.canvas.getContext("2d");
+ this.CellSize = 50;
+ this.numberofCells = Math.floor(this.canvas.width / this.CellSize);
+ this.canvas.width = this.CellSize * this.numberofCells + 2;
+ this.canvas.height = this.canvas.width;
+
+ this.PosX = 0;
+ this.PosY = 0;
+ this.color = ["red", "blue"];
+ this.turn = 0;
+ this.isDot = new Array(this.numberofCells);
+ for(let i = 0; i < this.numberofCells; i++){
+ this.isDot[i] = new Array(this.numberofCells);
+ }
+
+ this.Dots = {
+ "red": [],
+ "blue": []
+ };
+
+ this.header_text = ["Ход Красного", "Ход Синего"];
+ this.header_color = ["red", "blue"];
+
+ this.setupEventListeners();
+ this.drawGrid();
+ this.updateTurnDisplay();
+ }
+
+ setupEventListeners() {
+ window.addEventListener("load", () => this.drawGrid());
+
+ this.canvas.addEventListener("mousemove", (event) => {
+ this.PosX = event.offsetX;
+ this.PosY = event.offsetY;
+ });
+
+ this.canvas.addEventListener("mousedown", () => {
+ this.handleCanvasClick();
+ });
+ }
+
+ handleCanvasClick() {
+ let ostX1 = this.PosX % this.CellSize;
+ let ostX2 = this.CellSize - ostX1;
+ let ostY1 = this.PosY % this.CellSize;
+ let ostY2 = this.CellSize - ostY1;
+ this.PosX = (ostX1 <= 20 ? this.PosX - ostX1 : (ostX2 <= 20 ? this.PosX + ostX2 : this.PosX));
+ this.PosY = (ostY1 <= 20 ? this.PosY - ostY1 : (ostY2 <= 20 ? this.PosY + ostY2 : this.PosY));
+
+ if(this.PosX % this.CellSize === 0 && this.PosY % this.CellSize === 0 &&
+ this.isDot[Math.floor(this.PosX / this.CellSize)][Math.floor(this.PosY / this.CellSize)] === undefined){
+
+ let x = Math.floor(this.PosX / this.CellSize);
+ let y = Math.floor(this.PosY / this.CellSize);
+
+ this.isDot[x][y] = this.color[this.turn];
+ this.Dots[this.color[this.turn]].push([x, y]);
+
+ this.drawDot(this.PosX, this.PosY, this.color[this.turn]);
+
+ // Проверяем наличие цикла
+ this.checkForCycle(x, y);
+
+ this.turn = 1 - this.turn; // Переключаем ход
+ this.updateTurnDisplay();
+ }
+ }
+
+ drawDot(x, y, color) {
+ this.ctx.beginPath();
+ this.ctx.arc(x, y, 10, 0, 2 * Math.PI);
+ this.ctx.fillStyle = color;
+ this.ctx.lineWidth = 1;
+ this.ctx.strokeStyle = color;
+ this.ctx.stroke();
+ this.ctx.fill();
+ }
+
+ updateTurnDisplay() {
+ const turnElement = document.getElementById("turn");
+ turnElement.innerHTML = this.header_text[this.turn];
+ turnElement.removeAttribute("class");
+ turnElement.classList.add(this.header_color[this.turn]);
+ }
+
+ good(x, y) {
+ return (x > 0 && y > 0 && x < this.numberofCells && y < this.numberofCells);
+ }
+
+ findCycle(startX, startY, color) {
+ const used = {};
+ const parent = {};
+ const cycle = [];
+ let cycleEnd = null;
+ const cycleStart = [startX, startY];
+
+ // Инициализируем used и parent
+ this.Dots[color].forEach(dot => {
+ const key = `${dot[0]},${dot[1]}`;
+ used[key] = 0;
+ parent[key] = [-1, -1];
+ });
+
+ const dfs = (x, y) => {
+ const currentKey = `${x},${y}`;
+ used[currentKey] = 1;
+
+ // Проверяем все 8 соседей
+ for(let i = -1; i <= 1; i++){
+ for(let j = -1; j <= 1; j++){
+ if(i === 0 && j === 0){
+ continue;
+ }
+ let newx = x + i;
+ let newy = y + j;
+
+ if(this.good(newx, newy)){
+ if(this.isDot[newx][newy] === color){
+ const neighborKey = `${newx},${newy}`;
+
+ if(used[neighborKey] === 0){
+ parent[neighborKey] = [x, y];
+ dfs(newx, newy);
+ } else if(newx === cycleStart[0] && newy === cycleStart[1] &&
+ (parent[currentKey][0] !== newx || parent[currentKey][1] !== newy)){
+ cycleEnd = [x, y];
+ let v = cycleEnd;
+ while(!(v[0] === cycleStart[0] && v[1] === cycleStart[1])) {
+ cycle.push(v);
+ const parentKey = `${v[0]},${v[1]}`;
+ v = parent[parentKey];
+ }
+ cycle.push(cycleStart);
+ this.checkCycle(cycle, color);
+ }
+ }
+ }
+ }
+ }
+ };
+
+ dfs(startX, startY);
+ }
+
+ checkCycle(cycle, color) {
+ let minix = Infinity, maxix = -Infinity, miniy = Infinity, maxiy = -Infinity;
+
+ cycle.forEach(v => {
+ minix = Math.min(minix, v[0]);
+ maxix = Math.max(maxix, v[0]);
+ miniy = Math.min(miniy, v[1]);
+ maxiy = Math.max(maxiy, v[1]);
+ });
+
+ const enemies = [];
+ for(let i = miniy; i <= maxiy; i++){
+ let left = -1, right = -1;
+ for(let j = minix; j <= maxix; j++){
+ if(this.isDot[j][i] === color){
+ left = j;
+ break;
+ }
+ }
+ for(let j = maxix; j >= minix; j--){
+ if(this.isDot[j][i] === color){
+ right = j;
+ break;
+ }
+ }
+ if(left !== -1 && right !== -1) {
+ for(let j = left; j <= right; j++){
+ if(this.isDot[j][i] === (color === 'red' ? 'blue' : 'red')){
+ enemies.push([j, i]);
+ }
+ }
+ }
+ }
+
+ if(enemies.length > 0){
+ enemies.forEach(enemy => {
+ this.isDot[enemy[0]][enemy[1]] = '.';
+ });
+
+ // Визуализируем захваченную территорию
+ this.ctx.beginPath();
+ this.ctx.lineWidth = 5;
+ this.ctx.strokeStyle = color;
+ this.ctx.globalAlpha = 0.3; // Прозрачность для визуального эффекта
+ this.ctx.moveTo(cycle[0][0] * this.CellSize, cycle[0][1] * this.CellSize);
+
+ for(let i = 1; i < cycle.length; i++){
+ this.ctx.lineTo(cycle[i][0] * this.CellSize, cycle[i][1] * this.CellSize);
+ }
+ this.ctx.closePath();
+ this.ctx.stroke();
+ this.ctx.globalAlpha = 1.0; // Восстанавливаем прозрачность
+ }
+ }
+
+ checkForCycle(x, y) {
+ this.findCycle(x, y, this.color[this.turn]);
+ }
+
+ drawGrid() {
+ this.ctx.clearRect(0, 0, this.canvas.width, this.canvas.height);
+ this.ctx.strokeStyle = "black";
+ this.ctx.lineWidth = "1";
+
+ for(let i = 0; i < this.canvas.height; i += this.CellSize){
+ this.ctx.beginPath();
+ this.ctx.moveTo(0, i);
+ this.ctx.lineTo(this.canvas.width, i);
+ this.ctx.stroke();
+ }
+
+ for(let i = 0; i < this.canvas.width; i += this.CellSize){
+ this.ctx.beginPath();
+ this.ctx.moveTo(i, 0);
+ this.ctx.lineTo(i, this.canvas.height);
+ this.ctx.stroke();
+ }
+ }
+}
+
+// Инициализация игры при загрузке
+document.addEventListener('DOMContentLoaded', () => {
+ const game = new GoGame('canvas');
+});
\ No newline at end of file