文字雨的简单单向链表实现

简介

简单链表动态存储和管理节点的示例文字雨
用于理解单向链表类的基本构建

结点内容

每个节点包含一个字符串、一个颜色值以及在窗口中的x和y坐标

主要功能

  1. 链表动态生成文字节点,每个节点:
    数据为随机选择的字符串(如“happy”、“new”、“year”)
    随机颜色和随机x坐标,初始y坐标为0
    文字节点逐渐向下移动,直到填满整个图形窗口
  2. 当画布窗口被填满后,清空链表和画布,再重新生成链表
  3. 对链表操作的基本功能:
    如判断链表是否为空、在链表末尾添加节点、遍历链表以及清空链表

说明

需要安装EasyX库,官网 https://easyx.cn/easyx
EasyX Graphics Library 是针对 Visual C++ 的免费绘图库,支持 VC6.0 ~ VC2022,简单易用
“下载 -> 安装 -> 使用”,这个库的安装本质是把头文件h和库文件lib拷贝到系统目录下,所以不复杂也不需要配置,全过程一分钟
EasyX官方作品库 https://codebus.cn ,有很多用该库完成的游戏、画图类的小作品,适于学习。例如橘子钟表、樱花树、烟花、玫瑰花、跳动的爱心、贪吃蛇、俄罗斯方块、数字游戏、数独、棋类游戏等

源码

/* 原创,转载请注明出处*/
#define _CRT_SECURE_NO_WARNINGS //回避VS需要strcpy_s等更安全要求
#include<iostream>
#include<ctime>
#include<string>     
#include<graphics.h> //EasyX
using namespace std;

struct Data
{
	int x, y;
	string ch;
	int color;
	Data():x(0), y(0), ch(""), color(0) {} 
	Data(int nx, int ny, string nch, int ncolor) : x(nx), y(ny), ch(nch), color(ncolor) {} 
};
struct Node
{
	Data data;
	Node* pnext;
	Node() : data(), pnext(nullptr) {} 
	Node(const Data& ndata, Node* npnext) : data(ndata), pnext(npnext) {}
};
class MyList
{
public:
	MyList() :head(nullptr), tail(nullptr), size(0) {} //初始化一个空链表
	~MyList() { Clear(); }
	bool IsEmpty();//判断链表是否为空
	void Append(Node* pNode);//链表末尾插入一个结点
	void Travel(void(*dosth)(Node* pNode));//遍历链表,修改或访问
	void Clear();
	bool LastNodeYLessOrEqualTo(int value) //检查末尾节点的 y 值
	{
		if (tail == nullptr) 
			return false;

		return tail->data.y <= value;
	}
private:
	Node* head;
	Node* tail;
	int size;
};

//判断链表是否为空
/*为空返回true,反之返回false*/
bool MyList::IsEmpty()
{ return size==0;}
//链表末尾插入一个结点
void MyList::Append(Node* pNode)
{
	if (size == 0)
	{		head = tail = pNode;	}
	else
	{	tail->pnext = pNode;
		tail = pNode;
	}
	size++;
}
void MyList::Clear()
{
	while (!IsEmpty())
	{
		Node* temp = head;
		head = head->pnext;
		delete temp;
		size--;
	}
	head = tail = nullptr;
}
//遍历链表,修改或访问
void MyList::Travel(void(*dosth)(Node* pNode))
{
	Node* ptemp = head;
	while (ptemp)
	{
		dosth(ptemp);
		ptemp = ptemp->pnext;
	}
}
void ShowNode(Node* pNode)
{
	settextcolor(pNode->data.color);
	moveto(pNode->data.x, pNode->data.y);
	wstring wS(pNode->data.ch.begin(), pNode->data.ch.end());
	outtext(wS.c_str());
}
void ModifyY(Node* pNode)
{
	pNode->data.y += rand() % 10;
}
int main()
{
	initgraph(1800, 800);
	srand((unsigned)time(NULL));

	MyList list1;
	Node* pnode = nullptr;

	string words[3] = { "happy","new","year"};//单词数组

	clock_t start_time = clock();  // 获取开始时间
	const clock_t delay = CLOCKS_PER_SEC * 5;  // 设置5秒延时


	while (true)
	{//随机生成结点,填满画布
		do
		{
			pnode = new Node;
			pnode->data.x = rand() % 1800;
			pnode->data.y = 0;
		
			int wordIndex = rand() % 3;
			pnode->data.ch = words[wordIndex];

			pnode->data.color = RGB(rand() % 256, rand() % 256, rand() % 256);
			pnode->pnext = nullptr;
			list1.Append(pnode);
			list1.Travel(ShowNode);
			list1.Travel(ModifyY);
			

			//清空画布
			clock_t current_time = clock();  // 获取当前时间
			if (current_time - start_time >= delay) {
				cleardevice();  // 每5秒清除一次画布
				start_time = current_time;  // 重置开始时间
			}
			Sleep(20);

		} while (list1.LastNodeYLessOrEqualTo(800));		

		//清除链表
		list1.Clear();		
	}
		// 关闭图形界面
		closegraph();
	return 0;
}

运行结果是动态在屏幕顶端出现文字结点,直到屏幕最底端
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

dotdotyy

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

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

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

打赏作者

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

抵扣说明:

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

余额充值