練習問題4(盤のゲーム)

3目並べ

/* tick-tack-toe(二人で遊ぶ3目並べ) */
#include <stdio.h>
/*
#define	DEBUG
*/
#define	NONE	'.'
#define	MARU	'O'
#define	BATU	'X'
#define	KOUSAN	-1
#define	CONT	0
#define	ERR	1

int	ban[3][3];	/* 盤 */
/*
    A B C
  0 . . .
  1 . . .
  2 . . .
*/

main()
{
	void	disp();	/* 盤を表示する */
	int	move( int mb );	/* mbの番の処理 */
	int	counter( int mb );	/* 相手の番にする */

	int	x, y;	/* 座標(x,y) */
	int	k;	/* 回数 */
	int	mb;	/* 番 */

	/* 初期化 */
	for( y = 0; y < 3; y++ )
		for( x = 0; x < 3; x++ )
			ban[y][x] = NONE;
	printf("\n");
	/* 操作説明 */
	printf("自分の順番の時に、A0、a0、0A、0a等と場所を指定した後、Enterキーを押す。\n");
	printf("降参するときは--の後、Enterキーを押す。\n");
	disp();
	mb = MARU;
	for( k = 0; k < 9; k++)
	{
		if( move( mb ) == KOUSAN )
		{
			printf("%c の勝ち!\n", counter(mb) );
			exit(0);
		}
		disp();
		mb = counter(mb);
	}
	printf("引き分けです。\n");
}

/* 盤を表示する */
void	disp()
{
	int	x, y;

	printf("\n    ");
	for( x = 0; x < 3; x++ )
		printf("%c ", 'A'+x );
	printf("\n");
	for( y = 0; y < 3; y++ )
	{
		printf("%3d ", y );
		for( x = 0; x < 3; x++ )
			printf("%c ", ban[y][x] );
		printf("\n");
	}
	printf("\n");
}

/* mbの番の処理 */
int move( int mb )
{
	int	makexy( char s[], int *x, int *y );

	char	buf[10];
	int	x, y;
	int	t;

	for(;;)
	{
		printf("%c の番です。何処に打ちますか?:", mb);
		scanf("%s", buf);
		t = makexy( buf, &x, &y );
#ifdef	DEBUG
		printf("makexy=%d, x = %d, y = %d\n", t, x, y );
#endif
		switch( t )
		{
		case CONT:
			if( ban[y][x] == NONE )
			{
				ban[y][x] = mb;
				return( CONT );
			}
			else
			{
				printf("そこは既に打ってあります。\n");
				continue;
			}
		case KOUSAN:
			return( KOUSAN );
		default:/* ERR */
			continue;
		}
	}
}

/*
入力文字(ABCabc012)から座標(x, y)に変換
*/
int makexy( char s[], int *x, int *y )
{
	int	f;

	f = CONT;
	switch( s[0] )
	{
	case '-':
		return( KOUSAN );
	case 'A':
	case 'B':
	case 'C':
		*x = s[0] - 'A';
		break;
	case 'a':
	case 'b':
	case 'c':
		*x = s[0] - 'a';
		break;
	case '0':
	case '1':
	case '2':
		*y = s[0] - '0';
		break;
	default:
		f = ERR;
	}
	switch( s[1] )
	{
	case '-':
		return( KOUSAN );
	case 'A':
	case 'B':
	case 'C':
		*x = s[1] - 'A';
		break;
	case 'a':
	case 'b':
	case 'c':
		*x = s[1] - 'a';
		break;
	case '0':
	case '1':
	case '2':
		*y = s[1] - '0';
		break;
	default:
		f = ERR;
	}
	return( f );
}

int counter( int mb )
{
	switch( mb )
	{
	case BATU:
		return( MARU );
	case MARU:
		return( BATU );
	}
}

/* end of ttt0.c */
  1. 座標を 0 0 と入れてみよ!この例外処理を行え!
  2. 3目並んだことを調べ、勝敗を判定するように改良せよ!
  3. 盤の大きさを SIZE で与えられるようにせよ!
  4. 盤の画面表示を、.、O、X ではなく、+、○、● に変えてみよ!
  5. 五目並べに(連珠)拡張してみよ(SIZE=15)
  6. オセロに拡張してみよ(SIZE=8)

  7. 3目並べを人対コンピュータにしてみよ