/*
 *	clipvsl.c
 *
 *	ビデオスロットゲーム用サブルーチン集
 *
 *	CLiP - Common Library for P/ECE
 *	Copyright (C) 2001-2016 Naoyuki Sawa
 *
 *	* Thu Feb 11 21:46:05 JST 2016 Naoyuki Sawa
 *	- 1st リリース。
 *	* Fri Jun 03 21:47:06 JST 2016 Naoyuki Sawa
 *	- シンボルタイプの定数を定義しました。
 *	  これまではシンボルタイプを直値(-1,0,1)で指定していましたが、今後はシンボル(VslTyp_*)で指定して下さい。
 *	* Tue Jun 07 22:13:11 JST 2016 Naoyuki Sawa
 *	- 通常ラインタイプの、配当額取得関数(旧:fnGetPay)を、ライン配当額取得関数(新:fnLinPay)と、スキャッター配当額取得関数(新:fnScaPay)に分けました。
 *	  243ウェイ・ルート払い戻しタイプの、配当額取得関数(旧:fnGetPay)を、ウェイ配当額取得(新:fnWayPay)と、スキャッター配当額取得関数(新:fnScaPay)に分けました。
 *	  上記のように変更した理由は、揃ったライン(又はウェイ)によって、配当額が変わるケースに対応するためです。
 *	  揃ったライン(又はウェイ)によって配当額が変わるルールの場合は、引数iLin(又はiRow[])を参照して、揃ったラインに応じた配当額を返して下さい。
 *	  揃ったライン(又はウェイ)によって配当額が変わらないルールの場合は、引数iLin(又はiRow[])を無視して下さい。
 *	* Thu Jul 07 21:12:07 JST 2016 Naoyuki Sawa
 *	- 3行以外の行数に対応しました。
 *	  これまでは、5リール3行固定でしたが、今後は、5リール1行～5リール(VslRow_Max)行まで対応可能になりました。
 *	  行数は、ST_Vsl5nl_GetWin_Inf構造体,又は,ST_Vsl243_GetWin_InfのnRowフィールドで指定して下さい。
 *	- 今回の変更により、'243ウェイ・ルート払い戻しタイプ'は厳密には243ウェイではなく、(nRow^5)ウェイとなります。
 *	  しかし便宜上、243ウェイという名前の方が判り易いので、関数名は変えない事にしました。
 *	- 変更後の検証がまだ不十分です。(特にVsl243_GetWin())
 *	  今後、実際に使いながら、検証する予定です。
 *	* Wed Jul 20 21:23:00 JST 2016 Naoyuki Sawa
 *	- シンボルタイプ(列挙値)を廃止し、シンボル属性(フラグ)に変更しました。
 *	  アプリケーション定義の、シンボルタイプ取得関数(*fnGetTyp)()を、シンボル属性取得関数(*fnGetAtt)()に変更しました。
 *	  この変更によって、通常シンボル,ワイルドシンボル,スキャッターシンボルに加えて、スキャッターワイルドシンボルも表現出来るようになりました。
 *	* Sun Aug 07 21:13:31 JST 2016 Naoyuki Sawa
 *	- VslRel_GetSensorCrossingCount_Linear(),VslRel_GetSensorCrossingCount_Circular()を追加しました。
 *	  直線上,又は,円周上の移動において、特定の位置を跨いだ回数を求める、汎用的な処理ですが、
 *	  今回は、リールアニメーション処理で使用するために作成したので、当モジュールに含める事にしました。
 *	  他の用途にも、使用出来ると思います。
 *	* Mon Aug 29 21:46:36 JST 2016 Naoyuki Sawa
 *	- VslRel_GetSensorExceedingCount_Linear()を追加しました。
 */
#include "clip.h"
/****************************************************************************
 *	共通処理
 ****************************************************************************/
//入賞判定の共通処理を行う。
static int VslCmn_GetWin(int TBL_Sta[5/*iRel*/][VslRow_Max/*iRow*/],
    int nRow,
    int (*fnScaPay)(int iSym, int nOak, void* arg),
    int (*fnGetAtt)(int iSym, void* arg),
    int (*fnGetSta)(int iRel, int iRow, void* arg),
    void (*fnScaWin)(int iSym, int nOak, int nPay, void* arg),
    void* arg) {
	int nPaySum = 0;						//スキャッターシンボルの賞金総額。
	int TBL_Sca[(5*VslRow_Max)/*nSca*/][2/*[0]=iSym,[1]=nOak*/];	//スキャッターシンボルの出現数。スキャッターワイルドシンボルは含めない。	理論上最大で(5*VslRow_Max)種類のスキャッターシンボルが同時に出現しても対応可能である。(まず有り得ないが)
	int nSca = 0;							//スキャッターシンボルの種類数。スキャッターワイルドシンボルは含めない。
	int nScwCnt =  0;						//スキャッターワイルドシンボル出現数。複数種類のスキャッターワイルドシンボルが出現した場合は合算する。
	int iScwSym = -1;						//スキャッターワイルドシンボルの種類。(nScwCnt>=1)の場合のみ有効。複数種類のスキャッターワイルドシンボルが出現した場合はどれを格納するかは不定です。	スキャッターワイルドシンボルだけが出現した場合は、どのスキャッターワイルドシンボルで払い出しても同じ配当となるようにペイテーブルを設計せよ。	←←←←要注意!!
	if((nRow < 1) || (nRow > VslRow_Max)) { DIE(); }
	//--- 停止形を取得する ---
	{
		int iRel;
		for(iRel = 0; iRel < 5; iRel++) {
			int iRow;
			for(iRow = 0; iRow < nRow; iRow++) {
				int iSym = (*fnGetSta)(iRel, iRow, arg);	//シンボルを取得する。
				int iAtt = (*fnGetAtt)(iSym, arg);		//シンボル属性を取得する。
				TBL_Sta[iRel][iRow] = iSym;			//停止形を格納する。
			    //{{停止形を取得しながら、スキャッターウィンの処理も行う。
				//このシンボルがスキャッター属性を持つシンボルならば…
				if(iAtt & VslAtt_Scatter) {
					//このシンボルがワイルド属性を持つシンボルならば…
					if(iAtt & VslAtt_Wild) {
						//スキャッターワイルドシンボル出現数を増やす。
						nScwCnt++;
						//スキャッターワイルドシンボルの種類を格納する。
						iScwSym = iSym;	//既に格納されていた場合も上書きする。(必須ではない。既に格納されている方を優先しても構わない。)
					//このシンボルがワイルド属性を持たないシンボルならば…
					} else {
						//この種類のスキャッターシンボルが既に出現しているか?
						int iSca;
						for(iSca = 0; iSca < nSca; iSca++) {
							if(TBL_Sca[iSca][0/*iSym*/] == iSym) { break; }
						}
						//この種類のスキャッターシンボルが初出ならば、種類を登録する。
						if(iSca == nSca) {
							if(++nSca > ARRAY_SIZE(TBL_Sca)) { DIE(); }	//当関数のバグ
							TBL_Sca[iSca][0/*iSym*/] = iSym;
							TBL_Sca[iSca][1/*nOak*/] = 0;	//すぐこの下で1になる。
						}
						//この種類のスキャッターシンボルの出現数を増やす。
						TBL_Sca[iSca][1/*nOak*/]++;
					}
				}
			    //}}停止形を取得しながら、スキャッターウィンの処理も行う。
			}
		}
	}
	//--- スキャッターウィン ---
	{
		//ワイルド属性を持たないスキャッターシンボルが一種類以上出現していたら、スキャッターワイルドシンボルはそれに含めて通知する。
		//スキャッターワイルドシンボル単体での通知は行わない。
		if(nSca) {
			int iSca;
			for(iSca = 0; iSca < nSca; iSca++) {
				int iSym = TBL_Sca[iSca][0/*iSym*/];
				int nOak = TBL_Sca[iSca][1/*nOak*/] + nScwCnt/*0以上*/;
				int nPay = (*fnScaPay)(iSym, nOak, arg);
				(*fnScaWin)(iSym, nOak, nPay, arg);	//スキャッターウィン通知
				nPaySum += nPay;	//スキャッターシンボルの賞金総額を加算する。
			}
		//ワイルド属性を持たないスキャッターシンボルが一種類も出現していなければ、スキャッターワイルドシンボル単体で通知する。
		//スキャッターワイルドシンボルが二種類以上出現していた場合は、任意の一種類のスキャッターワイルドシンボルに合算して通知する。
		} else if(nScwCnt) {
			int nPay = (*fnScaPay)(iScwSym, nScwCnt, arg);
			(*fnScaWin)(iScwSym, nScwCnt, nPay, arg);	//スキャッターウィン通知
			nPaySum += nPay;		//スキャッターシンボルの賞金総額を加算する。
		}
	}
	return nPaySum;	//スキャッターシンボルの賞金総額を返す。
}
/****************************************************************************
 *	通常ラインタイプ
 ****************************************************************************/
//通常ラインタイプの、入賞判定処理を行う。
//制約:1つのゲームモードの中でワイルドシンボルは1種類以下である事を前提とする。		⇒{{2016/07/20コメント追記:リールストリップとペイテーブルが注意深く設計されていれば、ワイルドシンボルが2種類以上でも対応可能である。ただしワイルドシンボルが2種類以上有る場合の問題点として、例えば{Wa,Wa,Wa,Wb,Pa}の並びを「Waの純粋3oak又はPaの複合5oak」と見なすか「W*の純粋4oak又はPaの複合5oak」と見なすかが曖昧である。現在は前者の判定としている。現在のアリゴリズムでは後者の判定を行う事は不可能であり、もし後者の判定とする場合はアルゴリズムの変更が必要となる。}}
int Vsl5nl_GetWin(const ST_Vsl5nl_GetWin_Inf* pInf, void* arg) {
	int nPaySum;					//賞金総額
	int TBL_Sta[5/*iRel*/][VslRow_Max/*iRow*/];	//停止形
	//--- 共通処理 ---
	{
		nPaySum = VslCmn_GetWin(TBL_Sta,
			pInf->nRow,
			pInf->fnScaPay,
			pInf->fnGetAtt,
			pInf->fnGetSta,
			pInf->fnScaWin,
			arg);
	}
	//--- ラインウィン ---
	{
		int iLin, iRel, iRow, iSym[5], iAtt;
		int iPurSym, nPurOak, nPurPay;	//純粋コンビネーションの、シンボル,出現数,賞金額
		int iCpxSym, nCpxOak, nCpxPay;	//複合コンビネーションの、シンボル,出現数,賞金額
		for(iLin = 0; iLin < pInf->nLin; iLin++) {
			//このライン上のシンボルを取得する。
			for(iRel = 0; iRel < 5; iRel++) {
				iRow = (*pInf->fnGetRow)(iLin, iRel, arg);
				if((unsigned)iRow >= (unsigned)pInf->nRow) { DIE(); }
				iSym[iRel] = TBL_Sta[iRel][iRow];
			}
			//第1リールに、ワイルド属性を持たないスキャッターシンボルが有れば、純粋コンビネーションも複合コンビネーションも成立しない。
			if((*pInf->fnGetAtt)(iSym[0], arg) == VslAtt_Scatter) { continue; }	//次のラインの処理へ
			//純粋コンビネーションの、シンボル,及び,出現数(1～5),及び,賞金額を求める。
			// - '純粋コンビネーション'とは、自分で勝手につけた呼び方です。
			//   'スキャッターシンボル以外の特定のシンボル'が、第1リールから連続して並んでいる事を指します。
			iPurSym = iSym[0];
			for(nPurOak = 1; nPurOak < 5; nPurOak++) {
				iAtt = (*pInf->fnGetAtt)(iSym[nPurOak], arg);	//このシンボルの属性を取得する。
				if(iAtt == VslAtt_Scatter) { break; }		//このシンボルが、ワイルド属性を持たないスキャッターシンボルならば、ここまで。
				if(iSym[nPurOak] != iPurSym) { break; }		//異なるシンボルが出現したら、ここまで。
			}
			nPurPay = (*pInf->fnLinPay)(iPurSym, nPurOak, iLin, arg);
			//複合コンビネーションの、シンボル,及び,出現数(1～5),及び,賞金額を求める。
			// - '複合コンビネーション'とは、自分で勝手につけた呼び方です。
			//   'スキャッターシンボル以外の特定のシンボル'が、0個以上のワイルドシンボルを含んで、第1リールから連続して並んでいる事を指します。
			//   'スキャッターシンボル以外の特定のシンボル'自体が、ワイルドシンボルである事も有り得ます。
			iCpxSym = iSym[0];
			for(nCpxOak = 1; nCpxOak < 5; nCpxOak++) {
				iAtt = (*pInf->fnGetAtt)(iSym[nCpxOak], arg);	//このシンボルの属性を取得する。
				if(iAtt == VslAtt_Scatter) { break; }		//このシンボルが、ワイルド属性を持たないスキャッターシンボルならば、ここまで。
				if(iSym[nCpxOak] != iCpxSym) {			//異なるシンボルが出現したら…
					if(!(iAtt & VslAtt_Wild)) {		//このシンボルがワイルド属性を持っていなければ…
						if(!((*pInf->fnGetAtt)(iCpxSym, arg) & VslAtt_Wild)) { break; }	//ワイルド属性を持っていない初出のシンボルでなければ、ここまで。
						iCpxSym = iSym[nCpxOak];	//ワイルド属性を持っていない初出のシンボルを格納する。
					}
				}
			}
			nCpxPay = (*pInf->fnLinPay)(iCpxSym, nCpxOak, iLin, arg);
			//純粋コンビネーションの賞金額の方が大きければ…
			if(nPurPay > nCpxPay) {
				//純粋コンビネーションを通知する。
				(*pInf->fnLinWin)(iPurSym, nPurOak, iLin, nPurPay, arg);	//ラインウィン通知
				nPaySum += nPurPay;	//賞金総額を加算する。
			//複合コンビネーションの賞金額の方が大きい,又は,同じならば、
			} else {
				//複合コンビネーションを通知する。
				// - 複合コンビネーションの方が、出現数が大きい値になっているはずである。
				//   賞金額が同じ場合、出現数が大きい方で入賞を表示する方が、遊技者に不信感を与えないだろうと思い、こうする事にした。
				(*pInf->fnLinWin)(iCpxSym, nCpxOak, iLin, nCpxPay, arg);	//ラインウィン通知
				nPaySum += nCpxPay;	//賞金総額を加算する。
			}
		}
	}
	return nPaySum;	//賞金総額を返す。
}
/****************************************************************************
 *	243ウェイ・ルート払い戻しタイプ
 ****************************************************************************/
//243ウェイ・ルート払い戻しタイプの、入賞判定処理を行う。
//制約:ワイルドシンボルの並びには配当額が設定されていない事を前提とする。
int Vsl243_GetWin(const ST_Vsl243_GetWin_Inf* pInf, void* arg) {
	int nPaySum;					//賞金総額
	int TBL_Sta[5/*iRel*/][VslRow_Max/*iRow*/];	//停止形
	//--- 共通処理 ---
	{
		nPaySum = VslCmn_GetWin(TBL_Sta,
			pInf->nRow,
			pInf->fnScaPay,
			pInf->fnGetAtt,
			pInf->fnGetSta,
			pInf->fnScaWin,
			arg);
	}
	//--- ウェイウィン ---
	{
		int bWay[5], iRow[5], iSym[5], iAtt, nPay;
		bWay[0] = 0;	//1リールウェイ入賞フラグ
		for(iRow[0] = 0; iRow[0] < pInf->nRow; iRow[0]++) {
			iSym[0] = TBL_Sta[0][iRow[0]];			//このリールのシンボルを取得する。
			iAtt = (*pInf->fnGetAtt)(iSym[0], arg);		//このリールのシンボルの属性を取得する。
			if(iAtt == VslAtt_Scatter) { continue; }	//このシンボルが、ワイルド属性を持たないスキャッターシンボルならば、ここまで。
			if(iAtt & VslAtt_Wild) { iSym[0] = -1; }	//このシンボルがワイルド属性を持っていたら、ワイルドシンボルを示す値として(-1)を格納しておく。
			{
				bWay[1] = 0;	//2リールウェイ入賞フラグ
				for(iRow[1] = 0; iRow[1] < pInf->nRow; iRow[1]++) {
					iSym[1] = TBL_Sta[1][iRow[1]];			//このリールのシンボルを取得する。
					iAtt = (*pInf->fnGetAtt)(iSym[1], arg);		//このリールのシンボルの属性を取得する。
					if(iAtt == VslAtt_Scatter) { continue; }	//このシンボルが、ワイルド属性を持たないスキャッターシンボルならば、ここまで。
					if(iAtt & VslAtt_Wild) { iSym[1] = -1; }	//このシンボルがワイルド属性を持っていたら、ワイルドシンボルを示す値として(-1)を格納しておく。
					if(iSym[0] != iSym[1]) {			//前のリールのシンボルと、このリールのシンボルが違ったら…
						if(iSym[0] != -1) {			//前のリールのシンボルが、ワイルドシンボルでなければ…
							if(iSym[1] != -1) {		//このリールのシンボルがワイルドシンボルでなければ…
								continue;		//このリールのこのウェイから派生する入賞判定を行わない。
							} else {			//このリールのシンボルがワイルドシンボルならば…
								iSym[1] = iSym[0];	//このリールのシンボルを、前のリールのシンボルに合わせる。
							}
						}
					}
					{
						bWay[2] = 0;	//3リールウェイ入賞フラグ
						for(iRow[2] = 0; iRow[2] < pInf->nRow; iRow[2]++) {
							iSym[2] = TBL_Sta[2][iRow[2]];			//このリールのシンボルを取得する。
							iAtt = (*pInf->fnGetAtt)(iSym[2], arg);		//このリールのシンボルの属性を取得する。
							if(iAtt == VslAtt_Scatter) { continue; }	//このシンボルが、ワイルド属性を持たないスキャッターシンボルならば、ここまで。
							if(iAtt & VslAtt_Wild) { iSym[2] = -1; }	//このシンボルがワイルド属性を持っていたら、ワイルドシンボルを示す値として(-1)を格納しておく。
							if(iSym[1] != iSym[2]) {			//前のリールのシンボルと、このリールのシンボルが違ったら…
								if(iSym[1] != -1) {			//前のリールのシンボルが、ワイルドシンボルでなければ…
									if(iSym[2] != -1) {		//このリールのシンボルがワイルドシンボルでなければ…
										continue;		//このリールのこのウェイから派生する入賞判定を行わない。
									} else {			//このリールのシンボルがワイルドシンボルならば…
										iSym[2] = iSym[1];	//このリールのシンボルを、前のリールのシンボルに合わせる。
									}
								}
							}
							{
								bWay[3] = 0;	//4リールウェイ入賞フラグ
								for(iRow[3] = 0; iRow[3] < pInf->nRow; iRow[3]++) {
									iSym[3] = TBL_Sta[3][iRow[3]];			//このリールのシンボルを取得する。
									iAtt = (*pInf->fnGetAtt)(iSym[3], arg);		//このリールのシンボルの属性を取得する。
									if(iAtt == VslAtt_Scatter) { continue; }	//このシンボルが、ワイルド属性を持たないスキャッターシンボルならば、ここまで。
									if(iAtt & VslAtt_Wild) { iSym[3] = -1; }	//このシンボルがワイルド属性を持っていたら、ワイルドシンボルを示す値として(-1)を格納しておく。
									if(iSym[2] != iSym[3]) {			//前のリールのシンボルと、このリールのシンボルが違ったら…
										if(iSym[2] != -1) {			//前のリールのシンボルが、ワイルドシンボルでなければ…
											if(iSym[3] != -1) {		//このリールのシンボルがワイルドシンボルでなければ…
												continue;		//このリールのこのウェイから派生する入賞判定を行わない。
											} else {			//このリールのシンボルがワイルドシンボルならば…
												iSym[3] = iSym[2];	//このリールのシンボルを、前のリールのシンボルに合わせる。
											}
										}
									}
									{
										bWay[4] = 0;	//5リールウェイ入賞フラグ
										for(iRow[4] = 0; iRow[4] < pInf->nRow; iRow[4]++) {
											iSym[4] = TBL_Sta[4][iRow[4]];			//このリールのシンボルを取得する。
											iAtt = (*pInf->fnGetAtt)(iSym[4], arg);		//このリールのシンボルの属性を取得する。
											if(iAtt == VslAtt_Scatter) { continue; }	//このシンボルが、ワイルド属性を持たないスキャッターシンボルならば、ここまで。
											if(iAtt & VslAtt_Wild) { iSym[4] = -1; }	//このシンボルがワイルド属性を持っていたら、ワイルドシンボルを示す値として(-1)を格納しておく。
											if(iSym[3] != iSym[4]) {			//前のリールのシンボルと、このリールのシンボルが違ったら…
												if(iSym[3] != -1) {			//前のリールのシンボルが、ワイルドシンボルでなければ…
													if(iSym[4] != -1) {		//このリールのシンボルがワイルドシンボルでなければ…
														continue;		//このリールのこのウェイから派生する入賞判定を行わない。
													} else {			//このリールのシンボルがワイルドシンボルならば…
														iSym[4] = iSym[3];	//このリールのシンボルを、前のリールのシンボルに合わせる。
													}
												}
											}
											//5リールウェイ入賞判定
											if(iSym[4] != -1) {	//このリールまでに一つでもワイルドシンボル以外が有れば…	「243ウェイ・ルート払い戻しタイプ」においては、ワイルドシンボルだけの並びに対して配当を設定しない。後述のコメントを参照せよ。
												nPay = (*pInf->fnWayPay)(iSym[4], 5/*nOak*/, iRow, arg);
												(*pInf->fnWayWin)(iSym[4], 5/*nOak*/, iRow, nPay, arg);	//ウェイウィン通知
												nPaySum += nPay;	//賞金総額を加算する。
												bWay[4] = 1;	//5リールウェイ入賞有り
											}
										}
										if(bWay[4]) {	//5リールウェイ入賞有りならば、この4リールウェイ以下の入賞判定を行わない。
											bWay[3] = 1;	//4リールウェイ入賞有りと見なす
										} else {
											//4リールウェイ入賞判定
											if(iSym[3] != -1) {	//このリールまでに一つでもワイルドシンボル以外が有れば…	「243ウェイ・ルート払い戻しタイプ」においては、ワイルドシンボルだけの並びに対して配当を設定しない。後述のコメントを参照せよ。
												nPay = (*pInf->fnWayPay)(iSym[3], 4/*nOak*/, iRow, arg);
												(*pInf->fnWayWin)(iSym[3], 4/*nOak*/, iRow, nPay, arg);	//ウェイウィン通知
												nPaySum += nPay;	//賞金総額を加算する。
												bWay[3] = 1;	//4リールウェイ入賞有り
											}
										}
									}
								}
								if(bWay[3]) {	//4リールウェイ入賞有りならば、この3リールウェイ以下の入賞判定を行わない。
									bWay[2] = 1;	//3リールウェイ入賞有りと見なす
								} else {
									//3リールウェイ入賞判定
									if(iSym[2] != -1) {	//このリールまでに一つでもワイルドシンボル以外が有れば…	「243ウェイ・ルート払い戻しタイプ」においては、ワイルドシンボルだけの並びに対して配当を設定しない。後述のコメントを参照せよ。
										nPay = (*pInf->fnWayPay)(iSym[2], 3/*nOak*/, iRow, arg);
										(*pInf->fnWayWin)(iSym[2], 3/*nOak*/, iRow, nPay, arg);	//ウェイウィン通知
										nPaySum += nPay;	//賞金総額を加算する。
										bWay[2] = 1;	//3リールウェイ入賞有り
									}
								}
							}
						}
						if(bWay[2]) {	//3リールウェイ入賞有りならば、この2リールウェイ以下の入賞判定を行わない。
							bWay[1] = 1;	//2リールウェイ入賞有りと見なす
						} else {
							//2リールウェイ入賞判定
							if(iSym[1] != -1) {	//このリールまでに一つでもワイルドシンボル以外が有れば…	「243ウェイ・ルート払い戻しタイプ」においては、ワイルドシンボルだけの並びに対して配当を設定しない。後述のコメントを参照せよ。
								nPay = (*pInf->fnWayPay)(iSym[1], 2/*nOak*/, iRow, arg);
								(*pInf->fnWayWin)(iSym[1], 2/*nOak*/, iRow, nPay, arg);	//ウェイウィン通知
								nPaySum += nPay;	//賞金総額を加算する。
								bWay[1] = 1;	//2リールウェイ入賞有り
							}
						}
					}
				}
				if(bWay[1]) {	//2リールウェイ入賞有りならば、この1リールウェイ以下の入賞判定を行わない。
					bWay[0] = 1;	//1リールウェイ入賞有りと見なす
				} else {
					//1リールウェイ入賞判定
					if(iSym[0] != -1) {	//このリールまでに一つでもワイルドシンボル以外が有れば…	「243ウェイ・ルート払い戻しタイプ」においては、ワイルドシンボルだけの並びに対して配当を設定しない。後述のコメントを参照せよ。
						nPay = (*pInf->fnWayPay)(iSym[0], 1/*nOak*/, iRow, arg);
						(*pInf->fnWayWin)(iSym[0], 1/*nOak*/, iRow, nPay, arg);	//ウェイウィン通知
						nPaySum += nPay;	//賞金総額を加算する。
						bWay[0] = 1;	//1リールウェイ入賞有り
					}
				}
			}
		}
	}
	return nPaySum;	//賞金総額を返す。
}
//■「243ウェイ・ルート払い戻しタイプ」においては、ワイルドシンボルだけの並びに対して配当を設定しない。
//│そうしないと、以下の例のような問題が生じるからです。
//□問題が生じる例
//│仮にワイルドシンボルだけの並びに対して配当を設定したと仮定して、下表のようなペイテーブルを設定したとする。
//│  PayTable
//│    Sym 4oak 5oak
//│    Wd    10   15
//│    Pa     1    5
//│    Pb     2   20
//│遊技中に、下図のような停止形が出現したとする。
//│  1st 2nd 3rd 4th 5th
//│   -   -   -   -  Pa 
//│  Wd  Wd  Wd  Wd   - 
//│   -   -   -   -  Pb 
//│この時、賞金額が決定出来ない問題が生じる。具体的には、以下の通りです。
//│  ①仮に「Wd Wd Wd Wd Pa」と「Wd Wd Wd Wd Pb」に対して払い出しを行った場合、
//│    「Wd Wd Wd Wd」よりも「Wd Wd Wd Wd Wa」の方が安いのに、「Wd Wd Wd Wd」を捨てて「Wd Wd Wd Wd Wa」を取って良いのか？という問題が生じる。
//│  ②仮に「Wd Wd Wd Wd」と「Wd Wd Wd Wd Pb」に対して払い出しを行った場合、
//│    「Wd Wd Wd Wd」は「Wd Wd Wd Wd Pb」に含まれるのに、両方に払い出して良いのか？という問題が生じる。
//│①②どちらの方法を取っても、243ウェイ機の原則である、「ウェイ毎に最大の賞金の組み合わせだけに対して支払われる」というルールに反してしまう。
//□解決方法
//│既存のオンラインビデオスロットでは、ワイルドシンボルだけの並びに対して配当を設定しない事で、上記の問題を回避している。
//│また、1stリールにワイルドシンボルを配置しない事で、ワイルドシンボルだけの並びに対して配当を設定しない事を自然に見せている機種も多いようだ。
/****************************************************************************
 *	リールアニメーション処理の補助関数
 ****************************************************************************/
//直線上の移動において、センサを跨いだ回数を求める。
//[in]
//		oldpos		移動前の位置
//		vec		移動距離					(vec＞0.0)ならば正方向の移動、(vec＜0.0)ならば逆方向の移動、(vec＝0.0)ならば移動無し
//		snspos		センサの位置
//		pnewpos		移動後の位置を格納する変数へのポインタ		NULLを指定すると、移動後の位置を格納しません。
//[out]
//		戻り値		正方向にセンサを跨いだ回数(1),又は,逆方向にセンサを跨いだ回数(-1),又は,センサを跨いでいない(0)を返す。
//[note]
//		- 正方向の移動の場合、移動前の位置がセンサの位置未満で、移動後の位置がセンサの位置以上ならば、センサを跨いだと見なす。
//		  逆方向の移動の場合、移動前の位置がセンサの位置以上で、移動後の位置がセンサの位置未満ならば、センサを跨いだと見なす。
//		- リールアニメーション処理では、多分、VslRel_GetSensorCrossingCount_Circular()しか使わないと思います。
//		  VslRel_GetSensorCrossingCount_Linear()は、一応、用意しておいただけで、多分、使う事は無いと思います。
int VslRel_GetSensorCrossingCount_Linear(double oldpos, double vec, double snspos, double* pnewpos/*NULL可*/) {
	int count = 0;	//この変数に、正方向にセンサを跨いだ回数(1),又は,逆方向にセンサを跨いだ回数(-1),又は,センサを跨いでいない(0)を格納する。
	//移動後の位置を求める。
	const double newpos = oldpos + vec;
	//移動方向が正方向ならば…
	if(vec > 0.0) {
		//移動前の位置がセンサの位置未満で、移動後の位置がセンサの位置以上ならば、正方向にセンサを跨いだと見なして1加算する。
		if((oldpos < snspos) && (newpos >= snspos)) { count++; }
	//移動方向が逆方向ならば…
	} else if(vec < 0.0) {
		//移動前の位置がセンサの位置以上で、移動後の位置がセンサの位置未満ならば、逆方向にセンサを跨いだと見なして1減算する。
		if((oldpos >= snspos) && (newpos < snspos)) { count--; }
	//移動方向が無ければ…
	} else {
		/** no job **/
	}
	//移動後の位置を格納する変数のポインタが指定されていたら、移動後の位置を格納する。
	if(pnewpos) { *pnewpos = newpos; }
	//正方向にセンサを跨いだ回数(1),又は,逆方向にセンサを跨いだ回数(-1),又は,センサを跨いでいない(0)を返す。
	return count;
}
/*--------------------------------------------------------------------------*/
//円周上の移動において、センサを跨いだ回数を求める。
//[in]
//		oldpos		移動前の位置					[lbound,ubound)の範囲外を指定しても構いません。当関数が自動的に補正します。			リールアニメーション処理においては、現在のリール位置を指定する事になるだろう。
//		vec		移動距離					(vec＞0.0)ならば正方向の移動、(vec＜0.0)ならば逆方向の移動、(vec＝0.0)ならば移動無し		リールアニメーション処理においては、回転速度を指定する事になるだろう。
//		snspos		センサの位置					[lbound,ubound)の範囲外を指定しても構いません。当関数が自動的に補正します。			リールアニメーション処理においては、停止アニメーション状態(バウンド状態など)へ移行するリール位置を指定する事になるだろう。
//		lbound		下界						┬位置の値を[lbound,ubound)の範囲に補正します。							リールアニメーション処理においては、0.0を指定する事になるだろう。
//		ubound		上界						┘												リールアニメーション処理においては、リールストリップ長を指定する事になるだろう。
//		pnewpos		移動後の位置を格納する変数へのポインタ		NULLを指定すると、移動後の位置を格納しません。							呼び出し側で移動後の位置を別途計算しても構わないが、演算誤差でセンサを跨いだ位置と移動後の位置が矛盾する事を避けるために、当関数が返した移動後の位置を使用する方が望ましい。
//[out]
//		戻り値		正方向にセンサを跨いだ回数(N),又は,逆方向にセンサを跨いだ回数(-N),又は,センサを跨いでいない(0)を返す。						リールアニメーション処理においては、0か0以外かしか見なくて良いだろう。一回の移動で一周分以上回るような速度は設定しないし、万一有ったとしても最初のトリガ以外は無視するから。
//[note]
//		- 正方向の移動の場合、移動前の位置がセンサの位置未満で、移動後の位置がセンサの位置以上ならば、センサを跨いだと見なす。
//		  逆方向の移動の場合、移動前の位置がセンサの位置以上で、移動後の位置がセンサの位置未満ならば、センサを跨いだと見なす。
int VslRel_GetSensorCrossingCount_Circular(double oldpos, double vec, double snspos, double lbound, double ubound, double* pnewpos/*NULL可*/) {
	int count = 0;	//この変数に、正方向にセンサを跨いだ回数(N),又は,逆方向にセンサを跨いだ回数(-N),又は,センサを跨いでいない(0)を格納する。
	//領域の幅を求める。
	const double width = ubound - lbound;
	if(width <= 0.0) { DIE(); }	//(lbound≧ubound)が指定された。呼び出し側のバグです。
	//移動前の位置を、[lbound,ubound)の範囲に補正する。
	oldpos -= lbound;
	oldpos = fmod(oldpos, width);
	if(oldpos < 0.0) { oldpos += width; }
	oldpos += lbound;
	//センサの位置を、[lbound,ubound)の範囲に補正する。
	snspos -= lbound;
	snspos = fmod(snspos, width);
	if(snspos < 0.0) { snspos += width; }
	snspos += lbound;
	{
		//初回のために、移動前の位置を、仮想的な前回の移動後の位置とする。
		double newpos = oldpos;
		//移動方向が正方向ならば…
		if(vec > 0.0) {
			do {
				//前回の移動後の位置を、今回の移動前の位置とする。
				oldpos = newpos;
				//移動後の位置を求める。
				newpos = oldpos + vec;	//(newpos≧ubound)になっても構わない。
				//移動前の位置がセンサの位置未満で、移動後の位置がセンサの位置以上ならば、正方向にセンサを跨いだと見なして1加算する。
				if((oldpos < snspos) && (newpos >= snspos)) { count++; }
				//移動後の位置が上界を超過した分を、次回の移動距離とする。
				vec = newpos - ubound;	//(vec＜0.0)になっても構わない。								//┐
				//移動後の位置が上界以上ならば…											//│
				if(vec >= 0.0) {	//「if(newpos>=ubound){～」で判定しても同じです。	①←┐					//├この処理順序を逆にしないように注意!!
					//移動後の位置を、下界に折り返す。					//　│					//│
					newpos = lbound;							//　│					//┘
					//移動後の位置がセンサの位置以上(イコール判定でも構わない)ならば、正方向にセンサを跨いだと見なして1加算する。	//┬(snspos==lbound)が指定された場合のための判定処理です。
					if(newpos >= snspos) { count++; }	//(newpos==snspos)で判定しても構わない。				//┘(newpos==snspos)でなく(newpos>=snspos)で判定した理由は、上の処理と見た目を合わせるためだけで、実際にはどちらでも構いません。
				}										//　│
			} while(vec > 0.0);	//次回の移動距離が残っている間、繰り返す。			②←┴①は≧,②は＞である事に注意しろ。
		//移動方向が逆方向ならば…
		} else if(vec < 0.0) {
			do {
				//前回の移動後の位置を、今回の移動前の位置とする。
				oldpos = newpos;
				//移動後の位置を求める。
				newpos = oldpos + vec;	//(newpos＜lbound)になっても構わない。
				//移動前の位置がセンサの位置以上で、移動後の位置がセンサの位置未満ならば、逆方向にセンサを跨いだと見なして1減算する。	//┬(snspos==lbound)が指定された場合もここで判定出来ます。
				if((oldpos >= snspos) && (newpos < snspos)) { count--; }								//┘移動方向が正方向の場合の処理と違って、移動後の位置を折り返す処理の中で、センサを跨いだかどうかの判定を行う必要は有りません。
				//移動後の位置が下界を下回った分を、次回の移動距離とする。
				vec = newpos - lbound;	//(vec＞0.0)になっても構わない。								//┐
				//移動後の位置が下界未満ならば…											//│
				if(vec < 0.0) {		//「if(newpos<lbound){～」で判定しても同じです。						//├この処理順序を逆にしないように注意!!
					//移動後の位置を、上界に折り返す。										//│
					newpos = ubound;	//一時的に[lbound,ubound)の範囲外となりますが、必ず次回のループが有るので大丈夫です。	//┘
				}
			} while(vec < 0.0);	//次回の移動距離が残っている間、繰り返す。
		}
		//移動後の位置を格納する変数のポインタが指定されていたら、移動後の位置を格納する。
		if(pnewpos) { *pnewpos = newpos; }
	}
	//正方向にセンサを跨いだ回数(N),又は,逆方向にセンサを跨いだ回数(-N),又は,センサを跨いでいない(0)を返す。
	return count;
}
/*--------------------------------------------------------------------------*/
//□テストスイート
#if 0
void TestSuite() {
	int count;
	double oldpos, vec, snspos, newpos, lbound, ubound;
	//=== VslRel_GetSensorCrossingCount_Linear ===
	//--- Test1.1 ---
	puts("Test1.1");
	//			0.0		1.0
	//			▽				センサ
	//			★──────→☆		移動前→移動後
	oldpos = 0.0, vec = 1.0, snspos = 0.0;
	count = VslRel_GetSensorCrossingCount_Linear(oldpos, vec, snspos, &newpos);
	printf("count = % d, oldpos = % .1f, vec = % .1f, snspos = % .1f, newpos = % .1f\n", count, oldpos, vec, snspos, newpos);	//count =  0, oldpos =  0.0, vec =  1.0, snspos =  0.0, newpos =  1.0
	//			0.0		1.0
	//			▽				センサ
	//			☆←──────★		移動前→移動後
	oldpos = newpos, vec = -vec;
	count = VslRel_GetSensorCrossingCount_Linear(oldpos, vec, snspos, &newpos);
	printf("count = % d, oldpos = % .1f, vec = % .1f, snspos = % .1f, newpos = % .1f\n", count, oldpos, vec, snspos, newpos);	//count =  0, oldpos =  0.0, vec =  1.0, snspos =  0.0, newpos =  1.0
	//--- Test1.2 ---
	puts("Test1.2");
	//		-0.5	0.0	0.5
	//			▽					センサ
	//		★──────→☆			移動前→移動後
	oldpos = -0.5, vec = 1.0, snspos = 0.0;
	count = VslRel_GetSensorCrossingCount_Linear(oldpos, vec, snspos, &newpos);
	printf("count = % d, oldpos = % .1f, vec = % .1f, snspos = % .1f, newpos = % .1f\n", count, oldpos, vec, snspos, newpos);	//count =  1, oldpos = -0.5, vec =  1.0, snspos =  0.0, newpos =  0.5
	//		-0.5	0.0	0.5
	//			▽					センサ
	//		☆←──────★			移動前→移動後
	oldpos = newpos, vec = -vec;
	count = VslRel_GetSensorCrossingCount_Linear(oldpos, vec, snspos, &newpos);
	printf("count = % d, oldpos = % .1f, vec = % .1f, snspos = % .1f, newpos = % .1f\n", count, oldpos, vec, snspos, newpos);	//count = -1, oldpos =  0.5, vec = -1.0, snspos =  0.0, newpos = -0.5
	//--- Test1.3 ---
	puts("Test1.3");
	//	-1.0		0.0
	//			▽					センサ
	//	★──────→☆				移動前→移動後
	oldpos = -1.0, vec = 1.0, snspos = 0.0;
	count = VslRel_GetSensorCrossingCount_Linear(oldpos, vec, snspos, &newpos);
	printf("count = % d, oldpos = % .1f, vec = % .1f, snspos = % .1f, newpos = % .1f\n", count, oldpos, vec, snspos, newpos);	//count =  1, oldpos = -1.0, vec =  1.0, snspos =  0.0, newpos =  0.0
	//	-1.0		0.0
	//			▽					センサ
	//	☆←──────★				移動前→移動後
	oldpos = newpos, vec = -vec;
	count = VslRel_GetSensorCrossingCount_Linear(oldpos, vec, snspos, &newpos);
	printf("count = % d, oldpos = % .1f, vec = % .1f, snspos = % .1f, newpos = % .1f\n", count, oldpos, vec, snspos, newpos);	//count = -1, oldpos =  0.0, vec = -1.0, snspos =  0.0, newpos = -1.0
	//=== VslRel_GetSensorCrossingCount_Circular ===
	//--- Test2.1 ---
	puts("Test2.1");
	//		-0.5	0.0		1.0	1.5
	//		●				〇	下界～上界
	//			▽				センサ
	//			★──────→☆		移動前→移動後
	oldpos = 0.0, vec = 1.0, snspos = 0.0, lbound = -0.5, ubound = 1.5;
	count = VslRel_GetSensorCrossingCount_Circular(oldpos, vec, snspos, lbound, ubound, &newpos);
	printf("count = % d, oldpos = % .1f, vec = % .1f, snspos = % .1f, lbound = % .1f, ubound = % .1f, newpos = % .1f\n", count, oldpos, vec, snspos, lbound, ubound, newpos);	//count =  0, oldpos =  0.0, vec =  1.0, snspos =  0.0, lbound = -0.5, ubound =  1.5, newpos =  1.0
	//		-0.5	0.0		1.0	1.5
	//		●				〇	下界～上界
	//			▽				センサ
	//			☆←──────★		移動前→移動後
	oldpos = newpos, vec = -vec;
	count = VslRel_GetSensorCrossingCount_Circular(oldpos, vec, snspos, lbound, ubound, &newpos);
	printf("count = % d, oldpos = % .1f, vec = % .1f, snspos = % .1f, lbound = % .1f, ubound = % .1f, newpos = % .1f\n", count, oldpos, vec, snspos, lbound, ubound, newpos);	//count =  0, oldpos =  1.0, vec = -1.0, snspos =  0.0, lbound = -0.5, ubound =  1.5, newpos =  0.0
	//--- Test2.2 ---
	puts("Test2.2");
	//			0.0		1.0
	//			●		〇		下界～上界
	//			▽				センサ
	//			★──────→		移動前→移動後
	//			☆
	oldpos = 0.0, vec = 1.0, snspos = 0.0, lbound = 0.0, ubound = 1.0;
	count = VslRel_GetSensorCrossingCount_Circular(oldpos, vec, snspos, lbound, ubound, &newpos);
	printf("count = % d, oldpos = % .1f, vec = % .1f, snspos = % .1f, lbound = % .1f, ubound = % .1f, newpos = % .1f\n", count, oldpos, vec, snspos, lbound, ubound, newpos);	//count =  1, oldpos =  0.0, vec =  1.0, snspos =  0.0, lbound =  0.0, ubound =  1.0, newpos =  0.0
	//			0.0		1.0
	//			●		〇		下界～上界
	//			▽				センサ
	//			★				移動前→移動後
	//			☆←──────
	oldpos = newpos, vec = -vec;
	count = VslRel_GetSensorCrossingCount_Circular(oldpos, vec, snspos, lbound, ubound, &newpos);
	printf("count = % d, oldpos = % .1f, vec = % .1f, snspos = % .1f, lbound = % .1f, ubound = % .1f, newpos = % .1f\n", count, oldpos, vec, snspos, lbound, ubound, newpos);	//count = -1, oldpos =  0.0, vec = -1.0, snspos =  0.0, lbound =  0.0, ubound =  1.0, newpos =  0.0
	//--- Test2.3 ---
	puts("Test2.3");
	//			0.0	0.5	1.0
	//			●		〇		下界～上界
	//				▽			センサ
	//			★──────→		移動前→移動後
	//			☆
	oldpos = 0.0, vec = 1.0, snspos = 0.5, lbound = 0.0, ubound = 1.0;
	count = VslRel_GetSensorCrossingCount_Circular(oldpos, vec, snspos, lbound, ubound, &newpos);
	printf("count = % d, oldpos = % .1f, vec = % .1f, snspos = % .1f, lbound = % .1f, ubound = % .1f, newpos = % .1f\n", count, oldpos, vec, snspos, lbound, ubound, newpos);	//count =  1, oldpos =  0.0, vec =  1.0, snspos =  0.5, lbound =  0.0, ubound =  1.0, newpos =  0.0
	//			0.0	0.5	1.0
	//			●		〇		下界～上界
	//				▽			センサ
	//			★				移動前→移動後
	//			☆←──────
	oldpos = newpos, vec = -vec;
	count = VslRel_GetSensorCrossingCount_Circular(oldpos, vec, snspos, lbound, ubound, &newpos);
	printf("count = % d, oldpos = % .1f, vec = % .1f, snspos = % .1f, lbound = % .1f, ubound = % .1f, newpos = % .1f\n", count, oldpos, vec, snspos, lbound, ubound, newpos);	//count = -1, oldpos =  0.0, vec = -1.0, snspos =  0.5, lbound =  0.0, ubound =  1.0, newpos =  0.0
	//--- Test2.4 ---
	puts("Test2.4");
	//			0.0	0.5	1.0
	//			●		〇		下界～上界
	//				▽			センサ
	//			★──────→		移動前→移動後
	//			　──────→
	//			　──────→
	//			☆
	oldpos = 0.0, vec = 3.0, snspos = 0.5, lbound = 0.0, ubound = 1.0;
	count = VslRel_GetSensorCrossingCount_Circular(oldpos, vec, snspos, lbound, ubound, &newpos);
	printf("count = % d, oldpos = % .1f, vec = % .1f, snspos = % .1f, lbound = % .1f, ubound = % .1f, newpos = % .1f\n", count, oldpos, vec, snspos, lbound, ubound, newpos);	//count =  3, oldpos =  0.0, vec =  3.0, snspos =  0.5, lbound =  0.0, ubound =  1.0, newpos =  0.0
	//			0.0	0.5	1.0
	//			●		〇		下界～上界
	//				▽			センサ
	//			★				移動前→移動後
	//			　←──────
	//			　←──────
	//			☆←──────
	oldpos = newpos, vec = -vec;
	count = VslRel_GetSensorCrossingCount_Circular(oldpos, vec, snspos, lbound, ubound, &newpos);
	printf("count = % d, oldpos = % .1f, vec = % .1f, snspos = % .1f, lbound = % .1f, ubound = % .1f, newpos = % .1f\n", count, oldpos, vec, snspos, lbound, ubound, newpos);	//count = -3, oldpos =  0.0, vec = -3.0, snspos =  0.5, lbound =  0.0, ubound =  1.0, newpos =  0.0
	//--- Test2.5 ---
	puts("Test2.5");
	//			0.0	0.5	1.0
	//			●		〇		下界～上界
	//				▽			センサ
	//			★──────→		移動前→移動後
	//			　──────→
	//			　─────→☆
	oldpos = 0.0, vec = 2.9, snspos = 0.5, lbound = 0.0, ubound = 1.0;
	count = VslRel_GetSensorCrossingCount_Circular(oldpos, vec, snspos, lbound, ubound, &newpos);
	printf("count = % d, oldpos = % .1f, vec = % .1f, snspos = % .1f, lbound = % .1f, ubound = % .1f, newpos = % .1f\n", count, oldpos, vec, snspos, lbound, ubound, newpos);	//count =  3, oldpos =  0.0, vec =  2.9, snspos =  0.5, lbound =  0.0, ubound =  1.0, newpos =  0.9
	//			0.0	0.5	1.0
	//			●		〇		下界～上界
	//				▽			センサ
	//			　←─────★		移動前→移動後
	//			　←──────
	//			☆←──────
	oldpos = newpos, vec = -vec;
	count = VslRel_GetSensorCrossingCount_Circular(oldpos, vec, snspos, lbound, ubound, &newpos);
	printf("count = % d, oldpos = % .1f, vec = % .1f, snspos = % .1f, lbound = % .1f, ubound = % .1f, newpos = % .1f\n", count, oldpos, vec, snspos, lbound, ubound, newpos);	//count = -3, oldpos =  0.9, vec = -2.9, snspos =  0.5, lbound =  0.0, ubound =  1.0, newpos =  0.0
}
#endif
/*--------------------------------------------------------------------------*/
//□使用例
#if 0
//※TODO:
#endif
/*--------------------------------------------------------------------------*/
//直線上の移動において、センサを超えた回数を求める。
//[in]
//		oldpos		移動前の位置
//		vec		移動距離					(vec＞0.0)ならば正方向の移動、(vec＜0.0)ならば逆方向の移動、(vec＝0.0)ならば移動無し
//		snspos		センサの位置
//		pnewpos		移動後の位置を格納する変数へのポインタ		NULLを指定すると、移動後の位置を格納しません。
//[out]
//		戻り値		正方向にセンサを超えた回数(1),又は,逆方向にセンサを超えた回数(-1),又は,センサを超えていない(0)を返す。
//[note]
//		- 正方向の移動の場合、移動前の位置に関係無く、移動後の位置がセンサの位置以上ならば、センサを超えたと見なす。
//		  逆方向の移動の場合、移動前の位置に関係無く、移動後の位置がセンサの位置未満ならば、センサを超えたと見なす。
//		- 実際の用途としては、位置の判定ではなく、速度の判定を行うために、当関数を追加しました。
//		  <使用例>
//		  │void BoundStart() {
//		  │        double dSpeed       =  1.0;	//初速度
//		  │  const double dAccel       = -0.3;	//加減速度
//		  │  const double dTargetSpeed = -1.0;	//目標速度
//		  │  for(;;) {
//		  │    schedule();
//		  │    //現在速度に加減速度(+ならば正方向加速,-ならば逆方向加速)を加算して、現在速度が目標速度に達したら…
//		  │    if(VslRel_GetSensorExceedingCount_Linear(dSpeed, dAccel, dTargetSpeed, &dSpeed)) {
//		  │      //現在速度を、目標速度に切り詰める。
//		  │      dSpeed = dTargetSpeed;
//		  │      //目標速度に到達した時の処理を行う。
//		  │      printf("目標速度に到達しました。\n"); //実際には、状態遷移等の処理を行う。
//		  │    }
//		  │  }
//		  │}
int VslRel_GetSensorExceedingCount_Linear(double oldpos, double vec, double snspos, double* pnewpos/*NULL可*/) {
	int count = 0;	//この変数に、正方向にセンサを超えた回数(1),又は,逆方向にセンサを超えた回数(-1),又は,センサを超えていない(0)を格納する。
	//移動後の位置を求める。
	const double newpos = oldpos + vec;
	//移動方向が正方向ならば…
	if(vec > 0.0) {
		//移動前の位置に関係無く、移動後の位置がセンサの位置以上ならば、正方向にセンサを超えたと見なして1加算する。
		if(newpos >= snspos) { count++; }
	//移動方向が逆方向ならば…
	} else if(vec < 0.0) {
		//移動前の位置に関係無く、移動後の位置がセンサの位置未満ならば、逆方向にセンサを超えたと見なして1減算する。
		if(newpos <  snspos) { count--; }
	//移動方向が無ければ…
	} else {
		/** no job **/
	}
	//移動後の位置を格納する変数のポインタが指定されていたら、移動後の位置を格納する。
	if(pnewpos) { *pnewpos = newpos; }
	//正方向にセンサを超えた回数(1),又は,逆方向にセンサを超えた回数(-1),又は,センサを超えていない(0)を返す。
	return count;
}
