411 Report
411 Report
Section 1: Description
The program contains 8 functions 4 of which are functions being overridden from
the QWidth super class below are the functions and their uses
Subsection 1: init()
The init function creates the needed functionality and initial setup of the
gameboard. First it creates a 1D array and fills it to represent each index of the of the
gameboard. Then various variables used throughout the game combined with various
functions setting up windows are used for initial running. Finally the board is shuffled to
prepare user to play the game.
Subsection 2: mousePressEvent()
This is the function that activates whenever the window has been clicked. Firstly
it checks if board is solved and if so does nothing are requested by assignment. It then
calculates index clicked by user and sends to swapcell which handles the change in
board. The screen is then updated to show this change.
Subsection 3: paintEvent()
This is the function responsible for drawing the screen; it first grabs the size of
the window for positioning purposes. Afterwards, the painter function calculates the
necessary location to center game board on x axis and a set place to lower the board
into nice spot. The boardSize and cellSizes are than calculated such that the cells fit
inside the board and that the board fits within screen and looks decent. The board is
then drawn followed by all cell indexes. Then there is an if statement used to display the
win textif applicable and number of moves done so far.
Subsection 4: show()
The show function is a simple gram its main function is to call the parent
functions show and to set a reasonable size to the window.
Subsection 5: shuffle()
The shuffle function's job is to generate a random order of cells such that there is
only 1 of each number and one empty cell. I have represented the empty cell with a -1 as
it is a value no matter the number of cells that wont be used. The algorithm I used was to
create and array of all allowed indexes and to remove a random one and set the front
most not set cell to that number. I felt this solution was computationally simple and
unlikely to cause need major debuggings
Subsection 6: isSolved()
Since a function is solved when all numbers are in order and the last element is
empty of -1 implementation of this was rather simple as it ends up being and if
statement checking if first if that -1 is at end followed by if the array sorted and
therefore in order combined with the -1 removed since it doesnt need to be considered
is same as the array if not the array is not in order and therefore not solved. This
algorithm similar to last one left little room for debugging and error.
Subsection 7: isSolveable()
For this algorithm I first find the row of the empty index which is needed as the
algorithm given requires the knowledge of it. After that I use an algorithm to determine
number of inversions however inverted the other way as I thought working with
incrementing rather than decrementing for loops would be easier to work with. After
calculating inversions we simply returned true if it met and of 3 conditions to be
solvable.
Subsection 8: swapCell()
The job of the swap cell function is to move indexes around according to the rules
of the assignment. The function considers two cases first is if you clicked on same row as
the empty cell second is if the column is the same as the empty cell if neither is true
nothing is done and therefore not considered. The row function works by simply moving
the -1 to the clicked cell this naturall displaces everything properly although doesn’t
work on columns as it will push lower columns over columns. For columns I simmplete
loop through swapping each cell. For the first algorithm I calculate the amount of moves
that would’ve happened which is simply the amount of cells between. For loop I simply
increment by 1 and then decrease by 1 to remove the -1 swap move with itself.
Section 2: Pictures
#Imports
import sys
import math as m
import random as r
from PyQt5.QtGui import QPainter, QPen, QBrush, QColor, QFont
from PyQt5.QtWidgets import QWidget, QApplication, QDesktopWidget, QLabel
from PyQt5.QtCore import Qt, QRect, QPoint
#Generates GameBoard
self.gameGrid = [i+1 for i in range(gridWidth**2 - 1)] #We want to do a square because thats the
shape of the game
self.gameGrid.append(-1)
#Sets Various needed variables for game such as the games move count and the amount of cells
wide the board is
self.gridWidth = gridWidth
self.moves = 0
#Draws Grid
self.show()
def mousePressEvent(self, event):
if(self.isSolved()):
return
self.update()
return
def isSolved(self):
if self.gameGrid[len(self.gameGrid) - 1] == -1 and sorted(self.gameGrid[:-1]) == self.gameGrid[:-
1]:
return True
else:
return False
return False
def shuffle(self):
unusedIndexes = [i+1 for i in range(self.gridWidth**2 - 1)] #We want to do a square because
thats the shape of the game
unusedIndexes.append(-1)
for i in range(len(self.gameGrid)):
randomNum = r.randint(0,len(unusedIndexes) - 1)
self.gameGrid[i] = unusedIndexes[randomNum]
unusedIndexes.pop(randomNum)
fontSize = 65
#Adds Number to square
painter.setFont(QFont('Arial', fontSize, QFont.Bold))
#painter.setBold(True)
painter.drawText(self.gridStartX + self.cellSize * (index % self.cellWidth) + int(self.cellSize / 2 -
fontSize / 2) , self.gridStartY + self.cellSize * int(index / self.cellWidth) + int(self.cellSize / 2 +
fontSize / 2),str(indexNumber))
if(self.isSolved()):
painter.setPen(QColor(0,150,0))
painter.drawText(int(self.width / 2) - int(fontSize / 2) * len("YOU WIN!!!"),fontSize + 8,"YOU
WIN!!!")
print(self.moves)
painter.setPen(QColor(0,0,0))
painter.setFont(QFont('Arial', 25, QFont.Bold))
painter.drawText(int(self.width / 2 * 1.5),fontSize + 8,f"Moves: {self.moves}")
#Closes things up
painter.end()
if __name__ == '__main__':
#Generates Application Object
app = QApplication(sys.argv)
#closes Application
sys.exit(app.exec_())
Section 4: Sources
I made a lot of use of documentation and in class examples for getting functions.
There was occsional usage of python functions such as pop and insert which is
particularly exclusive to my algorithms.
Section 5: Sources
I received minor help for Cole Barbes who told me that the functions had to be named a
specific thing to override the Widget classes functions