Attribute error from an object that isn't called upon [closed] - python

Closed. This question is not reproducible or was caused by typos. It is not currently accepting answers.
This question was caused by a typo or a problem that can no longer be reproduced. While similar questions may be on-topic here, this one was resolved in a way less likely to help future readers.
Closed 1 year ago.
Improve this question
I am working on a Mastermind game in python, and one of my classes is called the Game class. This runs a 'setup' of the game as such (like finding the player count, player names etc.). However, one of my methods which checks the name inputted against a player list previously defined/stored in a separate class is bringing up an AttributeError when I try to append the name to a new list created in my Game class. This is what my Game class currently looks like:
class WorldOfMastermind:
"""WOM class - Runs whole game, takes results from other classes and stores them (namely players and their scores)"""
def __init__(self):
self.__playerList = []
self.__playerDetails = dict()
def run(self):
"""Run method - holds the menu screen - allows for the user to add player, show scores, play game or quit"""
cpuNames = ComputerPlayer.addDetails(self)
self.__playerList.extend((cpuNames))
start = input('What would you like to do?\n (r) register a new user\n (s) show the score board\n (p) play a game\n (q) quit\n')
if start == 'r':
tempName = HumanPlayer.addDetails(self)
for i in self.__playerList:
if i == tempName:
print('')
print('Sorry, that name already exists')
print('')
self.run()
self.__playerList.append(tempName)
self.__playerDetails[tempName] = [0, 0, float(0)]
print('Welcome,', tempName + '!')
print('')
self.run()
elif start == 's':
self.printScoreBoard()
elif start == 'p':
print('Let\'s play the game of Mastermind!')
Game.startPrep(self, self.__playerList)
elif start == 'q':
print('Thank you for playing the World of Mastermind!')
exit()
else:
print('\nSorry, that is an invalid input')
print('')
self.run()
def printScoreBoard(self):
""" Print the scoreboard by iterating through the dictionary """
print('=====================================')
print('Name Score Games Average ')
print('=====================================')
for i in self.__playerDetails:
print('{:<15} '.format(i), '{:>5}'.format(self.__playerDetails[i][0]), '{:>5}'.format(self.__playerDetails[i][1]), '{:>7}'.format(self.__playerDetails[i][2]))
print('=====================================\n')
self.run()
class Game:
"""Begin the initialization of the game and return results to WOM class"""
def __init__(self, playerCount):
self.__playerCount = playerCount
self.__playingList = []
def startPrep(self, playerList):
"""Prepares the game"""
Game.getPlayerCount(self)
Game.getPlayerNames(self, playerList)
def getPlayerCount(self):
"""Gathers the number of players"""
while True:
try:
self.__playerCount = int(input('How many players (2-4)?'))
except ValueError:
print('Only numbers allowed')
else:
if self.__playerCount < 2 or self.__playerCount > 4:
print('Player count must be between 2-4 inclusive')
else:
break
def getPlayerNames(self, playerList):
"""Gathers names of players and puts them into a list"""
while True:
if self.__playerCount == 2:
while True:
player1 = input('What is the name of player #1?')
if player1 in playerList:
print('successful')
self.__playingList.append(player1)
break
else:
print('Invalid username')
while True:
player2 = input('What is the name of player #2?')
if player2 in playerList:
if player2 not in self.__playingList:
print('successful')
self.__playingList.append(player2)
break
else:
print(player2, 'is already in the game.')
else:
print('Invalid username')
break
Where I feel the error is coming from is in the calling of the getPlayerNames method. As it takes a parameter (the player list from another class), this is purely to check that the name inputted is actually in the game, and if so it prints 'successful' (which it does) but when trying to append the inputted name into the new 'playingList' it brings up the error. I'm not sure why this is as the append line doesn't have any need to reference attributes from another class. Any advice would be appreciated thanks!

Your code works for me, formatted as below.. If I run the following, it asks for the player count and makes sure the names you give are in the eligible player list.
class Game:
"""Begin the initialization of the game and return results to WOM class"""
def __init__(self, playerCount=0):
self.__playerCount = playerCount
self.__playingList = []
def startPrep(self, eligible):
"""Prepares the game"""
self.getPlayerCount()
self.getPlayerNames(eligible)
def getPlayerCount(self):
"""Gathers the number of players"""
while True:
try:
self.__playerCount = int(input('How many players (2-4)?'))
except ValueError:
print('Only numbers allowed')
else:
if self.__playerCount < 2 or self.__playerCount > 4:
print('Player count must be between 2-4 inclusive')
else:
break
def getPlayerNames(self, playerList):
"""Gathers names of players and puts them into a list"""
for i in range(self.__playerCount):
while True:
s = 'What is the name of player #%d? '%(i+1)
player = input(s)
if player in playerList:
print('successful')
self.__playingList.append(player)
break
else:
print('Invalid username')
g = Game()
g.startPrep(['bob','bill'])

Related

How to make a Cage Fighting Simulation with user input instead of random for Python

Here is my code so far using random to pick moves:
import time
import random
PHealth = 10
CHealth = 10
PShots = [
"Great Body Shot To Your Opponent!",
"Nice Take Down!",
"Nice Punch!",
"Strong Kick!",
"You Have Him Pinned Against The Cage!",
"Excellent Counter-Shot!"
]
CShots = [
"You Took a Shot to the Body!",
"You Got Taken Down!",
"Strong Kick Hit You!",
"You Took A Big Punch!",
"You Are Pinned Against The Cage",
"Counter-Shot Got Ya!"
]
for i in range(20):
i = random.randint(0, 100)
if i >= 51:
print(random.choice(PShots))
CHealth = CHealth -1
if CHealth >= 1:
print("Player Health", PHealth)
print("Computer Health", CHealth)
time.sleep(5)
if i <= 50:
print(random.choice(CShots))
PHealth = PHealth -1
if PHealth >= 1:
print("Player Health", PHealth)
print("Computer Health", CHealth)
time.sleep(5)
if CHealth < 1:
print("What A Shot!")
time.sleep(1)
print("Down He Goes!")
time.sleep(1)
print("The Referee Has Stopped The Fight!!")
time.sleep(1)
print("Player Wins!!!")
break
if PHealth < 1:
print("What A Shot!")
time.sleep(1)
print("Down You Go!")
time.sleep(1)
print("The Referee Has Stopped The Fight!!")
time.sleep(1)
print("Computer Wins!!!")
break
Basically I'd like to understand how a player can input one move. So if a player inputs body shot it beats take down. If a player inputs kick it beats punch. If a player inputs take down it beats pinned against the cage, etc. Thinking 6-7 variations and counters.
Here is an idea of how you could implement something akin to what you seem to be looking for using a mix of classes and functions.
The following code should work with Python 3.9+ and has no additional dependencies.
First we define a Move class, instances of which need to have a name, a text_used (for when the player successfully uses the move), and a text_affected (for when move is used against the player). Each instance also stores a set of other Move objects, which it trumps, as well as a set of those it is trumped by. We have a helper method should_beat to easily define such a relationship between two moves.
class Move:
def __init__(self, name: str, text_used: str, text_affected: str, damage: int = 1) -> None:
self.name: str = name
self.text_used: str = text_used
self.text_affected: str = text_affected
self.damage: int = damage
self.trumps: set['Move'] = set()
self.trumped_by: set['Move'] = set()
def __str__(self) -> str:
return self.name
def should_beat(self, other_move: 'Move') -> None:
self.trumps.add(other_move)
other_move.trumped_by.add(self)
Next we define a Player class. Its instances have a name and an optional starting_health set to a previously defined constant by default.
A Player also has a use_move method that takes a Move object, another Player object (the opponent), and a second Move object (the move used by the opponent). That method checks which move beats which and calculates the health subtraction accordingly.
Finally, the Player object has win and lose methods that can be called to print out the win/loss statements when necessary.
class Player:
def __init__(self, name: str, starting_health: int = DEFAULT_STARTING_HEALTH) -> None:
self.name: str = name
self.health: int = starting_health
def __str__(self) -> str:
return self.name
def use_move(self, move: Move, vs_player: 'Player', vs_move: Move) -> None:
if vs_move in move.trumped_by:
self.health -= vs_move.damage
print(vs_move.text_affected)
elif move in vs_move.trumped_by:
vs_player.health -= move.damage
print(move.text_used)
else:
print(TEXT_NO_EFFECT)
def win(self, vs: 'Player') -> None:
print("What A Shot!")
sleep(1)
print(f"{vs} Goes Down!")
sleep(1)
print("The Referee Has Stopped The Fight!!")
sleep(1)
print(f"{self} Wins!!!")
def lose(self, vs: 'Player') -> None:
print("What A Shot!")
sleep(1)
print(f"Down You Go, {self}!")
sleep(1)
print("The Referee Has Stopped The Fight!!")
sleep(1)
print(f"{vs} Wins!!!")
Next, we want a function to define our moves and one that conveniently prints a list of moves to the terminal. Obviously you will want to expand the define_moves function to incorporate all your desired moves and their relationships. It should return a list of all your Move objects.
def define_moves() -> list[Move]:
kick = Move("kick", "Strong Kick!", "Strong Kick Hit You!")
punch = Move("punch", "Nice Punch!", "You Took A Big Punch!")
...
kick.should_beat(punch)
...
return [
kick,
punch,
]
def print_moves(moves_list: list[Move]) -> None:
print("Available moves:")
for i, move in enumerate(moves_list):
print(i, "-", move.name)
Now for the fun part, we need our main fighting loop. In each iteration, we prompt the player for a number that corresponds to an index in our list of moves defined earlier. (The player may also type h to see the moves again.) We do some checks to make sure we received a valid number to get our Move object.
Then we randomly chose a move for the computer opponent out of our moves list, and call our use_move method. It does the health calculations for us. So after that we just check, if someone is done to call the appropriate win or lose method and break out of the loop. Otherwise we print the current health stats and continue.
def fight_computer(player: Player, moves_list: list[Move]) -> None:
computer = Player(name="Computer")
while True:
string = input('Choose your move! (or type "h" to see available moves again)\n').strip().lower()
if string == 'h':
print_moves(moves_list)
continue
try:
i = int(string)
except ValueError:
print("You need to pick a number!")
continue
try:
move = moves_list[i]
except IndexError:
print("No move available with number", i)
continue
computer_move = choice(moves_list)
print(computer, "chose", computer_move)
player.use_move(move, vs_player=computer, vs_move=computer_move)
if player.health < 1:
player.lose(vs=computer)
break
if computer.health < 1:
player.win(vs=computer)
break
print(player, "health:", player.health)
print(computer, "health:", computer.health)
sleep(1)
Lastly, we need a main function to put it all together, prompt the player for his name, etc.
def main() -> None:
player_name = input("Enter your name: ").strip()
player = Player(player_name)
moves_list = define_moves()
print_moves(moves_list)
fight_computer(player, moves_list)
if __name__ == '__main__':
main()
Don't forget to add your imports and constant definitions to the start of the module:
from random import choice
from time import sleep
DEFAULT_STARTING_HEALTH = 10
TEXT_NO_EFFECT = "Your move had no effect!"
All together, this should give you a crude version of the game you described. Try it out. Hope this helps.

Why changing a function argument reflects to the main value that is I passed to that function?

I have tried to create a BLACKJACK game using python (actually I'm learning python). Currently I have not setup bet command (that is written in my Account class). I only takes name from my Account class.
I have a main file : blackjack.py
and two classes in files : deckofcards.py, account.py
I am only accessing name from account class, so I wont be putting that long mess here.
blackjack.py :
from account import Account
player = Account('kalaLokia')
cards = DeckOfCards()
play = False
playershand = []
dealershand = []
action = ''
blackjack = False
def showCards(items, name):
'''
Shows {name}'s cards and hand value
'''
print(f"{name}'s hand: ")
print(f"\t{' - '.join(items)}")
print(f"Hand value: {cards.handValue(items)}")
def bust(hand):
'''
Whether a someone has busted or not
'''
if(cards.handValue(hand) > 21):
return True
return False
def dealersMove():
'''
Dealers move: executes when player calls "stand"
Dealer perform hit until he gets bust, wins or his hand value becomes >= 17
When hand value is >17 and players has greater value, dealer loses ;-)
'''
global blackjack
if(cards.handValue(dealershand) == 21):
print('Dealer got a BLACKJACK')
print('Dealer WINS')
return
elif(blackjack):
print(f'{player.name} got a BLACKJACK')
print(f'{player.name} WINS')
blackjack=False
return
while(not bust(dealershand)):
if(cards.handValue(dealershand) > cards.handValue(playershand)):
print('Dealer WINS')
showCards(dealershand, 'Dealer')
break
elif(cards.handValue(dealershand) == cards.handValue(playershand)):
print("It's a TIE!!\n Dealer WINS")
break
elif(cards.handValue(dealershand) > 17):
print(f'Dealer loses\n{player.name} has WON.')
print(f'{cards.handValue(playershand)} > {cards.handValue(dealershand)}')
break
dealershand.append(cards.hit())
else:
print(f'Dealer busts! \n{player.name} has WON the game.')
def start():
'''
The actiona that can be performed
'''
global blackjack
if(cards.handValue(playershand) == 21):
blackjack = True
dealersMove()
return
while(not bust(playershand)):
action = input(
f"{player.name}'s turn: Do you want to hit or stand ? ").lower()
if(action == 'hit'):
playershand.append(cards.hit())
showCards(playershand, player.name)
elif(action == 'stand'):
dealersMove()
break
else:
print('Please enter a valid action !')
else:
print(f'{player.name} has been BUSTED')
if __name__ == "__main__":
print(f'Hello {player.name}, Welcome to BlackJack Game')
# Tell game rules here, may be
response = input('Do you want to start the game (Y/n)? ').lower()
if(response != 'y'):
play = False
print('You have been exited the game')
else:
play = True
# Ask for bet amount later
while(play):
cards = DeckOfCards()
cards.shuffle()
print('Cards on the table is now shuffled')
playershand = list(cards.initiate())
dealershand = list(cards.initiate())
print(
f"{player.name}'s hand:\n {playershand[0]} - {playershand[1]}\nHand value: {cards.handValue(playershand)}\n")
print(f"Dealer's hand:\n {dealershand[0]} - ?\n")
start()
if(input('Do you want to play again (Y/n)?').lower() != 'y'):
print('The End')
play = False
deckofcards.py :
import random
class DeckOfCards():
'''
All talks here is about cards
'''
cards = {'A':11,'K':10,'Q':10,'J':10,'2':2,'3':3,'4':4,'5':5,'6':6,'7':7,'8':8,'9':9,'10':10}
def __init__(self):
'''
Initialize deck of cards
'''
self.deck = list(self.cards.keys())*4
def shuffle(self):
'''
Simply shuffles the deck of cards
'''
return random.shuffle(self.deck)
def handValue(self, hand):
'''
Calculates and returns the hand value, expecting a string value to be feeded.
'''
result = 0
for element in hand:
result = result + self.cards[element]
while('A' in hand and result > 21):
if(hand[0]=='A'):
result = result - 10
# Somehow this hand.pop is poping out from main value itself. Why ???
hand.pop(0)
if(hand == []):
break
return result
def hit(self):
'''
Pop out and returns the last card in the deck
'''
return self.deck.pop()
def initiate(self):
'''
Pop out 2 cards from the deck and return as a tuple
'''
return (self.deck.pop(), self.deck.pop() )
Issue:
When I have an ACE in my hand and my hand value is greater than 21, the while condition executes in the handValue function (which is in DeckofCards class) as it is. Problem is, after that while condition executes, playershand (declared in main file) I just passed to this handValue function gets empty. That is the hand.pop(0) actually seems popping out value from main object playershand itself (It seems me so).
When I press a hit after that, I get a single new card, all other cards are got popped out. I don't understand why it is so.
On hit(user enter hit) : actually I am passing playershand (cards on the player hand, it's a list) to function showCards (which is also in the main file) where it takes it as argument items and pass it to handValue function in the class DeckOfCards.
So why is it happening? even though I am passing playershand as an argument to other functions, how pop() function affecting playershand which has only access to hand object in the handValue class ?
I have my complete code in github repo to test out, the files in folder blackjack

manipulate class instance

I want to give the second instance of my Player class the remaining marker after the first instance gets one of them.
class Player():
available_markers = ['X', 'O']
num_of_players = 0
player2_marker = ' '
def __init__(self):
self.name = input('Please enter your name : ')
self.marker = ' '
Player.num_of_players += 1
def choose_marker(self):
while Player.num_of_players != 2:
self.marker = input('Choose X or O')
if self.marker == Player.available_markers[0]:
Player.player2_marker == Player.available_markers[-1]
else:
Player.player2_marker == Player.available_markers[0]
else:
self.marker = Player.player2_marke
I would like to accomplish this in the instance method but have went through a lot of code that doesn't quite work.
There are some misunderstandings of object-oriented coding in your code so I'll try to address them in my answer. One of the goals of object-oriented programming is the separation of concerns. If you have some logic about how a game works and you have some logic about how a player works, you don't want the logic for both in the same place intermixed.
All the player really needs to know is what their name, marker and player number are:
class Player():
num_of_players = 0
def __init__(self, name, marker):
Player.num_of_players += 1
self.name = name
self.marker = marker
self.number = Player.num_of_players
print(self.number, self.marker)
Separate from that is how you want to start the game and initialize the players. You could create another class called Game but for now, I'll just do a function:
def start_game():
available_markers = ['X', 'O']
print("Player 1")
name = input('Please enter your name : ')
Let's not trust that the user of the program will enter the right thing:
while True:
marker = input('Choose X or O: ')
We will loop forever and just break out of it if a valid option is chosen:
if marker in available_markers:
break
else:
print("Invalid choice. Please pick again")
player1 = Player(name, marker)
We'll remove that marker from the list so the list just has one element in it now:
available_markers.remove(marker)
print("Player 2")
name = input('Please enter your name : ')
player2 = Player(name, available_markers[0])
start_game()
# Player 1
# Please enter your name : Adam
# Choose X or O: X
# 1 X
# Player 2
# Please enter your name : Joe
# 2 O
Note that I create two separate instances of Player.
Let's talk briefly about class variables vs instant variables. I kept num_of_players as a class variable to track the total number of players (accessible by doing Player.num_of_players or player1.num_of_players both will return that there are 2 total players). I also created another variable number so each player can track what their number is. That's an instance variable and tracked separately for each instance.

Attribute Error Blackjack Python [closed]

Closed. This question is not reproducible or was caused by typos. It is not currently accepting answers.
This question was caused by a typo or a problem that can no longer be reproduced. While similar questions may be on-topic here, this one was resolved in a way less likely to help future readers.
Closed 8 years ago.
Improve this question
I have to modify this program from my text book to use bets but I cant even get the original program to run. This is the program as it appears in the book except each class are on different pages. I'm not sure if I need to even type out all these classes because my professor said take the blackjack program and modify it to accept bets but it imports deck and card so I'm not sure. I typed them out just in case because I figured it wouldn't do much harm maybe I am wrong.
class Card(object):
RANKS=(1,2,3,4,5,6,7,8,9,10,11,12,13)
SUITS=('Spades','Diamonds','Hearts','Clubs')
def _init_(self,rank,suit):
self.rank=rank
self.suit=suit
def _str_(self):
if self.rank==1:
rank='Ace'
elif self.rank==11:
rank='Jack'
elif self.rank==12:
rank='Queen'
elif self.rank==13:
rank='King'
else:
rank=self.rank
return str(rank)+ ' of ' + self.suit
import random
class Deck(Card,object):
def _init_(self):
self._cards=[]
for suit in Card.SUITS:
for rank in Card.RANKS:
c=Card(rank,suit)
self._cards.append(c)
def shuffle(self):
random.shuffle(self._cards)
def deal(self):
if len(self)==0:
return None
else:
return self._cards.pop(0)
def _len_(self):
return len(self._cards)
def _str_(self):
result=''
for c in self._cards:
result= result+str(c)+'\n'
return result
class Player(Deck,object):
def _init_(self, cards):
self._cards= cards
def _str_(self):
result=",".join(map(str,self._cards))
results += "\n " + str(self.getPoints()) + " points"
return result
def hit(self,card):
self._cards.append(card)
def getPoints(self):
count=0
for card in self._cards:
if card.rank>9:
count+=10
elif card.rank==1:
count+=11
else:
count+=card.rank
for card in self._cards:
if count <=21:
break
elif card.rank==1:
count -= 10
return count
def hasBlackjack(self):
return len(self._cards)==2 and self.getpoints()==21
class Dealer(Player,object):
def _init_(self,cards):
Player._init_(self,cards)
self._showOneCard= True
def _str_(self):
if self._showOneCard:
return str(self._cards[0])
else:
return Player._str_(self)
def hit(self,deck):
self._showOneCard= False
while self.getPoints() <17:
self.Cards.append(deck.deal())
class Blackjack(Player, object):
def _init_(self):
self._deck = Deck()
self._deck.shuffle()
self._player = Player([self._deck.deal(),
self._deck.deal()])
self._dealer = Dealer([self._deck.deal(),
self._deck.deal()])
def play(self):
print ("Player:\n", self._player)
print ("Dealer:\n", self._dealer)
while True:
choice = input("Do you want to hit? [y/n]: ")
if choice in ("Y","y"):
self._player.hit(self._deck.deal())
points = self._player.getPoints()
print ("Player:\n", self._player)
if points >= 21:
break
else:
break
playerPoints = self._player.getPoints()
if playerPoints> 21:
print ("You bust and lose")
else:
self._dealer.hit(self._deck)
print ("Dealer:\n", self._dealer)
dealerPoints=self._dealer.getpoints()
if dealerPoints >21:
print ("Dealer busts you win")
elif dealerPoints>playerPoints:
print ("Dealer wins")
elif dealerPoints<playerPoints and playerPoints <= 21:
print ("You win")
elif dealerPoints == playerPoints:
if self._player.hasBlackjack() and not self._dealer.hasBlackjack():
print ("You win")
elif not self._player.hasBlackjack() and self._dealer.hasBlackjack():
print ("Dealer wins")
else:
print ("There is a tie")
Blackjack().play()
I get
Traceback (most recent call last):
File "C:\Users\Schuler\bj.py", line 151, in <module>
Blackjack().play()
File "C:\Users\Schuler\bj.py", line 117, in play
print ("Player:\n", self._player)
AttributeError: 'Blackjack' object has no attribute '_player'
I copied everything straight from the book and I can't figure out what is wrong.
_____Edit_____
So It was pointed out I forgot double underscores so I fixed that. Then I ran if like 10 more times and found small spelling mistakes it runs now.
It looks like you left out the double underscores on some of your method definitions. It's __init__, not _init_. Same goes for __str__, __len__, and other special class methods.
These special method names have to be written exactly otherwise they won't work. For instance, if you have a method named __init__ then the code in that method will get run automatically when you instantiate an object of that type. Because you typed it wrong the method never ran and your code gave the error.
A simple illustration of how __init__ works:
class Player(object):
def __init__(self):
print 'new player object'
Player() # __init__() called automatically and prints 'new player object'

Need help writing algorithm in Python/Sage

I'm a complete novice to python and sage so I need some help and clarification on the steps all the way through. This is a question concerning game theory.
First I will describe the algorithm and then I will propose a solution the best I can.
The algorithm:
I want to start the program with a random variable from 1-100. This
variable will be defined 'S'. I also want to define a set of variables
'C' which can be deducted from S every turn, this set is {1,2,3,4,5,6}
(in other words the user and computer can deduct 1, 2, 3, 4, 5 or 6
from S. If variable S is divisible by 7 (e.g. 21), then print: "I
lose". If not, the game can begin.
Let's say that the random variable turns out to be 20. The player is
now prompted to enter a number within the range of C. When the player
has entered the number, I want the program to deduct that number from
S, so if the player enters 4 (a legal move), S is then 20-4=16. The
computer then calculates mod(S,7) and finds out that modulo 16,7 is 2
so it deducts 2 from S, in other words, 16-2=14.
If the player enters a number which results in S being divisible by 7, such as 6 (20-6=14) then the computer simply deducts 1 and attempts to get to such a number again next round.
The game continues until the computer eventually wins as the player is
eventually placed at 7 and has to deduct a number which the computer
can finish with (user deducts 6, computer deducts the last one and
wins). Print: "I win".
So like I said, I have literally no experience in python and sage so I can only go by my (limited) java experience:
I would attempt to establish a variable S with some 'ran' element (no idea what it's called in python). I would then attempt something like:
if S%7=0 then print "I lose"
else
prompt "Pick a number between 1 and 6, those included".
Declare user input as variable U.
Do S-U=S
Now do S-S%7=S
Now I want the program to realize when S=7 and then print: "You lose". If you can help me go all the way, though, that would be great.
import random
def playgame():
s = random.randint(1,100) #grabs a random integer between 1 and 100
POSS = range(1,7) #range ignores the last number, so this is [1,2,3,4,5,6]
if not s % 7: #if s%7 != 0
print("I lose")
return #exit the function
while s > 0: #while s is still positive
choice = 0 #set choice to 0 (this may as well have been "foo",
# I just needed it to not be in POSS)
while choice not in POSS: #until the user picks a valid number
choice = int(input("Select a number between 1 and 6: ")) #prompt for input
s -= choice #subtract choice from s, then set the difference to s
print("You subtracted {}, leaving {}".format(choice,s)) #print for the user
comp_choice = s%7 #the computer's choice is always s%7
s -= comp_choice #subtract the comp's choice from s, then set the diff to s
print("I subtracted {}, leaving {}".format(comp_choice,s)) #print for user
print("I win!") #since we know computer will always win, I don't have to do a check
playgame() #run the function
Here's a vastly more complicated function that does essentially the exact same thing ;-)
class Entity(object):
"""Base class that should not be instantiated on its own -- only
exists to be inherited from. Use Player() and Computer() instead"""
def __init__(self,name=None):
if name is None:
name = input("What's your name? ")
self.name = name
self.myturn = False
def __str__(self):
# this magic function means calling str(self) returns str(self.name)
# included so I can do print(player)
return self.name
def makemove(self,choice):
"""finds the global s and subtracts a given choice from it,
printing the choice and the result to the user."""
global s
s -= choice
print("{} chooses {}, leaving {}".format(self,choice,s))
return choice
def activate(self):
self.myturn = True
return self
def deactivate(self):
"""does exactly self.myturn = False"""
self.myturn = False
class Player(Entity):
"""A player-controlled Entity"""
def getchoice(self):
"""Prompts the user for a choice, ensuring it's between 1 and 6, then
calls Entity's makemove() with that as an argument"""
choice = None
while choice not in range(1,7):
choice = int(input("Pick a number between 1 and 6: "))
return super().makemove(choice)
class Computer(Entity):
def __init__(self):
super().__init__(name="Computer Player")
#overrides to ensure every Computer object has the name Computer Player
def getchoice(self):
"""grabs a number for the computer, and makes its move"""
global s
choice = s%7
if choice == 0: #edge case where computer goes first on an s where s%7==0
choice = random.randint(1,6)
return super().makemove(choice)
class Game(object):
"""Class defining an instance of the Game
FUNCTIONS:
Game.start() <-- use this to start the game"""
def __init__(self,playerArray=[]):
"""defines s as a global, ensures the players array is built
correctly, and gives s a random int value between 1-100"""
global s
if type(playerArray) is Player:
playerArray = [playerArray]
while len(playerArray) < 2:
playerArray.append(Computer())
self.players = playerArray
s = random.randint(1,100)
def start(self):
"""Let's play!"""
global s
print ("""
====================================
THE GAME BEGINS NOW!!!
We will begin with a value of: {:3}
====================================""".format(s).lstrip())
turn = random.randint(1,len(self.players))-1
while True:
try:active_player = self.players[turn].activate()
except IndexError: print(turn)
choice = active_player.getchoice()
if s <= 0: break
active_player.deactivate() # is active_player.myturn = False
turn += 1
if turn == len(self.players): turn = 0 #wrap the list
for player in self.players:
#this will execute the turn s becomes zero
if player.myturn:
winner = player
break
print("Winner: {}".format(winner))
import random
game = Game()
game.start()
S=random.randint(1,100) #will pick a random number
user_input = int(raw_input("Enter a number:")) #will get an integer from the user
#subtraction and modulo work just like in any other language ...
if(condition):
do_something() #is the format for if statements
does that cover all your questions? or did I miss some?

Categories