Compare commits
No commits in common. "44cb7a697b119d7b1a995af1bd9790d14c9a2d1d" and "157b7e3c90212f51aa229ef352ea71652481cbe8" have entirely different histories.
44cb7a697b
...
157b7e3c90
|
@ -1,9 +1,9 @@
|
||||||
# About
|
# About
|
||||||
This is just a Sudoku program written in python using the PySide2 library. It's supposed to be a learning experience
|
This is just a Sudoku program written in python using the PyQt5 library. It's supposed to be a learning experience
|
||||||
about the graphics system of PyQt.
|
about the graphics system of PyQt. The goal(?) is to make it as animated as possible.
|
||||||
|
|
||||||
## Requirements
|
## Requirements
|
||||||
Requires `Python 3`, `PySide2`, and `Numpy`.
|
Requires `Python 3`, `PyQt5`, and `Numpy`.
|
||||||
|
|
||||||
Use the requirements.txt to install the dependencies.
|
Use the requirements.txt to install the dependencies.
|
||||||
|
|
||||||
|
|
|
@ -43,12 +43,10 @@ def generate_completed_grid(n):
|
||||||
|
|
||||||
def generate_dig_sequence(difficulty):
|
def generate_dig_sequence(difficulty):
|
||||||
if difficulty <= 1:
|
if difficulty <= 1:
|
||||||
# Random Digging
|
|
||||||
random_number = list(range(81))
|
random_number = list(range(81))
|
||||||
while len(random_number) > 0:
|
while len(random_number) > 0:
|
||||||
yield random_number.pop(random.randint(0, len(random_number)-1))
|
yield random_number.pop(random.randint(0, len(random_number)-1))
|
||||||
elif difficulty == 2:
|
elif difficulty == 2:
|
||||||
# Skip one cell
|
|
||||||
current = 0
|
current = 0
|
||||||
while current < 162:
|
while current < 162:
|
||||||
actual = current % 81
|
actual = current % 81
|
||||||
|
@ -59,7 +57,6 @@ def generate_dig_sequence(difficulty):
|
||||||
yield (row+1) * 9 - 1 - (actual % 9) % 81
|
yield (row+1) * 9 - 1 - (actual % 9) % 81
|
||||||
current += 2
|
current += 2
|
||||||
elif difficulty == 3:
|
elif difficulty == 3:
|
||||||
# S wandering
|
|
||||||
current = 0
|
current = 0
|
||||||
while current < 81:
|
while current < 81:
|
||||||
row = int(current / 9)
|
row = int(current / 9)
|
||||||
|
@ -69,7 +66,6 @@ def generate_dig_sequence(difficulty):
|
||||||
yield (row+1) * 9 - 1 - (current % 9)
|
yield (row+1) * 9 - 1 - (current % 9)
|
||||||
current += 1
|
current += 1
|
||||||
elif difficulty == 4:
|
elif difficulty == 4:
|
||||||
# Left-to-right, top-to-bottom
|
|
||||||
current = 0
|
current = 0
|
||||||
while current < 81:
|
while current < 81:
|
||||||
yield current
|
yield current
|
||||||
|
|
|
@ -3,7 +3,7 @@ of the boards."""
|
||||||
|
|
||||||
from PySide2.QtGui import QPen
|
from PySide2.QtGui import QPen
|
||||||
from PySide2.QtWidgets import QSizePolicy, QGraphicsWidget
|
from PySide2.QtWidgets import QSizePolicy, QGraphicsWidget
|
||||||
from PySide2.QtCore import (QAbstractAnimation, Qt, QLineF, QPropertyAnimation, Property, Signal, QSizeF, QRectF, QTimer)
|
from PySide2.QtCore import (QAbstractAnimation, Qt, QLineF, QPropertyAnimation, Property, Signal, QSizeF, QRectF)
|
||||||
|
|
||||||
from . import sudoku_graphics as sdk_grap
|
from . import sudoku_graphics as sdk_grap
|
||||||
from . import menu_graphics as menu_grap
|
from . import menu_graphics as menu_grap
|
||||||
|
@ -147,7 +147,7 @@ class GameBoard(BoxBoard):
|
||||||
self.numring = sdk_grap.NumberRing(parent=self)
|
self.numring = sdk_grap.NumberRing(parent=self)
|
||||||
self.playmenu = sdk_grap.PlayMenu(parent=self)
|
self.playmenu = sdk_grap.PlayMenu(parent=self)
|
||||||
|
|
||||||
#self.gamegrid.setFocus(Qt.MouseFocusReason)
|
self.gamegrid.setFocus(Qt.MouseFocusReason)
|
||||||
self.show_grid(False)
|
self.show_grid(False)
|
||||||
self.show_playmenu(False)
|
self.show_playmenu(False)
|
||||||
|
|
||||||
|
@ -161,10 +161,6 @@ class GameBoard(BoxBoard):
|
||||||
self.anim.finished.connect(lambda: self.show_playmenu(True))
|
self.anim.finished.connect(lambda: self.show_playmenu(True))
|
||||||
self.toggle_anim(True)
|
self.toggle_anim(True)
|
||||||
|
|
||||||
self.refocus_timer = QTimer()
|
|
||||||
self.refocus_timer.timeout.connect(self.game_refocus)
|
|
||||||
self.refocus_timer.setSingleShot(True)
|
|
||||||
|
|
||||||
def show_number_ring(self, x=0, y=0, scribbling=False):
|
def show_number_ring(self, x=0, y=0, scribbling=False):
|
||||||
"""Display the Number Ring if it is not visible, while setting the focus to it
|
"""Display the Number Ring if it is not visible, while setting the focus to it
|
||||||
|
|
||||||
|
@ -178,7 +174,6 @@ class GameBoard(BoxBoard):
|
||||||
True to set Scribble mode, False otherwise
|
True to set Scribble mode, False otherwise
|
||||||
"""
|
"""
|
||||||
if not self.numring.isVisible():
|
if not self.numring.isVisible():
|
||||||
self.game_unfocus()
|
|
||||||
self.numring.setPos(x, y)
|
self.numring.setPos(x, y)
|
||||||
self.numring.setVisible(True)
|
self.numring.setVisible(True)
|
||||||
self.numring.setFocus()
|
self.numring.setFocus()
|
||||||
|
@ -206,17 +201,9 @@ class GameBoard(BoxBoard):
|
||||||
"""Enable the grid and give it grid focus
|
"""Enable the grid and give it grid focus
|
||||||
"""
|
"""
|
||||||
self.gamegrid.set_disabled(False)
|
self.gamegrid.set_disabled(False)
|
||||||
#self.gamegrid.setFocus()
|
self.gamegrid.setFocus()
|
||||||
self.gamegrid.scribbling = self.numring.scribbling # To update the grid scribbling mode
|
self.gamegrid.scribbling = self.numring.scribbling # To update the grid scribbling mode
|
||||||
|
|
||||||
def game_unfocus(self):
|
|
||||||
"""Enable the grid and give it grid focus
|
|
||||||
"""
|
|
||||||
self.gamegrid.set_disabled(True)
|
|
||||||
#self.gamegrid.setFocus()
|
|
||||||
#self.gamegrid.scribbling = self.numring.scribbling # To update the grid scribbling mode
|
|
||||||
|
|
||||||
|
|
||||||
def show_grid(self, state):
|
def show_grid(self, state):
|
||||||
"""Show the grid, if it is not; Hide the grid, if it is.
|
"""Show the grid, if it is not; Hide the grid, if it is.
|
||||||
Note: Animation only plays when showing the grid.
|
Note: Animation only plays when showing the grid.
|
||||||
|
|
|
@ -64,7 +64,6 @@ class AnimBox(QGraphicsObject):
|
||||||
|
|
||||||
self.line_order = [self.up, self.right, self.down, self.left]
|
self.line_order = [self.up, self.right, self.down, self.left]
|
||||||
|
|
||||||
self.accepted_buttons = Qt.LeftButton
|
|
||||||
self.set_freeze(False)
|
self.set_freeze(False)
|
||||||
|
|
||||||
self.length = 0
|
self.length = 0
|
||||||
|
@ -86,7 +85,7 @@ class AnimBox(QGraphicsObject):
|
||||||
self.setAcceptedMouseButtons(Qt.NoButton)
|
self.setAcceptedMouseButtons(Qt.NoButton)
|
||||||
self.setAcceptHoverEvents(False)
|
self.setAcceptHoverEvents(False)
|
||||||
else:
|
else:
|
||||||
self.setAcceptedMouseButtons(self.accepted_buttons)
|
self.setAcceptedMouseButtons(Qt.LeftButton)
|
||||||
self.setAcceptHoverEvents(True)
|
self.setAcceptHoverEvents(True)
|
||||||
|
|
||||||
def toggle_anim(self, toggling):
|
def toggle_anim(self, toggling):
|
||||||
|
@ -202,7 +201,7 @@ class RingButton(AnimBox):
|
||||||
buttonClicked: Signal(str)
|
buttonClicked: Signal(str)
|
||||||
Emitted when it is clicked. Sends the text of the button
|
Emitted when it is clicked. Sends the text of the button
|
||||||
"""
|
"""
|
||||||
buttonClicked = Signal(str, int)
|
buttonClicked = Signal(str)
|
||||||
|
|
||||||
# Initialisation
|
# Initialisation
|
||||||
def __init__(self, x, y, width, height, text, parent=None):
|
def __init__(self, x, y, width, height, text, parent=None):
|
||||||
|
@ -217,7 +216,6 @@ class RingButton(AnimBox):
|
||||||
super().__init__(x, y, width, height, parent=parent)
|
super().__init__(x, y, width, height, parent=parent)
|
||||||
self.text = text
|
self.text = text
|
||||||
self.transparent = False
|
self.transparent = False
|
||||||
self.accepted_buttons = self.accepted_buttons | Qt.RightButton
|
|
||||||
|
|
||||||
def set_transparent(self, state):
|
def set_transparent(self, state):
|
||||||
"""Make the button transparent
|
"""Make the button transparent
|
||||||
|
@ -254,7 +252,7 @@ class RingButton(AnimBox):
|
||||||
"""
|
"""
|
||||||
event.accept()
|
event.accept()
|
||||||
self.toggle_anim(False)
|
self.toggle_anim(False)
|
||||||
self.buttonClicked.emit(self.text, event.button())
|
self.buttonClicked.emit(self.text)
|
||||||
|
|
||||||
|
|
||||||
class MenuButton(AnimBox):
|
class MenuButton(AnimBox):
|
||||||
|
|
|
@ -84,19 +84,23 @@ class TimerDisplayer(QGraphicsWidget):
|
||||||
|
|
||||||
|
|
||||||
class DifficultyDisplayer(QGraphicsWidget):
|
class DifficultyDisplayer(QGraphicsWidget):
|
||||||
|
<<<<<<< HEAD
|
||||||
|
notFocus = Signal()
|
||||||
|
difficultySelected = Signal(str)
|
||||||
|
=======
|
||||||
"""Display the current difficulty. Clicking on it displays the difficulty menu.
|
"""Display the current difficulty. Clicking on it displays the difficulty menu.
|
||||||
|
|
||||||
Attributes
|
Attributes
|
||||||
----------
|
----------
|
||||||
notFocus: Signal
|
notFocus: pyqtSignal
|
||||||
Emitted when it loses focus
|
Emitted when it loses focus
|
||||||
|
|
||||||
difficultySelected = Signal(str)
|
difficultySelected = pyqtSignal(str)
|
||||||
Emitted when a difficulty is selected. Emits the selected difficulty
|
Emitted when a difficulty is selected. Emits the selected difficulty
|
||||||
"""
|
"""
|
||||||
notFocus = Signal()
|
notFocus = pyqtSignal()
|
||||||
difficultySelected = Signal(str)
|
difficultySelected = pyqtSignal(str)
|
||||||
menuClicked = Signal(str)
|
>>>>>>> Document menu_graphics
|
||||||
|
|
||||||
def __init__(self, parent=None):
|
def __init__(self, parent=None):
|
||||||
"""Create the box and the text.
|
"""Create the box and the text.
|
||||||
|
@ -115,7 +119,6 @@ class DifficultyDisplayer(QGraphicsWidget):
|
||||||
self.diff_menu = DifficultyMenu(self.width, self.height, self)
|
self.diff_menu = DifficultyMenu(self.width, self.height, self)
|
||||||
self.diff_menu.setY(-self.diff_menu.height)
|
self.diff_menu.setY(-self.diff_menu.height)
|
||||||
self.diff_menu.setVisible(False)
|
self.diff_menu.setVisible(False)
|
||||||
self.diff_menu.menuClicked.connect(self.menuClicked.emit)
|
|
||||||
|
|
||||||
self.box_pen = QPen()
|
self.box_pen = QPen()
|
||||||
self.box_pen.setColor(Qt.white)
|
self.box_pen.setColor(Qt.white)
|
||||||
|
@ -164,7 +167,6 @@ class DifficultyDisplayer(QGraphicsWidget):
|
||||||
if not self.diff_menu.isVisible():
|
if not self.diff_menu.isVisible():
|
||||||
self.diff_menu.setFocus()
|
self.diff_menu.setFocus()
|
||||||
self.diff_menu.setVisible(True)
|
self.diff_menu.setVisible(True)
|
||||||
#self.clicked.emit()
|
|
||||||
else:
|
else:
|
||||||
self.diff_menu.setVisible(False)
|
self.diff_menu.setVisible(False)
|
||||||
self.notFocus.emit()
|
self.notFocus.emit()
|
||||||
|
@ -245,7 +247,7 @@ class DifficultyMenu(QGraphicsWidget):
|
||||||
return QRectF(0, 0, self.width, self.height)
|
return QRectF(0, 0, self.width, self.height)
|
||||||
|
|
||||||
def clicked_on(self, string):
|
def clicked_on(self, string):
|
||||||
"""Emits the menuClicked signal with the selected difficulty, when one of the buttons is pressed.
|
"""Emits the menuCLicked signal with the selected difficulty, when one of the buttons is pressed.
|
||||||
|
|
||||||
Parameters
|
Parameters
|
||||||
----------
|
----------
|
||||||
|
|
|
@ -192,7 +192,7 @@ class SudokuGrid(BaseSudokuItem):
|
||||||
|
|
||||||
self.setAcceptHoverEvents(True)
|
self.setAcceptHoverEvents(True)
|
||||||
self.setAcceptedMouseButtons(Qt.LeftButton)
|
self.setAcceptedMouseButtons(Qt.LeftButton)
|
||||||
#self.setFlag(QGraphicsItem.ItemIsFocusable, True)
|
self.setFlag(QGraphicsItem.ItemIsFocusable, True)
|
||||||
self.set_disabled(False)
|
self.set_disabled(False)
|
||||||
|
|
||||||
# Set up the animation
|
# Set up the animation
|
||||||
|
@ -326,19 +326,18 @@ class SudokuGrid(BaseSudokuItem):
|
||||||
|
|
||||||
if not self.sudoku_grid.get_cell_status(self.mouse_h, self.mouse_w) == sdk.FIXED:
|
if not self.sudoku_grid.get_cell_status(self.mouse_h, self.mouse_w) == sdk.FIXED:
|
||||||
self.buttonClicked.emit(w, h, self.scribbling)
|
self.buttonClicked.emit(w, h, self.scribbling)
|
||||||
self.set_disabled(True)
|
|
||||||
else:
|
else:
|
||||||
self.buttonClicked.emit(0, 0, self.scribbling)
|
self.buttonClicked.emit(0, 0, self.scribbling)
|
||||||
|
|
||||||
#def focusInEvent(self, event):
|
def focusInEvent(self, event):
|
||||||
"""Reimplemented from QGraphicsObject. Unfreeze the grid on focus
|
"""Reimplemented from QGraphicsObject. Unfreeze the grid on focus
|
||||||
"""
|
"""
|
||||||
#self.set_disabled(False)
|
self.set_disabled(False)
|
||||||
|
|
||||||
#def focusOutEvent(self, event):
|
def focusOutEvent(self, event):
|
||||||
"""Reimplemented from QGraphicsObject. Freeze the grid when out of focus
|
"""Reimplemented from QGraphicsObject. Freeze the grid when out of focus
|
||||||
"""
|
"""
|
||||||
#self.set_disabled(True)
|
self.set_disabled(True)
|
||||||
|
|
||||||
def keyPressEvent(self, event):
|
def keyPressEvent(self, event):
|
||||||
"""Reimplemented from QGraphicsObject. Check if scribble key is held, toggling on scribbling mode.
|
"""Reimplemented from QGraphicsObject. Check if scribble key is held, toggling on scribbling mode.
|
||||||
|
@ -466,7 +465,7 @@ class NumberRing(BaseSudokuItem):
|
||||||
"""
|
"""
|
||||||
pass
|
pass
|
||||||
|
|
||||||
def send_button_press(self, val, btn):
|
def send_button_press(self, val):
|
||||||
"""Emits the keyPressed signal if any of the buttons is pressed, and attempts to close the ring
|
"""Emits the keyPressed signal if any of the buttons is pressed, and attempts to close the ring
|
||||||
|
|
||||||
Parameters
|
Parameters
|
||||||
|
@ -474,10 +473,8 @@ class NumberRing(BaseSudokuItem):
|
||||||
val : str
|
val : str
|
||||||
The digit to be emitted
|
The digit to be emitted
|
||||||
"""
|
"""
|
||||||
scribble = btn == 2
|
self.keyPressed.emit(val, self.scribbling)
|
||||||
self.keyPressed.emit(val, scribble)
|
self.close_menu()
|
||||||
if not scribble:
|
|
||||||
self.close_menu()
|
|
||||||
|
|
||||||
def freeze_buttons(self, freeze):
|
def freeze_buttons(self, freeze):
|
||||||
"""Freezes the button
|
"""Freezes the button
|
||||||
|
|
3
main.py
3
main.py
|
@ -43,8 +43,7 @@ class SudokuWindow(QGraphicsView):
|
||||||
self.gameboard.gridDrawn.connect(lambda: self.menuboard.show_children(True))
|
self.gameboard.gridDrawn.connect(lambda: self.menuboard.show_children(True))
|
||||||
self.gameboard.newGameSelected.connect(self.menuboard.set_difficulty_text)
|
self.gameboard.newGameSelected.connect(self.menuboard.set_difficulty_text)
|
||||||
self.gameboard.sudokuDone.connect(self.menuboard.finish_the_game)
|
self.gameboard.sudokuDone.connect(self.menuboard.finish_the_game)
|
||||||
self.menuboard.diff_display.menuClicked.connect(self.gameboard.game_unfocus)
|
self.menuboard.diff_display.notFocus.connect(self.gameboard.game_refocus)
|
||||||
self.menuboard.diff_display.notFocus.connect(lambda: self.gameboard.refocus_timer.start(10))
|
|
||||||
self.menuboard.diff_display.difficultySelected.connect(self.gameboard.new_game)
|
self.menuboard.diff_display.difficultySelected.connect(self.gameboard.new_game)
|
||||||
|
|
||||||
def resizeEvent(self, event):
|
def resizeEvent(self, event):
|
||||||
|
|
Loading…
Reference in New Issue