2016-12-06 50 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 
相关问题