栏目分类:
子分类:
返回
文库吧用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
文库吧 > IT > 软件开发 > 后端开发 > C/C++/C#

【C语言】-三子棋

C/C++/C# 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

【C语言】-三子棋

文章目录
  • 一、游戏菜单
  • 二、主函数
  • 三、game()
  • 四、init_board()
  • 五、display_board()
  • 六、player_move()
  • 七、computer_move()
  • 八、is_win()
  • 九、is_full()
  • 总结-完整代码
    • 1.game.h
    • 2.game.c
    • 3.test.c
  • 十、具体实现效果

一、游戏菜单
void menu()
{
	printf("*****************************n");
	printf("********** 1. play **********n");
	printf("********** 0. exit **********n");
	printf("*****************************n");

游戏菜单是给玩家选择是否进入游戏的界面

二、主函数
int main()
{
	srand((unsigned int)time(NULL));
	int input = 0;
	do
	{
		menu();
		printf("请选择:>");
		scanf("%d", &input);
		switch (input)
		{
		case 1:
			game();
			break;
		case 0:
			printf("退出游戏n");
			break;
		default:
			printf("选择错误,重新选择n"); 
		}
	} while (input);
	return 0;
}

这里的逻辑是:进入游戏菜单后,玩家输入 1,即可进入游戏,玩家输入0,即可退出游戏。

三、game()
void game()
{
	int ret;
	char board[3][3] = { 0 };
	init_board(board, ROW, COL); 
	display_board(board,ROW,COL);
	while (1)
	{
		player_move(board, ROW, COL);
		ret = is_win(board, ROW, COL);
		if (ret != 'C')
		{
			break;
		}
		computer_move(board, ROW, COL);
		ret = is_win(board, ROW, COL);
		if (ret != 'C')
		{
			break;
		}
		display_board(board, ROW, COL);
	}
	if (ret == 'Q')
	{
		printf("平局n");
	}
	else if (ret == '*')
	{
		printf("玩家赢n");
	}
	else if (ret == '#')
	{
		printf("电脑赢n");
	}
	

}

这部分是实现游戏流程的逻辑。例如,玩家下棋,电脑下棋,打印棋盘等等的逻辑先后以及循环逻辑

四、init_board()
void init_board(char board[ROW][COL], int row, int col)
{
	for (int i = 0; i < row; i++)
	{
		for (int j = 0; j < col; j++)
		{
			board[i][j] = ' ';
		}
	}
}

init_board函数的目的是初始化棋盘,将棋盘的九个格子的内容初始化为‘空格’,那么为什么不可以初始化为0呢,打印出来我们同样看不见。这里的原因是打印出来0是不占字符的,它不仅看不见,而且还不占位置。所以,如果使用0代替空格的话,打印出来的效果如下:


由于0不占位置,所以打印出来的第一行的’|‘与第二行的’|‘无法对齐。
而正确使用’空格‘打印出来的效果才是正确的
如下:

五、display_board()
void display_board(char board[ROW][COL], int row, int col)
{
	for (int i = 0; i < row; i++)
	{
		for (int j = 0; j < col; j++)
		{
			printf(" %c ",board[i][j]);
			if (j < col - 1)
				printf("|");
		}
		printf("n");
		if (i < row - 1)
		{
			for (int j = 0; j < col; j++)
			{
				printf("---");
				if (j < col - 1)
					printf("|");
			}
		}
		printf("n");
	}
}

这段代码的作用是将数组中的字符以及三子棋的棋盘打印出来,打印效果如下:

打印时,我们需要注意的几点是,最后一列不要打印’|‘,最后一行不要打印’—‘
我们就可以用if语句来控制打印。所以采用了if(i 六、player_move()

void player_move(char board[ROW][COL], int row, int col)
{
	int x, y;
	while (1)
	{
		printf("请输入要下棋的坐标n");
		printf("玩家下棋:>");
		scanf("%d %d", &x, &y);
		if (x > 0 && x <= col && y > 0 && y <= row)
		{
			if (board[x - 1][y - 1] == ' ')
			{
				board[x-1][y-1] = '*';
				break;
			}
			else
			{
				printf("该坐标已被占用,请重新输入");
			}
			
		}
		else
		{
			printf("坐标非法,请重新输入");
		}
	}
}

player_move()函数的作用是,让玩家下棋,由于玩家认为的坐标与实际数组对应的位置相差1,所以当玩家输入坐标后,在对应的x-1,y-1的位置上的数组改为’*‘,同时要保证输入数据的有效性

七、computer_move()
void computer_move(char board[ROW][COL], int row, int col)
{
	while (1)
	{
		int x = rand() % row;
		int y = rand() % col;
		if (board[x][y] == ' ')
		{
			board[x][y] = '#';
			break;
		}
	}

}

由于学艺不精,我无法用c语言实现电脑智能下棋,只能让电脑随机下棋。采用rand函数对随机数取余。在对应坐标位置上将数组上的‘空格’,改为‘#’;

八、is_win()
char is_win(char board[ROW][COL], int row, int col)
{
	//横
	for (int i = 0; i < row; i++)
	{
		if (board[i][0] == board[i][1] && board[i][2] == board[i][1] && board[i][0] != ' ')
		{
			return board[i][0];
		}
	}
	//竖
	for (int 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];
	}

	if (is_full(board,row,col) == 1)
	{
		return 'Q';
	}
	return 'C';


}

该函数的作用是对棋盘进行判断游戏是否继续;若游戏终止,则返回对应的结果,若玩家获胜,则返回‘*’,若电脑获胜,则返回‘#’;

九、is_full()
int is_full(char board[ROW][COL], int row, int col)
{
	for (int i = 0; i < row; i++)
	{
		for (int j = 0; j < col; j++)
		{
			if (board[i][j] == ' ')
			{
				return 0;
			}
		}
	}
	return 1;
}

is_full函数的目的是判断棋盘是否以及满了,该函数与is_win函数搭配使用。为is_win函数功能的完成做铺垫。

总结-完整代码 1.game.h
#pragma once
#define _CRT_SECURE_NO_WARNINGS 1
#define ROW 3
#define COL 3
#include
#include
#include

void display_board(char board[ROW][COL],int row,int col);
void init_board(char board[ROW][COL], int row, int col);
void player_move(char board[ROW][COL], int row, int col);
void computer_move(char board[ROW][COL], int row, int col);
char is_win(char board[ROW][COL], int row, int col);
2.game.c
#pragma once
#include "game.h"
void init_board(char board[ROW][COL], int row, int col)
{
	for (int i = 0; i < row; i++)
	{
		for (int j = 0; j < col; j++)
		{
			board[i][j] = ' ';
		}
	}
}

void display_board(char board[ROW][COL], int row, int col)
{
	for (int i = 0; i < row; i++)
	{
		for (int j = 0; j < col; j++)
		{
			printf(" %c ",board[i][j]);
			if (j < col - 1)
				printf("|");
		}
		printf("n");
		if (i < row - 1)
		{
			for (int j = 0; j < col; j++)
			{
				printf("---");
				if (j < col - 1)
					printf("|");
			}
		}
		printf("n");
	}
}
void player_move(char board[ROW][COL], int row, int col)
{
	int x, y;
	while (1)
	{
		printf("请输入要下棋的坐标n");
		printf("玩家下棋:>");
		scanf("%d %d", &x, &y);
		if (x > 0 && x <= col && y > 0 && y <= row)
		{
			if (board[x - 1][y - 1] == ' ')
			{
				board[x-1][y-1] = '*';
				break;
			}
			else
			{
				printf("该坐标已被占用,请重新输入");
			}
			
		}
		else
		{
			printf("坐标非法,请重新输入");
		}
	}
}
void computer_move(char board[ROW][COL], int row, int col)
{
	while (1)
	{
		int x = rand() % row;
		int y = rand() % col;
		if (board[x][y] == ' ')
		{
			board[x][y] = '#';
			break;
		}
	}

}
int is_full(char board[ROW][COL], int row, int col)
{
	for (int i = 0; i < row; i++)
	{
		for (int j = 0; j < col; j++)
		{
			if (board[i][j] == ' ')
			{
				return 0;
			}
		}
	}
	return 1;
}
char is_win(char board[ROW][COL], int row, int col)
{
	//横
	for (int i = 0; i < row; i++)
	{
		if (board[i][0] == board[i][1] && board[i][2] == board[i][1] && board[i][0] != ' ')
		{
			return board[i][0];
		}
	}
	//竖
	for (int 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];
	}

	if (is_full(board,row,col) == 1)
	{
		return 'Q';
	}
	return 'C';


}
3.test.c
#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()
{
	int ret;
	char board[3][3] = { 0 };
	init_board(board, ROW, COL); 
	display_board(board,ROW,COL);
	while (1)
	{
		player_move(board, ROW, COL);
		ret = is_win(board, ROW, COL);
		if (ret != 'C')
		{
			break;
		}
		computer_move(board, ROW, COL);
		ret = is_win(board, ROW, COL);
		if (ret != 'C')
		{
			break;
		}
		display_board(board, ROW, COL);
	}
	if (ret == 'Q')
	{
		printf("平局n");
	}
	else if (ret == '*')
	{
		printf("玩家赢n");
	}
	else if (ret == '#')
	{
		printf("电脑赢n");
	}
	

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

赶紧让代码在你的编译器上跑起来试试叭~

十、具体实现效果

转载请注明:文章转载自 www.wk8.com.cn
本文地址:https://www.wk8.com.cn/it/1037022.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 wk8.com.cn

ICP备案号:晋ICP备2021003244-6号