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.scala.

Notes

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.scala 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.scala that uses these ideas.