目標
神経衰弱のカードゲームに挑戦
結論
2時間ほどで出来上がりました。
ポイントまとめ
- 12枚のカードを用意
- 1から6までのペアの数値を12枚のカードにランダムに振る
- カードをめくり、1枚目のカードの数値と2枚目のカードの数値を比較
- 数値が同じだったら、カード確定するため、めくることをできなくする
- 数値が異なる場合、0.4秒後にカードを裏返す
- めくれるカードがなくなったらクリア
実装
カードの配置(card.kv)
#: kivy 2.3.0
<MemoryGame>
BoxLayout:
id: content
orientation: 'vertical'
spacing: 10
pos_hint: {'center_x': 0 }
pos_hint_x: 1
ImageButtonクラスを用意
class ImageButton(ButtonBehavior, Image):
def __init__(self, source, front_source, back_source, text, **kwargs):
super().__init__(**kwargs)
# イメージパス
self.source = source
# 裏側
self.back_source = back_source
# 表側
self.font_source = front_source
# テキスト(判定用)画像比較はやりません。
self.text = text
神経衰弱ゲーム本体クラス
コンストラクタ
class MemoryGame(BoxLayout):
def __init__(self, **kwargs):
super(MemoryGame, self).__init__(**kwargs)
# 1から6までの数値を2ペア生成
self.cards = list(range(1, 7)) * 2
# シャフルする
random.shuffle(self.cards)
# 裏返し(フリップ用リスト)
self.flipped = []
# ボタン登録用リスト
self.buttons = []
# ボード作成メソッド(ゲーム画面カード作成)
self.create_board()
カード配置メソッド
def create_board(self):
for i in range(3): # 3 rows for 4 columns
inner_layout = BoxLayout(orientation='horizontal', height=300, width=300, size_hint_y=None, spacing=10)
for j in range(4): # 4 columns
index = 4 * i + j
if index < len(self.cards): # Ensure we don't go out of range
btn = ImageButton(source="./f.png",
front_source= "./f.png",
back_source=f"./{self.cards[index]}.png",text=" ")
btn.index = index
btn.bind(on_press=self.card_click)
self.buttons.append(btn)
inner_layout.add_widget(btn)
self.ids['content'].add_widget(inner_layout)
カードめくった時(カードクリック)のアルゴリズム
def card_click(self, instance):
# Check if the card is already flipped
if instance.text != " ":
return # If the card is already flipped, do nothing
if instance.source == "f.png":
instance.source = f"./{self.cards[instance.index]}.png"
# Flip the card
instance.text = str(self.cards[instance.index])
# instance.font_size = '50sp'
# Check if this is the first card flipped
if not self.flipped:
self.flipped.append(instance)
self.first_card = self.cards[instance.index]
self.first_card_index = instance.index
else:
# This is the second card flipped
self.second_card = self.cards[instance.index]
self.second_card_index = instance.index
# Check if the cards match
if self.first_card != self.second_card:
# If the cards do not match, flip them back after a delay
Clock.schedule_once(lambda dt: self.flip_back(self.first_card_index, self.second_card_index), 1)
# Reset the flipped list for the next pair
self.flipped = []
# Check if all cards are matched
if len([btn for btn in self.buttons if btn.text == " "]) == 0:
print("Clear")
カード判定
# Check if the cards match
if self.first_card != self.second_card:
# If the cards do not match, flip them back after a delay
Clock.schedule_once(lambda dt: self.flip_back(self.first_card_index, self.second_card_index), 1)
カードを裏返す処理
def flip_back(self, first_card_index, second_card_index):
self.buttons[first_card_index].text = " "
self.buttons[second_card_index].text = " "
self.buttons[first_card_index].source = './f.png'
self.buttons[second_card_index].source = './f.png'
感想
最初はいろいろ難しく考えすぎて、わけわかめ状態でしたが、整理するとそんなに難しいアルゴリズム使ったわけでもありませんでした。普段はこういうゲーム特性あまり考えていないので、やはりすこし悩みました。