欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

【C语言】经典小游戏--三子棋(井字棋)平民版VS豪华版

程序员文章站 2022-05-19 15:02:24
...

致读者:

 三子棋(井字棋)---记得小时候经常玩的就是这个游戏,虽然不是多么高大尚,但也饶有趣味!

emmmmmm.......大概就是这个样子吧

【C语言】经典小游戏--三子棋(井字棋)平民版VS豪华版

这个小游戏你还知道怎样玩吗?我们一起简单回顾一下:

将三子棋看作3x3的一个二维数组,由玩家和电脑分别填充这个数组。当行、列、叉能够达到三连时,就判断输赢。 

默认玩家先行且棋子为 ‘ X ’,电脑后手棋子为 ‘ 0 ’。 

《平民版》代码如下:

//项目名称:三子棋小游戏
//创建日期:2.18.4.17 
//创建者: Mr.Yao
#define _CRT_SECURE_NO_WARNINGS 1
#include <stdio.h>  
#include <time.h>  

enum NUMBER                         //枚举类型  
{
	EXIT,
	PLAY
};

void Printf(char a[3][3])      //打印数组也就是打印每个操作后的状态  
{
	int i = 0, j = 0;

	for (i = 0; i<3; i++)
	{
		for (j = 0; j<3; j++)
		{
			printf("%c  ", a[i][j]);
		}
		printf("\n");
	}
}

void menu()                    //菜单  
{
	printf("##############1.开始游戏##############\n");
	printf("##############0.退出游戏##############\n");
}

void fill(char a[3][3])       //填充 即玩家和电脑进行‘下棋子’  
{
	int x = 0, y = 0;                 //分别表示 玩家输入的横坐标和纵坐标  
	int ran1 = 0, ran2 = 0;    //分别表示 电脑产生的连个随机数 用来确定电脑下子的坐标  
	srand((unsigned)time(NULL));//随机数发生器的初始化函数。  

	while (1)
	{
		x = 0, y = 0;                //在玩家每次下子前初始化坐标为00  
		printf("请输入你的坐标:");
		scanf("%d%d", &x, &y);
		if (x>3 || x<1 || y>3 || y<1)//玩家所输入的横纵坐标都必须要在1-3之间  
		{
			printf("坐标有误,请重新输入!\n");
			continue;
		}
		if (a[x - 1][y - 1] == '_')   //数组初始化每个元素为_ 为真时说明该坐标还未被填充  
		{
			a[x - 1][y - 1] = 'X';
			Check(a);       //检查是否获胜  
		}
		else
		{
			printf("已被填充,请重新填充!\n");
			continue;
		}
		while ((a[ran1 - 1][ran2 - 1] != '_'))  //一直产生随机数直到 该坐标未被填充  
		{
			ran1 = rand() % 3 + 1;
			ran2 = rand() % 3 + 1;
		}
		a[ran1 - 1][ran2 - 1] = '0';       //电脑下子  
		Check(a);

		Printf(a);  //双方下完一次后打印出结果  

	}
}

int Check(char a[3][3])
{
	int i, j;
	int count = 0; //用来标记数组中未被填充的元素个数  
	//共8中获胜可能   
	if (a[0][0] == a[0][1] && a[0][1] == a[0][2] && a[0][2] == 'X'
		|| a[1][0] == a[1][1] && a[1][1] == a[1][2] && a[1][2] == 'X'
		|| a[2][0] == a[2][1] && a[2][1] == a[2][2] && a[2][2] == 'X'
		|| a[0][0] == a[1][1] && a[1][1] == a[2][2] && a[2][2] == 'X'
		|| a[2][0] == a[1][1] && a[1][1] == a[0][2] && a[0][2] == 'X'
		|| a[0][0] == a[1][0] && a[1][0] == a[2][0] && a[2][0] == 'X'
		|| a[0][1] == a[1][1] && a[1][1] == a[2][1] && a[2][1] == 'X'
		|| a[0][2] == a[1][2] && a[1][2] == a[2][2] && a[2][2] == 'X')
	{
		printf("玩家赢!\n");
		system("pause");
		Printf(a);
		exit(0);
	}
	else if (a[0][0] == a[0][1] && a[0][1] == a[0][2] && a[0][2] == '0'
		|| a[1][0] == a[1][1] && a[1][1] == a[1][2] && a[1][2] == '0'
		|| a[2][0] == a[2][1] && a[2][1] == a[2][2] && a[2][2] == '0'
		|| a[0][0] == a[1][1] && a[1][1] == a[2][2] && a[2][2] == '0'
		|| a[2][0] == a[1][1] && a[1][1] == a[0][2] && a[0][2] == '0'
		|| a[0][0] == a[1][0] && a[1][0] == a[2][0] && a[2][0] == '0'
		|| a[0][1] == a[1][1] && a[1][1] == a[2][1] && a[2][1] == '0'
		|| a[0][2] == a[1][2] && a[1][2] == a[2][2] && a[2][2] == '0')
	{
		printf("电脑赢!\n");
		Printf(a);
		system("pause");
		exit(0);
	}
	else
	{


		for (i = 0; i<3; i++)
		{
			for (j = 0; j<3; j++)
			{
				if (a[i][j] == '_')
					count++;
			}
		}
		if (count == 0)
		{
			printf("和棋!\n");
			Printf(a);
			system("pause");
			exit(0);
		}
		count = 0;
	}

}

void init(char arr[3][3])
{
	int i = 0, j = 0;
	char arry[3][3] = { "___", "___", "___" };

	for (i = 0; i<3; i++)
	{
		for (j = 0; j<3; j++)
		{
			arr[i][j] = arry[i][j];
			printf("%c  ", arr[i][j]);
		}
		printf("\n");
	}
}

void PlayGame(char arr[3][3])
{
	init(arr);
	fill(arr);
}
int main()
{
	char game[3][3] = { 0 };
	int choose = 1;
	while (choose)
	{
		menu();
		printf("请选择:");
		scanf("%d", &choose);
		switch (choose)
		{
		case PLAY:
			PlayGame(game);
			break;
		case EXIT:
			return 0;
			break;
		default:
			printf("输入错误\n");
			break;
		}
	}
	system("pause");
	return 0;
}

示图如下:

【C语言】经典小游戏--三子棋(井字棋)平民版VS豪华版


《豪华版》代码如下:

game.h:

//项目名称:三子棋
//编译环境:VS 2013
//创建时间:2018.4.20

#ifndef __GAME_H__
#define __GAME_H__

#include<stdio.h>
#include<stdlib.h>
#include<time.h>
#include<string.h>
 
typedef unsigned int uint;

enum APP
{
	EXIT,
	START
};


#define ROW 3
#define  COL 3

void InitBoard(char board[ROW][COL], int row, int col);
void PrintBoard(char board[ROW][COL], int row, int col);
void ComputerMove(char board[ROW][COL], int row, int col);
void PlayerMove(char board[ROW][COL], int row, int col);
char is_win(char board[ROW][COL], int row, int col);

#endif //__GAME_H__

game.c:

#define _CRT_SECURE_NO_WARNINGS 1


#include"game.h"


void InitBoard(char board[ROW][COL], int row, int col)
{
	memset(board, ' ', sizeof(char)* row*col);
}//memset函数用来对一段内存空间全部设置为某个字符


void PrintBoard(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 != 2)
		{
			printf("---|---|---\n");
		}
	}
}


void  PlayerMove(char board[ROW][COL], int row, int col)
{
	int x = 0;
	int y = 0;
	printf("请输入落子的坐标:\n");
	while (1)
	{
		scanf("%d%d", &x, &y);
		//保证输入坐标的合法性,玩家输入的坐标是从1开始的
		if (((x >= 1) && (x <= row)) && ((y >= 1) && (y <= col)))
		{
			if (board[x - 1][y - 1] == ' ')
			{
				board[x - 1][y - 1] = 'X';//玩家落子
				break;
			}
			else
			{
				printf("该坐标已被占用,请换一个坐标:\n");
			}
		}
		else
		{
			printf("输入坐标不合法,请重新输入:\n");
		}
	}
}


void ComputerMove(char board[ROW][COL], int row, int col)
{
	int x = 0;
	int y = 0;
	while (1)
	{
		x = rand() % row;
		y = rand() % col;//利用rand函数生成随机坐标
		if (board[x][y] == ' ')
		{
			board[x][y] = '0';
			break;
		}
	}


}


static int is_full(char board[ROW][COL], int row, int col)
//函数is_full只在is_win中被调用,可以加上static改变其链接属性
{
	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 is_win(char board[ROW][COL], int row, int col)
{
	int i = 0;
	int j = 0;
	for (i = 0; i < row; i++)
	{
		if ((board[i][0] == board[i][1]) && (board[i][1] == board[i][2]) && (board[i][2] != ' '))
		{
			return  board[i][1];
		}
	}
	for (j = 0; j < col; j++)
	{
		if ((board[0][j] == board[1][j]) && (board[1][j] == board[2][j]) && (board[2][j] != ' '))
		{
			return  board[1][j];
		}
	}
	if ((board[0][0] == board[1][1]) && (board[1][1] == board[2][2]) && (board[2][2] != ' '))
	{
		return board[1][1];
	}
	else if ((board[0][2] == board[1][1]) && (board[1][1] == board[2][0]) && (board[1][1] != ' '))
	{
		return board[1][1];
	}
	else if (is_full(board, ROW, COL) == 1)
	{
		return 'Q';//表示棋盘下满了
	}
	else
		return ' ';
}

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");
	printf("*************************\n");
}


void game()
{
	char ret;
	char board[ROW][COL];
	InitBoard(board, ROW, COL);
	PrintBoard(board, ROW, COL);
	while (1)
	{
		printf("玩家走:\n");
		PlayerMove(board, ROW, COL);
		PrintBoard(board, ROW, COL);
		ret = is_win(board, ROW, COL);
		if (ret != ' ')
			break;
		printf("电脑走:\n");
		ComputerMove(board, ROW, COL);
		PrintBoard(board, ROW, COL);
		ret = is_win(board, ROW, COL);
		if (ret != ' ')
			break;
	}
	if (ret == 'X')
	{
		printf(" 你赢了!\n");
	}
	else if (ret == '0')
	{
		printf(" 你输了\n");
	}
	else if (ret == 'Q')
	{
		printf("平局\n");
	}
}


void test()
{


	int input = 0;
	srand((uint)time(NULL));
	do {
		menu();
		printf("请选择:");
		scanf("%d", &input);
		switch (input)
		{
		case START:
			game();
			break;
		case EXIT:
			break;
		default:
			break;
		}


	} while (input);
}
int main()
{
	test();
	system("pause");
	return 0;
}

示图如下:

【C语言】经典小游戏--三子棋(井字棋)平民版VS豪华版

不正之处,多多指正!