forked from DarthJDG/NumGuess
-
Notifications
You must be signed in to change notification settings - Fork 1
/
NumGuess.j
412 lines (303 loc) · 7.68 KB
/
NumGuess.j
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
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
.source NumGuess.j
.class public NumGuess
.super java/lang/Object
.field private static reader Ljava/io/BufferedReader;
; ================================
.method static public <clinit>()V
.limit stack 5
; initialize static field "reader" with a BufferedReader
; based on stdin
new java/io/BufferedReader
dup
new java/io/InputStreamReader
dup
getstatic java/lang/System/in Ljava/io/InputStream;
invokespecial java/io/InputStreamReader/<init>(Ljava/io/InputStream;)V
invokespecial java/io/BufferedReader/<init>(Ljava/io/Reader;)V
putstatic NumGuess/reader Ljava/io/BufferedReader;
return
.end method
; =======================
.method public <init>()V
aload_0
invokenonvirtual java/lang/Object/<init>()V
return
.end method
; ===============================================
.method public static main([Ljava/lang/String;)V
.throws java/lang/Exception
.limit stack 20
.limit locals 20
; display greeting
ldc "Welcome to NumGuess Jasmin version!\n\n"
invokestatic NumGuess/printString(Ljava/lang/String;)V
; get the player's name
; stored in local variable 11
ldc "Enter your name: "
invokestatic NumGuess/printString(Ljava/lang/String;)V
invokestatic NumGuess/readString()Ljava/lang/String;
astore 11
; check if empty length
aload 11
invokevirtual java/lang/String/length()I
ifne NameOK
ldc "Player"
astore 11
NameOK:
; settings summary
ldc "Welcome "
invokestatic NumGuess/printString(Ljava/lang/String;)V
aload 11
invokestatic NumGuess/printString(Ljava/lang/String;)V
ldc ", enter upper limit: "
invokestatic NumGuess/printString(Ljava/lang/String;)V
invokestatic NumGuess/readInt()I
dup
ldc 10
if_icmpge LimitOK
; use 10 if input is smaller
pop
ldc 10
LimitOK:
; limit
istore 12
; a single game starts here
PlayLoop:
; generate random number (in the range of 1-limit)
; stored in local variable 13
invokestatic java/lang/Math/random()D
iload 12
i2d
dmul
d2i
iconst_1
iadd
istore 13
; start message
ldc "Guess my number between 1 and "
invokestatic NumGuess/printString(Ljava/lang/String;)V
iload 12
invokestatic NumGuess/printInt(I)V
ldc "!\n\n"
invokestatic NumGuess/printString(Ljava/lang/String;)V
; guesses counted in local variable 14
iconst_0
istore 14
; a single guess (loop while no match)
GuessLoop:
iload 12
invokestatic NumGuess/readGuess(I)I
; increase guess count
iinc 14 1
; get the difference
iload 13
isub
dup
ifge NumberGE
pop
ldc "Too low!\n"
invokestatic NumGuess/printString(Ljava/lang/String;)V
goto GuessLoop
; greater or equal
NumberGE:
ifle Win
ldc "Too high!\n"
invokestatic NumGuess/printString(Ljava/lang/String;)V
goto GuessLoop
; win - the numbers are matching
Win:
; display game summary
ldc "\nWell done "
invokestatic NumGuess/printString(Ljava/lang/String;)V
; player name
aload 11
invokestatic NumGuess/printString(Ljava/lang/String;)V
ldc ", you guessed my number from "
invokestatic NumGuess/printString(Ljava/lang/String;)V
; guess count
iload 14
invokestatic NumGuess/printInt(I)V
iload 14
iconst_1
if_icmpeq OneTry
; multiple tries
ldc " tries!\n"
invokestatic NumGuess/printString(Ljava/lang/String;)V
goto CustomMessage
OneTry:
; a single try
ldc " try!\n"
invokestatic NumGuess/printString(Ljava/lang/String;)V
goto CustomMessage
; display custom message
CustomMessage:
; calculate "max" and store it to local variable 15
iload 12
i2d
invokestatic java/lang/Math/log(D)D
iconst_2
i2d
invokestatic java/lang/Math/log(D)D
ddiv
d2i
iconst_1
iadd
istore 15
; keep guesses on stack for faster access (needs cleanup later)
iload 14
dup
iconst_1
if_icmpeq GuessCountOne
dup
iload 15
if_icmplt GuessCountLessThanMax
dup
iload 15
if_icmpeq GuessCountMax
dup
iload 15
i2d
ldc 1.1
f2d
dmul
d2i
if_icmple GuessCountMaxPlus
dup
iload 12
if_icmple GuessCountLTELimit
goto GuessCountMoreThanLimit
GuessCountOne:
ldc "You're one lucky bastard!\n"
goto DisplayCustomMessage
GuessCountLessThanMax:
ldc "You are the master of this game!\n"
goto DisplayCustomMessage
GuessCountMax:
ldc "You are a machine!\n"
goto DisplayCustomMessage
GuessCountMaxPlus:
ldc "Very good result!\n"
goto DisplayCustomMessage
GuessCountLTELimit:
ldc "Try harder, you can do better!\n"
goto DisplayCustomMessage
GuessCountMoreThanLimit:
ldc "I find your lack of skill disturbing!\n"
goto DisplayCustomMessage
DisplayCustomMessage:
invokestatic NumGuess/printString(Ljava/lang/String;)V
; pop guesses from stack (cleanup)
pop
; play again?
ldc "Play again [y/N]? "
invokestatic NumGuess/printString(Ljava/lang/String;)V
invokestatic NumGuess/readString()Ljava/lang/String;
; check if input is an empty string
dup
invokevirtual java/lang/String/length()I
ifne CheckIfNot
pop
goto QuitGame
; check if first character of input is lower or upper case N
; please note: ifeq is executed on FALSE (as it converts to zero)
CheckIfNot:
iconst_0
iconst_1
invokevirtual java/lang/String/substring(II)Ljava/lang/String;
invokevirtual java/lang/String/toLowerCase()Ljava/lang/String;
ldc "n"
invokevirtual java/lang/String/equals(Ljava/lang/Object;)Z
ifeq PlayLoop
QuitGame:
ldc "\nOkay, bye.\n"
invokestatic NumGuess/printString(Ljava/lang/String;)V
return
.end method
; ===============================================
; method to read an integer
.method public static readGuess(I)I
.throws java/io/IOException
.limit stack 10
.limit locals 5
.catch java/lang/NumberFormatException from ReadIntTry to ReadIntCatch using ReadIntCatch
Read:
ldc "Guess: "
invokestatic NumGuess/printString(Ljava/lang/String;)V
getstatic NumGuess/reader Ljava/io/BufferedReader;
invokevirtual java/io/BufferedReader/readLine()Ljava/lang/String;
ReadIntTry:
invokestatic java/lang/Integer/parseInt(Ljava/lang/String;)I
goto ReadIntDone
ReadIntCatch:
pop
ldc "That's just plain wrong.\n"
invokestatic NumGuess/printString(Ljava/lang/String;)V
goto Read
ReadIntDone:
dup
iconst_1
if_icmplt OutOfRange
dup
iload_0
if_icmpgt OutOfRange
goto NumberOK
OutOfRange:
ldc "Out of range.\n"
invokestatic NumGuess/printString(Ljava/lang/String;)V
pop
goto Read
NumberOK:
ireturn
.end method
; ===============================================
; method to read an integer
.method public static readInt()I
.throws java/io/IOException
.limit stack 10
.limit locals 5
.catch java/lang/NumberFormatException from ReadIntTry to ReadIntCatch using ReadIntCatch
getstatic NumGuess/reader Ljava/io/BufferedReader;
invokevirtual java/io/BufferedReader/readLine()Ljava/lang/String;
ReadIntTry:
invokestatic java/lang/Integer/parseInt(Ljava/lang/String;)I
goto ReadIntDone
ReadIntCatch:
pop
iconst_0
ReadIntDone:
ireturn
.end method
; ===============================================
; method to read a string
.method public static readString()Ljava/lang/String;
.throws java/io/IOException
.limit stack 10
.limit locals 5
getstatic NumGuess/reader Ljava/io/BufferedReader;
invokevirtual java/io/BufferedReader/readLine()Ljava/lang/String;
areturn
.end method
; ===============================================
; method to output a string
.method public static printString(Ljava/lang/String;)V
.throws java/io/IOException
.limit stack 10
.limit locals 5
getstatic java/lang/System/out Ljava/io/PrintStream;
aload_0
invokevirtual java/io/PrintStream/print(Ljava/lang/String;)V
return
.end method
; ===============================================
; method to output an integer
.method public static printInt(I)V
.throws java/io/IOException
.limit stack 10
.limit locals 5
iload_0
invokestatic java/lang/Integer/toString(I)Ljava/lang/String;
getstatic java/lang/System/out Ljava/io/PrintStream;
swap
invokevirtual java/io/PrintStream/print(Ljava/lang/String;)V
return
.end method