アプリ版:「スタンプのみでお礼する」機能のリリースについて

#include<stdio.h>

int main (void)
{
int bord[8][8];
int x,y;
int i,j,l,a;
int player;

//ボードの初期化//
for(i=0;i<8;i++)
{
for(j=0;j<8;j++)
{
bord[i][j]=0;
}
}
bord[3][3]=1;
bord[4][4]=1;
bord[3][4]=2;
bord[4][3]=2;

//bordの表示//
player=0;


for(i=0;i<8;i++)
{
for(j=0;j<8;j++)
{
if(bord[i][j] == 0)
{
printf(" □ ");
}
else if(bord[i][j] == 1)
{
printf(" ● ");
}
else
{
printf(" ○ ");
}
}
printf("\n");
}
//黒か白か判定//
if(player%2==0)
{
bord[i][j]=1;
printf("黒の番です。\n");
printf("y=");
scanf("%d",&y);
printf("x=");
scanf("%d",&x);
}
if(player%2==1)
{
bord[i][j]=0;
printf("白の番です。\n");
printf("y=");
scanf("%d",&y);
printf("x=");
scanf("%d",&x);
}
//ひっくりかえす//
//石を置く権利を相手に移す
if(x==100 && y==100)
{
printf("\n");
printf("石を置く権利を相手に渡します。\n");
player++;
}
//エラー処理(入力された数字が許容範囲外)
if(x<0 || x>=8 || y<0 || y>=8 )
{
printf("許容範囲外です。\n");
printf("もう一度入力してください。\n");
}
//エラー処理(同じところには置けない)
if(bord[y][x]!=0)
{
printf("\n");
printf("置かれてるよ!\n");
}
//ひっくり返す
if(x>=0 && x<8 && y>=0 && y<8 && bord[y][x]==0)
{
if(bord[y][x] == 1)
{
bord[y][x]=2;
}
else
{
if(bord[y][x]==0)
{
bord[y][x]=1;
}
}
printf("\n");
printf("石が置かれました。\n");
player++;
}
return 0;
}


このプログラムは、リバーシをするものです。

・置いてある判定はできたものの、実際のマスには置けていません。

また、以下のことを追加したいです。


・配置

1□⇒







 a b c d e f g h

のようにする。

・出力は、黒の番>>a3
  白の番>>e5 のように

実際の処理がy、x入力になってしまっている。。

・ルール上ひっくり返せるところのみにおけるように。
・一方が置けなかったら、PASSするように
・どちらも置けなかったら、終了
・勝敗判定


ご指摘お願いします。

質問者からの補足コメント

  • 出力はx.yで大丈夫です。

      補足日時:2016/01/16 16:48
  • W.Hは奇数のみ。
    ■は偶然のみ。
    ルールに従ってやりたいです。

      補足日時:2016/01/19 18:54

A 回答 (6件)

課題の進捗どうですか?


//石を置く権利を相手に移す
if(x==100 && y==100)
{
  printf("\n");
  printf("石を置く権利を相手に渡します。\n");
  player++;
}

player++;はあまり良くないかと
    • good
    • 0

> 白の番>>e5 のように



入力は、scanf()ではなく、fgets()を使用してchar型配列に読み込ませます。
'a'~'h'が代入されている変数から、'a'をマイナスすると0~7の数値に変換できます。
  fgets(buffer, SIZE, stdin);
  x = buffer[0] - 'a';
'1'~'8'も同様です。


> ・ルール上ひっくり返せるところのみにおけるように。

人間が判断するのと同じことをプログラムに判断させます。
指定座標の周囲8か所に相手方の石が置いてあるか?
 1 無い場合は、置ける場所ではない。
 2 有る場合、その方向の石の置いてある状態を見ていく。
   a 相手方の石が続き、その後に自分の石があればひっくり返せる。
   b それ以外、置ける場所でない。



あと、ご提示のプログラムでは白黒の入力でほぼ同じ内容が記述されていますが、この様な共通化できる部分は関数にしましょう。ボードを初期化する処理、ボードを表示する処理、石が置けるか判断する処理なども関数化すればmain()の中がすっきりすると思います。
    • good
    • 0

一度で投稿出来ないので二分割



#include<stdio.h>
#include<string.h>

const int MM = 4;
const char KURO[3] = {"○"};
const char SIRO[3] = {"●"};
const char NASI[3] = {"・"};
const int XY_WAY[][2] = {
{ 1, 1},
{ 0, 1},
{ -1, 1},
{ -1, 0},
{ -1, -1},
{ 0, -1},
{ 1, -1},
{ 1, 0}
};
const int XY_NUM = sizeof(XY_WAY) / (sizeof(int) * 2);

// ボードの初期化
void bord_init(char bord[MM][MM][3], char player[3], char msg[256]) {
int y, x;

strcpy(player, SIRO);
msg[0] = '\0';

for(y = 0; y < MM; y++) {
for(x = 0; x < MM; x++) strcpy(bord[y][x], NASI);
}
strcpy(bord[MM/2-1][MM/2-1], KURO);
strcpy(bord[MM/2][MM/2], KURO);
strcpy(bord[MM/2-1][MM/2], SIRO);
strcpy(bord[MM/2][MM/2-1], SIRO);
}

// ボードの表示
void bord_prt(char bord[MM][MM][3], char msg[256]) {
int y, x;

system("cls");
if(msg[0] != '\0') printf("%s\n", msg);
msg[0] = '\0';

for(y = 0; y < MM; y++) {
printf(" %d | ", y + 1);
for(x = 0; x < MM; x++) printf(" %s", bord[y][x]);
printf("\n");
}
printf("---+-");
for(y = 0; y < MM; y++) printf("---");
printf("\n | ");
for(y = 0; y < MM; y++) printf(" %c ", 'a' + y);
}

// キーボード入力
int input_chr(char *msg, char *arr) {
int x, inp = 0;
while( 1 ) {
printf(msg, "ESC=中断");
inp = getch();
if(inp == 0x1b) return( inp );
for(x = 0; arr[x] != 0; x++) if(inp == arr[x]) return( inp );
printf("\r");
}
}

// X,Yの入力
int input_xy(char player[3], int *y, int *x) {
char yarr[MM + 1];
char xarr[MM + 1];
int i;

for(i = 0; i < MM; i++) yarr[i] = 0x31 + i;
yarr[MM] = 0;
for(i = 0; i < MM; i++) xarr[i] = 0x61 + i;
yarr[MM] = 0;

printf("\n%sの番です。\n", player);

*y = input_chr("y[1-8](%s) = ", yarr);
if(*y == 0x1b) return( 0 );
*y -= 0x31;
printf("%d\n", *y + 1);

*x = input_chr("x[a-h](%s) = ", xarr);
if(*y == 0x1b) return( 0 );
printf("%c\n", *x);
*x -= 0x61;

return( 1 );
}

// 同じ石を探す。
int is_SameThing(char bord[MM][MM][3], char player[3], int y, int x , int y_way, int x_way) {
int xx, yy;

// 直ぐとなりが同じ石、無しなら無効
xx = x + x_way; yy = y + y_way;
if(!strcmp(bord[yy][xx], player)) return( 0 );
if(!strcmp(bord[yy][xx], NASI)) return( 0 );

xx += x_way; yy += y_way;
while(xx >= 0 && xx < MM && yy >= 0 && yy < MM) {
// 未配置のコマがあればダメ
if(!strcmp(bord[yy][xx], NASI)) return( 0 );
// 同じ石が見つかればOK
if(!strcmp(bord[yy][xx], player)) return( 1 );
xx += x_way; yy += y_way;
}

return( 0 );
}

// 特定の座標に石が置けるかチェックする
int sameThing_check(char bord[MM][MM][3], char player[3], int y, int x) {
int i;
for(i = 0; i < XY_NUM; i++) {
if(is_SameThing(bord, player, y, x, XY_WAY[i][0], XY_WAY[i][1]) > 0) return( 1 );
}

return( 0 );
}

// 一方向の石を反転
void way_reversi(char bord[MM][MM][3], char player[3], int y, int x, int y_way, int x_way) {
int xx, yy;

xx = x + x_way; yy = y + y_way;
while(xx >= 0 && xx < MM && yy >= 0 && yy < MM) {
if(!strcmp(bord[yy][xx], player)) return;
strcpy(bord[yy][xx], player);
xx += x_way; yy += y_way;
}
}
    • good
    • 0
この回答へのお礼

アスキーコード、エスケープシーケンスを今まで使ったことなくて、どの様な働きをします?あと、コメントあると幸いです。すみません。

お礼日時:2016/01/17 21:55

後半



// ひっくり返す
void bord_reversi(char bord[MM][MM][3], char player[3], int y, int x) {
int i;
// 石を置く
strcpy(bord[y][x], player);

// 配置する位置から全方向に同じ石があるか確認し、存在すれば石を反転する。
for(i = 0; i < XY_NUM; i++) {
if(is_SameThing(bord, player, y, x, XY_WAY[i][0], XY_WAY[i][1]) > 0)
way_reversi(bord, player, y, x, XY_WAY[i][0], XY_WAY[i][1]);
}
}

// 置けるか?
int place_check(char bord[MM][MM][3], char player[3], int y, int x) {
if(strcmp(bord[y][x], NASI) != 0) {
printf("\n置かれてるよ!\n");
return( 0 );
}
if(sameThing_check(bord, player, y, x) < 1) {
printf("\n置けません!\n");
return( 0 );
}

return( 1 );
}

// プレイヤーがプレイ可能か?
int player_play(char bord[MM][MM][3], char player[3]) {
int yy, xx;
for(yy = 0; yy < MM; yy++) {
for(xx = 0; xx < MM; xx++) {
// 石が未配置のコマ
if(!strcmp(bord[yy][xx], NASI)) {
// 全方向で置くことが出来るかチェック
if(sameThing_check(bord, player, yy, xx) > 0) return( 1 );
}
}
}
return( 0 );
}

// ゲーム終了
int game_end(char bord[MM][MM][3], char player[3], char msg[256], int cntSiro, int cntKuro) {
char arr[] = {0x63, 0x65, 0x1b, 0};
int ret;

// bordの表示
bord_prt(bord, msg);

printf("\n\n\t");
if(cntSiro == cntKuro) {
printf("引き分け");
} else {
printf("%sの勝ち", (cntSiro > cntKuro) ? SIRO : KURO);
}
printf("(%s=%d,%s=%d)\n\n", SIRO, cntSiro, KURO, cntKuro);

ret = input_chr("e=終了、c=もう一度、%s) = ", arr);
if(ret == 0x1b) return( 0 );
printf("%c\n", ret);
if(ret == 0x65) return( 0 );

bord_init(bord, player, msg);
return( 1 );
}

// 次の回の処理
int check_next(char bord[MM][MM][3], char player[3], char msg[256]) {
char player2[3];
int yy, xx, cntSiro, cntKuro;

// 白と黒の石のカウント
cntSiro = cntKuro = 0;
for(yy = 0; yy < MM; yy++) {
for(xx = 0; xx < MM; xx++) {
if(!strcmp(bord[yy][xx], SIRO)) cntSiro++;
if(!strcmp(bord[yy][xx], KURO)) cntKuro++;
}
}

// 次のプレイヤー
strcpy(player2, (strcmp(player, SIRO) == 0) ? KURO : SIRO);

if(cntSiro == 0 || cntKuro == 0) {
// どちらかが0個なら終了
return(game_end(bord, player, msg, cntSiro, cntKuro));
} else if(!player_play(bord, player2)) {
// 次のプレイヤーが置けない
if(!player_play(bord, player)) {
// 両方置けない場合、終了
return(game_end(bord, player, msg, cntSiro, cntKuro));
}
strcpy(msg, "\n石を置く権利を相手に渡します。\n");
} else {
// プレイヤー交代
strcpy(player, player2);
}

return( 1 );
}

// メイン処理
int main (void) {
char bord[MM][MM][3];
char player[3];
char msg[256];
int x, y;
int roop_flg = 1;

//ボードの初期化
bord_init(bord, player, msg);

while(roop_flg) {
// bordの表示
bord_prt(bord, msg);

// X,Yの入力
do {
if(input_xy(player, &y, &x) < 1) return( 0 );
} while(place_check(bord, player, y, x) < 1);

//ひっくり返す
bord_reversi(bord, player, y, x);

// 次プレイヤーのチェック
roop_flg = check_next(bord, player, msg);
}

return 0;
}
    • good
    • 0
この回答へのお礼

あと、getchが定義されてない。とでます。

お礼日時:2016/01/17 22:27

間違ってアップした。



先頭の、
const int MM = 4;

const int MM = 8;

ASCIIコード
http://e-words.jp/p/r-ascii.html

エスケープシーケンス一覧表
http://wisdom.sakura.ne.jp/programming/c/Cdata1. …

肝心なのは、配置する位置(5,5)とすると
(5,5)-(6,6)-(7,7)・・・
(5,5)-(5,6)-(5,7)・・・
(5,5)-(4,6)-(3,7)・・・
(5,5)-(4,5)-(3,5)・・・
(5,5)-(4,4)-(3,3)・・・
(5,5)-(5,4)-(5,3)・・・
(5,5)-(6,4)-(7,3)・・・
(5,5)-(6,5)-(7,5)・・・
この8方向に検索し、白なら黒が並んだ後に白があるかを検索する事。(挟めるか?)
これは、石を配置出来るか?のチェックと石の反転チェックにも使う。

どちらかの石の個数が0になるか、どちらも石を置けなくなったらゲーム終了。
    • good
    • 0
この回答へのお礼

よろしくお願い致します。

お礼日時:2016/01/19 22:11

>あと、getchが定義されてない。

とでます。
#include <conio.h>
    • good
    • 0
この回答へのお礼

ありがとうございます。意味を理解しようと思います。また、新しいのに迷路の問題がありますが、指摘して頂ければ幸いです。乱数でお願い致します、

お礼日時:2016/01/18 20:21

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!