diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..43ae0e2
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,2 @@
+__pycache__/
+*.py[cod]
diff --git a/UI/app.js b/UI/app.js
index 19d2553..c75b44d 100644
--- a/UI/app.js
+++ b/UI/app.js
@@ -9,6 +9,7 @@ function startNew(mode) {
// hard -> 18X32=576 -> 100 bombs | 24 -> 100 bombs
// extreme-> 26X50=1300 -> 220 bombs | 30 -> 200 bombs
// const mode = element.value;
+ isOpen = document.getElementById('isOpen').checked;
if (mode === "easy") {
size = 10;
bombs = 15;
@@ -32,7 +33,7 @@ function startNew(mode) {
document.getElementById("h1").classList.remove("won");
document.getElementById("h1").classList.remove("lost");
document.getElementById("h1").innerHTML = `Minesweeper`;
- eel.makeBoard(size, bombs)(); //size, bombs
+ eel.makeBoard(size, bombs, isOpen)(); //size, bombs
drawFirst();
}
diff --git a/UI/index.html b/UI/index.html
index a7d8222..dcad8c1 100644
--- a/UI/index.html
+++ b/UI/index.html
@@ -11,6 +11,8 @@
Minesweeper
+ Show Open
+
2:
+ raise ValueError(f"Only one or two dimensions supported, got {dim}")
+
+ self.dim = dim
+ self.numMines = m_numMines
+
+ self.values = np.zeros(self.shape, dtype=int)
+ self.selected = np.zeros(shape=self.values.shape, dtype=bool)
+
+ mine_indices = np.array(np.unravel_index(np.random.choice(self.values.size, size=m_numMines, replace=False), self.values.shape))
+ self.values[*mine_indices] = -1
+
+ for m in range(mine_indices.shape[-1]):
+ mine_index = mine_indices[:, m]
+ current_index = mine_index.copy()
+ for k in range(dim):
+ for a in [-1, 0, 1]:
+ if mine_index[k] + a >= self.values.shape[k] or mine_index[k] + a < 0:
+ continue
+ current_index[k] = mine_index[k] + a
+ for j in range(k):
+ for b in [-1, 0, 1]:
+ if mine_index[j] + b >= self.values.shape[j] or mine_index[j] + b < 0:
+ continue
+ current_index[j] = mine_index[j] + b
+ self.values[*current_index] += 1 if self.values[*current_index] >= 0 else 0
+
+
+ self.selectableSpots = self.values.size - m_numMines
+
+ @property
+ def boardSize(self):
+ return self.values.shape[0] # TODO generalize
+
def __str__(self):
+ if self.dim > 2:
+ raise ValueError(f"Only one or two dimensions supported, got {self.dim}")
returnString = " "
divider = "\n---"
- for i in range(0, self.boardSize):
- returnString += " | " + str(i)
- divider += "----"
- divider += "\n"
+ if len(self.values.shape > 1):
+
+ for i in range(0, self.values.shape[0]):
+ returnString += " | " + str(i)
+ divider += "----"
+ divider += "\n"
returnString += divider
for y in range(0, self.boardSize):
returnString += str(y)
for x in range(0, self.boardSize):
- if self.board[x][y].mine and self.board[x][y].selected:
- returnString += " |" + str(self.board[x][y].value)
- elif self.board[x][y].selected:
- returnString += " | " + str(self.board[x][y].value)
+ if self.values[x, y] < 0 and self.selected[x, y]:
+ returnString += " |" + str(self.values[x, y])
+ elif self.selected[x, y]:
+ returnString += " | " + str(self.values[x, y])
else:
returnString += " | "
returnString += " |"
returnString += divider
return returnString
- def addMine(self, x, y):
- self.board[x][y].value = -1
- self.board[x][y].mine = True
- for i in range(x-1, x+2):
- if i >= 0 and i < self.boardSize:
- if y-1 >= 0 and not self.board[i][y-1].mine:
- self.board[i][y-1].value += 1
- if y+1 < self.boardSize and not self.board[i][y+1].mine:
- self.board[i][y+1].value += 1
- if x-1 >= 0 and not self.board[x-1][y].mine:
- self.board[x-1][y].value += 1
- if x+1 < self.boardSize and not self.board[x+1][y].mine:
- self.board[x+1][y].value += 1
-
def makeMove(self, x, y):
- self.board[x][y].selected = True
+ self.selected[x, y] = True
self.selectableSpots -= 1
- if self.board[x][y].value == -1:
+ if self.values[x, y] == -1:
return False
- if self.board[x][y].value == 0:
+ if self.values[x, y] == 0:
for i in range(x-1, x+2):
if i >= 0 and i < self.boardSize:
- if y-1 >= 0 and not self.board[i][y-1].selected:
+ if y-1 >= 0 and not self.selected[i, y-1]:
self.makeMove(i, y-1)
- if y+1 < self.boardSize and not self.board[i][y+1].selected:
+ if y+1 < self.boardSize and not self.selected[i, y+1]:
self.makeMove(i, y+1)
- if x-1 >= 0 and not self.board[x-1][y].selected:
+ if x-1 >= 0 and not self.selected[x-1,y]:
self.makeMove(x-1, y)
- if x+1 < self.boardSize and not self.board[x+1][y].selected:
+ if x+1 < self.boardSize and not self.selected[x+1, y]:
self.makeMove(x+1, y)
return True
else:
return True
def hitMine(self, x, y):
- return self.board[x][y].value == -1
+ return self.values[x, y] == -1
def isWinner(self):
return self.selectableSpots == 0
+def increment_tuple(t: tuple, index: int = 0, value: int = 1) -> tuple:
+ if not t or index < 0 or index >= len(t):
+ return t # Return original tuple if empty or index is out of range
+
+ t_list = list(t)
+ t_list[index] += value
+ return tuple(t_list)
#play game
def playGame():
boardSize = int(input("Choose the Width of the board: "))
numMines = int(input("Choose the number of mines: "))
+ dim = int(input("Choose dimensions of board: "))
gameOver = False
winner = False
- Board = boardClass(boardSize, numMines)
+ Board = boardClass(boardSize, numMines, dim=dim)
while not gameOver:
print(Board)
print("Make your move:")
@@ -112,7 +118,7 @@ def playGame():
y = int(input("y: "))
Board.makeMove(x, y)
gameOver = Board.hitMine(x, y)
- if Board.isWinner() and gameOver == False:
+ if Board.isWinner() and gameOver is False:
gameOver = True
winner = True
@@ -122,4 +128,5 @@ def playGame():
else:
print("You hit a mine, Game Over!")
-playGame()
+if __name__ == "__main__":
+ playGame()
diff --git a/minesweeperGUI.py b/minesweeperGUI.py
index 4b2f546..c1c160c 100644
--- a/minesweeperGUI.py
+++ b/minesweeperGUI.py
@@ -1,95 +1,36 @@
-import random
import eel
+from minesweeper import boardClass
-class boardSpot(object):
- value = 0
- selected = False
- mine = False
-
- def __init__(self):
- self.selected = False
-
- def __str__(self):
- return str(boardSpot.value)
-
- def isMine(self):
- if boardSpot.value == -1:
- return True
- return False
-
-
-class boardClass(object):
- def __init__(self, m_boardSize, m_numMines):
- self.board = [[boardSpot() for i in range(m_boardSize)]
- for j in range(m_boardSize)]
- self.boardSize = m_boardSize
- self.numMines = m_numMines
- self.selectableSpots = m_boardSize * m_boardSize - m_numMines
- i = 0
- while i < m_numMines:
- x = random.randint(0, self.boardSize-1)
- y = random.randint(0, self.boardSize-1)
- if not self.board[x][y].mine:
- self.addMine(x, y)
- i += 1
- else:
- i -= 1
+class GUIBoardClass(boardClass):
def __str__(self):
returnString = ""
for y in range(0, self.boardSize):
# returnString += str(y)
for x in range(0, self.boardSize):
- if self.board[x][y].mine and self.board[x][y].selected:
+ if self.values[x, y] == -1 and self.selected[x, y]:
returnString += 'B'
# returnString += str(self.board[x][y].value)
- elif self.board[x][y].selected:
- returnString += str(self.board[x][y].value)
+ elif self.selected[x, y]:
+ returnString += str(self.values[x, y])
else: # empthy cell
returnString += "E"
return returnString
- def addMine(self, x, y):
- self.board[x][y].value = -1
- self.board[x][y].mine = True
- for i in range(x-1, x+2):
- if i >= 0 and i < self.boardSize:
- if y-1 >= 0 and not self.board[i][y-1].mine:
- self.board[i][y-1].value += 1
- if y+1 < self.boardSize and not self.board[i][y+1].mine:
- self.board[i][y+1].value += 1
- if x-1 >= 0 and not self.board[x-1][y].mine:
- self.board[x-1][y].value += 1
- if x+1 < self.boardSize and not self.board[x+1][y].mine:
- self.board[x+1][y].value += 1
-
- def makeMove(self, x, y):
- self.board[x][y].selected = True
- self.selectableSpots -= 1
- if self.board[x][y].value == -1:
- return False
- if self.board[x][y].value == 0:
- for i in range(x-1, x+2):
- if i >= 0 and i < self.boardSize:
- if y-1 >= 0 and not self.board[i][y-1].selected:
- self.makeMove(i, y-1)
- if y+1 < self.boardSize and not self.board[i][y+1].selected:
- self.makeMove(i, y+1)
- if x-1 >= 0 and not self.board[x-1][y].selected:
- self.makeMove(x-1, y)
- if x+1 < self.boardSize and not self.board[x+1][y].selected:
- self.makeMove(x+1, y)
- return True
- else:
- return True
-
- def hitMine(self, x, y):
- return self.board[x][y].value == -1
-
- def isWinner(self):
- return self.selectableSpots == 0
+
+class OpenGUIBoardClass(boardClass):
+ def __str__(self):
+ returnString = ""
+ for y in range(0, self.boardSize):
+ # returnString += str(y)
+ for x in range(0, self.boardSize):
+ if self.values[x, y] == -1:
+ returnString += str(0)
+ else:
+ returnString += str(self.values[x, y])
+ return returnString
#### For UI ####
@@ -109,7 +50,7 @@ def clickedOnTheCell(x, y):
if GO_IN:
BOARD.makeMove(x, y)
GAME_OVER = BOARD.hitMine(x, y)
- if BOARD.isWinner() and GAME_OVER == False:
+ if BOARD.isWinner() and GAME_OVER is False:
GAME_OVER = True
WINNER = True
print("Won")
@@ -121,10 +62,13 @@ def clickedOnTheCell(x, y):
@eel.expose
-def makeBoard(boardSize, numMines):
+def makeBoard(boardSize, numMines, isOpen=False):
global BOARD
del BOARD
- BOARD = boardClass(boardSize, numMines)
+ if isOpen:
+ BOARD = OpenGUIBoardClass(boardSize, numMines)
+ else:
+ BOARD = GUIBoardClass(boardSize, numMines) # noqa: F841
web_app_options = {
diff --git a/requirements.txt b/requirements.txt
index b81a462..2abcaf0 100644
--- a/requirements.txt
+++ b/requirements.txt
@@ -1 +1,2 @@
-eel==0.14.0
\ No newline at end of file
+eel==0.14.0
+numpy==2.2.4
\ No newline at end of file