このディレクトリの索引
http://hibari.2ch.net/test/read.cgi/tech/1312201995/981
#  [1] 授業単元:基礎C 
#  [2] 問題文(含コード&リンク):下のAAを縦20横30くらいのマップ上でこいつを 
#  キーボードのAを押せばジャンプして地面まで落下、Sを押せばマップ上を右へ、 
#  Dを押せば左へ行くプログラムを作成せよ。 
#   
#  ↓AA 
#   
#  (^ω^) 
#  (   ) 
#   l  l 
#   
#  

ゲーム(_画面の左上行位置,_画面の左上の列位置,_画面の右下の行位置,_画面の右下の列位置,LL1,LL2) :-
        length(LL1,_行数),
        [L|_] = LL1,
        length(L,_列数),
        _下側余り is _行数 - _画面の右下の行位置,
        _上側余り is _行数 - _画面の左上の行位置,
        _右側余り is _列数 - _画面の右下の列位置,
        _左側余り is _列数 - _画面の左上の列位置,
        rawmode,
        ゲーム(LL1,_下側余り,_上側余り,_下側余り,_右側余り,_左側余り,_画面の左上行位置,_画面の左上の列位置,_画面の右下の行位置,_画面の右下の列位置),
        norawmode.

ゲーム(LL1,_下側余り,_上側余り_1,_下側余り_1,_右側余り_1,_左側余り_1,_画面の左上行位置,_画面の左上の列位置,_画面の右下の行位置,_画面の右下の列位置) :-
        画面を消去してカーソルを先頭に移動,
        画面表示(LL1,_画面の左上行位置,_画面の左上の列位置,_画面の右下の行位置,_画面の右下の列位置),
        get_char(_文字),
        機能(_文字,LL1,_上側余り_1,_下側余り_1,_右側余り_1,_左側余り_1,LL2,_上側余り_2,_下側余り_2,_右側余り_2,_左側余り_2),
        ゲーム(LL2,_下側余り,_上側余り_2,_下側余り_2,_右側余り_2,_左側余り_2,_画面の左上行位置,_画面の左上の列位置,_画面の右下の行位置,_画面の右下の列位置).
ゲーム(_,_,_,_,_,_,_,_,_,_) :-
        write('game over !!\n').

機能('q',_,_,_,_,_,_,_,_,_,_,_) :- !,fail.
機能('s',LL1,_,_上側余り_1,_下側余り_1,_右側余り_1,_左側余り_1,LL2,_上側余り_2,_下側余り_2,_右側余り_2,_左側余り_2) :-
        右に行く(LL1,_上側余り_1,_下側余り_1,_右側余り_1,_左側余り_1,LL2,_上側余り_2,_下側余り_2,_右側余り_2,_左側余り_2),!.
機能('d',LL1,_,_上側余り_1,_下側余り_1,_右側余り_1,_左側余り_1,LL2,_上側余り_2,_下側余り_2,_右側余り_2,_左側余り_2) :-
        左に行く(LL1,_上側余り_1,_下側余り_1,_右側余り_1,_左側余り_1,LL2,_上側余り_2,_下側余り_2,_右側余り_2,_左側余り_2),!.
機能('a',LL1,_下側余り,_上側余り_1,_下側余り_1,_右側余り_1,_左側余り_1,LL2,_上側余り_2,_下側余り_2,_右側余り_2,_左側余り_2) :-
        地面まで落下(LL1,_上側余り_1,_下側余り_1,_右側余り_1,_左側余り_1,LL2,_上側余り_2,_下側余り_2,_右側余り_2,_左側余り_2),!.


地面まで落下(LL,_下側余り,_上側余り,_下側余り,_右側余り,_左側余り,LL,_上側余り,_下側余り,_右側余り,_左側余り) :- !.
地面まで落下(LL1,_下側余り,_上側余り_1,_下側余り_1,_右側余り,_左側余り,LL2,_上側余り_2,_下側余り,_右側余り,_左側余り) :-
        _下へ is _下側余り_1 - _下側余り,
        _下へ >= 0,
        _上側余り_2 is _上側余り_1 - _下へ,
        length(LL3,_下へ),
        append(LL4,LL3,LL1),
        append(LL3,LL4,LL2),!.
地面まで落下(LL1,_下側余り,_上側余り_1,_下側余り_1,_右側余り,_左側余り,LL2,_上側余り_2,_下側余り,_右側余り,_左側余り) :-
        _上へ is _下側余り - _下側余り_1,
        _上側余り_2 is _上側余り_1 - _上へ,
        length(LL3,_上へ),
        append(LL3,LL4,LL1),
        append(LL4,LL3,LL2),!.

左に行く(LL,_上側余り,_下側余り,_右側余り,0,LL,_上側余り,_下側余り,_右側余り,0) :- !.
左に行く(LL1,_上側余り,_下側余り,_右側余り_1,_左側余り_1,LL2,_上側余り,_下側余り,_右側余り_2,_左側余り_2) :-
        findall(L,(
                    append(_,[[A|L1]|_],LL1),
                    append(L1,[A],L)),
               LL2),
        _右側余り_2 is _右側余り_1 + 1,
        _左側余り_2 is _左側余り_1 - 1,!.

右に行く(LL,_上側余り,_下側余り,0,_左側余り,LL,_上側余り,_下側余り,0,_左側余り) :- !.
右に行く(LL1,_上側余り,_下側余り,_右側余り_1,_左側余り_1,LL2,_上側余り,_下側余り,_右側余り_2,_左側余り_2) :-
        findall([A|L],(
                    append(_,[L1|_],LL1),
                    append(L,[A],L1)),
               LL2),
        _右側余り_2 is _右側余り_1 - 1,
        _左側余り_2 is _左側余り_1 + 1,!.

上に行く(LL,0,_下側余り,_右側余り,_左側余り,LL,0,_下側余り,_右側余り,_左側余り) :- !.
上に行く([L0|LL1],_上側余り_1,_下側余り_1,_右側余り_1,_左側余り_1,LL2,_上側余り_2,_下側余り_2,_右側余り,_左側余り) :-
        append(LL1,[L0],LL2),
        _上側余り_2 is _上側余り_1 - 1,
        _下側余り_2 is _下側余り_2 + 1,!.

下に行く(LL,_上側余り,0,_右側余り,_左側余り,LL,_上側余り,0,_右側余り,_左側余り) :- !.
下に行く(LL1,_上側余り_1,_下側余り_1,_右側余り,_左側余り,LL2,_上側余り_2,_下側余り_2,_右側余り,_左側余り) :-
        append(LL0,[L1],LL1),
        LL2 = [L1|LL0],
        _上側余り_2 is _上側余り_1 + 1,
        _下側余り_2 is _下側余り_2 - 1,!.

画面表示(LL1,_画面の左上行位置,_画面の左上の列位置,_画面の右下の行位置,_画面の右下の列位置) :-
        画面表示(LL1,1,_画面の左上行位置,_画面の左上の列位置,_画面の右下の行位置,_画面の右下の列位置).

画面表示(_,M,_画面の左上行位置,_画面の左上の列位置,_画面の右下の行位置,_画面の右下の列位置) :-
        M > _画面の右下の行位置,!.
画面表示([_|R],M,_画面の左上行位置,_画面の左上の列位置,_画面の右下の行位置,_画面の右下の列位置) :-
        M < _画面の左上行位置,
        M_2 is M + 1,
        画面表示(R,M_2,_画面の左上行位置,N2,_画面の左上の列位置,N3,_画面の右下の行位置,N4,_画面の右下の列位置).
画面表示([_行|R],M,_画面の左上行位置,N2,_画面の左上の列位置,N3,_画面の右下の行位置,N4,_画面の右下の列位置) :-
        M >= _画面の左上行位置,
        M =< _画面の右下行位置,
        列表示(L,1,_画面の左上の列位置,_画面の右下の列位置),
        M_2 is M + 1,
        画面表示(R,M_2,_画面の左上行位置,_画面の左上の列位置,N3,_画面の右下の行位置,N4,_画面の右下の列位置).
画面表示([],_,_,_,_).

列表示([],_,_,_) :- !.
列表示(_,N,_,_画面の右下の列位置) :-
        N > _画面の右下の列位置,
        write('\n'),!.
列表示([_|R],N,_画面の左上の列位置,_画面の右下の列位置) :-
        N < _画面の左上の列位置,
        N_2 is N + 1,
        列表示(R,N_2,_画面の左上の列位置,_画面の右下の列位置).
列表示([A|R],N,_画面の左上の列位置,_画面の右下の列位置) :-
        N >= _画面の左上の列位置,
        N =< _画面の右下の列位置,
        write(A),
        N_2 is N + 1,
        列表示(R,N_2,_画面の左上の列位置,_画面の右下の列位置).

画面を消去してカーソルを先頭に移動 :-
        画面全体を消去,
        カーソルを画面の先頭に移動.

画面全体を消去 :-
        write('\E[2J').

カーソルを画面の先頭に移動 :-
        write('\E[1;1H').