# Commits

committed 6a42279

Allow playing a hazard on another hazard, even if it's dumb.

• Participants
• Parent commits 5ac2bb6

# File mille.py

` `
` 	def is_legal(self, player, playee):`
` 		self.is_legal_base(player, playee)`
`-		self.playee_is_not_rolling(player, playee)`
`-`
`-		if self.on_discard(playee) or (not playee.battle_pile):`
`+		if self.on_discard(playee):`
` 			return`
` `
`-		top = playee.battle_pile[-1]`
`+		top = playee.normalized_battle_top()`
`+		if top is None:`
`+			self.illegal(", playee has not started rolling")`
`+`
` 		if (isinstance(top, Remedy)`
` 			and (top is not roll)`
`-			and (right_of_way not in playee.safeties)`
` 			):`
` 			self.illegal(", can't play a hazard on a remedy (" + repr(top) + ") (unless they've played the safety")`
` `
` 	def other(self):`
` 		return self.game.players[1 - int(self.game.players[1] == self)]`
` `
`-	def rolling(self):`
`-		row = right_of_way in self.safeties`
`+	def normalized_battle_top(self):`
`+		"""`
`+		Simulated top of battle pile once safeties are taken into effect.`
`+		 * if, all things considered, we're rolling, return roll.`
`+		 * if top is a hazard but we've played the safety (non-coup fourre)`
`+		   and we don't have Right-Of-Way`
`+		   then return the remedy.`
`+		"""`
`+		row = roll if right_of_way in self.safeties else None`
` 		if not self.battle_pile:`
` 			return row`
`+`
` 		top = self.battle_pile[-1]`
`-		if top == roll:`
`-			return True`
`+		if top is roll:`
`+			return top`
` 		if isinstance(top, Remedy):`
`-			return row`
`+			return row or top`
` 		assert isinstance(top, Hazard)`
`-		return row and (top.safety in self.safeties)`
`+		safety = top.safety`
`+		if safety in self.safeties:`
`+			return row or top.remedy`
`+		return top`
`+`
`+	def rolling(self):`
`+		return self.normalized_battle_top() == roll`
` `
` 	def autobahn(self):`
` 		row = right_of_way in self.safeties`
` 			self.hand.play()`
` `
` 			p1, p2 = self.players`
`-			p1_score = p1.score().score`
`-			p2_score = p2.score().score`
`-			if p1_score == p2_score:`
`+			if p1.mileage() in {700, 1000}:`
`+				winner = p1`
`+			elif p2.mileage() in {700, 1000}:`
`+				winner = p2`
`+			else:`
` 				winner = None`
`-			elif p1_score > p2_score:`
`-				winner = p1`
`-			else:`
`-				winner = p2`
` `
` 			self.winner = pickle_player(winner)`
` 			self.state = "hand end"`
` 		self.p1.draw_and_discard(25)`
` 		self.p2.draw_and_play(hazard2, self.p1)`
` `
`-	def can_play_accident_then_accident(self):`
`+	def test_can_play_accident_then_accident(self):`
` 		self.can_play_hazard_on_hazard(accident, accident)`
` `
`-	def can_play_accident_then_flat_tire(self):`
`+	def test_can_play_accident_then_flat_tire(self):`
` 		self.can_play_hazard_on_hazard(accident, flat_tire)`
` `
`-	def can_play_accident_then_out_of_gas(self):`
`+	def test_can_play_accident_then_out_of_gas(self):`
` 		self.can_play_hazard_on_hazard(accident, out_of_gas)`
` `
`-	def can_play_accident_then_stop(self):`
`+	def test_can_play_accident_then_stop(self):`
` 		self.can_play_hazard_on_hazard(accident, stop)`
` `
`-	def can_play_flat_tire_then_accident(self):`
`+	def test_can_play_flat_tire_then_accident(self):`
` 		self.can_play_hazard_on_hazard(flat_tire, accident)`
` `
`-	def can_play_flat_tire_then_flat_tire(self):`
`+	def test_can_play_flat_tire_then_flat_tire(self):`
` 		self.can_play_hazard_on_hazard(flat_tire, flat_tire)`
` `
`-	def can_play_flat_tire_then_out_of_gas(self):`
`+	def test_can_play_flat_tire_then_out_of_gas(self):`
` 		self.can_play_hazard_on_hazard(flat_tire, out_of_gas)`
` `
`-	def can_play_flat_tire_then_stop(self):`
`+	def test_can_play_flat_tire_then_stop(self):`
` 		self.can_play_hazard_on_hazard(flat_tire, stop)`
` `
`-	def can_play_out_of_gas_then_accident(self):`
`+	def test_can_play_out_of_gas_then_accident(self):`
` 		self.can_play_hazard_on_hazard(out_of_gas, accident)`
` `
`-	def can_play_out_of_gas_then_flat_tire(self):`
`+	def test_can_play_out_of_gas_then_flat_tire(self):`
` 		self.can_play_hazard_on_hazard(out_of_gas, flat_tire)`
` `
`-	def can_play_out_of_gas_then_out_of_gas(self):`
`+	def test_can_play_out_of_gas_then_out_of_gas(self):`
` 		self.can_play_hazard_on_hazard(out_of_gas, out_of_gas)`
` `
`-	def can_play_out_of_gas_then_stop(self):`
`+	def test_can_play_out_of_gas_then_stop(self):`
` 		self.can_play_hazard_on_hazard(out_of_gas, stop)`
` `
`-	def can_play_stop_then_accident(self):`
`+	def test_can_play_stop_then_accident(self):`
` 		self.can_play_hazard_on_hazard(stop, accident)`
` `
`-	def can_play_stop_then_flat_tire(self):`
`+	def test_can_play_stop_then_flat_tire(self):`
` 		self.can_play_hazard_on_hazard(stop, flat_tire)`
` `
`-	def can_play_stop_then_out_of_gas(self):`
`+	def test_can_play_stop_then_out_of_gas(self):`
` 		self.can_play_hazard_on_hazard(stop, out_of_gas)`
` `
`-	def can_play_stop_then_stop(self):`
`+	def test_can_play_stop_then_stop(self):`
` 		self.can_play_hazard_on_hazard(stop, stop)`
` `
` 	def can_play_hazard_on_hazard_when_other_player_uses_safety_and_has_right_of_way(self, hazard1, hazard2):`
` 				line1 = []`
` 				line2 = []`
` 				highlight = self.last_drawn`
`-				before = fill = after = " "`
`-				just_before = " "`
`+				stomp_next = ""`
`+				fill = " "`
` 				for i, card in enumerate(self.cards, 1):`
`-					line1.append(after)`
`-					line2.append(after)`
`-					after = " "`
`+`
` 					if card == highlight:`
`-						before = ">"`
`-						after = "<"`
`-						before = after = fill = ":"`
`+						fill = "."`
`+`
`+					field1 = ("[" + str(i) + "]").rjust(10, fill)`
`+					field2 = (repr(card)[:9]).rjust(10, fill)`
`+`
`+					if stomp_next:`
`+						field1 = stomp_next + field1[1:]`
`+						field2 = stomp_next + field2[1:]`
`+						stomp_next = ""`
`+					elif card == highlight:`
`+						def remove_alternating(s, removed):`
`+							a = []`
`+							next = " "`
`+							for c in s:`
`+								if c == removed:`
`+									a.append(next)`
`+									next = " " if next == removed else removed`
`+								else:`
`+									a.append(c)`
`+							return "".join(a)`
`+						field1 = ">" + remove_alternating(field1[1:], fill)`
`+						field2 = ">" + remove_alternating(field2[1:], fill)`
`+						stomp_next = "<"`
`+						fill = " "`
`+						# only highlight one card, even if we have more than one`
` 						highlight = None`
`-					else:`
`-						before = " "`
`-`
`-					line1.append((just_before + "[" + str(i) + "]").rjust(10, fill))`
`-					line2.append((just_before + repr(card)).rjust(10, fill)[:10])`
`-					fill = " "`
`-`
`-				if after:`
`-					line1.append(after)`
`-					line2.append(after)`
`+`
`+					line1.append(field1)`
`+					line2.append(field2)`
`+`
`+				if stomp_next:`
`+					line1.append(stomp_next)`
`+					line2.append(stomp_next)`
` `
` 				print()`
` 				print(" ", ''.join(line1))`