CubeSEを開発した話

この記事はSpeedcubing Advent Calendar202224日目の記事です。23日目の記事はむぎ茶さんの「Visual Cube Plus の使い方」でした。25日目の記事は佐村健人さんの「アジア大会報告記完全版」です。

 

はじめまして、TRCです。

GitHubから来られた方向けに説明をすると、このブログはルービックキューブ界隈のアドベントカレンダーに投稿されている記事です。CubeSEの使い方の日本語版の案内も兼ねてますのでご安心ください。

キューバーの方向けに説明をすると、この記事はGitHubのレポジトリにあるREADMEにリンクされてます。この記事がキューブ界と非キューブ界を結ぶ架け橋として、なんかいい感じのことが起きることを願ってます。

 

 

はじめに

WindowsでしかCubeSEは動きません。ごめんなさい...。

CubeSEというルービックキューブの手順を探索するためのデスクトップアプリケーション(パソコンで動かすアプリ)を作ったのですが、ことの発端は2021年の4月中旬に遡ります。皆さんは2006NISH01さんによる、こちらの素晴らしい記事を覚えてますでしょうか?

qiita.com

当時の私はこれを見て非常に感動し、これを更に発展させて手順探索用のアプリを作りたいと思うようになりました。そこから今に至るまで開発し続け、今日リリースしたという流れです。

開発にあたり、にゃにゃんさん(山名琢翔さん)をはじめ、試験配布に協力してくださった方々や友人に大変助けていただきました。また、CubeSEのアイコンは友人に描いていただきました。この場をお借りして深く感謝申し上げます。

 

インストール方法

CubeSEをお使いのパソコンで使用するための手順です。英語版はCubeSEのREADMEにも書いてあります。Microsoft Edgeの例で説明を進めていきます。それではまず以下のリンクに飛んでください。

github.com

飛んだ先から最新のリリースのCubeSE installer vX.X.X.exe(vX.X.Xは最新のバージョン名)をクリックしてください。するとインストーラのダウンロードが始まります。これが終わるとEdgeが警告を出してくるので、「...」をクリックし、「保存」を押します。その後さらに「詳細を表示」を押し、「保持する」を選択します。これで第一段階は完了です。

次に、CubeSEはPython3で動くので最新のPythonをインストールしてください。Pythonのインストールは以下のサイトを参考にすると良いです。

www.python.jp

この時に忘れずにPATHを通すようにしてください。上の記事の内容に従えば大丈夫です。Pythonが正常にインストールできたら、Windowsキー + Rを押して「ファイル名を指定して実行」を開きます。そこに「cmd」と入力してEnterを押します。するとコマンドプロンプトが起動します。そこに「pip install Pillow」と打ってEnterを押してください。以下の画像の様になれば大丈夫です。これで第二段階は完了です。

最後に、最初にダウンロードしたCubeSE installer vX.X.X.exeをダブルクリックして実行してください。するとWindowsによってPCが保護されました、と出てくるので「詳細情報」を押して新しく現れた「実行」を押してください。これでインストーラが起動します。あとはインストーラの指示に従ってください。これでCubeSEが使えるようになりました!!

初めてCubeSEを実行するときは、このファイルを開く方法を選んでください。と出ると思います。その時は以下の写真のアイコンのPythonを選択するか、アイコンが表示されない場合は「その他のアプリ」、「このPCで別のアプリを探す」と進みpythonw.exeを選択してください。これはAppData\Local\Programs\Python\Python3XX\pythonw.exeにあります。AppDataは隠しファイルなので気を付けてください。

使い方

それでは使い方を説明していきます!

CubeSEが提供する機能は大まかに3つです。

  1. 与えられたスクランブルに対してなるべく短い解を探す

  2. キューブの色を塗って解かせる
  3. 手順探索

多分キューバーの皆さんが主に使うのは3の機能でしょう。順に説明していきます。

与えられたスクランブルに対してなるべく短い解を探す

これはCubeSEの中のSolver for cubersにあたります。各項目の説明をしていきます。

  • Input scramble

スクランブルを入力するところです。ファットムーブやスライスムーブ、持ち替え記号はサポートされていません。普通のスクランブルを入力してください。

  • Designate the first searching depth

簡単に言えば最短で何手の解を許容するかを指定するところです。ちゃんと説明するとTwo phase algorithmにおいて最初のphaseでIDA*を始める深さを指定するところです。

  • Designate max searching depth

最長で何手の解を表示させるかを示すところです。例えば25に指定すると、25手の解が見つかった後に25手以上かかる解を表示しません。24手以下の解が見つかった時のみ表示されます。

  • Designate searching time in second

何秒間解を探し続けるかです。もし100000000秒とかに指定してしまっても途中で止められますのでご心配なく。

  • Start/Stopボタン

解を探し始めるボタンと、それを途中で止めるボタンです。注意点として、一時停止ボタンではないです。一度Stopを押せば、その後またStartを押しても表示されていたところの続きからではなく、最初から探索しなおしになります。想定している使い方としては、「Designate searching time in second」で長すぎる時間を指定してしまったとき用です。

  • Check to delte recent solutions

2回目以降Startボタンを押したときに表示されていた解を全て消して解を表示するか、追加でその下に表示するかを選べます。

  • Select searching mode

解を探すのにTwo phase algorithmを使っているのですが、これはDomino Reductionのようなものです。そのためEOをどの面を基準にして考えるかで3パターン探索方法があります。EOの基準面をUD面にするかRL面にするかFB面にするかです。どれを選択したら最も早く短い解が見つかるかはわからないので、Use allという3パターンの探索方法を平行処理させるモードも搭載しています。

  • Check to insert rotation letters

チェックを入れるとその下にある回転記号が書かれたボタンを押したときに展開図が変化するだけでなく、Input scrambleの欄にもその回転記号が追加されます。持ち替え記号は入力されません。

  • 回転記号/Resetボタン

押すと展開図が変化します。Resetで元に戻ります。Check to insert rotation lettersにチェックを付けていればInput scrambleの欄にも追加されますし、ResetをおせばInput scrambleの欄もリセットされます。

キューブの色を塗って解かせる

これはCubeSEの中のSolver for Beginnersにあたります。各項目の説明をしていきます。なお、以降説明済みのものは割愛します。

  • Select color

下にある6色の四角形をクリックすることで現在選択している色を変化させることができます。展開図中のグレーの部分はクリックすると選択している色で塗られます。センターは固定です。塗り間違えたら正しい色でまたそこをクリックすれば塗り替えられます。

  • Selected color

現在選択している色が表示されています。

  • Reset/Solved/Startボタン

Resetボタンは展開図を初期のグレーの状態に戻します。

Solvedボタンは展開図を揃っている状態に塗ります。

Startボタンは解を探索し始めるものです。解は一番最初に見つかったものが1つだけ表示されます。

  • Press buttons below to show how to rotate the Rubik’s cube

回転記号の意味があやふやだったりわからなかったりする人用です。回転記号の意味を教えてくれる画像が表示されます。Hideボタンで表示させないこともできます。

 

手順探索

みなさんお待ちかねの本題です。手順探索はさらにPLL, OLL, F2L, sub stepsに分かれています。これらもまた順に説明していきます。

PLL Explorer

PLLの手順を探索するためのモードです。

  • Select PLL

文字通り手順を探したいPLLを選択してください。

  • Designate how many solutions to explore

探索する手順の個数を指定できます。スクランブルから解を求める機能では、何秒間探索するかという時間を指定していましたが手順探索では何個手順を探すかで探索の終了条件を設定します。初期値は50ですが、10万とか指定することもできます。

  • Check faces you want to use

genを指定するところです。チェックを付けなかった面は手順に含まれなくなります。細かい話をすると、探索する時点でその面を回す、という操作を行わなくなります。探索結果からその面を回す操作を含む手順を省いてるわけではないです。

  • allow fat and slice moves

重要な機能です。ファットムーブとスライスムーブのgenを制限できます。これは例えば、Rw, Rw2, Rw'は使いたいけどR, R2, R'は使いたくないという条件も指定できます。

どうです?便利でしょう?

  • Use half turns

半回転(U2とかD2)とかを使うかどうか指定できます。これは確か試験配布したときに要望があって実装した機能です。

AUF, ADFを括弧の中に入れた状態で手順を出力します。

  • Select the orientation

探索したいPLLを指定したとき、画面右にPLLの画像が表示されていますが、そこにどの向きがR, L, F, Bなのか書いてあります。これが初期の位置です。この状態から持ち替えてPLLの手順を探したいときに指定する部分です。「y, y2, y'」と「x, x'」を組み合わせて指定できます。ここで「y, y2, y'」の存在を疑問に思う人もいるでしょう。理由はCubeSEがいかなる場合においても最初の一手として「U, U2, U', Uw, Uw2, Uw'」を回さないためです。純粋に指定した持ち替え状態からの手順のみが出力されます。

どうです??便利でしょう??

OLL Explorer

OLLの手順を探索するためのモードです。

基本的に指定する項目はPLL Explorerと同じです。探索するOLLの指定方法は、画面右側の展開図に色を塗ることです。こちらは同じ場所をクリックするたびに、黄色、グレーと交互に変化します。

F2L Explorer

F2Lの手順を探索するためのモードです。

こちらでは指定できる項目が一部減っています。F2LにAUF, ADFは存在しないので、「Put AUF and ADF into brackets」と「x, x'」の持ち替えが指定できなくなっています。F2L回してるときにx持ち替えする人は(多分)いない(はず)なので大丈夫だと思います。

探索するF2Lの指定方法は、Solver for Beginnersと同じ感じに展開図に色を塗って指定してください。新しく増えた指定項目について説明します。

  • Solve :

揃えたいF2Lが展開図の状態(青F黄色U)から考えてどのスロットかを指定するところです。

  • Solved slot :

F2L手順は、他のスロットが揃っていた場合そこを崩さない必要があります。そこですでに揃っているスロットを指定しておくのがこの部分です。

  • Reset

展開図の状態と、上記「Solved slot :」の指定をリセットします。

sub steps Explorer

いろいろなsub stepの手順を探索するためのモードです。指定できる項目はPLL探索とかとほぼ変わりません。新しいのは1つだけです。

  • Select :

sub stepの大まかな種類をここで指定します。指定できるのは

  1. OLL + PLL
  2. OLL + CPLL
  3. LS + EOLL
  4. LS + OLL
  5. Advanced F2L(Adj)
  6. Advanced F2L(Opp)

の6種類です。念のため、CPLLはコーナーの位置だけ揃えるもので、LSはF2Lの最後のスロット、EOLLはエッジの向きだけ揃えるもの、Adj/Oppはそれぞれ隣接と対角の意味です。

OLL + PLLでは例えばZBLL, 1LLL, ELLなどの手順を探索できます。

OLL + CPLLでは例えばCOLL, OLLCPなどの手順を探索できます。

LS + EOLLでは例えばZBLSなどの手順を探索できます。

LS + OLLでは例えばCLS, VLS, WV, SVなどの手順を探索できます。

Advanced F2Lでは例えば2スロットを同時に処理するPseudo slottingの手順などを探索できます。

注意点として、LSを含むものや、Advenced F2Lでは x 系の持ち替えが指定できません。

 

いかがでしたでしょうか。これで全ての機能の説明が終わりました。

どうです???便利でしょう???

技術的な話

CubeSEの開発にはVScodePythonを書いて、Visual Studio 2019でC++を書いてました。

GUIPythontkinterを使ってます。tkinter使うよりwebアプリにした方がはるかに楽だということに気づいたときには、修正をかけるには遅すぎたためこうなりました。一応異なる解像度のPCに入れてもそれなりに動くように、GUI上のウィジェットはPCの縦横のサイズの相対位置で指定してます。そのため画面が小さい人は最大化、大きい人は良い感じにウィンドウサイズを調整して使ってください。

元々はPythonだけで全て完結させる予定だったのですが、いかんせん処理が遅い遅い遅い遅い!!それにPythonをexe化するとどうにもウイルス判定によく引っかかるので、Pythonをインストールしていただく形になりました。

Cythonも試しましたがあまり高速化せず、諦めてC++を学びました。高一の夏休みはそれで殆ど潰れました笑。今ではRustとかC++より速いらしいからいつか書き換えるかなぁとか思ってます。

Pythonで作ったGUIからC++コンパイルした実行ファイルを呼び出してるのですが、初回実行時はキャッシュが無いため呼び出すのに時間がかかります。2回目以降はすぐに呼び出せます。

Solver for BeginnersとPLL探索で画像を表示させていましたが、その画像をPCの画面サイズに合わせて拡大縮小するのにPillowというライブラリを使ってます。だから最初にpipでインストールしてもらったんですね。

Solver for cubersとSolver for BeginnersではTwo phase algorithmを、手順探索ではIDA*を使ってます。枝刈りは最初に紹介した素晴らしい記事で使われている考え方を元に、作れる限りのものを作り、その枝刈り表の性能を試験によって評価して使用するものを決定しました。枝刈り表はバイナリで保存されていて、すべての値が4bitに収まっていたので隣り合う2つの値を、1つ目を上位4bitに、2つ目を下位4bitに格納することでなるべくファイルサイズを小さくしてます。

遷移表はjsonファイルに保存してあります。大体技術面の話はこんな感じですね。

あとがき

いやぁ...CubeSEを開発しようと決意した2021年4月22日。あれからずいぶん長い年月が経ちました。当時は高校生になってパソコンを買ってもらったのと、学校で行われた授業でPythonの紹介があり、ほな、ちょっと手でもだしてみるかなぁという感覚で始めたのでプログラミングのプのpすらわからない状態でした。それでも毎日大量のコードとエラーとバグにもまれているうちに、しっかりと学習した覚えはないのにいつの間にかそこそこプログラミングができる状態に進化していました。慣れって恐ろしいですね。

今にして思えば、運動部で自称進()の高校生が一人でデスクトップアプリケーションを開発するとか頭おかしいです。実際周りにも言われました。GUIのデザインからフロントエンド的なものの実装、バックエンド的なものの実装、その過程で高速化やら軽量化やらでめちゃくちゃ対照実験を行ってデータを取り続けてました。しかもGUItkinter。何度途中で後悔したかわかりません。でもやっぱり完成してみるとすべての苦い思い出も美化されるものです。ここまで長々と書き連ねてきましたが、皆さんのお役に立てれば嬉しいです。

CubeSEについてご感想、ご要望、バグの報告などは私のTwitterからDMをいただけますと幸いです。

最後までお付き合いいただきありがとうございました。