a-sanの日記

 | 

2007-01-08

Haskellオセロ

とりあえず「ハスケリ本」と「ふつケル本」は読んで、例題の数行ぐらいなら何とか書けるようになったぐらいです。

年末からオセロ移植していたのだけれど、やっとマトモに動くレベルまでこぎつけました。添削歓迎

{------------------------------------------------------------------------------
Reversi
Haskellの習得のため、Schemeで書かれたリバーシ(オセロ)をHaskellに移植してみる。
参考:
http://www.stdio.h.kyoto-u.ac.jp/~hioki/gairon-enshuu/kadai2005/7.html
盤面上のマスは(x,y)で指定する(1<= x,y <= 8).
-------------------------------------------------------------------------------}
data Piece = Empty | Black | White | Wall deriving (Eq, Show)
type Board = [[Piece]]
type Pt = (Int,Int)

-------------------------------------------------------------------------------
-- 盤面サイズ
-------------------------------------------------------------------------------
boardSize :: Int
boardSize = 8

-------------------------------------------------------------------------------
-- 8方向(dx,dy)のリスト
-------------------------------------------------------------------------------
directions :: [Pt]
directions = [(0, 1),(-1, 1),(-1, 0),(-1, -1),(0, -1),(1,-1),(1, 0),(1, 1)]

-------------------------------------------------------------------------------
-- 盤面の初期化
-- 境界に「壁」をダミーとして置いてある.
-------------------------------------------------------------------------------
initBoard:: Board
initBoard = [[ (f x y) | x <- [0..9]] | y <- [0..9]]
    where f x y
        | x == 0 || y == 0 || x == 9 || y == 9  = Wall
        | x == 4 && y == 4  = White
        | x == 5 && y == 5  = White
        | x == 4 && y == 5  = Black
        | x == 5 && y == 4  = Black
        | otherwise         = Empty

-------------------------------------------------------------------------------
-- 盤面の指定された場所のコマを返す。
-------------------------------------------------------------------------------
getBoard:: Board -> Pt -> Piece
getBoard board (x,y) = board !! y !! x

-------------------------------------------------------------------------------
-- 盤面の指定された場所にコマを置いて、新しい盤面を返す。
-------------------------------------------------------------------------------
setBoard:: Board -> Pt -> Piece -> Board
setBoard board (x,y) val = 
    (take y board) ++ ((take x b) ++ val : (drop (x+1) b)) : (drop (y+1) board)
    where
        b = board !! y

-------------------------------------------------------------------------------
-- 盤面の内容を表示する
-------------------------------------------------------------------------------
showBoard:: Board -> IO ()
showBoard board = putStr (concat (map showLine board))
    where
        showLine line =
            concat (map getSymbol line) ++ "\n"
        getSymbol val = case val of
            Empty -> "- "
            Black -> "B "
            White -> "W "
            Wall  -> "X "

-------------------------------------------------------------------------------
-- 相手の色
-------------------------------------------------------------------------------
opponent:: Piece -> Piece
opponent bw = if bw==White then Black else White

-------------------------------------------------------------------------------
-- 盤面上の白黒いずれかの個数を返す.
-------------------------------------------------------------------------------
pcount:: Board -> Piece -> Int
pcount board bw =
    length (filter (\val -> val == bw) (concat board))

{-
-------------------------------------------------------------------------------
-- 盤面上の白黒の個数を返す.
-- (黒の個数 白の個数)というタプルを返す
-------------------------------------------------------------------------------
bw_count:: Board -> (Int,Int)
bw_count board = (pcount board Black, pcount board White)
-}

-------------------------------------------------------------------------------
-- 与えられた点のある方向の位置 neighbor (5,3) (-1,1) のとき (4,4) を返す
-------------------------------------------------------------------------------
neighbor:: Pt -> Pt -> Pt
neighbor (x,y) (dx,dy) = (x+dx, y+dy)

-------------------------------------------------------------------------------
-- 同一色のrunの終点を調べる.
-- pointのdir方向の隣接点から延びるbwのrunの終点を調べる.
-- そのようなrunがなければ,pointそのものを返す.
--   pt    調べ始める場所
--   dir   方向
--   bw    調べる色
--   board 局面
-------------------------------------------------------------------------------
run_end:: Pt -> Pt -> Piece -> Board -> Pt
run_end pt dir bw board =
    if getBoard board p == bw
        then (run_end p dir bw board)
        else pt
    where
        p = neighbor pt dir

-------------------------------------------------------------------------------
-- p1 と p2 は同一地点か??
-------------------------------------------------------------------------------
the_same_point:: Pt -> Pt -> Bool
the_same_point (x1,y1) (x2,y2) = x1==x2 && y1==y2

-------------------------------------------------------------------------------
-- dirは有効な方向の指定か?
-------------------------------------------------------------------------------
valid_direction:: Pt -> Bool
valid_direction (dx,dy) =
     ((abs dx <= 1) && (abs dy <= 1)) &&
     (not ((dx==0)&&(dy==0)))

-------------------------------------------------------------------------------
-- pointが盤面の境界を越えているか??
-------------------------------------------------------------------------------
out_of_bounds:: Pt -> Bool
out_of_bounds (x,y) =
    (y<0) || (x<0) || (y>=boardSize) || (x>=boardSize)

-------------------------------------------------------------------------------
-- flippable-range+-dir: 1方向に関して石の挟むことのできる範囲を返す.
-- bwの手番でpointのdir方向で挟むことのできる石の範囲を返す.
-- 挟める石がなければ[]を返す.
-- 範囲は,(反転できる始点 反転できる終点の隣)を返す
--   bw    手番
--   point 石を置く場所
--   dir   方向
--   board 局面
-- 例:
-- flippable_range_dir Black (1,1) (0,1) board => [(1,2),(1,6)]
-- (1,2) (1,3) (1,4) (1,5)が反転できることを意味する.
-- つまり,(1,2)--(1,5)は相手の石,(1,6)はbwの石である.
-------------------------------------------------------------------------------
flippable_range_dir:: Piece -> Pt -> Pt -> Board -> [Pt]
flippable_range_dir bw point dir board =
    if
        (getBoard board point == Empty) && (valid_direction dir)
    then
        if (the_same_point s_end point)
        then []
        else
            if (getBoard board s_end_next) == bw
            then [(neighbor point dir), s_end_next]
            else []
    else
        []
    where
        s_end = (run_end point dir (opponent bw) board)
        s_end_next = (neighbor s_end dir)
-- flippable_range_dir black [3,4] [1,0] initBoard => [[4,4],[5,4]]


-------------------------------------------------------------------------------
-- run-dirs: 石を挟める方向を列挙する
-- bwの手番でpointで石を挟める方向を列挙する
--   bw    手番
--   point 石を置く場所
--   board 局面
-------------------------------------------------------------------------------
run_dirs:: Piece -> Pt -> Board -> [Pt]
run_dirs bw point board =
    aux [] directions
    where
        aux p dirs
            | (null dirs) = p
            | null (flippable_range_dir bw point (head dirs) board) = aux p (tail dirs)
            | otherwise = aux (p ++ [head dirs]) (tail dirs)
-- run_dirs black [3,4] initBoard => [(1,0)]

-------------------------------------------------------------------------------
-- do-flip-dir: 1方向に関して石の反転処理を行う.
-- pointのdir方向にbwへの反転を実行する.
-- dir方向の隣接点から反転することに注意.
-- (point自体については操作しない)
--   bw    手番
--   point 石を置く場所
--   dir   方向
--   board 局面
-------------------------------------------------------------------------------
do_flip_dir:: Piece -> Pt -> Pt -> Board -> Board
do_flip_dir bw point dir board =
    flip board (neighbor point dir)
    where
        seq = (flippable_range_dir bw point dir board)
        seq_end = head(tail seq)
        flip board p =
            if the_same_point p seq_end
            then board
            else (flip (setBoard board p bw) (neighbor p dir))
-- do_flip_dir black [3,4] [1,0] initBoard => [[1,0]]
-- setBoard initBoard [3,4] black


-------------------------------------------------------------------------------
-- do-move: 石を置く
-- 引数
--   bw    手番
--   point 石を置く場所 (y x)
--   board 局面
-- bwの手番で,pointに石を置く.
-- 手が有効であれば,石を置く処理を行って#tを返す.
-- そうでなければ,#fを返す.
-------------------------------------------------------------------------------
do_move:: Piece -> Pt -> Board -> (Bool,Board)
do_move bw point board =
    let
        d = (run_dirs bw point board)
    in
        if (null d)
        then (False, board)
        else (True, (do_move_aux board d))
    where
        -- do-move-aux: 石を置く処理を行う
        -- 引数 
        --   dirs 反転処理を行う方向のリスト
        -- dirsが空であれば,石をpointに置く.
        -- そうでなければ,dirsに含まれる方向について石の反転処理を行う
        do_move_aux board dirs =
            if null dirs
            then
                (setBoard board point bw)
            else
                (do_move_aux (do_flip_dir bw point (head dirs) board) (tail dirs))
-- do_move black [3,4] initBoard

-------------------------------------------------------------------------------
-- 候補手のリストを生成する.
--   bw    手番
--   board 局面
-------------------------------------------------------------------------------
moves:: Piece -> Board -> [Pt]
moves bw board =
    filter
        (\point -> not $ null (run_dirs bw point board))
        [(x,y) | x<-[1..8], y<-[1..8]]
-- moves black initBoard => [[3,4],[4,3],[5,6],[6,5]]
-- moves white initBoard => [[3,5],[4,6],[5,3],[6,4]]


-------------------------------------------------------------------------------
-- ゲームの補助関数
-- 引数
--   bw     手番
--   board  現在の局面データ
--   count  盤面上の石の個数
--   passed 相手が直前にパスしたか(True/False)
-------------------------------------------------------------------------------
game_aux:: (Piece->Board->IO(Bool,Board)) -> (Piece->Board->IO(Bool,Board)) -> Piece -> Board -> Int -> Bool -> IO()
game_aux black_player white_player bw board count passed = do
    -- 局面の表示
    showBoard board
    if count == boardSize * boardSize || pcount board bw == 0
        then
            -- 盤面が全て埋めつくされているか,
            -- 手番のプレイヤbwの石がないなら終了
            game_end_message board
        else
            -- 一手進める
            if null (moves bw board)
            then
                -- bwの打つ手がない場合(PASS)
                if passed
                    -- 直前に相手もPASSをしていた場合
                    -- お互いに打つところがない→終了
                    then game_end_message board
                    -- そうでない場合は,相手の手番に移る
                    else do
                        putStrLn (show bw ++ " PASS")
                        -- 次の手番(bwはPASSした)
                        game_aux black_player white_player (opponent bw) board count True
            else
                -- bwに手を決めて石を置いてもらう
                do
                    (done,newBoard) <- (if bw == Black then black_player else white_player) bw board
                    -- 次の手番(*-player-moveが True を返した場合)
                    if done
                        then game_aux black_player white_player (opponent bw) newBoard (1 + count) False
                        -- 投了(*-player-moveが False を返した場合)
                        else game_end_message board
    where
        game_end_message board = do
            putStrLn "*** GAME OVER ***"
            putStrLn ("Black vs White " ++ show (pcount board Black) ++ " " ++ show (pcount board White))

-------------------------------------------------------------------------------
-- reversiの対戦を行う
-- 引数
--   black_player 黒番の操作を行う関数
--   white_player 白番の操作を行う関数
--   これらの関数は,手を決めて石を配置する処理を適宜行う
--   ものとする.また次のように真偽値を返すものとする.
--     1. ゲームを続行する場合は True
--     2. 投了する場合は False
-- man_moveを使うとユーザが操作を行うことになる.
-------------------------------------------------------------------------------
game:: (Piece->Board->IO(Bool,Board)) -> (Piece->Board->IO(Bool,Board)) -> IO()
game black_player white_player =
    -- gameの本体(game-auxの呼びだし)
    -- 現在の状態が与えられない場合は,初期状態からスタート
    game_aux black_player white_player Black initBoard 4 False


-------------------------------------------------------------------------------
-- man-move: MANプレイヤ操作関数
-- 引数
--   bw    手番
--   board 局面
-- 手を(y x)で入力して 局面を進めて,#tを返す.
-- 入力が^Dであった場合は,投了であるとして,#fを返す.
-------------------------------------------------------------------------------
man_move:: Piece -> Board -> IO (Bool,Board)
man_move bw board = do
    -- プロンプト
    putStrLn (show bw ++ ">> ")
    -- 手を読み込む
    x <- getLine >>= return . read
    y <- getLine >>= return . read
    if x == -1
        then  return (False, board) -- ^Dなら#fを返して終了
        else
            if out_of_bounds (x,y)
                then do
                    putStrLn "illegal position"
                    man_move bw board       -- 手が無効(盤の外)
                else
                    let
                        (done,newBoard) = do_move bw (x,y) board    -- 指定された石を置く
                    in
                        if done 
                            then return (done,newBoard)
                            else do
                                putStrLn "illegal position"
                                man_move bw board

-------------------------------------------------------------------------------
-- メイン
-------------------------------------------------------------------------------
main:: IO ()
main = game man_move man_move

{------------------------------------------------------------------------------
使用例:
C:\user\lisp\Haskell>ghc Reversi.hs -o Reversi.exe

C:\user\lisp\Haskell>Reversi
X X X X X X X X X X
X - - - - - - - - X
X - - - - - - - - X
X - - - - - - - - X
X - - - W B - - - X
X - - - B W - - - X
X - - - - - - - - X
X - - - - - - - - X
X - - - - - - - - X
X X X X X X X X X X
Black>>
3
4
X X X X X X X X X X
X - - - - - - - - X
X - - - - - - - - X
X - - - - - - - - X
X - - B B B - - - X
X - - - B W - - - X
X - - - - - - - - X
X - - - - - - - - X
X - - - - - - - - X
X X X X X X X X X X
White>>
1
1
illegal position
White>>
-1
-1
*** GAME OVER ***
Black vs White 4 1
------------------------------------------------------------------------------}

EfrenEfren 2007/07/02 05:06 http://53f5d6b7addf717e63dbdc56fd9ea1f7-t.xxpogy.org <a href="http://53f5d6b7addf717e63dbdc56fd9ea1f7-h.xxpogy.org">53f5d6b7addf717e63dbdc56fd9ea1f7</a> [url]http://53f5d6b7addf717e63dbdc56fd9ea1f7-b1.xxpogy.org[/url] [url=http://53f5d6b7addf717e63dbdc56fd9ea1f7-b2.xxpogy.org]53f5d6b7addf717e63dbdc56fd9ea1f7[/url] [u]http://53f5d6b7addf717e63dbdc56fd9ea1f7-b3.xxpogy.org[/u] 9dc75301cfe28cfb0fb3d1863c1dee5e

expedia comexpedia com 2007/07/24 21:30 <a href="http://www.cwclewmm.cn/page38.html">family search lds</a> family search lds,<a href="http://www.cwclewmm.cn/page27.html">find labeling activities for anatomy and physiology</a> find labeling activities for anatomy and physiology,<a href="http://www.cwclewmm.cn/page9.html">anal dwelling butt monkey</a> anal dwelling butt monkey,<a href="http://www.cwclewmm.cn/page45.html">false dilemma</a> false dilemma,<a href="http://www.cwclewmm.cn/page46.html">green trail maps</a> green trail maps,<a href="http://www.cwclewmm.cn/page47.html">info http www californiainstitut</a> info http www californiainstitut,<a href="http://www.cwclewmm.cn/page5.html">crossed legs girls</a> crossed legs girls,<a href="http://www.cwclewmm.cn/page14.html">girl modles</a> girl modles,<a href="http://www.cwclewmm.cn/page29.html">crystal clear porno</a> crystal clear porno,<a href="http://www.cwclewmm.cn/page7.html">death of superman signed poster</a> death of superman signed poster,

gay inuyasha hentaigay inuyasha hentai 2007/07/25 03:36 <a href="http://www.uuyvnckt.cn/page4.html">bay area events</a> bay area events,<a href="http://www.uuyvnckt.cn/page13.html">hentai cum</a> hentai cum,<a href="http://www.uuyvnckt.cn/page44.html">2005 ferrari picture</a> 2005 ferrari picture,<a href="http://www.uuyvnckt.cn/page9.html">friends are the family we choose</a> friends are the family we choose,<a href="http://www.uuyvnckt.cn/page25.html">florida horse trails</a> florida horse trails,<a href="http://www.uuyvnckt.cn/page2.html">emule servers</a> emule servers,<a href="http://www.uuyvnckt.cn/page7.html">1986 mustang convertible switch</a> 1986 mustang convertible switch,<a href="http://www.uuyvnckt.cn/page32.html">index of supermodels</a> index of supermodels,<a href="http://www.uuyvnckt.cn/page28.html">golf shoes spike</a> golf shoes spike,<a href="http://www.uuyvnckt.cn/page36.html">jojo kincaid</a> jojo kincaid,

google printgoogle print 2007/07/25 08:31 <a href="http://www.jftbepvk.cn/page37.html">jeep 4 door unlimted</a> jeep 4 door unlimted,<a href="http://www.jftbepvk.cn/page12.html">claudia schiffer porno</a> claudia schiffer porno,<a href="http://www.jftbepvk.cn/page36.html">britney skye lesbian</a> britney skye lesbian,<a href="http://www.jftbepvk.cn/page37.html">diagnose 2003 jeep grand cherokee transmission problem</a> diagnose 2003 jeep grand cherokee transmission problem,<a href="http://www.jftbepvk.cn/page21.html">a new account in gmail</a> a new account in gmail,<a href="http://www.jftbepvk.cn/page40.html">dvd movie copier</a> dvd movie copier,<a href="http://www.jftbepvk.cn/page6.html">buy toyota celica</a> buy toyota celica,<a href="http://www.jftbepvk.cn/page20.html">coloring online page spongebob</a> coloring online page spongebob,<a href="http://www.jftbepvk.cn/page9.html">false restraining orders</a> false restraining orders,<a href="http://www.jftbepvk.cn/page16.html">big dog cycle</a> big dog cycle,

250 gt ferrari250 gt ferrari 2007/07/26 03:24 <a href="http://www.heqtwaps.cn/page94.html">download quick books</a> download quick books,<a href="http://www.heqtwaps.cn/page85.html">information manager software</a> information manager software,<a href="http://www.heqtwaps.cn/page56.html">gay black men sample</a> gay black men sample,<a href="http://www.heqtwaps.cn/page74.html">dolly partons tits</a> dolly partons tits,<a href="http://www.heqtwaps.cn/page51.html">category 1 3 point hitch</a> category 1 3 point hitch,<a href="http://www.heqtwaps.cn/page72.html">kingdom hearts manga volume 4</a> kingdom hearts manga volume 4,<a href="http://www.heqtwaps.cn/page56.html">black men in latex</a> black men in latex,<a href="http://www.heqtwaps.cn/page50.html">black woman dating service</a> black woman dating service,<a href="http://www.heqtwaps.cn/page77.html">ask jeffers</a> ask jeffers,<a href="http://www.heqtwaps.cn/page81.html">info http www colorfulimages com</a> info http www colorfulimages com,

dog breed selectorsdog breed selectors 2007/07/26 05:31 <a href="http://www.gbneombg.cn/page64.html">girls having sex with perky tits</a> girls having sex with perky tits,<a href="http://www.gbneombg.cn/page71.html">hombre sexo</a> hombre sexo,<a href="http://www.gbneombg.cn/page92.html">codes and cheats for pogo games</a> codes and cheats for pogo games,<a href="http://www.gbneombg.cn/page54.html">flowers for algernon lesson plan</a> flowers for algernon lesson plan,<a href="http://www.gbneombg.cn/page63.html">dexter nude</a> dexter nude,<a href="http://www.gbneombg.cn/page81.html">apple ipod headphones</a> apple ipod headphones,<a href="http://www.gbneombg.cn/page92.html">aolcom free game pogo</a> aolcom free game pogo,<a href="http://www.gbneombg.cn/page61.html">anal rim job</a> anal rim job,<a href="http://www.gbneombg.cn/page66.html">email hotmail msn</a> email hotmail msn,<a href="http://www.gbneombg.cn/page83.html">adult dvd hits</a> adult dvd hits,

labyrinth lyricslabyrinth lyrics 2007/07/26 06:18 <a href="http://www.evazoimy.cn/page84.html">adult acne care product review</a> adult acne care product review,<a href="http://www.evazoimy.cn/page67.html">chess online site</a> chess online site,<a href="http://www.evazoimy.cn/page86.html">ares lite free download</a> ares lite free download,<a href="http://www.evazoimy.cn/page56.html">free aol password recovery</a> free aol password recovery,<a href="http://www.evazoimy.cn/page80.html">kids nascar clothing</a> kids nascar clothing,<a href="http://www.evazoimy.cn/page59.html">far west books</a> far west books,<a href="http://www.evazoimy.cn/page64.html">anti-flag - emo</a> anti-flag - emo,<a href="http://www.evazoimy.cn/page93.html">a simple network monitoring system-requirements document</a> a simple network monitoring system-requirements document,<a href="http://www.evazoimy.cn/page93.html">how to make a simple robot</a> how to make a simple robot,<a href="http://www.evazoimy.cn/page99.html">erect men in speedos</a> erect men in speedos,

beach camp girlbeach camp girl 2007/07/26 06:24 <a href="http://www.kiqakrca.cn/page66.html">ebay suspensions</a> ebay suspensions,<a href="http://www.kiqakrca.cn/page54.html">kitty cat paw print tattoos</a> kitty cat paw print tattoos,<a href="http://www.kiqakrca.cn/page96.html">fifth wheel trailer hitches</a> fifth wheel trailer hitches,<a href="http://www.kiqakrca.cn/page54.html">busta rhymes back tattoos</a> busta rhymes back tattoos,<a href="http://www.kiqakrca.cn/page54.html">big cat tattoos</a> big cat tattoos,<a href="http://www.kiqakrca.cn/page94.html">jason aldean naked</a> jason aldean naked,<a href="http://www.kiqakrca.cn/page72.html">fiona horne playboy</a> fiona horne playboy,<a href="http://www.kiqakrca.cn/page57.html">how to insert background images on myspace</a> how to insert background images on myspace,<a href="http://www.kiqakrca.cn/page60.html">convert outlook 2003 contacts to windows address book .wab</a> convert outlook 2003 contacts to windows address book .wab,<a href="http://www.kiqakrca.cn/page76.html">50's mustangs cars pictures</a> 50's mustangs cars pictures,

ibsenhenrikadoll146ibsenhenrikadoll146 2007/08/01 07:56 <a href="httpwwwlefnytjucnpage63html">girdleslittlegirls</a> girdleslittlegirls,<a href="httpwwwlefnytjucnpage63html">hotmiddleeasterncollegegirls</a> hotmiddleeasterncollegegirls,<a href="httpwwwlefnytjucnpage53html">wirelessphonetracfoneairtimecardsminutes</a> wirelessphonetracfoneairtimecardsminutes,<a href="httpwwwlefnytjucnpage58html">electricpizzaoven</a> electricpizzaoven,<a href="httpwwwlefnytjucnpage58html">handtossedpizzadoughrecipes</a> handtossedpizzadoughrecipes,<a href="httpwwwlefnytjucnpage42html">lalingeriedeperla</a> lalingeriedeperla,<a href="httpwwwlefnytjucnpage42html">fullfigureleatherlingerie</a> fullfigureleatherlingerie,<a href="httpwwwlefnytjucnpage61html">governmenttaxsalesrealestatemaine</a> governmenttaxsalesrealestatemaine,<a href="httpwwwlefnytjucnpage65html">paradisekiss-animepics</a> paradisekiss-animepics,<a href="httpwwwlefnytjucnpage51html">housesforrentinalexanderarkansas</a> housesforrentinalexanderarkansas,

lizearleyboobslizearleyboobs 2007/08/01 18:52 <a href="httpwwwffyrwvdzcnpage52html">h228</a> h228,<a href="httpwwwffyrwvdzcnpage48html">bluemarblechihuahua</a> bluemarblechihuahua,<a href="httpwwwffyrwvdzcnpage59html">steelsheltersforcarsandboats</a> steelsheltersforcarsandboats,<a href="httpwwwffyrwvdzcnpage43html">corvettedenimvarsityjacket</a> corvettedenimvarsityjacket,<a href="httpwwwffyrwvdzcnpage50html">fontagentprotrashpreferences</a> fontagentprotrashpreferences,<a href="httpwwwffyrwvdzcnpage54html">osenfermos</a> osenfermos,<a href="httpwwwffyrwvdzcnpage60html">whereishansonrunescape</a> whereishansonrunescape,<a href="httpwwwffyrwvdzcnpage52html">suspendedsentencevic</a> suspendedsentencevic,<a href="httpwwwffyrwvdzcnpage69html">p2pkazaa</a> p2pkazaa,<a href="httpwwwffyrwvdzcnpage52html">hardwoodsuspendedtartan</a> hardwoodsuspendedtartan,

SanamSanam 2012/12/20 12:29 Knowledge wants to be free, just like these artciels!

zpcbkqvzpcbkqv 2012/12/23 07:48 qu0Z3P , [url=http://ezxbohmlmdbo.com/]ezxbohmlmdbo[/url], [link=http://zywxhxwefhmb.com/]zywxhxwefhmb[/link], http://uhozkkmlgnkv.com/

xequnsruuhxequnsruuh 2014/06/03 19:35 hzrovibtlfmm, <a href="http://www.ogjflyxfad.com/">rdezwnpkxe</a> , [url=http://www.uzhkmbbure.com/]ighzisjbql[/url], http://www.ycrvltzlbj.com/ rdezwnpkxe

ゲスト



トラックバック - http://haskell.g.hatena.ne.jp/a-san/20070108
 |