]> git.lizzy.rs Git - rust.git/blob - src/doc/trpl/guessing-game.md
Rollup merge of #22524 - stevencrockett:master, r=steveklabnik
[rust.git] / src / doc / trpl / guessing-game.md
1 % Guessing Game
2
3 Okay! We've got the basics of Rust down. Let's write a bigger program.
4
5 For our first project, we'll implement a classic beginner programming problem:
6 the guessing game. Here's how it works: Our program will generate a random
7 integer between one and a hundred. It will then prompt us to enter a guess.
8 Upon entering our guess, it will tell us if we're too low or too high. Once we
9 guess correctly, it will congratulate us. Sound good?
10
11 ## Set up
12
13 Let's set up a new project. Go to your projects directory. Remember how we
14 had to create our directory structure and a `Cargo.toml` for `hello_world`? Cargo
15 has a command that does that for us. Let's give it a shot:
16
17 ```{bash}
18 $ cd ~/projects
19 $ cargo new guessing_game --bin
20 $ cd guessing_game
21 ```
22
23 We pass the name of our project to `cargo new`, and then the `--bin` flag,
24 since we're making a binary, rather than a library.
25
26 Check out the generated `Cargo.toml`:
27
28 ```toml
29 [package]
30
31 name = "guessing_game"
32 version = "0.0.1"
33 authors = ["Your Name <you@example.com>"]
34 ```
35
36 Cargo gets this information from your environment. If it's not correct, go ahead
37 and fix that.
38
39 Finally, Cargo generated a "Hello, world!" for us. Check out `src/main.rs`:
40
41 ```{rust}
42 fn main() {
43     println!("Hello, world!")
44 }
45 ```
46
47 Let's try compiling what Cargo gave us:
48
49 ```{bash}
50 $ cargo build
51    Compiling guessing_game v0.0.1 (file:///home/you/projects/guessing_game)
52 ```
53
54 Excellent! Open up your `src/main.rs` again. We'll be writing all of
55 our code in this file. We'll talk about multiple-file projects later on in the
56 guide.
57
58 Before we move on, let me show you one more Cargo command: `run`. `cargo run`
59 is kind of like `cargo build`, but it also then runs the produced executable.
60 Try it out:
61
62 ```bash
63 $ cargo run
64    Compiling guessing_game v0.0.1 (file:///home/you/projects/guessing_game)
65      Running `target/guessing_game`
66 Hello, world!
67 ```
68
69 Great! The `run` command comes in handy when you need to rapidly iterate on a project.
70 Our game is just such a project, we need to quickly test each iteration before moving on to the next one.
71
72 ## Processing a Guess
73
74 Let's get to it! The first thing we need to do for our guessing game is
75 allow our player to input a guess. Put this in your `src/main.rs`:
76
77 ```{rust,no_run}
78 use std::old_io;
79
80 fn main() {
81     println!("Guess the number!");
82
83     println!("Please input your guess.");
84
85     let input = old_io::stdin().read_line()
86                            .ok()
87                            .expect("Failed to read line");
88
89     println!("You guessed: {}", input);
90 }
91 ```
92
93 You've seen this code before, when we talked about standard input. We
94 import the `std::old_io` module with `use`, and then our `main` function contains
95 our program's logic. We print a little message announcing the game, ask the
96 user to input a guess, get their input, and then print it out.
97
98 Because we talked about this in the section on standard I/O, I won't go into
99 more details here. If you need a refresher, go re-read that section.
100
101 ## Generating a secret number
102
103 Next, we need to generate a secret number. To do that, we need to use Rust's
104 random number generation, which we haven't talked about yet. Rust includes a
105 bunch of interesting functions in its standard library. If you need a bit of
106 code, it's possible that it's already been written for you! In this case,
107 we do know that Rust has random number generation, but we don't know how to
108 use it.
109
110 Enter the docs. Rust has a page specifically to document the standard library.
111 You can find that page [here](../std/index.html). There's a lot of information on
112 that page, but the best part is the search bar. Right up at the top, there's
113 a box that you can enter in a search term. The search is pretty primitive
114 right now, but is getting better all the time. If you type "random" in that
115 box, the page will update to [this one](../std/index.html?search=random). The very
116 first result is a link to [`std::rand::random`](../std/rand/fn.random.html). If we
117 click on that result, we'll be taken to its documentation page.
118
119 This page shows us a few things: the type signature of the function, some
120 explanatory text, and then an example. Let's try to modify our code to add in the
121 `random` function and see what happens:
122
123 ```{rust,ignore}
124 use std::old_io;
125 use std::rand;
126
127 fn main() {
128     println!("Guess the number!");
129
130     let secret_number = (rand::random() % 100) + 1; // secret_number: i32
131
132     println!("The secret number is: {}", secret_number);
133
134     println!("Please input your guess.");
135
136     let input = old_io::stdin().read_line()
137                            .ok()
138                            .expect("Failed to read line");
139
140
141     println!("You guessed: {}", input);
142 }
143 ```
144
145 The first thing we changed was to `use std::rand`, as the docs
146 explained.  We then added in a `let` expression to create a variable binding
147 named `secret_number`, and we printed out its result.
148
149 Also, you may wonder why we are using `%` on the result of `rand::random()`.
150 This operator is called *modulo*, and it returns the remainder of a division.
151 By taking the modulo of the result of `rand::random()`, we're limiting the
152 values to be between 0 and 99. Then, we add one to the result, making it from 1
153 to 100. Using modulo can give you a very, very small bias in the result, but
154 for this example, it is not important.
155
156 Let's try to compile this using `cargo build`:
157
158 ```bash
159 $ cargo build
160    Compiling guessing_game v0.0.1 (file:///home/you/projects/guessing_game)
161 src/main.rs:7:26: 7:34 error: the type of this value must be known in this context
162 src/main.rs:7     let secret_number = (rand::random() % 100) + 1;
163                                        ^~~~~~~~
164 error: aborting due to previous error
165 ```
166
167 It didn't work! Rust says "the type of this value must be known in this
168 context." What's up with that? Well, as it turns out, `rand::random()` can
169 generate many kinds of random values, not just integers. And in this case, Rust
170 isn't sure what kind of value `random()` should generate. So we have to help
171 it. With number literals, we can just add an `i32` onto the end to tell Rust they're
172 integers, but that does not work with functions. There's a different syntax,
173 and it looks like this:
174
175 ```{rust,ignore}
176 rand::random::<i32>();
177 ```
178
179 This says "please give me a random `i32` value." We can change our code to use
180 this hint:
181
182 ```{rust,no_run}
183 use std::old_io;
184 use std::rand;
185
186 fn main() {
187     println!("Guess the number!");
188
189     let secret_number = (rand::random::<i32>() % 100) + 1;
190
191     println!("The secret number is: {}", secret_number);
192
193     println!("Please input your guess.");
194
195     let input = old_io::stdin().read_line()
196                            .ok()
197                            .expect("Failed to read line");
198
199
200     println!("You guessed: {}", input);
201 }
202 ```
203
204 Try running our new program a few times:
205
206 ```bash
207 $ cargo run
208    Compiling guessing_game v0.0.1 (file:///home/you/projects/guessing_game)
209      Running `target/guessing_game`
210 Guess the number!
211 The secret number is: 7
212 Please input your guess.
213 4
214 You guessed: 4
215 $ ./target/guessing_game
216 Guess the number!
217 The secret number is: 83
218 Please input your guess.
219 5
220 You guessed: 5
221 $ ./target/guessing_game
222 Guess the number!
223 The secret number is: -29
224 Please input your guess.
225 42
226 You guessed: 42
227 ```
228
229 Wait. Negative 29? We wanted a number between one and a hundred! We have two
230 options here: we can either ask `random()` to generate an unsigned integer, which
231 can only be positive, or we can use the `abs()` function. Let's go with the
232 unsigned integer approach. If we want a random positive number, we should ask for
233 a random positive number. Our code looks like this now:
234
235 ```{rust,no_run}
236 use std::old_io;
237 use std::rand;
238
239 fn main() {
240     println!("Guess the number!");
241
242     let secret_number = (rand::random::<u32>() % 100) + 1;
243
244     println!("The secret number is: {}", secret_number);
245
246     println!("Please input your guess.");
247
248     let input = old_io::stdin().read_line()
249                            .ok()
250                            .expect("Failed to read line");
251
252
253     println!("You guessed: {}", input);
254 }
255 ```
256
257 And trying it out:
258
259 ```bash
260 $ cargo run
261    Compiling guessing_game v0.0.1 (file:///home/you/projects/guessing_game)
262      Running `target/guessing_game`
263 Guess the number!
264 The secret number is: 57
265 Please input your guess.
266 3
267 You guessed: 3
268 ```
269
270 Great! Next up: let's compare our guess to the secret guess.
271
272 ## Comparing guesses
273
274 If you remember, earlier in the guide, we made a `cmp` function that compared
275 two numbers. Let's add that in, along with a `match` statement to compare our
276 guess to the secret number:
277
278 ```{rust,ignore}
279 use std::old_io;
280 use std::rand;
281 use std::cmp::Ordering;
282
283 fn main() {
284     println!("Guess the number!");
285
286     let secret_number = (rand::random::<u32>() % 100) + 1;
287
288     println!("The secret number is: {}", secret_number);
289
290     println!("Please input your guess.");
291
292     let input = old_io::stdin().read_line()
293                            .ok()
294                            .expect("Failed to read line");
295
296
297     println!("You guessed: {}", input);
298
299     match cmp(input, secret_number) {
300         Ordering::Less => println!("Too small!"),
301         Ordering::Greater => println!("Too big!"),
302         Ordering::Equal => println!("You win!"),
303     }
304 }
305
306 fn cmp(a: i32, b: i32) -> Ordering {
307     if a < b { Ordering::Less }
308     else if a > b { Ordering::Greater }
309     else { Ordering::Equal }
310 }
311 ```
312
313 If we try to compile, we'll get some errors:
314
315 ```bash
316 $ cargo build
317    Compiling guessing_game v0.0.1 (file:///home/you/projects/guessing_game)
318 src/main.rs:20:15: 20:20 error: mismatched types: expected `i32` but found `collections::string::String` (expected i32 but found struct collections::string::String)
319 src/main.rs:20     match cmp(input, secret_number) {
320                              ^~~~~
321 src/main.rs:20:22: 20:35 error: mismatched types: expected `i32` but found `u32` (expected i32 but found u32)
322 src/main.rs:20     match cmp(input, secret_number) {
323                                     ^~~~~~~~~~~~~
324 error: aborting due to 2 previous errors
325 ```
326
327 This often happens when writing Rust programs, and is one of Rust's greatest
328 strengths. You try out some code, see if it compiles, and Rust tells you that
329 you've done something wrong. In this case, our `cmp` function works on integers,
330 but we've given it unsigned integers. In this case, the fix is easy, because
331 we wrote the `cmp` function! Let's change it to take `u32`s:
332
333 ```{rust,ignore}
334 use std::old_io;
335 use std::rand;
336 use std::cmp::Ordering;
337
338 fn main() {
339     println!("Guess the number!");
340
341     let secret_number = (rand::random::<u32>() % 100) + 1;
342
343     println!("The secret number is: {}", secret_number);
344
345     println!("Please input your guess.");
346
347     let input = old_io::stdin().read_line()
348                            .ok()
349                            .expect("Failed to read line");
350
351
352     println!("You guessed: {}", input);
353
354     match cmp(input, secret_number) {
355         Ordering::Less => println!("Too small!"),
356         Ordering::Greater => println!("Too big!"),
357         Ordering::Equal => println!("You win!"),
358     }
359 }
360
361 fn cmp(a: u32, b: u32) -> Ordering {
362     if a < b { Ordering::Less }
363     else if a > b { Ordering::Greater }
364     else { Ordering::Equal }
365 }
366 ```
367
368 And try compiling again:
369
370 ```bash
371 $ cargo build
372    Compiling guessing_game v0.0.1 (file:///home/you/projects/guessing_game)
373 src/main.rs:20:15: 20:20 error: mismatched types: expected `u32` but found `collections::string::String` (expected u32 but found struct collections::string::String)
374 src/main.rs:20     match cmp(input, secret_number) {
375                              ^~~~~
376 error: aborting due to previous error
377 ```
378
379 This error is similar to the last one: we expected to get a `u32`, but we got
380 a `String` instead! That's because our `input` variable is coming from the
381 standard input, and you can guess anything. Try it:
382
383 ```bash
384 $ ./target/guessing_game
385 Guess the number!
386 The secret number is: 73
387 Please input your guess.
388 hello
389 You guessed: hello
390 ```
391
392 Oops! Also, you'll note that we just ran our program even though it didn't compile.
393 This works because the older version we did successfully compile was still lying
394 around. Gotta be careful!
395
396 Anyway, we have a `String`, but we need a `u32`. What to do? Well, there's
397 a function for that:
398
399 ```{rust,ignore}
400 let input = old_io::stdin().read_line()
401                        .ok()
402                        .expect("Failed to read line");
403 let input_num: Result<u32, _> = input.parse();
404 ```
405
406 The `parse` function takes in a `&str` value and converts it into something.
407 We tell it what kind of something with a type hint. Remember our type hint with
408 `random()`? It looked like this:
409
410 ```{rust,ignore}
411 rand::random::<u32>();
412 ```
413
414 There's an alternate way of providing a hint too, and that's declaring the type
415 in a `let`:
416
417 ```{rust,ignore}
418 let x: u32 = rand::random();
419 ```
420
421 In this case, we say `x` is a `u32` explicitly, so Rust is able to properly
422 tell `random()` what to generate. In a similar fashion, both of these work:
423
424 ```{rust,ignore}
425 let input_num = "5".parse::<u32>(); // input_num: Option<u32>
426 let input_num: Result<u32, _> = "5".parse(); // input_num: Result<u32, <u32 as FromStr>::Err>
427 ```
428
429 Here we're converting the `Result` returned by `parse` to an `Option` by using
430 the `ok` method as well.  Anyway, with us now converting our input to a number,
431 our code looks like this:
432
433 ```{rust,ignore}
434 use std::old_io;
435 use std::rand;
436 use std::cmp::Ordering;
437
438 fn main() {
439     println!("Guess the number!");
440
441     let secret_number = (rand::random::<u32>() % 100) + 1;
442
443     println!("The secret number is: {}", secret_number);
444
445     println!("Please input your guess.");
446
447     let input = old_io::stdin().read_line()
448                            .ok()
449                            .expect("Failed to read line");
450     let input_num: Result<u32, _> = input.parse();
451
452     println!("You guessed: {:?}", input_num);
453
454     match cmp(input_num, secret_number) {
455         Ordering::Less => println!("Too small!"),
456         Ordering::Greater => println!("Too big!"),
457         Ordering::Equal => println!("You win!"),
458     }
459 }
460
461 fn cmp(a: u32, b: u32) -> Ordering {
462     if a < b { Ordering::Less }
463     else if a > b { Ordering::Greater }
464     else { Ordering::Equal }
465 }
466 ```
467
468 Let's try it out!
469
470 ```bash
471 $ cargo build
472    Compiling guessing_game v0.0.1 (file:///home/you/projects/guessing_game)
473 src/main.rs:22:15: 22:24 error: mismatched types: expected `u32` but found `core::option::Option<u32>` (expected u32 but found enum core::option::Option)
474 src/main.rs:22     match cmp(input_num, secret_number) {
475                              ^~~~~~~~~
476 error: aborting due to previous error
477 ```
478
479 Oh yeah! Our `input_num` has the type `Option<u32>`, rather than `u32`. We
480 need to unwrap the Option. If you remember from before, `match` is a great way
481 to do that. Try this code:
482
483 ```{rust,no_run}
484 use std::old_io;
485 use std::rand;
486 use std::cmp::Ordering;
487
488 fn main() {
489     println!("Guess the number!");
490
491     let secret_number = (rand::random::<u32>() % 100) + 1;
492
493     println!("The secret number is: {}", secret_number);
494
495     println!("Please input your guess.");
496
497     let input = old_io::stdin().read_line()
498                            .ok()
499                            .expect("Failed to read line");
500     let input_num: Result<u32, _> = input.parse();
501
502     let num = match input_num {
503         Ok(num) => num,
504         Err(_) => {
505             println!("Please input a number!");
506             return;
507         }
508     };
509
510
511     println!("You guessed: {}", num);
512
513     match cmp(num, secret_number) {
514         Ordering::Less => println!("Too small!"),
515         Ordering::Greater => println!("Too big!"),
516         Ordering::Equal => println!("You win!"),
517     }
518 }
519
520 fn cmp(a: u32, b: u32) -> Ordering {
521     if a < b { Ordering::Less }
522     else if a > b { Ordering::Greater }
523     else { Ordering::Equal }
524 }
525 ```
526
527 We use a `match` to either give us the `u32` inside of the `Option`, or else
528 print an error message and return. Let's give this a shot:
529
530 ```bash
531 $ cargo run
532    Compiling guessing_game v0.0.1 (file:///home/you/projects/guessing_game)
533      Running `target/guessing_game`
534 Guess the number!
535 The secret number is: 17
536 Please input your guess.
537 5
538 Please input a number!
539 ```
540
541 Uh, what? But we did!
542
543 ... actually, we didn't. See, when you get a line of input from `stdin()`,
544 you get all the input. Including the `\n` character from you pressing Enter.
545 Therefore, `parse()` sees the string `"5\n"` and says "nope, that's not a
546 number; there's non-number stuff in there!" Luckily for us, `&str`s have an easy
547 method we can use defined on them: `trim()`. One small modification, and our
548 code looks like this:
549
550 ```{rust,no_run}
551 use std::old_io;
552 use std::rand;
553 use std::cmp::Ordering;
554
555 fn main() {
556     println!("Guess the number!");
557
558     let secret_number = (rand::random::<u32>() % 100) + 1;
559
560     println!("The secret number is: {}", secret_number);
561
562     println!("Please input your guess.");
563
564     let input = old_io::stdin().read_line()
565                            .ok()
566                            .expect("Failed to read line");
567     let input_num: Result<u32, _> = input.trim().parse();
568
569     let num = match input_num {
570         Ok(num) => num,
571         Err(_) => {
572             println!("Please input a number!");
573             return;
574         }
575     };
576
577
578     println!("You guessed: {}", num);
579
580     match cmp(num, secret_number) {
581         Ordering::Less => println!("Too small!"),
582         Ordering::Greater => println!("Too big!"),
583         Ordering::Equal => println!("You win!"),
584     }
585 }
586
587 fn cmp(a: u32, b: u32) -> Ordering {
588     if a < b { Ordering::Less }
589     else if a > b { Ordering::Greater }
590     else { Ordering::Equal }
591 }
592 ```
593
594 Let's try it!
595
596 ```bash
597 $ cargo run
598    Compiling guessing_game v0.0.1 (file:///home/you/projects/guessing_game)
599      Running `target/guessing_game`
600 Guess the number!
601 The secret number is: 58
602 Please input your guess.
603   76
604 You guessed: 76
605 Too big!
606 ```
607
608 Nice! You can see I even added spaces before my guess, and it still figured
609 out that I guessed 76. Run the program a few times, and verify that guessing
610 the number works, as well as guessing a number too small.
611
612 The Rust compiler helped us out quite a bit there! This technique is called
613 "leaning on the compiler", and it's often useful when working on some code.
614 Let the error messages help guide you towards the correct types.
615
616 Now we've got most of the game working, but we can only make one guess. Let's
617 change that by adding loops!
618
619 ## Looping
620
621 As we already discussed, the `loop` keyword gives us an infinite loop.
622 Let's add that in:
623
624 ```{rust,no_run}
625 use std::old_io;
626 use std::rand;
627 use std::cmp::Ordering;
628
629 fn main() {
630     println!("Guess the number!");
631
632     let secret_number = (rand::random::<u32>() % 100) + 1;
633
634     println!("The secret number is: {}", secret_number);
635
636     loop {
637
638         println!("Please input your guess.");
639
640         let input = old_io::stdin().read_line()
641                                .ok()
642                                .expect("Failed to read line");
643         let input_num: Result<u32, _> = input.trim().parse();
644
645         let num = match input_num {
646             Ok(num) => num,
647             Err(_) => {
648                 println!("Please input a number!");
649                 return;
650             }
651         };
652
653
654         println!("You guessed: {}", num);
655
656         match cmp(num, secret_number) {
657             Ordering::Less => println!("Too small!"),
658             Ordering::Greater => println!("Too big!"),
659             Ordering::Equal => println!("You win!"),
660         }
661     }
662 }
663
664 fn cmp(a: u32, b: u32) -> Ordering {
665     if a < b { Ordering::Less }
666     else if a > b { Ordering::Greater }
667     else { Ordering::Equal }
668 }
669 ```
670
671 And try it out. But wait, didn't we just add an infinite loop? Yup. Remember
672 that `return`? If we give a non-number answer, we'll `return` and quit. Observe:
673
674 ```bash
675 $ cargo run
676    Compiling guessing_game v0.0.1 (file:///home/you/projects/guessing_game)
677      Running `target/guessing_game`
678 Guess the number!
679 The secret number is: 59
680 Please input your guess.
681 45
682 You guessed: 45
683 Too small!
684 Please input your guess.
685 60
686 You guessed: 60
687 Too big!
688 Please input your guess.
689 59
690 You guessed: 59
691 You win!
692 Please input your guess.
693 quit
694 Please input a number!
695 ```
696
697 Ha! `quit` actually quits. As does any other non-number input. Well, this is
698 suboptimal to say the least. First, let's actually quit when you win the game:
699
700 ```{rust,no_run}
701 use std::old_io;
702 use std::rand;
703 use std::cmp::Ordering;
704
705 fn main() {
706     println!("Guess the number!");
707
708     let secret_number = (rand::random::<u32>() % 100) + 1;
709
710     println!("The secret number is: {}", secret_number);
711
712     loop {
713
714         println!("Please input your guess.");
715
716         let input = old_io::stdin().read_line()
717                                .ok()
718                                .expect("Failed to read line");
719         let input_num: Result<u32, _> = input.trim().parse();
720
721         let num = match input_num {
722             Ok(num) => num,
723             Err(_) => {
724                 println!("Please input a number!");
725                 return;
726             }
727         };
728
729
730         println!("You guessed: {}", num);
731
732         match cmp(num, secret_number) {
733             Ordering::Less => println!("Too small!"),
734             Ordering::Greater => println!("Too big!"),
735             Ordering::Equal => {
736                 println!("You win!");
737                 return;
738             },
739         }
740     }
741 }
742
743 fn cmp(a: u32, b: u32) -> Ordering {
744     if a < b { Ordering::Less }
745     else if a > b { Ordering::Greater }
746     else { Ordering::Equal }
747 }
748 ```
749
750 By adding the `return` line after the `You win!`, we'll exit the program when
751 we win. We have just one more tweak to make: when someone inputs a non-number,
752 we don't want to quit, we just want to ignore it. Change that `return` to
753 `continue`:
754
755
756 ```{rust,no_run}
757 use std::old_io;
758 use std::rand;
759 use std::cmp::Ordering;
760
761 fn main() {
762     println!("Guess the number!");
763
764     let secret_number = (rand::random::<u32>() % 100) + 1;
765
766     println!("The secret number is: {}", secret_number);
767
768     loop {
769
770         println!("Please input your guess.");
771
772         let input = old_io::stdin().read_line()
773                                .ok()
774                                .expect("Failed to read line");
775         let input_num: Result<u32, _> = input.trim().parse();
776
777         let num = match input_num {
778             Ok(num) => num,
779             Err(_) => {
780                 println!("Please input a number!");
781                 continue;
782             }
783         };
784
785
786         println!("You guessed: {}", num);
787
788         match cmp(num, secret_number) {
789             Ordering::Less => println!("Too small!"),
790             Ordering::Greater => println!("Too big!"),
791             Ordering::Equal => {
792                 println!("You win!");
793                 return;
794             },
795         }
796     }
797 }
798
799 fn cmp(a: u32, b: u32) -> Ordering {
800     if a < b { Ordering::Less }
801     else if a > b { Ordering::Greater }
802     else { Ordering::Equal }
803 }
804 ```
805
806 Now we should be good! Let's try:
807
808 ```bash
809 $ cargo run
810    Compiling guessing_game v0.0.1 (file:///home/you/projects/guessing_game)
811      Running `target/guessing_game`
812 Guess the number!
813 The secret number is: 61
814 Please input your guess.
815 10
816 You guessed: 10
817 Too small!
818 Please input your guess.
819 99
820 You guessed: 99
821 Too big!
822 Please input your guess.
823 foo
824 Please input a number!
825 Please input your guess.
826 61
827 You guessed: 61
828 You win!
829 ```
830
831 Awesome! With one tiny last tweak, we have finished the guessing game. Can you
832 think of what it is? That's right, we don't want to print out the secret number.
833 It was good for testing, but it kind of ruins the game. Here's our final source:
834
835 ```{rust,no_run}
836 use std::old_io;
837 use std::rand;
838 use std::cmp::Ordering;
839
840 fn main() {
841     println!("Guess the number!");
842
843     let secret_number = (rand::random::<u32>() % 100) + 1;
844
845     loop {
846
847         println!("Please input your guess.");
848
849         let input = old_io::stdin().read_line()
850                                .ok()
851                                .expect("Failed to read line");
852         let input_num: Result<u32, _> = input.trim().parse();
853
854         let num = match input_num {
855             Ok(num) => num,
856             Err(_) => {
857                 println!("Please input a number!");
858                 continue;
859             }
860         };
861
862
863         println!("You guessed: {}", num);
864
865         match cmp(num, secret_number) {
866             Ordering::Less => println!("Too small!"),
867             Ordering::Greater => println!("Too big!"),
868             Ordering::Equal => {
869                 println!("You win!");
870                 return;
871             },
872         }
873     }
874 }
875
876 fn cmp(a: u32, b: u32) -> Ordering {
877     if a < b { Ordering::Less }
878     else if a > b { Ordering::Greater }
879     else { Ordering::Equal }
880 }
881 ```
882
883 ## Complete!
884
885 At this point, you have successfully built the Guessing Game! Congratulations!
886
887 You've now learned the basic syntax of Rust. All of this is relatively close to
888 various other programming languages you have used in the past. These
889 fundamental syntactical and semantic elements will form the foundation for the
890 rest of your Rust education.
891
892 Now that you're an expert at the basics, it's time to learn about some of
893 Rust's more unique features.