www.pudn.com > CÓïÑÔµÄС±àÒëÆ÷.zip > TTT3D.C


/* 
 * 3D Tic Tac Toe. 
 * 
 * Original Author Unknown 
 */ 
#include \MC\stdio.h 
 
#define	EMPTY	0 
#define	PLAYER	1 
#define	BEAST	5 
 
/* 
 * This is a table of all winning combinations. 
 * From Kilobaud, April 78. 
 * You can look there to see how it is ordered. 
 */ 
char w[] = { 
	0,	1,	2,	3, 
	4,	5,	6,	7, 
	8,	9,	10,	11, 
	12,	13,	14,	15, 
	0,	4,	8,	12, 
	1,	5,	9,	13, 
	2,	6,	10,	14, 
	3,	7,	11,	15, 
	0,	5,	10,	15, 
	3,	6,	9,	12, 
	16,	17,	18,	19, 
	20,	21,	22,	23, 
	24,	25,	26,	27, 
	28,	29,	30,	31, 
	16,	20,	24,	28, 
	17,	21,	25,	29, 
	18,	22,	26,	30, 
	19,	23,	27,	31, 
	16,	21,	26,	31, 
	19,	22,	25,	28, 
	32,	33,	34,	35, 
	36,	37,	38,	39, 
	40,	41,	42,	43, 
	44,	45,	46,	47, 
	32,	36,	40,	44, 
	33,	37,	41,	45, 
	34,	38,	42,	46, 
	35,	39,	43,	47, 
	32,	37,	42,	47, 
	35,	38,	41,	44, 
	48,	49,	50,	51, 
	52,	53,	54,	55, 
	56,	57,	58,	59, 
	60,	61,	62,	63, 
	48,	52,	56,	60, 
	49,	53,	57,	61, 
	50,	54,	58,	62, 
	51,	55,	59,	63, 
	48,	53,	58,	63, 
	51,	54,	57,	60, 
	0,	16,	32,	48, 
	1,	17,	33,	49, 
	2,	18,	34,	50, 
	3,	19,	35,	51, 
	4,	20,	36,	52, 
	5,	21,	37,	53, 
	6,	22,	38,	54, 
	7,	23,	39,	55, 
	8,	24,	40,	56, 
	9,	25,	41,	57, 
	10,	26,	42,	58, 
	11,	27,	43,	59, 
	13,	29,	45,	61, 
	12,	28,	44,	60, 
	14,	30,	46,	62, 
	15,	31,	47,	63, 
	0,	21,	42,	63, 
	4,	21,	38,	55, 
	8,	25,	42,	59, 
	12,	25,	38,	51, 
	1,	21,	41,	61, 
	13,	25,	37,	49, 
	2,	22,	42,	62, 
	14,	26,	38,	50, 
	3,	22,	41,	60, 
	7,	22,	37,	52, 
	11,	26,	41,	56, 
	15,	26,	37,	48, 
	0,	20,	40,	60, 
	0,	17,	34,	51, 
	3,	18,	33,	48, 
	3,	23,	43,	63, 
	12,	24,	36,	48, 
	12,	29,	46,	63, 
	15,	30,	45,	60, 
	15,	27,	39,	51 
}; 
 
/* 
 * This is the board. 
 * Starts off all empty. 
 */ 
char	b[64] = 0; 
char	sep[] = "  -----------  -----------  -----------  -----------\n"; 
 
/* 
 * The mainline is just a driver. 
 */ 
main() 
{ 
	char buf[20]; 
 
	printf("Do you want the rules? "); 
	fgets(buf, 20, stdin); 
	if(buf[0]=='Y' || buf[0]=='y') 
		rules(); 
	printf("Do you want to go first? "); 
	fgets(buf,20,stdin); 
	if(buf[0]=='Y' || buf[0]=='y') 
		user(); 
	for(;;) { 
		beast(); 
		user(); 
	} 
} 
 
/* 
 * Print the rules of the game. 
 */ 
rules() 
{ 
	printf("Three dimensional tic-tac-toe is played on a 4x4x4\n"); 
	printf("board. To win you must get 4 in a row.  Your moves\n"); 
	printf("are specified as a 3 digit number; the first digit\n"); 
	printf("is the level, the second the row and the third the\n"); 
	printf("column. Levels and columns  go  from left to right\n"); 
	printf("from 1 to 3. Rows go from top to bottom with  0 on\n"); 
	printf("the top.\n"); 
} 
 
/* 
 * Accept a user move. Exit if he wins. 
 */ 
user() 
{ 
	register int i, j, t; 
	char buf[20]; 
 
	board(); 
	for(;;) { 
		printf("Your move (L/R/C)? "); 
		if(!fgets(buf,20,stdin)) { 
			printf("Chicken.\n"); 
			exit(0); 
		} 
		i = 16*(buf[0]-'1') + (buf[1]-'1') + 4*(buf[2]-'1'); 
		if(i>=0 && i<=63 && b[i]==EMPTY) 
			break; 
		printf("Eh?\n"); 
	} 
	b[i] = PLAYER; 
	for(i=0; i<4*76; i+=4) { 
		t = 0; 
		for(j=0; j<4; ++j) 
			t += b[w[i+j]]; 
		if(t == 4*PLAYER) { 
			printf("You win.\n"); 
			exit(0); 
		} 
	} 
} 
 
/* 
 * Display the board. (Not as easy as it sounds) 
 */ 
board() 
{ 
	register int i, j; 
 
	for(i=1; i < 5; ++i) 
		printf("       %d     ", i); 
	printf("\n"); 
	for(i=0; i<4; ++i) { 
		printf(sep); 
		printf("%d ", i+1); 
		for(j=0; j<64; j+=4) { 
			psq(i+j); 
			if(j==12 || j==28 || j==44) 
				printf("  "); 
			else if(j >= 60) 
				putc('\n', stdout); 
			else 
				putc('!', stdout); 
		} 
	} 
	printf(sep); 
	for(i=0; i < 4; ++i) { 
		for(j=1; j < 5; ++j) 
			printf("  %d", j); 
		printf(" "); } 
	printf("\n"); 
} 
 
/* 
 * Format and put out square `s' of the board. 
 */ 
psq(s) 
	int s; 
{ 
	register int v; 
 
	v = b[s]; 
	if(v == PLAYER) 
		printf("PP"); 
	else if(v == BEAST) 
		printf("CC"); 
	else 
		printf("  "); 
} 
 
/* 
 * Move for the machine. Just exit on machine wins and draws. 
 */ 
beast() 
{ 
	register int i, j, t; 
	int s, bs, bt, v[76]; 
 
	for(i=0; i<4*76; i+=4) { 
		t = 0; 
		for(j=0; j<4; ++j) 
			t += b[w[i+j]]; 
		v[i>>2] = t; 
		if(t == 3*BEAST) 
			break; 
	} 
	if(i < 4*76) { 
		for(j=0; j<4; ++j) 
			if(b[w[i+j]] == EMPTY) { 
				b[w[i+j]] = BEAST; 
				break; 
			} 
		board(); 
		printf("I win.\n"); 
		exit(0); 
	} 
	bt = 0; 
	for(s=0; s<64; ++s) { 
		if(b[s] != EMPTY) 
			continue; 
		t = 0; 
		for(i=0; i<4*76; i+=4) { 
			for(j=0; j<4; ++j) 
				if(w[i+j] == s) 
					break; 
			if(j != 4) { 
				if(v[i>>2] == 3*PLAYER) { 
					b[s] = BEAST; 
					return; 
				} 
				t += weight(v[i>>2]); 
			} 
		} 
		if(t > bt) { 
			bt = t; 
			bs = s; 
		} 
	} 
	if(bt != 0) 
		b[bs] = BEAST; 
	else { 
		for(s=0; s<64; ++s) 
			if(b[s] == EMPTY) 
				break; 
		if(s == 64) { 
			printf("Draw.\n"); 
			exit(0); 
		} 
		b[s] = BEAST; 
	} 
} 
 
/* 
 * Given a total along a winning combination, return the weight value. 
 */ 
weight(at) 
	int at; 
{ 
	register int t; 
 
	t = at; 
	if(t == PLAYER) 
		return(1); 
	if(t == 2*PLAYER) 
		return(4); 
	if(t == BEAST) 
		return(1); 
	if(t == 2*BEAST) 
		return(2); 
	return(0); 
}