I want to create a simple game in which two players "roll the dice against each other". Winner is whoever gets one number three times in a row. I tried many different ways but in the end I always struggled with the evaluation.
How can I determine which player got one specific number 3-times in a row? Thanks for your advice!
import random
#Initialisieren der Variablen
wurf1_1 = 0
wurf2_1 = 0
gewuerfelt_s1 = []
gewuerfelt_s2 = []
n = 1
while (True):
#Bestimmen der Augenzahlen des Würfels
wurf1_1 = random.randint(1,6)
wurf2_1 = random.randint(1,6)
print("Spiel " + str(n) + ":\tSpieler 1: " + str(wurf1_1) + "; Spieler 2: " + str(wurf2_1))
gewuerfelt_s1.append(wurf1_1)
gewuerfelt_s2.append(wurf2_1)
wurf1_2 = random.randint(1,6)
wurf2_2 = random.randint(1,6)
n += 1
print("Spiel " + str(n) + ":\tSpieler 1: " + str(wurf1_2) + "; Spieler 2: " + str(wurf2_2))
if (wurf1_2 == gewuerfelt_s1[0]):
gewuerfelt_s1.append(wurf1_2)
wurf1_3 = random.randint(1,6)
n += 1
print("Spiel " + str(n) + ":\tSpieler 1: " + str(wurf1_3) + "; Spieler 2: " + str(wurf2_2))
if wurf1_3 == gewuerfelt_s1[1]:
print("Spieler 1 hat dreimal hintereinander die Zahl", gewuerfelt_s1[1], "gewürfelt. Sieger!")
break
else:
del gewuerfelt_s1[:]
continue
else:
del gewuerfelt_s1[:]
continue
Don't delete elements from your list. You can check the most recently appended elements of a list by indexing from the end
The last element of a list is:
my_list[-1]
The second last is:
my_list[-2]
So for each roll after the second roll, you can check:
my_list[-1] == my_list[-2] == my_list[-3]
(Can't comment, low rep)
First of all, make a function that will simulate the dice, it should return an integer number between [1,6] and should be generated using easily available (pseudo)random functions.
Once this is done, Declare variables, continous1, continous2, prev1, prev2.
The prev variables would store the prev dice role answer for that player if the current turn is the same as the prev for that player, increasing the continuous count. The first to reach the 3 is your answer. Use a while loop to simulate this.
Here is the code
import random
continous1 = 0
continous2 = 0
prev1 = 0
prev2 = 0
while continous1 != 3 and continous2 != 3:
person1 = random.randint(1,6)
person2 = random.randint(1,6)
if person1 == prev1:
continous1 += 1
else:
continous1 = 0
if person2 == prev2:
continous2 += 1
else:
continous2 = 0
prev1 = person1
prev2 = person2
# Note that even if both persons win the game at the same time, the first person will be chosen as the winner
if continous1 == 3:
print("Person 1 won the game")
else:
print("Person 2 won the game")
Check this pseudo code
PlayGame()
{
bool gameover = false;
int turns ;
player1_values = []
player2_values = []
While(!gameover)
{
player1_values.Add(getrandon(1,6));
player2_values.Add(getrandon(1,6));
bool player1_won = Check(player1_values);
if(!player1_won && player1_values.Count == 3)
player1_values.Clear();
bool player2_won = Check(player2_values);
if(!player1_won && player2_values.Count == 3)
player2_values.Clear();
gameover = player1_won || player2_won;
}
}
Check(values)
{
if(values.Count < 3)
return false;
int num = values[0];
for(int i = 1;i<3;i++)
{
if(values[i] != num)
return false;
}
return true;
}
Related
I am a beginner in Python and I think I need some help with my program. Any kind of help or advice would be appreciated:)
You can see the program below, when I run it it gets stuck on the part of comparing the random ticket with the winning ticket(win_combination).
from random import choice
#Winning ticket
win_combination = input("Enter the winning combination of 4 numbers(1-digit-numbers): ")
while len(win_combination) != 4:
if len(win_combination) > 4:
win_combination = input("Reenter a shorter combination(4 one-digit-numbers): ")
elif len(win_combination) < 4:
win_combination = input("Reenter a longer combination(4 one-digit-numbers): ")
print(f"Winning combination is {win_combination}.")
#Specifying range of numbers to choose from
range = range(0, 10)
#Making a fake comparison-ticket to start of the loop
random_ticket = [0, 0]
random_ticket_string = f"{random_ticket[0]}{random_ticket[1]}{random_ticket[2]}{random_ticket[3]}"
#Params for the loop
n_tries = 0
n_guesses = 1
while random_ticket_string != win_combination:
while n_tries > 4:
random_ticket.clear()
number = choice(range)
random_ticket.append(number)
n_tries += 1
n_guesses += 1
random_ticket_string = f"{random_ticket[0]}{random_ticket[1]}"
if random_ticket_string == win_combination:
chance_to_win = f"{(1 / n_guesses) * 100}%"
print("Estimated percent to win is " + chance_to_win + ", it took " + f"{n_guesses} to match the winning combination.")
else:
n_tries = 0
I'm trying to run a simple tic tac toe game script in python. I use a list to track in which cell of the table there is a "X", an "Y" or nothing. to set the value you have to input the coordinate of the cell you want to play in and if the coordinate doesn't exist or it is already occupied, you get an error message and the game ask you to input again. the problem is that whenever i input a number, i get the error message and the program stop. I can't spot the error, can anyone help me?
the cose is the following:
class Tris:
def __init__(self, xo = True):
self.tabella = [0, 0, 0,
0, 0, 0,
0, 0, 0] # -this is the starting table
self.xo = xo # -to check if it is "x" turn or "o" turn
self.finito = False # -to check if the game is unfinished
# -just to print grafic style of the table: ignore that
def print_tabella(self):
giocatore = "X" if self.xo else "Y"
tabella_convertita = self.tabella
for n, i in enumerate(tabella_convertita):
if i == 0:
tabella_convertita[n] = " "
elif i == 1:
tabella_convertita[n] = "X"
else:
tabella_convertita[n] = "O"
t1 = "|".join(str(i) for i in tabella_convertita[0:3])
t2 = "|".join(str(i) for i in tabella_convertita[3:6])
t3 = "|".join(str(i) for i in tabella_convertita[6:9])
spazio_casella = "-+-+-"
testo_segnaposto = """use following numbers to set X/O:
0|1|2
-+-+-
3|4|5
-+-+-
6|7|8"""
turno_di = f"turn : {giocatore}"
tab_finale = t1 + "\n" + spazio_casella + "\n" + t2 + "\n" + spazio_casella + "\n" + t3 + "\n"+ testo_segnaposto +"\n" + turno_di
return tab_finale
def controlla(self, casella):
if casella.isalpha(): # check if the input is not numerical
return False
else:
if not 0 <= int(casella) <= 8: # the value must be between 0 and 8
return False
else:
return self.tabella[int(casella)] == 0 # the cell must not be containing another symbol
def is_winner(self): # check if there is a row, a column or a diagonal with the same symbol
lista_righe = [[self.tabella[0], self.tabella[1], self.tabella[2]], [self.tabella[3], self.tabella[4], self.tabella[5]],
[self.tabella[6], self.tabella[7], self.tabella[8]]]
lista_colonne = [[self.tabella[0], self.tabella[3], self.tabella[6]], [self.tabella[1], self.tabella[4], self.tabella[7]],
[self.tabella[2], self.tabella[5], self.tabella[8]]]
lista_diagonali = [[self.tabella[0], self.tabella[4], self.tabella[8]], [self.tabella[2], self.tabella[4], self.tabella[6]], ]
lista_vincite = [lista_colonne, lista_diagonali, lista_righe]
winner = False
for i in lista_vincite:
for liste in i:
if liste[0] == liste[1] and liste[1] == liste[2] and liste[0] != 0:
winner = True
break
return winner
def gioca(self):
while self.finito == False: # check if the game is finished
if self.is_winner(): # check if there is a winner
self.finito = True
break
print(self.print_tabella()) # print the table in grafic form
inp = input("choose a number to set X/O: ")
if not self.controlla(inp): # check if the input is in valid form
print("invalid number or cell already used") # or if the chosen cell is available
else:
self.xo = not self.xo # to track if it is X turn or O turn
if self.xo:
self.tabella[int(inp)] = 1
else:
self.tabella[int(inp)] = 2
gioco_tris = Tris()
gioco_tris.gioca()
The problem is that print_tabella mutates tabella. When you do:
tabella_convertita = self.tabella
... you are not creating a new list, but just a synonym for self.tabella. So whatever you do to tabella_convertita is happening to self.tabella: the numeric content gets replaced with characters.
Instead do:
tabella_convertita = self.tabella[:]
I'm making an isWin function that checks if there is a character that appears 5 consecutive times (either horizontally, vertically or diagonally).
I've tried using this code:
#VERTICAL WIN
count = 0
for row in range(1,grid_height):
print(row)
for col in range(1,grid_width):
print(col)
if grid[row][col-2] == p_char:
count += 1
if count == 5:
return True
else:
count = 0
continue
#HORIZONAL WIN
count=0
for col in range(0,grid_width):
for row in range(0,grid_height):
if grid[row][col-2] == p_char:
count += 1
if count == 5:
return True
else:
count = 0
continue
And this is where i place it in my main program:
def play():
grid,grid_height,grid_width,p1_name,p1_char,p2_name,p2_char=getGameSettings()
displayGrid(grid,grid_height,grid_width)
print('WELCOME TO THE GAME!')
playerA = Player(p1_name, PLAYING)
playerB = Player(p2_name, WAITING)
grid=[]
for row in range(grid_height): # FOR ROW
z =[]
for col in range(grid_width): # FOR COLUMN
z.append(" ")
grid.append(z)
numColFull = 0
turn=0
while turn < grid_height*grid_width:
player = playerA
if turn % 2 == 0 : #IF TURN IS AN ODD NUMBER, THEN IT IS player 1's turn, IF TURN IS EVEN, THEN IT IS player 2's turn
p_char= p1_char
player = playerA
playerA.setState(PLAYING)
playerB.setState(WAITING)
else :
p_char= p2_char
player = playerB
playerB.setState(PLAYING)
playerA.setState(WAITING)
print(".................................................. ")
print("User to play : ", player.playerInfo() , " SEQ : ", str(turn)) # TO COUNT THE TOTAL NUMBER OF MOVES
print(".................................................. ")
if numColFull == grid_width: #THE isDRAW function but embedded into the main function
# IF the numColFull is equal to gridwidth, it means that all of the columns has been occupied, meaning
#that every space has already been occupied, thus, game is over.
print('........All spaces had been occupied...........')
print('................THE GAME IS DRAW...............')
print('.................GAME OVER.....................')
break
else:
while True:
try:
move=int(input('Enter your move: '))
except ValueError:
print('Please enter a valid input.')
if move < 1 or move > grid_width:
print('Please enter a valid input.')
continue
break
updateGrid(grid,grid_height-1,grid_width,move,p_char)
while True:
if grid[0][move-2] == p_char: #IF THE TOP ROW OF A COLUMN HAS A PIECE IN IT, IT MEANS ITS ALREADY FULL
displayGrid(grid,grid_height, grid_width)
print('Column is full. Please choose another column for the next move.')
numColFull += 1
break
elif isWin == True: #IF THE IF CONDITION DIDNT HOLD TRUE, THEN THE FUNCTION CONTINUES AS USUAL
print(player, 'WINS!!!')
('.................GAME OVER.....................')
else:
displayGrid(grid,grid_height, grid_width)
break #GOES BACK TO THE THE WHILE CONDITION
turn += 1 #INCREMENTS 1 TO TURN SO IT WILL SWITCH BETWEEN BEING ODD AND EVEN
And this is my grid:
def displayGrid(grid,grid_height,grid_width):
for row in range(1,grid_height):
#print(row) #for checking
for col in range(grid_width):
print("|", end="")
print(str(grid[row-1][col-1]),end = "")
print("|")
print(" "+" ".join([str(i) for i in range(1, grid_width+1)]))
return grid
def updateGrid(grid,grid_height,grid_width,move,p_char):
for i in range(1,grid_height+1):
print(i)
#print(i) #ROW COUNTING STARTS FROM 1
if grid[grid_height-i][move-2] == " ":
grid[grid_height-i][move-2]= p_char #REPLACES THE " " TO THE CURRENT PLAYER'S CHARACTER (p_char)
else:
continue
break
return grid
I guess you are writing Five In a Row? But anyway, this code should work:
def isWin():
# Horizontal
for i in range(grid_height):
for j in range(grid_width - 4):
if set(grid[i][j:j+5]) == {p_char}:
return True
# Vertical
for i in range(grid_height - 4):
for j in range(grid_width):
if { grid[i+k][j] for k in range(5) } == {p_char}:
return True
# Diagonal
for i in range(grid_height - 4):
for j in range(grid_width - 4):
if { grid[i+k][j+k] for k in range(5) } == {p_char}:
return True
return False
# Simplified
def isWin():
return any(set(grid[i][j:j+5]) == {p_char} for i in range(grid_height) for j in range(grid_width - 4)) or \
any({ grid[i+k][j] for k in range(5) } == {p_char} for i in range(grid_height - 4) for j in range(grid_width)) or \
any({ grid[j+k][i+k] for k in range(5) } == {p_char} for i in range(grid_width - 4) for j in range(grid_width - 4))
Since set cannot have duplicates, using expressions like { grid[j+k][i+k] for k in range(5) } will put 5 consecutive pieces into a set. If there are 5 consecutive p_chars, then the set will become {p_char}.
while not endgame:
cardsOnTable = OnTable()
faceUp1 = player1.dequeue()
cardsOnTable.place('player1',faceUp1,False)
faceUp2 = player2.dequeue()
cardsOnTable.place('player2',faceUp2,False)
print(str(cardsOnTable))
size1 = player1.size()
size2 = player2.size()
print('Player1 : '+str(size1),'Player2 : '+str(size2))
result = compareCard(faceUp1,faceUp2)
elif result == 0:
print('WAR STARTS!!!')
i = 0
player1war = [] #a list for placing player1's card in war(cards on table)
player2war = [] #a list for placing player2's card in war(cards on table)
while i < nbWarCards:
faceDown1 = player1.dequeue()
player1war.append(faceDown1)
faceDown2 = player2.dequeue()
player2war.append(faceDown2)
i += 1
for card in player1war:
cardsOnTable.place('player1',card,True)
player1war.clear()
for card in player2war:
cardsOnTable.place('player2',card,True)
player2war.clear()
if player1.size() == 0 or player2.size() == 0:
endgame = True
my problem happens when I tried to print(str(cardOnTable)) when the first time this while loop runs, it will give me [AS | AH], that's what I want. However, when this while loop runs second time, it is supposed to print [A3 XX XX XX AS | AH XX XX XX A5],it only prints [A3 | A5].
this is my class OnTable():
class OnTable:
def __init__(self):
self.__cards = []
self.__faceUp = []
def place(self,player,card,hidden):
if player == 'player2':
self.__cards.append(card)
if hidden == False:
self.__faceUp.append(False)
elif hidden == True:
self.__faceUp.append(True)
elif player == 'player1':
self.__cards.insert(0,card)
if hidden == False:
self.__faceUp.insert(0,False)
elif hidden == True:
self.__faceUp.insert(0,True)
#return self.__cards
def cleanTable(self):
self.__cards.clear()
self.__faceUp.clear()
def __str__(self):
for i in range(len(self.__faceUp)):
if self.__faceUp[i] == True:
self.__cards[i] = 'XX'
list1 = '['
for item in self.__cards:
list1 += (str(item)+' ')
list1 = re.sub(' ', ' ', list1.strip())
half = int(len(list1)//2)
list1 = list1[:half] + ' |' + list1[half:]
return list1 + ']'
I tried to track my code, and I found self.__cards have all variables before second time the player1.dequeue(), then it loses all the previous variables.
Could someone please tell how to fix this problem? Thank you
I am working on a Hangman game, but I am having trouble replacing the dashes with the guessed letter. The new string just adds on new dashes instead of replacing the dashes with the guessed letter.
I would really appreciate it if anyone could help.
import random
import math
import os
game = 0
points = 4
original = ["++12345","+*2222","*+33333","**444"]
plusortimes = ["+","*"]
numbers = ["1","2","3"]
#FUNCTIONS
def firstPart():
print "Welcome to the Numeric-Hangman game!"
def example():
result = ""
ori = random.choice(original)
for i in range(2,len(ori)):
if i % 2 == 0:
result = result + ori[i] + ori[0]
else:
result = result + ori[i] + ori[1]
return ori
# def actualGame(length):
#TOP LEVEL
firstPart()
play = raw_input("Do you want to play ? Y - yes, N - no: ")
while (play == "Y" and (points >= 2)):
game = game + 1
points = points
print "Playing game #: ",game
print "Your points so far are: ",points
limit = input("Maximum wrong guesses you want to have allowed? ")
length = input("Maximum length you want for the formulas (including symbols) (must be >= 5)? ")
result = "" #TRACE
ori = random.choice(original)
for i in range(2,len(ori)):
if i % 2 == 0:
result = result + ori[i] + ori[0]
else:
result = result + ori[i] + ori[1]
test = eval(result[:-1])
v = random.choice(plusortimes) #start of randomly generated formula
va = random.choice(plusortimes)
formula = ""
while (len(formula) <= (length - 3)):
formula = formula + random.choice(numbers)
formula2 = str(v + va + formula)
kind = ""
for i in range(2,len(formula2)):
if i % 2 == 0:
kind = kind + formula2[i] + formula2[0]
else:
kind = kind + formula2[i] + formula2[1]
formula3 = eval(kind[:-1])
partial_fmla = "------"
print " (JUST TO TRACE, the program invented the formula: )" ,ori
print " (JUST TO TRACE, the program evaluated the formula: )",test
print "The formula you will have to guess has",length,"symbols: ",partial_fmla
print "You can use digits 1 to 3 and symbols + *"
guess = raw_input("Please enter an operation symbol or digit: ")
a = 0
new = ""
while a<limit:
for i in range(len(formula2)):
if (formula2[i] == partial_fmla[i]):
new = new + partial_fmla[i]
elif (formula2[i] == guess):
new[i] = guess
else:
new[i] =new + "-"
a = a+1
print new
guess = raw_input("Please enter an operation symbol or digit: ")
play = raw_input("Do you want to play ? Y - yes, N - no: ")
The following block seems problematic:
elif (formula2[i] == guess):
new[i] = guess
else:
new[i] =new + "-"
Python does not allow modification of characters within strings, as they are immutable (cannot be changed). Try appending the desired character to your new string instead. For example:
elif formula2[i] == guess:
new += guess
else:
new += '-'
Finally, you should put the definition of new inside the loop directly under, as you want to regenerate it after each guess.