443,908 Members | 1,892 Online Need help? Post your question and get tips & solutions from a community of 443,908 IT Pros & Developers. It's quick & easy.

# Help with tic tac toe game

 P: 8 Hi, This time I'm trying to make a tic tac toe game. I'm trying to make a game where player is able to choose the size of the board and how many marks is needed in line to win. I have created a m*n sized board like this: Expand|Select|Wrap|Line Numbers import numpy   def new_board(m,n):     row = []     rows = []     for i in range(n):         element = '_'         row.append(element)     for i in range(m):         rows.append(row)     board = numpy.array(rows)     return board   def main():     m = input('Rows: ')     n = input('Columns: ')     board = new_board(m,n)     .     .     .   main()   My problem is that I can't make a function that sets the winning conditions and a function that checks them. This is very hard because there is infinite amount of winning conditions in m*n board where you need k marks in line to win. Can anyone give me any help? Nov 25 '08 #1
7 Replies

 Expert Mod 2.5K+ P: 2,851 You would only check for a winning condition after a board position is selected. There are 4 directions to check: left to right (row) top to bottom (column) diagonal (row+, column+) diagonal (row+, column-) I would set up the board as a class object with an instance method to determine the necessary adjacent positions, and maybe another method to determine if the winning number of adjacent positions are occupied by a player. I am not convinced numpy is necessary, but I have never used it. Nov 25 '08 #2

 P: 8 I'm using numpy only because of with it that table could be printed in very nice form and still it could be used like list. I think that there is surely a better way to do it, but as I am pretty new to python this way seemed best for me :) Bvdet, you suggested making the board for a class object and also that instance method to determine those necessary adjacent positions. Can you tell me what are class objects and how to make that board into one? Also can you be more specific with that method? So far I have used very much loops for coding and those other commands aren't very familiar to me. That's also one reason why I'm trying to make this game to work with functions so that I could finally get rid of complicated "for in", "while" and "if" structures. :) Nov 25 '08 #3

 Expert 100+ P: 469 If you're not familiar with classes, you probably would be better off not using them. They are a big thing to learn about. But to check whether a player has won, what you could do is: Expand|Select|Wrap|Line Numbers Count the number of pieces above the played piece. Count the number of pieces below it. If the sum of those numbers is high enough, then the player has won. Otherwise:     Count the number of pieces to the left of the played piece.     Count the number of pieces to its right. and so on. To find the number of pieces in a certian direction from a piece, you could use a loop that counts the pieces until it finds a square without a piece. You might be able to create a function that counts the number of pieces in a specified direction to make this more compact. I hope this is helpful. Nov 25 '08 #4

 Expert Mod 2.5K+ P: 2,851 I think boxfish is right about not attempting to write it as a class since you are not familiar with them. For general definition, a class defines a set of attributes associated with objects known as instances. An instance is created by calling a class object as you would call a function. A good example would be a point object. A point could be created similar to this: Expand|Select|Wrap|Line Numbers >>> p1 = Point(0,0,0) An instance (p1 in this case) will have properties and methods that were defined in the class object and contain data and perform operations. These are called attributes. An example of the use of a method would be to calculate the distance between 2 point objects or return the unit vector. Examples of data attributes are X, Y, and Z coordinates. Expand|Select|Wrap|Line Numbers >>> p2 = Point(1,1,1) >>> p1.dist(p2) 1.7320508075688772 >>> p2.uv() Point(0.577350, 0.577350, 0.577350) >>> p1.x 0.0 >>> p2.z 1.0 >>>  You should be able to reach your goal with functions. I have an example to get the adjacent (n-1) elements of a list. Expand|Select|Wrap|Line Numbers >>> def get_adj_items(itemList, col, n=3): ...     return itemList[max(0,col-(n-1)):col]+itemList[col:min(len(itemList),col+n)] ...  >>> get_adj_items([0,1,2,3,4,5,6,7,8,9,0], 4, 3) [2, 3, 4, 5, 6] >>> get_adj_items([0,1,2,3,4,5,6,7,8,9,0], 4, 4) [1, 2, 3, 4, 5, 6, 7] >>> get_adj_items([0,1,2,3,4,5,6,7,8,9,0], 1, 4) [0, 1, 2, 3, 4] >>>  That would narrow it down in determining if consecutive items are the same. Nov 26 '08 #5

 P: 8 Phew, I finally managed to make that algorithm. Maybe it's not the best way to do such check-function, but at least this works well for infinite board. I made different algorithms for rows, columns and diagonals. Here's that code: Here m represents the number of rows, n number of columns and k number of adjacent marks needed to win the game. Expand|Select|Wrap|Line Numbers def Row(board, m,n, k, mark):     counter = 0     for i in range(m):         for j in range(n):             if board[i][j] == mark:                 counter += 1                 if j == n-1 and counter != k:                     counter = 0                 elif counter == k:                     return True             else:                 counter = 0     return False   def Columns(board,m,n,k,mark):     counter = 0     for i in range(n):         for j in range(m):             if lauta[j][i] == mark:                 counter += 1                 if j == n-1 and counter != k:                     counter = 0                 elif counter == k:                    return True             else:                 counter = 0     return False   def DiagonalUp(board,m,n,k,mark):     counter = 0     for i in range(m):         for j in range(n):             if board[i][j] == mark:                 counter += 1                 if counter == k:                     return True             else:                 counter = 0             i -= 1             j += 1                         if i == -1 or j == n:                             counter = 0     return False     def DiagonalDown(board, m, n, k, mark):     counter = 0     for i in range(m):         for j in range(n):             if board[i][j] == mark:                 counter += 1                 if counter == k:                     return True             else:                 counter = 0             i += 1             if i == m:                 i = 0                                 counter = 0             elif j == n:                 j = 0     return False   def winner(board,mark,k, win,m,n):     R = Row(board,m,n,k,mark)     C = Columns(board,m,n,k,mark)     DU = DiagonalUp(board,m,n,k,mark)     DD = DiagonalDown(board,m,n,k,mark)     if R == True or C == True or DU == True or DD == True:         win = 0         return win     else:         win = 1         return win   Dec 8 '08 #6

 Expert 100+ P: 469 Does your program still detect a win if you get more than k pieces in a row? Edit: I think it does; never mind. Dec 8 '08 #7

 P: 8 Yes it does. That program checks if there are at least k pieces in a row, so if there are more it doesn't matter. But instead of that I found one mistake: If board size is rows:m and columns:m+2(or more), that checker wont work at all. If number of columns is rows + 1 or same as rows it will work. Also if there are more columns than rows it will work too. Now i need to check out where is that mistake and try to fix it. Dec 10 '08 #8 