创建项目及其代码分类 三子棋(井字棋)横竖斜三子连成线则获胜
test.c - 游戏逻辑代码编写
game.h - 游戏函数声明,符号定义,头文件的包含
game.c - 游戏函数代码实现
主函数和菜单函数编写 在test.c写入主函数main
使用do while循环语句可以让程序一开始就执行一次
我们需要调用一个menu函数用于游戏的开始界面
然后通过输入1或者0 开始游戏或退出游戏
输入非1和0的输需重新输入
开始游戏后调用game函数
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 int  main () { 	int  input = 0 ; 	do  	{ 		menu(); 		printf ("请选择:>" ); 		scanf ("%d" ,&input); 		switch  (input) 		{ 		case  1 : 			printf ("开始三子棋游戏\n" ); 			printf ("游戏需要输入坐标(如:1 2 即第一行第二列)\n" ); 			game(); 			break ; 		case  0 : 			printf ("退出游戏\n" ); 			break ; 		default : 			printf ("选择错误,请重新选择\n" ); 			break ; 		} 	} while  (input); 	return  0 ; } 
在主函数上面定义一个menu函数,完成游戏开始界面
1 2 3 4 5 6 7 void  menu () { 	printf ("**********************************\n" ); 	printf ("**********    1.play    **********\n" ); 	printf ("**********    0.exit    **********\n" ); 	printf ("**********************************\n" ); } 
游戏逻辑函数编写 开始游戏后,主函数内调用game函数
我们在主函数上面定义一个game函数
并创建一个二维数组
1 2 3 4 5 6 void  game () { 	 	char  board[ROW][COL]; } 
然后在头文件game.h中,使用#define定义两个常量,行和列
1 2 3 #define  ROW 3 #define  COL 3 
在game函数中调用InitBoard函数,用于初始化棋盘
1 2 3 4 5 6 7 void  game () { 	 	char  board[ROW][COL]; 	 	InitBoard(board,ROW,COL); } 
初始化棋盘 在实现函数功能前,我们需要先在头文件game.h里声明函数
1 2 void  InitBoard (char  board[ROW][COL], int  row, int  col) ;
然后再game.c中进行实现初始化棋盘
就是把二维数组中的所有元素都变为空格
1 2 3 4 5 6 7 8 9 10 11 12 13 14 void  InitBoard (char  board[ROW][COL], int  row, int  col) { 	int  i = 0 ; 	int  j = 0 ; 	for  ( i = 0 ; i < row; i++) 	{ 		for  ( j = 0 ; j < col; j++) 		{ 			 			board[i][j] = ' ' ; 		} 	} } 
打印棋盘 然后我们需要制作一个棋盘,也就是打印一个棋盘
我们先在game函数中调用函数DisplayBoard,用来打印棋盘
1 2 3 4 5 6 7 8 9 void  game () { 	 	char  board[ROW][COL]; 	 	InitBoard(board,ROW,COL); 	 	DisplayBoard(board, ROW, COL); } 
同样的,在头文件中进行声明
1 2 void  DisplayBoard (char  board[ROW][COL], int  row, int  col) ;
然后在game.c进行实现
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 void  DisplayBoard (char  board[ROW][COL], int  row, int  col) { 	int  i = 0 ; 	int  j = 0 ; 	for  (i = 0 ; i < row; i++) 	{ 		for  (j = 0 ; j < col; j++) 		{ 			printf (" %c " , board[i][j]);  			if  (j  < col -1 )  			{ 				printf ("|" );  			} 			else  			{ 				printf ("\n" ); 			} 		} 		if  (i < row -1 ) 		{ 			for  ( j = 0 ; j < col; j++) 			{ 				printf ("---" ); 				if  (j < col - 1 ) 				{ 					printf ("|" ); 				} 				else  				{ 					printf ("\n" ); 				} 			} 		} 	} } 
头文件包含 我们可以将需要引入的c语言头文件放到我们自己创建的头文件game.h中
这样我们只需要引用game.h即可
1 2 3 #include  <stdio.h>  #include  <string.h>  
玩家下棋 在game函数内进行循环,调用PlayerMove函数
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 void  game () { 	 	char  board[ROW][COL]; 	 	InitBoard(board,ROW,COL); 	 	DisplayBoard(board, ROW, COL); 	while  (1 ) 	{ 		 		PlayerMove(board, ROW, COL); 		DisplayBoard(board, ROW, COL);     } } 
声明函数
1 2 void  PlayerMove (char  board[ROW][COL], int  row, int  col) ;
我们先需要判断我们输入的下标是否合法
然后判断我们输入的下标的位置是否已经有棋子,即是否为空格
是空格的话,下棋,不是的话,重新输入
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 void  PlayerMove (char  board[ROW][COL], int  row, int  col) { 	int  x = 0 ; 	int  y = 0 ; 	printf ("玩家回合\n" ); 	while  (1 ) 	{ 		printf ("请输入下棋的坐标:>" ); 		scanf ("%d %d" , &x, &y); 		 		if  (x >= 1  && x <= row && y >= 1  && y <= col) 		{ 			 			if  (board[x-1 ][y-1 ] == ' ' ) 			{ 				board[x - 1 ][y - 1 ] = '*' ; 				break ; 			} 			else  			{ 				printf ("该坐标已经有棋子咯,请重新输入\n" ); 			} 		} 		else  		{ 			printf ("坐标非法,请重新输入\n" ); 		} 	} } 
电脑下棋 玩家下完棋之后,电脑开始下棋
game函数中调用ComputerMove函数
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 void  game () { 	 	char  board[ROW][COL]; 	 	InitBoard(board,ROW,COL); 	 	DisplayBoard(board, ROW, COL); 	while  (1 ) 	{ 		 		PlayerMove(board, ROW, COL); 		DisplayBoard(board, ROW, COL);          		ComputerMove(board, ROW, COL); 		DisplayBoard(board, ROW, COL);     } } 
声明函数
1 2 void  ComputerMove (char  board[ROW][COL], int  row, int  col) ;
接着在game.c中实现
我们使用随机数的方式让电脑下棋
需要先在主函数中使用srand
然后在ComputerMove函数中使用随机数rand
然后判断当前位置是否为空格
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 int  main () { 	int  input = 0 ; 	srand((unsigned  int )time(NULL )); 	do  	{ 		menu(); 		printf ("请选择:>" ); 		scanf ("%d" ,&input); 		switch  (input) 		{ 		case  1 : 			printf ("开始三子棋游戏\n" ); 			printf ("游戏需要输入坐标(如:1 2 即第一行第二列)\n" ); 			game(); 			break ; 		case  0 : 			printf ("退出游戏\n" ); 			break ; 		default : 			printf ("选择错误,请重新选择\n" ); 			break ; 		} 	} while  (input); 	return  0 ; } 
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 void  ComputerMove (char  board[ROW][COL], int  row, int  col) { 	printf ("电脑回合:>\n" ); 	while  (1 ) 	{ 		int  x = rand() % row; 		int  y = rand() % col; 		if  (board[x][y] == ' ' ) 		{ 			board[x][y] = '#' ; 			break ; 		} 	} 	 } 
别忘记了引入头文件
1 2 3 4 5 #include  <stdio.h>  #include  <string.h>  #include  <time.h>  #include  <stdlib.h>  
判断输赢 一共有四种情况
1.玩家赢了 - return *
 
我们让电脑或玩家赢的时候返回自身的棋子的字符,比较方便
首先定义一个值ret用于存储返回来的字符
game函数中调用IsWin,把其的返回值赋值给ret
如果返回值不为 C ,说明游戏已结束,退出循环
进行判断胜负
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 void  game () { 	 	char  board[ROW][COL]; 	 	InitBoard(board,ROW,COL); 	 	DisplayBoard(board, ROW, COL); 	while  (1 ) 	{ 		 		PlayerMove(board, ROW, COL); 		DisplayBoard(board, ROW, COL); 		 		ret = IsWin(board, ROW, COL); 		if  (ret != 'C' ) 			break ; 		 		ComputerMove(board, ROW, COL); 		DisplayBoard(board, ROW, COL); 		 		ret = IsWin(board, ROW, COL); 		if  (ret != 'C' ) 			break ;     }     if  (ret == '*' ) 	{ 		printf ("你赢了!!!\n" ); 	} 	else  if (ret == '#' ) 	{ 		printf ("你输了!!!\n" ); 	} 	else  	{ 		printf ("平局\n" ); 	} } 
然后开始编写IsWin函数
先声明函数
1 2 char  IsWin (char  board[ROW][COL], int  row, int  col) ;
然后实现函数
我们通过循环判断行和列是否有相同的棋子
然后写一个函数IsFull来判断两个对角线是否有相同的棋子
注意:这种方法只能用于3*3的三子棋 
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 char  IsFull (char  board[ROW][COL], int  row, int  col) { 	int  i = 0 ; 	int  j = 0 ; 	for  ( i = 0 ; i < row; i++) 	{ 		for  ( j = 0 ; j < col; j++) 		{ 			if  (board[i][j] == ' ' ) 			{ 				return  'C' ; 			} 		} 	} 	return  'Q' ; } char  IsWin (char  board[ROW][COL], int  row, int  col) { 	int  i = 0 ; 	 	for  ( i = 0 ; i < row; i++) 	{ 		 		if  (board[i][0 ] == board[i][1 ] && board[i][1 ] == board[i][2 ] && board[i][0 ] != ' ' ) 		{ 			return  board[i][0 ]; 		} 	} 	 	for  (i = 0 ; i < col; i++) 	{ 		 		if  (board[0 ][i] == board[1 ][i] && board[1 ][i] == board[2 ][i] && board[0 ][i] != ' ' ) 		{ 			return  board[0 ][i]; 		} 	} 	 	if  (board[0 ][0 ] == board[1 ][1 ] && board[1 ][1 ] == board[2 ][2 ] && board[0 ][0 ] != ' ' ) 	{ 		return  board[0 ][0 ]; 	} 	if  (board[0 ][2 ] == board[1 ][1 ] && board[1 ][1 ] == board[2 ][0 ] && board[0 ][2 ] != ' ' ) 	{ 		return  board[0 ][2 ]; 	} 	 	int  ret = IsFull(board, ROW, COL); 		return  ret; } 
功能增加 其实代码还有很多地方可以优化,特别是最后进行判断的时候,只能用于3*3的三子棋,不过如果需要通用,要用到算法,过于困难了
这里就增加几个比较简单的功能
电脑下棋优化 我们可以让电脑下棋时把中间位置先占据
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 void  ComputerMove (char  board[ROW][COL], int  row, int  col) { 	printf ("电脑回合:>\n" ); 	while  (1 ) 	{ 		int  x = rand() % row; 		int  y = rand() % col; 		if  (board[x][y] == ' ' ) 		{ 			if  (board[row / 2 ][col / 2 ] == ' ' ) 			{ 				board[row / 2 ][col / 2 ] = '#' ; 				break ; 			} 			else  			{ 				board[x][y] = '#' ; 				break ; 			} 		} 	} 	 } 
先后手和重新开始游戏倒计时 在前面的代码里都是玩家先手,我们可以设置个随机数,随机让玩家或者电脑先手
然后在判断胜负后加上重新开始游戏的倒计时
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 void  game () { 	 	char  board[ROW][COL]; 	 	InitBoard(board,ROW,COL); 	 	DisplayBoard(board, ROW, COL); 	char  ret = 0 ; 	int  n = rand() % 2 ;  	if  (n) 	{ 		while  (1 ) 		{ 			 			PlayerMove(board, ROW, COL); 			DisplayBoard(board, ROW, COL); 			 			ret = IsWin(board, ROW, COL); 			if  (ret != 'C' ) 				break ; 			 			ComputerMove(board, ROW, COL); 			DisplayBoard(board, ROW, COL); 			 			ret = IsWin(board, ROW, COL); 			if  (ret != 'C' ) 				break ; 		} 	} 	else   	{ 		while  (1 ) 		{ 			 			ComputerMove(board, ROW, COL); 			DisplayBoard(board, ROW, COL); 			 			ret = IsWin(board, ROW, COL); 			if  (ret != 'C' ) 				break ; 			 			PlayerMove(board, ROW, COL); 			DisplayBoard(board, ROW, COL); 			 			ret = IsWin(board, ROW, COL); 			if  (ret != 'C' ) 				break ; 		} 	} 	 	if  (ret == '*' ) 	{ 		printf ("你赢了!!!\n" ); 	} 	else  if (ret == '#' ) 	{ 		printf ("你输了!!!\n" ); 	} 	else  	{ 		printf ("平局\n" ); 	} 	DisplayBoard(board, ROW, COL); 	Sleep(1000 ); 	for  (int  i = 3 ; i > 0 ; i--) 	{ 		printf ("倒计时后重新开始游戏:%d\n"  , i); 		Sleep(1000 ); 	} 	system("cls" ); } 
功能展示 代码展示 test.c 
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 #define  _CRT_SECURE_NO_WARNINGS 1 #include  "game.h"  void  menu () { 	printf ("**********************************\n" ); 	printf ("**********    1.play    **********\n" ); 	printf ("**********    0.exit    **********\n" ); 	printf ("**********************************\n" ); } void  game () { 	 	char  board[ROW][COL]; 	 	InitBoard(board,ROW,COL); 	 	DisplayBoard(board, ROW, COL); 	char  ret = 0 ; 	int  n = rand() % 2 ;  	if  (n) 	{ 		while  (1 ) 		{ 			 			PlayerMove(board, ROW, COL); 			DisplayBoard(board, ROW, COL); 			 			ret = IsWin(board, ROW, COL); 			if  (ret != 'C' ) 				break ; 			 			ComputerMove(board, ROW, COL); 			DisplayBoard(board, ROW, COL); 			 			ret = IsWin(board, ROW, COL); 			if  (ret != 'C' ) 				break ; 		} 	} 	else   	{ 		while  (1 ) 		{ 			 			ComputerMove(board, ROW, COL); 			DisplayBoard(board, ROW, COL); 			 			ret = IsWin(board, ROW, COL); 			if  (ret != 'C' ) 				break ; 			 			PlayerMove(board, ROW, COL); 			DisplayBoard(board, ROW, COL); 			 			ret = IsWin(board, ROW, COL); 			if  (ret != 'C' ) 				break ; 		} 	} 	 	if  (ret == '*' ) 	{ 		printf ("你赢了!!!\n" ); 	} 	else  if (ret == '#' ) 	{ 		printf ("你输了!!!\n" ); 	} 	else  	{ 		printf ("平局\n" ); 	} 	DisplayBoard(board, ROW, COL); 	Sleep(1000 ); 	for  (int  i = 3 ; i > 0 ; i--) 	{ 		printf ("倒计时后重新开始游戏:%d\n"  , i); 		Sleep(1000 ); 	} 	system("cls" ); } int  main () { 	int  input = 0 ; 	srand((unsigned  int )time(NULL )); 	do  	{ 		menu(); 		printf ("请选择:>" ); 		scanf ("%d" ,&input); 		switch  (input) 		{ 		case  1 : 			printf ("开始三子棋游戏\n" ); 			printf ("游戏需要输入坐标(如:1 2 即第一行第二列)\n" ); 			game(); 			break ; 		case  0 : 			printf ("退出游戏\n" ); 			break ; 		default : 			printf ("选择错误,请重新选择\n" ); 			break ; 		} 	} while  (input); 	return  0 ; } 
game.h 
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 #pragma  once #define  ROW 3 #define  COL 3 #include  <stdio.h>  #include  <string.h>  #include  <time.h>  #include  <stdlib.h>  #include  <windows.h>  void  InitBoard (char  board[ROW][COL], int  row, int  col) ;void  DisplayBoard (char  board[ROW][COL], int  row, int  col) ;void  PlayerMove (char  board[ROW][COL], int  row, int  col) ;void  ComputerMove (char  board[ROW][COL], int  row, int  col) ;char  IsWin (char  board[ROW][COL], int  row, int  col) ;
game.c 
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 #define  _CRT_SECURE_NO_WARNINGS 1 #include  "game.h"  void  InitBoard (char  board[ROW][COL], int  row, int  col) { 	int  i = 0 ; 	int  j = 0 ; 	for  ( i = 0 ; i < row; i++) 	{ 		for  ( j = 0 ; j < col; j++) 		{ 			 			board[i][j] = ' ' ; 		} 	} } void  DisplayBoard (char  board[ROW][COL], int  row, int  col) { 	int  i = 0 ; 	int  j = 0 ; 	for  (i = 0 ; i < row; i++) 	{ 		for  (j = 0 ; j < col; j++) 		{ 			printf (" %c " , board[i][j]);  			if  (j  < col -1 )  			{ 				printf ("|" );  			} 			else  			{ 				printf ("\n" ); 			} 		} 		if  (i < row -1 ) 		{ 			for  ( j = 0 ; j < col; j++) 			{ 				printf ("---" ); 				if  (j < col - 1 ) 				{ 					printf ("|" ); 				} 				else  				{ 					printf ("\n" ); 				} 			} 		} 	} } void  PlayerMove (char  board[ROW][COL], int  row, int  col) { 	int  x = 0 ; 	int  y = 0 ; 	printf ("玩家回合\n" ); 	while  (1 ) 	{ 		printf ("请输入下棋的坐标:>" );         while  (getchar() != '\n' ) 		{ 		} 		scanf ("%d %d" , &x, &y); 		 		if  (x >= 1  && x <= row && y >= 1  && y <= col) 		{ 			 			if  (board[x-1 ][y-1 ] == ' ' ) 			{ 				board[x - 1 ][y - 1 ] = '*' ; 				break ; 			} 			else  			{ 				printf ("该坐标已经有棋子咯,请重新输入\n" ); 			} 		} 		else  		{ 			printf ("坐标非法,请重新输入\n" ); 		} 	} } void  ComputerMove (char  board[ROW][COL], int  row, int  col) { 	printf ("电脑回合:>\n" ); 	while  (1 ) 	{ 		int  x = rand() % row; 		int  y = rand() % col; 		if  (board[x][y] == ' ' ) 		{ 			if  (board[row / 2 ][col / 2 ] == ' ' ) 			{ 				board[row / 2 ][col / 2 ] = '#' ; 				break ; 			} 			else  			{ 				board[x][y] = '#' ; 				break ; 			} 		} 	} 	 } char  IsFull (char  board[ROW][COL], int  row, int  col) { 	int  i = 0 ; 	int  j = 0 ; 	for  ( i = 0 ; i < row; i++) 	{ 		for  ( j = 0 ; j < col; j++) 		{ 			if  (board[i][j] == ' ' ) 			{ 				return  'C' ; 			} 		} 	} 	return  'Q' ; } char  IsWin (char  board[ROW][COL], int  row, int  col) { 	int  i = 0 ; 	 	for  ( i = 0 ; i < row; i++) 	{ 		 		if  (board[i][0 ] == board[i][1 ] && board[i][1 ] == board[i][2 ] && board[i][0 ] != ' ' ) 		{ 			return  board[i][0 ]; 		} 	} 	 	for  (i = 0 ; i < col; i++) 	{ 		 		if  (board[0 ][i] == board[1 ][i] && board[1 ][i] == board[2 ][i] && board[0 ][i] != ' ' ) 		{ 			return  board[0 ][i]; 		} 	} 	 	if  (board[0 ][0 ] == board[1 ][1 ] && board[1 ][1 ] == board[2 ][2 ] && board[0 ][0 ] != ' ' ) 	{ 		return  board[0 ][0 ]; 	} 	if  (board[0 ][2 ] == board[1 ][1 ] && board[1 ][1 ] == board[2 ][0 ] && board[0 ][2 ] != ' ' ) 	{ 		return  board[0 ][2 ]; 	} 	 	int  ret = IsFull(board, ROW, COL); 		return  ret; } 
三子棋程序下载链接 点击这里进行下载