[杂项项目]纯C语言实现控制台小游戏——数字拼图

一年前写的小游戏,当时感觉小有成就,现在发现缺陷真的很多。不禁感叹,当时为什么会用那么多goto呢。在这里真的建议大家不要用goto。只是现在懒得改了,毕竟是小程序。贴出来供大家参考。如果有时间后序再添加注释。如有问题欢迎评论。

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
#include <stdio.h>  
#include <stdlib.h>
#include<math.h>
#include <time.h>
#define max 10
int x, y, step, label = 0;
typedef struct score {
int steps, steps2;
double times;
char name[18];
}score;
score sco[max + 1];
char ch, buff[3];
bool flag, flag1 = false;
clock_t start, finish;
bool over(){
system("cls");
printf("\n\n\n\n\t\t\t您共用了 %d 步 ,耗时 %.3f 分钟\n", step, (double)(finish - start) / 40000);
system("pause");
system("cls");
printf("\n\n\n\n\n\n\n\n\t******************* 您是否重新开始游戏 (Y/N) ? *******************\n\n");
scanf("%s", buff);
ch = buff[0];
if (ch != 'n'&&ch != 'N') {
return false;
}
else {
printf("\n\n\n\n\t++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\n");
printf("\t+++++++++++++++++++++++++ 感谢您的使用 +++++++++++++++++++++++++\n", step);
printf("\t++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\n\n");
system("pause");
exit(0);
}
return true;
}
void rank(score sco[],int n) {
int i, j;
sco[0] = sco[n];
for (i = 0; i < n; i++)
if (sco[n].steps2>sco[i].steps2) {
for (j = n; j > i; j--)
sco[j] = sco[j - 1];
sco[i] = sco[0];
break;
}
for (j = i - 1; j > 0; j--)
if (sco[i].steps2 == sco[j].steps2&&sco[i].steps < sco[j].steps)
sco[0] = sco[i], sco[i] = sco[j], sco[j] = sco[0], i = j;
else if (sco[i].steps2 == sco[j].steps2&&sco[i].steps == sco[j].steps)
if (sco[i].times < sco[j].times)
sco[0] = sco[i], sco[i] = sco[j], sco[j] = sco[0], i = j;
}
int check2(int *p, int n) {
int i, j, flag2 = 0;
for (i = 1; i < n*n - 1; i++)
for (j = 0; j < i; j++)
if (p[j] > p[i])
flag2++;
if (!flag2)
return 0;
else if (flag2 % 2 == 0)
return 2;
else
return 1;
}
bool check(int *p,int n) {
int i;
flag = true;
for (i = 0; i<n*n - 1; i++)
if (p[i] != i + 1)
flag = false;
if (flag) {
flag1 = false;
return false;
}
return true;
}
int operation(int *p,int n) {
scanf("%s", buff);
ch = buff[0];
if (ch >= 'a'&&ch <= 'z')
ch -= 32;
switch (ch) {
case 'A': if (y == n - 1) return 1;
p[x*n + y] = p[x*n + y + 1];
p[x*n + y + 1] = 0;
y++;
step++;
return 1;
case 'W': if (x == n - 1) return 1;
p[x*n + y] = p[(x + 1)*n + y];
p[(x + 1)*n + y] = 0;
x++;
step++;
return 1;
case 'D': if (y == 0) return 1;
p[x*n + y] = p[x*n + y - 1];
p[x*n + y - 1] = 0;
y--;
step++;
return 1;
case 'S': if (x == 0) return 1;
p[x*n + y] = p[(x - 1)*n + y];
p[(x - 1)*n + y] = 0;
x--;
step++;
return 1;
case 'R': return 2;
case 'M': return 3;
case 'Q': printf("\n\n\t********************* 您是否要离开游戏 (Y/N) ? *********************\n\n");
scanf("%s", buff);
ch = buff[0];
if (ch == 'y' || ch == 'Y')
return 4;
else
return 1;
default: return 1;
}
return 0;
}
void map(int *p, int n) {
int i, j;
system("cls");
printf("\n\n\n");
for (i = 0; i < n; i++)
{
printf("\t");
for (j = 0; j < n; j++)
{
if (p[n*i + j] != 0)
printf("%-4d", p[n*i + j]);
else
printf(" ");
}
printf("\n\n");
}
printf("\n\t按方向键移动卡片至无卡片的地方 W:上 S:下 A:左 D:右 M:返回菜单 R:换图 Q:退出\n\n");
finish = clock();
printf("\n\t\t\t\t步数: %d\t 使用时间: %.3f 分钟 \n\n", step, (double)(finish - start) / 40000);
}
void reset(int *p, int n) {
int i, j, flag2;
system("cls");
do {
for (i = 0; i < n*n - 1; i++) {
do {
flag2 = 1;
p[i] = rand() % (n*n - 1) + 1;
for (j = 0; j < i; j++)
if (p[i] == p[j])
flag2 = 0;
} while (!flag2);
}
flag2 = check2(p, n);
if (flag2 == 1) {
flag2 = p[n*n - 2];
p[n*n - 2] = p[n*n - 3];
p[n*n - 3] = flag2;
}
} while (!flag2);
p[n*n - 1] = 0;
for (i = 0; i<n; i++)
for (j = 0; j<n; j++)
if (p[i*n + j] == 0){
x = i;
y = j;
}
}
void help() {
int i = 0;
system("cls");
printf("\n\n\n\n\t--------------------------------+ 基本操作 +--------------------------------\n\n");
printf("\n\n\t按方向键移动卡片至无卡片的地方 W:上 S:下 A:左 D:右 M:返回菜单 R:换图 Q:退出\n\n");
printf("\n\n\t---------------------------+ 浅悠悠(王骏)制作 +---------------------------\n\n");
if (label == 0)
printf("\n\n\t--------------------------+ 暂时没有任何游戏记录 +--------------------------\n\n");
else
for (i = 1; i <= label; i++)
printf("\n\n\t 第%02d名:%-18s 步数:%-5d 阶数:%-5d 时间:%-6.3lf分钟\n\n",
i, sco[i].name, sco[i].steps, sco[i].steps2, sco[i].times);
printf("\n\n\t----------------------------+ 按任意键返回菜单 +----------------------------\n\n");
system("pause");
}
void game() {
int n, *p;
int mark;
do {
system("cls");
printf("\n\n\n\n\t------------------+ 请输入阶数(推荐3——20阶) +------------------\n\n");
scanf("%d", &n);
if (n > 1)
p = (int*)calloc(n*n, sizeof(int));
else
printf("\t********************** 您输入有误,请重新输入 **********************\n\n"), system("pause");
} while (n <= 1);
next1:
step = 0;
start = clock();
reset(p, n);
next2:
map(p, n);
if (check(p, n) == false) {
printf("\n\n\t=================+ 恭喜您完成游戏,请输入您的姓名 +=================\n\n");
scanf("%s", sco[++label].name);
sco[label].steps = step;
sco[label].steps2 = n;
sco[label].times = (double)(finish - start) / 40000;
rank(sco, label);
if (over() == false)
return;
}
mark = operation(p, n);
if (mark == 1)
goto next2;
else if (mark == 2)
goto next1;
else if (mark == 3)
return;
else if (mark == 4)
if (over() == false)
return;
free(p);
}
int main(){
srand((int)time(0));
do {
system("cls");
printf("\t-------------+ 欢迎来到浅悠悠数字拼图,请选择您的操作 +-------------\n\n");
printf("\t-----+ 1.开始游戏 +-----+ 2.帮助 +-----+ 0(或其他).退出 +-----\n\n");
printf("\t++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\n\n");
scanf("%s", buff);
ch = buff[0];
switch (ch){
case'1':
game(); break;
case'2':
help(); break;
case'0':
exit(0);
default:
exit(0);
}
} while (ch != '0');
return 0;
}

纸短情长啊文章结束了但我们的故事还在继续
坚持原创技术分享,您的支持将鼓励我继续创作!