2013年11月10日日曜日

第一回AI麻雀大会開催しました

先日公開したAI麻雀サーバを利用して第一回AI麻雀大会を開きました。

第一回ということでとりあえず都合のついた二人だけで対戦しました。

まずユーザのプロフィール紹介。

ユーザ名 戦略の概要
developing 喰いタンのみ、役牌のみなどを狙い誰よりも早く上がることを目指す
shizimily7 シャンテン数が一番小さくなるものを計算して捨て牌を選択。役があるかは考慮せず リーチを掛けることによって最低限の役を確保する戦略

そして結果の概要。

ユーザ名 勝利回数
developing 5
shizimily7 93
*引き分け 2回


100回行った対戦の平均点数は次のようになりました。
ユーザ名 平均点数
developing 22942
shizimily7 30638
sampleAI1 22368
sampleAI2 22056


結果としてはshizimily7の圧勝。結果を解析すると、上がり回数、平均上がり得点ともにdevelopingより優秀。特に普通に 七対子や大三元を上がるなどソツのない優秀なAIに仕上がる。developingは鳴きを駆使して早上がりを目指す戦略にであったが上がり回数でも shizimily7を下回っていることを考えると、もう少しプログラムの作り込みに期待したいところ。      

2013年11月1日金曜日

麻雀のAIサーバ作りました

麻雀のAI(Artificial intelligence)サーバを作りました。

https://github.com/kentan/SmartBird

最近では電王戦と称した将棋のAIが話題ですが、
麻雀のAIを作っていろいろ遊んでみたくしてみたくなり、このたびAIサーバを作成してみました。

将棋・チェス・碁などはいわゆる「二人ゼロ和有限確定完全情報ゲーム」と呼ばれるもので、

簡単にいうと、下記のようなゲームのことを意味します。


  • 一方の負け点数が他方の勝ち点数になる(二人ゼロ和)
  • 戦略の数が有限(有限)
  • サイコロをふるなどの運要素がない(確定)
  • 戦略を判断するための情報を全部知ることが出来る(完全情報)



有限で完全情報であるゲームは基本的にコンピュータのリソースをふんだんに使うと強くなります。
10年ほど前にはプロの相手にならなかった将棋のAIがちらほら勝てるようになったのもそのためです。

それに対し、麻雀は


  • 4人ゲーム(Not 二人ゼロ和)
  • 次に選択できる手が(ツモる牌)が確定的でない(Not 確定)
  • 戦略を決定するための情報のほとんどを知ることが出来ない(Not 完全情報)


といった特徴があり、将棋や碁よりもAIの難易度が高いといえます。






2013年10月15日火曜日

App Ranking HIstoryにチャート機能を実装した

AppleのRSSからiPhoneアプリのランキングを取得するApp Ranking Historyにチャートを導入してみました。

気になるアプリのランキング推移をチャートで確認できます。



google chart apiを使って作りました。
定番のchartはひと通り揃ってていい感じです。

一応スマフォでも見れるようには作りましたが、レイアウトとか見栄えが若干いまいち。

iPhoneのサファリで株価とかgoogle検索すると綺麗に表示されるんだけど、これはどうやってるんだろうか。これもgoogle chart apiつかってるのだろうか。




ところで、このサービス、暇な時にちょこちょこいじってましたが、ここまで来ると次はアプリ名で検索とかしたくなりますね。まあそれは気が向いた時にでもやってみます。

2013年8月4日日曜日

iOSアプリトラッカー アップデートしました

前にブログで紹介したiTunesストアで1位をとったアプリを時系列で表示させるiOSアプリトラッカーをちょっとだけ機能拡張しました。

今回の修正では1位だけじゃなくて2位以降も表示出来るようにしました。






日付のところをクリックすると、今まではiTunesストアのアプリページに飛んでいたのですが、今回からは次のような画面に遷移して2位以降のアプリも見ることができます。

2013年7月16日火曜日

Kotlinはじめました。

IntelliJ IDEAで有名なjetbrains社が推進しているスクリプト言語Kotlin始めました。

Kotlinは静的型付けのJVM上で動作するスクリプト( statically-typed JVM-targeted programming language)です。


公式サイトによると、以下の項目を開発のゴールとしている。
  • Java互換の言語であること
  • Javaと同等の実行速度であること
  • NullPointerError Exceptionの静的にチェックによりJavaより安全であること
  • 動的型推論、高階関数、extension functionなど様々な機能による豊か、かつ簡潔な表現力をもつこと

ふーむ。ということでとりあえず書いてみる。Hello World。


package demo 
 
fun main(args : Array<string>) { 
  println("Hello, world!") 
}

しかし、さすがにHello Worldしただけじゃ面白くないので、15 puzzle書いてみた。
ただの反復深化です。枝狩りなし。githubはこっち




package demo
 
fun main(args : Array<string>) {
    val data = array(1,2,3,0,5,6,7,4,9,10,11,8,13,14,15,12);
    var limit:Int = 0;
    var LIMIT_MAX:Int = 20;
    while(limit <= LIMIT_MAX){
        print(limit);
        if(run(data,0,-1,limit)){
            break;
        }
        limit += 1;
    }
}
 
fun search_white_space_pos(data : Array<int>):Int{
    for(i in data.indices){
        if(data[i] == 0){
            return i;
        }
    }
    return -1;
}
 
fun finish(data : Array<int>):Boolean{
    for(i:Int in data.indices){
    if(i == 15){
        if(data[i] == 0){
            return true;
        }else{
            return false;
        }
    }else{
        if(data[i] == i + 1){
            continue;
        }
        return false;
    }
}
return true;
}
 
fun is_move_down(white_space_pos:Int):Boolean{
    if(white_space_pos >= 12 && white_space_pos <= 15){
        return false;
    }
    return true;
}
fun is_move_up(white_space_pos:Int):Boolean{
    if(white_space_pos >= 0 && white_space_pos <= 3){
        return false;
    }
    return true;
}
fun is_move_left(white_space_pos:Int):Boolean{
    if(white_space_pos == 0 || white_space_pos == 4 || white_space_pos == 8 || white_space_pos == 12){
        return false;
    }
    return true;
}
fun is_move_right(white_space_pos:Int):Boolean{
    if(white_space_pos == 3 || white_space_pos == 7 || white_space_pos == 9 || white_space_pos == 15){
        return false;
    }
    return true;
}
fun swap(data:Array<int>,pos1:Int,pos2:Int){
    var temp:Int = data[pos2];
    data[pos2] = data[pos1];
    data[pos1] = temp;
}
 
fun show(data:Array<int>){
    for(d in data){
        print(d);
        print(" ");
    }
    println();
}
 
fun run(data : Array<int>,depth:Int,previous:Int,limit:Int):Boolean{
    var white_space_pos:Int = search_white_space_pos(data);
 
    if(depth > limit){
 
        return false;
    }
    if(finish(data)){
        println("found");
        show(data);
        return true;
    }
    if(previous != 1 && is_move_down(white_space_pos)){
        swap(data,white_space_pos,white_space_pos + 4);
        if(run(data,depth + 1,0,limit)){
            return true;
        }
        swap(data,white_space_pos + 4,white_space_pos);
    }
    if(previous != 0 && is_move_up(white_space_pos)){
        swap(data,white_space_pos,white_space_pos - 4);
        if(run(data,depth + 1,1,limit)){
            return false;
        }
        swap(data,white_space_pos - 4,white_space_pos);
    }
    if(previous != 3 && is_move_left(white_space_pos)){
        swap(data,white_space_pos,white_space_pos - 1);
        if(run(data,depth + 1,2,limit)){
            return false;
        }
        swap(data,white_space_pos - 1,white_space_pos);
    }
    if(previous != 2 && is_move_right(white_space_pos)){
        swap(data,white_space_pos,white_space_pos + 1);
        if(run(data,depth + 1,3,limit)){
            return false;
        }
        swap(data,white_space_pos + 1,white_space_pos);
    }
    return false;
}

Kotlinっぽい機能全く使ってないけど、普通のjavascriptでも書いてる気分でかけました。とりあえずとっつきやすそう。

参考文献


2013年7月10日水曜日

LEAN IN(リーン・イン) 女性、仕事、リーダーへの意欲



1 怖がらなければ何ができる?
2 同じテーブルに着く
3 できる女は嫌われる
4 梯子ではなくジャングルジム
5 メンターになってくれませんか?
6 本音のコミュニケーション
7 辞めなければならないときまで辞めないで
9 スーパーママ神話
10 声を上げよう
11 ともに力を


FacebookのCOOであるシェリル・サンドバーグが書いた女性のキャリアについての本。

先日日本語版も発売され、Amazonのランキング上位をキープし続けているようだ。

日本のメディアを通して見るアメリカは、女性の活躍に対して好意的であり先進的であるように思っていた。数字でこそまだまだ社会進出の割合が低いようだが、これは時間の問題であり20年後にはすんなりと多くの女性が社会の重要な地位を占めるのだろうと思っていた。

しかし、本書によれば、日本とそう変わらず、家事・育児が女性が行うことを前提とする社会的風潮や、仕事に対して活発な女性に対するネガティブな捉え方、またキャリアアップのチャンスを自ら逃してしまう要因が存在するとのことだ。

これらについて本書では興味深い研究事例が紹介されている。

10年ほどまえ、ビジネススクールの学生たちを2つのグループに分け、とあるビジネスパーソンが人脈を駆使して投資家として成功しようとしている事例を読ませた。その上で、その人に対してどのような印象を持ったか感想を述べてもらうという実験が行われた。

2つのグループに渡された事例は全く同じであるが、主人公の名前だけ変えられている。
一方は女性の名前の主人公で、他方は男性の名前の主人公であった。

結果、男性の名前が書かれた事例を読んだグループは主人公に対して好意的な印象を持ち、ともに働きたいとコメントをしたのに対し、女性の名前が書かれた事例を読んだグループは、否定的な印象を持ち、仕事をともにすることを嫌がった。

男性は仕事の評価と個人の評価が正の相関を持つのに対し、女性は負の相関を持つという、驚きつつも胸に手を当てて見れば、そことなく腑に落ちる結論が導かれている。


また周囲の人間の評価以外にも、不利な要素が潜む。

本書によれば、総じて自分に対する評価というものは、女性よりも男性のほうが高い傾向にあるとのことだ。客観的に見れば同程度だとしても、男性は自分を高く評価する傾向にある。

このため、何か新しいチャンスが有った時、積極的に飛びつくのは圧倒的に男性が多い。
そしてその結果、成果を出すのも男性が多くなる。こちらも言われてみれば心当たりのある話しである。


本書を非常に興味深い気持ちで読ませてもらったが、これを読んだ後、アメリカ人はどう考えてるのかとても気になった。

Amazon.comのレビューでは次のようなレビューが寄せられている。評価の高い好意的なレビュー2件ほどから抜粋する。

The best message to take from this book is to be aware of what is going on in the workplace. Take the opportunity to change the inequality. Don't wait for someone to "fix" things for you. When opportunities present themselves jump on them if it's what you want. Take control.  

I found myself in every chapter she wrote. I feel that her advices directly address my insecurity and help me find strength to move on to bigger and better things. 

彼女に共感し、これを変化の契機としよう、という意見だ。高評価のレビューは概ねこのような意見が多かった。

2013年7月9日時点で、総計で1123のレビューが寄せられ、注目の高さが伺われる。
そのうち、963件が星4つ以上であるので、米国では好意的な問題提起として捉えられているのだろう。


個人的にあこのような本を読んでいつも心配になるのは、変化の流れをすべての人間に当てはめようとする人が現れることである。とりわけメディアは女性の社会進出を煽り、すべての女性は仕事を家庭を両立しなければならないかのように掻き立てる。

この懸念については本書でもところどころ触れられているが、問題の解決の際には個人の志向性を最大限尊重させながら取り組む必要があるだろう。


シェリル・サンドバーグ自身も問題は多数あれど解決は困難なことを認めている。
それでも女性が政治、産業のトップにもっと進出することによって、世の中が良くなることを渇望している。

私自身も、すべての人が望む生活をおくるのに支障が少しでも少ない世の中になるのはとてもいい事だと思う。





 TEDで講演した時の動画。

2013年5月5日日曜日

javaからscalaを呼び出すサンプルプログラム

最近話題のscala。

コンパイル結果が.classファイルになるので、javaから普通に呼び出すことが出来るみたいです。

なので、scalaのコードをコンパイルして、jarを生成し、そのjarをjavaから呼び出すサンプルプログラムを書いてみました。

まずscalaのコード。

object JarMain {
    def main(args:Array[String]) = {
     println("Hi, I am Scala.");
     println("I've got your message:");
     for (elem <- args) println("> " + elem);
    }
}

これをscalaでコンパイルした後、javaのコマンドを用いてjarを生成する。

それを呼び出すjavaのコードは下記のよう。

public class Main {
 public static void main(String args[]){

  String[] strs={"Hi, I'm Java"};
  JarMain.main(strs);
 }
}

で、実行結果
Hi, I am Scala.
I've got your message:
> Hi, I'm Java

簡単。そして地味にすごい。

最終的にjarに落としこむことができるので、ひとつのjavaプロジェクトの中で一部分だけscalaで書くということが簡単に実現できる。

これはtraditionalで大規模な開発を行なっている企業には特に嬉しい。
一つのプロジェクトで一部分だけscalaでスモールスタートして、様子を検証しつつ、上手く行ったら徐々にscalaに置き換えていくストーリーが実現可能になる。

この点は非常に重要で、例えば一昔まえに流行ったruby on railsなんかだと、導入するとなったら全部変えなきゃいけないので、アーキテクチャ全体の変更が必要だわ、多数のエンジニアの教育が必要だわ、とかくtraditionalな会社では導入の敷居がかなり高かった。

でもscalaならまずは最小限からスタートさせて徐々にjavaを置き換えていくということも簡単に出来るので、保守的かつ大規模に開発している企業とかでも容易に導入が進みそう。