忍者ブログ

PPM - Python Program Magazine

Pythonのプログラムを公開するだけのブログ

[PR]

×

[PR]上記の広告は3ヶ月以上新規記事投稿のないブログに表示されています。新しい記事を書く事で広告が消えます。

ねこばかり

天秤にねこを乗せてみた

右の天秤に隠れているねこを当てるゲームです。


遊び方

下に居るねこを左のねこタワーに乗せて「計測開始」ボタンを押すと天秤が傾きます。
重いと下がり軽いと上がるので傾き加減で予想して右側のねこを当ててください。

プログラムの説明

 このプログラムはGUIをつかっています。GUIは標準ライブラリのtkinterです。
 画像を使ったプログラムを試したくて作ってみました。
 昔VC#で作ったもののリメイクなのですが、やはりGUIはVC#の方が作りやすいですね。

プログラム

ダウンロード

nekobakari.py

from email import message
from itertools import count
import random
from re import X
from struct import pack
import tkinter as tk
from tkinter import ttk
from tkinter import messagebox
from PIL import Image, ImageTk
import data

# 答え
ans = 0
# カウンタ
counter = 0
# 入力値
neko_weight = 0

def initialize():
    '''
    初期化
    '''
    global ans
    global counter
    global neko_weight

    # 答え
    max = 2**7
    print(f"{max}")
    ans = random.randint(1, max)
    print(f"{ans}")
    # カウンタ
    counter = 0
    # 入力値
    neko_weight = 0
    return

def initialize_neko():
    '''
    ねこ画像初期化
    '''
    for index, item in enumerate(data.item_info):
        item['enable'] = True

    canvas.lift('base')
    canvas.lift('tower')
    canvas.lift('neko')
    return

def show_answerneko():
    '''
    解答表示
    '''
    for index, item in enumerate(data.item_info):
        if item['enable'] == False:
            canvas.lift(answerneko_id[index], towerId[1])
    return

def move_neko(event):
    '''
    ねこ移動
    '''
    global neko_id
    global neko_weight
    global towerneko_id
    global towerId
    # マウスカーソルの位置に一番近い図形のIDのタプルを取得
    closest_ids = canvas.find_closest(event.x, event.y)
    index = neko_id.index(closest_ids[0])
    print(f'id : {closest_ids}')
    print(f'neko_id {index}')
    data.item_info[index]['enable'] = False
    event.widget.lift(towerneko_id[index], towerId[0])
    event.widget.lift(base_id[index], neko_id[index])
    neko_weight += data.item_info[index]['weight']
    print(f'neko_weight {neko_weight}')
    return

def return_neko(event):
    '''
    ねこ移動
    '''
    global base_id
    global neko_id
    global neko_weight
    global towerneko_id
    global towerId
    # マウスカーソルの位置に一番近い図形のIDのタプルを取得
    closest_ids = canvas.find_closest(event.x, event.y)
    index = towerneko_id.index(closest_ids[0])
    print(f'id : {closest_ids}')
    print(f'towerneko_id {index}')
    data.item_info[index]['enable'] = True
    event.widget.lower(towerneko_id[index], towerId[0])
    event.widget.lift(neko_id[index], base_id[index])
    neko_weight -= data.item_info[index]['weight']
    print(f'neko_weight {neko_weight}')
    return

def move_tower(diff):
    '''
    ねこタワー移動
    '''
    canvas.move(towerId[0], 0, -diff)
    canvas.move('towerneko', 0, -diff)
    canvas.move(towerId[1], 0, diff)
    canvas.move('answerneko', 0, diff)
    return

def return_tower(diff):
    '''
    ねこタワー正位置へ
    '''
    canvas.move(towerId[0], 0, diff)
    canvas.move('towerneko', 0, diff)
    canvas.move(towerId[1], 0, -diff)
    canvas.move('answerneko', 0, -diff)
    return

def check_weight():
    '''
    計測実行
    '''
    global canvas
    global counter
    global neko_weight
    global ans
    counter += 1
    diff = ans - neko_weight
    print(f"counter={counter} neko_weight={neko_weight} answer={ans}")
    if diff == 0:
        show_answerneko()
        messagebox.showinfo('終了', f'{counter}回目です。正解!')
        initialize()
        initialize_neko()
    else:
        move_tower(diff)
        if diff > 0:
            message = '軽い'
        else:
            message = '重い'
        messagebox.showinfo('判定', f'{counter}回目です。{message}')
        return_tower(diff)
    return


#version = tk.Tcl().eval('info patchlevel')

root = tk.Tk()
root.title(f'ねこばかり')
root.geometry('480x480')
#root.geometry('640x480')

# 画像表示
neko = []
for index, fname in enumerate(data.item_info):
    if index > 0:
        data.item_info[index]['x'] = data.item_info[index-1]['x'] + data.item_info[index-1]['width'] + 4
        data.item_info[index]['y'] = data.item_info[index-1]['y'] + 6

    img = Image.open(fname['file'])
    size = [fname['width'], fname['height']] 
    img = img.resize(size=size)
    img = ImageTk.PhotoImage(img)
    neko.append(img)

tower = []
for index, fname in enumerate(data.tower_info):
    img = Image.open(fname['file'])
    img = ImageTk.PhotoImage(img)
    tower.append(img)

# Canvasの作成
canvas = tk.Canvas(bg='wheat1', width=476, height=476)
canvas.place(x=0, y=0)

base_id = []
for index, item in enumerate(data.item_info):
    base_id.append(canvas.create_rectangle( 
                        item['x'], item['y'], 
                        item['x']+item['width'], 
                        item['y']+item['height'],  
                        fill='wheat2', width = 0, tag="base"))

neko_id = []
for index, pic in enumerate(neko):
    neko_id.append(canvas.create_image(
                        data.item_info[index]['x'], 
                        data.item_info[index]['y'], 
                        image=pic, anchor=tk.NW, tag='neko'))
canvas.tag_bind('neko', '<ButtonPress>', move_neko)

towerneko_id = []
for index, pic in enumerate(neko):
    towerneko_id.append(canvas.create_image(
                        data.item_info[index]['cagex'], 
                        data.item_info[index]['cagey'], 
                        image=pic, anchor=tk.NW, tag='towerneko'))
canvas.tag_bind('towerneko', '<ButtonPress>', return_neko)

answerneko_id = []
for index, pic in enumerate(neko):
    answerneko_id.append(canvas.create_image(
                        data.item_info[index]['cagex'] + 240,
                        data.item_info[index]['cagey'], 
                        image=pic, anchor=tk.NW, tag='answerneko'))

towerId = []
for index, pic in enumerate(tower):
    towerId.append(canvas.create_image(
                        data.tower_info[index]['x'], 
                        data.tower_info[index]['y'], 
                        image=pic, anchor=tk.NW, tag='tower'))

canvas.grid(row=0, column=0, rowspan=7)

btn = tk.Button(root,
            text='計測開始',
            command=check_weight)
btn.grid(row=3,column=0)

initialize()
root.mainloop()

data.py

itemarea_left = (480-346)/2
itemarea_top = 480-64-8
item_info = [
    {
        'enable':True, 
        'weight':64,
        'file':'./app1/neko11.png', 
        'width':64, 
        'height':64, 
        'cagex':120-64-2, 
        'cagey':300-64,
        'home_x':itemarea_left, 
        'home_y':itemarea_top, 
        'x':itemarea_left, 
        'y':itemarea_top, 
    },{
        'enable':True, 
        'weight':32,
        'file':'./app1/neko21.png', 
        'width':58, 
        'height':58, 
        'cagex':120+2,    
        'cagey':300-64-58/2-4,
        'home_x':itemarea_left, 
        'home_y':itemarea_top, 
        'x':itemarea_left, 
        'y':itemarea_top, 
    },{
        'enable':True, 
        'weight':16,
        'file':'./app1/neko31.png', 
        'width':52, 
        'height':52, 
        'cagex':120-52-2, 
        'cagey':300-64-52-4,
        'home_x':itemarea_left, 
        'home_y':itemarea_top, 
        'x':itemarea_left, 
        'y':itemarea_top, 
    },{
        'enable':True, 
        'weight':8,
        'file':'./app1/neko41.png', 
        'width':46, 
        'height':46, 
        'cagex':120+2,    
        'cagey':300-64-58/2-46-4*2,
        'home_x':itemarea_left, 
        'home_y':itemarea_top, 
        'x':itemarea_left, 
        'y':itemarea_top, 
    },{
        'enable':True, 
        'weight':4,
        'file':'./app1/neko51.png', 
        'width':40, 
        'height':40, 
        'cagex':120-40-2, 
        'cagey':300-64-52-40-4*2,
        'home_x':itemarea_left, 
        'home_y':itemarea_top, 
        'x':itemarea_left, 
        'y':itemarea_top, 
    },{
        'enable':True, 
        'weight':2,
        'file':'./app1/neko61.png', 
        'width':34, 
        'height':34, 
        'cagex':120+2,    
        'cagey':300-64-58/2-46-34-4*3,
        'home_x':itemarea_left, 
        'home_y':itemarea_top, 
        'x':itemarea_left, 
        'y':itemarea_top, 
    },{
        'enable':True, 
        'weight':1,
        'file':'./app1/neko71.png', 
        'width':28, 
        'height':28, 
        'cagex':120-28-2, 
        'cagey':300-64-52-40-28-4*3,
        'home_x':itemarea_left, 
        'home_y':itemarea_top, 
        'x':itemarea_left, 
        'y':itemarea_top, 
    },
]

towerarea_left = 53
towerarea_top = 80
tower_info = [
        {
            'file':'./app1/tower01.png',
            'home_x':towerarea_left,
            'home_y':towerarea_top,
            'x':towerarea_left,
            'y':towerarea_top,
        },
        {
            'file':'./app1/tower02.png',
            'home_x':towerarea_left+240, #293,
            'home_y':towerarea_top,
            'x':towerarea_left+240,
            'y':towerarea_top,
        },
]

画像データ

拍手[0回]

PR