だぶるばいせっぷす 新館

ホワイトカラーではないブルーカラーからの視点

【プログラミング】 python奮闘記 その14 ~フレームでまとめる

この記事は、現在進行系でゼロからプログラミングを勉強している私が、勉強の一環として進展状況をアウトプットする目的で投稿しています。
その為、間違った記述や無駄な作業が結構多めとなっていますが、『それでも良いから一緒に勉強している気になりたい』という方に向けて書いていますので、予め御了承ください。
kimniy8.hatenablog.com

前回までで、ユーザーの入力値を元にボール紙の大きさを計算し、それを元に価格を割り出すというところまで書きました。
次は、ボール紙の種類をベースに、追加で紙の種類を指定して、紙の値段を算出していこうと思います。
紙の種類は値段によって4種類に分けてあり、ボール紙の大きさが4種類なので、合計、16種類の値段があることになります。

カテゴリーが4つで、大きさはボール紙の大きさを流用するという事で、ユーザーには4種類の紙のカテゴリーを選択してもらう事で、価格が出るようにしたいと思います。
『4つの中から1つを選ぶ』というのは、tkinterの中のRadiobuttonというウィジェットを使う事でできそうなので、それを使っていこうと思いうのですが…

ここで、一つ問題が。
追加するウィジェットが多くなってきて、いちいち『place』でx,yを指定してられなくなってきました。
というのも、この方式で一つ一つ指定していくと、既にあるウィジェットの間に別のウィジェットを挿入しようと思うと、それより下の位置を全て修正しなければなりません。
そんな面倒くさいことはしたくないので、もっと簡単に配置する方法を考えていきます。

ウィジェットに対して位置を指定しておく方法は、実は『place』だけではなく、その他にも2つ存在します。
それが、『pack』と『grid』です。
『pack』は、何も指定しない状態で『()』として置くと、一番上の真ん中に表示されます。
複数のウィジェットを指定なしで『pack()』で置くと、プログラム上で一番上で指定したものが中央そろえで上に表示され、次のものはその下に配置されていきます。
ただ、引数として(side=LEFT)って感じで指定すると、左詰めて順番に横方向に並べていきます。
この他にも引数として指定できるものは沢山あるようですが、これだけわかれば大丈夫でしょう。気になる人は、自分で調べてみてください。

もう一つの『grid』は、ウィジェット表計算ソフトのように規則正しく並べてくれる。
引数として『column』(x軸方向)と『row』(y軸方向)を設定する事で、置く場所を指定することが出来ます。
例えば、grid(column=1,row=5, padx=5)って書くと、2列目の6行目という感じで置いてくれる(数字は1からではなく0から始まるから)
この2つを利用すると、今までのようにx,yを指定しなくても適当に配置するだけで自動で調整してくれるのでかなり便利。

ただ、この2つだけでは、自分が思い描いたとおりの配置は難しい…
という事で、別の機能をもう一つ使うことにします。それが、『Frame』です。
『Frame』は、境界線のようなもので、このフレイムを表示カテゴリーの数だけ作ってまとめておけば、レイアウトがより簡単に調整できるようになります。
例えるなら、『Frame』自体は空箱のようなもので、そこに、4つある入力欄をまとめて入れておく。
そして、プログラム上で『Frame』を配置すれば、好きな場所に入力欄をまとめたものを配置できる。

これを、さっきの『pack』や『grid』と組み合わせることで、自分の好きなレイアウトを簡単に実現することが出来て、その上、配置換えの手間も楽になります。
という事で早速、『Frame』を作っていきましょう。

現段階では、『見出し部分』『入力欄』『見積価格』『詳細内訳』があり、これに加えて『ラジオボタン』を追加したいので、フレームを5個作ります。
作り方は簡単で、こんな感じで記述します。

frame1 = tkinter.Frame(root)

分かりやすいように、変数に『frame1』として、tkinterのFrameを呼び出し、引数に(root)を当てます。
引数の『root』は、メインとなるWindowの名前でしたよね。そのWindow上にフレームを配置するという意味で、引数を当てています。
これを1~5まで作ります。

各場所は、分かりやすいように、それぞれのフレームに入れる要素の一番上に書いておけばいいと思います。
フレームを作ったら、それぞれのウィジェットをフレームに入れていくわけですが、入れ方というのは、それぞれのウィジェットの引数に、入れたいフレームの変数を入れるだけです。
例えばこんな感じ。

# テキスト表示
frame1 = tkinter.Frame(root)
heading = tkinter.Label(frame1, text="お見積り")
heading.pack()

ウィジェットの引数は、『表示させる場所』の受付を行っているので、その場所にそのまま書き込むだけです。
ちなみに何も書かなければ、『root』に表示されます。 デフォルト値としてメインウィンドウが指定してあるんでしょうね。

このフレームですが、フレーム自体もプログラムで位置を指定して設置するという指示をしないと、設置されません。
その為、画面表示の最後の方に、このように記述して配置を行います。

# Frame配置
frame1.pack()
frame3.pack()
frame2.pack()
frame5.pack()
frame4.pack()

1~6のフレームを作ったからと言って、1から順番に並べなければならないということはありません。
好きな順番で並べても大丈夫です。
今回は試していませんが、Frameの中にFrameを入れることも可能でしょうから、フレーム配置が多くなって配置が面倒になる場合などは、更に大きなFrameで括って整理するのも良いかもしれません。

という事で今回は、ウィジェットの位置を指定して配置する『pack』『grid』『Frame』について書いていきました。
次回は、ラジオボタンの設置について書いていこうと思います。

【Podcast #だぶるばいせっぷす 原稿 】第30回【ヒッピー】ティモシー・リアリー(6) ~ヒューマン・ビーイン

この投稿は、私が配信している Podcast番組『だぶるばいせっぷす ~思想と哲学史』で使用した原稿です。
放送内容は、私が理解した事を元に行っています。ご了承ください。
goo.gl

youtubeでも音声を公開しています。興味の有る方は、チャンネル登録お願い致します。
www.youtube.com

youtu.be

前回までで、長く続いてきたヒッピー回が終了しましたので、今回から、新しいテーマに移っていこうと思います。
今回から取り扱うテーマは、もう一度基本に戻って、『ギリシャ哲学』を最初から勉強していこうと思います。

最初に言っておきますと、このコンテンツ全体について言えることなのですが、このコンテンツは、私自身が勉強して理解した範囲の事を話しているに過ぎません。
現在進行系で勉強しながらのコンテンツ制作なので、読んでいない本も知らない情報も多く、中には、私自身が誤解して理解していることも多数あると思います。
もし気になった点や、興味のある部分が見つかった際は、自分自身で情報を集めて勉強することをおすすめします。

話を戻すと、このコンテンツでは、第2回からギリシャ哲学のソクラテスプラトンアリストテレスをテーマに取り上げましたが、その時は、もの凄く簡単にしか触れていませんでした。
その理由としましては、このコンテンツの立ち上げ当初は、文字で書いていたブログの延長としてやって行くつもりだったというのが大きいです。
文字で書くだけだと伝わらないようなニュアンスを、音声で読み上げることで伝えようとして始めたので、テーマも哲学や思想に関わるものだけではなく、日々思った事を話すようなコンテンツを想定して立ち上げたのですが…

アリストテレスをテーマに取り上げたくらいからですかね。
アリストテレスの主張を簡単に伝えることは難しいなと思い始め、もっと詳しく丁寧に説明しようと思って、哲学や思想に限定したコンテンツに方向転換したんです。
その為、それ以前のソクラテスプラトンについては、本当に簡単に触れただけ…
というより、私自身が勉強不足で知らない事が多過ぎた為に、簡単にしか紹介できませんでした。

今回からの回は、その部分について、私自身も改めて勉強しながら、作っていく回となります。
という事で今回は、哲学の祖とも呼ばれているソクラテス以前の話からしていこうと思います。

このコンテンツの第2回では、元々は世界のあり方は、神様が登場する神話などで説明していたという話をしました。
元々は小さな人々の集団が、それぞれの文化の中で神話を作り出していく。そして、時間の経過と共に共同体の人数が大きくなっていって、住む土地の広さが拡大していく。
そこら中に点在していた小さな集団が、同じように住む地域を拡大していくことで、違った神話を持つもの同士がふれあって、そこで違った価値観に出会う事で、相対主義が生まれたという話をしたんですが…

まず、その話は一旦、忘れてください。
完全に間違った話といったわけでは無いと思いますが、全体の話を大雑把に理解する為の話になるので、一旦忘れて、まっさらな気持ちで聴いてください。

前に説明した際には、物事を神話によって説明していたと言いましたが、果たして本当にそうなのかという事について考えていきます。
人間が意識を持って、自分自身の頭で考えるという行動を取れるようになって、一番最初に考え出すことって、神様の存在なんでしょうか?

私達のように、現代に生まれてきた人間については、小さな頃から『神様』という存在について、親から教えられます。
これは、神様や仏様、お天道さま、なんでも良いのですが、躾の一環として、悪いことをした際などに、同じことを繰り返さないようにと、人間以外の上位の存在から『罰が当てられる』と刷り込まれます。
こうして育った人間が、何らかの超常的な減少を目にしたときや、奇跡のような事が重なった際に、『神』といった概念が頭を過る事は不思議でもなんでもないのですが…

なんの刷り込みもなく、前提とした知識もなく、ただ、大自然の前に放り出された、意識を持った人間が、目の前に起こっていることを理解する為に、神といった存在を持ち出すのでしょうか?
おそらく、持ち出さないでしょう。 仮に、いきなり神という存在を定義して、その神を中心とした神話を作り出せる人間がいたとしたら、その人間は天才です。

大部分の普通の人間は、太陽が登ってくるのを目にして『神が最初に『光りあれ!』と言ったから太陽が出来て、その後6日間で世界を作り上げた!』なんて思いません。
普通に、眩しい存在が定期的に光を照らすとしか思いません。
山火事などが起こって火を目撃したとしても、『火の神が!』なんて思わずに、単純に熱いと思うでしょうし、夜でも明るいなとしか思わないでしょう。

『神』という存在は、その存在そのものが一種の発明で、その発明品である『神』という概念が無かった原始の世界では、あるがままをそのまま受け入れるという事しか行われていなかったと考えるのが自然でしょう。
つまり、あるがままをそのまま観察して、経験として蓄積していく、科学という分野が最初に生まれたと考える方が自然という事です。

太陽と呼ばれる、光り輝く丸い物体が一定期間ごとに登る事で、昼という状態が生まれる。
それが沈んで暗くなると、その変わりに、月や星々と言った別の物体が夜空に浮かび上がる。
適当に散りばめられていると思いこんでいた星々は、よくよく観察すると、その配置は毎回同じもので、時間と共に場所を移動していく。

パターン認識によって、大自然の中に法則性を見つけ出していくという事が最初に行われ、その知識は時間の経過とともに蓄えられていったんでしょう。
知識というのは、ある一定以上の蓄積によって、演繹的に発展していきます。
演繹とは、推測の様なものと捉えても良いと思います。
例えば数学の場合、足し算・引き算・掛け算・割り算を覚えると、頭の良い人であれば、そこから考えを応用して発展させて、方程式という概念を生み出せます。

このようにして、最初は科学というものが発展していきます。
ちなみに、この科学という言葉ですが、昔は哲学と呼ばれていました。 哲学は『考える事』全般を指す言葉だったので、全ての学問は哲学と呼ばれていたようです。

この哲学が発展していき、古代エジプトでは、天体の動きから暦を発明して、ナイル川の反乱を予測する事に使われるようになりました。
また、ナイル川が反乱することで周囲の田畑が水浸しになり、土地の境界線も消えてしまう為に、土地の大きさを正確に測る計算方法も開発されます。
古代ギリシャ人は、古代エジプト人の平面の計測方法を学んでギリシャに持ち帰り、それを応用する事で、四角形以外の面積も測れることを発見したようです。

この計算方法の応用・発展によってギリシャの数学は飛躍的に進歩したようです。
では、神という存在や神話は、どのようにして生まれたのでしょか。

これは私自身の推測も多く含まれますが、天文学の研究の派生として生まれていったんだと思います。
先程も言いましたが、夜空に輝く星々の配置というのは決まっていて、それを覚える事で、季節や方角と言った情報を知ることが出来ます。
これをパターン認識によって法則化したものが天文学の起源なんでしょうけれども、無数にある星の配置をそのまま覚える事って、かなり難しいですよね。

人は、無機質に羅列するものを覚える場合は、どうするでしょう。
元素記号でも、ルートの計算でも、歴史の年号でもそうですが、何のつながりもない記号や数字を覚える場合は、単純に丸暗記するよりも、語呂合わせ等によって一つのストーリーにしてしまう方が覚えやすいです。
Hの後にHe、Hが水素で、次がヘリウムと覚えて行くよりも、『すいへーりーべーぼくのふね』と覚える方が楽ですし、順番も間違いにくいですよね。

星座の場合も同じで、単純に星の配置を丸暗記するというのは効率も悪いし、間違いも起こりやすい。
それよりも、数個の星を1グループにして、それに絵を当てはめていって星座にして、その星座を役者に見立てて物語を展開させれば、物語を覚えるだけで、星の配置を覚えられる上に、間違いが起こりにくい。
こうして生み出された物語には、当然のように、パターン認識によって蓄えられた現実世界で起こる法則も、組み込まれていったんでしょう。
例えば、特定の星座が特定の位置に来る頃にナイル川が反乱するので、その星座の行動をナイル川の反乱と結びつけようといった具合にですね。
ナイル川の反乱という現実世界の出来事を物語に投影するわけですから、その星座が持つ役者としての性格も、そのように設定されて作られていきます。

こうして作られた物語は、印刷技術がまだない古代では、演劇などを通して、一般に娯楽として提供されて居たのでしょうし、親が子に語り継ぐなどして、代々と受け継がれていったんでしょう。
そして、代を重ねるごとに、科学や学問としての要素が徐々に削ぎ落とされていって、物語そのものに焦点が当たるようになり、最終的には神話として語り継がれていったんだと思います。
このようにして、一度、神話という概念が生まれると、科学と同じように、応用されて発展していきます。

神話そのものがメインになり、現実世界にも登場人物を祀る神殿などが作られるようになっていきます。
神殿が作られて、そこに聖地巡礼をしに来る観光客などが訪れるようになると、大都市と聖地を結ぶ道に飲食店や土産物店などが出来るようになって、経済的にも潤うようになってくる事もあるでしょう。
経済的に利益が得られるのであれば、辺鄙な場所にある地域なんかは、観光客を誘致するために、自分達の地域ゆかりの登場人物を神話に登場させて、観光収入を得ようと頑張る地域も出てくるでしょう。

また、神話は経済面だけでなく、人々のコミュニケーションも円滑にします。
今の私達もそうですが、日々、顔を合わすだけで、特に繋がりのない人間であったり、繋がりはあってコミュニケーションを取りたいけれども、何を話して良いのかわからないと言ったことはよくありますよね。
でも、そういった際でも、共通の話題があれば、話しかける際のハードルは一気に下がったりしますよね。

神話を共同体全体で共有するということは、共同体の中で価値観を共有するのに役立ちますし、コミュニケーションを円滑に進める為にも効率的です。

この神話の成り立ちがピンとこない場合は、この出来事を現代の出来事に当てはめてみると分かりやすいかもしれません。
例えば、数年前に『ゆるキャラブーム』というものがありましたが、あの時は、いろんな自治体がキャラクターを一斉に作って、地域を盛り上げようとしましたよね。

地域の宣伝としては、アニメなんかも貢献していたりします。
特定の地域を舞台としたアニメ作品が公開されると、そのアニメの舞台を聖地として、聖地巡礼などがファンの間で行われます。
名シーンに使われた場所などを特定し、その場所に行って同じ様なシチュエーションで写真を撮ったりといった行動を行う人達も少なからず存在します。
そういう人たちが増えていけば、一時的には、その地域の経済も潤うこともあるでしょう。

そして、2018年の今、現在進行形で作られている、世界レベルで有名な神話といえば、マーベル・シネマティック・ユニバースでしょう。
アイアンマンから始まったアメコミ映画は、その後、新たに誕生した数々のヒーローが登場するようになり、アベンジャーズシリーズではそれぞれのヒーローが共演します。
ここで描かれる物語は、単純な勧善懲悪のストーリーではなく、それぞれの立場の違う人達に寄り添った物語となっています。

最初のアイアンマンこそ、事業家として成功したチョイ悪オヤジが、自分のやってきた事を反省することで、正義に目覚めたヒーローになるという分かりやすいストーリーとなっていますが…
それ以降、ストーリーが派生してきて新たに登場するキャラクターたちは、アイアンマンとは別の正義を掲げて戦っていたりします。
そして、それぞれの観点の元に出来上がった価値観が衝突したりもします。

マーベル・シネマティック・ユニバースに登場するキャラクターは、敵も味方も含めて、神話に登場する神レベルの能力を持っているので…
そんなキャラクター達が、全力を出してそれぞれの正義の元に戦うわけですから、無力な人類は、ただただ、逃げ惑うことしか出来ません。
この構成というのは、昔に生み出された神話そのものですよね。

強大な力を持ったキャラクターが大量に生み出されて、そのキャラクターはそれぞれの信じる正義を遂行する為に行動します。
映画を見た人たちは、純粋な人であっても、捻くれた人であっても、サイコパスだったとしても、登場人物の誰かに感情移入できるように作られています。
映画の中で取り上げられる問題は、世の中で実際に起こりそうな問題を、より派手に、ドラマティックにした内容で、その問題に対して、それぞれの正義を持つキャラクターが、自分の信念の元に行動をしていく。

この様な、映画の中で語られる神話の物語を共有している人の間では、会話をする際のハードルがかなり引き下げられますよね。
だって、合計で百時間を超えるような時間を一つのシリーズに注ぎ込んでいる者同士なわけですから、その作品を観た感想を語り合うだけで、一気に打ち解けることが出来ます。
また、その登場人物の誰を支持するのかによって、その人の性格を短時間で深く知る事も可能になります。

これは、古代ギリシャで生み出された神話にも当てはまります。
星座から派生して生み出された神々というキャラクターは、ナイルの反乱や山火事、噴火など、人には不可能な天変地異を起こすことが可能だったりします。
神々には、それぞれに生い立ちが合って、それぞれの観点からみた正義を持っていて、そのように振る舞います。

これは、マーベル・シネマティック・ユニバースの構造と同じですよね。
また、神話という物語が発明されて、それが発展していって膨張していくと、神話を発展させる為のキャラ付けというのも生まれてきます。
ギリシャ神話でゼウスという最高神がやたらと浮気をして子供を作りまくるというキャラクターだったりするんですが、これも、物語としてのキャラ付けだったんでしょう。

既にある程度完成している神話に、新キャラを生み出して加えようと思うと、単独でいきなり出すよりも、何らかの有名キャラクターと紐づけて出す方が覚えてもらいやすいです。
有名なキャラクターであればある程、覚えてもらいやすくなる為、ゼウスの親族として登場させるという方法が多用されたんでしょう。
そして、それを正当化するように、ゼウスの性格も、そこら中で子供を作るキャラクターへと変貌していったんでしょう。

夫が浮気ばかりをすると、妻の性格もいじらざるを得ません。
物語というのは感情移入出来なければ面白さは半減してしまいますから、浮気をしまくるゼウスの妻のヘラは、嫉妬深いキャラクター像へと固定されていきます。
浮気グセがあるゼウスとヘラとの喧嘩は、現実世界で起こりうる何らかの不幸とリンクされて、神話というのは、より、具体性を増していき、物語として膨らんでいったのでしょう

これは、現代の神話であるマーベル・シネマティック・ユニバースでも同じなんでしょう。
例えば、スパイダーマンですが、スパイダーマンは単体でも有名なキャラクターですが、改めて、マーベル・シネマティック・ユニバースという神話に組み込もうと思うと、何らかのキャラクターと紐付けなければ孤立してしまいます。
結果としてMCUでは、アイアンマンがスポンサーになって、アベンジャーズ内での父親の代わりという役を演じることで、スパイダーマンが神話の中に自然と溶け込めるような環境が作られています。

また、世界大戦等の大きな事件も、その影にはヒーローに匹敵するような力を持ったヴィランが暗躍していたりしますし、そのヴィランとヒーローが対峙して対話することで、物語や歴史は進んでいきます。
今の時代は、この様なエンターテイメントがそのまま神話として定着することもないでしょうし、世界大戦の裏側にはヴィランが居たなんて本気で信じる人もあまり居ないとは思いますけれども…
今のように科学も教育も進んでおらず、情報の伝達手段も限られている古代では、このようにして作られていった神話が一般層を中心に鵜呑みにされていったんでしょう。

【ゲーム感想】ゴッド・オブ・ウォー (God of War) 【最高難易度】

今日は、少し前に『約束された神ゲー』という触れ込みで話題となった、『ゴッド・オブ・ウォー (God of War)』のプレイ感想となります。



      

ゴッド・オブ・ウォーといえば、PS2時代から続くシリーズで、全世代・全々世代のハードで出していたのにもかかわらず、超絶グラフィックで世間を驚かせていたアクションゲーム。
舞台となっているのはギリシャ神話で、元々はスパルタの戦士だったクレイトスが神となって…といった感じの話。
私自身は、『3』しかプレイしていないので、1と2の詳しい話は知らないのですが、ストーリー云々よりも、圧倒的なパワーで敵を蹂躙していく爽快なアクションが売りって感じのゲームだったように思えます。

そんなゴッド・オブ・ウォーが、ナンバリングをリセットして新たに発売したのが、今回、紹介する『ゴッド・オブ・ウォー』です。

タイトルを新たに一から作るということだからか、ゲームのシステムそのものも変わり、ダークソウル的な感じのアクションに変化。
カメラは基本的には主人公のクレイトスを斜め後ろから追いかける感じで固定されていて、自分もその現場にいるような感覚が味わえるようになっています。
また、今までの作品が基本的にクレイトス1人で動いていたのに対し、今回はアトレウスという自身の子供が一緒に行動する為、謎解きやパズル要素は、アンチャーテッドシリーズのようになっていたりもします。

プレイした感想としては、グラフィックは相変わらず、エグいくらいキレイ。。
ただ、グラフィックにかなりこだわり過ぎて、ゲームを動かすのに物凄いパワーがいるからなのでしょうか…
私はPS4Proでプレイしていたのですが、ファンが掃除機のような大きな音を建ててフル回転し続けていました。

その代わりといってはなんですが、エグいぐらいのグラフィックにもかかわらず、ロード時間がなくノーカットでゲームが進んでいくのは、純粋に凄いと思いました。
普通のゲームであれば、イベントや新マップと、事あるごとにロードが挟まってゲームが中断されるところですが、このゲームにはそれが無く、没入感が削がれること無くゲームが楽しめる作りになっています。

ストーリーは、これからやる方もいらっしゃると思うので、あまりネタバレにならないように書いていこうと思いますが、父と子の物語って感じで、結構楽しめました。
私は結婚もしておらず、当然のように子供もいないわけですが、仮に子供がいたら、こんな感じの感情を抱くのかなと思ったり。
若い世代がやれば、子供であるアトレウスの方に感情移入が出来ますし、世代を選ばずにストーリーを楽しめるという意味では、よく出来た作品だと思いました。
とはいっても、表現にグロがある為、ソフトの方で年齢制限がされているので、本当の子供は出来なかったりするんですけどね。

こんな感じで、客観的にゲームを振り返ってみると、『約束された神ゲー』の名に恥じない、よく出来たゲームだと思いましたが…

個人的には、手放しでベタ褒め出来るゲームなのかというと、そうとは言えないとも思いました。
という事で、ここからは個人的なプレイ感想を書いていこうと思います。

このゲームですが、買おうかどうかを迷っていたところ、Twitterで背中を押してくださる方がいて、その勧めもあって購入したんですよね。
その際に、『ゲームに慣れた方の場合は、難易度 『God of War』でやると良いですよ!と勧められたんですよ。

素直な私は、その助言をそのまま受け入れて、初プレイで最高難易度である『God of War』でプレイしたわけですが…
これが、本当に辛い。というか、バランス悪すぎ。
(以降、ちょっとした悪口になるわけですが、一応言っておきますと、クリアーはしましたからね。)
f:id:kimniy8:20180615205909j:plain
どれほど辛いのかというと、チュートリアルと思われる一番最初の敵が倒せない。
最初の先頭は、合計で10体程度のドラウグルを倒すというものだったと思いますが、これを全て倒すのが難しすぎる。
というのも、こちらは3回攻撃を食らうとゲームオーバーな訳ですが、チュートリアルで出てくるドラウグルは20発程度斬りつけないと倒すことが出来ない。

3体同時で出てこられたりすると、1体を仕留める前に他の敵が攻撃してきたりする。その為、絶えず敵を1方向にまとめるような操作を要求される。
これだけなら、まだ、マシ。 最高難易度で辛いのは、敵に傷を負わせた状態で一定時間放置すると、敵が力を溜めるモーションを行い、2秒程で覚醒状態に!
覚醒状態になると目が光り、体力が回復した上にレベルが1個上がり、スーパーアーマーが付与されます。。。

このゲームでは、敵と自キャラの相対レベルによって、ダメージ計算などがされているようで…
こっちは初めての戦闘でレベル1なのに対し、敵は覚醒でレベル2になるので、レベル差2倍。 ただでさえ硬い敵が、倍ほど固くなった上にスーパーアーマーで怯みなしですから、難しいというよりも理不尽。
一番最初の敵で困難ですから、かなりストレスが溜まる…

でもまぁ、根気強くやって慣れていけば、対処できそうな感じではあるので、何とか頑張ってプレイしていったわけですが…
チュートリアルのレベルがどんどん上っていく。。
まぁ、先に進めば進むほどに難しくなるのは頷けますが、とにかく、新しい敵や新たなアクションを覚えている段階のチュートリアルで、ヤバイぐらいの難易度になっていきます。

一番弱いはずのドラウグルは、一度に5体ぐらいが襲いかかってくるようになり、その上、飛び道具を撃つ敵も出現。
その上、ドラウグルの3倍ぐらい打たれ強くて、2倍ぐらい火力が高いヘビードラウグルなんかも乱入してくる。
ひどい場合には、レヴェナントと言われる、遠距離攻撃をしてくる上に近距離攻撃の火力も高く、こちらが攻撃してもテレポートで攻撃を避ける敵まで出てくる。。

一応言っておきますと、まだこの時点でチュートリアルですからね。
正直、チュートリアルの時点でかなり心が折れ、ゲームオーバーのなり過ぎて、心が完全に死んで、死んだ魚の様な目で無心でボタンを押し続ける。
半ば投げやりで、ゲームをしているのにストレスが溜まっていく状態まで追い込まれました。

ここまで読まれた方は、『最高難易度』なんて選ぶからでしょ。とツッコまれるでしょう。
確かのそのとおりです。 イージー・ノーマル・ハード・ゴッド・オブ・ウォーと選べる状態で最高難易度を選んだのは私ですし、その最高難易度が難しいと感じるなら、私のプレイレベルが低いだけ。
そう思いますよね。 私もそう思っていました。 中盤の後半まで進めるまでは。

最初の方でも、『バランス悪すぎ』と書きましたが、このゲーム、中盤以降、2回程、一気に難易度が下がるんです。
一つは、アトレウスが魔法の矢(雷)を覚えたタイミングで、もう一つが、主人公のクレイトスが2つ目の武器を手に入れた時。
この2つのタイミングで一気に難易度が下がる為、後半になるに連れて簡単になっていきます。

つまり、どういうことかというと、最高難易度でプレイした場合、一番難しいのはチュートリアルという事です。
逆にいえば、チュートリアルがクリアーできるのであれば、最後までクリアーするのは簡単だという事です。
厳密にいえば、ダークエルフとその王。それと、『マグニ』『モージ』という兄弟キャラクターがボスとして中盤に出てくるのですが、チュートリアル後の難関は、ダークエルフ関連とこの兄弟ぐらいで、他は手こずらずにクリアーできます。

ついでに言っておくと、この兄弟戦もバランス調整が最悪です。
2体動時に襲いかかってくるわけですが、最終形態では画面の7割ぐらいをカバーする上に1発喰らえば体力が9割減る合体攻撃を頻繁にしてきます。
この攻撃はガード不能なので、モーションを観た瞬間に範囲外に走って逃げなければその時点でゲームオーバー。
ちなみ、画面の7割ぐらいをカバーする範囲攻撃なので、マップの中心ぐらいで出されると回避が間に合わずに喰らいます。

ここで、『合体攻撃であれば、なんとかして1体を倒せば後は楽だよね。』って思うじゃないですか。。
そこが、バランス調整が悪い部分なんですが、その戦略はイージー~ハードまでなら片方ずつ倒すというのは有効な手段っぽいんですが、最高難易度で1体を先に倒すと、数秒のインターバルを開けて体力全回復するんです…
つまり、最高難易度でクリアーしようとする場合、同時撃破が条件になってるんです。 無茶苦茶です。
片一方が鎧着た上で盾持ちで、もう一方は裸で両手武器。 全面に出てくるのは裸の方なので、どうしても裸の兄貴のライフが先に削れてしまうわけですが、先に倒しちゃうと体力全回復するので、体力を調整しながら攻撃し続けなければなりません。
1発食らったら終わりの範囲攻撃を避けながら! コイツラを倒すだけで、数時間もかかってしまいました。

これが終わると、しばらくして2個めの武器が手に入るわけですが、此処から先はイージーモード。
攻撃ボタンを連打してるだけで敵が勝手に死んでいくので、今までの苦労が何だったのかというほどにスムーズに進んでいきます。
ラスボスも同様で、正直、チュートリアルのドラウグルの方が強い。

何度も書きますが、バランスが悪すぎるんですよ。

タイミングよくパリィを決めても優位になるわけでもなく、致命傷を与えられるわけでもない。
背後をとっても、スタン値が溜まりやすいぐらいで、一方的に有利になるわけでもなく、相変わらずザコ敵に数十発の攻撃を当て続けなければならない。
『最高難易度では死にゲーの雰囲気が味わえますよ!』って触れ込みでしたが、このゲームをやって改めて、『BLOOD BORN』の調整の素晴らしさが理解できました。

…とまぁ、最後の方はかなり愚痴っぽくなったわけですが、雰囲気やストーリーを味わうのが目的であれば、ノーマルでやればストレスも溜まること無く、楽しめる作品だと思います。
グラフィックなどは現時点でのPS4で最高峰だと思うので、それを観るだけでも価値のある作品だと思います。
      

【プログラミング】 python奮闘記 その13 ~さらなる条件分枝

この記事は、現在進行系でゼロからプログラミングを勉強している私が、勉強の一環として進展状況をアウトプットする目的で投稿しています。
その為、間違った記述や無駄な作業が結構多めとなっていますが、『それでも良いから一緒に勉強している気になりたい』という方に向けて書いていますので、予め御了承ください。
前回は、if文を追加することによって、入力された数値を元に大きさのカテゴリー分けをするところまで進みました。
今回は、その条件をもう少し細かく設定していきます。
kimniy8.hatenablog.com
前回のカテゴリー分けでは、大きく4つのカテゴリーに分けたわけですが、それでは、いろいろと問題も出てきます。
というのも、前回の分け方では、どんな小さな数値を入力したとしても、『cardboard_a』にカテゴライズされてしまいます。
しかし実際には、作るのが無理な大きさのものも存在します。
例えば、高さや幅が1mmしかないとかね。

という事で今回は、作るのが無理な大きさを指定された場合は、見積自体を断るという条件を設定していきます。
まずは、NG項目を考えていきます。

・高さが100mmを超える、または20mmを下回る
・幅または長さの1辺の長さが70mmを下回る
・必要なボール紙の大きさが、600mm且つ450mm以上の場合
思いつくのはこんな感じなので、この条件に当てはまった場合は、見積価格の場所に『作れません』といった内容のコメントを表示させたい。
ということで取り敢えず、価格表示欄を作るところから始めてみます。

これは、ボール紙の大きさなどを表示させたのと同じ手法で出来そうなので、簡単ですね。
ボタン表示と内訳表示の間ぐらいに、こんな感じで記述します。

# 答え表示
answer = tkinter.Label(text="一箱あたりの価格")
answer.place(x=10, y=80)

準備が整ったので、次に、受付できない条件を書いていこうと思います。『条件』という所から推測出来る通り、これも、if文を使えばできそうですね。
実行のタイミングとしては、前回に書いた、詳細表示やカテゴリー分けよりも前のタイミングでif文が発動しないと駄目なので、それらよりも前に記述します。
関数内に書くため、インデントに注意して書き込んでいきます。

    # NG要項
    if b_hi > 100 or b_hi < 20 or b_wid < 70 or b_long < 70 \
       or not(max(b_tate, b_yoko) <= 600 or min(b_tate, b_yoko) <= 450):
        answer["text"] = "申し訳ございませんが、弊社の設備では製造できません"

if以降に、不等号と『or』『and』『not』を使用して、NG項目を設定しています。
『b_hi > 100』というのは、高さが100mmを超えた場合という意味ですね。
それらのNG項目を『or』で繋げています。 『or』は、どれかに当てはまった際は『if』を実行するという事になる為、逆にいえば、どれか1個の条件に当てはまるだけで、NG項目として認識されます。
途中で挟まっている『\』マークは、改行の意味です
プログラムでは、改行そのものに意味が出てくるようで、改行マークを入れなければ一つの文として認識してもらえません。
その為、長くなりそうな場合は『\』マークを入れて、改行しているということをコンピューターに伝えましょう。 

これでNG項目の設定は完了です。後は、NG項目に入っていない場合は関数による計算で処理が続くようにするだけですが、これは簡単で、前回に書いた文の直ぐ上に『else:』と書くだけです。
こうすることで、NG項目に抵触しない場合だけ、前回書いたプログラムが動き始めます。
当然ですが、前回に書いた処理は『else:』の下に入るので、else:以降の文は全部、インデントとして字下げしなければなりません。

複数行をまとめて字下げする場合は、マウスで範囲を指定した状態で『tab key』を押すと出来ます。

良い感じで進んできましたね。
ただ、今の状態では、蓋の高さというものが変更できません。
浅い蓋や深い蓋など、お客さんにとっては選べたほうが便利ですよね。
という事で、その分を追記してみました。

#テキストボックス
box_height_f = tkinter.Entry(width=10, bd=4)
box_height_f.place(x=210, y=80)
# ボール紙の大きさ
b_hi_f = int(box_height_f.get()) # 箱の蓋の高さ

テキストボックス欄に、Entryを追加し、ボール紙の大きさの欄で、Entryから値をとってきています。
ただ、お客さんによっては、『蓋の深さとか決めたくないから、適当に』という方もいらっしゃるかもしれないので、デフォルト値として、『身』の深さの3分の2の高さを入れてみたい。。
という事で、先程の『# 箱の蓋の高さ』の下に、何となくこんな文を追加してみましたが…

    if b_hi_f is "":
        b_hi_f = int(float(b_hi)*0.67)

見事に動かず。
エントリーが空欄の場合に、蓋の高さ(b_hi)の高さに0.67を掛けたものを整数値にして、『b_hi_f』に代入するってイメージで書いたのですが、間違ってたようです。
その後、2日ぐらい考えたのですが全く先に進まないので、この機能は後回しということにしようと思います。

次は、ボール紙の値段を元に、紙の値段を表示させてみようと思いますが、それはまた次回にしようと思います。
kimniy8.hatenablog.com

【プログラミング】 python奮闘記 その12 ~ifでカテゴリー分けをする

この記事は、現在進行系でゼロからプログラミングを勉強している私が、勉強の一環として進展状況をアウトプットする目的で投稿しています。
その為、間違った記述や無駄な作業が結構多めとなっていますが、『それでも良いから一緒に勉強している気になりたい』という方に向けて書いていますので、予め御了承ください。
前回は、ボタンを押すことで関数が実行されるという状態にして、その上で、実行される関数を作り始めました。
最終的には、ボタンを押すと見積価格が出るようにするところを目指します。
kimniy8.hatenablog.com
見積ソフトは、極論をいえば見積価格さえ出れば良いのですが、ボタンを押すことで単純に答えだけが出力されるよりも、材料の単価などが出てくれた方が、見積に説得力があります。
どちらにしても、計算の過程で材料単価は出てくることになるので、見積の詳細表示として、単価を表示させるようにしてみましょう。
念の為にもう一度、ボール紙のカテゴリーや単価の表を貼り付けておきますね。
f:id:kimniy8:20180604224543j:plain
まずは、ボール紙のカテゴリー分けです。
関数内で行った『ボール紙の大きさ』の変数の定義の直ぐ下辺りに、こんな感じで書いていきます。

    # 身のボール紙の種類
    cardboard_a = max(b_tate, b_yoko) <= 232 and min(b_tate, b_yoko) <= 222
    cardboard_b = max(b_tate, b_yoko) <= 354 and min(b_tate, b_yoko) <= 323
    cardboard_c = max(b_tate, b_yoko) <= 505 and min(b_tate, b_yoko) <= 354
    cardboard_d = max(b_tate, b_yoko) <= 748 and min(b_tate, b_yoko) <= 505

    # 蓋のボール紙の種類
    cardboard_a_f = max(b_tate_f, b_yoko_f) <= 232 and min(b_tate_f, b_yoko_f) <= 222
    cardboard_b_f = max(b_tate_f, b_yoko_f) <= 354 and min(b_tate_f, b_yoko_f) <= 323
    cardboard_c_f = max(b_tate_f, b_yoko_f) <= 505 and min(b_tate_f, b_yoko_f) <= 354
    cardboard_d_f = max(b_tate_f, b_yoko_f) <= 748 and min(b_tate_f, b_yoko_f) <= 505

変数名は、ボール紙の英語名となる『cardboard』にする事にし、それぞれのカテゴリーにa~dを付けています。
『max』とか『min』といったよく分からない物が出てきましたので、解説しましょう。
『max』と『min』は、何となく想像できるかも知れませんが、数値を比較して条件にあったものだけを抽出してくれる関数です。
『max』は、引数で渡された数字の中から大きいものを取り出す関数で『min』はその逆で、引数の中から小さい方を取り出してくれる関数です。

前にも出てきた『and』を使い、両方の条件に当てはまるものだけを変数としています。
具体的に、cardboard_aの条件を見た場合、縦横の大きい方の数値が232以下で『且つ(and)』縦横の大きさの小さい方が222以下の場合はcardboard_aに当てはまると行った感じで設定しています。
これと同じ様な方法で、a~dを設定しています。

ただ、この方法で書くと、『cardboard_d』は、全ての条件が満たされている状態になるので、何でもかんでも『cardboard_d』になってしまう可能性もあるんですけどね。
まぁ、プログラムは上から順番に読んでいくそうなので、一番条件がタイトな『_a』を一番最初に記載しているので、期待通りのカテゴリー分けをしてくれるとは思いますが…
若干不安は残りますが、今回は初めて作るプログラムという事で、テスト的な意味合いも大きいので、このままにしておこうと思います。

これで、カテゴリー分けの変数の定義は出来たわけですが、これだけでは、しっかりとカテゴリー分けが出来ているかどうかを確認できませんので、何らかの形で出力が出来るようにします。
まず、表示させるための場所を確保しましょう。
プログラムの『# 内訳表示』の部分に、以下の文を書き込みます。

cardboard_price = tkinter.Label(text="【身】ボール紙の価格")
cardboard_price.place(x=10, y=170)

cardboard_price_f = tkinter.Label(text="【蓋】ボール紙の価格")
cardboard_price_f.place(x=10, y=230)

場所の指定は『place』で指定して有るので、このコードは何処に書いても良いのですが、後から見返した時に見やすい位置に書いておくと良いと思います。
変数『cardboard_price』に、tkinterのLabelを使って、表示スペースを確保しています。
ただこのままだと、『cardboard_price』に値がない状態の時は何も表示されないので、デフォルト値として引数に『text="【身】ボール紙の価格"』を指定しておきます。

場所の確保が終わったので、次は、『cardboard_price』の定義を書いていきます。
書く場所は、関数内の変数定義の下です。 まぁ、現状では関数で変数の定義しかしてないので、一番下と言っても良いかも知れません。

        # 身のボール紙の価格
        if cardboard_a:
            cardboard_price["text"] = "ボール紙の価格" + str(40) + "円"
        elif cardboard_b:
            cardboard_price["text"] = "ボール紙の価格" + str(50) + "円"
        elif cardboard_c:
            cardboard_price["text"] = "ボール紙の価格" + str(70) + "円"
        elif cardboard_d:
            cardboard_price["text"] = "ボール紙の価格" + str(100) + "円"
            
        # 蓋のボール紙の価格
        if cardboard_a_f:
            cardboard_price_f["text"] = "ボール紙の価格" + str(40) + "円"
        elif cardboard_b_f:
            cardboard_price_f["text"] = "ボール紙の価格" + str(50) + "円"
        elif cardboard_c_f:
            cardboard_price_f["text"] = "ボール紙の価格" + str(70) + "円"
        elif cardboard_d_f:
            cardboard_price_f["text"] = "ボール紙の価格" + str(100) + "円"

入力された数値に基づいてカテゴリー分けを行いたいので、手段としては、if文を使った条件分枝が良さそうです。
上記のように入力する事で、もし、『cardboard_a』の条件に当てはまるなら、『cardboard_price』という、先程、表示場所を確保した変数に、テキスト表示『["text"]』として、『=』以降の計算式の結果を出力してください。という命令を行っています。
足し算は文字列でしか行えないので、数字の部分を文字列に変換するために、str()で括っています。

プログラムは上から順番に読まれるので、a~dといった具合に上から順番に書く事で、カテゴリー分けがしっかりとされるはずです。
早速テストしてみましょう。
f:id:kimniy8:20180613210427j:plain
成功です!!
という事で、今回はここまでで、次回は、更に別の設定を付け加えていきます。

今までのコードのまとめはこちら

import tkinter

# ウィンドウ作成
root = tkinter.Tk()
root.title("見積もり")
root.minsize(640, 480)

# 画像表示
canvas = tkinter.Canvas(bg="black", width=640, height=480)
canvas.place(x=0, y=0)


# テキスト表示
heading = tkinter.Label(text="お見積り")
heading.place(x=10, y=10)


# テキストボックス表示
box_width = tkinter.Entry(width=10, bd=4)
box_width.place(x=10, y=40)

box_length = tkinter.Entry(width=10, bd=4)
box_length.place(x=110, y=40)

box_height = tkinter.Entry(width=10, bd=4)
box_height.place(x=210, y=40)

# ボタン表示
askbutton = tkinter.Button(text="見積開始")
askbutton.place(x=310, y=40)


# 内訳表示
b_areax = tkinter.Label(text="ボール紙の身の横幅")
b_areax.place(x=10, y=140)
b_areay = tkinter.Label(text="ボール紙の身の縦幅")
b_areay.place(x=180, y=140)

cardboard_price = tkinter.Label(text="【身】ボール紙の価格")
cardboard_price.place(x=10, y=170)

b_areax_f = tkinter.Label(text="ボール紙の蓋の横幅")
b_areax_f.place(x=10, y=200)
b_areay_f = tkinter.Label(text="ボール紙の蓋の縦幅")
b_areay_f.place(x=180, y=200)

cardboard_price_f = tkinter.Label(text="【蓋】ボール紙の価格")
cardboard_price_f.place(x=10, y=230)

# ボール紙の大きさ
def ask_click():
    b_hi = int(box_height.get()) # 箱の高さ
    b_wid = int(box_width.get()) # 箱の幅
    b_long = int(box_length.get()) # 箱の長さ
    b_tate = b_long + b_hi*2 # ボール紙の長さ
    b_yoko = b_wid + b_hi*2 # ボール紙の幅
    b_tate_f = b_long + 5 + b_hi*2 # ボール紙の蓋の縦
    b_yoko_f = b_wid + 5 + b_hi*2 # ボール紙の蓋の横

        # 身のボール紙の種類
    cardboard_a = max(b_tate, b_yoko) <= 232 and min(b_tate, b_yoko) <= 222
    cardboard_b = max(b_tate, b_yoko) <= 354 and min(b_tate, b_yoko) <= 323
    cardboard_c = max(b_tate, b_yoko) <= 505 and min(b_tate, b_yoko) <= 354
    cardboard_d = max(b_tate, b_yoko) <= 748 and min(b_tate, b_yoko) <= 505

    # 蓋のボール紙の種類
    cardboard_a_f = max(b_tate_f, b_yoko_f) <= 232 and min(b_tate_f, b_yoko_f) <= 222
    cardboard_b_f = max(b_tate_f, b_yoko_f) <= 354 and min(b_tate_f, b_yoko_f) <= 323
    cardboard_c_f = max(b_tate_f, b_yoko_f) <= 505 and min(b_tate_f, b_yoko_f) <= 354
    cardboard_d_f = max(b_tate_f, b_yoko_f) <= 748 and min(b_tate_f, b_yoko_f) <= 505

    b_areay["text"] = "身のボール紙の身の縦" + str(b_tate) + "mm"
    b_areax["text"] = "身のボール紙の身の横" + str(b_yoko) + "mm"
    b_areax_f["text"] = "身のボール紙の蓋の縦" + str(b_tate_f) + "mm"
    b_areay_f["text"] = "身のボール紙の蓋の横" + str(b_yoko_f) + "mm"
    # 身のボール紙の価格
    if cardboard_a:
        cardboard_price["text"] = "ボール紙の価格" + str(40) + "円"
    elif cardboard_b:
        cardboard_price["text"] = "ボール紙の価格" + str(50) + "円"
    elif cardboard_c:
        cardboard_price["text"] = "ボール紙の価格" + str(70) + "円"
    elif cardboard_d:
        cardboard_price["text"] = "ボール紙の価格" + str(100) + "円"
        
    # 身のボール紙の価格
    if cardboard_a_f:
        cardboard_price_f["text"] = "ボール紙の価格" + str(40) + "円"
    elif cardboard_b_f:
        cardboard_price_f["text"] = "ボール紙の価格" + str(50) + "円"
    elif cardboard_c_f:
        cardboard_price_f["text"] = "ボール紙の価格" + str(70) + "円"
    elif cardboard_d_f:
        cardboard_price_f["text"] = "ボール紙の価格" + str(100) + "円"


askbutton["command"] = ask_click            
# メインループ
root.mainloop()

【映画感想・考察】 インフィニティ・ウォー

このブログでは、偶に行っている映画関連の投稿ですが、今回は『インフィニティ・ウォー』を取り上げたいと思います。


今回の投稿では、映画を見た上での感想や考察を中心に書いていく予定ですので、当然ですが、ネタバレも多分に含んでいます。
まだ見ていない方で、情報を入れたくないという方は、読まないようにお願い致します。


私はこの映画は1度しか観てないのですが、最初に感想を書いておくと、来年の後編が始まる前にDVDで見れば良かったかなといった感じの印象でした。
というのも今回の映画は、今までのMCUのキャラクター総出演(出てきてないキャラもいますが)ってところが最大のウリになっているわけですが、出てくるキャラクター数が多過ぎるんですよね。
そして、多すぎるキャラクター全てに見せ場を用意しようと頑張った結果、キャラクター紹介映像の詰合せのような感じになってしまっていたような印象を受けました。

こんな印象を受けたからといって、面白くなかったのかと聴かれれば『そんな事はない』と答えますし、扱っているテーマも、現実の世界に住む私達の生活にもリンクしていて、考えさせられる。
全体的に観て楽しめたわけですが、一つ一つのチームの物語が短かったせいなのか、物語の中に没入出来なかった印象がありました。

ただ、先程も書きましたが、取り扱われているテーマは非常に重いものですし、考えさせられるものだったので、今回は、個人的な考察などを書いていこうと思います。

今回の敵役として登場したのは、MCUの作品でも度々登場していたサノスという人物。
今までの登場回でも、悪者たちを影から操るボス的な描かれ方をしていましたし、本作でも、宇宙の人間を半分抹殺することを目的とした、最悪・最凶のキャラクターとして登場します。
その登場の仕方も絶望的で、最初はマイティ・ソーとハルクが乗っている宇宙船を襲撃し、中の住人を虐殺していきます。

当然のように、ソーとハルクはサノスの前に立ちはだかるわけですが…
アベンジャーズの中でも最強のパワーを持つと言われていて、1人で核弾頭クラスのパワーがあると表現されている2人が、単純なパワーで蹂躙される。
この出来事でハルクは、完全に自信を失ってしまい、変身できなくなってしまう程のトラウマを抱えることになります。

手が届く範囲の射程距離にさえ入ってしまえば、確実に殴り勝てると思われていた最強のハルクが、単純に腕力でボロ負けになるというサノスの登場シーンは、シリーズを観ている人間に絶望を与える表現としては凄かったと思います。
ただ、ストーリーが進んでいくと、そんな完全無欠の力を持ち、全宇宙の半分の生命を抹殺すると宣言している悪の親玉・サノスの主張が全面に押し出され始めます。

そこから先の話では、この映画の主人公が完全に入れ替わります。
つまりは、サノスが物語の主人公となり、アベンジャーズ達は、その事が理解できていないし理解しようとも思わない無能集団となり果てます。
アベンジャーズ達は感情に身を任せて、単純に目の前の事だけに対処していく集団として描かれ、それに対するサノスは、自分の事は一切考えずに、全宇宙のことを考えた上で『善い』と思った事を確実に成し遂げる男として描かれる。

起こった出来事に対して『対処』しかしていないアベンジャーズに対し、この計画の為に全てを捧げてきたサノス。
『意思』の違いによって、当然のようにサノスの願いは成就し、全宇宙のバランスは調整されて宇宙に安定がもたらされ、見事にハッピーエンドとなる。

インフィニティ・ウォーを要約すると、この様な感じの物語になるわけですが、この、サノスが突きつけた問題というのは、現在の私達に突きつけられた問題でもあるんですよね。
というのも、現在、私達は地球に住んでいるわけですけれども、その地球のキャパというのが、既に限界を超えているからなんです。

地球には70億人という人間が住んでいる訳ですが、その全ての人が、日本人や欧米人と同じ様な生活を送ったとすれば、地球環境的にも資源的にも、破滅するといわれているからです。
冷静になって考えればわかりますよね。
中国で消費が活発になり、その需要を埋める為の供給を増やしただけで、中国の大気汚染が凄い事になって、日本にまでPM2.5が来ると大騒ぎになっているわけです。

中国だけでなく、インドやアフリカなど、人口が多い地域が一斉に先進国の人と同じ様な暮らしを望めば、環境汚染は地球全土に広がり、資源はアッという間に枯渇し、文明に完全依存している人類は生きていくことが出来なくなります。
では、全ての人が先進国と同じ様な生活をおくれる人口というのはどれぐらいなのでしょうか。
これは、約30億人程度と言われていますので、誤差などを入れたとしても、今の地球人口が半分にならないと地球が保たない事を意味します。

つまり、今までというのは、人口が多い中国やインド、アフリカ等の後進国と呼ばれる人達に地球環境に負荷をかけない生活をしてもらう事で、何とかバランスが取れていた状態ともいえます。
その為に、圧力をかけたり特定の集団を後押ししたり、国境を歪な形で引いたりして内乱などを起こさせてきたわけですが、それも限界が来始めている。
資本主義という、膨張し続けないと破綻する経済システムでは、後進国には先進国の仲間入りをしてもらわないと、需要が伸びずに破綻してしまう。

『直近の儲け』にしか興味がない資本家たちと、その援助を受けている政治家達は、資本主義をより膨張させる為に新たなマーケットを求め、貧困を押し付けていた国を顧客に仕立て上げる。
今の地球というのは、『直近の事』に対する『儲け』を最優先し、それによって生じる問題の『対処』しか考えていない人達が政治経済の中心となり、先々を見ずに運営している。

これは、今の日本の政治を見てもわかりますよね。
日本というのは島国で、国土の7割程は山岳地帯。 住む場所が限定されている状態なのに、破綻している年金システムの寿命を先延ばしするためだけに、『少子化対策』を掲げています。
地球全体で観ると人口は3~40億人減らなきゃだめなのに、経済システムを延命させるためだけに、人口を増やそうとしているのが日本です。

そんな直近の儲けを優先した際に生じる問題の対処しか出来ない人たちの前に、さっそうと現れたのが、サノスです。
現状の地球というのは、後進国に負担を押し付けることで何とかバランスを保っているわけですが、サノスの主張は違います。
老いも若きも、美醜も資産の有無も、男女の区別も優劣の差も、全て関係なく、平等に、きっちり半分消す。』

サノスはこの理想を実現する為に、最愛の娘を手にかけます。
付き従う部下も同じで、サノスの理想が実現されれば、自分も含めて仲間の半分が消え去るかもしれない。
それでも、大義の為に付き従う。 まさに、『大正義』

地球の問題に置き換えて考えてみるとわかりますが、これって、単純にサノスを倒せば終わるという話ではないんですよ。
サノスが下した決断は、全宇宙の半分の命を消し去ることではなく、半分の命を助けるということなんですから。
半分の命を救済したサノスを倒すということは、全滅を受け入れるという事と同意です。

また、この映画では問題を『地球』というのではなく、全宇宙規模の話にしているので、逃げ道がないのも辛いですよね。
単純に、地球の環境や資源の問題というだけなら、ガンダムのように、スペースコロニーを使って170億人の人類を地球外に捨ててしまえば良い。
でも、全宇宙の問題になると、宇宙よりも外には何も無いわけですから、脱出のしようも、他から資源やエネルギーを持ってくるといった選択も出来ないわけです。

こんな、重大な問題を突きつけられたアベンジャーズ。 一体、どうするんでしょうかね。

個人的な考察としては、宇宙の捉え方という部分に問題の解決方法があるような気がします。
というのも、宇宙であるユニバースの『ユニ』という部分には、『1つの』という意味が込められています。
宇宙が1つしかなく、その宇宙には外側がないのであれば、ユニバースは1つの閉じた世界となり、その中でバランスをとろうと思うのであれば、サノスの決断が最良のモノということになります。

しかし、宇宙が1つのユニバースではなく、マルチバースで有ったとしたらどうでしょうか?
今作内で、唯一、サノスに打ち勝つ方法を見つけたと断言したドクター・ストレンジは、魔術士の弟子になる前に、後に師匠となるエンシェント・ワンによって、魔術の世界の片鱗を観させられます。
その正に最中に、エンシェント・ワンから、『世界がマルチバースである可能性』について告げられます。

仮に世界がマルチバースであり、可能性の数だけ無限に存在する多宇宙が存在するのであれば、多宇宙を含めた上でのバランス調整が可能になるわけで、サノスの決断が最良のものにはならない可能性もあるんですよね。
まぁ、答えは1年待つだけで出てくるので、後はそれを楽しみに待つだけなんですが、希望を言うなら、『友情パワー』や、『頑張れば、道は見つけられる!』等の絆だけで何とかなるなんてオチだけは止めて欲しかったりはしますけどね。

【プログラミング】 python奮闘記 その11 ~ボタンを作ってみる

この記事は、現在進行系でゼロからプログラミングを勉強している私が、勉強の一環として進展状況をアウトプットする目的で投稿しています。
その為、間違った記述や無駄な作業が結構多めとなっていますが、『それでも良いから一緒に勉強している気になりたい』という方に向けて書いていますので、予め御了承ください。

前回は、記入欄の設置と、そこから値を取り出して、関数によって数値を加工するというところまでやりました。
ただ、前回までの記述では、関数を動かすことが出来てないので、プログラム上で正常に動くかどうかも分かりません。
プログラム上で動いている事が分かるように、関数を動かすための仕組みを作ろうと思います。
kimniy8.hatenablog.com

このプログラムでは、『見積もり開始』ボタンが押された事をキッカケにして、プログラムが動くようにしたいので、まず、そのボタンを作ります。
ボタンを作るのは、『tkinter』の『Button』で作れます。
質問ボタンという意味で、ボタンの値を入れる変数には『askbutton』という名前を付けてみました。

# ボタン表示
askbutton = tkinter.Button(text="見積開始")
askbutton.place(x=310, y=40)

『text』部分には、ボタンに表示させる文字列が書いてあります。
ボタンの大きさは、文字の長さによって自動的に決めてくれるので、非常に簡単に設置できますね。
placeでは、お馴染み、ボタンの場所を指定しています。
f:id:kimniy8:20180607234826j:plain
ボタン部分の記述は、ボタンの位置が記入欄の横なので、記入欄の次ぐらいに書いておくと良いかも知れません。

次に、ボタンが押された際に実行できるようにする為には

askbutton["command"] = ask_click    

と書きます。
位置としては、メインループの真上ぐらいが良いと思います。
この記述の意味としては、『askbutton』が押された時に『命令(command)』が下され、命令によって、『ask_click』が発動するという意味です。
ボタンが押された際に関数が発動するという状態にしたい場合は、取り合えす『ボタンの変数名["command"] = 関数名』と書いておけば良いと暗記しておけば良いでしょう。
私もまだまだ知識が浅いので、これぐらいの認識しか出来ていません。

これで、ボタンを押すことで関数を実行することは出来るんですが、作った関数が答えを出力する場所を作っていないので、実行したとしても意味がありません。
という事で、何らかの数値を出力するようにしてみましょう。

取り敢えず動く感じが見たいという事で、簡単な出力にしておきます。
表示させるのは、ボール紙の『縦』『横』の大きさだけです。
画面上に変数を表示させるので、まずは、変数に必要な情報を代入していきます。

関数内で変数を定義した場所の下ぐらいの場所で、変数に表示させたい内容を代入していきます。
関数内なので、インデントを合わせる事に注意しましょう。

    b_areay["text"] = "身のボール紙の縦" + str(b_tate) + "mm"
    b_areax["text"] = "身のボール紙の横" + str(b_yoko) + "mm"
    b_areax_f["text"] = "身のボール紙の縦" + str(b_tate_f) + "mm"
    b_areay_f["text"] = "身のボール紙の横" + str(b_yoko_f) + "mm"

変数名の意味合いとしては、ボール紙のローマ字の頭文字と、面積を表す『aera』に、x軸とy軸という意味のx,yをくっつけただけで、_fは『蓋』の略です。
これで、実行できるはずです。早速、数値を適当に入れて実行してみましょう。

このついでに、結果を画面に出す為の場所も作っておきましょう。
ボタン表示の下ぐらいのスペースに、内訳表示としてこう書きます。

# 内訳表示
b_areax = tkinter.Label(text="ボール紙の身の横幅")
b_areax.place(x=10, y=140)
b_areay = tkinter.Label(text="ボール紙の身の縦幅")
b_areay.place(x=180, y=140)

b_areax_f = tkinter.Label(text="ボール紙の蓋の横幅")
b_areax_f.place(x=10, y=200)
b_areay_f = tkinter.Label(text="ボール紙の蓋の縦幅")
b_areay_f.place(x=180, y=200)

もう説明も不要ですね。
ウィンドウに文字を表示させてくれる『tkinter.Label』です。引数である『text=""』の中身は、関数発動前のデフォルトの値として表示される内容で、関数が発動すると、文字の内容は変数の内容に変化します。
つまり、関数が発動前で、変数に何の値も入っていない時は、デフォルト値として『text=""』以降の文が表示されるけど、関数が発動して変数に値が入ると、表示内容が変数の値に変わるって認識で良いと思います。
引数としてなにも設定しない場合は、何も表示されません。

これで、入力した値を元に計算を行い、結果を出力するというプログラムが完成しました。
早速実行してみましょう。
f:id:kimniy8:20180607234914j:plain
はい、見事にエラーが出ました。
私は英語は読めませんが、『b_tate_f = b_long + 5 + b_hi*2 # ボール紙の蓋の縦』の部分で『typeエラー』が出ていて、『str』『not』『int』という言葉が読み取れます。
エラーの種類としては、『str』という文字列と、『int』という整数値という『type』が違う者同士を計算式、厳密には足し算に織り交ぜたことが原因のようです。文字列と掛け算は可能ですしね。
でも変ですよね? 変数『b_tate_f』も『b_hi』も『5』も、全部整数値であるintのハズなのに、なんでエラー?
これは、私が設定した記入欄の問題で、『tkinter.Entry』は、記入欄を作ってくれるんですが、その入力値は文字列になってしまうようなんです。
つまり、数字を入力したとしても、『"100"』という文字として受け取っている為、文字列を足し算がある計算式に入れると、『違うタイプ同士は計算できないよ!』というエラーが出てきたという事。

解決策として、関数開始直後の変数値を、改造します。
改造前がこちら

    b_hi = box_height.get() # 箱の高さ
    b_wid = box_width.get() # 箱の幅
    b_long = box_length.get() # 箱の長さ

そして改造後がこちら

    b_hi = int(box_height.get()) # 箱の高さ
    b_wid = int(box_width.get()) # 箱の幅
    b_long = int(box_length.get()) # 箱の長さ

記入欄である『Entry』の値を格変数に代入する際に、int()で括ることによって、値を整数値に変換しています。
注意としては、()の数は合わせましょう。 最後の部分は、get()の)とint()の)が被ることによって『))』となっています。
これで値の『type』が揃ったはずなので、エラーが出ずに結果が出るはずです。
早速試してみましょう。
f:id:kimniy8:20180607235013j:plain
はい、見事に出ました。
これで、数値を入力して結果を表示するという簡単なプログラムが完成したことになります。
後は、見積もりが出来るようにするために、この関数を改造していくだけですが、それは次回以降にしていきます。
kimniy8.hatenablog.com

今回までで書いたプログラムの全体はこんな感じです。

import tkinter

# ウィンドウ作成
root = tkinter.Tk()
root.title("見積もり")
root.minsize(640, 480)

# 画像表示
canvas = tkinter.Canvas(bg="black", width=640, height=480)
canvas.place(x=0, y=0)


# テキスト表示
heading = tkinter.Label(text="お見積り")
heading.place(x=10, y=10)


# テキストボックス表示
box_width = tkinter.Entry(width=10, bd=4)
box_width.place(x=10, y=40)

box_length = tkinter.Entry(width=10, bd=4)
box_length.place(x=110, y=40)

box_height = tkinter.Entry(width=10, bd=4)
box_height.place(x=210, y=40)

# ボタン表示
askbutton = tkinter.Button(text="見積開始")
askbutton.place(x=310, y=40)


# 内訳表示
b_areax = tkinter.Label(text="ボール紙の身の横幅")
b_areax.place(x=10, y=140)
b_areay = tkinter.Label(text="ボール紙の身の縦幅")
b_areay.place(x=180, y=140)

b_areax_f = tkinter.Label(text="ボール紙の蓋の横幅")
b_areax_f.place(x=10, y=200)
b_areay_f = tkinter.Label(text="ボール紙の蓋の縦幅")
b_areay_f.place(x=180, y=200)


# ボール紙の大きさ
def ask_click():
    b_hi = int(box_height.get()) # 箱の高さ
    b_wid = int(box_width.get()) # 箱の幅
    b_long = int(box_length.get()) # 箱の長さ
    b_tate = b_long + b_hi*2 # ボール紙の長さ
    b_yoko = b_wid + b_hi*2 # ボール紙の幅
    b_tate_f = b_long + 5 + b_hi*2 # ボール紙の蓋の縦
    b_yoko_f = b_wid + 5 + b_hi*2 # ボール紙の蓋の横

    b_areay["text"] = "身のボール紙の身の縦" + str(b_tate) + "mm"
    b_areax["text"] = "身のボール紙の身の横" + str(b_yoko) + "mm"
    b_areax_f["text"] = "身のボール紙の蓋の縦" + str(b_tate_f) + "mm"
    b_areay_f["text"] = "身のボール紙の蓋の横" + str(b_yoko_f) + "mm"

askbutton["command"] = ask_click            
# メインループ
root.mainloop()