Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #axis and allies battle simulator program
- #prefix definitions: a = attacker, d = defender, o = original
- #
- #
- #this version uses/supports:
- #'sub insta kills' rule
- #'two hit battleships' rule - bug: subs can still kill batts in 1 hit
- #battleship bombardment
- #
- #
- #add proper error handling
- #add optional 'type of mission' options
- #
- #
- #Planning/Notes:
- #
- #TYPES OF 'MISSIONS'
- #unit arrangement for above scenario (lose left units first):
- #if conditions for missions not met, default to weakest/(cheapest?) die first
- #
- #1. Occupy enemy territory at all costs (attacker only)
- #if tank > 0:
- #inf, fight, bomb, *ships here, order doesn't matter*
- #elif inf > 0:
- #tank, fight, bomb, inf, *ships here*
- #else:
- #weakest die first
- #
- #2. Protect [x unit] at all costs
- #############################################################################################
- # #
- # FOR THOSE NOT FAMILIAR WITH THE BOARD GAME 'AXIS & ALLIES': #
- # #
- # -1- AA is similar to Risk but there are different units which have different #
- # attack and defense skills #
- # -2- 'two hit battleship' means battleships can take 2 hits before being destroyed. #
- # they still only fire one shot each, like the other units #
- # -3- 'sub insta kills' means victims of attacking submarines cannot fire back #
- # and are destroyed immediately (unless the victim is a two hit battleship, in which #
- # case it simply gets damaged and IS allowed to return fire) #
- # -4- antiaircraft guns (AA guns) can only fire at the beginning of a battle #
- # -5- only the defender can have an AA gun, and only one may exist at one time #
- # -6- 'bombarding battleships' only fire once, and are only supposed to be usable #
- # against land targets (as opposed to sea). only attackers can bombard #
- # #
- # This information is presented as it's relevant to this program. Not all of this info #
- # is directly translatable to the actual board game #
- #############################################################################################
- import random
- class mainClass():
- def army_chooser(self, team):
- inf = 0; tank = 0; fight = 0; bomb = 0; trans = 0; dummy_unit = 0
- sub = 0; carr = 0; batt = 0; battb = 0; dbatt = 0; army_ready = 0; aa_gun = 0
- while army_ready != 1:
- print "\nEnter 0 when all %s units have been entered\n" % team
- print 'Current %s force:' % team
- print inf, 'Infantry'
- print tank, 'Tank(s)'
- print fight, 'Fighter(s)'
- print bomb, 'Bomber(s)'
- print trans, 'Transport(s)'
- print sub, 'Submarine(s)'
- print carr, 'Carrier(s)'
- print batt / 2, 'Battleship(s)'
- if team == 'defending':
- print aa_gun, 'AA gun(s)'
- else:
- print battb, 'Bombarding battleships'
- print '\n1. Infantry\n2. Tank\n3. Fighter\n4. Bomber\n5. Transport\n6. Submarine'
- print '7. Carrier\n8. Battleship'
- if team == 'defending':
- print '9. AA Gun'
- else:
- print '9. Bombarding battleship'
- try:
- choice = input('\nEnter the number to add a type of unit')
- if choice == 0:
- army_ready = 1
- elif choice == 1:
- inf = input('How many?')
- elif choice == 2:
- tank = input('How many?')
- elif choice == 3:
- fight = input('How many?')
- elif choice == 4:
- bomb = input('How many?')
- elif choice == 5:
- trans = input('How many?')
- elif choice == 6:
- sub = input('How many?')
- elif choice == 7:
- carr = input('How many?')
- elif choice == 8:
- batt = input('How many?') * 2
- elif (choice == 9) and (team == 'attacking'):
- battb = input('How many?')
- elif (choice == 9) and (team == 'defending'):
- aa_gun = 1
- except:
- print 'Invalid input'
- #numbers after unit names are their attack and defense skills, respectively
- #some units, like battb, are an exception
- return [trans, 0, 1, 'trans'], [inf, 1, 2, 'inf'], [tank, 3, 2, 'tank'],\
- [fight, 3, 4, 'fight'], [bomb, 4, 1, 'bomb'], [sub, 2, 2, 'sub'],\
- [carr, 1, 3, 'carr'], [batt, 4, 4, 'batt'],\
- [battb, 0, 0, 'battb'], [dbatt, 4, 4, 'dbatt'],\
- [aa_gun, 0, 0, 'aa'], [dummy_unit, 0, 0, 'dummy']
- def duplicate_original_armies(self, o_a_units, o_d_units):
- a_units = []; d_units = []
- for i in o_a_units:
- a_units.append(i[:])
- for i in o_d_units:
- d_units.append(i[:])
- return a_units, d_units
- def roll(self, units, stance, team, a_units, d_units):
- hits = 0; sub_insta_kills = 0; d_sub_hits = 0; batt_present = 0
- for i in units:
- if i[0] > 0: #i[0] is amount of a specific unit
- skill = i[stance] #chooses attacker or defender fighting skill
- if i[3] == 'batt': #if battleship
- units[7][0] = units[7][0] / 2 #each 2 hit battleship only takes one shot each
- batt_present = 1
- for j in range(i[0]): #roll one die per unit present
- if random.randint(1, 6) <= skill:
- if (i[3] == 'sub') and (team == 'a'):
- sub_insta_kills += 1
- elif (i[3] == 'sub') and (team == 'd'):
- d_sub_hits += 1
- else:
- hits += 1
- if batt_present == 1:
- units[7][0] = units[7][0] * 2 #restore original battleship value
- return [hits], sub_insta_kills, d_sub_hits
- def remove_casualties(self, units, opposing_hits, d_sub_hits):
- passer = 0
- for i in units:
- while (i[0] > 0) and ((opposing_hits > 0) or (d_sub_hits > 0)):
- if i[3] == 'batt':
- while (opposing_hits > 0) and (i[0] > 0):
- i[0] = i[0] - 2 #battleship - 2
- opposing_hits = opposing_hits - 1
- units[9][0] += 1 #dbatt + 1
- while (d_sub_hits > 0) and (i[0] > 0):
- i[0] = i[0] - 2
- d_sub_hits = d_sub_hits - 1
- units[9][0] += 1 #dbatt + 1
- elif (i[3] == 'fight') or (i[3] == 'bomb'):
- passer += 1
- while (opposing_hits > 0) and (i[0] > 0):
- i[0] = i[0] - 1
- opposing_hits = opposing_hits - 1
- elif i[3] == 'dummy':
- d_sub_hits = 0
- if ((i[3] != 'batt') and (i[3] != 'fight')) and ((i[3] != 'bomb') and (i[3] != 'dummy')) and\
- (i[3] != 'battb'):
- while ((opposing_hits > 0) or (d_sub_hits > 0)) and (i[0] > 0):
- i[0] = i[0] - 1
- opposing_hits = opposing_hits - 1
- if passer >= 3:
- d_sub_hits = 0
- return units
- def fire_aa_and_remove_aa_casualties(self, aa_gun, a_units):
- planes = 0; aa_hits = 0
- if aa_gun == 1:
- for i in a_units:
- if (i[3] == 'fight') or (i[3] == 'bomb'):
- planes += i[0]
- for j in range(planes):
- if random.randint(1, 6) == 1:
- aa_hits += 1
- print 'aa gun hits = ', aa_hits
- for i in a_units:
- while ((i[3] == 'fight') or (i[3] == 'bomb')) and ((i[0] > 0) and (aa_hits > 0)):
- i[0] = i[0] - 1
- aa_hits = aa_hits - 1
- return a_units
- def fire_battb_and_remove_casualties(self, a_units, d_units):
- bombard_hits = 0
- for i in a_units:
- if (i[3] == 'battb') and (i[0] > 0):
- for k in range(i[0]):
- if random.randint(1, 6) <= 4:
- bombard_hits += 1
- for j in d_units:
- while (bombard_hits > 0) and (j[0] > 0):
- j[0] = j[0] - 1
- bombard_hits = bombard_hits - 1
- a_units[8][0] = 0
- return d_units
- def remove_sub_insta_kills(self, units, sub_insta_kills): #submarine kills don't allow victim unit to fire back
- passer = 0 #except (undamaged) two hit battleships
- for i in units:
- while (i[0] > 0) and (sub_insta_kills > 0):
- if (i[3] == 'fight') or (i[3] == 'bomb'):
- #subs aren't allowed to destroy planes
- passer += 1
- if passer == 3:
- sub_insta_kills = 0 #nothing present that subs can kill
- else:
- i[0] = i[0] - 1
- sub_insta_kills = sub_insta_kills - 1
- return units
- def check_if_battle_over(self, a_units, d_units, a_wins, d_wins, draw, iterations):
- restart_round = 1; a_dead = 1; d_dead = 1; a_won = 0; d_won = 0
- for i in a_units:
- if i[0] > 0: #if any units alive
- a_dead = 0
- if a_dead == 1:
- d_wins += 1
- d_won = 'yes'
- for i in d_units:
- if i[0] > 0:
- d_dead = 0
- if d_dead == 1:
- a_wins += 1
- a_won = 'yes'
- if (a_dead == 1) and (d_dead == 1):
- draw += 1; a_wins = a_wins - 1; d_wins = d_wins - 1
- if (a_dead == 1) or (d_dead == 1):
- iterations += 1
- restart_round = 0
- return a_wins, d_wins, draw, iterations, restart_round, a_won, d_won
- def run_battle(self, a_units, d_units):
- desired_iterations = input('How many times do you want to run the battle?')
- rerun = 1
- while rerun == 1:
- iterations = 0; a_wins = 0; d_wins = 0; draw = 0; average_units_left = [0, 0]
- while iterations < desired_iterations:
- restart_round = 1
- print 'processing battle #', iterations + 1
- dupes = x.duplicate_original_armies(o_a_units, o_d_units)
- a_units = dupes[0]; d_units = dupes[1]
- while restart_round == 1:
- a_units = x.fire_aa_and_remove_aa_casualties(d_units[10][0], a_units)
- d_units[10][0] = 0
- total_a_hits = x.roll(a_units, 1, 'a', a_units, d_units)
- a_hits = total_a_hits[0][0]; sub_insta_kills = total_a_hits[1]
- d_units = x.remove_sub_insta_kills(d_units, sub_insta_kills)
- d_units = x.fire_battb_and_remove_casualties(a_units, d_units)
- total_d_hits = x.roll(d_units, 2, 'd', a_units, d_units)
- d_hits = total_d_hits[0][0]
- d_sub_hits = total_d_hits[2]
- x.remove_casualties(a_units, d_hits, d_sub_hits)
- x.remove_casualties(d_units, a_hits, 0)
- y = x.check_if_battle_over(a_units, d_units, a_wins, d_wins, draw, iterations)
- a_wins = y[0]; d_wins = y[1]; draw = y[2]; iterations = y[3]; restart_round = y[4]
- a_units[7][0] = a_units[7][0] / 2; d_units[7][0] = d_units[7][0] / 2
- if y[5] == 'yes': #if a won
- for i in a_units:
- for j in range(i[0]):
- average_units_left[0] += 1
- elif y[6] == 'yes': #if d won
- for i in d_units:
- for j in range(i[0]):
- average_units_left[1] += 1
- a_units[7][0] = a_units[7][0] * 2; d_units[7][0] = d_units[7][0] * 2
- rerun = x.statistics(a_wins, d_wins, draw, iterations, average_units_left)
- def statistics(self, a_wins, d_wins, draw, iterations, average_units_left):
- print '\nResults for', iterations, 'simulations'
- print '\nAttacker win % =', float(a_wins) / iterations * 100,
- if a_wins > 0:
- print ' Average units left:', float(average_units_left[0]) / a_wins
- print 'Defender win % =', float(d_wins) / iterations * 100,
- if d_wins > 0:
- print ' Average units left:', float(average_units_left[1]) / d_wins
- print 'Draw % =', float(draw) / iterations * 100
- return input('\nRerun last simulation? 0 for no, 1 for yes')
- program_restart = 1
- restart_round = 1
- while program_restart == 1:
- x = mainClass()
- o_a_units = x.army_chooser('attacking')
- o_d_units = x.army_chooser('defending')
- z = x.run_battle(o_a_units, o_d_units)
- program_restart = input('\nRestart Program? 0 for no, 1 for yes')
- raw_input('exit')
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement