Question
Add to the __assign_army method in the Army the implementation of creating an army when the formation value is 1. Add to the Battle class
Add to the __assign_army method in the Army the implementation of creating an army when the formation value is 1.
Add to the Battle class the method fairer_combat(self, player_one: str, player_two: str) -> int, which reads and creates an army for each player, sets those armies (e.g army1, army2) in queue formation, calls __conduct_combat(self, army1, army2, 1) and returns the combat result.
Fairer Style Combat
While each army has at least one Fighter unit in their force:
- Serve a unit from each army (say U1 and U2).
- Attack and defend following the rules indicated in the Background.
- Any unit still alive after step 2 is appended back into the queue.
- If at least one army is empty, combat ends. Otherwise go back to step 1.
Testing
Add extra tests to test_task5.py for __conduct_combat. This will require you to add the __str__ method to the CircularQueue class. Also, test fairer_combat with manual inputs.
"""
Testing file for Question 5 of Interview Prac 2
__author__ = "Maria Garcia de la Banda"
__edited__ = "Ben Di Stefano"
"""
import unittest
from army import Archer, Soldier, Cavalry, Army
from battle import Battle
class TestTask5(unittest.TestCase):
def setUp(self):
self.verificationErrors = []
def tearDown(self):
for item in self.verificationErrors:
print(item)
print("Number of Errors = "+str(len(self.verificationErrors)))
def test__conduct_combat(self):
t1 = Army()
t2 = Army()
battle = Battle()
formation = 1
# Test if combat is conducted correctly and if it returns
# appropriate result for all Archer p1 army and empty p2 army
# Assumes __assign_army is working correctly
t1._Army__assign_army("", 0, 10, 0, formation)
t2._Army__assign_army("", 0, 0, 0, formation)
try:
self.assertTrue(battle._Battle__conduct_combat(t1, t2, formation) == 1, "Fairer 0,10,0 0,0,0 failed")
except AssertionError as e:
self.verificationErrors.append(str(e))
# Tests combat is conducted correctly and if it
# returns appropriate result for 1 Soldier p1 army and 1 Archer p2 army
# Assumes __assign_army is working correctly
t1._Army__assign_army("", 1, 0, 0, formation)
t2._Army__assign_army("", 0, 1, 0, formation)
try:
self.assertTrue(battle._Battle__conduct_combat(t1, t2, formation) == 2, "Fairer 1,0,0 0,1,0 failed")
except AssertionError as e:
self.verificationErrors.append(str(e))
try:
self.assertEqual(str(t1.force), "", msg="Army 1 wrong for Fairer 1,0,0 0,1,0")
except AssertionError as e:
self.verificationErrors.append(str(e))
try:
self.assertEqual(str(t2.force), "Archer's life = 1 and experience = 1", msg="Army 2 wrong for Fairer 1,0,0 0")
except AssertionError as e:
self.verificationErrors.append(str(e))
# your tests for __conduct_combat go here
if __name__ == '__main__':
suite = unittest.TestLoader().loadTestsFromTestCase(TestTask5)
unittest.TextTestRunner(verbosity=0).run(suite)
""" Queue ADT and an array implementation.
Defines a generic abstract queue with the usual methods, and implements
a circular queue using arrays. Also defines UnitTests for the class.
"""
__author__ = "Maria Garcia de la Banda for the base"+"XXXXX student for"
__docformat__ = 'reStructuredText'
import unittest
from abc import ABC, abstractmethod
from typing import TypeVar, Generic
from referential_array import ArrayR, T
class Queue(ABC, Generic[T]):
""" Abstract class for a generic Queue. """
def __init__(self) -> None:
self.length = 0
@abstractmethod
def append(self,item:T) -> None:
""" Adds an element to the rear of the queue."""
pass
@abstractmethod
def serve(self) -> T:
""" Deletes and returns the element at the queue's front."""
pass
def __len__(self) -> int:
""" Returns the number of elements in the queue."""
return self.length
def is_empty(self) -> bool:
""" True if the queue is empty. """
return len(self) == 0
@abstractmethod
def is_full(self) -> bool:
""" True if the stack is full and no element can be pushed. """
pass
def clear(self):
""" Clears all elements from the queue. """
self.length = 0
class CircularQueue(Queue[T]):
""" Circular implementation of a queue with arrays.
Attributes:
length (int): number of elements in the stack (inherited)
front (int): index of the element at the front of the queue
rear (int): index of the first empty space at the oback of the queue
array (ArrayR[T]): array storing the elements of the queue
ArrayR cannot create empty arrays. So MIN_CAPCITY used to avoid this.
"""
MIN_CAPACITY = 1
def __init__(self,max_capacity:int) -> None:
Queue.__init__(self)
self.front = 0
self.rear = 0
self.array = ArrayR(max(self.MIN_CAPACITY,max_capacity))
def append(self, item: T) -> None:
""" Adds an element to the rear of the queue.
:pre: queue is not full
:raises Exception: if the queueu is full
"""
if self.is_full():
raise Exception("Queue is full")
self.array[self.rear] = item
self.length += 1
self.rear = (self.rear + 1) % len(self.array)
def serve(self) -> T:
""" Deletes and returns the element at the queue's front.
:pre: queue is not empty
:raises Exception: if the queue is empty
"""
if self.is_empty():
raise Exception("Queue is empty")
self.length -= 1
item = self.array[self.front]
self.front = (self.front+1) % len(self.array)
return item
def is_full(self) -> T:
""" True if the queue is full and no element can be appended. """
return len(self) == len(self.array)
def clear(self) -> None:
""" Clears all elements from the queue. """
Queue.__init__(self)
self.front = 0
self.rear = 0
class TestQueue(unittest.TestCase):
""" Tests for the above class."""
EMPTY = 0
ROOMY = 5
LARGE = 10
CAPACITY = 20
def setUp(self):
self.lengths = [self.EMPTY, self.ROOMY, self.LARGE, self.ROOMY, self.LARGE]
self.queues = [CircularQueue(self.CAPACITY) for i in range(len(self.lengths))]
for queue, length in zip(self.queues, self.lengths):
for i in range(length):
queue.append(i)
self.empty_queue = self.queues[0]
self.roomy_queue = self.queues[1]
self.large_queue = self.queues[2]
#we build empty queues from clear.
#this is an indirect way of testing if clear works!
#(perhaps not the best)
self.clear_queue = self.queues[3]
self.clear_queue.clear()
self.lengths[3] = 0
self.queues[4].clear()
self.lengths[4] = 0
def tearDown(self):
for s in self.queues:
s.clear()
def test_init(self):
self.assertTrue(self.empty_queue.is_empty())
self.assertEqual(len(self.empty_queue), 0)
def test_len(self):
""" Tests the length of all queues created during setup."""
for queue, length in zip(self.queues, self.lengths):
self.assertEqual(len(queue), length)
def test_is_empty_add(self):
""" Tests queues that have been created empty/non-empty."""
self.assertTrue(self.empty_queue.is_empty())
self.assertFalse(self.roomy_queue.is_empty())
self.assertFalse(self.large_queue.is_empty())
def test_is_empty_clear(self):
""" Tests queues that have been cleared."""
for queue in self.queues:
queue.clear()
self.assertTrue(queue.is_empty())
def test_is_empty_serve(self):
""" Tests queues that have been served completely."""
for queue in self.queues:
#we empty the queue
try:
while True:
was_empty = queue.is_empty()
queue.serve()
#if we have served without raising an assertion,
#then the queue was not empty.
self.assertFalse(was_empty)
except:
self.assertTrue(queue.is_empty())
def test_is_full_add(self):
""" Tests queues that have been created not full."""
self.assertFalse(self.empty_queue.is_full())
self.assertFalse(self.roomy_queue.is_full())
self.assertFalse(self.large_queue.is_full())
def test_append_and_serve(self):
for queue in self.queues:
nitems = self.ROOMY
for i in range(nitems):
queue.append(i)
for i in range(nitems):
self.assertEqual(queue.serve(), i)
def test_clear(self):
for queue in self.queues:
queue.clear()
self.assertEqual(len(queue), 0)
self.assertTrue(queue.is_empty())
if __name__ == '__main__':
testtorun = TestQueue()
suite = unittest.TestLoader().loadTestsFromModule(testtorun)
unittest.TextTestRunner().run(suite)
""" Stack ADT and an array implementation.
Defines a generic abstract stack with the usual methods, and implements
a stack using arrays. Also defines UnitTests for the class.
"""
__author__ = "Maria Garcia de la Banda for the base"+"XXXXX student for"
__docformat__ = 'reStructuredText'
import unittest
from abc import ABC, abstractmethod
from typing import TypeVar, Generic
from referential_array import ArrayR, T
class Stack(ABC, Generic[T]):
def __init__(self) -> None:
self.length = 0
@abstractmethod
def push(self,item:T) -> None:
""" Pushes an element to the top of the stack."""
pass
@abstractmethod
def pop(self) -> T:
""" Pops an element from the top of the stack."""
pass
@abstractmethod
def peek(self) -> T:
""" Pops the element at the top of the stack."""
pass
def __len__(self) -> int:
""" Returns the number of elements in the stack."""
return self.length
def is_empty(self) -> bool:
""" True if the stack is empty. """
return len(self) == 0
@abstractmethod
def is_full(self) -> bool:
""" True if the stack is full and no element can be pushed. """
pass
def clear(self):
""" Clears all elements from the stack. """
self.length = 0
class ArrayStack(Stack[T]):
""" Implementation of a stack with arrays.
Attributes:
length (int): number of elements in the stack (inherited)
array (ArrayR[T]): array storing the elements of the queue
ArrayR cannot create empty arrays. So MIN_CAPCITY used to avoid this.
"""
MIN_CAPACITY = 1
def __init__(self, max_capacity: int) -> None:
""" Initialises the length and the array with the given capacity.
If max_capacity is 0, the array is created with MIN_CAPACITY.
"""
Stack.__init__(self)
self.array = ArrayR(max(self.MIN_CAPACITY, max_capacity))
def is_full(self) -> bool:
""" True if the stack is full and no element can be pushed. """
return len(self) == len(self.array)
def push(self, item: T) -> None:
""" Pushes an element to the top of the stack.
:pre: stack is not full
:raises Exception: if the stack is full
"""
if self.is_full():
raise Exception("Stack is full")
self.array[len(self)] = item
self.length += 1
def pop(self) -> T:
""" Pops the element at the top of the stack.
:pre: stack is not empty
:raises Exception: if the stack is empty
"""
if self.is_empty():
raise Exception("Stack is empty")
self.length -= 1
return self.array[self.length]
def peek(self) -> T:
""" Returns the element at the top, without popping it from stack.
:pre: stack is not empty
:raises Exception: if the stack is empty
"""
if self.is_empty():
raise Exception("Stack is empty")
return self.array[self.length-1]
class TestStack(unittest.TestCase):
""" Tests for the above class."""
EMPTY = 0
ROOMY = 5
LARGE = 10
CAPACITY = 20
def setUp(self):
self.lengths = [self.EMPTY, self.ROOMY, self.LARGE, self.ROOMY, self.LARGE]
self.stacks = [ArrayStack(self.CAPACITY) for i in range(len(self.lengths))]
for stack, length in zip(self.stacks, self.lengths):
for i in range(length):
stack.push(i)
self.empty_stack = self.stacks[0]
self.roomy_stack = self.stacks[1]
self.large_stack = self.stacks[2]
#we build empty stacks from clear.
#this is an indirect way of testing if clear works!
#(perhaps not the best)
self.clear_stack = self.stacks[3]
self.clear_stack.clear()
self.lengths[3] = 0
self.stacks[4].clear()
self.lengths[4] = 0
def tearDown(self):
for s in self.stacks:
s.clear()
def test_init(self):
self.assertTrue(self.empty_stack.is_empty())
self.assertEqual(len(self.empty_stack), 0)
def test_len(self):
""" Tests the length of all stacks created during setup."""
for stack, length in zip(self.stacks, self.lengths):
self.assertEqual(len(stack), length)
def test_is_empty_add(self):
""" Tests stacks that have been created empty/non-empty."""
self.assertTrue(self.empty_stack.is_empty())
self.assertFalse(self.roomy_stack.is_empty())
self.assertFalse(self.large_stack.is_empty())
def test_is_empty_clear(self):
""" Tests stacks that have been cleared."""
for stack in self.stacks:
stack.clear()
self.assertTrue(stack.is_empty())
def test_is_empty_pop(self):
""" Tests stacks that have been popped completely."""
for stack in self.stacks:
#we empty the stack
try:
while True:
was_empty = stack.is_empty()
stack.pop()
#if we have popped without raising an assertion,
#then the stack was not empty.
self.assertFalse(was_empty)
except:
self.assertTrue(stack.is_empty())
def test_is_full_add(self):
""" Tests stacks that have been created not full."""
self.assertFalse(self.empty_stack.is_full())
self.assertFalse(self.roomy_stack.is_full())
self.assertFalse(self.large_stack.is_full())
def test_push_and_pop(self):
for stack in self.stacks:
nitems = self.ROOMY
for i in range(nitems):
stack.push(i)
for i in range(nitems-1, -1, -1):
self.assertEqual(stack.pop(), i)
def test_clear(self):
for stack in self.stacks:
stack.clear()
self.assertEqual(len(stack), 0)
self.assertTrue(stack.is_empty())
if __name__ == '__main__':
testtorun = TestStack()
suite = unittest.TestLoader().loadTestsFromModule(testtorun)
unittest.TextTestRunner().run(suite)
class Battle:
def gladiatorial_combat(self, player_one: str, player_two: str) -> int:
pass
def __conduct_combat(self, army1: Army, army2: Army, formation: int) -> int:
pass
Step by Step Solution
There are 3 Steps involved in it
Step: 1
Get Instant Access to Expert-Tailored Solutions
See step-by-step solutions with expert insights and AI powered tools for academic success
Step: 2
Step: 3
Ace Your Homework with AI
Get the answers you need in no time with our AI-driven, step-by-step assistance
Get Started