Skip to main content

TileSet

Struct TileSet 

Source
pub struct TileSet<EdgeData>
where EdgeData: Clone + PartialEq + Debug,
{ /* private fields */ }
Expand description

瓷砖集具体实现 - 包含所有固定方法和数据存储

Implementations§

Source§

impl<EdgeData> TileSet<EdgeData>
where EdgeData: Clone + PartialEq + Debug,

Source

pub fn new() -> Self

创建新的瓷砖集

Examples found in repository?
examples/orthogonal_2d_wfc.rs (line 121)
119    fn new() -> Self {
120        Self {
121            tiles: TileSet::new(),
122        }
123    }
More examples
Hide additional examples
examples/tile_system_demo.rs (line 28)
26    fn new() -> Self {
27        Self {
28            tiles: TileSet::new(),
29        }
30    }
31
32    fn get_all_tiles(&self) -> &[Tile<&'static str>] {
33        self.tiles.get_all_tiles()
34    }
35}
36
37impl TileSetVirtual<&'static str> for SimpleTileSet {
38    fn build_tile_set(&mut self) -> Result<(), GridError> {
39        // 构建基础瓷砖
40        self.tiles.clear();
41
42        // 添加全草地瓷砖
43        self.tiles
44            .add_tile(vec!["grass", "grass", "grass", "grass"], 50);
45
46        // 添加全水面瓷砖
47        self.tiles
48            .add_tile(vec!["water", "water", "water", "water"], 30);
49
50        // 添加边界瓷砖
51        self.tiles
52            .add_tile(vec!["grass", "water", "grass", "water"], 20);
53        self.tiles
54            .add_tile(vec!["water", "grass", "water", "grass"], 20);
55
56        println!("构建完成:添加了 {} 个瓷砖", self.tiles.get_tile_count());
57        Ok(())
58    }
59
60    fn judge_possibility(&self, neighbor_possibilities: &[Vec<TileId>], candidate: TileId) -> bool {
61        // 简单的兼容性检查:如果有邻居约束,检查候选瓷砖是否存在
62        if neighbor_possibilities.is_empty() {
63            return true;
64        }
65
66        // 检查候选瓷砖是否存在
67        self.tiles.get_tile(candidate).is_some()
68    }
69
70    fn get_tile(&self, tile_id: TileId) -> Option<&Tile<&'static str>> {
71        self.tiles.get_tile(tile_id)
72    }
73
74    fn get_tile_count(&self) -> usize {
75        self.tiles.get_tile_count()
76    }
77
78    fn get_all_tile_ids(&self) -> Vec<TileId> {
79        self.tiles.get_all_tile_ids()
80    }
81}
82
83// =============================================================================
84// 数字瓷砖集实现 - 数字边数据
85// =============================================================================
86
87/// 数字瓷砖集,使用整数作为边数据
88///
89/// 展示如何使用数字来表示边的类型,适合更复杂的约束计算。
90struct NumericTileSet {
91    tiles: TileSet<i32>,
92}
93
94impl NumericTileSet {
95    fn new() -> Self {
96        Self {
97            tiles: TileSet::new(),
98        }
99    }
100}
101
102impl TileSetVirtual<i32> for NumericTileSet {
103    fn build_tile_set(&mut self) -> Result<(), GridError> {
104        // 构建数值瓷砖
105        self.tiles.clear();
106
107        // 添加基础连接模式
108        self.tiles.add_tile(vec![1, 1, 1, 1], 40); // 全连接
109        self.tiles.add_tile(vec![0, 0, 0, 0], 30); // 全断开
110        self.tiles.add_tile(vec![1, 0, 1, 0], 20); // 上下连接
111        self.tiles.add_tile(vec![0, 1, 0, 1], 20); // 左右连接
112
113        println!("数值瓷砖集构建完成:{} 个瓷砖", self.tiles.get_tile_count());
114        Ok(())
115    }
116
117    fn judge_possibility(&self, neighbor_possibilities: &[Vec<TileId>], candidate: TileId) -> bool {
118        let Some(candidate_tile) = self.tiles.get_tile(candidate) else {
119            return false;
120        };
121
122        for (direction, neighbor_ids) in neighbor_possibilities.iter().enumerate() {
123            if neighbor_ids.is_empty() {
124                continue;
125            }
126
127            let is_compatible = neighbor_ids.iter().any(|&neighbor_id| {
128                if let Some(neighbor_tile) = self.tiles.get_tile(neighbor_id) {
129                    let opposite_direction = (direction + 2) % 4;
130                    if let (Some(&current_edge), Some(&neighbor_edge)) = (
131                        candidate_tile.get_edge(direction),
132                        neighbor_tile.get_edge(opposite_direction),
133                    ) {
134                        // 数字边需要完全匹配
135                        current_edge == neighbor_edge
136                    } else {
137                        false
138                    }
139                } else {
140                    false
141                }
142            });
143
144            if !is_compatible {
145                return false;
146            }
147        }
148
149        true
150    }
151
152    fn get_tile(&self, tile_id: TileId) -> Option<&Tile<i32>> {
153        self.tiles.get_tile(tile_id)
154    }
155
156    fn get_tile_count(&self) -> usize {
157        self.tiles.get_tile_count()
158    }
159
160    fn get_all_tile_ids(&self) -> Vec<TileId> {
161        self.tiles.get_all_tile_ids()
162    }
163}
164
165// =============================================================================
166// 主函数 - 演示所有瓷砖集
167// =============================================================================
168
169fn main() -> Result<(), Box<dyn std::error::Error>> {
170    println!("=== 瓷砖系统综合示例 ===\n");
171
172    // 1. 基础TileSet演示
173    println!("1. 基础TileSet使用:");
174    demonstrate_basic_tileset()?;
175
176    // 2. 简单瓷砖集演示
177    println!("\n2. 简单瓷砖集 (字符串边):");
178    demonstrate_simple_tileset()?;
179
180    // 3. 数字瓷砖集演示
181    println!("\n3. 数字瓷砖集 (整数边):");
182    demonstrate_numeric_tileset()?;
183
184    // 4. 约束判断演示
185    println!("\n4. 约束判断测试:");
186    demonstrate_constraint_checking()?;
187
188    println!("\n=== 示例完成 ===");
189    Ok(())
190}
191
192/// 演示基础TileSet的使用
193fn demonstrate_basic_tileset() -> Result<(), Box<dyn std::error::Error>> {
194    let mut tile_set = TileSet::new();
195
196    println!("   创建基础瓷砖集...");
197
198    // 添加一些基础瓷砖
199    let tile1 = tile_set.add_tile(vec!["A", "B", "C", "D"], 10);
200    let tile2 = tile_set.add_tile(vec!["B", "A", "D", "C"], 15);
201    let _tile3 = tile_set.add_tile(vec!["C", "D", "A", "B"], 5);
202
203    println!("   添加了 {} 个瓷砖", tile_set.get_tile_count());
204
205    // 展示瓷砖信息
206    for (i, tile) in tile_set.get_all_tiles().iter().enumerate() {
207        println!(
208            "   瓷砖 {}: ID={}, 权重={}, 边={:?}",
209            i, tile.id, tile.weight, tile.edges
210        );
211    }
212
213    // 测试瓷砖兼容性
214    if let (Some(t1), Some(t2)) = (tile_set.get_tile(tile1), tile_set.get_tile(tile2)) {
215        let compatible = t1.is_compatible_with(t2, 0); // 方向0
216        println!("   瓷砖0和瓷砖1在方向0兼容: {}", compatible);
217    }
218
219    Ok(())
220}
Source

pub fn add_tile(&mut self, edges: Vec<EdgeData>, weight: i32) -> TileId

添加瓷砖 - 对应C++的addTile方法

§⚠️ 重要:边数据顺序约束

传入的 edges 向量必须严格按照 neighbors() 返回顺序排列, 即:[北, 西, 南, 东] 的顺序。

§顺序约定的重要性

这个顺序约定确保了:

  1. 直接索引映射judge_possibility() 中可以直接通过索引访问对应方向的边数据
  2. 零成本抽象:无需运行时的方向转换
  3. 统一语义:网格系统和瓷砖系统使用相同的索引语义
  4. 高效兼容性检查:O(1) 时间复杂度的边数据访问
§索引到方向的映射
edges[0] -> 北方向的边数据 (对应 neighbors()[0])
edges[1] -> 西方向的边数据 (对应 neighbors()[1])  
edges[2] -> 南方向的边数据 (对应 neighbors()[2])
edges[3] -> 东方向的边数据 (对应 neighbors()[3])
§正确使用示例
use rlwfc::TileSet;

let mut tile_set = TileSet::new();

// ✅ 正确:按照 [北, 西, 南, 东] 顺序排列
tile_set.add_tile(vec![
    "forest",  // 北边:与北邻居连接的边
    "water",   // 西边:与西邻居连接的边
    "grass",   // 南边:与南邻居连接的边
    "stone",   // 东边:与东邻居连接的边
], 10);

// ❌ 错误:任意顺序会破坏方向对应关系
tile_set.add_tile(vec![
    "stone",   // 这样排列无法正确对应方向
    "grass",
    "water",
    "forest",
], 5);
§在兼容性判断中的应用

正确的边数据顺序使得兼容性判断变得高效:

fn judge_possibility(
    &self,
    neighbor_possibilities: &[Vec<TileId>],
    candidate: TileId
) -> bool {
    let Some(candidate_tile) = self.get_tile(candidate) else {
        return false;
    };
     
    for (direction_index, neighbor_tiles) in neighbor_possibilities.iter().enumerate() {
        // 🎯 直接获取候选瓷砖在该方向的边数据
        let candidate_edge = &candidate_tile.edges[direction_index];
         
        // 检查与该方向所有可能邻居的兼容性
        let is_compatible = neighbor_tiles.iter().any(|&neighbor_id| {
            if let Some(neighbor_tile) = self.get_tile(neighbor_id) {
                // 获取邻居瓷砖相对方向的边数据
                let opposite_index = match direction_index {
                    0 => 2,  // 北 ↔ 南
                    1 => 3,  // 西 ↔ 东
                    2 => 0,  // 南 ↔ 北  
                    3 => 1,  // 东 ↔ 西
                    _ => return false,
                };
                let neighbor_edge = &neighbor_tile.edges[opposite_index];
                 
                // 边兼容性检查(具体规则由应用定义)
                candidate_edge == neighbor_edge
            } else {
                false
            }
        });
         
        if !is_compatible {
            return false;
        }
    }
    true
}
§参数
  • edges - 边数据列表,必须按 [北, 西, 南, 东] 顺序排列
  • weight - 瓷砖权重,影响在WFC算法中被选择的概率
§返回值
  • 新创建瓷砖的ID,可用于后续的瓷砖引用和查询
§性能说明
  • 时间复杂度:O(1) - 直接向量追加
  • 空间复杂度:O(E) - E为边数据的大小
  • 瓷砖ID就是其在内部向量中的索引,查询效率为O(1)
Examples found in repository?
examples/tile_system_demo.rs (line 44)
38    fn build_tile_set(&mut self) -> Result<(), GridError> {
39        // 构建基础瓷砖
40        self.tiles.clear();
41
42        // 添加全草地瓷砖
43        self.tiles
44            .add_tile(vec!["grass", "grass", "grass", "grass"], 50);
45
46        // 添加全水面瓷砖
47        self.tiles
48            .add_tile(vec!["water", "water", "water", "water"], 30);
49
50        // 添加边界瓷砖
51        self.tiles
52            .add_tile(vec!["grass", "water", "grass", "water"], 20);
53        self.tiles
54            .add_tile(vec!["water", "grass", "water", "grass"], 20);
55
56        println!("构建完成:添加了 {} 个瓷砖", self.tiles.get_tile_count());
57        Ok(())
58    }
59
60    fn judge_possibility(&self, neighbor_possibilities: &[Vec<TileId>], candidate: TileId) -> bool {
61        // 简单的兼容性检查:如果有邻居约束,检查候选瓷砖是否存在
62        if neighbor_possibilities.is_empty() {
63            return true;
64        }
65
66        // 检查候选瓷砖是否存在
67        self.tiles.get_tile(candidate).is_some()
68    }
69
70    fn get_tile(&self, tile_id: TileId) -> Option<&Tile<&'static str>> {
71        self.tiles.get_tile(tile_id)
72    }
73
74    fn get_tile_count(&self) -> usize {
75        self.tiles.get_tile_count()
76    }
77
78    fn get_all_tile_ids(&self) -> Vec<TileId> {
79        self.tiles.get_all_tile_ids()
80    }
81}
82
83// =============================================================================
84// 数字瓷砖集实现 - 数字边数据
85// =============================================================================
86
87/// 数字瓷砖集,使用整数作为边数据
88///
89/// 展示如何使用数字来表示边的类型,适合更复杂的约束计算。
90struct NumericTileSet {
91    tiles: TileSet<i32>,
92}
93
94impl NumericTileSet {
95    fn new() -> Self {
96        Self {
97            tiles: TileSet::new(),
98        }
99    }
100}
101
102impl TileSetVirtual<i32> for NumericTileSet {
103    fn build_tile_set(&mut self) -> Result<(), GridError> {
104        // 构建数值瓷砖
105        self.tiles.clear();
106
107        // 添加基础连接模式
108        self.tiles.add_tile(vec![1, 1, 1, 1], 40); // 全连接
109        self.tiles.add_tile(vec![0, 0, 0, 0], 30); // 全断开
110        self.tiles.add_tile(vec![1, 0, 1, 0], 20); // 上下连接
111        self.tiles.add_tile(vec![0, 1, 0, 1], 20); // 左右连接
112
113        println!("数值瓷砖集构建完成:{} 个瓷砖", self.tiles.get_tile_count());
114        Ok(())
115    }
116
117    fn judge_possibility(&self, neighbor_possibilities: &[Vec<TileId>], candidate: TileId) -> bool {
118        let Some(candidate_tile) = self.tiles.get_tile(candidate) else {
119            return false;
120        };
121
122        for (direction, neighbor_ids) in neighbor_possibilities.iter().enumerate() {
123            if neighbor_ids.is_empty() {
124                continue;
125            }
126
127            let is_compatible = neighbor_ids.iter().any(|&neighbor_id| {
128                if let Some(neighbor_tile) = self.tiles.get_tile(neighbor_id) {
129                    let opposite_direction = (direction + 2) % 4;
130                    if let (Some(&current_edge), Some(&neighbor_edge)) = (
131                        candidate_tile.get_edge(direction),
132                        neighbor_tile.get_edge(opposite_direction),
133                    ) {
134                        // 数字边需要完全匹配
135                        current_edge == neighbor_edge
136                    } else {
137                        false
138                    }
139                } else {
140                    false
141                }
142            });
143
144            if !is_compatible {
145                return false;
146            }
147        }
148
149        true
150    }
151
152    fn get_tile(&self, tile_id: TileId) -> Option<&Tile<i32>> {
153        self.tiles.get_tile(tile_id)
154    }
155
156    fn get_tile_count(&self) -> usize {
157        self.tiles.get_tile_count()
158    }
159
160    fn get_all_tile_ids(&self) -> Vec<TileId> {
161        self.tiles.get_all_tile_ids()
162    }
163}
164
165// =============================================================================
166// 主函数 - 演示所有瓷砖集
167// =============================================================================
168
169fn main() -> Result<(), Box<dyn std::error::Error>> {
170    println!("=== 瓷砖系统综合示例 ===\n");
171
172    // 1. 基础TileSet演示
173    println!("1. 基础TileSet使用:");
174    demonstrate_basic_tileset()?;
175
176    // 2. 简单瓷砖集演示
177    println!("\n2. 简单瓷砖集 (字符串边):");
178    demonstrate_simple_tileset()?;
179
180    // 3. 数字瓷砖集演示
181    println!("\n3. 数字瓷砖集 (整数边):");
182    demonstrate_numeric_tileset()?;
183
184    // 4. 约束判断演示
185    println!("\n4. 约束判断测试:");
186    demonstrate_constraint_checking()?;
187
188    println!("\n=== 示例完成 ===");
189    Ok(())
190}
191
192/// 演示基础TileSet的使用
193fn demonstrate_basic_tileset() -> Result<(), Box<dyn std::error::Error>> {
194    let mut tile_set = TileSet::new();
195
196    println!("   创建基础瓷砖集...");
197
198    // 添加一些基础瓷砖
199    let tile1 = tile_set.add_tile(vec!["A", "B", "C", "D"], 10);
200    let tile2 = tile_set.add_tile(vec!["B", "A", "D", "C"], 15);
201    let _tile3 = tile_set.add_tile(vec!["C", "D", "A", "B"], 5);
202
203    println!("   添加了 {} 个瓷砖", tile_set.get_tile_count());
204
205    // 展示瓷砖信息
206    for (i, tile) in tile_set.get_all_tiles().iter().enumerate() {
207        println!(
208            "   瓷砖 {}: ID={}, 权重={}, 边={:?}",
209            i, tile.id, tile.weight, tile.edges
210        );
211    }
212
213    // 测试瓷砖兼容性
214    if let (Some(t1), Some(t2)) = (tile_set.get_tile(tile1), tile_set.get_tile(tile2)) {
215        let compatible = t1.is_compatible_with(t2, 0); // 方向0
216        println!("   瓷砖0和瓷砖1在方向0兼容: {}", compatible);
217    }
218
219    Ok(())
220}
More examples
Hide additional examples
examples/orthogonal_2d_wfc.rs (line 135)
128    fn build_tile_set(&mut self) -> Result<(), GridError> {
129        self.tiles.clear();
130
131        // 添加基础瓷砖,用数字表示连接类型
132        // 0 = 空白,1 = 路径
133
134        // 全空白瓷砖
135        self.tiles.add_tile(vec![0, 0, 0, 0], 1); // [北, 西, 南, 东]
136
137        // 直线路径瓷砖
138        self.tiles.add_tile(vec![1, 0, 1, 0], 1); // 垂直路径
139        self.tiles.add_tile(vec![0, 1, 0, 1], 1); // 水平路径
140
141        // 端点
142        // self.tiles.add_tile(vec![1, 0, 0, 0], 1);
143        // self.tiles.add_tile(vec![0, 1, 0, 0], 1);
144        // self.tiles.add_tile(vec![0, 0, 1, 0], 1);
145        // self.tiles.add_tile(vec![0, 0, 0, 1], 1);
146
147        // 转角路径瓷砖
148        // self.tiles.add_tile(vec![1, 1, 0, 0], 1);  // 左上角
149        // self.tiles.add_tile(vec![1, 0, 0, 1], 1);  // 右上角
150        // self.tiles.add_tile(vec![0, 1, 1, 0], 1);  // 左下角
151        // self.tiles.add_tile(vec![0, 0, 1, 1], 1);  // 右下角
152
153        // T型路径瓷砖
154        self.tiles.add_tile(vec![1, 1, 1, 0], 1); // 向右开口的T
155        self.tiles.add_tile(vec![1, 0, 1, 1], 1); // 向左开口的T
156        self.tiles.add_tile(vec![0, 1, 1, 1], 1); // 向上开口的T
157        self.tiles.add_tile(vec![1, 1, 0, 1], 1); // 向下开口的T
158
159        // 十字路口瓷砖
160        self.tiles.add_tile(vec![1, 1, 1, 1], 1); // 全连通
161
162        println!("瓷砖集构建完成:{} 种瓷砖", self.tiles.get_tile_count());
163        Ok(())
164    }
Source

pub fn get_all_tiles(&self) -> &[Tile<EdgeData>]

获取所有瓷砖 - 对应C++的getAllTiles()方法

Examples found in repository?
examples/tile_system_demo.rs (line 33)
32    fn get_all_tiles(&self) -> &[Tile<&'static str>] {
33        self.tiles.get_all_tiles()
34    }
35}
36
37impl TileSetVirtual<&'static str> for SimpleTileSet {
38    fn build_tile_set(&mut self) -> Result<(), GridError> {
39        // 构建基础瓷砖
40        self.tiles.clear();
41
42        // 添加全草地瓷砖
43        self.tiles
44            .add_tile(vec!["grass", "grass", "grass", "grass"], 50);
45
46        // 添加全水面瓷砖
47        self.tiles
48            .add_tile(vec!["water", "water", "water", "water"], 30);
49
50        // 添加边界瓷砖
51        self.tiles
52            .add_tile(vec!["grass", "water", "grass", "water"], 20);
53        self.tiles
54            .add_tile(vec!["water", "grass", "water", "grass"], 20);
55
56        println!("构建完成:添加了 {} 个瓷砖", self.tiles.get_tile_count());
57        Ok(())
58    }
59
60    fn judge_possibility(&self, neighbor_possibilities: &[Vec<TileId>], candidate: TileId) -> bool {
61        // 简单的兼容性检查:如果有邻居约束,检查候选瓷砖是否存在
62        if neighbor_possibilities.is_empty() {
63            return true;
64        }
65
66        // 检查候选瓷砖是否存在
67        self.tiles.get_tile(candidate).is_some()
68    }
69
70    fn get_tile(&self, tile_id: TileId) -> Option<&Tile<&'static str>> {
71        self.tiles.get_tile(tile_id)
72    }
73
74    fn get_tile_count(&self) -> usize {
75        self.tiles.get_tile_count()
76    }
77
78    fn get_all_tile_ids(&self) -> Vec<TileId> {
79        self.tiles.get_all_tile_ids()
80    }
81}
82
83// =============================================================================
84// 数字瓷砖集实现 - 数字边数据
85// =============================================================================
86
87/// 数字瓷砖集,使用整数作为边数据
88///
89/// 展示如何使用数字来表示边的类型,适合更复杂的约束计算。
90struct NumericTileSet {
91    tiles: TileSet<i32>,
92}
93
94impl NumericTileSet {
95    fn new() -> Self {
96        Self {
97            tiles: TileSet::new(),
98        }
99    }
100}
101
102impl TileSetVirtual<i32> for NumericTileSet {
103    fn build_tile_set(&mut self) -> Result<(), GridError> {
104        // 构建数值瓷砖
105        self.tiles.clear();
106
107        // 添加基础连接模式
108        self.tiles.add_tile(vec![1, 1, 1, 1], 40); // 全连接
109        self.tiles.add_tile(vec![0, 0, 0, 0], 30); // 全断开
110        self.tiles.add_tile(vec![1, 0, 1, 0], 20); // 上下连接
111        self.tiles.add_tile(vec![0, 1, 0, 1], 20); // 左右连接
112
113        println!("数值瓷砖集构建完成:{} 个瓷砖", self.tiles.get_tile_count());
114        Ok(())
115    }
116
117    fn judge_possibility(&self, neighbor_possibilities: &[Vec<TileId>], candidate: TileId) -> bool {
118        let Some(candidate_tile) = self.tiles.get_tile(candidate) else {
119            return false;
120        };
121
122        for (direction, neighbor_ids) in neighbor_possibilities.iter().enumerate() {
123            if neighbor_ids.is_empty() {
124                continue;
125            }
126
127            let is_compatible = neighbor_ids.iter().any(|&neighbor_id| {
128                if let Some(neighbor_tile) = self.tiles.get_tile(neighbor_id) {
129                    let opposite_direction = (direction + 2) % 4;
130                    if let (Some(&current_edge), Some(&neighbor_edge)) = (
131                        candidate_tile.get_edge(direction),
132                        neighbor_tile.get_edge(opposite_direction),
133                    ) {
134                        // 数字边需要完全匹配
135                        current_edge == neighbor_edge
136                    } else {
137                        false
138                    }
139                } else {
140                    false
141                }
142            });
143
144            if !is_compatible {
145                return false;
146            }
147        }
148
149        true
150    }
151
152    fn get_tile(&self, tile_id: TileId) -> Option<&Tile<i32>> {
153        self.tiles.get_tile(tile_id)
154    }
155
156    fn get_tile_count(&self) -> usize {
157        self.tiles.get_tile_count()
158    }
159
160    fn get_all_tile_ids(&self) -> Vec<TileId> {
161        self.tiles.get_all_tile_ids()
162    }
163}
164
165// =============================================================================
166// 主函数 - 演示所有瓷砖集
167// =============================================================================
168
169fn main() -> Result<(), Box<dyn std::error::Error>> {
170    println!("=== 瓷砖系统综合示例 ===\n");
171
172    // 1. 基础TileSet演示
173    println!("1. 基础TileSet使用:");
174    demonstrate_basic_tileset()?;
175
176    // 2. 简单瓷砖集演示
177    println!("\n2. 简单瓷砖集 (字符串边):");
178    demonstrate_simple_tileset()?;
179
180    // 3. 数字瓷砖集演示
181    println!("\n3. 数字瓷砖集 (整数边):");
182    demonstrate_numeric_tileset()?;
183
184    // 4. 约束判断演示
185    println!("\n4. 约束判断测试:");
186    demonstrate_constraint_checking()?;
187
188    println!("\n=== 示例完成 ===");
189    Ok(())
190}
191
192/// 演示基础TileSet的使用
193fn demonstrate_basic_tileset() -> Result<(), Box<dyn std::error::Error>> {
194    let mut tile_set = TileSet::new();
195
196    println!("   创建基础瓷砖集...");
197
198    // 添加一些基础瓷砖
199    let tile1 = tile_set.add_tile(vec!["A", "B", "C", "D"], 10);
200    let tile2 = tile_set.add_tile(vec!["B", "A", "D", "C"], 15);
201    let _tile3 = tile_set.add_tile(vec!["C", "D", "A", "B"], 5);
202
203    println!("   添加了 {} 个瓷砖", tile_set.get_tile_count());
204
205    // 展示瓷砖信息
206    for (i, tile) in tile_set.get_all_tiles().iter().enumerate() {
207        println!(
208            "   瓷砖 {}: ID={}, 权重={}, 边={:?}",
209            i, tile.id, tile.weight, tile.edges
210        );
211    }
212
213    // 测试瓷砖兼容性
214    if let (Some(t1), Some(t2)) = (tile_set.get_tile(tile1), tile_set.get_tile(tile2)) {
215        let compatible = t1.is_compatible_with(t2, 0); // 方向0
216        println!("   瓷砖0和瓷砖1在方向0兼容: {}", compatible);
217    }
218
219    Ok(())
220}
221
222/// 演示简单瓷砖集
223fn demonstrate_simple_tileset() -> Result<(), Box<dyn std::error::Error>> {
224    let mut simple_tileset = SimpleTileSet::new();
225
226    // 构建瓷砖集
227    simple_tileset.build_tile_set()?;
228
229    // 展示所有瓷砖
230    println!("\n   瓷砖详情:");
231    for (i, tile) in simple_tileset.get_all_tiles().iter().enumerate() {
232        println!("     瓷砖 {}: 边={:?}, 权重={}", i, tile.edges, tile.weight);
233    }
234
235    // 测试约束判断
236    println!("\n   约束判断测试:");
237    test_constraint_judgment(&simple_tileset);
238
239    Ok(())
240}
241
242/// 演示数字瓷砖集
243fn demonstrate_numeric_tileset() -> Result<(), Box<dyn std::error::Error>> {
244    let mut numeric_tileset = NumericTileSet::new();
245
246    // 构建瓷砖集
247    numeric_tileset.build_tile_set()?;
248
249    // 展示瓷砖统计
250    println!("\n   瓷砖统计:");
251    let mut edge_types = std::collections::HashMap::new();
252    for tile in numeric_tileset.tiles.get_all_tiles() {
253        for &edge in &tile.edges {
254            *edge_types.entry(edge).or_insert(0) += 1;
255        }
256    }
257
258    for (edge_type, count) in edge_types {
259        let type_name = match edge_type {
260            0 => "平原",
261            1 => "山脉",
262            2 => "河流",
263            _ => "未知",
264        };
265        println!("     边类型 {} ({}): {} 个边", edge_type, type_name, count);
266    }
267
268    Ok(())
269}
Source

pub fn get_all_tile_ids(&self) -> Vec<TileId>

获取所有瓷砖ID

Examples found in repository?
examples/orthogonal_2d_wfc.rs (line 221)
220    fn get_all_tile_ids(&self) -> Vec<TileId> {
221        self.tiles.get_all_tile_ids()
222    }
More examples
Hide additional examples
examples/tile_system_demo.rs (line 79)
78    fn get_all_tile_ids(&self) -> Vec<TileId> {
79        self.tiles.get_all_tile_ids()
80    }
81}
82
83// =============================================================================
84// 数字瓷砖集实现 - 数字边数据
85// =============================================================================
86
87/// 数字瓷砖集,使用整数作为边数据
88///
89/// 展示如何使用数字来表示边的类型,适合更复杂的约束计算。
90struct NumericTileSet {
91    tiles: TileSet<i32>,
92}
93
94impl NumericTileSet {
95    fn new() -> Self {
96        Self {
97            tiles: TileSet::new(),
98        }
99    }
100}
101
102impl TileSetVirtual<i32> for NumericTileSet {
103    fn build_tile_set(&mut self) -> Result<(), GridError> {
104        // 构建数值瓷砖
105        self.tiles.clear();
106
107        // 添加基础连接模式
108        self.tiles.add_tile(vec![1, 1, 1, 1], 40); // 全连接
109        self.tiles.add_tile(vec![0, 0, 0, 0], 30); // 全断开
110        self.tiles.add_tile(vec![1, 0, 1, 0], 20); // 上下连接
111        self.tiles.add_tile(vec![0, 1, 0, 1], 20); // 左右连接
112
113        println!("数值瓷砖集构建完成:{} 个瓷砖", self.tiles.get_tile_count());
114        Ok(())
115    }
116
117    fn judge_possibility(&self, neighbor_possibilities: &[Vec<TileId>], candidate: TileId) -> bool {
118        let Some(candidate_tile) = self.tiles.get_tile(candidate) else {
119            return false;
120        };
121
122        for (direction, neighbor_ids) in neighbor_possibilities.iter().enumerate() {
123            if neighbor_ids.is_empty() {
124                continue;
125            }
126
127            let is_compatible = neighbor_ids.iter().any(|&neighbor_id| {
128                if let Some(neighbor_tile) = self.tiles.get_tile(neighbor_id) {
129                    let opposite_direction = (direction + 2) % 4;
130                    if let (Some(&current_edge), Some(&neighbor_edge)) = (
131                        candidate_tile.get_edge(direction),
132                        neighbor_tile.get_edge(opposite_direction),
133                    ) {
134                        // 数字边需要完全匹配
135                        current_edge == neighbor_edge
136                    } else {
137                        false
138                    }
139                } else {
140                    false
141                }
142            });
143
144            if !is_compatible {
145                return false;
146            }
147        }
148
149        true
150    }
151
152    fn get_tile(&self, tile_id: TileId) -> Option<&Tile<i32>> {
153        self.tiles.get_tile(tile_id)
154    }
155
156    fn get_tile_count(&self) -> usize {
157        self.tiles.get_tile_count()
158    }
159
160    fn get_all_tile_ids(&self) -> Vec<TileId> {
161        self.tiles.get_all_tile_ids()
162    }
Source

pub fn get_tile(&self, tile_id: TileId) -> Option<&Tile<EdgeData>>

根据ID获取瓷砖

Examples found in repository?
examples/tile_system_demo.rs (line 67)
60    fn judge_possibility(&self, neighbor_possibilities: &[Vec<TileId>], candidate: TileId) -> bool {
61        // 简单的兼容性检查:如果有邻居约束,检查候选瓷砖是否存在
62        if neighbor_possibilities.is_empty() {
63            return true;
64        }
65
66        // 检查候选瓷砖是否存在
67        self.tiles.get_tile(candidate).is_some()
68    }
69
70    fn get_tile(&self, tile_id: TileId) -> Option<&Tile<&'static str>> {
71        self.tiles.get_tile(tile_id)
72    }
73
74    fn get_tile_count(&self) -> usize {
75        self.tiles.get_tile_count()
76    }
77
78    fn get_all_tile_ids(&self) -> Vec<TileId> {
79        self.tiles.get_all_tile_ids()
80    }
81}
82
83// =============================================================================
84// 数字瓷砖集实现 - 数字边数据
85// =============================================================================
86
87/// 数字瓷砖集,使用整数作为边数据
88///
89/// 展示如何使用数字来表示边的类型,适合更复杂的约束计算。
90struct NumericTileSet {
91    tiles: TileSet<i32>,
92}
93
94impl NumericTileSet {
95    fn new() -> Self {
96        Self {
97            tiles: TileSet::new(),
98        }
99    }
100}
101
102impl TileSetVirtual<i32> for NumericTileSet {
103    fn build_tile_set(&mut self) -> Result<(), GridError> {
104        // 构建数值瓷砖
105        self.tiles.clear();
106
107        // 添加基础连接模式
108        self.tiles.add_tile(vec![1, 1, 1, 1], 40); // 全连接
109        self.tiles.add_tile(vec![0, 0, 0, 0], 30); // 全断开
110        self.tiles.add_tile(vec![1, 0, 1, 0], 20); // 上下连接
111        self.tiles.add_tile(vec![0, 1, 0, 1], 20); // 左右连接
112
113        println!("数值瓷砖集构建完成:{} 个瓷砖", self.tiles.get_tile_count());
114        Ok(())
115    }
116
117    fn judge_possibility(&self, neighbor_possibilities: &[Vec<TileId>], candidate: TileId) -> bool {
118        let Some(candidate_tile) = self.tiles.get_tile(candidate) else {
119            return false;
120        };
121
122        for (direction, neighbor_ids) in neighbor_possibilities.iter().enumerate() {
123            if neighbor_ids.is_empty() {
124                continue;
125            }
126
127            let is_compatible = neighbor_ids.iter().any(|&neighbor_id| {
128                if let Some(neighbor_tile) = self.tiles.get_tile(neighbor_id) {
129                    let opposite_direction = (direction + 2) % 4;
130                    if let (Some(&current_edge), Some(&neighbor_edge)) = (
131                        candidate_tile.get_edge(direction),
132                        neighbor_tile.get_edge(opposite_direction),
133                    ) {
134                        // 数字边需要完全匹配
135                        current_edge == neighbor_edge
136                    } else {
137                        false
138                    }
139                } else {
140                    false
141                }
142            });
143
144            if !is_compatible {
145                return false;
146            }
147        }
148
149        true
150    }
151
152    fn get_tile(&self, tile_id: TileId) -> Option<&Tile<i32>> {
153        self.tiles.get_tile(tile_id)
154    }
155
156    fn get_tile_count(&self) -> usize {
157        self.tiles.get_tile_count()
158    }
159
160    fn get_all_tile_ids(&self) -> Vec<TileId> {
161        self.tiles.get_all_tile_ids()
162    }
163}
164
165// =============================================================================
166// 主函数 - 演示所有瓷砖集
167// =============================================================================
168
169fn main() -> Result<(), Box<dyn std::error::Error>> {
170    println!("=== 瓷砖系统综合示例 ===\n");
171
172    // 1. 基础TileSet演示
173    println!("1. 基础TileSet使用:");
174    demonstrate_basic_tileset()?;
175
176    // 2. 简单瓷砖集演示
177    println!("\n2. 简单瓷砖集 (字符串边):");
178    demonstrate_simple_tileset()?;
179
180    // 3. 数字瓷砖集演示
181    println!("\n3. 数字瓷砖集 (整数边):");
182    demonstrate_numeric_tileset()?;
183
184    // 4. 约束判断演示
185    println!("\n4. 约束判断测试:");
186    demonstrate_constraint_checking()?;
187
188    println!("\n=== 示例完成 ===");
189    Ok(())
190}
191
192/// 演示基础TileSet的使用
193fn demonstrate_basic_tileset() -> Result<(), Box<dyn std::error::Error>> {
194    let mut tile_set = TileSet::new();
195
196    println!("   创建基础瓷砖集...");
197
198    // 添加一些基础瓷砖
199    let tile1 = tile_set.add_tile(vec!["A", "B", "C", "D"], 10);
200    let tile2 = tile_set.add_tile(vec!["B", "A", "D", "C"], 15);
201    let _tile3 = tile_set.add_tile(vec!["C", "D", "A", "B"], 5);
202
203    println!("   添加了 {} 个瓷砖", tile_set.get_tile_count());
204
205    // 展示瓷砖信息
206    for (i, tile) in tile_set.get_all_tiles().iter().enumerate() {
207        println!(
208            "   瓷砖 {}: ID={}, 权重={}, 边={:?}",
209            i, tile.id, tile.weight, tile.edges
210        );
211    }
212
213    // 测试瓷砖兼容性
214    if let (Some(t1), Some(t2)) = (tile_set.get_tile(tile1), tile_set.get_tile(tile2)) {
215        let compatible = t1.is_compatible_with(t2, 0); // 方向0
216        println!("   瓷砖0和瓷砖1在方向0兼容: {}", compatible);
217    }
218
219    Ok(())
220}
More examples
Hide additional examples
examples/orthogonal_2d_wfc.rs (line 167)
166    fn judge_possibility(&self, neighbor_possibilities: &[Vec<TileId>], candidate: TileId) -> bool {
167        let candidate_tile = match self.tiles.get_tile(candidate) {
168            Some(tile) => tile,
169            None => return false,
170        };
171
172        // 检查候选瓷砖与所有邻居的兼容性
173        // neighbor_possibilities的索引对应:[北, 西, 南, 东]
174        for (direction_index, neighbor_tiles) in neighbor_possibilities.iter().enumerate() {
175            if neighbor_tiles.is_empty() {
176                continue;
177            }
178
179            let mut edge_compatible = false;
180            let candidate_edge = candidate_tile.edges[direction_index];
181
182            for &neighbor_tile_id in neighbor_tiles {
183                if let Some(neighbor_tile) = self.tiles.get_tile(neighbor_tile_id) {
184                    // 计算邻居瓷砖对应方向的边索引
185                    // 边数据顺序:[北, 西, 南, 东]
186                    let neighbor_edge_index = match direction_index {
187                        0 => 2, // 北边 -> 邻居的南边
188                        1 => 3, // 西边 -> 邻居的东边
189                        2 => 0, // 南边 -> 邻居的北边
190                        3 => 1, // 东边 -> 邻居的西边
191                        _ => continue,
192                    };
193
194                    let neighbor_edge = neighbor_tile.edges[neighbor_edge_index];
195
196                    // 相邻边必须相等才兼容
197                    if candidate_edge == neighbor_edge {
198                        edge_compatible = true;
199                        break;
200                    }
201                }
202            }
203
204            if !edge_compatible {
205                return false;
206            }
207        }
208
209        true
210    }
211
212    fn get_tile(&self, tile_id: TileId) -> Option<&Tile<i32>> {
213        self.tiles.get_tile(tile_id)
214    }
Source

pub fn get_tile_count(&self) -> usize

获取瓷砖数量

Examples found in repository?
examples/tile_system_demo.rs (line 56)
38    fn build_tile_set(&mut self) -> Result<(), GridError> {
39        // 构建基础瓷砖
40        self.tiles.clear();
41
42        // 添加全草地瓷砖
43        self.tiles
44            .add_tile(vec!["grass", "grass", "grass", "grass"], 50);
45
46        // 添加全水面瓷砖
47        self.tiles
48            .add_tile(vec!["water", "water", "water", "water"], 30);
49
50        // 添加边界瓷砖
51        self.tiles
52            .add_tile(vec!["grass", "water", "grass", "water"], 20);
53        self.tiles
54            .add_tile(vec!["water", "grass", "water", "grass"], 20);
55
56        println!("构建完成:添加了 {} 个瓷砖", self.tiles.get_tile_count());
57        Ok(())
58    }
59
60    fn judge_possibility(&self, neighbor_possibilities: &[Vec<TileId>], candidate: TileId) -> bool {
61        // 简单的兼容性检查:如果有邻居约束,检查候选瓷砖是否存在
62        if neighbor_possibilities.is_empty() {
63            return true;
64        }
65
66        // 检查候选瓷砖是否存在
67        self.tiles.get_tile(candidate).is_some()
68    }
69
70    fn get_tile(&self, tile_id: TileId) -> Option<&Tile<&'static str>> {
71        self.tiles.get_tile(tile_id)
72    }
73
74    fn get_tile_count(&self) -> usize {
75        self.tiles.get_tile_count()
76    }
77
78    fn get_all_tile_ids(&self) -> Vec<TileId> {
79        self.tiles.get_all_tile_ids()
80    }
81}
82
83// =============================================================================
84// 数字瓷砖集实现 - 数字边数据
85// =============================================================================
86
87/// 数字瓷砖集,使用整数作为边数据
88///
89/// 展示如何使用数字来表示边的类型,适合更复杂的约束计算。
90struct NumericTileSet {
91    tiles: TileSet<i32>,
92}
93
94impl NumericTileSet {
95    fn new() -> Self {
96        Self {
97            tiles: TileSet::new(),
98        }
99    }
100}
101
102impl TileSetVirtual<i32> for NumericTileSet {
103    fn build_tile_set(&mut self) -> Result<(), GridError> {
104        // 构建数值瓷砖
105        self.tiles.clear();
106
107        // 添加基础连接模式
108        self.tiles.add_tile(vec![1, 1, 1, 1], 40); // 全连接
109        self.tiles.add_tile(vec![0, 0, 0, 0], 30); // 全断开
110        self.tiles.add_tile(vec![1, 0, 1, 0], 20); // 上下连接
111        self.tiles.add_tile(vec![0, 1, 0, 1], 20); // 左右连接
112
113        println!("数值瓷砖集构建完成:{} 个瓷砖", self.tiles.get_tile_count());
114        Ok(())
115    }
116
117    fn judge_possibility(&self, neighbor_possibilities: &[Vec<TileId>], candidate: TileId) -> bool {
118        let Some(candidate_tile) = self.tiles.get_tile(candidate) else {
119            return false;
120        };
121
122        for (direction, neighbor_ids) in neighbor_possibilities.iter().enumerate() {
123            if neighbor_ids.is_empty() {
124                continue;
125            }
126
127            let is_compatible = neighbor_ids.iter().any(|&neighbor_id| {
128                if let Some(neighbor_tile) = self.tiles.get_tile(neighbor_id) {
129                    let opposite_direction = (direction + 2) % 4;
130                    if let (Some(&current_edge), Some(&neighbor_edge)) = (
131                        candidate_tile.get_edge(direction),
132                        neighbor_tile.get_edge(opposite_direction),
133                    ) {
134                        // 数字边需要完全匹配
135                        current_edge == neighbor_edge
136                    } else {
137                        false
138                    }
139                } else {
140                    false
141                }
142            });
143
144            if !is_compatible {
145                return false;
146            }
147        }
148
149        true
150    }
151
152    fn get_tile(&self, tile_id: TileId) -> Option<&Tile<i32>> {
153        self.tiles.get_tile(tile_id)
154    }
155
156    fn get_tile_count(&self) -> usize {
157        self.tiles.get_tile_count()
158    }
159
160    fn get_all_tile_ids(&self) -> Vec<TileId> {
161        self.tiles.get_all_tile_ids()
162    }
163}
164
165// =============================================================================
166// 主函数 - 演示所有瓷砖集
167// =============================================================================
168
169fn main() -> Result<(), Box<dyn std::error::Error>> {
170    println!("=== 瓷砖系统综合示例 ===\n");
171
172    // 1. 基础TileSet演示
173    println!("1. 基础TileSet使用:");
174    demonstrate_basic_tileset()?;
175
176    // 2. 简单瓷砖集演示
177    println!("\n2. 简单瓷砖集 (字符串边):");
178    demonstrate_simple_tileset()?;
179
180    // 3. 数字瓷砖集演示
181    println!("\n3. 数字瓷砖集 (整数边):");
182    demonstrate_numeric_tileset()?;
183
184    // 4. 约束判断演示
185    println!("\n4. 约束判断测试:");
186    demonstrate_constraint_checking()?;
187
188    println!("\n=== 示例完成 ===");
189    Ok(())
190}
191
192/// 演示基础TileSet的使用
193fn demonstrate_basic_tileset() -> Result<(), Box<dyn std::error::Error>> {
194    let mut tile_set = TileSet::new();
195
196    println!("   创建基础瓷砖集...");
197
198    // 添加一些基础瓷砖
199    let tile1 = tile_set.add_tile(vec!["A", "B", "C", "D"], 10);
200    let tile2 = tile_set.add_tile(vec!["B", "A", "D", "C"], 15);
201    let _tile3 = tile_set.add_tile(vec!["C", "D", "A", "B"], 5);
202
203    println!("   添加了 {} 个瓷砖", tile_set.get_tile_count());
204
205    // 展示瓷砖信息
206    for (i, tile) in tile_set.get_all_tiles().iter().enumerate() {
207        println!(
208            "   瓷砖 {}: ID={}, 权重={}, 边={:?}",
209            i, tile.id, tile.weight, tile.edges
210        );
211    }
212
213    // 测试瓷砖兼容性
214    if let (Some(t1), Some(t2)) = (tile_set.get_tile(tile1), tile_set.get_tile(tile2)) {
215        let compatible = t1.is_compatible_with(t2, 0); // 方向0
216        println!("   瓷砖0和瓷砖1在方向0兼容: {}", compatible);
217    }
218
219    Ok(())
220}
More examples
Hide additional examples
examples/orthogonal_2d_wfc.rs (line 162)
128    fn build_tile_set(&mut self) -> Result<(), GridError> {
129        self.tiles.clear();
130
131        // 添加基础瓷砖,用数字表示连接类型
132        // 0 = 空白,1 = 路径
133
134        // 全空白瓷砖
135        self.tiles.add_tile(vec![0, 0, 0, 0], 1); // [北, 西, 南, 东]
136
137        // 直线路径瓷砖
138        self.tiles.add_tile(vec![1, 0, 1, 0], 1); // 垂直路径
139        self.tiles.add_tile(vec![0, 1, 0, 1], 1); // 水平路径
140
141        // 端点
142        // self.tiles.add_tile(vec![1, 0, 0, 0], 1);
143        // self.tiles.add_tile(vec![0, 1, 0, 0], 1);
144        // self.tiles.add_tile(vec![0, 0, 1, 0], 1);
145        // self.tiles.add_tile(vec![0, 0, 0, 1], 1);
146
147        // 转角路径瓷砖
148        // self.tiles.add_tile(vec![1, 1, 0, 0], 1);  // 左上角
149        // self.tiles.add_tile(vec![1, 0, 0, 1], 1);  // 右上角
150        // self.tiles.add_tile(vec![0, 1, 1, 0], 1);  // 左下角
151        // self.tiles.add_tile(vec![0, 0, 1, 1], 1);  // 右下角
152
153        // T型路径瓷砖
154        self.tiles.add_tile(vec![1, 1, 1, 0], 1); // 向右开口的T
155        self.tiles.add_tile(vec![1, 0, 1, 1], 1); // 向左开口的T
156        self.tiles.add_tile(vec![0, 1, 1, 1], 1); // 向上开口的T
157        self.tiles.add_tile(vec![1, 1, 0, 1], 1); // 向下开口的T
158
159        // 十字路口瓷砖
160        self.tiles.add_tile(vec![1, 1, 1, 1], 1); // 全连通
161
162        println!("瓷砖集构建完成:{} 种瓷砖", self.tiles.get_tile_count());
163        Ok(())
164    }
165
166    fn judge_possibility(&self, neighbor_possibilities: &[Vec<TileId>], candidate: TileId) -> bool {
167        let candidate_tile = match self.tiles.get_tile(candidate) {
168            Some(tile) => tile,
169            None => return false,
170        };
171
172        // 检查候选瓷砖与所有邻居的兼容性
173        // neighbor_possibilities的索引对应:[北, 西, 南, 东]
174        for (direction_index, neighbor_tiles) in neighbor_possibilities.iter().enumerate() {
175            if neighbor_tiles.is_empty() {
176                continue;
177            }
178
179            let mut edge_compatible = false;
180            let candidate_edge = candidate_tile.edges[direction_index];
181
182            for &neighbor_tile_id in neighbor_tiles {
183                if let Some(neighbor_tile) = self.tiles.get_tile(neighbor_tile_id) {
184                    // 计算邻居瓷砖对应方向的边索引
185                    // 边数据顺序:[北, 西, 南, 东]
186                    let neighbor_edge_index = match direction_index {
187                        0 => 2, // 北边 -> 邻居的南边
188                        1 => 3, // 西边 -> 邻居的东边
189                        2 => 0, // 南边 -> 邻居的北边
190                        3 => 1, // 东边 -> 邻居的西边
191                        _ => continue,
192                    };
193
194                    let neighbor_edge = neighbor_tile.edges[neighbor_edge_index];
195
196                    // 相邻边必须相等才兼容
197                    if candidate_edge == neighbor_edge {
198                        edge_compatible = true;
199                        break;
200                    }
201                }
202            }
203
204            if !edge_compatible {
205                return false;
206            }
207        }
208
209        true
210    }
211
212    fn get_tile(&self, tile_id: TileId) -> Option<&Tile<i32>> {
213        self.tiles.get_tile(tile_id)
214    }
215
216    fn get_tile_count(&self) -> usize {
217        self.tiles.get_tile_count()
218    }
Source

pub fn clear(&mut self)

清空瓷砖集

Examples found in repository?
examples/tile_system_demo.rs (line 40)
38    fn build_tile_set(&mut self) -> Result<(), GridError> {
39        // 构建基础瓷砖
40        self.tiles.clear();
41
42        // 添加全草地瓷砖
43        self.tiles
44            .add_tile(vec!["grass", "grass", "grass", "grass"], 50);
45
46        // 添加全水面瓷砖
47        self.tiles
48            .add_tile(vec!["water", "water", "water", "water"], 30);
49
50        // 添加边界瓷砖
51        self.tiles
52            .add_tile(vec!["grass", "water", "grass", "water"], 20);
53        self.tiles
54            .add_tile(vec!["water", "grass", "water", "grass"], 20);
55
56        println!("构建完成:添加了 {} 个瓷砖", self.tiles.get_tile_count());
57        Ok(())
58    }
59
60    fn judge_possibility(&self, neighbor_possibilities: &[Vec<TileId>], candidate: TileId) -> bool {
61        // 简单的兼容性检查:如果有邻居约束,检查候选瓷砖是否存在
62        if neighbor_possibilities.is_empty() {
63            return true;
64        }
65
66        // 检查候选瓷砖是否存在
67        self.tiles.get_tile(candidate).is_some()
68    }
69
70    fn get_tile(&self, tile_id: TileId) -> Option<&Tile<&'static str>> {
71        self.tiles.get_tile(tile_id)
72    }
73
74    fn get_tile_count(&self) -> usize {
75        self.tiles.get_tile_count()
76    }
77
78    fn get_all_tile_ids(&self) -> Vec<TileId> {
79        self.tiles.get_all_tile_ids()
80    }
81}
82
83// =============================================================================
84// 数字瓷砖集实现 - 数字边数据
85// =============================================================================
86
87/// 数字瓷砖集,使用整数作为边数据
88///
89/// 展示如何使用数字来表示边的类型,适合更复杂的约束计算。
90struct NumericTileSet {
91    tiles: TileSet<i32>,
92}
93
94impl NumericTileSet {
95    fn new() -> Self {
96        Self {
97            tiles: TileSet::new(),
98        }
99    }
100}
101
102impl TileSetVirtual<i32> for NumericTileSet {
103    fn build_tile_set(&mut self) -> Result<(), GridError> {
104        // 构建数值瓷砖
105        self.tiles.clear();
106
107        // 添加基础连接模式
108        self.tiles.add_tile(vec![1, 1, 1, 1], 40); // 全连接
109        self.tiles.add_tile(vec![0, 0, 0, 0], 30); // 全断开
110        self.tiles.add_tile(vec![1, 0, 1, 0], 20); // 上下连接
111        self.tiles.add_tile(vec![0, 1, 0, 1], 20); // 左右连接
112
113        println!("数值瓷砖集构建完成:{} 个瓷砖", self.tiles.get_tile_count());
114        Ok(())
115    }
More examples
Hide additional examples
examples/orthogonal_2d_wfc.rs (line 129)
128    fn build_tile_set(&mut self) -> Result<(), GridError> {
129        self.tiles.clear();
130
131        // 添加基础瓷砖,用数字表示连接类型
132        // 0 = 空白,1 = 路径
133
134        // 全空白瓷砖
135        self.tiles.add_tile(vec![0, 0, 0, 0], 1); // [北, 西, 南, 东]
136
137        // 直线路径瓷砖
138        self.tiles.add_tile(vec![1, 0, 1, 0], 1); // 垂直路径
139        self.tiles.add_tile(vec![0, 1, 0, 1], 1); // 水平路径
140
141        // 端点
142        // self.tiles.add_tile(vec![1, 0, 0, 0], 1);
143        // self.tiles.add_tile(vec![0, 1, 0, 0], 1);
144        // self.tiles.add_tile(vec![0, 0, 1, 0], 1);
145        // self.tiles.add_tile(vec![0, 0, 0, 1], 1);
146
147        // 转角路径瓷砖
148        // self.tiles.add_tile(vec![1, 1, 0, 0], 1);  // 左上角
149        // self.tiles.add_tile(vec![1, 0, 0, 1], 1);  // 右上角
150        // self.tiles.add_tile(vec![0, 1, 1, 0], 1);  // 左下角
151        // self.tiles.add_tile(vec![0, 0, 1, 1], 1);  // 右下角
152
153        // T型路径瓷砖
154        self.tiles.add_tile(vec![1, 1, 1, 0], 1); // 向右开口的T
155        self.tiles.add_tile(vec![1, 0, 1, 1], 1); // 向左开口的T
156        self.tiles.add_tile(vec![0, 1, 1, 1], 1); // 向上开口的T
157        self.tiles.add_tile(vec![1, 1, 0, 1], 1); // 向下开口的T
158
159        // 十字路口瓷砖
160        self.tiles.add_tile(vec![1, 1, 1, 1], 1); // 全连通
161
162        println!("瓷砖集构建完成:{} 种瓷砖", self.tiles.get_tile_count());
163        Ok(())
164    }
Source

pub fn contains_tile(&self, tile_id: TileId) -> bool

检查瓷砖是否存在

Source

pub fn is_empty(&self) -> bool

检查瓷砖集是否为空

Trait Implementations§

Source§

impl<EdgeData> Clone for TileSet<EdgeData>
where EdgeData: Clone + PartialEq + Debug + Clone,

Source§

fn clone(&self) -> TileSet<EdgeData>

Returns a duplicate of the value. Read more
1.0.0 · Source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
Source§

impl<EdgeData> Debug for TileSet<EdgeData>
where EdgeData: Clone + PartialEq + Debug + Debug,

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
Source§

impl<EdgeData> Default for TileSet<EdgeData>
where EdgeData: Clone + PartialEq + Debug,

Source§

fn default() -> Self

Returns the “default value” for a type. Read more

Auto Trait Implementations§

§

impl<EdgeData> Freeze for TileSet<EdgeData>

§

impl<EdgeData> RefUnwindSafe for TileSet<EdgeData>
where EdgeData: RefUnwindSafe,

§

impl<EdgeData> Send for TileSet<EdgeData>
where EdgeData: Send,

§

impl<EdgeData> Sync for TileSet<EdgeData>
where EdgeData: Sync,

§

impl<EdgeData> Unpin for TileSet<EdgeData>
where EdgeData: Unpin,

§

impl<EdgeData> UnsafeUnpin for TileSet<EdgeData>

§

impl<EdgeData> UnwindSafe for TileSet<EdgeData>
where EdgeData: UnwindSafe,

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> CloneToUninit for T
where T: Clone,

Source§

unsafe fn clone_to_uninit(&self, dest: *mut u8)

🔬This is a nightly-only experimental API. (clone_to_uninit)
Performs copy-assignment from self to dest. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> ToOwned for T
where T: Clone,

Source§

type Owned = T

The resulting type after obtaining ownership.
Source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
Source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
Source§

impl<V, T> VZip<V> for T
where V: MultiLane<T>,

Source§

fn vzip(self) -> V