MJexeIO.DLL(東風荘画面入出力用ダイナミックリンクライブラリ) 開発者マニュアル


★使用法★

通常のDLLと同様です。現バージョンにはヘッダファイルがありません。
C++以外からの利用法は、各自で調べてください(動作保証はしませんが利用可能でしょう。どうやるかまでは知りません)。
下はC++ Builderでボタンを押したときにドラを取得して表示するためのサンプルコードです。
一般に、東風の画面からデータを読む時には、東風の画面がユーザに見えていなければいけません。
ユーザが東風のウインドウを画面端に追いやっていたり、他のウインドウによって見えなくなっている場合にはうまく情報を取得できません。
そのような可能性に対するエラーチェックは別途行ってください。

(一部の関数をインポートしていないかもしれない。必要ならこれを参考にして、使いたい関数を適宜追加すること)

//★以下はヘッダ部分に記述
//インポート関数の型定義(下の各関数の説明を読んで、同じ型で定義します)
typedef int (*GETTEHAI)(int,int *);
typedef int (*GETSUTEHAI)(int,int,int *);
typedef int (*GETSUTEHAIEX)(int,int,int *,int *);
typedef int (*GETSUTEHAIEX2)(int,int,int *,int *,int *,int *);
typedef int (*GETSUTEHAINUM)(int,int,int *);
typedef int (*GETDLLVERSION)(void);
typedef int (*GETKAZE)(int);
typedef int (*GETTURNPLAYER)(int);
typedef int (*GETFUROHAI)(int,int,int *);
typedef int (*GETTONPUDATA)(char *);
typedef int (*GETHAISIZE)(void);
typedef int (*GETDORAHAI)(int,int *);
typedef int (*PUSHHAI)(int,int);
typedef int (*PUSHFUNCTIONKEY)(int);
typedef int (*RCLICK)(void);
typedef int (*GETTONPUINFO)(HWND *,HWND *);
typedef int (*CHECK_TENPAI)(int *,int *);
typedef int (*CHECK_AGARI)(int *,int);
typedef int (*SETMODE)(int);
typedef int (*GETAVAILABLEFUNCTIONKEY)(int *,int);
typedef int (*EXISTAVAILABLEFUNCTIONKEY)(int);
typedef int (*GETRIGHTESTTEHAI)(void);
typedef int (*EXT_GETHAI)(int,int,int,int);
typedef int (*GETPLAYERINFO)(int *,int *,int,int) ;
typedef int (*GETHOLDTIME)(int);
typedef int (*GETREACH)(int,int);
typedef int (*SENDCHAT)(char *,int,int);
typedef int (*SIMULATEORDER)(int,int *,int *,int *,int *,int *,int *,int *,int *,int *,int *,int *,int *,int *,int *);
typedef int (*GETORDER)(int,int,int,int);
typedef int (*GETNEXTORDER)(int,int,int *);
typedef int (*GETEXTENDINFORMATION)(int *,int);
typedef int (*GETEXTENDINFORMATIONSIZE)(void);
typedef int (*SETTONPUCONNECTIONINFO)(int,char *,char *);
typedef int (*CANSELTONPUCONNECTION)(void);
typedef int (*GETTONPUCONNECTIONSTATUS)(void);
typedef int (*PUSHTONPUCONNECTIONBUTTON)(void);
typedef int (*SUPERQUICKWATCHING)(void);
typedef int (*PUSHYOYAKUBUTTON)(void);
typedef int (*PUSHTORIKESIBUTTON)(void);
typedef int (*PUSHJOUHOUBUTTON)(void);
typedef int (*PUSHKANSENBUTTON)(void);
typedef int (*PUSHSYUURYOUBUTTON)(void);
typedef int (*SELECTTAKU)(int,int);
typedef int (*GETCHATLINENUM)(void);
typedef int (*GETCHATLINE)(char *,int);
typedef int (*GETPLAYINFO)(int *);

//インポート関数型の関数へのポインタ変数宣言
GETTEHAI GetTehai;
GETSUTEHAI GetSutehai;
GETSUTEHAIEX GetSutehaiEx;
GETSUTEHAIEX2 GetSutehaiEx2;
GETSUTEHAINUM GetSutehaiNum;
GETDLLVERSION GetDLLVersion;
GETKAZE GetKaze;
GETTURNPLAYER GetTurnPlayer;
GETFUROHAI GetFurohai;
GETTONPUDATA GetTonpuData;
GETHAISIZE GetHaiSize;
GETDORAHAI GetDorahai;
PUSHHAI PushHai;
PUSHFUNCTIONKEY PushFunctionKey;
RCLICK RClick;
GETTONPUINFO GetTonpuInfo;
CHECK_TENPAI Check_tenpai;
CHECK_AGARI Check_agari;
SETMODE SetMode;
GETAVAILABLEFUNCTIONKEY GetAvailableFunctionKey;
EXISTAVAILABLEFUNCTIONKEY ExistAvailableFunctionKey;
GETRIGHTESTTEHAI GetRightestTehai;
EXT_GETHAI ext_GetHai;
GETPLAYERINFO GetPlayerInfo;
GETHOLDTIME GetHoldTime;
GETREACH GetReach;
SENDCHAT SendChat;
SIMULATEORDER SimulateOrder;
GETORDER GetOrder;
GETNEXTORDER GetNextOrder;
GETEXTENDINFORMATION GetExtendInformation;
GETEXTENDINFORMATIONSIZE GetExtendInformationSize;
SETTONPUCONNECTIONINFO SetTonpuConnectionInfo;
CANSELTONPUCONNECTION CanselTonpuConnection;
GETTONPUCONNECTIONSTATUS GetTonpuConnectionStatus;
PUSHTONPUCONNECTIONBUTTON PushTonpuConnectionButton;
SUPERQUICKWATCHING SuperQuickWatching;
PUSHYOYAKUBUTTON PushYoyakuButton;
PUSHTORIKESIBUTTON PushTorikesiButton;
PUSHJOUHOUBUTTON PushJouhouButton;
PUSHKANSENBUTTON PushKansenButton;
PUSHSYUURYOUBUTTON PushSyuuryouButton;
SELECTTAKU SelectTaku;
GETCHATLINENUM GetChatLineNum;
GETCHATLINE GetChatLine;
GETPLAYINFO GetPlayInfo;

//★以下をボタンクリックイベント内に記述
//注意! VisualC++の場合、キャストの制限が違います。
//GetHaiSize = ( GETHAISIZE )::GetProcAddress( hDll, "_GetHaiSize" );
//のような部分でキャストエラーが出るようです。
//コンパイラの指示通り、ここを
//GetHaiSize = ( GETHAISIZE )::GetProcAddress( (struct HINSTANCE__ *)hDll, "_GetHaiSize" );
//に直してやることで、コンパイルできます。
{
int tmphai[51],size; //汎用

HANDLE hDll = ::LoadLibrary( "MJexeIO.dll" ); //DLLをロード
if(hDll==NULL){ShowMessage("DLLオープンできません");return;} //DLLロードのエラーチェック

//DLLから必要な関数をインポート
GetHaiSize = ( GETHAISIZE )::GetProcAddress( hDll, "_GetHaiSize" );
GetDorahai = ( GETDORAHAI )::GetProcAddress( hDll, "_GetDorahai" );
GetTehai = ( GETTEHAI )::GetProcAddress( hDll, "_GetTehai" );
GetSutehai = ( GETSUTEHAI )::GetProcAddress( hDll, "_GetSutehai" );
GetSutehaiEx = ( GETSUTEHAIEX )::GetProcAddress( hDll, "_GetSutehaiEx" );
GetSutehaiEx2 = ( GETSUTEHAIEX2 )::GetProcAddress( hDll, "_GetSutehaiEx2" );
GetSutehaiNum = ( GETSUTEHAINUM )::GetProcAddress( hDll, "_GetSutehaiNum" );
GetDLLVersion = ( GETDLLVERSION )::GetProcAddress( hDll, "_GetDLLVersion" );
GetKaze = ( GETKAZE )::GetProcAddress( hDll, "_GetKaze" );
GetTurnPlayer = ( GETTURNPLAYER )::GetProcAddress( hDll, "_GetTurnPlayer" );
GetFurohai = ( GETFUROHAI )::GetProcAddress( hDll, "_GetFurohai" );
GetTonpuData = ( GETTONPUDATA )::GetProcAddress( hDll, "_GetTonpuData" );
PushHai = ( PUSHHAI )::GetProcAddress( hDll, "_PushHai" );
PushFunctionKey = ( PUSHFUNCTIONKEY )::GetProcAddress( hDll, "_PushFunctionKey" );
RClick = ( RCLICK )::GetProcAddress( hDll, "_RClick" );
GetTonpuInfo = (GETTONPUINFO)::GetProcAddress(hDll,"_GetTonpuInfo");
Check_tenpai = (CHECK_TENPAI)::GetProcAddress(hDll,"_Check_tenpai");
Check_agari = (CHECK_AGARI)::GetProcAddress(hDll,"_Check_agari");
SetMode = (SETMODE)::GetProcAddress(hDll,"_SetMode");
GetAvailableFunctionKey = (GETAVAILABLEFUNCTIONKEY)::GetProcAddress(hDll,"_GetAvailableFunctionKey");
ExistAvailableFunctionKey = (EXISTAVAILABLEFUNCTIONKEY)::GetProcAddress(hDll,"_ExistAvailableFunctionKey");
GetRightestTehai = (GETRIGHTESTTEHAI)::GetProcAddress(hDll,"_GetRightestTehai");
ext_GetHai = (EXT_GETHAI)::GetProcAddress(hDll,"_ext_GetHai");
GetPlayerInfo = (GETPLAYERINFO)::GetProcAddress(hDll,"_GetPlayerInfo");
GetHoldTime = (GETHOLDTIME)::GetProcAddress(hDll,"_GetHoldTime");
GetReach = (GETREACH)::GetProcAddress(hDll,"_GetReach");
SendChat = (SENDCHAT)::GetProcAddress(hDll,"_SendChat");
SimulateOrder = (SIMULATEORDER)::GetProcAddress(hDll,"_SimulateOrder");
GetOrder = (GETORDER)::GetProcAddress(hDll,"_GetOrder");
GetNextOrder = (GETNEXTORDER)::GetProcAddress(hDll,"_GetNextOrder");
GetExtendInformation = (GETEXTENDINFORMATION)::GetProcAddress(hDll,"_GetExtendInformation");
GetExtendInformationSize = (GETEXTENDINFORMATIONSIZE)::GetProcAddress(hDll,"_GetExtendInformationSize");
SetTonpuConnectionInfo = (SETTONPUCONNECTIONINFO)::GetProcAddress(hDll,"_SetTonpuConnectionInfo");
CanselTonpuConnection = (CANSELTONPUCONNECTION)::GetProcAddress(hDll,"_CanselTonpuConnection");
GetTonpuConnectionStatus = (GETTONPUCONNECTIONSTATUS)::GetProcAddress(hDll,"_GetTonpuConnectionStatus");
PushTonpuConnectionButton = (PUSHTONPUCONNECTIONBUTTON)::GetProcAddress(hDll,"_PushTonpuConnectionButton");
SuperQuickWatching = (SUPERQUICKWATCHING)::GetProcAddress(hDll,"_SuperQuickWatching");
PushYoyakuButton = (PUSHYOYAKUBUTTON)::GetProcAddress(hDll,"_PushYoyakuButton");
PushTorikesiButton = (PUSHTORIKESIBUTTON)::GetProcAddress(hDll,"_PushTorikesiButton");
PushJouhouButton = (PUSHJOUHOUBUTTON)::GetProcAddress(hDll,"_PushJouhouButton");
PushKansenButton = (PUSHKANSENBUTTON)::GetProcAddress(hDll,"_PushKansenButton");
PushSyuuryouButton = (PUSHSYUURYOUBUTTON)::GetProcAddress(hDll,"_PushSyuuryouButton");
SelectTaku = (SELECTTAKU)::GetProcAddress(hDll,"_SelectTaku");
GetChatLineNum = (GETCHATLINENUM)::GetProcAddress(hDll,"_GetChatLineNum");
GetChatLine = (GETCHATLINE)::GetProcAddress(hDll,"_GetChatLine");
GetPlayInfo = (GETPLAYINFO)::GetProcAddress(hDll,"_GetPlayInfo");

//DLL関数インポートのエラーチェック。この例では2つの関数だけをチェックしている。
if(GetHaiSize==NULL){ShowMessage("GetHaiSize関数をインポートできません");return;} //DLL関数インポートのエラーチェック
if(GetDorahai==NULL){ShowMessage("GetDoraHai関数をインポートできません");return;} //DLL関数インポートのエラーチェック

//★以下を自由にコーディングする
//使い方例
size=GetHaiSize(); //牌サイズ取得
GetDorahai(size,tmphai); //ドラ表示牌の取得
ShowMessage((AnsiString)tmphai[1]); //ドラ表示牌の表示
//★以上を自由にコーディングする

//★以下は全ての動作を終了した後に一度だけ行う
//DLLの開放
FreeLibrary( hDll );
}


★使用のヒント★

卓内の情報を取得するためにはほとんど必ず、牌のサイズ情報が必要になるので、上の例のように牌サイズを最初に取得するようにしましょう。

まずは上のサンプルコードを実行してみましょう。ちゃんと東風荘の卓画面を出した状態で実行すれば、ドラ表示牌の牌番号が表示されるはずです。
//使い方例 の部分を自分の好きなコードに書き換えることで、東風荘入出力機能を持ったソフトウェアを手軽にコーディングできます。
他の関数を使う場合、上と全く同様にすれば利用できます。

関数へのポインタを取得してしまえば、通常の関数とまったく同様に
ShowMessage(GetDLLVersion(MspWnd));
のように使用できます。

このページの一番下に、実際にこのDLLを使って「場に見えている牌の枚数をカウントする」サンプルコードをつけておきます。
参考にしてください。


★定義★

・Mode(赤牌の扱い)

MJexeIO.dllが東風の画面から牌を読み出すような全ての状況について、赤牌をどう認識するかを、Modeとして指定します。
ModeはSetMode()関数で変更します。
初期状態ではMode=0で、この状態では、赤牌は単なる通常牌と認識されます。
例えばドラが赤5マンの時、Mode=0でGetDoraHai()を呼び出すと、MJexeIO.dllは「5(5マン)」を返します。
Mode=1の場合、赤牌を赤牌であるとみなし、その後牌番号を取得するような場合に、特別な牌番号を返します。
例えばドラが赤5マンの時、Mode=1でGetDoraHai()を呼び出すと、MJexeIO.dllは「38(赤5マン)」を返します。
ただし、テンパイチェックなどを行う場合(Check_tenpai関数)、特別な牌番号を含んだままでは動作しません。
あくまでも牌の読み出しの返り値において赤牌に対応するかどうかであって、他の様々な処理をする場合は、牌番号の調整を行う必要がありますので注意してください。

・牌の表し方
牌番号と実際の牌の種類は、次のように対応付けられています。
1 1マン
2 2マン
・・・
5 5マンまたは赤5マン(Modeによる)
・・・
9 9マン
10 未定義

11 1ピン
12 2ピン
・・・
15 5ピンまたは赤5ピン(Modeによる)
・・・
19 9ピン
20 未定義

21 1ソウ
22 2ソウ
・・・
25 5ソウまたは赤5ソウ(Modeによる)
・・・
29 9ソウ
30 未定義

31 東
32 南
33 西
34 北
35 白
36 発
37 中

38 未定義または赤5マン(Modeによる)
39 未定義または赤5ピン(Modeによる)
40 未定義または赤5ソウ(Modeによる)

41 裏向けの牌(v0.77以前のバージョンでは255でした)

牌の種類として0~33などを使うものも多いと思いますが、直感的にわかりやすくして無用なバグを出しにくくするために、このように決められています。
不都合なら変換用の関数を用意して使ってください。
牌の情報を扱うときは、intで50以上のサイズの配列を用意して使うことを推奨します。

・関数の返り値としての -255
関数が-255の返り値を持つとき、東風荘のウインドウハンドルまたはデバイスコンテキストの取得に失敗したことを意味します。
具体的には、東風荘が起動していないか、東風荘の対戦卓画面でのみ有効な関数を待合室で呼び出した場合などにこの値が返ります。


★関数マニュアル★


int CanselTonpuConnection()  (紅孔雀さん開発)

東風接続試行をキャンセルする。

[引数]

[返り値]
0 成功
-1 失敗


int Check_tenpai(int pai[],int agari[])

テンパイチェックを行う関数。
pai[]には、各々の牌の枚数が入る。
ただし、pai[]に赤牌が含まれていると正常に動作しないので注意。赤牌入りのpai[]をテンパイチェックする場合、TehaiNormalizeで正規化してから行う。
配列agari[]には、あがり牌の数字が返る(例えば、4萬と7萬の待ちなら、agari_pai[1]に4が、agari_pai[2]に7が返る。[3]以下は0)。
ただし、agari_pai[0]には、上がり牌が全部でいくつあるかの個数が返る(上の場合だと2)。
この関数は、あくまでも「フーロしていない牌の構成」部分についてのチェックを行うものである。
ポンやカンやチーした牌については、pai[]から除外せねばならないし、この関数はそれについては関知しない。
例えば、3フーロして 1m2m7m7m という形であれば、これは「ペンチャンテンパイ」とみなされ、3mを当たり牌として返す。

[引数]
pai[] 手牌の配列。
agari[] 上がり牌情報を返すための配列。

[返り値]
リャンメン待ちなら1、シャンポン待ちなら2、カンチャン待ちなら3、ペンチャン待ちなら4、単騎待ちならば5、あがり牌が3つ以上ある場合は6、その他の場合は7を返す。
ノーテンならば0を返す。また特殊な場合として、国士13面待ちの場合8を返す。
なお、1112などの形についてだが、その待ちの形が、当たり牌6枚以上持ち得る形である場合(1234の14待ちなど)、一般にリャンメン扱いになる
agari[0] 上がり牌の個数。
agari[1~20] 各々の上がり牌の番号。

・注意点
待ちの形の返り値は目安である。1が帰ったからといって、必ずしもスジ待ちとは限らないので注意する。詳しくはagari[]の内容から判断すること。


int Check_agari(int pai[],int x)

pai[]に与えられた牌構成の「通常手」に対して、牌xが上がり牌であるかどうかを返す。
「通常手」とは、国士無双とチートイツを除く全ての手のことである。
Check_tenpaiと同様の注意が必要である。
例えば、pai[]に「1m2m」だけの情報が入っているとき、3mは「上がり牌である」とみなされる。
要するに、pai[]で与えられた牌+xで与えられた牌の組み合わせに対して、整数個のメンツと1つの頭が抜き出せるとき、上がりと見なされる。


[引数]
pai[] 手牌の配列。
x 上がり牌であるかどうか調べる牌。

[返り値]
0 上がり牌でない
その他 上がり牌である(値は、Check_tenpaiから使われるために待ちの形などによって変化するが、これはCheck_tenpaiの返り値と必ずしも一致しない)


int ExistAvailableFunctionKey(int size)  (紅孔雀さん開発)

東風の画面で、ボタンが出ているかを取得する関数。

[引数]
size 牌のサイズ。1=小、2=中、3=大

[返り値]
0 何も押せない
1 何かが押せる
-1 エラー(取得失敗)


int ext_GetHai(int sizes,int x,int y,int houkou)

東風の画面上にある牌画を読み、牌番号を返す。

[引数]
size 牌のサイズ。1=小、2=中、3=大
x,y 「牌の左上点」を、東風の画面のデバイスコンテキスト上の相対座標で示す。牌の左上点は、「牌のデザイン上の左上」であって、実際の画面上では牌の向きによって「左上」とは限らない。
houkou 読み込みたい牌の向きを指定する。1=自分の牌(正面向き) 2=下家の牌(正面の牌を左に90度回転したもの) 3=上家の牌(180度回転) 4=上家の牌(270度回転)


int GetAvailableFunctionKey(int *flags,int size)  (紅孔雀さん開発)

東風の画面で、「F3 次へ進む」などのボタンが出ているか、出ているならその表記はどうであるかを取得する関数。
結果はflags[]に返る。flags[]は要素数10以上のサイズにすること。

[引数]
flags[x] キーxが押せる状態にあるか、また押せる場合その表記がどうであるかを返すための配列。
size 牌のサイズ。1=小、2=中、3=大

[返り値]
0 取得成功
-1 エラー
flags[] に、以下の表のように数値が返る。

flags[x] =0 =1 =2 =3
x=2 (F2ボタンなし) F2捨て牌表示 (未定義) (未定義)
x=3 (F3ボタンなし) F3次へ進む F3得点表示 (未定義)
x=4 (F4ボタンなし) F4観戦終了 F4終了 (未定義)
x=5 (F5ボタンなし) F5鳴無(反転なし) F5鳴無(反転中) F5無し
x=6 (F6ボタンなし) F6カン (未定義) (未定義)
x=7 (F7ボタンなし) F7ポン F7リーチ(反転なし) F7リーチ(反転中)
x=8 (F8ボタンなし) F8チー(反転なし) F8チー(反転あり) F8倒牌
x=9 (F9ボタンなし) F9ツモ F9ロン (未定義)



int GetChatLine(char * str,int index)  (紅孔雀さん開発)

チャット欄の、指定した行の文字列を取得する関数。対戦画面でも待合でも同様に使える。

[引数]
str 文字列を受け取るための文字型配列へのポインタ
index 受け取りたい行を指定する。0がチャット欄の最上段の行で、最新のものに近づけば近づくほど値が増える。

[返り値]
0 成功
-1 失敗
取得するために指定した行が存在しない場合や、エラーが出た場合などは、strに\0が返ることが保障される。
なお、チャット欄に何も表示されていない時に呼び出すと、関数全体としては0(成功)を返すが、strは\0になる。


int GetChatLineNum()  (紅孔雀さん開発)

チャット欄の行数を返す関数。これで取得した値から1を引いたindexを与えてGetChatLineを呼び出せば、最新の発言を取得できる。

[引数]

[返り値]
n チャット欄はn行ある(ただし0行の場合は特別に1が返る)
-1 失敗


bool GetCursorDCPos(LPRECT lprect)

APIのGetCursorPosと全く同じ形式で使え、マウスカーソルの座標を、東風荘の対戦画面のデバイスコンテキスト上の相対位置で返す。

[引数]
lprect XY座標を格納するRECT構造体へのポインタ

[返り値]
true 成功
false 失敗


int GetDLLVersion(void)

DLLのバージョン番号を取得する関数。

[引数]
なし

[返り値]
バージョン番号の100倍の整数値(3.20なら320)。


int GetDorahai(int size,int *dorahai)

ドラ表示牌を返す。

[引数]
size 牌のサイズ。1=小、2=中、3=大
dorahai ドラ表示牌情報を受け取るためのint配列を指すポインタ

[返り値]
-1 sizeが異常
0 取得失敗
dorahai[0~]には以下の情報が返る。
[0]ドラ表示牌の枚数
[1]ドラ表示牌(1つめ)の牌番号
[2]ドラ表示牌(2つめ)の牌番号
・・・


int GetExtendInformation(int * mem,int sizes)

DLLの拡張作業領域のデータを指定バイト数だけ読み出す関数。
例えば現バージョンで、ある関数f()は、情報Aと情報Bを取得するための関数だったとする。
ここで、関数f()に、新しく情報Cを取得する機能もつける必要が生じたとする。
ところが、安易にf()の引数や返り値を変更させてしまうと、互換性が保てず、これまでf()を使用していたユーザが混乱してしまう。
このような場合、f()は、引数や返り値自体は今まで通りで、DLLの拡張作業領域に情報Cを書き込むように変更される。
従来のユーザは無意識にこれまでと同じ情報A、情報Bを取得でき、また拡張作業領域を読み出すことで、情報Cを得ることもできるようになる。
将来的に、全ての関数は、拡張作業領域に書き込みを行う可能性があるとする。したがって読み出しは必ず、関数を呼んだ直後に行う必要がある。

[引数]
mem 拡張作業領域のデータをコピーするためのint配列へのポインタ。
sizes コピーするバイト数。

[返り値]
0 成功
-1 サイズが異常(コピーサイズ0にした場合も-1が帰る)


int GetExtendInformationSize()

拡張作業領域のサイズをバイト数で返す関数。

[引数]

[返り値]
拡張作業領域のバイト数。


int GetFurohai(int player,int size,int * furohai)

フーロ牌を取得する関数。

[引数]
player 誰のフーロ牌を取得するか。1=自分、2=下家、3=トイメン、4=上家
size 牌のサイズ。1=小、2=中、3=大
furohai フーロ牌情報を受け取るためのint配列を指すポインタ

[返り値]
0~ 読み出せたフーロメンツ個数
furohai[0~]には以下の値が返る。
n+1番目のフーロ牌についてのデータとして
[0+4*n] フーロの種類。0=フーロなし、1=ポン、2=チー、3=アンカン、4=ミンカン
[1+4*n] そのフーロメンツの構成牌のうちもっとも牌番号の小さい牌の番号。
[2+4*n] そのフーロメンツのうち、他家から取得した牌の牌番号。
[3+4*n] その人から相対的に見た、食った他家の番号。1=下家、2=トイメン、3=上家

・注意点
この関数はfurohaiとして与えるアドレスから+50までのアドレスに対して書き込みを行う可能性がある。int furohai[51]以上の大きさの配列を確保して使うこと。


int GetHaiSize(void)

現在対戦卓にいる場合は牌のサイズを取得する関数。

[引数]

[返り値]
0 牌のサイズ取得失敗。対戦画面でないか、他のウインドウが重なっているか、Deviceの値が不適切
1~3 牌のサイズ。1=小、2=中、3=大


int GetHoldTime(int size)  (紅孔雀さん開発)

現在自分のターンの時、打牌するまでの制限時間を取得する。

[引数]
size 牌のサイズ。1=小、2=中、3=大

[返り値]
-1 失敗
-1以外 制限時間


int GetKaze(int size)

自分(手前のプレイヤー)の風を取得する関数。

[引数]
size 牌のサイズ。1=小、2=中、3=大

[返り値]
-1 sizeが異常
0 読み取り失敗
1 自分は東
2 自分は南
3 自分は西
4 自分は北


int GetNextOrder(int A,int a,int orders[5])

プレイヤーAがa番目に切った牌の次に、他の各々のプレイヤーが切る牌の位置を返す関数。
ただし、SimulateOrder関数で事前にシミュレートしておく必要がある。
なお、シミュレート結果に少しでも非決定性がある場合はこの関数は動作しないので注意。
例えば、ポンやチーがなければ、親が5番目の捨て牌を捨てた次に、他の各々のプレイヤーが切る牌の位置は5である。
また、子が5番目の捨て牌を捨てた次に、親が切る牌の位置は6番目である。
リーチ牌の後に通った牌がどれかなどを手軽に取得するのに利用できる。

[引数]
A プレイヤー番号
a 切った牌の、捨て牌上の位置
orders 返り値を返すための配列

[返り値]
0 成功
-1 シミュレート結果に不確定性がある
orders[n] プレイヤーnが次に出す捨て牌の位置が返る


int GetOrder(int A,int a,int B,int b)

プレイヤーAがa番目に切った牌が、プレイヤーBがb番目に切った牌に対してどういう順序であるかを返す関数。
ただし、SimulateOrder関数で事前にシミュレートしておく必要がある。
ここにアルゴリズムの概略と、順序決定についての説明がある。
例えば、GetOrder(1,1,4,1)の結果は、自分(手前のプレイヤー)が親なら0、上家が親なら1である(その他の場合は状況によって変化する)。
なぜなら、自分が親である限り、自分の1番最初に切った牌は常に、4(上家)が1番最初に切った牌より先に切られており、逆に上家が親であれば、自分の1番最初に切った牌は、上家が1番最初に切った牌より後に切られているからである。また、もし下家が親で、自分が親の第一打をポンしていれば、自分の1番最初に切った牌は、上家の一番最初に切った牌よりも先になる。
同様にして任意の牌に対する順序付けを取得できる。「不定」とは、どちらが先である可能性も論理的にあり得る場合の返り値である。

[引数]
A,B プレイヤー番号
a,b 切った牌の、捨て牌上の位置

[返り値]
0 牌aが前と確定
1 牌aが後と確定
2 順序は不定
-1 記録なし(シミュレートされていない、まだ捨てられていない牌に対して読み込んだ、など)


int GetPlayInfo(int * data)

対戦画面(観戦画面)での、ウインドウのタイトルバー情報から情報を読み取る。
dataの各値は、読み取りに成功した場合はその値が、失敗した場合は-1が保障される。要素数は10以上確保すること

[引数]
data 情報を受け取るためのint配列へのポインタ。

[返り値]
0 成功
-1 卓画面でないなど、失敗
dataには以下の情報が整数値として返る。
data[0] 卓番号
data[1] 東場か(値=1)、南場(値=2)か、西場(値=3)か、北場(値=4)か
data[2] 何局か
data[3] 何本場か
data[4] リーチ棒数
data[5] 観戦者数
data[6] 残り枚数


int GetPlayerInfo(int * point,int * rate,int player,int size)  (紅孔雀さん開発)

プレイヤーの持ち点とレートを取得する。チャット中心卓など、レート表記のない卓ではrate取得失敗なので、*rateには1が返る。

[引数]
point 指定プレイヤーの持ち点を返すためのint型へのポインタ。取得に失敗した場合は1。
rate 指定プレイヤーのレートを返すためのint型へのポインタ。取得に失敗した場合は1。
player 誰の情報を取得するか。1=自分、2=下家、3=トイメン、4=上家
size 牌のサイズ。1=小、2=中、3=大

[返り値]
0 成功(得点またはレートのいずれかの取得に成功)
-1 失敗(いずれの取得も失敗)


int GetPlayStatus

局終了時の画面を読み取る。未実装。


int GetRightestTehai(void)

最後にGetTehaiを呼び出した時の、一番最後に読み出した牌(一番右の牌)を返す関数。
自分のツモ番の時にツモった牌を取得する場合などに使用する。なお自分が牌をツモった瞬間を判別するには、(GetTehaiの返り値)%3==2 であるかどうかを用いると良い。

[引数]

[返り値]
最近GetTehaiの内部で読まれた牌のうちの、最後の牌の牌番号。


int GetReach(int player,int size)

指定キャラがリーチしているか否かを取得する関数。
「リーチ棒」のグラフィックから直接読んでいるために、GetSutehaiなどより非常に高速である。
対戦中などでない場合にも「リーチしていない」という返り値が帰るので、リーチ時のみに行う処理がある場合に有効である。

[引数]
player 誰の捨て牌を取得するか。1=自分、2=下家、3=トイメン、4=上家
size 牌のサイズ。1=小、2=中、3=大

[返り値]
0 リーチしていない(あるいは対戦卓の画面でないなど)。
1 リーチしている。


int GetSutehai(int player,int size,int * sutehai)

捨て牌を取得する関数。

[引数]
player 誰の捨て牌を取得するか。1=自分、2=下家、3=トイメン、4=上家
size 牌のサイズ。1=小、2=中、3=大
sutehai 捨て牌情報を受け取るためのint配列を指すポインタ

[返り値]
0~ 読み出せた捨て牌個数
sutehai[0~]には以下の値が返る。
[0]リーチ宣言牌の位置。0以下の時リーチなし(この関数を呼んだときは常に保障される)。-1の時、読み込みエラーであることが確実。
[n]n番目に捨てられた牌の番号。

・注意点
この関数はsutehaiとして与えるアドレスから+50までのアドレスに対して書き込みを行う可能性がある。int sutehai[51]以上の大きさの配列を確保して使うこと。
リーチ宣言牌の位置は、リーチした順目を直接表さないので注意する必要がある。例えば自分が1を2枚切ったとき、片方はトイメンにポンされもう片方は下家にチーされているとすると、どちらが先にフーロしたかを一意に定めることはできないので、リーチ後に通った牌を定めるためには、常に東風の情報を読み込んでいなければならない。


int GetSutehaiEx(int player,int size,int * sutehai,int * sutehaidata)

捨て牌を取得する関数の拡張版。捨て牌のうちの、どの牌に網がかかっているかも取得できる。
GetSutehaiEx2があるバージョンを利用している場合、基本的にGetSutehaiEx2を利用すべきである。

[引数]
player 誰の捨て牌を取得するか。1=自分、2=下家、3=トイメン、4=上家
size 牌のサイズ。1=小、2=中、3=大
sutehai 捨て牌情報を受け取るためのint配列を指すポインタ
sutehaidata 網のかかった捨て牌がどこであるかの情報を受け取るためのint配列を指すポインタ

[返り値]
0~ 読み出せた捨て牌個数
sutehai[0~]には以下の値が返る。
[0]リーチ宣言牌の位置。0以下の時リーチなし(この関数を呼んだときは常に保障される)。-1の時、読み込みエラーであることが確実。
[n]n番目に捨てられた牌の番号。
sutehaidata[1~]には以下の値が返る。
[n]n番目に捨てられた牌に網がかかっているかどうか。0 かかっていない 1 かかっている

・注意点
GetSutehaiと同様。sutehaidataへの書き込みはsutehaiへの書き込みに準ずる。


int GetSutehaiEx2(int player,int size,int * sutehai,int * sutehaidata,int * tumokiridata,int * RedBorder)

捨て牌を取得する関数の拡張版。
捨て牌のうちの、どの牌に網がかかっているか、どの牌にツモ切り線がついているか、どの牌が赤ワクで囲まれているかも取得できる。

[引数]
player 誰の捨て牌を取得するか。1=自分、2=下家、3=トイメン、4=上家
size 牌のサイズ。1=小、2=中、3=大
sutehai 捨て牌情報を受け取るためのint配列を指すポインタ
sutehaidata 網のかかった捨て牌がどこであるかの情報を受け取るためのint配列を指すポインタ
tumokiridata ツモ切り線(水色の線)がついた牌がどこであるかの情報を受け取るためのint配列を指すポインタ
RedBorder 赤ワクで囲まれた牌(ポンやチーやロンが可能な対象牌)の位置を返すためのint変数へのポインタ

[返り値]
0~ 読み出せた捨て牌個数
sutehai[0~]には以下の値が返る。
[0]リーチ宣言牌の位置。0以下の時リーチなし(この関数を呼んだときは常に保障される)。-1の時、読み込みエラーであることが確実。
[n]n番目に捨てられた牌の番号。
sutehaidata[1~]には以下の値が返る。
[n]n番目に捨てられた牌に網がかかっているかどうか。0 かかっていない 1 かかっている
tumokiridata[1~]には以下の値が返る。
[n]n番目に捨てられた牌にツモ切り線がついているかどうか。0 ついていない 1 ついている
RedBorder 0 そのプレイヤーの捨て牌には赤ワクで囲まれた牌が存在しない n そのプレイヤーのn番目の捨て牌が赤ワクで囲まれている

・注意点
GetSutehaiと同様。配列への書き込みはsutehaiへの書き込みに準ずる。


int GetSutehaiNum(int player,int size,int * sutehai)

捨て牌の数とリーチ順目だけを、GetSutehaiよりも高速に取得する関数。

[引数]
player 誰の捨て牌を取得するか。1=自分、2=下家、3=トイメン、4=上家
size 牌のサイズ。1=小、2=中、3=大
sutehai 情報を受け取るためのint配列を指すポインタ

[返り値]
0~ 読み出せた捨て牌個数
sutehai[0~]には以下の値が返る。
[0]リーチ宣言牌の位置。0以下の時リーチなし(この関数を呼んだときは常に保障される)。-1の時、読み込みエラーであることが確実。
[n]変化しない(書き込まれない)。

・注意点
リーチ宣言牌の位置は、リーチした順目を直接表さないので注意する必要がある。例えば自分が1を2枚切ったとき、片方はトイメンにポンされもう片方は下家にチーされているとすると、どちらが先にフーロしたかを一意に定めることはできないので、リーチ後に通った牌を定めるためには、常に東風の情報を読み込んでいなければならない。


int GetTehai(int size,int * tehai)

自分のメンゼン牌を取得する関数。

[引数]
size 牌のサイズ。1=小、2=中、3=大
tehai 手牌情報を受け取るためのint配列を指すポインタ

[返り値]
0 読み出しに失敗し、読み出せた牌が0個
1~14 読み出せた牌の個数(必ずしも読み出し成功を保証しない)
tehai[0~]には以下の値が返る。
[n]牌nを持っている枚数

・関数の動作
関数は、自分の手牌を読み出してtehai[0~37]に返す。tehai[0]は自分のメンゼン手牌の数(例えば通常は13、裸単騎の時は1)。

・注意点
この関数はtehaiとして与えるアドレスから+50までのアドレスに対して書き込みを行う可能性がある。int tehai[51]以上の大きさの配列を確保して使うこと。
東風荘のウインドウが、他のウインドウによって隠れていたりする場合正常に動作しない。
しかもその際、この関数は必ずしも「エラー」を返さない。
安定した動作のためには、東風荘のウインドウを前面に移動させるなど、別途工夫が必要である。


int GetTonpuConnectionStatus()  (紅孔雀さん開発)

東風への接続試行状態を取得する。

[引数]

[返り値]
-1 エラー(接続ウィンドウが無い場合もここに含む)
0 非接続中
1 東風サーバに接続中
2 会員情報送信中
3 エラーダイアログが出ている(サーバへの接続に失敗しました。)
4 エラーダイアログが出ている(満員で接続できませんでした。)
5 エラーダイアログが出ている(このサーバへの接続権限がありません。)
6 エラーダイアログが出ている(とりあえずエラーダイアログが出ている。)


int GetTonpuData(char * string)

東風荘ウインドウのタイトルバー文字列を取得する。

[引数]
string 取得した文字列を返すためのchar配列を指すポインタ。タイトルバーに含まれ得る文字列の大きさ以上の配列を確保すること。

[返り値]
-2 起動された東風荘自体が存在しない
-1 東風荘は起動されているが待合室でもなく対戦中でもなく観戦中でもない。
0 現在待合室
1または2 (不定) 現在対戦中または観戦中


int GetTonpuInfo(HWND *hMachiai_p,HWND *hPlayRoom_p)

東風のゲーム画面のウインドウハンドルを返す。

[引数]
*hMachiai_p 待合室ウインドウのハンドルを入れるHWNDへのポインタ
*hPlayRoom_p 卓ウインドウのハンドルを入れるHWNDへのポインタ

[返り値]
引数として与えたポインタに、各々のウインドウハンドルが返る。見つからなかった場合はNULL。
intの返り値は接続サーバを表し、以下の意味を持つ。
0 どこにも接続されていない
1~3 第○東風荘に接続中
4 VIPに接続中


int GetTurnPlayer(int size)

現在ツモおよび打牌中の他家の番号を返す。

[引数]
size 牌のサイズ。1=小、2=中、3=大

[返り値]
-1 sizeが異常
0 読み取り失敗
1 手前のプレイヤーのターン
2 下家のプレイヤーのターン
3 トイメンのプレイヤーのターン
4 上家のプレイヤーのターン


int PushFunctionKey(int keyno)

ファンクションキー入力するための関数。

[引数]
keyno 1~12。その数字のファンクションキーを押す。例えば観戦中に観戦終了させたい場合、keyno=4(F4キー)としてこの関数を呼べばいい。

[返り値]
-2 無効なkeyno


int PushHai(int size,int haiposition)

自分の牌の位置を左クリックするための関数。

[引数]
size 牌のサイズ。1=小、2=中、3=大
haiposition 左から何番目の牌位置を左クリックするか。1~14。例えば14だと「ツモ切り」に相当する。

[返り値]
-1 sizeが異常
-2 無効なhaiposition


int PushJouhouButton()  (紅孔雀さん開発)

東風の待合にいるとき、「卓情報」ボタンを押す。

[引数]

[返り値]
0 成功
-1 失敗


int PushKansenButton()  (紅孔雀さん開発)

東風の待合にいるとき、「観戦」ボタンを押す。

[引数]

[返り値]
0 成功
-1 失敗




int PushSyuuryouButton()  (紅孔雀さん開発)

東風の待合にいるとき、「終了」ボタンを押す。

[引数]

[返り値]
0 成功
-1 失敗


int PushTonpuConnectionButton()  (紅孔雀さん開発)

東風への接続試行を開始する(接続ボタンを押す)。

[引数]

[返り値]
0 成功
-1 失敗


int PushTorikesiButton()  (紅孔雀さん開発)

東風の待合にいるとき、「予約取消」ボタンを押す。

[引数]

[返り値]
0 成功
-1 失敗


int PushYoyakuButton()  (紅孔雀さん開発)

東風の待合にいるとき、「予約」ボタンを押す。

[引数]

[返り値]
0 成功
-1 失敗


int RClick(void)

東風の画面で右クリックするための関数。ポンやチーをキャンセルする場合に用いる。

[引数]

[返り値]


int SelectTaku(int TakuType,int TakuNo)  (紅孔雀さん開発)

待合で、卓を選択する関数。

[引数]
TakuType リストボックス内のどの卓種類を選択するかを指定する。02/07/30現在では 0 ワイワイ卓【チャット中心】 1 ワイワイ卓【麻雀中心】 ・・・ 4 超ラン卓
TakuNo その卓種類の中での、相対的な卓の位置を指す。例えば超ランが501卓から始まっているとすると、TakuTypa=4、TakuNo=0とすると、501卓を指定したことになる。

[返り値]
-1 失敗(その卓種類が存在しない、卓番号が大きすぎる、など)

注意点:
卓種類ごとの卓の数は、東風荘のバージョンによって若干変化することもあるので注意する。


int SendChat(char * strings,int nonsense,int mode)  (紅孔雀さん開発)

チャット出力を行う関数。
例えば strings[]="/w プレイヤー名" にしてこの関数を呼び出すと、東風のチャットウインドウに/w した結果が表示される。
チャットの幅は最大入力数64文字(半角)なので、64文字を超える場合は自動的に64文字までに切り詰められて送信される。

[引数]
strings チャット文字列。
nonsense 指定しても無意味(過去のバージョンとの互換性)
mode 0 チャットウインドウに、指定した文字列を代入して動作  0以外 チャットウインドウに、指定した文字列を置換(追記)して動作

[返り値]
0 成功
-1 失敗


int SetMode(int Mode)

以後、MJexeIO.dllが牌の読み出しを行う際に、赤牌の牌番号をどう扱うか(通常の牌と区別不能にするか、特別な牌番号を使うか)を決定する。なお起動直後はMode=0である。
通常、テンパイチェックやフリテンチェックの際には赤牌は無視して良いので、Mode=0を用い、点数計算など必要な場合だけMode=1にする方が混乱が少ない。

[引数]
Mode=0 赤牌であっても通常牌として扱う。赤5マンの牌番号は5、赤5ピンの牌番号は15、赤5ソウの牌番号は25。
Mode=1 赤牌には牌番号38,39,40を割り当てる。赤5マンの牌番号は38、赤5ピンの牌番号は39、赤5ソウの牌番号は40。

[返り値]
0


int SetTonpuConnectionInfo(int server,char *number,char *password)  (紅孔雀さん開発)

東風荘の接続ウィンドウに接続情報をセットする。

[引数]
server 接続するサーバ(1~3=第一~第三,4=VIP)
number 会員番号
password パスワード
[返り値]
0 成功
-1 失敗


int SimulateOrder
(int kaze,
 int furohais1[50],int furohais2[50],int furohais3[50],int furohais4[50],int furokosuus[5],
 int sutehais1[50],int sutehais2[50],int sutehais3[50],int sutehais4[50],int sutehaikosuus[5],
 int sutehaidatas1[50],int sutehaidatas2[50],int sutehaidatas3[50],int sutehaidatas4[50])


捨て牌、フーロ牌の情報から、牌の順序を求めるためのシミュレーションを行う。
例えばポンチーが入り乱れているときに「親の5番目の捨て牌と、南家の5番目の捨て牌は、どちらが先に切られたか?」ということを取得するための準備としてこの関数を呼ぶ。
この結果は、GetOrder関数で読み出すことができる。
方法としては、ここにアルゴリズムの概略がある。

[引数]
kaze 手前のプレイヤーの風。GetKazeで取得した返り値
furohais1 GetFurohaiによって得られた、プレイヤー1のフーロ牌データそのもの
furohais2 GetFurohaiによって得られた、プレイヤー2のフーロ牌データそのもの
furohais3 GetFurohaiによって得られた、プレイヤー3のフーロ牌データそのもの
furohais4 GetFurohaiによって得られた、プレイヤー4のフーロ牌データそのもの
furokosuus[n] プレイヤーnの、フーロ数。GetFurohaiの返り値を入れる。
sutehais1 GetSutehaiExによって得られた、プレイヤー1のsutehaiデータそのもの
sutehais2 GetSutehaiExによって得られた、プレイヤー2のsutehaiデータそのもの
sutehais3 GetSutehaiExによって得られた、プレイヤー3のsutehaiデータそのもの
sutehais4 GetSutehaiExによって得られた、プレイヤー4のsutehaiデータそのもの
sutehais[n] プレイヤーnの、読み出せた捨て牌の個数。GetSutehaiの返り値を入れる。
sutehaidatas1 GetSutehaiExによって得られた、プレイヤー1のsutehaidataデータそのもの
sutehaidatas2 GetSutehaiExによって得られた、プレイヤー2のsutehaidataデータそのもの
sutehaidatas3 GetSutehaiExによって得られた、プレイヤー3のsutehaidataデータそのもの
sutehaidatas4 GetSutehaiExによって得られた、プレイヤー4のsutehaidataデータそのもの

[返り値]
-1 失敗(どれかのデータがおかしい)
0 成功


int SuperQuickWatching()  (紅孔雀さん開発)

チャ卓→ワイ卓→・・・の順で観戦できる卓を探し、瞬間観戦を行う関数。

[引数]
なし

[返り値]
0 成功
-1 失敗


int TehaiNormalize(int norm_pai[],int pai[])

赤牌入りのpai[]から、通常のnorm_pai[]に変換する。
つまりpai[38](赤5マン)はnorm_pai[5](5マン)に変換され、norm_pai[38]は0になるような動作をする。
未定義の牌番号の牌は0になる。
牌の分布などを数えた後、最後にこれを呼び出すことで、赤牌を無視した処理を行うことができる。
なお、norm_pai[]の要素数は49までに対して書き込みを行う可能性がある。

[引数]
norm_pai[] 変換された牌が入る。
pai[] 変換する牌を入れる。

[返り値]
0


★サンプルコード★


サンプルコード1・場に見えている牌の枚数の数え上げ

最初のサンプルコードの「以下を自由にコーディングする」の部分に、次のようなコードを書くと、「自分から見た場に出た牌の枚数」をbahai[]に取り込むことができます。
もちろん、bahai[]は別途宣言し、初期化しておいてください。
また動作を確認するためにはShowMessageなどを用いて、bahai[]の内容を表示してください。

このコードで重要なのはフーロ牌の取り扱い方です。
フーロ牌の表現は若干ややこしいので、注意してください。

このコードでは卓上にある「プレイヤー」から見た全ての牌の取り扱いを行っています。
このコードを少し変更することで、卓上の牌を容易に取得することができます。
なお、実際の使用の際には、例えば4人目のフーロ牌を取得するタイミングで東風荘ウインドウが他のウインドウによって隠されたりすることによる取得失敗の可能性があるため、毎回の牌読み込みに対してチェックを行うべきです。


int index=0; //牌を指すための汎用変数

//ドラ表示牌に使われている枚数分をカウント
int gettmp=GetDorahai(size,tmphai);
if(gettmp<=0){ShowMessage("ドラ取得失敗");return;}
for(int i=1;i<=tmphai[0];i++)
{
index=tmphai[i];
bahai[index]++;
}

//自分の手牌に使われている枚数分をカウント
gettmp=GetTehai(size,tmphai);
if(gettmp>=1)
for(int i=1;i<=37;i++)
{
bahai[i]+=tmphai[i];
}

//4人分の捨て牌に使われている枚数分をカウント
for(int j=1;j<=4;j++) //各プレイヤーに渡って繰り返し
{
gettmp=GetSutehai(j,size,tmphai);
if(gettmp<0){ShowMessage("捨て牌取得失敗");return;}
if(gettmp>=1)
for(int i=1;i<=gettmp;i++)
{
index=tmphai[i];
bahai[index]++;
}
}

//4人分のフーロ牌に使われている枚数分をカウント
for(int j=1;j<=4;j++) //各プレイヤーに渡って繰り返し
{
gettmp=GetFurohai(j,size,tmphai);
if(gettmp>0)
for(int k=1;k<=gettmp;k++) //当該プレイヤーのフーロ数だけ繰り返す
{
if(tmphai[0+4*(k-1)]==1) //そのフーロの種類が1(ポン)なら
{
index=tmphai[1+4*(k-1)];
bahai[index]+=3; //ポンの軸となっている牌を3枚「場に出た」とみなし
index=tmphai[2+4*(k-1)];
bahai[index]--; //ポンされた牌の、捨て牌とのダブルカウントを考慮する
}

else if(tmphai[0+4*(k-1)]==2) //そのフーロの種類が2(チー)なら
{
index=tmphai[1+4*(k-1)];
bahai[index]++;
bahai[index+1]++;
bahai[index+2]++; //チーされている牌を、その軸部分から3つ「場に出た」とみなし
index=tmphai[2+4*(k-1)];
bahai[index]--; //チーされた牌の、捨て牌とのダブルカウントを考慮する
}

else if(tmphai[0+4*(k-1)]==3) //そのフーロの種類が3(アンカン)なら
{
index;
index=tmphai[1+4*(k-1)];
bahai[index]+=4; //カンの軸となっている牌を4枚「場に出た」とみなす
}

else if(tmphai[0+4*(k-1)]==4) //そのフーロの種類が4(ミンカン)なら
{
int index=tmphai[1+4*(k-1)];
bahai[index]+=4; //カンの軸となっている牌を4枚「場に出た」とみなし
index=tmphai[2+4*(k-1)];
bahai[index]--; //カンされた牌の、捨て牌とのダブルカウントを考慮する
}
}
}




サンプルコード2・テンパイチェック(上がり牌調べ、待ちの形判定を含む)

最初のサンプルコードの「以下を自由にコーディングする」の部分に、次のようなコードを書くと、「自分の手牌がテンパイしているかどうか」「上がり牌は何か」「待ちの形は何か」を判別できます。
動作を確認するためには適宜結果を表示させてください。
Check_tenpaiの返り値についての詳細はマニュアル本文をごらんください。


char tehai[100];
char agaripais[100];
int size; //適当に宣言

size=GetHaiSize(); //牌サイズの取得
SetMode(0); //赤牌を無視して取得する
int kosuu=GetTehai(size,tehai); //手牌を取得し、取得できた枚数を保持
if(kosuu%3==2){int index=GetRightestTehai();tehai[index]--;} //もし自分がツモった直後なら、ツモってきた牌を手牌から除く
int tenpai=Check_tenpai(tehai,agaripais); //テンパイチェックを行う




サンプルコード3(初心者向け・オススメ)・一括「/w」

最初のサンプルコードの「以下を自由にコーディングする」の部分に、次のようなコードを書くと、指定されたHNを一括検索した結果を、東風のチャットウインドウに表示させられます。
なお、strcpyはCの標準関数です。
必要な場合(「strcpyは未定義」などのエラーが出る場合)は、プログラムの一番最初に#include"string.h"を記述します(こういった場合はマニュアルや検索で「strcpy」を調べるクセをつけてください)。

int i;
char str[1024]; //返り値受け取り用の文字列
char players[5][20];

strcpy(players[0],"/w とつげき東北\0");
strcpy(players[1],"/w とつ開発研究\0");
strcpy(players[2],"/w 紅孔雀さん\0");
strcpy(players[3],"/w バイマンキン\0");
strcpy(players[4],"/w デシマンキン\0");
for(i=0;i<5;i++)
SendChat(players[i],0,0); //チャットに文字列送信

具体的にこのプログラムを動かすには?




サンプルコード4・ポンやチーが入り乱れた画面で、リーチ後に切られた牌はどこからかのチェック

「以下を自由にコーディングする」の部分に、次のようなコードを書くと、手前のプレイヤー(自分)のリーチ後に、他家が初めて切った牌の位置を表示することができます。
簡単な例ですが、複雑にポンやチーが入り乱れた静止画面から、フリテンチェックなどを容易に行うことができます。

//★以下を自由にコーディングする
int furohais[5][50];
int sutehais[5][50];
int sutehaidatas[5][50];
int furokosuus[5];
int sutehaikosuus[5];
memset(furohais,0,sizeof(int)*5*50);
memset(sutehais,0,sizeof(int)*5*50);
memset(sutehaidatas,0,sizeof(int)*5*50);
memset(furokosuus,0,sizeof(int)*5);
memset(sutehaikosuus,0,sizeof(int)*5);

size=GetHaiSize(); //牌サイズ取得
//以下、SimulateOrderのために必要な各種情報を取得
int kaze=GetKaze(size);
for(int i=1;i<=4;i++)
{
int j=GetFurohai(i,size,furohais[i]);
furokosuus[i]=j;
j=GetSutehaiEx(i,size,sutehais[i],sutehaidatas[i]);
sutehaikosuus[i]=j;
}
//SimulateOrderを呼び出してシミュレート
if(
SimulateOrder(kaze,
furohais[1],furohais[2],furohais[3],furohais[4],furokosuus,
sutehais[1],sutehais[2],sutehais[3],sutehais[4],sutehaikosuus,
sutehaidatas[1],sutehaidatas[2],sutehaidatas[3],sutehaidatas[4])
==-1){ShowMessage("シミュレート失敗");FreeLibrary( hDll );exit(0);}
//リーチがあるか?
if(sutehais[1][0]<=0){ShowMessage("手前プレイヤーはリーチしていない");FreeLibrary( hDll );exit(0);}
//GetOrderで特定の牌以降に切られた他家の牌の位置を取得して表示
int kekkas[5];
GetNextOrder(1,sutehais[1][0],kekkas);
ShowMessage("手前プレイヤーのリーチ後に切られる牌は、プレイヤー2の"+(AnsiString)kekkas[2]+"番目の捨て牌、プレイヤー3の"+(AnsiString)kekkas[3]+"番目の捨て牌、プレイヤー4の"+(AnsiString)kekkas[4]+"番目の捨て牌");
//★以上を自由にコーディングする