951 lines
41 KiB
Python
951 lines
41 KiB
Python
from PyQt5 import QtCore, QtGui, QtWidgets
|
||
from PyQt5.QtWidgets import *
|
||
from PyQt5.Qt import *
|
||
import SQLEasy, json, os, random, corelib
|
||
import launcher # Интерфейс
|
||
|
||
|
||
def game(gameStyle, databaseObj, gamerID, gamehash, muzicOn=True, MINES=random.randint(25, 55)):
|
||
MINES_COMPR = False
|
||
import pygame
|
||
|
||
corelib.tool.showGUI_wait()
|
||
|
||
databaseObj.setItem('lastGame', gameStyle, 'ID', gamerID, DatabaseName='users')
|
||
# Импорт конфига
|
||
with open(f"source/{gameStyle}/about.json", 'r', encoding='utf-8') as gameconfig:
|
||
gameconfig = json.loads(gameconfig.read())
|
||
# Функции
|
||
|
||
|
||
def checkEnd(field):
|
||
endgame = True
|
||
for r in field:
|
||
for c in r:
|
||
if c in ('M:O', 'M', 'M:F'):
|
||
return True
|
||
if 'R' in c and ':O' not in c:
|
||
endgame = False
|
||
return endgame
|
||
|
||
|
||
def checkWin(field, endgamecheck=False):
|
||
fieldCheck = list()
|
||
endgame = True
|
||
for r in field:
|
||
for c in r:
|
||
fieldCheck.append(c)
|
||
if 'R' in c and ':O' not in c:
|
||
endgame = False
|
||
if endgamecheck:
|
||
return 'M:O' not in fieldCheck and endgame
|
||
else:
|
||
return 'M:O' not in fieldCheck
|
||
|
||
|
||
def compareFields(old_field, field):
|
||
if checkWin(field, True):
|
||
return
|
||
|
||
class emptySound:
|
||
def play(self):
|
||
pass
|
||
|
||
sounds = [
|
||
emptySound(),
|
||
pygame.mixer.Sound(f"source/{gameStyle}/openCell.wav"),
|
||
pygame.mixer.Sound(f"source/{gameStyle}/flag.wav")
|
||
]
|
||
|
||
actID = 0
|
||
|
||
comlete = False
|
||
|
||
for rowID in range(len(field)):
|
||
for cellID in range(len(field[rowID])):
|
||
if field[rowID][cellID] != old_field[rowID][cellID]:
|
||
if ':F' in field[rowID][cellID]:
|
||
actID = 2
|
||
comlete = True
|
||
break
|
||
elif ':O' in field[rowID][cellID] and field[rowID][cellID] != 'M:O':
|
||
actID = 1
|
||
comlete = True
|
||
break
|
||
if comlete:
|
||
break
|
||
|
||
sounds[actID].play()
|
||
# Классы игровых объектов
|
||
|
||
|
||
class controlBanner(pygame.sprite.Sprite):
|
||
def __init__(self, X, Y, platform='XBox', info_contentID=0):
|
||
infocontent = ['openCell', 'flagCell', 'restart']
|
||
pygame.sprite.Sprite.__init__(self)
|
||
self.image = pygame.Surface((228, 77))
|
||
self.platform = platform
|
||
self.info_contentID = info_contentID
|
||
self.image = pygame.image.load(f"source/{gameStyle}/{platform}_{infocontent[info_contentID]}.png")
|
||
self.rect = self.image.get_rect()
|
||
self.rect.x = X
|
||
self.rect.y = Y
|
||
|
||
def changePlatform(self, platform):
|
||
infocontent = ['openCell', 'flagCell', 'restart']
|
||
self.platform = platform
|
||
self.image = pygame.image.load(f"source/{gameStyle}/{platform}_{infocontent[self.info_contentID]}.png")
|
||
|
||
|
||
class Border(pygame.sprite.Sprite):
|
||
def __init__(self, X, Y, borderType='Left'):
|
||
pygame.sprite.Sprite.__init__(self)
|
||
self.image = pygame.Surface((228, 77))
|
||
self.animationFrameTime = 0
|
||
self.borderType = borderType
|
||
self.image = pygame.image.load(f"source/{gameStyle}/score_end{borderType}(0).png")
|
||
self.rect = self.image.get_rect()
|
||
self.rect.x = X
|
||
self.rect.y = Y
|
||
|
||
def update(self):
|
||
self.animationFrameTime += 1
|
||
if self.animationFrameTime >= 45:
|
||
self.animationFrameTime = 0
|
||
self.image = pygame.image.load(f"source/{gameStyle}/score_end{self.borderType}({self.animationFrameTime // 15}).png")
|
||
|
||
|
||
class resetButton(pygame.sprite.Sprite):
|
||
def __init__(self, X, Y):
|
||
pygame.sprite.Sprite.__init__(self)
|
||
self.image = pygame.Surface((228, 77))
|
||
self.hide = 'noHover'
|
||
self.endStatus = ''
|
||
self.image = pygame.image.load(f"source/{gameStyle}/resetButton_{self.endStatus}_{self.hide}.png")
|
||
self.rect = self.image.get_rect()
|
||
self.x = X
|
||
self.y = Y
|
||
|
||
self.rect.x = X
|
||
self.rect.y = Y
|
||
|
||
def editCond(self, hide=None, endStatus=None):
|
||
if not(hide is None):
|
||
self.hide = hide
|
||
if not(endStatus is None):
|
||
self.endStatus = endStatus
|
||
|
||
self.image = pygame.image.load(f"source/{gameStyle}/resetButton_{self.endStatus}_{self.hide}.png")
|
||
|
||
def check_myself_Location(self, X, Y):
|
||
if X >= self.x and X <= self.x + 32 and Y >= self.y and Y <= self.y + 32:
|
||
return self
|
||
|
||
|
||
class timerCell(pygame.sprite.Sprite):
|
||
def __init__(self, X, Y, value='off'):
|
||
pygame.sprite.Sprite.__init__(self)
|
||
self.image = pygame.Surface((228, 77))
|
||
self.value = value
|
||
self.image = pygame.image.load(f"source/{gameStyle}/score_{value}.png")
|
||
self.rect = self.image.get_rect()
|
||
self.rect.x = X
|
||
self.rect.y = Y
|
||
|
||
def editValue(self, value='off'):
|
||
self.value = value
|
||
self.image = pygame.image.load(f"source/{gameStyle}/score_{self.value}.png")
|
||
|
||
def update(self):
|
||
self.image = pygame.image.load(f"source/{gameStyle}/score_{self.value}.png")
|
||
|
||
|
||
class tablet(pygame.sprite.Sprite):
|
||
def __init__(self, X, Y):
|
||
pygame.sprite.Sprite.__init__(self)
|
||
self.image = pygame.Surface((228, 77))
|
||
self.image = pygame.image.load(f"source/{gameStyle}/Tablet.png")
|
||
self.rect = self.image.get_rect()
|
||
self.rect.x = X
|
||
self.rect.y = Y
|
||
|
||
|
||
class fieldCursor(pygame.sprite.Sprite):
|
||
def __init__(self, X, Y):
|
||
pygame.sprite.Sprite.__init__(self)
|
||
self.image = pygame.Surface((32, 32))
|
||
self.image = pygame.image.load(f"source/{gameStyle}/Cursor.png")
|
||
self.cellPos = (X, Y)
|
||
self.rect = self.image.get_rect()
|
||
self.rect.x = 93 + X * 31
|
||
self.rect.y = 133 + Y * 31
|
||
|
||
def setCell_coord(self, X, Y):
|
||
self.rect.x = 93 + X * 31
|
||
self.rect.y = 133 + Y * 31
|
||
self.cellPos = (X, Y)
|
||
|
||
|
||
class cell(pygame.sprite.Sprite):
|
||
def __init__(self, X, Y, coords, condition='CLOSED'):
|
||
pygame.sprite.Sprite.__init__(self)
|
||
self.image = pygame.Surface((32, 32))
|
||
self.image = pygame.image.load(f"source/{gameStyle}/closed_cell.png")
|
||
self.rect = self.image.get_rect()
|
||
self.rect.x = X
|
||
self.rect.y = Y
|
||
self.cellPosition = {
|
||
"X": coords[0],
|
||
"Y": coords[1]
|
||
}
|
||
|
||
self.condition = condition
|
||
self.animationFrameS = 0
|
||
|
||
def getCondition(self):
|
||
return self.condition
|
||
|
||
def update(self):
|
||
if self.condition == 'CLOSED':
|
||
self.image.blit(pygame.image.load(f"source/{gameStyle}/closed_cell.png"), (0, 0))
|
||
elif 'num_' in self.condition:
|
||
number = int(self.condition.split('_')[-1])
|
||
self.animationFrameS += 1
|
||
if self.animationFrameS >= 40:
|
||
self.animationFrameS = 0
|
||
self.image.blit(pygame.image.load(f"source/{gameStyle}/mines_{number}({self.animationFrameS // 20}).png"), (0, 0))
|
||
elif self.condition == 'OPENED':
|
||
self.animationFrameS += 1
|
||
if self.animationFrameS >= 40:
|
||
self.animationFrameS = 0
|
||
self.image.blit(pygame.image.load(f"source/{gameStyle}/open_cell_{self.animationFrameS // 20}.png"), (0, 0))
|
||
elif self.condition == 'FLAG':
|
||
self.animationFrameS += 1
|
||
if self.animationFrameS >= 40:
|
||
self.animationFrameS = 0
|
||
self.image.blit(pygame.image.load(f"source/{gameStyle}/flag_{self.animationFrameS // 20}.png"), (0, 0))
|
||
elif self.condition == 'BOMB':
|
||
self.animationFrameS += 1
|
||
if self.animationFrameS >= 40:
|
||
self.animationFrameS = 0
|
||
self.image.blit(pygame.image.load(f"source/{gameStyle}/mine_bombed({self.animationFrameS // 20}).png"), (0, 0))
|
||
elif self.condition == 'DEFUSE':
|
||
self.animationFrameS += 1
|
||
if self.animationFrameS >= 40:
|
||
self.animationFrameS = 0
|
||
self.image.blit(pygame.image.load(f"source/{gameStyle}/mine_finded({self.animationFrameS // 20}).png"), (0, 0))
|
||
|
||
def setCondition(self, value):
|
||
self.condition = value
|
||
|
||
|
||
class sceneGame(pygame.sprite.Group):
|
||
def __init__(self, platform):
|
||
pygame.sprite.Group.__init__(self)
|
||
# Sounds
|
||
self.bombSound = pygame.mixer.Sound(f"source/{gameStyle}/bomb.wav")
|
||
self.winSound = pygame.mixer.Sound(f"source/{gameStyle}/win.wav")
|
||
|
||
self.soundNotPlayed = True
|
||
|
||
self.PLATFORM = platform
|
||
self.cells = list()
|
||
for row in range(10):
|
||
self.cells.append(list())
|
||
for _cell in range(10):
|
||
addCell = cell(93 + _cell * 31, 133 + row * 31, (_cell, row))
|
||
self.add(addCell)
|
||
self.cells[-1].append({
|
||
"cellObject": addCell,
|
||
"coord_start": [93 + _cell * 31, 133 + row * 31],
|
||
"coord_last": [93 + (_cell + 1) * 31, 133 + (row + 1) * 31],
|
||
"coords_in_field": (_cell, row)
|
||
})
|
||
self.add(tablet(130, 14))
|
||
self.positionCursor = (0, 0)
|
||
self.cursor = fieldCursor(*self.positionCursor)
|
||
self.add(self.cursor)
|
||
self.add(Border(166, 93))
|
||
self.timeCells = list()
|
||
for i in range(3):
|
||
timerCellObj = timerCell(198 + i * 32, 93)
|
||
self.add(timerCellObj)
|
||
self.timeCells.append(timerCellObj)
|
||
self.add(Border(294, 93, 'Right'))
|
||
self.resetButton = resetButton(228, 448)
|
||
self.add(self.resetButton)
|
||
|
||
self.InfoTables = list()
|
||
|
||
for i in range(3):
|
||
control_banner = controlBanner(0, 404 + i * 32, platform, i)
|
||
self.add(control_banner)
|
||
self.InfoTables.append(control_banner)
|
||
|
||
def changePlatform(self, PLATFORM):
|
||
self.PLATFORM = PLATFORM
|
||
for tableObj in self.InfoTables:
|
||
tableObj.changePlatform(PLATFORM)
|
||
|
||
def setScoreBoard_value(self, value=None):
|
||
if not(value is None):
|
||
value = str(value)
|
||
if len(value) == 1:
|
||
value = '00' + value
|
||
elif len(value) == 2:
|
||
value = '0' + value
|
||
|
||
for numID in range(len(value)):
|
||
self.timeCells[numID].editValue(int(value[numID]))
|
||
else:
|
||
for cellT in self.timeCells:
|
||
cellT.editValue()
|
||
|
||
def getCell_intoCoords(self, x, y):
|
||
for row in self.cells:
|
||
for _cell in row:
|
||
if (x >= _cell["coord_start"][0] and x <= _cell["coord_last"][0]) and (y >= _cell["coord_start"][1] and y <= _cell["coord_last"][1]):
|
||
return _cell["cellObject"]
|
||
|
||
def cursorMove(self, x, y):
|
||
self.positionCursor = (x, y)
|
||
self.cursor.setCell_coord(x, y)
|
||
|
||
def get_cursorPos(self):
|
||
return list(self.positionCursor)
|
||
|
||
def updateField(self, field, gamefinished=None):
|
||
global MINES_COMPR
|
||
|
||
listcells = list()
|
||
for r in field:
|
||
for c in r:
|
||
listcells.append(c)
|
||
if gamefinished is None:
|
||
gamefinished = 'M:O' in listcells
|
||
|
||
for rowId in range(len(field)):
|
||
row = field[rowId]
|
||
for cellID in range(len(field[rowId])):
|
||
_cell = field[rowId][cellID]
|
||
|
||
actCell = self.cells[rowId][cellID]["cellObject"]
|
||
if ':O' in _cell:
|
||
if not(gamefinished):
|
||
gamefinished = _cell == 'M:O'
|
||
|
||
if _cell == 'M:O':
|
||
actCell.setCondition('BOMB')
|
||
else:
|
||
SeeUp = rowId != 0
|
||
SeeDown = rowId != len(field) - 1
|
||
SeeLeft = cellID != 0
|
||
SeeRight = cellID != len(field) - 1
|
||
|
||
mines = 0
|
||
frontire = False
|
||
if SeeUp:
|
||
if field[rowId - 1][cellID] in ('M', 'M:F', 'M:O'):
|
||
mines += 1
|
||
if not(frontire):
|
||
frontire = _cell != field[rowId - 1][cellID] and ':O' not in field[rowId - 1][cellID]
|
||
if SeeDown:
|
||
if field[rowId + 1][cellID] in ('M', 'M:F', 'M:O'):
|
||
mines += 1
|
||
if not(frontire):
|
||
frontire = _cell != field[rowId + 1][cellID] and ':O' not in field[rowId + 1][cellID]
|
||
if SeeLeft:
|
||
if field[rowId][cellID - 1] in ('M', 'M:F', 'M:O'):
|
||
mines += 1
|
||
if not(frontire):
|
||
frontire = _cell != field[rowId][cellID - 1] and ':O' not in field[rowId][cellID - 1]
|
||
if SeeRight:
|
||
if field[rowId][cellID + 1] in ('M', 'M:F', 'M:O'):
|
||
mines += 1
|
||
if not(frontire):
|
||
frontire = _cell != field[rowId][cellID + 1] and ':O' not in field[rowId][cellID + 1]
|
||
# Диагонали
|
||
if SeeUp and SeeLeft:
|
||
if field[rowId - 1][cellID - 1] in ('M', 'M:F', 'M:O'):
|
||
mines += 1
|
||
if SeeUp and SeeRight:
|
||
if field[rowId - 1][cellID + 1] in ('M', 'M:F', 'M:O'):
|
||
mines += 1
|
||
if SeeDown and SeeLeft:
|
||
if field[rowId + 1][cellID - 1] in ('M', 'M:F', 'M:O'):
|
||
mines += 1
|
||
if SeeDown and SeeRight:
|
||
if field[rowId + 1][cellID + 1] in ('M', 'M:F', 'M:O'):
|
||
mines += 1
|
||
|
||
if mines > 0:
|
||
actCell.setCondition('num_%s' % mines)
|
||
elif frontire:
|
||
actCell.setCondition('num_1')
|
||
else:
|
||
actCell.setCondition('OPENED')
|
||
elif ':F' in _cell:
|
||
if gamefinished and _cell == 'M:F':
|
||
actCell.setCondition('DEFUSE')
|
||
else:
|
||
actCell.setCondition('FLAG')
|
||
else:
|
||
actCell.setCondition('CLOSED')
|
||
if not(gamefinished):
|
||
self.resetButton.editCond(endStatus='')
|
||
elif checkWin(field):
|
||
MINES_COMPR = True
|
||
self.resetButton.editCond(endStatus='win')
|
||
self.winSound.play()
|
||
minesDefused = 0
|
||
scores = 0
|
||
|
||
for row in field:
|
||
for _cell in row:
|
||
if _cell == 'M:F':
|
||
minesDefused += 1
|
||
|
||
for row in field:
|
||
for _cell in row:
|
||
if _cell == 'M:F':
|
||
if (minesDefused // 5) ** 2 > 15:
|
||
scores += (minesDefused // 5) ** 2 > 10
|
||
else:
|
||
scores += 15
|
||
|
||
databaseObj.setItem(
|
||
'minesDefuse',
|
||
SQLEasy.compareKey(databaseObj.getBase('users'), 'ID')[gamerID]['minesDefuse'] + minesDefused,
|
||
'ID',
|
||
gamerID,
|
||
DatabaseName='users'
|
||
)
|
||
|
||
databaseObj.setItem(
|
||
'points',
|
||
SQLEasy.compareKey(databaseObj.getBase('users'), 'ID')[gamerID]['points'] + scores,
|
||
'ID',
|
||
gamerID,
|
||
DatabaseName='users'
|
||
)
|
||
else:
|
||
MINES_COMPR = True
|
||
self.resetButton.editCond(endStatus='lose')
|
||
self.bombSound.play()
|
||
|
||
minesDefused = 0
|
||
scores = 0
|
||
|
||
for row in field:
|
||
for _cell in row:
|
||
if _cell == 'M:F':
|
||
minesDefused += 1
|
||
scores += 10
|
||
|
||
databaseObj.setItem(
|
||
'minesDefuse',
|
||
SQLEasy.compareKey(databaseObj.getBase('users'), 'ID')[gamerID]['minesDefuse'] + minesDefused,
|
||
'ID',
|
||
gamerID,
|
||
DatabaseName='users'
|
||
)
|
||
|
||
databaseObj.setItem(
|
||
'points',
|
||
SQLEasy.compareKey(databaseObj.getBase('users'), 'ID')[gamerID]['points'] + scores,
|
||
'ID',
|
||
gamerID,
|
||
DatabaseName='users'
|
||
)
|
||
|
||
|
||
# код игры
|
||
logicGame = corelib.getGameSession(gamehash)['response']
|
||
gamesession = logicGame["gamesession"]
|
||
field = logicGame["map"]
|
||
|
||
if gamesession not in SQLEasy.compareKey(databaseObj.getBase('gamehashes'), 'hash'):
|
||
databaseObj.add({
|
||
"hash": gamesession,
|
||
"userID": gamerID,
|
||
"mines": MINES,
|
||
"game": gameStyle,
|
||
"fieldJSON": json.dumps(field, indent="\t", ensure_ascii=False)
|
||
}, 'gamehashes')
|
||
|
||
pygame.init()
|
||
|
||
screen = pygame.display.set_mode((500, 500))
|
||
|
||
pygame.display.set_caption(gameconfig['title'])
|
||
pygame.display.set_icon(pygame.image.load(f"source/{gameStyle}/gameico.png"))
|
||
bg = pygame.image.load(f"source/{gameStyle}/bg.png")
|
||
screen.blit(bg, (0, 0))
|
||
|
||
PLATFORM = 'XBox' # (!) Сделать проверку
|
||
# Прорисовка полей
|
||
sceneGame = sceneGame(PLATFORM)
|
||
|
||
pygame.display.flip()
|
||
|
||
program_running = True
|
||
|
||
cursor_moveUp = False
|
||
cursor_moveDown = False
|
||
cursor_moveLeft = False
|
||
cursor_moveRight = False
|
||
|
||
# Muzic
|
||
pygame.mixer.music.load(f"source/{gameStyle}/muzic.wav")
|
||
if muzicOn:
|
||
pygame.mixer.music.play()
|
||
pygame.mixer.Sound(f"source/{gameStyle}/resetField.wav").play()
|
||
databaseObj.setItem(
|
||
'games',
|
||
SQLEasy.compareKey(databaseObj.getBase('users'), 'ID')[gamerID]['games'] + 1,
|
||
'ID',
|
||
gamerID,
|
||
DatabaseName='users'
|
||
)
|
||
|
||
sceneGame.updateField(field)
|
||
|
||
while program_running:
|
||
pygame.time.Clock().tick(60) # max FPS
|
||
for event in pygame.event.get():
|
||
if event.type == pygame.QUIT:
|
||
program_running = False
|
||
break
|
||
elif event.type == pygame.MOUSEMOTION:
|
||
POSITION = event.pos
|
||
cellSel = sceneGame.getCell_intoCoords(int(POSITION[0]), int(POSITION[1]))
|
||
|
||
resetButtonSel = sceneGame.resetButton.check_myself_Location(int(POSITION[0]), int(POSITION[1]))
|
||
if not(cellSel is None):
|
||
sceneGame.cursorMove(cellSel.cellPosition["X"], cellSel.cellPosition["Y"])
|
||
del POSITION, cellSel
|
||
if not(resetButtonSel is None):
|
||
resetButtonSel.editCond(hide='hover')
|
||
else:
|
||
sceneGame.resetButton.editCond(hide='noHover')
|
||
elif event.type == pygame.KEYDOWN:
|
||
cursor_moveUp = event.key == 1073741906
|
||
cursor_moveDown = event.key == 1073741905
|
||
cursor_moveLeft = event.key == 1073741904
|
||
cursor_moveRight = event.key == 1073741903
|
||
|
||
cursor_coords = sceneGame.get_cursorPos()
|
||
if cursor_moveUp:
|
||
cursor_coords[1] -= 1
|
||
if cursor_moveDown:
|
||
cursor_coords[1] += 1
|
||
if cursor_moveLeft:
|
||
cursor_coords[0] -= 1
|
||
if cursor_moveRight:
|
||
cursor_coords[0] += 1
|
||
|
||
if cursor_coords[0] <= -1:
|
||
cursor_coords[0] = 9
|
||
if cursor_coords[0] >= 10:
|
||
cursor_coords[0] = 0
|
||
if cursor_coords[1] <= -1:
|
||
cursor_coords[1] = 9
|
||
if cursor_coords[1] >= 10:
|
||
cursor_coords[1] = 0
|
||
|
||
sceneGame.cursorMove(*cursor_coords)
|
||
elif event.type == pygame.MOUSEBUTTONDOWN and event.button == 1:
|
||
POSITION = event.pos
|
||
cellSel = sceneGame.getCell_intoCoords(int(POSITION[0]), int(POSITION[1]))
|
||
|
||
resetButtonSel = sceneGame.resetButton.check_myself_Location(int(POSITION[0]), int(POSITION[1]))
|
||
if not(cellSel is None):
|
||
corelib.openItem(gamesession, X=cellSel.cellPosition["X"], Y=cellSel.cellPosition["Y"])
|
||
respObj = corelib.getGameSession(gamesession)['response']
|
||
old_field = field
|
||
field = respObj['map']
|
||
compareFields(old_field, field)
|
||
sceneGame.updateField(field, gamefinished=not(respObj['continue']))
|
||
del POSITION, cellSel
|
||
if not(resetButtonSel is None):
|
||
pygame.mixer.Sound(f"source/{gameStyle}/resetField.wav").play()
|
||
MINES = random.randint(25, 55)
|
||
logicGame = corelib.newGame(gamerID, mines=MINES)['response']
|
||
gamesession = logicGame["gamesession"]
|
||
sceneGame.updateField(logicGame["map"])
|
||
if muzicOn:
|
||
pygame.mixer.music.play()
|
||
MINES_COMPR = False
|
||
|
||
databaseObj.setItem(
|
||
'games',
|
||
SQLEasy.compareKey(databaseObj.getBase('users'), 'ID')[gamerID]['games'] + 1,
|
||
'ID',
|
||
gamerID,
|
||
DatabaseName='users')
|
||
|
||
databaseObj.add({
|
||
"hash": gamesession,
|
||
"userID": gamerID,
|
||
"game": gameStyle,
|
||
"mines": MINES,
|
||
"fieldJSON": json.dumps(field, indent="\t", ensure_ascii=False)
|
||
}, 'gamehashes')
|
||
elif event.type == pygame.MOUSEBUTTONDOWN and event.button == 3:
|
||
POSITION = event.pos
|
||
cellSel = sceneGame.getCell_intoCoords(int(POSITION[0]), int(POSITION[1]))
|
||
if not(cellSel is None):
|
||
if MINES > 0 and cellSel.getCondition() == 'CLOSED' and not(MINES_COMPR):
|
||
if 'response' in corelib.toggleFlag(gamesession, X=cellSel.cellPosition["X"], Y=cellSel.cellPosition["Y"]):
|
||
MINES -= 1
|
||
respObj = corelib.getGameSession(gamesession)['response']
|
||
old_field = field
|
||
field = respObj['map']
|
||
compareFields(old_field, field)
|
||
sceneGame.updateField(field, gamefinished=not(respObj['continue']))
|
||
del POSITION, cellSel
|
||
elif cellSel.getCondition() == 'FLAG' and not(MINES_COMPR):
|
||
if 'response' in corelib.toggleFlag(gamesession, X=cellSel.cellPosition["X"], Y=cellSel.cellPosition["Y"]):
|
||
MINES += 1
|
||
respObj = corelib.getGameSession(gamesession)['response']
|
||
old_field = field
|
||
field = respObj['map']
|
||
compareFields(old_field, field)
|
||
sceneGame.updateField(field, gamefinished=not(respObj['continue']))
|
||
del POSITION, cellSel
|
||
databaseObj.setItem(
|
||
'mines',
|
||
MINES,
|
||
'hash',
|
||
gamesession,
|
||
DatabaseName='gamehashes'
|
||
)
|
||
|
||
sceneGame.setScoreBoard_value(MINES)
|
||
|
||
sceneGame.draw(screen)
|
||
sceneGame.update()
|
||
pygame.display.flip()
|
||
|
||
pygame.quit()
|
||
|
||
|
||
def getGamesDict():
|
||
listGames = dict()
|
||
for directory in [f for f in os.listdir('source') if len(f.split('.')) == 1]:
|
||
if 'about.json' in os.listdir(f"source/{directory}"):
|
||
f = open(f"source/{directory}/about.json", 'r', encoding='utf-8')
|
||
content = json.loads(f.read())
|
||
listGames[directory] = {
|
||
"gamename": content['title'],
|
||
"path": f"source/{directory}"
|
||
}
|
||
return listGames
|
||
|
||
|
||
def getGameName(name):
|
||
if name in getGamesDict():
|
||
return getGamesDict()[name]["gamename"]
|
||
else:
|
||
return 'Game not founded.'
|
||
|
||
|
||
class app_win(QMainWindow):
|
||
def __init__(self):
|
||
super(app_win, self).__init__()
|
||
self.ui = launcher.Ui_Form()
|
||
self.ui.setupUi(self)
|
||
|
||
self.database = SQLEasy.database('gameDataBase.db')
|
||
|
||
# Во-первых, наполним список игроков
|
||
self.ui.StatTable.removeRow(0)
|
||
rowPosition = 0
|
||
for user in self.database.getBase(DatabaseName='users'):
|
||
self.ui.StatTable.insertRow(rowPosition)
|
||
self.ui.StatTable.setItem(rowPosition, 0, QTableWidgetItem(user["username"]))
|
||
self.ui.StatTable.setItem(rowPosition, 1, QTableWidgetItem(str(user["points"])))
|
||
self.ui.StatTable.setItem(rowPosition, 2, QTableWidgetItem(str(user["minesDefuse"])))
|
||
if user["games"] != 0:
|
||
st = str(user["minesDefuse"] // user["games"])
|
||
else:
|
||
st = '0'
|
||
self.ui.StatTable.setItem(rowPosition, 3, QTableWidgetItem(st))
|
||
self.ui.StatTable.setItem(rowPosition, 4, QTableWidgetItem(getGameName(user["lastGame"])))
|
||
|
||
rowPosition += 1
|
||
self.ui.usernamesList.clear()
|
||
self.accs = list()
|
||
for user in self.database.getBase(DatabaseName='users'): # Обновляем во вкладке Профили
|
||
self.ui.usernamesList.addItem(user["username"])
|
||
self.accs.append(user)
|
||
|
||
# Заполним список вариаций сапёра
|
||
self.ui.gameList.clear()
|
||
for gameDir in getGamesDict():
|
||
item = QtWidgets.QListWidgetItem(getGamesDict()[gameDir]['gamename'])
|
||
icon1 = QtGui.QIcon()
|
||
icon1.addPixmap(QtGui.QPixmap(f"source/{gameDir}/gameico.png"), QtGui.QIcon.Normal, QtGui.QIcon.Off)
|
||
item.setIcon(icon1)
|
||
self.ui.gameList.addItem(item)
|
||
|
||
self.show()
|
||
|
||
self.ui.usernamesList.doubleClicked.connect(self.importLogin)
|
||
self.ui.regButton.clicked.connect(self.register)
|
||
self.ui.loginButton.clicked.connect(self.logIn)
|
||
self.ui.play.clicked.connect(self.play)
|
||
self.ui.logOut.clicked.connect(self.logOut)
|
||
self.ui.updateGames.clicked.connect(self.upDate_sapers)
|
||
self.ui.loadGame.clicked.connect(self.LoadGame)
|
||
# Список сохранений...
|
||
self.ui.SaveList.clear()
|
||
self.savedGames = list()
|
||
|
||
multiMethod = corelib.multiMethod()
|
||
|
||
for save in self.database.getBase('gamehashes'):
|
||
if save['game'] in getGamesDict() and save['userID'] == self.database.getBase('gamedata')[0]['activeprofile']:
|
||
multiMethod.append(corelib.Method('getGameSession', gamesession=save['hash']))
|
||
|
||
resp = multiMethod.start()['responses']
|
||
respID = -1
|
||
|
||
for save in self.database.getBase('gamehashes'):
|
||
if save['game'] in getGamesDict() and save['userID'] == self.database.getBase('gamedata')[0]['activeprofile']:
|
||
respID += 1
|
||
if 'response' in resp[respID]:
|
||
if resp[respID]['response']['continue']:
|
||
item = QtWidgets.QListWidgetItem(
|
||
f"{getGamesDict()[save['game']]['gamename']}, мин: {save['mines']}"
|
||
)
|
||
icon1 = QtGui.QIcon()
|
||
icon1.addPixmap(QtGui.QPixmap(f"source/{save['game']}/gameico.png"), QtGui.QIcon.Normal, QtGui.QIcon.Off)
|
||
item.setIcon(icon1)
|
||
self.ui.SaveList.addItem(item)
|
||
self.savedGames.append([
|
||
save['hash'],
|
||
save['mines'],
|
||
save['game']
|
||
])
|
||
|
||
# Сделаем таймер
|
||
|
||
self.timer = QtCore.QTimer(self)
|
||
self.timer.timeout.connect(self.timerVoid)
|
||
self.timer.start(1)
|
||
|
||
def upDate_sapers(self):
|
||
self.ui.gameList.clear()
|
||
for gameDir in getGamesDict():
|
||
item = QtWidgets.QListWidgetItem(getGamesDict()[gameDir]['gamename'])
|
||
icon1 = QtGui.QIcon()
|
||
icon1.addPixmap(QtGui.QPixmap(f"source/{gameDir}/gameico.png"), QtGui.QIcon.Normal, QtGui.QIcon.Off)
|
||
item.setIcon(icon1)
|
||
self.ui.gameList.addItem(item)
|
||
|
||
def logOut(self):
|
||
self.database.setItem(
|
||
'activeprofile',
|
||
'-',
|
||
'ID',
|
||
1,
|
||
DatabaseName='gamedata')
|
||
self.ui.SaveList.clear()
|
||
QMessageBox.information(self, 'Успех!', 'Вы успешно вышли!!!', QMessageBox.Ok)
|
||
|
||
def logIn(self):
|
||
if self.ui.loginUsernameLine.text() in [user['username'] for user in self.database.getBase('users')]:
|
||
if SQLEasy.compareKey(self.database.getBase('users'), key='username')[self.ui.loginUsernameLine.text()]['password'] is None:
|
||
self.database.setItem(
|
||
'activeprofile',
|
||
SQLEasy.compareKey(self.database.getBase('users'), key='username')[self.ui.loginUsernameLine.text()]['ID'],
|
||
'ID',
|
||
1,
|
||
DatabaseName='gamedata')
|
||
QMessageBox.information(self, 'Успех!', 'Вы успешно вошли!!!', QMessageBox.Ok)
|
||
elif SQLEasy.compareKey(self.database.getBase('users'), key='username')[self.ui.loginUsernameLine.text()]['password'] == self.ui.loginHasloLine.text():
|
||
self.database.setItem(
|
||
'activeprofile',
|
||
SQLEasy.compareKey(self.database.getBase('users'), key='username')[self.ui.loginUsernameLine.text()]['ID'],
|
||
'ID',
|
||
1,
|
||
DatabaseName='gamedata')
|
||
QMessageBox.information(self, 'Успех!', 'Вы успешно вошли!!!', QMessageBox.Ok)
|
||
else:
|
||
QMessageBox.critical(self, 'Упс...', 'Неверный пароль!', QMessageBox.Ok)
|
||
else:
|
||
QMessageBox.critical(self, 'Упс...', 'Такого пользователя просто нет :(', QMessageBox.Ok)
|
||
|
||
self.ui.SaveList.clear()
|
||
self.savedGames = list()
|
||
|
||
multiMethod = corelib.multiMethod()
|
||
|
||
for save in self.database.getBase('gamehashes'):
|
||
if save['game'] in getGamesDict() and save['userID'] == self.database.getBase('gamedata')[0]['activeprofile']:
|
||
multiMethod.append(corelib.Method('getGameSession', gamesession=save['hash']))
|
||
|
||
resp = multiMethod.start()['responses']
|
||
respID = -1
|
||
|
||
for save in self.database.getBase('gamehashes'):
|
||
if save['game'] in getGamesDict() and save['userID'] == self.database.getBase('gamedata')[0]['activeprofile']:
|
||
respID += 1
|
||
if 'response' in resp[respID]:
|
||
if resp[respID]['response']['continue']:
|
||
item = QtWidgets.QListWidgetItem(
|
||
f"{getGamesDict()[save['game']]['gamename']}, мин: {save['mines']}"
|
||
)
|
||
icon1 = QtGui.QIcon()
|
||
icon1.addPixmap(QtGui.QPixmap(f"source/{save['game']}/gameico.png"), QtGui.QIcon.Normal, QtGui.QIcon.Off)
|
||
item.setIcon(icon1)
|
||
self.ui.SaveList.addItem(item)
|
||
self.savedGames.append([
|
||
save['hash'],
|
||
save['mines'],
|
||
save['game']
|
||
])
|
||
|
||
def register(self):
|
||
if self.ui.regLoginLine.text() in [user['username'] for user in self.database.getBase('users')]:
|
||
QMessageBox.critical(self, 'Упс...', 'Есть такой пользователь, ЕСТЬ!!!', QMessageBox.Ok)
|
||
return
|
||
if len(self.ui.regHasloLine.text()) > 0:
|
||
if len(self.ui.regHasloLine.text()) >= 65:
|
||
QMessageBox.warning(self, 'Warning!', 'Too many symbols on password!', QMessageBox.Ok)
|
||
return
|
||
|
||
if len(self.ui.regLoginLine.text()) >= 65:
|
||
QMessageBox.warning(self, 'Warning!', 'Too many symbols on login!', QMessageBox.Ok)
|
||
return
|
||
|
||
self.database.add({
|
||
"ID": len(self.database.getBase('users')),
|
||
"username": self.ui.regLoginLine.text()
|
||
}, 'users')
|
||
QMessageBox.information(self, 'Успех!', 'Профиль создан!', QMessageBox.Ok)
|
||
|
||
self.ui.usernamesList.clear()
|
||
self.accs = list()
|
||
for user in self.database.getBase(DatabaseName='users'): # Обновляем во вкладке Профили
|
||
self.ui.usernamesList.addItem(user["username"])
|
||
self.accs.append(user)
|
||
|
||
def importLogin(self):
|
||
if self.ui.usernamesList.currentRow() >= 0 and self.ui.usernamesList.currentRow() < len(self.ui.usernamesList):
|
||
user = self.accs[self.ui.usernamesList.currentRow()]
|
||
self.ui.loginUsernameLine.setText(user['username'])
|
||
|
||
def LoadGame(self):
|
||
global game
|
||
|
||
self.hide()
|
||
hashK = self.savedGames[self.ui.SaveList.currentRow()][0]
|
||
mines = self.savedGames[self.ui.SaveList.currentRow()][1]
|
||
|
||
game(
|
||
self.savedGames[self.ui.SaveList.currentRow()][2],
|
||
gamerID=self.database.getBase('gamedata')[0]['activeprofile'],
|
||
databaseObj=self.database,
|
||
gamehash=hashK,
|
||
MINES=mines,
|
||
muzicOn=self.ui.soundOn.isChecked()
|
||
)
|
||
os.abort()
|
||
del self
|
||
|
||
|
||
def play(self):
|
||
global game
|
||
|
||
self.hide()
|
||
hashK = corelib.newGame(ID=self.database.getBase('gamedata')[0]['activeprofile'], mines=25, fieldsize=10)['response']
|
||
mines = random.randint(25, 55)
|
||
|
||
game(
|
||
[k for k in getGamesDict()][self.ui.gameList.currentRow()],
|
||
gamerID=self.database.getBase('gamedata')[0]['activeprofile'],
|
||
databaseObj=self.database,
|
||
gamehash=hashK['gamesession'],
|
||
MINES=mines,
|
||
muzicOn=self.ui.soundOn.isChecked()
|
||
)
|
||
os.abort()
|
||
del self
|
||
|
||
def timerVoid(self):
|
||
def getCoorectLogin(string):
|
||
login = ''
|
||
for symbol in string:
|
||
if symbol in '0123456789qwertyuiopasdfghjklzxcvbnm_-.' + 'qwertyuiopasdfghjklzxcvbnm'.upper():
|
||
login += symbol
|
||
if len(login) > 64:
|
||
login = login[:64]
|
||
return login
|
||
|
||
self.ui.play.setEnabled(
|
||
self.ui.gameList.currentRow() >= 0 and
|
||
self.ui.gameList.currentRow() < len(self.ui.gameList) and
|
||
not(self.database.getBase('gamedata')[0]['activeprofile'] is None or self.database.getBase('gamedata')[0]['activeprofile'] == '-')
|
||
)
|
||
|
||
self.ui.logOut.setEnabled(not(self.database.getBase('gamedata')[0]['activeprofile'] is None or self.database.getBase('gamedata')[0]['activeprofile'] == '-'))
|
||
self.ui.loadGame.setEnabled(len(self.ui.SaveList) > 0)
|
||
|
||
if not(self.database.getBase('gamedata')[0]['activeprofile'] is None or self.database.getBase('gamedata')[0]['activeprofile'] == '-'):
|
||
nickname = SQLEasy.compareKey(self.database.getBase('users'), 'ID')
|
||
nickname = nickname[self.database.getBase('gamedata')[0]['activeprofile']]['username']
|
||
self.ui.gameinfo.setText(f"Добро пожаловать, {nickname}!")
|
||
else:
|
||
self.ui.gameinfo.setText("Войдите или зарегайте профиль, чтобы играть!")
|
||
|
||
self.ui.loginButton.setEnabled(
|
||
len(self.ui.loginUsernameLine.text()) > 8 and (len(self.ui.loginHasloLine.text()) > 8 or len(self.ui.loginHasloLine.text()) == 0)
|
||
)
|
||
self.ui.regButton.setEnabled(
|
||
len(self.ui.regLoginLine.text()) > 8 and (len(self.ui.regHasloLine.text()) > 8 or len(self.ui.regHasloLine.text()) == 0)
|
||
)
|
||
|
||
if self.ui.loginUsernameLine.text() != getCoorectLogin(self.ui.loginUsernameLine.text()):
|
||
self.ui.loginUsernameLine.setText(getCoorectLogin(self.ui.loginUsernameLine.text()))
|
||
if self.ui.regLoginLine.text() != getCoorectLogin(self.ui.regLoginLine.text()):
|
||
self.ui.regLoginLine.setText(getCoorectLogin(self.ui.regLoginLine.text()))
|
||
if self.ui.loginHasloLine.text() != getCoorectLogin(self.ui.loginHasloLine.text()):
|
||
self.ui.loginHasloLine.setText(getCoorectLogin(self.ui.loginHasloLine.text()))
|
||
if self.ui.regHasloLine.text() != getCoorectLogin(self.ui.regHasloLine.text()):
|
||
self.ui.regHasloLine.setText(getCoorectLogin(self.ui.regHasloLine.text()))
|
||
|
||
if self.ui.logPasShow.isChecked():
|
||
self.ui.loginHasloLine.setEchoMode(QtWidgets.QLineEdit.Normal)
|
||
else:
|
||
self.ui.loginHasloLine.setEchoMode(QtWidgets.QLineEdit.Password)
|
||
|
||
if self.ui.regPasShow.isChecked():
|
||
self.ui.regHasloLine.setEchoMode(QtWidgets.QLineEdit.Normal)
|
||
else:
|
||
self.ui.regHasloLine.setEchoMode(QtWidgets.QLineEdit.Password)
|
||
|
||
# Запрещаем редактировать стату
|
||
self.ui.StatTable.setRowCount(0)
|
||
rowPosition = 0
|
||
for user in sorted(self.database.getBase(DatabaseName='users'), key=lambda x: x['points'], reverse=True):
|
||
self.ui.StatTable.insertRow(rowPosition)
|
||
self.ui.StatTable.setItem(rowPosition, 0, QTableWidgetItem(user["username"]))
|
||
self.ui.StatTable.setItem(rowPosition, 1, QTableWidgetItem(str(user["points"])))
|
||
self.ui.StatTable.setItem(rowPosition, 2, QTableWidgetItem(str(user["minesDefuse"])))
|
||
|
||
if user["games"] != 0:
|
||
st = str(user["minesDefuse"] // user["games"])
|
||
else:
|
||
st = '0'
|
||
self.ui.StatTable.setItem(rowPosition, 3, QTableWidgetItem(st))
|
||
self.ui.StatTable.setItem(rowPosition, 4, QTableWidgetItem(getGameName(user["lastGame"])))
|
||
|
||
rowPosition += 1
|
||
|
||
|
||
app = QApplication([])
|
||
application = app_win()
|
||
app.exec()
|
||
os.abort() |