Je crée une version de Minesweeper en python et j'ai rencontré un petit problème. Dans ce morceau de code:Problème de jeu récursif en python
if winGame(mines):
printWorld(gameMap)
print 'You Win!'
answer = raw_input('Would you like to play again?')
if answer == 'y':
minesweeper()
else:
print 'Thanks for playing!'
break
Il appelle la fonction de démineur à nouveau, qui commence le jeu encore. Ce code est à l'intérieur d'un certain temps True: boucle avec le reste du code du jeu. Le seul problème est que si le jeu est recommencé et ensuite gagner et dire que vous ne voulez pas rejouer, il ne casse pas la boucle. Je pense que cela a quelque chose à voir avec le fait que j'utilise la récursivité pour rappeler la fonction. Pour l'instant, la seule chose qui fonctionne est d'utiliser sys.exit(), mais je préférerais avoir une solution plus légitime si cela a du sens.
Voici l'intégralité du code:
#Minesweeper Game
#difficulty levels
#make it look better text based
from random import *
import sys
gameMap = '''
#123456789#
1?????????1
2?????????2
3?????????3
4?????????4
#123456789#'''
row = 0
col = 0
coord = []
response = ''
numMines = 5
mines = []
answer = ''
#This runs the game
def minesweeper():
global gameMap
global row
global col
global coord
global mines
global response
global answer
#resets the gameboard after replaying.
gameMap = '''
#123456789#
1?????????1
2?????????2
3?????????3
4?????????4
#123456789#'''
#generates the mines
generateMines()
#converts the world into a list of lists. exception is for when playing again since
#it would try to convert it to a list of lists again
try:
initWorld()
except Exception, e:
pass
#main loop of the game.
while True:
#checks to see if you won the game
if winGame(mines):
printWorld(gameMap)
print 'You Win!'
answer = raw_input('Would you like to play again?')
if answer == 'y':
minesweeper()
else:
print 'Thanks for playing!'
break
#joins the list together so it can be printed
printWorld(gameMap)
print mines
#gets user input and converts it to an int, then adds coords to a list
getCoord()
#asks user what they want to do
clearOrFlag()
if response.lower() == 'c':
if isMine(mines):
answer = raw_input('Would you like to play again?')
if answer == 'y':
minesweeper()
else:
print 'Thanks for playing!'
break
else:
clearSpace(mines)
print '\n'
elif response.lower() == 'f':
flagSpace()
print '\n'
#randomly generates the mines and checks for duplicates
def generateMines():
global numMines
global mines
i = 0
mines = []
while i < numMines:
mines.append([randint(1,4),randint(1,9)])
i += 1
if checkDuplicateMines(mines):
generateMines()
#gets coordinates from the user
def getCoord():
global row
global col
global coord
global gameMap
row = 0
col = 0
coord = []
try:
row = raw_input('Enter an Row: ')
row = int(row)
col = raw_input('Enter a Column: ')
col = int(col)
except ValueError:
print 'Invalid Coordinates \n'
getCoord()
coord.append(row)
coord.append(col)
def isMine(mines):
global coord
global gameMap
for x in mines:
if coord == x:
showSolution(mines, gameMap)
return True
#asks user if they want to clear or flag a space
def clearOrFlag():
global response
response = raw_input("Clear (c), Flag/Unflag (f)")
#clears a space. if it's a mine, the player loses. If not it will write the
#number of surrounding mines to the space. Might break this up later.
def clearSpace(mines):
#checks to see if selected square is a ? (playable).
global gameMap
global row
global col
global coord
if gameMap[row][col] == '?' or gameMap[row][col] == 'F':
gameMap[row][col] = str(countMines(mines))
#flags a space, or unflags it if already flagged.
def flagSpace():
global gameMap
global row
global col
try:
if gameMap[row][col] == '?' :
gameMap[row][col] = 'F'
elif gameMap[row][col] == 'F':
gameMap[row][col] = '?'
except Exception, OutOfBounds:
print 'Invalid Coordinates \n'
#Prints the world
def printWorld(gameMap):
#just prints spaces to keep things tidy
print '\n' * 100
for row in gameMap:
print ' '.join(row)
print '\n'
print '\n'
#initializes the world so it can be printed
def initWorld():
global gameMap
# convert the gamemap into a list of lists
gameMap = gameMap.split('\n')
del gameMap[0]
for index in range(0, len(gameMap)):
gameMap[index] = list(gameMap[index])
#prints the gameBoard with all of the mines visible
def showSolution(mines, gameMap):
for x in mines:
gameMap[x[0]][x[1]] = 'M'
printWorld(gameMap)
print 'You Lose'
#counts the number of surrounding mines in a space
def countMines(mines):
global row
global col
count = 0
#theres probably a much better way to do this
for x in mines:
if [row+1,col] == x:
count += 1
if [row-1,col] == x:
count += 1
if [row,col+1] == x:
count += 1
if [row,col-1] == x:
count += 1
if [row+1,col+1] == x:
count += 1
if [row+1,col-1] == x:
count += 1
if [row-1,col+1] == x:
count += 1
if [row-1,col-1] == x:
count += 1
return count
#counts the number of flags on the board
def countFlags(mines):
global gameMap
numFlags = 0
for i in range (0, len(gameMap)):
for j in range (1, len(gameMap[0])-1):
if gameMap[i][j]=='F':
numFlags += 1
if numFlags == len(mines):
return True
else:
return False
#counts the number of mines flagged
def minesFlagged(mines):
global gameMap
count = 0
for x in mines:
if gameMap[x[0]][x[1]] == 'F':
count += 1
if count == numMines:
return True
else:
return False
#checks to see if there were duplicate mines generated
def checkDuplicateMines(mines):
mines.sort()
for x in range(0, len(mines)-1):
if mines[x] == mines[x+1]:
return True
x += 1
return False
#checks to see if player won the game
def winGame(mines):
if countFlags(mines):
if minesFlagged(mines):
return True
else:
return False
minesweeper()
Un appel récursif n'est probablement pas le meilleur moyen d'y parvenir. Vous devriez gérer exit/start/restart depuis une autre fonction. – asheeshr
Merci pour le conseil. Modification de l'état de la boucle while et déplacement de la lecture vers une autre fonction pour que tout fonctionne. – TaylorV