# A Tale of Two Cities Magnus Madsen. Software Architecture Project 2.

## Presentation on theme: "A Tale of Two Cities Magnus Madsen. Software Architecture Project 2."— Presentation transcript:

A Tale of Two Cities Magnus Madsen

Software Architecture Project 2

Winner Strategy You are asked to implement: where a player has won if he has conquered all cities, i.e. RED has won if BLU controls no cities (and vice versa) public Player getWinner(Collection cities); Real world issue: What if there are no cities? => Implementation dependent 3 / 12

Think, but don't speak How would you implement this in Java? In your favorite language? RED has won if BLU controls no cities (and vice versa) 4 / 12

Solution I public Player getWinner(GameImpl game) { Player winner = null; Player lastOwner = null; for (CityImpl c : game.getCities()) { if (lastOwner == null) { lastOwner = c.getOwner(); winner = lastOwner; } else { if (!lastOwner.equals(c.getOwner())) { winner = null; break; }}} return winner; } obvious? n > 2 players? single pass? early termination? easy to parallelize?   5 / 12

Solution II public Player getWinner(GameImpl game) { List players = new ArrayList (); for (CityImpl c : game.getCitiesIterable()) { if (!players.contains(c.getOwner())) { players.add(c.getOwner()); if (players.size() >= 2) break; } if (players.size() == 1) return players.get(0); else return null; } obvious? n > 2 players? single pass? early termination? easy to parallelize?   6 / 12

Solution III public Player computeWinner(GameImpl game) { Player assumedWinner = null; for (CityImpl c : game.getCities().values()) { if (assumedWinner == null) { assumedWinner = c.getOwner(); } else { if (!c.getOwner().equals(assumedWinner)) return null; } return assumedWinner; } obvious? n > 2 players? single pass? early termination? easy to parallelize?   7 / 12

Solution IV public Player computeWinner(GameImpl game) { int red = 0; int blue = 0; for (CityImpl c : game.getCities().values()) { if (c.getOwner() == Player.RED) { red++; } else { blue++; } } if (blue == 0) { return Player.RED; } if (red == 0) { return Player.BLUE; } return null; } obvious? n > 2 players? single pass? early termination? easy to parallelize?    8 / 12

Solution V def getWinner(cities: ParSet[City]): City = { val redCity = cities.exist(c => c.isRed); val blueCity = cities.exist(c => c.isBlue); if (!blueCity) Player.Red else if (!redCity) Player.Blue else null } obvious? n > 2 players? single pass? early termination? easy to parallelize?   9 / 12

Solution VI def getWinner(cities: ParSet[City]): City = { if (cities.isEmpty) return null; return cities.reduce((c1, c2) => if (c1 == c2) c1 else null ); } obvious? n > 2 players? single pass? early termination? easy to parallelize?  10 / 12

Solution VII def getWinner(cities: ParSet[City]): Color = { if (cities.isEmpty) return null; val c1 = cities.head.color; if (cities.exists(c2 => c1 != c2.color)) null else c1 } obvious? n > 2 players? single pass? early termination? easy to parallelize? 11 / 12

Summary Interesting properties: – obvious implementation (i.e. correctness)? – n > 2 players? – early termination? – single pass? – embarrassingly parallel? A variety of interesting solutions: – mutating, accumulating, counting, reducing,... 12 / 12