JP2007135613A - コンピュータゲーム装置およびコンピュータゲームプログラム - Google Patents
コンピュータゲーム装置およびコンピュータゲームプログラム Download PDFInfo
- Publication number
- JP2007135613A JP2007135613A JP2005319260A JP2005319260A JP2007135613A JP 2007135613 A JP2007135613 A JP 2007135613A JP 2005319260 A JP2005319260 A JP 2005319260A JP 2005319260 A JP2005319260 A JP 2005319260A JP 2007135613 A JP2007135613 A JP 2007135613A
- Authority
- JP
- Japan
- Prior art keywords
- max
- computer
- int
- count
- tonari
- Prior art date
- Legal status (The legal status is an assumption and is not a legal conclusion. Google has not performed a legal analysis and makes no representation as to the accuracy of the status listed.)
- Pending
Links
Abstract
【課題】リバーシのよさを活かしながらコンピュータ相手でも飽きないようなゲームを提供すること。
【解決手段】本発明は、リバーシ又はリバーシを変形したもののルールの全部又は一部を実施するコンピュータゲーム装置であって、盤の端や角以外のとこにも壁(それを縦または横にはさんでは取れないオブジェクト)および又は柱(それを斜めにはさんではとれないオブジェクト)が配置され、コンピュータがゲームの進行にあたり、壁および又は柱に関する前記ルールを適用することを特徴とするコンピュータゲーム装置を提供する。
【選択図】図3
【解決手段】本発明は、リバーシ又はリバーシを変形したもののルールの全部又は一部を実施するコンピュータゲーム装置であって、盤の端や角以外のとこにも壁(それを縦または横にはさんでは取れないオブジェクト)および又は柱(それを斜めにはさんではとれないオブジェクト)が配置され、コンピュータがゲームの進行にあたり、壁および又は柱に関する前記ルールを適用することを特徴とするコンピュータゲーム装置を提供する。
【選択図】図3
Description
本発明は、通常のリバーシ、およびその他の人対人がコンピュータなしで遊べる通常のボードゲーム、とは異なる戦略性を要求できるコンピュータゲーム装置およびプログラムに関する。
通常のリバーシ等はいつも同じ戦略性を要求するため、特にコンピュータが相手の場合は飽きてしまうことが多かった。
解決しようとする問題点は、通常のリバーシ等のよさ(シンプルさ、駒配置のわずかの差によるどんでん返し等)を活かしながらコンピュータ相手でも飽きないようなゲームを提供することである。
本発明は、リバーシ又はリバーシを変形したもののルールの全部又は一部を実施するコンピュータゲーム装置であって、盤の端や角以外のところにも壁(それを縦または横にはさんでは取れないオブジェクト)および又は柱(それを斜めにはさんではとれないオブジェクト)が配置され、コンピュータがゲームの進行にあたり、壁および又は柱に関する前記ルールを適用することを特徴とするコンピュータゲーム装置を提供する。
本発明では、コンピュータが相手をするモードにおいて、コンピュータが、座標のうち、一方にすぐ壁又は柱がありかつ対応する反対側には壁や柱がなく開いている方向数およびそれぞれの見通しよく開けている度合いが大きい座標(高度一方開放座標と呼ぶ)を優先してとることが好ましい。
また、コンピュータが、前記高度一方開放座標に隣接する座標をなるべくとらないようにすることが好ましい。
また、序盤でのみ、前記高度一方開放座標を優先的にとることが好ましい。
本発明では、コンピュータが相手をするモードにおいて、コンピュータが、座標のうち、一方にすぐ壁又は柱がありかつ対応する反対側には壁や柱がなく開いている方向数およびそれぞれの見通しよく開けている度合いの大きい座標(高度一方開放座標)に向けて同様に(一方にすぐ壁又は柱がありかつ対応する反対側には壁や柱がなく)開いている方向数およびそれぞれの高度一方開放座標を含む度合いの大きい座標(高度一方開放座標高度含有一方開放座標)を優先してとることが好ましい。
また、コンピュータが、前記高度一方開放座標高度含有一方開放座標に隣接する座標をなるべくとらないようにすることが好ましい。
また、序盤でのみ、前記高度一方開放座標高度含有一方開放座標を優先的にとることが好ましい。
本発明は、コンピュータが相手をするモードにおいて、現在のゲーム状態に対して過去にコンピュータの思考ルーチンが決定した手又は過去に有利に戦った対戦者が決定した手を採用するキャッシュ手段を有することが有利である。
また、コンピュータが相手をするモードにおいて、コンピュータの思考時間の短さの要請および又は先読みの度合いに対応する可能な手順の個数が、CPUおよび又はメモリの能力に比して十分小さくなるように、初期の敵味方駒、前記壁および又は前記柱の量および又は配置が調節されていることが有利である。
また、コンピュータが相手をするモードにおいて、より上位のハイスコアにスコア自体より大きい重みを与えながら、種々の盤(盤ごとに初期の敵味方駒、前記壁および又は前記柱の量および又は配置が異なる)のハイスコアを合計して表示するハイスコア合計手段を有することが好ましい。
本発明はまた、リバーシ又はリバーシを変形したもののルールの全部又は一部を実施するコンピュータゲームプログラムであって、盤の端や角以外のところにも壁(それを縦または横にはさんでは取れないオブジェクト)および又は柱(それを斜めにはさんではとれないオブジェクト)が配置され、コンピュータがゲームの進行にあたり、壁および又は柱に関する前記ルールを適用することを特徴とするコンピュータゲームプログラムを提供する。
本発明はまた、人対人がコンピュータなしで遊べるボードゲーム又は該ボードゲームを変形したもののルールの全部又は一部を実施するコンピュータゲームプログラムであって、盤の端や角以外のところにも壁(縦または横方向に関するゲームルール既定の効果を排除するオブジェクト)および又は柱(斜め方向に関するゲームルール既定の効果を排除するオブジェクト)が配置され、コンピュータがゲームの進行にあたり、壁および又は柱に関する前記ルールを適用することを特徴とするコンピュータゲームプログラムを提供する。
本発明はまた、人対人がコンピュータなしで遊べるボードゲーム又は該ボードゲームを変形したもののルールの全部又は一部を実施するコンピュータゲームプログラムであって、盤の端や角以外のところにも壁(縦または横方向に関するゲームルール既定の効果を排除するオブジェクト)および又は柱(斜め方向に関するゲームルール既定の効果を排除するオブジェクト)が配置され、コンピュータがゲームの進行にあたり、壁および又は柱に関する前記ルールを適用することを特徴とするコンピュータゲームプログラムを提供する。
請求項1、11および12の発明では、それぞれ(盤(=ボード)ごとに)異なる戦略性を要求することができ課題を達成できる。
請求項2および5の発明では、(壁や柱がなく)ひらけているため重要でかつ(反対方向に隣接する壁や柱があり)とられにくい地点(請求項2)およびそういった地点をとりやすい地点(請求項5)をコンピュータが優先してとるのでコンピュータの手が対戦相手としてふさわしい十分強いものになる。
また、請求項3および6の発明では、利用者が簡単に高度一方開放座標や高度一方開放座標高度含有一方開放座標をとることを防ぎゲームを面白くする。
また、請求項4および7の発明により、終盤では請求項2、5、3および6のようなヒューリスティックスよりも(公知の)MIN−MAX法等による具体的で確実な計算(ゲームの詰め)を優先することができる。
請求項8の発明により、コンピュータの思考ルーチンの応答時間を高速化したり応答内容(コンピュータの手)を多様化したり学習により強化したりすることが可能になる。また、本発明によるゲームではリバーシの定石データベース等が利用できない局面が多いため探索の機会およびコストが多大となり、探索結果を再活用したりできるこのような仕組みが特に効果的となる。また、壁や柱により探索空間(ゲーム空間)そのものが小さくなる場合があり、この場合にはリバーシよりもパターン(駒の配置パターン)の再現率(過去のパターンに出会うヒット率)が高くなるため、少ないメモリおよびオーバーヘッドで効果的に高速化を図ることができる。
また、請求項9の発明により、たとえば携帯電話用JAVA(登録商標)処理系などあまり処理スピードが高くないプラットフォームに対しても、十分、高速でかつ戦いがいのある強さのコンピュータ思考ルーチンを提供することができるようになる。
さらに請求項10の発明により、他のプレイヤーとの対立構造が生じる国盗り合戦形式のゲーム性を楽しむことが可能になる。すなわち、ある盤で他人のハイスコアを追い抜くことにより、順位に応じたハイスコアの重みも変わり、他人のハイスコア合計を減らすことが可能になり、国盗り合戦と同様の利害構造となる。
請求項2および5の発明では、(壁や柱がなく)ひらけているため重要でかつ(反対方向に隣接する壁や柱があり)とられにくい地点(請求項2)およびそういった地点をとりやすい地点(請求項5)をコンピュータが優先してとるのでコンピュータの手が対戦相手としてふさわしい十分強いものになる。
また、請求項3および6の発明では、利用者が簡単に高度一方開放座標や高度一方開放座標高度含有一方開放座標をとることを防ぎゲームを面白くする。
また、請求項4および7の発明により、終盤では請求項2、5、3および6のようなヒューリスティックスよりも(公知の)MIN−MAX法等による具体的で確実な計算(ゲームの詰め)を優先することができる。
請求項8の発明により、コンピュータの思考ルーチンの応答時間を高速化したり応答内容(コンピュータの手)を多様化したり学習により強化したりすることが可能になる。また、本発明によるゲームではリバーシの定石データベース等が利用できない局面が多いため探索の機会およびコストが多大となり、探索結果を再活用したりできるこのような仕組みが特に効果的となる。また、壁や柱により探索空間(ゲーム空間)そのものが小さくなる場合があり、この場合にはリバーシよりもパターン(駒の配置パターン)の再現率(過去のパターンに出会うヒット率)が高くなるため、少ないメモリおよびオーバーヘッドで効果的に高速化を図ることができる。
また、請求項9の発明により、たとえば携帯電話用JAVA(登録商標)処理系などあまり処理スピードが高くないプラットフォームに対しても、十分、高速でかつ戦いがいのある強さのコンピュータ思考ルーチンを提供することができるようになる。
さらに請求項10の発明により、他のプレイヤーとの対立構造が生じる国盗り合戦形式のゲーム性を楽しむことが可能になる。すなわち、ある盤で他人のハイスコアを追い抜くことにより、順位に応じたハイスコアの重みも変わり、他人のハイスコア合計を減らすことが可能になり、国盗り合戦と同様の利害構造となる。
本発明をWebシステム用ブラウザソフトウエアで遊ぶためのCGIプログラムとしてサーバーコンピュータが対戦相手およびルールの適用をするようにして実現した。
サーバープログラムの主要部分のアルゴリズムは、2つのC言語モジュールとして記載すると、参考資料A1((1)biwako.cおよび(2)ws.c)のとおりである。なお、これらの2つのソースコードの一部をよりわかりやすい形式(白をWで符号化し、黒をBで符号化した形式)に書き直す等したものを参考資料B2(JP-wakwayama1.c)および参考資料B3(wseuc_num8an.c)として添付した。また、参考資料B1は、コンピュータ相手のモードにつき国盗り合戦形式を楽しめるようにした「盤選択用&ハイスコア合計ランキング表示用TOPページ」(図1の画面に対応)のCGI(Perl言語で記載)プログラムである。参考資料B1、B2、B3および公知のミニマックス法(探索アルゴリズム)や公知の暗号化の知識があれば、当業者は、UNIX(登録商標)互換OS上でgcc等によりコンパイルしたり、さらにhttp(Web)サーバであるapache(登録商標)のCGI用ディレクトリに配置して実行パーミッションを与えるたりすることにより、本発明を容易に実施することができる。
なお、Webシステムのハードウエアと本発明によるCGIプログラム(参考資料A1(1)(2)をコンパイルしたもの(または、参考資料B2およびB3を一緒にコンパイルしたもの)および参考資料B1に実行権限を与えたもの)の関係について簡単に述べると、Webシステム用ブラウザソフトウエア(INTERNET EXPLORER(登録商標)等)は、家庭用PCのOSソフトウエア(MICROSOFT WINDOWS(登録商標)等)上で動作するように構成されており、OSソフトウエアの提供するTCP/IP通信機能等により、インターネットを介して、サーバーハードウエア(ワークステーション等)に、より上位のプロトコル(http)を用いて、本発明によるゲームの表示を要求する。サーバーハードウエアには上記UNIX(登録商標)等のサーバーOS用ソフトウエアが動作しており、このサーバーOS用ソフトウエアが、上記httpサーバープログラム(apache等)と本発明によるCGIプログラム(参考資料B1についてはさらにPerl実行環境も含む)との協働を制御して、CGIプログラムの標準出力の内容(HTTPプロトコル部分、HTML部分、その他の事前定義されたPC側WEBシステム用ブラウザ実行スクリプト等)を、やはりhttpプロトコルで、家庭用PCに返すことになる。Webシステム用ブラウザソフトウエアは、返されたHTML部分やその他の上記実行スクリプト等を解釈して、指定された場所に指定された色、文字、グラフィックやコントロールを配置し、利用者にゲームの状態(壁や柱の配置、地形の状況および白黒等の配置)を表示しかつゲームを進行するためのインターフェース(次の一手選択用リンクやハイスコアプレイヤー名入力欄やハイスコア送信ボタン等)を提供する(例えば、図2では利用者(白)の次の一手選択用のリンクがいくつか表示されている)。
図1は、本実施形態による「盤選択用&ハイスコア合計ランキング表示用TOPページ」の例を説明するものである。最上部の「tottori1鳥取県」で始まるリンク項目は、鳥取県の行政区画をモチーフにしたゲームを始めることができる。また対応する「隣人対戦」リンクでは、同じモチーフ(鳥取県)で人対人が対戦することができる。利用者は、同様に、さらに下の他の県等をモチーフにしたゲームを選択することができる。なお、別の実施形態では、県ではなく、物品や動物や幾何学模様や記号、さらにはより抽象的なマーケット構造などのモチーフを表現する盤のリストから選択できるようになっている。
図1の中央以下は、ハイスコア合計ランキングであり、1位はyoshiの7821390石である。これは本実施形態がモチーフとする各県等の行政区画を盤とした各ゲームでのハイスコアの合計であるが、1位は10000倍、2位は1000倍、3位は100倍、4位は10倍の重みで、ハイスコア「合計」に加算されるため、yoshiが1位である県(例えばchiba1)で他の人(例えばKN)にハイスコアを抜かれると、10000倍にして加算されていたchiba1のハイスコアが1000倍にしてyoshiのハイスコア合計に加算されるようになるため、yoshiのハイスコア合計値としては小さくなり、その他の人(KN)が結果的にchiba1を盗りハイスコア合計を大きく伸ばすことになる。
図1の中央以下は、ハイスコア合計ランキングであり、1位はyoshiの7821390石である。これは本実施形態がモチーフとする各県等の行政区画を盤とした各ゲームでのハイスコアの合計であるが、1位は10000倍、2位は1000倍、3位は100倍、4位は10倍の重みで、ハイスコア「合計」に加算されるため、yoshiが1位である県(例えばchiba1)で他の人(例えばKN)にハイスコアを抜かれると、10000倍にして加算されていたchiba1のハイスコアが1000倍にしてyoshiのハイスコア合計に加算されるようになるため、yoshiのハイスコア合計値としては小さくなり、その他の人(KN)が結果的にchiba1を盗りハイスコア合計を大きく伸ばすことになる。
図2は、本実施形態によりコンピュータが相手をするモードのゲーム状態の表示&操作画面の例である。人対人のモードの場合には、下部のランキングは表示されない。ランキングでは、上述したように上位の者が本来のハイスコアより大きい重み(10000倍等)を与えられている。
図2上部のJPは図1の「盤選択用&ハイスコア合計ランキング表示用TOPページ」に戻るためのリンク、UVは他のテーマのモチーフを集めた別の「盤選択用&ハイスコア合計ランキング表示用TOPページ」へ移動するためのリンクである。その下に、システム応答時間、盤名、現在の白黒の駒数、次のターンの駒色等が表示され、さらにその下に、現在のゲーム状態が表示される。通常のリバーシと異なり、本実施形態では、初期ゲーム状態の駒の配置がより自由に決められている。また、本発明による壁や柱がいくつか配置されている。ここでは、その配置のため、通常のリバーシでは取れる座標(X:6、Y:5)がとれない場所(青丸のない場所)になっている。これは、座標(X:6、Y:5)と座標(X:5、Y:5)の間に黄色の壁があるためである。この壁によって座標(X:5、Y:5)の黒は守られていることになる。
また、座標(X:6、Y:5)の右上の点は現実世界の湖ないし池を本発明による柱として作用させたものであり、右下の点は現実世界の行政区画においてその区切りをまたぐ大きな道がないため、壁の間に柱を加えて完全に遮断したものである。このように現実を反映させることでゲームを親しみやすくしている。
また、座標(X:1、Y:2)の下の青線は現実の川を本発明による壁として作用させたものである。また、下部の大きな青いエリアは海を示しており、陸との境界線に青い壁を配置することで、現実世界を反映した表示およびゲーム性にして利用者の興味を高めている。
図2上部のJPは図1の「盤選択用&ハイスコア合計ランキング表示用TOPページ」に戻るためのリンク、UVは他のテーマのモチーフを集めた別の「盤選択用&ハイスコア合計ランキング表示用TOPページ」へ移動するためのリンクである。その下に、システム応答時間、盤名、現在の白黒の駒数、次のターンの駒色等が表示され、さらにその下に、現在のゲーム状態が表示される。通常のリバーシと異なり、本実施形態では、初期ゲーム状態の駒の配置がより自由に決められている。また、本発明による壁や柱がいくつか配置されている。ここでは、その配置のため、通常のリバーシでは取れる座標(X:6、Y:5)がとれない場所(青丸のない場所)になっている。これは、座標(X:6、Y:5)と座標(X:5、Y:5)の間に黄色の壁があるためである。この壁によって座標(X:5、Y:5)の黒は守られていることになる。
また、座標(X:6、Y:5)の右上の点は現実世界の湖ないし池を本発明による柱として作用させたものであり、右下の点は現実世界の行政区画においてその区切りをまたぐ大きな道がないため、壁の間に柱を加えて完全に遮断したものである。このように現実を反映させることでゲームを親しみやすくしている。
また、座標(X:1、Y:2)の下の青線は現実の川を本発明による壁として作用させたものである。また、下部の大きな青いエリアは海を示しており、陸との境界線に青い壁を配置することで、現実世界を反映した表示およびゲーム性にして利用者の興味を高めている。
図3は、本実施形態による壁(盤内の縦、横の長方形)や柱(盤内の小さい正方形の点)の影響を説明した遊び方画面の例である。左側には、日英でのルール説明文が8か条があり、右側にはいくつかの壁と柱を有する盤の例および盤内の各オブジェクトの説明が示される。この盤の例では、壁は、行政区画の区切り線に沿って配置され、区切り線をまたぐ大きな道が現実世界にある場合には、区切り線(壁)の間に柱を配置せずに区切られたエリア間の相互の影響が少し(斜め方向のみ)残るようにし、大きな道がない場合には柱を配置して区切られたエリア間の相互の影響がないようにしている。
自然法則の利用は、上記送受信動作において、ノイマン型コンピュータとしてのPCやワークステーションが、OSソフトウエアや、本発明によるCGIプログラムや、その他のツールプログラム(上記apache、perl等)の実行に際し、物理メモリ、CPU、バス、通信ポート等のハードウエアを利用する際に明らかに行われる。特に、上記本発明による壁や柱の配置を管理するための配列変数やコンピュータ思考ルーチンのコンテキストを管理するためのスタック変数を、記憶手段としての高速な物理メモリ(RAM、ハードディスク)に展開して記憶および参照することにより、本発明に特有のルール(壁、柱による挟む効果の遮断)に正確に沿い、盤上配置の一貫性もあり、かつ十分高速であるゲーム進行(人間対戦モードおよびコンピュータ対戦モード)と、重複やもれのない高速な思考プロセス(コンピュータ対戦モード)と、を可能にする。
以降では、本発明の各機能と参考資料B中のソースコードとの対応あるいは機能の実現方法について述べる。
盤の端や角以外のところにも壁(それを縦または横にはさんでは取れないオブジェクト)および又は柱(それを斜めにはさんではとれないオブジェクト)を配置しているのは、参考資料B2の“char board[21*21]=”以降であり、例えば“+”は柱を、“|”は縦の壁を、“−”は横の壁を、“C”は海、湖や川としての壁や柱を、“G”は山や行政区画としての壁や柱を示している。
コンピュータがゲームの進行にあたり、壁および又は柱に関する前記ルールを適用する部分は、参考資料B3の0212行目のpos_check等であり、上記“+”等の存在を意識して盤オブジェクトを走査している。
コンピュータがゲームの進行にあたり、壁および又は柱に関する前記ルールを適用する部分は、参考資料B3の0212行目のpos_check等であり、上記“+”等の存在を意識して盤オブジェクトを走査している。
コンピュータが、座標のうち、一方にすぐ壁又は柱がありかつ対応する反対側には壁や柱がなく開いている方向数およびそれぞれの見通しよく開けている度合いが大きい座標(高度一方開放座標と呼ぶ)を優先してとるようにしているのは、参考資料B3の0088行目のvalue_init関数等である。この関数は高度一方開放座標の重み(valxy)が他の座標の重み(valxy)より重くなるようにし、pos_checkや思考ルーチンrecursive_all_pos_check(0979行目〜)でその重みの合計が多くなる手をコンピュータが選ぶようにすることにより、この機能を実現する。
コンピュータが、前記高度一方開放座標に隣接する座標をなるべくとらないようにすることも、value_init関数の0164行目から0186行目で行っている。すなわち、高度一方開放座標に隣接する座標はマイナスの重みなどとなり、(上記recursive_all_pos_check関数等で)重みの合計が多くなる手をコンピュータが選ぶ際に選択肢からはずされる。
序盤でのみ、前記高度一方開放座標を優先的にとるためには、参考資料B3のソースコードに、残り手数が所定の閾値(例えば8)以下になったとき等に重みvalxyをすべて1に固定するルーチンを、たとえば、value_initに条件実行文として加えればよい。これにより、すべての座標が平等な重みをもつことになり、客観的な勝利条件(駒数が多いほうが勝ち)を正確に反映したミニマックス判断等が可能になる。
コンピュータが、高度一方開放座標高度含有一方開放座標の重みvalxyを重くしてそれらを優先してとるための前処理は、参考資料B3内のvalue_initの0136行目から0156行目までで行っている。実際に優先してとる後処理は、高度一方開放座標と同様にpos_checkおよびrecursive_all_pos_checkが行う。
また、コンピュータが、前記高度一方開放座標高度含有一方開放座標に隣接する座標をなるべくとらないようにすることは、高度一方開放座標(多くの場合は高度一方開放座標高度含有一方開放座標と重なる)の場合と同様にvalue_init関数の0164行目から0186行目で行っている。
また、序盤でのみ、前記高度一方開放座標高度含有一方開放座標を優先的にとる処理も、上記高度一方開放座標の場合と同様に行うことができる。
現在のゲーム状態に対して過去にコンピュータの思考ルーチンが決定した手又は過去に有利に戦った対戦者が決定した手を採用するキャッシュ手段は、すべてのサーバープログラムの動作を図示しないデータベース等に残すことにより実現する。参考資料B3の1564行目の後に、now_status、黒およびMAP_LOOPをキーとしてmaxi、maxjを連想できるデータベース内データ構造(テーブル)への登録処理を挿入する。また、同じ1564行目を、now_status、黒およびMAP_LOOPがそのデータベース内データ構造(テーブル)に登録されていないときだけrecursive_all_pos_checkを実行して新たなmaxiおよびmaxjを求めるように書き換える。有利に戦った手の場合ログ統計等も参照して決定する。
コンピュータが相手をするモードにおいて、コンピュータの思考時間の短さの要請および又は先読みの度合いに対応する可能な手順の個数が、CPUおよび又はメモリの能力に比して十分小さくなるように、初期の敵味方駒、前記壁および又は前記柱の量および又は配置を調節することは、経験等に基づいて人手でおこなうこともできるが、プラットフォームのCPUパフォーマンス等を随時検出して、設計した盤および初期駒配置についてのゲーム空間の広さに関する所定の測定値(たとえば壁や柱の少なさ)と比較して、適合する盤および初期駒配置を自動的に選択して提供するようにすることも明らかに可能である。
コンピュータが相手をするモードにおいて、より上位のハイスコアにスコア自体より大きい重みを与えながら、種々の盤(盤ごとに初期の敵味方駒、前記壁および又は前記柱の量および又は配置が異なる)のハイスコアを合計して表示するハイスコア合計手段は、参考資料B1のCGIプログラム(Perl言語)の後半と、参考資料B3のソースコードの0835行目から0885行目までとが協働して実現している。
本明細書では、Webシステム用ブラウザソフトウエアとCGIプログラムとによるクライアントサーバー型通信で本発明のコンピュータゲーム装置を実現する例について、以上説明してきたが、本発明の範囲は、この例に限られず、特許請求の範囲によってのみ定められる。
例えば、本発明の開示により、CGIプログラムとして実施する代わりに、明らかに、サーブレットプログラムとしてJAVA言語その他のプラットフォームに移植する等して、実施することもできる。また、本発明の範囲内で、スタンドアロン型でも実施することができ、ソースコードとして示したサーバー用CGIプログラムの機能を、家庭用PC、ゲーム専用機、あるいは携帯電話等のソフトウエア(家庭用PCのネーティブコード、JAVAアプレット、その他の中間言語やスクリプト)内に含めるように構成し、他のサーバーとの送受信無しで実施することもできる。
また、例えば、壁や柱を太く大きく表示したり、柱を見やすく十字に表示したりすること等もできる。
また、例えば、リバーシの変形として盤内の座標をレンガ状に隣接させたり、蜂の巣状に隣接させたゲームにも適用することができ、この場合は、斜めのはさみ効果を遮断するものとして定義される柱は、板状に表示することができる。
また、将棋およびそれに類するルールを有するボードゲーム、囲碁およびそれに類するルールを有するボードゲーム、はさみ将棋およびそれに類するルール(全部飛車の動きではなく各駒固有の動きをしたり、王がとられたら終わりとしたりするルール)を有するボードゲーム、N目並べ(N>2)およびそれに類するルールを有するボードゲーム等においても、壁および柱を意識したコンピュータの動作をリバーシの場合と同様に実現することにより(リバーシのルールと全く関係がないゲームの場合も含めて)明らかに戦略性を変更することができる。
将棋などについては、桂馬しか飛び越えられない又はどの駒も跨げない又は接しない駒が跨げないオブジェクトとしての壁および又は柱を、やはり本発明と同様に地形のルールや表示も実施しながら、城、砦または城壁等として設置したりできる。ただし、コンピュータ相手の場合の請求項2以降のヒューリスティックスは将棋に併せて変更が必要となる。基本は、味方駒の種類や配置(持ち駒も含む)も加味した勢力の有利度(特に序盤で重視)や王駒の危険度(特に終盤で重視、なお、敵味方いずれかの王駒の危険度が所定閾値を超えた場合を終盤と定義したり、駒の勢力差が所定閾値を超えた場合を終盤と定義したり、それらを組み合わせたりできる)に応じたゲーム状態の総合評価(本発明のリバーシの場合では、序盤は味方valxyの合計(と敵valxyの合計の差)にあたる値、終盤は味方の駒数(と敵の駒数の差)にあたる値)が高まるような手をミニマックス法等により決定することになる。
囲碁などについては、盤の隅角(周囲)以外にも出現した壁等と併せた囲みにより囲んでとるというルールを、コンピュータを用いて当業者に自明なアルゴリズムで、本発明と同様のアイディア(現実の地形の反映等)と構成で実施できる。コンピュータ相手の場合の総合評価としては、将棋同様に囲碁に関する総合評価方式(盤上の陣地の量の差、いずれかを敵を囲んでとるまで(あるいは囲んでとることについてのダブルリーチまでの)工数およびとれる数の差等)を壁等を意識したものに変形して用いることができる。
はさみ将棋等の場合では、壁や柱をまたいでは移動できないようにしたり、壁や柱と敵駒により移動できなくなった駒はとられるというルールをコンピュータが(自然法則を利用して(これは、全部のゲームで同じ))適用することができる。コンピュータが相手をする場合の基本はやはりミニマックス法でよいが、その際のゲーム状態の総合評価方式としては、上記将棋と囲碁の評価方式を組み合わせたものとすることができる。ただし、王駒をとられても終了しない場合には、王駒の危険度は考慮しない。
N目並べ(5目ならべ等)については、壁や柱をはさんでN目に並べても勝ちではないというルールを、本発明と同様にコンピュータが適用することができる。コンピュータが相手をする場合の基本はやはりミニマックス法でよいが、その際のゲーム状態の総合評価方式としては敵のダブルリーチ構築工数−味方のダブルリーチ構築工数等とすることができる。
どのゲーム種類の場合も戦略性が盤ごとに変わるため飽きにくく、身近な地形などの表示により「○○地域重視戦略」などと戦略に名前をつけて利用者の間で共有して楽しんだり研究したりしやすいものとなっている。また、壁や柱によって生じるルールの適用のコスト、(壁や柱によって大きくなる場合もある)次に打てる手の選択肢の抽出の人的労力、盤によってかわる地形等の表示コストが、自然法則を利用した高速で安定したコンピュータの利用により大幅に削減され有利になる。また、壁や柱をつくるルール変更は他のルール変更(駒の配置や効力や属性が時間等によって勝手にかわる等)に比べて、各ゲームについての公知・公用のコンピュータ実施手法(例えば公知のゲーム状態評価方式、状態表示方式、手有効性判断方式)の多くを簡単に(場合によってはそのまま)とりいれることができ、本明細書によるリバーシの場合についての詳細な説明、上記のような各ゲームについての簡明なルール変更の説明および各ルール変更に対応したゲーム状態評価方式の新しい指針の説明があれば、当業者はリバーシ以外のそのようなゲームについても容易に壁や柱のあるものを実現できる。
また、例えば、壁や柱を太く大きく表示したり、柱を見やすく十字に表示したりすること等もできる。
また、例えば、リバーシの変形として盤内の座標をレンガ状に隣接させたり、蜂の巣状に隣接させたゲームにも適用することができ、この場合は、斜めのはさみ効果を遮断するものとして定義される柱は、板状に表示することができる。
また、将棋およびそれに類するルールを有するボードゲーム、囲碁およびそれに類するルールを有するボードゲーム、はさみ将棋およびそれに類するルール(全部飛車の動きではなく各駒固有の動きをしたり、王がとられたら終わりとしたりするルール)を有するボードゲーム、N目並べ(N>2)およびそれに類するルールを有するボードゲーム等においても、壁および柱を意識したコンピュータの動作をリバーシの場合と同様に実現することにより(リバーシのルールと全く関係がないゲームの場合も含めて)明らかに戦略性を変更することができる。
将棋などについては、桂馬しか飛び越えられない又はどの駒も跨げない又は接しない駒が跨げないオブジェクトとしての壁および又は柱を、やはり本発明と同様に地形のルールや表示も実施しながら、城、砦または城壁等として設置したりできる。ただし、コンピュータ相手の場合の請求項2以降のヒューリスティックスは将棋に併せて変更が必要となる。基本は、味方駒の種類や配置(持ち駒も含む)も加味した勢力の有利度(特に序盤で重視)や王駒の危険度(特に終盤で重視、なお、敵味方いずれかの王駒の危険度が所定閾値を超えた場合を終盤と定義したり、駒の勢力差が所定閾値を超えた場合を終盤と定義したり、それらを組み合わせたりできる)に応じたゲーム状態の総合評価(本発明のリバーシの場合では、序盤は味方valxyの合計(と敵valxyの合計の差)にあたる値、終盤は味方の駒数(と敵の駒数の差)にあたる値)が高まるような手をミニマックス法等により決定することになる。
囲碁などについては、盤の隅角(周囲)以外にも出現した壁等と併せた囲みにより囲んでとるというルールを、コンピュータを用いて当業者に自明なアルゴリズムで、本発明と同様のアイディア(現実の地形の反映等)と構成で実施できる。コンピュータ相手の場合の総合評価としては、将棋同様に囲碁に関する総合評価方式(盤上の陣地の量の差、いずれかを敵を囲んでとるまで(あるいは囲んでとることについてのダブルリーチまでの)工数およびとれる数の差等)を壁等を意識したものに変形して用いることができる。
はさみ将棋等の場合では、壁や柱をまたいでは移動できないようにしたり、壁や柱と敵駒により移動できなくなった駒はとられるというルールをコンピュータが(自然法則を利用して(これは、全部のゲームで同じ))適用することができる。コンピュータが相手をする場合の基本はやはりミニマックス法でよいが、その際のゲーム状態の総合評価方式としては、上記将棋と囲碁の評価方式を組み合わせたものとすることができる。ただし、王駒をとられても終了しない場合には、王駒の危険度は考慮しない。
N目並べ(5目ならべ等)については、壁や柱をはさんでN目に並べても勝ちではないというルールを、本発明と同様にコンピュータが適用することができる。コンピュータが相手をする場合の基本はやはりミニマックス法でよいが、その際のゲーム状態の総合評価方式としては敵のダブルリーチ構築工数−味方のダブルリーチ構築工数等とすることができる。
どのゲーム種類の場合も戦略性が盤ごとに変わるため飽きにくく、身近な地形などの表示により「○○地域重視戦略」などと戦略に名前をつけて利用者の間で共有して楽しんだり研究したりしやすいものとなっている。また、壁や柱によって生じるルールの適用のコスト、(壁や柱によって大きくなる場合もある)次に打てる手の選択肢の抽出の人的労力、盤によってかわる地形等の表示コストが、自然法則を利用した高速で安定したコンピュータの利用により大幅に削減され有利になる。また、壁や柱をつくるルール変更は他のルール変更(駒の配置や効力や属性が時間等によって勝手にかわる等)に比べて、各ゲームについての公知・公用のコンピュータ実施手法(例えば公知のゲーム状態評価方式、状態表示方式、手有効性判断方式)の多くを簡単に(場合によってはそのまま)とりいれることができ、本明細書によるリバーシの場合についての詳細な説明、上記のような各ゲームについての簡明なルール変更の説明および各ルール変更に対応したゲーム状態評価方式の新しい指針の説明があれば、当業者はリバーシ以外のそのようなゲームについても容易に壁や柱のあるものを実現できる。
以下に上記参考資料としてのソースコードを示す。
<参考資料A1(1)>
//以下、盤(=面、ラウンド、モチーフ)ごとのプログラム(biwako.c)
char board[]=
// JP-biwako1
"+---------------+"
"|CCCC |"
"|CCCC |"
"| |"
"| CCCCC |"
"| CCCCC |"
"| CCCCC |"
"| CCCCC |"
"| CCCCCCC |"
"| CCCCC |"
"| CCCCC |"
"| CCC |"
"| CCC |"
"| |"
"| |"
"| |"
"+---------------+"
;
char init[]=
// JP-biwako1
"NNNNNNNN"
"NNNNNNNN"
"NNWRNNNN"
"NNRWNNNN"
"NNNNNNNN"
"NNNNRWNN"
"NNNNWRNN"
"NNNNNNNN"
;
<参考資料A1(2)>
//以下メインプログラム( ws.c)
char CGINAME[ 1024 ];
extern char init[];
extern char board[];
#define IS_STACK_EST (0)
#define COLOR_GREEN "#33ff33"
#define MUGENM (-65535)
#define MUGENP (+65535)
#define GAME_SIZE_X (8)
#define GAME_SIZE_Y (8)
#define BOARD_SIZE_X (GAME_SIZE_X+GAME_SIZE_X+1)
#define BOARD_SIZE_Y (GAME_SIZE_Y+GAME_SIZE_Y+1)
//#define IMG "http://wallstreets.ws/icons/PIC_0041.JPG";
#define PIMGM "http://wallstreets.ws/icons/PIC_0043M.JPG";
#define PIMG "http://wallstreets.ws/icons/PIC_0043.JPG";
//char board[ 21*21 ] = {
/*
int valpr[ 9 ][ 9 ] = { 0 };
int valxy[ 9 ][ 9 ] = { 0 };
int dirnm[ 9 ][ 9 ] = { 0 };
char blockget( int sizex, int sizey, int x, int y, char *b)
{
return *(b + y*sizex + x);
}
int valdir( int basex, int basey, int dirx, int diry, char *b)
{
int point = 0;
int sizex = 8;
int sizey = 8;
while( blockget( sizex*2+1, sizey*2+1, (basex-1)*2+1-dirx, (basey-1)*2+1-diry, b) == ' '){
point++;
basex -= dirx;
basey -= diry;
}
return point;
}
int valdirxy( int basex, int basey, int dirx, int diry, char *b)
{
int point = 0;
int sizex = 8;
int sizey = 8;
while( blockget( sizex*2+1, sizey*2+1, (basex-1)*2+1-dirx, (basey-1)*2+1-diry, b) == ' '){
point += valpr[ basex ][ basey ];
basex -= dirx;
basey -= diry;
}
return point;
}
int valdirnb( int basex, int basey, int dirx, int diry, char *b)
{
return -valpr[ basex+dirx ][ basey+diry ]/dirnm[ basex+dirx ][ basey+diry ];
}
void value_init( char *b)
{
int sizex = 8;
int sizey = 8;
int cx, cy;
for( cx = 1; cx <= 8; cx++)
for( cy = 1; cy <= 8; cy++)
dirnm[ cx ][ cy ] =
((blockget( sizex*2+1, sizey*2+1, (cx-1)*2, (cy-1)*2, b) == ' ') ?
1:0)
+((blockget( sizex*2+1, sizey*2+1, (cx-1)*2, (cy-1)*2+1, b) == ' ') ?
1:0)
+((blockget( sizex*2+1, sizey*2+1, (cx-1)*2, (cy-1)*2+2, b) == ' ') ?
1:0)
+((blockget( sizex*2+1, sizey*2+1, (cx-1)*2+1, (cy-1)*2, b) == ' ') ?
1:0)
+((blockget( sizex*2+1, sizey*2+1, (cx-1)*2+1, (cy-1)*2+2, b) == ' ') ?
1:0)
+((blockget( sizex*2+1, sizey*2+1, (cx-1)*2+2, (cy-1)*2, b) == ' ') ?
1:0)
+((blockget( sizex*2+1, sizey*2+1, (cx-1)*2+2, (cy-1)*2+1, b) == ' ') ?
1:0)
+((blockget( sizex*2+1, sizey*2+1, (cx-1)*2+2, (cy-1)*2+2, b) == ' ') ?
1:0);
for( cx = 1; cx <= 8; cx++)
for( cy = 1; cy <= 8; cy++){
valpr[ cx ][ cy ] =
((blockget( sizex*2+1, sizey*2+1, (cx-1)*2, (cy-1)*2, b) == ' ') ?
0:valdir(cx,cy,-1,-1, b))
+((blockget( sizex*2+1, sizey*2+1, (cx-1)*2, (cy-1)*2+1, b) == ' ') ?
0:valdir(cx,cy,-1, 0, b))
+((blockget( sizex*2+1, sizey*2+1, (cx-1)*2, (cy-1)*2+2, b) == ' ') ?
0:valdir(cx,cy,-1,+1, b))
+((blockget( sizex*2+1, sizey*2+1, (cx-1)*2+1, (cy-1)*2, b) == ' ') ?
0:valdir(cx,cy, 0,-1, b))
+((blockget( sizex*2+1, sizey*2+1, (cx-1)*2+1, (cy-1)*2+2, b) == ' ') ?
0:valdir(cx,cy, 0,+1, b))
+((blockget( sizex*2+1, sizey*2+1, (cx-1)*2+2, (cy-1)*2, b) == ' ') ?
0:valdir(cx,cy,+1,-1, b))
+((blockget( sizex*2+1, sizey*2+1, (cx-1)*2+2, (cy-1)*2+1, b) == ' ') ?
0:valdir(cx,cy,+1, 0, b))
+((blockget( sizex*2+1, sizey*2+1, (cx-1)*2+2, (cy-1)*2+2, b) == ' ') ?
0:valdir(cx,cy,+1,+1, b))
;
}
for( cx = 1; cx <= 8; cx++)
for( cy = 1; cy <= 8; cy++){
valxy[ cx ][ cy ] = valpr[ cx ][ cy ]
+((blockget( sizex*2+1, sizey*2+1, (cx-1)*2, (cy-1)*2, b) == ' ') ?
0:valdirxy(cx,cy,-1,-1, b))
+((blockget( sizex*2+1, sizey*2+1, (cx-1)*2, (cy-1)*2+1, b) == ' ') ?
0:valdirxy(cx,cy,-1, 0, b))
+((blockget( sizex*2+1, sizey*2+1, (cx-1)*2, (cy-1)*2+2, b) == ' ') ?
0:valdirxy(cx,cy,-1,+1, b))
+((blockget( sizex*2+1, sizey*2+1, (cx-1)*2+1, (cy-1)*2, b) == ' ') ?
0:valdirxy(cx,cy, 0,-1, b))
+((blockget( sizex*2+1, sizey*2+1, (cx-1)*2+1, (cy-1)*2+2, b) == ' ') ?
0:valdirxy(cx,cy, 0,+1, b))
+((blockget( sizex*2+1, sizey*2+1, (cx-1)*2+2, (cy-1)*2, b) == ' ') ?
0:valdirxy(cx,cy,+1,-1, b))
+((blockget( sizex*2+1, sizey*2+1, (cx-1)*2+2, (cy-1)*2+1, b) == ' ') ?
0:valdirxy(cx,cy,+1, 0, b))
+((blockget( sizex*2+1, sizey*2+1, (cx-1)*2+2, (cy-1)*2+2, b) == ' ') ?
0:valdirxy(cx,cy,+1,+1, b))
;
}
for( cx = 1; cx <= 8; cx++)
for( cy = 1; cy <= 8; cy++)
valpr[ cx ][ cy ] = valxy[ cx ][ cy ];
{
int min = 65535;
for( cx = 1; cx <= 8; cx++)
for( cy = 1; cy <= 8; cy++){
valxy[ cx ][ cy ] = valpr[ cx ][ cy ]
+((blockget( sizex*2+1, sizey*2+1, (cx-1)*2, (cy-1)*2, b) != ' ') ?
0:valdirnb(cx,cy,-1,-1, b))
+((blockget( sizex*2+1, sizey*2+1, (cx-1)*2, (cy-1)*2+1, b) != ' ') ?
0:valdirnb(cx,cy,-1, 0, b))
+((blockget( sizex*2+1, sizey*2+1, (cx-1)*2, (cy-1)*2+2, b) != ' ') ?
0:valdirnb(cx,cy,-1,+1, b))
+((blockget( sizex*2+1, sizey*2+1, (cx-1)*2+1, (cy-1)*2, b) != ' ') ?
0:valdirnb(cx,cy, 0,-1, b))
+((blockget( sizex*2+1, sizey*2+1, (cx-1)*2+1, (cy-1)*2+2, b) != ' ') ?
0:valdirnb(cx,cy, 0,+1, b))
+((blockget( sizex*2+1, sizey*2+1, (cx-1)*2+2, (cy-1)*2, b) != ' ') ?
0:valdirnb(cx,cy,+1,-1, b))
+((blockget( sizex*2+1, sizey*2+1, (cx-1)*2+2, (cy-1)*2+1, b) != ' ') ?
0:valdirnb(cx,cy,+1, 0, b))
+((blockget( sizex*2+1, sizey*2+1, (cx-1)*2+2, (cy-1)*2+2, b) != ' ') ?
0:valdirnb(cx,cy,+1,+1, b))
;
if(min > valxy[ cx ][ cy ])
min = valxy[ cx ][ cy ];
}
if(0 && min < 1){
for( cx = 1; cx <= 8; cx++)
for( cy = 1; cy <= 8; cy++){
valxy[ cx ][ cy ] += (-min+1);
}
}
}
}
void set( char c, int sizex, int sizey, int x, int y, char *s)
{
*(s + (y-1)*sizex + (x-1)) = c;
}
char get( int sizex, int sizey, int x, int y, char *s)
{
return *(s + (y-1)*sizex + (x-1));
}
int pos_check(
int is_turn,
char turn,
int sizex,
int sizey,
int x,
int y,
char *s
)
{
int cx, cy;
int exist_count = 0;
char tonari = (turn == 'W') ? 'R':'W';
int tonari_count;
int tonari_count_val;
//左
for( tonari_count = 0, cx = x-1, cy = y; ; cx--){
if(cx == 0 ||
blockget( sizex*2+1, sizey*2+1, cx*2, (cy-1)*2+1, board) != ' '){
tonari_count = 0;
tonari_count_val = 0;
break;
}else{
char nc = get( sizex, sizey, cx, cy, s);
if(nc == tonari){
tonari_count++;
tonari_count_val+=valxy[ cx ][ cy ];
}else if(nc == turn && tonari_count > 0){
//exist_count += tonari_count_val;
exist_count += tonari_count;
break;
}else{
tonari_count = 0;
tonari_count_val = 0;
break;
}
}
}
if(is_turn && tonari_count){
for( cx = x-1, cy = y; tonari_count-- > 0; cx--){
set( turn, sizex, sizey, cx, cy, s);
}
}
//右
for( tonari_count = 0, cx = x+1, cy = y; ; cx++){
if(cx > sizex ||
blockget( sizex*2+1, sizey*2+1, (cx-1)*2, (cy-1)*2+1, board) != ' '){
tonari_count = 0;
tonari_count_val = 0;
break;
}else{
char nc = get( sizex, sizey, cx, cy, s);
if(nc == tonari){
tonari_count++;
tonari_count_val+=valxy[ cx ][ cy ];
}else if(nc == turn && tonari_count > 0){
//exist_count += tonari_count_val;
exist_count += tonari_count;
break;
}else{
tonari_count = 0;
tonari_count_val = 0;
break;
}
}
}
if(is_turn && tonari_count){
for( cx = x+1, cy = y; tonari_count-- > 0; cx++){
set( turn, sizex, sizey, cx, cy, s);
}
}
//上
for( tonari_count = 0, cx = x, cy = y-1; ; cy--){
if(cy == 0 ||
blockget( sizex*2+1, sizey*2+1, (cx-1)*2+1, cy*2, board) != ' '){
tonari_count = 0;
tonari_count_val = 0;
break;
}else{
char nc = get( sizex, sizey, cx, cy, s);
if(nc == tonari){
tonari_count++;
tonari_count_val+=valxy[ cx ][ cy ];
}else if(nc == turn && tonari_count > 0){
//exist_count += tonari_count_val;
exist_count += tonari_count;
break;
}else{
tonari_count = 0;
tonari_count_val = 0;
break;
}
}
}
if(is_turn && tonari_count){
for( cx = x, cy = y-1; tonari_count--; cy--){
set( turn, sizex, sizey, cx, cy, s);
}
}
//下
for( tonari_count = 0, cx = x, cy = y+1; ; cy++){
if(cy > sizey ||
blockget( sizex*2+1, sizey*2+1, (cx-1)*2+1, (cy-1)*2, board) != ' '){
tonari_count = 0;
tonari_count_val = 0;
break;
}else{
char nc = get( sizex, sizey, cx, cy, s);
if(nc == tonari){
tonari_count++;
tonari_count_val+=valxy[ cx ][ cy ];
}else if(nc == turn && tonari_count > 0){
//exist_count += tonari_count_val;
exist_count += tonari_count;
break;
}else{
tonari_count = 0;
tonari_count_val = 0;
break;
}
}
}
if(is_turn && tonari_count){
for( cx = x, cy = y+1; tonari_count--; cy++){
set( turn, sizex, sizey, cx, cy, s);
}
}
//左上
for( tonari_count = 0, cx = x-1, cy = y-1; ; cx--, cy--){
if(cx == 0 || cy == 0 ||
blockget( sizex*2+1, sizey*2+1, cx*2, cy*2, board) != ' '){
tonari_count = 0;
tonari_count_val = 0;
break;
}else{
char nc = get( sizex, sizey, cx, cy, s);
if(nc == tonari){
tonari_count++;
tonari_count_val+=valxy[ cx ][ cy ];
}else if(nc == turn && tonari_count > 0){
//exist_count += tonari_count_val;
exist_count += tonari_count;
break;
}else{
tonari_count = 0;
tonari_count_val = 0;
break;
}
}
}
if(is_turn && tonari_count){
for( cx = x-1, cy = y-1; tonari_count--; cx--, cy--){
set( turn, sizex, sizey, cx, cy, s);
}
}
//左下
for( tonari_count = 0, cx = x-1, cy = y+1; ; cx--, cy++){
if(cx == 0 || cy > sizey||
blockget( sizex*2+1, sizey*2+1, cx*2, (cy-1)*2, board) != ' '){
tonari_count = 0;
tonari_count_val = 0;
break;
}else{
char nc = get( sizex, sizey, cx, cy, s);
if(nc == tonari){
tonari_count++;
tonari_count_val+=valxy[ cx ][ cy ];
}else if(nc == turn && tonari_count > 0){
//exist_count += tonari_count_val;
exist_count += tonari_count;
break;
}else{
tonari_count = 0;
tonari_count_val = 0;
break;
}
}
}
if(is_turn && tonari_count){
for( cx = x-1, cy = y+1; tonari_count--; cx--, cy++){
set( turn, sizex, sizey, cx, cy, s);
}
}
//右上
for( tonari_count = 0, cx = x+1, cy = y-1; ; cx++, cy--){
if(cx > sizex || cy == 0 ||
blockget( sizex*2+1, sizey*2+1, (cx-1)*2, cy*2, board) != ' '){
tonari_count = 0;
tonari_count_val = 0;
break;
}else{
char nc = get( sizex, sizey, cx, cy, s);
if(nc == tonari){
tonari_count++;
tonari_count_val+=valxy[ cx ][ cy ];
}else if(nc == turn && tonari_count > 0){
//exist_count += tonari_count_val;
exist_count += tonari_count;
break;
}else{
tonari_count = 0;
tonari_count_val = 0;
break;
}
}
}
if(is_turn && tonari_count){
for( cx = x+1, cy = y-1; tonari_count--; cx++, cy--){
set( turn, sizex, sizey, cx, cy, s);
}
}
//右下
for( tonari_count = 0, cx = x+1, cy = y+1; ; cx++, cy++){
if(cx > sizex || cy > sizey ||
blockget( sizex*2+1, sizey*2+1, (cx-1)*2, (cy-1)*2, board) != ' '){
tonari_count = 0;
tonari_count_val = 0;
break;
}else{
char nc = get( sizex, sizey, cx, cy, s);
if(nc == tonari){
tonari_count++;
tonari_count_val+=valxy[ cx ][ cy ];
}else if(nc == turn && tonari_count > 0){
//exist_count += tonari_count_val;
exist_count += tonari_count;
break;
}else{
tonari_count = 0;
tonari_count_val = 0;
break;
}
}
}
if(is_turn && tonari_count){
for( cx = x+1, cy = y+1; tonari_count--; cx++, cy++){
set( turn, sizex, sizey, cx, cy, s);
}
}
if(is_turn && exist_count)
set( turn, sizex, sizey, x, y, s);
return exist_count;
}
int disp_now( char nextturn, int xsize, int ysize, char *status, int isblue, int bx, int by, char *orgstatus)
{
}
int i[ 64+1 ],j[ 64+1 ];
int max[ 64+1 ];
char status[ 64+1 ][ 64+1 ];
char turn[ 64+1 ];
int check[ 64+1 ];
char now_status[ 1024 ];
void disp_head(int i, char *s)
{
}
int whitenum( char *status)
{
int ret = 0;
while( *status){
if(*status == 'R')
ret++;
status++;
}
return ret;
}
char *mycrypt( char *msg)
{
static char ret[ 64+1 ];
return ret;
}
void disp_tail(char nextturn, char *msg)
{
}
int all_pos_check( char nextturn, int *maxi, int *maxj, char *now_status)
{
int i,j;
int max = 0;
*maxi = 0;
*maxj = 0;
for( i = 1; i <= 8; i++){
for( j = 1; j <=8; j++){
if(get( 8, 8, i, j, now_status) == 'N'){
int now = pos_check( 0, nextturn, 8, 8, i, j, now_status);
if(now > max){
*maxi = i;
*maxj = j;
max = now;
}
}
}
}
return max;
}
void p( char *str)
{
printf( "%s\n", str);
}
//int all_1_all_nM1_max_min_max; //最終決定値
//int now_1_all_nM1_max_min; //一手目ごとに 65535に初期化される
//int now_1_now_nM1_max; //N-1手目ごとに -65535に初期化される
int minmax[ 64+1 ];
//minmax[ 0 ] max_sp = 3 にとっての all_1_all_nM1_max_min_max; //最終決定値に対応
//minmax[ 1 ] max_sp = 3 にとっての now_1_all_nM1_max_min; //一手目ごとに 65535に初期化される
//minmax[ 2 ] max_sp = 3 にとっての now_1_now_nM1_max; //N-1手目ごとに -65535に初期化される
//minmax[ 3 ] max_sp = 3 にとっての sum //
int max_sp;
int now_max_loop;
#ifdef DEBUG
void disp_stack( int x, int y, char *msg)
{
int n;
printf( "<TR>\n");
for( n = 1; n <= max_sp /*&& max[ n ]*/; n++){
printf( "<TD valign=up>\n");
printf( "chk[ %d ] : %d / (%d,%d) = %d-%d<BR>\n", n, check[ n ], i[ n ], j[ n ], x, y);
//printf( "status[ %d ] = <BR>\n", i);
{
int m;
for(m = 0; m < 64; m++){
switch( status[ n ][ m ]){
case 'N': printf("×");break;
case 'W': printf("白丸");break;
case 'R':printf("黒丸");break;
}
if(m % 8 == 7)
printf("<BR>\n");
}
}
printf("turn = %c<BR>\n", turn[ n ]);
/*
printf("all_1_all_nM1_max_min_max %d<BR>\n", all_1_all_nM1_max_min_max); //最終決定値
printf("now_1_all_nM1_max_min %d<BR>\n", now_1_all_nM1_max_min); //一手目ごとに 65535に初期化される
printf("now_1_now_nM1_max %d<BR>\n", now_1_now_nM1_max); //N-1手目ごとに -65535に初期化される
*/
{
int m;
for(m = 0; m <= max_sp; m++)
printf( "%d ", minmax[ m ]);
printf( "<BR>\n");
}
if(msg){
printf( "%d : %s<BR>\n", now_max_loop, msg);
}
printf( "</TD>\n");
}
printf( "</TR>\n");
}
#else
void disp_stack( int x, int y, char *msg)
{
;
}
#endif
/*---------------------------------------------------------------------------------
関数名 recursive_all_pos_check
機能 最も有望な手を返す
引数 nextturn 有望な手を探索する側('W'/'R')
*maxi 有望な手のX座標
*maxj 有望な手のY座標
now_status 探索の対象となるゲーム状態
max_loop 最大の探索ループ数
---------------------------------------------------------------------------------*/
int recursive_all_pos_check(
char nextturn,
int *maxi,
int *maxj,
char *now_status,
unsigned long max_loop
)
{
const int level = LEVEL;
int first_get = 0;
int m,n;
*maxi = *maxj = 0;
//all_1_all_nM1_max_min_max = -65535; //最終決定値
minmax[ 0 ] = MUGENM;
// スタックの初期化
max_sp = 0;
turn[ 0 ] = 'N';
strcpy( status[ 0 ], now_status);
i[ 0 ] = j[ 0 ] = 0;
max[ 0 ] = 0;
#ifdef DEBUG
printf( "<TABLE border bgcolor=white>\n");
#endif
// 次の一手
++max_sp;
turn[ max_sp ] = nextturn;
i[ max_sp ] = j[ max_sp ] = 1;
max[ max_sp ] = 0;
do{
if(--max_loop == 0){
disp_stack( *maxi, *maxj, "LOOPOVER");
break;
}
now_max_loop = max_loop;
if( max_sp % 2 == 1 && max_sp < level){
// 1 or 3 のとき
minmax[ max_sp ] = MUGENP;
}
if( max_sp % 2 == 0 && max_sp < level){
// 2 or 4 のとき(0はありえないから)
minmax[ max_sp ] = MUGENM;
}
strcpy( status[ max_sp ], status[ max_sp-1 ]);
if( get( 8, 8, i[ max_sp ], j[ max_sp ], status[ max_sp ]) == 'N'
&& (check[ max_sp ]
= pos_check( 1, turn[ max_sp ], 8, 8, i[ max_sp ], j[ max_sp ], status[ max_sp ])) > 0){
// 注目した座標(i[max_sp],j[max_sp])に石がなくかつとれるので置ける場合
// 現在のmax_sp-1のゲーム状態に対して先の手max_spが存在することをマークする
max[ max_sp ] = check[ max_sp ];
if(max_sp < level){
// まだ先を読む必要がある場合,
//disp_stack( *maxi, *maxj, "THINKING");
// 置いてみた後のstatus[ max_sp ]をスタックにつむ
++max_sp;
turn[ max_sp ] = (turn[ max_sp-1 ] == 'W') ? 'R':'W';
i[ max_sp ] = j[ max_sp ] = 1;
max[ max_sp ] = 0;
}else{
// 最深読みレベルに達していた場合
// 最深読みレベルの評価を計算する
int sum = 0;
int k;
if(IS_STACK_EST)
{
for( k = 1; k <= max_sp; k++)
sum +=
(turn[ k ] == nextturn) ?
+(check[ k ]+valxy[i[ k ]][j[ k ]]) : -(check[ k ]+valxy[i[ k ]][j[ k ]]);
//+(check[ k ]) : -(check[ k ]);
}else{
int x,y;
int sumw = 0;
int sumb = 0;
for( x = 1; x <= 8; x++){
for( y = 1; y <= 8; y++){
switch(get( 8, 8, x, y, status[ max_sp ])){
case 'N': break;
case 'W': sumw += valxy[ x ][ y ]; break;
case 'R': sumb += valxy[ x ][ y ]; break;
}
}
}
sum = (nextturn == 'W') ? (sumw-sumb):(sumb-sumw);
}
if(/* 最深レベルは奇数故 max_sp % 2 = 1 のチェックはいらない */
sum > minmax[ max_sp-1 ]){
minmax[ max_sp-1 ] = sum;
//disp_stack( *maxi, *maxj, "sum > minmax[ max_sp-1 ]");
}
//disp_stack( *maxi, *maxj);
// 次の候補にポインタを移す
while( j[ max_sp ] == 8 && i[ max_sp ] == 8 && max_sp > 0){
max_sp --;
if(max_sp % 2 == 0 && max_sp < level){
if(minmax[ max_sp ] < minmax[ max_sp-1 ]){
minmax[ max_sp-1 ] = minmax[ max_sp ];
disp_stack( *maxi, *maxj, "minmax[ max_sp ] < minmax[ max_sp-1 ]");
}
}
if(max_sp % 2 == 1 && max_sp < level){
if(minmax[ max_sp-1 ] < minmax[ max_sp ]){
minmax[ max_sp-1 ] = minmax[ max_sp ];
disp_stack( *maxi, *maxj, "minmax[ max_sp-1 ] < minmax[ max_sp ]");
if( max_sp == 1){
*maxi = i[ 1 ];
*maxj = j[ 1 ];
first_get = check[ 1 ];
}
}
}
if(max_sp == 1)
disp_stack( *maxi, *maxj, "CANDIDATE");
}
if(max_sp > 0){
if(j[ max_sp ] < 8){
j[ max_sp ]++;
}else if(i[ max_sp ] < 8){
i[ max_sp ]++;
j[ max_sp ] = 1;
}
}
}
}else{
// 注目した座標(i[max_sp],j[max_sp])に既に石があるか,なくても置けないときの処理
if(j[ max_sp ] < 8){
j[ max_sp ]++;
}else if(i[ max_sp ] < 8){
i[ max_sp ]++;
j[ max_sp ] = 1;
}else{
//その手をすべて探索したとき
disp_stack( *maxi, *maxj, "all searched");
if(max[ max_sp ] == 0){
//すべて探索した結果としておけなかったとき
char revturn = (turn[ max_sp ] == 'W') ? 'R':'W';
int m,n,rev_check = 0;
int nokori = 0, rev_nokori = 0;
disp_stack( *maxi, *maxj, "max[ max_sp ] == 0");
// 番を相手にわたせるかどうか計算
for(m = 1; m <= 8; m++)
for(n = 1; n <= 8; n++){
char c = get( 8, 8, m, n, status[ max_sp ]);
if(c == 'N')
rev_check += pos_check( 0, revturn, 8, 8, m, n, status[ max_sp ]);
else if(c == revturn)
rev_nokori ++;
else
nokori ++;
}
if(rev_check > 0 && max_sp < level){
// 相手の置く場所があり番をわたせるとき
// 自分のturnはスキップする
i[ max_sp ] = 8;
j[ max_sp ] = 8;
// turnを交替して探索しなおし
++max_sp;
turn[ max_sp ] = revturn;
i[ max_sp ] = 1;
j[ max_sp ] = 0;
max[ max_sp ] = 0;
disp_stack( *maxi, *maxj, "PASS");
}else{
// ゲームルール上,自分も相手もおける石がなかった場合
if( max_sp == 1){
// 1手目で自分も相手もなにもできないとき
disp_stack( *maxi, *maxj, "1 te PASSPASS GAMEOVER");
;//ゲームオーバー
}else{
disp_stack( *maxi, *maxj, "max_sp > 1");
// 2手先読みでこの状態に遭遇したとき
if(max_sp == 2 && rev_nokori > nokori){
// 2手先で両者とも何もできなくなりコールド勝ちになる場合
*maxi = i[ 1 ];
*maxj = j[ 1 ];
//all_1_all_nM1_max_min_max = MUGENP;//この手に決めてしまう
minmax[ 0 ] = MUGENP;
first_get = check[ 1 ];
disp_stack( *maxi, *maxj, "COLD WIN");
}else{
// 2手先以上で両者とも何もできなくなり,負けか引き分けのとき
// 最深読みレベルの評価を計算する
int sum = 0;
int k;
if(IS_STACK_EST){
for( k = 1; k <= max_sp; k++)
sum +=
(turn[ k ] == nextturn) ?
+(check[ k ]+valxy[i[ k ]][j[ k ]]) : -(check[ k ]+valxy[i[ k ]][j[ k ]]);
//+(check[ k ]) : -(check[ k ]);
}else{
int x,y;
int sumw = 0;
int numw = 0;
int sumb = 0;
int numb = 0;
for( x = 1; x <= 8; x++){
for( y = 1; y <= 8; y++){
switch(get( 8, 8, x, y, status[ max_sp ])){
case 'N': break;
case 'W': numw++;sumw += valxy[ x ][ y ]; break;
case 'R': numb++;sumb += valxy[ x ][ y ]; break;
}
}
}
if(numw == 0){
sumw = MUGENM;
}
if(numb == 0){
sumb = MUGENM;
}
sum = (nextturn == 'W') ? (sumw-sumb):(sumb-sumw);
}
disp_stack( *maxi, *maxj, "LOSEorDRAW-BACKTRACK");
if(sum > minmax[ max_sp-1 ]){
// max_sp == 3 or 5 , max_sp-1 == 2 or 4を想定している
minmax[ max_sp-1 ] = sum;
disp_stack( *maxi, *maxj, "LOSEorDRAW-BACKTRACK sum > minmax[ max_sp-1 ]");
}
//負けか引き分けになりそうなときの処理終了
}
disp_stack( *maxi, *maxj, "NO GAME at 2 or more");
//2手先読み以上で遭遇した場合終了
}
disp_stack( *maxi, *maxj, "NO GAME at a context");
// ゲームルール上,自分も相手もおける石がなかった場合終了
}
disp_stack( *maxi, *maxj, "NO GAME");
// すべて探索した結果としておけなかったとき終了
}
//disp_stack( *maxi, *maxj, "NO TE");
// 次の候補にポインタを移す
while( j[ max_sp ] == 8 && i[ max_sp ] == 8 && max_sp > 0){
max_sp --;
if(max_sp % 2 == 0 && max_sp < level){
if(minmax[ max_sp ] < minmax[ max_sp-1 ]){
minmax[ max_sp-1 ] = minmax[ max_sp ];
disp_stack( *maxi, *maxj, "minmax[ max_sp ] < minmax[ max_sp-1 ]");
}
}
if(max_sp % 2 == 1 && max_sp < level){
if(minmax[ max_sp-1 ] < minmax[ max_sp ]){
minmax[ max_sp-1 ] = minmax[ max_sp ];
disp_stack( *maxi, *maxj, "minmax[ max_sp-1 ] < minmax[ max_sp ]");
if( max_sp == 1){
*maxi = i[ 1 ];
*maxj = j[ 1 ];
first_get = check[ 1 ];
}
}
}
}
//disp_stack( *maxi, *maxj, "BACKTRACK AFTER NO-TE");
if(max_sp > 0){
if(j[ max_sp ] < 8){
j[ max_sp ]++;
}else if(i[ max_sp ] < 8){
i[ max_sp ]++;
j[ max_sp ] = 1;
}
}
}
}
}while( max_sp > 0);
#ifdef DEBUG
printf( "</TABLE>\n");
#endif
return first_get;
}
int disp_point( int is_start, int x, int y, char *now_status, char nextturn, double t)
{
}
void countup( void)
{
/*
REMOTE_ADDR:スクリプトを提出してきたホストIPアドレス
QUERY_STRING:GETによう問い合わせにおける引数の方法URLで「?」の後ろにあるものすべて
REQUEST_METHOD:フォームの提出方法(POST or GET)
REFERER_URL:CGIを送るのに使われたページのURLクライアント変数の中身、
ユーザがサイトを訪れる直前にブラウザがいたロケーションURLを返す
CONTENT_TYPE:POSTによってフォームが提出されてくる場合
application/x-www-form-unlecodedという値になる
CONTENT_LENGTH:POST、GETによってフォームが提出される場合、標準出力から読み込む必要のあるバイト数
char buf[ 256 ];
char *user = getenv("REMOTE_ADDR");
int fd = open("/home/httpd/cgi-bin/ws/wscount.dat", "at");
int count = 10;
while( flock( fd, LOCK_EX)){
if(--count = 0)
exit(1);
sleep( 100);
}
fprintf( fp, "%s\n", usr);
flock( fd, LOCK_UN);
close( fd);
//system( buf);
*/
FILE *fp;
int fd;
int count = 0;
char buf[256];
bzero(buf, 256);
// ファイルを開く
fd = open("/home/httpd/cgi-bin/ws/counter.dat", O_RDWR | O_CREAT );
// 排他ロック
flock(fd, LOCK_EX );
// 読み込み
lseek(fd, 0, SEEK_SET);
read(fd, buf, 256);
// カウンタを足す
count = atoi(buf);
count++;
sprintf(buf, "%d", count);
// 書き込み
lseek(fd, 0, SEEK_SET);
write(fd, buf, 256);
fp = fopen("/home/httpd/cgi-bin/ws/log.dat", "at");
fprintf( fp, "%s:%s\n", buf, getenv("REMOTE_ADDR"));
fclose( fp);
// ロック開放
flock(fd, LOCK_UN );
close(fd);
}
const char codetbl[] = "0123456789ABCDEF";
int urldecode(char *in, char *out)
{
int cnt = 0;
int len;
char *str = in;
if (!in || (len = strlen(in)) == 0)
return -1;
memset( out, 0, len );
while( *str ) {
if (*str != '%') {
*(out + cnt++) = *str;
} else {
if ( *(str + 1) == 0 || *(str + 2) == 0) {
break;
}
*(out + cnt++) = 16 * (strchr(codetbl, *(str + 1)) - codetbl) \
+ (strchr(codetbl, *(str + 2)) - codetbl);
str = str + 2;
}
str++;
}
return(strlen(out));
}
int main( int argc, char *argv[])
{
int smode = 1;
int isloop = 1;
char org_status[ 1024 ];
clock_t start,end;
{
char *cp = strrchr( argv[ 0 ], '/');
strcpy(CGINAME, cp+1);
}
start = clock();
char autonext[ 1024 ] = {""};
char lastturn = 'N';
char nextturn = 'N';
int is_p2p = IS_P2P;
int x,y;
char cfgfilepath[ 1024 ];
char given_status[ 1024 ];
char *cp = getenv("QUERY_STRING"); cp = (cp) ? strcpy( given_status, cp) : NULL;
char *user = getenv("REMOTE_ADDR");
{
//char buf[ 256 ];
////sprintf( buf, "/home/httpd/cgi-bin/ws/wscount.pl %s", user);
//sprintf( buf, "/home/httpd/cgi-bin/ws/wscount.pl aaaaaaaaa");
//system( buf);
}
value_init( board);
//自分の色および場所を変数にいれる
if(cp == NULL || *cp == '\0' || *(cp+2)=='h'){
char buf[ 1024 ];
if(*(cp+2) =='h'){
char *sp;
char *ep;
int point = 0;
char sname[ 64 ];
char scrypt[ 64+1 ];
char ncrypt[ 64+1 ];
char sstat[ 64+1 ];
fgets( buf, 1024, stdin);
sp = buf+5;
ep = strchr( sp, '&');
*ep = '\0';
strcpy( sstat, sp);
strcpy( ncrypt, (const char *)mycrypt( sstat));
sp = ep+7;
ep = strchr( sp, '&');
*ep = '\0';
strcpy( scrypt, sp);
sp = ep+10;
urldecode( sp, sname);
//strcpy( sname, sp);
if(strlen(sname) > 0 && strcmp( ncrypt, scrypt) == 0){
int num = whitenum( sstat);
char buf[ 256 ];
char filename[ 256 ];
char filenamebak[ 256 ];
sprintf( filename, "%s.rank", CGINAME);
sprintf( filenamebak, "%s.rank.bak", CGINAME);
unlink( filenamebak);
rename( filename, filenamebak);
FILE *fin = fopen( filenamebak, "rb");
FILE *fout = fopen( filename, "wb");
if(fin){
while( fgets( buf, 256, fin ) ){
char *cp = strchr( buf, ',');
if(cp){
*cp = '\0';
if(atoi( buf) < num){
fprintf( fout, "%d,%s\n", num, sname);
num = 0;
}
fprintf( fout, "%s,%s", buf, cp+1);
}
}
fclose( fin);
//rename( filenamebak, filename);
fclose( fout);
}
}
//strcpy( buf, "test");
}else{
buf[0] = '\0';
}
// 引数が得られなかった場合
nextturn = 'R';
x = 0;
y = 0;
disp_head(0, NULL);
strcpy( now_status, init );
disp_point( 1, 0, 0, now_status, nextturn, 0.0f);
strcpy( org_status, now_status);
disp_now(
nextturn,
8, 8, now_status, 1, 0, 0, org_status
);
disp_tail(nextturn, user);
exit( 0);
}
// 引数を取得する
{
static char buf[ 1024 ];
char *ep;
/*
while(*cp != '=') cp++;
strcpy( cfgfilepath, ++cp);
set_cfg( cfgfilepath);
*/
while(*cp != '=') cp++;
nextturn = *(++cp);
while(*cp != '=') cp++;
ep = strchr( cp, (int)'&');
*ep = '\0';
x = atoi( ++cp);
while(*cp != '=') cp++;
ep = strchr( cp, (int)'&');
*ep = '\0';
y = atoi( ++cp);
while(*cp != '=') cp++;
strcpy( now_status, ++cp);
ep = strchr( now_status, (int)'&');
if( ep){
*ep = '\0';
while(*ep != '=') ep++;
_ADURL = strcpy(buf, ++ep);
}else{
_ADURL = NULL;
}
}
strcpy( org_status, now_status);
while( isloop){
int maxi, maxj;
switch( nextturn){
case 'r': // 'r'(置くのみ(波及せず))
if(smode == 1){
nextturn = toupper(nextturn);
}else{
char nextnextturn = toupper( nextturn); //Rを要求
sprintf( autonext,
"?t=%c&x=%d&y=%d&s=%s",
nextnextturn,
x,
y,
now_status
);
countup();
disp_head(0, autonext);//1秒後にジャンプ
//pos_check( 1, nextnextturn, 8, 8, x, y, now_status);
now_status[ (y-1)*8+(x-1) ] = 'R';
disp_point( 0, x, y, now_status, nextturn, 0.0f);
disp_now(
nextturn,
8, 8, now_status, 0, x, y, org_status
);
nextturn = nextnextturn;
disp_tail(nextturn, NULL);
exit( 0);
}
break;
case 'w': // 'w'(推論して置くのみ(波及せず)) 前フェーズで置けることをチェックして、このフェーズに入るようにする
if(smode == 1){
recursive_all_pos_check('W', &maxi, &maxj, now_status, MAX_LOOP);
x = maxi;
y = maxj;
nextturn = 'W';
}else{
char nextnextturn = toupper( nextturn);
recursive_all_pos_check('W', &maxi, &maxj, now_status, MAX_LOOP);
end = clock();
sprintf( autonext,
"?t=%c&x=%d&y=%d&s=%s",
'W',
maxi,
maxj,
now_status
);
disp_head(1, autonext);//1秒後にジャンプ
//pos_check( 1, nextnextturn, 8, 8, x, y, now_status);
now_status[ (maxj-1)*8+(maxi-1) ] = 'W';
disp_point( 0, maxi, maxj, now_status, nextturn, ((double)(end-start)/CLOCKS_PER_SEC));
disp_now(
nextturn,
8, 8, now_status, 0, maxi, maxj, org_status
);
nextturn = nextnextturn;
disp_tail(nextturn, NULL);
exit( 0);
isloop = 0;
}
break;
case 'R':
{
int isblue = 0;
pos_check( 1, 'R', 8, 8, x, y, now_status);
if(all_pos_check('W', &maxi, &maxj, now_status) > 0){
//白完(w要求)
sprintf( autonext,
"?t=%c&x=%d&y=%d&s=%s",
'w',
0,
0,
now_status
);
disp_head(1, autonext);
}else{
if(all_pos_check('R', &maxi, &maxj, now_status) > 0){
//青完
disp_head(0, "");
isblue = 1;
}else{
//相手も自分もおけなかったとき
nextturn = 'N';
disp_head(0, "");
}
}
disp_point( 0, x, y, now_status, nextturn, 0.0f);
disp_now(
nextturn,
8, 8, now_status, isblue, x, y, org_status
);
disp_tail(nextturn, NULL);
}
isloop = 0;
break;
case 'W':
{
int isblue = 1;
//now_status[ (y-1)*8+(x-1) ] = 'N';
pos_check( 1, 'W', 8, 8, x, y, now_status);
if(all_pos_check('R', &maxi, &maxj, now_status) > 0){
//青完
disp_head(0, "");
nextturn = 'R';
}else{
if(all_pos_check('W', &maxi, &maxj, now_status) > 0){
//黒完(w要求)
sprintf( autonext,
"?t=%c&x=%d&y=%d&s=%s",
'w',
0,
0,
now_status
);
isblue = 0;
disp_head(1, autonext);
}else{
//相手も自分もおけなかったとき
nextturn = 'N';
disp_head(0, "");
}
}
end = clock();
disp_point( 0, x, y, now_status, nextturn, ((double)(end-start)/CLOCKS_PER_SEC));
disp_now(
nextturn,
8, 8, now_status, isblue, x, y, org_status
);
disp_tail(nextturn, NULL);
}
isloop = 0;
break;
case 'N':
{
disp_head(0, "");
disp_point( 0, x, y, now_status, nextturn, 0.0f);
disp_now(
nextturn,
8, 8, now_status, 0, x, y, org_status
);
disp_tail(nextturn, NULL);
}
isloop = 0;
break;
}
}
}
<参考資料B1>
#
# index.cgi for Wallstreets top url
# Copyright(c) KeisukeNAKAMURA
# All rights reserved.
#
0001 #!/usr/bin/perl -w
0002
0003 print <<EOT;
0004 Content-type: text/html;charset=euc-jp;
0005
0006 <HTML>
0007 <HEAD>
0008 <TITLE>WALLSTREETS</TITLE>
0009
0010 </HEAD>
省略
0052 <TABLE BGCOLOR=#550000 style="width:410px;">
0053 <TR><TD><FONT color=silver>ここから選んでください↓(Please select board)</FONT></TD></TR>
0054 <TR><TD>
0055 EOT
0056
0057 my %ib_disp_head;
0058 my %ib_disp_tail;
0059
0060 open(FIN,"<ib_disp.txt");
0061 while($disp = <FIN>){
0062 chomp( $disp);
0063 ($key,$head,$tail) = split(/;/,$disp);
0064 $ib_disp_head{$key} = $head;
0065 $ib_disp_tail{$key} = $tail;
0066 }
0067 close(FIN);
0068
0069
0070 use DirHandle;
0071
0072 $count = 0;
0073 my %amount;
0074 my %entry;
0075 my %topplayer;
0076
0077 $dir = new DirHandle '.';
0078 while($data = $dir->read){
0079 if($data =~ /\.rank$/ and $data =~ /^ws5-JP/){
0080 open( FIN, "<$data") || last;
0081 undef %entry;
0082 for($i = 0; $i < 8; $i++){
0083 $e = <FIN>;
0084 #print "\t$e";
0085 chomp $e;
0086 ($a,$b) = split( /,/, $e);
0087 if($i == 0){
0088 $ter{$b} .= "$data;";
0089 $topplayer{$data}="$b<BR>$a";
0090 $a = $a * 10000;
0091 }
0092 if($i == 1){
0093 $a = $a * 1000;
0094 }
0095 if($i == 2){
0096 $a = $a * 100;
0097 }
0098 if($i == 3){
0099 $a = $a * 10;
0100 }
0101 if($a > 0 and $b ne "-" and !defined($entry{$b})){
0102 $entry{$b} = 1;
0103 $amount{"$b"} += $a;
0104 }
0105 }
0106 close(FIN);
0107 }
0108 }
0109 $dir->close;
0110
0111 $dir = new DirHandle '.';
0112 while($data = $dir->read){
0113 if($data =~ /\.cgi$/ and $data =~ /^ws5-JP/){
0114 ++$count;
0115 $wsp = $data;
0116 $wsp =~ s/ws5/wsp/;
0117 $pref = $data;
0118 $pref =~ s/ws5-JP-//;
0119 $pref =~ s/\.cgi$//;
0120 if(defined($ib_disp_head{$pref})){
0121 push @urllist,"$ib_disp_head{$pref}<A HREF=\"$data\"><FONT color=gold size=2>$pref</FONT>$ib_disp_tail{$pref}</A></TD><TD> <FONT color=silver size=1>$topplayer{$data.'.rank'}</FONT></TD><TD><A HREF=\"$wsp\"><FONT color=cyan size=2>隣人<BR>対戦</FONT></A>";
0122 }else{
0123 push @urllist,"<A HREF=\"$data\"><FONT color=gold>$pref </FONT></A>\n";
0124 }
0125 }
0126 }
0127 $dir->close;
0128 print "<TABLE bgcolor=#550000>";
0129 @s_urllist = sort @urllist;
0130 my $ci = 0;
0131 while( $ni = shift @s_urllist){
0132 $ci ++;
0133 if($ci % 2 == 0){
0134 print "<TR bgcolor=#553333><TD align=right>$ni</TD></TR>";
0135 }else{
0136 print "<TR bgcolor=#550000><TD align=right>$ni</TD></TR>";
0137 }
0138 }
0139
0140 print "</TABLE>";
0141 print "</TD></TR></TABLE><BR>";
0142
0143
0144 print "<TABLE style=\"width:410px;\" >\n";
0145 print "<TR><TD colspan=2 align=center><FONT color=silver size=3>スコア合計ランキング(HIGHSCORE AMOUNT RANKING)</FONT></TD></TR>\n";
0146
0147 while(($k,$v) = each %amount){
0148 $vf = sprintf("%8d 石", $v);
0149 if(defined($ter{$k})){
0150
0151
0152 $p = "<TR><TD align=right bgcolor=gold width=130><FONT size=5>$vf</FONT></TD><TD bgcolor=silver><font size=5>$k<BR></font>";
0153 @tops = sort split(/;/, $ter{$k});
0154 while( $aurl = shift @tops){
0155 $aurl =~ s/\.rank//;
0156 $burl = $aurl;
0157 $burl =~ s/\.cgi//;
0158 $burl =~ s/ws5-JP-//;
0159 $p .= "<a href=\"$aurl\"><FONT size=2>$burl</FONT></a>\n";
0160 }
0161 $p .= "<TD></TR>\n";
0162 push @rank, $p;
0163 }else{
0164 push @rank, "<TR><TD align=right bgcolor=gold width=130>$vf</TD><TD bgcolor=cyan><font size=3>$k</font><TD></TR>\n";
0165 }
0166 }
0167
0168 print sort {$b cmp $a} @rank;
0169
0170 print "</TABLE>\n";
0171
0172 print <<EOT;
0173
0174 <TABLE>
0175 <TR>
0176 <TD colspan=3 align=left>
0177 <FONT color=silver>Please contact to</FONT>
0178 </TD>
0179 </TR>
省略
0189 </TABLE>
0190
0191 <HR><FONT color=gold> Copyright(C) </font><A HREF="http://knowrel.com/"><FONT color=gold>KnowrelSystem,Inc.</FONT></A><FONT color=silver> Produced&Programmed by <A HREF="mailto:keisuke\@knowrel.com">KeisukeNAKAMURA</A></FONT>
0192 </CENTER>
0193 </BODY>
0194 </HTML>
0195 EOT
<参考資料B2>
#
# JP-wakayama1.c
#
# Copyright(c) KeisukeNAKAMURA
# All Rights Reserved.
#
char init[]=
"NNNNNNNN"
"NNNNNNNN"
"NNNNNNNN"
"NNNBWNNN"
"NNNWBNNN"
"NNNNNNNB"
"NNNNNNNN"
"NNNNNNNN";
char board[21*21]=
"CG---+-GGGGGGG--+"
"C + + + |"
"C + G |"
"C + |"
"CC + |"
"C + |"
"C + |"
"C + |"
"C C |"
"C + |"
"CCC C +++++|"
"CCC + |"
"CCCCC +|"
"CCCCC G"
"CCCCCCC C CCC"
"CCCCCCC CCC"
"CCCCCCCCCCCCCCCCC";
<参考資料B3>
#
# wseuc_num8an.c
#
# Copyright(c) KeisukeNAKAMURA
# All rights reserved.
#
0001 #include <stdio.h>
0002 #include <stdlib.h>
0003 #include <string.h>
0004 #include <ctype.h>
0005 #include <time.h>
0006 #include <sys/types.h>
0007 #include <sys/file.h>
0008 #include <sys/stat.h>
0009 #include <fcntl.h>
0010 //#include <malloc.h>
0011
0012 #define ___B___ 'B'
0013 #define ___b___ 'b'
0014 #define ___W___ 'W'
0015 #define ___w___ 'w'
0016 #define ___N___ 'N'
0017 #define ___n___ 'n'
0018
0019
省略
0021
0022 #define MAX_LOOP (2000000000)
0023
0024 //#define LEVEL 3
0025 #define LEVEL 5
0026 //#define LEVEL 7
0027
0028 #define IS_P2P (0)
0029 //#define IS_P2P (1)
0030
0031 //#define DEBUG
0032
0033 char CGINAME[ 1024 ];
0034
0035 #define IS_STACK_EST (0)
0036 #define COLOR_GREEN "#33ff33"
0037 #define MUGENM (-65535)
0038 #define MUGENP (+65535)
0039
0040 #define GAME_SIZE_X (8)
0041 #define GAME_SIZE_Y (8)
0042 #define BOARD_SIZE_X (GAME_SIZE_X+GAME_SIZE_X+1)
0043 #define BOARD_SIZE_Y (GAME_SIZE_Y+GAME_SIZE_Y+1)
0044
0045
0046 extern char init[];
0047
0048 extern char board[];
0049 int valpr[ 9 ][ 9 ] = { 0 };
0050 int valxy[ 9 ][ 9 ] = { 0 };
0051 int dirnm[ 9 ][ 9 ] = { 0 };
0052 char blockget( int sizex, int sizey, int x, int y, char *b)
0053 {
0054 return *(b + y*sizex + x);
0055 }
0056
0057 int valdir( int basex, int basey, int dirx, int diry, char *b)
0058 {
0059 int point = 0;
0060 int sizex = 8;
0061 int sizey = 8;
0062 while( blockget( sizex*2+1, sizey*2+1, (basex-1)*2+1-dirx, (basey-1)*2+1-diry, b) == ' '){
0063 point++;
0064 basex -= dirx;
0065 basey -= diry;
0066 }
0067 return point;
0068 }
0069
0070 int valdirxy( int basex, int basey, int dirx, int diry, char *b)
0071 {
0072 int point = 0;
0073 int sizex = 8;
0074 int sizey = 8;
0075 while( blockget( sizex*2+1, sizey*2+1, (basex-1)*2+1-dirx, (basey-1)*2+1-diry, b) == ' '){
0076 point += valpr[ basex ][ basey ];
0077 basex -= dirx;
0078 basey -= diry;
0079 }
0080 return point;
0081 }
0082
0083 int valdirnb( int basex, int basey, int dirx, int diry, char *b)
0084 {
0085 return -valpr[ basex+dirx ][ basey+diry ]/dirnm[ basex+dirx ][ basey+diry ];
0086 }
0087
0088 void value_init( char *b)
0089 {
0090 int sizex = 8;
0091 int sizey = 8;
0092 int cx, cy;
0093
盤の空いた座標の数(事前にグローバル変数化する)から序盤であるか
判断し、
序盤でないとき(またはより極端に中盤を除いて終盤のとき)に
すべてのvalxy[][]に1をいれて戻るコードをここに入れることが可能
0094 for( cx = 1; cx <= 8; cx++)
0095 for( cy = 1; cy <= 8; cy++)
0096 dirnm[ cx ][ cy ] =
0097 ((blockget( sizex*2+1, sizey*2+1, (cx-1)*2, (cy-1)*2, b) == ' ') ?
0098 1:0)
0099 +((blockget( sizex*2+1, sizey*2+1, (cx-1)*2, (cy-1)*2+1, b) == ' ') ?
0100 1:0)
0101 +((blockget( sizex*2+1, sizey*2+1, (cx-1)*2, (cy-1)*2+2, b) == ' ') ?
0102 1:0)
0103 +((blockget( sizex*2+1, sizey*2+1, (cx-1)*2+1, (cy-1)*2, b) == ' ') ?
0104 1:0)
0105 +((blockget( sizex*2+1, sizey*2+1, (cx-1)*2+1, (cy-1)*2+2, b) == ' ') ?
0106 1:0)
0107 +((blockget( sizex*2+1, sizey*2+1, (cx-1)*2+2, (cy-1)*2, b) == ' ') ?
0108 1:0)
0109 +((blockget( sizex*2+1, sizey*2+1, (cx-1)*2+2, (cy-1)*2+1, b) == ' ') ?
0110 1:0)
0111 +((blockget( sizex*2+1, sizey*2+1, (cx-1)*2+2, (cy-1)*2+2, b) == ' ') ?
0112 1:0);
0113
0114 for( cx = 1; cx <= 8; cx++)
0115 for( cy = 1; cy <= 8; cy++){
0116 valpr[ cx ][ cy ] =
0117 ((blockget( sizex*2+1, sizey*2+1, (cx-1)*2, (cy-1)*2, b) == ' ') ?
0118 0:valdir(cx,cy,-1,-1, b))
0119 +((blockget( sizex*2+1, sizey*2+1, (cx-1)*2, (cy-1)*2+1, b) == ' ') ?
0120 0:valdir(cx,cy,-1, 0, b))
0121 +((blockget( sizex*2+1, sizey*2+1, (cx-1)*2, (cy-1)*2+2, b) == ' ') ?
0122 0:valdir(cx,cy,-1,+1, b))
0123 +((blockget( sizex*2+1, sizey*2+1, (cx-1)*2+1, (cy-1)*2, b) == ' ') ?
0124 0:valdir(cx,cy, 0,-1, b))
0125 +((blockget( sizex*2+1, sizey*2+1, (cx-1)*2+1, (cy-1)*2+2, b) == ' ') ?
0126 0:valdir(cx,cy, 0,+1, b))
0127 +((blockget( sizex*2+1, sizey*2+1, (cx-1)*2+2, (cy-1)*2, b) == ' ') ?
0128 0:valdir(cx,cy,+1,-1, b))
0129 +((blockget( sizex*2+1, sizey*2+1, (cx-1)*2+2, (cy-1)*2+1, b) == ' ') ?
0130 0:valdir(cx,cy,+1, 0, b))
0131 +((blockget( sizex*2+1, sizey*2+1, (cx-1)*2+2, (cy-1)*2+2, b) == ' ') ?
0132 0:valdir(cx,cy,+1,+1, b))
0133 ;
0134 }
0135
0136 for( cx = 1; cx <= 8; cx++)
0137 for( cy = 1; cy <= 8; cy++){
0138 valxy[ cx ][ cy ] = valpr[ cx ][ cy ]
0139 +((blockget( sizex*2+1, sizey*2+1, (cx-1)*2, (cy-1)*2, b) == ' ') ?
0140 0:valdirxy(cx,cy,-1,-1, b))
0141 +((blockget( sizex*2+1, sizey*2+1, (cx-1)*2, (cy-1)*2+1, b) == ' ') ?
0142 0:valdirxy(cx,cy,-1, 0, b))
0143 +((blockget( sizex*2+1, sizey*2+1, (cx-1)*2, (cy-1)*2+2, b) == ' ') ?
0144 0:valdirxy(cx,cy,-1,+1, b))
0145 +((blockget( sizex*2+1, sizey*2+1, (cx-1)*2+1, (cy-1)*2, b) == ' ') ?
0146 0:valdirxy(cx,cy, 0,-1, b))
0147 +((blockget( sizex*2+1, sizey*2+1, (cx-1)*2+1, (cy-1)*2+2, b) == ' ') ?
0148 0:valdirxy(cx,cy, 0,+1, b))
0149 +((blockget( sizex*2+1, sizey*2+1, (cx-1)*2+2, (cy-1)*2, b) == ' ') ?
0150 0:valdirxy(cx,cy,+1,-1, b))
0151 +((blockget( sizex*2+1, sizey*2+1, (cx-1)*2+2, (cy-1)*2+1, b) == ' ') ?
0152 0:valdirxy(cx,cy,+1, 0, b))
0153 +((blockget( sizex*2+1, sizey*2+1, (cx-1)*2+2, (cy-1)*2+2, b) == ' ') ?
0154 0:valdirxy(cx,cy,+1,+1, b))
0155 ;
0156 }
0157
0158 for( cx = 1; cx <= 8; cx++)
0159 for( cy = 1; cy <= 8; cy++)
0160 valpr[ cx ][ cy ] = valxy[ cx ][ cy ];
0161
0162 {
0163 int min = 65535;
0164 for( cx = 1; cx <= 8; cx++)
0165 for( cy = 1; cy <= 8; cy++){
0166 valxy[ cx ][ cy ] = valpr[ cx ][ cy ]
0167 +((blockget( sizex*2+1, sizey*2+1, (cx-1)*2, (cy-1)*2, b) != ' ') ?
0168 0:valdirnb(cx,cy,-1,-1, b))
0169 +((blockget( sizex*2+1, sizey*2+1, (cx-1)*2, (cy-1)*2+1, b) != ' ') ?
0170 0:valdirnb(cx,cy,-1, 0, b))
0171 +((blockget( sizex*2+1, sizey*2+1, (cx-1)*2, (cy-1)*2+2, b) != ' ') ?
0172 0:valdirnb(cx,cy,-1,+1, b))
0173 +((blockget( sizex*2+1, sizey*2+1, (cx-1)*2+1, (cy-1)*2, b) != ' ') ?
0174 0:valdirnb(cx,cy, 0,-1, b))
0175 +((blockget( sizex*2+1, sizey*2+1, (cx-1)*2+1, (cy-1)*2+2, b) != ' ') ?
0176 0:valdirnb(cx,cy, 0,+1, b))
0177 +((blockget( sizex*2+1, sizey*2+1, (cx-1)*2+2, (cy-1)*2, b) != ' ') ?
0178 0:valdirnb(cx,cy,+1,-1, b))
0179 +((blockget( sizex*2+1, sizey*2+1, (cx-1)*2+2, (cy-1)*2+1, b) != ' ') ?
0180 0:valdirnb(cx,cy,+1, 0, b))
0181 +((blockget( sizex*2+1, sizey*2+1, (cx-1)*2+2, (cy-1)*2+2, b) != ' ') ?
0182 0:valdirnb(cx,cy,+1,+1, b))
0183 ;
0184 if(min > valxy[ cx ][ cy ])
0185 min = valxy[ cx ][ cy ];
0186 }
0187 if(0 && min < 1){
0188 for( cx = 1; cx <= 8; cx++)
0189 for( cy = 1; cy <= 8; cy++){
0190 valxy[ cx ][ cy ] += (-min+1);
0191 }
0192 }
0193 }
0194
0195 }
0196
0197
0198
0199 void set( char c, int sizex, int sizey, int x, int y, char *s)
0200 {
0201 *(s + (y-1)*sizex + (x-1)) = c;
0202 }
0203
0204 char get( int sizex, int sizey, int x, int y, char *s)
0205 {
0206 return *(s + (y-1)*sizex + (x-1));
0207 }
0208
0209
0210
0211
0212 int pos_check(
0213 int is_turn,
0214 char turn,
0215 int sizex,
0216 int sizey,
0217 int x,
0218 int y,
0219 char *s
0220 )
0221 {
0222 int cx, cy;
0223 int exist_count = 0;
0224 char tonari = (turn == ___B___) ? ___W___:___B___;
0225 int tonari_count;
0226 int tonari_count_val;
0227
0228 //左
0229 for( tonari_count = 0, cx = x-1, cy = y; ; cx--){
0230 if(cx == 0 ||
0231 blockget( sizex*2+1, sizey*2+1, cx*2, (cy-1)*2+1, board) != ' '){
0232 tonari_count = 0;
0233 tonari_count_val = 0;
0234 break;
0235 }else{
0236 char nc = get( sizex, sizey, cx, cy, s);
0237 if(nc == tonari){
0238 tonari_count++;
0239 tonari_count_val+=valxy[ cx ][ cy ];
0240 }else if(nc == turn && tonari_count > 0){
0241 //exist_count += tonari_count_val;
0242 exist_count += tonari_count;
0243 break;
0244 }else{
0245 tonari_count = 0;
0246 tonari_count_val = 0;
0247 break;
0248 }
0249 }
0250 }
0251 if(is_turn && tonari_count){
0252 for( cx = x-1, cy = y; tonari_count-- > 0; cx--){
0253 set( turn, sizex, sizey, cx, cy, s);
0254 }
0255 }
0256
0257 //右
0258 for( tonari_count = 0, cx = x+1, cy = y; ; cx++){
0259 if(cx > sizex ||
0260 blockget( sizex*2+1, sizey*2+1, (cx-1)*2, (cy-1)*2+1, board) != ' '){
0261 tonari_count = 0;
0262 tonari_count_val = 0;
0263 break;
0264 }else{
0265 char nc = get( sizex, sizey, cx, cy, s);
0266 if(nc == tonari){
0267 tonari_count++;
0268 tonari_count_val+=valxy[ cx ][ cy ];
0269 }else if(nc == turn && tonari_count > 0){
0270 //exist_count += tonari_count_val;
0271 exist_count += tonari_count;
0272 break;
0273 }else{
0274 tonari_count = 0;
0275 tonari_count_val = 0;
0276 break;
0277 }
0278 }
0279 }
0280 if(is_turn && tonari_count){
0281 for( cx = x+1, cy = y; tonari_count-- > 0; cx++){
0282 set( turn, sizex, sizey, cx, cy, s);
0283 }
0284 }
0285
0286 //上
0287 for( tonari_count = 0, cx = x, cy = y-1; ; cy--){
0288 if(cy == 0 ||
0289 blockget( sizex*2+1, sizey*2+1, (cx-1)*2+1, cy*2, board) != ' '){
0290 tonari_count = 0;
0291 tonari_count_val = 0;
0292 break;
0293 }else{
0294 char nc = get( sizex, sizey, cx, cy, s);
0295 if(nc == tonari){
0296 tonari_count++;
0297 tonari_count_val+=valxy[ cx ][ cy ];
0298 }else if(nc == turn && tonari_count > 0){
0299 //exist_count += tonari_count_val;
0300 exist_count += tonari_count;
0301 break;
0302 }else{
0303 tonari_count = 0;
0304 tonari_count_val = 0;
0305 break;
0306 }
0307 }
0308 }
0309 if(is_turn && tonari_count){
0310 for( cx = x, cy = y-1; tonari_count--; cy--){
0311 set( turn, sizex, sizey, cx, cy, s);
0312 }
0313 }
0314
0315 //下
0316 for( tonari_count = 0, cx = x, cy = y+1; ; cy++){
0317 if(cy > sizey ||
0318 blockget( sizex*2+1, sizey*2+1, (cx-1)*2+1, (cy-1)*2, board) != ' '){
0319 tonari_count = 0;
0320 tonari_count_val = 0;
0321 break;
0322 }else{
0323 char nc = get( sizex, sizey, cx, cy, s);
0324 if(nc == tonari){
0325 tonari_count++;
0326 tonari_count_val+=valxy[ cx ][ cy ];
0327 }else if(nc == turn && tonari_count > 0){
0328 //exist_count += tonari_count_val;
0329 exist_count += tonari_count;
0330 break;
0331 }else{
0332 tonari_count = 0;
0333 tonari_count_val = 0;
0334 break;
0335 }
0336 }
0337 }
0338 if(is_turn && tonari_count){
0339 for( cx = x, cy = y+1; tonari_count--; cy++){
0340 set( turn, sizex, sizey, cx, cy, s);
0341 }
0342 }
0343
0344 //左上
0345 for( tonari_count = 0, cx = x-1, cy = y-1; ; cx--, cy--){
0346 if(cx == 0 || cy == 0 ||
0347 blockget( sizex*2+1, sizey*2+1, cx*2, cy*2, board) != ' '){
0348 tonari_count = 0;
0349 tonari_count_val = 0;
0350 break;
0351 }else{
0352 char nc = get( sizex, sizey, cx, cy, s);
0353 if(nc == tonari){
0354 tonari_count++;
0355 tonari_count_val+=valxy[ cx ][ cy ];
0356 }else if(nc == turn && tonari_count > 0){
0357 //exist_count += tonari_count_val;
0358 exist_count += tonari_count;
0359 break;
0360 }else{
0361 tonari_count = 0;
0362 tonari_count_val = 0;
0363 break;
0364 }
0365 }
0366 }
0367 if(is_turn && tonari_count){
0368 for( cx = x-1, cy = y-1; tonari_count--; cx--, cy--){
0369 set( turn, sizex, sizey, cx, cy, s);
0370 }
0371 }
0372
0373 //左下
0374 for( tonari_count = 0, cx = x-1, cy = y+1; ; cx--, cy++){
0375 if(cx == 0 || cy > sizey||
0376 blockget( sizex*2+1, sizey*2+1, cx*2, (cy-1)*2, board) != ' '){
0377 tonari_count = 0;
0378 tonari_count_val = 0;
0379 break;
0380 }else{
0381 char nc = get( sizex, sizey, cx, cy, s);
0382 if(nc == tonari){
0383 tonari_count++;
0384 tonari_count_val+=valxy[ cx ][ cy ];
0385 }else if(nc == turn && tonari_count > 0){
0386 //exist_count += tonari_count_val;
0387 exist_count += tonari_count;
0388 break;
0389 }else{
0390 tonari_count = 0;
0391 tonari_count_val = 0;
0392 break;
0393 }
0394 }
0395 }
0396 if(is_turn && tonari_count){
0397 for( cx = x-1, cy = y+1; tonari_count--; cx--, cy++){
0398 set( turn, sizex, sizey, cx, cy, s);
0399 }
0400 }
0401
0402 //右上
0403 for( tonari_count = 0, cx = x+1, cy = y-1; ; cx++, cy--){
0404 if(cx > sizex || cy == 0 ||
0405 blockget( sizex*2+1, sizey*2+1, (cx-1)*2, cy*2, board) != ' '){
0406 tonari_count = 0;
0407 tonari_count_val = 0;
0408 break;
0409 }else{
0410 char nc = get( sizex, sizey, cx, cy, s);
0411 if(nc == tonari){
0412 tonari_count++;
0413 tonari_count_val+=valxy[ cx ][ cy ];
0414 }else if(nc == turn && tonari_count > 0){
0415 //exist_count += tonari_count_val;
0416 exist_count += tonari_count;
0417 break;
0418 }else{
0419 tonari_count = 0;
0420 tonari_count_val = 0;
0421 break;
0422 }
0423 }
0424 }
0425 if(is_turn && tonari_count){
0426 for( cx = x+1, cy = y-1; tonari_count--; cx++, cy--){
0427 set( turn, sizex, sizey, cx, cy, s);
0428 }
0429 }
0430
0431 //右下
0432 for( tonari_count = 0, cx = x+1, cy = y+1; ; cx++, cy++){
0433 if(cx > sizex || cy > sizey ||
0434 blockget( sizex*2+1, sizey*2+1, (cx-1)*2, (cy-1)*2, board) != ' '){
0435 tonari_count = 0;
0436 tonari_count_val = 0;
0437 break;
0438 }else{
0439 char nc = get( sizex, sizey, cx, cy, s);
0440 if(nc == tonari){
0441 tonari_count++;
0442 tonari_count_val+=valxy[ cx ][ cy ];
0443 }else if(nc == turn && tonari_count > 0){
0444 //exist_count += tonari_count_val;
0445 exist_count += tonari_count;
0446 break;
0447 }else{
0448 tonari_count = 0;
0449 tonari_count_val = 0;
0450 break;
0451 }
0452 }
0453 }
0454 if(is_turn && tonari_count){
0455 for( cx = x+1, cy = y+1; tonari_count--; cx++, cy++){
0456 set( turn, sizex, sizey, cx, cy, s);
0457 }
0458 }
0459
0460 if(is_turn && exist_count)
0461 set( turn, sizex, sizey, x, y, s);
0462
0463 return exist_count;
0464 }
0465
0466 const char urlcurs[ 63 ] = "0123456789"
0467 "abcdefghijklmnopqrstuvwxyz"
0468 "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
0469 char * cur2urlcur( char *urlcur, char *cur)
0470 {
0471 static char *ret;
0472 int num = 0;
0473 int i=0;
0474 ret = urlcur;
0475 while(i < 64){
0476 switch( *cur){
0477 case ___N___: num = num * 3; break;
0478 case ___B___: num = num * 3 + 1; break;
0479 case ___W___: num = num * 3 + 2; break;
0480 }
0481 cur++;
0482 i++;
0483 if( i % 3 == 0){
0484 *urlcur = urlcurs[ num ];
0485 urlcur++;
0486 num = 0;
0487 }
0488 }
0489 *urlcur = urlcurs[ num*3*3 ];
0490 urlcur++;
0491
0492 *urlcur = '\0';
0493
0494 return ret;
0495 }
0496
0497 char * urlcur2cur( char *cur, char *urlcur)
0498 {
0499 static char *ret;
0500 int i=0;
0501 ret = cur;
0502 *cur = '\0';
0503 while( i < 22){
0504 switch( *urlcur){
0505 case '0': *cur++ = ___N___; *cur++ = ___N___; *cur++ = ___N___; break;
0506 case '1': *cur++ = ___N___; *cur++ = ___N___; *cur++ = ___B___; break;
0507 case '2': *cur++ = ___N___; *cur++ = ___N___; *cur++ = ___W___; break;
0508 case '3': *cur++ = ___N___; *cur++ = ___B___; *cur++ = ___N___; break;
0509 case '4': *cur++ = ___N___; *cur++ = ___B___; *cur++ = ___B___; break;
0510 case '5': *cur++ = ___N___; *cur++ = ___B___; *cur++ = ___W___; break;
0511 case '6': *cur++ = ___N___; *cur++ = ___W___; *cur++ = ___N___; break;
0512 case '7': *cur++ = ___N___; *cur++ = ___W___; *cur++ = ___B___; break;
0513 case '8': *cur++ = ___N___; *cur++ = ___W___; *cur++ = ___W___; break;
0514
0515 case '9': *cur++ = ___B___; *cur++ = ___N___; *cur++ = ___N___; break;
0516 case 'a': *cur++ = ___B___; *cur++ = ___N___; *cur++ = ___B___; break;
0517 case 'b': *cur++ = ___B___; *cur++ = ___N___; *cur++ = ___W___; break;
0518 case 'c': *cur++ = ___B___; *cur++ = ___B___; *cur++ = ___N___; break;
0519 case 'd': *cur++ = ___B___; *cur++ = ___B___; *cur++ = ___B___; break;
0520 case 'e': *cur++ = ___B___; *cur++ = ___B___; *cur++ = ___W___; break;
0521 case 'f': *cur++ = ___B___; *cur++ = ___W___; *cur++ = ___N___; break;
0522 case 'g': *cur++ = ___B___; *cur++ = ___W___; *cur++ = ___B___; break;
0523 case 'h': *cur++ = ___B___; *cur++ = ___W___; *cur++ = ___W___; break;
0524
0525 case 'i': *cur++ = ___W___; *cur++ = ___N___; *cur++ = ___N___; break;
0526 case 'j': *cur++ = ___W___; *cur++ = ___N___; *cur++ = ___B___; break;
0527 case 'k': *cur++ = ___W___; *cur++ = ___N___; *cur++ = ___W___; break;
0528 case 'l': *cur++ = ___W___; *cur++ = ___B___; *cur++ = ___N___; break;
0529 case 'm': *cur++ = ___W___; *cur++ = ___B___; *cur++ = ___B___; break;
0530 case 'n': *cur++ = ___W___; *cur++ = ___B___; *cur++ = ___W___; break;
0531 case 'o': *cur++ = ___W___; *cur++ = ___W___; *cur++ = ___N___; break;
0532 case 'p': *cur++ = ___W___; *cur++ = ___W___; *cur++ = ___B___; break;
0533 case 'q': *cur++ = ___W___; *cur++ = ___W___; *cur++ = ___W___; break;
0534
0535 }
0536 i++;
0537 urlcur++;
0538 }
0539 cur-=2;//3*22-8*8
0540 *cur = '\0';
0541
0542 return ret;
0543 }
0544
0545
0546 #define WALLCOLOR "gold"
0547 char * colorstring( int c, char *def)
0548 {
0549 switch( c){
0550 case 'C':
0551 case 'c':
0552 return "#33AAFF";
0553 case 'H':
0554 case 'h':
0555 return "gray";
0556 case 'B':
0557 case 'b':
0558 return "black";
0559 case 'G':
0560 case 'g':
0561 return WALLCOLOR;
0562 case 'S':
0563 case 's':
0564 return "silver";
0565 case 'R':
0566 case 'r':
0567 return "red";
0568 case '+':
0569 case '-':
0570 case '|':
0571 default:
0572 return def;
0573 }
0574 }
0575
0576 char * colorPstring( int c, char *def)
0577 {
0578 switch( c){
0579 case 'C':
0580 case 'c':
0581 return "cyan";
0582 case 'H':
0583 case 'h':
0584 return "gray";
0585 case 'B':
0586 case 'b':
0587 return "black";
0588 case 'G':
0589 case 'g':
0590 return WALLCOLOR;
0591 case 'S':
0592 case 's':
0593 return "silver";
0594 case 'R':
0595 case 'r':
0596 return "red";
0597 case '+':
0598 case '-':
0599 case '|':
0600 default:
0601 return def;
0602 }
0603 }
0604 char * colorDstring( int c, char *def)
0605 {
0606 switch( c){
0607 case 'C':
0608 case 'c':
0609 return "cyan";
0610 case 'H':
0611 case 'h':
0612 return "gray";
0613 case 'B':
0614 case 'b':
0615 return "black";
0616 case 'G':
0617 case 'g':
0618 return WALLCOLOR;
0619 case 'S':
0620 case 's':
0621 return "silver";
0622 case 'R':
0623 case 'r':
0624 return "red";
0625 case '+':
0626 case '-':
0627 case '|':
0628 default:
0629 return def;
0630 }
0631 }
0632
0633 int disp_now( char nextturn, int xsize, int ysize, char *status, int isblue, int bx, int by, char *orgstatus)
0634 {
0635 char urlstatus[ 24 ];
0636 int i,j;
0637 printf("<TABLE bgcolor=green>\n");
0638 for( i = 0; i < (ysize*2)+1; i++)
0639 {
0640 printf("<TR hight=16>\n");
0641 for( j = 0; j < (xsize*2)+1; j++)
0642 {
0643 char c = board[ i*(xsize*2+1)+j ];
0644 char m = *(status+(i/2)*xsize+(j/2));
0645 if(i%2 && j%2){
0646 char ms[ 256 ];
0647 switch( m)
0648 {
0649 #ifdef IS_NUM
0650 case ___B___: sprintf( ms, "<FONT COLOR=WHITE>●<BR>%d</FONT>", valxy[ j/2+1 ][ i/2+1 ]);break;
0651 case ___W___: sprintf( ms, "<FONT COLOR=RED>●<BR>%d</FONT>", valxy[ j/2+1 ][ i/2+1 ]);break;
0652 #else
0653 case ___B___:
0654 if(i/2+1 == by && j/2+1 == bx)
0655 sprintf( ms, "<IMG SRC=\"/icons/black24f.gif\">");
0656 else if(*(orgstatus+(i/2)*xsize+(j/2)) != ___B___)
0657 sprintf( ms, "<IMG SRC=\"/icons/black24d.gif\">");
0658 else
0659 sprintf( ms, "<IMG SRC=\"/icons/black24c.gif\">");
0660 break;
0661 case ___W___:
0662 if(i/2+1 == by && j/2+1 == bx)
0663 sprintf( ms, "<IMG SRC=\"/icons/white24f.gif\">");
0664 else if(*(orgstatus+(i/2)*xsize+(j/2)) != ___W___)
0665 sprintf( ms, "<IMG SRC=\"/icons/white24d.gif\">");
0666 else
0667 sprintf( ms, "<IMG SRC=\"/icons/white24c.gif\">");
0668 break;
0669 #endif
0670 case ___N___: if(isblue == 0
0671 || nextturn == ___N___
0672 || nextturn == ___b___
0673 || nextturn == ___w___
0674 || pos_check( 0, nextturn, 8, 8, j/2+1, i/2+1, status) == 0){
0675 #ifdef IS_NUM
0676 sprintf( ms, "×<BR>%d", valxy[ j/2+1 ][ i/2+1 ]);
0677 #else
0678 if(c == ' ')
0679 sprintf( ms,
0680 "<IMG SRC=\"/icons/green24c.gif\" border=\"0\">");
0681 else
0682 sprintf( ms, "<FONT COLOR=\"%s\">■</FONT>",
0683 colorPstring( c, "green"));
0684 #endif
0685 }else{
0686 #ifdef IS_NUM
0687 sprintf( ms,
0688 "<A HREF=\"/cgi-bin/%s?t=%c&x=%d&y=%d&s=%s\">"
0689 "○<BR>%d"
0690 "</A>",
0691 CGINAME,
0692 tolower(nextturn), j/2+1, i/2+1,
0693 //status,
0694 cur2urlcur( urlstatus, status),
0695 valxy[ j/2+1 ][ i/2+1 ]
0696 );
0697 #else
0698 sprintf( ms,
0699 "<A HREF=\"/cgi-bin/%s?t=%c&x=%d&y=%d&s=%s\">"
0700 "<IMG SRC=\"/icons/blue24e.gif\" border=\"0\">"
0701 //"○"
0702 "</A>",
0703 CGINAME,
0704 tolower(nextturn), j/2+1, i/2+1,
0705 //status
0706 cur2urlcur( urlstatus, status)
0707 );
0708 #endif
0709 }
0710 break;
0711 }
0712 #ifdef IS_NUM
0713 printf(
0714 "<TD align=center bgcolor=green width=36 height=36>%s</TD>",
0715 ms
0716 );
0717 #else
0718 printf(
0719 "<TD align=center bgcolor=%s width=32 height=32>%s</TD>",
0720 ((c == ' ') ? "green":colorPstring(c, "green")) ,
0721 ms
0722 );
0723 #endif
0724 }else{
0725 printf( "<TD bgcolor=%s width=1 height=3></TD>",
0726 (c==' ') ?
0727 "#009900":
0728 (((i+j)%2) ?
0729 ((j == 0 ||
0730 j == (xsize*2) ||
0731 i == (ysize*2) ||
0732 i == 0) ?
0733 colorDstring(c, "black"):colorDstring(c, WALLCOLOR)
0734 )
0735 :
0736 ((j == 0 ||
0737 j == (xsize*2) ||
0738 i == (ysize*2) ||
0739 i == 0) ?
0740 colorDstring(c, "black"):colorDstring(c, WALLCOLOR)
0741 )
0742 )
0743 );
0744 }
0745 }
0746 printf("</TR>\n");
0747 }
0748 printf("</TABLE>\n");
0749 }
0750
0751 char * _ADURL = NULL;
0752
0753 int i[ 64+1 ],j[ 64+1 ];
0754 int max[ 64+1 ];
0755 char status[ 64+1 ][ 64+1 ];
0756 char turn[ 64+1 ];
0757 int check[ 64+1 ];
0758 char now_status[ 1024 ];
0759
0760 void disp_head(int i, char *s)
0761 {
0762 printf("Content-type: text/html;charset=euc-jp;\n\n");
0763 printf("<HTML>\n");
0764 printf("<HEAD>\n");
0765 if((i > 0 ||(s && *s)))
0766 printf("<META HTTP-EQUIV=\"REFRESH\" CONTENT=\"%d;URL=/cgi-bin/%s%s\">\n",i, CGINAME, s);
0767 printf("<TITLE>WALLSTREETS</TITLE>\n");
0768 printf("<STYLE TYPE=\"text/css\">");
0769 printf("<!--\n");
0770 printf("H1{font-size:16pt; color:gold}\n");
0771 printf("H2{font-size:8pt; color:blue}\n");
0772 printf("body {\n");
0773 printf("background-repeat: no-repeat;\n");
0774 printf("background-attachment: fixed;\n");
0775 printf("background-position: center middle;\n");
0776 printf("}\n");
0777 printf("A{\n");
0778 printf(" text-decoration: none;\n");
0779 printf("}\n");
0780 printf("A:HOVER{\n");
0781 printf("background:repat-x center bottom;\n");
0782 printf("}\n");
0783 printf("-->\n");
0784 printf("</STYLE>\n");
0785 printf("</HEAD>\n");
0786 printf("<BODY bgcolor=#000033>\n");
0787 printf("<CENTER>\n");
0788 if( s && *s){
0789 printf("<TABLE><TR><TD align=center valign=top>\n");
0790 }else{
0791 printf("<TABLE><TR><TD align=center valign=top>\n");
0792 }
0793 printf("<TABLE bgcolor=#550000 style=\"width:335px;\"><TR><TD align=center><FONT SIZE=5 COLOR=GOLD>WallStreets</FONT><A HREF=\"#\" onclick=\"var w01;w01=window.open('http://wallstreets.ws/','win1','width=480,height=730,resizable=yes');w01.focus()\"><FONT SIZE=3 COLOR=silver> JP</FONT></A><A HREF=\"#\" onclick=\"var w01;w01=window.open('http://wallstreets.ws/eu/','win1','width=480,height=730,resizable=yes');w01.focus()\"><FONT SIZE=3 COLOR=silver> UV</FONT></A></TD></TR></TABLE>\n");
0794 }
0795
0796 int whitenum( char *status)
0797 {
0798 int ret = 0;
0799 while( *status){
0800 if(*status == ___W___)
0801 ret++;
0802 status++;
0803 }
0804
0805 return ret;
0806 }
0807
0808 char *mycrypt( char *msg)
0809 {
暗号化コードのため省略
0823 }
0824
0825
0826 void disp_tail(char nextturn, char *msg)
0827 {
0828 char buf[ 256 ];
0829 char filename[ 256 ];
0830 char userpoint[ 8 ][ 160 ];
0831 char username[ 8 ][ 320 ];
0832 int i = 0;
0833
0834
0835 if(IS_P2P == 0){
0836 sprintf( filename, "%s.rank", CGINAME);
0837
0838 FILE *fp;
0839 do{
0840 fp = fopen( filename, "rb");
0841 if(!fp){
0842 FILE *fout = fopen(filename, "wb");
0843 fprintf(fout, "0,-\n0,-\n0,-\n0,-\n0,-\n0,-\n0,-\n0,-\n0,-\n");
0844 fclose(fout);
0845 }
0846 }while(!fp);
0847
0848 while( fgets( buf, 256, fp ) && i < 8){
0849 char *cp = strchr( buf, ',');
0850 *cp = '\0';
0851 strcpy( userpoint[ i ], buf);
0852 strcpy( username[ i ], cp+1);
0853 i++;
0854 }
0855 fclose( fp);
0856
0857
0858 printf("<TABLE bgcolor=#550000 style=\"width:335px;\">\n");
0859 if(nextturn==___N___ && whitenum( now_status) > atoi(userpoint[ 7 ])){
0860 printf("<TR><TD colspan=3 align=center>\n");
0861 printf("<FORM method=post action=\"http://wallstreets.ws/cgi-bin/%s?t=h\">\n", CGINAME);
0862 printf("<INPUT TYPE=hidden name=stat value=\"%s\">\n", now_status);
0863 printf("<INPUT TYPE=hidden name=crypt value=\"%s\">\n", mycrypt(now_status));
0864 printf("<FONT color=gold>nickname:</font><INPUT TYPE=text name=username value=\"\">\n");
0865 printf("<INPUT type=submit value=\"High Score Set\">\n");
0866 printf("</FORM>\n");
0867 printf("</TD></TR>\n");
0868 }
0869 {
0870 int i;
0871 if(atol(userpoint[0]) > 0) strcat( userpoint[ 0 ], "0000");
0872 if(atol(userpoint[1]) > 0) strcat( userpoint[ 1 ], "000");
0873 if(atol(userpoint[2]) > 0) strcat( userpoint[ 2 ], "00");
0874 if(atol(userpoint[3]) > 0) strcat( userpoint[ 3 ], "0");
0875 for(i = 0; i < 8; i++)
0876 {
0877 printf("<TR bgcolor=%s><TD align=right>\n", (i%2) ? "0x000033":"0x000011");
0878 printf("<FONT color=silver><%d></FONT></TD><TD align=right><FONT color=silver>%s</FONT></TD><TD align=center><FONT color=silver>%s</FONT>\n", i+1, userpoint[ i ] , username[ i ]);
0879 printf("</TD></TR>\n");
0880 }
0881 }
0882 printf("<TR><TD colspan=3 align=center>\n");
0883 printf("<FONT size=5 color=gold>★RANKING★</FONT>\n");
0884 printf("</TD></TR>\n");
0885 printf("</TABLE>\n");
0886 }
0887 printf("<TD></TR></TABLE>\n");
0888 printf("</BODY>\n");
0889 printf("</HTML>\n");
0890 }
0891
0892 int all_pos_check( char nextturn, int *maxi, int *maxj, char *now_status)
0893 {
0894 int i,j;
0895 int max = 0;
0896 *maxi = 0;
0897 *maxj = 0;
0898 for( i = 1; i <= 8; i++){
0899 for( j = 1; j <=8; j++){
0900 if(get( 8, 8, i, j, now_status) == ___N___){
0901 int now = pos_check( 0, nextturn, 8, 8, i, j, now_status);
0902 if(now > max){
0903 *maxi = i;
0904 *maxj = j;
0905 max = now;
0906 }
0907 }
0908 }
0909 }
0910 return max;
0911 }
0912
0913 void p( char *str)
0914 {
0915 printf( "%s\n", str);
0916 }
0917
0918
0919 int minmax[ 64+1 ];
省略
0926 int max_sp;
0927 int now_max_loop;
省略
0964 void disp_stack( int x, int y, char *msg)
0965 {
0966 ;
0967 }
省略
0969
0970 /*-----------------------------------------------------------------------------
0971 関数名 recursive_all_pos_check
0972 機能 最も有望な手を返す
0973 引数 nextturn 有望な手を探索する側(___B___/___W___)
0974 *maxi 有望な手のX座標
0975 *maxj 有望な手のY座標
0976 now_status 探索の対象となるゲーム状態
0977 max_loop 最大の探索ループ数
0978 ---------------------------------------------------------------------------*/
0979 int recursive_all_pos_check(
0980 char nextturn,
0981 int *maxi,
0982 int *maxj,
0983 char *now_status,
0984 unsigned long max_loop
0985 )
0986 {
以下では、多ゲームプロセス同時処理用のサーバーや携帯電話など少ないメモリしか利用しないプラットフォームで、しかも適度に負ける必要のある場合に対応する「ひとつのベストモード」として、スタックによる、深さレベル(=先読みレベル)制限つきの深さ優先探索をおこなっているが、多くのメモリが利用できるスピード優先ないし強さ優先(勝利優先)のモードでは、探索対象となるゲーム状態の合流(違う手として先読みして同じゲーム状態に遭遇する場合)をハッシュテーブル等により検知してその先の重複探索を回避したり、パターン化された有望な手筋についてのみ先読みの深さレベルを制限しないようにする等、より一般的な公知の探索手法も「別のベストモード」として採用できることは自明であり、これについては詳述しない。
基本的には公知のミニマックス法で最良の手を決定するが、手の評価において、自分の駒の置いてある座標の重み(value_init()で生成済のvalxy[][])の和がなるべく大きくなる手を最良の手として選ぶ。
また、適度の負ける必要がなく、より強さ優先にするには、終盤で、座標の重み(座標の価値を表すvalxy[][])を別途均一化し、単純に駒数で相手に優るような手を探索するようにする。
0987 const int level = LEVEL;
0988 int first_get = 0;
0989 int m,n;
0990
0991 *maxi = *maxj = 0;
0992
省略
0994 minmax[ 0 ] = MUGENM;
0995
0996 // スタックの初期化
0997 max_sp = 0;
0998 turn[ 0 ] = ___N___;
0999 strcpy( status[ 0 ], now_status);
1000 i[ 0 ] = j[ 0 ] = 0;
1001 max[ 0 ] = 0;
1002 #ifdef DEBUG
1003 printf( "<TABLE border bgcolor=white>\n");
1004 #endif
1005 // 次の一手
1006 ++max_sp;
1007 turn[ max_sp ] = nextturn;
1008 i[ max_sp ] = j[ max_sp ] = 1;
1009 max[ max_sp ] = 0;
1010 do{
1011
1012 if(--max_loop == 0){
1013 disp_stack( *maxi, *maxj, "LOOPOVER");
1014 break;
1015 }
1016 now_max_loop = max_loop;
1017
1018 if( max_sp % 2 == 1 && max_sp < level){
1019 // 1 or 3 のとき
1020 minmax[ max_sp ] = MUGENP;
1021 }
1022
1023 if( max_sp % 2 == 0 && max_sp < level){
1024 // 2 or 4 のとき(0はありえないから)
1025 minmax[ max_sp ] = MUGENM;
1026 }
1027
1028 strcpy( status[ max_sp ], status[ max_sp-1 ]);
1029
1030 if( get( 8, 8, i[ max_sp ], j[ max_sp ], status[ max_sp ]) == ___N___
1031 && (check[ max_sp ]
1032 = pos_check( 1, turn[ max_sp ], 8, 8, i[ max_sp ], j[ max_sp ], status[ max_sp ])) > 0){
1033 // 注目した座標(i[max_sp],j[max_sp])に石がなくかつとれるので置ける場合
1034
1035 // 現在のmax_sp-1のゲーム状態に対して先の手max_spが存在することをマークする
1036 max[ max_sp ] = check[ max_sp ];
1037
1038 if(max_sp < level){
1039 // まだ先を読む必要がある場合,
1040
1041 //disp_stack( *maxi, *maxj, "THINKING");
1042 // 置いてみた後のstatus[ max_sp ]をスタックにつむ
1043 ++max_sp;
1044 turn[ max_sp ] = (turn[ max_sp-1 ] == ___B___) ? ___W___:___B___;
1045 i[ max_sp ] = j[ max_sp ] = 1;
1046 max[ max_sp ] = 0;
1047
1048 }else{
1049 // 最深読みレベルに達していた場合
1050
1051 // 最深読みレベルの評価を計算する
1052 int sum = 0;
1053 int k;
1054 if(IS_STACK_EST)
1055 {
1056 for( k = 1; k <= max_sp; k++)
1057 sum +=
1058 (turn[ k ] == nextturn) ?
1059 +(check[ k ]+valxy[i[ k ]][j[ k ]]) : -(check[ k ]+valxy[i[ k ]][j[ k ]]);
1060 //+(check[ k ]) : -(check[ k ]);
1061 }else{
1062 int x,y;
1063 int sumw = 0;
1064 int sumb = 0;
1065 for( x = 1; x <= 8; x++){
1066 for( y = 1; y <= 8; y++){
1067 switch(get( 8, 8, x, y, status[ max_sp ])){
1068 case ___N___: break;
1069 case ___B___: sumw += valxy[ x ][ y ]; break;
1070 case ___W___: sumb += valxy[ x ][ y ]; break;
1071 }
1072 }
1073 }
1074 sum = (nextturn == ___B___) ? (sumw-sumb):(sumb-sumw);
1075 }
1076 if(/* 最深レベルは奇数故 max_sp % 2 = 1 のチェックはいらない */
1077 sum > minmax[ max_sp-1 ]){
1078 minmax[ max_sp-1 ] = sum;
1079 //disp_stack( *maxi, *maxj, "sum > minmax[ max_sp-1 ]");
1080 }
1081 //disp_stack( *maxi, *maxj);
1082
1083 // 次の候補にポインタを移す
1084 while( j[ max_sp ] == 8 && i[ max_sp ] == 8 && max_sp > 0){
1085 max_sp --;
1086 if(max_sp % 2 == 0 && max_sp < level){
1087 if(minmax[ max_sp ] < minmax[ max_sp-1 ]){
1088 minmax[ max_sp-1 ] = minmax[ max_sp ];
1089 disp_stack( *maxi, *maxj, "minmax[ max_sp ] < minmax[ max_sp-1 ]");
1090 }
1091 }
1092
1093 if(max_sp % 2 == 1 && max_sp < level){
1094 if(minmax[ max_sp-1 ] < minmax[ max_sp ]){
1095 minmax[ max_sp-1 ] = minmax[ max_sp ];
1096 disp_stack( *maxi, *maxj, "minmax[ max_sp-1 ] < minmax[ max_sp ]");
1097 if( max_sp == 1){
1098 *maxi = i[ 1 ];
1099 *maxj = j[ 1 ];
1100 first_get = check[ 1 ];
1101 }
1102 }
1103 }
1104 if(max_sp == 1)
1105 disp_stack( *maxi, *maxj, "CANDIDATE");
1106 }
1107
1108 if(max_sp > 0){
1109 if(j[ max_sp ] < 8){
1110 j[ max_sp ]++;
1111 }else if(i[ max_sp ] < 8){
1112 i[ max_sp ]++;
1113 j[ max_sp ] = 1;
1114 }
1115 }
1116 }
1117 }else{
1118 // 注目した座標(i[max_sp],j[max_sp])に既に石があるか,なくても置けないときの処理
1119 if(j[ max_sp ] < 8){
1120 j[ max_sp ]++;
1121 }else if(i[ max_sp ] < 8){
1122 i[ max_sp ]++;
1123 j[ max_sp ] = 1;
1124 }else{
1125 //その手をすべて探索したとき
1126 disp_stack( *maxi, *maxj, "all searched");
1127 if(max[ max_sp ] == 0){
1128 //すべて探索した結果としておけなかったとき
1129 char revturn = (turn[ max_sp ] == ___B___) ? ___W___:___B___;
1130 int m,n,rev_check = 0;
1131 int nokori = 0, rev_nokori = 0;
1132
1133 disp_stack( *maxi, *maxj, "max[ max_sp ] == 0");
1134 // 番を相手にわたせるかどうか計算
1135 for(m = 1; m <= 8; m++)
1136 for(n = 1; n <= 8; n++){
1137 char c = get( 8, 8, m, n, status[ max_sp ]);
1138 if(c == ___N___)
1139 rev_check += pos_check( 0, revturn, 8, 8, m, n, status[ max_sp ]);
1140 else if(c == revturn)
1141 rev_nokori ++;
1142 else
1143 nokori ++;
1144 }
1145
1146 if(rev_check > 0 && max_sp < level){
1147 // 相手の置く場所があり番をわたせるとき
1148
1149 // 自分のturnはスキップする
1150 i[ max_sp ] = 8;
1151 j[ max_sp ] = 8;
1152
1153 // turnを交替して探索しなおし
1154 ++max_sp;
1155 turn[ max_sp ] = revturn;
1156 i[ max_sp ] = 1;
1157 j[ max_sp ] = 0;
1158 max[ max_sp ] = 0;
1159
1160 disp_stack( *maxi, *maxj, "PASS");
1161
1162 }else{
1163 // ゲームルール上,自分も相手もおける石がなかった場合
1164 if( max_sp == 1){
1165 // 1手目で自分も相手もなにもできないとき
1166 disp_stack( *maxi, *maxj, "1 te PASSPASS GAMEOVER");
1167 ;//ゲームオーバー
1168 }else{
1169 disp_stack( *maxi, *maxj, "max_sp > 1");
1170 // 2手先読みでこの状態に遭遇したとき
1171 if(max_sp == 2 && rev_nokori > nokori){
1172 // 2手先で両者とも何もできなくなりコールド勝ちになる場合
1173 *maxi = i[ 1 ];
1174 *maxj = j[ 1 ];
1175 //all_1_all_nM1_max_min_max = MUGENP;//この手に決めてしまう
1176 minmax[ 0 ] = MUGENP;
1177 first_get = check[ 1 ];
1178 disp_stack( *maxi, *maxj, "COLD WIN");
1179 }else{
1180 // 2手先以上で両者とも何もできなくなり,負けか引き分けのとき
1181 // 最深読みレベルの評価を計算する
1182 int sum = 0;
1183 int k;
1184 if(IS_STACK_EST){
1185 for( k = 1; k <= max_sp; k++)
1186 sum +=
1187 (turn[ k ] == nextturn) ?
1188 +(check[ k ]+valxy[i[ k ]][j[ k ]]) : -(check[ k ]+valxy[i[ k ]][j[ k ]]);
1189 //+(check[ k ]) : -(check[ k ]);
1190 }else{
1191 int x,y;
1192 int sumw = 0;
1193 int numw = 0;
1194 int sumb = 0;
1195 int numb = 0;
1196 for( x = 1; x <= 8; x++){
1197 for( y = 1; y <= 8; y++){
1198 switch(get( 8, 8, x, y, status[ max_sp ])){
1199 case ___N___: break;
1200 case ___B___: numw++;sumw += valxy[ x ][ y ]; break;
1201 case ___W___: numb++;sumb += valxy[ x ][ y ]; break;
1202 }
1203 }
1204 }
1205 if(numw == 0){
1206 sumw = MUGENM;
1207 }
1208 if(numb == 0){
1209 sumb = MUGENM;
1210 }
1211 sum = (nextturn == ___B___) ? (sumw-sumb):(sumb-sumw);
1212 }
1213 disp_stack( *maxi, *maxj, "LOSEorDRAW-BACKTRACK");
1214 if(sum > minmax[ max_sp-1 ]){
1215 // max_sp == 3 or 5 , max_sp-1 == 2 or 4を想定している
1216 minmax[ max_sp-1 ] = sum;
1217 disp_stack( *maxi, *maxj, "LOSEorDRAW-BACKTRACK sum > minmax[ max_sp-1 ]");
1218 }
1219 //負けか引き分けになりそうなときの処理終了
1220 }
1221 disp_stack( *maxi, *maxj, "NO GAME at 2 or more");
1222 //2手先読み以上で遭遇した場合終了
1223 }
1224 disp_stack( *maxi, *maxj, "NO GAME at a context");
1225 // ゲームルール上,自分も相手もおける石がなかった場合終了
1226 }
1227 disp_stack( *maxi, *maxj, "NO GAME");
1228 // すべて探索した結果としておけなかったとき終了
1229 }
1230
1231 //disp_stack( *maxi, *maxj, "NO TE");
1232
1233 // 次の候補にポインタを移す
1234 while( j[ max_sp ] == 8 && i[ max_sp ] == 8 && max_sp > 0){
1235 max_sp --;
1236 if(max_sp % 2 == 0 && max_sp < level){
1237 if(minmax[ max_sp ] < minmax[ max_sp-1 ]){
1238 minmax[ max_sp-1 ] = minmax[ max_sp ];
1239 disp_stack( *maxi, *maxj, "minmax[ max_sp ] < minmax[ max_sp-1 ]");
1240 }
1241 }
1242 if(max_sp % 2 == 1 && max_sp < level){
1243 if(minmax[ max_sp-1 ] < minmax[ max_sp ]){
1244 minmax[ max_sp-1 ] = minmax[ max_sp ];
1245 disp_stack( *maxi, *maxj, "minmax[ max_sp-1 ] < minmax[ max_sp ]");
1246 if( max_sp == 1){
1247 *maxi = i[ 1 ];
1248 *maxj = j[ 1 ];
1249 first_get = check[ 1 ];
1250 }
1251 }
1252 }
1253 }
1254 //disp_stack( *maxi, *maxj, "BACKTRACK AFTER NO-TE");
1255 if(max_sp > 0){
1256 if(j[ max_sp ] < 8){
1257 j[ max_sp ]++;
1258 }else if(i[ max_sp ] < 8){
1259 i[ max_sp ]++;
1260 j[ max_sp ] = 1;
1261 }
1262 }
1263 }
1264 }
1265 }while( max_sp > 0);
1266
1267 #ifdef DEBUG
1268 printf( "</TABLE>\n");
1269 #endif
1270
1271 return first_get
1272 }
1273
1274 int disp_point( int is_start, int x, int y, char *now_status, char nextturn, double t)
1275 {
1276 int i;
1277 int W = 0;
1278 int R = 0;
1279 char ch;
1280 char name[ 256 ];
1281 char *cp;
1282 strcpy( name, CGINAME);
1283 cp= strchr( name, '.');
1284 *cp = '\0';
1285
1286 for( i = 0; i < 8*8; i++)
1287 {
1288 switch( now_status[ i ]){
1289 case ___N___: break;
1290 #ifdef IS_NUM
1291 case ___B___: W += valxy[ i % 8 + 1 ][ i / 8 + 1 ]; break;
1292 case ___W___: R += valxy[ i % 8 + 1 ][ i / 8 + 1 ]; break;
1293 #else
1294 case ___B___: W ++; break;
1295 case ___W___: R ++; break;
1296 #endif
1297 }
1298 }
1299 if(W == R)
1300 ch = '=';
1301 else if(W > R)
1302 ch = '>';
1303 else
1304 ch = '<';
1305 if(nextturn == ___N___)
1306 printf("<TABLE style=\"width:335px;\" bgcolor=#550000><TR><TD align=center><FONT COLOR=gold SIZE=1>%.2fs %s </FONT><FONT color=silver size=3><IMG SRC=\"/icons/black24c.gif\" width=12> %d %c <IMG SRC=\"/icons/white24c.gif\" width=12> %d → <A HREF=\"/cgi-bin/%s\"><IMG SRC=\"/icons/replay.gif\" width=256></A><FONT></TD></TR></TABLE>\n", t, name, W, ch, R, CGINAME);
1307 else
1308 printf("<TABLE style=\"width:335px;\" bgcolor=#550000><TR><TD align=center><FONT COLOR=gold SIZE=1>%.2fs %s </FONT><FONT color=silver size=3><IMG SRC=\"/icons/black24c.gif\" width=12> %d %c <IMG SRC=\"/icons/white24c.gif\" width=12> %d → <IMG SRC=\"/icons/%s24e.gif\" width=12> %s</FONT></TD></TR></TABLE>\n", t, name, W, ch, R, (nextturn == ___W___||nextturn == ___w___) ? "white":"black", ((nextturn == ___W___||nextturn == ___w___) || IS_P2P == 1) ? "<font color=gold size=1>pls. select</font>":"<font color=gold size=1>please wait</font>");
1309 }
1310
1311 void countup( void)
1312 {
省略
1347 }
1348
1349 const char codetbl[] = "0123456789ABCDEF";
1350
1351 int urldecode(char *in, char *out)
1352 {
省略
1380 }
1381
1382 int main( int argc, char *argv[])
1383 {
1384 int smode = 1;
1385 int isloop = 1;
1386 char org_status[ 1024 ];
1387 char url_status[ 64 ];
1388
1389 clock_t start,end;
1390 {
1391 char *cp = strrchr( argv[ 0 ], '/');
1392 strcpy(CGINAME, cp+1);
1393 }
1394 start = clock();
1395
1396
1397
1398 char autonext[ 1024 ] = {""};
1399 char lastturn = ___N___;
1400 char nextturn = ___N___;
1401 int x,y;
1402 char cfgfilepath[ 1024 ];
1403 char given_status[ 1024 ];
1404 char *cp = getenv("QUERY_STRING"); cp = (cp) ? strcpy( given_status, cp) : NULL;
1405 char *user = getenv("REMOTE_ADDR");
1406
1407 value_init( board);
1408
1409 //自分の色および場所を変数にいれる
1410 if(cp == NULL || *cp == '\0' || *(cp+2)=='h'){
1411
1412 char buf[ 1024 ];
1413
1414 if(*(cp+2) =='h'){
1415 char *sp;
1416 char *ep;
1417 int point = 0;
1418 char sname[ 64 ];
1419 char scrypt[ 64+1 ];
1420 char ncrypt[ 64+1 ];
1421 char sstat[ 64+1 ];
1422
1423 fgets( buf, 1024, stdin);
1424
1425
1426 sp = buf+5;
1427 ep = strchr( sp, '&');
1428 *ep = '\0';
1429 strcpy( sstat, sp);
1430 strcpy( ncrypt, (const char *)mycrypt( sstat));
1431
1432 sp = ep+7;
1433 ep = strchr( sp, '&');
1434 *ep = '\0';
1435 strcpy( scrypt, sp);
1436
1437 sp = ep+10;
1438 urldecode( sp, sname);
1439
1440 if(strlen(sname) > 0 && strcmp( ncrypt, scrypt) == 0){
1441 int num = whitenum( sstat);
1442 char buf[ 256 ];
1443 char filename[ 256 ];
1444 char filenamebak[ 256 ];
1445 sprintf( filename, "%s.rank", CGINAME);
1446 sprintf( filenamebak, "%s.rank.bak", CGINAME);
1447 unlink( filenamebak);
1448 rename( filename, filenamebak);
1449 FILE *fin = fopen( filenamebak, "rb");
1450 FILE *fout = fopen( filename, "wb");
1451 if(fin){
1452 while( fgets( buf, 256, fin ) ){
1453 char *cp = strchr( buf, ',');
1454 if(cp){
1455 *cp = '\0';
1456 if(atoi( buf) < num){
1457 fprintf( fout, "%d,%s\n", num, sname);
1458 num = 0;
1459 }
1460 fprintf( fout, "%s,%s", buf, cp+1);
1461 }
1462 }
1463
1464 fclose( fin);
1465 //rename( filenamebak, filename);
1466 fclose( fout);
1467 }
1468 }
1469
1470 }else{
1471 buf[0] = '\0';
1472 }
1473
1474 // 引数が得られなかった場合
1475 nextturn = (IS_P2P) ? ___B___:___W___;
1476 x = 0;
1477 y = 0;
1478 disp_head(0, NULL);
1479 strcpy( now_status, init );
1480 disp_point( 1, 0, 0, now_status, nextturn, 0.0f);
1481 strcpy( org_status, now_status);
1482 disp_now(
1483 nextturn,
1484 8, 8, now_status, 1, 0, 0, org_status
1485 );
1486 disp_tail(nextturn, user);
1487 exit( 0);
1488 }
1489
1490
1491 // 引数を取得する
1492 {
1493 static char buf[ 1024 ];
1494 char *ep;
1495 while(*cp != '=') cp++;
1496 nextturn = *(++cp);
1497 while(*cp != '=') cp++;
1498 ep = strchr( cp, (int)'&');
1499 *ep = '\0';
1500 x = atoi( ++cp);
1501
1502 while(*cp != '=') cp++;
1503 ep = strchr( cp, (int)'&');
1504 *ep = '\0';
1505 y = atoi( ++cp);
1506
1507 while(*cp != '=') cp++;
1508
1509 ++cp;
1510 if(*cp == ___N___ || *cp == ___B___ || *cp == ___W___)
1511 strcpy( now_status, cp);
1512 else
1513 urlcur2cur( now_status, cp);
1514
1515 ep = strchr( now_status, (int)'&');
1516 if( ep){
1517 *ep = '\0';
1518 while(*ep != '=') ep++;
1519 _ADURL = strcpy(buf, ++ep);
1520 }else{
1521 _ADURL = NULL;
1522 }
1523 }
1524
1525 strcpy( org_status, now_status);
1526
1527 while( isloop){
1528 int maxi, maxj;
1529
1530 switch( nextturn){
1531 case ___w___: // ___w___(置くのみ(波及せず))
1532 if(smode == 1){
1533 nextturn = toupper(nextturn);
1534 }else{
省略
1557 }
1558 break;
1559 case ___b___: // ___b___(推論して置くのみ(波及せず)) 前フェーズで置けることをチェックして、このフェーズに入るようにする
1560 if(smode == 1){
1561 if(IS_P2P){
1562 nextturn = ___B___;
1563 }else{
1564 recursive_all_pos_check(___B___, &maxi, &maxj, now_status, MAX_LOOP);
1565 x = maxi;
1566 y = maxj;
1567 nextturn = ___B___;
1568 }
1569 }else{
省略
1594 }
1595 break;
1596 case ___W___:
1597 {
1598 int isblue = IS_P2P;
1599 pos_check( 1, ___W___, 8, 8, x, y, now_status);
1600 if(all_pos_check(___B___, &maxi, &maxj, now_status) > 0){
1601 //白完(w要求)
1602 nextturn = ___B___;
1603 if(IS_P2P)
1604 disp_head(0, "");
1605 else{
1606 sprintf( autonext,
1607 "?t=%c&x=%d&y=%d&s=%s",
1608 (IS_P2P) ? ___B___:___b___,
1609 0,
1610 0,
1611 //now_status
1612 cur2urlcur( url_status, now_status)
1613 );
1614 disp_head(1, autonext);
1615 }
1616 disp_point( 0, x, y, now_status, ___B___, 0.0f);
1617 }else{
1618 if(all_pos_check(___W___, &maxi, &maxj, now_status) > 0){
1619 //青完
1620 disp_head(0, "");
1621 isblue = 1;
1622 disp_point( 0, x, y, now_status, ___W___, 0.0f);
1623 }else{
1624 //相手も自分もおけなかったとき
1625 nextturn = ___N___;
1626 disp_head(0, "");
1627 disp_point( 0, x, y, now_status, ___N___, 0.0f);
1628 }
1629 }
1630 disp_now(
1631 nextturn,
1632 8, 8, now_status, isblue, x, y, org_status
1633 );
1634 disp_tail(nextturn, NULL);
1635 isloop = 0;
1636 }
1637 break;
1638 case ___B___:
1639 if(IS_P2P){
1640 int isblue = 1;
1641 pos_check( 1, ___B___, 8, 8, x, y, now_status);
1642 if(all_pos_check(___W___, &maxi, &maxj, now_status) > 0){
1643 //白完(w要求)
1644 nextturn = ___W___;
1645 disp_head(0, "");
1646 disp_point( 0, x, y, now_status, ___W___, 0.0f);
1647 }else{
1648 if(all_pos_check(___B___, &maxi, &maxj, now_status) > 0){
1649 //青完
1650 disp_head(0, "");
1651 isblue = 1;
1652 disp_point( 0, x, y, now_status, ___B___, 0.0f);
1653 }else{
1654 //相手も自分もおけなかったとき
1655 nextturn = ___N___;
1656 disp_head(0, "");
1657 disp_point( 0, x, y, now_status, ___N___, 0.0f);
1658 }
1659 }
1660 disp_now(
1661 nextturn,
1662 8, 8, now_status, isblue, x, y, org_status
1663 );
1664 disp_tail(nextturn, NULL);
1665 isloop = 0;
1666 }else{
1667 int isblue = 1;
1668
1669 //now_status[ (y-1)*8+(x-1) ] = ___N___;
1670 pos_check( 1, ___B___, 8, 8, x, y, now_status);
1671 if(all_pos_check(___W___, &maxi, &maxj, now_status) > 0){
1672 //青完
1673 disp_head(0, "");
1674 nextturn = ___W___;
1675 end = clock();
1676 disp_point( 0, x, y, now_status, nextturn, ((double)(end-start)/CLOCKS_PER_SEC));
1677 }else{
1678 if(all_pos_check(___B___, &maxi, &maxj, now_status) > 0){
1679 //黒完(w要求)
1680 sprintf( autonext,
1681 "?t=%c&x=%d&y=%d&s=%s",
1682 ___b___,
1683 0,
1684 0,
1685 //now_status
1686 cur2urlcur( url_status, now_status)
1687 );
1688 isblue = 0;
1689 disp_head(1, autonext);
1690 end = clock();
1691 disp_point( 0, x, y, now_status, nextturn, ((double)(end-start)/CLOCKS_PER_SEC));
1692 }else{
1693 //相手も自分もおけなかったとき
1694 nextturn = ___N___;
1695 disp_head(0, "");
1696 end = clock();
1697 disp_point( 0, x, y, now_status, nextturn, ((double)(end-start)/CLOCKS_PER_SEC));
1698 }
1699 }
1700 disp_now(
1701 nextturn,
1702 8, 8, now_status, isblue, x, y, org_status
1703 );
1704
1705 disp_tail(nextturn, NULL);
1706 isloop = 0;
1707 }
1708 break;
1709 case ___N___:
1710 {
1711 disp_head(0, "");
1712 disp_point( 0, x, y, now_status, nextturn, 0.0f);
1713 disp_now(
1714 nextturn,
1715 8, 8, now_status, 0, x, y, org_status
1716 );
1717 disp_tail(nextturn, NULL);
1718 isloop = 0;
1719 }
1720 break;
1721 }
1722 }
1723 }
<参考資料A1(1)>
//以下、盤(=面、ラウンド、モチーフ)ごとのプログラム(biwako.c)
char board[]=
// JP-biwako1
"+---------------+"
"|CCCC |"
"|CCCC |"
"| |"
"| CCCCC |"
"| CCCCC |"
"| CCCCC |"
"| CCCCC |"
"| CCCCCCC |"
"| CCCCC |"
"| CCCCC |"
"| CCC |"
"| CCC |"
"| |"
"| |"
"| |"
"+---------------+"
;
char init[]=
// JP-biwako1
"NNNNNNNN"
"NNNNNNNN"
"NNWRNNNN"
"NNRWNNNN"
"NNNNNNNN"
"NNNNRWNN"
"NNNNWRNN"
"NNNNNNNN"
;
<参考資料A1(2)>
//以下メインプログラム( ws.c)
char CGINAME[ 1024 ];
extern char init[];
extern char board[];
#define IS_STACK_EST (0)
#define COLOR_GREEN "#33ff33"
#define MUGENM (-65535)
#define MUGENP (+65535)
#define GAME_SIZE_X (8)
#define GAME_SIZE_Y (8)
#define BOARD_SIZE_X (GAME_SIZE_X+GAME_SIZE_X+1)
#define BOARD_SIZE_Y (GAME_SIZE_Y+GAME_SIZE_Y+1)
//#define IMG "http://wallstreets.ws/icons/PIC_0041.JPG";
#define PIMGM "http://wallstreets.ws/icons/PIC_0043M.JPG";
#define PIMG "http://wallstreets.ws/icons/PIC_0043.JPG";
//char board[ 21*21 ] = {
/*
int valpr[ 9 ][ 9 ] = { 0 };
int valxy[ 9 ][ 9 ] = { 0 };
int dirnm[ 9 ][ 9 ] = { 0 };
char blockget( int sizex, int sizey, int x, int y, char *b)
{
return *(b + y*sizex + x);
}
int valdir( int basex, int basey, int dirx, int diry, char *b)
{
int point = 0;
int sizex = 8;
int sizey = 8;
while( blockget( sizex*2+1, sizey*2+1, (basex-1)*2+1-dirx, (basey-1)*2+1-diry, b) == ' '){
point++;
basex -= dirx;
basey -= diry;
}
return point;
}
int valdirxy( int basex, int basey, int dirx, int diry, char *b)
{
int point = 0;
int sizex = 8;
int sizey = 8;
while( blockget( sizex*2+1, sizey*2+1, (basex-1)*2+1-dirx, (basey-1)*2+1-diry, b) == ' '){
point += valpr[ basex ][ basey ];
basex -= dirx;
basey -= diry;
}
return point;
}
int valdirnb( int basex, int basey, int dirx, int diry, char *b)
{
return -valpr[ basex+dirx ][ basey+diry ]/dirnm[ basex+dirx ][ basey+diry ];
}
void value_init( char *b)
{
int sizex = 8;
int sizey = 8;
int cx, cy;
for( cx = 1; cx <= 8; cx++)
for( cy = 1; cy <= 8; cy++)
dirnm[ cx ][ cy ] =
((blockget( sizex*2+1, sizey*2+1, (cx-1)*2, (cy-1)*2, b) == ' ') ?
1:0)
+((blockget( sizex*2+1, sizey*2+1, (cx-1)*2, (cy-1)*2+1, b) == ' ') ?
1:0)
+((blockget( sizex*2+1, sizey*2+1, (cx-1)*2, (cy-1)*2+2, b) == ' ') ?
1:0)
+((blockget( sizex*2+1, sizey*2+1, (cx-1)*2+1, (cy-1)*2, b) == ' ') ?
1:0)
+((blockget( sizex*2+1, sizey*2+1, (cx-1)*2+1, (cy-1)*2+2, b) == ' ') ?
1:0)
+((blockget( sizex*2+1, sizey*2+1, (cx-1)*2+2, (cy-1)*2, b) == ' ') ?
1:0)
+((blockget( sizex*2+1, sizey*2+1, (cx-1)*2+2, (cy-1)*2+1, b) == ' ') ?
1:0)
+((blockget( sizex*2+1, sizey*2+1, (cx-1)*2+2, (cy-1)*2+2, b) == ' ') ?
1:0);
for( cx = 1; cx <= 8; cx++)
for( cy = 1; cy <= 8; cy++){
valpr[ cx ][ cy ] =
((blockget( sizex*2+1, sizey*2+1, (cx-1)*2, (cy-1)*2, b) == ' ') ?
0:valdir(cx,cy,-1,-1, b))
+((blockget( sizex*2+1, sizey*2+1, (cx-1)*2, (cy-1)*2+1, b) == ' ') ?
0:valdir(cx,cy,-1, 0, b))
+((blockget( sizex*2+1, sizey*2+1, (cx-1)*2, (cy-1)*2+2, b) == ' ') ?
0:valdir(cx,cy,-1,+1, b))
+((blockget( sizex*2+1, sizey*2+1, (cx-1)*2+1, (cy-1)*2, b) == ' ') ?
0:valdir(cx,cy, 0,-1, b))
+((blockget( sizex*2+1, sizey*2+1, (cx-1)*2+1, (cy-1)*2+2, b) == ' ') ?
0:valdir(cx,cy, 0,+1, b))
+((blockget( sizex*2+1, sizey*2+1, (cx-1)*2+2, (cy-1)*2, b) == ' ') ?
0:valdir(cx,cy,+1,-1, b))
+((blockget( sizex*2+1, sizey*2+1, (cx-1)*2+2, (cy-1)*2+1, b) == ' ') ?
0:valdir(cx,cy,+1, 0, b))
+((blockget( sizex*2+1, sizey*2+1, (cx-1)*2+2, (cy-1)*2+2, b) == ' ') ?
0:valdir(cx,cy,+1,+1, b))
;
}
for( cx = 1; cx <= 8; cx++)
for( cy = 1; cy <= 8; cy++){
valxy[ cx ][ cy ] = valpr[ cx ][ cy ]
+((blockget( sizex*2+1, sizey*2+1, (cx-1)*2, (cy-1)*2, b) == ' ') ?
0:valdirxy(cx,cy,-1,-1, b))
+((blockget( sizex*2+1, sizey*2+1, (cx-1)*2, (cy-1)*2+1, b) == ' ') ?
0:valdirxy(cx,cy,-1, 0, b))
+((blockget( sizex*2+1, sizey*2+1, (cx-1)*2, (cy-1)*2+2, b) == ' ') ?
0:valdirxy(cx,cy,-1,+1, b))
+((blockget( sizex*2+1, sizey*2+1, (cx-1)*2+1, (cy-1)*2, b) == ' ') ?
0:valdirxy(cx,cy, 0,-1, b))
+((blockget( sizex*2+1, sizey*2+1, (cx-1)*2+1, (cy-1)*2+2, b) == ' ') ?
0:valdirxy(cx,cy, 0,+1, b))
+((blockget( sizex*2+1, sizey*2+1, (cx-1)*2+2, (cy-1)*2, b) == ' ') ?
0:valdirxy(cx,cy,+1,-1, b))
+((blockget( sizex*2+1, sizey*2+1, (cx-1)*2+2, (cy-1)*2+1, b) == ' ') ?
0:valdirxy(cx,cy,+1, 0, b))
+((blockget( sizex*2+1, sizey*2+1, (cx-1)*2+2, (cy-1)*2+2, b) == ' ') ?
0:valdirxy(cx,cy,+1,+1, b))
;
}
for( cx = 1; cx <= 8; cx++)
for( cy = 1; cy <= 8; cy++)
valpr[ cx ][ cy ] = valxy[ cx ][ cy ];
{
int min = 65535;
for( cx = 1; cx <= 8; cx++)
for( cy = 1; cy <= 8; cy++){
valxy[ cx ][ cy ] = valpr[ cx ][ cy ]
+((blockget( sizex*2+1, sizey*2+1, (cx-1)*2, (cy-1)*2, b) != ' ') ?
0:valdirnb(cx,cy,-1,-1, b))
+((blockget( sizex*2+1, sizey*2+1, (cx-1)*2, (cy-1)*2+1, b) != ' ') ?
0:valdirnb(cx,cy,-1, 0, b))
+((blockget( sizex*2+1, sizey*2+1, (cx-1)*2, (cy-1)*2+2, b) != ' ') ?
0:valdirnb(cx,cy,-1,+1, b))
+((blockget( sizex*2+1, sizey*2+1, (cx-1)*2+1, (cy-1)*2, b) != ' ') ?
0:valdirnb(cx,cy, 0,-1, b))
+((blockget( sizex*2+1, sizey*2+1, (cx-1)*2+1, (cy-1)*2+2, b) != ' ') ?
0:valdirnb(cx,cy, 0,+1, b))
+((blockget( sizex*2+1, sizey*2+1, (cx-1)*2+2, (cy-1)*2, b) != ' ') ?
0:valdirnb(cx,cy,+1,-1, b))
+((blockget( sizex*2+1, sizey*2+1, (cx-1)*2+2, (cy-1)*2+1, b) != ' ') ?
0:valdirnb(cx,cy,+1, 0, b))
+((blockget( sizex*2+1, sizey*2+1, (cx-1)*2+2, (cy-1)*2+2, b) != ' ') ?
0:valdirnb(cx,cy,+1,+1, b))
;
if(min > valxy[ cx ][ cy ])
min = valxy[ cx ][ cy ];
}
if(0 && min < 1){
for( cx = 1; cx <= 8; cx++)
for( cy = 1; cy <= 8; cy++){
valxy[ cx ][ cy ] += (-min+1);
}
}
}
}
void set( char c, int sizex, int sizey, int x, int y, char *s)
{
*(s + (y-1)*sizex + (x-1)) = c;
}
char get( int sizex, int sizey, int x, int y, char *s)
{
return *(s + (y-1)*sizex + (x-1));
}
int pos_check(
int is_turn,
char turn,
int sizex,
int sizey,
int x,
int y,
char *s
)
{
int cx, cy;
int exist_count = 0;
char tonari = (turn == 'W') ? 'R':'W';
int tonari_count;
int tonari_count_val;
//左
for( tonari_count = 0, cx = x-1, cy = y; ; cx--){
if(cx == 0 ||
blockget( sizex*2+1, sizey*2+1, cx*2, (cy-1)*2+1, board) != ' '){
tonari_count = 0;
tonari_count_val = 0;
break;
}else{
char nc = get( sizex, sizey, cx, cy, s);
if(nc == tonari){
tonari_count++;
tonari_count_val+=valxy[ cx ][ cy ];
}else if(nc == turn && tonari_count > 0){
//exist_count += tonari_count_val;
exist_count += tonari_count;
break;
}else{
tonari_count = 0;
tonari_count_val = 0;
break;
}
}
}
if(is_turn && tonari_count){
for( cx = x-1, cy = y; tonari_count-- > 0; cx--){
set( turn, sizex, sizey, cx, cy, s);
}
}
//右
for( tonari_count = 0, cx = x+1, cy = y; ; cx++){
if(cx > sizex ||
blockget( sizex*2+1, sizey*2+1, (cx-1)*2, (cy-1)*2+1, board) != ' '){
tonari_count = 0;
tonari_count_val = 0;
break;
}else{
char nc = get( sizex, sizey, cx, cy, s);
if(nc == tonari){
tonari_count++;
tonari_count_val+=valxy[ cx ][ cy ];
}else if(nc == turn && tonari_count > 0){
//exist_count += tonari_count_val;
exist_count += tonari_count;
break;
}else{
tonari_count = 0;
tonari_count_val = 0;
break;
}
}
}
if(is_turn && tonari_count){
for( cx = x+1, cy = y; tonari_count-- > 0; cx++){
set( turn, sizex, sizey, cx, cy, s);
}
}
//上
for( tonari_count = 0, cx = x, cy = y-1; ; cy--){
if(cy == 0 ||
blockget( sizex*2+1, sizey*2+1, (cx-1)*2+1, cy*2, board) != ' '){
tonari_count = 0;
tonari_count_val = 0;
break;
}else{
char nc = get( sizex, sizey, cx, cy, s);
if(nc == tonari){
tonari_count++;
tonari_count_val+=valxy[ cx ][ cy ];
}else if(nc == turn && tonari_count > 0){
//exist_count += tonari_count_val;
exist_count += tonari_count;
break;
}else{
tonari_count = 0;
tonari_count_val = 0;
break;
}
}
}
if(is_turn && tonari_count){
for( cx = x, cy = y-1; tonari_count--; cy--){
set( turn, sizex, sizey, cx, cy, s);
}
}
//下
for( tonari_count = 0, cx = x, cy = y+1; ; cy++){
if(cy > sizey ||
blockget( sizex*2+1, sizey*2+1, (cx-1)*2+1, (cy-1)*2, board) != ' '){
tonari_count = 0;
tonari_count_val = 0;
break;
}else{
char nc = get( sizex, sizey, cx, cy, s);
if(nc == tonari){
tonari_count++;
tonari_count_val+=valxy[ cx ][ cy ];
}else if(nc == turn && tonari_count > 0){
//exist_count += tonari_count_val;
exist_count += tonari_count;
break;
}else{
tonari_count = 0;
tonari_count_val = 0;
break;
}
}
}
if(is_turn && tonari_count){
for( cx = x, cy = y+1; tonari_count--; cy++){
set( turn, sizex, sizey, cx, cy, s);
}
}
//左上
for( tonari_count = 0, cx = x-1, cy = y-1; ; cx--, cy--){
if(cx == 0 || cy == 0 ||
blockget( sizex*2+1, sizey*2+1, cx*2, cy*2, board) != ' '){
tonari_count = 0;
tonari_count_val = 0;
break;
}else{
char nc = get( sizex, sizey, cx, cy, s);
if(nc == tonari){
tonari_count++;
tonari_count_val+=valxy[ cx ][ cy ];
}else if(nc == turn && tonari_count > 0){
//exist_count += tonari_count_val;
exist_count += tonari_count;
break;
}else{
tonari_count = 0;
tonari_count_val = 0;
break;
}
}
}
if(is_turn && tonari_count){
for( cx = x-1, cy = y-1; tonari_count--; cx--, cy--){
set( turn, sizex, sizey, cx, cy, s);
}
}
//左下
for( tonari_count = 0, cx = x-1, cy = y+1; ; cx--, cy++){
if(cx == 0 || cy > sizey||
blockget( sizex*2+1, sizey*2+1, cx*2, (cy-1)*2, board) != ' '){
tonari_count = 0;
tonari_count_val = 0;
break;
}else{
char nc = get( sizex, sizey, cx, cy, s);
if(nc == tonari){
tonari_count++;
tonari_count_val+=valxy[ cx ][ cy ];
}else if(nc == turn && tonari_count > 0){
//exist_count += tonari_count_val;
exist_count += tonari_count;
break;
}else{
tonari_count = 0;
tonari_count_val = 0;
break;
}
}
}
if(is_turn && tonari_count){
for( cx = x-1, cy = y+1; tonari_count--; cx--, cy++){
set( turn, sizex, sizey, cx, cy, s);
}
}
//右上
for( tonari_count = 0, cx = x+1, cy = y-1; ; cx++, cy--){
if(cx > sizex || cy == 0 ||
blockget( sizex*2+1, sizey*2+1, (cx-1)*2, cy*2, board) != ' '){
tonari_count = 0;
tonari_count_val = 0;
break;
}else{
char nc = get( sizex, sizey, cx, cy, s);
if(nc == tonari){
tonari_count++;
tonari_count_val+=valxy[ cx ][ cy ];
}else if(nc == turn && tonari_count > 0){
//exist_count += tonari_count_val;
exist_count += tonari_count;
break;
}else{
tonari_count = 0;
tonari_count_val = 0;
break;
}
}
}
if(is_turn && tonari_count){
for( cx = x+1, cy = y-1; tonari_count--; cx++, cy--){
set( turn, sizex, sizey, cx, cy, s);
}
}
//右下
for( tonari_count = 0, cx = x+1, cy = y+1; ; cx++, cy++){
if(cx > sizex || cy > sizey ||
blockget( sizex*2+1, sizey*2+1, (cx-1)*2, (cy-1)*2, board) != ' '){
tonari_count = 0;
tonari_count_val = 0;
break;
}else{
char nc = get( sizex, sizey, cx, cy, s);
if(nc == tonari){
tonari_count++;
tonari_count_val+=valxy[ cx ][ cy ];
}else if(nc == turn && tonari_count > 0){
//exist_count += tonari_count_val;
exist_count += tonari_count;
break;
}else{
tonari_count = 0;
tonari_count_val = 0;
break;
}
}
}
if(is_turn && tonari_count){
for( cx = x+1, cy = y+1; tonari_count--; cx++, cy++){
set( turn, sizex, sizey, cx, cy, s);
}
}
if(is_turn && exist_count)
set( turn, sizex, sizey, x, y, s);
return exist_count;
}
int disp_now( char nextturn, int xsize, int ysize, char *status, int isblue, int bx, int by, char *orgstatus)
{
}
int i[ 64+1 ],j[ 64+1 ];
int max[ 64+1 ];
char status[ 64+1 ][ 64+1 ];
char turn[ 64+1 ];
int check[ 64+1 ];
char now_status[ 1024 ];
void disp_head(int i, char *s)
{
}
int whitenum( char *status)
{
int ret = 0;
while( *status){
if(*status == 'R')
ret++;
status++;
}
return ret;
}
char *mycrypt( char *msg)
{
static char ret[ 64+1 ];
return ret;
}
void disp_tail(char nextturn, char *msg)
{
}
int all_pos_check( char nextturn, int *maxi, int *maxj, char *now_status)
{
int i,j;
int max = 0;
*maxi = 0;
*maxj = 0;
for( i = 1; i <= 8; i++){
for( j = 1; j <=8; j++){
if(get( 8, 8, i, j, now_status) == 'N'){
int now = pos_check( 0, nextturn, 8, 8, i, j, now_status);
if(now > max){
*maxi = i;
*maxj = j;
max = now;
}
}
}
}
return max;
}
void p( char *str)
{
printf( "%s\n", str);
}
//int all_1_all_nM1_max_min_max; //最終決定値
//int now_1_all_nM1_max_min; //一手目ごとに 65535に初期化される
//int now_1_now_nM1_max; //N-1手目ごとに -65535に初期化される
int minmax[ 64+1 ];
//minmax[ 0 ] max_sp = 3 にとっての all_1_all_nM1_max_min_max; //最終決定値に対応
//minmax[ 1 ] max_sp = 3 にとっての now_1_all_nM1_max_min; //一手目ごとに 65535に初期化される
//minmax[ 2 ] max_sp = 3 にとっての now_1_now_nM1_max; //N-1手目ごとに -65535に初期化される
//minmax[ 3 ] max_sp = 3 にとっての sum //
int max_sp;
int now_max_loop;
#ifdef DEBUG
void disp_stack( int x, int y, char *msg)
{
int n;
printf( "<TR>\n");
for( n = 1; n <= max_sp /*&& max[ n ]*/; n++){
printf( "<TD valign=up>\n");
printf( "chk[ %d ] : %d / (%d,%d) = %d-%d<BR>\n", n, check[ n ], i[ n ], j[ n ], x, y);
//printf( "status[ %d ] = <BR>\n", i);
{
int m;
for(m = 0; m < 64; m++){
switch( status[ n ][ m ]){
case 'N': printf("×");break;
case 'W': printf("白丸");break;
case 'R':printf("黒丸");break;
}
if(m % 8 == 7)
printf("<BR>\n");
}
}
printf("turn = %c<BR>\n", turn[ n ]);
/*
printf("all_1_all_nM1_max_min_max %d<BR>\n", all_1_all_nM1_max_min_max); //最終決定値
printf("now_1_all_nM1_max_min %d<BR>\n", now_1_all_nM1_max_min); //一手目ごとに 65535に初期化される
printf("now_1_now_nM1_max %d<BR>\n", now_1_now_nM1_max); //N-1手目ごとに -65535に初期化される
*/
{
int m;
for(m = 0; m <= max_sp; m++)
printf( "%d ", minmax[ m ]);
printf( "<BR>\n");
}
if(msg){
printf( "%d : %s<BR>\n", now_max_loop, msg);
}
printf( "</TD>\n");
}
printf( "</TR>\n");
}
#else
void disp_stack( int x, int y, char *msg)
{
;
}
#endif
/*---------------------------------------------------------------------------------
関数名 recursive_all_pos_check
機能 最も有望な手を返す
引数 nextturn 有望な手を探索する側('W'/'R')
*maxi 有望な手のX座標
*maxj 有望な手のY座標
now_status 探索の対象となるゲーム状態
max_loop 最大の探索ループ数
---------------------------------------------------------------------------------*/
int recursive_all_pos_check(
char nextturn,
int *maxi,
int *maxj,
char *now_status,
unsigned long max_loop
)
{
const int level = LEVEL;
int first_get = 0;
int m,n;
*maxi = *maxj = 0;
//all_1_all_nM1_max_min_max = -65535; //最終決定値
minmax[ 0 ] = MUGENM;
// スタックの初期化
max_sp = 0;
turn[ 0 ] = 'N';
strcpy( status[ 0 ], now_status);
i[ 0 ] = j[ 0 ] = 0;
max[ 0 ] = 0;
#ifdef DEBUG
printf( "<TABLE border bgcolor=white>\n");
#endif
// 次の一手
++max_sp;
turn[ max_sp ] = nextturn;
i[ max_sp ] = j[ max_sp ] = 1;
max[ max_sp ] = 0;
do{
if(--max_loop == 0){
disp_stack( *maxi, *maxj, "LOOPOVER");
break;
}
now_max_loop = max_loop;
if( max_sp % 2 == 1 && max_sp < level){
// 1 or 3 のとき
minmax[ max_sp ] = MUGENP;
}
if( max_sp % 2 == 0 && max_sp < level){
// 2 or 4 のとき(0はありえないから)
minmax[ max_sp ] = MUGENM;
}
strcpy( status[ max_sp ], status[ max_sp-1 ]);
if( get( 8, 8, i[ max_sp ], j[ max_sp ], status[ max_sp ]) == 'N'
&& (check[ max_sp ]
= pos_check( 1, turn[ max_sp ], 8, 8, i[ max_sp ], j[ max_sp ], status[ max_sp ])) > 0){
// 注目した座標(i[max_sp],j[max_sp])に石がなくかつとれるので置ける場合
// 現在のmax_sp-1のゲーム状態に対して先の手max_spが存在することをマークする
max[ max_sp ] = check[ max_sp ];
if(max_sp < level){
// まだ先を読む必要がある場合,
//disp_stack( *maxi, *maxj, "THINKING");
// 置いてみた後のstatus[ max_sp ]をスタックにつむ
++max_sp;
turn[ max_sp ] = (turn[ max_sp-1 ] == 'W') ? 'R':'W';
i[ max_sp ] = j[ max_sp ] = 1;
max[ max_sp ] = 0;
}else{
// 最深読みレベルに達していた場合
// 最深読みレベルの評価を計算する
int sum = 0;
int k;
if(IS_STACK_EST)
{
for( k = 1; k <= max_sp; k++)
sum +=
(turn[ k ] == nextturn) ?
+(check[ k ]+valxy[i[ k ]][j[ k ]]) : -(check[ k ]+valxy[i[ k ]][j[ k ]]);
//+(check[ k ]) : -(check[ k ]);
}else{
int x,y;
int sumw = 0;
int sumb = 0;
for( x = 1; x <= 8; x++){
for( y = 1; y <= 8; y++){
switch(get( 8, 8, x, y, status[ max_sp ])){
case 'N': break;
case 'W': sumw += valxy[ x ][ y ]; break;
case 'R': sumb += valxy[ x ][ y ]; break;
}
}
}
sum = (nextturn == 'W') ? (sumw-sumb):(sumb-sumw);
}
if(/* 最深レベルは奇数故 max_sp % 2 = 1 のチェックはいらない */
sum > minmax[ max_sp-1 ]){
minmax[ max_sp-1 ] = sum;
//disp_stack( *maxi, *maxj, "sum > minmax[ max_sp-1 ]");
}
//disp_stack( *maxi, *maxj);
// 次の候補にポインタを移す
while( j[ max_sp ] == 8 && i[ max_sp ] == 8 && max_sp > 0){
max_sp --;
if(max_sp % 2 == 0 && max_sp < level){
if(minmax[ max_sp ] < minmax[ max_sp-1 ]){
minmax[ max_sp-1 ] = minmax[ max_sp ];
disp_stack( *maxi, *maxj, "minmax[ max_sp ] < minmax[ max_sp-1 ]");
}
}
if(max_sp % 2 == 1 && max_sp < level){
if(minmax[ max_sp-1 ] < minmax[ max_sp ]){
minmax[ max_sp-1 ] = minmax[ max_sp ];
disp_stack( *maxi, *maxj, "minmax[ max_sp-1 ] < minmax[ max_sp ]");
if( max_sp == 1){
*maxi = i[ 1 ];
*maxj = j[ 1 ];
first_get = check[ 1 ];
}
}
}
if(max_sp == 1)
disp_stack( *maxi, *maxj, "CANDIDATE");
}
if(max_sp > 0){
if(j[ max_sp ] < 8){
j[ max_sp ]++;
}else if(i[ max_sp ] < 8){
i[ max_sp ]++;
j[ max_sp ] = 1;
}
}
}
}else{
// 注目した座標(i[max_sp],j[max_sp])に既に石があるか,なくても置けないときの処理
if(j[ max_sp ] < 8){
j[ max_sp ]++;
}else if(i[ max_sp ] < 8){
i[ max_sp ]++;
j[ max_sp ] = 1;
}else{
//その手をすべて探索したとき
disp_stack( *maxi, *maxj, "all searched");
if(max[ max_sp ] == 0){
//すべて探索した結果としておけなかったとき
char revturn = (turn[ max_sp ] == 'W') ? 'R':'W';
int m,n,rev_check = 0;
int nokori = 0, rev_nokori = 0;
disp_stack( *maxi, *maxj, "max[ max_sp ] == 0");
// 番を相手にわたせるかどうか計算
for(m = 1; m <= 8; m++)
for(n = 1; n <= 8; n++){
char c = get( 8, 8, m, n, status[ max_sp ]);
if(c == 'N')
rev_check += pos_check( 0, revturn, 8, 8, m, n, status[ max_sp ]);
else if(c == revturn)
rev_nokori ++;
else
nokori ++;
}
if(rev_check > 0 && max_sp < level){
// 相手の置く場所があり番をわたせるとき
// 自分のturnはスキップする
i[ max_sp ] = 8;
j[ max_sp ] = 8;
// turnを交替して探索しなおし
++max_sp;
turn[ max_sp ] = revturn;
i[ max_sp ] = 1;
j[ max_sp ] = 0;
max[ max_sp ] = 0;
disp_stack( *maxi, *maxj, "PASS");
}else{
// ゲームルール上,自分も相手もおける石がなかった場合
if( max_sp == 1){
// 1手目で自分も相手もなにもできないとき
disp_stack( *maxi, *maxj, "1 te PASSPASS GAMEOVER");
;//ゲームオーバー
}else{
disp_stack( *maxi, *maxj, "max_sp > 1");
// 2手先読みでこの状態に遭遇したとき
if(max_sp == 2 && rev_nokori > nokori){
// 2手先で両者とも何もできなくなりコールド勝ちになる場合
*maxi = i[ 1 ];
*maxj = j[ 1 ];
//all_1_all_nM1_max_min_max = MUGENP;//この手に決めてしまう
minmax[ 0 ] = MUGENP;
first_get = check[ 1 ];
disp_stack( *maxi, *maxj, "COLD WIN");
}else{
// 2手先以上で両者とも何もできなくなり,負けか引き分けのとき
// 最深読みレベルの評価を計算する
int sum = 0;
int k;
if(IS_STACK_EST){
for( k = 1; k <= max_sp; k++)
sum +=
(turn[ k ] == nextturn) ?
+(check[ k ]+valxy[i[ k ]][j[ k ]]) : -(check[ k ]+valxy[i[ k ]][j[ k ]]);
//+(check[ k ]) : -(check[ k ]);
}else{
int x,y;
int sumw = 0;
int numw = 0;
int sumb = 0;
int numb = 0;
for( x = 1; x <= 8; x++){
for( y = 1; y <= 8; y++){
switch(get( 8, 8, x, y, status[ max_sp ])){
case 'N': break;
case 'W': numw++;sumw += valxy[ x ][ y ]; break;
case 'R': numb++;sumb += valxy[ x ][ y ]; break;
}
}
}
if(numw == 0){
sumw = MUGENM;
}
if(numb == 0){
sumb = MUGENM;
}
sum = (nextturn == 'W') ? (sumw-sumb):(sumb-sumw);
}
disp_stack( *maxi, *maxj, "LOSEorDRAW-BACKTRACK");
if(sum > minmax[ max_sp-1 ]){
// max_sp == 3 or 5 , max_sp-1 == 2 or 4を想定している
minmax[ max_sp-1 ] = sum;
disp_stack( *maxi, *maxj, "LOSEorDRAW-BACKTRACK sum > minmax[ max_sp-1 ]");
}
//負けか引き分けになりそうなときの処理終了
}
disp_stack( *maxi, *maxj, "NO GAME at 2 or more");
//2手先読み以上で遭遇した場合終了
}
disp_stack( *maxi, *maxj, "NO GAME at a context");
// ゲームルール上,自分も相手もおける石がなかった場合終了
}
disp_stack( *maxi, *maxj, "NO GAME");
// すべて探索した結果としておけなかったとき終了
}
//disp_stack( *maxi, *maxj, "NO TE");
// 次の候補にポインタを移す
while( j[ max_sp ] == 8 && i[ max_sp ] == 8 && max_sp > 0){
max_sp --;
if(max_sp % 2 == 0 && max_sp < level){
if(minmax[ max_sp ] < minmax[ max_sp-1 ]){
minmax[ max_sp-1 ] = minmax[ max_sp ];
disp_stack( *maxi, *maxj, "minmax[ max_sp ] < minmax[ max_sp-1 ]");
}
}
if(max_sp % 2 == 1 && max_sp < level){
if(minmax[ max_sp-1 ] < minmax[ max_sp ]){
minmax[ max_sp-1 ] = minmax[ max_sp ];
disp_stack( *maxi, *maxj, "minmax[ max_sp-1 ] < minmax[ max_sp ]");
if( max_sp == 1){
*maxi = i[ 1 ];
*maxj = j[ 1 ];
first_get = check[ 1 ];
}
}
}
}
//disp_stack( *maxi, *maxj, "BACKTRACK AFTER NO-TE");
if(max_sp > 0){
if(j[ max_sp ] < 8){
j[ max_sp ]++;
}else if(i[ max_sp ] < 8){
i[ max_sp ]++;
j[ max_sp ] = 1;
}
}
}
}
}while( max_sp > 0);
#ifdef DEBUG
printf( "</TABLE>\n");
#endif
return first_get;
}
int disp_point( int is_start, int x, int y, char *now_status, char nextturn, double t)
{
}
void countup( void)
{
/*
REMOTE_ADDR:スクリプトを提出してきたホストIPアドレス
QUERY_STRING:GETによう問い合わせにおける引数の方法URLで「?」の後ろにあるものすべて
REQUEST_METHOD:フォームの提出方法(POST or GET)
REFERER_URL:CGIを送るのに使われたページのURLクライアント変数の中身、
ユーザがサイトを訪れる直前にブラウザがいたロケーションURLを返す
CONTENT_TYPE:POSTによってフォームが提出されてくる場合
application/x-www-form-unlecodedという値になる
CONTENT_LENGTH:POST、GETによってフォームが提出される場合、標準出力から読み込む必要のあるバイト数
char buf[ 256 ];
char *user = getenv("REMOTE_ADDR");
int fd = open("/home/httpd/cgi-bin/ws/wscount.dat", "at");
int count = 10;
while( flock( fd, LOCK_EX)){
if(--count = 0)
exit(1);
sleep( 100);
}
fprintf( fp, "%s\n", usr);
flock( fd, LOCK_UN);
close( fd);
//system( buf);
*/
FILE *fp;
int fd;
int count = 0;
char buf[256];
bzero(buf, 256);
// ファイルを開く
fd = open("/home/httpd/cgi-bin/ws/counter.dat", O_RDWR | O_CREAT );
// 排他ロック
flock(fd, LOCK_EX );
// 読み込み
lseek(fd, 0, SEEK_SET);
read(fd, buf, 256);
// カウンタを足す
count = atoi(buf);
count++;
sprintf(buf, "%d", count);
// 書き込み
lseek(fd, 0, SEEK_SET);
write(fd, buf, 256);
fp = fopen("/home/httpd/cgi-bin/ws/log.dat", "at");
fprintf( fp, "%s:%s\n", buf, getenv("REMOTE_ADDR"));
fclose( fp);
// ロック開放
flock(fd, LOCK_UN );
close(fd);
}
const char codetbl[] = "0123456789ABCDEF";
int urldecode(char *in, char *out)
{
int cnt = 0;
int len;
char *str = in;
if (!in || (len = strlen(in)) == 0)
return -1;
memset( out, 0, len );
while( *str ) {
if (*str != '%') {
*(out + cnt++) = *str;
} else {
if ( *(str + 1) == 0 || *(str + 2) == 0) {
break;
}
*(out + cnt++) = 16 * (strchr(codetbl, *(str + 1)) - codetbl) \
+ (strchr(codetbl, *(str + 2)) - codetbl);
str = str + 2;
}
str++;
}
return(strlen(out));
}
int main( int argc, char *argv[])
{
int smode = 1;
int isloop = 1;
char org_status[ 1024 ];
clock_t start,end;
{
char *cp = strrchr( argv[ 0 ], '/');
strcpy(CGINAME, cp+1);
}
start = clock();
char autonext[ 1024 ] = {""};
char lastturn = 'N';
char nextturn = 'N';
int is_p2p = IS_P2P;
int x,y;
char cfgfilepath[ 1024 ];
char given_status[ 1024 ];
char *cp = getenv("QUERY_STRING"); cp = (cp) ? strcpy( given_status, cp) : NULL;
char *user = getenv("REMOTE_ADDR");
{
//char buf[ 256 ];
////sprintf( buf, "/home/httpd/cgi-bin/ws/wscount.pl %s", user);
//sprintf( buf, "/home/httpd/cgi-bin/ws/wscount.pl aaaaaaaaa");
//system( buf);
}
value_init( board);
//自分の色および場所を変数にいれる
if(cp == NULL || *cp == '\0' || *(cp+2)=='h'){
char buf[ 1024 ];
if(*(cp+2) =='h'){
char *sp;
char *ep;
int point = 0;
char sname[ 64 ];
char scrypt[ 64+1 ];
char ncrypt[ 64+1 ];
char sstat[ 64+1 ];
fgets( buf, 1024, stdin);
sp = buf+5;
ep = strchr( sp, '&');
*ep = '\0';
strcpy( sstat, sp);
strcpy( ncrypt, (const char *)mycrypt( sstat));
sp = ep+7;
ep = strchr( sp, '&');
*ep = '\0';
strcpy( scrypt, sp);
sp = ep+10;
urldecode( sp, sname);
//strcpy( sname, sp);
if(strlen(sname) > 0 && strcmp( ncrypt, scrypt) == 0){
int num = whitenum( sstat);
char buf[ 256 ];
char filename[ 256 ];
char filenamebak[ 256 ];
sprintf( filename, "%s.rank", CGINAME);
sprintf( filenamebak, "%s.rank.bak", CGINAME);
unlink( filenamebak);
rename( filename, filenamebak);
FILE *fin = fopen( filenamebak, "rb");
FILE *fout = fopen( filename, "wb");
if(fin){
while( fgets( buf, 256, fin ) ){
char *cp = strchr( buf, ',');
if(cp){
*cp = '\0';
if(atoi( buf) < num){
fprintf( fout, "%d,%s\n", num, sname);
num = 0;
}
fprintf( fout, "%s,%s", buf, cp+1);
}
}
fclose( fin);
//rename( filenamebak, filename);
fclose( fout);
}
}
//strcpy( buf, "test");
}else{
buf[0] = '\0';
}
// 引数が得られなかった場合
nextturn = 'R';
x = 0;
y = 0;
disp_head(0, NULL);
strcpy( now_status, init );
disp_point( 1, 0, 0, now_status, nextturn, 0.0f);
strcpy( org_status, now_status);
disp_now(
nextturn,
8, 8, now_status, 1, 0, 0, org_status
);
disp_tail(nextturn, user);
exit( 0);
}
// 引数を取得する
{
static char buf[ 1024 ];
char *ep;
/*
while(*cp != '=') cp++;
strcpy( cfgfilepath, ++cp);
set_cfg( cfgfilepath);
*/
while(*cp != '=') cp++;
nextturn = *(++cp);
while(*cp != '=') cp++;
ep = strchr( cp, (int)'&');
*ep = '\0';
x = atoi( ++cp);
while(*cp != '=') cp++;
ep = strchr( cp, (int)'&');
*ep = '\0';
y = atoi( ++cp);
while(*cp != '=') cp++;
strcpy( now_status, ++cp);
ep = strchr( now_status, (int)'&');
if( ep){
*ep = '\0';
while(*ep != '=') ep++;
_ADURL = strcpy(buf, ++ep);
}else{
_ADURL = NULL;
}
}
strcpy( org_status, now_status);
while( isloop){
int maxi, maxj;
switch( nextturn){
case 'r': // 'r'(置くのみ(波及せず))
if(smode == 1){
nextturn = toupper(nextturn);
}else{
char nextnextturn = toupper( nextturn); //Rを要求
sprintf( autonext,
"?t=%c&x=%d&y=%d&s=%s",
nextnextturn,
x,
y,
now_status
);
countup();
disp_head(0, autonext);//1秒後にジャンプ
//pos_check( 1, nextnextturn, 8, 8, x, y, now_status);
now_status[ (y-1)*8+(x-1) ] = 'R';
disp_point( 0, x, y, now_status, nextturn, 0.0f);
disp_now(
nextturn,
8, 8, now_status, 0, x, y, org_status
);
nextturn = nextnextturn;
disp_tail(nextturn, NULL);
exit( 0);
}
break;
case 'w': // 'w'(推論して置くのみ(波及せず)) 前フェーズで置けることをチェックして、このフェーズに入るようにする
if(smode == 1){
recursive_all_pos_check('W', &maxi, &maxj, now_status, MAX_LOOP);
x = maxi;
y = maxj;
nextturn = 'W';
}else{
char nextnextturn = toupper( nextturn);
recursive_all_pos_check('W', &maxi, &maxj, now_status, MAX_LOOP);
end = clock();
sprintf( autonext,
"?t=%c&x=%d&y=%d&s=%s",
'W',
maxi,
maxj,
now_status
);
disp_head(1, autonext);//1秒後にジャンプ
//pos_check( 1, nextnextturn, 8, 8, x, y, now_status);
now_status[ (maxj-1)*8+(maxi-1) ] = 'W';
disp_point( 0, maxi, maxj, now_status, nextturn, ((double)(end-start)/CLOCKS_PER_SEC));
disp_now(
nextturn,
8, 8, now_status, 0, maxi, maxj, org_status
);
nextturn = nextnextturn;
disp_tail(nextturn, NULL);
exit( 0);
isloop = 0;
}
break;
case 'R':
{
int isblue = 0;
pos_check( 1, 'R', 8, 8, x, y, now_status);
if(all_pos_check('W', &maxi, &maxj, now_status) > 0){
//白完(w要求)
sprintf( autonext,
"?t=%c&x=%d&y=%d&s=%s",
'w',
0,
0,
now_status
);
disp_head(1, autonext);
}else{
if(all_pos_check('R', &maxi, &maxj, now_status) > 0){
//青完
disp_head(0, "");
isblue = 1;
}else{
//相手も自分もおけなかったとき
nextturn = 'N';
disp_head(0, "");
}
}
disp_point( 0, x, y, now_status, nextturn, 0.0f);
disp_now(
nextturn,
8, 8, now_status, isblue, x, y, org_status
);
disp_tail(nextturn, NULL);
}
isloop = 0;
break;
case 'W':
{
int isblue = 1;
//now_status[ (y-1)*8+(x-1) ] = 'N';
pos_check( 1, 'W', 8, 8, x, y, now_status);
if(all_pos_check('R', &maxi, &maxj, now_status) > 0){
//青完
disp_head(0, "");
nextturn = 'R';
}else{
if(all_pos_check('W', &maxi, &maxj, now_status) > 0){
//黒完(w要求)
sprintf( autonext,
"?t=%c&x=%d&y=%d&s=%s",
'w',
0,
0,
now_status
);
isblue = 0;
disp_head(1, autonext);
}else{
//相手も自分もおけなかったとき
nextturn = 'N';
disp_head(0, "");
}
}
end = clock();
disp_point( 0, x, y, now_status, nextturn, ((double)(end-start)/CLOCKS_PER_SEC));
disp_now(
nextturn,
8, 8, now_status, isblue, x, y, org_status
);
disp_tail(nextturn, NULL);
}
isloop = 0;
break;
case 'N':
{
disp_head(0, "");
disp_point( 0, x, y, now_status, nextturn, 0.0f);
disp_now(
nextturn,
8, 8, now_status, 0, x, y, org_status
);
disp_tail(nextturn, NULL);
}
isloop = 0;
break;
}
}
}
<参考資料B1>
#
# index.cgi for Wallstreets top url
# Copyright(c) KeisukeNAKAMURA
# All rights reserved.
#
0001 #!/usr/bin/perl -w
0002
0003 print <<EOT;
0004 Content-type: text/html;charset=euc-jp;
0005
0006 <HTML>
0007 <HEAD>
0008 <TITLE>WALLSTREETS</TITLE>
0009
0010 </HEAD>
省略
0052 <TABLE BGCOLOR=#550000 style="width:410px;">
0053 <TR><TD><FONT color=silver>ここから選んでください↓(Please select board)</FONT></TD></TR>
0054 <TR><TD>
0055 EOT
0056
0057 my %ib_disp_head;
0058 my %ib_disp_tail;
0059
0060 open(FIN,"<ib_disp.txt");
0061 while($disp = <FIN>){
0062 chomp( $disp);
0063 ($key,$head,$tail) = split(/;/,$disp);
0064 $ib_disp_head{$key} = $head;
0065 $ib_disp_tail{$key} = $tail;
0066 }
0067 close(FIN);
0068
0069
0070 use DirHandle;
0071
0072 $count = 0;
0073 my %amount;
0074 my %entry;
0075 my %topplayer;
0076
0077 $dir = new DirHandle '.';
0078 while($data = $dir->read){
0079 if($data =~ /\.rank$/ and $data =~ /^ws5-JP/){
0080 open( FIN, "<$data") || last;
0081 undef %entry;
0082 for($i = 0; $i < 8; $i++){
0083 $e = <FIN>;
0084 #print "\t$e";
0085 chomp $e;
0086 ($a,$b) = split( /,/, $e);
0087 if($i == 0){
0088 $ter{$b} .= "$data;";
0089 $topplayer{$data}="$b<BR>$a";
0090 $a = $a * 10000;
0091 }
0092 if($i == 1){
0093 $a = $a * 1000;
0094 }
0095 if($i == 2){
0096 $a = $a * 100;
0097 }
0098 if($i == 3){
0099 $a = $a * 10;
0100 }
0101 if($a > 0 and $b ne "-" and !defined($entry{$b})){
0102 $entry{$b} = 1;
0103 $amount{"$b"} += $a;
0104 }
0105 }
0106 close(FIN);
0107 }
0108 }
0109 $dir->close;
0110
0111 $dir = new DirHandle '.';
0112 while($data = $dir->read){
0113 if($data =~ /\.cgi$/ and $data =~ /^ws5-JP/){
0114 ++$count;
0115 $wsp = $data;
0116 $wsp =~ s/ws5/wsp/;
0117 $pref = $data;
0118 $pref =~ s/ws5-JP-//;
0119 $pref =~ s/\.cgi$//;
0120 if(defined($ib_disp_head{$pref})){
0121 push @urllist,"$ib_disp_head{$pref}<A HREF=\"$data\"><FONT color=gold size=2>$pref</FONT>$ib_disp_tail{$pref}</A></TD><TD> <FONT color=silver size=1>$topplayer{$data.'.rank'}</FONT></TD><TD><A HREF=\"$wsp\"><FONT color=cyan size=2>隣人<BR>対戦</FONT></A>";
0122 }else{
0123 push @urllist,"<A HREF=\"$data\"><FONT color=gold>$pref </FONT></A>\n";
0124 }
0125 }
0126 }
0127 $dir->close;
0128 print "<TABLE bgcolor=#550000>";
0129 @s_urllist = sort @urllist;
0130 my $ci = 0;
0131 while( $ni = shift @s_urllist){
0132 $ci ++;
0133 if($ci % 2 == 0){
0134 print "<TR bgcolor=#553333><TD align=right>$ni</TD></TR>";
0135 }else{
0136 print "<TR bgcolor=#550000><TD align=right>$ni</TD></TR>";
0137 }
0138 }
0139
0140 print "</TABLE>";
0141 print "</TD></TR></TABLE><BR>";
0142
0143
0144 print "<TABLE style=\"width:410px;\" >\n";
0145 print "<TR><TD colspan=2 align=center><FONT color=silver size=3>スコア合計ランキング(HIGHSCORE AMOUNT RANKING)</FONT></TD></TR>\n";
0146
0147 while(($k,$v) = each %amount){
0148 $vf = sprintf("%8d 石", $v);
0149 if(defined($ter{$k})){
0150
0151
0152 $p = "<TR><TD align=right bgcolor=gold width=130><FONT size=5>$vf</FONT></TD><TD bgcolor=silver><font size=5>$k<BR></font>";
0153 @tops = sort split(/;/, $ter{$k});
0154 while( $aurl = shift @tops){
0155 $aurl =~ s/\.rank//;
0156 $burl = $aurl;
0157 $burl =~ s/\.cgi//;
0158 $burl =~ s/ws5-JP-//;
0159 $p .= "<a href=\"$aurl\"><FONT size=2>$burl</FONT></a>\n";
0160 }
0161 $p .= "<TD></TR>\n";
0162 push @rank, $p;
0163 }else{
0164 push @rank, "<TR><TD align=right bgcolor=gold width=130>$vf</TD><TD bgcolor=cyan><font size=3>$k</font><TD></TR>\n";
0165 }
0166 }
0167
0168 print sort {$b cmp $a} @rank;
0169
0170 print "</TABLE>\n";
0171
0172 print <<EOT;
0173
0174 <TABLE>
0175 <TR>
0176 <TD colspan=3 align=left>
0177 <FONT color=silver>Please contact to</FONT>
0178 </TD>
0179 </TR>
省略
0189 </TABLE>
0190
0191 <HR><FONT color=gold> Copyright(C) </font><A HREF="http://knowrel.com/"><FONT color=gold>KnowrelSystem,Inc.</FONT></A><FONT color=silver> Produced&Programmed by <A HREF="mailto:keisuke\@knowrel.com">KeisukeNAKAMURA</A></FONT>
0192 </CENTER>
0193 </BODY>
0194 </HTML>
0195 EOT
<参考資料B2>
#
# JP-wakayama1.c
#
# Copyright(c) KeisukeNAKAMURA
# All Rights Reserved.
#
char init[]=
"NNNNNNNN"
"NNNNNNNN"
"NNNNNNNN"
"NNNBWNNN"
"NNNWBNNN"
"NNNNNNNB"
"NNNNNNNN"
"NNNNNNNN";
char board[21*21]=
"CG---+-GGGGGGG--+"
"C + + + |"
"C + G |"
"C + |"
"CC + |"
"C + |"
"C + |"
"C + |"
"C C |"
"C + |"
"CCC C +++++|"
"CCC + |"
"CCCCC +|"
"CCCCC G"
"CCCCCCC C CCC"
"CCCCCCC CCC"
"CCCCCCCCCCCCCCCCC";
<参考資料B3>
#
# wseuc_num8an.c
#
# Copyright(c) KeisukeNAKAMURA
# All rights reserved.
#
0001 #include <stdio.h>
0002 #include <stdlib.h>
0003 #include <string.h>
0004 #include <ctype.h>
0005 #include <time.h>
0006 #include <sys/types.h>
0007 #include <sys/file.h>
0008 #include <sys/stat.h>
0009 #include <fcntl.h>
0010 //#include <malloc.h>
0011
0012 #define ___B___ 'B'
0013 #define ___b___ 'b'
0014 #define ___W___ 'W'
0015 #define ___w___ 'w'
0016 #define ___N___ 'N'
0017 #define ___n___ 'n'
0018
0019
省略
0021
0022 #define MAX_LOOP (2000000000)
0023
0024 //#define LEVEL 3
0025 #define LEVEL 5
0026 //#define LEVEL 7
0027
0028 #define IS_P2P (0)
0029 //#define IS_P2P (1)
0030
0031 //#define DEBUG
0032
0033 char CGINAME[ 1024 ];
0034
0035 #define IS_STACK_EST (0)
0036 #define COLOR_GREEN "#33ff33"
0037 #define MUGENM (-65535)
0038 #define MUGENP (+65535)
0039
0040 #define GAME_SIZE_X (8)
0041 #define GAME_SIZE_Y (8)
0042 #define BOARD_SIZE_X (GAME_SIZE_X+GAME_SIZE_X+1)
0043 #define BOARD_SIZE_Y (GAME_SIZE_Y+GAME_SIZE_Y+1)
0044
0045
0046 extern char init[];
0047
0048 extern char board[];
0049 int valpr[ 9 ][ 9 ] = { 0 };
0050 int valxy[ 9 ][ 9 ] = { 0 };
0051 int dirnm[ 9 ][ 9 ] = { 0 };
0052 char blockget( int sizex, int sizey, int x, int y, char *b)
0053 {
0054 return *(b + y*sizex + x);
0055 }
0056
0057 int valdir( int basex, int basey, int dirx, int diry, char *b)
0058 {
0059 int point = 0;
0060 int sizex = 8;
0061 int sizey = 8;
0062 while( blockget( sizex*2+1, sizey*2+1, (basex-1)*2+1-dirx, (basey-1)*2+1-diry, b) == ' '){
0063 point++;
0064 basex -= dirx;
0065 basey -= diry;
0066 }
0067 return point;
0068 }
0069
0070 int valdirxy( int basex, int basey, int dirx, int diry, char *b)
0071 {
0072 int point = 0;
0073 int sizex = 8;
0074 int sizey = 8;
0075 while( blockget( sizex*2+1, sizey*2+1, (basex-1)*2+1-dirx, (basey-1)*2+1-diry, b) == ' '){
0076 point += valpr[ basex ][ basey ];
0077 basex -= dirx;
0078 basey -= diry;
0079 }
0080 return point;
0081 }
0082
0083 int valdirnb( int basex, int basey, int dirx, int diry, char *b)
0084 {
0085 return -valpr[ basex+dirx ][ basey+diry ]/dirnm[ basex+dirx ][ basey+diry ];
0086 }
0087
0088 void value_init( char *b)
0089 {
0090 int sizex = 8;
0091 int sizey = 8;
0092 int cx, cy;
0093
盤の空いた座標の数(事前にグローバル変数化する)から序盤であるか
判断し、
序盤でないとき(またはより極端に中盤を除いて終盤のとき)に
すべてのvalxy[][]に1をいれて戻るコードをここに入れることが可能
0094 for( cx = 1; cx <= 8; cx++)
0095 for( cy = 1; cy <= 8; cy++)
0096 dirnm[ cx ][ cy ] =
0097 ((blockget( sizex*2+1, sizey*2+1, (cx-1)*2, (cy-1)*2, b) == ' ') ?
0098 1:0)
0099 +((blockget( sizex*2+1, sizey*2+1, (cx-1)*2, (cy-1)*2+1, b) == ' ') ?
0100 1:0)
0101 +((blockget( sizex*2+1, sizey*2+1, (cx-1)*2, (cy-1)*2+2, b) == ' ') ?
0102 1:0)
0103 +((blockget( sizex*2+1, sizey*2+1, (cx-1)*2+1, (cy-1)*2, b) == ' ') ?
0104 1:0)
0105 +((blockget( sizex*2+1, sizey*2+1, (cx-1)*2+1, (cy-1)*2+2, b) == ' ') ?
0106 1:0)
0107 +((blockget( sizex*2+1, sizey*2+1, (cx-1)*2+2, (cy-1)*2, b) == ' ') ?
0108 1:0)
0109 +((blockget( sizex*2+1, sizey*2+1, (cx-1)*2+2, (cy-1)*2+1, b) == ' ') ?
0110 1:0)
0111 +((blockget( sizex*2+1, sizey*2+1, (cx-1)*2+2, (cy-1)*2+2, b) == ' ') ?
0112 1:0);
0113
0114 for( cx = 1; cx <= 8; cx++)
0115 for( cy = 1; cy <= 8; cy++){
0116 valpr[ cx ][ cy ] =
0117 ((blockget( sizex*2+1, sizey*2+1, (cx-1)*2, (cy-1)*2, b) == ' ') ?
0118 0:valdir(cx,cy,-1,-1, b))
0119 +((blockget( sizex*2+1, sizey*2+1, (cx-1)*2, (cy-1)*2+1, b) == ' ') ?
0120 0:valdir(cx,cy,-1, 0, b))
0121 +((blockget( sizex*2+1, sizey*2+1, (cx-1)*2, (cy-1)*2+2, b) == ' ') ?
0122 0:valdir(cx,cy,-1,+1, b))
0123 +((blockget( sizex*2+1, sizey*2+1, (cx-1)*2+1, (cy-1)*2, b) == ' ') ?
0124 0:valdir(cx,cy, 0,-1, b))
0125 +((blockget( sizex*2+1, sizey*2+1, (cx-1)*2+1, (cy-1)*2+2, b) == ' ') ?
0126 0:valdir(cx,cy, 0,+1, b))
0127 +((blockget( sizex*2+1, sizey*2+1, (cx-1)*2+2, (cy-1)*2, b) == ' ') ?
0128 0:valdir(cx,cy,+1,-1, b))
0129 +((blockget( sizex*2+1, sizey*2+1, (cx-1)*2+2, (cy-1)*2+1, b) == ' ') ?
0130 0:valdir(cx,cy,+1, 0, b))
0131 +((blockget( sizex*2+1, sizey*2+1, (cx-1)*2+2, (cy-1)*2+2, b) == ' ') ?
0132 0:valdir(cx,cy,+1,+1, b))
0133 ;
0134 }
0135
0136 for( cx = 1; cx <= 8; cx++)
0137 for( cy = 1; cy <= 8; cy++){
0138 valxy[ cx ][ cy ] = valpr[ cx ][ cy ]
0139 +((blockget( sizex*2+1, sizey*2+1, (cx-1)*2, (cy-1)*2, b) == ' ') ?
0140 0:valdirxy(cx,cy,-1,-1, b))
0141 +((blockget( sizex*2+1, sizey*2+1, (cx-1)*2, (cy-1)*2+1, b) == ' ') ?
0142 0:valdirxy(cx,cy,-1, 0, b))
0143 +((blockget( sizex*2+1, sizey*2+1, (cx-1)*2, (cy-1)*2+2, b) == ' ') ?
0144 0:valdirxy(cx,cy,-1,+1, b))
0145 +((blockget( sizex*2+1, sizey*2+1, (cx-1)*2+1, (cy-1)*2, b) == ' ') ?
0146 0:valdirxy(cx,cy, 0,-1, b))
0147 +((blockget( sizex*2+1, sizey*2+1, (cx-1)*2+1, (cy-1)*2+2, b) == ' ') ?
0148 0:valdirxy(cx,cy, 0,+1, b))
0149 +((blockget( sizex*2+1, sizey*2+1, (cx-1)*2+2, (cy-1)*2, b) == ' ') ?
0150 0:valdirxy(cx,cy,+1,-1, b))
0151 +((blockget( sizex*2+1, sizey*2+1, (cx-1)*2+2, (cy-1)*2+1, b) == ' ') ?
0152 0:valdirxy(cx,cy,+1, 0, b))
0153 +((blockget( sizex*2+1, sizey*2+1, (cx-1)*2+2, (cy-1)*2+2, b) == ' ') ?
0154 0:valdirxy(cx,cy,+1,+1, b))
0155 ;
0156 }
0157
0158 for( cx = 1; cx <= 8; cx++)
0159 for( cy = 1; cy <= 8; cy++)
0160 valpr[ cx ][ cy ] = valxy[ cx ][ cy ];
0161
0162 {
0163 int min = 65535;
0164 for( cx = 1; cx <= 8; cx++)
0165 for( cy = 1; cy <= 8; cy++){
0166 valxy[ cx ][ cy ] = valpr[ cx ][ cy ]
0167 +((blockget( sizex*2+1, sizey*2+1, (cx-1)*2, (cy-1)*2, b) != ' ') ?
0168 0:valdirnb(cx,cy,-1,-1, b))
0169 +((blockget( sizex*2+1, sizey*2+1, (cx-1)*2, (cy-1)*2+1, b) != ' ') ?
0170 0:valdirnb(cx,cy,-1, 0, b))
0171 +((blockget( sizex*2+1, sizey*2+1, (cx-1)*2, (cy-1)*2+2, b) != ' ') ?
0172 0:valdirnb(cx,cy,-1,+1, b))
0173 +((blockget( sizex*2+1, sizey*2+1, (cx-1)*2+1, (cy-1)*2, b) != ' ') ?
0174 0:valdirnb(cx,cy, 0,-1, b))
0175 +((blockget( sizex*2+1, sizey*2+1, (cx-1)*2+1, (cy-1)*2+2, b) != ' ') ?
0176 0:valdirnb(cx,cy, 0,+1, b))
0177 +((blockget( sizex*2+1, sizey*2+1, (cx-1)*2+2, (cy-1)*2, b) != ' ') ?
0178 0:valdirnb(cx,cy,+1,-1, b))
0179 +((blockget( sizex*2+1, sizey*2+1, (cx-1)*2+2, (cy-1)*2+1, b) != ' ') ?
0180 0:valdirnb(cx,cy,+1, 0, b))
0181 +((blockget( sizex*2+1, sizey*2+1, (cx-1)*2+2, (cy-1)*2+2, b) != ' ') ?
0182 0:valdirnb(cx,cy,+1,+1, b))
0183 ;
0184 if(min > valxy[ cx ][ cy ])
0185 min = valxy[ cx ][ cy ];
0186 }
0187 if(0 && min < 1){
0188 for( cx = 1; cx <= 8; cx++)
0189 for( cy = 1; cy <= 8; cy++){
0190 valxy[ cx ][ cy ] += (-min+1);
0191 }
0192 }
0193 }
0194
0195 }
0196
0197
0198
0199 void set( char c, int sizex, int sizey, int x, int y, char *s)
0200 {
0201 *(s + (y-1)*sizex + (x-1)) = c;
0202 }
0203
0204 char get( int sizex, int sizey, int x, int y, char *s)
0205 {
0206 return *(s + (y-1)*sizex + (x-1));
0207 }
0208
0209
0210
0211
0212 int pos_check(
0213 int is_turn,
0214 char turn,
0215 int sizex,
0216 int sizey,
0217 int x,
0218 int y,
0219 char *s
0220 )
0221 {
0222 int cx, cy;
0223 int exist_count = 0;
0224 char tonari = (turn == ___B___) ? ___W___:___B___;
0225 int tonari_count;
0226 int tonari_count_val;
0227
0228 //左
0229 for( tonari_count = 0, cx = x-1, cy = y; ; cx--){
0230 if(cx == 0 ||
0231 blockget( sizex*2+1, sizey*2+1, cx*2, (cy-1)*2+1, board) != ' '){
0232 tonari_count = 0;
0233 tonari_count_val = 0;
0234 break;
0235 }else{
0236 char nc = get( sizex, sizey, cx, cy, s);
0237 if(nc == tonari){
0238 tonari_count++;
0239 tonari_count_val+=valxy[ cx ][ cy ];
0240 }else if(nc == turn && tonari_count > 0){
0241 //exist_count += tonari_count_val;
0242 exist_count += tonari_count;
0243 break;
0244 }else{
0245 tonari_count = 0;
0246 tonari_count_val = 0;
0247 break;
0248 }
0249 }
0250 }
0251 if(is_turn && tonari_count){
0252 for( cx = x-1, cy = y; tonari_count-- > 0; cx--){
0253 set( turn, sizex, sizey, cx, cy, s);
0254 }
0255 }
0256
0257 //右
0258 for( tonari_count = 0, cx = x+1, cy = y; ; cx++){
0259 if(cx > sizex ||
0260 blockget( sizex*2+1, sizey*2+1, (cx-1)*2, (cy-1)*2+1, board) != ' '){
0261 tonari_count = 0;
0262 tonari_count_val = 0;
0263 break;
0264 }else{
0265 char nc = get( sizex, sizey, cx, cy, s);
0266 if(nc == tonari){
0267 tonari_count++;
0268 tonari_count_val+=valxy[ cx ][ cy ];
0269 }else if(nc == turn && tonari_count > 0){
0270 //exist_count += tonari_count_val;
0271 exist_count += tonari_count;
0272 break;
0273 }else{
0274 tonari_count = 0;
0275 tonari_count_val = 0;
0276 break;
0277 }
0278 }
0279 }
0280 if(is_turn && tonari_count){
0281 for( cx = x+1, cy = y; tonari_count-- > 0; cx++){
0282 set( turn, sizex, sizey, cx, cy, s);
0283 }
0284 }
0285
0286 //上
0287 for( tonari_count = 0, cx = x, cy = y-1; ; cy--){
0288 if(cy == 0 ||
0289 blockget( sizex*2+1, sizey*2+1, (cx-1)*2+1, cy*2, board) != ' '){
0290 tonari_count = 0;
0291 tonari_count_val = 0;
0292 break;
0293 }else{
0294 char nc = get( sizex, sizey, cx, cy, s);
0295 if(nc == tonari){
0296 tonari_count++;
0297 tonari_count_val+=valxy[ cx ][ cy ];
0298 }else if(nc == turn && tonari_count > 0){
0299 //exist_count += tonari_count_val;
0300 exist_count += tonari_count;
0301 break;
0302 }else{
0303 tonari_count = 0;
0304 tonari_count_val = 0;
0305 break;
0306 }
0307 }
0308 }
0309 if(is_turn && tonari_count){
0310 for( cx = x, cy = y-1; tonari_count--; cy--){
0311 set( turn, sizex, sizey, cx, cy, s);
0312 }
0313 }
0314
0315 //下
0316 for( tonari_count = 0, cx = x, cy = y+1; ; cy++){
0317 if(cy > sizey ||
0318 blockget( sizex*2+1, sizey*2+1, (cx-1)*2+1, (cy-1)*2, board) != ' '){
0319 tonari_count = 0;
0320 tonari_count_val = 0;
0321 break;
0322 }else{
0323 char nc = get( sizex, sizey, cx, cy, s);
0324 if(nc == tonari){
0325 tonari_count++;
0326 tonari_count_val+=valxy[ cx ][ cy ];
0327 }else if(nc == turn && tonari_count > 0){
0328 //exist_count += tonari_count_val;
0329 exist_count += tonari_count;
0330 break;
0331 }else{
0332 tonari_count = 0;
0333 tonari_count_val = 0;
0334 break;
0335 }
0336 }
0337 }
0338 if(is_turn && tonari_count){
0339 for( cx = x, cy = y+1; tonari_count--; cy++){
0340 set( turn, sizex, sizey, cx, cy, s);
0341 }
0342 }
0343
0344 //左上
0345 for( tonari_count = 0, cx = x-1, cy = y-1; ; cx--, cy--){
0346 if(cx == 0 || cy == 0 ||
0347 blockget( sizex*2+1, sizey*2+1, cx*2, cy*2, board) != ' '){
0348 tonari_count = 0;
0349 tonari_count_val = 0;
0350 break;
0351 }else{
0352 char nc = get( sizex, sizey, cx, cy, s);
0353 if(nc == tonari){
0354 tonari_count++;
0355 tonari_count_val+=valxy[ cx ][ cy ];
0356 }else if(nc == turn && tonari_count > 0){
0357 //exist_count += tonari_count_val;
0358 exist_count += tonari_count;
0359 break;
0360 }else{
0361 tonari_count = 0;
0362 tonari_count_val = 0;
0363 break;
0364 }
0365 }
0366 }
0367 if(is_turn && tonari_count){
0368 for( cx = x-1, cy = y-1; tonari_count--; cx--, cy--){
0369 set( turn, sizex, sizey, cx, cy, s);
0370 }
0371 }
0372
0373 //左下
0374 for( tonari_count = 0, cx = x-1, cy = y+1; ; cx--, cy++){
0375 if(cx == 0 || cy > sizey||
0376 blockget( sizex*2+1, sizey*2+1, cx*2, (cy-1)*2, board) != ' '){
0377 tonari_count = 0;
0378 tonari_count_val = 0;
0379 break;
0380 }else{
0381 char nc = get( sizex, sizey, cx, cy, s);
0382 if(nc == tonari){
0383 tonari_count++;
0384 tonari_count_val+=valxy[ cx ][ cy ];
0385 }else if(nc == turn && tonari_count > 0){
0386 //exist_count += tonari_count_val;
0387 exist_count += tonari_count;
0388 break;
0389 }else{
0390 tonari_count = 0;
0391 tonari_count_val = 0;
0392 break;
0393 }
0394 }
0395 }
0396 if(is_turn && tonari_count){
0397 for( cx = x-1, cy = y+1; tonari_count--; cx--, cy++){
0398 set( turn, sizex, sizey, cx, cy, s);
0399 }
0400 }
0401
0402 //右上
0403 for( tonari_count = 0, cx = x+1, cy = y-1; ; cx++, cy--){
0404 if(cx > sizex || cy == 0 ||
0405 blockget( sizex*2+1, sizey*2+1, (cx-1)*2, cy*2, board) != ' '){
0406 tonari_count = 0;
0407 tonari_count_val = 0;
0408 break;
0409 }else{
0410 char nc = get( sizex, sizey, cx, cy, s);
0411 if(nc == tonari){
0412 tonari_count++;
0413 tonari_count_val+=valxy[ cx ][ cy ];
0414 }else if(nc == turn && tonari_count > 0){
0415 //exist_count += tonari_count_val;
0416 exist_count += tonari_count;
0417 break;
0418 }else{
0419 tonari_count = 0;
0420 tonari_count_val = 0;
0421 break;
0422 }
0423 }
0424 }
0425 if(is_turn && tonari_count){
0426 for( cx = x+1, cy = y-1; tonari_count--; cx++, cy--){
0427 set( turn, sizex, sizey, cx, cy, s);
0428 }
0429 }
0430
0431 //右下
0432 for( tonari_count = 0, cx = x+1, cy = y+1; ; cx++, cy++){
0433 if(cx > sizex || cy > sizey ||
0434 blockget( sizex*2+1, sizey*2+1, (cx-1)*2, (cy-1)*2, board) != ' '){
0435 tonari_count = 0;
0436 tonari_count_val = 0;
0437 break;
0438 }else{
0439 char nc = get( sizex, sizey, cx, cy, s);
0440 if(nc == tonari){
0441 tonari_count++;
0442 tonari_count_val+=valxy[ cx ][ cy ];
0443 }else if(nc == turn && tonari_count > 0){
0444 //exist_count += tonari_count_val;
0445 exist_count += tonari_count;
0446 break;
0447 }else{
0448 tonari_count = 0;
0449 tonari_count_val = 0;
0450 break;
0451 }
0452 }
0453 }
0454 if(is_turn && tonari_count){
0455 for( cx = x+1, cy = y+1; tonari_count--; cx++, cy++){
0456 set( turn, sizex, sizey, cx, cy, s);
0457 }
0458 }
0459
0460 if(is_turn && exist_count)
0461 set( turn, sizex, sizey, x, y, s);
0462
0463 return exist_count;
0464 }
0465
0466 const char urlcurs[ 63 ] = "0123456789"
0467 "abcdefghijklmnopqrstuvwxyz"
0468 "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
0469 char * cur2urlcur( char *urlcur, char *cur)
0470 {
0471 static char *ret;
0472 int num = 0;
0473 int i=0;
0474 ret = urlcur;
0475 while(i < 64){
0476 switch( *cur){
0477 case ___N___: num = num * 3; break;
0478 case ___B___: num = num * 3 + 1; break;
0479 case ___W___: num = num * 3 + 2; break;
0480 }
0481 cur++;
0482 i++;
0483 if( i % 3 == 0){
0484 *urlcur = urlcurs[ num ];
0485 urlcur++;
0486 num = 0;
0487 }
0488 }
0489 *urlcur = urlcurs[ num*3*3 ];
0490 urlcur++;
0491
0492 *urlcur = '\0';
0493
0494 return ret;
0495 }
0496
0497 char * urlcur2cur( char *cur, char *urlcur)
0498 {
0499 static char *ret;
0500 int i=0;
0501 ret = cur;
0502 *cur = '\0';
0503 while( i < 22){
0504 switch( *urlcur){
0505 case '0': *cur++ = ___N___; *cur++ = ___N___; *cur++ = ___N___; break;
0506 case '1': *cur++ = ___N___; *cur++ = ___N___; *cur++ = ___B___; break;
0507 case '2': *cur++ = ___N___; *cur++ = ___N___; *cur++ = ___W___; break;
0508 case '3': *cur++ = ___N___; *cur++ = ___B___; *cur++ = ___N___; break;
0509 case '4': *cur++ = ___N___; *cur++ = ___B___; *cur++ = ___B___; break;
0510 case '5': *cur++ = ___N___; *cur++ = ___B___; *cur++ = ___W___; break;
0511 case '6': *cur++ = ___N___; *cur++ = ___W___; *cur++ = ___N___; break;
0512 case '7': *cur++ = ___N___; *cur++ = ___W___; *cur++ = ___B___; break;
0513 case '8': *cur++ = ___N___; *cur++ = ___W___; *cur++ = ___W___; break;
0514
0515 case '9': *cur++ = ___B___; *cur++ = ___N___; *cur++ = ___N___; break;
0516 case 'a': *cur++ = ___B___; *cur++ = ___N___; *cur++ = ___B___; break;
0517 case 'b': *cur++ = ___B___; *cur++ = ___N___; *cur++ = ___W___; break;
0518 case 'c': *cur++ = ___B___; *cur++ = ___B___; *cur++ = ___N___; break;
0519 case 'd': *cur++ = ___B___; *cur++ = ___B___; *cur++ = ___B___; break;
0520 case 'e': *cur++ = ___B___; *cur++ = ___B___; *cur++ = ___W___; break;
0521 case 'f': *cur++ = ___B___; *cur++ = ___W___; *cur++ = ___N___; break;
0522 case 'g': *cur++ = ___B___; *cur++ = ___W___; *cur++ = ___B___; break;
0523 case 'h': *cur++ = ___B___; *cur++ = ___W___; *cur++ = ___W___; break;
0524
0525 case 'i': *cur++ = ___W___; *cur++ = ___N___; *cur++ = ___N___; break;
0526 case 'j': *cur++ = ___W___; *cur++ = ___N___; *cur++ = ___B___; break;
0527 case 'k': *cur++ = ___W___; *cur++ = ___N___; *cur++ = ___W___; break;
0528 case 'l': *cur++ = ___W___; *cur++ = ___B___; *cur++ = ___N___; break;
0529 case 'm': *cur++ = ___W___; *cur++ = ___B___; *cur++ = ___B___; break;
0530 case 'n': *cur++ = ___W___; *cur++ = ___B___; *cur++ = ___W___; break;
0531 case 'o': *cur++ = ___W___; *cur++ = ___W___; *cur++ = ___N___; break;
0532 case 'p': *cur++ = ___W___; *cur++ = ___W___; *cur++ = ___B___; break;
0533 case 'q': *cur++ = ___W___; *cur++ = ___W___; *cur++ = ___W___; break;
0534
0535 }
0536 i++;
0537 urlcur++;
0538 }
0539 cur-=2;//3*22-8*8
0540 *cur = '\0';
0541
0542 return ret;
0543 }
0544
0545
0546 #define WALLCOLOR "gold"
0547 char * colorstring( int c, char *def)
0548 {
0549 switch( c){
0550 case 'C':
0551 case 'c':
0552 return "#33AAFF";
0553 case 'H':
0554 case 'h':
0555 return "gray";
0556 case 'B':
0557 case 'b':
0558 return "black";
0559 case 'G':
0560 case 'g':
0561 return WALLCOLOR;
0562 case 'S':
0563 case 's':
0564 return "silver";
0565 case 'R':
0566 case 'r':
0567 return "red";
0568 case '+':
0569 case '-':
0570 case '|':
0571 default:
0572 return def;
0573 }
0574 }
0575
0576 char * colorPstring( int c, char *def)
0577 {
0578 switch( c){
0579 case 'C':
0580 case 'c':
0581 return "cyan";
0582 case 'H':
0583 case 'h':
0584 return "gray";
0585 case 'B':
0586 case 'b':
0587 return "black";
0588 case 'G':
0589 case 'g':
0590 return WALLCOLOR;
0591 case 'S':
0592 case 's':
0593 return "silver";
0594 case 'R':
0595 case 'r':
0596 return "red";
0597 case '+':
0598 case '-':
0599 case '|':
0600 default:
0601 return def;
0602 }
0603 }
0604 char * colorDstring( int c, char *def)
0605 {
0606 switch( c){
0607 case 'C':
0608 case 'c':
0609 return "cyan";
0610 case 'H':
0611 case 'h':
0612 return "gray";
0613 case 'B':
0614 case 'b':
0615 return "black";
0616 case 'G':
0617 case 'g':
0618 return WALLCOLOR;
0619 case 'S':
0620 case 's':
0621 return "silver";
0622 case 'R':
0623 case 'r':
0624 return "red";
0625 case '+':
0626 case '-':
0627 case '|':
0628 default:
0629 return def;
0630 }
0631 }
0632
0633 int disp_now( char nextturn, int xsize, int ysize, char *status, int isblue, int bx, int by, char *orgstatus)
0634 {
0635 char urlstatus[ 24 ];
0636 int i,j;
0637 printf("<TABLE bgcolor=green>\n");
0638 for( i = 0; i < (ysize*2)+1; i++)
0639 {
0640 printf("<TR hight=16>\n");
0641 for( j = 0; j < (xsize*2)+1; j++)
0642 {
0643 char c = board[ i*(xsize*2+1)+j ];
0644 char m = *(status+(i/2)*xsize+(j/2));
0645 if(i%2 && j%2){
0646 char ms[ 256 ];
0647 switch( m)
0648 {
0649 #ifdef IS_NUM
0650 case ___B___: sprintf( ms, "<FONT COLOR=WHITE>●<BR>%d</FONT>", valxy[ j/2+1 ][ i/2+1 ]);break;
0651 case ___W___: sprintf( ms, "<FONT COLOR=RED>●<BR>%d</FONT>", valxy[ j/2+1 ][ i/2+1 ]);break;
0652 #else
0653 case ___B___:
0654 if(i/2+1 == by && j/2+1 == bx)
0655 sprintf( ms, "<IMG SRC=\"/icons/black24f.gif\">");
0656 else if(*(orgstatus+(i/2)*xsize+(j/2)) != ___B___)
0657 sprintf( ms, "<IMG SRC=\"/icons/black24d.gif\">");
0658 else
0659 sprintf( ms, "<IMG SRC=\"/icons/black24c.gif\">");
0660 break;
0661 case ___W___:
0662 if(i/2+1 == by && j/2+1 == bx)
0663 sprintf( ms, "<IMG SRC=\"/icons/white24f.gif\">");
0664 else if(*(orgstatus+(i/2)*xsize+(j/2)) != ___W___)
0665 sprintf( ms, "<IMG SRC=\"/icons/white24d.gif\">");
0666 else
0667 sprintf( ms, "<IMG SRC=\"/icons/white24c.gif\">");
0668 break;
0669 #endif
0670 case ___N___: if(isblue == 0
0671 || nextturn == ___N___
0672 || nextturn == ___b___
0673 || nextturn == ___w___
0674 || pos_check( 0, nextturn, 8, 8, j/2+1, i/2+1, status) == 0){
0675 #ifdef IS_NUM
0676 sprintf( ms, "×<BR>%d", valxy[ j/2+1 ][ i/2+1 ]);
0677 #else
0678 if(c == ' ')
0679 sprintf( ms,
0680 "<IMG SRC=\"/icons/green24c.gif\" border=\"0\">");
0681 else
0682 sprintf( ms, "<FONT COLOR=\"%s\">■</FONT>",
0683 colorPstring( c, "green"));
0684 #endif
0685 }else{
0686 #ifdef IS_NUM
0687 sprintf( ms,
0688 "<A HREF=\"/cgi-bin/%s?t=%c&x=%d&y=%d&s=%s\">"
0689 "○<BR>%d"
0690 "</A>",
0691 CGINAME,
0692 tolower(nextturn), j/2+1, i/2+1,
0693 //status,
0694 cur2urlcur( urlstatus, status),
0695 valxy[ j/2+1 ][ i/2+1 ]
0696 );
0697 #else
0698 sprintf( ms,
0699 "<A HREF=\"/cgi-bin/%s?t=%c&x=%d&y=%d&s=%s\">"
0700 "<IMG SRC=\"/icons/blue24e.gif\" border=\"0\">"
0701 //"○"
0702 "</A>",
0703 CGINAME,
0704 tolower(nextturn), j/2+1, i/2+1,
0705 //status
0706 cur2urlcur( urlstatus, status)
0707 );
0708 #endif
0709 }
0710 break;
0711 }
0712 #ifdef IS_NUM
0713 printf(
0714 "<TD align=center bgcolor=green width=36 height=36>%s</TD>",
0715 ms
0716 );
0717 #else
0718 printf(
0719 "<TD align=center bgcolor=%s width=32 height=32>%s</TD>",
0720 ((c == ' ') ? "green":colorPstring(c, "green")) ,
0721 ms
0722 );
0723 #endif
0724 }else{
0725 printf( "<TD bgcolor=%s width=1 height=3></TD>",
0726 (c==' ') ?
0727 "#009900":
0728 (((i+j)%2) ?
0729 ((j == 0 ||
0730 j == (xsize*2) ||
0731 i == (ysize*2) ||
0732 i == 0) ?
0733 colorDstring(c, "black"):colorDstring(c, WALLCOLOR)
0734 )
0735 :
0736 ((j == 0 ||
0737 j == (xsize*2) ||
0738 i == (ysize*2) ||
0739 i == 0) ?
0740 colorDstring(c, "black"):colorDstring(c, WALLCOLOR)
0741 )
0742 )
0743 );
0744 }
0745 }
0746 printf("</TR>\n");
0747 }
0748 printf("</TABLE>\n");
0749 }
0750
0751 char * _ADURL = NULL;
0752
0753 int i[ 64+1 ],j[ 64+1 ];
0754 int max[ 64+1 ];
0755 char status[ 64+1 ][ 64+1 ];
0756 char turn[ 64+1 ];
0757 int check[ 64+1 ];
0758 char now_status[ 1024 ];
0759
0760 void disp_head(int i, char *s)
0761 {
0762 printf("Content-type: text/html;charset=euc-jp;\n\n");
0763 printf("<HTML>\n");
0764 printf("<HEAD>\n");
0765 if((i > 0 ||(s && *s)))
0766 printf("<META HTTP-EQUIV=\"REFRESH\" CONTENT=\"%d;URL=/cgi-bin/%s%s\">\n",i, CGINAME, s);
0767 printf("<TITLE>WALLSTREETS</TITLE>\n");
0768 printf("<STYLE TYPE=\"text/css\">");
0769 printf("<!--\n");
0770 printf("H1{font-size:16pt; color:gold}\n");
0771 printf("H2{font-size:8pt; color:blue}\n");
0772 printf("body {\n");
0773 printf("background-repeat: no-repeat;\n");
0774 printf("background-attachment: fixed;\n");
0775 printf("background-position: center middle;\n");
0776 printf("}\n");
0777 printf("A{\n");
0778 printf(" text-decoration: none;\n");
0779 printf("}\n");
0780 printf("A:HOVER{\n");
0781 printf("background:repat-x center bottom;\n");
0782 printf("}\n");
0783 printf("-->\n");
0784 printf("</STYLE>\n");
0785 printf("</HEAD>\n");
0786 printf("<BODY bgcolor=#000033>\n");
0787 printf("<CENTER>\n");
0788 if( s && *s){
0789 printf("<TABLE><TR><TD align=center valign=top>\n");
0790 }else{
0791 printf("<TABLE><TR><TD align=center valign=top>\n");
0792 }
0793 printf("<TABLE bgcolor=#550000 style=\"width:335px;\"><TR><TD align=center><FONT SIZE=5 COLOR=GOLD>WallStreets</FONT><A HREF=\"#\" onclick=\"var w01;w01=window.open('http://wallstreets.ws/','win1','width=480,height=730,resizable=yes');w01.focus()\"><FONT SIZE=3 COLOR=silver> JP</FONT></A><A HREF=\"#\" onclick=\"var w01;w01=window.open('http://wallstreets.ws/eu/','win1','width=480,height=730,resizable=yes');w01.focus()\"><FONT SIZE=3 COLOR=silver> UV</FONT></A></TD></TR></TABLE>\n");
0794 }
0795
0796 int whitenum( char *status)
0797 {
0798 int ret = 0;
0799 while( *status){
0800 if(*status == ___W___)
0801 ret++;
0802 status++;
0803 }
0804
0805 return ret;
0806 }
0807
0808 char *mycrypt( char *msg)
0809 {
暗号化コードのため省略
0823 }
0824
0825
0826 void disp_tail(char nextturn, char *msg)
0827 {
0828 char buf[ 256 ];
0829 char filename[ 256 ];
0830 char userpoint[ 8 ][ 160 ];
0831 char username[ 8 ][ 320 ];
0832 int i = 0;
0833
0834
0835 if(IS_P2P == 0){
0836 sprintf( filename, "%s.rank", CGINAME);
0837
0838 FILE *fp;
0839 do{
0840 fp = fopen( filename, "rb");
0841 if(!fp){
0842 FILE *fout = fopen(filename, "wb");
0843 fprintf(fout, "0,-\n0,-\n0,-\n0,-\n0,-\n0,-\n0,-\n0,-\n0,-\n");
0844 fclose(fout);
0845 }
0846 }while(!fp);
0847
0848 while( fgets( buf, 256, fp ) && i < 8){
0849 char *cp = strchr( buf, ',');
0850 *cp = '\0';
0851 strcpy( userpoint[ i ], buf);
0852 strcpy( username[ i ], cp+1);
0853 i++;
0854 }
0855 fclose( fp);
0856
0857
0858 printf("<TABLE bgcolor=#550000 style=\"width:335px;\">\n");
0859 if(nextturn==___N___ && whitenum( now_status) > atoi(userpoint[ 7 ])){
0860 printf("<TR><TD colspan=3 align=center>\n");
0861 printf("<FORM method=post action=\"http://wallstreets.ws/cgi-bin/%s?t=h\">\n", CGINAME);
0862 printf("<INPUT TYPE=hidden name=stat value=\"%s\">\n", now_status);
0863 printf("<INPUT TYPE=hidden name=crypt value=\"%s\">\n", mycrypt(now_status));
0864 printf("<FONT color=gold>nickname:</font><INPUT TYPE=text name=username value=\"\">\n");
0865 printf("<INPUT type=submit value=\"High Score Set\">\n");
0866 printf("</FORM>\n");
0867 printf("</TD></TR>\n");
0868 }
0869 {
0870 int i;
0871 if(atol(userpoint[0]) > 0) strcat( userpoint[ 0 ], "0000");
0872 if(atol(userpoint[1]) > 0) strcat( userpoint[ 1 ], "000");
0873 if(atol(userpoint[2]) > 0) strcat( userpoint[ 2 ], "00");
0874 if(atol(userpoint[3]) > 0) strcat( userpoint[ 3 ], "0");
0875 for(i = 0; i < 8; i++)
0876 {
0877 printf("<TR bgcolor=%s><TD align=right>\n", (i%2) ? "0x000033":"0x000011");
0878 printf("<FONT color=silver><%d></FONT></TD><TD align=right><FONT color=silver>%s</FONT></TD><TD align=center><FONT color=silver>%s</FONT>\n", i+1, userpoint[ i ] , username[ i ]);
0879 printf("</TD></TR>\n");
0880 }
0881 }
0882 printf("<TR><TD colspan=3 align=center>\n");
0883 printf("<FONT size=5 color=gold>★RANKING★</FONT>\n");
0884 printf("</TD></TR>\n");
0885 printf("</TABLE>\n");
0886 }
0887 printf("<TD></TR></TABLE>\n");
0888 printf("</BODY>\n");
0889 printf("</HTML>\n");
0890 }
0891
0892 int all_pos_check( char nextturn, int *maxi, int *maxj, char *now_status)
0893 {
0894 int i,j;
0895 int max = 0;
0896 *maxi = 0;
0897 *maxj = 0;
0898 for( i = 1; i <= 8; i++){
0899 for( j = 1; j <=8; j++){
0900 if(get( 8, 8, i, j, now_status) == ___N___){
0901 int now = pos_check( 0, nextturn, 8, 8, i, j, now_status);
0902 if(now > max){
0903 *maxi = i;
0904 *maxj = j;
0905 max = now;
0906 }
0907 }
0908 }
0909 }
0910 return max;
0911 }
0912
0913 void p( char *str)
0914 {
0915 printf( "%s\n", str);
0916 }
0917
0918
0919 int minmax[ 64+1 ];
省略
0926 int max_sp;
0927 int now_max_loop;
省略
0964 void disp_stack( int x, int y, char *msg)
0965 {
0966 ;
0967 }
省略
0969
0970 /*-----------------------------------------------------------------------------
0971 関数名 recursive_all_pos_check
0972 機能 最も有望な手を返す
0973 引数 nextturn 有望な手を探索する側(___B___/___W___)
0974 *maxi 有望な手のX座標
0975 *maxj 有望な手のY座標
0976 now_status 探索の対象となるゲーム状態
0977 max_loop 最大の探索ループ数
0978 ---------------------------------------------------------------------------*/
0979 int recursive_all_pos_check(
0980 char nextturn,
0981 int *maxi,
0982 int *maxj,
0983 char *now_status,
0984 unsigned long max_loop
0985 )
0986 {
以下では、多ゲームプロセス同時処理用のサーバーや携帯電話など少ないメモリしか利用しないプラットフォームで、しかも適度に負ける必要のある場合に対応する「ひとつのベストモード」として、スタックによる、深さレベル(=先読みレベル)制限つきの深さ優先探索をおこなっているが、多くのメモリが利用できるスピード優先ないし強さ優先(勝利優先)のモードでは、探索対象となるゲーム状態の合流(違う手として先読みして同じゲーム状態に遭遇する場合)をハッシュテーブル等により検知してその先の重複探索を回避したり、パターン化された有望な手筋についてのみ先読みの深さレベルを制限しないようにする等、より一般的な公知の探索手法も「別のベストモード」として採用できることは自明であり、これについては詳述しない。
基本的には公知のミニマックス法で最良の手を決定するが、手の評価において、自分の駒の置いてある座標の重み(value_init()で生成済のvalxy[][])の和がなるべく大きくなる手を最良の手として選ぶ。
また、適度の負ける必要がなく、より強さ優先にするには、終盤で、座標の重み(座標の価値を表すvalxy[][])を別途均一化し、単純に駒数で相手に優るような手を探索するようにする。
0987 const int level = LEVEL;
0988 int first_get = 0;
0989 int m,n;
0990
0991 *maxi = *maxj = 0;
0992
省略
0994 minmax[ 0 ] = MUGENM;
0995
0996 // スタックの初期化
0997 max_sp = 0;
0998 turn[ 0 ] = ___N___;
0999 strcpy( status[ 0 ], now_status);
1000 i[ 0 ] = j[ 0 ] = 0;
1001 max[ 0 ] = 0;
1002 #ifdef DEBUG
1003 printf( "<TABLE border bgcolor=white>\n");
1004 #endif
1005 // 次の一手
1006 ++max_sp;
1007 turn[ max_sp ] = nextturn;
1008 i[ max_sp ] = j[ max_sp ] = 1;
1009 max[ max_sp ] = 0;
1010 do{
1011
1012 if(--max_loop == 0){
1013 disp_stack( *maxi, *maxj, "LOOPOVER");
1014 break;
1015 }
1016 now_max_loop = max_loop;
1017
1018 if( max_sp % 2 == 1 && max_sp < level){
1019 // 1 or 3 のとき
1020 minmax[ max_sp ] = MUGENP;
1021 }
1022
1023 if( max_sp % 2 == 0 && max_sp < level){
1024 // 2 or 4 のとき(0はありえないから)
1025 minmax[ max_sp ] = MUGENM;
1026 }
1027
1028 strcpy( status[ max_sp ], status[ max_sp-1 ]);
1029
1030 if( get( 8, 8, i[ max_sp ], j[ max_sp ], status[ max_sp ]) == ___N___
1031 && (check[ max_sp ]
1032 = pos_check( 1, turn[ max_sp ], 8, 8, i[ max_sp ], j[ max_sp ], status[ max_sp ])) > 0){
1033 // 注目した座標(i[max_sp],j[max_sp])に石がなくかつとれるので置ける場合
1034
1035 // 現在のmax_sp-1のゲーム状態に対して先の手max_spが存在することをマークする
1036 max[ max_sp ] = check[ max_sp ];
1037
1038 if(max_sp < level){
1039 // まだ先を読む必要がある場合,
1040
1041 //disp_stack( *maxi, *maxj, "THINKING");
1042 // 置いてみた後のstatus[ max_sp ]をスタックにつむ
1043 ++max_sp;
1044 turn[ max_sp ] = (turn[ max_sp-1 ] == ___B___) ? ___W___:___B___;
1045 i[ max_sp ] = j[ max_sp ] = 1;
1046 max[ max_sp ] = 0;
1047
1048 }else{
1049 // 最深読みレベルに達していた場合
1050
1051 // 最深読みレベルの評価を計算する
1052 int sum = 0;
1053 int k;
1054 if(IS_STACK_EST)
1055 {
1056 for( k = 1; k <= max_sp; k++)
1057 sum +=
1058 (turn[ k ] == nextturn) ?
1059 +(check[ k ]+valxy[i[ k ]][j[ k ]]) : -(check[ k ]+valxy[i[ k ]][j[ k ]]);
1060 //+(check[ k ]) : -(check[ k ]);
1061 }else{
1062 int x,y;
1063 int sumw = 0;
1064 int sumb = 0;
1065 for( x = 1; x <= 8; x++){
1066 for( y = 1; y <= 8; y++){
1067 switch(get( 8, 8, x, y, status[ max_sp ])){
1068 case ___N___: break;
1069 case ___B___: sumw += valxy[ x ][ y ]; break;
1070 case ___W___: sumb += valxy[ x ][ y ]; break;
1071 }
1072 }
1073 }
1074 sum = (nextturn == ___B___) ? (sumw-sumb):(sumb-sumw);
1075 }
1076 if(/* 最深レベルは奇数故 max_sp % 2 = 1 のチェックはいらない */
1077 sum > minmax[ max_sp-1 ]){
1078 minmax[ max_sp-1 ] = sum;
1079 //disp_stack( *maxi, *maxj, "sum > minmax[ max_sp-1 ]");
1080 }
1081 //disp_stack( *maxi, *maxj);
1082
1083 // 次の候補にポインタを移す
1084 while( j[ max_sp ] == 8 && i[ max_sp ] == 8 && max_sp > 0){
1085 max_sp --;
1086 if(max_sp % 2 == 0 && max_sp < level){
1087 if(minmax[ max_sp ] < minmax[ max_sp-1 ]){
1088 minmax[ max_sp-1 ] = minmax[ max_sp ];
1089 disp_stack( *maxi, *maxj, "minmax[ max_sp ] < minmax[ max_sp-1 ]");
1090 }
1091 }
1092
1093 if(max_sp % 2 == 1 && max_sp < level){
1094 if(minmax[ max_sp-1 ] < minmax[ max_sp ]){
1095 minmax[ max_sp-1 ] = minmax[ max_sp ];
1096 disp_stack( *maxi, *maxj, "minmax[ max_sp-1 ] < minmax[ max_sp ]");
1097 if( max_sp == 1){
1098 *maxi = i[ 1 ];
1099 *maxj = j[ 1 ];
1100 first_get = check[ 1 ];
1101 }
1102 }
1103 }
1104 if(max_sp == 1)
1105 disp_stack( *maxi, *maxj, "CANDIDATE");
1106 }
1107
1108 if(max_sp > 0){
1109 if(j[ max_sp ] < 8){
1110 j[ max_sp ]++;
1111 }else if(i[ max_sp ] < 8){
1112 i[ max_sp ]++;
1113 j[ max_sp ] = 1;
1114 }
1115 }
1116 }
1117 }else{
1118 // 注目した座標(i[max_sp],j[max_sp])に既に石があるか,なくても置けないときの処理
1119 if(j[ max_sp ] < 8){
1120 j[ max_sp ]++;
1121 }else if(i[ max_sp ] < 8){
1122 i[ max_sp ]++;
1123 j[ max_sp ] = 1;
1124 }else{
1125 //その手をすべて探索したとき
1126 disp_stack( *maxi, *maxj, "all searched");
1127 if(max[ max_sp ] == 0){
1128 //すべて探索した結果としておけなかったとき
1129 char revturn = (turn[ max_sp ] == ___B___) ? ___W___:___B___;
1130 int m,n,rev_check = 0;
1131 int nokori = 0, rev_nokori = 0;
1132
1133 disp_stack( *maxi, *maxj, "max[ max_sp ] == 0");
1134 // 番を相手にわたせるかどうか計算
1135 for(m = 1; m <= 8; m++)
1136 for(n = 1; n <= 8; n++){
1137 char c = get( 8, 8, m, n, status[ max_sp ]);
1138 if(c == ___N___)
1139 rev_check += pos_check( 0, revturn, 8, 8, m, n, status[ max_sp ]);
1140 else if(c == revturn)
1141 rev_nokori ++;
1142 else
1143 nokori ++;
1144 }
1145
1146 if(rev_check > 0 && max_sp < level){
1147 // 相手の置く場所があり番をわたせるとき
1148
1149 // 自分のturnはスキップする
1150 i[ max_sp ] = 8;
1151 j[ max_sp ] = 8;
1152
1153 // turnを交替して探索しなおし
1154 ++max_sp;
1155 turn[ max_sp ] = revturn;
1156 i[ max_sp ] = 1;
1157 j[ max_sp ] = 0;
1158 max[ max_sp ] = 0;
1159
1160 disp_stack( *maxi, *maxj, "PASS");
1161
1162 }else{
1163 // ゲームルール上,自分も相手もおける石がなかった場合
1164 if( max_sp == 1){
1165 // 1手目で自分も相手もなにもできないとき
1166 disp_stack( *maxi, *maxj, "1 te PASSPASS GAMEOVER");
1167 ;//ゲームオーバー
1168 }else{
1169 disp_stack( *maxi, *maxj, "max_sp > 1");
1170 // 2手先読みでこの状態に遭遇したとき
1171 if(max_sp == 2 && rev_nokori > nokori){
1172 // 2手先で両者とも何もできなくなりコールド勝ちになる場合
1173 *maxi = i[ 1 ];
1174 *maxj = j[ 1 ];
1175 //all_1_all_nM1_max_min_max = MUGENP;//この手に決めてしまう
1176 minmax[ 0 ] = MUGENP;
1177 first_get = check[ 1 ];
1178 disp_stack( *maxi, *maxj, "COLD WIN");
1179 }else{
1180 // 2手先以上で両者とも何もできなくなり,負けか引き分けのとき
1181 // 最深読みレベルの評価を計算する
1182 int sum = 0;
1183 int k;
1184 if(IS_STACK_EST){
1185 for( k = 1; k <= max_sp; k++)
1186 sum +=
1187 (turn[ k ] == nextturn) ?
1188 +(check[ k ]+valxy[i[ k ]][j[ k ]]) : -(check[ k ]+valxy[i[ k ]][j[ k ]]);
1189 //+(check[ k ]) : -(check[ k ]);
1190 }else{
1191 int x,y;
1192 int sumw = 0;
1193 int numw = 0;
1194 int sumb = 0;
1195 int numb = 0;
1196 for( x = 1; x <= 8; x++){
1197 for( y = 1; y <= 8; y++){
1198 switch(get( 8, 8, x, y, status[ max_sp ])){
1199 case ___N___: break;
1200 case ___B___: numw++;sumw += valxy[ x ][ y ]; break;
1201 case ___W___: numb++;sumb += valxy[ x ][ y ]; break;
1202 }
1203 }
1204 }
1205 if(numw == 0){
1206 sumw = MUGENM;
1207 }
1208 if(numb == 0){
1209 sumb = MUGENM;
1210 }
1211 sum = (nextturn == ___B___) ? (sumw-sumb):(sumb-sumw);
1212 }
1213 disp_stack( *maxi, *maxj, "LOSEorDRAW-BACKTRACK");
1214 if(sum > minmax[ max_sp-1 ]){
1215 // max_sp == 3 or 5 , max_sp-1 == 2 or 4を想定している
1216 minmax[ max_sp-1 ] = sum;
1217 disp_stack( *maxi, *maxj, "LOSEorDRAW-BACKTRACK sum > minmax[ max_sp-1 ]");
1218 }
1219 //負けか引き分けになりそうなときの処理終了
1220 }
1221 disp_stack( *maxi, *maxj, "NO GAME at 2 or more");
1222 //2手先読み以上で遭遇した場合終了
1223 }
1224 disp_stack( *maxi, *maxj, "NO GAME at a context");
1225 // ゲームルール上,自分も相手もおける石がなかった場合終了
1226 }
1227 disp_stack( *maxi, *maxj, "NO GAME");
1228 // すべて探索した結果としておけなかったとき終了
1229 }
1230
1231 //disp_stack( *maxi, *maxj, "NO TE");
1232
1233 // 次の候補にポインタを移す
1234 while( j[ max_sp ] == 8 && i[ max_sp ] == 8 && max_sp > 0){
1235 max_sp --;
1236 if(max_sp % 2 == 0 && max_sp < level){
1237 if(minmax[ max_sp ] < minmax[ max_sp-1 ]){
1238 minmax[ max_sp-1 ] = minmax[ max_sp ];
1239 disp_stack( *maxi, *maxj, "minmax[ max_sp ] < minmax[ max_sp-1 ]");
1240 }
1241 }
1242 if(max_sp % 2 == 1 && max_sp < level){
1243 if(minmax[ max_sp-1 ] < minmax[ max_sp ]){
1244 minmax[ max_sp-1 ] = minmax[ max_sp ];
1245 disp_stack( *maxi, *maxj, "minmax[ max_sp-1 ] < minmax[ max_sp ]");
1246 if( max_sp == 1){
1247 *maxi = i[ 1 ];
1248 *maxj = j[ 1 ];
1249 first_get = check[ 1 ];
1250 }
1251 }
1252 }
1253 }
1254 //disp_stack( *maxi, *maxj, "BACKTRACK AFTER NO-TE");
1255 if(max_sp > 0){
1256 if(j[ max_sp ] < 8){
1257 j[ max_sp ]++;
1258 }else if(i[ max_sp ] < 8){
1259 i[ max_sp ]++;
1260 j[ max_sp ] = 1;
1261 }
1262 }
1263 }
1264 }
1265 }while( max_sp > 0);
1266
1267 #ifdef DEBUG
1268 printf( "</TABLE>\n");
1269 #endif
1270
1271 return first_get
1272 }
1273
1274 int disp_point( int is_start, int x, int y, char *now_status, char nextturn, double t)
1275 {
1276 int i;
1277 int W = 0;
1278 int R = 0;
1279 char ch;
1280 char name[ 256 ];
1281 char *cp;
1282 strcpy( name, CGINAME);
1283 cp= strchr( name, '.');
1284 *cp = '\0';
1285
1286 for( i = 0; i < 8*8; i++)
1287 {
1288 switch( now_status[ i ]){
1289 case ___N___: break;
1290 #ifdef IS_NUM
1291 case ___B___: W += valxy[ i % 8 + 1 ][ i / 8 + 1 ]; break;
1292 case ___W___: R += valxy[ i % 8 + 1 ][ i / 8 + 1 ]; break;
1293 #else
1294 case ___B___: W ++; break;
1295 case ___W___: R ++; break;
1296 #endif
1297 }
1298 }
1299 if(W == R)
1300 ch = '=';
1301 else if(W > R)
1302 ch = '>';
1303 else
1304 ch = '<';
1305 if(nextturn == ___N___)
1306 printf("<TABLE style=\"width:335px;\" bgcolor=#550000><TR><TD align=center><FONT COLOR=gold SIZE=1>%.2fs %s </FONT><FONT color=silver size=3><IMG SRC=\"/icons/black24c.gif\" width=12> %d %c <IMG SRC=\"/icons/white24c.gif\" width=12> %d → <A HREF=\"/cgi-bin/%s\"><IMG SRC=\"/icons/replay.gif\" width=256></A><FONT></TD></TR></TABLE>\n", t, name, W, ch, R, CGINAME);
1307 else
1308 printf("<TABLE style=\"width:335px;\" bgcolor=#550000><TR><TD align=center><FONT COLOR=gold SIZE=1>%.2fs %s </FONT><FONT color=silver size=3><IMG SRC=\"/icons/black24c.gif\" width=12> %d %c <IMG SRC=\"/icons/white24c.gif\" width=12> %d → <IMG SRC=\"/icons/%s24e.gif\" width=12> %s</FONT></TD></TR></TABLE>\n", t, name, W, ch, R, (nextturn == ___W___||nextturn == ___w___) ? "white":"black", ((nextturn == ___W___||nextturn == ___w___) || IS_P2P == 1) ? "<font color=gold size=1>pls. select</font>":"<font color=gold size=1>please wait</font>");
1309 }
1310
1311 void countup( void)
1312 {
省略
1347 }
1348
1349 const char codetbl[] = "0123456789ABCDEF";
1350
1351 int urldecode(char *in, char *out)
1352 {
省略
1380 }
1381
1382 int main( int argc, char *argv[])
1383 {
1384 int smode = 1;
1385 int isloop = 1;
1386 char org_status[ 1024 ];
1387 char url_status[ 64 ];
1388
1389 clock_t start,end;
1390 {
1391 char *cp = strrchr( argv[ 0 ], '/');
1392 strcpy(CGINAME, cp+1);
1393 }
1394 start = clock();
1395
1396
1397
1398 char autonext[ 1024 ] = {""};
1399 char lastturn = ___N___;
1400 char nextturn = ___N___;
1401 int x,y;
1402 char cfgfilepath[ 1024 ];
1403 char given_status[ 1024 ];
1404 char *cp = getenv("QUERY_STRING"); cp = (cp) ? strcpy( given_status, cp) : NULL;
1405 char *user = getenv("REMOTE_ADDR");
1406
1407 value_init( board);
1408
1409 //自分の色および場所を変数にいれる
1410 if(cp == NULL || *cp == '\0' || *(cp+2)=='h'){
1411
1412 char buf[ 1024 ];
1413
1414 if(*(cp+2) =='h'){
1415 char *sp;
1416 char *ep;
1417 int point = 0;
1418 char sname[ 64 ];
1419 char scrypt[ 64+1 ];
1420 char ncrypt[ 64+1 ];
1421 char sstat[ 64+1 ];
1422
1423 fgets( buf, 1024, stdin);
1424
1425
1426 sp = buf+5;
1427 ep = strchr( sp, '&');
1428 *ep = '\0';
1429 strcpy( sstat, sp);
1430 strcpy( ncrypt, (const char *)mycrypt( sstat));
1431
1432 sp = ep+7;
1433 ep = strchr( sp, '&');
1434 *ep = '\0';
1435 strcpy( scrypt, sp);
1436
1437 sp = ep+10;
1438 urldecode( sp, sname);
1439
1440 if(strlen(sname) > 0 && strcmp( ncrypt, scrypt) == 0){
1441 int num = whitenum( sstat);
1442 char buf[ 256 ];
1443 char filename[ 256 ];
1444 char filenamebak[ 256 ];
1445 sprintf( filename, "%s.rank", CGINAME);
1446 sprintf( filenamebak, "%s.rank.bak", CGINAME);
1447 unlink( filenamebak);
1448 rename( filename, filenamebak);
1449 FILE *fin = fopen( filenamebak, "rb");
1450 FILE *fout = fopen( filename, "wb");
1451 if(fin){
1452 while( fgets( buf, 256, fin ) ){
1453 char *cp = strchr( buf, ',');
1454 if(cp){
1455 *cp = '\0';
1456 if(atoi( buf) < num){
1457 fprintf( fout, "%d,%s\n", num, sname);
1458 num = 0;
1459 }
1460 fprintf( fout, "%s,%s", buf, cp+1);
1461 }
1462 }
1463
1464 fclose( fin);
1465 //rename( filenamebak, filename);
1466 fclose( fout);
1467 }
1468 }
1469
1470 }else{
1471 buf[0] = '\0';
1472 }
1473
1474 // 引数が得られなかった場合
1475 nextturn = (IS_P2P) ? ___B___:___W___;
1476 x = 0;
1477 y = 0;
1478 disp_head(0, NULL);
1479 strcpy( now_status, init );
1480 disp_point( 1, 0, 0, now_status, nextturn, 0.0f);
1481 strcpy( org_status, now_status);
1482 disp_now(
1483 nextturn,
1484 8, 8, now_status, 1, 0, 0, org_status
1485 );
1486 disp_tail(nextturn, user);
1487 exit( 0);
1488 }
1489
1490
1491 // 引数を取得する
1492 {
1493 static char buf[ 1024 ];
1494 char *ep;
1495 while(*cp != '=') cp++;
1496 nextturn = *(++cp);
1497 while(*cp != '=') cp++;
1498 ep = strchr( cp, (int)'&');
1499 *ep = '\0';
1500 x = atoi( ++cp);
1501
1502 while(*cp != '=') cp++;
1503 ep = strchr( cp, (int)'&');
1504 *ep = '\0';
1505 y = atoi( ++cp);
1506
1507 while(*cp != '=') cp++;
1508
1509 ++cp;
1510 if(*cp == ___N___ || *cp == ___B___ || *cp == ___W___)
1511 strcpy( now_status, cp);
1512 else
1513 urlcur2cur( now_status, cp);
1514
1515 ep = strchr( now_status, (int)'&');
1516 if( ep){
1517 *ep = '\0';
1518 while(*ep != '=') ep++;
1519 _ADURL = strcpy(buf, ++ep);
1520 }else{
1521 _ADURL = NULL;
1522 }
1523 }
1524
1525 strcpy( org_status, now_status);
1526
1527 while( isloop){
1528 int maxi, maxj;
1529
1530 switch( nextturn){
1531 case ___w___: // ___w___(置くのみ(波及せず))
1532 if(smode == 1){
1533 nextturn = toupper(nextturn);
1534 }else{
省略
1557 }
1558 break;
1559 case ___b___: // ___b___(推論して置くのみ(波及せず)) 前フェーズで置けることをチェックして、このフェーズに入るようにする
1560 if(smode == 1){
1561 if(IS_P2P){
1562 nextturn = ___B___;
1563 }else{
1564 recursive_all_pos_check(___B___, &maxi, &maxj, now_status, MAX_LOOP);
1565 x = maxi;
1566 y = maxj;
1567 nextturn = ___B___;
1568 }
1569 }else{
省略
1594 }
1595 break;
1596 case ___W___:
1597 {
1598 int isblue = IS_P2P;
1599 pos_check( 1, ___W___, 8, 8, x, y, now_status);
1600 if(all_pos_check(___B___, &maxi, &maxj, now_status) > 0){
1601 //白完(w要求)
1602 nextturn = ___B___;
1603 if(IS_P2P)
1604 disp_head(0, "");
1605 else{
1606 sprintf( autonext,
1607 "?t=%c&x=%d&y=%d&s=%s",
1608 (IS_P2P) ? ___B___:___b___,
1609 0,
1610 0,
1611 //now_status
1612 cur2urlcur( url_status, now_status)
1613 );
1614 disp_head(1, autonext);
1615 }
1616 disp_point( 0, x, y, now_status, ___B___, 0.0f);
1617 }else{
1618 if(all_pos_check(___W___, &maxi, &maxj, now_status) > 0){
1619 //青完
1620 disp_head(0, "");
1621 isblue = 1;
1622 disp_point( 0, x, y, now_status, ___W___, 0.0f);
1623 }else{
1624 //相手も自分もおけなかったとき
1625 nextturn = ___N___;
1626 disp_head(0, "");
1627 disp_point( 0, x, y, now_status, ___N___, 0.0f);
1628 }
1629 }
1630 disp_now(
1631 nextturn,
1632 8, 8, now_status, isblue, x, y, org_status
1633 );
1634 disp_tail(nextturn, NULL);
1635 isloop = 0;
1636 }
1637 break;
1638 case ___B___:
1639 if(IS_P2P){
1640 int isblue = 1;
1641 pos_check( 1, ___B___, 8, 8, x, y, now_status);
1642 if(all_pos_check(___W___, &maxi, &maxj, now_status) > 0){
1643 //白完(w要求)
1644 nextturn = ___W___;
1645 disp_head(0, "");
1646 disp_point( 0, x, y, now_status, ___W___, 0.0f);
1647 }else{
1648 if(all_pos_check(___B___, &maxi, &maxj, now_status) > 0){
1649 //青完
1650 disp_head(0, "");
1651 isblue = 1;
1652 disp_point( 0, x, y, now_status, ___B___, 0.0f);
1653 }else{
1654 //相手も自分もおけなかったとき
1655 nextturn = ___N___;
1656 disp_head(0, "");
1657 disp_point( 0, x, y, now_status, ___N___, 0.0f);
1658 }
1659 }
1660 disp_now(
1661 nextturn,
1662 8, 8, now_status, isblue, x, y, org_status
1663 );
1664 disp_tail(nextturn, NULL);
1665 isloop = 0;
1666 }else{
1667 int isblue = 1;
1668
1669 //now_status[ (y-1)*8+(x-1) ] = ___N___;
1670 pos_check( 1, ___B___, 8, 8, x, y, now_status);
1671 if(all_pos_check(___W___, &maxi, &maxj, now_status) > 0){
1672 //青完
1673 disp_head(0, "");
1674 nextturn = ___W___;
1675 end = clock();
1676 disp_point( 0, x, y, now_status, nextturn, ((double)(end-start)/CLOCKS_PER_SEC));
1677 }else{
1678 if(all_pos_check(___B___, &maxi, &maxj, now_status) > 0){
1679 //黒完(w要求)
1680 sprintf( autonext,
1681 "?t=%c&x=%d&y=%d&s=%s",
1682 ___b___,
1683 0,
1684 0,
1685 //now_status
1686 cur2urlcur( url_status, now_status)
1687 );
1688 isblue = 0;
1689 disp_head(1, autonext);
1690 end = clock();
1691 disp_point( 0, x, y, now_status, nextturn, ((double)(end-start)/CLOCKS_PER_SEC));
1692 }else{
1693 //相手も自分もおけなかったとき
1694 nextturn = ___N___;
1695 disp_head(0, "");
1696 end = clock();
1697 disp_point( 0, x, y, now_status, nextturn, ((double)(end-start)/CLOCKS_PER_SEC));
1698 }
1699 }
1700 disp_now(
1701 nextturn,
1702 8, 8, now_status, isblue, x, y, org_status
1703 );
1704
1705 disp_tail(nextturn, NULL);
1706 isloop = 0;
1707 }
1708 break;
1709 case ___N___:
1710 {
1711 disp_head(0, "");
1712 disp_point( 0, x, y, now_status, nextturn, 0.0f);
1713 disp_now(
1714 nextturn,
1715 8, 8, now_status, 0, x, y, org_status
1716 );
1717 disp_tail(nextturn, NULL);
1718 isloop = 0;
1719 }
1720 break;
1721 }
1722 }
1723 }
本発明は、広くゲーム産業、知育産業、教育産業、ボケ防止等に利用可能である。
tottori1 鳥取県の行政区画(県の形)をモチーフにしたゲームへのリンク
wakayama1 和歌山県の行政区画(県の形)をモチーフにしたゲームへのリンク
yoshi ゲームの利用者1(ハイスコア合計が最高の利用者)
KN ゲームの利用者2(ハイスコア合計が4位の利用者)
○ コンピュータ相手のモードにおいて利用者が現在のゲーム状態で駒(白)をおける場所
小さい点 柱
横棒 横の壁(縦方向のはさむ力を遮断する)
縦棒 縦の壁(横方向のはさむ力を遮断する)
wakayama1 和歌山県の行政区画(県の形)をモチーフにしたゲームへのリンク
yoshi ゲームの利用者1(ハイスコア合計が最高の利用者)
KN ゲームの利用者2(ハイスコア合計が4位の利用者)
○ コンピュータ相手のモードにおいて利用者が現在のゲーム状態で駒(白)をおける場所
小さい点 柱
横棒 横の壁(縦方向のはさむ力を遮断する)
縦棒 縦の壁(横方向のはさむ力を遮断する)
Claims (12)
- リバーシ又はリバーシを変形したもののルールの全部又は一部を実施するコンピュータゲーム装置であって、盤の端や角以外のところにも壁(それを縦または横にはさんでは取れないオブジェクト)および又は柱(それを斜めにはさんではとれないオブジェクト)が配置され、コンピュータがゲームの進行にあたり、壁および又は柱に関する前記ルールを適用することを特徴とするコンピュータゲーム装置。
- コンピュータが相手をするモードにおいて、コンピュータが、座標のうち、一方にすぐ壁又は柱がありかつ対応する反対側には壁や柱がなく開いている方向数およびそれぞれの見通しよく開けている度合いが大きい座標(高度一方開放座標と呼ぶ)を優先してとることを特徴とする、請求項1に記載のコンピュータゲーム装置。
- コンピュータが、前記高度一方開放座標に隣接する座標をなるべくとらないようにすることを特徴とする、請求項1に記載のコンピュータゲーム装置。
- 序盤でのみ、前記高度一方開放座標を優先的にとることを特徴とする、請求項1に記載のコンピュータゲーム装置。
- コンピュータが相手をするモードにおいて、コンピュータが、座標のうち、一方にすぐ壁又は柱がありかつ対応する反対側には壁や柱がなく開いている方向数およびそれぞれの見通しよく開けている度合いの大きい座標(高度一方開放座標と呼ぶ)に向けて同様に(一方にすぐ壁又は柱がありかつ対応する反対側には壁や柱がなく)開いている方向数およびそれぞれの高度一方開放座標を含む度合いの大きい座標(高度一方開放座標高度含有一方開放座標と呼ぶ)を優先してとることを特徴とする、請求項1に記載のコンピュータゲーム装置。
- コンピュータが、前記高度一方開放座標高度含有一方開放座標に隣接する座標をなるべくとらないようにすることを特徴とする、請求項1に記載のコンピュータゲーム装置。
- 序盤でのみ、前記高度一方開放座標高度含有一方開放座標を優先的にとることを特徴とする、請求項1に記載のコンピュータゲーム装置。
- コンピュータが相手をするモードにおいて、現在のゲーム状態に対して過去にコンピュータの思考ルーチンが決定した手又は過去に有利に戦った対戦者が決定した手を採用するキャッシュ手段を有する、請求項1に記載のコンピュータゲーム装置。
- コンピュータが相手をするモードにおいて、コンピュータの思考時間の短さの要請および又は先読みの度合いに対応する可能な手順の個数が、CPUおよび又はメモリの能力に比して十分小さくなるように、初期の敵味方駒、前記壁および又は前記柱の量および又は配置が調節された、請求項1に記載のコンピュータゲーム装置。
- コンピュータが相手をするモードにおいて、より上位のハイスコアにスコア自体より大きい重みを与えながら、種々の盤(盤ごとに初期の敵味方駒、前記壁および又は前記柱の量および又は配置が異なる)のハイスコアを合計して表示するハイスコア合計手段を有する、請求項1に記載のコンピュータゲーム装置。
- リバーシ又はリバーシを変形したもののルールの全部又は一部を実施するコンピュータゲームプログラムであって、盤の端や角以外のところにも壁(それを縦または横にはさんでは取れないオブジェクト)および又は柱(それを斜めにはさんではとれないオブジェクト)が配置され、コンピュータがゲームの進行にあたり、壁および又は柱に関する前記ルールを適用することを特徴とするコンピュータゲームプログラム
- 人対人がコンピュータなしで遊べるボードゲーム又は該ボードゲームを変形したもののルールの全部又は一部を実施するコンピュータゲームプログラムであって、盤の端や角以外のところにも壁(縦または横方向に関するゲームルール既定の効果を排除するオブジェクト)および又は柱(斜め方向に関するゲームルール既定の効果を排除するオブジェクト)が配置され、コンピュータがゲームの進行にあたり、壁および又は柱に関する前記ルールを適用することを特徴とするコンピュータゲームプログラム。
Priority Applications (1)
Application Number | Priority Date | Filing Date | Title |
---|---|---|---|
JP2005319260A JP2007135613A (ja) | 2005-10-19 | 2005-11-02 | コンピュータゲーム装置およびコンピュータゲームプログラム |
Applications Claiming Priority (2)
Application Number | Priority Date | Filing Date | Title |
---|---|---|---|
JP2005303801 | 2005-10-19 | ||
JP2005319260A JP2007135613A (ja) | 2005-10-19 | 2005-11-02 | コンピュータゲーム装置およびコンピュータゲームプログラム |
Publications (1)
Publication Number | Publication Date |
---|---|
JP2007135613A true JP2007135613A (ja) | 2007-06-07 |
Family
ID=38199197
Family Applications (1)
Application Number | Title | Priority Date | Filing Date |
---|---|---|---|
JP2005319260A Pending JP2007135613A (ja) | 2005-10-19 | 2005-11-02 | コンピュータゲーム装置およびコンピュータゲームプログラム |
Country Status (1)
Country | Link |
---|---|
JP (1) | JP2007135613A (ja) |
Cited By (1)
Publication number | Priority date | Publication date | Assignee | Title |
---|---|---|---|---|
JP2008279024A (ja) * | 2007-05-09 | 2008-11-20 | Knowrel System Inc | コンピュータゲーム装置、方法およびプログラム |
-
2005
- 2005-11-02 JP JP2005319260A patent/JP2007135613A/ja active Pending
Cited By (1)
Publication number | Priority date | Publication date | Assignee | Title |
---|---|---|---|---|
JP2008279024A (ja) * | 2007-05-09 | 2008-11-20 | Knowrel System Inc | コンピュータゲーム装置、方法およびプログラム |
Similar Documents
Publication | Publication Date | Title |
---|---|---|
US9272219B2 (en) | Three dimensional operations in an isometric projection | |
JP5732559B1 (ja) | コンピュータプログラム、ゲームシステム、及びその制御方法 | |
Ashmore et al. | The quest in a generated world | |
US11395966B2 (en) | Generating game configurations | |
US20160170589A1 (en) | Smart ping system | |
JP2009136411A (ja) | プログラム、情報記憶媒体及びゲーム装置 | |
CN107899246A (zh) | 信息处理方法、装置、电子设备及存储介质 | |
JP2007111355A (ja) | 携帯型ゲーム装置およびゲームシステム | |
JP5827434B2 (ja) | コンピュータプログラム、ゲームシステム、及びその制御方法 | |
KR20230130109A (ko) | 가상 시나리오 디스플레이 방법, 장치, 단말 및 저장매체 | |
KR20120034310A (ko) | 전략 시뮬레이션 방식을 도입한 전투 게임을 제공하기 위한 시스템 및 방법 | |
JP2022048285A (ja) | プログラム、制御方法および情報処理装置 | |
JP6564809B2 (ja) | プログラム、制御方法および情報処理装置 | |
JP2007135613A (ja) | コンピュータゲーム装置およびコンピュータゲームプログラム | |
US20140155160A1 (en) | Gaming system providing a destructible game object mechanic | |
JP6170599B1 (ja) | プログラム、制御方法および情報処理装置 | |
Zackariasson et al. | Creativity in the video game industry | |
George et al. | Developing a Game in Python | |
Patel | Desegmenting a Gameworld: The Super Mario Series | |
Ramos Boira | Application of Wave Function Collapse Algorithm for Procedural Content Generation in Video Games | |
Chen | Tower Defense Game Design based on Unity3D | |
JP5770954B1 (ja) | ゲームプログラム、コンピュータの制御方法、およびコンピュータ | |
Capellman et al. | Animations and Text | |
Oliver | POLYGON DESTINIES | |
Stemkoski et al. | Additional Game Case Studies |