添加 MX-PD-盘古 项目文件

将 MX-PD-盘古 - new 目录下的所有文件添加到主仓库
This commit is contained in:
Shi.Ji
2026-05-18 11:43:09 +08:00
parent 03632a379d
commit e31d3560bb
739 changed files with 99783 additions and 0 deletions

View File

@@ -0,0 +1,385 @@
# MainShell/Process/DieTransfer/Planning ˵<><CBB5><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
## 1. <20><>Χ
<EFBFBD><EFBFBD><EFBFBD><EFBFBD>˵<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> `MainShell/Process/DieTransfer/Planning` Ŀ¼<C4BF>µĹ滮<C4B9><E6BBAE><EFBFBD><EFBFBD>ʵ<EFBFBD>֣<EFBFBD><D6A3><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ļ<EFBFBD><C4BC><EFBFBD>
- `DieTransferPathGenerator.cs`
- `DieTransferPlanningContext.cs`
- `DieTransferPathRequest.cs`
- `DieTransferPathPlan.cs`
- `DieTransferPathRegionPlan.cs`
- `DieTransferPathStep.cs`
- `DieTransferRegion.cs`
- `DieTransferRow.cs`
- `PadTransferRow.cs`
- `DieTransferRowDirection.cs`
- `SubstrateRowDirectionStrategy.cs`
- `IDieTransferPathGenerator.cs`
## 2. ģ<>鶨λ
<EFBFBD><EFBFBD>ģ<EFBFBD><EFBFBD><EFBFBD><EFBFBD> Die Transfer <20>ġ<EFBFBD><C4A1><EFBFBD><EFBFBD><E3A1B1>ְ<EFBFBD><D6B0><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ִ<EFBFBD><D6B4><EFBFBD>˶<EFBFBD><CBB6><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ǰѺ<C7B0>ѡ Die <20><><EFBFBD>Ϻͺ<CFBA>ѡ Pad <20><><EFBFBD><EFBFBD>ת<EFBFBD><D7AA><EFBFBD><EFBFBD>һ<EFBFBD>ݿ<EFBFBD>ִ<EFBFBD>е<EFBFBD>·<EFBFBD><C2B7><EFBFBD>ƻ<EFBFBD><C6BB><EFBFBD>
<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
- <20><>ѡ Die <20><><EFBFBD><EFBFBD>
- <20><>ѡ Pad <20><><EFBFBD><EFBFBD>
- Die <20><><EFBFBD><EFBFBD>
- Substrate <20><><EFBFBD><EFBFBD>
- ·<><C2B7><EFBFBD><EFBFBD><EFBFBD>ɲ<EFBFBD><C9B2><EFBFBD>
- <20>Ƿ<EFBFBD><C7B7><EFBFBD><EFBFBD><EFBFBD> NG Die
- <20><><EFBFBD><EFBFBD><EFBFBD>з<EFBFBD><D0B7><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
- <20><><EFBFBD><EFBFBD><EFBFBD>ɵ<EFBFBD><C9B5><EFBFBD><EFBFBD>Բ<EFBFBD><D4B2><EFBFBD> `Steps`
- <20><><EFBFBD>˺<EFBFBD><CBBA>Ŀ<EFBFBD><C4BF><EFBFBD> Die / Pad <20><><EFBFBD><EFBFBD>
- ʣ<><CAA3>δ<EFBFBD><CEB4><EFBFBD>Ե<EFBFBD> Die / Pad
- ʣ<><CAA3><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>нṹ<D0BD><E1B9B9><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>߽<EFBFBD>
<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ǻ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ģ<EFBFBD><EFBFBD><EFBFBD>߼<EFBFBD><EFBFBD><EFBFBD><EFBFBD>˶<EFBFBD>ִ<EFBFBD>н<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ֶ<EFBFBD>ģʽ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Զ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>̣<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ը<EFBFBD><EFBFBD><EFBFBD>ͬһ<EFBFBD><EFBFBD>·<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
## 3. <20><><EFBFBD>Ķ<EFBFBD><C4B6><EFBFBD>ְ<EFBFBD><D6B0>
### 3.1 `DieTransferPathRequest`
·<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
<EFBFBD>ؼ<EFBFBD><EFBFBD>ֶΣ<EFBFBD>
- `DieCandidates`<60><><EFBFBD><EFBFBD>ѡ Die <20><><EFBFBD><EFBFBD>
- `PadCandidates`<60><><EFBFBD><EFBFBD>ѡ Pad <20><><EFBFBD><EFBFBD>
- `DieRegion`<60><>Die <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
- `SubstrateRegion`<60><>Pad <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
- `TransPathType`<60><>·<EFBFBD><C2B7><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ģʽ
- `SubstrateRowDirectionStrategy`<60><>Pad <20>б<EFBFBD><D0B1><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
- `SkipNgDie`<60><><EFBFBD>Ƿ<EFBFBD><C7B7><EFBFBD><EFBFBD><EFBFBD> NG Die
Ĭ<EFBFBD><EFBFBD>ֵ<EFBFBD><EFBFBD><EFBFBD>ñȽϺ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
- Ĭ<><C4AC>ģʽ<C4A3><CABD> `Sequence`
- Ĭ<><C4AC> Pad <20>з<EFBFBD><D0B7><EFBFBD><EFBFBD><EFBFBD> `AllPositive`
- Ĭ<><C4AC><EFBFBD><EFBFBD><EFBFBD><EFBFBD> NG Die
### 3.2 `DieTransferPlanningContext`
<EFBFBD><EFBFBD><EFBFBD>ǵ<EFBFBD>ǰģ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ĵ<EFBFBD><EFBFBD>м<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ò<EFBFBD><EFBFBD>Ƕ<EFBFBD><EFBFBD>Ⱪ¶<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ǰ<EFBFBD> request Ԥ<><D4A4><EFBFBD><EFBFBD><EFBFBD>ɡ<EFBFBD><C9A1><EFBFBD>ֱ<EFBFBD><D6B1><EFBFBD><EFBFBD><EFBFBD><EFBFBD>·<EFBFBD><C2B7><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ڲ<EFBFBD><DAB2><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ġ<EFBFBD>
<EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ҫ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>£<EFBFBD>
1. <20><> `RegionModel` ת<><D7AA><EFBFBD>ڲ<EFBFBD>ʹ<EFBFBD>õ<EFBFBD> `DieTransferRegion`
2. <20><>ԭʼ<D4AD><CABC>ѡ<EFBFBD><D1A1><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ɰ<EFBFBD><C9B0>з<EFBFBD><D0B7><EFBFBD><EFBFBD><EFBFBD> `DieTransferRow` / `PadTransferRow`
3. <20><><EFBFBD><EFBFBD><EFBFBD>з<EFBFBD><D0B7><EFBFBD><EFBFBD><EFBFBD><EFBFBD>򣬰<EFBFBD>ÿһ<C3BF>еĵ<D0B5><C4B5><EFBFBD>֯<EFBFBD><D6AF>ȷ<EFBFBD><C8B7>˳<EFBFBD><CBB3>
<EFBFBD><EFBFBD><EFBFBD>仰˵<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ġ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>򡢹<EFBFBD><EFBFBD>ˡ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>֯<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> generator <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFA3AC><EFBFBD><EFBFBD><EFBFBD><EFBFBD> context <20><><EFBFBD><EFBFBD><EFBFBD>׶<EFBFBD><D7B6><EFBFBD><EFBFBD>ɡ<EFBFBD>
### 3.3 `DieTransferPathGenerator`
·<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ڡ<EFBFBD>
<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ĸ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
- `Generate()`<60><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> `DieTransferPathPlan`
- `GenerateByRegion()`<60><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> `DieTransferPathRegionPlan`
- `GenerateByCandidates()`<60><><EFBFBD><EFBFBD><EFBFBD>ݴ<EFBFBD><DDB4><EFBFBD><EFBFBD><EFBFBD> Pad <20><><EFBFBD>Ϻ<EFBFBD> Die <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> `DieTransferPathRegionPlan`
- `GenerateByRows()`<60><><EFBFBD><EFBFBD><EFBFBD>ݴ<EFBFBD><DDB4><EFBFBD><EFBFBD><EFBFBD> `PadTransferRow` / `DieTransferRow` ֱ<><D6B1><EFBFBD><EFBFBD><EFBFBD><EFBFBD> `DieTransferPathRegionPlan`
<EFBFBD><EFBFBD><EFBFBD><EFBFBD> `Generate()` ʵ<><CAB5>ֻ<EFBFBD><D6BB>ת<EFBFBD><D7AA> `GenerateByRegion()`<60><>ֻ<EFBFBD>ǰѷ<C7B0><D1B7><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>խ<EFBFBD>ɻ<EFBFBD><C9BB><EFBFBD><E0A1A3><EFBFBD>ˣ<EFBFBD>
- <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>÷<EFBFBD>ֻ<EFBFBD><D6BB><EFBFBD>IJ<EFBFBD><C4B2><EFBFBD><EFBFBD>б<EFBFBD><D0B1><EFBFBD>ͳ<EFBFBD><CDB3><EFBFBD><EFBFBD>Ϣ<EFBFBD><CFA2><EFBFBD><EFBFBD> `Generate()` <20><><EFBFBD><EFBFBD>
- <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>÷<EFBFBD><C3B7><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʣ<EFBFBD><CAA3> Die / Pad <20><>ʣ<EFBFBD><CAA3><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ӧ<EFBFBD><D3A6>ʹ<EFBFBD><CAB9> `GenerateByRegion()`
<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ڵĶ<EFBFBD>λ<EFBFBD><EFBFBD><EFBFBD>£<EFBFBD>
- `GenerateByCandidates()`<60><><EFBFBD>ʺϵ<CABA><CFB5>÷<EFBFBD><C3B7><EFBFBD><EFBFBD><EFBFBD>ֻ<EFBFBD><D6BB>ԭʼ<D4AD><CABC>ѡ<EFBFBD><EFBFBD>ϣ<EFBFBD><CFA3><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Լ<EFBFBD><D4BC><EFBFBD>װ `DieTransferPathRequest` <20>ij<EFBFBD><C4B3><EFBFBD><EFBFBD><EFBFBD><EFBFBD>÷<EFBFBD><C3B7><EFBFBD><EFBFBD>ڲ<EFBFBD><DAB2>Ի<EFBFBD><D4BB><EFBFBD><EFBFBD><EFBFBD><EFBFBD>е<EFBFBD> request/context Ԥ<><D4A4><EFBFBD><EFBFBD><EFBFBD>߼<EFBFBD><DFBC><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ɵ<EFBFBD>·<EFBFBD><C2B7>ͳһ<CDB3>ӷ<EFBFBD><D3B7>ؽ<EFBFBD><D8BD><EFBFBD><EFBFBD><EFBFBD> `Steps` <20>л<EFBFBD>ȡ<EFBFBD><C8A1>
- `GenerateByRows()`<60><><EFBFBD>ʺϵ<CABA><CFB5>÷<EFBFBD><C3B7>Ѿ<EFBFBD><D1BE><EFBFBD><EFBFBD>ɰ<EFBFBD><C9B0>з<EFBFBD><D0B7><EFBFBD><E9A1A2><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>NG <20><><EFBFBD>˲<EFBFBD><CBB2><EFBFBD><EFBFBD><EFBFBD><EFBFBD>õij<C3B5><C4B3><EFBFBD><EFBFBD><EFBFBD><EFBFBD>÷<EFBFBD><C3B7><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>¹<EFBFBD><C2B9><EFBFBD> planning context<78><74><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ֱ<EFBFBD>ӰѴ<D3B0><D1B4><EFBFBD><EFBFBD><EFBFBD>չ<EFBFBD><D5B9>Ϊ<EFBFBD><CEAA><EFBFBD><EFBFBD> Die / Pad<61><64><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ɲ<EFBFBD><C9B2><EFBFBD><EFBFBD><EFBFBD>ʣ<EFBFBD><CAA3><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
### 3.4 `DieTransferPathPlan` / `DieTransferPathRegionPlan`
`DieTransferPathPlan` <20><>ʾ<EFBFBD><CABE><EFBFBD><EFBFBD><EFBFBD><EFBFBD><E6BBAE><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
- `TransPathType`
- `Steps`
- `AvailableDieCount`
- `AvailablePadCount`
- `GeneratedStepCount`
`DieTransferPathRegionPlan` <20>ڴ˻<DAB4><CBBB><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>չ<EFBFBD><D5B9>ʣ<EFBFBD><CAA3><EFBFBD><EFBFBD>Ϣ<EFBFBD><CFA2>
- `RemainingDies`
- `RemainingPads`
- `RemainingDieRows`
- `RemainingPadRows`
- `RemainingDieRegion`
- `RemainingSubstrateRegion`
<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ζ<EFBFBD>Ÿ<EFBFBD>ģ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>һ<EFBFBD><EFBFBD>·<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ܸ<EFBFBD><EFBFBD><EFBFBD>һ<EFBFBD>ּ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ġ<EFBFBD>
### 3.5 `DieTransferPathStep`
<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Խ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>󣬼<EFBFBD>¼<EFBFBD><EFBFBD>
- <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> `StepIndex`
- Die <20><><EFBFBD>к<EFBFBD><D0BA><EFBFBD><EFBFBD><EFBFBD>
- Pad <20><><EFBFBD>к<EFBFBD><D0BA><EFBFBD><EFBFBD><EFBFBD>
- <20><>ǰ·<C7B0><C2B7><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ƵñȽ<EFBFBD>ֱ<EFBFBD>ӣ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> UI <20><>ִ<EFBFBD>в㶼<D0B2><E3B6BC><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ѡ<EFBFBD>
## 4. <20><><EFBFBD>ɷ<EFBFBD><C9B7><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
·<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ɵ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>£<EFBFBD>
1. <20><><EFBFBD>÷<EFBFBD><C3B7><EFBFBD><EFBFBD><EFBFBD> `DieTransferPathRequest`
2. `DieTransferPathGenerator.GenerateByRegion()` У<><D0A3> request <20>ǿ<EFBFBD>
3. `DieTransferPlanningContext.Create(request)` <20><><EFBFBD>ɹ滮<C9B9><E6BBAE><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
4. <20><> context <20><>ȡ<EFBFBD><C8A1><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> Die <20>б<EFBFBD><D0B1><EFBFBD> Pad <20>б<EFBFBD>
5. <20><> `TransPathType` ѡ<><D1A1><EFBFBD><EFBFBD><EFBFBD>ɲ<EFBFBD><C9B2><EFBFBD>
6. <20><><EFBFBD><EFBFBD> `DieTransferPathStep` <20>б<EFBFBD>
7. <20><><EFBFBD><EFBFBD>δ<EFBFBD><CEB4><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ե<EFBFBD>ʣ<EFBFBD><CAA3> Die / Pad
8. <20><><EFBFBD><EFBFBD>ʣ<EFBFBD><CAA3><EFBFBD>нṹ<D0BD><E1B9B9>ʣ<EFBFBD><CAA3><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
9. <20><>װ `DieTransferPathRegionPlan` <20><><EFBFBD><EFBFBD>
<EFBFBD><EFBFBD><EFBFBD>԰<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ϊ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʽ<EFBFBD><EFBFBD><EFBFBD>̣<EFBFBD>
- <20><>һ<EFBFBD>Σ<EFBFBD>Ԥ<EFBFBD><D4A4><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>õ<EFBFBD><C3B5>ȶ<EFBFBD>˳<EFBFBD><CBB3>
- <20>ڶ<EFBFBD><DAB6>Σ<EFBFBD><CEA3><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> Die <20><> Pad <20><>һһ<D2BB><D2BB><EFBFBD><EFBFBD>
<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ڣ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ֻ<EFBFBD>Ǹı<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ı䡰·<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
- `GenerateByCandidates()`<60><><EFBFBD>Ӻ<EFBFBD>ѡ<EFBFBD><D1A1><EFBFBD>Ͻ<EFBFBD><CFBD><EFBFBD>ٸ<EFBFBD><D9B8><EFBFBD> `GenerateByRegion()` <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
- `GenerateByRows()`<60><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> request/context <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ֱ<EFBFBD>Ӵ<EFBFBD><D3B4>ж<EFBFBD><D0B6><EFBFBD>չ<EFBFBD><D5B9>Ϊ<EFBFBD><CEAA><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ϻ<EFBFBD><CFBA><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Խ׶<D4BD>
## 5. Ԥ<><D4A4><EFBFBD><EFBFBD><EFBFBD>׶ν<D7B6><CEBD><EFBFBD>
### 5.1 <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
`DieTransferPlanningContext.Create()` <20><><EFBFBD>Ȱ<EFBFBD> `request.DieRegion` <20><> `request.SubstrateRegion` ת<><D7AA> `DieTransferRegion`<60><>
`DieTransferRegion.Contains(row, column)` <20><><EFBFBD><EFBFBD><EFBFBD>жϵ<D0B6><CFB5>Ƿ<EFBFBD><C7B7><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ڡ<EFBFBD>
<EFBFBD><EFBFBD>ǰ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>£<EFBFBD>
- <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ϊ<EFBFBD>գ<EFBFBD><D5A3><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
- <20><><EFBFBD><EFBFBD>Ϊ<EFBFBD>գ<EFBFBD><D5A3><EFBFBD>Ϊ<EFBFBD><CEAA><EFBFBD><EFBFBD><EFBFBD>ˣ<EFBFBD><CBA3><EFBFBD><EFBFBD>к<EFBFBD>ѡ<EFBFBD><D1A1><EFBFBD><EFBFBD><EFBFBD>ɲ<EFBFBD><C9B2><EFBFBD><EFBFBD>
<EFBFBD><EFBFBD>һ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʵ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ģ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ĵ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ӿ<EFBFBD>ע<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ȷ˵<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ϊ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>һ<EFBFBD><EFBFBD>ҵ<EFBFBD><EFBFBD>Լ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>
### 5.2 <20><><EFBFBD>з<EFBFBD><D0B7><EFBFBD>
Pad <20><> Die <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ֱ<EFBFBD><D6B1><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>򣬶<EFBFBD><F2A3ACB6><EFBFBD><EFBFBD>Ȱ<EFBFBD> `Row` <20><><EFBFBD><EFBFBD><E9A3AC><EFBFBD><EFBFBD>ÿһ<C3BF><D2BB><EFBFBD>ڲ<EFBFBD><DAB2><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
Pad ͨ<><CDA8> `CreatePadRows()` <20><><EFBFBD><EFBFBD> `PadTransferRow`<60><>
- <20>ȹ<EFBFBD><C8B9>˿ն<CBBF><D5B6><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
- <20><> `Row` <20><><EFBFBD><EFBFBD>
- ÿ<>鰴 `Column` <20><><EFBFBD>򱣴<EFBFBD>ԭʼ<D4AD><CABC><EFBFBD><EFBFBD>
- <20>ٸ<EFBFBD><D9B8>ݲ<EFBFBD><DDB2>Ծ<EFBFBD><D4BE><EFBFBD><EFBFBD><EFBFBD>ǰ<EFBFBD><C7B0><EFBFBD><EFBFBD><EFBFBD>ն<EFBFBD>ȡ<EFBFBD><C8A1><EFBFBD><EFBFBD>
Die ͨ<><CDA8> `CreateDieRows()` <20><><EFBFBD><EFBFBD> `DieTransferRow`<60><>
- <20>ȹ<EFBFBD><C8B9>˿ն<CBBF><D5B6><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
- <20><> `Row` <20><><EFBFBD><EFBFBD>
- ÿ<>鰴 `Column` <20><><EFBFBD>򱣴<EFBFBD>
- <20>з<EFBFBD><D0B7><EFBFBD><EFBFBD>̶<EFBFBD><CCB6><EFBFBD><EFBFBD><EFBFBD><EFBFBD>η<EFBFBD>ʽ<EFBFBD><CABD><EFBFBD><EFBFBD>
- `SkipNgDie` <20><><EFBFBD>ж<EFBFBD><D0B6><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ч
### 5.3 <20>з<EFBFBD><D0B7><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
Pad <20><><EFBFBD>з<EFBFBD><D0B7><EFBFBD><EFBFBD><EFBFBD> `SubstrateRowDirectionStrategy` <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
- `AllPositive`<60><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ж<EFBFBD><D0B6><EFBFBD>С<EFBFBD>е<EFBFBD><D0B5><EFBFBD><EFBFBD><EFBFBD>
- `AllNegative`<60><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ж<EFBFBD><D0B6>Ӵ<EFBFBD><D3B4>е<EFBFBD>С<EFBFBD><D0A1>
- `Serpentine`<60><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ż<EFBFBD><C5BC><EFBFBD>з<EFBFBD><D0B7><EFBFBD>
Die <20><><EFBFBD>з<EFBFBD><D0B7><EFBFBD><EFBFBD><EFBFBD>ǰ<EFBFBD>̶<EFBFBD><CCB6><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ι<EFBFBD><CEB9><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ϊ `CreateDieRows()` <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʱ `useSerpentineDirection` <20>̶<EFBFBD><CCB6><EFBFBD><EFBFBD><EFBFBD> `true`<60><>
- <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
- ż<><C5BC><EFBFBD>з<EFBFBD><D0B7><EFBFBD>
<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ζ<EFBFBD>ŵ<EFBFBD>ǰ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Die <20>ı<EFBFBD><C4B1><EFBFBD>˳<EFBFBD><CBB3><EFBFBD><EFBFBD> Pad <20><><EFBFBD><EFBFBD>ǿԼ<C7BF><D4BC><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>÷<EFBFBD><C3B7>޷<EFBFBD><DEB7><EFBFBD> request <20>е<EFBFBD><D0B5><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> Die <20>з<EFBFBD><D0B7><EFBFBD><EFBFBD><EFBFBD>
### 5.4 <20><><EFBFBD>õ<EFBFBD><C3B5><EFBFBD>ȡ
<EFBFBD>ڷ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ɺ<EFBFBD><EFBFBD><EFBFBD>context ͨ<><CDA8><EFBFBD><EFBFBD><EFBFBD>·<EFBFBD><C2B7><EFBFBD>չƽ<D5B9><C6BD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>б<EFBFBD><D0B1><EFBFBD>
- `GetOrderedPads()`
- `GetOrderedDies()`
<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ᰴ `RowIndex` <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>У<EFBFBD><D0A3><EFBFBD>ƴ<EFBFBD><C6B4>ÿ<EFBFBD>еĿ<D0B5><C4BF>õ<EFBFBD><C3B5><EFBFBD><EFBFBD>С<EFBFBD>
<EFBFBD><EFBFBD><EFBFBD><EFBFBD> Die <20><><EFBFBD>ġ<EFBFBD><C4A1><EFBFBD><EFBFBD>á<EFBFBD><C3A1><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> `SkipNgDie` Ӱ<>
- `SkipNgDie = true` ʱ<><CAB1>`DieStatus.Ng` <20><EFBFBD>ų<EFBFBD>
- `SkipNgDie = false` ʱ<><CAB1><EFBFBD><EFBFBD><EFBFBD><EFBFBD> Die <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
<EFBFBD><EFBFBD><EFBFBD>ˣ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ɵIJ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> request <20><><EFBFBD><EFBFBD>ԭʼ<D4AD><CABC>ѡ<EFBFBD><D1A1><EFBFBD>ϣ<EFBFBD><CFA3><EFBFBD><EFBFBD>ǡ<EFBFBD><C7A1><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ˡ<EFBFBD><CBA1><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>NG <20><><EFBFBD>˺<EFBFBD><CBBA><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>С<EFBFBD><D0A1><EFBFBD>
## 6. <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ɷ<EFBFBD><C9B7><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
### 6.1 ˳<><CBB3><EFBFBD><EFBFBD><EFBFBD><EFBFBD> `BuildSequenceSteps`
<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ֱ<EFBFBD>ӵIJ<EFBFBD><EFBFBD>ԡ<EFBFBD>
<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʽ<EFBFBD><EFBFBD>
1. <20>ȵõ<C8B5> `orderedDies` <20><> `orderedPads`
2. ȡ `Math.Min(dies.Count, pads.Count)` <20><>Ϊ<EFBFBD><CEAA><EFBFBD><EFBFBD><EFBFBD>ɲ<EFBFBD><C9B2><EFBFBD>
3. <20><> `i` <20><> Die <20><><EFBFBD><EFBFBD> `i` <20><> Pad ֱ<><D6B1><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
4. <20><><EFBFBD><EFBFBD> `CreateStep()` <20><><EFBFBD>ɲ<EFBFBD><C9B2><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
α<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>£<EFBFBD>
```text
stepCount = min(orderedDies.Count, orderedPads.Count)
for i in [0 .. stepCount - 1]
step = CreateStep(i + 1, orderedDies[i], orderedPads[i])
steps.Add(step)
```
<EFBFBD>ò<EFBFBD><EFBFBD>Ե<EFBFBD><EFBFBD>ص<EFBFBD><EFBFBD>ǣ<EFBFBD>
- <20><>ȫ<EFBFBD><C8AB><EFBFBD><EFBFBD>Ԥ<EFBFBD><D4A4><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>˳<EFBFBD><CBB3>
- <20><EFBFBD>򵥣<EFBFBD><F2B5A5A3><EFBFBD><EFBFBD>Ӷȵ<D3B6>
- <20><><EFBFBD><EFBFBD><EFBFBD>ȶ<EFBFBD><C8B6><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>׷<EFBFBD><D7B7>
- <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʵ<EFBFBD>ʼ<EFBFBD><CABC>ξ<EFBFBD><CEBE>룬ֻ<EBA3AC><D6BB><EFBFBD><EFBFBD><EFBFBD>ź<EFBFBD><C5BA><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ķ<EFBFBD>Ӧ<EFBFBD><D3A6>ϵ
<EFBFBD><EFBFBD><EFBFBD>ó<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
- <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ĸ<EFBFBD><C4B8><EFBFBD><EFBFBD><EFBFBD>˳<EFBFBD><CBB3>һ<EFBFBD><D2BB><EFBFBD><EFBFBD>
- <20><><EFBFBD><EFBFBD><EFBFBD>Ѿ<EFBFBD><D1BE><EFBFBD>֤ Die / Pad <20><><EFBFBD><EFBFBD>һһ<D2BB><D2BB>Ӧ
- ϣ<><CFA3>·<EFBFBD><C2B7><EFBFBD><EFBFBD>Ԥ<EFBFBD><EFBFBD><E2A1A2><EFBFBD><EFBFBD>У<EFBFBD><D0A3><EFBFBD>͸<EFBFBD><CDB8><EFBFBD>
### 6.2 <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> `BuildNearestSteps`
<EFBFBD><EFBFBD><EFBFBD>Ǹ<EFBFBD>ƫ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ż<EFBFBD><EFBFBD>IJ<EFBFBD><EFBFBD>ԡ<EFBFBD>
<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʽ<EFBFBD><EFBFBD>
1. <20>ȸ<EFBFBD><C8B8><EFBFBD>һ<EFBFBD><D2BB> `remainingDies`
2. <20><> Pad <20>ļȶ<C4BC>˳<EFBFBD><CBB3><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ÿ<EFBFBD><C3BF> Pad
3. <20>ڵ<EFBFBD>ǰʣ<C7B0><CAA3> Die <20>У<EFBFBD><D0A3>ҳ<EFBFBD><D2B3><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> Pad <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> Die
4. <20><><EFBFBD><EFBFBD>һ<EFBFBD><D2BB><EFBFBD><EFBFBD><EFBFBD>Ժ󣬰Ѹ<F3A3ACB0> Die <20><> `remainingDies` <20><><EFBFBD>Ƴ<EFBFBD>
5. <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>һ<EFBFBD><D2BB> Pad<61><64>ֱ<EFBFBD><D6B1> Die <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> Pad <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
α<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>£<EFBFBD>
```text
remainingDies = orderedDies
for each pad in orderedPads
if remainingDies is empty
break
die = SelectNearestDie(pad, remainingDies)
steps.Add(CreateStep(stepIndex, die, pad))
remainingDies.Remove(die)
stepIndex++
```
<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Բ<EFBFBD><EFBFBD><EFBFBD>ȫ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ƥ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ǡ<EFBFBD><EFBFBD><EFBFBD> Pad ˳<><CBB3><EFBFBD><EFBFBD><EFBFBD><EFBFBD>̰<EFBFBD><CCB0>ѡ<EFBFBD><D1A1><EFBFBD><EFBFBD><EFBFBD><EFBFBD> Die<69><65><EFBFBD><EFBFBD>
<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ŵ<EFBFBD><EFBFBD>ǣ<EFBFBD>
- ʵ<>ּ<EFBFBD><D6BC><EFBFBD>
- <20>Ծֲ<D4BE><D6B2>ƶ<EFBFBD><C6B6><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ż<EFBFBD><C5BB><EFBFBD><EFBFBD><EFBFBD>
- <20><><EFBFBD><EFBFBD>ȫ˳<C8AB><CBB3><EFBFBD><EFBFBD><EFBFBD>Ը<EFBFBD><D4B8><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ռ<EFBFBD>λ<EFBFBD><CEBB>
<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ҳ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ȷ<EFBFBD><EFBFBD>
- <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>һ<E3B7A8><D2BB><EFBFBD><EFBFBD>ȫ<EFBFBD><C8AB><EFBFBD><EFBFBD><EFBFBD>Ž<EFBFBD>
- ǰ<><C7B0> Pad <20><>ѡ<EFBFBD><D1A1><EFBFBD><EFBFBD>Ӱ<EFBFBD><D3B0><EFBFBD><EFBFBD><EFBFBD><EFBFBD> Pad <20>Ŀ<EFBFBD>ѡ Die
- <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>·<EFBFBD>̲<EFBFBD>һ<EFBFBD><D2BB><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
<EFBFBD><EFBFBD><EFBFBD>ˣ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ԡ<EFBFBD><EFBFBD><EFBFBD>׼ȷ<EFBFBD>ı<EFBFBD><EFBFBD><EFBFBD>Ӧ<EFBFBD><EFBFBD><EFBFBD>ǣ<EFBFBD>
- <20><> Pad ˳<><CBB3>ִ<EFBFBD>еľֲ<C4BE>̰<EFBFBD><CCB0><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ƥ<EFBFBD><C6A5>
### 6.3 <20><><EFBFBD><EFBFBD> Die <20><>ѡȡ<D1A1><C8A1><EFBFBD><EFBFBD> `SelectNearestDie`
`SelectNearestDie()` <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ǰ<EFBFBD><C7B0><EFBFBD><EFBFBD>ʣ<EFBFBD><CAA3> Die<69><65><EFBFBD><EFBFBD>ѡ<EFBFBD><D1A1><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>С<EFBFBD><D0A1><EFBFBD>Ǹ<EFBFBD><C7B8><EFBFBD>
<EFBFBD><EFBFBD>ǰ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʽΪ<EFBFBD><EFBFBD>
```text
(die.X - pad.X)^2 + (die.Y - pad.Y)^2
```
<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ص<EFBFBD><EFBFBD><EFBFBD>ƽ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ǿ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ŷ<EFBFBD>Ͼ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ڡ<EFBFBD><EFBFBD>Ƚ<EFBFBD>˭<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ƽ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ǵȼ۵ģ<EFBFBD><EFBFBD>Ҽ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʡ<EFBFBD><EFBFBD>
<EFBFBD><EFBFBD>Ҫע<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
1. `CalculateDistance()` <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ȷ<EFBFBD><C8B7>ʵ<EFBFBD>ʸ<EFBFBD><CAB8><EFBFBD> `CalculateSquaredDistance()`
2. <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʱ<EFBFBD><CAB1><EFBFBD><EFBFBD>ǰ<EFBFBD><C7B0><EFBFBD><EFBFBD><EBB0B4><EFBFBD>ȱ<EFBFBD><C8B1><EFBFBD><EFBFBD><EFBFBD>˭<EFBFBD>ͱ<EFBFBD><CDB1><EFBFBD>˭<EFBFBD><CBAD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
<EFBFBD>ڶ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ҫ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
- <20><>ǰ tie-break <20><><EFBFBD><EFBFBD>ֱ<EFBFBD>Ӱ<EFBFBD> `Row`<60><>`Column` <20>Ƚ<EFBFBD>
- <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> `remainingDies` <20>ĵ<EFBFBD>ǰ˳<C7B0><CBB3>
- <20><> `remainingDies` <20><>˳<EFBFBD><CBB3><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> Die <20>е<EFBFBD><D0B5><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>֯<EFBFBD><D6AF><EFBFBD><EFBFBD>
Ҳ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>˵<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> Die <20><>ͬһ<CDAC><D2BB> Pad <20>Ⱦ<EFBFBD>ʱ<EFBFBD><CAB1><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʤ<EFBFBD><CAA4><EFBFBD>߱<EFBFBD><DFB1><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ɡ<EFBFBD>Die Ԥ<><D4A4><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>˳<EFBFBD>򡱾<EFBFBD><F2A1B1BE><EFBFBD><EFBFBD><EFBFBD>
## 7. ʣ<><CAA3><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ɷ<EFBFBD>ʽ
·<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ɺ<EFBFBD><EFBFBD><EFBFBD>`GenerateByRegion()` <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>һ<EFBFBD>㡰ʣ<E3A1B0><CAA3>״̬<D7B4><CCAC>ȡ<EFBFBD><C8A1><EFBFBD><EFBFBD>
<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>˵<EFBFBD><EFBFBD>ʣ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ɹ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ֱ<EFBFBD><EFBFBD>ǣ<EFBFBD>
- `GenerateByCandidates()`<60><><EFBFBD><EFBFBD> `GenerateByRegion()` <20><>ȫһ<C8AB>£<EFBFBD><C2A3><EFBFBD>Ϊ<EFBFBD>ڲ<EFBFBD><DAB2><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>װ request <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
- `GenerateByRows()`<60><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>÷<EFBFBD><C3B7><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ж<EFBFBD><D0B6><EFBFBD><EFBFBD>е<EFBFBD> `RowIndex`<60><>`Direction`<60><>`SkipNgDie` <20><><EFBFBD>м<EFBFBD><D0BC><EFBFBD><EFBFBD>ã<EFBFBD>ֻ<EFBFBD><D6BB><EFBFBD>˵<EFBFBD><CBB5><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʹ<EFBFBD>õ<EFBFBD>λ<EFBFBD><CEBB><EFBFBD>ٹ<EFBFBD><D9B9><EFBFBD> `RemainingPadRows` / `RemainingDieRows`
### 7.1 ʣ<><CAA3> Die / Pad <20><><EFBFBD><EFBFBD>
ͨ<EFBFBD><EFBFBD> `CreateRemainingPads()` <20><> `CreateRemainingDies()`<60><>
- <20>Ӳ<EFBFBD><D3B2><EFBFBD><EFBFBD>б<EFBFBD><D0B1><EFBFBD><EFBFBD><EFBFBD>ȡ<EFBFBD>Ѿ<EFBFBD>ʹ<EFBFBD>ù<EFBFBD><C3B9><EFBFBD> `(row, column)` <20><>
- <20><>ԭ<EFBFBD><D4AD><EFBFBD><EFBFBD><EFBFBD>򼯺<EFBFBD><F2BCAFBA><EFBFBD><EFBFBD>
- <20>õ<EFBFBD>δ<EFBFBD><CEB4><EFBFBD><EFBFBD>ֹ滮<D6B9>ĵ<EFBFBD>
<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʹ<EFBFBD><EFBFBD> `(row, column)` <20><>ΪΨһ<CEA8><D2BB><EFBFBD><EFBFBD>˵<EFBFBD><CBB5><EFBFBD><EFBFBD>ǰģ<C7B0><C4A3>Ĭ<EFBFBD><C4AC>һ<EFBFBD><D2BB><EFBFBD><EFBFBD>λ<EFBFBD><CEBB><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ψһ<CEA8><D2BB>ʶ<EFBFBD><CAB6>
### 7.2 ʣ<><CAA3><EFBFBD>нṹ<D0BD>ؽ<EFBFBD>
ʣ<EFBFBD><EFBFBD> Pad / Die <20><><EFBFBD><EFBFBD>ֻ<EFBFBD>Ǽ򵥷<C7BC><F2B5A5B7><EFBFBD><EFBFBD>б<EFBFBD><D0B1><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ɣ<EFBFBD>
- `RemainingPadRows`
- `RemainingDieRows`
<EFBFBD><EFBFBD><EFBFBD>dz<EFBFBD><EFBFBD>м<EFBFBD>ֵ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ϊ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ҫ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ι<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ҫ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ȫ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ݽṹ<EFBFBD><EFBFBD>
### 7.3 ʣ<><CAA3><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ؽ<EFBFBD>
`CreateRegionFromPads()` <20><> `CreateRegionFromDies()` <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʣ<EFBFBD><CAA3><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>¼<EFBFBD><C2BC><EFBFBD><EFBFBD><EFBFBD>С<EFBFBD><D0A1>Χ<EFBFBD><CEA7><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
- <20><>С<EFBFBD><D0A1>
- <20><>С<EFBFBD><D0A1>
- <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
- <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
<EFBFBD><EFBFBD><EFBFBD><EFBFBD>û<EFBFBD><EFBFBD>ʣ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>򷵻<EFBFBD> `null`<60><>
<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>õ<EFBFBD><EFBFBD>÷<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>жϣ<EFBFBD>
- <20><>ǰ<EFBFBD>Ƿ<EFBFBD><C7B7><EFBFBD>ȫ<EFBFBD><C8AB><EFBFBD><EFBFBD><E6BBAE><EFBFBD><EFBFBD>
- <20><>ʣ<EFBFBD><CAA3><EFBFBD><EFBFBD>һƬ<D2BB><C6AC><EFBFBD><EFBFBD>δ<EFBFBD><CEB4><EFBFBD><EFBFBD>
## 8. <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ľ<EFBFBD><C4BD><EFBFBD>
### 8.1 <20>ŵ<EFBFBD>
<EFBFBD><EFBFBD>ģ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ŵ<EFBFBD><EFBFBD>Ƚ<EFBFBD><EFBFBD><EFBFBD>ȷ<EFBFBD><EFBFBD>
- ְ<><D6B0><EFBFBD><EFBFBD>һ<EFBFBD><D2BB>רע<D7A8>ڹ滮<DAB9><E6BBAE><EFBFBD><EFBFBD>ִ<EFBFBD><D6B4>
- request / context / result <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><E1B9B9><EFBFBD><EFBFBD>
- ˳<><CBB3><EFBFBD><EFBFBD><EFBFBD>Ժ<EFBFBD><D4BA><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ա߽<D4B1><DFBD><EFBFBD>ȷ
- ʣ<><CAA3><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ǿ<EFBFBD>˸<EFBFBD><CBB8><EFBFBD><EFBFBD><EFBFBD>
- <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ɶ<EFBFBD><C9B6>ԽϺã<CFBA><C3A3><EFBFBD>չ<EFBFBD><D5B9><EFBFBD><EFBFBD>Ҳ<EFBFBD>Ƚ<EFBFBD><C8BD><EFBFBD><EFBFBD><EFBFBD>
### 8.2 <20><>Ҫע<D2AA><D7A2><EFBFBD>ĵ<EFBFBD>
<EFBFBD><EFBFBD>ǰʵ<EFBFBD><EFBFBD>û<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Թ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ȱ<EFBFBD>ݣ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>м<EFBFBD><EFBFBD><EFBFBD>ά<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ע<EFBFBD><EFBFBD><EFBFBD>
1. `CalculateDistance()` ʵ<><CAB5><EFBFBD><EFBFBD>ƽ<EFBFBD><C6BD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EBA3AC><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ע<EFBFBD><D7A2>
2. <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ǿֲ<C7BE>̰<EFBFBD>ģ<EFBFBD><C4A3><EFBFBD><EFBFBD><EFBFBD>ȫ<EFBFBD><C8AB><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ƥ<EFBFBD><EFBFBD><E4A3AC><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ĵ<EFBFBD><C4B5><EFBFBD><EFBFBD><EFBFBD>ȷ
3. <20>Ⱦ<EFBFBD>ʱ<EFBFBD><CAB1>ѡ<EFBFBD><D1A1><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> Die Ԥ<><D4A4><EFBFBD><EFBFBD>˳<EFBFBD>򣬽<EFBFBD><F2A3ACBD><EFBFBD><EFBFBD><EFBFBD>ȷд<C8B7><D0B4>˵<EFBFBD><CBB5>
4. `AvailableDieCount` / `AvailablePadCount` <20><>ʾ<EFBFBD><CABE><EFBFBD>˺<EFBFBD><CBBA>Ŀ<EFBFBD><C4BF><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ԭʼ<D4AD><CABC>ѡ<EFBFBD><D1A1>
5. <20><><EFBFBD><EFBFBD>Ϊ `null` ʱ<><CAB1>ʾ<EFBFBD><CABE><EFBFBD><EFBFBD><EFBFBD>ˣ<EFBFBD><CBA3><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʽԼ<CABD><D4BC><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><E9B2B9>˵<EFBFBD><CBB5>
6. `Generate()` <20><><EFBFBD>ػ<EFBFBD><D8BB><EFBFBD><E0A3AC>ʵ<EFBFBD><CAB5><EFBFBD>ڲ<EFBFBD><DAB2><EFBFBD><EFBFBD>ɵ<EFBFBD><C9B5><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ƻ<EFBFBD><C6BB><EFBFBD><EFBFBD>󣬵<EFBFBD><F3A3ACB5>÷<EFBFBD><C3B7><EFBFBD><EFBFBD><EFBFBD>ȷ<EFBFBD>Լ<EFBFBD><D4BC>Ƿ<EFBFBD><C7B7><EFBFBD>Ҫʣ<D2AA><CAA3><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ϣ
### 8.3 <20>ɸĽ<C9B8><C4BD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ع<EFBFBD><D8B9>ĵ<EFBFBD>
<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ڣ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ϊ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ģ<EFBFBD>
- <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ǿ<EFBFBD>дģ<D0B4>ͣ<EFBFBD><CDA3><EFBFBD><EFBFBD>ڱ<EFBFBD><DAB1>ⲿ<EFBFBD>޸ĵĿ<C4B5><C4BF><EFBFBD>
- `DieTransferPathGenerator` <20>б<EFBFBD><D0B1><EFBFBD><EFBFBD><EFBFBD>δ<EFBFBD><CEB4>ʹ<EFBFBD>õ<EFBFBD> `OrderDies()` / `OrderPads()` ˽<>з<EFBFBD><D0B7><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ں<EFBFBD><DABA><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
- <20><><EFBFBD><EFBFBD><EFBFBD>ռ<EFBFBD><D5BC><EFBFBD>ͳһʹ<D2BB><CAB9> `MainShell.Process`<60><><EFBFBD><EFBFBD>Ŀ¼<C4BF><C2BC><EFBFBD>β<EFBFBD><CEB2><EFBFBD><EFBFBD><EFBFBD>ȫһһ<D2BB><D2BB>Ӧ<EFBFBD><D3A6><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ϵ<EFBFBD>ǰ<EFBFBD>ֿ<EFBFBD><D6BF><EFBFBD><EFBFBD><EFBFBD>
## 9. <20>ܽ<EFBFBD>
Planning ģ<><C4A3><EFBFBD>ĺ<EFBFBD><C4BA><EFBFBD>˼·<CBBC><C2B7><EFBFBD>Ը<EFBFBD><D4B8><EFBFBD>Ϊһ<CEAA><EFBFBD><E4BBB0>
<EFBFBD>ȰѺ<EFBFBD>ѡ Die / Pad <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>з<EFBFBD><D0B7><EFBFBD><EFBFBD><EFBFBD>NG <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ȶ<EFBFBD>˳<EFBFBD><CBB3><EFBFBD><EFBFBD><EFBFBD>ٰ<EFBFBD><D9B0><EFBFBD>˳<EFBFBD><CBB3><EFBFBD><EFBFBD><EFBFBD>ԡ<EFBFBD><D4A1>򡰾ֲ<F2A1B0BE>̰<EFBFBD><CCB0><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ԡ<EFBFBD><D4A1><EFBFBD><EFBFBD><EFBFBD> `DieTransferPathStep` <20>б<EFBFBD><D0B1><EFBFBD><EFBFBD><EFBFBD><EFBFBD>󲹳<EFBFBD>ʣ<EFBFBD><CAA3><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʣ<EFBFBD><CAA3><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ϣ<EFBFBD><CFA2>
<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ӿ<EFBFBD>ά<EFBFBD><EFBFBD><EFBFBD>Կ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʵ<EFBFBD><EFBFBD><EFBFBD>Ѿ<EFBFBD><EFBFBD>߱<EFBFBD><EFBFBD>ϺõĻ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ǰ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ҫ<EFBFBD><EFBFBD><EFBFBD>ǰѲ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ع<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ϊ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ĵ<EFBFBD><EFBFBD><EFBFBD>ע<EFBFBD>͵Ĺ̶<EFBFBD>˵<EFBFBD><EFBFBD><EFBFBD><EFBFBD>
- <20><><EFBFBD><EFBFBD>ģʽ<C4A3>Ǿֲ<C7BE>̰<EFBFBD>ģ<EFBFBD><C4A3><EFBFBD><EFBFBD><EFBFBD>ȫ<EFBFBD><C8AB><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
- <20><><EFBFBD><EFBFBD><EFBFBD>Ƚ<EFBFBD>ʹ<EFBFBD><CAB9>ƽ<EFBFBD><C6BD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
- <20>Ⱦ<EFBFBD>ʱ<EFBFBD><CAB1>ѭ Die Ԥ<><D4A4><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ⱥ<EFBFBD>˳<EFBFBD><CBB3>

View File

@@ -0,0 +1,347 @@
using MainShell.Common;
using MainShell.Models.Wafer;
using MainShell.Recipe.BaseBoard.Model;
using System;
using System.Collections.Generic;
using System.Linq;
namespace MainShell.Process
{
public class DieTransferPathGenerator : IDieTransferPathGenerator
{
public DieTransferPathPlan Generate(DieTransferPathRequest request)
{
return GenerateByRegion(request);
}
public DieTransferPathRegionPlan GenerateByRegion(DieTransferPathRequest request)
{
if (request == null)
{
throw new ArgumentNullException(nameof(request));
}
DieTransferPlanningContext planningContext = DieTransferPlanningContext.Create(request);
int effectiveCount = Math.Min(planningContext.AvailablePadCount, planningContext.AvailableDieCount);
List<PadTransferRow> remainingPadRows;
List<DieTransferRow> remainingDieRows;
List<PadTransferRow> activePadRows = DieTransferPlanningContext.TrimPadRows(planningContext.PadRows, effectiveCount, out remainingPadRows);
List<DieTransferRow> activeDieRows = DieTransferPlanningContext.TrimDieRows(planningContext.DieRows, effectiveCount, out remainingDieRows);
DieTransferPathRegionPlan pathPlan = GenerateByRows(activePadRows, activeDieRows, planningContext.TransPathType);
List<Pad> remainingPads = GetOrderedPads(remainingPadRows);
List<Die> remainingDies = GetOrderedDies(remainingDieRows);
pathPlan.AvailableDieCount = planningContext.AvailableDieCount;
pathPlan.AvailablePadCount = planningContext.AvailablePadCount;
pathPlan.RemainingPads = remainingPads;
pathPlan.RemainingDies = remainingDies;
pathPlan.RemainingPadRows = DieTransferPlanningContext.CreatePadRows(remainingPads, planningContext.SubstrateRegion, planningContext.PadRowDirectionStrategy);
pathPlan.RemainingDieRows = DieTransferPlanningContext.CreateDieRows(remainingDies, planningContext.DieRegion, planningContext.SkipNgDie, planningContext.DieRowDirectionStrategy);
pathPlan.RemainingSubstrateRegion = CreateRegionFromPads(remainingPads);
pathPlan.RemainingDieRegion = CreateRegionFromDies(remainingDies);
return pathPlan;
}
public DieTransferPathRegionPlan GenerateByCandidates(
IReadOnlyCollection<Pad> padCandidates,
IReadOnlyCollection<Die> dieCandidates,
TransPathType transPathType,
bool skipNgDie,
DieTransferRowTraversalStrategy padRowDirectionStrategy,
DieTransferRowTraversalStrategy dieRowDirectionStrategy)
{
DieTransferPathRequest request = new DieTransferPathRequest();
request.PadCandidates = padCandidates ?? Array.Empty<Pad>();
request.DieCandidates = dieCandidates ?? Array.Empty<Die>();
request.TransPathType = transPathType;
request.SkipNgDie = skipNgDie;
request.PadRowDirectionStrategy = padRowDirectionStrategy;
request.DieRowDirectionStrategy = dieRowDirectionStrategy;
return GenerateByRegion(request);
}
public DieTransferPathRegionPlan GenerateByRows(
IReadOnlyCollection<PadTransferRow> padRows,
IReadOnlyCollection<DieTransferRow> dieRows,
TransPathType transPathType)
{
IReadOnlyCollection<PadTransferRow> safePadRows = padRows ?? Array.Empty<PadTransferRow>();
IReadOnlyCollection<DieTransferRow> safeDieRows = dieRows ?? Array.Empty<DieTransferRow>();
List<Pad> orderedPads = GetOrderedPads(safePadRows);
List<Die> orderedDies = GetOrderedDies(safeDieRows);
List<DieTransferPathStep> steps = CreateSteps(orderedDies, orderedPads, transPathType);
List<Pad> remainingPads = CreateRemainingPads(orderedPads, steps);
List<Die> remainingDies = CreateRemainingDies(orderedDies, steps);
DieTransferPathRegionPlan pathPlan = new DieTransferPathRegionPlan();
pathPlan.TransPathType = transPathType;
pathPlan.AvailablePadCount = GetAvailablePadCount(safePadRows);
pathPlan.AvailableDieCount = GetAvailableDieCount(safeDieRows);
pathPlan.Steps = steps;
pathPlan.RemainingPads = remainingPads;
pathPlan.RemainingDies = remainingDies;
pathPlan.RemainingPadRows = CreateRemainingPadRows(safePadRows, remainingPads);
pathPlan.RemainingDieRows = CreateRemainingDieRows(safeDieRows, remainingDies);
pathPlan.RemainingSubstrateRegion = CreateRegionFromPads(remainingPads);
pathPlan.RemainingDieRegion = CreateRegionFromDies(remainingDies);
return pathPlan;
}
private static List<DieTransferPathStep> CreateSteps(IReadOnlyList<Die> dies, IReadOnlyList<Pad> pads, TransPathType transPathType)
{
return transPathType == TransPathType.Nearest
? BuildNearestSteps(dies, pads, transPathType)
: BuildSequenceSteps(dies, pads, transPathType);
}
private static List<DieTransferPathStep> BuildSequenceSteps(IReadOnlyList<Die> dies, IReadOnlyList<Pad> pads, TransPathType transPathType)
{
int stepCount = Math.Min(dies.Count, pads.Count);
List<DieTransferPathStep> steps = new List<DieTransferPathStep>(stepCount);
for (int i = 0; i < stepCount; i++)
{
steps.Add(CreateStep(i + 1, dies[i], pads[i], transPathType));
}
return steps;
}
private static List<DieTransferPathStep> BuildNearestSteps(IReadOnlyList<Die> dies, IReadOnlyList<Pad> pads, TransPathType transPathType)
{
List<Die> remainingDies = (dies ?? Array.Empty<Die>()).Where(die => die != null).ToList();
List<DieTransferPathStep> steps = new List<DieTransferPathStep>(Math.Min(remainingDies.Count, pads.Count));
int stepIndex = 1;
foreach (Pad pad in pads)
{
if (remainingDies.Count == 0)
{
break;
}
Die nearestDie = SelectNearestDie(pad, remainingDies);
steps.Add(CreateStep(stepIndex, nearestDie, pad, transPathType));
remainingDies.Remove(nearestDie);
stepIndex++;
}
return steps;
}
private static Die SelectNearestDie(Pad pad, IReadOnlyList<Die> dies)
{
Die selectedDie = null;
double bestDistance = double.MaxValue;
for (int index = 0; index < dies.Count; index++)
{
Die die = dies[index];
double currentDistance = CalculateSquaredDistance(die.X, die.Y, pad.X, pad.Y);
if (currentDistance < bestDistance)
{
selectedDie = die;
bestDistance = currentDistance;
}
}
return selectedDie;
}
private static double CalculateSquaredDistance(double sourceX, double sourceY, double targetX, double targetY)
{
double deltaX = sourceX - targetX;
double deltaY = sourceY - targetY;
return (deltaX * deltaX) + (deltaY * deltaY);
}
private static DieTransferPathStep CreateStep(int stepIndex, Die die, Pad pad, TransPathType transPathType)
{
DieTransferPathStep step = new DieTransferPathStep();
step.StepIndex = stepIndex;
step.DieRow = die.Row;
step.DieColumn = die.Column;
step.PadRow = pad.Row;
step.PadColumn = pad.Column;
step.DieX = die.X;
step.DieY = die.Y;
step.PadX = pad.X;
step.PadY = pad.Y;
step.TransPathType = transPathType;
return step;
}
private static int GetAvailablePadCount(IEnumerable<PadTransferRow> padRows)
{
return (padRows ?? Array.Empty<PadTransferRow>())
.Where(row => row != null)
.Sum(row => row.AvailableCount);
}
private static int GetAvailableDieCount(IEnumerable<DieTransferRow> dieRows)
{
return (dieRows ?? Array.Empty<DieTransferRow>())
.Where(row => row != null)
.Sum(row => row.AvailableCount);
}
private static List<Pad> GetOrderedPads(IEnumerable<PadTransferRow> padRows)
{
List<Pad> orderedPads = new List<Pad>();
foreach (PadTransferRow padRow in (padRows ?? Array.Empty<PadTransferRow>()).Where(row => row != null).OrderBy(row => row.RowIndex))
{
orderedPads.AddRange(padRow.GetAvailablePads());
}
return orderedPads;
}
private static List<Die> GetOrderedDies(IEnumerable<DieTransferRow> dieRows)
{
List<Die> orderedDies = new List<Die>();
foreach (DieTransferRow dieRow in (dieRows ?? Array.Empty<DieTransferRow>()).Where(row => row != null).OrderBy(row => row.RowIndex))
{
orderedDies.AddRange(dieRow.GetAvailableDies());
}
return orderedDies;
}
private static List<PadTransferRow> CreateRemainingPadRows(IEnumerable<PadTransferRow> sourceRows, IReadOnlyCollection<Pad> remainingPads)
{
HashSet<string> remainingPadKeys = CreatePointKeys(remainingPads, pad => pad.Row, pad => pad.Column);
List<PadTransferRow> remainingPadRows = new List<PadTransferRow>();
foreach (PadTransferRow sourceRow in (sourceRows ?? Array.Empty<PadTransferRow>()).Where(row => row != null).OrderBy(row => row.RowIndex))
{
List<Pad> rowPads = (sourceRow.Pads ?? new List<Pad>())
.Where(pad => pad != null && remainingPadKeys.Contains(CreatePointKey(pad.Row, pad.Column)))
.OrderBy(pad => pad.Column)
.ToList();
if (rowPads.Count == 0)
{
continue;
}
PadTransferRow remainingRow = new PadTransferRow();
remainingRow.RowIndex = sourceRow.RowIndex;
remainingRow.Direction = sourceRow.Direction;
remainingRow.Pads = rowPads;
remainingPadRows.Add(remainingRow);
}
return remainingPadRows;
}
private static List<DieTransferRow> CreateRemainingDieRows(IEnumerable<DieTransferRow> sourceRows, IReadOnlyCollection<Die> remainingDies)
{
HashSet<string> remainingDieKeys = CreatePointKeys(remainingDies, die => die.Row, die => die.Column);
List<DieTransferRow> remainingDieRows = new List<DieTransferRow>();
foreach (DieTransferRow sourceRow in (sourceRows ?? Array.Empty<DieTransferRow>()).Where(row => row != null).OrderBy(row => row.RowIndex))
{
List<Die> rowDies = (sourceRow.Dies ?? new List<Die>())
.Where(die => die != null && remainingDieKeys.Contains(CreatePointKey(die.Row, die.Column)))
.OrderBy(die => die.Column)
.ToList();
if (rowDies.Count == 0)
{
continue;
}
DieTransferRow remainingRow = new DieTransferRow();
remainingRow.RowIndex = sourceRow.RowIndex;
remainingRow.Direction = sourceRow.Direction;
remainingRow.SkipNgDie = sourceRow.SkipNgDie;
remainingRow.Dies = rowDies;
remainingDieRows.Add(remainingRow);
}
return remainingDieRows;
}
private static HashSet<string> CreatePointKeys<TPoint>(IEnumerable<TPoint> points, Func<TPoint, int> getRow, Func<TPoint, int> getColumn)
where TPoint : class
{
HashSet<string> pointKeys = new HashSet<string>();
foreach (TPoint point in points ?? Array.Empty<TPoint>())
{
if (point == null)
{
continue;
}
pointKeys.Add(CreatePointKey(getRow(point), getColumn(point)));
}
return pointKeys;
}
private static List<Pad> CreateRemainingPads(IReadOnlyList<Pad> orderedPads, IReadOnlyList<DieTransferPathStep> steps)
{
HashSet<string> usedPadKeys = new HashSet<string>();
foreach (DieTransferPathStep step in steps ?? Array.Empty<DieTransferPathStep>())
{
usedPadKeys.Add(CreatePointKey(step.PadRow, step.PadColumn));
}
return (orderedPads ?? Array.Empty<Pad>())
.Where(pad => pad != null && !usedPadKeys.Contains(CreatePointKey(pad.Row, pad.Column)))
.ToList();
}
private static List<Die> CreateRemainingDies(IReadOnlyList<Die> orderedDies, IReadOnlyList<DieTransferPathStep> steps)
{
HashSet<string> usedDieKeys = new HashSet<string>();
foreach (DieTransferPathStep step in steps ?? Array.Empty<DieTransferPathStep>())
{
usedDieKeys.Add(CreatePointKey(step.DieRow, step.DieColumn));
}
return (orderedDies ?? Array.Empty<Die>())
.Where(die => die != null && !usedDieKeys.Contains(CreatePointKey(die.Row, die.Column)))
.ToList();
}
private static string CreatePointKey(int row, int column)
{
return $"{row}:{column}";
}
private static DieTransferRegion CreateRegionFromPads(IEnumerable<Pad> pads)
{
List<Pad> availablePads = (pads ?? Array.Empty<Pad>()).Where(pad => pad != null).ToList();
if (availablePads.Count == 0)
{
return null;
}
DieTransferRegion region = new DieTransferRegion();
region.StartRow = availablePads.Min(pad => pad.Row);
region.StartCol = availablePads.Min(pad => pad.Column);
region.EndRow = availablePads.Max(pad => pad.Row);
region.EndCol = availablePads.Max(pad => pad.Column);
return region;
}
private static DieTransferRegion CreateRegionFromDies(IEnumerable<Die> dies)
{
List<Die> availableDies = (dies ?? Array.Empty<Die>()).Where(die => die != null).ToList();
if (availableDies.Count == 0)
{
return null;
}
DieTransferRegion region = new DieTransferRegion();
region.StartRow = availableDies.Min(die => die.Row);
region.StartCol = availableDies.Min(die => die.Column);
region.EndRow = availableDies.Max(die => die.Row);
region.EndCol = availableDies.Max(die => die.Column);
return region;
}
}
}

View File

@@ -0,0 +1,30 @@
using MainShell.Common;
using System;
using System.Collections.Generic;
namespace MainShell.Process
{
public class DieTransferPathPlan
{
public DieTransferPathPlan()
{
Steps = Array.Empty<DieTransferPathStep>();
}
public TransPathType TransPathType { get; set; }
public IReadOnlyList<DieTransferPathStep> Steps { get; set; }
public int AvailableDieCount { get; set; }
public int AvailablePadCount { get; set; }
public int GeneratedStepCount
{
get
{
return Steps == null ? 0 : Steps.Count;
}
}
}
}

View File

@@ -0,0 +1,30 @@
using MainShell.Models.Wafer;
using MainShell.Recipe.BaseBoard.Model;
using System;
using System.Collections.Generic;
namespace MainShell.Process
{
public class DieTransferPathRegionPlan : DieTransferPathPlan
{
public DieTransferPathRegionPlan()
{
RemainingDieRows = Array.Empty<DieTransferRow>();
RemainingPadRows = Array.Empty<PadTransferRow>();
RemainingDies = Array.Empty<Die>();
RemainingPads = Array.Empty<Pad>();
}
public DieTransferRegion RemainingDieRegion { get; set; }
public DieTransferRegion RemainingSubstrateRegion { get; set; }
public IReadOnlyList<DieTransferRow> RemainingDieRows { get; set; }
public IReadOnlyList<PadTransferRow> RemainingPadRows { get; set; }
public IReadOnlyList<Die> RemainingDies { get; set; }
public IReadOnlyList<Pad> RemainingPads { get; set; }
}
}

View File

@@ -0,0 +1,38 @@
using MainShell.Common;
using MainShell.Models;
using MainShell.Models.Wafer;
using MainShell.Recipe.BaseBoard.Model;
using System;
using System.Collections.Generic;
namespace MainShell.Process
{
public class DieTransferPathRequest
{
public DieTransferPathRequest()
{
DieCandidates = Array.Empty<Die>();
PadCandidates = Array.Empty<Pad>();
TransPathType = TransPathType.Sequence;
PadRowDirectionStrategy = DieTransferRowTraversalStrategy.AllPositive;
DieRowDirectionStrategy = DieTransferRowTraversalStrategy.Serpentine;
SkipNgDie = true;
}
public IReadOnlyCollection<Die> DieCandidates { get; set; }
public IReadOnlyCollection<Pad> PadCandidates { get; set; }
public RegionModel DieRegion { get; set; }
public RegionModel SubstrateRegion { get; set; }
public TransPathType TransPathType { get; set; }
public DieTransferRowTraversalStrategy PadRowDirectionStrategy { get; set; }
public DieTransferRowTraversalStrategy DieRowDirectionStrategy { get; set; }
public bool SkipNgDie { get; set; }
}
}

View File

@@ -0,0 +1,27 @@
using MainShell.Common;
namespace MainShell.Process
{
public class DieTransferPathStep
{
public int StepIndex { get; set; }
public int DieRow { get; set; }
public int DieColumn { get; set; }
public int PadRow { get; set; }
public int PadColumn { get; set; }
public double DieX { get; set; }
public double DieY { get; set; }
public double PadX { get; set; }
public double PadY { get; set; }
public TransPathType TransPathType { get; set; }
}
}

View File

@@ -0,0 +1,258 @@
using MainShell.Common;
using MainShell.Models;
using MainShell.Models.Wafer;
using MainShell.Recipe.BaseBoard.Model;
using System;
using System.Collections.Generic;
using System.Linq;
namespace MainShell.Process
{
public class DieTransferPlanningContext
{
public DieTransferPlanningContext()
{
PadRows = new List<PadTransferRow>();
DieRows = new List<DieTransferRow>();
TransPathType = TransPathType.Sequence;
PadRowDirectionStrategy = DieTransferRowTraversalStrategy.AllPositive;
DieRowDirectionStrategy = DieTransferRowTraversalStrategy.Serpentine;
SkipNgDie = true;
}
public DieTransferRegion DieRegion { get; set; }
public DieTransferRegion SubstrateRegion { get; set; }
public TransPathType TransPathType { get; set; }
public DieTransferRowTraversalStrategy PadRowDirectionStrategy { get; set; }
public DieTransferRowTraversalStrategy DieRowDirectionStrategy { get; set; }
public bool SkipNgDie { get; set; }
public List<PadTransferRow> PadRows { get; set; }
public List<DieTransferRow> DieRows { get; set; }
public int AvailablePadCount
{
get
{
return PadRows == null ? 0 : PadRows.Sum(row => row.AvailableCount);
}
}
public int AvailableDieCount
{
get
{
return DieRows == null ? 0 : DieRows.Sum(row => row.AvailableCount);
}
}
public List<Pad> GetOrderedPads()
{
List<Pad> pads = new List<Pad>();
if (PadRows == null)
{
return pads;
}
foreach (PadTransferRow row in PadRows.OrderBy(item => item.RowIndex))
{
pads.AddRange(row.GetAvailablePads());
}
return pads;
}
public List<Die> GetOrderedDies()
{
List<Die> dies = new List<Die>();
if (DieRows == null)
{
return dies;
}
foreach (DieTransferRow row in DieRows.OrderBy(item => item.RowIndex))
{
dies.AddRange(row.GetAvailableDies());
}
return dies;
}
public static DieTransferPlanningContext Create(DieTransferPathRequest request)
{
if (request == null)
{
throw new ArgumentNullException(nameof(request));
}
DieTransferPlanningContext context = new DieTransferPlanningContext();
context.DieRegion = DieTransferRegion.FromRegionModel(request.DieRegion);
context.SubstrateRegion = DieTransferRegion.FromRegionModel(request.SubstrateRegion);
context.TransPathType = request.TransPathType;
context.PadRowDirectionStrategy = request.PadRowDirectionStrategy;
context.DieRowDirectionStrategy = request.DieRowDirectionStrategy;
context.SkipNgDie = request.SkipNgDie;
context.PadRows = CreatePadRows(request.PadCandidates, context.SubstrateRegion, context.PadRowDirectionStrategy);
context.DieRows = CreateDieRows(request.DieCandidates, context.DieRegion, request.SkipNgDie, context.DieRowDirectionStrategy);
return context;
}
public static List<PadTransferRow> CreatePadRows(IReadOnlyCollection<Pad> padCandidates, DieTransferRegion region, DieTransferRowTraversalStrategy rowTraversalStrategy)
{
IEnumerable<Pad> filteredPads = (padCandidates ?? Array.Empty<Pad>())
.Where(pad => pad != null && IsInRegion(pad.Row, pad.Column, region));
List<PadTransferRow> rows = new List<PadTransferRow>();
foreach (IGrouping<int, Pad> rowGroup in filteredPads.GroupBy(pad => pad.Row).OrderBy(group => group.Key))
{
PadTransferRow row = new PadTransferRow();
row.RowIndex = rowGroup.Key;
row.Direction = ResolveRowDirection(rowGroup.Key, rowTraversalStrategy);
row.Pads = rowGroup.OrderBy(pad => pad.Column).ToList();
rows.Add(row);
}
return rows;
}
public static List<DieTransferRow> CreateDieRows(IReadOnlyCollection<Die> dieCandidates, DieTransferRegion region, bool skipNgDie, DieTransferRowTraversalStrategy rowTraversalStrategy)
{
IEnumerable<Die> filteredDies = (dieCandidates ?? Array.Empty<Die>())
.Where(die => die != null && IsInRegion(die.Row, die.Column, region));
List<DieTransferRow> rows = new List<DieTransferRow>();
foreach (IGrouping<int, Die> rowGroup in filteredDies.GroupBy(die => die.Row).OrderBy(group => group.Key))
{
DieTransferRow row = new DieTransferRow();
row.RowIndex = rowGroup.Key;
row.Direction = ResolveRowDirection(rowGroup.Key, rowTraversalStrategy);
row.SkipNgDie = skipNgDie;
row.Dies = rowGroup.OrderBy(die => die.Column).ToList();
rows.Add(row);
}
return rows;
}
public static List<PadTransferRow> TrimPadRows(IReadOnlyCollection<PadTransferRow> sourceRows, int targetCount, out List<PadTransferRow> remainingRows)
{
List<PadTransferRow> activeRows = new List<PadTransferRow>();
remainingRows = new List<PadTransferRow>();
int remainingCount = Math.Max(0, targetCount);
foreach (PadTransferRow sourceRow in (sourceRows ?? Array.Empty<PadTransferRow>()).Where(row => row != null).OrderBy(row => row.RowIndex))
{
List<Pad> availablePads = sourceRow.GetAvailablePads().ToList();
if (availablePads.Count == 0)
{
continue;
}
if (remainingCount <= 0)
{
remainingRows.Add(CreatePadRow(sourceRow.RowIndex, sourceRow.Direction, availablePads));
continue;
}
if (availablePads.Count <= remainingCount)
{
activeRows.Add(CreatePadRow(sourceRow.RowIndex, sourceRow.Direction, availablePads));
remainingCount -= availablePads.Count;
continue;
}
activeRows.Add(CreatePadRow(sourceRow.RowIndex, sourceRow.Direction, availablePads.Take(remainingCount)));
remainingRows.Add(CreatePadRow(sourceRow.RowIndex, sourceRow.Direction, availablePads.Skip(remainingCount)));
remainingCount = 0;
}
return activeRows;
}
public static List<DieTransferRow> TrimDieRows(IReadOnlyCollection<DieTransferRow> sourceRows, int targetCount, out List<DieTransferRow> remainingRows)
{
List<DieTransferRow> activeRows = new List<DieTransferRow>();
remainingRows = new List<DieTransferRow>();
int remainingCount = Math.Max(0, targetCount);
foreach (DieTransferRow sourceRow in (sourceRows ?? Array.Empty<DieTransferRow>()).Where(row => row != null).OrderBy(row => row.RowIndex))
{
List<Die> availableDies = sourceRow.GetAvailableDies().ToList();
if (availableDies.Count == 0)
{
continue;
}
if (remainingCount <= 0)
{
remainingRows.Add(CreateDieRow(sourceRow.RowIndex, sourceRow.Direction, sourceRow.SkipNgDie, availableDies));
continue;
}
if (availableDies.Count <= remainingCount)
{
activeRows.Add(CreateDieRow(sourceRow.RowIndex, sourceRow.Direction, sourceRow.SkipNgDie, availableDies));
remainingCount -= availableDies.Count;
continue;
}
activeRows.Add(CreateDieRow(sourceRow.RowIndex, sourceRow.Direction, sourceRow.SkipNgDie, availableDies.Take(remainingCount)));
remainingRows.Add(CreateDieRow(sourceRow.RowIndex, sourceRow.Direction, sourceRow.SkipNgDie, availableDies.Skip(remainingCount)));
remainingCount = 0;
}
return activeRows;
}
private static bool IsInRegion(int row, int column, DieTransferRegion region)
{
if (region == null)
{
return true;
}
return region.Contains(row, column);
}
private static DieTransferRowDirection ResolveRowDirection(int rowIndex, DieTransferRowTraversalStrategy rowTraversalStrategy)
{
switch (rowTraversalStrategy)
{
case DieTransferRowTraversalStrategy.AllNegative:
return DieTransferRowDirection.Negative;
case DieTransferRowTraversalStrategy.Serpentine:
return rowIndex % 2 == 0 ? DieTransferRowDirection.Negative : DieTransferRowDirection.Positive;
case DieTransferRowTraversalStrategy.AllPositive:
default:
return DieTransferRowDirection.Positive;
}
}
private static PadTransferRow CreatePadRow(int rowIndex, DieTransferRowDirection direction, IEnumerable<Pad> pads)
{
PadTransferRow row = new PadTransferRow();
row.RowIndex = rowIndex;
row.Direction = direction;
row.Pads = (pads ?? Array.Empty<Pad>()).Where(pad => pad != null).ToList();
return row;
}
private static DieTransferRow CreateDieRow(int rowIndex, DieTransferRowDirection direction, bool skipNgDie, IEnumerable<Die> dies)
{
DieTransferRow row = new DieTransferRow();
row.RowIndex = rowIndex;
row.Direction = direction;
row.SkipNgDie = skipNgDie;
row.Dies = (dies ?? Array.Empty<Die>()).Where(die => die != null).ToList();
return row;
}
}
}

View File

@@ -0,0 +1,52 @@
using MainShell.Models;
using System;
namespace MainShell.Process
{
public class DieTransferRegion
{
public int StartRow { get; set; }
public int StartCol { get; set; }
public int EndRow { get; set; }
public int EndCol { get; set; }
public int RowCount
{
get
{
return EndRow - StartRow + 1;
}
}
public int ColCount
{
get
{
return EndCol - StartCol + 1;
}
}
public bool Contains(int row, int column)
{
return row >= StartRow && row <= EndRow && column >= StartCol && column <= EndCol;
}
public static DieTransferRegion FromRegionModel(RegionModel regionModel)
{
if (regionModel == null)
{
return null;
}
DieTransferRegion region = new DieTransferRegion();
region.StartRow = regionModel.StartRow;
region.StartCol = regionModel.StartCol;
region.EndRow = regionModel.EndRow;
region.EndCol = regionModel.EndCol;
return region;
}
}
}

View File

@@ -0,0 +1,55 @@
using MainShell.Models.Wafer;
using System.Collections.Generic;
using System.Linq;
namespace MainShell.Process
{
public class DieTransferRow
{
public DieTransferRow()
{
Dies = new List<Die>();
Direction = DieTransferRowDirection.Positive;
}
public int RowIndex { get; set; }
public DieTransferRowDirection Direction { get; set; }
public bool SkipNgDie { get; set; }
public List<Die> Dies { get; set; }
public int AvailableCount
{
get
{
return GetAvailableDies().Count;
}
}
public IReadOnlyList<Die> GetOrderedDies()
{
if (Dies == null)
{
return new List<Die>();
}
IEnumerable<Die> orderedDies = Direction == DieTransferRowDirection.Positive
? Dies.OrderBy(die => die.Column)
: Dies.OrderByDescending(die => die.Column);
return orderedDies.ToList();
}
public IReadOnlyList<Die> GetAvailableDies()
{
IEnumerable<Die> availableDies = GetOrderedDies().Where(die => die != null);
if (SkipNgDie)
{
availableDies = availableDies.Where(die => die.Status != DieStatus.Ng);
}
return availableDies.ToList();
}
}
}

View File

@@ -0,0 +1,8 @@
namespace MainShell.Process
{
public enum DieTransferRowDirection
{
Positive = 0,
Negative = 1
}
}

View File

@@ -0,0 +1,27 @@
using MainShell.Common;
using MainShell.Models.Wafer;
using MainShell.Recipe.BaseBoard.Model;
using System.Collections.Generic;
namespace MainShell.Process
{
public interface IDieTransferPathGenerator
{
DieTransferPathPlan Generate(DieTransferPathRequest request);
DieTransferPathRegionPlan GenerateByRegion(DieTransferPathRequest request);
DieTransferPathRegionPlan GenerateByCandidates(
IReadOnlyCollection<Pad> padCandidates,
IReadOnlyCollection<Die> dieCandidates,
TransPathType transPathType,
bool skipNgDie,
DieTransferRowTraversalStrategy padRowDirectionStrategy,
DieTransferRowTraversalStrategy dieRowDirectionStrategy);
DieTransferPathRegionPlan GenerateByRows(
IReadOnlyCollection<PadTransferRow> padRows,
IReadOnlyCollection<DieTransferRow> dieRows,
TransPathType transPathType);
}
}

View File

@@ -0,0 +1,47 @@
using MainShell.Recipe.BaseBoard.Model;
using System.Collections.Generic;
using System.Linq;
namespace MainShell.Process
{
public class PadTransferRow
{
public PadTransferRow()
{
Pads = new List<Pad>();
Direction = DieTransferRowDirection.Positive;
}
public int RowIndex { get; set; }
public DieTransferRowDirection Direction { get; set; }
public List<Pad> Pads { get; set; }
public int AvailableCount
{
get
{
return Pads == null ? 0 : Pads.Count(pad => pad != null);
}
}
public IReadOnlyList<Pad> GetOrderedPads()
{
if (Pads == null)
{
return new List<Pad>();
}
IEnumerable<Pad> orderedPads = Direction == DieTransferRowDirection.Positive
? Pads.OrderBy(pad => pad.Column)
: Pads.OrderByDescending(pad => pad.Column);
return orderedPads.ToList();
}
public IReadOnlyList<Pad> GetAvailablePads()
{
return GetOrderedPads().Where(pad => pad != null).ToList();
}
}
}