王手確認関数の追加とバグ修正をしました。
ソース:stime_16031001(一部抜粋)
int main()
{
int menuno; //メニュー番号
while (1) {
menuno = menu(); //メニュー番号選択
switch (menuno)
{
case 0: //先手人間vs後手人間の対局(通常ルール)
s_game_set.com = 0; //先手人間
g_game_set.com = 0; //後手人間
s_game_set.tomogui = 0; //先手味方の駒取得禁止
g_game_set.tomogui = 0; //後手味方の駒取得禁止
s_game_set.nifu = 0; //先手二歩禁止
g_game_set.nifu = 0; //後手二歩禁止
break;
case 1: //先手人間vs後手コンピュータの対局(通常ルール)
s_game_set.com = 0; //先手人間
g_game_set.com = 1; //後手コンピュータ
s_game_set.tomogui = 0; //先手味方の駒取得禁止
g_game_set.tomogui = 0; //後手味方の駒取得禁止
s_game_set.nifu = 0; //先手二歩禁止
g_game_set.nifu = 0; //後手二歩禁止
break;
case 2: //先手コンピュータvs後手人間の対局(通常ルール)
s_game_set.com = 1; //先手コンピュータ
g_game_set.com = 0; //後手人間
s_game_set.tomogui = 0; //先手味方の駒取得禁止
g_game_set.tomogui = 0; //後手味方の駒取得禁止
s_game_set.nifu = 0; //先手二歩禁止
g_game_set.nifu = 0; //後手二歩禁止
break;
case 3: //先手コンピュータvs後手コンピュータの対局(通常ルール)
s_game_set.com = 1; //先手コンピュータ
g_game_set.com = 1; //後手コンピュータ
s_game_set.tomogui = 0; //先手味方の駒取得禁止
g_game_set.tomogui = 0; //後手味方の駒取得禁止
s_game_set.nifu = 0; //先手二歩禁止
g_game_set.nifu = 0; //後手二歩禁止
break;
case 4: //先手人間vs後手人間の対局(特殊ルール)
s_game_set.com = 0; //先手人間
g_game_set.com = 0; //後手人間
s_game_set.tomogui = 1; //先手味方の駒取得許可
g_game_set.tomogui = 1; //後手味方の駒取得許可
s_game_set.nifu = 1; //先手二歩許可
g_game_set.nifu = 1; //後手二歩許可
break;
case 5: //先手人間vs後手コンピュータの対局(特殊ルール)
s_game_set.com = 0; //先手人間
g_game_set.com = 1; //後手コンピュータ
s_game_set.tomogui = 1; //先手味方の駒取得許可
g_game_set.tomogui = 1; //後手味方の駒取得許可
s_game_set.nifu = 1; //先手二歩許可
g_game_set.nifu = 1; //後手二歩許可
break;
case 6: //先手コンピュータvs後手人間の対局(特殊ルール)
s_game_set.com = 1; //先手コンピュータ
g_game_set.com = 0; //後手人間
s_game_set.tomogui = 1; //先手味方の駒取得許可
g_game_set.tomogui = 1; //後手味方の駒取得許可
s_game_set.nifu = 1; //先手二歩許可
g_game_set.nifu = 1; //後手二歩許可
break;
case 7: //先手コンピュータvs後手コンピュータの対局(特殊ルール)
s_game_set.com = 1; //先手コンピュータ
g_game_set.com = 1; //後手コンピュータ
s_game_set.tomogui = 1; //先手味方の駒取得許可
g_game_set.tomogui = 1; //後手味方の駒取得許可
s_game_set.nifu = 1; //先手二歩許可
g_game_set.nifu = 1; //後手二歩許可
break;
default:
printf("メニュー番号を入力してください。\n");
break;
}
if (0 <= menuno && menuno <= 7) //メニュー番号が0から7ならループ終了
break;
}
tesuu_n = 0; //手数カウント初期化
gyoku_r = 5; //玉の位置(列)の初期化
gyoku_g = 9; //玉の位置(行)の初期化
ou_r = 5; //王の位置(列)の初期化
ou_g = 1; //王の位置(行)の初期化
system("cls"); //画面クリア
motigoma_hyouji(); //持ち駒表示関数
banmen_hyouji(); //盤面表示関数
/* 指し手ファイルを上書き作成 */
FILE *fp;
fopen_s(&fp, "sasite.txt", "w");
if (fp == NULL) {
perror("ファイル・オープンに失敗しました\n");
return -1;
}
fclose(fp);
while (1){
if (s_game_set.com == 1){
if (sente_sikou() == 1){ //先手がコンピュータの思考関数
printf("\n詰みました。後手の勝利です。");
break;
}
}
else {
if (sente_nyuuryoku() == 1){ //先手の指し手の入力関数
printf("\n詰みました。先手の勝利です。");
break;
}
}
system("cls"); //画面クリア
sasite_hyouji(SENTE); //先手の指し手表示関数
motigoma_hyouji(); //持ち駒表示関数
banmen_hyouji(); //盤面表示関数
if (g_game_set.com == 1){
if (gote_sikou() == 1){ //後手がコンピュータの思考関数
printf("\n詰みました。先手の勝利です。");
break;
}
}
else {
if (gote_nyuuryoku() == 1){ //後手の指し手の入力関数
printf("\n詰みました。後手の勝利です。");
break;
}
}
system("cls"); //画面クリア
sasite_hyouji(GOTE); //後手の指し手表示関数
motigoma_hyouji(); //持ち駒表示関数
banmen_hyouji(); //盤面表示関数
}
return 0;
}
/* 先手の指し手の入力関数 */
int sente_nyuuryoku()
{
SENTE_MOTO: //先手移動元入力
while (1)
{
s_tem_m_koma_n = 0;
sasite_koma_n = 0;
s_te_n = 0;
/* 先手の指し手の移動元(列)の入力 */
printf("\n先手の指し手の移動元(列)か持ち駒(0)を入力してください:");
s_te_m_r = sasite_nyuuryoku(); //指し手を取得
if (s_te_m_r == 0){ //持ち駒が選択された場合
if (s_motigoma.kazu == 0){
printf("\n持ち駒がありません。");
goto SENTE_MOTO; //先手移動元入力やり直し
}
s_motigoma_n = motigoma_nyuuryoku(&s_motigoma);
if (s_motigoma_n > 0){
s_tem_m_koma_n = s_motigoma_n;
sasite_koma_n = s_tem_m_koma_n;
break;
}
else
goto SENTE_MOTO; //先手移動元入力やり直し
}
else {
s_motigoma_n = 0;
/* 先手の指し手の移動元(行)の入力 */
printf("\n先手の指し手の移動元(行)か前に戻る(0)を入力してください:");
s_te_m_g = sasite_nyuuryoku(); //指し手を取得
if (s_te_m_g == 0) //前に戻るが選択された場合
goto SENTE_MOTO; //先手移動元入力やり直し
s_tem_m_koma_n = banmen[s_te_m_g - 1][s_te_m_r - 1]; //先手の指し手の移動元(駒番号)を保存
sasite_koma_n = s_tem_m_koma_n;
}
if (teban_koma_chk(s_tem_m_koma_n, SENTE) == OK) //移動元が先手の駒の場合
break;
else
printf("\n先手の駒を入力してください。");
}
while (1)
{
/* 先手の指し手の移動先(列)の入力 */
printf("\n先手の指し手の移動先(列)か前に戻る(0)を入力してください:");
s_te_s_r = sasite_nyuuryoku(); //指し手を取得
if (s_te_s_r == 0) //前に戻るが選択された場合
goto SENTE_MOTO; //先手移動元入力やり直し
/* 先手の指し手の移動先(行)の入力 */
printf("\n先手の指し手の移動先(行)か前に戻る(0)を入力してください:");
s_te_s_g = sasite_nyuuryoku(); //指し手を取得
if (s_te_s_g == 0) //前に戻るが選択された場合
goto SENTE_MOTO; //先手移動元入力やり直し
s_tem_s_koma_n = banmen[s_te_s_g - 1][s_te_s_r - 1]; //先手の指し手の移動先(駒番号)を保存
if (s_tem_m_koma_n == GYOKU_N) //先手の移動元が玉の場合
{
gyoku_g = s_te_s_g; //玉の移動先(行)の保存
gyoku_r = s_te_s_r; //玉の移動先(列)の保存
}
if (s_motigoma_n > 0) { //持ち駒の場合
banmen[s_te_s_g - 1][s_te_s_r - 1] = s_tem_m_koma_n; //先手の指し手の移動先に移動元の駒を保存(仮)
if (motigoma_ido_chk(s_tem_s_koma_n, s_motigoma_n, SENTE) == NG) { //持ち駒の移動チェックがNGの場合
printf("\n移動可能な移動先を入力してください。");
banmen[s_te_s_g - 1][s_te_s_r - 1] = s_tem_s_koma_n; //先手の指し手の移動先に移動先の駒を戻す
}
else{
motigoma_set(&s_motigoma, s_motigoma_n); //持ち駒の設定関数
break;
}
}
else if (koma_ido_chk(s_tem_m_koma_n, s_te_m_g, s_te_m_r, s_te_s_g, s_te_s_r) == NG) //駒の移動が正しくない場合
printf("\n移動可能な移動先を入力してください。");
else if ((s_game_set.tomogui == 0) && (teban_koma_chk(s_tem_s_koma_n, SENTE) == OK)) //味方の駒取得禁止で移動先が先手の駒の場合
printf("\n味方の駒の位置には移動できません。");
else if (s_tem_s_koma_n == GYOKU_N) //移動先が先手の玉の場合(味方の駒取得可能特別ルール内の例外)
printf("\n移動可能な移動先を入力してください。");
else {
banmen[s_te_m_g - 1][s_te_m_r - 1] = KUHAKU_N; //先手の指し手の移動元に空白を保存
banmen[s_te_s_g - 1][s_te_s_r - 1] = s_tem_m_koma_n; //先手の指し手の移動先に移動元の駒を保存(仮)
if (oute_chk(SENTE) == OK) { //王手の場合
printf("\n王手です。");
banmen[s_te_m_g - 1][s_te_m_r - 1] = s_tem_m_koma_n; //先手の指し手の移動元に移動元の駒を戻す
banmen[s_te_s_g - 1][s_te_s_r - 1] = s_tem_s_koma_n; //先手の指し手の移動先に移動先の駒を戻す
}
else
break;
}
}
if (s_motigoma_n > 0) { //持ち駒の場合
s_te_n = 0; //成らず
return 0;
}
/* 先手の歩か香で移動先が後手陣地の最終行の場合 */
else if (((FU_N == s_tem_m_koma_n) || (KYO_N == s_tem_m_koma_n)) && (s_te_s_g == 1)) {
s_te_n = 1; //成り
s_tem_m_koma_n = s_tem_m_koma_n | NARI_N; //移動元駒をビット和で成駒に変換
/* 先手の桂で移動先が後手陣地の最終と手前行の場合 */
} else if ((KEI_N == s_tem_m_koma_n) && (s_te_s_g < 3)) {
s_te_n = 1; //成り
s_tem_m_koma_n = s_tem_m_koma_n | NARI_N; //移動元駒をビット和で成駒に変換
/* 先手の移動元か移動先が後手陣地の場合 */
} else if (((FU_N <= s_tem_m_koma_n) && (s_tem_m_koma_n <= HI_N) && (s_tem_m_koma_n != KIN_N)) && (s_te_m_g < 4 || s_te_s_g < 4)) {
printf("\n成りますか?(Yes:1, No:0):"); //成るか確認
while (1){
s_te_n = _getche();
if (s_te_n == '1'){ //成りが選択されたら
s_tem_m_koma_n = s_tem_m_koma_n | NARI_N; //移動元駒をビット和で成駒に変換
break; //whileループを抜ける
}
else
{
s_te_n = 0;
break; //whileループを抜ける
}
}
}
motigoma_get(&s_motigoma, s_tem_s_koma_n); //持ち駒取得関数
banmen[s_te_s_g - 1][s_te_s_r - 1] = s_tem_m_koma_n; //先手の指し手の移動先に移動元の駒を保存
return 0;
}
/* 後手の指し手の入力関数 */
int gote_nyuuryoku()
{
GOTE_MOTO: //後手移動元入力
while (1)
{
g_tem_m_koma_n = 0;
sasite_koma_n = 0;
g_te_n = 0;
/* 後手の指し手の移動元(列)の入力 */
printf(AOIRO"\n後手の指し手の移動元(列)か持ち駒(0)を入力してください:"KIHONIRO);
g_te_m_r = sasite_nyuuryoku(); //指し手を取得
if (g_te_m_r == 0){ //持ち駒が選択された場合
if (g_motigoma.kazu == 0){
printf(AOIRO"\n持ち駒がありません。"KIHONIRO);
goto GOTE_MOTO; //後手移動元入力やり直し
}
g_motigoma_n = motigoma_nyuuryoku(&g_motigoma);
if (g_motigoma_n > 0){
g_tem_m_koma_n = g_motigoma_n | GOTE_N; //持ち駒をビット和で後手の駒に変換
sasite_koma_n = g_tem_m_koma_n;
break;
}
}
else {
g_motigoma_n = 0;
/* 後手の指し手の移動元(行)の入力 */
printf(AOIRO"\n後手の指し手の移動元(行)か前に戻る(0)を入力してください:"KIHONIRO);
g_te_m_g = sasite_nyuuryoku(); //指し手を取得
if (g_te_m_g == 0) //前に戻るが選択された場合
goto GOTE_MOTO; //後手移動元入力やり直し
g_tem_m_koma_n = banmen[g_te_m_g - 1][g_te_m_r - 1]; //後手の指し手の移動元(駒番号)を保存
sasite_koma_n = g_tem_m_koma_n;
}
if (teban_koma_chk(g_tem_m_koma_n, GOTE) == OK) //移動元が後手の駒の場合
break;
else
printf(AOIRO"\n後手の駒を入力してください。"KIHONIRO);
}
while (1)
{
/* 後手の指し手の移動先(列)の入力 */
printf(AOIRO"\n後手の指し手の移動先(列)か前に戻る(0)を入力してください:"KIHONIRO);
g_te_s_r = sasite_nyuuryoku(); //指し手を取得
if (g_te_s_r == 0) //前に戻るが選択された場合
goto GOTE_MOTO; //後手移動元入力やり直し
/* 後手の指し手の移動先(行)の入力 */
printf(AOIRO"\n後手の指し手の移動先(行)を入力してください:"KIHONIRO);
g_te_s_g = sasite_nyuuryoku(); //指し手を取得
g_tem_s_koma_n = banmen[g_te_s_g - 1][g_te_s_r - 1]; //後手の指し手の移動先(駒番号)を保存
if (g_tem_m_koma_n == OU_N) //後手の移動元が王の場合
{
ou_g = g_te_s_g; //王の移動先(行)の保存
ou_r = g_te_s_r; //王の移動先(列)の保存
}
if (g_motigoma_n > 0){ //持ち駒の場合
banmen[g_te_s_g - 1][g_te_s_r - 1] = g_tem_m_koma_n; //後手の指し手の移動先に移動元の駒を保存(仮)
if (motigoma_ido_chk(g_tem_s_koma_n, g_motigoma_n, GOTE) == NG) { //持ち駒の移動チェックがNGの場合
printf(AOIRO"\n移動可能な移動先を入力してください。"KIHONIRO);
banmen[g_te_s_g - 1][g_te_s_r - 1] = g_tem_s_koma_n; //後手の指し手の移動先に移動先の駒を戻す
}
else {
motigoma_set(&g_motigoma, g_motigoma_n); //持ち駒の設定関数
break;
}
}
else if (koma_ido_chk(g_tem_m_koma_n, g_te_m_g, g_te_m_r, g_te_s_g, g_te_s_r) == NG) //持ち駒でなく、駒の移動が正しくない場合
printf(AOIRO"\n移動可能な移動先を入力してください。"KIHONIRO);
else if ((g_game_set.tomogui == 0) && (teban_koma_chk(g_tem_s_koma_n, GOTE) == OK)) //味方の駒取得禁止で移動先が後手の駒の場合
printf(AOIRO"\n味方の駒の位置には移動できません。"KIHONIRO);
else if (g_tem_s_koma_n == OU_N) //移動先が後手の王の場合(味方の駒取得可能特別ルール内の例外)
printf(AOIRO"\n移動可能な移動先を入力してください。"KIHONIRO);
else {
banmen[g_te_m_g - 1][g_te_m_r - 1] = KUHAKU_N; //後手の指し手の移動元に空白を保存
banmen[g_te_s_g - 1][g_te_s_r - 1] = g_tem_m_koma_n; //後手の指し手の移動先に移動元の駒を保存(仮)
if (oute_chk(GOTE) == OK) { //王手の場合
printf("\n王手です。");
banmen[g_te_m_g - 1][g_te_m_r - 1] = g_tem_m_koma_n; //後手の指し手の移動元に移動元の駒を戻す
banmen[g_te_s_g - 1][g_te_s_r - 1] = g_tem_s_koma_n; //後手の指し手の移動先に移動先の駒を戻す
}
else
break;
}
}
if (g_motigoma_n > 0) { //持ち駒の場合
g_te_n = 0; //成らず
return 0;
}
/* 後手の歩か香で移動先が先手陣地の最終行の場合 */
else if (((G_FU_N == g_tem_m_koma_n) || (G_KYO_N == g_tem_m_koma_n)) && (g_te_s_g == 9)) {
g_te_n = 1; //成り
g_tem_m_koma_n = g_tem_m_koma_n | NARI_N; //移動元駒をビット和で成駒に変換
/* 後手の桂で移動先が先手陣地の最終と手前行の場合 */
} else if ((G_KEI_N == g_tem_m_koma_n) && (g_te_s_g > 7)) {
g_te_n = 1; //成り
g_tem_m_koma_n = g_tem_m_koma_n | NARI_N; //移動元駒をビット和で成駒に変換
/* 後手の移動元か移動先が先手陣地の場合 */
} else if (((G_FU_N <= g_tem_m_koma_n) && (g_tem_m_koma_n <= G_HI_N) && (g_tem_m_koma_n != G_KIN_N)) && (g_te_m_g > 6 || g_te_s_g > 6)) {
printf(AOIRO"\n成りますか?(Yes:1, No:0):"KIHONIRO); //成るか確認
while (1){
g_te_n = _getche();
if (g_te_n == '1'){ //成りが選択されたら
g_tem_m_koma_n = g_tem_m_koma_n | NARI_N; //移動元駒をビット和で成駒に変換
break; //whileループを抜ける
}
else
{
g_te_n = 0;
break; //whileループを抜ける
}
}
}
motigoma_get(&g_motigoma, g_tem_s_koma_n); //持ち駒取得関数
banmen[g_te_s_g - 1][g_te_s_r - 1] = g_tem_m_koma_n; //後手の指し手の移動先に移動元の駒を保存
return 0;
}
/* 先手がコンピュータの思考関数 */
int sente_sikou()
{
int i, j;
int x, y;
s_tem_m_koma_n = 0;
sasite_koma_n = 0;
if (s_motigoma.kazu > 0){ //持ち駒があるなら優先的に使用
if (s_motigoma.hi > 0){
s_motigoma_n = HI_N;
}
else if (s_motigoma.kaku > 0){
s_motigoma_n = KAKU_N;
}
else if (s_motigoma.kin > 0){
s_motigoma_n = KIN_N;
}
else if (s_motigoma.gin > 0){
s_motigoma_n = GIN_N;
}
else if (s_motigoma.kei > 0){
s_motigoma_n = KEI_N;
}
else if (s_motigoma.kyo > 0){
s_motigoma_n = KYO_N;
}
else if (s_motigoma.fu > 0){
s_motigoma_n = FU_N;
}
s_tem_m_koma_n = s_motigoma_n;
sasite_koma_n = s_tem_m_koma_n;
goto SENTE_SAKI;
}
else {
SENTE_MOTO:
s_motigoma_n = 0;
for (i = 1; i <= 9; i++)
{
for (j = 1; j <= 9; j++)
{
s_tem_m_koma_n = banmen[i - 1][j - 1]; //先手の指し手の移動元(駒番号)を保存
if (teban_koma_chk(s_tem_m_koma_n, SENTE) == OK){ //移動元が先手の駒の場合
s_te_m_r = j; //移動元列を取得
s_te_m_g = i; //移動元行を取得
SENTE_SAKI:
for (x = 1; x <= 9; x++)
{
for (y = 1; y <= 9; y++)
{
s_te_s_r = y; //移動先列を取得
s_te_s_g = x; //移動先行を取得
s_tem_s_koma_n = banmen[s_te_s_g - 1][s_te_s_r - 1]; //先手の指し手の移動先(駒番号)を保存
if (s_tem_m_koma_n == GYOKU_N) //先手の移動元が玉の場合
{
gyoku_g = s_te_s_g; //玉の移動先(行)の保存
gyoku_r = s_te_s_r; //玉の移動先(列)の保存
}
if (s_motigoma_n > 0) { //持ち駒の場合
banmen[s_te_s_g - 1][s_te_s_r - 1] = s_tem_m_koma_n; //先手の指し手の移動先に移動元の駒を保存(仮)
if (motigoma_ido_chk(s_tem_s_koma_n, s_motigoma_n, SENTE) == NG) { //持ち駒の移動チェックがNGの場合
banmen[s_te_s_g - 1][s_te_s_r - 1] = s_tem_s_koma_n; //先手の指し手の移動先に移動先の駒を戻す
if ((x == 9) && (y == 9)) //持ち駒が盤面に打てない時
goto SENTE_MOTO;
else
continue;
}
else {
motigoma_set(&s_motigoma, s_motigoma_n); //持ち駒の設定関数
goto SENTE_END;
}
}
else if ((koma_ido_chk(s_tem_m_koma_n, s_te_m_g, s_te_m_r, s_te_s_g, s_te_s_r) == NG) //持ち駒でなく、駒の移動が正しくない場合
|| ((s_game_set.tomogui == 0) && (teban_koma_chk(s_tem_s_koma_n, SENTE) == OK))) { //味方の駒取得禁止で移動先が先手の駒の場合
if ((x == 9) && (y == 9)) { //移動先がない時
if ((i == 9) && (j == 9)) //指し手がない時
return 1; //詰み(後手の勝利)
else {
if (s_tem_m_koma_n == GYOKU_N) //先手の移動元が玉の場合
{
gyoku_g = s_te_m_g; //玉の移動先(行)の戻し
gyoku_r = s_te_m_r; //玉の移動先(列)の戻し
}
goto SENTE_MOTO_NEXT;
}
}
else
continue;
}
else if (s_tem_s_koma_n == GYOKU_N) { //移動先が先手の玉の場合(味方の駒取得可能特別ルール内の例外)
if ((x == 9) && (y == 9)) { //移動先がない時
if ((i == 9) && (j == 9)) //指し手がない時
return 1; //詰み(先手の勝利)
else
continue;
}
else
continue;
}
else{
banmen[s_te_m_g - 1][s_te_m_r - 1] = KUHAKU_N; //先手の指し手の移動元に空白を保存
banmen[s_te_s_g - 1][s_te_s_r - 1] = s_tem_m_koma_n; //先手の指し手の移動先に移動元の駒を保存(仮)
if (oute_chk(SENTE) == OK) { //王手の場合
if ((x == 9) && (y == 9)) //指し手がない時
return 1; //詰み(後手の勝利)
banmen[s_te_m_g - 1][s_te_m_r - 1] = s_tem_m_koma_n; //先手の指し手の移動元に移動元の駒を戻す
banmen[s_te_s_g - 1][s_te_s_r - 1] = s_tem_s_koma_n; //先手の指し手の移動先に移動先の駒を戻す
}
else
goto SENTE_END;
}
}
}
}
else if ((i == 9) && (j == 9)) //指し手がない時
return 1; //詰み(後手の勝利)
SENTE_MOTO_NEXT:
printf(""); //ラベルの次の文がないとエラーになるため
}
}
}
SENTE_END:
sasite_koma_n = s_tem_m_koma_n;
if (s_motigoma_n > 0) { //持ち駒の場合
s_te_n = 0; //成らず
return 0;
}
/* 先手の歩か香で移動先が後手陣地の最終行の場合 */
else if (((FU_N == s_tem_m_koma_n) || (KYO_N == s_tem_m_koma_n)) && (s_te_s_g == 1)){
s_te_n = 1; //成り
s_tem_m_koma_n = s_tem_m_koma_n | NARI_N; //移動元駒をビット和で成駒に変換
}
/* 先手の桂で移動先が後手陣地の最終と手前行の場合 */
else if ((KEI_N == s_tem_m_koma_n) && (s_te_s_g < 3)){
s_te_n = 1; //成り
s_tem_m_koma_n = s_tem_m_koma_n | NARI_N; //移動元駒をビット和で成駒に変換
}
/* 先手の移動元か移動先が後手陣地で移動元が持ち駒でない場合 */
else if (((FU_N <= s_tem_m_koma_n) && (s_tem_m_koma_n <= HI_N) && (s_tem_m_koma_n != KIN_N)) && (s_te_m_g < 4 || s_te_s_g < 4)) {
s_te_n = 1; //成り優先
if (s_te_n == '1'){ //成りが選択されたら
s_tem_m_koma_n = s_tem_m_koma_n | NARI_N; //移動元駒をビット和で成駒に変換
}
}
motigoma_get(&s_motigoma, s_tem_s_koma_n); //持ち駒取得関数
banmen[s_te_s_g - 1][s_te_s_r - 1] = s_tem_m_koma_n; //先手の指し手の移動先に移動元の駒を保存
return 0;
}
/* 後手がコンピュータの思考関数 */
int gote_sikou()
{
int i, j;
int x, y;
g_tem_m_koma_n = 0;
sasite_koma_n = 0;
if (g_motigoma.kazu > 0){ //持ち駒があるなら優先的に使用
if (g_motigoma.hi > 0){
g_motigoma_n = HI_N;
}
else if (g_motigoma.kaku > 0){
g_motigoma_n = KAKU_N;
}
else if (g_motigoma.kin > 0){
g_motigoma_n = KIN_N;
}
else if (g_motigoma.gin > 0){
g_motigoma_n = GIN_N;
}
else if (g_motigoma.kei > 0){
g_motigoma_n = KEI_N;
}
else if (g_motigoma.kyo > 0){
g_motigoma_n = KYO_N;
}
else if (g_motigoma.fu > 0){
g_motigoma_n = FU_N;
}
g_tem_m_koma_n = g_motigoma_n | GOTE_N; //持ち駒をビット和で後手の駒に変換
sasite_koma_n = g_tem_m_koma_n;
goto GOTE_SAKI;
}
else {
GOTE_MOTO:
g_motigoma_n = 0;
for (i = 1; i <= 9; i++)
{
for (j = 1; j <= 9; j++)
{
g_tem_m_koma_n = banmen[i - 1][j - 1]; //後手の指し手の移動元(駒番号)を保存
if (teban_koma_chk(g_tem_m_koma_n, GOTE) == OK){ //移動元が後手の駒の場合
g_te_m_r = j; //移動元列を取得
g_te_m_g = i; //移動元行を取得
GOTE_SAKI:
for (x = 1; x <= 9; x++)
{
for (y = 1; y <= 9; y++)
{
g_te_s_r = y; //移動先列を取得
g_te_s_g = x; //移動先行を取得
g_tem_s_koma_n = banmen[g_te_s_g - 1][g_te_s_r - 1]; //先手の指し手の移動先(駒番号)を保存
if (g_tem_m_koma_n == OU_N) //後手の移動元が王の場合
{
ou_g = g_te_s_g; //王の移動先(行)の保存
ou_r = g_te_s_r; //王の移動先(列)の保存
}
if (g_motigoma_n > 0) { //持ち駒の場合
if (motigoma_ido_chk(g_tem_s_koma_n, g_motigoma_n, GOTE) == NG) { //持ち駒の移動チェックがNGの場合
if ((x == 9) && (y == 9)) //持ち駒が盤面に打てない時
goto GOTE_MOTO;
else
continue;
} else {
motigoma_set(&g_motigoma, g_motigoma_n); //持ち駒の設定関数
goto GOTE_END;
}
}
else if ((koma_ido_chk(g_tem_m_koma_n, g_te_m_g, g_te_m_r, g_te_s_g, g_te_s_r) == NG) //持ち駒でなく、駒の移動が正しくない場合
|| ((g_game_set.tomogui == 0) && (teban_koma_chk(g_tem_s_koma_n, GOTE) == OK))) { //味方の駒取得禁止で移動先が後手の駒の場合
if ((x == 9) && (y == 9)) { //移動先がない時
if ((i == 9) && (j == 9)) //指し手がない時
return 1; //詰み(先手の勝利)
else {
if (g_tem_m_koma_n == OU_N) //後手の移動元が王の場合
{
ou_g = g_te_m_g; //王の移動先(行)の戻し
ou_r = g_te_m_r; //王の移動先(列)の戻し
}
goto GOTE_MOTO_NEXT;
}
}
else
continue;
}
else if (g_tem_s_koma_n == OU_N) { //移動先が後手の王の場合(味方の駒取得可能特別ルール内の例外)
if ((x == 9) && (y == 9)) { //移動先がない時
if ((i == 9) && (j == 9)) //指し手がない時
return 1; //詰み(先手の勝利)
else
continue;
}
else
continue;
}
else {
banmen[g_te_m_g - 1][g_te_m_r - 1] = KUHAKU_N; //後手の指し手の移動元に空白を保存
banmen[g_te_s_g - 1][g_te_s_r - 1] = g_tem_m_koma_n; //後手の指し手の移動先に移動元の駒を保存(仮)
if (oute_chk(GOTE) == OK) { //王手の場合
if ((x == 9) && (y == 9)) { //移動先がない時
if ((i == 9) && (j == 9)) //指し手がない時
return 1; //詰み(先手の勝利)
}
banmen[g_te_m_g - 1][g_te_m_r - 1] = g_tem_m_koma_n; //後手の指し手の移動元に移動元の駒を戻す
banmen[g_te_s_g - 1][g_te_s_r - 1] = g_tem_s_koma_n; //後手の指し手の移動先に移動先の駒を戻す
}
else {
goto GOTE_END;
}
}
}
}
}
else if ((i == 9) && (j == 9)) //指し手がない時
return 1; //詰み(先手の勝利)
GOTE_MOTO_NEXT:
printf(""); //ラベルの次の文がないとエラーになるため
}
}
}
GOTE_END:
sasite_koma_n = g_tem_m_koma_n;
if (g_motigoma_n > 0) { //持ち駒の場合
g_te_n = 0; //成らず
return 0;
}
/* 後手の歩か香で移動先が先手陣地の最終行の場合 */
else if (((G_FU_N == g_tem_m_koma_n) || (G_KYO_N == g_tem_m_koma_n)) && (g_te_s_g == 9)){
g_te_n = 1; //成り
g_tem_m_koma_n = g_tem_m_koma_n | NARI_N; //移動元駒をビット和で成駒に変換
}
/* 後手の桂で移動先が先手陣地の最終と手前行の場合 */
else if ((G_KEI_N == g_tem_m_koma_n) && (g_te_s_g > 7)){
g_te_n = 1; //成り
g_tem_m_koma_n = g_tem_m_koma_n | NARI_N; //移動元駒をビット和で成駒に変換
}
/* 先手の移動元か移動先が後手陣地で移動元が持ち駒でない場合 */
else if (((G_FU_N <= g_tem_m_koma_n) && (g_tem_m_koma_n <= G_HI_N) && (g_tem_m_koma_n != G_KIN_N)) && (g_te_m_g > 6 || g_te_s_g > 6)) {
g_te_n = 1; //成り優先
if (g_te_n == '1'){ //成りが選択されたら
g_tem_m_koma_n = g_tem_m_koma_n | NARI_N; //移動元駒をビット和で成駒に変換
}
}
motigoma_get(&g_motigoma, g_tem_s_koma_n); //持ち駒取得関数
banmen[g_te_s_g - 1][g_te_s_r - 1] = g_tem_m_koma_n; //先手の指し手の移動先に移動元の駒を保存
return 0;
}
/* 持ち駒の移動確認関数 */
int motigoma_ido_chk(int saki_koma_n, int motigoma_koma_n, int teban)
{
int i;
if (saki_koma_n != KUHAKU_N) //駒のある移動先の場合
return NG;
/* 持ち駒が歩か香の場合 */
else if ((motigoma_koma_n == FU_N) || (motigoma_koma_n == KYO_N)) {
/* 移動先が相手陣地の最終行の場合 */
if (((teban == SENTE) && (s_te_s_g == 1)) || ((teban == GOTE) && (g_te_s_g == 9)))
return NG;
/* 持ち駒が桂の場合 */
} else if (motigoma_koma_n == KEI_N) {
/* 移動先が相手陣地の最終と手前行の場合 */
if (((teban == SENTE) && (s_te_s_g < 3)) || ((teban == GOTE) && (g_te_s_g > 7)))
return NG;
}
/* 先手番で先手二歩禁止で持ち駒が歩の場合 */
if ((teban == SENTE) && (s_game_set.nifu == 0) && (motigoma_koma_n == FU_N)) {
/* 移動先の列に先手の歩があるか */
for (i = 1; i <= 9; i++)
{
if (banmen[i - 1][s_te_s_r - 1] == FU_N){
if (s_game_set.com == 0) //先手人間の場合
printf("\n二歩です。");
return NG;
}
}
/* 後手番で後手二歩禁止で持ち駒が歩の場合 */
}
else if ((teban == GOTE) && (g_game_set.nifu == 0) && (motigoma_koma_n == FU_N)) {
/* 移動先の列に後手の歩があるか */
for (i = 1; i <= 9; i++)
{
if (banmen[i - 1][g_te_s_r - 1] == G_FU_N){
if (g_game_set.com == 0) //後手人間の場合
printf("\n二歩です。");
return NG;
}
}
}
/* 王手の場合 */
if (oute_chk(teban) == OK)
{
if (((teban == SENTE) && (s_game_set.com == 0)) || ((teban == GOTE) && (g_game_set.com == 0))) //先手番で先手人間か後手番で後手人間の場合
printf("\n王手です。");
return NG;
}
return OK;
}
/* 王手の確認関数確認関数 */
int oute_chk(int teban)
{
int i, j;
for (i = 1; i <= 9; i++)
{
for (j = 1; j <= 9; j++)
{
if ((teban == SENTE) && (teban_koma_chk(banmen[i - 1][j - 1], GOTE) == OK)) { //先手番で後手の駒の場合
if ((koma_ido_chk(banmen[i - 1][j - 1], i, j, gyoku_g, gyoku_r) == OK)) //後手の駒が玉に移動可能な場合
return OK;
}
if ((teban == GOTE) && (teban_koma_chk(banmen[i - 1][j - 1], SENTE) == OK)) { //後手番で先手の駒の場合
if ((koma_ido_chk(banmen[i - 1][j - 1], i, j, ou_g, ou_r) == OK)) { //先手の駒が王に移動可能な場合
return OK;
}
}
}
}
return NG;
}










