以前は、pythonを使用して、ヘビ、タンクバトル、宇宙船バトル、ゴモクなどのゲームを実装していました。
今日はpythonを使用してminesweeperゲームを実装しています
このゲームにはたくさんのコードとソースファイルがあります
あなたは私のGitHubアドレスからそれを得ることができます
地雷原を建設する
import random
fromenumimport Enum
BLOCK_WIDTH =30
BLOCK_HEIGHT =16
SIZE =20 #ブロックサイズ
MINE_COUNT =99 #地雷の数
classBlockStatus(Enum):
normal =1 #クリックされない
opened =2 #クリック
mine =3 #地雷
flag =4 #地雷としてマーク
ask =5 #疑問符としてマーク
bomb =6 #地雷を踏んだ
hint =7 #周囲をダブルクリック
double =8 #マウスの左ボタンと右ボタンでダブルクリックされる
classMine:
def __init__(self, x, y, value=0):
self._x = x
self._y = y
self._value =0
self._around_mine_count =-1
self._status = BlockStatus.normal
self.set_value(value)
def __repr__(self):returnstr(self._value)
# return f'({self._x},{self._y})={self._value}, status={self.status}'
def get_x(self):return self._x
def set_x(self, x):
self._x = x
x =property(fget=get_x, fset=set_x)
def get_y(self):return self._y
def set_y(self, y):
self._y = y
y =property(fget=get_y, fset=set_y)
def get_value(self):return self._value
def set_value(self, value):if value:
self._value =1else:
self._value =0
value =property(fget=get_value, fset=set_value, doc='0:非鉱山1:私の')
def get_around_mine_count(self):return self._around_mine_count
def set_around_mine_count(self, around_mine_count):
self._around_mine_count = around_mine_count
around_mine_count =property(fget=get_around_mine_count, fset=set_around_mine_count, doc='周りの地雷の数')
def get_status(self):return self._status
def set_status(self, value):
self._status = value
status =property(fget=get_status, fset=set_status, doc='BlockStatus')classMineBlock:
def __init__(self):
self._block =[[Mine(i, j)for i inrange(BLOCK_WIDTH)]for j inrange(BLOCK_HEIGHT)]
# 私の鉱山
for i in random.sample(range(BLOCK_WIDTH * BLOCK_HEIGHT), MINE_COUNT):
self._block[i // BLOCK_WIDTH][i % BLOCK_WIDTH].value = 1
def get_block(self):return self._block
block =property(fget=get_block)
def getmine(self, x, y):return self._block[y][x]
def open_mine(self, x, y):
# 雷を踏んだ
if self._block[y][x].value:
self._block[y][x].status = BlockStatus.bomb
return False
# まず、ステータスをオープンに変更します
self._block[y][x].status = BlockStatus.opened
around =_get_around(x, y)
_ sum =0for i, j in around:if self._block[j][i].value:
_ sum +=1
self._block[y][x].around_mine_count = _sum
# 周りに雷がない場合は、周囲の8つのミスを再帰的にカウントします
# これは大きな開口部の効果を達成することができます
if _sum ==0:for i, j in around:if self._block[j][i].around_mine_count ==-1:
self.open_mine(i, j)return True
def double_mouse_button_down(self, x, y):if self._block[y][x].around_mine_count ==0:return True
self._block[y][x].status = BlockStatus.double
around =_get_around(x, y)
sumflag =0 #周りのマークされた鉱山の数
for i, j in_get_around(x, y):if self._block[j][i].status == BlockStatus.flag:
sumflag +=1
# 周囲の鉱山はすべてマークされています
result = True
if sumflag == self._block[y][x].around_mine_count:for i, j in around:if self._block[j][i].status == BlockStatus.normal:if not self.open_mine(i, j):
result = False
else:for i, j in around:if self._block[j][i].status == BlockStatus.normal:
self._block[j][i].status = BlockStatus.hint
return result
def double_mouse_button_up(self, x, y):
self._block[y][x].status = BlockStatus.opened
for i, j in_get_around(x, y):if self._block[j][i].status == BlockStatus.hint:
self._block[j][i].status = BlockStatus.normal
def _get_around(x, y):"""戻る(x, y)周囲の点の座標"""
# ここで、範囲の終わりはオープンレンジであるため、1つのリターンを追加することに注意してください[(i, j)for i inrange(max(0, x -1),min(BLOCK_WIDTH -1, x +1)+1)for j inrange(max(0, y -1),min(BLOCK_HEIGHT -1, y +1)+1)if i != x or j != y]
メイン機能
import sys
import time
fromenumimport Enum
import pygame
from pygame.locals import*from mineblock import*
# ゲーム画面の幅
SCREEN_WIDTH = BLOCK_WIDTH * SIZE
# ゲーム画面の高さ
SCREEN_HEIGHT =(BLOCK_HEIGHT +2)* SIZE
classGameStatus(Enum):
readied =1,
started =2,
over =3,
win =4
def print_text(screen, font, x, y, text, fcolor=(255,255,255)):
imgText = font.render(text, True, fcolor)
screen.blit(imgText,(x, y))
def main():
pygame.init()
screen = pygame.display.set_mode((SCREEN_WIDTH, SCREEN_HEIGHT))
pygame.display.set_caption('地雷除去')
font1 = pygame.font.Font('resources/a.TTF', SIZE *2) #スコアフォント
fwidth, fheight = font1.size('999')
red =(200,40,40)
# リソースファイルのサイズが異なるため、リソースイメージをロードします。これにより、統一されたズームプロセスが実行されます。
img0 = pygame.image.load('resources/0.bmp').convert()
img0 = pygame.transform.smoothscale(img0,(SIZE, SIZE))
img1 = pygame.image.load('resources/1.bmp').convert()
img1 = pygame.transform.smoothscale(img1,(SIZE, SIZE))
img2 = pygame.image.load('resources/2.bmp').convert()
img2 = pygame.transform.smoothscale(img2,(SIZE, SIZE))
img3 = pygame.image.load('resources/3.bmp').convert()
img3 = pygame.transform.smoothscale(img3,(SIZE, SIZE))
img4 = pygame.image.load('resources/4.bmp').convert()
img4 = pygame.transform.smoothscale(img4,(SIZE, SIZE))
img5 = pygame.image.load('resources/5.bmp').convert()
img5 = pygame.transform.smoothscale(img5,(SIZE, SIZE))
img6 = pygame.image.load('resources/6.bmp').convert()
img6 = pygame.transform.smoothscale(img6,(SIZE, SIZE))
img7 = pygame.image.load('resources/7.bmp').convert()
img7 = pygame.transform.smoothscale(img7,(SIZE, SIZE))
img8 = pygame.image.load('resources/8.bmp').convert()
img8 = pygame.transform.smoothscale(img8,(SIZE, SIZE))
img_blank = pygame.image.load('resources/blank.bmp').convert()
img_blank = pygame.transform.smoothscale(img_blank,(SIZE, SIZE))
img_flag = pygame.image.load('resources/flag.bmp').convert()
img_flag = pygame.transform.smoothscale(img_flag,(SIZE, SIZE))
img_ask = pygame.image.load('resources/ask.bmp').convert()
img_ask = pygame.transform.smoothscale(img_ask,(SIZE, SIZE))
img_mine = pygame.image.load('resources/mine.bmp').convert()
img_mine = pygame.transform.smoothscale(img_mine,(SIZE, SIZE))
img_blood = pygame.image.load('resources/blood.bmp').convert()
img_blood = pygame.transform.smoothscale(img_blood,(SIZE, SIZE))
img_error = pygame.image.load('resources/error.bmp').convert()
img_error = pygame.transform.smoothscale(img_error,(SIZE, SIZE))
face_size =int(SIZE *1.25)
img_face_fail = pygame.image.load('resources/face_fail.bmp').convert()
img_face_fail = pygame.transform.smoothscale(img_face_fail,(face_size, face_size))
img_face_normal = pygame.image.load('resources/face_normal.bmp').convert()
img_face_normal = pygame.transform.smoothscale(img_face_normal,(face_size, face_size))
img_face_success = pygame.image.load('resources/face_success.bmp').convert()
img_face_success = pygame.transform.smoothscale(img_face_success,(face_size, face_size))
face_pos_x =(SCREEN_WIDTH - face_size)// 2
face_pos_y =(SIZE *2- face_size)// 2
img_dict ={0: img0,1: img1,2: img2,3: img3,4: img4,5: img5,6: img6,7: img7,8: img8
}
bgcolor =(225,225,225) #背景色
block =MineBlock()
game_status = GameStatus.readied
start_time = None #開始時間
elapsed_time =0 #時間がかかる
while True:
# 背景色を塗りつぶす
screen.fill(bgcolor)for event in pygame.event.get():if event.type == QUIT:
sys.exit()
elif event.type == MOUSEBUTTONDOWN:
mouse_x, mouse_y = event.pos
x = mouse_x // SIZE
y = mouse_y // SIZE - 2
b1, b2, b3 = pygame.mouse.get_pressed()if game_status == GameStatus.started:
# マウスの左ボタンと右ボタンを同時に押し、すべての地雷がマークされている場合は、周囲の円を開きます
# すべての地雷がマークされていない場合、周囲の円が同時に押される効果があります
if b1 and b3:
mine = block.getmine(x, y)if mine.status == BlockStatus.opened:if not block.double_mouse_button_down(x, y):
game_status = GameStatus.over
elif event.type == MOUSEBUTTONUP:if y <0:if face_pos_x <= mouse_x <= face_pos_x + face_size \
and face_pos_y <= mouse_y <= face_pos_y + face_size:
game_status = GameStatus.readied
block =MineBlock()
start_time = time.time()
elapsed_time =0continueif game_status == GameStatus.readied:
game_status = GameStatus.started
start_time = time.time()
elapsed_time =0if game_status == GameStatus.started:
mine = block.getmine(x, y)if b1 and not b3: #マウスの左ボタン
if mine.status == BlockStatus.normal:if not block.open_mine(x, y):
game_status = GameStatus.over
elif not b1 and b3: #右クリック
if mine.status == BlockStatus.normal:
mine.status = BlockStatus.flag
elif mine.status == BlockStatus.flag:
mine.status = BlockStatus.ask
elif mine.status == BlockStatus.ask:
mine.status = BlockStatus.normal
elif b1 and b3:if mine.status == BlockStatus.double:
block.double_mouse_button_up(x, y)
flag_count =0
opened_count =0for row in block.block:for mine in row:
pos =(mine.x * SIZE,(mine.y +2)* SIZE)if mine.status == BlockStatus.opened:
screen.blit(img_dict[mine.around_mine_count], pos)
opened_count +=1
elif mine.status == BlockStatus.double:
screen.blit(img_dict[mine.around_mine_count], pos)
elif mine.status == BlockStatus.bomb:
screen.blit(img_blood, pos)
elif mine.status == BlockStatus.flag:
screen.blit(img_flag, pos)
flag_count +=1
elif mine.status == BlockStatus.ask:
screen.blit(img_ask, pos)
elif mine.status == BlockStatus.hint:
screen.blit(img0, pos)
elif game_status == GameStatus.over and mine.value:
screen.blit(img_mine, pos)
elif mine.value ==0 and mine.status == BlockStatus.flag:
screen.blit(img_error, pos)
elif mine.status == BlockStatus.normal:
screen.blit(img_blank, pos)print_text(screen, font1,30,(SIZE *2- fheight)// 2 - 2, '%02d' % (MINE_COUNT - flag_count), red)if game_status == GameStatus.started:
elapsed_time =int(time.time()- start_time)print_text(screen, font1, SCREEN_WIDTH - fwidth -30,(SIZE *2- fheight)// 2 - 2, '%03d' % elapsed_time, red)if flag_count + opened_count == BLOCK_WIDTH * BLOCK_HEIGHT:
game_status = GameStatus.win
if game_status == GameStatus.over:
screen.blit(img_face_fail,(face_pos_x, face_pos_y))
elif game_status == GameStatus.win:
screen.blit(img_face_success,(face_pos_x, face_pos_y))else:
screen.blit(img_face_normal,(face_pos_x, face_pos_y))
pygame.display.update()if __name__ =='__main__':main()
実行結果
より興味深い古典的なミニゲームの実装トピック、あなたと共有してください:
C ++クラシックゲームの概要
Pythonクラシックゲームの概要
pythontetrisゲームコレクション
JavaScriptクラシックゲームは常にプレイされています
古典的なJavaゲームの概要
JavaScriptクラシックゲームの概要
以上が本稿の内容ですので、皆様のご勉強に役立てていただければ幸いです。
Recommended Posts