commit 84d4d22666d7dd6c2bd904098c0ae0a0696b420f
Author: sej <sej@sejdt.localhost>
Date: Sun, 13 Oct 2024 21:51:55 +0200
Initial commit
Diffstat:
| A | data.py | | | 130 | +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
| A | minestryger.py | | | 142 | +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
2 files changed, 272 insertions(+), 0 deletions(-)
diff --git a/data.py b/data.py
@@ -0,0 +1,130 @@
+import random
+
+class Minestryger():
+
+
+ def __init__(self, w, h, b):
+ if type(w) != int:
+ raise TypeError("Bredden skal være af typen int (heltal)")
+ if type(h) != int:
+ raise TypeError("Højden skal være af typen int (heltal)")
+ if type(b) != int:
+ raise TypeError("Antallet af bomber skal være af typen int (heltal)")
+
+ if b+9 > w*h:
+ raise ValueError("Der kan ikke være flere bomber på pladen end pladens størrelse.")
+ self.w = w
+ self.h = h
+ self.b = b
+ self.grid = [[ -2 for _ in range(self.w)] for _ in range(self.h)]
+ self.flag = [[ 0 for _ in range(self.w)] for _ in range(self.h)]
+ #self.gen_grid()
+ self.state = 0 #når state = 0 er der ikke nogle bomber på spillepladen
+ #når state = 1 er spillet i gang
+ #når state = 2 er spillet tabt
+ #når state = 3 er spillet vundet
+ print("h: {}".format(self.h))
+ print("w: {}".format(self.w))
+ print("b: {}".format(self.w))
+ #self.pg()
+
+ def uncover(self, x, y):
+ if self.on_grid(x, y):
+ if self.grid[y][x] < 0 and self.flag[y][x] != 1:
+ if self.grid[y][x] == -1:
+ print("Du døde")
+ self.state = 2
+ elif self.grid[y][x] == -2:
+ print("uncovering")
+ b = self.surrounding(x, y)
+ self.grid[y][x] = b
+ if b == 0:
+ for i in range(-1, 2):
+ for u in range(-1, 2):
+ self.uncover(x + u, y + i)
+ self.win_cond()
+
+ def mm_uncover(self, x, y):
+ if self.on_grid(x, y):
+ sflag = self.surrounding(x, y, f = True) #beregn omkringliggende flag
+ if sflag == self.grid[y][x]:
+ for i in range(-1, 2):
+ for u in range(-1, 2):
+ self.uncover(x + u, y + i)
+
+ def surrounding(self, x, y, f = False):
+ if f:
+ g = self.flag
+ c = 1
+
+ elif not f:
+ g = self.grid
+ c = -1
+
+ s = 0
+ for i in range(-1, 2):
+ for u in range(-1, 2):
+ dy = y + i
+ if dy < 0:
+ continue
+ dx = x + u
+ if dx < 0:
+ continue
+ try:
+ q = g[dy][dx]
+ if q == c:
+ s += 1
+ except:
+ q = 0 #hvis koordinatet falder uden for spillepladen
+ #self.pg()
+ return s
+
+ def pg(self):
+ for row in self.flag:
+ print(row)
+ for row in self.grid:
+ print(row)
+
+ def gen_grid(self, sx, sy):
+ # negative tal er undiscovered tiles, -1 for bombe, -2 for fri
+ # positive tal angiver antallet af omkringliggende bomber
+ # nul er discovered frit felt uden omkringliggende bomber
+ if self.on_grid(sx, sy):
+ miner = set()
+ print( sx -1, sx +1 )
+ print( sy -1, sy +1)
+ while len(miner) < self.b:
+ rx = random.randint(0,self.w-1)
+ ry = random.randint(0,self.h-1)
+ if not (sx - 1 <= rx <= sx + 1 and sy - 1 <= ry <= sy + 1):
+ #if sx != rx or sy != ry:
+ self.grid[ry][rx] = -1
+ miner.add((rx,ry))
+ self.state = 1
+
+ def set_flag(self, x, y):
+ if self.on_grid(x, y):
+ if self.flag[y][x] != 1 and not self.grid[y][x] >= 0:
+ self.flag[y][x] = 1
+ else:
+ self.flag[y][x] = 0
+
+ def get_remaining_bombs(self):
+ total = 0
+ for x in range(self.w):
+ for y in range(self.h):
+ total += self.flag[y][x]
+
+ return total
+
+ def on_grid(self, x, y):
+ if 0 <= x < self.w and 0 <= y < self.h:
+ return True
+ else:
+ return False
+
+ def win_cond(self):
+ for row in self.grid:
+ if -2 in row:
+ return
+ self.state = 3
diff --git a/minestryger.py b/minestryger.py
@@ -0,0 +1,142 @@
+#!/usr/bin/env python3
+import pygame as pg
+from data import Minestryger
+import argparse
+import sys
+
+#commandline parametre
+parser = argparse.ArgumentParser(description = "Minestryger")
+parser.add_argument('-d', action='store_true', help='Slå demotilstand til der gør at bomber vises')
+parser.add_argument('-wh', nargs=2, metavar=('W', 'H'), type=int, help='Bredde og højde')
+parser.add_argument('-b', type=int, help='Antal bomber')
+parser.add_argument('-c', type=int, help='Cellestørrelse')
+parser.add_argument('--overwrite-recursion-limit', metavar='limit', type=int, help='Til store spilleplader med relativt få bomber. Eget ansvar.')
+
+oargs = parser.parse_args() #oprindelige argumenter
+
+args = vars(oargs) #dict til argumenter
+print(args)
+print(len(sys.argv))
+
+if len(sys.argv) == 1: #hvis programmet køres uden parametre
+ spil = Minestryger(9, 9, 10)
+else:
+ spil = Minestryger(args["wh"][0], args["wh"][1], args["b"]) #giver fejl hvis parametrene mangler eller er forkerte
+
+if oargs.c:
+ cs = args["c"] #cellestørrelse
+else:
+ cs = 20
+
+if oargs.overwrite_recursion_limit:
+ sys.setrecursionlimit(oargs.overwrite_recursion_limit) #til store spilleplader med relativt få bomber
+
+#opsætning af pygame
+pg.init()
+screen = pg.display.set_mode(( 500 if spil.w * cs < 500 else spil.w * cs, spil.h * cs +50)) #bredden er mindst 500px
+screen.fill((0,0,0))
+clock = pg.time.Clock()
+
+#fonts
+font = pg.font.SysFont(None, int(cs*1.8))
+text = []
+farver = [(255,255,255),(0,0,255), (0,123,0), (255,0,0), (0,0,123), (123,0,0), (0,123,123), (0,0,0), (123,123,13)]
+for i in range(9):
+ tal = font.render(str(i), True, farver[i])
+ text.append(tal)
+
+font2 = pg.font.SysFont(None, 25)
+
+tab_text = font2.render("Desværre tabte du spillet. Tryk her for at starte forfra.", True, (255,255,255))
+vind_text = font2.render("Tillykke! Du vandt spillet. Tryk her for at starte forfra.", True, (255,255,255))
+
+
+def draw_game():
+ pg.draw.rect(screen, (255,255,255), pg.Rect(0, 0, pg.display.get_window_size()[0], pg.display.get_window_size()[1]))
+ for x in range(spil.w):
+ for y in range(spil.h):
+ if spil.grid[y][x] < 0:
+ pg.draw.rect(screen, (120,120,120), pg.Rect(x * cs, y * cs, cs, cs))
+
+ if spil.grid[y][x] == 0:
+ pg.draw.rect(screen, (255,255,255), pg.Rect(x * cs, y * cs, cs, cs))
+
+ if oargs.d:
+ if spil.grid[y][x] == -1:
+ pg.draw.rect(screen, (12,120,120), pg.Rect(x * cs, y * cs, cs, cs))
+
+ if spil.flag[y][x] == 1:
+ pg.draw.rect(screen, (120,0,0), pg.Rect(x * cs, y * cs, cs, cs))
+
+ if spil.grid[y][x] > 0:
+ t = spil.grid[y][x]
+ screen.blit(text[t], (x * cs,y * cs))
+ #pg.draw.rect(screen, (0,0,255), pg.Rect(x*80, y*80, 80, 80))
+
+ pg.draw.rect(screen, (0,0,0), pg.Rect(0, cs * spil.h, pg.display.get_window_size()[0], 50)) #underbaren
+ tb = spil.get_remaining_bombs()
+ tbt = font2.render("{} / {}".format(tb, spil.b), True, (255,255,255))
+ screen.blit(tbt, (0,spil.h * cs+25))
+
+
+def draw_bombs():
+ for x in range(spil.w):
+ for y in range(spil.h):
+ if spil.grid[y][x] == -1:
+ pg.draw.rect(screen, (12,12,12), pg.Rect(x * cs, y * cs, cs, cs))
+ if spil.flag[y][x] == 1 and spil.grid[y][x] == -1:
+ pg.draw.rect(screen, (50,110,255), pg.Rect(x * cs, y * cs, cs, cs))
+ elif spil.flag[y][x] == 1:
+ pg.draw.rect(screen, (255,0,0), pg.Rect(x * cs, y * cs, cs, cs))
+
+def draw_loss():
+ pg.draw.rect(screen, (0,0,0), pg.Rect(0, cs * spil.h, pg.display.get_window_size()[0], 50)) #underbaren
+ screen.blit(tab_text, (0,spil.h * cs))
+
+def draw_win():
+ pg.draw.rect(screen, (0,0,0), pg.Rect(0, cs * spil.h, pg.display.get_window_size()[0], 50)) #underbaren
+ screen.blit(vind_text, (0, spil.h * cs))
+
+draw_game()
+while spil.state != -1: #game loop
+#tilstandsmaskine
+ pg.display.update()
+ events = pg.event.get()
+ for event in events: #håndtér input
+ if event.type == pg.MOUSEBUTTONUP:
+ mx, my = pg.mouse.get_pos()
+ cx = mx // cs # x-koordinat på celle
+ cy = my // cs # y-koordinat på celle
+ if event.button == 1: #venstreklik
+ if spil.state == 0:
+ spil.gen_grid(cx, cy)
+ if spil.state == 1:
+ spil.uncover(cx, cy)
+ if spil.state == 2 or spil.state == 3:
+ if my > spil.h *cs:
+ if len(sys.argv) == 1:
+ spil = Minestryger(9, 9, 10) #hvis programmet køres uden parametre
+ else:
+ spil = Minestryger(args["wh"][0], args["wh"][1], args["b"])
+
+ if event.button == 3: #højreklik
+ if spil.state == 1:
+ spil.set_flag(cx, cy)
+
+ if event.button == 2: #middleklik
+ if spil.state == 1:
+ spil.mm_uncover(cx, cy)
+ draw_game()
+
+ if event.type == pg.QUIT:
+ spil.state = -1
+
+ if spil.state == 2:
+ draw_loss()
+ draw_bombs()
+
+ if spil.state == 3:
+ draw_bombs()
+ draw_win()
+
+ clock.tick(60)