三字棋(N子棋)

目录

1.游戏介绍

2.程序构成

 3.游戏思路和实现

1.创建棋盘并打印 

2.玩家和电脑实现下棋步骤

3.判断双方谁先获得胜利或者双方平局


1.游戏介绍

三子棋又名井字棋,相信大家小时候都玩过,在一个3x3的棋盘上下棋,最先实现三字连成一条线的玩家获得胜利。

2.程序构成

 game.h

#define _CRT_SECURE_NO_WARNINGS 1
#include <stdio.h>
#include <stdlib.h>// rand srand
#include <time.h>// time
#include <windows.h>//Sleep

#define ROW 3
#define COL 3

//初始化棋盘
void init_board(char board[ROW][COL], int row, int col);   

//打印棋盘
void print_board(char board[ROW][COL], int row, int col);

//玩家下棋
void player_input(char board[ROW][COL],int row,int col);

//电脑下棋
void computer_input(char board[ROW][COL], int row, int col);

//判断结果(输 赢 平局)
//玩家赢返回 '* ',电脑赢返回 '# ',返回 'B'(游戏继续),返回 'C'(平局)
char is_win(char board[ROW][COL], int row, int col);

//判断棋盘是否已满,没满返回0(继续游戏),满了返回1(平局)
int is_full(char board[ROW][COL], int row, int col);

game.c

#include "game.h"

void init_board(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 print_board(char board[ROW][COL], int row, int col)
{
	int i = 0;
	for (i = 0; i < row; i++)
	{
		int j = 0;
		// %c | %c | %c ;
		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 < row - 1)
				{	
					printf("|");
				}
			}
		}
		
		printf("\n");
	}
}

void player_input(char board[ROW][COL], int row, int col)
{
	printf("玩家请下棋->\n");
	int x = 0;
	int y = 0;
	while (1)
	{
		scanf("%d %d", &x, &y);
		if (x >= 1 && x <= row && y >= 1 && y <= col && board[x - 1][y - 1] == ' ')
		//x = 1 2 3; y = 1 2 3; 不懂数组的人玩这个游戏,并不知道数组的坐标,例如第一行第一列的坐标是0,0,方便游客游玩我们将每个坐标 + 1
		{
			board[x-1][y-1] = '*';//当我们输入1 ,1 将第一行第一列下棋为 * 时,数组这里 - 1,对应数组坐标 0,0
			break;
		}
		else if(board[x - 1][y - 1] != ' ')//坐标不为空格时表示已经有棋
		{
			printf("此格已经有棋子,请重输入->\n");
		}
		else//最后一种可能就是坐标输入超出棋盘坐标
			printf("超出棋盘,重新输入->\n");
	}

}

void computer_input(char board[ROW][COL], int row, int col,int ret)
{
	printf("电脑下棋中->\n");
	while (1)
	{
		int x = rand() % row;
		int y = rand() % col;
		Sleep(2000);
		if (board[x][y] == ' ')
		{
			board[x][y] = '#';
			break;
		}
	}
}

char is_win(char board[ROW][COL], int row, int col)
{	
	//横排判断
	int i = 0;
	int j = 0;
	for (i = 0; i < row; i++)
	{
		int count1 = 0;
		for (j = 0; j < col-1; j++)
		{
			if (board[i][j] == board[i][j + 1] && board[i][j] != ' ')
				count1++;
		}
		if (count1 == col - 1)
		{
			return board[i][j];
		}
	}
	//数列判断
	for (j = 0; j < col; j++)
	{
		int count2 = 0;
		for (i = 0; i < row - 1; i++)
		{
			if (board[i][j] == board[i + 1][j] && board[i][j] != ' ')
				count2++;
		}
		if (count2 == row - 1)
		{
			return board[i][j];
		}
	}
	//右斜线判断,从左上角判断到右下角
	int count3 = 0;
	for (i = 0; i < row-1; i++)
	{
		if (board[i][i] == board[i + 1][i + 1] && board[i][i] != ' ')
		{
			count3++;
		}
		if (count3 == col - 1)
		{
			return board[i][i];
		}
	}
	//左斜线判断,从右上角判断到左下角
	int count4 = 0;
	for (i = 0; i < row - 1; i++)
	{
		if (board[i][row - 1 - i] == board[i+1][row - 2 - i] && board[i][row - 1 - i] != ' ')
		{
			count4++;
		}
		if (count4 == row - 1)
		{
			return board[i][row - 1 - i];
		}
		int x =is_full(board, ROW, COL);
		if (x == 0)
		{
			return 'B';
		}
		else
		{
			return 'C';
		}
	}
}

int is_full(char board[ROW][COL], int row, int col)
{
	int i = 0;
	int j = 0;
	while(1)
	{
		int count = 0;
		for (i = 0; i < row; i++)
		{
			for (j = 0; j < col; j++)
			{
				if (board[i][j] == ' ')
				{
					return 0;
					break;
				}
				else
				{
					count++;
				}
			}
			if (count == row * col)//棋盘所有格子数等于 行 X 列
			{
				return 1;
			}
		}
	}
	
}

test.c

#include "game.h"

void menu()
{
	printf("**********1.play**********\n");
	printf("**********0.exit**********\n");
}
void game()
{
	char board[ROW][COL] = { 0 };
	srand((unsigned int)time(NULL));
	init_board(board, ROW, COL);
	print_board(board, ROW, COL);
	//先初始化棋盘再打印棋盘,不能将执行顺序搞反
	while (1)
	{
		player_input(board, ROW, COL);
		print_board(board, ROW, COL);
		char ret = is_win(board,ROW,COL);//is_win返回一个值给ret来判断游戏结果,* 玩家赢 # 电脑赢 C 棋盘满 平局
		if (ret == '*')
		{
			printf("恭喜你赢了!!!\n");
			break;
		}
		else if(ret == '#')
		{
			printf("很遗憾电脑赢了,再接再厉\n");
			break;
		}
		else if (ret == 'C')
		{
			printf("棋盘已满,平局\n");
			break;
		}
		computer_input(board, ROW, COL);
		print_board(board, ROW, COL);
		ret = is_win(board, ROW, COL);
		if (ret == '*')
		{
			printf("恭喜你赢了!!!\n");
			break;
		}
		else if (ret == '#')
		{
			printf("很遗憾电脑赢了,再接再厉\n");
			break;
		}
		else if (ret == 'C')
		{
			printf("棋盘已满,平局\n");
			break;
		}
	}
}  
int main()

{
	int input = 0;
	do 
	{
		menu();
		printf("请选择 -->");
		scanf("%d", &input);
		switch (input)
		{
		case 1:
			game();
			break;
		case 0:
			printf("退出游戏\n");
			break;
		default:
			printf("输入错误,请重新输入\n");
			break;
		}
	} while (input);
	return 0;
}

 3.游戏思路和实现

1.创建棋盘并打印 

 先创建出一个棋盘数组,行为ROW,列为COL

创建形参row 和 col来接收ROW 和 COL 的值

char board[ROW][COL] = { 0 };
init_board(board, ROW, COL);
print_board(board, ROW, COL);

//初始化棋盘
void init_board(char board[ROW][COL], int row, int col);   

init_board 程序构成:

void init_board(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 print_board(char board[ROW][COL], int row, int col);

 print_board程序构成:

void print_board(char board[ROW][COL], int row, int col)
{
	int i = 0;
	for (i = 0; i < row; i++)
	{
		int j = 0;
		// %c | %c | %c ;
		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 < row - 1)
				{
					printf("|");
				}
			}
		}
		
		printf("\n");
	}
}

 

竖排列可以理解为

需要三行            ' ' | ' ' | ' '         (红色圈的地方)当棋盘是3(ROW)x3(COL)时,需要row行

需要三个        ' '        和二个        |        (红绿色重叠部分)

当棋盘是3(ROW)x3(COL)时,需要col个        ' '        和col-1个        |        

横行可以理解为

需要俩行    ---|---|---      (红色圈的地方)  当棋盘是3(ROW)x3(COL)时,需要row-1行

每行需要三个        ---        和二个        |       (红绿色重叠部分)

当棋盘是3(ROW)x3(COL)时,需要col个        ---        和col-1个        |        

2.玩家和电脑实现下棋步骤

player_input(board, ROW, COL);
computer_input(board, ROW, COL);    
srand((unsigned int)time(NULL));//

rand函数可以返回一个整型随机数值,但是起点是一样的,所以每次rand的随机值都是一样的

例如这次rand是 2 ,15 ,33 ,1,44,下次程序执行还是 2 ,15 ,33 ,1,44,

srand可以初始化rand的起点,这时候使用time函数给srand随机的值,rand就可以每次返回不同的整型数值了。

具体请看

玩家下棋:

void player_input(char board[ROW][COL], int row, int col)

player_input 程序构成 :

void player_input(char board[ROW][COL], int row, int col)
{
	printf("玩家请下棋->\n");
	int x = 0;
	int y = 0;
	while (1)
	{
		scanf("%d %d", &x, &y);
		if (x >= 1 && x <= row && y >= 1 && y <= col && board[x - 1][y - 1] == ' ')
		//x = 1 2 3; y = 1 2 3; 不懂数组的人玩这个游戏,并不知道数组的坐标,例如第一行第一列的坐标是0,0,方便游客游玩我们将每个坐标 + 1
		{
			board[x-1][y-1] = '*';//当我们输入1 ,1 将第一行第一列下棋为 * 时,数组这里 - 1,对应数组坐标 0,0
			break;
		}
		else if(board[x - 1][y - 1] != ' ')//坐标不为空格时表示已经有棋
		{
			printf("此格已经有棋子,请重输入->\n");
		}
		else//最后一种可能就是坐标输入超出棋盘坐标
			printf("超出棋盘,重新输入->\n");
	}

}

方便游玩我们将坐标+1 

电脑下棋:

void computer_input(char board[ROW][COL], int row, int col,int ret)

computer_input 程序构成:

void computer_input(char board[ROW][COL], int row, int col,int ret)
{
	printf("电脑下棋中->\n");
	while (1)
	{
		int x = rand() % row;
		int y = rand() % col;
		Sleep(2000);
		if (board[x][y] == ' ')
		{
			board[x][y] = '#';
			break;
		}
	}
}

3.判断双方谁先获得胜利或者双方平局

胜利条件:横排、竖排、x 交叉斜线(俩条)三个相同棋子连成一条线

平局条件:棋盘下满,无棋盘位可下

while (1)
	{
		player_input(board, ROW, COL);
		print_board(board, ROW, COL);
		char ret = is_win(board,ROW,COL);
		if (ret == '*')
		{
			printf("恭喜你赢了!!!\n");
			break;
		}
		else if(ret == '#')
		{
			printf("很遗憾电脑赢了,再接再厉\n");
			break;
		}
		else if (ret == 'C')
		{
			printf("棋盘已满,平局\n");
			break;
		}
		computer_input(board, ROW, COL);
		print_board(board, ROW, COL);
		ret = is_win(board, ROW, COL);
		if (ret == '*')
		{
			printf("恭喜你赢了!!!\n");
			break;
		}
		else if (ret == '#')
		{
			printf("很遗憾电脑赢了,再接再厉\n");
			break;
		}
		else if (ret == 'C')
		{
			printf("棋盘已满,平局\n");
			break;
		}
	}
}  
char is_win(char board[ROW][COL], int row, int col)
{	
	//横排判断
	int i = 0;
	int j = 0;
	for (i = 0; i < row; i++)
	{
		int count1 = 0;
		for (j = 0; j < col-1; j++)
		{
			if (board[i][j] == board[i][j + 1] && board[i][j] != ' ')
				count1++;
		}
		if (count1 == col - 1)
		{
			return board[i][j];
		}
	}
	//数列判断
	for (j = 0; j < col; j++)
	{
		int count2 = 0;
		for (i = 0; i < row - 1; i++)
		{
			if (board[i][j] == board[i + 1][j] && board[i][j] != ' ')
				count2++;
		}
		if (count2 == row - 1)
		{
			return board[i][j];
		}
	}
	//右斜线判断,从左上角判断到右下角
	int count3 = 0;
	for (i = 0; i < row-1; i++)
	{
		if (board[i][i] == board[i + 1][i + 1] && board[i][i] != ' ')
		{
			count3++;
		}
		if (count3 == col - 1)
		{
			return board[i][i];
		}
	}
	//左斜线判断,从右上角判断到左下角
	int count4 = 0;
	for (i = 0; i < row - 1; i++)
	{
		if (board[i][row - 1 - i] == board[i+1][row - 2 - i] && board[i][row - 1 - i] != ' ')
		{
			count4++;
		}
		if (count4 == row - 1)
		{
			return board[i][row - 1 - i];
		}
		int x =is_full(board, ROW, COL);
		if (x == 0)
		{
			return 'B';
		}
		else
		{
			return 'C';
		}
	}
}

棋盘满时判断:

is_full(board, ROW, COL);
int is_full(char board[ROW][COL], int row, int col)
{
	int i = 0;
	int j = 0;
	while(1)
	{
		int count = 0;
		for (i = 0; i < row; i++)
		{
			for (j = 0; j < col; j++)
			{
				if (board[i][j] == ' ')
				{
					return 0;
					break;
				}
				else
				{
					count++;
				}
			}
			if (count == row * col)//棋盘所有格子数等于 行 X 列
			{
				return 1;
			}
		}
	}
	
}

  • 5
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值