汉诺塔Tower of Hanoi

汉诺塔Tower of Hanoi

游戏起源

法国数学家爱德华·卢卡斯曾编写过一个印度的古老传说:在世界中心贝拿勒斯(在印度北部)的圣庙里,一块黄铜板上插着三根宝石针。印度教的主神梵天在创造世界的时候,在其中一根针上从下到上地穿好了由大到小的64片金片,这就是所谓的汉诺塔。不论白天黑夜,总有一个僧侣在按照下面的法则移动这些金片:一次只移动一片,不管在哪根针上,小片必须在大片上面。僧侣们预言,当所有的金片都从梵天穿好的那根针上移到另外一根针上时,世界就将在一声霹雳中消灭,而梵塔、庙宇和众生也都将同归于尽。

游戏规则

有三根相邻的柱子依次为a,b,c
柱子a从下到上按金字塔状叠放着n个不同大小的圆盘
每次将一根柱子的最上方的圆盘移动到另一根柱子的最上方
同一根柱子上不能出现大盘子在小盘子上方的情况
当柱子c从下到上按金字塔状叠放着n个不同大小的圆盘时即游戏胜利

在线游玩

Gitee创作者张晓雷制作的汉诺塔游戏,可以游玩+演示
汉诺塔1

Github创作者霸都丶傲天制作的汉诺塔游戏,可以演示
汉诺塔2

程序编写

我用c语言写了一个4层的汉诺塔游戏

程序源码

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
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
/*
C语言-4层汉诺塔
2022/11/25
Garmin 2896583803@qq.com
*/

#include<stdio.h>
#include<stdlib.h>//清屏指令所在库函数
#define N 4

int cmd = 0, j = 0, m = 0, n = 0, k = 0,q=0;// cmd是输入指令变量 j是中间变量 m是中间变量 n是计数变量 k是循环控制变量 q是循环控制变量
int a[4] = { 1,2,3,4 }, b[4] = { }, c[4] = { };
void print_tower_0();
void print_tower_1();
void print_tower_2();
void print_tower_3();
void print_tower_4();
void print_tower();
int main()
{
printf("游戏规则如下\n");
printf("有三根相邻的柱子依次为a,b,c\n");
printf("柱子a从下到上按金字塔状叠放着n个不同大小的圆盘\n");
printf("每次将一根柱子的最上方的圆盘移动到另一根柱子的最上方\n");
printf("同一根柱子上不能出现大盘子在小盘子上方的情况\n");
printf("当柱子c从下到上按金字塔状叠放着n个不同大小的圆盘时即游戏胜利\n");
printf("_________________________\n");
printf("这是4层的汉诺塔游戏\n");
printf("从左到右依次为塔a b c\n");
printf("操作指令如下 步数0\n");
printf("1 a→b 4 b→a\n");
printf("2 a→c 5 c→a\n");
printf("3 b→c 6 c→b\n");
print_tower();
printf("\n");
while (k == 0)
{
printf("请输入操作指令 ");
scanf_s("%1d", &cmd);

if (cmd == 1)//a to b
{
for (int i = 0; i < N; i++)
{
if (a[i] != 0)
{
j = a[i];
m = i;
a[i] = 0;
break;
}
if(a[3]==0)
{
q = 1;
n--;
break;
}
}

for (int i = N - 2; q==0 && i > -1; i--)
{
if (b[3] == 0)
{
b[3] = j;
break;
}
else if (b[i] == 0 && j < b[i + 1])
{
b[i] = j;
break;
}
if(j > b[i + 1])
{
a[m] = j;
n--;
break;
}
}
q = 0;
n++;
}

if (cmd == 2)//a to c
{
for (int i = 0; i < N; i++)
{
if (a[i] != 0)
{
j = a[i];
m = i;
a[i] = 0;
break;
}
if (a[3] == 0)
{
q = 1;
n--;
break;
}
}

for (int i = N - 2; q == 0 && i > -1; i--)
{
if (c[3] == 0)
{
c[3] = j;
break;
}
else if (c[i] == 0 && j < c[i + 1])
{
c[i] = j;
break;
}
if (j > c[i + 1])
{
a[m] = j;
n--;
break;
}
}
q = 0;
n++;
}

if (cmd == 3)//b to c
{
for (int i = 0; i < N; i++)
{
if (b[i] != 0)
{
j = b[i];
m = i;
b[i] = 0;
break;
}
if (b[3] == 0)
{
q = 1;
n--;
break;
}
}

for (int i = N - 2; q == 0 && i > -1; i--)
{
if (c[3] == 0)
{
c[3] = j;
break;
}
else if (c[i] == 0 && j < c[i + 1])
{
c[i] = j;
break;
}
if (j > c[i + 1])
{
b[m] = j;
n--;
break;
}
}
q = 0;
n++;
}

if (cmd == 4)//b to a
{
for (int i = 0; i < N; i++)
{
if (b[i] != 0)
{
j = b[i];
m = i;
b[i] = 0;
break;
}
if (b[3] == 0)
{
q = 1;
n--;
break;
}
}

for (int i = N - 2; q == 0 && i > -1; i--)
{
if (a[3] == 0)
{
a[3] = j;
break;
}
else if (a[i] == 0 && j < a[i + 1])
{
a[i] = j;
break;
}
if (j > a[i + 1])
{
b[m] = j;
n--;
break;
}
}
q = 0;
n++;
}

if (cmd == 5)//c to a
{
for (int i = 0; i < N; i++)
{
if (c[i] != 0)
{
j = c[i];
m = i;
c[i] = 0;
break;
}
if (c[3] == 0)
{
q = 1;
n--;
break;
}
}

for (int i = N - 2; q == 0 && i > -1; i--)
{
if (a[3] == 0)
{
a[3] = j;
break;
}
else if (a[i] == 0 && j < a[i + 1])
{
a[i] = j;
break;
}
if (j > a[i + 1])
{
c[m] = j;
n--;
break;
}
}
q = 0;
n++;
}

if (cmd == 6)//c to b
{
for (int i = 0; i < N; i++)
{
if (c[i] != 0)
{
j = c[i];
m = i;
c[i] = 0;
break;
}
if (c[3] == 0)
{
q = 1;
n--;
break;
}
}

for (int i = N - 2; q == 0 && i > -1; i--)
{
if (b[3] == 0)
{
b[3] = j;
break;
}
else if (b[i] == 0 && j < b[i + 1])
{
b[i] = j;
break;
}
if (j > b[i + 1])
{
c[m] = j;
n--;
break;
}
}
q = 0;
n++;
}

//配合while退出循环
if (c[0] == 1 && c[1] == 2 && c[2] == 3 && c[3] == 4)k = 1;
//输出塔形
system("cls");
printf("操作指令如下 步数%d\n", n);
printf("1 a→b 4 b→a\n");
printf("2 a→c 5 c→a\n");
printf("3 b→c 6 c→b\n");
print_tower();
}
//胜利信息
system("cls");
printf("************\n");
printf("************\n");
printf("**You win!**\n");
printf("************\n");
printf("************\n");
printf("***步数%d***\n",n);
printf("************\n");
printf("输入任意数字并按下回车键后退出游戏\n");
scanf_s("%d",&n);
return 0;
}

void print_tower_0()
{
printf(" | ");
}

void print_tower_1()
{
printf(" # ");
}

void print_tower_2()
{
printf(" ### ");
}

void print_tower_3()
{
printf(" ##### ");
}

void print_tower_4()
{
printf(" ####### ");
}

//输出塔形
void print_tower()
{
printf("_________________________\n");
for (int i = 0; i < N; i++)
{
switch (a[i])
{
case 4:print_tower_4(); break;
case 3:print_tower_3(); break;
case 2:print_tower_2(); break;
case 1:print_tower_1(); break;
case 0:print_tower_0(); break;
}
switch (b[i])
{
case 4:print_tower_4(); break;
case 3:print_tower_3(); break;
case 2:print_tower_2(); break;
case 1:print_tower_1(); break;
case 0:print_tower_0(); break;
}
switch (c[i])
{
case 4:print_tower_4(); break;
case 3:print_tower_3(); break;
case 2:print_tower_2(); break;
case 1:print_tower_1(); break;
case 0:print_tower_0(); break;
}
printf("\n");
}
printf("\n");
printf(" a b c \n");
printf("_________________________\n");
}

exe下载

apk下载

游戏解读

有趣的汉诺塔游戏怎么玩?-哔哩哔哩

C语言-汉诺塔详解-CSDN

汉诺塔-经典递归问题-CSDN博客

程序编写

可以使用c语言采取递归方法计算出汉诺塔游戏的最优解方案

程序源码

计算步数

1
2
3
4
5
6
7
8
9
#include<stdio.h>
#include<math.h>
int main()
{
int num = 0;
scanf_s("%d", &num);//塔数
printf("完成%d层的汉诺塔需要%d步\n", num, (int)pow(2, num) - 1);
return 0;
}

计算方案

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
#include<stdio.h>
void Hanio_Step(int n, char A, char B, char C)
{
if (1 == n)
printf("%c->%c\n", A, C);
else
{
Hanio_Step(n - 1, A, C, B);
printf("%c->%c\n", A, C);
Hanio_Step(n - 1, B, A, C);
}
}
int main()
{
int n = 0;
printf("请输入塔的层数 ");
scanf_s("%d", &n);
Hanio_Step(n, 'A', 'B', 'C');
return 0;
}

exe下载

版权说明

这是博主写的第一个c语言小游戏,花了三个小时左右,前前后后修了几十个bug。
源码都放出来了,不开源搞啥呢?


汉诺塔Tower of Hanoi
http://example.com/2023/01/14/Project项目-汉诺塔/
许可协议