「lisp勉強14日目NimをCPUと対戦してみる」の編集履歴(バックアップ)一覧に戻る

lisp勉強14日目NimをCPUと対戦してみる - (2013/06/03 (月) 18:45:53) のソース

%prolog勉強14日目
% nimをプレイするCPUをPrologで自力で書いてみる。C++なら一瞬で書ける問題がprologで書くと何か凄く難しい。
% 普通に書いてもよいのですが今回はレジスターマシン的な発想でかつ、
% 整数論的にs(s(,,,s(0),,,))的に山に残ってる石の数を認識してコードを書いてみました
% 本当は取らない山二つの数をxorしてその値が残りの山より小さいなら残りの山をその値まで取ればいいのですがまあ趣味的に書いてみました
% 単なる勉強用なので入力チェックやエラー処理はあまりしてません


xor_hit(X,Y,Z):-Calc is X xor Y xor Z,Calc=:=0.


dell(Yamas,No,Dell,Result,ReYama):-nth0(No,Yamas,Size),Size<1,!,fail.
dell([X,Y,Z],No,Dell,Result,ReYama):-
		(No=:=0 -> X1 is X-1,Y1 is Y,  Z1 is Z  ;true),
		(No=:=1 -> X1 is X,  Y1 is Y-1,Z1 is Z  ;true),
		(No=:=2 -> X1 is X,  Y1 is Y,  Z1 is Z-1;true),
		Dell1 is Dell+1,
		(xor_hit(X1,Y1,Z1) ->
			Result is Dell1,ReYama=[X1,Y1,Z1];
			dell([X1,Y1,Z1],No,Dell1,Result,ReYama)).



dell_search([0,0,0],ReYama,No,-1,-1):-!,fail.
dell_search([X,Y,Z],[X1,Y1,Z1],3,1,0):-Y=<X,Z=<X,X1 is X-1,Y1 is Y  ,Z1 is Z,  !.
dell_search([X,Y,Z],[X1,Y1,Z1],3,1,1):-X=<Y,Z=<Y,X1 is X  ,Y1 is Y-1,Z1 is Z,  !.
dell_search([X,Y,Z],[X1,Y1,Z1],3,1,2):-X=<Z,Y=<Z,X1 is X  ,Y1 is Y,  Z1 is Z-1,!.

dell_search(Yamas,ReYama,No,Result,ReNo):-
		(dell(Yamas,No,0,Result,ReYama)->ReNo is No;
			No1 is No+1,dell_search(Yamas,ReYama,No1,Result,ReNo)).

%プレーヤのターン

user_input(Yamas,Te):-
	repeat,
	format('Input mountain No And number taken from a mountain.~n'),
	read(Te),
	length(Te,2),
	[X,Y]=Te,
	integer(X),
	integer(Y),
	0=<X,
	X=<2,
	nth0(X,Yamas,Size),
	1=<Y,
	Y=<Size,
	!.
	

play([X,Y,Z],0):-X<1,Y<1,Z<1,!,format('your loss.~n').
play([X,Y,Z],1):-X<1,Y<1,Z<1,!,format('your win.~n').
play(Yamas,0):-
	user_input(Yamas,Te),
	[X,Y,Z]=Yamas,
	[No,Size]=Te,
	(No=:=0 -> X1 is X-Size,Y1 is Y,     Z1 is Z     ;true),
	(No=:=1 -> X1 is X,     Y1 is Y-Size,Z1 is Z     ;true),
	(No=:=2 -> X1 is X,     Y1 is Y,     Z1 is Z-Size;true),
	play([X1,Y1,Z1],1).
play(Yamas,1):-
	dell_search(Yamas,ReYama,No,Result,ReNo),
	[X,Y,Z]=ReYama,
	format('CPU Get ~d ~d Yama(~d ~d ~d)',[ReNo,Result,X,Y,Z]),
	play(ReYama,0).

nim:-format('Nim Please input three numbers.~n'),
	read(Yamas),
	play(Yamas,0).