Continue and Break

Java, like most languages, provides continue and break commands for escaping from loops. Recall that continue transfers control to the top of the loop while break transfers control to the end of the loop.

Example: Java BlackJack

In our version of Black Jack the deck is an array of 52 "cards". A card is simply identified by its point value (no suits). This is an integer k such that -1 <= k <= 10. We regard negative-valued cards as "jokers". The player keeps drawing cards, skipping jokers, until the total value of cards in his hand is 21 or greater. The player wins if the total is exactly 21.

Here's the Java implementation: BlackJack.java.

Notes

·       If cards[i] <= 0, we don't add it to the total, but use a continue command to skip to the next cards in the deck. When the total is at least 21 we use a break command to jump out of the loop.

Problem 1: Scala BlackJack version 1

Scala does have a break command… sort of. Here's how it works:

Break is a supplemental feature, so it needs to be imported:

import util.control.Breaks._

Here's the equivalent of a Java break command:

breakable {
  for(i <- 0 until N) {
     if (cond) break
     // do something
  }
}

Here's the equivalent of a Java continue command:

for(i <- 0 until N) {
  breakable {
     if (cond) break
     // do something
  }
}

Using these ideas, complete and test the implementation of BlackJack1 in BlackJack.scala.

Notes

1. This file uses Scala 1 syntax, which is similar to Java.

2. Instead of a static main method, Scala 1 uses a singleton object that extends the built-in App object. An App object is runnable. Everything inside of it is executed.

3. It's interesting to compare the way the cards array is initialized in Java and Scala. In Java we write:

for(int i = 0; i < 52; i++) cards[i] = (gen.nextBoolean())? gen.nextInt(11): -1;

The equivalent line in Scala is:

for(i <- 0 until 52) cards(i) = if (gen.nextBoolean()) gen.nextInt(11) else -1

How many differences can you spot? How many differences can you explain?

Problem 2: Scala BlackJack version 2

Another alternative is to use throw commands to mimic break and continue. Here's how to mimic break:

try {
  for(i <- 0 until N) {
     if (cond) throw new Exception
     // do something
  }
} catch {
  case _: Throwable => // no op
}

We can mimic continue by putting the try-catch block inside the loop:

for(i <- 0 until N) {
  try {
     if (cond) throw new Exception
     // do something
  } catch {
     case _: Throwable => // no op
  }
}

Implement BlackJack2 using these ideas.

Problem 3: Scala BlackJack version 3

The purpose of providing programmers with break and continue commands is to discourage them from using goto commands to get in and out of loops. (Very dangerous!) But are they necessary? Recall that Scala's for loop allows programmers to specify a guard condition to break out of a loop:

for(i <- 0 until N if cond) { 
  // do something
}

This is equivalent to:

for(int i = 0; i < N; i++) {
  if (!cond) break;
  // do something
}

And of course we can always use simple conditionals instead of a continue command:

for(i <- 0 until N) {
  if (cond) {
     // do something
  }
}

This is equivalent to:

for(int i = 0; i < N; i++) {
  if (!cond) continue;
  // do something
}

Implement BlackJack3 that uses these ideas.

Notes

This solution differs from the other in that the loop is executed 52 times, it's just that nothing happens if the guard conditions aren't met.