Add files via upload
This commit is contained in:
parent
c8155c3d74
commit
91ef430eb6
68
README.md
68
README.md
@ -1,34 +1,34 @@
|
||||
# Version 0.9 Beta
|
||||
Тестовая версия для GNU Linux и OS Windows (x64).<br/>
|
||||
Для запуска программы требуется **python 3.6+**!!!<br/>
|
||||
В релизных версиях есть файл для запуска с консолью (для отладки) и стандартный файл<br/>
|
||||
Код писался под **OS Windows x64**, однако, в теории код работает и с GNU Linux, однако, автор **не гарантирует** 100% работу под Linux.
|
||||
## Советы для работы с ядром
|
||||
**Не запускайте скомпилированное ядро!! это может привести к некорректной работе игры!!!**<br/>
|
||||
Ниже приведён пример конфигурационного файла ядра.
|
||||
```json
|
||||
{
|
||||
"pythonRun": true, # Запуск ядра при помощи python
|
||||
"pythonPath_win32": "python ", # Путь к python на OS Windows x64
|
||||
"pythonPath_unix": "python3 ", # Путь к python на GNU Linux
|
||||
"max_responseTime": 15, # Время ожидания отклика ядра (сек)
|
||||
"core_file": "gamecore.py", # Файл ядра
|
||||
"log_enable": false # Включить логгирование
|
||||
}
|
||||
```
|
||||
## Методы ядра
|
||||
Запросы принимаются через файл **gamestat.json**
|
||||
```json
|
||||
{
|
||||
"status": "method" # Метод
|
||||
"request": [] # Тело запроса
|
||||
}
|
||||
```
|
||||
После выполнения запроса, ядро высылает ответ в файле **response.json**
|
||||
```json
|
||||
{
|
||||
"response": [] # Тело ответа
|
||||
"response_randomID": [] # random ID
|
||||
}
|
||||
```
|
||||
Подробнее читайте в документации.
|
||||
# Version 0.9 Beta
|
||||
Тестовая версия для GNU Linux и OS Windows (x64).<br/>
|
||||
Для запуска программы требуется **python 3.6+**!!!<br/>
|
||||
В релизных версиях есть файл для запуска с консолью (для отладки) и стандартный файл<br/>
|
||||
Код писался под **OS Windows x64**, однако, в теории код работает и с GNU Linux, однако, автор **не гарантирует** 100% работу под Linux.
|
||||
## Советы для работы с ядром
|
||||
**Не запускайте скомпилированное ядро!! это может привести к некорректной работе игры!!!**<br/>
|
||||
Ниже приведён пример конфигурационного файла ядра.
|
||||
```json
|
||||
{
|
||||
"pythonRun": true, # Запуск ядра при помощи python
|
||||
"pythonPath_win32": "python ", # Путь к python на OS Windows x64
|
||||
"pythonPath_unix": "python3 ", # Путь к python на GNU Linux
|
||||
"max_responseTime": 15, # Время ожидания отклика ядра (сек)
|
||||
"core_file": "gamecore.py", # Файл ядра
|
||||
"log_enable": false # Включить логгирование
|
||||
}
|
||||
```
|
||||
## Методы ядра
|
||||
Запросы принимаются через файл **gamestat.json**
|
||||
```json
|
||||
{
|
||||
"status": "method" # Метод
|
||||
"request": [] # Тело запроса
|
||||
}
|
||||
```
|
||||
После выполнения запроса, ядро высылает ответ в файле **response.json**
|
||||
```json
|
||||
{
|
||||
"response": [] # Тело ответа
|
||||
"response_randomID": [] # random ID
|
||||
}
|
||||
```
|
||||
Подробнее читайте в документации.
|
||||
|
192
SQLEasy.py
Normal file
192
SQLEasy.py
Normal file
@ -0,0 +1,192 @@
|
||||
import sqlite3
|
||||
|
||||
|
||||
class SQLiteEasyException(Exception):
|
||||
pass
|
||||
|
||||
|
||||
def compareKey(DBlist, key, type_of_key=lambda x: x):
|
||||
if not(type(DBlist) is list):
|
||||
raise SQLiteEasyException(f"function compareKey need List object, unsupported type: {type(DBlist)}")
|
||||
|
||||
if len(DBlist) > 0:
|
||||
if key not in DBlist[0]:
|
||||
raise SQLiteEasyException(f"key '{key}' not founded.")
|
||||
DB_Dictonary = dict()
|
||||
for BD in sorted(DBlist, key=lambda List: List[key]):
|
||||
comparedBD = dict()
|
||||
for Key in BD:
|
||||
if not(Key == key):
|
||||
comparedBD[Key] = BD[Key]
|
||||
DB_Dictonary[type_of_key(BD[key])] = comparedBD
|
||||
|
||||
return DB_Dictonary
|
||||
|
||||
|
||||
class database:
|
||||
def dict_factory(self, cursor, row):
|
||||
dictDB = {}
|
||||
for idx, col in enumerate(cursor.description):
|
||||
dictDB[col[0]] = row[idx]
|
||||
return dictDB
|
||||
|
||||
def encodeSQLiteType(self, objectum, all_as_str=False):
|
||||
if type(objectum) is str:
|
||||
return "'%s'" % objectum.replace('\'', '\\\'')
|
||||
elif objectum is None and all_as_str:
|
||||
return "''"
|
||||
elif objectum is None:
|
||||
return 'NULL'
|
||||
elif type(objectum) is bool and objectum and all_as_str:
|
||||
return "'TRUE'"
|
||||
elif type(objectum) is bool and objectum:
|
||||
return 'TRUE'
|
||||
elif type(objectum) is bool and not(objectum) and all_as_str:
|
||||
return "'FALSE'"
|
||||
elif type(objectum) is bool and not(objectum):
|
||||
return 'FALSE'
|
||||
elif all_as_str and True in [type(objectum) is int, type(objectum) is float]:
|
||||
return "'%s'" % objectum
|
||||
elif not(all_as_str) and True in [type(objectum) is int, type(objectum) is float]:
|
||||
return objectum
|
||||
else:
|
||||
raise SQLiteEasyException(f"Unsupported type: {type(objectum)}")
|
||||
|
||||
def __init__(self, PATH, DatabaseName=None):
|
||||
self.ConnectedFile = sqlite3.connect(PATH)
|
||||
self.databaseChoosed = DatabaseName
|
||||
self.ConnectedFile.row_factory = self.dict_factory
|
||||
self.act_commit = True
|
||||
|
||||
def toggleCommit(self, value=None):
|
||||
if value in (False, True):
|
||||
self.act_commit = value
|
||||
else:
|
||||
if self.act_commit:
|
||||
self.act_commit = False
|
||||
else:
|
||||
self.act_commit = True
|
||||
|
||||
def commit(self):
|
||||
self.ConnectedFile.commit()
|
||||
|
||||
def getBase(self, DatabaseName=None, elementsFromDB='*'):
|
||||
elementsFromDB = str(elementsFromDB)
|
||||
if DatabaseName is None and self.databaseChoosed is None:
|
||||
raise SQLiteEasyException("Database is not choosed")
|
||||
elif DatabaseName is None and not(self.databaseChoosed is None):
|
||||
dbCursore = self.ConnectedFile.cursor()
|
||||
dbCursore.execute(f"select {elementsFromDB} from {self.databaseChoosed}")
|
||||
return dbCursore.fetchall()
|
||||
else:
|
||||
dbCursore = self.ConnectedFile.cursor()
|
||||
dbCursore.execute(f"select {elementsFromDB} from {DatabaseName}")
|
||||
self.databaseChoosed = DatabaseName
|
||||
return dbCursore.fetchall()
|
||||
|
||||
def pop(self, key, value, DatabaseName=None):
|
||||
if type(value) is str:
|
||||
value = f"'%s'" % value.replace('\'', '\\\'')
|
||||
if DatabaseName is None and not(self.databaseChoosed is None):
|
||||
DatabaseName = self.databaseChoosed
|
||||
elif DatabaseName is None:
|
||||
raise SQLiteEasyException("Database is not choosed")
|
||||
dbCursore = self.ConnectedFile.cursor()
|
||||
dbCursore.execute('DELETE FROM %s\n\nWHERE %s == %s;' % (DatabaseName, key, value))
|
||||
if self.act_commit:
|
||||
self.ConnectedFile.commit()
|
||||
|
||||
def setItem(self, key, newValue, indexKey, value, DatabaseName=None):
|
||||
newValue = self.encodeSQLiteType(newValue)
|
||||
value = self.encodeSQLiteType(value)
|
||||
if DatabaseName is None and not(self.databaseChoosed is None):
|
||||
DatabaseName = self.databaseChoosed
|
||||
elif DatabaseName is None:
|
||||
raise SQLiteEasyException("Database is not choosed")
|
||||
dbCursore = self.ConnectedFile.cursor()
|
||||
if value is None:
|
||||
dbCursore.execute('UPDATE %s SET %s = %s WHERE %s is NULL;' % (DatabaseName, key, newValue, indexKey))
|
||||
else:
|
||||
dbCursore.execute('UPDATE %s SET %s = %s WHERE %s = %s;' % (DatabaseName, key, newValue, indexKey, value))
|
||||
if self.act_commit:
|
||||
self.ConnectedFile.commit()
|
||||
|
||||
def add(self, values, DatabaseName=None):
|
||||
if DatabaseName is None and not(self.databaseChoosed is None):
|
||||
DatabaseName = self.databaseChoosed
|
||||
elif DatabaseName is None:
|
||||
raise SQLiteEasyException("Database is not choosed")
|
||||
if DatabaseName is None and not(self.databaseChoosed is None):
|
||||
DatabaseName = self.databaseChoosed
|
||||
elif DatabaseName is None:
|
||||
raise SQLiteEasyException("Database is not choosed")
|
||||
|
||||
keys = [str(key) for key in values]
|
||||
values = [self.encodeSQLiteType(values[key], all_as_str=True) for key in values]
|
||||
|
||||
dbCursore = self.ConnectedFile.cursor()
|
||||
dbCursore.execute('INSERT INTO %s (%s) VALUES (%s)' % (DatabaseName, ', '.join(keys), ', '.join(values)))
|
||||
if self.act_commit:
|
||||
self.ConnectedFile.commit()
|
||||
|
||||
def uploadFiles(self, binary, DatabaseName=None): # Uwaga! Может работать с ошибками.
|
||||
if not(type(binary) is bytes or type(binary) is bytearray):
|
||||
raise SQLiteEasyException('You can upload only byte or bytearray types!!')
|
||||
dbCursore = self.ConnectedFile.cursor()
|
||||
binary = sqlite3.Binary(binary)
|
||||
|
||||
if DatabaseName is None and not(self.databaseChoosed is None):
|
||||
DatabaseName = self.databaseChoosed
|
||||
elif DatabaseName is None:
|
||||
raise SQLiteEasyException("Database is not choosed")
|
||||
if DatabaseName is None and not(self.databaseChoosed is None):
|
||||
DatabaseName = self.databaseChoosed
|
||||
elif DatabaseName is None:
|
||||
raise SQLiteEasyException("Database is not choosed")
|
||||
# (!) Дописать
|
||||
|
||||
def chooseDataBase(self, DatabaseName):
|
||||
self.getBase(DatabaseName)
|
||||
self.databaseChoosed = DatabaseName
|
||||
|
||||
def currentIndex(self, key, value, DatabaseName=None):
|
||||
if DatabaseName is None and not(self.databaseChoosed is None):
|
||||
DatabaseName = self.databaseChoosed
|
||||
elif DatabaseName is None:
|
||||
raise SQLiteEasyException("Database is not choosed")
|
||||
|
||||
DB = self.getBase(DatabaseName)
|
||||
|
||||
ID = 0
|
||||
for Dictonary in sorted(DB, key=lambda dictonary: dictonary[key]):
|
||||
if Dictonary[key] == value:
|
||||
return ID
|
||||
ID += 1
|
||||
|
||||
def currentValue(self, key, value, DatabaseName=None):
|
||||
if DatabaseName is None and not(self.databaseChoosed is None):
|
||||
DatabaseName = self.databaseChoosed
|
||||
elif DatabaseName is None:
|
||||
raise SQLiteEasyException("Database is not choosed")
|
||||
|
||||
DB = self.getBase(DatabaseName)
|
||||
|
||||
for Dictonary in sorted(DB, key=lambda dictonary: dictonary[key]):
|
||||
if Dictonary[key] == value:
|
||||
return Dictonary
|
||||
|
||||
def getTables(self):
|
||||
dbCursore = self.ConnectedFile.cursor()
|
||||
dbCursore.execute('SELECT name from sqlite_master where type= "table"')
|
||||
return [item['name'] for item in dbCursore.fetchall()]
|
||||
|
||||
def getDict(self):
|
||||
dictonary = dict()
|
||||
tables = self.getTables()
|
||||
for table in tables:
|
||||
dictonary[table] = self.getBase(table)
|
||||
return dictonary
|
||||
|
||||
|
||||
def formingTable(dictonary, path):
|
||||
pass # В разработке
|
BIN
Theory/scheme.png
Normal file
BIN
Theory/scheme.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 21 KiB |
BIN
Theory/scheme_noBg.png
Normal file
BIN
Theory/scheme_noBg.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 20 KiB |
168
corelib.py
Normal file
168
corelib.py
Normal file
@ -0,0 +1,168 @@
|
||||
import os, sys, json
|
||||
|
||||
import threading, Gamecore.guiDrawWaiting
|
||||
from PyQt5 import QtCore, QtGui, QtWidgets
|
||||
from PyQt5.QtWidgets import *
|
||||
from PyQt5.Qt import *
|
||||
|
||||
with open('Gamecore/config.json', 'r', encoding='utf-8') as cfg:
|
||||
cfg = json.loads(cfg.read())
|
||||
|
||||
if cfg["pythonRun"]:
|
||||
if sys.platform == 'win32':
|
||||
runCoreApp = cfg["pythonPath_win32"]
|
||||
else:
|
||||
runCoreApp = cfg["pythonPath_unix"]
|
||||
else:
|
||||
if sys.platform == 'win32':
|
||||
runCoreApp = 'start '
|
||||
else:
|
||||
runCoreApp = './'
|
||||
|
||||
|
||||
class tool:
|
||||
def __init__(self):
|
||||
def showGUI():
|
||||
class coreGUI(threading.Thread):
|
||||
def run(self):
|
||||
class app_win(QMainWindow):
|
||||
def __init__(self):
|
||||
super(app_win, self).__init__()
|
||||
self.ui = Gamecore.guiDrawWaiting.Ui_Form()
|
||||
self.ui.setupUi(self)
|
||||
self.show()
|
||||
|
||||
self.app = QApplication([])
|
||||
self.application = app_win()
|
||||
self.app.exec()
|
||||
|
||||
def stop(self):
|
||||
self.application.hide()
|
||||
del self
|
||||
|
||||
thrObj = coreGUI()
|
||||
thrObj.start()
|
||||
return thrObj
|
||||
|
||||
def noneGUI(*args, **kwargs):
|
||||
pass
|
||||
|
||||
def stopGUI(thrObj):
|
||||
thrObj.stop()
|
||||
|
||||
self.showGUI = showGUI
|
||||
self.noneGUI = noneGUI
|
||||
self.stopGUI = stopGUI
|
||||
|
||||
self.wait = self.noneGUI
|
||||
self.resp = self.noneGUI
|
||||
|
||||
def showGUI_wait(self, show=True):
|
||||
if show:
|
||||
print('WARNING! You will be using GUI corelib!!!')
|
||||
self.wait = self.showGUI
|
||||
self.resp = self.stopGUI
|
||||
else:
|
||||
self.wait = self.noneGUI
|
||||
self.resp = self.noneGUI
|
||||
|
||||
def response(self, resp):
|
||||
waitObj = self.wait()
|
||||
|
||||
respf = open('Gamecore/gamestat.json', 'wt', encoding='utf-8')
|
||||
respf.write(json.dumps(resp, indent="\t", ensure_ascii=False))
|
||||
respf.close()
|
||||
|
||||
shellScript = open('runCore.sh', 'wt', encoding='utf-8')
|
||||
print(f"cd Gamecore\n{runCoreApp}{cfg['core_file']}")
|
||||
shellScript.write(f"cd Gamecore\n{runCoreApp}{cfg['core_file']}")
|
||||
shellScript.close()
|
||||
if sys.platform != 'win32':
|
||||
os.system("./runCore.sh")
|
||||
else:
|
||||
os.system("runCore.sh")
|
||||
|
||||
output = open('Gamecore/response.json', 'r', encoding='utf-8')
|
||||
outp = output.read()
|
||||
output.close()
|
||||
|
||||
returnObj = json.loads(outp)
|
||||
self.resp(waitObj)
|
||||
return returnObj
|
||||
|
||||
|
||||
tool = tool()
|
||||
|
||||
|
||||
def newGame(ID, mines=25, fieldsize=10):
|
||||
return tool.response({
|
||||
"status": "newGame",
|
||||
"request": {
|
||||
"ID": ID,
|
||||
"Mines": mines,
|
||||
"size": fieldsize
|
||||
}
|
||||
})
|
||||
|
||||
|
||||
def openItem(gamesession, X, Y):
|
||||
return tool.response({
|
||||
"status": "openItem",
|
||||
"request": {
|
||||
"gamesession": gamesession,
|
||||
"X": X,
|
||||
"Y": Y
|
||||
}
|
||||
})
|
||||
|
||||
|
||||
def getGameSession(gamesession):
|
||||
return tool.response({
|
||||
"status": "getGameSession",
|
||||
"request": {
|
||||
"gamesession": gamesession
|
||||
}
|
||||
})
|
||||
|
||||
|
||||
def toggleFlag(gamesession, X, Y):
|
||||
return tool.response({
|
||||
"status": "toggleFlag",
|
||||
"request": {
|
||||
"gamesession": gamesession,
|
||||
"X": X,
|
||||
"Y": Y
|
||||
}
|
||||
})
|
||||
|
||||
|
||||
class Method:
|
||||
def __init__(self, method, **kwargs):
|
||||
self.method = method
|
||||
self.kwargs = kwargs
|
||||
|
||||
def start(self):
|
||||
return eval(self.method)(**kwargs)
|
||||
|
||||
|
||||
class multiMethod:
|
||||
def __init__(self, *methods):
|
||||
self.methods = list(methods)
|
||||
|
||||
def append(self, method):
|
||||
self.methods.append(method)
|
||||
|
||||
def pop(self, index):
|
||||
self.methods.pop(index)
|
||||
|
||||
def __len__(self):
|
||||
return len(self.methods)
|
||||
|
||||
def start(self):
|
||||
request = {"status": 'multiMethod', 'requests': list()}
|
||||
for method in self.methods:
|
||||
request['requests'].append({
|
||||
"status": method.method,
|
||||
"request": method.kwargs
|
||||
})
|
||||
return tool.response(request)
|
951
game.py
Normal file
951
game.py
Normal file
@ -0,0 +1,951 @@
|
||||
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()
|
BIN
gameDataBase.db
Normal file
BIN
gameDataBase.db
Normal file
Binary file not shown.
210
launcher.py
Normal file
210
launcher.py
Normal file
@ -0,0 +1,210 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
# Form implementation generated from reading ui file 'launcher.ui'
|
||||
#
|
||||
# Created by: PyQt5 UI code generator 5.15.1
|
||||
#
|
||||
# WARNING: Any manual changes made to this file will be lost when pyuic5 is
|
||||
# run again. Do not edit this file unless you know what you are doing.
|
||||
|
||||
|
||||
from PyQt5 import QtCore, QtGui, QtWidgets
|
||||
|
||||
|
||||
class Ui_Form(object):
|
||||
def setupUi(self, Form):
|
||||
Form.setObjectName("Form")
|
||||
Form.resize(460, 341)
|
||||
icon = QtGui.QIcon()
|
||||
icon.addPixmap(QtGui.QPixmap("source/gameico.ico"), QtGui.QIcon.Normal, QtGui.QIcon.Off)
|
||||
Form.setWindowIcon(icon)
|
||||
self.tabWidget = QtWidgets.QTabWidget(Form)
|
||||
self.tabWidget.setGeometry(QtCore.QRect(10, 10, 441, 281))
|
||||
self.tabWidget.setObjectName("tabWidget")
|
||||
self.Launcher = QtWidgets.QWidget()
|
||||
self.Launcher.setObjectName("Launcher")
|
||||
self.gameList = QtWidgets.QListWidget(self.Launcher)
|
||||
self.gameList.setGeometry(QtCore.QRect(20, 30, 391, 171))
|
||||
self.gameList.setObjectName("gameList")
|
||||
item = QtWidgets.QListWidgetItem()
|
||||
icon1 = QtGui.QIcon()
|
||||
icon1.addPixmap(QtGui.QPixmap("source/sys admin/gameico.png"), QtGui.QIcon.Normal, QtGui.QIcon.Off)
|
||||
item.setIcon(icon1)
|
||||
self.gameList.addItem(item)
|
||||
self.play = QtWidgets.QPushButton(self.Launcher)
|
||||
self.play.setGeometry(QtCore.QRect(180, 220, 75, 23))
|
||||
self.play.setCursor(QtGui.QCursor(QtCore.Qt.PointingHandCursor))
|
||||
self.play.setObjectName("play")
|
||||
self.soundOn = QtWidgets.QCheckBox(self.Launcher)
|
||||
self.soundOn.setGeometry(QtCore.QRect(310, 230, 121, 21))
|
||||
self.soundOn.setCursor(QtGui.QCursor(QtCore.Qt.PointingHandCursor))
|
||||
self.soundOn.setChecked(True)
|
||||
self.soundOn.setObjectName("soundOn")
|
||||
self.updateGames = QtWidgets.QPushButton(self.Launcher)
|
||||
self.updateGames.setGeometry(QtCore.QRect(20, 210, 75, 23))
|
||||
self.updateGames.setCursor(QtGui.QCursor(QtCore.Qt.PointingHandCursor))
|
||||
self.updateGames.setObjectName("updateGames")
|
||||
self.tabWidget.addTab(self.Launcher, "")
|
||||
self.tab = QtWidgets.QWidget()
|
||||
self.tab.setObjectName("tab")
|
||||
self.StatTable = QtWidgets.QTableWidget(self.tab)
|
||||
self.StatTable.setGeometry(QtCore.QRect(10, 0, 421, 231))
|
||||
self.StatTable.setObjectName("StatTable")
|
||||
self.StatTable.setColumnCount(5)
|
||||
self.StatTable.setRowCount(1)
|
||||
item = QtWidgets.QTableWidgetItem()
|
||||
self.StatTable.setVerticalHeaderItem(0, item)
|
||||
item = QtWidgets.QTableWidgetItem()
|
||||
self.StatTable.setHorizontalHeaderItem(0, item)
|
||||
item = QtWidgets.QTableWidgetItem()
|
||||
self.StatTable.setHorizontalHeaderItem(1, item)
|
||||
item = QtWidgets.QTableWidgetItem()
|
||||
self.StatTable.setHorizontalHeaderItem(2, item)
|
||||
item = QtWidgets.QTableWidgetItem()
|
||||
self.StatTable.setHorizontalHeaderItem(3, item)
|
||||
item = QtWidgets.QTableWidgetItem()
|
||||
self.StatTable.setHorizontalHeaderItem(4, item)
|
||||
item = QtWidgets.QTableWidgetItem()
|
||||
self.StatTable.setItem(0, 0, item)
|
||||
item = QtWidgets.QTableWidgetItem()
|
||||
self.StatTable.setItem(0, 1, item)
|
||||
item = QtWidgets.QTableWidgetItem()
|
||||
self.StatTable.setItem(0, 2, item)
|
||||
item = QtWidgets.QTableWidgetItem()
|
||||
self.StatTable.setItem(0, 3, item)
|
||||
item = QtWidgets.QTableWidgetItem()
|
||||
self.StatTable.setItem(0, 4, item)
|
||||
self.tabWidget.addTab(self.tab, "")
|
||||
self.saves = QtWidgets.QWidget()
|
||||
self.saves.setObjectName("saves")
|
||||
self.SaveList = QtWidgets.QListWidget(self.saves)
|
||||
self.SaveList.setGeometry(QtCore.QRect(10, 10, 411, 211))
|
||||
self.SaveList.setObjectName("SaveList")
|
||||
item = QtWidgets.QListWidgetItem()
|
||||
item.setIcon(icon1)
|
||||
self.SaveList.addItem(item)
|
||||
self.loadGame = QtWidgets.QPushButton(self.saves)
|
||||
self.loadGame.setGeometry(QtCore.QRect(10, 230, 75, 23))
|
||||
self.loadGame.setCursor(QtGui.QCursor(QtCore.Qt.PointingHandCursor))
|
||||
self.loadGame.setObjectName("loadGame")
|
||||
self.tabWidget.addTab(self.saves, "")
|
||||
self.profiles = QtWidgets.QWidget()
|
||||
self.profiles.setObjectName("profiles")
|
||||
self.groupBox = QtWidgets.QGroupBox(self.profiles)
|
||||
self.groupBox.setGeometry(QtCore.QRect(0, 10, 171, 121))
|
||||
self.groupBox.setObjectName("groupBox")
|
||||
self.loginUsernameLine = QtWidgets.QLineEdit(self.groupBox)
|
||||
self.loginUsernameLine.setGeometry(QtCore.QRect(10, 20, 151, 20))
|
||||
self.loginUsernameLine.setObjectName("loginUsernameLine")
|
||||
self.loginHasloLine = QtWidgets.QLineEdit(self.groupBox)
|
||||
self.loginHasloLine.setGeometry(QtCore.QRect(10, 50, 151, 20))
|
||||
self.loginHasloLine.setEchoMode(QtWidgets.QLineEdit.Password)
|
||||
self.loginHasloLine.setObjectName("loginHasloLine")
|
||||
self.loginButton = QtWidgets.QPushButton(self.groupBox)
|
||||
self.loginButton.setGeometry(QtCore.QRect(90, 90, 75, 23))
|
||||
self.loginButton.setCursor(QtGui.QCursor(QtCore.Qt.PointingHandCursor))
|
||||
self.loginButton.setObjectName("loginButton")
|
||||
self.logPasShow = QtWidgets.QCheckBox(self.groupBox)
|
||||
self.logPasShow.setGeometry(QtCore.QRect(10, 90, 70, 17))
|
||||
self.logPasShow.setCursor(QtGui.QCursor(QtCore.Qt.PointingHandCursor))
|
||||
self.logPasShow.setObjectName("logPasShow")
|
||||
self.usernamesList = QtWidgets.QListWidget(self.profiles)
|
||||
self.usernamesList.setGeometry(QtCore.QRect(185, 10, 231, 201))
|
||||
self.usernamesList.setObjectName("usernamesList")
|
||||
item = QtWidgets.QListWidgetItem()
|
||||
self.usernamesList.addItem(item)
|
||||
self.groupBox_2 = QtWidgets.QGroupBox(self.profiles)
|
||||
self.groupBox_2.setGeometry(QtCore.QRect(0, 130, 171, 121))
|
||||
self.groupBox_2.setObjectName("groupBox_2")
|
||||
self.regLoginLine = QtWidgets.QLineEdit(self.groupBox_2)
|
||||
self.regLoginLine.setGeometry(QtCore.QRect(10, 20, 151, 20))
|
||||
self.regLoginLine.setObjectName("regLoginLine")
|
||||
self.regHasloLine = QtWidgets.QLineEdit(self.groupBox_2)
|
||||
self.regHasloLine.setGeometry(QtCore.QRect(10, 50, 151, 20))
|
||||
self.regHasloLine.setEchoMode(QtWidgets.QLineEdit.Password)
|
||||
self.regHasloLine.setObjectName("regHasloLine")
|
||||
self.regButton = QtWidgets.QPushButton(self.groupBox_2)
|
||||
self.regButton.setGeometry(QtCore.QRect(90, 90, 75, 23))
|
||||
self.regButton.setCursor(QtGui.QCursor(QtCore.Qt.PointingHandCursor))
|
||||
self.regButton.setObjectName("regButton")
|
||||
self.regPasShow = QtWidgets.QCheckBox(self.groupBox_2)
|
||||
self.regPasShow.setGeometry(QtCore.QRect(10, 90, 70, 17))
|
||||
self.regPasShow.setCursor(QtGui.QCursor(QtCore.Qt.PointingHandCursor))
|
||||
self.regPasShow.setObjectName("regPasShow")
|
||||
self.logOut = QtWidgets.QPushButton(self.profiles)
|
||||
self.logOut.setEnabled(False)
|
||||
self.logOut.setGeometry(QtCore.QRect(330, 230, 75, 23))
|
||||
self.logOut.setCursor(QtGui.QCursor(QtCore.Qt.PointingHandCursor))
|
||||
self.logOut.setObjectName("logOut")
|
||||
self.tabWidget.addTab(self.profiles, "")
|
||||
self.gameinfo = QtWidgets.QLabel(Form)
|
||||
self.gameinfo.setGeometry(QtCore.QRect(20, 300, 411, 31))
|
||||
self.gameinfo.setObjectName("gameinfo")
|
||||
|
||||
self.retranslateUi(Form)
|
||||
self.tabWidget.setCurrentIndex(0)
|
||||
QtCore.QMetaObject.connectSlotsByName(Form)
|
||||
|
||||
def retranslateUi(self, Form):
|
||||
_translate = QtCore.QCoreApplication.translate
|
||||
Form.setWindowTitle(_translate("Form", "Сапёр игровой лаунчер"))
|
||||
__sortingEnabled = self.gameList.isSortingEnabled()
|
||||
self.gameList.setSortingEnabled(False)
|
||||
item = self.gameList.item(0)
|
||||
item.setText(_translate("Form", "Системный администратор"))
|
||||
self.gameList.setSortingEnabled(__sortingEnabled)
|
||||
self.play.setText(_translate("Form", "Играть"))
|
||||
self.soundOn.setText(_translate("Form", "Включить музыку"))
|
||||
self.updateGames.setText(_translate("Form", "Обновить"))
|
||||
self.tabWidget.setTabText(self.tabWidget.indexOf(self.Launcher), _translate("Form", "Игра"))
|
||||
item = self.StatTable.verticalHeaderItem(0)
|
||||
item.setText(_translate("Form", "1"))
|
||||
item = self.StatTable.horizontalHeaderItem(0)
|
||||
item.setText(_translate("Form", "Никнейм"))
|
||||
item = self.StatTable.horizontalHeaderItem(1)
|
||||
item.setText(_translate("Form", "Очки"))
|
||||
item = self.StatTable.horizontalHeaderItem(2)
|
||||
item.setText(_translate("Form", "Обезврежено мин"))
|
||||
item = self.StatTable.horizontalHeaderItem(3)
|
||||
item.setText(_translate("Form", "Среднее количество обезвреженных мин"))
|
||||
item = self.StatTable.horizontalHeaderItem(4)
|
||||
item.setText(_translate("Form", "Последняя запущена игра..."))
|
||||
__sortingEnabled = self.StatTable.isSortingEnabled()
|
||||
self.StatTable.setSortingEnabled(False)
|
||||
item = self.StatTable.item(0, 0)
|
||||
item.setText(_translate("Form", "Игрок"))
|
||||
item = self.StatTable.item(0, 1)
|
||||
item.setText(_translate("Form", "0"))
|
||||
item = self.StatTable.item(0, 2)
|
||||
item.setText(_translate("Form", "0"))
|
||||
item = self.StatTable.item(0, 3)
|
||||
item.setText(_translate("Form", "0"))
|
||||
item = self.StatTable.item(0, 4)
|
||||
item.setText(_translate("Form", "0"))
|
||||
self.StatTable.setSortingEnabled(__sortingEnabled)
|
||||
self.tabWidget.setTabText(self.tabWidget.indexOf(self.tab), _translate("Form", "Статистика"))
|
||||
__sortingEnabled = self.SaveList.isSortingEnabled()
|
||||
self.SaveList.setSortingEnabled(False)
|
||||
item = self.SaveList.item(0)
|
||||
item.setText(_translate("Form", "User, 22.09.2003 14:50, Системный администратор (не закончено)"))
|
||||
self.SaveList.setSortingEnabled(__sortingEnabled)
|
||||
self.loadGame.setText(_translate("Form", "Загрузить"))
|
||||
self.tabWidget.setTabText(self.tabWidget.indexOf(self.saves), _translate("Form", "Сохранения"))
|
||||
self.groupBox.setTitle(_translate("Form", "Войти"))
|
||||
self.loginUsernameLine.setPlaceholderText(_translate("Form", "Логин"))
|
||||
self.loginHasloLine.setPlaceholderText(_translate("Form", "Пароль"))
|
||||
self.loginButton.setText(_translate("Form", "Войти"))
|
||||
self.logPasShow.setText(_translate("Form", "Показать"))
|
||||
__sortingEnabled = self.usernamesList.isSortingEnabled()
|
||||
self.usernamesList.setSortingEnabled(False)
|
||||
item = self.usernamesList.item(0)
|
||||
item.setText(_translate("Form", "Игрок"))
|
||||
self.usernamesList.setSortingEnabled(__sortingEnabled)
|
||||
self.groupBox_2.setTitle(_translate("Form", "Зарегистрировать профиль"))
|
||||
self.regLoginLine.setPlaceholderText(_translate("Form", "Логин"))
|
||||
self.regHasloLine.setPlaceholderText(_translate("Form", "Пароль"))
|
||||
self.regButton.setText(_translate("Form", "Регистрация"))
|
||||
self.regPasShow.setText(_translate("Form", "Показать"))
|
||||
self.logOut.setText(_translate("Form", "Выйти"))
|
||||
self.tabWidget.setTabText(self.tabWidget.indexOf(self.profiles), _translate("Form", "Профили"))
|
||||
self.gameinfo.setText(_translate("Form", "Войдите или зарегайте профиль, чтобы играть!"))
|
421
launcher.ui
Normal file
421
launcher.ui
Normal file
@ -0,0 +1,421 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>Form</class>
|
||||
<widget class="QWidget" name="Form">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>460</width>
|
||||
<height>341</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string>Сапёр игровой лаунчер</string>
|
||||
</property>
|
||||
<property name="windowIcon">
|
||||
<iconset>
|
||||
<normaloff>source/gameico.ico</normaloff>source/gameico.ico</iconset>
|
||||
</property>
|
||||
<widget class="QTabWidget" name="tabWidget">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>10</x>
|
||||
<y>10</y>
|
||||
<width>441</width>
|
||||
<height>281</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="currentIndex">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<widget class="QWidget" name="Launcher">
|
||||
<attribute name="title">
|
||||
<string>Игра</string>
|
||||
</attribute>
|
||||
<widget class="QListWidget" name="gameList">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>20</x>
|
||||
<y>30</y>
|
||||
<width>391</width>
|
||||
<height>171</height>
|
||||
</rect>
|
||||
</property>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>Системный администратор</string>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset>
|
||||
<normaloff>source/sys admin/gameico.png</normaloff>source/sys admin/gameico.png</iconset>
|
||||
</property>
|
||||
</item>
|
||||
</widget>
|
||||
<widget class="QPushButton" name="play">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>180</x>
|
||||
<y>220</y>
|
||||
<width>75</width>
|
||||
<height>23</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="cursor">
|
||||
<cursorShape>PointingHandCursor</cursorShape>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Играть</string>
|
||||
</property>
|
||||
</widget>
|
||||
<widget class="QCheckBox" name="soundOn">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>310</x>
|
||||
<y>230</y>
|
||||
<width>121</width>
|
||||
<height>21</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="cursor">
|
||||
<cursorShape>PointingHandCursor</cursorShape>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Включить музыку</string>
|
||||
</property>
|
||||
<property name="checked">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
<widget class="QPushButton" name="updateGames">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>20</x>
|
||||
<y>210</y>
|
||||
<width>75</width>
|
||||
<height>23</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="cursor">
|
||||
<cursorShape>PointingHandCursor</cursorShape>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Обновить</string>
|
||||
</property>
|
||||
</widget>
|
||||
</widget>
|
||||
<widget class="QWidget" name="tab">
|
||||
<attribute name="title">
|
||||
<string>Статистика</string>
|
||||
</attribute>
|
||||
<widget class="QTableWidget" name="StatTable">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>10</x>
|
||||
<y>0</y>
|
||||
<width>421</width>
|
||||
<height>231</height>
|
||||
</rect>
|
||||
</property>
|
||||
<row>
|
||||
<property name="text">
|
||||
<string>1</string>
|
||||
</property>
|
||||
</row>
|
||||
<column>
|
||||
<property name="text">
|
||||
<string>Никнейм</string>
|
||||
</property>
|
||||
</column>
|
||||
<column>
|
||||
<property name="text">
|
||||
<string>Очки</string>
|
||||
</property>
|
||||
</column>
|
||||
<column>
|
||||
<property name="text">
|
||||
<string>Обезврежено мин</string>
|
||||
</property>
|
||||
</column>
|
||||
<column>
|
||||
<property name="text">
|
||||
<string>Среднее количество обезвреженных мин</string>
|
||||
</property>
|
||||
</column>
|
||||
<column>
|
||||
<property name="text">
|
||||
<string>Любимая игра</string>
|
||||
</property>
|
||||
</column>
|
||||
<item row="0" column="0">
|
||||
<property name="text">
|
||||
<string>Игрок</string>
|
||||
</property>
|
||||
</item>
|
||||
<item row="0" column="1">
|
||||
<property name="text">
|
||||
<string>0</string>
|
||||
</property>
|
||||
</item>
|
||||
<item row="0" column="2">
|
||||
<property name="text">
|
||||
<string>0</string>
|
||||
</property>
|
||||
</item>
|
||||
<item row="0" column="3">
|
||||
<property name="text">
|
||||
<string>0</string>
|
||||
</property>
|
||||
</item>
|
||||
<item row="0" column="4">
|
||||
<property name="text">
|
||||
<string>0</string>
|
||||
</property>
|
||||
</item>
|
||||
</widget>
|
||||
</widget>
|
||||
<widget class="QWidget" name="saves">
|
||||
<attribute name="title">
|
||||
<string>Сохранения</string>
|
||||
</attribute>
|
||||
<widget class="QListWidget" name="SaveList">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>10</x>
|
||||
<y>10</y>
|
||||
<width>411</width>
|
||||
<height>211</height>
|
||||
</rect>
|
||||
</property>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>User, 22.09.2003 14:50, Системный администратор (не закончено)</string>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset>
|
||||
<normaloff>source/sys admin/gameico.png</normaloff>source/sys admin/gameico.png</iconset>
|
||||
</property>
|
||||
</item>
|
||||
</widget>
|
||||
<widget class="QPushButton" name="loadGame">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>10</x>
|
||||
<y>230</y>
|
||||
<width>75</width>
|
||||
<height>23</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="cursor">
|
||||
<cursorShape>PointingHandCursor</cursorShape>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Загрузить</string>
|
||||
</property>
|
||||
</widget>
|
||||
</widget>
|
||||
<widget class="QWidget" name="profiles">
|
||||
<attribute name="title">
|
||||
<string>Профили</string>
|
||||
</attribute>
|
||||
<widget class="QGroupBox" name="groupBox">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>10</y>
|
||||
<width>171</width>
|
||||
<height>121</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="title">
|
||||
<string>Войти</string>
|
||||
</property>
|
||||
<widget class="QLineEdit" name="loginUsernameLine">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>10</x>
|
||||
<y>20</y>
|
||||
<width>151</width>
|
||||
<height>20</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="placeholderText">
|
||||
<string>Логин</string>
|
||||
</property>
|
||||
</widget>
|
||||
<widget class="QLineEdit" name="loginHasloLine">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>10</x>
|
||||
<y>50</y>
|
||||
<width>151</width>
|
||||
<height>20</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="echoMode">
|
||||
<enum>QLineEdit::Password</enum>
|
||||
</property>
|
||||
<property name="placeholderText">
|
||||
<string>Пароль</string>
|
||||
</property>
|
||||
</widget>
|
||||
<widget class="QPushButton" name="loginButton">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>90</x>
|
||||
<y>90</y>
|
||||
<width>75</width>
|
||||
<height>23</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="cursor">
|
||||
<cursorShape>PointingHandCursor</cursorShape>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Войти</string>
|
||||
</property>
|
||||
</widget>
|
||||
<widget class="QCheckBox" name="logPasShow">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>10</x>
|
||||
<y>90</y>
|
||||
<width>70</width>
|
||||
<height>17</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="cursor">
|
||||
<cursorShape>PointingHandCursor</cursorShape>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Показать</string>
|
||||
</property>
|
||||
</widget>
|
||||
</widget>
|
||||
<widget class="QListWidget" name="usernamesList">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>185</x>
|
||||
<y>10</y>
|
||||
<width>231</width>
|
||||
<height>201</height>
|
||||
</rect>
|
||||
</property>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>Игрок</string>
|
||||
</property>
|
||||
</item>
|
||||
</widget>
|
||||
<widget class="QGroupBox" name="groupBox_2">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>130</y>
|
||||
<width>171</width>
|
||||
<height>121</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="title">
|
||||
<string>Зарегистрировать профиль</string>
|
||||
</property>
|
||||
<widget class="QLineEdit" name="regLoginLine">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>10</x>
|
||||
<y>20</y>
|
||||
<width>151</width>
|
||||
<height>20</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="placeholderText">
|
||||
<string>Логин</string>
|
||||
</property>
|
||||
</widget>
|
||||
<widget class="QLineEdit" name="regHasloLine">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>10</x>
|
||||
<y>50</y>
|
||||
<width>151</width>
|
||||
<height>20</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="echoMode">
|
||||
<enum>QLineEdit::Password</enum>
|
||||
</property>
|
||||
<property name="placeholderText">
|
||||
<string>Пароль</string>
|
||||
</property>
|
||||
</widget>
|
||||
<widget class="QPushButton" name="regButton">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>90</x>
|
||||
<y>90</y>
|
||||
<width>75</width>
|
||||
<height>23</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="cursor">
|
||||
<cursorShape>PointingHandCursor</cursorShape>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Регистрация</string>
|
||||
</property>
|
||||
</widget>
|
||||
<widget class="QCheckBox" name="regPasShow">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>10</x>
|
||||
<y>90</y>
|
||||
<width>70</width>
|
||||
<height>17</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="cursor">
|
||||
<cursorShape>PointingHandCursor</cursorShape>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Показать</string>
|
||||
</property>
|
||||
</widget>
|
||||
</widget>
|
||||
<widget class="QPushButton" name="logOut">
|
||||
<property name="enabled">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>330</x>
|
||||
<y>230</y>
|
||||
<width>75</width>
|
||||
<height>23</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="cursor">
|
||||
<cursorShape>PointingHandCursor</cursorShape>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Выйти</string>
|
||||
</property>
|
||||
</widget>
|
||||
</widget>
|
||||
</widget>
|
||||
<widget class="QLabel" name="gameinfo">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>20</x>
|
||||
<y>300</y>
|
||||
<width>411</width>
|
||||
<height>31</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Войдите или зарегайте профиль, чтобы играть!</string>
|
||||
</property>
|
||||
</widget>
|
||||
</widget>
|
||||
<resources/>
|
||||
<connections/>
|
||||
</ui>
|
2
runCore.sh
Normal file
2
runCore.sh
Normal file
@ -0,0 +1,2 @@
|
||||
cd Gamecore
|
||||
start gamecore.exe
|
109
testgame.py
Normal file
109
testgame.py
Normal file
@ -0,0 +1,109 @@
|
||||
import corelib, os, termcolor, colorama
|
||||
colorama.init()
|
||||
|
||||
clear = lambda: os.system('cls')
|
||||
gamedata = corelib.newGame(ID=0, mines=25, fieldsize=10)['response']
|
||||
gamedata['continue'] = True
|
||||
clear()
|
||||
|
||||
|
||||
def getuserfield(field, gamefinnised=False):
|
||||
maxFieldCoord = len(field) - 1
|
||||
# ░ свободная клетка
|
||||
# █ Не открытая клетка
|
||||
# F Помечена флагом
|
||||
# 1..4 Мины рядом
|
||||
# X Минa взорвана
|
||||
# S Минa обезврежена
|
||||
retfield = list()
|
||||
for row in field:
|
||||
X = field.index(row)
|
||||
retfield.append(list())
|
||||
for cell in row:
|
||||
Y = field[X].index(cell)
|
||||
if ':O' in cell and cell != 'M:O':
|
||||
mines = 0
|
||||
# Проверим наличие мин
|
||||
upCoord = Y != 0
|
||||
downCoord = Y != maxFieldCoord
|
||||
leftCoord = X != 0
|
||||
rightCoord = X != maxFieldCoord
|
||||
|
||||
if upCoord and field[X][Y - 1] != cell and ':O' not in field[X][Y - 1]:
|
||||
mines += 1
|
||||
if downCoord and field[X][Y + 1] != cell and ':O' not in field[X][Y + 1]:
|
||||
mines += 1
|
||||
if leftCoord and field[X - 1][Y] != cell and ':O' not in field[X - 1][Y]:
|
||||
mines += 1
|
||||
if rightCoord and field[X + 1][Y] != cell and ':O' not in field[X + 1][Y]:
|
||||
mines += 1
|
||||
if mines == 0:
|
||||
if upCoord and field[X][Y - 1] != cell:
|
||||
mines = 1
|
||||
elif downCoord and field[X][Y + 1] != cell:
|
||||
mines = 1
|
||||
elif leftCoord and field[X - 1][Y] != cell:
|
||||
mines = 1
|
||||
elif rightCoord and field[X + 1][Y] != cell:
|
||||
mines = 1
|
||||
|
||||
if mines == 0:
|
||||
retfield[-1].append('░')
|
||||
elif mines >= 3:
|
||||
retfield[-1].append(termcolor.colored(f"{mines}", "red"))
|
||||
elif mines == 2:
|
||||
retfield[-1].append(termcolor.colored(f"{mines}", "yellow"))
|
||||
elif mines == 1:
|
||||
retfield[-1].append(termcolor.colored(f"{mines}", "green"))
|
||||
elif cell == 'M:F':
|
||||
if gamefinnised:
|
||||
retfield[-1].append('S')
|
||||
else:
|
||||
retfield[-1].append('F')
|
||||
elif ':F' in cell:
|
||||
retfield[-1].append('F')
|
||||
elif cell == 'M':
|
||||
if gamefinnised:
|
||||
retfield[-1].append('X')
|
||||
else:
|
||||
retfield[-1].append('█')
|
||||
else:
|
||||
retfield[-1].append('█')
|
||||
|
||||
return retfield
|
||||
|
||||
|
||||
clear()
|
||||
while gamedata['continue']:
|
||||
print('Y/X| 0123456789\n---|=============')
|
||||
i = 0
|
||||
for row in getuserfield(gamedata['map'], gamefinnised=not(gamedata['continue'])):
|
||||
print(f"{i}|. ", ''.join(row))
|
||||
i += 1
|
||||
|
||||
while True:
|
||||
try:
|
||||
X = int(input('Введите X: '))
|
||||
break
|
||||
except:
|
||||
pass
|
||||
while True:
|
||||
try:
|
||||
Y = int(input('Введите Y: '))
|
||||
break
|
||||
except:
|
||||
pass
|
||||
if input('Введите 0 если хотите поставить флаг: ') == '0':
|
||||
corelib.toggleFlag(gamedata['gamesession'], X, Y)
|
||||
else:
|
||||
corelib.openItem(gamedata['gamesession'], X, Y)
|
||||
|
||||
gamedata = corelib.getGameSession(gamedata['gamesession'])['response']
|
||||
clear()
|
||||
|
||||
print('Y/X| 0123456789\n---|=============')
|
||||
i = 0
|
||||
for row in getuserfield(gamedata['map'], gamefinnised=not(gamedata['continue'])):
|
||||
print(f"{i}|. ", ''.join(row))
|
||||
i += 1
|
||||
print('Игра окончена!')
|
3
update.bat
Normal file
3
update.bat
Normal file
@ -0,0 +1,3 @@
|
||||
git add .
|
||||
git commit -m "Up-Date repository"
|
||||
git push
|
Loading…
Reference in New Issue
Block a user