WPF 做一个超级简单的 1024 数字接龙游戏
这是一个我给自己做着玩的游戏,没有什么复杂的界面,就一些简单的逻辑
游戏的规则十分简单,那就是有多个列表。程序会给出一个数字,玩家决定数字放在哪个列表里面。如果放入列表里面的数字和列表里面最后一个数字相同,那两个数字将会叠加进行合并,合并两个 1024 将会自动清理掉整个列表
如下图,有 5 个列表。最右边有一个数字。此时点击列表下方的 "点击" 按钮,即表示将最右边的数字放在这一列表中
如下图,就是点击了首个列表的“点击”按钮,将上图的 1024 数字放在首个列表里
如下图,首个列表里面的最后一个是 2 的数字,最右边的数字也是 2 的数字,可以将其进行合并
如下图,合并之后,首个列表的 2 将会和最右边的数字 2 合并为 4 作为最后一个数字
规则介绍完了,接下来咱来开始开发咯。如果只是想玩这个简单的游戏的伙伴,可以快速到本文末尾,找到本文的所有代码的下载方法
如上面的界面图,可以看到有多个列表,那不如每个列表就一个 UserControl 用户控件好了。这里没有什么最佳实践,这么简单的应用,想怎么写就怎么写就好了
我这里都不想好好命名,直接就用 Whitman 工具随机一个名为 CecaqemdarYefarqukeafai 的控件名好了
在 CecaqemdarYefarqukeafai.xaml.cs 里面存放一个 ObservableCollection<int>
集合,用来表示界面上每个列表里面的数据,代码如下
public ObservableCollection<int> Collection { get; } = new ObservableCollection<int>();
在 CecaqemdarYefarqukeafai.xaml 的界面写一个 ListView 进行绑定这个 Collection 属性,代码如下
<ListView ItemsSource="{Binding ElementName=Root,Path=Collection}">
<ListView.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding .}"></TextBlock>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
这里我写的绑定是 ElementName=Root
的方式,这是我的习惯使用方法。对于简单没有 MVVM 的模式下,可以将控件自身当成自己的绑定源,这样在控件后台代码编写的属性就可以很方便进行绑定
具体的实现方法就是将用户控件自身加上 x:Name="Root"
属性,加上之后的用户控件的代码大概如下
<UserControl x:Class="BawjadurbaWurahuwa.CecaqemdarYefarqukeafai"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:local="clr-namespace:BawjadurbaWurahuwa"
mc:Ignorable="d"
x:Name="Root"
d:DesignHeight="450" d:DesignWidth="800">
<Grid>
... 忽略其他代码
<ListView ItemsSource="{Binding ElementName=Root,Path=Collection}">
<ListView.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding .}"></TextBlock>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
... 忽略其他代码
</Grid>
</UserControl>
如上图界面,可以看到每个列表下方都有一个点击按钮。那就继续修改 CecaqemdarYefarqukeafai.xaml 界面,加上一个按钮,代码如下
<Button Margin="10,10,10,10" HorizontalAlignment="Center" Click="Button_OnClick">点击</Button>
加上按钮需要稍微修改一下布局,修改一下 Grid 加上两行,代码如下
<Grid.RowDefinitions>
<RowDefinition></RowDefinition>
<RowDefinition Height="Auto"></RowDefinition>
</Grid.RowDefinitions>
以上就配置了列表的地方有多少空间使用多少空间,配置下面一行给按钮使用,按钮需要多少空间再给多少空间
修改之后的 CecaqemdarYefarqukeafai.xaml 的全部代码如下
<UserControl x:Class="BawjadurbaWurahuwa.CecaqemdarYefarqukeafai"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:local="clr-namespace:BawjadurbaWurahuwa"
mc:Ignorable="d"
x:Name="Root"
d:DesignHeight="450" d:DesignWidth="800">
<Grid>
<Grid.RowDefinitions>
<RowDefinition></RowDefinition>
<RowDefinition Height="Auto"></RowDefinition>
</Grid.RowDefinitions>
<ListView ItemsSource="{Binding ElementName=Root,Path=Collection}">
<ListView.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding .}"></TextBlock>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
<Button Grid.Row="1" Margin="10,10,10,10" HorizontalAlignment="Center" Click="Button_OnClick">点击</Button>
</Grid>
</UserControl>
可以看到实现非常简单,即使不使用用户控件也是可以的
这里的点击按钮需要将事件给到外面订阅,编辑后台 CecaqemdarYefarqukeafai.xaml.cs 代码,实现按钮点击逻辑,代码如下
public event EventHandler<CecaqemdarYefarqukeafai>? Click;
private void Button_OnClick(object sender, RoutedEventArgs e)
{
Click?.Invoke(this, this);
}
如此即可在点击按钮的时候,触发 Click 事件给到外面订阅
修改之后的 CecaqemdarYefarqukeafai.xaml.cs 的全部代码如下
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
namespace BawjadurbaWurahuwa;
/// <summary>
/// CecaqemdarYefarqukeafai.xaml 的交互逻辑
/// </summary>
public partial class CecaqemdarYefarqukeafai : UserControl
{
public CecaqemdarYefarqukeafai()
{
InitializeComponent();
}
public ObservableCollection<int> Collection { get; } = new ObservableCollection<int>();
public event EventHandler<CecaqemdarYefarqukeafai>? Click;
private void Button_OnClick(object sender, RoutedEventArgs e)
{
Click?.Invoke(this, this);
}
}
回到主界面
主界面需要显示 5 列,那就直接写 5 个 CecaqemdarYefarqukeafai 控件好了。如果数量更多的话,那可以试试写一个 ListView 之类的控件
如上图,整个主界面可以分为 6 列,其中前面 5 列是 CecaqemdarYefarqukeafai 控件,最后一列是一个文本,用来说明下一个数字
实现的 MainWindow.xaml 代码如下
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition></ColumnDefinition>
<ColumnDefinition></ColumnDefinition>
<ColumnDefinition></ColumnDefinition>
<ColumnDefinition></ColumnDefinition>
<ColumnDefinition></ColumnDefinition>
<ColumnDefinition></ColumnDefinition>
</Grid.ColumnDefinitions>
<local:CecaqemdarYefarqukeafai Click="CecaqemdarYefarqukeafai_OnClick"/>
<local:CecaqemdarYefarqukeafai Grid.Column="1" Click="CecaqemdarYefarqukeafai_OnClick"/>
<local:CecaqemdarYefarqukeafai Grid.Column="2" Click="CecaqemdarYefarqukeafai_OnClick"/>
<local:CecaqemdarYefarqukeafai Grid.Column="3" Click="CecaqemdarYefarqukeafai_OnClick"/>
<local:CecaqemdarYefarqukeafai Grid.Column="4" Click="CecaqemdarYefarqukeafai_OnClick"/>
<TextBlock x:Name="CurrentTextBlock" Grid.Column="5" HorizontalAlignment="Center"></TextBlock>
</Grid>
也许有伙伴开始好奇了,为什么上面代码里面的 5 个 CecaqemdarYefarqukeafai 的 Click 事件都是相同的方法,那方法内是如何区分点击的是哪个列表的?答案是不需要区分,在 CecaqemdarYefarqukeafai 的定义事件的代码里面,就将列表控件自身给传递进入了,如下面代码
public partial class CecaqemdarYefarqukeafai : UserControl
{
... // 忽略其他代码
public event EventHandler<CecaqemdarYefarqukeafai>? Click;
... // 忽略其他代码
}
于是在 MainWindow.xaml.cs 后台代码实现方法里面,就可以通过参数了解到当前点击按钮属于哪个用户控件了
private void CecaqemdarYefarqukeafai_OnClick(object? sender, CecaqemdarYefarqukeafai e)
{
... // 忽略其他代码
}
为了方便拿到和表示当前最右侧显示的当前的数字,咱使用的是建立一个数组和一个索引的方式表示。如此即可实现后续进行随机给一个数字的方法,也可以让给出的数字一定在数组内。定义在 MainWindow.xaml.cs 的字段代码如下
private int _index;
private readonly int[] _list = new int[] { 1024, 512, 256, 128, 64, 32, 16, 8, 4, 2 };
那是否可以省略这个数组,没错,因为这些都是 2 的倍数,想要省略也是可以的。省略了这个数组,那就每次自己计算就好了。可不要觉得每次都重新计算速度很慢,对于现代 CPU 来说,你接近测试不出来这两者的性能差异。但总之这个数组也很小,占用内存基本可以忽略,就随大家想用什么就用什么咯
为什么有时候数组很小我也会关注,有时候数组即使不小我也不会关注。这其实和业务有关系,在本文例子里面的这个数组只有一次定义,且全局只有一个,那这个数组就这点空间,自然就可以忽略其占用内存了。但如果这个数组是需要每次都创建的,那这时候我可能会稍微考虑一下。如果这个数组是每次都需要创建的,且创建之后很难释放,那才会考虑一下
回到点击事件里面,通过索引和数组即可拿到当前最右侧的数字,代码如下
private void CecaqemdarYefarqukeafai_OnClick(object? sender, CecaqemdarYefarqukeafai e)
{
var number = _list[_index];
... // 忽略其他代码
}
将此数字加入到 CecaqemdarYefarqukeafai 的集合里面,代码如下
private void CecaqemdarYefarqukeafai_OnClick(object? sender, CecaqemdarYefarqukeafai e)
{
var number = _list[_index];
e.Collection.Add(number);
... // 忽略其他代码
}
如此就完成了点击按钮就将数字加到所点击的一列的基础逻辑了
根据游戏规则,如果列表里面最后相邻的两个数字是相同的,则进行合并。接下来再写一个方法,这个方法用于合并集合的数字,代码如下
private static void Clean(ObservableCollection<int> collection)
{
while (collection.Count > 1)
{
var n1 = collection[^1];
var n2 = collection[^2];
if (n1 == n2)
{
collection.RemoveAt(collection.Count - 1);
collection.RemoveAt(collection.Count - 1);
collection.Add(n1 + n2);
}
else
{
break;
}
}
if (collection[^1] == 1024 * 2)
{
collection.Clear();
}
}
为了这个方法需要一个循环?这是因为如果最后的数字刚好是 4、2、2 的话,那就可以先对 2 和 2 进行合并,合并完成拿到的 4 再和 4 进行合并
合并的方法就是移除这两个数字,再添加一个新的更大的数字
为什么移除的时候都是使用 collection.RemoveAt(collection.Count - 1);
代码移除,为什么两次移除都是相同的代码?这是因为首先集合列表数组都是从 0 开始的,想象一下,一个只有元素的集合,想要移除最后一个元素,那下标是多少,没错就是 0 作为下标。因此 collection.Count - 1
表示的是最后一个元素。那为什么调用两次?这是因为第一次调用的时候,最后一个元素就被移除了。那原本倒数的第二个元素现在就成为倒数第一个元素了,自然再次移除最后一个元素就是移除掉原先的倒数第二个元素。举个例子,假如你每次都是全班倒数第二,某天全班倒数第一退学了,那你是不是就成为全班倒数第一了
如何全部合并之后,最后一个数字是两倍的 1024 则将列表清空。嗯,这里的话,只去掉当前这个数也可以,这个看大家的规则
完成了 Clean 方法之后,尝试调用一下,代码如下
private void CecaqemdarYefarqukeafai_OnClick(object? sender, CecaqemdarYefarqukeafai e)
{
var number = _list[_index];
e.Collection.Add(number);
Clean(e.Collection);
... // 忽略其他代码
}
如此就完成了将数字加入到所点击的列表里面,且如果数字和列表最后一个数字相同则进行合并
根据游戏的规则,此时咱就需要再生成最右侧的新的数字了。如上文可以知道,最右侧的数字是使用数组和索引表示的,那就是随机生成一个在数组范围内的索引就可以了。既可以降低难度,按照顺序生成索引,如下面代码
private void CecaqemdarYefarqukeafai_OnClick(object? sender, CecaqemdarYefarqukeafai e)
{
... // 忽略其他代码
_index++;
if (_index == _list.Length)
{
_index = 0;
}
... // 忽略其他代码
}
也可以使用随机数生成,代码如下
private void CecaqemdarYefarqukeafai_OnClick(object? sender, CecaqemdarYefarqukeafai e)
{
... // 忽略其他代码
_index = Random.Shared.Next(_list.Length);
... // 忽略其他代码
}
生成完成之后,将结果设置到界面的 CurrentTextBlock 控件里面,如此即可在界面显示
private void CecaqemdarYefarqukeafai_OnClick(object? sender, CecaqemdarYefarqukeafai e)
{
... // 忽略其他代码
CurrentTextBlock.Text = $"第 {_count} 次\r\n下一个 {_list[_index]}";
}
上述的 _count
字段这时一个类似游戏分数的作用,表示的是当前是第多少次,实现代码如下
private void CecaqemdarYefarqukeafai_OnClick(object? sender, CecaqemdarYefarqukeafai e)
{
_count++;
... // 忽略其他代码
CurrentTextBlock.Text = $"第 {_count} 次\r\n下一个 {_list[_index]}";
}
private int _count;
最后别忘了修改一下 MainWindow 构造函数,在其初始化时给最右侧一个数字,代码如下
public MainWindow()
{
InitializeComponent();
CurrentTextBlock.Text = _list[_index].ToString();
}
如此即可完成简单的实现逻辑,代码大概如下
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
CurrentTextBlock.Text = _list[_index].ToString();
}
private void CecaqemdarYefarqukeafai_OnClick(object? sender, CecaqemdarYefarqukeafai e)
{
_count++;
var number = _list[_index];
e.Collection.Add(number);
Clean(e.Collection);
_index++;
if (_index == _list.Length)
{
_index = 0;
}
CurrentTextBlock.Text = $"第 {_count} 次\r\n下一个 {_list[_index]}";
}
private static void Clean(ObservableCollection<int> collection)
{
while (collection.Count > 1)
{
var n1 = collection[^1];
var n2 = collection[^2];
if (n1 == n2)
{
collection.RemoveAt(collection.Count - 1);
collection.RemoveAt(collection.Count - 1);
collection.Add(n1 + n2);
}
else
{
break;
}
}
if (collection[^1] == 1024 * 2)
{
collection.Clear();
}
}
private int _index;
private int _count;
private readonly int[] _list = new int[] { 1024, 512, 256, 128, 64, 32, 16, 8, 4, 2 };
}
作为开发者,我玩着玩着就想着看程序自己玩,做成挂机游戏。于是再写点算法让程序自己玩好了,实现代码如下
public MainWindow()
{
InitializeComponent();
CurrentTextBlock.Text = _list[_index].ToString();
Loaded += MainWindow_Loaded;
}
private async void MainWindow_Loaded(object sender, RoutedEventArgs e)
{
while (Content is Grid grid)
{
var number = _list[_index];
var maxValue = 1024;
var cecaqemdarYefarqukeafai =
grid.Children.OfType<CecaqemdarYefarqukeafai>()
.FirstOrDefault(t => t.Collection.Count > 0 && t.Collection[^1] == number);
cecaqemdarYefarqukeafai ??= grid.Children.OfType<CecaqemdarYefarqukeafai>().Where(t => t.Collection.Count > 0 && t.Collection[^1] > number).MinBy(t => t.Collection[^1]);
cecaqemdarYefarqukeafai ??= grid.Children.OfType<CecaqemdarYefarqukeafai>()
.FirstOrDefault(t => t.Collection.Count == 0);
cecaqemdarYefarqukeafai ??= grid.Children.OfType<CecaqemdarYefarqukeafai>().MinBy(t =>
{
if (t.Collection.Count > 0)
{
var lastValue = t.Collection[^1];
if (lastValue > number)
{
return lastValue;
}
else
{
return maxValue;
}
}
return 0;
});
if (cecaqemdarYefarqukeafai is null)
{
continue;
}
cecaqemdarYefarqukeafai.Collection.Add(number);
Clean(cecaqemdarYefarqukeafai.Collection);
_index = Random.Shared.Next(_list.Length);
_count++;
CurrentTextBlock.Text = $"第 {_count} 次\r\n下一个 {_list[_index]}";
await Task.Delay(300);
}
}
相信以上的逻辑大家看看也能明白,这是我随意写的简单算法,核心只是决定将数字放在哪个列表而已
完成之后的代码如下
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
namespace BawjadurbaWurahuwa;
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
CurrentTextBlock.Text = _list[_index].ToString();
Loaded += MainWindow_Loaded;
}
private async void MainWindow_Loaded(object sender, RoutedEventArgs e)
{
while (Content is Grid grid)
{
var number = _list[_index];
var maxValue = 1024;
var cecaqemdarYefarqukeafai =
grid.Children.OfType<CecaqemdarYefarqukeafai>()
.FirstOrDefault(t => t.Collection.Count > 0 && t.Collection[^1] == number);
cecaqemdarYefarqukeafai ??= grid.Children.OfType<CecaqemdarYefarqukeafai>().Where(t => t.Collection.Count > 0 && t.Collection[^1] > number).MinBy(t => t.Collection[^1]);
cecaqemdarYefarqukeafai ??= grid.Children.OfType<CecaqemdarYefarqukeafai>()
.FirstOrDefault(t => t.Collection.Count == 0);
cecaqemdarYefarqukeafai ??= grid.Children.OfType<CecaqemdarYefarqukeafai>().MinBy(t =>
{
if (t.Collection.Count > 0)
{
var lastValue = t.Collection[^1];
if (lastValue > number)
{
return lastValue;
}
else
{
return maxValue;
}
}
return 0;
});
if (cecaqemdarYefarqukeafai is null)
{
continue;
}
cecaqemdarYefarqukeafai.Collection.Add(number);
Clean(cecaqemdarYefarqukeafai.Collection);
_index = Random.Shared.Next(_list.Length);
_count++;
CurrentTextBlock.Text = $"第 {_count} 次\r\n下一个 {_list[_index]}";
await Task.Delay(300);
}
}
private void CecaqemdarYefarqukeafai_OnClick(object? sender, CecaqemdarYefarqukeafai e)
{
_count++;
var number = _list[_index];
e.Collection.Add(number);
Clean(e.Collection);
_index++;
if (_index == _list.Length)
{
_index = 0;
}
CurrentTextBlock.Text = $"第 {_count} 次\r\n下一个 {_list[_index]}";
}
private static void Clean(ObservableCollection<int> collection)
{
while (collection.Count > 1)
{
var n1 = collection[^1];
var n2 = collection[^2];
if (n1 == n2)
{
collection.RemoveAt(collection.Count - 1);
collection.RemoveAt(collection.Count - 1);
collection.Add(n1 + n2);
}
else
{
break;
}
}
if (collection[^1] == 1024 * 2)
{
collection.Clear();
}
}
private int _index;
private int _count;
private readonly int[] _list = new int[] { 1024, 512, 256, 128, 64, 32, 16, 8, 4, 2 };
}
本文以上代码放在 github 和 gitee 上,可以使用如下命令行拉取代码
先创建一个空文件夹,接着使用命令行 cd 命令进入此空文件夹,在命令行里面输入以下代码,即可获取到本文的代码
git init
git remote add origin https://gitee.com/lindexi/lindexi_gd.git
git pull origin 243d50c0b94013e5beb782e384c98a7b6e3f629d
以上使用的是 gitee 的源,如果 gitee 不能访问,请替换为 github 的源。请在命令行继续输入以下代码,将 gitee 源换成 github 源进行拉取代码
git remote remove origin
git remote add origin https://github.com/lindexi/lindexi_gd.git
git pull origin 243d50c0b94013e5beb782e384c98a7b6e3f629d
获取代码之后,进入 WPFDemo/BawjadurbaWurahuwa 文件夹,即可获取到源代码
进入文件夹之后使用 VisualStudio 2022 或更高版本的 VisualStudio 打开 BawjadurbaWurahuwa.sln 文件,然后试试按下 F5 进行构建且运行即可开始玩游戏
WPF 做一个超级简单的 1024 数字接龙游戏的更多相关文章
- pygame学习笔记(6)——一个超级简单的游戏
转载请注明:@小五义 http://www.cnblogs.com/xiaowuyi 学了这么长时间的Pygame,一直想写个游戏实战一下.看起来很简单的游戏,写其来怎么这么难.最初想写个俄罗斯方块 ...
- vs2015制作一个超级简单的MVC项目
使用vs2015制作一个超级简单的MVC项目 本文链接:https://blog.csdn.net/qq_40919762/article/details/100705314 直奔主题一,创建一个 ...
- 尝试做一个.NET简单、高效、避免OOM的Excel工具
Github : https://github.com/shps951023/MiniExcel 简介 我尝试做一个.NET简单.高效.避免OOM的Excel工具 目前主流框架大多将资料全载入到记忆体 ...
- JavaScript,一个超级简单的方法判断浏览器的内核前缀
先说明,此处的方法是说超级简单的方法,不是指代码超级少,而是用非常简单的知识点,只要懂得怎么写JavaScript的行内样式就可以判断. 大家应该还记得JavaScript行内样式怎么写吧?(看来我是 ...
- ConstraintLayout+radioGroup做一个tab.简单好用。
主页tab是必须会有的,各种实现也很多.各有千秋.但目标都是简单.可控.今天用ConstraintLayout+radioGroup做一个tab.简单性可控性都还可以.本文目的把ConstraintL ...
- 一听就懂:用Python做一个超简单的小游戏
写它会用到 while 循环random 模块if 语句输入输出函数
- 一个超级简单的node.js爬虫(内附表情包)
之所以会想到要写爬虫,并不是出于什么高大上的理由,仅仅是为了下载个表情包而已-- 容我先推荐一下西乔出品的神秘的程序员表情包. 这套表情包着实是抵御产品.对付测试.嘲讽队友.恐吓前任的良品, 不过不知 ...
- 一个超级简单php的留言板
第一步:配置好测试环境:(详细略了) 第二部:新建一个数据库,命名为guestbook(名字可以随便改),可以直接在phpmyadmin里面操作,在数据库里面新建一张表‘content’,表里面有4个 ...
- 用WPF做关于MEF 简单学习记录
写在前面:下面学习所得多是从自http://www.cnblogs.com/comsokey/p/MEF1.html和http://www.cnblogs.com/yunfeifei/p/392266 ...
- 一个超级简单的HTML模板框架源代码以及使用示例
HTML模板框架源代码 var HtmlTemplate = (function () { function HtmlTemplate(htmlSource) { this.htmlSource = ...
随机推荐
- nginx部署使用history模式的vue项目详细配置【可多级目录】
介绍 本文是篇详细的介绍vue项目在history模式下发布时build,项目如何配置,nginx如何配置,才能正常的使用历史模式.或者在二级目录下,多级路径下也能正常使用历史模式. 本文的例子中假设 ...
- RT-Thead移植时缺少SystemCoreClockUpdate函数
一.问题 在移植 RT-Thead 时,需要获取mcu当前的 HCLK 时钟频率来设置滴答时钟,而我使用的库函数中刚好缺少SystemCoreClockUpdate函数. 我之前在RT-Thread移 ...
- C语言,实现数字谱到简谱的转换
C语言,实现数字谱到简谱的转换 前言:本文初编辑于2024年4月28日 CSDN:https://blog.csdn.net/rvdgdsva 博客园:https://www.cnblogs.com/ ...
- SQL函数详解SUM\COUNT\AVG......
朋友们,个人公众号:SQL数据库运维 移动端的学习分享,各种数据库基础知识,一起进步,共同学习,期待你的加入. 函数的类型 1.聚合函数:对一组值执行计算,并返回单个值,也被称为组函数.聚合函数经常与 ...
- console小知识
console.log(JSON.stringify(object,null,2));
- $KMP$学习记
<不浪漫罪名>--王杰 没有花 这刹那被破坏吗 无野火都会温暖吗 无烟花一起庆祝好吗 若爱恋 仿似戏剧那样假 如布景一切都美化 连相拥都参照主角吗 你说我未能定时 令你每天欢笑一次 我没说 ...
- 【漏洞复现】用友NC-Cloud PMCloudDriveProjectStateServlet接口存在JNDI注入漏洞
阅读须知 花果山的技术文章仅供参考,此文所提供的信息只为网络安全人员对自己所负责的网站.服务器等(包括但不限于)进行检测或维护参考,未经授权请勿利用文章中的技术资料对任何计算机系统进行入侵操作.利用此 ...
- nginx分流配置
user nginx; worker_processes 1; error_log /var/log/nginx/error.log warn; pid /var/run/nginx.pid; eve ...
- mysql忘记密码找回的方法
mysql忘记密码找回的方法: 在找回之前需要对 --skip-networking 参数进行了解 --skip-grant-tables: 关闭mysql验证模块 同时还需要关闭远程连接(避免他人连 ...
- ansible搭建
ansible配置步骤 1.创建用户 2.用户提权 3.用户免密 4.cp ansible配置文件 5.配置主机清单 6.修改ansible 用户路径下的配置文件 1.创建用户(都要做) [root@ ...