2016-12-06 18 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」と「グリッド寸法」を作ることです。議論 最初に私は、すべての "例(グリッドなど)"がクラス内にどのように入っているかを見ることができないという問題を抱えていました。私はそれらを "Minesweeper.example(grid、etc)"に変更した後、コードはそれが想定されているように開始します。

  1. トレースバック(最新の最後の呼び出し):マーカス\のAppData \ローカル\プログラム\ Pythonの\ Python35-32 \ minesweeper2 \ \ユーザー: 」Cファイルエラーイムが取得

    は次のとおりです。プレイゲームの中の グリッド、鉱山=情報(の)、 の行227、 のplaygame()ファイル "C:\ Users \ Marcus \ AppData \ Local \ Programs \ Python \ Python35-32 \ minesweeper2.py"、 .setupgrid(cell)ファイル "C:¥Users¥Marcus¥AppData¥Local¥Programs¥Python¥Python35-32¥minesweeper2.py"、 17行、setupgrid mines = Minesweeper.getmines(self、eファイルの "C:\ Users \ Marcus \ AppData \ Local \ Programs \ Python \ Python35-32 \ minesweeper2.py"、 行77、getmines内 neighbors = Minesweeper.getneighbors(grid、* start)TypeError: getneighbors()は4つの位置引数をとりますが、10が与えられました

「地雷除去」を置くたびに「getneighbors(grid、* start)」には6つの位置引数が追加されており、周りを回ることはできません。

これはどのように修正できますか、あるいは私が最初から間違ったやり方でコードを修正するために何をする必要があるかを知っていますか? 皆のお手伝いを楽しみにしています!

+0

をさまざまな場所で何らかの理由で 'Minesweeper.getneighbors()'やその他の方法でメソッドを呼び出しています。どうして? –

+1

Danielのコメントに続いて、クラスメソッドを呼び出すたびに、 'Minesweeper.method'ではなく' self.method'を使う必要があります。 – Navidad20

+0

これは私の側からの知識の不足の可能性が最も高い、私はPythonの初心者です。 私は 'Minesweeper'を' self'に変更しましたが、すでにエラーが発生しているのを見ることができます。 10の引数についての主なエラーは、代わりに4に落ちました。フィードバックをお寄せいただきありがとうございます :) – Flargy

答えて

0

あなたはそれを一つの引数を与えるプラスあなたは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 

出力の合計サイズ9のリスト解凍:あなたが正しく参照するには、 `self`を使用しているほとんどのケースで

received the following arguments: 
sauce 
1 
2 
5 
8 
関連する問題