I have created a module for a War Simulator. I am getting "AttributeError: 'NoneType' object has no attribute 'value'" when I am calling the function.
Here is the code for the module:
import Deck
import Player
WAR_DRAW_COUNT = 5
player_one_cards = []
player_two_cards = []
def create_players() -> tuple[Player, Player]:
player_one = Player.Player("Billy Bob")
player_two = Player.Player("Joe Bab")
return (player_one, player_two)
def create_deck() -> Deck:
deck = Deck.Deck()
deck.shuffle()
return deck
def deal_cards(deck: Deck, player_one: Player, player_two: Player) -> None:
for cards in range(26):
player_one.add_cards(deck.deal_one())
player_two.add_cards(deck.deal_one())
def can_go_to_war(player: Player) -> bool:
if player.has_empty_hand() and player.get_play_hand_card_values() < 5:
return False
return True
def draw_war_cards(player_one: Player, player_two: Player,
player_one_cards: list, player_two_cards: list) -> None:
for card in range(WAR_DRAW_COUNT):
player_one_cards.append(player_one.remove_card())
player_two_cards.append(player_two.remove_card())
return None
def has_no_cards(player_one: Player, player_two: Player) -> bool:
if player_one.has_empty_hand():
print(f"{player_one.name} out of cards!")
print(f"{player_two.name.upper()} WINS!")
return True
if player_two.has_empty_hand():
print(f"{player_two.name} out of cards!")
print(f"{player_one.name.upper()} WINS!")
return True
return False
def prepare_hands(player_one: Player, player_two: Player,
player_one_cards, player_two_cards) -> None:
player_one_cards.append(player_one.remove_card())
player_two_cards.append(player_two.remove_card())
return None
def compare_values(player_one: Player, player_two: Player) -> bool:
if player_one_cards[-1].value > player_two_cards[-1].value:
player_one.add_cards(player_one_cards)
player_one.add_cards(player_two_cards)
return False
elif player_one_cards[-1].value < player_two_cards[-1].value:
player_two.add_cards(player_one_cards)
player_two.add_cards(player_two_cards)
return False
else:
print('WAR!')
return True
When I call the funtion from the main function at_war = War.compare_values(player_one, player_two), I get the error: AttributeError: 'NoneType' object has no attribute 'value'
Why is this?
I separated the code into main modules, Deck, Player, Card, and War.
Here is the traceback error:
File ***\main.py", line 54, in <module>
main()
File "***\main.py", line 33, in main
at_war = War.compare_values(player_one, player_two,
File "\***\War.py", line 69, in compare_values
if player_one_cards[-1].value > player_two_cards[-1].value:
AttributeError: 'NoneType' object has no attribute 'value'
Here is the additional Code:
class Player:
def __init__(self, name):
self.name = name
self.all_cards = []
def get_name(self):
return self.name
def remove_card(self):
if self.has_empty_hand():
print(f"{self.name} has no cards to remove")
return None
return self.all_cards.pop(0)
def add_cards(self, new_cards):
if type(new_cards) == type([]):
# List of single card objects
self.all_cards.extend(new_cards)
else:
# List of multiple card objects
self.all_cards.append(new_cards)
def get_card_count(self):
return len(self.all_cards)
def has_empty_hand(self):
if len(self.all_cards) == 0:
return True
else:
return False
def __str__(self):
if len(self.all_cards) == 1:
return f"{self.name} has {len(self.all_cards)} card."
else:
return f"{self.name} has {len(self.all_cards)} cards."
import War
def main():
round_number = 0
game_on = True
at_war = True
# War.setup
player_one, player_two = War.create_players()
deck = War.create_deck()
War.deal_cards(deck, player_one, player_two)
while game_on:
round_number += 1
print(f'Round {round_number}')
if War.has_no_cards(player_one, player_two):
break
# Start a new round
War.player_one_cards.clear()
War.player_two_cards.clear()
War.prepare_hands(player_one, player_two,
War.player_one_cards, War.player_two_cards)
at_war = True
while at_war:
at_war = War.compare_values(player_one, player_two)
if at_war:
if not War.can_go_to_war(player_one):
print(f"{player_one.name} unable to declare war.")
print(f"{player_two.name.upper()} WINS!")
game_on = False
break
if not War.can_go_to_war(player_two):
print(f"{player_two.name} unable to declare war.")
print(f"{player_one.name.upper()} WINS!")
game_on = False
break
War.draw_war_cards(player_one, player_two,
player_one_cards, player_two_cards)
if __name__ == "__main__":
main()