Add files via upload

This commit is contained in:
Nikiroy78 2021-01-28 20:17:14 +03:00 committed by GitHub
parent c8155c3d74
commit 91ef430eb6
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
13 changed files with 2090 additions and 34 deletions

View File

@ -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
View 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

Binary file not shown.

After

Width:  |  Height:  |  Size: 21 KiB

BIN
Theory/scheme_noBg.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 20 KiB

168
corelib.py Normal file
View 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
View 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

Binary file not shown.

BIN
icon.ico Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 66 KiB

210
launcher.py Normal file
View 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
View 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
View File

@ -0,0 +1,2 @@
cd Gamecore
start gamecore.exe

109
testgame.py Normal file
View 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
View File

@ -0,0 +1,3 @@
git add .
git commit -m "Up-Date repository"
git push