みなくんの日記

やる気が皆無で自由気ままに生きてる人のブログ

プログラムよ、とにかく動け ~4桁のヒット&ブローゲーム「4Numbers」を作ろう~その1

今回の目標

毎回この講座的なアレは目標を最初に書いてからやって行こうと思います。というのも、自分の性格上冗長になりやすい性質があって話が無限に脱線してしまうからです。
あとは最初の所をみてもらえば何をやってるかが理解してもらえるかな、と。

目標

  • 「4Numbers」で実際に行われている処理を明確にして(または処理したいことを盛り込んで)「設計図」の作成
  • [Chapter.1] ランダムで重複のない数字の生成

はじめの一歩-設計図の作成-

まずは今回の処理を大まかに説明できるような設計図を簡単に作成したいと思います。私もこれがないとコードが書けなくなってしまうので、アイデア保管庫的な意味合いも込めてこのセクションを入れています。
今回の設計図はこちら。(汚くてすみません) f:id:minamint:20170618160330p:plain
まずは流れを書き、「どんなことをするのか」を明確に。次に「それを実現するにはどんな処理が必要なのか」を端的に。これさえ見れば、書かずとも少しはイメージが浮かぶのではないでしょうか。
今回のプログラミング講座では、この設計図を基にプログラムを作成していきたいと思います。
なんでわざわざ設計図なんて書いたんだ、とかそういう諸々については「蛇足ですが」に長々と。

Chapter.1 ランダムで重複のない数字の生成をしよう

では早速設計図の1番目に書いてある「重複のないランダム4桁の生成」を行いましょう。実はこれとても簡単で、pythonに準備されている関数を使うだけで簡単に出来ちゃうわけです。
それは、randomモジュールのsampleメソッド。これを用いるだけで簡単に重複のないランダム数字が生成できてしまいます。インタプリタで軽く例題として出力してみると…

>>>import random
>>>test=random.sample(range(10),4)
>>>test
[2,4,9,5] 
>>>#複数回ランダムに数字を生成してみる
...for i in range(5):
...    test=random.sample(range(10),4)
...    test
...
[8,2,5,4]
[6,4,8,9]
[7,4,2,1]
[8,1,7,2]
[1,4,0,8]
>>>exit()

といったように、たった1文(importするので2文ですが)だけ書けばすぐに正解桁は作れてしまうわけです。ではこれを実際にパーツとして組み込んでいきますが、ここで一つ問題が発生します。
見て分かるように、ランダムで取った値はリストに入れられており,連続する4桁の数字ではないわけです。そこで、この4つの数字を4桁にするという処理を行うことにしましょう。
操作は簡単です。4つの数字をa,b,c,dとするならば、a×1+b×10+c×100+d×1000にするだけです。これで誰もが納得する4桁の数字になりますね。
納得出来ないですよね。知ってました。
4桁の数字にならない可能性があります。それはd=0であったとき。0に何をかけても0なので、1000の桁が存在しないことになり、3桁になってしまうんですね。
さあどうしましょう。
数字のままだと0から始まる値なんて作れないので、文字列に変換して最初に0を付け足してしまえば簡単なので、今回はそうしてしまいましょう。
文章であれこれ説明したものを実際に組み込んだのが以下のコードになります。コードがクラスを用いて書かれていますが、各chapter毎に作成したものをパーツとして利用するためにやっています。この方が最後のメインプログラムを書く際に今まで作ったものをインポートして利用するだけでプログラムが完成するため、非常に便利になるわけです。

import random

class create_random:
    def create_num(self):
        data = random.sample(range(10),4) #0-9のなかで4桁をランダム&重複なしに設定
        number=0 #正解桁を返す際の変数定義
        mul=[1,10,100,1000] #掛け算に使用するリスト
        for i in range(4):
            number += data[i] * mul[i] #ランダムで取り出したバラバラの数字を4桁の数字にしていく
        number=str(number) #数値を文字列に変換(この方が都合が良いため)
        if len(number)==3: #3桁しかない,即ち0から始まる値(0123など)の場合
            number = "0" + number #0を最初に付け加える
        return number
#---test section---

#number=create_random.create_num()
#print(number)

#---test end---

実行結果(結果は毎回変わります)

8390

0から始まる値になった場合の実行結果(0以降の値は毎回変わります)

0743

test sectionはちゃんと動作してくれるかを確かめているメモ書きみたいなものなので、本作成時には使いません。このコードを動かすと、ランダムな数字が表示され、ちゃんと動作していることが確認できます。
さて、コメントで説明はしていますが、例の問題の解決策として、数値を文字列に変換した後if文で3桁の場合の処理を追加しました。3桁であるなら、最初に0を付けて4桁にする。ただそれだけです。これを数値のまま0を付け足す処理を行おうとすると、「int型を持って来られても、str型でしかその処理出来ないので無理」と怒られるので気を付けましょう。
これで正解桁の準備ができましたね!次はユーザの入力処理を行っていきましょう!

まとめ

  • 設計図を書いて大まかな動きを理解した
  • ランダム数字生成はrandom.sample()で簡単に行えた!
    以上、案外あっさり終わってしまって少し困惑したみなくんでした。

蛇足ですが

設計図の必要性について長ったらしく生意気に語ります。自分へのメッセージとして。
例えば、「Push "1" to say "hello"」という文章を表示し、ユーザーに「1」と入力された場合に「Hello!」と返す単純なプログラムを書くとしましょう。
この例題をあなたがお好きな言語でコードを書いて解くとき、どうやって解いているでしょうか。感覚で解きますか?それとも「あれがこうなって…」と脳内で考えながらその場でパパっと書きますか?
今回の例題は動かすことだけを考えた場合実に簡単です。以下にcとpythonでの例題に沿ったコードを乗せてみます。
test.c(c言語)

#include<stdio.h>

int main(void){
    int i;
    printf("Push \"1\" to say \"hello\"\n");
    scanf("%d",&i); //ユーザからのキーボード入力を受け付ける
    if(i==1) //もし1だったら
        printf("hello!\n");

    return 0;
}

test.py(python言語)

print("Push \"1\" to say \"hello\"")
test=input() #ユーザからのキーボード入力を受け付ける
if test=='1': #もし1だったら
    print("hello!")

これで半角数字「1」を入力された場合、仕様通りの動作をするプログラムが完成します。
さて、この例題は簡単だったので、感覚で解くというのは容易だったと思います。python3系使いの方で感覚で解いた方は、恐らく「「Push "1" to say "hello"」という文章を表示("print()"で一発)し、ユーザーに「1」と入力された場合("input()"で一発)に「Hello!」と返す("print()"で一発)」と脳内で考えてコードを書いたことでしょう。 もっと簡単に言えば「喋って入力させて喋ったら終わりでしょ?簡単じゃん」――仰る通りです。
じゃあ、こんな例題はどうでしょうか。「スタックを用いてユーザの入力したデータを保存し、それを最後に結果として出すプログラムを作ってよ」と言われた場合。
最初の例題と同じく動作説明は明確に行われていますが、文章を見ただけでコードが見えるでしょうか。少し難しいのではないかと思います。
つまり脳内だけで処理してしまうと記憶保持や順序がバラバラになってしまうといった事態が発生しかねないので、アウトプットする意味で設計図を書く必要があるわけです。あとは誰かに説明したいとき、手伝ってほしいときに理解してもらえる、というメリットもあります。具体的な処理内容は後から記述する際にまとめていけばいいので、まずは大まかな動作図を示しましょう。「こうしたいんだよ」というイメージが明確でないと、コードは書けません。
ではスタックの例題で設計図を作ってみましょう!
1. スタックを用いて → データ格納(pushメソッド)とデータ取り出し(popメソッド)が必要
2. ユーザの入力した → キーボード入力を受け付けないと
3. データを保存し  → キーボード入力を受け付けて、それからpushさせるのか!
4. 最後に結果で出す → すべて終わったら、全部popすれば良いわけだ

と、全4段階に区切って考えることができます。そして区切った後に「どのような処理をさせると良いのか」を書いています。これを少し書くだけで、どんなコードを書けばいいのか理解しやすいですね。 「この仕様通りの動きにしたいけど、どうやったらいいか分からない」と言いながら仕様文だけ読んでじーっと考えてる人がたまにいます。ぜひ考える前に、大まかな動作が分かる設計図を作ってください。そうすれば、コードは見えずともどういう処理をすればいいのかは分かるはずですから。
上から順番にプログラムを書くのではなく、大まかな形を作りながら書く、といったように。枠を作ってから後で中身を詳しく書いていく、というスタイルにしてみると随分書きやすくなるかと思います。今まで考えたこともなかったと言う人がいたら、是非トライしてみてください!

プログラムよ、とにかく動け ~4桁のヒット&ブローゲーム「4Numbers」を作ろう~その0

待望のプログラミング講座です

誰も待ってないし、少なくとも教えられるほどの腕はありません。ごめんなさい。

目立ったバグもなく動けば合格、とりあえずそれを目標に行う私のプログラミングですが、せっかくなのでここで備忘録的な感じで残していくことにしました。

アルゴリズムがデタラメだったり、オーダがO(n^2)だったりして滅茶苦茶なことが多く、「これ時間処理も何も考えてないだろ」ってプログラムを平気で書いてる奴なので、たくさん改善点はあると思いますが…。(優しく教えてくれる人募集中)

全何回になるか分からない上に更新頻度も謎です。ご了承ください。

プロローグ Pythonで簡単なゲームを作成してみたい

上にある通り、最近私の中でプチブームになっている「Python」言語を用いて今回はプログラミングしていきます。ちなみに、これ以外に私が触ったことがあるのは「アセンブリ言語」「C言語」「Java言語」「C#言語」なのですが、個人的に一番しっくりきたというか、興味が湧いたのがこの「Python」でした。でもヘビは嫌いです。大嫌い。

今回作成するゲームというのは、「ヒットアンドブロー」。皆さんはご存知でしょうか。私はこのゲームが実は大好きで、暇な時間にやっていることもあります。地味な頭の体操になる…らしいです。無意識にやってるので正直そんな感覚は一切ないですが。

ルールは以下の通りです。このゲームのルールはそこそこで違うみたいなので、一応オリジナルルールということで。

・4桁の答えとなる数字が設定される。その4桁は0から始まっても良いが、数字の重複をしてはいけない。(例えば0123)

・プレイヤーは正解と思う4桁の数字を提示する。こちらも数字の重複をしてはいけない。(例えば0267)

・答えと正解を以下の基準で比較する。

 (1)正解とプレイヤーの答えが完全一致の場合、正解となる。(例では[0123][0267]で一致しないため不正解)

 (2)正解とプレイヤーの答えが一致している桁(例では[0]がそれに該当)を「ヒット」とする。

 (3)プレイヤーの答えに、「正解の数字ではあるが桁が違う」という数字があった場合(例では[2]がそれに該当)を「ブロー」とする。

・不正解であったなら、「ヒット数・ブロー数」をヒントとしてプレイヤーに教え、再挑戦させる。(例では[1Hit 1blow]となる)

・正解するまで再挑戦でき、正解したらゲームは終了。正解までにかかった時間、およびトライ数が表示される。より短い時間で、試行回数が少ない方が良い、という感じ。

 

要するに数あてゲームです。当たるまでの時間と手数が短い方がベスト。今回はこのゲームを作っていきます。名付けて「4Numbers」。(実はアプリに同じ名前があるのですが、パクリスペクトです。許して)

 

というわけで、このゲームのプログラムを早速作成…といきたいのですが、何事も段階を踏むことが大切。今回はプロローグ、ということで、「こんなゲームを作るよ」という予告程度に留め、次回から本格的に入っていこうと思います。次回はどのような動作をするゲームなのかを考え、それに合わせた「どのような処理を行うのか」ということを考える段階からスタートする予定です。

今回はここまで。また次回お会いしましょう!

 

おまけ

おまけというか余談ですが、実は2年程前にこのゲームをC言語で作っています。初心者のくせにいきなりそんなプログラム組むから、それはもうとんでもない労力と時間を使いましたが、長期休暇を使って仕上げたのはいい思い出です。よかったら遊んでみてください。ただ、色々バグが残ってるので…動作が安定するかどうかは分かりません。(一部から「ウイルスの疑いがある」と警告されると言われましたが、ウイルスを入れられるほど高度な技術は持っていないので安心してください。)

あと、1桁ずつ入れなければいけない、という特殊な入力の仕方になります。複数桁入れても変な答えになるだけなのでお気をつけて。

 

ダウンロードはこちら(Windowsのみ対応、Win10動作確認済み[Dropboxで開きます])

ダウンロード配布は終了しました。ご了承ください。(2017/5/18追記)

 

bash on Ubuntu on Windowsを入れてみた

Windowsでターミナル開いてLinuxでやってるアレコレがやりたい…

大学でプログラミングなどを習っているため、自宅でもその復習をする、課された課題をこなす…といった具合に、結構ターミナルを用いた作業をすることが多いわけです。

私は大学で用意されている端末でただ「こうすればプログラミング出来るから」と言われ、言われるがままにemacsvimを使ってきたわけで、ターミナルとか、bashとかそういうものに関しては正直無知です。分からないと今後色々とまずそうだけど。

で、自宅にWindowsしかなく、Linuxと同じ環境が用意できてない人はプログラミングしようとする時に困るわけで。

UNIXライクな環境をWindowsで使えるCygwinを入れてみたり、sshを使える人はTera Termを入れたり、デュアルブートUbuntuなどのLinuxのOSを入れる…と、人によって結構その辺りの対処は違いますね。

私の場合はCygwinの導入と、cmd(コマンドプロンプト)にOpen SSH を導入して強引にsshをする…といったことをしていました。ですが諸事情によりCygwinが壊れ、再インストールが必要に…さらにcmdでsshをするとvimで謎のエラーが出てまともに文字が書けなくなるという…。これは困った。早急に別の対処法を考えるか、諦めて再インストールをするか…。

そんな悩みを抱えていた時に友人から聞いたのが、「bash on Ubuntu on Windows」でした。

これを利用すれば、Windows上でUbuntuが起動できる(Windows上にUbuntuを乗せて動かすことができる[要するに仮想的に動かせるということかな])と聞いて、即インストール作業を始めました。

インストールは以下のサイトを見ながらちまちまと…。

qiita.com

インストール完了!

インストールとアップデートが終わったので、軽く使ってみました。

 

うん、普通のターミナルだ!

 

いつものLinux端末で使うターミナルと同じで、とても扱いやすかったです。専門家から言わせれば色々と問題点はあるようですが(ネットでちらほら見かける)…最悪sshvimgccぐらい使えれば今のところ大丈夫なので、私は大満足です。

でも、あまりにも無知過ぎてターミナルでの他の操作とか、新しい何かのインストールとか…そういうの全く分からなくてちょっと悲しくなりました。プログラミングだけじゃなくて、自分の作業環境もパパッと整えられるぐらいにはならないと。

 

以上、bash on Ubuntu on Windowsを入れたという報告でした。(報告したかっただけ)

 

 

春の訪れ

外に出てみると一気に桜が。しかし連日の雨でお花見とまではいかず…。散ってしまわないか心配している人もいるようです。春だなあ、もう春なのか…そんな気持ちで毎日を過ごしてます。

新生活が始まった人も多く、私も進級したことによって新しい学年での新しい学びがスタートしました。久しぶりに講義を受けて、何となく懐かしくなりました。そして大学生の楽しさも再認識し、大学へ行くことの充実感も感じつつあります。休み過ぎると本当に何もしなくなる人間なので適度に大学はあった方がいいのでしょうね。

このブログで何か学んだことでも書けばいいのに、なんて思うこともあったのですが。

 

書けるほど学びを深めていない という悲しい現実があるので書けそうにないですね。

 

多少プログラミング言語の勉強をしていたから、そのことについて少し触れてみてもいいのかもしれない…と思いつつ。気が向けば書くかもしれません。

特に書きたいことないのでここで終わり(唐突

春休みももう終わり

あっという間に3月が終わり、4月になってしまいました。

この春休みの間に何かをやっていたのか、と言われれば何をしていたわけでもなく…。しかし、鳥取への列車を使った旅行、アルバイトなど人生においてとても貴重な体験をすることができたのではないかな、と思ってます。振り返ってみれば充実した春休みだったかなーと。去年の何もしてない春休みよりはマシでしょう。

それに、この季節の変わり目で私の周りもかなり環境が変わりました。結構色々と悩まされることも多く…。何も考えてないようで、地味に日々悩まされ続けている私です。

成人してからお酒に頼ることも増えましたね。寝付けないから、気分が優れないからと、1日感覚で飲んでみたり飲まなかったり。「お酒は精神安定剤じゃねーんだぞ」ということは重々承知してるんですけどねー。やめられない。適量に抑えてるし許して。

小さな悩みから、大きな悩みまで。小さな頭で精いっぱい考えて、正解か分からない答えを出して行動してみる。一つ一つの行動にかかるリスクは凄いものだけど、やれるだけの手は尽くして、自分なりに行動して、答えを出せていけたらいいなーと思います。何も答えは1つではないし。皆の力も借りちゃうかもしれません。そのときはよろしくお願いします。

 

話は変わるけど

春休みが終わったことで、大学生活が再びスタートすることになりました。3年というこの時期、院か、就職かという一大行事の前ということでかなり気合が入っています。この1年どう動くかで自分の未来が変わるのかと思うと、学生時代の将来への影響力ってすごいんだなぁー、と感じさせられたり。大学生の皆さんはもう時間割とか決めましたか?私もそろそろ決めて、前期をどう過ごすか決めるつもりです。結構忙しくなりそうで、不安も一杯だけど、やれるだけのことはやってみます!落単はしないぞ!(してる場合じゃないのが本音)

 

暇があれば随時このブログ更新していくけど、一体何を書けばいいんだろうか…。暫くは迷走しそうだなあと思いつつ、今日はここまでにしておきます。

どうも、はじめました。

はじめまして

正直Twitterが日記のようなものなのでここに改めて書くことなんかあるのか、と言われると「全くない」で終わりなのですが、Twitterで自分の見苦しいツイートを遡るのも大変だからブログを書くことにしました。

実はブログを書くのは3年ぶりぐらいになります。今でもその書いてたサイト残ってると思うけど、ろくなこと書いてないので見る気も起きません。あの頃は「Yahoo!ジオシティーズ」でしたね。懐かしい。

そんなどうでもいいことはさておいて、このブログではTwitterで語らないこと、語ってることも含め「ブログにまとめたい」と思ったことを書き残すことにします。更新頻度とかそういうものは気にしないでください。知らない間に更新します。

たまーに自分の学んでいる分野のことを言うかもしれませんが、基本的にそういうこと言うと叩かれる世の中だと思ってるので滅多にしません。

以上、どうぞよろしくお願いします!

余談的な、昔話的な何か

ブログを始めたついでに懐かし話をツラツラと書きます。要するに自己満足。自己紹介ついでだけど見る必要なし。

 

Yahoo!ジオシティーズでテンプレートを使ったブログを書く前はホームページビルダーでホームページを作っていました。今から6,7年前になります。

そのころ「みんなでGOLF 5」が流行っていて、その中でチームなるものを結成したときに「ホームページが欲しい、じゃあ作ろう」という話になり…その当時は面倒臭いよりも好奇心が勝っていたので、必死になって作っていたものです。今見てみればかなりひどいホームページだろうけど、あの頃の自分は出来栄えに満足していました。

結局そのホームページも作ったはいいけどチームがそもそも人数不足で盛り上がらず、自然消滅といった形になってしまい…。良い経験にはなりましたけどね。

 

とにかくPCで何かするのが好きな性格だったので、随分昔から様々なものには触れて来ました。

10年ぐらい前に触れた「WOLF RPGエディター」をはじめとして、ホームページビルダー、動画編集ソフト(Aviutl,ゆっくりムービーメーカー)、音声編集ソフト(Audacity)、ねとらじ(インターネットラジオサービス)、ブログ…といった感じで、幅広く色んなものに触れて来ました。

しかし中途半端に学ぶせいで、入門レベルは分かれども高度なテクニックは何一つ使えない…という残念っぷり。飽きっぽい性格が裏目に出たんでしょうね。自分の嫌いなところだったり。

これから先も中途半端にいろんなものに触れると思いますが、是非1つで良いから「これは負けない」といった物を修得したいなと思ってます。