-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathbfs.cs
130 lines (116 loc) · 3.59 KB
/
bfs.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace N_Puzzle_Game
{
public class bfs
{
class bfs_node
{
public string state;
public bfs_node parent;
}
bool is_goal_done = false;
string goal { set; get; }
private trie visited;
public Stack<string> solution = new Stack<string>();
Queue<bfs_node> q = new Queue<bfs_node>();
public bfs(string state)
{
solution.Clear();
goal = get_goal(state.Length);
visited = new trie(state.Length);
bfs_node root = create_node(state, null);
solve(root);
}
private bfs_node create_node(string state, bfs_node parent)
{
bfs_node nd = new bfs_node();
nd.state = state;
nd.parent = parent;
visited.add(state); q.Enqueue(nd);
return nd;
}
private string get_goal(int p)
{
string ans = "0";
for (char i = (char)(48 + p - 1); i > '0'; i--)
ans = i + ans;
return ans;
}
bool is_goal(string state)
{
for (int i = 0; i < state.Length; i++)
if (state[i] != goal[i])
return false;
return true;
}
void solve(bfs_node nd)
{
while (q.Count >= 1 && !is_goal_done)
{
nd = q.Dequeue();
get_child(nd);
}
}
void path(bfs_node nd)
{
bfs_node tmp = nd;
while (tmp != null)
{
solution.Push(tmp.state);
tmp = tmp.parent;
}
}
void get_child(bfs_node nd)
{
if (is_goal_done) return;
int idx = get_idx(nd.state), x = (int)Math.Sqrt(nd.state.Length);
if (idx >= x) // move top
{
string c_state = generate_state(nd.state, idx - x);
if (!visited.is_visited(c_state)) add(nd, c_state);
}
if (idx % x < x - 1 && !is_goal_done) // move right
{
string c_state = generate_state(nd.state, idx + 1);
if (!visited.is_visited(c_state)) add(nd, c_state);
}
if (idx < (x - 1) * x && !is_goal_done) // move down
{
string c_state = generate_state(nd.state, idx + x);
if (!visited.is_visited(c_state)) add(nd, c_state);
}
if (idx % x > 0 && !is_goal_done) // move left
{
string c_state = generate_state(nd.state, idx - 1);
if (!visited.is_visited(c_state)) add(nd, c_state);
}
}
private int get_idx(string state)
{
for (int i = 0; i < state.Length; i++)
{
if (state[i] == 48)
return i;
}
return -1;
}
private void add(bfs_node parent, string c_state)
{
bfs_node ch_nd = create_node(c_state, parent);
is_goal_done = is_goal(c_state) ? true : false;
if (is_goal_done) path(ch_nd);
}
private string generate_state(string state, int idx)
{
string ans = state;
ans = ans.Replace((char)48, (char)1000);
ans = ans.Replace(ans[idx], (char)48);
ans = ans.Replace((char)1000, state[idx]);
return ans;
}
}
}