軟件工程基礎-我的項目-sudoku遊戲

我的項目任務和要求

Github項目地址

 https://github.com/richardevan/sudokugame
python

PSP 表格git

PSP2.1 Personal Software Process Stages 預估耗時(分鐘)  實際耗時(分鐘)
Planning  計劃    
   Estimate   估計這個任務須要多少時間   40  50
Development  開發     
  Analysis    需求分析(包括學習新技術)   70  70
  Design Spec     生成射進文檔   60  60
  Design Review    設計複審(和同事審覈設計文檔)   20  30
  Coding Standard     代碼規範 (爲目前的開發制定合適的規範)  20   40
  Design   具體設計  70  80
  Coding    具體編碼   1400   1500
  Code Review    代碼複審   180   190
  Test    測試(自我測試,修改代碼,提交修改)   200   200 
Reporting  報告    
  Test Report    測試報告   80   100
  Size Measurement    計算工做量   40   40
  Postmortem & Process Improvement Plan   過後總結,並提出過程進計劃   40   40 
   合計  2220  2400

解題思路 

  數獨橫九豎九共八十一個格子,同時又分爲9個九宮格。規則很簡單——須要每個格中的數字,都保證與其所在橫排和豎排以及九宮格內無相同數字。因此咱們的大概思路就是,從第一個空格開始試着填數,從 1 開始填,若是 1 不知足橫排豎排九宮格無重複的話,就再填入 2 ,以此類推,直到填入一個暫時知足規則的數,中斷此格,移動到下一個空格重複這個過程。若是到達某個空格發現已經無數可選了,說明前面某一格填錯了,那就返回上一格,從上一格的中斷處繼續往 9 嘗試,直到這樣回朔到填錯的那一格。github

  這樣的話,咱們就能夠整理出重要的步驟了:canvas

    1. 畫一個空白的屏幕格式性能優化

    def canvas_click(self, event):
        print("Click! (%d,%d)" % (event.x, event.y))
        self.canvas.focus_set()
        rsize = 512/9
        (x, y) = (0, 0)
        if event.x > rsize:
            x = int(event.x/rsize)
        if event.y > rsize:
            y = int(event.y/rsize)
        print(x, y)
        if self.current:
            (tx, ty) = self.current
            # self.canvas.itemconfig(self.handles[ty][tx][0],
            # fill=rgb(128,128,128))
        self.current = (x, y)

    def canvas_key(self, event):
        print("Clack! (%s)" % (event.char))
        if event.char.isdigit() and int(event.char) > 0 and self.current:
            (x, y) = self.current
            # self.canvas.itemconfig(self.handles[y][x][0],
            # fill=rgb(128,128,128))
            try:
                self.board.set(x, y, int(event.char))
                self.sync_board_and_canvas()
            except ValueError:
                pass

    2. 在屏幕上畫一個網格app

    def make_grid(self):
        c = Canvas(self, bg=rgb(128, 128, 128), width='512', height='512')
        c.pack(side='top', fill='both', expand='1')
        self.rects = [[None for x in range(9)] for y in range(9)]
        self.handles = [[None for x in range(9)] for y in range(9)]
        rsize = 512/9
        guidesize = 512/3

        for y in range(9):
            for x in range(9):
                (xr, yr) = (x*guidesize, y*guidesize)
                self.rects[y][x] = c.create_rectangle(xr, yr, xr+guidesize,
                                                      yr+guidesize, width=3)
                (xr, yr) = (x*rsize, y*rsize)
                r = c.create_rectangle(xr, yr, xr+rsize, yr+rsize)
                t = c.create_text(xr+rsize/2, yr+rsize/2, text="SUDO",
                                  font="System 15 bold")
                self.handles[y][x] = (r, t)

        self.canvas = c
        self.sync_board_and_canvas()

      而後別忘了配合空白的屏幕和網格。dom

    def sync_board_and_canvas(self):
        g = self.board.grid
        for y in range(9):
            for x in range(9):
                if g[y][x] != 0:
                    self.canvas.itemconfig(self.handles[y][x][1],
                                           text=str(g[y][x]))
                else:
                    self.canvas.itemconfig(self.handles[y][x][1],
text
='')

      還有作小的網格。ide

    def clear(self):
        self.grid = [[0 for x in range(9)] for y in range(9)]
        self.locked = []

    def get_row(self, row):
        return self.grid[row]

    def get_cols(self, col):
        return [y[col] for y in self.grid]

    def get_nearest_region(self, col, row):
        """Regions are 3x3 sections of the grid."""
        def make_index(v):
            if v <= 2:
                return 0
            elif v <= 5:
                return 3
            else:
                return 6
        return [y[make_index(col):make_index(col)+3] for y in
                self.grid[make_index(row):make_index(row)+3]]

    def set(self, col, row, v, lock=False):
        if v == self.grid[row][col] or (col, row) in self.locked:
            return
        for v2 in self.get_row(row):
            if v == v2:
                raise ValueError()
        for v2 in self.get_cols(col):
            if v == v2:
                raise ValueError()
        for y in self.get_nearest_region(col, row):
            for x in y:
                if v == x:
                    raise ValueError()
        self.grid[row][col] = v
        if lock:
            self.locked.append((col, row))

    def get(self, col, row):
        return self.grid[row][col]

    3. 輪流填入格中數字 1 到 9,還有 遞歸判斷填入數是否符合規則函數

def sudogen_1(board):
    """Algorithm: enter a random number between 1-9 to each
   subgrid in the board, don't enter a duplicate random numbers.
""" board.clear() added = [0] for y in range(0, 9, 3): for x in range(0, 9, 3): if len(added) == 10: return i = 0 while i in added: i = random.randint(1, 9) try: board.set(random.randint(x, x+2), random.randint(y, y+2), i, lock=True) except ValueError: print("Board rule violation, this shouldn't happen!") added.append(i)

  對於不知道遊戲或玩遊戲的玩家,您能夠先閱讀遊戲介紹。打開這個連接: https://en.wikipedia.org/wiki/Sudoku性能

性能優化

  1. 單元測試

    

  2. 覆蓋率測試

    

 

    ncalls =爲調用的數量。

    tottime =花在給定函數的總時間(不包括時間在調用子函數)。

    percall(1) =商tottime除以ncalls。

    cumtime =累計時間花在這和全部子功能(從調用到出口)。這個數字即便是遞歸函數也是精確的。

    percall(2) =商cumtime除以原始調用。

    文件名:株(功能)=提供每一個函數的相應數據。

小結

  此次我的項目對我來講有點麻煩。由於用python的能力沒那麼厲害。原本,我想用C語言來完成做業。可是用C語言看起來很麻煩,很複雜,須要很長時間完成的,因此我換了一個語言就是python。用python完成做業後,我python的能力提升了。我也獲得不少知識。但願這些知識能在之後幫助我。

 

相關文章
相關標籤/搜索