InteligentnySaper/classes/minesweeper.py

400 lines
13 KiB
Python
Raw Normal View History

2022-03-09 01:36:46 +01:00
import pygame
from classes import system
2022-03-09 23:37:42 +01:00
from random import randrange
2022-03-09 01:36:46 +01:00
2022-03-09 23:37:42 +01:00
pygame.mixer.init()
#mina
class Mine:
2022-03-09 01:36:46 +01:00
position_x:int
position_y:int
2022-03-09 23:37:42 +01:00
size:int
2022-03-09 01:36:46 +01:00
image:pygame.surface.Surface
2022-03-24 11:28:11 +01:00
difficulty:int = 1
weight:float = 1.0
2022-03-09 23:37:42 +01:00
def __init__(self,position_x, position_y, size):
2022-03-09 01:36:46 +01:00
self.position_x=position_x
self.position_y=position_y
2022-03-09 23:37:42 +01:00
self.size=size
2022-03-24 17:45:52 +01:00
self.image = pygame.image.load("assets/sprites/mine_fun_sized.png")
2022-03-09 01:36:46 +01:00
self.image = pygame.transform.scale(self.image, (self.size, self.size))
2022-03-09 23:37:42 +01:00
def draw(self, window):
position_on_screen = (self.size*self.position_x, self.size*self.position_y)
window.blit(self.image, position_on_screen)
2022-03-09 01:36:46 +01:00
2022-03-10 18:40:11 +01:00
class Cliff:
position_x:int
position_y:int
size:int
image:pygame.surface.Surface
2022-03-24 11:28:11 +01:00
type:int
2022-03-10 18:40:11 +01:00
rotation:int
2022-03-24 11:28:11 +01:00
def __init__(self,position_x, position_y, size, rotation, type=0):
2022-03-10 18:40:11 +01:00
self.position_x=position_x
self.position_y=position_y
self.size=size
self.rotation = rotation
2022-03-24 11:28:11 +01:00
self.type = type
if self.type==0:
self.image = pygame.image.load("assets/sprites/cliff.png")
elif self.type==1:
self.image = pygame.image.load("assets/sprites/cliff_corner.png")
elif self.type==2:
self.image = pygame.image.load("assets/sprites/cliff_end1.png")
elif self.type==3:
self.image = pygame.image.load("assets/sprites/cliff_end2.png")
2022-03-10 18:40:11 +01:00
self.image = pygame.transform.scale(self.image, (self.size, self.size))
self.image = pygame.transform.rotate(self.image, self.rotation)
def draw(self, window):
position_on_screen = (self.size*self.position_x, self.size*self.position_y)
window.blit(self.image, position_on_screen)
2022-03-09 23:37:42 +01:00
#mapa
2022-03-09 01:36:46 +01:00
class Map:
window:system.Window
tile_size:int
tiles_x:int
tiles_y:int
2022-03-09 23:37:42 +01:00
2022-03-09 01:36:46 +01:00
tile_palette:list
2022-03-09 23:37:42 +01:00
terrain_matrix:list
2022-03-09 01:36:46 +01:00
2022-03-10 18:40:11 +01:00
cliffs=[]
2022-03-09 23:37:42 +01:00
mines=[]
2022-03-09 01:36:46 +01:00
def __init__(self, window:system.Window, tile_size:int=64, tiles_x:int=8, tiles_y:int=8):
self.window = window
self.tile_size = tile_size
self.tiles_x = tiles_x
self.tiles_y = tiles_y
#dodanie grafik wszystkich typów terenu do jednej listy
2022-03-09 23:37:42 +01:00
self.tile_palette=[None]*20
2022-03-09 01:36:46 +01:00
image = pygame.image.load("assets/sprites/sand.png")
image = pygame.transform.scale(image, (tile_size,tile_size))
2022-03-09 23:37:42 +01:00
self.tile_palette[0]=image
image = pygame.image.load("assets/sprites/stone.png")
image = pygame.transform.scale(image, (tile_size,tile_size))
self.tile_palette[10]=image
2022-03-09 01:36:46 +01:00
def generate(self):
#generowanie terenu
matrix = []
for i in range(self.tiles_y):
matrix.append([])
for j in range(self.tiles_x):
2022-03-24 11:28:11 +01:00
#sprawdza czy są tu jakieś klify
ok = True
for cliff in self.cliffs:
for i2 in range(i-1,i+2):
if (j, i2) == (cliff.position_x, cliff.position_y):
ok = False
break
elif (j-1, i2) == (cliff.position_x, cliff.position_y):
ok = False
break
elif (j+1, i2) == (cliff.position_x, cliff.position_y):
ok = False
break
2022-03-09 01:36:46 +01:00
#od liczby zależy jaki teren, np. 0 - piasek
2022-03-10 18:40:11 +01:00
rng = randrange(10)
2022-03-24 11:28:11 +01:00
if ok and rng==0 and not (i<2 and j<3):
2022-03-09 23:37:42 +01:00
matrix[i].append(10)
2022-03-24 11:28:11 +01:00
elif ok and rng<2 and not (i<2 and j<3):
2022-03-10 18:40:11 +01:00
matrix[i].append(0)
2022-03-24 11:28:11 +01:00
rand_rotate = 0#randrange(4)*90
if rand_rotate==0 and j+3<self.tiles_x and not (i==0 or i==self.tiles_y-1 or j==0 or j==self.tiles_x-1):
cliff = Cliff(j,i,self.tile_size, rand_rotate, type=2)
self.cliffs.append(cliff)
cliff = Cliff(j+1,i,self.tile_size, rand_rotate, type=0)
self.cliffs.append(cliff)
cliff = Cliff(j+2,i,self.tile_size, rand_rotate, type=3)
self.cliffs.append(cliff)
2022-03-09 23:37:42 +01:00
else:
matrix[i].append(0)
2022-03-09 01:36:46 +01:00
self.terrain_matrix = matrix
2022-03-09 23:37:42 +01:00
for i in range(self.tiles_y):
for j in range(self.tiles_x):
if matrix[i][j]<10:
2022-03-24 11:28:11 +01:00
ok = True
for cliff in self.cliffs:
if (j, i) == (cliff.position_x, cliff.position_y):
ok = False
break
if ok and randrange(10)==0 and not (i<2 and j<3):
2022-03-09 23:37:42 +01:00
mine = Mine(j, i, self.tile_size)
self.mines.append(mine)
2022-03-09 01:36:46 +01:00
def draw_tiles(self):
#narysowanie na ekranie terenu
for i in range(len(self.terrain_matrix)):
for j in range(len(self.terrain_matrix[i])):
self.window.window.blit(self.tile_palette[self.terrain_matrix[i][j]], (self.tile_size*j, self.tile_size*i))
2022-03-09 23:37:42 +01:00
def draw_objects(self):
for mine in self.mines:
mine.draw(self.window.window)
2022-03-10 18:40:11 +01:00
for cliff in self.cliffs:
cliff.draw(self.window.window)
2022-03-09 23:37:42 +01:00
2022-03-24 11:28:11 +01:00
#broń
class Weapon:
size:int
image:pygame.surface.Surface
rotated_image:pygame.surface.Surface
owner:str
weight:float
weapon_type:int
#baza operacji
class Base:
position_x:int
position_y:int
size:int
image:pygame.surface.Surface
weapon_level:int
weapons=[]
#schron
class Shelter:
position_x:int
position_y:int
size:int
image:pygame.surface.Surface
#składowisko
class Dumpster:
position_x:int
position_y:int
size:int
image:pygame.surface.Surface
#cywile
class NPC:
position_x:int
position_y:int
size:int
image:pygame.surface.Surface
rotated_image:pygame.surface.Surface
offset_x:int=0
offset_y:int=0
current_map:Map
2022-03-24 17:45:52 +01:00
type:str
2022-03-24 11:28:11 +01:00
value:int
weight:float
2022-03-09 23:37:42 +01:00
#saper
class Minesweeper:
size:int
rotation_degrees:int
2022-03-09 23:37:42 +01:00
position_x:int
position_y:int
image:pygame.surface.Surface
rotated_image:pygame.surface.Surface
offset_x:int=0
offset_y:int=0
2022-03-24 11:28:11 +01:00
current_map:Map
2022-03-09 23:37:42 +01:00
carried_objects=[]
2022-03-09 01:36:46 +01:00
2022-03-09 23:37:42 +01:00
speed=1
ability=1
max_carried_weight=5.0
def __init__(self, position_x=0, position_y=0, size=64):
self.position_x=position_x
self.position_y=position_y
self.size = size
2022-03-24 17:45:52 +01:00
self.image = pygame.image.load("assets/sprites/saper_fun_sized.png")
2022-03-09 23:37:42 +01:00
self.image = pygame.transform.scale(self.image, (self.size, self.size))
self.rotated_image = self.image
self.rotation_degrees=0
2022-03-09 23:37:42 +01:00
2022-03-24 11:28:11 +01:00
def set_map(self, map:Map):
self.current_map = map
2022-03-09 23:37:42 +01:00
2022-03-24 11:28:11 +01:00
def update_offset(self, delta:float):
2022-03-09 23:37:42 +01:00
dist=round(self.speed*delta/8)
finished=False
if self.offset_x>0:
self.offset_x-=dist
if self.offset_x<=0:
finished=True
elif self.offset_x<0:
self.offset_x+=dist
if self.offset_x>=0:
finished=True
if self.offset_y>0:
self.offset_y-=dist
if self.offset_y<=0:
finished=True
elif self.offset_y<0:
self.offset_y+=dist
if self.offset_y<-self.size and self.offset_y>-1.2*self.size:
pygame.mixer.Channel(1).play(pygame.mixer.Sound("assets/sounds/ledge.wav"))
2022-03-09 23:37:42 +01:00
if self.offset_y>=0:
finished=True
if finished:
2022-03-10 00:13:14 +01:00
pygame.mixer.Channel(1).stop()
2022-03-09 23:37:42 +01:00
self.offset_y=0
self.offset_x=0
2022-03-24 11:28:11 +01:00
def draw(self, window, delta:float):
2022-03-09 23:37:42 +01:00
position_on_screen = (self.size*self.position_x + self.offset_x, self.size*self.position_y + self.offset_y)
window.blit(self.rotated_image, position_on_screen)
2022-03-24 11:28:11 +01:00
self.update_offset(delta)
2022-03-09 23:37:42 +01:00
def rotate(self, dir:str):
dirr=0
if dir=="N":
dirr=180
elif dir=="S":
dirr=0
elif dir=="W":
dirr=270
elif dir=="E":
dirr=90
2022-04-07 17:51:51 +02:00
elif dir=="left":
dirr = (self.rotation_degrees+90) % 360
elif dir=="right":
dirr = (self.rotation_degrees-90) % 360
else:
return
self.rotation_degrees=dirr
self.rotated_image = pygame.transform.rotate(self.image, dirr)
def move(self, dir:int=-1):
2022-03-09 23:37:42 +01:00
#południe - 0
#wschód - 90
#północ - 180
#zachód - 270
if self.offset_x!=0 or self.offset_y!=0:
return
if dir==-1:
dir = self.rotation_degrees
else:
self.rotation_degrees=dir
self.rotated_image = pygame.transform.rotate(self.image, dir)
2022-03-09 23:37:42 +01:00
move_legal=True
2022-03-24 11:28:11 +01:00
cliff_jump=False
2022-03-24 17:45:52 +01:00
next_x=self.position_x
next_y=self.position_y
2022-03-09 23:37:42 +01:00
if dir==0:
2022-03-24 17:45:52 +01:00
next_y=self.position_y+1
2022-03-09 23:37:42 +01:00
elif dir==180:
2022-03-24 17:45:52 +01:00
next_y=self.position_y-1
2022-03-09 23:37:42 +01:00
elif dir==270:
2022-03-24 17:45:52 +01:00
next_x=self.position_x-1
2022-03-09 23:37:42 +01:00
elif dir==90:
2022-03-24 17:45:52 +01:00
next_x=self.position_x+1
if next_x == self.current_map.tiles_x or next_x == -1:
move_legal=False
elif next_y == self.current_map.tiles_y or next_y == -1:
2022-03-24 17:45:52 +01:00
move_legal=False
elif self.current_map.terrain_matrix[next_y][next_x]>9:
2022-03-24 17:45:52 +01:00
move_legal=False
for cliff in self.current_map.cliffs:
if (next_x, next_y) == (cliff.position_x, cliff.position_y):
if dir==0 and cliff.rotation==0:
cliff_jump=True
else:
move_legal=False
2022-03-10 18:40:11 +01:00
2022-03-09 23:37:42 +01:00
if move_legal:
2022-03-10 00:13:14 +01:00
pygame.mixer.Channel(1).set_volume(0.3)
pygame.mixer.Channel(1).play(pygame.mixer.Sound("assets/sounds/moving.wav"))
2022-03-09 23:37:42 +01:00
if dir==0:
self.position_y+=1
self.offset_y=-self.size
2022-03-24 17:45:52 +01:00
if cliff_jump:
self.position_y+=1
self.offset_y=-2*self.size
2022-03-09 23:37:42 +01:00
elif dir==180:
self.position_y-=1
self.offset_y=self.size
elif dir==270:
self.position_x-=1
self.offset_x=self.size
elif dir==90:
self.position_x+=1
self.offset_x=-self.size
else:
2022-03-10 00:13:14 +01:00
pygame.mixer.Channel(2).set_volume(0.5)
2022-03-24 11:28:11 +01:00
pygame.mixer.Channel(2).play(pygame.mixer.Sound("assets/sounds/collision.wav"))
def pick_up(self):
if self.offset_x!=0 or self.offset_y!=0:
return
for mine in self.current_map.mines:
if (self.position_x, self.position_y) == (mine.position_x, mine.position_y):
self.current_map.mines.remove(mine)
pygame.mixer.Channel(3).set_volume(0.7)
pygame.mixer.Channel(3).play(pygame.mixer.Sound("assets/sounds/pickup.wav"))
break
def drop_bombs(self):
pass
def drop_civilians(self):
pass
def sensor(self, x:int=-1, y:int=-1):
if x==-1:
x = self.position_x
if y==-1:
y = self.position_y
sensor_list = [["","",""],["","",""],["","",""]]
for i in range(3):
for j in range(3):
posx = x-1+j
posy = y-1+i
if posx >= self.current_map.tiles_x or posx <= -1:
sensor_list[i][j]="wall"
elif posy >= self.current_map.tiles_y or posy <= -1:
sensor_list[i][j]="wall"
elif self.current_map.terrain_matrix[posy][posx]>9:
sensor_list[i][j]="wall"
else:
sensor_list[i][j]="sand"
for cliff in self.current_map.cliffs:
if (posx, posy) == (cliff.position_x, cliff.position_y):
if cliff.rotation==0:
sensor_list[i][j]="cliff_south"
elif cliff.rotation==90:
sensor_list[i][j]="cliff_east"
elif cliff.rotation==180:
sensor_list[i][j]="cliff_north"
elif cliff.rotation==270:
sensor_list[i][j]="cliff_west"
break
for mine in self.current_map.mines:
if (posx, posy) == (mine.position_x, mine.position_y):
sensor_list[i][j]="mine"
break
2022-03-24 11:28:11 +01:00
return sensor_list