王手確認関数の追加とバグ修正をしました。


ソース: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;
}


将時画面16031001


二歩の判定を入れました。


ソース:stime_16030701(一部抜粋)


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; //手数カウント初期化
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(AOIRO"\n詰みました。後手の勝利です。"KIHONIRO);
break;
}
}
else {
if (gote_nyuuryoku() == 1){ //後手の指し手の入力関数
printf(AOIRO"\n詰みました。後手の勝利です。"KIHONIRO);
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;

/* 先手の指し手の移動元(列)の入力 */
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_motigoma_n > 0) { //持ち駒の場合
if (motigoma_ido_chk(s_tem_s_koma_n, s_motigoma_n, SENTE) == NG) //持ち駒の移動チェックがNGの場合
printf("\n移動可能な移動先を入力してください。");
else{
motigoma_set(&s_motigoma, s_motigoma_n); //持ち駒の設定関数
break;
}
}
else if ((s_game_set.tomogui == 0) && (teban_koma_chk(s_tem_s_koma_n, SENTE) == OK)) //味方の駒取得禁止で移動先が先手の駒の場合
printf("\n味方の駒の位置には移動できません。");
else if (koma_ido_chk(s_tem_m_koma_n, s_te_m_r, s_te_m_g, s_te_s_r, s_te_s_g) == NG) //駒の移動が正しくない場合
printf("\n移動可能な移動先を入力してください。");
else if (s_tem_s_koma_n == OU_N) //移動先が後手の王の場合
return 1; //詰み(先手の勝利)
else if (s_tem_s_koma_n == GYOKU_N) //移動先が先手の玉の場合(味方の駒取得可能特別ルール内の例外)
printf("\n移動可能な移動先を入力してください。");
else
break;
}

if (s_motigoma_n > 0) { //持ち駒の場合
s_te_n = 0; //成らず
banmen[s_te_s_g - 1][s_te_s_r - 1] = s_tem_m_koma_n; //先手の指し手の移動先に移動元の駒を保存
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ループを抜ける
}
}
}

banmen[s_te_m_g - 1][s_te_m_r - 1] = KUHAKU_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 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){
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){
printf("\n二歩です。");
return NG;
}
}
}
return OK;
}


将時画面16030701


通常ルールは味方の駒取得できないようにとバグ修正しました。

特殊ルールとして、味方の駒取得可能ルールも面白そうなので、残しておきます。


ソース:stime_16030302(一部抜粋)


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; //後手味方の駒取得禁止
break;
case 1: //先手人間vs後手コンピュータの対局(通常ルール)
s_game_set.com = 0; //先手人間
g_game_set.com = 1; //後手コンピュータ
s_game_set.tomogui = 0; //先手味方の駒取得禁止
g_game_set.tomogui = 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; //後手味方の駒取得禁止
break;
case 3: //先手コンピュータvs後手コンピュータの対局(通常ルール)
s_game_set.com = 1; //先手コンピュータ
g_game_set.com = 1; //後手コンピュータ
s_game_set.tomogui = 0; //先手味方の駒取得禁止
g_game_set.tomogui = 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; //後手味方の駒取得許可
break;
case 5: //先手人間vs後手コンピュータの対局(特殊ルール)
s_game_set.com = 0; //先手人間
g_game_set.com = 1; //後手コンピュータ
s_game_set.tomogui = 1; //先手味方の駒取得許可
g_game_set.tomogui = 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; //後手味方の駒取得許可
break;
case 7: //先手コンピュータvs後手コンピュータの対局(特殊ルール)
s_game_set.com = 1; //先手コンピュータ
g_game_set.com = 1; //後手コンピュータ
s_game_set.tomogui = 1; //先手味方の駒取得許可
g_game_set.tomogui = 1; //後手味方の駒取得許可
break;
default:
printf("メニュー番号を入力してください。\n");
break;
}
if (0 <= menuno && menuno <= 7) //メニュー番号が0から7ならループ終了
break;
}

tesuu_n = 0; //手数カウント初期化
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(AOIRO"\n詰みました。後手の勝利です。"KIHONIRO);
break;
}
}
else {
if (gote_nyuuryoku() == 1){ //後手の指し手の入力関数
printf(AOIRO"\n詰みました。後手の勝利です。"KIHONIRO);
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;

/* 先手の指し手の移動元(列)の入力 */
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_motigoma_n > 0) { //持ち駒の場合
if (motigoma_ido_chk(s_tem_s_koma_n, s_motigoma_n, SENTE) == NG) //持ち駒の移動チェックがNGの場合
printf("\n移動可能な移動先を入力してください。");
else{
motigoma_set(&s_motigoma, s_motigoma_n); //持ち駒の設定関数
break;
}
}
else if ((s_game_set.tomogui == 0) && (teban_koma_chk(s_tem_s_koma_n, SENTE) == OK)) //味方の駒取得禁止で移動先が先手の駒の場合
printf("\n移動可能な移動先を入力してください。");
else if (koma_ido_chk(s_tem_m_koma_n, s_te_m_r, s_te_m_g, s_te_s_r, s_te_s_g) == NG) //駒の移動が正しくない場合
printf("\n移動可能な移動先を入力してください。");
else if (s_tem_s_koma_n == OU_N) //移動先が後手の王の場合
return 1; //詰み(先手の勝利)
else if (s_tem_s_koma_n == GYOKU_N) //移動先が先手の玉の場合(味方の駒取得可能特別ルール内の例外)
printf("\n移動可能な移動先を入力してください。");
else
break;
}

if (s_motigoma_n > 0) //持ち駒の場合
s_te_n = 0; //成らず
/* 先手の歩か香で移動先が後手陣地の最終行の場合 */
else if (((FU_N == s_tem_m_koma_n) || (KYO_N == s_tem_m_koma_n)) && (s_te_s_g == 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_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ループを抜ける
}
}
}

banmen[s_te_m_g - 1][s_te_m_r - 1] = KUHAKU_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_nyuuryoku()
{

GOTE_MOTO: //後手移動元入力

while (1)
{
g_tem_m_koma_n = 0;
sasite_koma_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_motigoma_n > 0){ //持ち駒の場合
if (motigoma_ido_chk(g_tem_s_koma_n, g_motigoma_n, GOTE) == NG) //持ち駒の移動チェックがNGの場合
printf(AOIRO"\n移動可能な移動先を入力してください。"KIHONIRO);
else {
motigoma_set(&g_motigoma, g_motigoma_n); //持ち駒の設定関数
break;
}
}
else if ((g_game_set.tomogui == 0) && (teban_koma_chk(g_tem_s_koma_n, GOTE) == OK)) //味方の駒取得禁止で移動先が後手の駒の場合
printf(AOIRO"\n移動可能な移動先を入力してください。"KIHONIRO);
else if (koma_ido_chk(g_tem_m_koma_n, g_te_m_r, g_te_m_g, g_te_s_r, g_te_s_g) == NG) //持ち駒でなく、駒の移動が正しくない場合
printf(AOIRO"\n移動可能な移動先を入力してください。"KIHONIRO);
else if (g_tem_s_koma_n == GYOKU_N) //移動先が先手の玉の場合
return 1; //詰み(後手の勝利)
else if (g_tem_s_koma_n == OU_N) //移動先が後手の王の場合(味方の駒取得可能特別ルール内の例外)
printf(AOIRO"\n移動可能な移動先を入力してください。"KIHONIRO);
else
break;
}

if (g_motigoma_n > 0) //持ち駒の場合
g_te_n = 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_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_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ループを抜ける
}
}
}

banmen[g_te_m_g - 1][g_te_m_r - 1] = KUHAKU_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 menu()
{
char ret[8];

while (1) {
printf("将時\n");
printf("************************************************************\n");
printf("0:先手人間vs後手人間の対局(通常ルール)\n");
printf("1:先手人間vs後手コンピュータの対局(通常ルール)\n");
printf("2:先手コンピュータvs後手人間の対局(通常ルール)\n");
printf("3:先手コンピュータvs後手コンピュータの対局(通常ルール)\n");
printf("4:先手人間vs後手人間の対局(特殊ルール)\n");
printf("5:先手人間vs後手コンピュータの対局(特殊ルール)\n");
printf("6:先手コンピュータvs後手人間の対局(特殊ルール)\n");
printf("7:先手コンピュータvs後手コンピュータの対局(特殊ルール)\n");
printf("************************************************************\n");
printf("メニュー番号を入力してください。:");
fgets(ret, sizeof(ret), stdin);
ret[1] = '\0';
if (ret[0] < '0' || ret[0] > '7') {
printf("番号が不正です。\n");
continue;
}
return atoi(ret);
}
}

/* 先手がコンピュータの思考関数 */
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;
}
else {
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; //移動元行を取得
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_motigoma_n > 0) { //持ち駒の場合
if (motigoma_ido_chk(s_tem_s_koma_n, s_motigoma_n, SENTE) == NG) //持ち駒の移動チェックがNGの場合
continue;
else {
motigoma_set(&s_motigoma, s_motigoma_n); //持ち駒の設定関数
goto SENTE_END;
}
}
else if ((s_game_set.tomogui == 0) && (teban_koma_chk(s_tem_s_koma_n, SENTE) == OK)) //味方の駒取得禁止で移動先が先手の駒の場合
continue;
else if (koma_ido_chk(s_tem_m_koma_n, s_te_m_r, s_te_m_g, s_te_s_r, s_te_s_g) == NG) //持ち駒でなく、駒の移動が正しくない場合
continue;
else if (s_tem_s_koma_n == OU_N) //移動先が後手の王の場合
return 1; //詰み(先手の勝利)
else if (s_tem_s_koma_n == GYOKU_N) //移動先が先手の玉の場合(味方の駒取得可能特別ルール内の例外)
continue;
else
goto SENTE_END;
}
}
}
}
}
}

SENTE_END:

sasite_koma_n = s_tem_m_koma_n;

if (s_motigoma_n > 0) //持ち駒の場合
s_te_n = 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; //移動元駒をビット和で成駒に変換
}
}

banmen[s_te_m_g - 1][s_te_m_r - 1] = KUHAKU_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;
}
else {
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; //移動元行を取得
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_motigoma_n > 0) { //持ち駒の場合
if (motigoma_ido_chk(g_tem_s_koma_n, g_motigoma_n, GOTE) == NG) //持ち駒の移動チェックがNGの場合
continue;
else {
motigoma_set(&g_motigoma, g_motigoma_n); //持ち駒の設定関数
goto GOTE_END;
}
}
else if ((g_game_set.tomogui == 0) && (teban_koma_chk(g_tem_s_koma_n, GOTE) == OK)) //味方の駒取得禁止で移動先が後手の駒の場合
continue;
else if (koma_ido_chk(g_tem_m_koma_n, g_te_m_r, g_te_m_g, g_te_s_r, g_te_s_g) == NG) //持ち駒でなく、駒の移動が正しくない場合
continue;
else if (g_tem_s_koma_n == OU_N) //移動先が後手の王の場合
return 1; //詰み(先手の勝利)
else if (g_tem_s_koma_n == GYOKU_N) //移動先が先手の玉の場合(味方の駒取得可能特別ルール内の例外)
continue;
else
goto GOTE_END;
}
}
}
}
}
}

GOTE_END:

sasite_koma_n = g_tem_m_koma_n;

if (g_motigoma_n > 0) //持ち駒の場合
g_te_n = 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; //移動元駒をビット和で成駒に変換
}
}

banmen[g_te_m_g - 1][g_te_m_r - 1] = KUHAKU_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;
}


将時画面16030302


コンピュータの最初の思考ルーチンの追加とバグ修正しました。

コンピュータは持ち駒の大駒を先に使用で盤面の小さい方から見つかった手を打つだけです。


ソース:stime_16030301一部抜粋

int main()
{

int menuno; //メニュー番号

while (1) {
menuno = menu(); //メニュー番号選択
switch (menuno)
{
case 0: //先手人間vs後手人間の対局
s_game_set.com = 0; //先手人間
g_game_set.com = 0; //後手人間
break;
case 1: //先手人間vs後手コンピュータの対局
s_game_set.com = 0; //先手人間
g_game_set.com = 1; //後手コンピュータ
break;
case 2: //先手コンピュータvs後手人間の対局
s_game_set.com = 1; //先手コンピュータ
g_game_set.com = 0; //後手人間
break;
case 3: //先手コンピュータvs後手コンピュータの対局
s_game_set.com = 1; //先手コンピュータ
g_game_set.com = 1; //後手コンピュータ
break;
default:
printf("メニュー番号を入力してください。\n");
break;
}
if (0 <= menuno && menuno <= 3) //メニュー番号が0から3ならループ終了
break;
}

tesuu_n = 0; //手数カウント初期化
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(AOIRO"\n詰みました。後手の勝利です。"KIHONIRO);
break;
}
}
else {
if (gote_nyuuryoku() == 1){ //後手の指し手の入力関数
printf(AOIRO"\n詰みました。後手の勝利です。"KIHONIRO);
break;
}
}

system("cls"); //画面クリア
sasite_hyouji(GOTE); //後手の指し手表示関数
motigoma_hyouji(); //持ち駒表示関数
banmen_hyouji(); //盤面表示関数
}

return 0;
}

/* 先手がコンピュータの思考関数 */
int sente_sikou()
{
int i, j;

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;
}
else {
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; //移動元行を取得
goto MOTO_END;
}
}
}

MOTO_END:

sasite_koma_n = s_tem_m_koma_n;
}

for (i = 1; i <= 9; i++)
{
for (j = 1; j <= 9; j++)
{
s_te_s_r = j; //移動先列を取得
s_te_s_g = i; //移動先行を取得

s_tem_s_koma_n = banmen[s_te_s_g - 1][s_te_s_r - 1]; //先手の指し手の移動先(駒番号)を保存
if (s_motigoma_n > 0) { //持ち駒の場合
if (motigoma_ido_chk(s_tem_s_koma_n, s_motigoma_n, SENTE) == NG) //持ち駒の移動チェックがNGの場合
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_r, s_te_m_g, s_te_s_r, s_te_s_g) == NG) //持ち駒でなく、駒の移動が正しくない場合
continue;
else if (s_tem_s_koma_n == OU_N) //移動先が後手の王の場合
return 1; //詰み(先手の勝利)
else if (s_tem_s_koma_n == GYOKU_N) //移動先が先手の玉の場合(味方の駒取得可能特別ルール内の例外)
continue;
else
goto SENTE_END;
}
}

SENTE_END:

if (s_motigoma_n > 0) //持ち駒の場合
s_te_n = 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; //移動元駒をビット和で成駒に変換
}
}

banmen[s_te_m_g - 1][s_te_m_r - 1] = KUHAKU_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;

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;
}
else {
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; //移動元行を取得
goto MOTO_END;
}
}
}

MOTO_END:

sasite_koma_n = g_tem_m_koma_n;
}

for (i = 1; i <= 9; i++)
{
for (j = 1; j <= 9; j++)
{
g_te_s_r = j; //移動先列を取得
g_te_s_g = i; //移動先行を取得

g_tem_s_koma_n = banmen[g_te_s_g - 1][g_te_s_r - 1]; //先手の指し手の移動先(駒番号)を保存
if (g_motigoma_n > 0) { //持ち駒の場合
if (motigoma_ido_chk(g_tem_s_koma_n, g_motigoma_n, GOTE) == NG) //持ち駒の移動チェックがNGの場合
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_r, g_te_m_g, g_te_s_r, g_te_s_g) == NG) //持ち駒でなく、駒の移動が正しくない場合
continue;
else if (g_tem_s_koma_n == OU_N) //移動先が後手の王の場合
return 1; //詰み(先手の勝利)
else if (g_tem_s_koma_n == GYOKU_N) //移動先が先手の玉の場合(味方の駒取得可能特別ルール内の例外)
continue;
else
goto GOTE_END;
}
}

GOTE_END:

if (g_motigoma_n > 0) //持ち駒の場合
g_te_n = 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; //移動元駒をビット和で成駒に変換
}
}

banmen[g_te_m_g - 1][g_te_m_r - 1] = KUHAKU_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;
}


将時画面16030301




メニュー関数を追加しました。


ソース:stime_16022905


/* stime.c */

#define KUHAKU " " //KUHAKUを" "と定義

#define OK 0 //OKを0と定義
#define NG -1 //NGを-1と定義

#define FU "歩" //FUを歩と定義
#define KYO "香" //KYOを香と定義
#define KEI "桂" //KEIを桂と定義
#define GIN "銀" //GINを銀と定義
#define KIN "金" //KINを金と定義
#define KAKU "角" //KAKUを角と定義
#define HI "飛" //HIを飛と定義
#define GYOKU "玉" //GYOKUを玉と定義

#define AOIRO "\x1b[34m" //AOIROを青色のエスケープシーケンスと定義
#define KIHONIRO "\x1b[39m" //KIHONIROを基本色のエスケープシーケンスと定義
#define B_AKA "\x1b[41m" //B_AKAを赤色背景のエスケープシーケンスと定義
#define B_AOIRO "\x1b[44m" //B_AOIROを青色背景のエスケープシーケンスと定義
#define B_KIHONIRO "\x1b[49m" //B_KIHONIROを基本色背景のエスケープシーケンスと定義

#define G_FU AOIRO"歩"KIHONIRO //G_FUを青色の歩と定義
#define G_KYO AOIRO"香"KIHONIRO //G_KYOを青色の香と定義
#define G_KEI AOIRO"桂"KIHONIRO //G_KEIを青色の桂と定義
#define G_GIN AOIRO"銀"KIHONIRO //G_GINを青色の銀と定義
#define G_KIN AOIRO"金"KIHONIRO //G_KINを青色の金と定義
#define G_KAKU AOIRO"角"KIHONIRO //G_KAKUを青色の角と定義
#define G_HI AOIRO"飛"KIHONIRO //G_HIを青色の飛と定義
#define OU AOIRO"王"KIHONIRO //OUを青色の王と定義

#define N_FU B_AKA"と"B_KIHONIRO //N_FUを赤色背景のとと定義
#define N_KYO B_AKA"香"B_KIHONIRO //N_KYOを赤色背景の香と定義
#define N_KEI B_AKA"桂"B_KIHONIRO //N_KEIを赤色背景の桂と定義
#define N_GIN B_AKA"銀"B_KIHONIRO //N_GINを赤色背景の銀と定義
#define N_KAKU B_AKA"馬"B_KIHONIRO //N_KAKUを赤色背景の馬と定義
#define N_HI B_AKA"龍"B_KIHONIRO //N_HIを赤色背景の龍と定義

#define N_G_FU B_AOIRO"と"B_KIHONIRO //N_G_FUを青色背景のとと定義
#define N_G_KYO B_AOIRO"香"B_KIHONIRO //N_G_KYOを青色背景の香と定義
#define N_G_KEI B_AOIRO"桂"B_KIHONIRO //N_G_KEIを青色背景の桂と定義
#define N_G_GIN B_AOIRO"銀"B_KIHONIRO //N_G_GINを青色背景の銀と定義
#define N_G_KAKU B_AOIRO"馬"B_KIHONIRO //N_G_KAKUを青色背景の馬と定義
#define N_G_HI B_AOIRO"龍"B_KIHONIRO //N_G_HIを青色背景の龍と定義

#define N_H_FU "と" //N_H_FUをとと定義
#define N_H_KYO "成香" //N_H_KYOを成香と定義
#define N_H_KEI "成桂" //N_H_KEIを成桂と定義
#define N_H_GIN "成銀" //N_H_GINを成銀と定義
#define N_H_KAKU "馬" //N_H_KAKUを馬と定義
#define N_H_HI "龍" //N_H_HIを龍と定義
#define H_OU "王" //H_OUを王と定義

#define KUHAKU_N 0 // KUHAKU_Nを" "の番号0(00000000)と定義
#define FU_N 1 // FU_Nを先手の歩の番号1(00000001)と定義
#define KYO_N 2 // KYO_Nを先手の香の番号2(00000010)と定義
#define KEI_N 3 // KEI_Nを先手の桂の番号3(00000011)と定義
#define GIN_N 4 // GIN_Nを先手の銀の番号4(00000100)と定義
#define KIN_N 5 // KIN_Nを先手の金の番号5(00000101)と定義
#define KAKU_N 6 // KAKU_Nを先手の角の番号6(00000110)と定義
#define HI_N 7 // HI_Nを先手の飛の番号7(00000111)と定義
#define GYOKU_N 8 // GYOKU_Nを先手の玉の番号8(00001000)と定義
#define NARI_N 8 // NARI_Nを成り変換番号8(00001000)と定義
#define N_FU_N 9 // N_FU_Nを先手のとの番号9(00001001)と定義
#define N_KYO_N 10 // N_KYO_Nを先手の成香の番号10(00001010)と定義
#define N_KEI_N 11 // N_KEI_Nを先手の成桂の番号11(00001011)と定義
#define N_GIN_N 12 // N_GIN_Nを先手の成銀の番号12(00001100)と定義
#define N_KAKU_N 14 // N_KAKU_Nを先手の馬の番号14(00001110)と定義
#define N_HI_N 15 // N_HI_Nを先手の龍の番号15(00001111)と定義
#define GOTE_N 16 // GOTE_Nを先手→後手番号16(00010000)と定義
#define G_FU_N 17 // G_FU_Nを後手の歩の番号17(00010001)と定義
#define G_KYO_N 18 // G_KYO_Nを後手の香の番号18(00010010)と定義
#define G_KEI_N 19 // G_KEI_Nを後手の桂の番号19(00010011)と定義
#define G_GIN_N 20 // G_GIN_Nを後手の銀の番号20(00010100)と定義
#define G_KIN_N 21 // G_KIN_Nを後手の金の番号21(00010101)と定義
#define G_KAKU_N 22 // G_KAKU_Nを後手の角の番号22(00010110)と定義
#define G_HI_N 23 // G_HI_Nを後手の飛の番号23(00010111)と定義
#define OU_N 24 // OU_Nを後手の王の番号24(00011000)と定義
#define N_G_FU_N 25 // N_G_FU_Nを後手のとの番号25(00011001)と定義
#define N_G_KYO_N 26 //N_G_KYO_Nを後手の成香の番号26(00011010)と定義
#define N_G_KEI_N 27 //N_G_KEI_Nを後手の成桂の番号27(00011011)と定義
#define N_G_GIN_N 28 //N_G_GIN_Nを後手の成銀の番号28(00011100)と定義
#define N_G_KAKU_N 30 // N_G_KAKU_Nを後手の馬の番号30(00011110)と定義
#define N_G_HI_N 31 // N_G_HI_Nを後手の龍の番号31(00011111)と定義

#define SENTE 0 //SENTEを0と定義
#define GOTE 1 //GOTEを1と定義

#include <stdio.h>
#include <conio.h>
#include <stdlib.h>

int tesuu_n; //手数カウント

int s_te_m_r; //先手の指し手の移動元(列)
int s_te_m_g; //先手の指し手の移動元(行)
int s_te_s_r; //先手の指し手の移動先(列)
int s_te_s_g; //先手の指し手の移動先(行)
int s_te_n; //先手の成りフラグ

int g_te_m_r; //後手の指し手の移動元(列)
int g_te_m_g; //後手の指し手の移動元(行)
int g_te_s_r; //後手の指し手の移動先(列)
int g_te_s_g; //後手の指し手の移動先(行)
int g_te_n; //後手の成りフラグ

int s_tem_m_koma_n = 0; //先手の指し手の移動元(駒番号)
int s_tem_s_koma_n = 0; //先手の指し手の移動先(駒番号)
int g_tem_m_koma_n = 0; //後手の指し手の移動元(駒番号)
int g_tem_s_koma_n = 0; //後手の指し手の移動先(駒番号)
int sasite_koma_n = 0; //指し手表示用(駒番号)

char *koma_h[] = {
KUHAKU, // 要素0にKUHAKUをセット
FU, // 要素1にFUをセット
KYO, // 要素2にKYOをセット
KEI, // 要素3にKEIをセット
GIN, // 要素4にGINをセット
KIN, // 要素5にKINをセット
KAKU, // 要素6にKAKUをセット
HI, // 要素7にHIをセット
GYOKU, // 要素8にGYOKUをセット
N_FU, // 要素9にN_FUをセット
N_KYO, //要素10にN_KYOをセット
N_KEI, //要素11にN_KEIをセット
N_GIN, //要素12にN_GINをセット
KUHAKU, //要素13にKUHAKUをセット
N_KAKU, //要素14にN_KAKUをセット
N_HI, //要素15にN_HIをセット
KUHAKU, //要素16にKUHAKUをセット
G_FU, //要素17にG_FUをセット
G_KYO, //要素18にG_KYOをセット
G_KEI, //要素19にG_KEIをセット
G_GIN, //要素20にG_GINをセット
G_KIN, //要素21にG_KINをセット
G_KAKU, //要素22にG_KAKUをセット
G_HI, //要素23にG_HIをセット
OU, //要素24にOUをセット
N_G_FU, //要素25にN_G_FUをセット
N_G_KYO, //要素26にN_G_KYOをセット
N_G_KEI, //要素27にN_G_KEIをセット
N_G_GIN, //要素28にN_G_GINをセット
KUHAKU, //要素29にKUHAKUをセット
N_G_KAKU, //要素30にN_G_KAKUをセット
N_G_HI //要素31にN_G_HIをセット
};

char *koma_s_h[] = {
KUHAKU, // 要素0にKUHAKUをセット
FU, // 要素1にFUをセット
KYO, // 要素2にKYOをセット
KEI, // 要素3にKEIをセット
GIN, // 要素4にGINをセット
KIN, // 要素5にKINをセット
KAKU, // 要素6にKAKUをセット
HI, // 要素7にHIをセット
GYOKU, // 要素8にGYOKUをセット
N_H_FU, // 要素9にN_H_FUをセット
N_H_KYO, //要素10にN_H_KYOをセット
N_H_KEI, //要素11にN_H_KEIをセット
N_H_GIN, //要素12にN_H_GINをセット
KUHAKU, //要素13にKUHAKUをセット
N_H_KAKU, //要素14にN_H_KAKUをセット
N_H_HI, //要素15にN_H_HIをセット
KUHAKU, //要素16にKUHAKUをセット
FU, //要素17にFUをセット
KYO, //要素18にKYOをセット
KEI, //要素19にKEIをセット
GIN, //要素20にGINをセット
KIN, //要素21にKINをセット
KAKU, //要素22にKAKUをセット
HI, //要素23にHIをセット
H_OU, //要素24にH_OUをセット
N_H_FU, //要素25にN_H_FUをセット
N_H_KYO, //要素26にN_H_KYOをセット
N_H_KEI, //要素27にN_H_KEIをセット
N_H_GIN, //要素28にN_H_GINをセット
N_H_KAKU, //要素30にN_H_KAKUをセット
N_H_HI //要素31にN_H_HIをセット
};

/* 盤面の初期設定 */
int banmen[9][9] = { { G_KYO_N, G_KEI_N, G_GIN_N, G_KIN_N, OU_N, G_KIN_N, G_GIN_N, G_KEI_N, G_KYO_N },
{ KUHAKU_N, G_KAKU_N, KUHAKU_N, KUHAKU_N, KUHAKU_N, KUHAKU_N, KUHAKU_N, G_HI_N, KUHAKU_N },
{ G_FU_N, G_FU_N, G_FU_N, G_FU_N, G_FU_N, G_FU_N, G_FU_N, G_FU_N, G_FU_N },
{ KUHAKU_N, KUHAKU_N, KUHAKU_N, KUHAKU_N, KUHAKU_N, KUHAKU_N, KUHAKU_N, KUHAKU_N, KUHAKU_N },
{ KUHAKU_N, KUHAKU_N, KUHAKU_N, KUHAKU_N, KUHAKU_N, KUHAKU_N, KUHAKU_N, KUHAKU_N, KUHAKU_N },
{ KUHAKU_N, KUHAKU_N, KUHAKU_N, KUHAKU_N, KUHAKU_N, KUHAKU_N, KUHAKU_N, KUHAKU_N, KUHAKU_N },
{ FU_N, FU_N, FU_N, FU_N, FU_N, FU_N, FU_N, FU_N, FU_N },
{ KUHAKU_N, HI_N, KUHAKU_N, KUHAKU_N, KUHAKU_N, KUHAKU_N, KUHAKU_N, KAKU_N, KUHAKU_N },
{ KYO_N, KEI_N, GIN_N, KIN_N, GYOKU_N, KIN_N, GIN_N, KEI_N, KYO_N } };

/* 持ち駒の構造体 */
struct Motigoma{
int kazu;
int fu;
int kyo;
int kei;
int gin;
int kin;
int kaku;
int hi;
};

struct Motigoma s_motigoma = { 0, 0, 0, 0, 0, 0, 0, 0 }; //先手の持ち駒の構造体
struct Motigoma g_motigoma = { 0, 0, 0, 0, 0, 0, 0, 0 }; //後手の持ち駒の構造体
int s_motigoma_n; //先手の持ち駒番号
int g_motigoma_n; //後手の持ち駒番号

/* ゲーム設定の構造体 */
struct Game_set{
int com; //0:人間、1:コンピュータ
int nifu; //0:二歩禁止、1:二歩許可
int tomogui; //0:味方の駒取得禁止、1:味方の駒取得許可
int banmen; //0:平手、1:香落ち、2:角落ち、3:飛落ち、4:飛香落ち、5:二枚落ち、6:四枚落ち、7:六枚落ち、8:八枚落ち、9:その他
};

struct Game_set s_game_set = { 0, 0, 0, 0 }; //先手のゲーム設定の構造体
struct Game_set g_game_set = { 0, 0, 0, 0 }; //後手のゲーム設定の構造体

int banmen_hyouji(); //盤面の表示関数
int sente_nyuuryoku(); //先手の指し手の入力関数
int gote_nyuuryoku(); //後手の指し手の入力関数
int sasite_hyouji(int); //指し手の表示関数
int sasite_nyuuryoku(); //指し手の入力関数
int motigoma_hyouji(); //持ち駒の表示関数
int motigoma_nyuuryoku(struct Motigoma *); //持ち駒の入力関数
int koma_ido_chk(int,int,int,int,int); //駒の移動チェック関数
int menu(); //メニューの表示関数

int main()
{

int menuno; //メニュー番号

while (1) {
menuno = menu(); //メニュー番号選択
switch (menuno)
{
case 0: //先手人間vs後手人間の対局
s_game_set.com = 0; //先手人間
g_game_set.com = 0; //後手人間
break;
case 1: //先手人間vs後手コンピュータの対局
s_game_set.com = 0; //先手人間
g_game_set.com = 1; //後手コンピュータ
break;
case 2: //先手コンピュータvs後手人間の対局
s_game_set.com = 1; //先手コンピュータ
g_game_set.com = 0; //後手人間
break;
case 3: //先手コンピュータvs後手コンピュータの対局
s_game_set.com = 1; //先手コンピュータ
g_game_set.com = 1; //後手コンピュータ
break;
default:
printf("メニュー番号を入力してください。\n");
break;
}
if (0 <= menuno && menuno <= 3) //メニュー番号が0から3ならループ終了
break;
}

tesuu_n = 0; //手数カウント初期化
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 (sente_nyuuryoku() == 1){ //先手の指し手の入力関数
printf("\n詰みました。先手の勝利です。");
break;
}

system("cls"); //画面クリア
sasite_hyouji(SENTE); //先手の指し手表示関数
motigoma_hyouji(); //持ち駒表示関数
banmen_hyouji(); //盤面表示関数

if (gote_nyuuryoku() == 1){ //後手の指し手の入力関数
printf(AOIRO"\n詰みました。後手の勝利です。"KIHONIRO);
break;
}

system("cls"); //画面クリア
sasite_hyouji(GOTE); //後手の指し手表示関数
motigoma_hyouji(); //持ち駒表示関数
banmen_hyouji(); //盤面表示関数
}

return 0;
}

/* 持ち駒の表示関数 */
int motigoma_hyouji()
{
printf("\n持ち駒番号:1 2 3 4 5 6 7");
printf("\n持ち駒種類:歩 香 桂 銀 金 角 飛");

if (s_game_set.com == 0)
printf("\n先手MAN");
else
printf("\n先手COM");

printf(":%2d %2d %2d %2d %2d %2d %2d", s_motigoma.fu, s_motigoma.kyo, s_motigoma.kei, s_motigoma.gin, s_motigoma.kin, s_motigoma.kaku, s_motigoma.hi);

if (g_game_set.com == 0)
printf(AOIRO"\n後手MAN"KIHONIRO);
else
printf(AOIRO"\n後手COM"KIHONIRO);

printf(AOIRO":%2d %2d %2d %2d %2d %2d %2d"KIHONIRO, g_motigoma.fu, g_motigoma.kyo, g_motigoma.kei, g_motigoma.gin, g_motigoma.kin, g_motigoma.kaku, g_motigoma.hi);

return 0;
}


/* メニューの表示関数 */
int menu()
{
char ret[8];

while (1) {
printf("将時\n");
printf("**************************************************\n");
printf("0:先手人間vs後手人間の対局\n");
printf("1:先手人間vs後手コンピュータの対局\n");
printf("2:先手コンピュータvs後手人間の対局\n");
printf("3:先手コンピュータvs後手コンピュータの対局\n");
printf("**************************************************\n");
printf("メニュー番号を入力してください。:");
fgets(ret, sizeof(ret), stdin);
ret[1] = '\0';
if (ret[0] < '0' || ret[0] > '3') {
printf("番号が不正です。\n");
continue;
}
return atoi(ret);
}
}


将時画面16022905
将時画面16022906



指し手入力のやり直しルーチンの追加とコード修正しました。


ソース:stime_16022904


/* 先手の指し手の入力関数 */
int sente_nyuuryoku()
{

SENTE_MOTO: //先手移動元入力

while (1)
{
s_tem_m_koma_n = 0;
sasite_koma_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 ((FU_N <= s_tem_m_koma_n) && (s_tem_m_koma_n <= GYOKU_N)) //移動元が先手の駒の場合
break;
else if ((N_FU_N <= s_tem_m_koma_n) && (s_tem_m_koma_n <= N_HI_N)) //移動元が先手の成駒の場合
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_s_koma_n == OU_N) && (s_motigoma_n == 0)) //移動先が後手の王で移動元が持ち駒でない場合
return 1; //詰み(先手の勝利)
else if ((s_te_m_r == s_te_s_r) && (s_te_m_g == s_te_s_g)) //移動元と移動先が同じ場合
printf("\n移動可能な移動先を入力してください。");
else if (s_tem_s_koma_n == GYOKU_N) //移動先が先手の玉の場合(味方の駒取得可能特別ルール内の例外)
printf("\n移動可能な移動先を入力してください。");
else if ((s_motigoma_n > 0) && (s_tem_s_koma_n != KUHAKU_N)) //持ち駒で駒のある移動先の場合
printf("\n駒がない場所を入力してください。");
/* 先手持ち駒の歩か香で移動先が後手陣地の最終行の場合 */
else if ((s_motigoma_n > 0) && ((FU_N == s_tem_m_koma_n) || (KYO_N == s_tem_m_koma_n)) && (s_te_s_g == 1))
printf("\n移動可能な移動先を入力してください。");
/* 先手持ち駒の桂で移動先が後手陣地の最終と手前行の場合 */
else if ((s_motigoma_n > 0) && (KEI_N == s_tem_m_koma_n) && (s_te_s_g < 3))
printf("\n移動可能な移動先を入力してください。");
else if ((s_motigoma_n == 0) && (koma_ido_chk(s_tem_m_koma_n, s_te_m_r, s_te_m_g, s_te_s_r, s_te_s_g) == NG)) //持ち駒でなく、駒の移動が正しくない場合
printf("\n移動可能な移動先を入力してください。");
else
break;
}

/* 先手の歩か香で移動先が後手陣地の最終行の場合 */
if (((FU_N == s_tem_m_koma_n) || (KYO_N == s_tem_m_koma_n)) && (s_te_s_g == 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_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_motigoma_n == 0)) {
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ループを抜ける
}
}
}
else {
s_te_n = 0;
}

banmen[s_te_m_g - 1][s_te_m_r - 1] = KUHAKU_N; //先手の指し手の移動元に空白を保存

if (s_tem_s_koma_n != KUHAKU_N) { //移動先に駒がある場合
/* 移動先が歩の場合 */
if ((s_tem_s_koma_n == G_FU_N) || (s_tem_s_koma_n == FU_N) || (s_tem_s_koma_n == N_G_FU_N) || (s_tem_s_koma_n == N_FU_N)){
s_motigoma.fu++; //歩を持ち駒に加える
s_motigoma.kazu++; //持ち駒カウントを増やす
}
/* 移動先が香の場合 */
else if ((s_tem_s_koma_n == G_KYO_N) || (s_tem_s_koma_n == KYO_N) || (s_tem_s_koma_n == N_G_KYO_N) || (s_tem_s_koma_n == N_KYO_N)){
s_motigoma.kyo++; //香を持ち駒に加える
s_motigoma.kazu++; //持ち駒カウントを増やす
}
/* 移動先が桂の場合 */
else if ((s_tem_s_koma_n == G_KEI_N) || (s_tem_s_koma_n == KEI_N) || (s_tem_s_koma_n == N_G_KEI_N) || (s_tem_s_koma_n == N_KEI_N)){
s_motigoma.kei++; //桂を持ち駒に加える
s_motigoma.kazu++; //持ち駒カウントを増やす
}
/* 移動先が銀の場合 */
else if ((s_tem_s_koma_n == G_GIN_N) || (s_tem_s_koma_n == GIN_N) || (s_tem_s_koma_n == N_G_GIN_N) || (s_tem_s_koma_n == N_GIN_N)){
s_motigoma.gin++; //銀を持ち駒に加える
s_motigoma.kazu++; //持ち駒カウントを増やす
}
/* 移動先が金の場合 */
else if ((s_tem_s_koma_n == G_KIN_N) || (s_tem_s_koma_n == KIN_N)){
s_motigoma.kin++; //金を持ち駒に加える
s_motigoma.kazu++; //持ち駒カウントを増やす
}
/* 移動先が角の場合 */
else if ((s_tem_s_koma_n == G_KAKU_N) || (s_tem_s_koma_n == KAKU_N) || (s_tem_s_koma_n == N_G_KAKU_N) || (s_tem_s_koma_n == N_KAKU_N)){
s_motigoma.kaku++; //角を持ち駒に加える
s_motigoma.kazu++; //持ち駒カウントを増やす
}
/* 移動先が飛の場合 */
else if ((s_tem_s_koma_n == G_HI_N) || (s_tem_s_koma_n == HI_N) || (s_tem_s_koma_n == N_G_HI_N) || (s_tem_s_koma_n == N_HI_N)){
s_motigoma.hi++; //飛を持ち駒に加える
s_motigoma.kazu++; //持ち駒カウントを増やす
}
}

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;

/* 後手の指し手の移動元(列)の入力 */
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 ((G_FU_N <= g_tem_m_koma_n) && (g_tem_m_koma_n <= OU_N)) //移動元が後手の駒の場合
break;
else if ((N_G_FU_N <= g_tem_m_koma_n) && (g_tem_m_koma_n <= N_G_HI_N)) //移動元が後手の成駒の場合
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_s_koma_n == GYOKU_N) && (g_motigoma_n == 0)) //移動先が先手の玉で移動元が持ち駒でない場合
return 1; //詰み(先手の勝利)
else if ((g_te_m_r == g_te_s_r) && (g_te_m_g == g_te_s_g)) //移動元と移動先が同じ場合
printf(AOIRO"\n移動可能な移動先を入力してください。"KIHONIRO);
else if (g_tem_s_koma_n == OU_N) //移動先が後手の王の場合(味方の駒取得可能特別ルール内の例外)
printf(AOIRO"\n移動可能な移動先を入力してください。"KIHONIRO);
else if (g_motigoma_n > 0 && (g_tem_s_koma_n != KUHAKU_N)) //持ち駒で駒のある移動先の場合
printf(AOIRO"\n駒がない場所を入力してください。"KIHONIRO);
/* 後手持ち駒の歩か香で移動先が先手陣地の最終行の場合 */
else if ((g_motigoma_n > 0) && ((G_FU_N == g_tem_m_koma_n) || (G_KYO_N == g_tem_m_koma_n)) && (g_te_s_g == 9))
printf(AOIRO"\n駒がない場所を入力してください。"KIHONIRO);
/* 後手持ち駒の桂で移動先が先手陣地の最終と手前行の場合 */
else if ((g_motigoma_n > 0) && (G_KEI_N == g_tem_m_koma_n) && (g_te_s_g > 7))
printf(AOIRO"\n駒がない場所を入力してください。"KIHONIRO);
else if ((g_motigoma_n == 0) && (koma_ido_chk(g_tem_m_koma_n, g_te_m_r, g_te_m_g, g_te_s_r, g_te_s_g) == NG)) //持ち駒でなく、駒の移動が正しくない場合
printf(AOIRO"\n駒がない場所を入力してください。"KIHONIRO);
else
break;
}

/* 後手の歩か香で移動先が先手陣地の最終行の場合 */
if (((G_FU_N == g_tem_m_koma_n) || (G_KYO_N == g_tem_m_koma_n)) && (g_te_s_g == 9)) {
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_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_motigoma_n == 0)) {
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ループを抜ける
}
}
}
else {
g_te_n = 0;
}

banmen[g_te_m_g - 1][g_te_m_r - 1] = KUHAKU_N; //後手の指し手の移動元に空白を保存

if (g_tem_s_koma_n != KUHAKU_N) { //移動先に駒がある場合
/* 移動先が歩の場合 */
if ((g_tem_s_koma_n == G_FU_N) || (g_tem_s_koma_n == FU_N) || (g_tem_s_koma_n == N_G_FU_N) || (g_tem_s_koma_n == N_FU_N)) {
g_motigoma.fu++; //歩を持ち駒に加える
g_motigoma.kazu++; //持ち駒カウントを増やす
}
/* 移動先が香の場合 */
else if ((g_tem_s_koma_n == G_KYO_N) || (g_tem_s_koma_n == KYO_N) || (g_tem_s_koma_n == N_G_KYO_N) || (g_tem_s_koma_n == N_KYO_N)){
g_motigoma.kyo++; //香を持ち駒に加える
g_motigoma.kazu++; //持ち駒カウントを増やす
}
/* 移動先が桂の場合 */
else if ((g_tem_s_koma_n == G_KEI_N) || (g_tem_s_koma_n == KEI_N) || (g_tem_s_koma_n == N_G_KEI_N) || (g_tem_s_koma_n == N_KEI_N)){
g_motigoma.kei++; //桂を持ち駒に加える
g_motigoma.kazu++; //持ち駒カウントを増やす
}
/* 移動先が銀の場合 */
else if ((g_tem_s_koma_n == G_GIN_N) || (g_tem_s_koma_n == GIN_N) || (g_tem_s_koma_n == N_G_GIN_N) || (g_tem_s_koma_n == N_GIN_N)){
g_motigoma.gin++; //銀を持ち駒に加える
g_motigoma.kazu++; //持ち駒カウントを増やす
}
/* 移動先が金の場合 */
else if ((g_tem_s_koma_n == G_KIN_N) || (g_tem_s_koma_n == KIN_N)){
g_motigoma.kin++; //金を持ち駒に加える
g_motigoma.kazu++; //持ち駒カウントを増やす
}
/* 移動先が角の場合 */
else if ((g_tem_s_koma_n == G_KAKU_N) || (g_tem_s_koma_n == KAKU_N) || (g_tem_s_koma_n == N_G_KAKU_N) || (g_tem_s_koma_n == N_KAKU_N)){
g_motigoma.kaku++; //角を持ち駒に加える
g_motigoma.kazu++; //持ち駒カウントを増やす
}
/* 移動先が飛の場合 */
else if ((g_tem_s_koma_n == G_HI_N) || (g_tem_s_koma_n == HI_N) || (g_tem_s_koma_n == N_G_HI_N) || (g_tem_s_koma_n == N_HI_N)){
g_motigoma.hi++; //飛を持ち駒に加える
g_motigoma.kazu++; //持ち駒カウントを増やす
}
}

banmen[g_te_s_g - 1][g_te_s_r - 1] = g_tem_m_koma_n; //後手の指し手の移動先に移動元の駒を保存

return 0;
}


将時画面16022904


移動できない位置に持ち駒使用した時のエラー判定を追加しました。


ソース:stime_16022903


int sente_nyuuryoku()
{
while (1)
{
s_tem_m_koma_n = 0;
sasite_koma_n = 0;

/* 先手の指し手の移動元(列)の入力 */
printf("\n先手の指し手の移動元(列)か持ち駒(0)を入力してください:");

s_te_m_r = sasite_nyuuryoku(); //指し手を取得

if (s_te_m_r == 0){ //持ち駒が選択された場合
if (s_motigoma.kazu == 0){
printf("\n持ち駒がありません。");
continue;
}
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 {
s_motigoma_n = 0;

/* 先手の指し手の移動元(行)の入力 */
printf("\n先手の指し手の移動元(行)か前に戻る(0)を入力してください:");

s_te_m_g = sasite_nyuuryoku(); //指し手を取得

if (s_te_m_g == 0) //前に戻るが選択された場合
continue;

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 ((FU_N <= s_tem_m_koma_n) && (s_tem_m_koma_n <= GYOKU_N)) //移動元が先手の駒の場合
break;
else if ((N_FU_N <= s_tem_m_koma_n) && (s_tem_m_koma_n <= N_HI_N)) //移動元が先手の成駒の場合
break;
else if (s_motigoma_n == 0) //元に戻る場合
continue;
else
printf("\n先手の駒を入力してください。");
}

while (1)
{
/* 先手の指し手の移動先(列)の入力 */
printf("\n先手の指し手の移動先(列)か前に戻る(0)を入力してください:");

s_te_s_r = sasite_nyuuryoku(); //指し手を取得

if (s_te_s_r == 0) //前に戻るが選択された場合
continue;

/* 先手の指し手の移動先(行)の入力 */
printf("\n先手の指し手の移動先(行)か前に戻る(0)を入力してください:");

s_te_s_g = sasite_nyuuryoku(); //指し手を取得

if (s_te_s_g == 0) //前に戻るが選択された場合
continue;

s_tem_s_koma_n = banmen[s_te_s_g - 1][s_te_s_r - 1]; //先手の指し手の移動先(駒番号)を保存
if ((s_tem_s_koma_n == OU_N) && (s_motigoma_n == 0)) //移動先が後手の王で移動元が持ち駒でない場合
return 1; //詰み(先手の勝利)
else if ((s_te_m_r == s_te_s_r) && (s_te_m_g == s_te_s_g)) //移動元と移動先が同じ場合
printf("\n移動可能な移動先を入力してください。");
else if (s_tem_s_koma_n == GYOKU_N) //移動先が先手の玉の場合(味方の駒取得可能特別ルール内の例外)
printf("\n移動可能な移動先を入力してください。");
else if ((s_motigoma_n > 0) && (s_tem_s_koma_n != KUHAKU_N)) //持ち駒で駒のある移動先の場合
printf("\n駒がない場所を入力してください。");
/* 先手持ち駒の歩か香で移動先が後手陣地の最終行の場合 */
else if ((s_motigoma_n > 0) && ((FU_N == s_tem_m_koma_n) || (KYO_N == s_tem_m_koma_n)) && (s_te_s_g == 1))
printf("\n移動可能な移動先を入力してください。");
/* 先手持ち駒の桂で移動先が後手陣地の最終と手前行の場合 */
else if ((s_motigoma_n > 0) && (KEI_N == s_tem_m_koma_n) && (s_te_s_g < 3))
printf("\n移動可能な移動先を入力してください。");
else if ((s_motigoma_n == 0) && (koma_ido_chk(s_tem_m_koma_n, s_te_m_r, s_te_m_g, s_te_s_r, s_te_s_g) == NG)) //持ち駒でなく、駒の移動が正しくない場合
printf("\n移動可能な移動先を入力してください。");
else
break;
}

/* 先手の歩か香で移動先が後手陣地の最終行の場合 */
if (((FU_N == s_tem_m_koma_n) || (KYO_N == s_tem_m_koma_n)) && (s_te_s_g == 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_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_motigoma_n == 0)) {
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ループを抜ける
}
}
}
else {
s_te_n = 0;
}

banmen[s_te_m_g - 1][s_te_m_r - 1] = KUHAKU_N; //先手の指し手の移動元に空白を保存

if (s_tem_s_koma_n != KUHAKU_N) { //移動先に駒がある場合
/* 移動先が歩の場合 */
if ((s_tem_s_koma_n == G_FU_N) || (s_tem_s_koma_n == FU_N) || (s_tem_s_koma_n == N_G_FU_N) || (s_tem_s_koma_n == N_FU_N)){
s_motigoma.fu++; //歩を持ち駒に加える
s_motigoma.kazu++; //持ち駒カウントを増やす
}
/* 移動先が香の場合 */
else if ((s_tem_s_koma_n == G_KYO_N) || (s_tem_s_koma_n == KYO_N) || (s_tem_s_koma_n == N_G_KYO_N) || (s_tem_s_koma_n == N_KYO_N)){
s_motigoma.kyo++; //香を持ち駒に加える
s_motigoma.kazu++; //持ち駒カウントを増やす
}
/* 移動先が桂の場合 */
else if ((s_tem_s_koma_n == G_KEI_N) || (s_tem_s_koma_n == KEI_N) || (s_tem_s_koma_n == N_G_KEI_N) || (s_tem_s_koma_n == N_KEI_N)){
s_motigoma.kei++; //桂を持ち駒に加える
s_motigoma.kazu++; //持ち駒カウントを増やす
}
/* 移動先が銀の場合 */
else if ((s_tem_s_koma_n == G_GIN_N) || (s_tem_s_koma_n == GIN_N) || (s_tem_s_koma_n == N_G_GIN_N) || (s_tem_s_koma_n == N_GIN_N)){
s_motigoma.gin++; //銀を持ち駒に加える
s_motigoma.kazu++; //持ち駒カウントを増やす
}
/* 移動先が金の場合 */
else if ((s_tem_s_koma_n == G_KIN_N) || (s_tem_s_koma_n == KIN_N)){
s_motigoma.kin++; //金を持ち駒に加える
s_motigoma.kazu++; //持ち駒カウントを増やす
}
/* 移動先が角の場合 */
else if ((s_tem_s_koma_n == G_KAKU_N) || (s_tem_s_koma_n == KAKU_N) || (s_tem_s_koma_n == N_G_KAKU_N) || (s_tem_s_koma_n == N_KAKU_N)){
s_motigoma.kaku++; //角を持ち駒に加える
s_motigoma.kazu++; //持ち駒カウントを増やす
}
/* 移動先が飛の場合 */
else if ((s_tem_s_koma_n == G_HI_N) || (s_tem_s_koma_n == HI_N) || (s_tem_s_koma_n == N_G_HI_N) || (s_tem_s_koma_n == N_HI_N)){
s_motigoma.hi++; //飛を持ち駒に加える
s_motigoma.kazu++; //持ち駒カウントを増やす
}
}

banmen[s_te_s_g - 1][s_te_s_r - 1] = s_tem_m_koma_n; //先手の指し手の移動先に移動元の駒を保存

return 0;
}

/* 後手の指し手の入力関数 */
int gote_nyuuryoku()
{
while (1)
{
g_tem_m_koma_n = 0;
sasite_koma_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);
continue;
}
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) //前に戻るが選択された場合
continue;

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 ((G_FU_N <= g_tem_m_koma_n) && (g_tem_m_koma_n <= OU_N)) //移動元が後手の駒の場合
break;
else if ((N_G_FU_N <= g_tem_m_koma_n) && (g_tem_m_koma_n <= N_G_HI_N)) //移動元が後手の成駒の場合
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) //前に戻るが選択された場合
continue;

/* 後手の指し手の移動先(行)の入力 */
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_s_koma_n == GYOKU_N) && (g_motigoma_n == 0)) //移動先が先手の玉で移動元が持ち駒でない場合
return 1; //詰み(先手の勝利)
else if ((g_te_m_r == g_te_s_r) && (g_te_m_g == g_te_s_g)) //移動元と移動先が同じ場合
printf(AOIRO"\n移動可能な移動先を入力してください。"KIHONIRO);
else if (g_tem_s_koma_n == OU_N) //移動先が後手の王の場合(味方の駒取得可能特別ルール内の例外)
printf(AOIRO"\n移動可能な移動先を入力してください。"KIHONIRO);
else if (g_motigoma_n > 0 && (g_tem_s_koma_n != KUHAKU_N)) //持ち駒で駒のある移動先の場合
printf(AOIRO"\n駒がない場所を入力してください。"KIHONIRO);
/* 後手持ち駒の歩か香で移動先が先手陣地の最終行の場合 */
else if ((g_motigoma_n > 0) && ((G_FU_N == g_tem_m_koma_n) || (G_KYO_N == g_tem_m_koma_n)) && (g_te_s_g == 9))
printf(AOIRO"\n駒がない場所を入力してください。"KIHONIRO);
/* 後手持ち駒の桂で移動先が先手陣地の最終と手前行の場合 */
else if ((g_motigoma_n > 0) && (G_KEI_N == g_tem_m_koma_n) && (g_te_s_g > 7))
printf(AOIRO"\n駒がない場所を入力してください。"KIHONIRO);
else if ((g_motigoma_n == 0) && (koma_ido_chk(g_tem_m_koma_n, g_te_m_r, g_te_m_g, g_te_s_r, g_te_s_g) == NG)) //持ち駒でなく、駒の移動が正しくない場合
printf(AOIRO"\n駒がない場所を入力してください。"KIHONIRO);
else
break;
}

/* 後手の歩か香で移動先が先手陣地の最終行の場合 */
if (((G_FU_N == g_tem_m_koma_n) || (G_KYO_N == g_tem_m_koma_n)) && (g_te_s_g == 9)) {
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_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_motigoma_n == 0)) {
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ループを抜ける
}
}
}
else {
g_te_n = 0;
}

banmen[g_te_m_g - 1][g_te_m_r - 1] = KUHAKU_N; //後手の指し手の移動元に空白を保存

if (g_tem_s_koma_n != KUHAKU_N) { //移動先に駒がある場合
/* 移動先が歩の場合 */
if ((g_tem_s_koma_n == G_FU_N) || (g_tem_s_koma_n == FU_N) || (g_tem_s_koma_n == N_G_FU_N) || (g_tem_s_koma_n == N_FU_N)) {
g_motigoma.fu++; //歩を持ち駒に加える
g_motigoma.kazu++; //持ち駒カウントを増やす
}
/* 移動先が香の場合 */
else if ((g_tem_s_koma_n == G_KYO_N) || (g_tem_s_koma_n == KYO_N) || (g_tem_s_koma_n == N_G_KYO_N) || (g_tem_s_koma_n == N_KYO_N)){
g_motigoma.kyo++; //香を持ち駒に加える
g_motigoma.kazu++; //持ち駒カウントを増やす
}
/* 移動先が桂の場合 */
else if ((g_tem_s_koma_n == G_KEI_N) || (g_tem_s_koma_n == KEI_N) || (g_tem_s_koma_n == N_G_KEI_N) || (g_tem_s_koma_n == N_KEI_N)){
g_motigoma.kei++; //桂を持ち駒に加える
g_motigoma.kazu++; //持ち駒カウントを増やす
}
/* 移動先が銀の場合 */
else if ((g_tem_s_koma_n == G_GIN_N) || (g_tem_s_koma_n == GIN_N) || (g_tem_s_koma_n == N_G_GIN_N) || (g_tem_s_koma_n == N_GIN_N)){
g_motigoma.gin++; //銀を持ち駒に加える
g_motigoma.kazu++; //持ち駒カウントを増やす
}
/* 移動先が金の場合 */
else if ((g_tem_s_koma_n == G_KIN_N) || (g_tem_s_koma_n == KIN_N)){
g_motigoma.kin++; //金を持ち駒に加える
g_motigoma.kazu++; //持ち駒カウントを増やす
}
/* 移動先が角の場合 */
else if ((g_tem_s_koma_n == G_KAKU_N) || (g_tem_s_koma_n == KAKU_N) || (g_tem_s_koma_n == N_G_KAKU_N) || (g_tem_s_koma_n == N_KAKU_N)){
g_motigoma.kaku++; //角を持ち駒に加える
g_motigoma.kazu++; //持ち駒カウントを増やす
}
/* 移動先が飛の場合 */
else if ((g_tem_s_koma_n == G_HI_N) || (g_tem_s_koma_n == HI_N) || (g_tem_s_koma_n == N_G_HI_N) || (g_tem_s_koma_n == N_HI_N)){
g_motigoma.hi++; //飛を持ち駒に加える
g_motigoma.kazu++; //持ち駒カウントを増やす
}
}

banmen[g_te_s_g - 1][g_te_s_r - 1] = g_tem_m_koma_n; //後手の指し手の移動先に移動元の駒を保存

return 0;
}



将時画面16022903


移動できない位置に移動した時、強制的に成るようにしました。


ソース:stime_16022902


/* 先手の指し手の入力関数 */
int sente_nyuuryoku()
{
while (1)
{
s_tem_m_koma_n = 0;
sasite_koma_n = 0;

/* 先手の指し手の移動元(列)の入力 */
printf("\n先手の指し手の移動元(列)か持ち駒(0)を入力してください:");

s_te_m_r = sasite_nyuuryoku(); //指し手を取得

if (s_te_m_r == 0){ //持ち駒が選択された場合
if (s_motigoma.kazu == 0){
printf("\n持ち駒がありません。");
continue;
}
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 {
s_motigoma_n = 0;

/* 先手の指し手の移動元(行)の入力 */
printf("\n先手の指し手の移動元(行)か前に戻る(0)を入力してください:");

s_te_m_g = sasite_nyuuryoku(); //指し手を取得

if (s_te_m_g == 0) //前に戻るが選択された場合
continue;

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 ((FU_N <= s_tem_m_koma_n) && (s_tem_m_koma_n <= GYOKU_N)) //移動元が先手の駒の場合
break;
else if ((N_FU_N <= s_tem_m_koma_n) && (s_tem_m_koma_n <= N_HI_N)) //移動元が先手の成駒の場合
break;
else if (s_motigoma_n == 0) //元に戻る場合
continue;
else
printf("\n先手の駒を入力してください。");
}

while (1)
{
/* 先手の指し手の移動先(列)の入力 */
printf("\n先手の指し手の移動先(列)か前に戻る(0)を入力してください:");

s_te_s_r = sasite_nyuuryoku(); //指し手を取得

if (s_te_s_r == 0) //前に戻るが選択された場合
continue;

/* 先手の指し手の移動先(行)の入力 */
printf("\n先手の指し手の移動先(行)か前に戻る(0)を入力してください:");

s_te_s_g = sasite_nyuuryoku(); //指し手を取得

if (s_te_s_g == 0) //前に戻るが選択された場合
continue;

s_tem_s_koma_n = banmen[s_te_s_g - 1][s_te_s_r - 1]; //先手の指し手の移動先(駒番号)を保存
if ((s_tem_s_koma_n == OU_N) && (s_motigoma_n == 0)) //移動先が後手の王で移動元が持ち駒でない場合
return 1; //詰み(先手の勝利)
else if ((s_te_m_r == s_te_s_r) && (s_te_m_g == s_te_s_g)) //移動元と移動先が同じ場合
printf("\n移動可能な移動先を入力してください。");
else if (s_tem_s_koma_n == GYOKU_N) //移動先が先手の玉の場合(味方の駒取得可能特別ルール内の例外)
printf("\n移動可能な移動先を入力してください。");
else if (s_motigoma_n > 0 && (s_tem_s_koma_n != KUHAKU_N)) //持ち駒で駒のある移動先の場合
printf("\n駒がない場所を入力してください。");
else if ((s_motigoma_n == 0) && (koma_ido_chk(s_tem_m_koma_n, s_te_m_r, s_te_m_g, s_te_s_r, s_te_s_g) == NG)) //持ち駒でなく、駒の移動が正しくない場合
printf("\n移動可能な移動先を入力してください。");
else
break;
}

/* 先手の歩か香で移動先が後手陣地の最終行の場合 */
if (((FU_N == s_tem_m_koma_n) || (KYO_N == s_tem_m_koma_n)) && (s_te_s_g == 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_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_motigoma_n == 0)) {
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ループを抜ける
}
}
}
else {
s_te_n = 0;
}

banmen[s_te_m_g - 1][s_te_m_r - 1] = KUHAKU_N; //先手の指し手の移動元に空白を保存

if (s_tem_s_koma_n != KUHAKU_N) { //移動先に駒がある場合
/* 移動先が歩の場合 */
if ((s_tem_s_koma_n == G_FU_N) || (s_tem_s_koma_n == FU_N) || (s_tem_s_koma_n == N_G_FU_N) || (s_tem_s_koma_n == N_FU_N)){
s_motigoma.fu++; //歩を持ち駒に加える
s_motigoma.kazu++; //持ち駒カウントを増やす
}
/* 移動先が香の場合 */
else if ((s_tem_s_koma_n == G_KYO_N) || (s_tem_s_koma_n == KYO_N) || (s_tem_s_koma_n == N_G_KYO_N) || (s_tem_s_koma_n == N_KYO_N)){
s_motigoma.kyo++; //香を持ち駒に加える
s_motigoma.kazu++; //持ち駒カウントを増やす
}
/* 移動先が桂の場合 */
else if ((s_tem_s_koma_n == G_KEI_N) || (s_tem_s_koma_n == KEI_N) || (s_tem_s_koma_n == N_G_KEI_N) || (s_tem_s_koma_n == N_KEI_N)){
s_motigoma.kei++; //桂を持ち駒に加える
s_motigoma.kazu++; //持ち駒カウントを増やす
}
/* 移動先が銀の場合 */
else if ((s_tem_s_koma_n == G_GIN_N) || (s_tem_s_koma_n == GIN_N) || (s_tem_s_koma_n == N_G_GIN_N) || (s_tem_s_koma_n == N_GIN_N)){
s_motigoma.gin++; //銀を持ち駒に加える
s_motigoma.kazu++; //持ち駒カウントを増やす
}
/* 移動先が金の場合 */
else if ((s_tem_s_koma_n == G_KIN_N) || (s_tem_s_koma_n == KIN_N)){
s_motigoma.kin++; //金を持ち駒に加える
s_motigoma.kazu++; //持ち駒カウントを増やす
}
/* 移動先が角の場合 */
else if ((s_tem_s_koma_n == G_KAKU_N) || (s_tem_s_koma_n == KAKU_N) || (s_tem_s_koma_n == N_G_KAKU_N) || (s_tem_s_koma_n == N_KAKU_N)){
s_motigoma.kaku++; //角を持ち駒に加える
s_motigoma.kazu++; //持ち駒カウントを増やす
}
/* 移動先が飛の場合 */
else if ((s_tem_s_koma_n == G_HI_N) || (s_tem_s_koma_n == HI_N) || (s_tem_s_koma_n == N_G_HI_N) || (s_tem_s_koma_n == N_HI_N)){
s_motigoma.hi++; //飛を持ち駒に加える
s_motigoma.kazu++; //持ち駒カウントを増やす
}
}

banmen[s_te_s_g - 1][s_te_s_r - 1] = s_tem_m_koma_n; //先手の指し手の移動先に移動元の駒を保存

return 0;
}

/* 後手の指し手の入力関数 */
int gote_nyuuryoku()
{
while (1)
{
g_tem_m_koma_n = 0;
sasite_koma_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);
continue;
}
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) //前に戻るが選択された場合
continue;

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 ((G_FU_N <= g_tem_m_koma_n) && (g_tem_m_koma_n <= OU_N)) //移動元が後手の駒の場合
break;
else if ((N_G_FU_N <= g_tem_m_koma_n) && (g_tem_m_koma_n <= N_G_HI_N)) //移動元が後手の成駒の場合
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) //前に戻るが選択された場合
continue;

/* 後手の指し手の移動先(行)の入力 */
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_s_koma_n == GYOKU_N) && (g_motigoma_n == 0)) //移動先が先手の玉で移動元が持ち駒でない場合
return 1; //詰み(先手の勝利)
else if ((g_te_m_r == g_te_s_r) && (g_te_m_g == g_te_s_g)) //移動元と移動先が同じ場合
printf(AOIRO"\n移動可能な移動先を入力してください。"KIHONIRO);
else if (g_tem_s_koma_n == OU_N) //移動先が後手の王の場合(味方の駒取得可能特別ルール内の例外)
printf(AOIRO"\n移動可能な移動先を入力してください。"KIHONIRO);
else if (g_motigoma_n > 0 && (g_tem_s_koma_n != KUHAKU_N)) //持ち駒で駒のある移動先の場合
printf(AOIRO"\n駒がない場所を入力してください。"KIHONIRO);
else if ((g_motigoma_n == 0) && (koma_ido_chk(g_tem_m_koma_n, g_te_m_r, g_te_m_g, g_te_s_r, g_te_s_g) == NG)) //持ち駒でなく、駒の移動が正しくない場合
printf("\n移動可能な移動先を入力してください。");
else
break;
}

/* 後手の歩か香で移動先が先手陣地の最終行の場合 */
if (((G_FU_N == g_tem_m_koma_n) || (G_KYO_N == g_tem_m_koma_n)) && (g_te_s_g == 9)) {
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_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_motigoma_n == 0)) {
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ループを抜ける
}
}
}
else {
g_te_n = 0;
}

banmen[g_te_m_g - 1][g_te_m_r - 1] = KUHAKU_N; //後手の指し手の移動元に空白を保存

if (g_tem_s_koma_n != KUHAKU_N) { //移動先に駒がある場合
/* 移動先が歩の場合 */
if ((g_tem_s_koma_n == G_FU_N) || (g_tem_s_koma_n == FU_N) || (g_tem_s_koma_n == N_G_FU_N) || (g_tem_s_koma_n == N_FU_N)) {
g_motigoma.fu++; //歩を持ち駒に加える
g_motigoma.kazu++; //持ち駒カウントを増やす
}
/* 移動先が香の場合 */
else if ((g_tem_s_koma_n == G_KYO_N) || (g_tem_s_koma_n == KYO_N) || (g_tem_s_koma_n == N_G_KYO_N) || (g_tem_s_koma_n == N_KYO_N)){
g_motigoma.kyo++; //香を持ち駒に加える
g_motigoma.kazu++; //持ち駒カウントを増やす
}
/* 移動先が桂の場合 */
else if ((g_tem_s_koma_n == G_KEI_N) || (g_tem_s_koma_n == KEI_N) || (g_tem_s_koma_n == N_G_KEI_N) || (g_tem_s_koma_n == N_KEI_N)){
g_motigoma.kei++; //桂を持ち駒に加える
g_motigoma.kazu++; //持ち駒カウントを増やす
}
/* 移動先が銀の場合 */
else if ((g_tem_s_koma_n == G_GIN_N) || (g_tem_s_koma_n == GIN_N) || (g_tem_s_koma_n == N_G_GIN_N) || (g_tem_s_koma_n == N_GIN_N)){
g_motigoma.gin++; //銀を持ち駒に加える
g_motigoma.kazu++; //持ち駒カウントを増やす
}
/* 移動先が金の場合 */
else if ((g_tem_s_koma_n == G_KIN_N) || (g_tem_s_koma_n == KIN_N)){
g_motigoma.kin++; //金を持ち駒に加える
g_motigoma.kazu++; //持ち駒カウントを増やす
}
/* 移動先が角の場合 */
else if ((g_tem_s_koma_n == G_KAKU_N) || (g_tem_s_koma_n == KAKU_N) || (g_tem_s_koma_n == N_G_KAKU_N) || (g_tem_s_koma_n == N_KAKU_N)){
g_motigoma.kaku++; //角を持ち駒に加える
g_motigoma.kazu++; //持ち駒カウントを増やす
}
/* 移動先が飛の場合 */
else if ((g_tem_s_koma_n == G_HI_N) || (g_tem_s_koma_n == HI_N) || (g_tem_s_koma_n == N_G_HI_N) || (g_tem_s_koma_n == N_HI_N)){
g_motigoma.hi++; //飛を持ち駒に加える
g_motigoma.kazu++; //持ち駒カウントを増やす
}
}

banmen[g_te_s_g - 1][g_te_s_r - 1] = g_tem_m_koma_n; //後手の指し手の移動先に移動元の駒を保存

return 0;
}



将時画面16022902


駒の移動チェック関数の追加とバグ修正しました。


ソース:stime_16022901


/* stime.c */

#define KUHAKU " " //KUHAKUを" "と定義

#define OK 0 //OKを0と定義
#define NG -1 //NGを-1と定義

#define FU "歩" //FUを歩と定義
#define KYO "香" //KYOを香と定義
#define KEI "桂" //KEIを桂と定義
#define GIN "銀" //GINを銀と定義
#define KIN "金" //KINを金と定義
#define KAKU "角" //KAKUを角と定義
#define HI "飛" //HIを飛と定義
#define GYOKU "玉" //GYOKUを玉と定義

#define AOIRO "\x1b[34m" //AOIROを青色のエスケープシーケンスと定義
#define KIHONIRO "\x1b[39m" //KIHONIROを基本色のエスケープシーケンスと定義
#define B_AKA "\x1b[41m" //B_AKAを赤色背景のエスケープシーケンスと定義
#define B_AOIRO "\x1b[44m" //B_AOIROを青色背景のエスケープシーケンスと定義
#define B_KIHONIRO "\x1b[49m" //B_KIHONIROを基本色背景のエスケープシーケンスと定義

#define G_FU AOIRO"歩"KIHONIRO //G_FUを青色の歩と定義
#define G_KYO AOIRO"香"KIHONIRO //G_KYOを青色の香と定義
#define G_KEI AOIRO"桂"KIHONIRO //G_KEIを青色の桂と定義
#define G_GIN AOIRO"銀"KIHONIRO //G_GINを青色の銀と定義
#define G_KIN AOIRO"金"KIHONIRO //G_KINを青色の金と定義
#define G_KAKU AOIRO"角"KIHONIRO //G_KAKUを青色の角と定義
#define G_HI AOIRO"飛"KIHONIRO //G_HIを青色の飛と定義
#define OU AOIRO"王"KIHONIRO //OUを青色の王と定義

#define N_FU B_AKA"と"B_KIHONIRO //N_FUを赤色背景のとと定義
#define N_KYO B_AKA"香"B_KIHONIRO //N_KYOを赤色背景の香と定義
#define N_KEI B_AKA"桂"B_KIHONIRO //N_KEIを赤色背景の桂と定義
#define N_GIN B_AKA"銀"B_KIHONIRO //N_GINを赤色背景の銀と定義
#define N_KAKU B_AKA"馬"B_KIHONIRO //N_KAKUを赤色背景の馬と定義
#define N_HI B_AKA"龍"B_KIHONIRO //N_HIを赤色背景の龍と定義

#define N_G_FU B_AOIRO"と"B_KIHONIRO //N_G_FUを青色背景のとと定義
#define N_G_KYO B_AOIRO"香"B_KIHONIRO //N_G_KYOを青色背景の香と定義
#define N_G_KEI B_AOIRO"桂"B_KIHONIRO //N_G_KEIを青色背景の桂と定義
#define N_G_GIN B_AOIRO"銀"B_KIHONIRO //N_G_GINを青色背景の銀と定義
#define N_G_KAKU B_AOIRO"馬"B_KIHONIRO //N_G_KAKUを青色背景の馬と定義
#define N_G_HI B_AOIRO"龍"B_KIHONIRO //N_G_HIを青色背景の龍と定義

#define N_H_FU "と" //N_H_FUをとと定義
#define N_H_KYO "成香" //N_H_KYOを成香と定義
#define N_H_KEI "成桂" //N_H_KEIを成桂と定義
#define N_H_GIN "成銀" //N_H_GINを成銀と定義
#define N_H_KAKU "馬" //N_H_KAKUを馬と定義
#define N_H_HI "龍" //N_H_HIを龍と定義
#define H_OU "王" //H_OUを王と定義

#define KUHAKU_N 0 // KUHAKU_Nを" "の番号0(00000000)と定義
#define FU_N 1 // FU_Nを先手の歩の番号1(00000001)と定義
#define KYO_N 2 // KYO_Nを先手の香の番号2(00000010)と定義
#define KEI_N 3 // KEI_Nを先手の桂の番号3(00000011)と定義
#define GIN_N 4 // GIN_Nを先手の銀の番号4(00000100)と定義
#define KIN_N 5 // KIN_Nを先手の金の番号5(00000101)と定義
#define KAKU_N 6 // KAKU_Nを先手の角の番号6(00000110)と定義
#define HI_N 7 // HI_Nを先手の飛の番号7(00000111)と定義
#define GYOKU_N 8 // GYOKU_Nを先手の玉の番号8(00001000)と定義
#define NARI_N 8 // NARI_Nを成り変換番号8(00001000)と定義
#define N_FU_N 9 // N_FU_Nを先手のとの番号9(00001001)と定義
#define N_KYO_N 10 // N_KYO_Nを先手の成香の番号10(00001010)と定義
#define N_KEI_N 11 // N_KEI_Nを先手の成桂の番号11(00001011)と定義
#define N_GIN_N 12 // N_GIN_Nを先手の成銀の番号12(00001100)と定義
#define N_KAKU_N 14 // N_KAKU_Nを先手の馬の番号14(00001110)と定義
#define N_HI_N 15 // N_HI_Nを先手の龍の番号15(00001111)と定義
#define GOTE_N 16 // GOTE_Nを先手→後手番号16(00010000)と定義
#define G_FU_N 17 // G_FU_Nを後手の歩の番号17(00010001)と定義
#define G_KYO_N 18 // G_KYO_Nを後手の香の番号18(00010010)と定義
#define G_KEI_N 19 // G_KEI_Nを後手の桂の番号19(00010011)と定義
#define G_GIN_N 20 // G_GIN_Nを後手の銀の番号20(00010100)と定義
#define G_KIN_N 21 // G_KIN_Nを後手の金の番号21(00010101)と定義
#define G_KAKU_N 22 // G_KAKU_Nを後手の角の番号22(00010110)と定義
#define G_HI_N 23 // G_HI_Nを後手の飛の番号23(00010111)と定義
#define OU_N 24 // OU_Nを後手の王の番号24(00011000)と定義
#define N_G_FU_N 25 // N_G_FU_Nを後手のとの番号25(00011001)と定義
#define N_G_KYO_N 26 //N_G_KYO_Nを後手の成香の番号26(00011010)と定義
#define N_G_KEI_N 27 //N_G_KEI_Nを後手の成桂の番号27(00011011)と定義
#define N_G_GIN_N 28 //N_G_GIN_Nを後手の成銀の番号28(00011100)と定義
#define N_G_KAKU_N 30 // N_G_KAKU_Nを後手の馬の番号30(00011110)と定義
#define N_G_HI_N 31 // N_G_HI_Nを後手の龍の番号31(00011111)と定義

#define SENTE 0 //SENTEを0と定義
#define GOTE 1 //GOTEを1と定義

#include <stdio.h>
#include <conio.h>
#include <stdlib.h>

int tesuu_n; //手数カウント

int s_te_m_r; //先手の指し手の移動元(列)
int s_te_m_g; //先手の指し手の移動元(行)
int s_te_s_r; //先手の指し手の移動先(列)
int s_te_s_g; //先手の指し手の移動先(行)
int s_te_n; //先手の成りフラグ

int g_te_m_r; //後手の指し手の移動元(列)
int g_te_m_g; //後手の指し手の移動元(行)
int g_te_s_r; //後手の指し手の移動先(列)
int g_te_s_g; //後手の指し手の移動先(行)
int g_te_n; //後手の成りフラグ

int s_tem_m_koma_n = 0; //先手の指し手の移動元(駒番号)
int s_tem_s_koma_n = 0; //先手の指し手の移動先(駒番号)
int g_tem_m_koma_n = 0; //後手の指し手の移動元(駒番号)
int g_tem_s_koma_n = 0; //後手の指し手の移動先(駒番号)
int sasite_koma_n = 0; //指し手表示用(駒番号)

char *koma_h[] = {
KUHAKU, // 要素0にKUHAKUをセット
FU, // 要素1にFUをセット
KYO, // 要素2にKYOをセット
KEI, // 要素3にKEIをセット
GIN, // 要素4にGINをセット
KIN, // 要素5にKINをセット
KAKU, // 要素6にKAKUをセット
HI, // 要素7にHIをセット
GYOKU, // 要素8にGYOKUをセット
N_FU, // 要素9にN_FUをセット
N_KYO, //要素10にN_KYOをセット
N_KEI, //要素11にN_KEIをセット
N_GIN, //要素12にN_GINをセット
KUHAKU, //要素13にKUHAKUをセット
N_KAKU, //要素14にN_KAKUをセット
N_HI, //要素15にN_HIをセット
KUHAKU, //要素16にKUHAKUをセット
G_FU, //要素17にG_FUをセット
G_KYO, //要素18にG_KYOをセット
G_KEI, //要素19にG_KEIをセット
G_GIN, //要素20にG_GINをセット
G_KIN, //要素21にG_KINをセット
G_KAKU, //要素22にG_KAKUをセット
G_HI, //要素23にG_HIをセット
OU, //要素24にOUをセット
N_G_FU, //要素25にN_G_FUをセット
N_G_KYO, //要素26にN_G_KYOをセット
N_G_KEI, //要素27にN_G_KEIをセット
N_G_GIN, //要素28にN_G_GINをセット
KUHAKU, //要素29にKUHAKUをセット
N_G_KAKU, //要素30にN_G_KAKUをセット
N_G_HI //要素31にN_G_HIをセット
};

char *koma_s_h[] = {
KUHAKU, // 要素0にKUHAKUをセット
FU, // 要素1にFUをセット
KYO, // 要素2にKYOをセット
KEI, // 要素3にKEIをセット
GIN, // 要素4にGINをセット
KIN, // 要素5にKINをセット
KAKU, // 要素6にKAKUをセット
HI, // 要素7にHIをセット
GYOKU, // 要素8にGYOKUをセット
N_H_FU, // 要素9にN_H_FUをセット
N_H_KYO, //要素10にN_H_KYOをセット
N_H_KEI, //要素11にN_H_KEIをセット
N_H_GIN, //要素12にN_H_GINをセット
KUHAKU, //要素13にKUHAKUをセット
N_H_KAKU, //要素14にN_H_KAKUをセット
N_H_HI, //要素15にN_H_HIをセット
KUHAKU, //要素16にKUHAKUをセット
FU, //要素17にFUをセット
KYO, //要素18にKYOをセット
KEI, //要素19にKEIをセット
GIN, //要素20にGINをセット
KIN, //要素21にKINをセット
KAKU, //要素22にKAKUをセット
HI, //要素23にHIをセット
H_OU, //要素24にH_OUをセット
N_H_FU, //要素25にN_H_FUをセット
N_H_KYO, //要素26にN_H_KYOをセット
N_H_KEI, //要素27にN_H_KEIをセット
N_H_GIN, //要素28にN_H_GINをセット
N_H_KAKU, //要素30にN_H_KAKUをセット
N_H_HI //要素31にN_H_HIをセット
};

/* 盤面の初期設定 */
int banmen[9][9] = { { G_KYO_N, G_KEI_N, G_GIN_N, G_KIN_N, OU_N, G_KIN_N, G_GIN_N, G_KEI_N, G_KYO_N },
{ KUHAKU_N, G_KAKU_N, KUHAKU_N, KUHAKU_N, KUHAKU_N, KUHAKU_N, KUHAKU_N, G_HI_N, KUHAKU_N },
{ G_FU_N, G_FU_N, G_FU_N, G_FU_N, G_FU_N, G_FU_N, G_FU_N, G_FU_N, G_FU_N },
{ KUHAKU_N, KUHAKU_N, KUHAKU_N, KUHAKU_N, KUHAKU_N, KUHAKU_N, KUHAKU_N, KUHAKU_N, KUHAKU_N },
{ KUHAKU_N, KUHAKU_N, KUHAKU_N, KUHAKU_N, KUHAKU_N, KUHAKU_N, KUHAKU_N, KUHAKU_N, KUHAKU_N },
{ KUHAKU_N, KUHAKU_N, KUHAKU_N, KUHAKU_N, KUHAKU_N, KUHAKU_N, KUHAKU_N, KUHAKU_N, KUHAKU_N },
{ FU_N, FU_N, FU_N, FU_N, FU_N, FU_N, FU_N, FU_N, FU_N },
{ KUHAKU_N, HI_N, KUHAKU_N, KUHAKU_N, KUHAKU_N, KUHAKU_N, KUHAKU_N, KAKU_N, KUHAKU_N },
{ KYO_N, KEI_N, GIN_N, KIN_N, GYOKU_N, KIN_N, GIN_N, KEI_N, KYO_N } };

/* 持ち駒の構造体 */
struct Motigoma{
int kazu;
int fu;
int kyo;
int kei;
int gin;
int kin;
int kaku;
int hi;
};

struct Motigoma s_motigoma = { 0, 0, 0, 0, 0, 0, 0, 0 }; //先手の持ち駒の構造体
struct Motigoma g_motigoma = { 0, 0, 0, 0, 0, 0, 0, 0 }; //後手の持ち駒の構造体
int s_motigoma_n; //先手の持ち駒番号
int g_motigoma_n; //後手の持ち駒番号

int banmen_hyouji(); //盤面の表示関数
int sente_nyuuryoku(); //先手の指し手の入力関数
int gote_nyuuryoku(); //後手の指し手の入力関数
int sasite_hyouji(int); //指し手の表示関数
int sasite_nyuuryoku(); //指し手の入力関数
int motigoma_hyouji(); //持ち駒の表示関数
int motigoma_nyuuryoku(struct Motigoma *); //持ち駒の入力関数
int koma_ido_chk(int,int,int,int,int); //駒の移動チェック関数

/* 先手の指し手の入力関数 */
int sente_nyuuryoku()
{
while (1)
{
s_tem_m_koma_n = 0;
sasite_koma_n = 0;

/* 先手の指し手の移動元(列)の入力 */
printf("\n先手の指し手の移動元(列)か持ち駒(0)を入力してください:");

s_te_m_r = sasite_nyuuryoku(); //指し手を取得

if (s_te_m_r == 0){ //持ち駒が選択された場合
if (s_motigoma.kazu == 0){
printf("\n持ち駒がありません。");
continue;
}
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 {
s_motigoma_n = 0;

/* 先手の指し手の移動元(行)の入力 */
printf("\n先手の指し手の移動元(行)か前に戻る(0)を入力してください:");

s_te_m_g = sasite_nyuuryoku(); //指し手を取得

if (s_te_m_g == 0) //前に戻るが選択された場合
continue;

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 ((FU_N <= s_tem_m_koma_n) && (s_tem_m_koma_n <= GYOKU_N)) //移動元が先手の駒の場合
break;
else if ((N_FU_N <= s_tem_m_koma_n) && (s_tem_m_koma_n <= N_HI_N)) //移動元が先手の成駒の場合
break;
else if (s_motigoma_n == 0) //元に戻る場合
continue;
else
printf("\n先手の駒を入力してください。");
}

while (1)
{
/* 先手の指し手の移動先(列)の入力 */
printf("\n先手の指し手の移動先(列)か前に戻る(0)を入力してください:");

s_te_s_r = sasite_nyuuryoku(); //指し手を取得

if (s_te_s_r == 0) //前に戻るが選択された場合
continue;

/* 先手の指し手の移動先(行)の入力 */
printf("\n先手の指し手の移動先(行)か前に戻る(0)を入力してください:");

s_te_s_g = sasite_nyuuryoku(); //指し手を取得

if (s_te_s_g == 0) //前に戻るが選択された場合
continue;

s_tem_s_koma_n = banmen[s_te_s_g - 1][s_te_s_r - 1]; //先手の指し手の移動先(駒番号)を保存
if ((s_tem_s_koma_n == OU_N) && (s_motigoma_n == 0)) //移動先が後手の王で移動元が持ち駒でない場合
return 1; //詰み(先手の勝利)
else if ((s_te_m_r == s_te_s_r) && (s_te_m_g == s_te_s_g)) //移動元と移動先が同じ場合
printf("\n移動可能な移動先を入力してください。");
else if (s_tem_s_koma_n == GYOKU_N) //移動先が先手の玉の場合(味方の駒取得可能特別ルール内の例外)
printf("\n移動可能な移動先を入力してください。");
else if (s_motigoma_n > 0 && (s_tem_s_koma_n != KUHAKU_N)) //持ち駒で駒のある移動先の場合
printf("\n駒がない場所を入力してください。");
else if ((s_motigoma_n == 0) && (koma_ido_chk(s_tem_m_koma_n, s_te_m_r, s_te_m_g, s_te_s_r, s_te_s_g) == NG)) //持ち駒でなく、駒の移動が正しくない場合
printf("\n移動可能な移動先を入力してください。");
else
break;
}

/* 先手の移動元か移動先が後手陣地で移動元が持ち駒でない場合 */
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_motigoma_n == 0) {
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ループを抜ける
}
}
}
else {
s_te_n = 0;
}

banmen[s_te_m_g - 1][s_te_m_r - 1] = KUHAKU_N; //先手の指し手の移動元に空白を保存

if (s_tem_s_koma_n != KUHAKU_N) { //移動先に駒がある場合
/* 移動先が歩の場合 */
if ((s_tem_s_koma_n == G_FU_N) || (s_tem_s_koma_n == FU_N) || (s_tem_s_koma_n == N_G_FU_N) || (s_tem_s_koma_n == N_FU_N)){
s_motigoma.fu++; //歩を持ち駒に加える
s_motigoma.kazu++; //持ち駒カウントを増やす
}
/* 移動先が香の場合 */
else if ((s_tem_s_koma_n == G_KYO_N) || (s_tem_s_koma_n == KYO_N) || (s_tem_s_koma_n == N_G_KYO_N) || (s_tem_s_koma_n == N_KYO_N)){
s_motigoma.kyo++; //香を持ち駒に加える
s_motigoma.kazu++; //持ち駒カウントを増やす
}
/* 移動先が桂の場合 */
else if ((s_tem_s_koma_n == G_KEI_N) || (s_tem_s_koma_n == KEI_N) || (s_tem_s_koma_n == N_G_KEI_N) || (s_tem_s_koma_n == N_KEI_N)){
s_motigoma.kei++; //桂を持ち駒に加える
s_motigoma.kazu++; //持ち駒カウントを増やす
}
/* 移動先が銀の場合 */
else if ((s_tem_s_koma_n == G_GIN_N) || (s_tem_s_koma_n == GIN_N) || (s_tem_s_koma_n == N_G_GIN_N) || (s_tem_s_koma_n == N_GIN_N)){
s_motigoma.gin++; //銀を持ち駒に加える
s_motigoma.kazu++; //持ち駒カウントを増やす
}
/* 移動先が金の場合 */
else if ((s_tem_s_koma_n == G_KIN_N) || (s_tem_s_koma_n == KIN_N)){
s_motigoma.kin++; //金を持ち駒に加える
s_motigoma.kazu++; //持ち駒カウントを増やす
}
/* 移動先が角の場合 */
else if ((s_tem_s_koma_n == G_KAKU_N) || (s_tem_s_koma_n == KAKU_N) || (s_tem_s_koma_n == N_G_KAKU_N) || (s_tem_s_koma_n == N_KAKU_N)){
s_motigoma.kaku++; //角を持ち駒に加える
s_motigoma.kazu++; //持ち駒カウントを増やす
}
/* 移動先が飛の場合 */
else if ((s_tem_s_koma_n == G_HI_N) || (s_tem_s_koma_n == HI_N) || (s_tem_s_koma_n == N_G_HI_N) || (s_tem_s_koma_n == N_HI_N)){
s_motigoma.hi++; //飛を持ち駒に加える
s_motigoma.kazu++; //持ち駒カウントを増やす
}
}

banmen[s_te_s_g - 1][s_te_s_r - 1] = s_tem_m_koma_n; //先手の指し手の移動先に移動元の駒を保存

return 0;
}

/* 後手の指し手の入力関数 */
int gote_nyuuryoku()
{
while (1)
{
g_tem_m_koma_n = 0;
sasite_koma_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);
continue;
}
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) //前に戻るが選択された場合
continue;

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 ((G_FU_N <= g_tem_m_koma_n) && (g_tem_m_koma_n <= OU_N)) //移動元が後手の駒の場合
break;
else if ((N_G_FU_N <= g_tem_m_koma_n) && (g_tem_m_koma_n <= N_G_HI_N)) //移動元が後手の成駒の場合
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) //前に戻るが選択された場合
continue;

/* 後手の指し手の移動先(行)の入力 */
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_s_koma_n == GYOKU_N) && (g_motigoma_n == 0)) //移動先が先手の玉で移動元が持ち駒でない場合
return 1; //詰み(先手の勝利)
else if ((g_te_m_r == g_te_s_r) && (g_te_m_g == g_te_s_g)) //移動元と移動先が同じ場合
printf(AOIRO"\n移動可能な移動先を入力してください。"KIHONIRO);
else if (g_tem_s_koma_n == OU_N) //移動先が後手の王の場合(味方の駒取得可能特別ルール内の例外)
printf(AOIRO"\n移動可能な移動先を入力してください。"KIHONIRO);
else if (g_motigoma_n > 0 && (g_tem_s_koma_n != KUHAKU_N)) //持ち駒で駒のある移動先の場合
printf(AOIRO"\n駒がない場所を入力してください。"KIHONIRO);
else if ((g_motigoma_n == 0) && (koma_ido_chk(g_tem_m_koma_n, g_te_m_r, g_te_m_g, g_te_s_r, g_te_s_g) == NG)) //持ち駒でなく、駒の移動が正しくない場合
printf("\n移動可能な移動先を入力してください。");
else
break;
}

/* 後手の移動元か移動先が先手陣地で移動元が持ち駒でない場合 */
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_motigoma_n == 0)) {
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ループを抜ける
}
}
}
else {
g_te_n = 0;
}

banmen[g_te_m_g - 1][g_te_m_r - 1] = KUHAKU_N; //後手の指し手の移動元に空白を保存

if (g_tem_s_koma_n != KUHAKU_N) { //移動先に駒がある場合
/* 移動先が歩の場合 */
if ((g_tem_s_koma_n == G_FU_N) || (g_tem_s_koma_n == FU_N) || (g_tem_s_koma_n == N_G_FU_N) || (g_tem_s_koma_n == N_FU_N)) {
g_motigoma.fu++; //歩を持ち駒に加える
g_motigoma.kazu++; //持ち駒カウントを増やす
}
/* 移動先が香の場合 */
else if ((g_tem_s_koma_n == G_KYO_N) || (g_tem_s_koma_n == KYO_N) || (g_tem_s_koma_n == N_G_KYO_N) || (g_tem_s_koma_n == N_KYO_N)){
g_motigoma.kyo++; //香を持ち駒に加える
g_motigoma.kazu++; //持ち駒カウントを増やす
}
/* 移動先が桂の場合 */
else if ((g_tem_s_koma_n == G_KEI_N) || (g_tem_s_koma_n == KEI_N) || (g_tem_s_koma_n == N_G_KEI_N) || (g_tem_s_koma_n == N_KEI_N)){
g_motigoma.kei++; //桂を持ち駒に加える
g_motigoma.kazu++; //持ち駒カウントを増やす
}
/* 移動先が銀の場合 */
else if ((g_tem_s_koma_n == G_GIN_N) || (g_tem_s_koma_n == GIN_N) || (g_tem_s_koma_n == N_G_GIN_N) || (g_tem_s_koma_n == N_GIN_N)){
g_motigoma.gin++; //銀を持ち駒に加える
g_motigoma.kazu++; //持ち駒カウントを増やす
}
/* 移動先が金の場合 */
else if ((g_tem_s_koma_n == G_KIN_N) || (g_tem_s_koma_n == KIN_N)){
g_motigoma.kin++; //金を持ち駒に加える
g_motigoma.kazu++; //持ち駒カウントを増やす
}
/* 移動先が角の場合 */
else if ((g_tem_s_koma_n == G_KAKU_N) || (g_tem_s_koma_n == KAKU_N) || (g_tem_s_koma_n == N_G_KAKU_N) || (g_tem_s_koma_n == N_KAKU_N)){
g_motigoma.kaku++; //角を持ち駒に加える
g_motigoma.kazu++; //持ち駒カウントを増やす
}
/* 移動先が飛の場合 */
else if ((g_tem_s_koma_n == G_HI_N) || (g_tem_s_koma_n == HI_N) || (g_tem_s_koma_n == N_G_HI_N) || (g_tem_s_koma_n == N_HI_N)){
g_motigoma.hi++; //飛を持ち駒に加える
g_motigoma.kazu++; //持ち駒カウントを増やす
}
}

banmen[g_te_s_g - 1][g_te_s_r - 1] = g_tem_m_koma_n; //後手の指し手の移動先に移動元の駒を保存

return 0;
}

/* 駒の移動チェック関数 */
int koma_ido_chk(int ido_moto_koma_n, int ido_m_r, int ido_m_g, int ido_s_r, int ido_s_g)
{
int i,j;

switch (ido_moto_koma_n)
{
case FU_N: //移動元駒が先手の歩の場合
if ((ido_m_r == ido_s_r) && (ido_m_g - 1 == ido_s_g)) //移動元列と移動先列が同じで移動先行が移動元行-1の時
return OK;
else
return NG;
case G_FU_N: //移動元駒が後手の歩の場合
if ((ido_m_r == ido_s_r) && (ido_m_g + 1 == ido_s_g)) //移動元列と移動先列が同じで移動先行が移動元行+1の時
return OK;
else
return NG;
case KYO_N: //移動元駒が先手の香の場合
if ((ido_m_r == ido_s_r) && (ido_m_g > ido_s_g)){ //移動元列と移動先列が同じで移動先行が移動元行より小さい時
for (i = ido_m_g - 1 ; i > ido_s_g; i--){ //移動元行から移動先行手前まで
if (banmen[i - 1][ido_s_r - 1] != KUHAKU_N) //途中に駒がある場合
return NG;
}
return OK;
}
else
return NG;
case G_KYO_N: //移動元駒が後手の香の場合
if ((ido_m_r == ido_s_r) && (ido_m_g < ido_s_g)){ //移動元列と移動先列が同じで移動先行が移動元行より大きい時
for (i = ido_m_g + 1 ; i < ido_s_g; i++){ //移動元行から移動先行手前まで
if (banmen[i - 1][ido_s_r - 1] != KUHAKU_N) //途中に駒がある場合
return NG;
}
return OK;
}
else
return NG;
case KEI_N: //移動元駒が先手の桂の場合
if (((ido_m_r - 1 == ido_s_r) || (ido_m_r + 1 == ido_s_r)) //移動先列が移動元列±1で
&& (ido_m_g - 2 == ido_s_g)) //移動先行が移動元行-2の時
return OK;
else
return NG;
case G_KEI_N: //移動元駒が後手の桂の場合
if (((ido_m_r - 1 == ido_s_r) || (ido_m_r + 1 == ido_s_r)) //移動先列が移動元列±1で
&& (ido_m_g + 2 == ido_s_g)) //移動先行が移動元行+2の時
return OK;
else
return NG;
case GIN_N: //移動元駒が先手の銀の場合
if ((((ido_m_r - 1 == ido_s_r) || (ido_m_r + 1 == ido_s_r)) //移動先列が移動元列±1で
&& ((ido_m_g - 1 == ido_s_g) || (ido_m_g + 1 == ido_s_g))) //移動先行が移動元行±1か
|| ((ido_m_r == ido_s_r) && (ido_m_g - 1 == ido_s_g))) //移動元列と移動先列が同じで移動先行が移動元行-1の時
return OK;
else
return NG;
case KIN_N: //移動元駒が先手の金の場合
case N_FU_N: //移動元駒が先手のとの場合
case N_KYO_N: //移動元駒が先手の成香のの場合
case N_KEI_N: //移動元駒が先手の成桂の場合
case N_GIN_N: //移動元駒が先手の成銀の場合
if ((((ido_m_r - 1 == ido_s_r) || (ido_m_r + 1 == ido_s_r)) //移動先列が移動元列±1で
&& ((ido_m_g - 1 == ido_s_g) || (ido_m_g == ido_s_g))) //移動先行が移動元行-1か同じか
|| (ido_m_r == ido_s_r) //移動元列と移動先列が同じで
&& ((ido_m_g - 1 == ido_s_g) || (ido_m_g + 1 == ido_s_g))) //移動先行が移動元行±1の時
return OK;
else
return NG;
case G_KIN_N: //移動元駒が後手の金の場合
case N_G_FU_N: //移動元駒が後手のとの場合
case N_G_KYO_N: //移動元駒が後手の成香のの場合
case N_G_KEI_N: //移動元駒が後手の成桂の場合
case N_G_GIN_N: //移動元駒が後手の成銀の場合
if ((((ido_m_r - 1 == ido_s_r) || (ido_m_r + 1 == ido_s_r)) //移動先列が移動元列±1で
&& ((ido_m_g + 1 == ido_s_g) || (ido_m_g == ido_s_g))) //移動先行が移動元行+1か同じか
|| (ido_m_r == ido_s_r) //移動元列と移動先列が同じで
&& ((ido_m_g - 1 == ido_s_g) || (ido_m_g + 1 == ido_s_g))) //移動先行が移動元行±1の時
return OK;
else
return NG;
case N_KAKU_N: //移動元駒が先手の馬の場合
case N_G_KAKU_N: //移動元駒が後手の馬の場合
if (((ido_m_r == ido_s_r) || (ido_m_r - 1 == ido_s_r) || (ido_m_r + 1 == ido_s_r)) //移動元列と移動先列が同じか±で1
&& ((ido_m_g == ido_s_g) || (ido_m_g - 1 == ido_s_g) || (ido_m_g + 1 == ido_s_g))) //移動元行と移動先行が同じか±1の時
return OK;
case KAKU_N: //移動元駒が先手の角の場合
case G_KAKU_N: //移動元駒が後手の角の場合
if ((ido_m_r > ido_s_r) && (ido_m_g > ido_s_g)){ //移動先列が移動元列より小さく、移動先行が移動元行より小さい時
if ((ido_m_r - ido_s_r) != (ido_m_g - ido_s_g)) //列と行の移動値が一致しない時
return NG;
for (i = ido_m_g - 1, j = ido_m_r - 1; i > ido_s_g, j > ido_s_r; i--, j--){ //移動元から移動先手前まで
if (banmen[i - 1][j - 1] != KUHAKU_N) //途中に駒がある場合
return NG;
}
return OK;
}
else if ((ido_m_r > ido_s_r) && (ido_m_g < ido_s_g)){ //移動先列が移動元列より小さく、移動先行が移動元行より大きい時
if ((ido_m_r - ido_s_r) != (ido_s_g - ido_m_g)) //列と行の移動値が一致しない時
return NG;
for (i = ido_m_g + 1, j = ido_m_r - 1; i < ido_s_g, j > ido_s_r; i++, j--){ //移動元から移動先手前まで
if (banmen[i - 1][j - 1] != KUHAKU_N) //途中に駒がある場合
return NG;
}
return OK;
}
else if ((ido_m_r < ido_s_r) && (ido_m_g > ido_s_g)){ //移動先列が移動元列より大きく、移動先行が移動元行より小さい時
if ((ido_s_r - ido_m_r) != (ido_m_g - ido_s_g)) //列と行の移動値が一致しない時
return NG;
for (i = ido_m_g - 1, j = ido_m_r + 1; i > ido_s_g, j < ido_s_r; i--, j++){ //移動元から移動先手前まで
if (banmen[i - 1][j - 1] != KUHAKU_N) //途中に駒がある場合
return NG;
}
return OK;
}
else if ((ido_m_r < ido_s_r) && (ido_m_g < ido_s_g)){ //移動先列が移動元列より大きく、移動先行が移動元行より大きい時
if ((ido_s_r - ido_m_r) != (ido_s_g - ido_m_g)) //列と行の移動値が一致しない時
return NG;
for (i = ido_m_g + 1, j = ido_m_r + 1; i < ido_s_g, j < ido_s_r; i++, j++){ //移動元から移動先手前まで
if (banmen[i - 1][j - 1] != KUHAKU_N) //途中に駒がある場合
return NG;
}
return OK;
}
else
return NG;
case N_HI_N: //移動元駒が先手の龍の場合
case N_G_HI_N: //移動元駒が後手の龍の場合
if (((ido_m_r - 1 == ido_s_r) || (ido_m_r + 1 == ido_s_r)) //移動元列と移動先列が±で1
&& ((ido_m_g - 1 == ido_s_g) || (ido_m_g + 1 == ido_s_g))) //移動元行と移動先行が±1の時
return OK;
case HI_N: //移動元駒が先手の飛の場合
case G_HI_N: //移動元駒が後手の飛の場合
if ((ido_m_r == ido_s_r) && (ido_m_g > ido_s_g)){ //移動元列と移動先列が同じで移動先行が移動元行より小さい時
for (i = ido_m_g - 1; i > ido_s_g; i--){ //移動元行から移動先行手前まで
if (banmen[i - 1][ido_s_r - 1] != KUHAKU_N) //途中に駒がある場合
return NG;
}
return OK;
}
else if ((ido_m_r == ido_s_r) && (ido_m_g < ido_s_g)){ //移動元列と移動先列が同じで移動先行が移動元行より大きい時
for (i = ido_m_g + 1; i < ido_s_g; i++){ //移動元行から移動先行手前まで
if (banmen[i - 1][ido_s_r - 1] != KUHAKU_N) //途中に駒がある場合
return NG;
}
return OK;
}
else if ((ido_m_r > ido_s_r) && (ido_m_g == ido_s_g)){ //移動元行と移動先行が同じで移動先列が移動元列より小さい時
for (i = ido_m_r - 1; i > ido_s_r; i--){ //移動元列から移動先列手前まで
if (banmen[ido_s_g - 1][i - 1] != KUHAKU_N) //途中に駒がある場合
return NG;
}
return OK;
}
else if ((ido_m_r < ido_s_r) && (ido_m_g == ido_s_g)){ //移動元行と移動先行が同じで移動先列が移動元列より大きい時
for (i = ido_m_r + 1; i < ido_s_r; i++){ //移動元列から移動先列手前まで
if (banmen[ido_s_g - 1][i - 1] != KUHAKU_N) //途中に駒がある場合
return NG;
}
return OK;
}
else
return NG;
case GYOKU_N: //移動元駒が先手の玉の場合
case OU_N: //移動元駒が後手の王の場合
if (((ido_m_r == ido_s_r) || (ido_m_r - 1 == ido_s_r) || (ido_m_r + 1 == ido_s_r)) //移動元列と移動先列が同じか±で1
&& ((ido_m_g == ido_s_g) || (ido_m_g - 1 == ido_s_g) || (ido_m_g + 1 == ido_s_g))) //移動元行と移動先行が同じか±1の時
return OK;
else
return NG;
default:
return OK;
break;
}
}



将時画面16022901


指し手のファイル保管と表示の追加とバグ修正をしました。


ソース:stime_16022601


/* stime.c */

#define KUHAKU " " //KUHAKUを" "と定義

#define FU "歩" //FUを歩と定義
#define KYO "香" //KYOを香と定義
#define KEI "桂" //KEIを桂と定義
#define GIN "銀" //GINを銀と定義
#define KIN "金" //KINを金と定義
#define KAKU "角" //KAKUを角と定義
#define HI "飛" //HIを飛と定義
#define GYOKU "玉" //GYOKUを玉と定義

#define AOIRO "\x1b[34m" //AOIROを青色のエスケープシーケンスと定義
#define KIHONIRO "\x1b[39m" //KIHONIROを基本色のエスケープシーケンスと定義
#define B_AKA "\x1b[41m" //B_AKAを赤色背景のエスケープシーケンスと定義
#define B_AOIRO "\x1b[44m" //B_AOIROを青色背景のエスケープシーケンスと定義
#define B_KIHONIRO "\x1b[49m" //B_KIHONIROを基本色背景のエスケープシーケンスと定義

#define G_FU AOIRO"歩"KIHONIRO //G_FUを青色の歩と定義
#define G_KYO AOIRO"香"KIHONIRO //G_KYOを青色の香と定義
#define G_KEI AOIRO"桂"KIHONIRO //G_KEIを青色の桂と定義
#define G_GIN AOIRO"銀"KIHONIRO //G_GINを青色の銀と定義
#define G_KIN AOIRO"金"KIHONIRO //G_KINを青色の金と定義
#define G_KAKU AOIRO"角"KIHONIRO //G_KAKUを青色の角と定義
#define G_HI AOIRO"飛"KIHONIRO //G_HIを青色の飛と定義
#define OU AOIRO"王"KIHONIRO //G_OUを青色の王と定義

#define N_FU B_AKA"と"B_KIHONIRO //N_FUを赤色背景のとと定義
#define N_KYO B_AKA"香"B_KIHONIRO //N_KYOを赤色背景の香と定義
#define N_KEI B_AKA"桂"B_KIHONIRO //N_KEIを赤色背景の桂と定義
#define N_GIN B_AKA"銀"B_KIHONIRO //N_GINを赤色背景の銀と定義
#define N_KAKU B_AKA"馬"B_KIHONIRO //N_KAKUを赤色背景の馬と定義
#define N_HI B_AKA"龍"B_KIHONIRO //N_HIを赤色背景の龍と定義

#define N_G_FU B_AOIRO"と"B_KIHONIRO //N_G_FUを青色背景のとと定義
#define N_G_KYO B_AOIRO"香"B_KIHONIRO //N_G_KYOを青色背景の香と定義
#define N_G_KEI B_AOIRO"桂"B_KIHONIRO //N_G_KEIを青色背景の桂と定義
#define N_G_GIN B_AOIRO"銀"B_KIHONIRO //N_G_GINを青色背景の銀と定義
#define N_G_KAKU B_AOIRO"馬"B_KIHONIRO //N_G_KAKUを青色背景の馬と定義
#define N_G_HI B_AOIRO"龍"B_KIHONIRO //N_G_HIを青色背景の龍と定義

#define N_H_FU "と" //N_H_FUをとと定義
#define N_H_KYO "成香" //N_H_KYOを成香と定義
#define N_H_KEI "成桂" //N_H_KEIを成桂と定義
#define N_H_GIN "成銀" //N_H_GINを成銀と定義
#define N_H_KAKU "馬" //N_H_KAKUを馬と定義
#define N_H_HI "龍" //N_H_HIを龍と定義

#define KUHAKU_N 0 // KUHAKU_Nを" "の番号0(00000000)と定義
#define FU_N 1 // FU_Nを先手の歩の番号1(00000001)と定義
#define KYO_N 2 // KYO_Nを先手の香の番号2(00000010)と定義
#define KEI_N 3 // KEI_Nを先手の桂の番号3(00000011)と定義
#define GIN_N 4 // GIN_Nを先手の銀の番号4(00000100)と定義
#define KIN_N 5 // KIN_Nを先手の金の番号5(00000101)と定義
#define KAKU_N 6 // KAKU_Nを先手の角の番号6(00000110)と定義
#define HI_N 7 // HI_Nを先手の飛の番号7(00000111)と定義
#define GYOKU_N 8 // GYOKU_Nを先手の玉の番号8(00001000)と定義
#define NARI_N 8 // NARI_Nを成り変換番号8(00001000)と定義
#define N_FU_N 9 // N_FU_Nを先手のとの番号9(00001001)と定義
#define N_KYO_N 10 // N_KYO_Nを先手の成香の番号10(00001010)と定義
#define N_KEI_N 11 // N_KEI_Nを先手の成桂の番号11(00001011)と定義
#define N_GIN_N 12 // N_GIN_Nを先手の成銀の番号12(00001100)と定義
#define N_KAKU_N 14 // N_KAKU_Nを先手の馬の番号14(00001110)と定義
#define N_HI_N 15 // N_HI_Nを先手の龍の番号15(00001111)と定義
#define GOTE_N 16 // GOTE_Nを先手→後手番号16(00010000)と定義
#define G_FU_N 17 // G_FU_Nを後手の歩の番号17(00010001)と定義
#define G_KYO_N 18 // G_KYO_Nを後手の香の番号18(00010010)と定義
#define G_KEI_N 19 // G_KEI_Nを後手の桂の番号19(00010011)と定義
#define G_GIN_N 20 // G_GIN_Nを後手の銀の番号20(00010100)と定義
#define G_KIN_N 21 // G_KIN_Nを後手の金の番号21(00010101)と定義
#define G_KAKU_N 22 // G_KAKU_Nを後手の角の番号22(00010110)と定義
#define G_HI_N 23 // G_HI_Nを後手の飛の番号23(00010111)と定義
#define OU_N 24 // OU_Nを後手の王の番号24(00011000)と定義
#define N_G_FU_N 25 // N_G_FU_Nを後手のとの番号25(00011001)と定義
#define N_G_KYO_N 26 //N_G_KYO_Nを後手の成香の番号26(00011010)と定義
#define N_G_KEI_N 27 //N_G_KEI_Nを後手の成桂の番号27(00011011)と定義
#define N_G_GIN_N 28 //N_G_GIN_Nを後手の成銀の番号28(00011100)と定義
#define N_G_KAKU_N 30 // N_G_KAKU_Nを後手の馬の番号30(00011110)と定義
#define N_G_HI_N 31 // N_G_HI_Nを後手の龍の番号31(00011111)と定義

#define SENTE 0 //SENTEを0と定義
#define GOTE 1 //GOTEを1と定義

#include <stdio.h>
#include <conio.h>
#include <stdlib.h>

int tesuu_n; //手数カウント

int s_te_m_r; //先手の指し手の移動元(列)
int s_te_m_g; //先手の指し手の移動元(行)
int s_te_s_r; //先手の指し手の移動先(列)
int s_te_s_g; //先手の指し手の移動先(行)
int s_te_n; //先手の成りフラグ

int g_te_m_r; //後手の指し手の移動元(列)
int g_te_m_g; //後手の指し手の移動元(行)
int g_te_s_r; //後手の指し手の移動先(列)
int g_te_s_g; //後手の指し手の移動先(行)
int g_te_n; //後手の成りフラグ

int s_tem_m_koma_n = 0; //先手の指し手の移動元(駒番号)
int s_tem_s_koma_n = 0; //先手の指し手の移動先(駒番号)
int g_tem_m_koma_n = 0; //後手の指し手の移動元(駒番号)
int g_tem_s_koma_n = 0; //後手の指し手の移動先(駒番号)
int sasite_koma_n = 0; //指し手表示用(駒番号)

char *koma_h[] = {
KUHAKU, // 要素0にKUHAKUをセット
FU, // 要素1にFUをセット
KYO, // 要素2にKYOをセット
KEI, // 要素3にKEIをセット
GIN, // 要素4にGINをセット
KIN, // 要素5にKINをセット
KAKU, // 要素6にKAKUをセット
HI, // 要素7にHIをセット
GYOKU, // 要素8にGYOKUをセット
N_FU, // 要素9にN_FUをセット
N_KYO, //要素10にN_KYOをセット
N_KEI, //要素11にN_KEIをセット
N_GIN, //要素12にN_GINをセット
KUHAKU, //要素13にKUHAKUをセット
N_KAKU, //要素14にN_KAKUをセット
N_HI, //要素15にN_HIをセット
KUHAKU, //要素16にKUHAKUをセット
G_FU, //要素17にG_FUをセット
G_KYO, //要素18にG_KYOをセット
G_KEI, //要素19にG_KEIをセット
G_GIN, //要素20にG_GINをセット
G_KIN, //要素21にG_KINをセット
G_KAKU, //要素22にG_KAKUをセット
G_HI, //要素23にG_HIをセット
OU, //要素24にOUをセット
N_G_FU, //要素25にN_G_FUをセット
N_G_KYO, //要素26にN_G_KYOをセット
N_G_KEI, //要素27にN_G_KEIをセット
N_G_GIN, //要素28にN_G_GINをセット
KUHAKU, //要素29にKUHAKUをセット
N_G_KAKU, //要素30にN_G_KAKUをセット
N_G_HI //要素31にN_G_HIをセット
};

char *koma_s_h[] = {
KUHAKU, // 要素0にKUHAKUをセット
FU, // 要素1にFUをセット
KYO, // 要素2にKYOをセット
KEI, // 要素3にKEIをセット
GIN, // 要素4にGINをセット
KIN, // 要素5にKINをセット
KAKU, // 要素6にKAKUをセット
HI, // 要素7にHIをセット
GYOKU, // 要素8にGYOKUをセット
N_H_FU, // 要素9にN_H_FUをセット
N_H_KYO, //要素10にN_H_KYOをセット
N_H_KEI, //要素11にN_H_KEIをセット
N_H_GIN, //要素12にN_H_GINをセット
KUHAKU, //要素13にKUHAKUをセット
N_H_KAKU, //要素14にN_H_KAKUをセット
N_H_HI, //要素15にN_H_HIをセット
KUHAKU, //要素16にKUHAKUをセット
FU, //要素17にFUをセット
KYO, //要素18にKYOをセット
KEI, //要素19にKEIをセット
GIN, //要素20にGINをセット
KIN, //要素21にKINをセット
KAKU, //要素22にKAKUをセット
HI, //要素23にHIをセット
OU, //要素24にOUをセット
N_H_FU, //要素25にN_H_FUをセット
N_H_KYO, //要素26にN_H_KYOをセット
N_H_KEI, //要素27にN_H_KEIをセット
N_H_GIN, //要素28にN_H_GINをセット
N_H_KAKU, //要素30にN_H_KAKUをセット
N_H_HI //要素31にN_H_HIをセット
};

/* 盤面の初期設定 */
int banmen[9][9] = { { G_KYO_N, G_KEI_N, G_GIN_N, G_KIN_N, OU_N, G_KIN_N, G_GIN_N, G_KEI_N, G_KYO_N },
{ KUHAKU_N, G_KAKU_N, KUHAKU_N, KUHAKU_N, KUHAKU_N, KUHAKU_N, KUHAKU_N, G_HI_N, KUHAKU_N },
{ G_FU_N, G_FU_N, G_FU_N, G_FU_N, G_FU_N, G_FU_N, G_FU_N, G_FU_N, G_FU_N },
{ KUHAKU_N, KUHAKU_N, KUHAKU_N, KUHAKU_N, KUHAKU_N, KUHAKU_N, KUHAKU_N, KUHAKU_N, KUHAKU_N },
{ KUHAKU_N, KUHAKU_N, KUHAKU_N, KUHAKU_N, KUHAKU_N, KUHAKU_N, KUHAKU_N, KUHAKU_N, KUHAKU_N },
{ KUHAKU_N, KUHAKU_N, KUHAKU_N, KUHAKU_N, KUHAKU_N, KUHAKU_N, KUHAKU_N, KUHAKU_N, KUHAKU_N },
{ FU_N, FU_N, FU_N, FU_N, FU_N, FU_N, FU_N, FU_N, FU_N },
{ KUHAKU_N, HI_N, KUHAKU_N, KUHAKU_N, KUHAKU_N, KUHAKU_N, KUHAKU_N, KAKU_N, KUHAKU_N },
{ KYO_N, KEI_N, GIN_N, KIN_N, GYOKU_N, KIN_N, GIN_N, KEI_N, KYO_N } };

/* 持ち駒の構造体 */
struct Motigoma{
int kazu;
int fu;
int kyo;
int kei;
int gin;
int kin;
int kaku;
int hi;
};

struct Motigoma s_motigoma = { 0, 0, 0, 0, 0, 0, 0, 0 }; //先手の持ち駒の構造体
struct Motigoma g_motigoma = { 0, 0, 0, 0, 0, 0, 0, 0 }; //後手の持ち駒の構造体
int s_motigoma_n; //先手の持ち駒番号
int g_motigoma_n; //後手の持ち駒番号

int banmen_hyouji(); //盤面の表示関数
int sente_nyuuryoku(); //先手の指し手の入力関数
int gote_nyuuryoku(); //後手の指し手の入力関数
int sasite_hyouji(int); //指し手の表示関数
int sasite_nyuuryoku(); //指し手の入力関数
int motigoma_hyouji(); //持ち駒の表示関数
int motigoma_nyuuryoku(struct Motigoma *); //持ち駒の入力関数

int main()
{

tesuu_n = 0; //手数カウント初期化
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 (sente_nyuuryoku() == 1){ //先手の指し手の入力関数
printf("\n詰みました。先手の勝利です。");
break;
}

system("cls"); //画面クリア
sasite_hyouji(SENTE); //先手の指し手表示関数
motigoma_hyouji(); //持ち駒表示関数
banmen_hyouji(); //盤面表示関数

if (gote_nyuuryoku() == 1){ //後手の指し手の入力関数
printf(AOIRO"\n詰みました。後手の勝利です。"KIHONIRO);
break;
}

system("cls"); //画面クリア
sasite_hyouji(GOTE); //後手の指し手表示関数
motigoma_hyouji(); //持ち駒表示関数
banmen_hyouji(); //盤面表示関数
}

return 0;
}

/* 指し手の表示関数 */
int sasite_hyouji(int teban)
{
FILE *fp;
char sasite[30];

fopen_s(&fp, "sasite.txt", "a");
if (fp == NULL) {
perror("ファイル・オープンに失敗しました\n");
return -1;
}

if (teban == SENTE){
tesuu_n++; //手数カウントを増やす

switch (s_te_s_g)
{
case 1:
fprintf(fp, "%d.先手:%d一%s", tesuu_n, s_te_s_r, koma_s_h[sasite_koma_n]);
break;
case 2:
fprintf(fp, "%d.先手:%d二%s", tesuu_n, s_te_s_r, koma_s_h[sasite_koma_n]);
break;
case 3:
fprintf(fp, "%d.先手:%d三%s", tesuu_n, s_te_s_r, koma_s_h[sasite_koma_n]);
break;
case 4:
fprintf(fp, "%d.先手:%d四%s", tesuu_n, s_te_s_r, koma_s_h[sasite_koma_n]);
break;
case 5:
fprintf(fp, "%d.先手:%d五%s", tesuu_n, s_te_s_r, koma_s_h[sasite_koma_n]);
break;
case 6:
fprintf(fp, "%d.先手:%d六%s", tesuu_n, s_te_s_r, koma_s_h[sasite_koma_n]);
break;
case 7:
fprintf(fp, "%d.先手:%d七%s", tesuu_n, s_te_s_r, koma_s_h[sasite_koma_n]);
break;
case 8:
fprintf(fp, "%d.先手:%d八%s", tesuu_n, s_te_s_r, koma_s_h[sasite_koma_n]);
break;
case 9:
fprintf(fp, "%d.先手:%d九%s", tesuu_n, s_te_s_r, koma_s_h[sasite_koma_n]);
break;
default:
break;
}

if (s_te_n == '1') //先手が成るか
fprintf(fp, "成");
if (s_motigoma_n > 0)
fprintf(fp, "成");
else {
switch (s_te_m_g)
{
case 1:
fprintf(fp, "(%d一)", s_te_m_r);
break;
case 2:
fprintf(fp, "(%d二)", s_te_m_r);
break;
case 3:
fprintf(fp, "(%d三)", s_te_m_r);
break;
case 4:
fprintf(fp, "(%d四)", s_te_m_r);
break;
case 5:
fprintf(fp, "(%d五)", s_te_m_r);
break;
case 6:
fprintf(fp, "(%d六)", s_te_m_r);
break;
case 7:
fprintf(fp, "(%d七)", s_te_m_r);
break;
case 8:
fprintf(fp, "(%d八)", s_te_m_r);
break;
case 9:
fprintf(fp, "(%d九)", s_te_m_r);
break;
default:
break;
}
}
}

if (teban == GOTE){
tesuu_n++; //手数カウントを増やす

switch (g_te_s_g)
{
case 1:
fprintf(fp, "%d.後手:%d一%s", tesuu_n, g_te_s_r, koma_s_h[sasite_koma_n]);
break;
case 2:
fprintf(fp, "%d.後手:%d二%s", tesuu_n, g_te_s_r, koma_s_h[sasite_koma_n]);
break;
case 3:
fprintf(fp, "%d.後手:%d三%s", tesuu_n, g_te_s_r, koma_s_h[sasite_koma_n]);
break;
case 4:
fprintf(fp, "%d.後手:%d四%s", tesuu_n, g_te_s_r, koma_s_h[sasite_koma_n]);
break;
case 5:
fprintf(fp, "%d.後手:%d五%s", tesuu_n, g_te_s_r, koma_s_h[sasite_koma_n]);
break;
case 6:
fprintf(fp, "%d.後手:%d六%s", tesuu_n, g_te_s_r, koma_s_h[sasite_koma_n]);
break;
case 7:
fprintf(fp, "%d.後手:%d七%s", tesuu_n, g_te_s_r, koma_s_h[sasite_koma_n]);
break;
case 8:
fprintf(fp, "%d.後手:%d八%s", tesuu_n, g_te_s_r, koma_s_h[sasite_koma_n]);
break;
case 9:
fprintf(fp, "%d.後手:%d九%s", tesuu_n, g_te_s_r, koma_s_h[sasite_koma_n]);
break;
default:
break;
}

if (g_te_n == '1') //後手が成るか
fprintf(fp, "成");
if (g_motigoma_n > 0)
fprintf(fp, "打");
else {
switch (g_te_m_g)
{
case 1:
fprintf(fp, "(%d一)", g_te_m_r);
break;
case 2:
fprintf(fp, "(%d二)", g_te_m_r);
break;
case 3:
fprintf(fp, "(%d三)", g_te_m_r);
break;
case 4:
fprintf(fp, "(%d四)", g_te_m_r);
break;
case 5:
fprintf(fp, "(%d五)", g_te_m_r);
break;
case 6:
fprintf(fp, "(%d六)", g_te_m_r);
break;
case 7:
fprintf(fp, "(%d七)", g_te_m_r);
break;
case 8:
fprintf(fp, "(%d八)", g_te_m_r);
break;
case 9:
fprintf(fp, "(%d九)", g_te_m_r);
break;
default:
break;
}
}
}

fprintf(fp, "\n");

fclose(fp);

fopen_s(&fp, "sasite.txt", "r");
if (fp == NULL) {
perror("ファイル・オープンに失敗しました\n");
return -1;
}

while (fscanf_s(fp, "%s", sasite, 30) != EOF)
printf("%s\n", sasite);

fclose(fp);

return 0;
}

将時画面16022601