2016-12-06 45 views
0

我最近開始使用Python工作,並得到一個任務,我們應該在現有的代碼中沒有類,並使用類和self.example變量重寫它。在Python中爲一個已經工作的程序創建一個類

我決定使用網上找到下面的代碼:

1. """A command line version of Minesweeper""" import random import re 
import time from string import ascii_lowercase 


def setupgrid(gridsize, start, numberofmines): 
    emptygrid = [['0' for i in range(gridsize)] for i in range(gridsize)] 

    mines = getmines(emptygrid, start, numberofmines) 

    for i, j in mines: 
     emptygrid[i][j] = 'X' 

    grid = getnumbers(emptygrid) 

    return (grid, mines) 


def showgrid(grid): 
    gridsize = len(grid) 

    horizontal = ' ' + (4 * gridsize * '-') + '-' 

    # Print top column letters 
    toplabel = '  ' 

    for i in ascii_lowercase[:gridsize]: 
     toplabel = toplabel + i + ' ' 

    print(toplabel + '\n' + horizontal) 

    # Print left row numbers 
    for idx, i in enumerate(grid): 
     row = '{0:2} |'.format(idx + 1) 

     for j in i: 
      row = row + ' ' + j + ' |' 

     print(row + '\n' + horizontal) 

    print('') 


def getrandomcell(grid): 
    gridsize = len(grid) 

    a = random.randint(0, gridsize - 1) 
    b = random.randint(0, gridsize - 1) 

    return (a, b) 


def getneighbors(grid, rowno, colno): 
    gridsize = len(grid) 
    neighbors = [] 

    for i in range(-1, 2): 
     for j in range(-1, 2): 
      if i == 0 and j == 0: 
       continue 
      elif -1 < (rowno + i) < gridsize and -1 < (colno + j) < gridsize: 
       neighbors.append((rowno + i, colno + j)) 

    return neighbors 


def getmines(grid, start, numberofmines): 
    mines = [] 
    neighbors = getneighbors(grid, *start) 

    for i in range(numberofmines): 
     cell = getrandomcell(grid) 
     while cell == start or cell in mines or cell in neighbors: 
      cell = getrandomcell(grid) 
     mines.append(cell) 

    return mines 


def getnumbers(grid): 
    for rowno, row in enumerate(grid): 
     for colno, cell in enumerate(row): 
      if cell != 'X': 
       # Gets the values of the neighbors 
       values = [grid[r][c] for r, c in getneighbors(grid, 
                   rowno, colno)] 

       # Counts how many are mines 
       grid[rowno][colno] = str(values.count('X')) 

    return grid 


def showcells(grid, currgrid, rowno, colno): 
    # Exit function if the cell was already shown 
    if currgrid[rowno][colno] != ' ': 
     return 

    # Show current cell 
    currgrid[rowno][colno] = grid[rowno][colno] 

    # Get the neighbors if the cell is empty 
    if grid[rowno][colno] == '0': 
     for r, c in getneighbors(grid, rowno, colno): 
      # Repeat function for each neighbor that doesn't have a flag 
      if currgrid[r][c] != 'F': 
       showcells(grid, currgrid, r, c) 


def playagain(): 
    choice = input('Play again? (y/n): ') 

    return choice.lower() == 'y' 


def parseinput(inputstring, gridsize, helpmessage): 
    cell =() 
    flag = False 
    message = "Invalid cell. " + helpmessage 

    pattern = r'([a-{}])([0-9]+)(f?)'.format(ascii_lowercase[gridsize - 1]) 
    validinput = re.match(pattern, inputstring) 

    if inputstring == 'help': 
     message = helpmessage 

    elif validinput: 
     rowno = int(validinput.group(2)) - 1 
     colno = ascii_lowercase.index(validinput.group(1)) 
     flag = bool(validinput.group(3)) 

     if -1 < rowno < gridsize: 
      cell = (rowno, colno) 
      message = '' 

    return {'cell': cell, 'flag': flag, 'message': message} 


def playgame(): 
    gridsize = 9 
    numberofmines = 10 

    currgrid = [[' ' for i in range(gridsize)] for i in range(gridsize)] 

    grid = [] 
    flags = [] 
    starttime = 0 

    helpmessage = ("Type the column followed by the row (eg. a5). " 
        "To put or remove a flag, add 'f' to the cell (eg. a5f).") 

    showgrid(currgrid) 
    print(helpmessage + " Type 'help' to show this message again.\n") 

    while True: 
     minesleft = numberofmines - len(flags) 
     prompt = input('Enter the cell ({} mines left): '.format(minesleft)) 
     result = parseinput(prompt, gridsize, helpmessage + '\n') 

     message = result['message'] 
     cell = result['cell'] 

     if cell: 
      print('\n\n') 
      rowno, colno = cell 
      currcell = currgrid[rowno][colno] 
      flag = result['flag'] 

      if not grid: 
       grid, mines = setupgrid(gridsize, cell, numberofmines) 
      if not starttime: 
       starttime = time.time() 

      if flag: 
       # Add a flag if the cell is empty 
       if currcell == ' ': 
        currgrid[rowno][colno] = 'F' 
        flags.append(cell) 
       # Remove the flag if there is one 
       elif currcell == 'F': 
        currgrid[rowno][colno] = ' ' 
        flags.remove(cell) 
       else: 
        message = 'Cannot put a flag there' 

      # If there is a flag there, show a message 
      elif cell in flags: 
       message = 'There is a flag there' 

      elif grid[rowno][colno] == 'X': 
       print('Game Over\n') 
       showgrid(grid) 
       if playagain(): 
        playgame() 
       return 

      elif currcell == ' ': 
       showcells(grid, currgrid, rowno, colno) 

      else: 
       message = "That cell is already shown" 

      if set(flags) == set(mines): 
       minutes, seconds = divmod(int(time.time() - starttime), 60) 
       print(
        'You Win. ' 
        'It took you {} minutes and {} seconds.\n'.format(minutes, 
                     seconds)) 
       showgrid(grid) 
       if playagain(): 
        playgame() 
       return 

     showgrid(currgrid) 
     print(message) 

playgame() 

此代碼的工作,就像它應該。這是我設法改變它(我很可能不理解一些基本的部分,這是它不工作的原因)。

1. import random import re import time from string import 
ascii_lowercase 

class Minesweeper: 


    def __init__(self, numberofbombs, gridsize): 
     self.numberofbombs = numberofbombs 
     self.gridsize = gridsize 

    def setupgrid(self, start): 
     emptygrid = [['0' for i in range(self.gridsize)] for i in range(self.gridsize)] 

     mines = Minesweeper.getmines(self, emptygrid, start) 

     for i, j in mines: 
      emptygrid[i][j] = 'X' 

     grid = Minesweeper.getnumbers(emptygrid) 

     return (grid, mines) 


    def showgrid(self, grid): 
     self.gridsize = len(grid) 

     horizontal = ' ' + (4 * self.gridsize * '-') + '-' 

     # Skriver ut bokstäverna för kolumnerna 
     toplabel = '  ' 

     for i in ascii_lowercase[:self.gridsize]: 
      toplabel = toplabel + i + ' ' 

     print(toplabel + '\n' + horizontal) 

     # Skriver ut radnummer 
     for idx, i in enumerate(grid): 
      row = '{0:2} |'.format(idx + 1) 

      for j in i: 
       row = row + ' ' + j + ' |' 

      print(row + '\n' + horizontal) 

     print('') 


    def getrandomcell(self, grid): 
     self.gridsize = len(grid) 

     a = random.randint(0, self.gridsize - 1) 
     b = random.randint(0, self.gridsize - 1) 

     return (a, b) 


    def getneighbors(self, grid, rowno, colno): 
     self.gridsize = len(grid) 
     neighbors = [] 

     for i in range(-1, 2): 
      for j in range(-1, 2): 
       if i == 0 and j == 0: 
        continue 
       elif -1 < (rowno + i) < self.gridsize and -1 < (colno + j) < self.gridsize: 
        neighbors.append((rowno + i, colno + j)) 

     return neighbors 


    def getmines(grid, start, self): 
     mines = [] 
     neighbors = Minesweeper.getneighbors(grid, *start) 

     for i in range(self.numberofmines): 
      cell = Minesweeper.getrandomcell(grid) 
      while cell == start or cell in mines or cell in neighbors: 
       cell = Minesweeper.getrandomcell(grid) 
      mines.append(cell) 

     return mines 


    def getnumbers(grid): 
     for rowno, row in enumerate(grid): 
      for colno, cell in enumerate(row): 
       if cell != 'X': 
        # Hämtar värdet av närliggande bomber 
        values = [grid[r][c] for r, c in Minesweeper.getneighbors(grid, 
                    rowno, colno)] 

        # Räknar hur många som är minor 
        grid[rowno][colno] = str(values.count('X')) 

     return grid 


    def showcells(grid, currgrid, rowno, colno): 
     # Exit function if the cell was already shown 
     if currgrid[rowno][colno] != ' ': 
      return 

     # Show current cell 
     currgrid[rowno][colno] = grid[rowno][colno] 

     # Get the neighbors if the cell is empty 
     if grid[rowno][colno] == '0': 
      for r, c in Minesweeper.getneighbors(grid, rowno, colno): 
       # Repeat function for each neighbor that doesn't have a flag 
       if currgrid[r][c] != 'F': 
        Minesweeper.showcells(grid, currgrid, r, c) 


    def playagain(): 
     choice = input("Vill du testa igen?? (y/n): ") 

     return choice.lower() == 'y' 


    def parseinput(self, inputstring, helpmessage): 
     cell =() 
     flag = False 
     message = "Denna ruta existerar inte. " + helpmessage 

     pattern = r'([a-{}])([0-9]+)(f?)'.format(ascii_lowercase[self.gridsize - 1]) 
     validinput = re.match(pattern, inputstring) 

     if inputstring == 'hjälp': 
      message = helpmessage 

     elif validinput: 
      rowno = int(validinput.group(2)) - 1 
      colno = ascii_lowercase.index(validinput.group(1)) 
      flag = bool(validinput.group(3)) 

      if -1 < rowno < self.gridsize: 
       cell = (rowno, colno) 
       message = '' 

     return {'cell': cell, 'flag': flag, 'message': message} 


def playgame(): 
    gridsize = int(input("Hur står vill du att spelplanen ska vara? Skriv t.ex 9 för 9x9: ")) 
    numberofmines = int(input("Hur många bomber vill du ha på spelplanen?: ")) 
    information = Minesweeper(gridsize, numberofmines) 

    currgrid = [[' ' for i in range(gridsize)] for i in range(gridsize)] 

    grid = [] 
    flags = [] 
    starttime = 0 

    helpmessage = ("Skriv kolumnen förljd av raden (t.ex a5). " 
         "För att placera eller ta bort en flagga, lägg till 'f' (t.ex a5f).") 

    information.showgrid(currgrid) 
    print(helpmessage + " Skriv 'hjälp' för att visa detta meddelande igen\n") 

    while True: 
     minesleft = numberofmines - len(flags) 
     prompt = input('Välj ruta ({} mines left): '.format(minesleft)) 
     result = information.parseinput(prompt, helpmessage + '\n') 

     message = result['message'] 
     cell = result['cell'] 


     if cell: 
      print('\n\n') 
      rowno, colno = cell 
      currcell = currgrid[rowno][colno] 
      flag = result['flag'] 

      if not grid: 
       grid, mines = information.setupgrid(cell) 
      if not starttime: 
       starttime = time.time() 

      # Kontrolerar placeringen av flaggor 
      if flag: 
       # Placerar en flagga om platsen är tom 
       if currcell == ' ': 
        currgrid[rowno][colno] = 'F' 
        flags.append(cell) 
       # Tar bort flaggan om det redan finns en där 
       elif currcell == 'F': 
        currgrid[rowno][colno] = ' ' 
        flags.remove(cell) 
       else: 
        message = 'Du kan inte placera en flagga här' 

      # Skapar en utskrift om det redan är en flagga där 
      elif cell in flags: 
       message = 'Det är en flagga här' 

      elif grid[rowno][colno] == 'X': 
       print('Du förlorade\n') 
       information.showgrid(grid) 
       if information.playagain(): 
        information.playgame() 
       return 

      elif currcell == ' ': 
       information.showcells(grid, currgrid, rowno, colno) 

      else: 
       message = "Denna ruta är redan synlig" 

      if set(flags) == set(mines): 
       minutes, seconds = divmod(int(time.time() - starttime), 60) 
       print(
        'Du vann! '      'Det tog dig {} minuter och {} sekunder.\n'.format(minutes, 
                     seconds)) 
       information.showgrid(grid) 
       if information.playagain(): 
        information.playgame() 
       return 

     information.showgrid(currgrid) 
     print(message) 

playgame() 

基本上我所做的就是創建一個類「掃雷」,並「numberofbombs」和「gridsize」爲自我。參數。 起初,我遇到了一個問題,即每個「示例(網格等)」都無法正常工作,看到他們現在正在一個班級中。在我將它們更改爲「Minesweeper.example(網格等)」之後,代碼現在按照它應該的那樣開始。

錯誤即時得到如下:

  1. 回溯(最近通話最後一個):文件 「C:\用戶\馬庫斯\應用程序數據\本地\程序\ Python的\ Python35-32 \ minesweeper2。 py「, 第227行,在 playgame()文件」C:\ Users \ Marcus \ AppData \ Local \ Programs \ Python \ Python35-32 \ minesweeper2.py「, 行180,玩遊戲 grid,mines = information .setupgrid(cell)文件「C:\ Users \ Marcus \ AppData \ Local \ Programs \ Python \ Python35-32 \ minesweeper2.py」, line 17,in setupgrid mines = Minesweeper.getmines(self,e mptygrid,start)文件「C:\ Users \ Marcus \ AppData \ Local \ Programs \ Python \ Python35-32 \ minesweeper2.py」, line 77,in getmines neighbors = Minesweeper.getneighbors(grid,* start)TypeError: getneighbors()需要4個位置參數,但有10個被分配

每當我把「掃雷」。到「getneighbors(grid,* start)」,它增加了6個位置參數,我似乎無法繞過它。

有沒有人知道如何解決這個問題,或者如果我從一開始就採取了錯誤的方式,需要做些什麼才能修復代碼? 期待大家的幫助!

+0

在大多數情況下,你正確使用'self'引用事情,但由於某種原因,你在各個地方通過'Minesweeper.getneighbors()'或其他方式調用方法。爲什麼? –

+1

按照Daniel的評論,每當你調用一個類方法時,你需要使用'self.method',而不是'Minesweeper.method' – Navidad20

+0

這很可能是我缺乏知識,我是python的新手。 我將所有'Minesweeper'切換到'self',並且可以看到錯誤消失。關於10個參數的主要錯誤代之以4。感謝您的反饋 :) – Flargy

回答

0

你給它一個參數加上你解壓規模9的名單,共10

def f(*args): 
    print('received the following arguments:') 
    for arg in args: 
     print(arg) 

foo = [1, 2, 5, 8] 
f('sauce', *foo) # 5 arguments 

輸出:

received the following arguments: 
sauce 
1 
2 
5 
8 
相關問題