井字棋的代码实现(c语言)(会堵棋)

功能实现

1.创建菜单,选择开始还是退出游戏

2.创建棋盘并初始化

3.打印棋盘

4.玩家下棋

5.电脑下棋

6.判断输赢

首先建立test.c、game.c、game.h,在test.c中写游戏的逻辑,在game.h中声明函数,在game.c中实现功能。

 1.1整体构造

使用do while循环,至少进行一次循环

int main()
{
	srand((unsigned int)time(NULL));//设置随机数生成起点
	int a = 0;
	do
	{menu();//打印菜单

	} while (a);
	return 0;
}

1.2打印菜单

void menu()
{
	printf("############################\n");
	printf("######1.play    0.exit #####\n");
	printf("############################\n");
}

1.3菜单功能的实现

输入1,进行游戏,输入0,退出游戏,游戏结束后,会再次弹出菜单进行选择。

printf("请选择:");
		scanf("%d", &a);
		switch (a)
		{
		case 1:
			game();
				break;
		case 0:
			printf("退出游戏\n");
				break;
		default:
			printf("选择错误\n");
			break;

2.1创建棋盘

井字棋最多有九个棋子,且呈3*3分布,所以建立二维数组board[3][3]。

void game()//要实现的功能:1.打印棋盘2.玩家下棋3.电脑下棋4.判断输赢
{
	int is = 0;
	char board[ROW][COL] = { 0 };//存放棋子的数组,棋子是#*,所以用char

此时为了方便之后将其改为五子棋等等,在game.h中定义全局变量ROW,COL表示行和列,可以随时改变行和列数

#define ROW 3//定义行和列,方便之后将三字棋改为五子棋或十字棋
#define COL 3

2.2初始化棋盘

令数组中每个元素都为空格

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] = ' ';//将数组的每一个元素都设置为空格
		}
	}
}

3.打印棋盘

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("|");
		}
		printf("\n");
		//打印分割信息
		if (i < row - 1)
		{
			for (j = 0; j < col; j++)
			{
				printf("---");
				if (j < col - 1)
				{
					printf("|");
				}
			}
		}
		printf("\n");
	}
}

4.1玩家下棋

playermove(board, ROW, COL);//玩家下棋
		is=iswin(board, ROW, COL);
		if (is != 1)
		{
			break;
		}
		displayboard(board, ROW, COL);
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 > 0 && x <= row && y > 0 && y <= col)
		{
			if (board[x - 1][y - 1] == ' ')
			{
				board[x - 1][y - 1] = '#';
				break;
			}
			else
			{
				printf("坐标被占用");
			}
		}
		else
		{
			printf("输入非法\n");
		}
	}
}

5.电脑下棋

computermove(board, ROW, COL);//电脑下棋
		is=iswin(board, ROW, COL);
		if (is != 1)
		{
			break;
		}
		displayboard(board, ROW, COL);
void computermove(char board[ROW][COL],int row,int col)//电脑下棋
{
	printf("电脑下棋\n");
	if (board[1][1] == ' ')//首先抢占(2,2)的中心位置
	{
		board[1][1] = '*';
		return 1;
	}
	else if (board[0][0] == ' ')//中心位置被占据,选择四角
	{
		board[0][0] = '*';
		return 1;
	}
	int x = 0;
	int y = 0;
	int i = 0;
	for(i=0;i<ROW;i++)//判断每行是否已经有两个相同的棋子并且是否有空位,如果有,在空的那个下
	{
		x = i;
		if (board[i][0] == board[i][1]&& board[i][0]!=' ' && board[i][2] == ' ')
		{
			y = 2;
			board[x][y] = '*';
			goto again;
	    }
		if (board[i][2] == board[i][1] && board[i][1] != ' ' && board[i][0] == ' ')
		{
			y = 0;
			board[x][y] = '*';
			goto again;
		}
		if (board[i][0] == board[i][2] && board[i][0] != ' ' && board[i][1] == ' ')
		{
			y = 1;
			board[x][y] = '*';
			goto again;
		}
     }
	int j = 0;
	for (j = 0; j < ROW; j++)//判断每列是否已经有两个相同的棋子并且是否有空位,如果有,在空的那个下
	{
		if (board[0][j] == board[1][j] && board[0][j] != ' ' && board[2][j] == ' ')
		{
			x = 2;
			y = j;
			board[x][y] = '*';
			goto again;
		}
		if (board[2][j] == board[1][j] && board[1][j] != ' ' && board[0][j] == ' ')
		{
			x = 0;
			y = j;
			board[x][y] = '*';
			goto again;
		}
		if (board[0][j] == board[2][j] && board[0][j] != ' ' && board[1][j] == ' ')
		{
			x = 1;
			y = j;
			board[x][y] = '*';
			goto again;
		}
	}
	//判断对角线是否已经有两个相同的棋子并且是否有空位,如果有,在空的那个下
	if (board[0][0] == board[1][1] && board[0][0] != ' ' && board[2][2] == ' ')
	{
		x = 2;
		y = 2;
		board[x][y] = '*';
		goto again;
	}
	if (board[0][0] == board[2][2] && board[0][0] != ' ' && board[1][1] == ' ')
	{
		x = 1;
		y = 1;
		board[x][y] = '*';
		goto again;
	}
	if (board[2][2] == board[1][1] && board[1][1] != ' ' && board[0][0] == ' ')
	{
		x = 0;
		y = 0;
		board[x][y] = '*';
		goto again;
	}
	if (board[2][0] == board[1][1] && board[1][1] != ' ' && board[0][2] == ' ')
	{
		x = 0;
		y = 2;
		board[x][y] = '*';
		goto again;
	}
	if (board[2][0] == board[0][2] && board[2][0] != ' ' && board[1][1] == ' ')
	{
		x = 1;
		y = 1;
		board[x][y] = '*';
		goto again;
	}
	if (board[0][2] == board[1][1] && board[0][2] != ' ' && board[2][0] == ' ')
	{
		x = 2;
		y = 0;
		board[x][y] = '*';
		goto again;
	}
	//上述条件均不满足,随机下
	while (1)
	{
		x = rand() % row;//使得x取值范围为0-row
		y = rand() % col;
		if (board[x][y] == ' ')
		{
			board[x][y] = '*';
			goto again;
		}

	}
	//上述语句有一个被满足,直接跳到这里,不要在执行其他判断语句了
	again:
	   return 0;
}

6.判断输赢

根据返回值判断结果

if (is != 1)
	{
		break;
	}
	if (is == 2)
	{
		printf("玩家赢\n");
	}
	if (is == 3)
	{
		printf("电脑赢\n");
	}
	if (is == 4)
	{
		printf("平局");
	}
	displayboard(board, ROW, COL);
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] != ' ')
		{
			if (board[i][0] == '#')
			{
				return 2;
			}
			if (board[i][0] == '*')
			{
				return 3;
			}
		}
	}
	//判断列
	int i1 = 0;
	for (i1 = 0; i1 <= COL; i1++)
	{
		if (board[0][i1] == board[1][i1] && board[1][i1] == board[2][i1] && board[0][i1] != ' ')
		{
			if (board[0][i1] == '#')
			{
				return 2;
			}
			if (board[0][i1] == '*')
			{
				return 3;
			}
		}
	}
	//判断对角线
	if (board[0][0] == board[1][1] && board[2][2] == board[1][1] && board[0][0] != ' ')
	{
		if (board[0][0] == '#')
		{
			return 2;
		}
		if (board[0][0] == '*')
		{
			return 3;
		}
	}
	if (board[2][0] == board[1][1] && board[0][2] == board[1][1] && board[1][1] != ' ')
	{
		if (board[1][1] == '#')
		{
			return 2;
		}
		if (board[1][1] == '*')
		{
			return 3;
		}
	}
	//判断平局
	if (isfull(board, ROW, COL))
	{
		return 4;
	}
	//..游戏继续
	return 1;
}

7.总体代码

test.c

#define _CRT_SECURE_NO_WARNINGS//游戏逻辑
#include"game.h"//包含头文件,直接使用定义的变量
void game()//要实现的功能:1.打印棋盘2.玩家下棋3.电脑下棋4.判断输赢
{
	int is = 0;
	char board[ROW][COL] = { 0 };//存放棋子的数组,棋子是#*,所以用char
	initboard(board, ROW, COL);//初始化棋盘
	displayboard(board, ROW, COL);//打印棋盘
	while (1)
	{
		playermove(board, ROW, COL);//玩家下棋
		is=iswin(board, ROW, COL);
		if (is != 1)
		{
			break;
		}
		displayboard(board, ROW, COL);
		//判断输赢
		computermove(board, ROW, COL);//电脑下棋
		is=iswin(board, ROW, COL);
		if (is != 1)
		{
			break;
		}
		displayboard(board, ROW, COL);
		//判断输赢
	}
	
	if (is == 2)
	{
		printf("玩家赢\n");
	}
	if (is == 3)
	{
		printf("电脑赢\n");
	}
	if (is == 4)
	{
		printf("平局");
	}
	displayboard(board, ROW, COL);
}
void menu()
{
	printf("############################\n");
	printf("######1.play    0.exit #####\n");
	printf("############################\n");
}
int main()
{
	srand((unsigned int)time(NULL));//设置随机数生成起点
	int a = 0;
	do
	{
		menu();//打印菜单
		printf("请选择:");
		scanf("%d", &a);
		switch (a)
		{
		case 1:
			game();
				break;
		case 0:
			printf("退出游戏\n");
				break;
		default:
			printf("选择错误\n");
			break;
		}
	} while (a);
	return 0;
}

game.h

#define _CRT_SECURE_NO_WARNINGS
#define ROW 3//定义行和列,方便之后将三字棋改为五子棋或十字棋
#define COL 3
#include<stdio.h>
#include<stdlib.h>
#include<time.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(int board[ROW][COL], int row, int col);//电脑下棋
char iswin(char board[ROW][COL], int row, int col);//判断输赢

game.c

#define _CRT_SECURE_NO_WARNINGS

#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;
//	for (i = 0; i < ROW; i++)
//	{
//		打印数据
//		printf(" %c | %c | %c \n",board[i][0],board[i][1],board[i][2]);//这样的代码太死板了,如果改为五子棋,行列无法变换
//		打印分割行
//		if(i<ROW-1)
//		printf("---|---|---\n");
//	}
//}

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("|");
		}
		printf("\n");
		//打印分割信息
		if (i < row - 1)
		{
			for (j = 0; j < col; j++)
			{
				printf("---");
				if (j < col - 1)
				{
					printf("|");
				}
			}
		}
		printf("\n");
	}
}

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 > 0 && x <= row && y > 0 && y <= col)
		{
			if (board[x - 1][y - 1] == ' ')
			{
				board[x - 1][y - 1] = '#';
				break;
			}
			else
			{
				printf("坐标被占用");
			}
		}
		else
		{
			printf("输入非法\n");
		}
	}
}

//void computermove(char board[ROW][COL],int row,int col)//电脑下棋,找空白位置随机下
//{
//	printf("电脑下棋\n");
//	int x = 0;
//	int y = 0;
//	while(1)
//	{ 
//	    x = rand() % row;//使得x取值范围为0-row
//	    y = rand() % col;
//		if (board[x][y] == ' ')
//		{
//			board[x][y] = '*';
//			break;
//		}
//		else
//			continue;
//     }
//}

void computermove(char board[ROW][COL],int row,int col)//电脑下棋
{
	printf("电脑下棋\n");
	if (board[1][1] == ' ')//首先抢占(2,2)的中心位置
	{
		board[1][1] = '*';
		return 1;
	}
	else if (board[0][0] == ' ')//中心位置被占据,选择四角
	{
		board[0][0] = '*';
		return 1;
	}
	int x = 0;
	int y = 0;
	int i = 0;
	for(i=0;i<ROW;i++)//判断每行是否已经有两个相同的棋子并且是否有空位,如果有,在空的那个下
	{
		x = i;
		if (board[i][0] == board[i][1]&& board[i][0]!=' ' && board[i][2] == ' ')
		{
			y = 2;
			board[x][y] = '*';
			goto again;
	    }
		if (board[i][2] == board[i][1] && board[i][1] != ' ' && board[i][0] == ' ')
		{
			y = 0;
			board[x][y] = '*';
			goto again;
		}
		if (board[i][0] == board[i][2] && board[i][0] != ' ' && board[i][1] == ' ')
		{
			y = 1;
			board[x][y] = '*';
			goto again;
		}
     }
	int j = 0;
	for (j = 0; j < ROW; j++)//判断每列是否已经有两个相同的棋子并且是否有空位,如果有,在空的那个下
	{
		if (board[0][j] == board[1][j] && board[0][j] != ' ' && board[2][j] == ' ')
		{
			x = 2;
			y = j;
			board[x][y] = '*';
			goto again;
		}
		if (board[2][j] == board[1][j] && board[1][j] != ' ' && board[0][j] == ' ')
		{
			x = 0;
			y = j;
			board[x][y] = '*';
			goto again;
		}
		if (board[0][j] == board[2][j] && board[0][j] != ' ' && board[1][j] == ' ')
		{
			x = 1;
			y = j;
			board[x][y] = '*';
			goto again;
		}
	}
	//判断对角线是否已经有两个相同的棋子并且是否有空位,如果有,在空的那个下
	if (board[0][0] == board[1][1] && board[0][0] != ' ' && board[2][2] == ' ')
	{
		x = 2;
		y = 2;
		board[x][y] = '*';
		goto again;
	}
	if (board[0][0] == board[2][2] && board[0][0] != ' ' && board[1][1] == ' ')
	{
		x = 1;
		y = 1;
		board[x][y] = '*';
		goto again;
	}
	if (board[2][2] == board[1][1] && board[1][1] != ' ' && board[0][0] == ' ')
	{
		x = 0;
		y = 0;
		board[x][y] = '*';
		goto again;
	}
	if (board[2][0] == board[1][1] && board[1][1] != ' ' && board[0][2] == ' ')
	{
		x = 0;
		y = 2;
		board[x][y] = '*';
		goto again;
	}
	if (board[2][0] == board[0][2] && board[2][0] != ' ' && board[1][1] == ' ')
	{
		x = 1;
		y = 1;
		board[x][y] = '*';
		goto again;
	}
	if (board[0][2] == board[1][1] && board[0][2] != ' ' && board[2][0] == ' ')
	{
		x = 2;
		y = 0;
		board[x][y] = '*';
		goto again;
	}
	//上述条件均不满足,随机下
	while (1)
	{
		x = rand() % row;//使得x取值范围为0-row
		y = rand() % col;
		if (board[x][y] == ' ')
		{
			board[x][y] = '*';
			goto again;
		}

	}
	//上述语句有一个被满足,直接跳到这里,不要在执行其他判断语句了
	again:
	   return 0;
}

char isfull(char board[ROW][COL], int row, int col)//棋盘是否满了
{
	
	int i = 0;
	for (i = 0; i <= ROW; i++)
	{
		int j = 0;
		for (j = 0; j <= COL; j++)
		{
			if (board[i][j] == ' ')
				return 0;//未满
		}
	}
	return 1;//满了
}
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] != ' ')
		{
			if (board[i][0] == '#')
			{
				return 2;
			}
			if (board[i][0] == '*')
			{
				return 3;
			}
		}
	}
	//判断列
	int i1 = 0;
	for (i1 = 0; i1 <= COL; i1++)
	{
		if (board[0][i1] == board[1][i1] && board[1][i1] == board[2][i1] && board[0][i1] != ' ')
		{
			if (board[0][i1] == '#')
			{
				return 2;
			}
			if (board[0][i1] == '*')
			{
				return 3;
			}
		}
	}
	//判断对角线
	if (board[0][0] == board[1][1] && board[2][2] == board[1][1] && board[0][0] != ' ')
	{
		if (board[0][0] == '#')
		{
			return 2;
		}
		if (board[0][0] == '*')
		{
			return 3;
		}
	}
	if (board[2][0] == board[1][1] && board[0][2] == board[1][1] && board[1][1] != ' ')
	{
		if (board[1][1] == '#')
		{
			return 2;
		}
		if (board[1][1] == '*')
		{
			return 3;
		}
	}
	//判断平局
	if (isfull(board, ROW, COL))
	{
		return 4;
	}
	//..游戏继续
	return 1;
}

初学c语言,第一次写博客,如有不足之处,请各位多多包涵与指教。

  • 3
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
以下是 C 语言井字棋代码加注释: ``` #include <stdio.h> #define BOARD_SIZE 3 // 定义棋盘大小为3 int board[BOARD_SIZE][BOARD_SIZE]; // 存储棋盘的二维数组 void init_board() { // 初始化棋盘,将所有位置都设置为0 int i, j; for (i = 0; i < BOARD_SIZE; i++) { for (j = 0; j < BOARD_SIZE; j++) { board[i][j] = 0; } } } void print_board() { // 打印棋盘 int i, j; for (i = 0; i < BOARD_SIZE; i++) { for (j = 0; j < BOARD_SIZE; j++) { if (board[i][j] == 0) { printf("_ "); // 未下棋的位置用"_"表示 } else if (board[i][j] == 1) { printf("X "); // 玩家1下的棋用"X"表示 } else if (board[i][j] == 2) { printf("O "); // 玩家2下的棋用"O"表示 } } printf("\n"); } } int check_win(int player) { // 检查指定玩家是否胜利,player为1表示玩家1,player为2表示玩家2 int i, j, win; // 检查每一行是否连成一线 for (i = 0; i < BOARD_SIZE; i++) { win = 1; for (j = 0; j < BOARD_SIZE; j++) { if (board[i][j] != player) { win = 0; break; } } if (win) { return 1; } } // 检查每一列是否连成一线 for (i = 0; i < BOARD_SIZE; i++) { win = 1; for (j = 0; j < BOARD_SIZE; j++) { if (board[j][i] != player) { win = 0; break; } } if (win) { return 1; } } // 检查对角线是否连成一线 win = 1; for (i = 0; i < BOARD_SIZE; i++) { if (board[i][i] != player) { win = 0; break; } } if (win) { return 1; } // 检查反对角线是否连成一线 win = 1; for (i = 0; i < BOARD_SIZE; i++) { if (board[i][BOARD_SIZE - 1 - i] != player) { win = 0; break; } } if (win) { return 1; } return 0; // 没有胜利返回0 } int main() { int i, j, row, col, player = 1, num_moves = 0; init_board(); // 初始化棋盘 while (1) { printf("Player %d's turn:\n", player); print_board(); // 打印棋盘 printf("Enter row and column to place %c: ", player == 1 ? 'X' : 'O'); scanf("%d %d", &row, &col); if (board[row][col] != 0) { // 如果该位置已有棋子,重新输入 printf("Invalid move, try again.\n"); continue; } board[row][col] = player; // 将棋子放入棋盘 if (check_win(player)) { // 检查是否胜利 printf("Player %d wins!\n", player); print_board(); break; } num_moves++; // 记录下棋步数 if (num_moves == BOARD_SIZE * BOARD_SIZE) { // 如果下满了棋盘,宣布平局 printf("Draw!\n"); print_board(); break; } player = player == 1 ? 2 : 1; // 切换玩家 } return 0; } ``` 注释中详细解释了每个函数和变量的作用,以及程序的流程。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值