自作クラスでPPAPテスト(js/VB/HSP/Lisp)

[続き: コールバックPPAPズンドコキヨシ(js/ts/VB/C#/HSP/Lisp)](http://qiita.com/yosgspec/items/5c7a8954fa5555593b21)

# 概要
* 元ネタ
  [Swift3でPPAPキヨシ](http://qiita.com/on0z/items/ef32f79bde5452a2ccec)
  [PPAPテストをPHPで](http://qiita.com/shinderuman@github/items/d0693aaa4a7a55585788)
  [PPAPテストを Web Audio API で](http://qiita.com/kichiki/items/c0b760375fd9cdcd9065)
* 作った[ズンドコクラス](http://qiita.com/yosgspec/items/5d6b25af830541c155cb)の実動テストネタに丁度良かった。
* 先頭台詞の重複可否を設定可能に。

# 出力
```txt:コンソール
アッポー
ペン
ペンアッポー
ペンペンアッポーアッポーペン
ペンパイナッポーパイナッポーアッポーペンパイナッポーアッポーペンアッポー
ペンアッポーアッポーパイナッポーペン
ペンペンアッポーアッポー
ペン
ペン
ペンペン
ペンアッポーアッポーパイナッポー
ペン
ペンアッポーアッポーパイナッポー
ペン
ペンパイナッポーアッポーペン
ペンパイナッポーアッポーペン ピコ!
```
# メイン部
```js:JavaScript/ppap.js
const zundoko=require("./zundoko");
(function(){
	const ppap=new zundoko(["\nペン","アッポー","パイナッポー","ペン"],"\nペンパイナッポーアッポーペン ピコ!",[0,2,1,3],true);
	console.log(ppap.kiyoshi());
})();
```
```vbnet:VB.net/ppap.vb
Imports System
Imports System.Console
Imports zundoko
Module Program
	Sub Main()
		Dim ppap As New zundoko({vbLf & "ペン","アッポー","パイナッポー","ペン"},vbLf & "ペンパイナッポーアッポーペン ピコ!",{0,2,1,3},True)
		WriteLine(ppap.kiyoshi())
	End Sub
End Module
```
```cpp:HSP/ppap.hsp
#runtime "hsp3cl"
#include "zundoko.as"

newmod ppap,zundoko
words="\nペン","アッポー","パイナッポー","ペン"
fin="\nペンパイナッポーアッポーペン ピコ!"
ptn=0,2,1,3
set_zd ppap,words,fin,ptn,1
mes kiyoshi(ppap)
```
```cl:CommonLisp/ppap.lisp
(load "zundoko")
(defparameter ppap (make-instance 'zundoko :words '("~%ペン" "アッポー" "パイナッポー" "ペン") :fin "ペンパイナッポーアッポーペン ピコ!" :ptn '(0 2 1 3) :dbl t))
(format t "~%~a~%" (kiyoshi ppap))
```
# ズンドコクラス
```js:JavaScript/zundoko.js
"use strict";

module.exports=function zundoko(_zundoko_list,_exit_kiyoshi,_zdchk,_dbl){
	var zundoko_list;
	var exit_kiyoshi;
	var zdchk;
	var dbl;
	var stk;

	var new_zundoko=function(args){
		if(zundoko.length==args.length){
			zundoko_list=_zundoko_list;
			exit_kiyoshi=_exit_kiyoshi;
			zdchk=_zdchk;
			dbl=_dbl;
		}
		else if(zundoko.length-1==args.length && _dbl==null){
			zundoko_list=_zundoko_list;
			exit_kiyoshi=_exit_kiyoshi;
			zdchk=_zdchk;
			dbl=false;
		}
		else{
			zundoko_list=["ズン","ドコ"];
			exit_kiyoshi="キ・ヨ・シ!";
			zdchk=[0,0,0,0,1]
			dbl=false;
		}
		stk=new Array(zdchk.length);
	}

	this.kiyoshi=function(){
		for(;;){
			let zd=Math.floor(Math.random()*zundoko_list.length);
			process.stdout.write(zundoko_list[zd]);
			stk.push(zundoko_list[zd])
			let stk0=stk.shift();
			if((dbl?true:stk0!=zundoko_list[zdchk[0]]) && stk.join()==zdchk.map(val=>zundoko_list[val]).join()){
				return exit_kiyoshi;
			}
		}
	}
	return new_zundoko(arguments);
}
```
```vbnet:VB.net/zundoko.vb
Imports System
Imports System.Console
Imports System.Collections.Generic
Class zundoko
	Dim rand As New Random()
	Dim zundoko_list As String()
	Dim exit_kiyoshi As String
	Dim zdchk As Integer()
	Dim dbl As Boolean
	Dim stk As New LinkedList(Of String)()
	Dim New2 As Action=Sub() Me.stk=New LinkedList(Of String)(New String(zdchk.Length-1){})

	Sub New(zundoko_list As String(),exit_kiyoshi As String,zdchk As Integer(),dbl As Boolean)
		Me.zundoko_list=zundoko_list.Clone
		Me.exit_kiyoshi=exit_kiyoshi
		Me.zdchk=zdchk.Clone
		Me.dbl=dbl
		New2()
	End Sub

	Sub New(zundoko_list As String(),exit_kiyoshi As String,zdchk As Integer())
		Me.zundoko_list=zundoko_list.Clone
		Me.exit_kiyoshi=exit_kiyoshi
		Me.zdchk=zdchk.Clone
		Me.dbl=False
		New2()
	End Sub

	Sub New()
		Me.zundoko_list={"ズン","ドコ"}.Clone
		Me.exit_kiyoshi="キ・ヨ・シ!"
		Me.zdchk={0,0,0,0,1}.Clone
		Me.dbl=False
		New2()
	End Sub

	Function kiyoshi() As String
		Do
			Dim zd As Long=rand.Next(zundoko_list.Length)
			Write(zundoko_list(zd))
			stk.AddLast(zundoko_list(zd))
			Dim stk0 As String=stk.First.Value
			stk.RemoveFirst()

			If if(dbl,True,stk0<>zundoko_list(zdchk(0))) And String.Join("",stk)=String.Join("",Array.ConvertAll(zdchk,Function(val) zundoko_list(val))) Then
				Return exit_kiyoshi
			End If
		Loop
	End Function
End Class
```
```cpp:HSP/zundoko.as
#uselib "msvcrt.dll"
randomize
#module zundoko zundoko_list,exit_kiyoshi,zdchk,dbl
	#func printf "printf" str
	#modinit
		zundoko_list="ズン","ドコ"
		exit_kiyoshi="キ・ヨ・シ!"
		zdchk=0,0,0,0,1
		dbl=0
		sdim stk,,length(zdchk)
	return

	#modfunc set_zd array _zundoko_list,str _exit_kiyoshi,array _zdchk,int _dbl
		sdim zundoko_list,,length(_zundoko_list)
		repeat length(_zundoko_list)
			zundoko_list(cnt)=_zundoko_list(cnt)
		loop

		exit_kiyoshi=_exit_kiyoshi
		sdim zdchk,,length(_zdchk)
		repeat length(_zdchk)
				zdchk(cnt)=_zdchk(cnt)
		loop

		dbl=_dbl
		sdim stk,,length(zdchk)
	return

	#modcfunc kiyoshi
		repeat
			zd=rnd(length(zundoko_list))
			stk0=stk(0)
			repeat length(stk)-1
				stk(cnt)=stk(cnt+1)
			loop

			printf zundoko_list(zd)
			stk(length(stk)-1)=zundoko_list(zd)
			double_check=stk0!=zundoko_list(zdchk(0))
			if dbl:double_check=1
			if double_check {
				repeat length(stk)
					if stk(cnt)!=zundoko_list(zdchk(cnt)){
						break
					}
					if cnt=length(stk)-1{
						return exit_kiyoshi
					}
				loop
			}
		loop
#global
```
```cl:CommonLisp/zundoko.lisp
(defclass zundoko()(
	(zundoko_list
		:initarg :words
		:initform '("ズン" "ドコ")
	)
	(exit_kiyoshi
		:initarg :fin
		:initform "キ・ヨ・シ!"
	)
	(zdchk
		:initarg :ptn
		:initform '(0 0 0 0 1)
	)
	(dbl
		:initarg :dbl
		:initform nil
	)
))

(defmethod kiyoshi((me zundoko))
	(let(
		(*random-state* (make-random-state t))
		(zundoko_list (slot-value me 'zundoko_list))
		(exit_kiyoshi (slot-value me 'exit_kiyoshi))
		(zdchk (slot-value me 'zdchk))
		(dbl (slot-value me 'dbl))
	)(let(
		(stk (mapcar #'(lambda(val)"") zdchk))
	)
		(defun fact(stk)
			(let(
				(zd(random(length zundoko_list)))
			)(let(
				(stkzd (append (rest stk) `(,(elt zundoko_list zd))))
			)
				(format t (elt zundoko_list zd))
				(if (and
					(if dbl t (string/= (first stk) (first zundoko_list)))
					(equal stkzd (mapcar #'(lambda(val)(elt zundoko_list val)) zdchk))
				)
					exit_kiyoshi
					(fact stkzd)
				)
			))
		)
		(fact stk)
	))
)
```
# 実行環境
JavaScript: node v4.3.2
VB.net: vbc 14.0.1055
HSP 3.32
CommonLisp: CLISP 2.49, SBCL 1.2.7