Et nyt bud på en simulation af krig

Min Python-simulation af kortspillet Krig var ikke særlig elegant. Ved krig og dobbelt-krig osv. var en masse “if”-sætninger inde i hinanden med samme logik. (Jeg fandt også nogle dumme fejl, så jeg har opdateret det oprindelige indlæg.)

Derfor har jeg prøvet at skrive en ny version.

Den fungerer fint og giver følgende output ved 1.000.000 spil:

Der blev spillet 1000000 spil
Det gennemsnitlige antal dueller var 177.217668
Det højeste antal dueller var 2238
Det laveste antal dueller var 3
Den spiller med højest sum af kort vandt 573276 gange (57%)
Den spiller med højest sum af kort tabte 397771 gange (40%)
Uafgjorte spil: 1
Antal enkeltkrig, dobbeltkrig, osv.: 12348559, 886651, 60655, 3722, 218, 11, 2
Vendte kort uden krig og med krig: 176766958, 13299818
Spillene tog 225.4 sekunder

Det nye program:

# KRIG #
import time
start_time = time.time()
import random

number_of_games_to_play = 1000000
number_of_games_counter = 0
number_of_plays_list = []
highest_deck_won = 0
highest_deck_lost = 0
equal_games = 0
war_types = [0,0,0,0,0,0,0]
war_or_not_war = [0,0]

# Loop to play games
percentage_copy = 0
i = 0
while i < number_of_games_to_play:
	# One is added to i so loop finishes once number of games have been played
	i += 1
	
	# Prints percentage done with 1 decimal every time it changes
	percentage_completed = round((i/number_of_games_to_play*100), 1)
	if percentage_copy != percentage_completed:
		print("{}% done".format(percentage_completed))
	percentage_copy = percentage_completed

	# Create a deck, shuffle it and divide between players
	deck = [2,2,2,2,3,3,3,3,4,4,4,4,5,5,5,5,6,6,6,6,7,7,7,7,8,8,8,8,9,9,9,9,10,10,10,10,11,11,11,11,12,12,12,12,13,13,13,13,14,14,14,14]
	random.shuffle(deck)
	player_a_deck = deck[0:26]
	player_b_deck = deck[26:52]

	# Which player has the highest sum of cards
	card_sum_a = sum(player_a_deck)
	card_sum_b = sum(player_b_deck)
	if card_sum_a > card_sum_b:
		highest_deck = "a"
	elif card_sum_a < card_sum_b:
		highest_deck = "b"
	else:
		highest_deck = "equal"
	
	# Loop to turn cards within games
	number_of_plays = 0
	index = 1
	while True:
		try:
			if index == 1:
				number_of_plays += 1	# Add 1 to number of plays counter
				war_count = 0			# Reset war counter	
			# Player a has the largest card
			if player_a_deck[index-1] > player_b_deck[index-1]:
				war_or_not_war[0] += 1
				player_a_deck.extend(player_a_deck[:index])
				player_a_deck.extend(player_b_deck[:index])	
				del player_a_deck[:index]
				del player_b_deck[:index]
				index = 1			# If a play is decided, index is reset
			# Player b has the largest card
			elif player_a_deck[index-1] < player_b_deck[index-1]:
				war_or_not_war[0] += 1
				# Cards are added in different order to deck in order to avoid (game) risk of going on forever (infinite loop)!
				player_b_deck.extend(player_b_deck[:index])	
				player_b_deck.extend(player_a_deck[:index])
				del player_a_deck[:index]
				del player_b_deck[:index]
				index = 1			# If a play is decided, index is reset
			# War is on!
			else:
				war_or_not_war[1] += 1
				index += 4			# In case of war the index is upped by four cards
				war_types[war_count] += 1
				war_count += 1
		# If a player has too few cards left to participate, game is over
		except IndexError:
			# If a player had no cards left and index is 1, the game was already over, so number of plays is corrected
			if index == 1:
				number_of_plays -= 1
			break
	
	# Single game is over #
	# Compare deck sizes to decide winner and add values to counters and lists
	deck_a = len(player_a_deck)
	deck_b = len(player_b_deck)
	if deck_a > deck_b:
		if highest_deck == "a":
			highest_deck_won += 1
		elif highest_deck == "b":
			highest_deck_lost += 1
	elif deck_a < deck_b:
		if highest_deck == "a":
			highest_deck_lost += 1
		elif highest_deck == "b"    :
			highest_deck_won += 1
	else:
		equal_games += 1
	
	number_of_plays_list.append(number_of_plays)
	number_of_games_counter += 1
	
# All games are over #
print("Der blev spillet {} spil".format(number_of_games_counter))
print("Det gennemsnitlige antal dueller var {}".format(sum(number_of_plays_list)/len(number_of_plays_list)))
print("Det højeste antal dueller var {}".format(max(number_of_plays_list)))
print("Det laveste antal dueller var {}".format(min(number_of_plays_list)))
print("Den spiller med højest sum af kort vandt {} gange ({}%)".format(highest_deck_won, round(highest_deck_won/number_of_games_counter*100)))
print("Den spiller med højest sum af kort tabte {} gange ({}%)".format(highest_deck_lost, round(highest_deck_lost/number_of_games_counter*100)))
print("Uafgjorte spil: {}".format(equal_games))
print("Antal enkeltkrig, dobbeltkrig, osv.: {}".format(", ".join(str(x) for x in war_types)))
print("Vendte kort uden krig og med krig: {}".format(", ".join(str(x) for x in war_or_not_war)))
print("Spillene tog {} sekunder".format(round(time.time() - start_time, 1)))