楽しい。
clash of clans(クラッシュオブクラン)に代表されるタワーディフェンスゲームにプログラミングの要素が加わったゲームがでた。Empire of Code いつでたのかはわかんない。これを作成したのが、checkio.orgと同じところだというので絶対時間奪われると思っていたのだけど、やり始めてしまった。
empireofcode.com/game/
checkioはPythonでしか書けなかったけど、empireofcodeはjavascriptも選べるので自分はjs側を選択した。
結局ゴールデンウイークはこれと、会社のパソコンが身代金Rockyウイルスでロックされてしまってメールにアクセスできないタスケテ!!っていう対応で奪われてしまった・・・。流行ってるみたいだから、みんなバック・アップしておこうね・・・。
さて、今みてみたら、checkioで遊んだのはもう2年2ヶ月前、Lv7まで遊んで放置したようだ。画面もずいぶん変わっていたのでバージョンアップしてまだ続いているみたい。一週間か1ヶ月か遊んで後半の問題をみて俺にはこれ以上先はしんどいなーと放置しちゃった気がする。
checkio.org/user/kuippa/
世界だとTopCoder、日本だとAtCoderとかに代表されるような競技プログラミングの世界があるのだが、個人的には詰将棋をやっているみたいで好きじゃない。反覆練習かって感じ。チューニングみたいなことを趣味でやりたくないし、人が考えた課題で先人達が上手くやっているにようなことに取り組むのはいまいち気乗りしないのだ。
みんなで車輪の再発明して職人芸を競うのには紅茶屋さんなので残念ながら興味もてないのだ。
クリアがないタワーディフェンス系のゲームは正直ゲームとしてはあまり面白くない。
使った時間と課金勢バンザイになるからだ。惰性でやめられなくなってる系。
ただ、このゲームでは課金の変わりに「プログラミング」があって、ユニットの索敵破壊アルゴリズムや、パワーアップが直接編集できたり、コードクイズを解くことで進化させることができる。
最初の自分の兵隊ユニットのロジックが突撃&破壊とあまりにもバカすぎるのでロジックを一生懸命弄ってたのだけど、
- askUnitsで一番最初に登場したユニットは他の仲間ユニットが参照できない
- doMove、doMovesで移動中にdoAttackをいれちゃうと移動がキャンセルされる
- 移動が終わるまでまってから攻撃をいれようとするとwhenIdleは一回しかコールされない
など、作りこみに限界と難があって。苦労する。自分は戦闘ユニットのロジック変更から入ってしまったけど、やらなくてよかったかもしれない。ストラテジーは必要最低限いじるだけに留めて、基地のバージョンアップをさせていったほうがいい。
デベロップメントクイズは、いまのところまだ簡単な問題がおおい。
さくっと合間時間に解けるので息抜きになる。
ただPlace Queensだけ、うへーーってなった。
8×8のチェスボードに縦横自由に動けるクイーン駒を8つ、互いにぶつからないように配置しなさいというクイズ。
例えば
placeQueens([“b2”, “c4”, “d6”, “e8”])
と渡されたら、
[“a5”, “f3”, “g1”, “h7”]
を返しなさいって感じ。
これが、予想外にいろいろな出題パターンが出現して結構悩ましく苦戦した。
codegolf
codegolfという問題があるのだが、コレが自分には未知の世界すぎてホンゲー!!?ってなる。
できるだけ少ない文字数でプログラミングをしなさいというジャンルなのだけど、Perl書きでもるまいし、このリソースリッチな時代に可読性下げてまでコードを短くする意味どこまであるのか知らないけど、このジャンルに苦戦している。
例えば、
For example: The number given is 123405. The result will be 1*2*3*4*5=120.
という問題があったとして、これを70文字以内に実装できればOKという問題。
これは、こんな風に書いた。
function golf(n){r=1;for(v of(n+””).match(/[1-9]/g)){r*=v};return r;}
解き方は人によって千差万別だろうが、正直自分で書いて気持ち悪い。三項演算子とかすら嫌いなので、こういうのヤダ。正規表現とか嫌い。
なんだこの変態ジャンルは。
Weak Pointは、与えられた2次元配列にたいして縦、横の合計が一番少ない数字を返せって問題。
普通に書けばこんな感じ
"use strict"; function golf(m) { l=m.length; p=m[0].length; sumr = new Array(l); sumc = new Array(p); sumr.fill(0); sumc.fill(0); for (var i=0;i<l;i++) { for (var j=0;j<p;j++) { sumr[i] += m[i][j]; sumc[j] += m[i][j]; } } // console.log(sumr + "/" + sumc); return [sumr.indexOf(Math.min.apply([],sumr)),sumc.indexOf(Math.min.apply([],sumc))]; }
ちょっと意識して短く書いたつもりだけどこれで、スペース込みで408文字。303文字
function golf(m){ l=m.length; r=Array(l).fill(0); c=r.concat(); for(i=l;i--;){ for(j=l;j--;){ r[i]+=m[i][j]; c[j]+=m[i][j]; } } return [x(r),x(c)] } function x(r){return r.indexOf(Math.min.apply([],r))}
変数の宣言を省略したり、concat()をつかってシャローコピーしたり、for文を–でデクリメントしたり、一個だけ関数をつくって外出ししたりして文字を稼ぐ。
これでスペース込みで265文字。186文字
ここから要らないスペースを取り除く。
function golf(m){l=m.length;r=Array(l).fill(0);c=r.concat();for(i=l;i--;){for(j=l;j--;){r[i]+=m[i][j];c[j]+=m[i][j];}}return [x(r),x(c)]} function x(r){return r.indexOf(Math.min.apply([],r))}
スペース込みで190文字。186文字
Rank1:Any code length.
Rank2:Your code should be shorter than 175 characters.
Rank3:Your code should be shorter than 125 characters.
ここまでやってRank2もとれない!!
l=m.length;
r=Array(l).fill(0);
を1行にまとめて
r=Array(l=m.length).fill(0);
これで2文字切り詰めて、
c=r.concat();
を
c=r.slice();
にして1文字稼ぐ。
Math.min.apply([],r)
は
Math.min.apply(0,r)
にできるのでこれでも1文字稼いで…
こんなんしてもまだRank1で、rank3になるにはさらに70文字削らなきゃいけないって気がついて、この路線無理!!ってなった。乾いた雑巾絞りすぎだろ。ちぎれるわ!!
でも、他のやりかたを考えると、かえって文字数が増える。ふんごーってなってます。
ループを使わずにeval(m[i].join(‘+’));とかなんだろうけど、2次元配列のピボットのショートカット手段が思い浮かばない。なんか、解けてもバッドノウハウの塊になりそうだよね。
これで躓いて、コードゴルフ問題が今何問も溜まってます。
このブログの文章よろしく、短く書くってことに思考を割いてこなかったのでちょっと苦労してます。
で、こんなゲームだれが楽しめるんじゃろ。ま、楽しいんだけど。
(追記)
function golf(m){ r=[]; p=[]; m.forEach(function(v) { p.push(eval(v.join('+'))); v.forEach(function(e, i) { isNaN(r[i])?r.push(e):r[i]+=e; }); }); return[x(p),x(r)] } function x(r){return r.indexOf(Math.min.apply(0,r))}
function golf(m){r=[];p=[];m.forEach(function(v){p.push(eval(v.join(‘+’)));v.forEach(function(e, i){isNaN(r[i])?r.push(e):r[i]+=e;});});return[x(p),x(r)]}
function x(r){return r.indexOf(Math.min.apply(0,r))}
スペース込みで206文字。202文字
長くなっちゃった・・・。
なんか!j?b=a:1;とか無茶な書き方をいっぱいしてチェックしてたらチェックサーバーが落ちちゃって、昨日から帰ってこない。。。