c++实现“见缝插圆”游戏

该程序使用EasyX图形库生成不相交的圆形图案,支持四种不同风格:黄色填充、随机颜色填充、随机颜色叠加填充和随机颜色边框。用户可通过空格键切换风格,同时控制圆圈的最大和最小半径,确保圆与圆之间不相交。程序实现了模块化,包括创建圆、检查相交、更新画布等功能。
摘要由CSDN通过智能技术生成

要求:1利用数组记录多个圆;

           2控制圆圈的最大和最小半径,且圆和圆之间不相交;

           3按空格键实现风格变化,分别是黄色,随机色,随机叠加色,随机色圈。

代码:

          


#include<stdio.h>
#include<graphics.h>
#include<conio.h>
#include<math.h>
#include<time.h>
float Dist2point(float x1, float y1, float x2, float y2) {
	float result1;
	result1 = sqrt((x1 - x2) * (x1 - x2) + (y1 - y2) * (y1 - y2));
	return result1;
}

int isTwociclesIntersect(float x1, float y1, float x2, float y2, float r1, float r2) {
	if (Dist2point(x1, y1, x2, y2) < r1 + r2) {
		return 1;
	}
	return 0;
}
void DrawCircles1(float x1, float y1, float r) {
	setlinecolor(RGB(0, 0, 0));
	setfillcolor(RGB(255, 255, 0));
	fillcircle(x1, y1, r);
}
void DrawCircles2(float x, float y, float r) {
	srand((INT)time(0));
	float h = rand() % 360;
	COLORREF COLOR = HSVtoRGB(h, 0.6, 0.7);
	setfillcolor(COLOR);
	fillcircle(x, y, r);
}
void DrawCircles3(float x, float y, float r) {
	srand((INT)time(0));
	while (r > 0) {
		float h = rand() % 360;
		COLORREF COLOR = HSVtoRGB(h, 0.6, 0.7);
		setfillcolor(COLOR);
		fillcircle(x, y, r);
		r -= 5;
	}
}
void DrawCircles4(float x1, float y1, float r) {
	srand((INT)time(0));
	while (r> 0) {
		float h = rand() % 360;
		COLORREF COLOR = HSVtoRGB(h, 0.6, 0.7);
		setlinecolor(COLOR);
		circle(x1,y1,r);
		r -= 5;
	}
}

// 运行程序: Ctrl + F5 或调试 >“开始执行(不调试)”菜单
// 调试程序: F5 或调试 >“开始调试”菜单

int main()
{
	int width = 600, height = 800;
	initgraph(width, height);
	setbkcolor(RGB(255, 255, 255));
	cleardevice();
	srand(time(0));
	int xarray[1000], yarray[1000], rarray[1000];
	int min = 8, max = 50;
	float x, y, r;
	int circlenum = 0;
	int i, j, drawMode = 2;
	int isNewcircleok = 0;

	while (circlenum < 1000) {
		isNewcircleok = 0;
		while (isNewcircleok == 0) {
			if (kbhit()) {
				char input = _getch();
				if (input == ' ') {
					circlenum = 0;
					cleardevice();
					drawMode += 1;
				}
				if (drawMode > 4) {
					drawMode = 1;
				}
			}
			x = rand () % width;
			y = rand() % height;
			r = min;
			for ( i = 0; i < circlenum; i++) {
				if(isTwociclesIntersect(xarray[i], yarray[i], x, y, rarray[i], r))
				break;
			}
			if (circlenum == i) {
				isNewcircleok = 1;
			}
		}
		isNewcircleok = 0;
		while (isNewcircleok == 0 && r < max) {
			r++;
			for ( j= 0; j<circlenum;j++) {
				if (isTwociclesIntersect(xarray[j],yarray[j], x, y, rarray[j], r)) {
					isNewcircleok = 1;
					break;
				}
			}
		}
		xarray[i] = x;
		yarray[i] = y;
		rarray[i] = r;
		circlenum++;
		if (drawMode == 1)
			DrawCircles1(x, y, r);
		if (drawMode == 2)
			DrawCircles2(x,y, r);
		if (drawMode == 3)
			DrawCircles3(x, y, r);
		if (drawMode == 4)
			DrawCircles4(x, y, r);
		Sleep(10);
	}
	_getch();
	closegraph();
	return 0;
}

 简化mian(),写更多分函数,效果一样,用模块的思想去实现:

空模块:

// Charper6.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。
//
#include"graphics.h"
#include <iostream>
#include "conio.h"
void initEasyxWindows(int width, int heigh);//初始化EasyX窗口
void drawCircleMode1(float x, float y, float r);
void drawCircleMode2(float x, float y, float r);
void drawCircleMode3(float x, float y, float r);
void drawCircleMode4(float x, float y, float r);
bool isTwoCirclesIntersect(float x1, float y1, float r1, float x2, float y2, float r2);//两圆是否相交
float countTwoPointDis(float x1, float y1, float x2, float y2);//两点间的距离
void updateWindows(int width, int heigh);//更新绘画圆的操作
int  creatBigCircle(int rmax, int circleNum, float x, float y, int xArray[100], int yArray[100], int rArray[100]);//创建最大的不相交圆
int  creatRandCircle(int circleNum, float x, float y, int r, int xArray[100], int yArray[100], int rArray[100]);//随机创建不相交圆

int main()
{
    int width = 600; // 窗口宽度
    int height = 600; // 窗口高度
    initEasyxWindows(width, height);
    updateWindows(width, height);
    _getch();	// 等待按键输入
    closegraph();  // 关闭窗口
    return 0;
    //std::cout << "Hello World!\n";
}
void initEasyxWindows(int width, int height)
{
    
}

/// <summary>
/// 随机创建一个圆,如果与已有的圆都不相交,返回1,否则返回0
/// </summary>
/// <param name="circleNum">已有的圆数量</param>
/// <param name="x">圆心的X坐标</param>
/// <param name="y">圆心的Y坐标</param>
/// <param name="r"></param>

/// <param name="xArray">已有的圆的X数组</param>
/// <param name="yArray">已有的圆的Y数组</param>
/// <param name="rArray">已有的圆的R数组</param>
/// <returns></returns>
int creatRandCircle(int circleNum, float x, float y, int r, int xArray[100], int yArray[100], int rArray[100])
{
   
    return  0;
}
int  creatBigCircle(int rmax, int circleNum, float x, float y, int xArray[100], int yArray[100], int rArray[100])
{
    return  0;
}
void updateWindows(int width, int height)
{
   

}
void drawCircleMode1(float x, float y, float r)
{
  
}
void drawCircleMode2(float x, float y, float r)
{
 
}
void drawCircleMode3(float x, float y, float r)
{
   
}
void drawCircleMode4(float x, float y, float r)
{
   

}
float countTwoPointDis(float x1, float y1, float x2, float y2)
{
  
 
    return 0;
}
bool isTwoCirclesIntersect(float x1, float y1, float r1, float x2, float y2, float r2)
{

    return 0;
}

 填充后:

// Charper6.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。
//
#include"graphics.h"
#include <iostream>
#include "conio.h"
void initEasyxWindows(int width, int heigh);//初始化EasyX窗口
void drawCircleMode1(float x, float y, float r);
void drawCircleMode2(float x, float y, float r);
void drawCircleMode3(float x, float y, float r);
void drawCircleMode4(float x, float y, float r);
bool isTwoCirclesIntersect(float x1, float y1, float r1, float x2, float y2, float r2);//两圆是否相交
float countTwoPointDis(float x1, float y1, float x2, float y2);//两点间的距离
void updateWindows(int width, int heigh);//更新绘画圆的操作
int  creatBigCircle(int rmax, int circleNum, float x, float y, int xArray[100], int yArray[100], int rArray[100]);//创建最大的不相交圆
int  creatRandCircle(int circleNum, float x, float y, int r, int xArray[100], int yArray[100], int rArray[100]);//随机创建不相交圆
int circleNum;
int main()
{
    int width = 600; // 窗口宽度
    int height = 600; // 窗口高度
    initEasyxWindows(width, height);
    updateWindows(width, height);
    _getch();	// 等待按键输入
    closegraph();  // 关闭窗口
    return 0;
    //std::cout << "Hello World!\n";
}
void initEasyxWindows(int width, int height)
{
    initgraph(width, height); // 新开一个窗口
    setbkcolor(RGB(255, 255, 255)); // 背景颜色为白色
    cleardevice(); // 以背景颜色清空背景
}

/// <summary>
/// 随机创建一个圆,如果与已有的圆都不相交,返回1,否则返回0
/// </summary>
/// <param name="circleNum">已有的圆数量</param>
/// <param name="x">圆心的X坐标</param>
/// <param name="y">圆心的Y坐标</param>
/// <param name="r"></param>

/// <param name="xArray">已有的圆的X数组</param>
/// <param name="yArray">已有的圆的Y数组</param>
/// <param name="rArray">已有的圆的R数组</param>
/// <returns></returns>
int aj(int drawMode1) {
    int  drawMode= drawMode1;
    if (_kbhit()) // 当按键时
    {
        char input = _getch(); // 获得用户按键
        if (input == ' ') // 空格键
        {
            circleNum = 0; // 圆的个数为0,相当于画面清除所有已有的圆圈
            cleardevice(); // 清屏
            drawMode = drawMode + 1; // 进行下一种绘图模式
            if (drawMode > 4) // 如果大于4,重新回到第1种绘图模式
                drawMode = 1;
        }
    }
    return drawMode;
 }
int creatRandCircle(int circleNum, float x, float y, int r, int xArray[100], int yArray[100], int rArray[100])
{
    
    int i;
    for (i = 0; i < circleNum; i++) {// 对已有圆遍历
        if (isTwoCirclesIntersect(xArray[i], yArray[i], rArray[i], x, y, r))
            break; // 如果已有圆和新圆相交,跳出循环,此时i<circleNum
    }
    if (i == circleNum) { // 如果上面for语句都不跳出,说明i等于circleNum
        return  1;
    }
    else
        return 0;
}
int  creatBigCircle(int rmax, int circleNum, float x, float y, int xArray[100], int yArray[100], int rArray[100])
{
    int r = 8;
    int j = 0;
    int isNewCircleOK = 0;
    while (isNewCircleOK == 0 && r < rmax) // 当不ok,并且新圆的半径小于最大半径时
    {
        r++; // 让半径+1
        for (j = 0; j < circleNum; j++) // 对所有旧圆遍历
        {
            if (isTwoCirclesIntersect(xArray[j], yArray[j], rArray[j], x, y, r))
            {
                isNewCircleOK = 1; // 一旦和一个旧圆相交,这时新圆Ok
                break; // 因为新圆半径已经达到最大的情况,这时跳出循环
            }
        }
    }

    return  r;
}
void updateWindows(int width, int height)
{
    int xArray[1000]; // 数组存储所有圆心的x坐标
    int yArray[1000]; // 数组存储所有圆心的y坐标 
    int rArray[1000]; // 数组存储所有圆的半径 
    int rmin = 8; // 圆的最小半径
    int rmax = 50; // 圆的最大半径
     circleNum = 0; // 生成的圆的个数
  //  float x, y, r; // 新增圆的圆心坐标、半径
    int isNewCircleOK = 0; // 用于判断新生成的圆是否可以了
    int i, j;
    int drawMode = 3; // 用于设定4种不同的绘制模式,开始设为3
    float x = 0;
    float y = 0;
    float r = 0;
    // int drawMode = 3;
    r = rmin; // 新圆的半径开始设为最小半径
    while (circleNum < 1000)
    {
        isNewCircleOK = 0;
        while (isNewCircleOK == 0)
        {
            x = rand() % width; // 新圆的圆心x坐标
            y = rand() % height; // 新圆的圆心y坐标
            
            isNewCircleOK = creatRandCircle(circleNum, x, y, rmin, xArray, yArray, rArray);

        }
        drawMode = aj(drawMode);
        isNewCircleOK = 0;
        r = creatBigCircle(rmax, circleNum, x, y, xArray, yArray, rArray);
        isNewCircleOK = 1;
        xArray[circleNum] = x; // 把新圆的圆心坐标添加到数组中
        yArray[circleNum] = y; //
        rArray[circleNum] = r; // 把新圆的半径添加到数组中
        circleNum++; // 圆的个数+1

        // 根据不同绘图模式进行绘制		
        if (drawMode == 1)
            drawCircleMode1(x, y, r);
        if (drawMode == 2)
            drawCircleMode2(x, y, r);
        if (drawMode == 3)
            drawCircleMode3(x, y, r);
        if (drawMode == 4)
            drawCircleMode4(x, y, r);

        Sleep(10); // 暂停若干毫秒
    }

}
void drawCircleMode1(float x, float y, float r)
{
    setlinecolor(RGB(0, 0, 0));
    setfillcolor(RGB(255, 255, 0));
    fillcircle(x, y, r);
}
void drawCircleMode2(float x, float y, float r)
{
    float h = rand() % 360;
    COLORREF  color = HSVtoRGB(h, 0.6, 0.8);
    setlinecolor(RGB(255, 255, 255));
    setfillcolor(color);
    fillcircle(x, y, r);
}
void drawCircleMode3(float x, float y, float r)
{
    while (r > 0)
    {
        float h = rand() % 360;
        COLORREF  color = HSVtoRGB(h, 0.6, 0.8);
        setlinecolor(RGB(255, 255, 255));
        setfillcolor(color);
        fillcircle(x, y, r);
        r = r - 5;
    }
}
void drawCircleMode4(float x, float y, float r)
{
    while (r > 0)
    {
        float h = rand() % 360;
        COLORREF  color = HSVtoRGB(h, 0.9, 0.8);
        setlinecolor(color);
        circle(x, y, r);
        r = r - 5;
    }

}
float countTwoPointDis(float x1, float y1, float x2, float y2)
{
    float result;
    result = sqrt((x1 - x2) * (x1 - x2) + (y1 - y2) * (y1 - y2));
    return result;
}
bool isTwoCirclesIntersect(float x1, float y1, float r1, float x2, float y2, float r2)
{
    if (countTwoPointDis(x1, y1, x2, y2) < r1 + r2)
        return 1;
    return 0;
}

运行结果:

风格1:

 

 风格2:

 风格3:

 风格4:

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

学徒在修行

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值