• Tidak ada hasil yang ditemukan

Two-Dimensional Sequences

Dalam dokumen Kent D. Lee Steve Hubbard (Halaman 126-130)

Sequences

4.8 Two-Dimensional Sequences

112 4 Sequences

Fig. 4.8 Quicksorting a List

it with the last item that is less than the pivot. Then partitioning is performed on the resulting two sublists.

The randomization done in the first step of quicksort helps to pick a more random pivot value. This has real consequences in the quicksort algorithm, especially when the sequence passed to quicksort has a chance of being sorted already. If the sequence given to quicksort is sorted, or almost sorted, in either ascending or descending order, then quicksort will not achieve O(n log n) complexity. In fact, the worst case complexity of the algorithm is O(n2). If the pivot chosen is the next least or greatest value, then the partitioning will not divide the problem into to smaller sublists as occurred when 9 was chosen as a pivot for a sublist in Fig.4.8. The algorithm will simply put one value in place and end up with one big partition of all the rest of the values. If this happened each time a pivot was chosen it would lead to O(n2) complexity. Randomizing the list prior to quicksorting it will help to ensure that this does not happen.

Merge sort is not affected by the choice of a pivot, since no choice is necessary.

Therefore, merge sort does not have a worst case or best case to consider. It will always achieve O(n log n) complexity. Even so, quicksort performs better in practice than merge sort because the quicksort algorithm does not need to copy to a new list and then back again. The quicksort algorithm is the de facto standard of sorting algorithms.

Fig. 4.9 A 2-Dimensional Matrix

the rows, then the matrix is said to be in row major form. If the main list contains references to the columns of the matrix, then it is in column major form. Most of the time, matrices are constructed in row major form. In Fig.4.9a matrix is drawn with a row major orientation, but the matrix could represent either row major or column major form. The actual organization of the data is the same either way. Theitems reference points at the main list. Theitemslist contains references to each of the rows of the matrix.

For example, consider a program that plays tic tac toe against a human opponent.

We would need to represent the board that tic tac toe is played on. To do so, we’ll create a Board class that mimics our PyList class in the previous section. The organization of our board class is shown graphically in Fig.4.9. The outline for the Board class is given in Sect.4.8.1.

4.8.1 The Board Class

1 class Board:

2 # When a board is constructed, you may want to make a copy of the board.

3 # This can be a shallow copy of the board because Turtle objects are

4 # Immutable from the perspective of a board object.

5 def __init__(self,board=None):

6 self.items = []

7 for i in range(3):

8 rowlst = []

9 for j in range(3):

10 if board==None:

11 rowlst.append(Dummy())

12 else:

114 4 Sequences

13 rowlst.append(board[i][j])

14

15 self.items.append(rowlst)

16

17 # The getitem method is used to index into the board. It should

18 # return a row of the board. That row itself is indexable (it is just

19 # a list) so accessing a row and column in the board can be written

20 # board[row][column] because of this method.

21 def __getitem__(self,index):

22 return self.items[index]

23

24 # This method should return true if the two boards, self and other,

25 # represent exactly the same state.

26 def __eq__(self,other):

27 pass

28

29 # This method will mutate this board to contain all dummy

30 # turtles. This way the board can be reset when a new game

31 # is selected. It should NOT be used except when starting

32 # a new game.

33 def reset(self):

34 screen.tracer(1)

35 for i in range(3):

36 for j in range(3):

37 self.items[i][j].goto(-100,-100)

38 self.items[i][j] = Dummy()

39

40 screen.tracer(0)

41

42 # This method should return an integer representing the

43 # state of the board. If the computer has won, return 1.

44 # If the human has won, return -1. Otherwise, return 0.

45 def eval(self):

46 pass

47

48 # This method should return True if the board

49 # is completely filled up (no dummy turtles).

50 # Otherwise, it should return false.

51 def full(self):

52 pass

53

54 # This method should draw the X’s and O’s

55 # Of this board on the screen.

56 def drawXOs(self):

57 for row in range(3):

58 for col in range(3):

59 if self[row][col].eval() != 0:

60 self[row][col].st()

61 self[row][col].goto(col*100+50,row*100+50)

62

63 screen.update()

Because each row is itself a list in the Board class, we can just use the built-inlist class for the rows of the matrix. Each location in each row of the matrix can hold either an X, an O, or a Dummy object. The Dummy objects are there for convenience and represent an open location in the board. The equal, eval, and full methods are left as an exercise for the student. The purpose of each will be described in the next section.

Many games, both animated and otherwise, are easy to implement using Tkinter and turtle graphics. Animated characters or tokens in a game can be implemented as a turtle that moves around on the screen as necessary. For the tic tac toe game the X’s and O’s can be implemented as RawTurtles. A RawTurtle is just like a Turtle object except that we must provide the canvas where a RawTurtle moves around. The code in Sect.4.8.2contains the three classes that define the X’s, the O’s, and the special Dummy class that is a placeholder for open locations in the board.

4.8.2 The X, O, and Dummy Classes

1 Human = -1 2 Computer = 1 3

4 # This class is just for placeholder objects when no move has been made 5 # yet at a position in the board. Having eval() return 0 is convenient when no 6 # move has been made.

7 class Dummy:

8 def __init__(self):

9 pass 10

11 def eval(self):

12 return 0 13

14 def goto(self,x,y):

15 pass 16

17 # In the X and O classes below the constructor begins by initializing the 18 # RawTurtle part of the object with the call to super().__init__(canvas). The 19 # super() call returns the class of the superclass (the class above the X or O 20 # in the class hierarchy). In this case, the superclass is RawTurtle. Then, 21 # calling __init__ on the superclass initializes the part of the object that is 22 # a RawTurtle.

23 class X(RawTurtle):

24 def __init__(self, canvas):

25 super().__init__(canvas) 26 self.ht()

27 self.getscreen().register_shape("X",((-40,-36),(-40,-44),(0,-4),(40,-44),\

28 (40,-36), (4,0),(40,36),(40,44),(0,4),(-40,44),(-40,36),(-4,0),(-40,-36))) 29 self.shape("X")

30 self.penup() 31 self.speed(5) 32 self.goto(-100,-100) 33

34 def eval(self):

35 return Computer 36

37 class O(RawTurtle):

38 def __init__(self, canvas):

39 super().__init__(canvas) 40 self.ht()

41 self.shape("circle") 42 self.penup() 43 self.speed(5) 44 self.goto(-100,-100) 45

46 def eval(self):

47 return Human

116 4 Sequences

Dalam dokumen Kent D. Lee Steve Hubbard (Halaman 126-130)