CheckiO で Python を学ぶ

この記事は Python Advent Calendar の15日目の記事として書かれています。

CheckiO とは何か?

CheckiO は Python を書くことでステージを攻略していく、ゲームサービスでした。今は Python と JavaScript のどちらか好きな方でプログラムを書くことができます。

姉妹サービスとして、Empire of Code というものもあります。こちらの方では、日本のソシャゲーのように、現実世界で一定時間が経過すると回復アイテムがもらえる仕組みがあり、定期的にログインさせるインセンティブを持たせたゲームデザインになっています。

この記事では CheckiO に絞って話を進めていきます。

CheckiO のよいところは何か?

ゲームを通じてプログラミングを学ぶというコンセプトはそれほど目新しいものではありません。例えば CodinGameCodeCombat など、様々なプログラミングゲームが存在します。“Programming Games” というクエリで Google 検索する と、このジャンルで一旗揚げようとしているサービスがとても多いことが分かると思います。

このように多数のプログラミングゲームが存在する中で、僕が CheckiO を特に気に入っている理由がいくつかあります。

問題が段階的に難しくなる

このゲームでは、いきなり高難度の問題に取り組むことができないようになっています。

ゲームを攻略していくことでスコアを獲得し、ある一定値を超えた段階で、より難しい問題に挑戦できるようになります。初学者が「どこから初めていいか分からない…」と途方に暮れることのないような設計になっています。

「とりあえず要件を満たすコード」を提出できれば他人のコードを読める

簡単な問題であっても、エキスパートのコードと初心者のコードではアプローチが大きく異なります。

「とりあえず動く」コードさえ提出できれば、エキスパートのコードを読み、どこに改善の余地があるのか学べます。

逆に言うと、「とりあえず動く」ところまでは自分で考え抜かなければなりません。そこまで自力で行ければ、基本的なロジックは理解できているということなので、他人のコードを消化する準備ができたと言えるわけです。よくできています。

時間制限がない

コーディング時間の制約が一切ないので、とことん考え抜くことができます。

仕事では往々にして決められたデッドラインに向けて、妥協をしつつプログラムを作成します。CheckiO では、時間的なプレッシャーがない中、閃きがあるまでずっと問題に取り組むことができます。

再提出回数の制限も存在しないので、「これで万全!」と思ったものであっても、さらに後で改良することができます。

出題に貢献できる

企業がホストしているゲームにも関わらず、問題文に “How to improve this question?” のリンクが存在し、プルリクエストベースで問題文の編集をリクエストすることができます。コミュニティベースでサービスをよくしていきたいという姿勢には好感が持てます。

(必要があれば) ヒントが与えられる

もし全く問題を解く糸口が見つからない場合、”I have no idea how to start solving this mission (どこから手をつけていいか分かりません)” というリンクをクリックすると、出題者からのヒントが読めます。

最初の一歩を踏み出す

CheckiO でアカウントを作ると、まずは「HOME」と「ELEMENTARY」というステージに行けるようになります。例として「ELEMENTARY」にある FizzBuzz の問題を取り上げましょう。

“Fizz buzz” is a word game we will use to teach the robots about division. Let’s learn computers.

You should write a function that will receive a positive integer and return:
“Fizz Buzz” if the number is divisible by 3 and by 5;
“Fizz” if the number is divisible by 3;
“Buzz” if the number is divisible by 5;
The number as a string for other cases.

典型的な FizzBuzz の要件です。”Solve It” ボタンをクリックして、解いてみましょう。

ひな形のコードが次のように与えられています。

def checkio(number):
    #Your code here  (コードはここに書いてください)
    #It's main function. Don't remove this function  (この関数が評価対象なので、削除しないでください)
    #It's using for auto-testing and must return a result for check.  (返り値を自動テストが確認するので、値を返してください)

    #replace this for solution  (ここを書き換えて解答を作成してください)
    return str(number)

ベタに書くと、こんな感じになるでしょうか。

def checkio(number):
    if number % 15 == 0:
        return "Fizz Buzz"
    if number % 5 == 0:
        return "Buzz"
    if number % 3 == 0:
        return "Fizz"

    return str(number)

コードを書き換えたら、画面左上の “Check” をクリックしてみましょう。

正解の場合は添付画像のように “View other solutions (他人の解答を見る)” というリンクが表示されます。

CheckiO の猛者について

“View other solutions (他人の解答を見る)” を実際にクリックしてみましょう。

各人の答えは「Speedy」や「Creative」などのように、カテゴリ分けされます。

本記事の執筆時点で最も Creative なスコアが高い解答は veky による次のコードです。

checkio=lambda n:("Fizz "*(1-n%3)+"Buzz "*(1-n%5))[:-1]or str(n)

ちょっと文章では説明しづらいですが、読解してみましょう。lambda で関数オブジェクトを作り、引数 n が 1-n%3 == 1 のときだけ "Fizz " を、1-n%5 == 1 のときだけ "Buzz " を作り出し文字列結合します。そして、最後の空白を削るために [:-1] しています。"Fizz " でも "Buzz " でもないとき、すなわち "" のときは bool 評価をすると False なので or で結んだ str(n) が返り値になります。

じっくり読めば理解できるけど、これを頭の中からひねり出すのは困難でしょう。勉強になります。

まとめ

「Python を学んで次の一歩を踏み出したいけど、適当なお題が見つからない」なら、CheckiO を試してみるのも一興かもしれません。ゲーム感覚で楽しめるし、他人のコードを読むことでプログラミング力の向上も望めることでしょう。

コメントを残す

コメントを投稿するには、以下のいずれかでログインしてください。

WordPress.com ロゴ

WordPress.com アカウントを使ってコメントしています。 ログアウト / 変更 )

Twitter 画像

Twitter アカウントを使ってコメントしています。 ログアウト / 変更 )

Facebook の写真

Facebook アカウントを使ってコメントしています。 ログアウト / 変更 )

Google+ フォト

Google+ アカウントを使ってコメントしています。 ログアウト / 変更 )

%s と連携中