hi, im trying to make a program that simulates the game Risk. It should output something like this:

``````Attacking Army: Army A
Defending Army: Army B
Number of attacking army: 4
Number of defending army: 3
-----------------------------------
Round 1: Army A: 3, Army B: 2
Attackers' Dice:  5 2 1
Defenders' Dice: 4 2
Army A loses 1 army, Army B loses 1 army.
-----------------------------------
Round 2: Army A: 3, Army B: 3
Attackers' Dice: 2 2 1
Defenders' Dice:4 4
Army A loses 2 armies.
-----------------------------------
Army B wins the battle with 3 armies.``````

Basically in the game, the number of rounds keep going until either the attacking army is reduced to 1 or the defending army is reduced to 0.
Every round the attackers can roll 3 dice unless their army is < 4, then they roll current attacking army - 1 dice, every round the defenders can roll 2 dice unless their army = 1, then they only roll 1 dice.
The highest die are compared. If both armies roll at least 2 dice, the highest 2 dice are compared. Then each army is removed according to the dices after each round. (Ex: If both armies roll 2 dice, and both the attacking army's dice > defending army's dice, then defending army would lose 2 armies in that round) (If the dice number are equal, like 2 and 2, the defending army wins that)

Here's my code:

``````import dice     #to use the dice.roll function

import random

def roll(numatt, numdef):
""" numatt is either 1, 2 or 3, numdef is either 1 or 2.
returns two strings of digits, with  numatt  characters
in the first string and  numdef  characters in the second,
such that the digits appear in order of largest to smallest. """
if numatt not in [1,2,3]:
raise ValueError("Number of attackers dice must be 1, 2 or 3.")
if numdef not in [1,2]:
raise ValueError("Number of defenders dice must be 1 or 2.")
attl = []
for i in range(numatt):
attl.append(chr(int(random.random() * 6.0) + 1 + ord('0')))
attl.sort()
attl.reverse()
atts = "".join(attl)
defl = []
for i in range(numdef):
defl.append(chr(int(random.random() * 6.0) + 1 + ord('0')))
defl.sort()
defl.reverse()
defs = "".join(defl)
return atts, defs

name_att = raw_input("Enter the name of the attacking territory: ")
name_def = raw_input("Enter the name of the defending territory: ")
num_att = int(raw_input("Enter the number of attacking armies: "))
num_def = int(raw_input("Enter the number of defending armies: "))

num_att_lost = num_att - 1
num_def_lost = num_def - 1

print name_att + ": " + str(num_att)
print name_def + ": " + str(num_def)
attdice, defdice = dice.roll(3, 2)
print "Attackers' dice: ", attdice[0], "", attdice[1], "", attdice[2]
print "Defenders' dice: ", defdice[0], "", defdice[1]
print '-' * 60

dice.roll(num_att, num_def)

#while num_att !=0 or num_def !=0: (this loop produced a infinite loop ><)
if attdice < defdice:
print str(name_att) + " " + "loses" + " " + str(num_att_lost) + " armies."
elif attdice == defdice:
print str(name_att) + " " + "loses" + " " + str(num_att_lost) + " armies."
else:
print str(name_def) + " " + "loses" + " " + str(num_def_lost) + " armies."

if num_att == 0:
print str(name_def) + " " + "wins the battle with" + " " + str(num_def) + \
" armies."
if num_def == 0:
print str(name_att) + " " + "wins the battle with" + " " + str(num_att) + \
" armies."``````

Some problems I have are:
-I don't know how to make a loop that generates each round until it it's over, like round 1, round 2. I tried using a while loop but it produced a infinite loop and I can't generate the round numbers. (I don't think I can use a for loop because I have no clue how many rounds it would take to finish the game)

-Another problem is that the calculations to remove armies from each side are wrong sometimes when I run my current code, sometimes it will only remove one army when it's supposed to remove 2, and I don't know how to make it so that the game will end when the attacking army is reduced to one, or when the defending army is reduced to 0.

-Also, I don't know why but I can't input more than 3 armies for the attacking army, and more than 2 for the defending army in the beginning.

Any help/explanations would be appreciated, thank you.

You want to use a class structure for this, so each player can be an instance of the same class, and divide the code into several small functions.

Also, I don't know why but I can't input more than 3 armies for the attacking army, and more than 2 for the defending army in the beginning.

``````if numatt not in [1,2,3]:
raise ValueError("Number of attackers dice must be 1, 2 or 3.")
if numdef not in [1,2]:
raise ValueError("Number of defenders dice must be 1 or 2.")``````

Here is some redundant code that you can put into one function that returns the result. And, sort() can sort in reverse, avoiding the extra statement,
attl.sort(reverse=True) http://wiki.python.org/moin/HowTo/Sorting

``````attl = []
for i in range(numatt):
attl.append(chr(int(random.random() * 6.0) + 1 + ord('0')))
attl.sort()
attl.reverse()
atts = "".join(attl)

## same as above
defl = []
for i in range(numdef):
defl.append(chr(int(random.random() * 6.0) + 1 + ord('0')))
defl.sort()
defl.reverse()
defs = "".join(defl)``````